Moving the _vtable_len into Klass
mikael.gerdin at oracle.com
Thu Dec 17 14:29:40 UTC 2015
On 2015-12-16 21:48, John Rose wrote:
> On Dec 16, 2015, at 9:26 AM, Chris Plummer <chris.plummer at oracle.com
> <mailto:chris.plummer at oracle.com>> wrote:
>>> Does anyone know if there is a reason for vtable_length_offset to be
>>> a word offset?
>> Sorry, I don't have any historical perspective here, other than saying
>> that specifying size, lengths, and offsets for InstanceKlass related
>> stuff seems to all be scaled to HeapWordSize. Just started looking in
>> this area recently for the first time myself. BTW, I think it should
>> be using wordSize instead of HeapWordSize, although they do both
>> evaluate to the same thing.
> Basic facts:
> InstanceKlass and ArrayKlass are the only subclasses of Klass.
> Java objects can be instances or arrays, and both have v-tables.
> Array v-tables have uninteresting Object methods (only clone is special).
> In the A2.0 future, Array v-tables will (probably) have additional methods.
> Therefore the property of having a v-table is universal to all Klasses.
> Therefore this is a good refactoring.
> Here are some bits of ancient history, plus thoughts on scaled sizes:
> In the old days (metadata in perm-gen) some Klasses (method-klass,
> instance-klass-klass, etc.) did *not* have v-tables.
> The necessary alignment of v-table position between InstanceKlass and
> ArrayKlass had to be forced by a hack. We have inherited this hack,
> but should get rid of it.
> The original sizing logic for HotSpot was designed for 32-bit machines.
> Using 32-bit integers, sizing logic for some Java data structures is subject
> to embarrassing overflows. (Consider `new long[0x7FFFFFFE]`.)
> Even size_t (which is unsigned) doesn't quite have enough bits of
> dynamic range. And size_t itself was new (not so portable) when
> HotSpot was first written. Also, 64-bit integer arithmetic was more
> expensive in those days, on some platforms, so the original coders
> did not resort to uint64_t for sizing calculations.
> By working with ints scaled by wordSize (== sizeof(HeapWord)),
> we bought a couple more bits of dynamic range, to avoid overflows
> more easily. Having 32-bit ints stored in metadata is also a little
> more compact, although this sometimes comes with a risk of
> truncation when large values pass through small storage fields.
I appreciate that word sizes are useful and sometimes necessary on 32
bit platforms but I think that offsets of fields inside structs should
never be so large as to require wordSize scaling.
> Today's trade-offs:
> Nowadays, it would be reasonable to use unscaled sizes almost
> everywhere, passed as uint64_t values, and stored smaller
> where possible (using scaling or var-ints or whatever, as a
> local decision).
> (BTW, I think we should use more UNSIGNED5 var-ints for
> metadata sizes, to save footprint and provide safer dynamic range.)
> Even from the beginning, the JVM used a mix of scaled
> and unscaled size values, although there was an attempt
> to make the scaled ones predominate. At some point
> we tried to introduce some static typing help to avoid
> the obvious sort of bugs; see classes ByteSize and
> WordSize. These are helpful but also not universal.
> So we have a mix of conventions, not always clearly
> sorted out. The complexity and bug-worthiness of
> this setup is the biggest down-side to scaled size logic.
> An up-side of having scaled sizes is you get 2-3 more bits
> of dynamic range. A down-side of having scaled sizes is
> you have to decode scaled values by shifting them 2-3 bits.
> Sometimes x86 addressing modes help make this decoding
> happen "for free" as part of an address formation operation,
> but in practice I think this happens unreliably.
> (Using a tighter encoding like UNSIGNED5 could decode
> about as quickly as an explicit shift, but gain more footprint
> benefits. But that's a future conversation.)
> I personally don't regard the up-sides for scaled sizes as
> sufficient, now that 64-bit math is perfectly cheap.
> It will be will be hard to change to unscaled sizes everywhere,
> (and I've surely not given the full arguments both ways!)
> so we will be living in a mixed world for the foreseeable
> future. I do think, however, that it is reasonable to remove
> scaled sizes from JVM internal APIs, incrementally over time.
> Bottom line: My suggestion is that you make Klass admit
> that it always has a v-table, and don't feel bad about using
> unscaled sizes appearing in the JVM internal APIs, as long
> as you control footprint inside each class.
Thanks for the detailed background info, John.
My current plan is to first modify the vtable_length_offset accessor to
return a byte offset (which is what it's translated to by all callers).
Then I'll tackle moving the _vtable_len field to Klass.
Finally I'll try to consolidate the vtable related methods to Klass,
where they belong.
The vtable_start_offset is a slightly more difficult beast since it's
more often used in wordSize scaled calculations, my current idea is to
leave it alone for now.
Does that sound like a good plan?
> — John
More information about the hotspot-dev