From 8659ab310af09a6ef10b820e565a7d92fe45b12c Mon Sep 17 00:00:00 2001 From: Aleksandar Micic Date: Mon, 20 Jan 2025 12:13:57 -0500 Subject: [PATCH] Force outlining for array EA API Signed-off-by: Aleksandar Micic --- runtime/oti/j9accessbarrier.h | 14 +++--- runtime/oti/j9accessbarrierhelpers.h | 66 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/runtime/oti/j9accessbarrier.h b/runtime/oti/j9accessbarrier.h index 86eb5494ed9..befcc3f0cee 100644 --- a/runtime/oti/j9accessbarrier.h +++ b/runtime/oti/j9accessbarrier.h @@ -161,14 +161,12 @@ typedef struct J9IndexableObject* mm_j9array_t; * else * discontiguous */ -#define J9JAVAARRAY_EA(vmThread, array, index, elemType) \ - ((J9IndexableObjectLayout_NoDataAddr_NoArraylet == (vmThread)->indexableObjectLayout) \ - ? J9JAVAARRAYCONTIGUOUS_BASE_EA(vmThread, array, index, elemType) \ - : ((J9IndexableObjectLayout_DataAddr_NoArraylet == (vmThread)->indexableObjectLayout) \ - ? J9JAVAARRAYCONTIGUOUS_WITH_DATAADDRESS_VIRTUALLARGEOBJECTHEAPENABLED_EA(vmThread, array, index, elemType) \ - : (J9ISCONTIGUOUSARRAY(vmThread, array) \ - ? J9JAVAARRAYCONTIGUOUS_EA(vmThread, array, index, elemType) \ - : J9JAVAARRAYDISCONTIGUOUS_EA(vmThread, array, index, elemType)))) + + + +/* There are lots of callers of this macro passing index as UDATA?! While callers keeping index in UDATA is probably overkill, + * we simply explicitly cast down to U_32 (what C helpers use) to avoid compiler loss of precision warning */ +#define J9JAVAARRAY_EA(vmThread, array, index, elemType) j9javaArray_##elemType##_EA(vmThread, (J9IndexableObject *)array, (U_32)index) #define J9JAVAARRAY_EA_VM(javaVM, array, index, elemType) \ ((J9IndexableObjectLayout_NoDataAddr_NoArraylet == (javaVM)->indexableObjectLayout) \ diff --git a/runtime/oti/j9accessbarrierhelpers.h b/runtime/oti/j9accessbarrierhelpers.h index e97a2efbea0..0fffa333a44 100644 --- a/runtime/oti/j9accessbarrierhelpers.h +++ b/runtime/oti/j9accessbarrierhelpers.h @@ -23,6 +23,72 @@ #ifndef J9ACCESSBARRIERHELPERS_H #define J9ACCESSBARRIERHELPERS_H +#if defined (J9VM_ENV_DATA64) +#if (defined(__GNUC__) && (defined(J9X86) || defined(S390))) +#endif /* (defined(__GNUC__) && defined(J9X86)) */ +__attribute__ ((noinline)) +static UDATA j9javaArray_BA(J9VMThread *vmThread, J9IndexableObject *array, U_32 *index, U_8 elementSize) +{ + UDATA baseAddress = (UDATA)array; + + if (J9VMTHREAD_COMPRESS_OBJECT_REFERENCES(vmThread)) { + baseAddress += sizeof(J9IndexableObjectContiguousCompressed); + } else { + baseAddress += sizeof(J9IndexableObjectContiguousFull); + } + + if (J9IndexableObjectLayout_NoDataAddr_NoArraylet == vmThread->indexableObjectLayout) { + /* Standard GCs */ + } else if (J9IndexableObjectLayout_DataAddr_NoArraylet == vmThread->indexableObjectLayout) { + /* Balanced Offheap; dereference dataAddr that is just after the (base) header */ + baseAddress = *(UDATA *)baseAddress; + } else { + /* GCs that may have arraylet (Balanced arraylet or Metronome) - will recalculate baseAddress from scratch */ + if (J9ISCONTIGUOUSARRAY(vmThread, array)) { + baseAddress = (UDATA)array + vmThread->contiguousIndexableHeaderSize; + } else { + fj9object_t *arrayoid = (fj9object_t *)((UDATA)array + vmThread->discontiguousIndexableHeaderSize); + /* While arrayletLeafSize is UDATA, the result of this division will fit into U_32 (simply because Java can't have more array elements) */ + U_32 elementsPerLeaf = (U_32)(J9VMTHREAD_JAVAVM(vmThread)->arrayletLeafSize / elementSize); + U_32 leafIndex = *index / elementsPerLeaf; + *index = *index % elementsPerLeaf; + + if (J9VMTHREAD_COMPRESS_OBJECT_REFERENCES(vmThread)) { + U_32 leafToken = *((U_32 *)arrayoid + leafIndex); + baseAddress = (UDATA)J9_CONVERT_POINTER_FROM_TOKEN__(vmThread, leafToken); + } else { + UDATA leafToken = *((UDATA *)arrayoid + leafIndex); + baseAddress = leafToken; + } + } + } + + + return baseAddress; +} + +#define J9JAVAARRAY_C_EA(elemType) \ +VMINLINE static elemType *j9javaArray_##elemType##_EA(J9VMThread *vmThread, J9IndexableObject *array, U_32 index) \ +{ \ + UDATA baseAddress = j9javaArray_BA(vmThread, array, &index, (U_8)sizeof(elemType)); \ + /* intentionally inlining this to treat sizeof value as an immediate */ \ + return (elemType *)(baseAddress + (UDATA)index * sizeof(elemType)); \ +} \ + +/* generate C bodies */ + +J9JAVAARRAY_C_EA(I_8) +J9JAVAARRAY_C_EA(U_8) +J9JAVAARRAY_C_EA(I_16) +J9JAVAARRAY_C_EA(U_16) +J9JAVAARRAY_C_EA(I_32) +J9JAVAARRAY_C_EA(U_32) +J9JAVAARRAY_C_EA(I_64) +J9JAVAARRAY_C_EA(U_64) +J9JAVAARRAY_C_EA(IDATA) +J9JAVAARRAY_C_EA(UDATA) +#endif /* defined (J9VM_ENV_DATA64) */ + /** * 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 * 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).