Skip to content

Commit a872cbd

Browse files
Aleksandar MicicAleksandar Micic
authored andcommitted
Force outlining for array EA API
Macros for Array Effective Address calculations are inherently inlined and seem to create much pressure either on register or code cash in Bytecode interpreter. They are rewritten in C and forced to be outlined specifically for GNU compilers on X and Z, where we saw regression when Offheap was introduced (what made the macros more complex, creating even more pressure). For other platforms where we did not see regression, we continue to inline (ATM unknown if outlining would have negative or possitive effect). Hence we still keep it in a header (*.h) file. Signed-off-by: Aleksandar Micic <[email protected]>
1 parent f714d73 commit a872cbd

File tree

2 files changed

+74
-8
lines changed

2 files changed

+74
-8
lines changed

runtime/oti/j9accessbarrier.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,11 @@ typedef struct J9IndexableObject* mm_j9array_t;
161161
* else
162162
* discontiguous
163163
*/
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))))
164+
165+
166+
167+
/* Effective Address calculation for callers using vmThread are passed to C implementation, which may force outlining for some platforms. */
168+
#define J9JAVAARRAY_EA(vmThread, array, index, elemType) j9javaArray_##elemType##_EA(vmThread, (J9IndexableObject *)(array), index)
172169

173170
#define J9JAVAARRAY_EA_VM(javaVM, array, index, elemType) \
174171
((J9IndexableObjectLayout_NoDataAddr_NoArraylet == (javaVM)->indexableObjectLayout) \

runtime/oti/j9accessbarrierhelpers.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,75 @@
2323
#ifndef J9ACCESSBARRIERHELPERS_H
2424
#define J9ACCESSBARRIERHELPERS_H
2525

26+
#if defined (J9VM_ENV_DATA64)
27+
#if (defined(__GNUC__) && (defined(J9HAMMER) || defined(S390)))
28+
/* Forcing non-inlining on GNU for X and Z, where inlining seems to create much register or code cache pressure within Bytecode Interpreter */
29+
__attribute__ ((noinline))
30+
#else /* (defined(__GNUC__) && (defined(J9HAMMER) || defined(S390))) */
31+
VMINLINE
32+
#endif /* (defined(__GNUC__) && (defined(J9HAMMER) || defined(S390))) */
33+
static UDATA j9javaArray_BA(J9VMThread *vmThread, J9IndexableObject *array, UDATA *index, U_8 elementSize)
34+
{
35+
UDATA baseAddress = (UDATA)array;
36+
37+
if (J9VMTHREAD_COMPRESS_OBJECT_REFERENCES(vmThread)) {
38+
baseAddress += sizeof(J9IndexableObjectContiguousCompressed);
39+
} else {
40+
baseAddress += sizeof(J9IndexableObjectContiguousFull);
41+
}
42+
43+
if (J9IndexableObjectLayout_NoDataAddr_NoArraylet == vmThread->indexableObjectLayout) {
44+
/* Standard GCs: nothing extra to do - just explicitly listed for clarity */
45+
} else if (J9IndexableObjectLayout_DataAddr_NoArraylet == vmThread->indexableObjectLayout) {
46+
/* Balanced Offheap; dereference dataAddr that is just after the (base) header */
47+
baseAddress = *(UDATA *)baseAddress;
48+
} else {
49+
/* GCs that may have arraylet (Balanced arraylet or Metronome) - will recalculate baseAddress from scratch */
50+
if (J9ISCONTIGUOUSARRAY(vmThread, array)) {
51+
baseAddress = (UDATA)array + vmThread->contiguousIndexableHeaderSize;
52+
} else {
53+
fj9object_t *arrayoid = (fj9object_t *)((UDATA)array + vmThread->discontiguousIndexableHeaderSize);
54+
/* While arrayletLeafSize is UDATA, the result of this division will fit into U_32 (simply because Java can't have more array elements) */
55+
U_32 elementsPerLeaf = (U_32)(J9VMTHREAD_JAVAVM(vmThread)->arrayletLeafSize / elementSize);
56+
U_32 leafIndex = ((U_32)*index) / elementsPerLeaf;
57+
*index = ((U_32)*index) % elementsPerLeaf;
58+
59+
if (J9VMTHREAD_COMPRESS_OBJECT_REFERENCES(vmThread)) {
60+
U_32 leafToken = *((U_32 *)arrayoid + leafIndex);
61+
baseAddress = (UDATA)J9_CONVERT_POINTER_FROM_TOKEN__(vmThread, leafToken);
62+
} else {
63+
UDATA leafToken = *((UDATA *)arrayoid + leafIndex);
64+
baseAddress = leafToken;
65+
}
66+
}
67+
}
68+
69+
70+
return baseAddress;
71+
}
72+
73+
#define J9JAVAARRAY_C_EA(elemType) \
74+
VMINLINE static elemType *j9javaArray_##elemType##_EA(J9VMThread *vmThread, J9IndexableObject *array, UDATA index) \
75+
{ \
76+
UDATA baseAddress = j9javaArray_BA(vmThread, array, &index, (U_8)sizeof(elemType)); \
77+
/* Intentionally inlining this to treat sizeof value as an immediate value */ \
78+
return (elemType *)(baseAddress + index * sizeof(elemType)); \
79+
} \
80+
81+
/* generate C bodies */
82+
83+
J9JAVAARRAY_C_EA(I_8)
84+
J9JAVAARRAY_C_EA(U_8)
85+
J9JAVAARRAY_C_EA(I_16)
86+
J9JAVAARRAY_C_EA(U_16)
87+
J9JAVAARRAY_C_EA(I_32)
88+
J9JAVAARRAY_C_EA(U_32)
89+
J9JAVAARRAY_C_EA(I_64)
90+
J9JAVAARRAY_C_EA(U_64)
91+
J9JAVAARRAY_C_EA(IDATA)
92+
J9JAVAARRAY_C_EA(UDATA)
93+
#endif /* defined (J9VM_ENV_DATA64) */
94+
2695
/**
2796
* These helpers could be written as macros (where the body of methods would be wrapped around oval parenthesis, which would mean that the last expression in the block
2897
* is return value of the block). However, it is not fully supported by ANSI, but only select C compilers, like GNU C: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html).

0 commit comments

Comments
 (0)