Skip to content

Commit cd7ba08

Browse files
committed
Optimize array access macros to reduce using is-contiguous check
Optimize array access macros to use is-contiguous check only in presence of arraylets Along with new offheap feature support, Macro Array Element Access J9JAVAARRAY_EA/J9JAVAARRAY_EA_VM need 1 or 2 more runtime flags check to handle new cases/new structures. extra runtime condition checks in the Macro, which is called in hotspot, could cause certain performance regression in some platforms. especially for standard GC cases, off-heap would not contribute any benefit at all. Optimize Macro J9JAVAARRAY_EA/J9JAVAARRAY_EA_VM to avoid runtime check IsContiguousArray for stamdard GC and balanced GC with off-heap eanable cases, because there is no discontigouos array for these cases(except o size array). 1, replace isVirtualLargeObjectHeapEnabled and isIndexableDataAddrPresent flag with indexableObjectLayout in JavaVM and J9VmThread. 2, indexableObjectLayout have only 4 states J9IndexableObjectLayout_NoDataAddr_NoArraylet 0x0 /* StandardGC case */ J9IndexableObjectLayout_NoDataAddr_Arraylet 0x1 /* Metronome GC case */ J9IndexableObjectLayout_DataAddr_NoArraylet 0x2 /* Balanced GC Offheap enabled case */ J9IndexableObjectLayout_DataAddr_Arraylet 0x3 /* Balanced GC Offheap disabled case */ 3, in Macro J9JAVAARRAY_EA/J9JAVAARRAY_EA_VM, check StandardGC case and Balanced GC Offheap enabled case first in order to reduce runtime condition check for standard GC(Balanced GC Offheap enabled case too), then avoid performance regression(reduce flag numbers in J9VmThread also could help reduce the regression for some platforms). 4, flag isVirtualLargeObjectHeapEnabled and isIndexableDataAddrPresent has been removed from J9VmThread flag isVirtualLargeObjectHeapEnabled has been removed from JavaVM (we still keep flag isIndexableDataAddrPresent in JavaVM for minimizing the changes). Signed-off-by: lhu <linhu@ca.ibm.com>
1 parent 9362c83 commit cd7ba08

9 files changed

+74
-50
lines changed

