RFR: 8334220: Optimize Klass layout after JDK-8180450
Xiaolong Peng
xpeng at openjdk.org
Sat Jun 29 20:03:26 UTC 2024
Hi all,
This PR is created to optimize the layout of Klass in hotspot, after JDK-8180450 the layout of Klsss seems broken, there are 3 holes, they are caused by alignment issue introduced by the 1 byte ```_hash_slot```.
(gdb) ptype /ox Klass
/* offset | size */ type = class Klass : public Metadata {
public:
static const uint KLASS_KIND_COUNT;
protected:
/* 0x000c | 0x0004 */ jint _layout_helper;
/* 0x0010 | 0x0004 */ const enum Klass::KlassKind _kind;
/* 0x0014 | 0x0004 */ jint _modifier_flags;
/* 0x0018 | 0x0004 */ juint _super_check_offset;
/* XXX 4-byte hole */
/* 0x0020 | 0x0008 */ class Symbol *_name;
/* 0x0028 | 0x0008 */ class Klass *_secondary_super_cache;
/* 0x0030 | 0x0008 */ class Array<Klass*> *_secondary_supers;
/* 0x0038 | 0x0040 */ class Klass *_primary_supers[8];
/* 0x0078 | 0x0008 */ class OopHandle {
private:
/* 0x0078 | 0x0008 */ class oop *_obj;
/* total size (bytes): 8 */
} _java_mirror;
/* 0x0080 | 0x0008 */ class Klass *_super;
/* 0x0088 | 0x0008 */ class Klass * volatile _subklass;
/* 0x0090 | 0x0008 */ class Klass * volatile _next_sibling;
/* 0x0098 | 0x0008 */ class Klass *_next_link;
/* 0x00a0 | 0x0008 */ class ClassLoaderData *_class_loader_data;
/* 0x00a8 | 0x0008 */ uintx _bitmap;
/* 0x00b0 | 0x0001 */ uint8_t _hash_slot;
/* XXX 3-byte hole */
/* 0x00b4 | 0x0004 */ int _vtable_len;
/* 0x00b8 | 0x0004 */ class AccessFlags {
private:
/* 0x00b8 | 0x0004 */ jint _flags;
/* total size (bytes): 4 */
} _access_flags;
/* XXX 4-byte hole */
/* 0x00c0 | 0x0008 */ traceid _trace_id;
private:
/* 0x00c8 | 0x0002 */ s2 _shared_class_path_index;
/* 0x00ca | 0x0002 */ u2 _shared_class_flags;
/* 0x00cc | 0x0004 */ int _archived_mirror_index;
public:
static const int SECONDARY_SUPERS_TABLE_SIZE;
static const int SECONDARY_SUPERS_TABLE_MASK;
static const uintx SECONDARY_SUPERS_BITMAP_EMPTY;
static const uintx SECONDARY_SUPERS_BITMAP_FULL;
static const int _lh_neutral_value;
static const int _lh_instance_slow_path_bit;
static const int _lh_log2_element_size_shift;
static const int _lh_log2_element_size_mask;
static const int _lh_element_type_shift;
static const int _lh_element_type_mask;
static const int _lh_header_size_shift;
static const int _lh_header_size_mask;
static const int _lh_array_tag_bits;
static const int _lh_array_tag_shift;
static const int _lh_array_tag_obj_value;
static const unsigned int _lh_array_tag_type_value;
/* total size (bytes): 208 */
}
As Aleksey suggested, moving _hash_slot to somewhere later could solve the alignments issue, I have tested it it works well, but causes 2 smaller holes in the private fields which could be solved by padding.
Layout after moving _hash_slot w/o padding
/* offset | size */ type = class Klass : public Metadata {
public:
static const uint KLASS_KIND_COUNT;
protected:
/* 0x0008 | 0x0004 */ jint _layout_helper;
/* 0x000c | 0x0004 */ const enum Klass::KlassKind _kind;
/* 0x0010 | 0x0004 */ jint _modifier_flags;
/* 0x0014 | 0x0004 */ juint _super_check_offset;
/* 0x0018 | 0x0008 */ class Symbol *_name;
/* 0x0020 | 0x0008 */ class Klass *_secondary_super_cache;
/* 0x0028 | 0x0008 */ class Array<Klass*> *_secondary_supers;
/* 0x0030 | 0x0040 */ class Klass *_primary_supers[8];
/* 0x0070 | 0x0008 */ class OopHandle {
private:
/* 0x0070 | 0x0008 */ oop *_obj;
/* total size (bytes): 8 */
} _java_mirror;
/* 0x0078 | 0x0008 */ class Klass *_super;
/* 0x0080 | 0x0008 */ class Klass * volatile _subklass;
/* 0x0088 | 0x0008 */ class Klass * volatile _next_sibling;
/* 0x0090 | 0x0008 */ class Klass *_next_link;
/* 0x0098 | 0x0008 */ class ClassLoaderData *_class_loader_data;
/* 0x00a0 | 0x0008 */ uintx _bitmap;
/* 0x00a8 | 0x0004 */ int _vtable_len;
/* 0x00ac | 0x0004 */ class AccessFlags {
private:
/* 0x00ac | 0x0004 */ jint _flags;
/* total size (bytes): 4 */
} _access_flags;
/* 0x00b0 | 0x0008 */ traceid _trace_id;
/* 0x00b8 | 0x0001 */ uint8_t _hash_slot;
private:
/* XXX 1-byte hole */
/* 0x00ba | 0x0002 */ s2 _shared_class_path_index;
/* 0x00bc | 0x0002 */ u2 _shared_class_flags;
/* XXX 2-byte hole */
/* 0x00c0 | 0x0004 */ int _archived_mirror_index;
public:
static const int SECONDARY_SUPERS_TABLE_SIZE;
static const int SECONDARY_SUPERS_TABLE_MASK;
static const uintx SECONDARY_SUPERS_BITMAP_EMPTY;
static const uintx SECONDARY_SUPERS_BITMAP_FULL;
static const int _lh_neutral_value;
static const int _lh_instance_slow_path_bit;
static const int _lh_log2_element_size_shift;
static const int _lh_log2_element_size_mask;
static const int _lh_element_type_shift;
static const int _lh_element_type_mask;
static const int _lh_header_size_shift;
static const int _lh_header_size_mask;
static const int _lh_array_tag_bits;
static const int _lh_array_tag_shift;
static const int _lh_array_tag_obj_value;
static const unsigned int _lh_array_tag_type_value;
/* XXX 4-byte padding */
/* total size (bytes): 200 */
}
```
Layout after moving _hash_slot with padding:
/* offset | size */ type = class Klass : public Metadata {
public:
static const uint KLASS_KIND_COUNT;
protected:
/* 0x0008 | 0x0004 */ jint _layout_helper;
/* 0x000c | 0x0004 */ const enum Klass::KlassKind _kind;
/* 0x0010 | 0x0004 */ jint _modifier_flags;
/* 0x0014 | 0x0004 */ juint _super_check_offset;
/* 0x0018 | 0x0008 */ class Symbol *_name;
/* 0x0020 | 0x0008 */ class Klass *_secondary_super_cache;
/* 0x0028 | 0x0008 */ class Array<Klass*> *_secondary_supers;
/* 0x0030 | 0x0040 */ class Klass *_primary_supers[8];
/* 0x0070 | 0x0008 */ class OopHandle {
private:
/* 0x0070 | 0x0008 */ oop *_obj;
/* total size (bytes): 8 */
} _java_mirror;
/* 0x0078 | 0x0008 */ class Klass *_super;
/* 0x0080 | 0x0008 */ class Klass * volatile _subklass;
/* 0x0088 | 0x0008 */ class Klass * volatile _next_sibling;
/* 0x0090 | 0x0008 */ class Klass *_next_link;
/* 0x0098 | 0x0008 */ class ClassLoaderData *_class_loader_data;
/* 0x00a0 | 0x0008 */ uintx _bitmap;
/* 0x00a8 | 0x0004 */ int _vtable_len;
/* 0x00ac | 0x0004 */ class AccessFlags {
private:
/* 0x00ac | 0x0004 */ jint _flags;
/* total size (bytes): 4 */
} _access_flags;
/* 0x00b0 | 0x0008 */ traceid _trace_id;
/* 0x00b8 | 0x0001 */ uint8_t _hash_slot;
/* 0x00b9 | 0x0003 */ char _pad_buf1[3];
private:
/* 0x00bc | 0x0002 */ s2 _shared_class_path_index;
/* 0x00be | 0x0002 */ u2 _shared_class_flags;
/* 0x00c0 | 0x0004 */ int _archived_mirror_index;
public:
static const int SECONDARY_SUPERS_TABLE_SIZE;
static const int SECONDARY_SUPERS_TABLE_MASK;
static const uintx SECONDARY_SUPERS_BITMAP_EMPTY;
static const uintx SECONDARY_SUPERS_BITMAP_FULL;
static const int _lh_neutral_value;
static const int _lh_instance_slow_path_bit;
static const int _lh_log2_element_size_shift;
static const int _lh_log2_element_size_mask;
static const int _lh_element_type_shift;
static const int _lh_element_type_mask;
static const int _lh_header_size_shift;
static const int _lh_header_size_mask;
static const int _lh_array_tag_bits;
static const int _lh_array_tag_shift;
static const int _lh_array_tag_obj_value;
static const unsigned int _lh_array_tag_type_value;
/* XXX 4-byte padding */
/* total size (bytes): 200 */
}
Best,
Xiaolong.
-------------
Commit messages:
- Merge branch 'openjdk:master' into klass-layout
- 8334220: Optimize Klass layout after JDK-8180450
Changes: https://git.openjdk.org/jdk/pull/19958/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=19958&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8334220
Stats: 4 lines in 1 file changed: 3 ins; 1 del; 0 mod
Patch: https://git.openjdk.org/jdk/pull/19958.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/19958/head:pull/19958
PR: https://git.openjdk.org/jdk/pull/19958
More information about the hotspot-dev
mailing list