The projected savings are on 64-bit only: 8 bytes savings per hotspot Method instance.
When allocating a Method class, also allocate the ConstMethod in a consecutive block in metaspace. This guarantees the distance from the Method to its _constMethod is never larger than 32-bits.
Also, change Method::_method_counters to a 2-level index with a 16bit top and 16bit bottom.
class Method {
private:
jint _const_method_offset;
ConstMethod* constMethod() const { return (ConstMethod*)(address(this) + _const_method_offset); }
ushort _method_counter_block;
ushort _method_counter_index;
MethodCounters* method_counters() const {
if (_method_counters_block == 0xffff) {
return NULL;
}
return &(_blocks[_method_counters_block][_method_counter_index]);
}
static MethodCounters** _blocks;
...
}
Note: in a CDS image, the Method and ConstMethod are allocated from two different regions (RW and RO), so they cannot be allocated consecutively. However, we can make sure that the (SharedReadWriteSize + SharedReadOnlySize) is less than 4GB, so _const_method_offset can still fit in 32 bits.