JDK-8334220 : Optimize Klass layout after JDK-8180450
  • Type: Sub-task
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 23
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2024-06-13
  • Updated: 2024-06-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
For unrelated change, I looked at `ptype /ox Klass` on recent mainline, and noticed considerable holes:

```
$ gdb shipilev-jdk/build/linux-aarch64-server-release/images/jdk/bin/java
...
(gdb) run
...
(gdb) ptype /ox Klass
...
/* 0x0098      |  0x0008 */    class ClassLoaderData *_class_loader_data;
/* 0x00a0      |  0x0008 */    uintx _bitmap;
/* 0x00a8      |  0x0001 */    uint8_t _hash_slot;
/* XXX  3-byte hole      */
/* 0x00ac      |  0x0004 */    int _vtable_len;
/* 0x00b0      |  0x0004 */    class AccessFlags {
                                 private:
/* 0x00b0      |  0x0004 */        jint _flags;

                                   /* total size (bytes):    4 */
                               } _access_flags;
/* XXX  4-byte hole      */
/* 0x00b8      |  0x0008 */    traceid _trace_id;
                             private:
/* 0x00c0      |  0x0002 */    s2 _shared_class_path_index;
/* 0x00c2      |  0x0002 */    u2 _shared_class_flags;
...
```

I believe this is caused by introduction of `uint8_t _hash_slot` with JDK-8180450. We can just move that field somewhere later to avoid `_access_flags` and `_trace_id` alignment gaps.

Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/19958 Date: 2024-06-29 19:58:23 +0000
29-06-2024

Here is the layout after adding 3 bytes after _hash_slot to align memory layout. ``` /* 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; ```
29-06-2024

After moving `uint8_t _hash_slot` to the place after traceid _trace_id, this is the layout, since _hash_slot is just one byte it still causes two smaller holes in the private fields, I think we could add 3 padding bytes after _hash_slot. ``` /* 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; ...
29-06-2024