RFR: 8334232: Optimize C1 classes layout

Neethu Prasad nprasad at openjdk.org
Fri Jul 5 15:03:12 UTC 2024


**Notes**

Rearrange C1 class fields to optimize footprint.


**Verification**

1. Ran tier2_compiler, hotspot_compiler, tier 1 & tier 2 tests.
2. Ran pahole on 64 bit machine post re-ordering and verified that there are no holes / reduction in total bytes.

| Class | Size | Cachelines | Holes | Sum holes | Last Cacheline | Padding |
| ----- | ----- | ---------- | ----- | ---------- | --------------- | -------- |
| Instruction | 96 -> 88 | 2 -> 2  |  2 -> 0  |  8 -> 0  | 32 -> 24  | 1 -> 1  |
| Intrinsic | 136 -> 120 | 3 -> 2  |  1 -> 1  | 4 -> 96   |  8 ->  56 |  4-> 0 |
| LIR_Address | 48 -> 40 | 1 -> 1  |  1-> 0  | 4 -> 0  |  48 -> 40 | 7 -> 3   |
| LIR_Op2 | 128 -> 120  | 2 -> 2  | 2 -> 0  |  11 -> 0  | N/A -> 56  | 4 -> 7  |
| LIR_Op4 | 136 -> 128  | 3 -> 2  | 1-> 0  |  7 -> 0 |  8-> 0  |  4 ->  3 |
| LIR_OpAllocArray  | 120 -> 112  | 2 -> 2  | 1-> 0   |  7 -> 0  | 56 -> 48 |  7 -> 6 |
|LIR_OpTypeCheck  | 144 -> 136  | 3 -> 3  | 1-> 0  |  7 -> 0  |  16 ->  8 |  3 -> 2  |



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

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

	int ()(void) * *           _vptr.Instruction;    /*     0     8 */
	int                        _id;                  /*     8     4 */
	int                        _use_count;           /*    12     4 */
	int                        _pin_state;           /*    16     4 */
	unsigned int               _flags;               /*    20     4 */
	class ValueType *          _type;                /*    24     8 */
	class Instruction *        _next;                /*    32     8 */
	class Instruction *        _subst;               /*    40     8 */
	class LIR_Opr             _operand;              /*    48     8 */
	class ValueStack *         _state_before;        /*    56     8 */
	/* --- cacheline 1 boundary (64 bytes) --- */
	class ValueStack *         _exception_state;     /*    64     8 */
	class XHandlers *          _exception_handlers;  /*    72     8 */
protected:

	class BlockBegin *         _block;               /*    80     8 */
public:


	/* Bitfield combined with previous fields */

	static const int                  no_bci;        /*     0     0 */
protected:

public:


	/* size: 88, cachelines: 2, members: 14, static members: 1 */
	/* paddings: 1, sum paddings: 1 */
	/* last cacheline: 24 bytes */
};




class LIR_Address : public LIR_OprPtr {
public:

	/* class LIR_OprPtr          <ancestor>; */      /*     0     8 */
	class LIR_Opr             _base;                 /*     8     8 */
	class LIR_Opr             _index;                /*    16     8 */
	intx                       _disp;                /*    24     8 */
	enum Scale                 _scale;               /*    32     4 */
	enum BasicType             _type;                /*    36     1 */

	/* size: 40, cachelines: 1, members: 6 */
	/* padding: 3 */
	/* last cacheline: 40 bytes */

	/* BRAIN FART ALERT! 40 bytes != 29 (member bytes) + 0 (member bits) + 0 (byte holes) + 0 (bit holes), diff = 64 bits */
};



class LIR_Op2 : public LIR_Op {
public:

	/* class LIR_Op              <ancestor>; */      /*     0    48 */
protected:

	class LIR_Opr             _opr1;                 /*    48     8 */
	class LIR_Opr             _opr2;                 /*    56     8 */
	/* --- cacheline 1 boundary (64 bytes) --- */
	class LIR_Opr             _tmp1;                 /*    64     8 */
	class LIR_Opr             _tmp2;                 /*    72     8 */
	class LIR_Opr             _tmp3;                 /*    80     8 */
	class LIR_Opr             _tmp4;                 /*    88     8 */
	class LIR_Opr             _tmp5;                 /*    96     8 */
	enum LIR_Condition         _condition;           /*   104     4 */
	int                        _fpu_stack_size;      /*   108     4 */
	enum BasicType             _type;                /*   112     1 */
public:

protected:

public:


	/* size: 120, cachelines: 2, members: 11 */
	/* padding: 7 */
	/* last cacheline: 56 bytes */

