Kaffe 1.0.6 on ARM
gback at cs.utah.edu
Tue Dec 19 15:23:59 PST 2000
Oops, sorry for sending that empty mail.
I was going to comment on Bart's mail.
The documentation his student wrote is definitely a good introduction;
there's also a link on that page to an earlier document written
by Kiyo Inaba.
I'd like to add that trampolines since take a third parameter,
"where". The parameter says where a pointer to that trampoline
is stored. In general, a non-static method can have multiple
trampolines that point to it. Specifically, you can have
pointers to trampolines:
- in the dispatch table of the defining class. This trampoline is the
"primary" trampoline (as defined by me on the fly.)
- in the dispatch table of any inheriting class
- in the interface dispatch tables of the defining or any inheriting class
The way the code is written, you can build a trampoline anywhere
should you need to, but those are the occassions where we use them.
The trampolines are freed when they're invoked, except for the
primary trampoline, which is freed when the first trampoline for
that method is invoked. This is possible because the primary
trampoline can be found through the dispatch table of the method's
defining class. (A more eager approach may keep track of all
trampolines for a method, and free them all once a method is invoked
for the first time. It may save some memory.)
Trampolines that haven't been used are freed when the class is unloaded.
Turns out the current code is broken in the presence of class gc.
If I have the time I'll put the necessary fixes in.
The reason it's broken is because the destroyClass method uses a
broken algorithm to find out whether a trampoline wasn't used.
Specifically, it checks whether the pointer points to a trampoline,
and if so, frees it. However, since destroyClass is run w/o the
allocator lock, it can happen (and in fact does happen) that a
trampoline that is invoked gets freed, reallocated by the jitter,
freed by destroyclass in a superclass when the defining method is freed,
reallocated as a new trampoline and then the pointer mistakenly freed
in a subclass.
It is unlikely to happen in standard kaffe because there's only
one garbage collector, but it is still possible because of the
priority inversion introduced by the allocator lock when objects
are freed, so the code is broken.
One answer is to declare trampoline GC_NOWALK and walk the dispatch
and interface dispatch tables in walkClass. Another answer would be
to take the more eager approach described above.
As a meta comment, this is one occassion where one of the design
decisions relating to how I implemented class gc in kaffe didn't turn
out as well.
My intention was to lighten the burden of the collector by essentially
minimizing the number of objects that it keeps track of.
My reasoning was that those objects that are associated with a class
have clearly defined lifetimes, and hence the explicit memory management
is manageable. While that may be true for most data associated with
class objects, it is not true for trampolines, and hence the right
thing to do is to have the collector track and free them. This just
as an aside. One always learns.
> In message <20001219101041.I1069 at marcus-lx> Marcus Smith wrote:
> > Is there a good document that explains what a "trampoline"
> > is? By studying the code, I think I know, but it would be
> > good to get a paragraph or two.
> One of my students wrote some documentation on this and
> other things a while back. See
> for a description of Kaffe trampolines, and kaffe/index.html
> for some general Kaffe implementation info and info about
> the student project. Some of the details are out of date,
> but I think the general ideas are sound. (If I'm wrong, I'm
> sure someone will be happy to publically correct this
> misapprehension. :-)
> Hope this helps!
> Bart Massey
> bart at cs.pdx.edu
More information about the kaffe