Re: Dynamic oplibs - intermediate summary
On Thu, Oct 16, 2003 at 05:40:30PM +0200, Leopold Toetsch wrote: As JIT code is unrolled, it IMHO can only call the function core (or CGP again) for loaded opcodes. As is this would mean that the JIT can't JIT any opcodes that are brought in by dynamically loaded classes, it would be pain for any heavy users of custom classes. Would it be beneficial (and feasible) to either provide a mechanism (flag on the command line, flag in the bytecode, whatever parrot treats treats a perl-level pragma as, etc, not sure) to either a: disable the JIT until the main program starts (running on CG or some other low startup cost core until then) or b: signal a (partial) re-JIT of something/everything after a library/ everything has loaded? I've no idea how easy this might be. Or sensible. Nicholas Clark
Re: Dynamic oplibs - intermediate summary
On Thu, 16 Oct 2003, Nicholas Clark wrote: On Thu, Oct 16, 2003 at 05:40:30PM +0200, Leopold Toetsch wrote: As JIT code is unrolled, it IMHO can only call the function core (or CGP again) for loaded opcodes. As is this would mean that the JIT can't JIT any opcodes that are brought in by dynamically loaded classes, it would be pain for any heavy users of custom classes. This should only be temporary. If the right information is tagged in the opcode library, then the JIT should be able to JIT the loaded ops (since we do, after all, have to have the library loaded when we enter the segment of code that uses the new ops. I don't mind just in time loading, but I figure we ought to do it more than one or two ops before we execute the new code. :) Dan
Dynamic oplibs - intermediate summary
Now all run cores[2] are able to execute dynoplibs/test.pasm [1]. This is currently done for all cores except the function (slow) core by running the wrapper__ opcode, which calls the real function in the parrot function core. Cores with an address table for function dispatch (CGoto, CGP) get a new address table, where all new entries are pointing to the wrapper__ opcode. CGP does use this address table only once when the opcode is predereferenced. The switch core calls the wrapper from the default case statement. JIT emits a call to the wrapper function. Next will be to try to find and load oplibs of the flavor of the currently running core. If a program is run with the -C (CGP) core, the dynop_register function will try to find the ..._cgp_ops_load symbol in the current dynamic oplib or in a separate file. If this is successful, the opcode dispatch can use these opcodes directly. The switch core will need some dispatch helpers (probably via next function pointers containing loaded switch_cores. JIT is different. As JIT code is unrolled, it IMHO can only call the function core (or CGP again) for loaded opcodes. When run from a source file, the Cloadlib opcode is executed immediately, so that the assembler can generate the bytecode with these new opcodes. At runtime the loadlib finds the library already loaded and does nothing (it could even be replaced by Cnoops if its known, that the program is to be run directly). When a PBC is generated, and the code is run from that, now the Cloadlib is honored, when it is executed. So when there are multiple loadlibs and these are not executed in the correct sequence, you'll get nice crashes. This will be replaced (as Dan did lay out) by putting the library PMCs into the metadata, so that library loading happens before program startup and in the desired sequence. Comments welcome, leo [1] $ cat dynoplibs/test.pasm ... loadlib P1, myops_ops ... fortytwo I0 print I0 what_do_you_get_if_you_multiply_six_by_nine S0 ... $ make shared export LD_LIBRARY_PATH=.:blib/lib $ make -C dynoplibs clean all make -C dynclasses make libnci.so $ parrot -j dynoplibs/test.pasm in test loaded myops_ops loaded foo loaded libnci found 3 libs Ops runtime/parrot/dynext/myops_ops.so PMC runtime/parrot/dynext/foo.so NCI libnci.so the answer is: 42 aka fortytwo [2] *if* platform supports dynamic loading of course. I didn't look at EXEC, but as it does use JIT for building its code, it could work too.
Re: Dynamic oplibs - intermediate summary
Nicholas Clark [EMAIL PROTECTED] wrote: On Thu, Oct 16, 2003 at 05:40:30PM +0200, Leopold Toetsch wrote: As JIT code is unrolled, it IMHO can only call the function core (or CGP again) for loaded opcodes. As is this would mean that the JIT can't JIT any opcodes that are brought in by dynamically loaded classes, it would be pain for any heavy users of custom classes. [ snip ] First - no pain. CGP and JIT rutimes are equally fast with PMC related code. JIT only shines with natural int loops doing int and float arithmetics. When it comes to HLL there is no difference in performance - both cores just do function calls. Second - as said the JIT core does unroll opcodes, that is each JITted assembly representation of any opcode is repeated in the execution stream of the JITted instructions. While any other core branches around in a fixed set of opcodes, the JIT runtime has a sequence of assembly instructions representing these opcodes. Now when you load such opcodes dynamically, there is no means to insert these into the current CPU instructions - there is no hardware CPU representaion for loaded ops (if there is any, the opcode would be in core, because it is important) Nicholas Clark leo