Rewriting byte codes

Erik Corry erik at arbat.com
Mon Apr 1 11:03:28 PST 2002


On Mon, Apr 01, 2002 at 01:05:50PM +0200, Artur Biesiadowski wrote:
> 
> Erik Corry wrote:
> 
> > There's a lot to be said for this, but since you can allocate
> > unlimited memory in an exception handler, every point that can
> > throw an exception has to be a safe point [...]
> 
> If exception is thrown, you don't care about registers (unless you 
> write-cache locals in registers,

Good point, but you still have the problems with a thread that
has been suspended by the OS at a random point (if you use OS
threads, which you have to if you want to benefit from SMP).

> but it will give problems even without 
> precise gc),

Why?  Not that x86 has enough registers, but it might be interesting
for RISC.  I think Hotspot allocates registers freely to both stack
and local variables.

> You also need to mark which local variables are live and which are 
> dead - because if you will use dead object pointers as live, you are 
> non-precise and possibly unstable (as it can point inside some newly 
> allocated object).

As far as I can see it can only be _either_ non-precise _or_
unstable.  It could be nonprecise in the sense that you might
not free some memory as soon as you could have (but not in the
sense that you can't have a moving collector), but if you don't
collect you can't get pointers inside a new object.  Obviously
imprecision is vastly preferable to instability.

You can get around the imprecision by inserting zeroing ops
at strategic places.  Even if you omit this step the GC
reliability is already much better than what we have now.

> But if you have variable map with local liveness you 
> can as well add object/primitive distinction there and forget about 
> explicit separation in memory :)

If you disambiguate local variables that can be used for
both references and nonreferences your 'map' is reduced
to a single bitmap per method, and the lookup function the
GC uses can be correspondingly simple.  If you also sort the
locals the map reduces to a single index which is the boundary
between the references and the nonreferences.

I still think you need a full map for the JVM operand stack
and/or registers.  You can make them quite compact if you get
clever about it.  For example you can put a rudimentary
disassembler in so the program can trace what's going on
from the last 'safe point' to the current place.

> AFAIK, hotspot stops thread, replaces closest safe points with some trap 
> and let thread run until it hit one. Then it restores original 
> instruction and voila.

This sounds pretty ugly to me, since it involves lots of writing
to the instruction stream with corresponding I-cache flushes etc.
But it's doable and perhaps simpler than keeping stack maps
around for all points.

> Generally - it is hard. Not even stack maps and their representation, 
> but getting everything working with threads in efficient manner.

Yes, I can see that.

-- 
Erik Corry erik at arbat.com


More information about the kaffe mailing list