	/* BRAIN FART ALERT! 120 bytes != 65 (member bytes) + 0 (member bits) + 0 (byte holes) + 0 (bit holes), diff = 384 bits */
};



class LIR_Op4 : public LIR_Op {
public:

	/* class LIR_Op              <ancestor>; */      /*     0    48 */
protected:

	class LIR_Opr             _opr1;                 /*    48     8 */
	class LIR_Opr             _opr2;                 /*    56     8 */
	/* --- cacheline 1 boundary (64 bytes) --- */
	class LIR_Opr             _opr3;                 /*    64     8 */
	class LIR_Opr             _opr4;                 /*    72     8 */
	class LIR_Opr             _tmp1;                 /*    80     8 */
	class LIR_Opr             _tmp2;                 /*    88     8 */
	class LIR_Opr             _tmp3;                 /*    96     8 */
	class LIR_Opr             _tmp4;                 /*   104     8 */
	class LIR_Opr             _tmp5;                 /*   112     8 */
	enum LIR_Condition         _condition;           /*   120     4 */
	enum BasicType             _type;                /*   124     1 */
public:


	/* size: 128, cachelines: 2, members: 12 */
	/* padding: 3 */

	/* BRAIN FART ALERT! 128 bytes != 77 (member bytes) + 0 (member bits) + 0 (byte holes) + 0 (bit holes), diff = 384 bits */
};



class LIR_OpAllocArray : public LIR_Op {
public:

	/* class LIR_Op              <ancestor>; */      /*     0    48 */
	class LIR_Opr             _klass;                /*    48     8 */
	class LIR_Opr             _len;                  /*    56     8 */
	/* --- cacheline 1 boundary (64 bytes) --- */
	class LIR_Opr             _tmp1;                 /*    64     8 */
	class LIR_Opr             _tmp2;                 /*    72     8 */
	class LIR_Opr             _tmp3;                 /*    80     8 */
	class LIR_Opr             _tmp4;                 /*    88     8 */
	class CodeStub *           _stub;                /*    96     8 */
	enum BasicType             _type;                /*   104     1 */
	bool                       _zero_array;          /*   105     1 */

	/* size: 112, cachelines: 2, members: 10 */
	/* padding: 6 */
	/* last cacheline: 48 bytes */

	/* BRAIN FART ALERT! 112 bytes != 58 (member bytes) + 0 (member bits) + 0 (byte holes) + 0 (bit holes), diff = 384 bits */
};



class LIR_OpTypeCheck : public LIR_Op {
public:

	/* class LIR_Op              <ancestor>; */      /*     0    48 */
	class LIR_Opr             _object;               /*    48     8 */
	class LIR_Opr             _array;                /*    56     8 */
	/* --- cacheline 1 boundary (64 bytes) --- */
	class ciKlass *            _klass;               /*    64     8 */
	class LIR_Opr             _tmp1;                 /*    72     8 */
	class LIR_Opr             _tmp2;                 /*    80     8 */
	class LIR_Opr             _tmp3;                 /*    88     8 */
	class CodeEmitInfo *       _info_for_patch;      /*    96     8 */
	class CodeEmitInfo *       _info_for_exception;  /*   104     8 */
	class CodeStub *           _stub;                /*   112     8 */
	class ciMethod *           _profiled_method;     /*   120     8 */
	/* --- cacheline 2 boundary (128 bytes) --- */
	int                        _profiled_bci;        /*   128     4 */
	bool                       _should_profile;      /*   132     1 */
	bool                       _fast_check;          /*   133     1 */

	/* size: 136, cachelines: 3, members: 14 */
	/* padding: 2 */
	/* last cacheline: 8 bytes */

	/* BRAIN FART ALERT! 136 bytes != 86 (member bytes) + 0 (member bits) + 0 (byte holes) + 0 (bit holes), diff = 384 bits */
};



class Intrinsic : public StateSplit {
public:

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

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

	/* --- cacheline 1 boundary (64 bytes) was 32 bytes ago --- */
	ID                         _id;                  /*    96     4 */
	class ArgsNonNullState    _nonnull_state;        /*   100     4 */
	Values *                   _args;                /*   104     8 */
	Value                      _recv;                /*   112     8 */

	/* size: 120, cachelines: 2, members: 5 */
	/* sum members: 24, holes: 1, sum holes: 96 */
	/* last cacheline: 56 bytes */
};

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

Commit messages:
 - 8334232: Optimize C1 classes layout

Changes: https://git.openjdk.org/jdk/pull/20017/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=20017&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8334232
  Stats: 47 lines in 3 files changed: 21 ins; 21 del; 5 mod
  Patch: https://git.openjdk.org/jdk/pull/20017.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/20017/head:pull/20017

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


More information about the hotspot-compiler-dev mailing list