On Thursday 14 November 2002 05:14, Leopold Toetsch wrote: > Dan Sugalski wrote: > > I'm about to do exceptions, and as such I wanted to give a quick warning > > to everyone who does Odd Things. (Which would be in the JIT, mainly :) > > > > Because of the way exceptions are going to work, we need to make sure > > that the code emitted for each individual opcode is self-contained, > > relative to the system stack. That is to say, when an opcode is done it > > can't leave any cruft on the system stack, and it shouldn't expect there > > to be any information on the system stack. > > This would mean, that current jit/i386 is not ok, because it pushes a > parrot Interp* on the stack in Parrot_jit_begin and leaves it there ... >
That's just a speed hack that will go away when the moment comes. > > The exception system's going to be based on setjmp/longjmp[*], with a > > setjmp done just before entering the runloop, and longjmps done when an > > exception is thrown. The low-level exception handler will then unwind > > the interpreter stacks until it finds an exception handler, at which > > point it'll enter the runloop at the point the exception handler > > dictates. > > .... but reentering the (jitted) runloop is just like Parrot_jit_begin + > jump to current_pc, so it would be ok. > > > ... So recursive > > calls to parrot functions can't recursively use the system stack or > > anything, as that'll get unwound by the low-level exception scheme and > > Bad Things Will Happen. And we wouldn't want that... > > I don't see any recursive calls. But anyway, when on (re)entering the > runloop everything gets setup as it ought to, an exception is a noop. > > What I'm missing here? > > The real problem is different IMHO and we had this already with perl 6 > exceptions[1]: resuming after an exception may theoretically happen on > an arbitrary opcode, which might be e.g. in midst of a jitted section, > where parrot registers live in processor registers. > What JIT needs to know is the location of the resume opcode, to mark it > as a jump target properly, so that processor registers can be setup > correctly. Well, any opcode could be a target, so I suggest to build something like a section entrance code that given the PC could load the apropiate registers and jump to the middle of a jitted section. Yes, it will be slow but we are talking about exceptions here. > More problems arise here: The exception handler might use parrot > registers, which might live (or better might have lived) in processor > registers, which the longjmp already has destroyed. > So we IMHO need to mark each OP with a flag, if it might throw an > exception and restore all processor registers to parrot registers before > doing this OP. > Since there isn't any jitted opcode throwing an exception (and all registers are saved back to parrot register before calling C code), and if there were any opcode jitted throwing an exception it must save the registers back before doing so. > [1] imcc marks the address of a set_addr OP as branch target, so that > this basic block wouldn't be removed by dead code detection and the > register allocator does know what to do. When a arbitrary opcode can > jump out of the current block and resume elsewhere, the register > allocator can't assign the same registers to these variables. > > So we have 3 levels, where we might have troubles: > - JIT: processor registers > - IMCC: parrot registers > - HL: lexicals > > leo Daniel Grunblatt.