Bug in Jitter

Alexandre Oliva oliva at dcc.unicamp.br
Wed Jul 8 01:11:20 PDT 1998


Tim Wilkinson wrote:

>> 3. It *does not* clean any registers nor does it flush the floating point
>> stack (on the x86).

If the FP pseudo-register is dirty, sync_registers will spill it,
which will remove it from the top of the FP stack.  That was the
problem I was trying to fix with my patch.  However, I installed it
quite a long time ago, and now I seem unable to reproduce the problem
I had met at some point in the past.  I should note, however, that I'm
no longer using sync_registers; end_sub_block was more like what I
wanted than sync_registers.

Godmar Back <gback at cs.utah.edu> writes:

> I also didn't see where it would flush the floating point stack.
> As far as I can see, sync_registers is used four times in icode.c:

It was not in Kaffe's code, it was Guaraná's code that triggered the
problem.  I was writing code like this, for INVOKEVIRTUAL:

#ifdef GUARANA
sync_registers();
load_offset_ref(tmp, ...)
cbranch_...(tmp, ...26)
#endif

/* Find dispatch table in object */
...
end_sub_block();
...
call(...);
...
popargs();

#ifdef GUARANA
branch_a(...27);
set_label(...26);
start_sub_block();
...
end_sub_block();
set_label(...27);
start_sub_block();
#endif
METHOD_RETURN_VALUE();


I used to have trouble when some instruction computed a float value in
the FP pseudo register, so the register was dirty.  When I ran
sync_registers, it would spill the FP register, because it was dirty,
but it would remain dirty.  Then, when it reached end_sub_block(),
before the `call', it would spill the FP register again, storing
garbage in the stack.  Now I see sync_registers does not do what I
expected, so the patch is probably unneeded.

> The difference between sync_registers and prepare_function_call
> is that sync_registers saves and restores the "enable_readonce" flag
> and that prepare_function_call flag "cleans" the register by resetting 
> the modified flag.  (As Tim says.)

That's probably the point: it marks a readonce register that was read
as unread.  But, in the contexts it is used, that is correct and, in
fact, that's exactly its purpose.  I just misunderstood its purpose.

> Tim also said:
>> You cannot use sync_registers() in a
>> position where the control flow will join another control flow 'cause it'll
>> break sometimes.

> I wonder when--and I guess that applies to prepare_function_call then as well...
> so that fix wouldn't work after all?

The scenario I presented above is one situation in which
sync_registers breaks, but prepare_function_call does not, because the
latter will not mark the read read-once register as not read.

Hope I was clear enough...

-- 
Alexandre Oliva
mailto:oliva at dcc.unicamp.br mailto:aoliva at acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil



More information about the kaffe mailing list