Call for Discussion: New Project: Lilliput

Gil Tene gil at azul.com
Sun Mar 14 05:49:59 UTC 2021



Sent from Gil's iPhone

> On Mar 13, 2021, at 6:44 PM, John Rose <john.r.rose at oracle.com> wrote:
> 
> On Mar 12, 2021, at 2:50 PM, Roman Kennke <rkennke at redhat.com> wrote:
>> 
>>> 
>>>  I had done experiments with a klass pointer indirection, which could effectively be a klass index.
>> 
>> I had a little exchange with Thomas Stuefe, and we believe we can split Klass into fixed-sized part, and variable-sized part, have the fixed-size base reference the variable-sized part. Then we can allocate the fixed Klass instances into a 'flat' array in a contiguous memory region, and with some smart placement and aligmment we can use a compressed pointer to address it, which will effectively be an index into that array. Which means that with N bits of compressed-class-pointer we could address 2^N Klasses :-) No indirection needed if done so afaict.
> 
> Coleen and I discussed similar work several years ago.
> My recollection is that there was a problem (at the time)
> with v-table access, because of the extra indirection.
> It may well have gotten worse in recent years.
> 
> I also think the fixed-part/variable-sized part (aka. near klass
> and far klass) are likely to be a winning idea, in part because
> we may wish to have a larger number of near-klasses than
> far-klasses when we start doing specialized classes.
> 
> I suggest making the size of the fixed-sized block (near-klass)
> configurable via a build-time or even run-time parameter.
> That would allow the first N items in the v-table to spill
> into the near-class, and avoid the indirection penalty for
> the first N virtual methods in any given class.
> 
> I suppose Gil’s team experimented with something like
> this before settling on “kids” pointing to pointers, which
> are the minimum size of a near-klass (64 bits).  Maybe they
> may have some further experience with this.

Yeah, we played around with all sorts of “what else, other
than a klass pointer, would you want in the klass table
(indexed by kid)?” questions for over a decade now.
There’s the “first few vtable entries” thing. And the “stuff
about interface relationships” thing. The “bit mapped
ooptable for the first n words in the object” thing. And lots
of other things.

In the end, a single 64 bit pointer is where we are at... we
do keep playing with aliased tables with such added
information, on and off, but nothing huge in those so far.
Our preferred approach when doing those experiments is
to use an additional flat arrays indexed by kid, rather than
extending the “struct” in the klass table beyond 64 bits
per entry.

The way I’d summarize our overall empiric observation is
that with tier-2 compilers doing stuff like multi-morphic
guarded inlining (e.g. bi-morphic, tri-morphic, etc.) and
multi-morphic inline caching, the impact of an extra
indirection on actual vtable calls in code that is either not
hot enough to get those optimizations or too mega-morphic
to benefit from them is not big enough to add vtable info
at that level...

Obviously, all of our type comparisons and checks are done
using kids and kid constants, not klass pointers. So no 
dereferencing is done unless we actually need to get at
something in a klass that is not already extracted as a
constant and inlined somewhere else.

It’s worth noting that in Zing, klasses still live in the heap, in a
permgen (much like pre-metaspace hotspot used to do),
because with a concurrent compacting collector (C4),
off-heaping that stuff was not a benefit, and would have only
added downsides (like needing to manage and gc a separate
meta space). That means that the “klass pointers” in the Zing
klass table are actually klass references (and proper oops).
But this difference should not be material to the subject at
hand. Metaspace “GC” in hotspot would obviously need to be
aware of the table, but that’s about it. I think.

> 
> — John


More information about the discuss mailing list