RFR: 8334231: Optimize MethodData layout

Xiaolong Peng xpeng at openjdk.org
Thu Jul 4 00:36:33 UTC 2024


Hi all,
     This PR is a part of the https://bugs.openjdk.org/browse/JDK-8334227 to optimize Hotspot C++ class layouts, this one is for the layout of  MethodData. Here is the original layout from `pahole`:

class MethodData : public Metadata {
public:

	/* class Metadata            <ancestor>; */      /*     0     0 */

	/* XXX 8 bytes hole, try to pack */

	class Method *             _method;              /*     8     8 */
	int                        _size;                /*    16     4 */
	int                        _hint_di;             /*    20     4 */
	class Mutex               _extra_data_lock;      /*    24   104 */
	/* --- cacheline 2 boundary (128 bytes) --- */
	class CompilerCounters    _compiler_counters;    /*   128    80 */
	/* --- cacheline 3 boundary (192 bytes) was 16 bytes ago --- */
	intx                       _eflags;              /*   208     8 */
	intx                       _arg_local;           /*   216     8 */
	intx                       _arg_stack;           /*   224     8 */
	intx                       _arg_returned;        /*   232     8 */
	int                        _creation_mileage;    /*   240     4 */
	class InvocationCounter   _invocation_counter;   /*   244     4 */
	class InvocationCounter   _backedge_counter;     /*   248     4 */
	int                        _invocation_counter_start; /*   252     4 */
	/* --- cacheline 4 boundary (256 bytes) --- */
	int                        _backedge_counter_start; /*   256     4 */
	uint                       _tenure_traps;        /*   260     4 */
	int                        _invoke_mask;         /*   264     4 */
	int                        _backedge_mask;       /*   268     4 */
	short int                  _num_loops;           /*   272     2 */
	short int                  _num_blocks;          /*   274     2 */
	enum WouldProfile          _would_profile;       /*   276     4 */
	int                        _jvmci_ir_size;       /*   280     4 */

	/* XXX 4 bytes hole, try to pack */

	class FailedSpeculation *  _failed_speculations; /*   288     8 */
	int                        _data_size;           /*   296     4 */
	int                        _parameters_type_data_di; /*   300     4 */
	int                        _exception_handler_data_di; /*   304     4 */

	/* XXX 4 bytes hole, try to pack */

	intptr_t                   _data[1];             /*   312     8 */

	/* size: 320, cachelines: 5, members: 27 */
	/* sum members: 304, holes: 3, sum holes: 16 */
};


There are 3 holes in the layout, the 1st 8-byte hole seems related to the ancestor Metadata which actually has 8-byte size, we may not be able to do anything to optimize:

class Metadata : public MetaspaceObj {
public:

	/* class MetaspaceObj        <ancestor>; */      /*     0     0 */

	/* XXX last struct has 1 byte of padding */

	int ()(void) * *           _vptr.Metadata;       /*     0     8 */

	/* size: 8, cachelines: 1, members: 2 */
	/* paddings: 1, sum paddings: 1 */
	/* last cacheline: 8 bytes */
};


The two 4-byte holes should be easy to fix, we can simply swap the position of  _jvmci_ir_size and _failed_speculations for better alignment. Here is the new layout after the change:

class MethodData : public Metadata {
public:

	/* class Metadata            <ancestor>; */      /*     0     0 */

	/* XXX 8 bytes hole, try to pack */

	class Method *             _method;              /*     8     8 */
	int                        _size;                /*    16     4 */
	int                        _hint_di;             /*    20     4 */
	class Mutex               _extra_data_lock;      /*    24   104 */
	/* --- cacheline 2 boundary (128 bytes) --- */
	class CompilerCounters    _compiler_counters;    /*   128    80 */
	/* --- cacheline 3 boundary (192 bytes) was 16 bytes ago --- */
	intx                       _eflags;              /*   208     8 */
	intx                       _arg_local;           /*   216     8 */
	intx                       _arg_stack;           /*   224     8 */
	intx                       _arg_returned;        /*   232     8 */
	int                        _creation_mileage;    /*   240     4 */
	class InvocationCounter   _invocation_counter;   /*   244     4 */
	class InvocationCounter   _backedge_counter;     /*   248     4 */
	int                        _invocation_counter_start; /*   252     4 */
	/* --- cacheline 4 boundary (256 bytes) --- */
	int                        _backedge_counter_start; /*   256     4 */
	uint                       _tenure_traps;        /*   260     4 */
	int                        _invoke_mask;         /*   264     4 */
	int                        _backedge_mask;       /*   268     4 */
	short int                  _num_loops;           /*   272     2 */
	short int                  _num_blocks;          /*   274     2 */
	enum WouldProfile          _would_profile;       /*   276     4 */
	class FailedSpeculation *  _failed_speculations; /*   280     8 */
	int                        _jvmci_ir_size;       /*   288     4 */
	int                        _data_size;           /*   292     4 */
	int                        _parameters_type_data_di; /*   296     4 */
	int                        _exception_handler_data_di; /*   300     4 */
	intptr_t                   _data[1];             /*   304     8 */

	/* size: 312, cachelines: 5, members: 27 */
	/* sum members: 304, holes: 1, sum holes: 8 */
	/* last cacheline: 56 bytes */
};


The two 4-byte holes are removed, saving 8 bytes. 

Also removed unnecessary `private: `  mark.

Additional test:
- [x] CONF=linux-x86_64-server-fastdebug CONF_CHECK=ignore make clean test TEST=tier2

Best,
Xiaolong.

-------------

Commit messages:
 - Swap position of _jvmci_ir_size and _failed_speculations for better alignment
 - Optimize MethodData layout

Changes: https://git.openjdk.org/jdk/pull/20019/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=20019&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8334231
  Stats: 3 lines in 1 file changed: 1 ins; 2 del; 0 mod
  Patch: https://git.openjdk.org/jdk/pull/20019.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/20019/head:pull/20019

PR: https://git.openjdk.org/jdk/pull/20019


More information about the hotspot-dev mailing list