runtime/gc_glue_java/EnvironmentDelegate.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ class MM_EnvironmentDelegate
207207
#if defined(J9VM_ENV_DATA64)
208208
if (objectModel->isIndexable(objectPtr)) {
209209
GC_ArrayObjectModel *indexableObjectModel = &_extensions->indexableObjectModel;
210-
if (_vmThread->isVirtualLargeObjectHeapEnabled && indexableObjectModel->isInlineContiguousArraylet((J9IndexableObject *)objectPtr)) {
210+
if (indexableObjectModel->isVirtualLargeObjectHeapEnabled() && indexableObjectModel->isInlineContiguousArraylet((J9IndexableObject *)objectPtr)) {
211211
_gcEnv._shouldFixupDataAddrForContiguous = indexableObjectModel->shouldFixupDataAddrForContiguous((J9IndexableObject *)objectPtr);
212212
} else {
213213
_gcEnv._shouldFixupDataAddrForContiguous = false;

runtime/gc_include/ObjectAllocationAPI.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ class MM_ObjectAllocationAPI
321321
: _gcAllocationType(currentThread->javaVM->gcAllocationType)
322322
, _contiguousIndexableHeaderSize(currentThread->contiguousIndexableHeaderSize)
323323
#if defined(J9VM_ENV_DATA64)
324-
, _isIndexableDataAddrPresent(currentThread->isIndexableDataAddrPresent)
324+
, _isIndexableDataAddrPresent(currentThread->javaVM->isIndexableDataAddrPresent)
325325
#endif /* defined(J9VM_ENV_DATA64) */
326326
#if defined(J9VM_GC_BATCH_CLEAR_TLH)
327327
, _initializeSlotsOnTLHAllocate(currentThread->javaVM->initializeSlotsOnTLHAllocate)

runtime/gc_modron_startup/mminit.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2972,7 +2972,7 @@ gcInitializeDefaults(J9JavaVM* vm)
29722972
#if defined(J9VM_ENV_DATA64)
29732973
vm->isIndexableDualHeaderShapeEnabled = TRUE;
29742974
vm->isIndexableDataAddrPresent = FALSE;
2975-
vm->isVirtualLargeObjectHeapEnabled = FALSE;
2975+
vm->indexableObjectLayout = J9IndexableObjectLayout_NoDataAddr_NoArraylet;
29762976
#endif /* defined(J9VM_ENV_DATA64) */
29772977

29782978
/* enable estimateFragmentation for all GCs as default for java, but not the estimated result would not affect concurrentgc kickoff by default */

runtime/gc_realtime/ConfigurationRealtime.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ MM_Heap *
108108
MM_ConfigurationRealtime::createHeapWithManager(MM_EnvironmentBase *env, uintptr_t heapBytesRequested, MM_HeapRegionManager *regionManager)
109109
{
110110
MM_GCExtensionsBase *extensions = env->getExtensions();
111-
111+
J9JavaVM *vm = (J9JavaVM *)extensions->getOmrVM()->_language_vm;
112+
/* Let VM know that Metronome GC has discontiguous indexable object (arraylet layout) */
113+
vm->indexableObjectLayout = J9IndexableObjectLayout_NoDataAddr_Arraylet;
112114
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
113115
PORT_ACCESS_FROM_ENVIRONMENT(env);
114116

runtime/gc_vlhgc/ConfigurationIncrementalGenerational.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ MM_ConfigurationIncrementalGenerational::createHeapWithManager(MM_EnvironmentBas
136136

137137
#if defined(J9VM_ENV_DATA64)
138138
extensions->indexableObjectModel.setIsDataAddressPresent(true);
139+
J9JavaVM *vm = (J9JavaVM *)extensions->getOmrVM()->_language_vm;
140+
/* Let VM know that indexable objects in Balanced always have dataAddr, and
141+
let's assume initially it has arraylets, which can be later overridden if Offheap is Enabled.
142+
*/
143+
vm->indexableObjectLayout = J9IndexableObjectLayout_DataAddr_Arraylet;
139144
#if defined(J9VM_GC_SPARSE_HEAP_ALLOCATION)
140145
if (extensions->isVirtualLargeObjectHeapRequested) {
141146
/* Create off-heap */
@@ -144,9 +149,9 @@ MM_ConfigurationIncrementalGenerational::createHeapWithManager(MM_EnvironmentBas
144149
extensions->largeObjectVirtualMemory = largeObjectVirtualMemory;
145150
extensions->indexableObjectModel.setEnableVirtualLargeObjectHeap(true);
146151
extensions->isVirtualLargeObjectHeapEnabled = true;
147-
/* reset vm->isVirtualLargeObjectHeapEnabled and vm->unsafeIndexableHeaderSize for off-heap case */
148-
J9JavaVM *vm = (J9JavaVM *)extensions->getOmrVM()->_language_vm;
149-
vm->isVirtualLargeObjectHeapEnabled = TRUE;
152+
/* Overriding the original assumption that Balanced has arraylets. */
153+
vm->indexableObjectLayout = J9IndexableObjectLayout_DataAddr_NoArraylet;
154+
/* reset vm->unsafeIndexableHeaderSize for off-heap case */
150155
vm->unsafeIndexableHeaderSize = 0;
151156
} else {
152157
#if defined(OMR_GC_VLHGC_CONCURRENT_COPY_FORWARD)

runtime/gc_vlhgc/VLHGCAccessBarrier.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ MM_VLHGCAccessBarrier::indexableDataDisplacement(J9VMThread *vmThread, J9Indexab
254254
IDATA displacement = 0;
255255

256256
#if defined(J9VM_ENV_DATA64)
257-
Assert_MM_true(vmThread->isVirtualLargeObjectHeapEnabled);
257+
Assert_MM_true(_extensions->isVirtualLargeObjectHeapEnabled);
258258
/* Adjacency check against dst object since src object may be overwritten during sliding compaction. */
259259
if (_extensions->indexableObjectModel.isDataAdjacentToHeader(dst))
260260
#endif /* defined(J9VM_ENV_DATA64) */

runtime/oti/j9accessbarrier.h

+41-37
Original file line numberDiff line numberDiff line change
@@ -123,17 +123,17 @@ typedef struct J9IndexableObject* mm_j9array_t;
123123
? (&((elemType*)((((J9IndexableObjectContiguousCompressed *)(array)) + 1)))[index]) \
124124
: (&((elemType*)((((J9IndexableObjectContiguousFull *)(array)) + 1)))[index]))
125125

126-
#if defined(J9VM_ENV_DATA64)
127-
#define J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPDISABLED_EA(vmThread, array, index, elemType) \
126+
#define J9ISCONTIGUOUSARRAY(vmThread, array) \
128127
(J9VMTHREAD_COMPRESS_OBJECT_REFERENCES(vmThread) \
129-
? (&((elemType*)((((J9IndexableObjectWithDataAddressContiguousCompressed *)(array)) + 1)))[index]) \
130-
: (&((elemType*)((((J9IndexableObjectWithDataAddressContiguousFull *)(array)) + 1)))[index]))
128+
? (0 != ((J9IndexableObjectContiguousCompressed *)(array))->size) \
129+
: (0 != ((J9IndexableObjectContiguousFull *)(array))->size))
131130

132-
#define J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPDISABLED_EA_VM(javaVM, array, index, elemType) \
131+
#define J9ISCONTIGUOUSARRAY_VM(javaVM, array) \
133132
(J9JAVAVM_COMPRESS_OBJECT_REFERENCES(javaVM) \
134-
? (&((elemType*)((((J9IndexableObjectWithDataAddressContiguousCompressed *)(array)) + 1)))[index]) \
135-
: (&((elemType*)((((J9IndexableObjectWithDataAddressContiguousFull *)(array)) + 1)))[index]))
133+
? (0 != ((J9IndexableObjectContiguousCompressed *)(array))->size) \
134+
: (0 != ((J9IndexableObjectContiguousFull *)(array))->size))
136135

136+
#if defined(J9VM_ENV_DATA64)
137137
#define J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPENABLED_EA(vmThread, array, index, elemType) \
138138
(J9VMTHREAD_COMPRESS_OBJECT_REFERENCES(vmThread) \
139139
? (&((elemType*)((((J9IndexableObjectWithDataAddressContiguousCompressed *)(array))->dataAddr)))[index]) \
@@ -145,41 +145,45 @@ typedef struct J9IndexableObject* mm_j9array_t;
145145
: (&((elemType*)((((J9IndexableObjectWithDataAddressContiguousFull *)(array))->dataAddr)))[index]))
146146

147147
#define J9JAVAARRAYCONTIGUOUS_EA(vmThread, array, index, elemType) \
148-
(((vmThread)->isIndexableDataAddrPresent) \
149-
? (((vmThread)->isVirtualLargeObjectHeapEnabled) \
150-
? J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPENABLED_EA(vmThread, array, index, elemType) \
151-
: J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPDISABLED_EA(vmThread, array, index, elemType)) \
152-
: J9JAVAARRAYCONTIGUOUS_BASE_EA(vmThread, array, index, elemType))
148+
(&((elemType*)((((UDATA)(array)) + (vmThread)->contiguousIndexableHeaderSize)))[(index)])
153149

154150
#define J9JAVAARRAYCONTIGUOUS_EA_VM(javaVM, array, index, elemType) \
155-
(((javaVM)->isIndexableDataAddrPresent) \
156-
? (((javaVM)->isVirtualLargeObjectHeapEnabled) \
157-
? J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPENABLED_EA_VM(javaVM, array, index, elemType) \
158-
: J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPDISABLED_EA_VM(javaVM, array, index, elemType)) \
159-
: J9JAVAARRAYCONTIGUOUS_BASE_EA_VM(javaVM, array, index, elemType))
160-
161-
#else /* defined(J9VM_ENV_DATA64) */
162-
#define J9JAVAARRAYCONTIGUOUS_EA(vmThread, array, index, elemType) \
163-
J9JAVAARRAYCONTIGUOUS_BASE_EA(vmThread, array, index, elemType)
164-
165-
#define J9JAVAARRAYCONTIGUOUS_EA_VM(javaVM, array, index, elemType) \
166-
J9JAVAARRAYCONTIGUOUS_BASE_EA_VM(javaVM, array, index, elemType)
167-
168-
#endif /* defined(J9VM_ENV_DATA64) */
151+
(&((elemType*)((((UDATA)(array)) + (javaVM)->contiguousIndexableHeaderSize)))[(index)])
169152

170-
#define J9ISCONTIGUOUSARRAY(vmThread, array) \
171-
(J9VMTHREAD_COMPRESS_OBJECT_REFERENCES(vmThread) \
172-
? (0 != ((J9IndexableObjectContiguousCompressed *)(array))->size) \
173-
: (0 != ((J9IndexableObjectContiguousFull *)(array))->size))
174-
175-
#define J9ISCONTIGUOUSARRAY_VM(javaVM, array) \
176-
(J9JAVAVM_COMPRESS_OBJECT_REFERENCES(javaVM) \
177-
? (0 != ((J9IndexableObjectContiguousCompressed *)(array))->size) \
178-
: (0 != ((J9IndexableObjectContiguousFull *)(array))->size))
153+
/*
154+
* if standard GC (J9IndexableObjectLayout_NoDataAddr_NoArraylet)
155+
* contiguous-base
156+
* else if off-heap enabled (J9IndexableObjectLayout_DataAddr_NoArraylet)
157+
* contiguous-via-dataAddr
158+
* else balancedGC with off-heap disabled or Metronome GC (J9IndexableObjectLayout_NoDataAddr_Arraylet or J9IndexableObjectLayout_DataAddr_Arraylet)
159+
* if contigious
160+
* contiguous
161+
* else
162+
* discontigous
163+
*/
164+
#define J9JAVAARRAY_EA(vmThread, array, index, elemType) \
165+
((J9IndexableObjectLayout_NoDataAddr_NoArraylet == (vmThread)->indexableObjectLayout) \
166+
? J9JAVAARRAYCONTIGUOUS_BASE_EA(vmThread, array, index, elemType) \
167+
: ((J9IndexableObjectLayout_DataAddr_NoArraylet == (vmThread)->indexableObjectLayout) \
168+
? J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPENABLED_EA(vmThread, array, index, elemType) \
169+
: (J9ISCONTIGUOUSARRAY(vmThread, array) \
170+
? J9JAVAARRAYCONTIGUOUS_EA(vmThread, array, index, elemType) \
171+
: J9JAVAARRAYDISCONTIGUOUS_EA(vmThread, array, index, elemType))))
172+
173+
#define J9JAVAARRAY_EA_VM(javaVM, array, index, elemType) \
174+
((J9IndexableObjectLayout_NoDataAddr_NoArraylet == (javaVM)->indexableObjectLayout) \
175+
? J9JAVAARRAYCONTIGUOUS_BASE_EA_VM(javaVM, array, index, elemType) \
176+
: ((J9IndexableObjectLayout_DataAddr_NoArraylet == (javaVM)->indexableObjectLayout) \
177+
? J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPENABLED_EA_VM(javaVM, array, index, elemType) \
178+
: (J9ISCONTIGUOUSARRAY_VM(javaVM, array) \
179+
? J9JAVAARRAYCONTIGUOUS_EA_VM(javaVM, array, index, elemType) \
180+
: J9JAVAARRAYDISCONTIGUOUS_EA_VM(javaVM, array, index, elemType))))
179181

182+
#else /* defined(J9VM_ENV_DATA64) */
180183
/* TODO: queries compressed twice - optimize? */
181-
#define J9JAVAARRAY_EA(vmThread, array, index, elemType) (J9ISCONTIGUOUSARRAY(vmThread, array) ? J9JAVAARRAYCONTIGUOUS_EA(vmThread, array, index, elemType) : J9JAVAARRAYDISCONTIGUOUS_EA(vmThread, array, index, elemType))
182-
#define J9JAVAARRAY_EA_VM(javaVM, array, index, elemType) (J9ISCONTIGUOUSARRAY_VM(javaVM, array) ? J9JAVAARRAYCONTIGUOUS_EA_VM(javaVM, array, index, elemType) : J9JAVAARRAYDISCONTIGUOUS_EA_VM(javaVM, array, index, elemType))
184+
#define J9JAVAARRAY_EA(vmThread, array, index, elemType) (J9ISCONTIGUOUSARRAY(vmThread, array) ? J9JAVAARRAYCONTIGUOUS_BASE_EA(vmThread, array, index, elemType) : J9JAVAARRAYDISCONTIGUOUS_EA(vmThread, array, index, elemType))
185+
#define J9JAVAARRAY_EA_VM(javaVM, array, index, elemType) (J9ISCONTIGUOUSARRAY_VM(javaVM, array) ? J9JAVAARRAYCONTIGUOUS_BASE_EA_VM(javaVM, array, index, elemType) : J9JAVAARRAYDISCONTIGUOUS_EA_VM(javaVM, array, index, elemType))
186+
#endif /* defined(J9VM_ENV_DATA64) */
183187

184188
/*
185189
* Private helpers for reference field types

runtime/oti/j9nonbuilder.h

+17-3
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@
140140
#define J9ArrayShape32Bit 0x2
141141
#define J9ArrayShape64Bit 0x3
142142

143+
/* J9IndexableObjectLayout_xxx are used in indexableObjectLayout field in J9VMThread and J9JavaVM */
144+
#define J9IndexableObjectLayout_NoDataAddr_NoArraylet 0x0 /* StandardGC case */
145+
#define J9IndexableObjectLayout_NoDataAddr_Arraylet 0x1 /* Metronome GC case */
146+
#define J9IndexableObjectLayout_DataAddr_NoArraylet 0x2 /* Balanced GC Offheap enabled case */
147+
#define J9IndexableObjectLayout_DataAddr_Arraylet 0x3 /* Balanced GC Offheap disabled case */
148+
#define J9IndexableObjectLayout_DataAddrMask 0x2
149+
#define J9IndexableObjectLayout_ArrayletMask 0x1
143150
/* @ddr_namespace: map_to_type=J9ClassInitFlags */
144151

145152
/* Constants from J9ClassInitFlags */
@@ -5540,8 +5547,7 @@ typedef struct J9VMThread {
55405547
UDATA contiguousIndexableHeaderSize;
55415548
UDATA discontiguousIndexableHeaderSize;
55425549
#if defined(J9VM_ENV_DATA64)
5543-
UDATA isIndexableDataAddrPresent;
5544-
U_32 isVirtualLargeObjectHeapEnabled;
5550+
U_32 indexableObjectLayout;
55455551
#endif /* defined(J9VM_ENV_DATA64) */
55465552
void* gpInfo;
55475553
void* jitVMwithThreadInfo;
@@ -5660,6 +5666,10 @@ typedef struct J9VMThread {
56605666
#endif /* defined(J9VM_OPT_JFR) */
56615667
} J9VMThread;
56625668

5669+
#if defined(J9VM_ENV_DATA64)
5670+
#define J9VMTHREAD_IS_ARRAYLET_ENABLED(vmThread) (J9IndexableObjectLayout_ArrayletMask & (vmThread)->indexableObjectLayout)
5671+
#define J9VMTHREAD_IS_INDEXBLE_DATAADDR_PRESENT(vmThread) (J9IndexableObjectLayout_DataAddrMask & (vmThread)->indexableObjectLayout)
5672+
#endif
56635673
#define J9VMTHREAD_ALIGNMENT 0x100
56645674
#define J9VMTHREAD_RESERVED_C_STACK_FRACTION 8
56655675
#define J9VMTHREAD_STATE_RUNNING 1
@@ -6106,7 +6116,7 @@ typedef struct J9JavaVM {
61066116
UDATA discontiguousIndexableHeaderSize;
61076117
#if defined(J9VM_ENV_DATA64)
61086118
UDATA isIndexableDataAddrPresent;
6109-
U_32 isVirtualLargeObjectHeapEnabled;
6119+
U_32 indexableObjectLayout;
61106120
U_32 isIndexableDualHeaderShapeEnabled;
61116121
#endif /* defined(J9VM_ENV_DATA64) */
61126122
struct J9VMThread* exclusiveVMAccessQueueHead;
@@ -6347,6 +6357,10 @@ typedef struct J9JavaVM {
63476357
#define J9JAVAVM_OBJECT_HEADER_SIZE(vm) (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm) ? sizeof(J9ObjectCompressed) : sizeof(J9ObjectFull))
63486358
#define J9JAVAVM_CONTIGUOUS_INDEXABLE_HEADER_SIZE(vm) ((vm)->contiguousIndexableHeaderSize)
63496359
#define J9JAVAVM_DISCONTIGUOUS_INDEXABLE_HEADER_SIZE(vm) ((vm)->discontiguousIndexableHeaderSize)
6360+
#if defined(J9VM_ENV_DATA64)
6361+
#define J9JAVAVM_IS_ARRAYLET_ENABLED(vm) (J9IndexableObjectLayout_ArrayletMask & (vm)->indexableObjectLayout)
6362+
#define J9JAVAVM_IS_INDEXBLE_DATAADDR_PRESENT(vm) (J9IndexableObjectLayout_DataAddrMask & (vm)->indexableObjectLayout)eObjectLayout)
6363+
#endif
63506364

63516365
#if JAVA_SPEC_VERSION >= 16
63526366
/* The mask for the signature type identifier */

runtime/vm/vmthread.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,7 @@ allocateVMThread(J9JavaVM *vm, omrthread_t osThread, UDATA privateFlags, void *m
196196
newThread->discontiguousIndexableHeaderSize = vm->discontiguousIndexableHeaderSize;
197197
newThread->unsafeIndexableHeaderSize = vm->unsafeIndexableHeaderSize;
198198
#if defined(J9VM_ENV_DATA64)
199-
newThread->isIndexableDataAddrPresent = vm->isIndexableDataAddrPresent;
200-
newThread->isVirtualLargeObjectHeapEnabled = vm->isVirtualLargeObjectHeapEnabled;
199+
newThread->indexableObjectLayout = vm->indexableObjectLayout;
201200
#endif /* defined(J9VM_ENV_DATA64) */
202201

203202
newThread->privateFlags = privateFlags;

0 commit comments

Comments
 (0)