[kaffe] Re: flestmail - daily - 365/365 passed (100.0%) (0 errors, 0 failures)
stack at cs.utah.edu
Wed Sep 18 08:09:29 PDT 2002
On Tuesday, September 17, 2002, at 10:52 PM, Patrick Tullmann wrote:
> [infinite exception dispatch loops]
>> So, lets try and reexamine the whole thing...
>> First, what does the pc in the parameter list correspond to? The
>> current pc or the next pc?
> Anyway, I would expect the "pc" passed to findExceptionBlockInMethod
> to be the current pc (i.e, the point where the exception occured). I
> think code that passes in something else is probably broken, right?
>> Oops... Maybe we should change the intrp engine to set mjbuf->pc to
>> npc and see if that fixes it.
> Wouldn't that break the code that jumps to an exception handler and
> re-sets the PC based on the exception handler?
From the looks of it, this is two distinct uses of the same field. The
engine uses it to tell the exception code where it is in the method and
what handler should apply, but, otherwise the value placed in there is
ignored. Then, the exception code uses it to tell the engine what code
to execute next, in this case, the appropriate handler. It might be
to use a union here to distinguish the two.
>>> For the jitter, this gets set by buildStackTrace in stackTrace.c:
>>> info[cnt].pc = STACKTRACEPC(trace);
>>> So, it uses the return pc found in the stack trace, which
>>> corresponds to
>>> the next instruction to execute.
>> er, spoke too quickly. For a synchronous interrupt and subsequent
>> exception, this will be the current instruction. But, for a regular
>> throw, it will be the next pc.
> Hmm... that's the next *native* instruction. That's not necessarily
> the next bytecode instruction. (I imagine it usually happens to be
> so, though.)
Alas, i seemed to have missed something in i386/jit.h:
/* Extract the PC & FP from the given frame */
#define PCFRAME(f) ((f)->retpc-1)
#define FPFRAME(f) ((f)->retbp)
So, when it gets pc its returning a pointer to the previous instruction.
An x86 'call' is just one byte right? So, i guess that was working
correctly and the EXCEPTIONFRAME macro is wrong.
>> But, the i386 freebsd and linux exception frame initializers add a
>> one to the current pc:
>> /* Get the first exception frame from a signal handler */
>> EXCEPTIONFRAME(f, c) \
>> (f).retbp = (c)->sc_ebp; \
>> (f).retpc = (c)->sc_eip + 1
> Ugh. I wonder if that was added to get around this exception problem?
> (that line is from March `98....) Anyway, adding 1 to an x86 EIP
> isn't always going to point to a real instruction is it?
> It seems that the regular throw JIT case is the only one where we
> might have trouble getting the "current" PC (since the STACKTRACEPC()
> macro pulls the return code off the stack which is probably the first
> native instruction of the next bytecode). Seems to me that the right
> thing to happen is to fix that up with some magic and a comment, and
> have all the other cases record the "current" pc directly.
Indeed, lets list the changes:
Your fix for the exception range check.
All EXCEPTIONFRAME() macros should set retpc to the current
pc and not add one to it.
Maybe make the "pc" field in vmException a union to clarify its
Add a test, this is a bit complicated since you need an exception
to be thrown on the very edge of the exception range.
Add some bloody comments
>> Also, grepping for "end_pc" turns up this code in
>> in jit/machine.c
>> /* include only if exception handler range matches pc */
>> if (meth->exception_table->entry[i].start_pc > pc ||
>> meth->exception_table->entry[i].end_pc <= pc)
>> Now, that doesn't look right to me...
> Heh, that's funny. Should the old jit just be removed from the
> current version? Do any architectures use it?
i think a couple of platforms still use it...
More information about the kaffe