diff --git a/runtime/gc_base/IndexableObjectAllocationModel.hpp b/runtime/gc_base/IndexableObjectAllocationModel.hpp index 3380ffddc7a..03f0b6feee1 100644 --- a/runtime/gc_base/IndexableObjectAllocationModel.hpp +++ b/runtime/gc_base/IndexableObjectAllocationModel.hpp @@ -83,7 +83,7 @@ class MM_IndexableObjectAllocationModel : public MM_JavaObjectAllocationModel 0, allocateObjectFlags | OMR_GC_ALLOCATE_OBJECT_INDEXABLE) , _numberOfIndexedFields(numberOfIndexedFields) , _dataSize(env->getExtensions()->indexableObjectModel.getDataSizeInBytes(_class, _numberOfIndexedFields)) - , _layout(env->getExtensions()->indexableObjectModel.getArrayletLayout(_class, _dataSize, + , _layout(env->getExtensions()->indexableObjectModel.getArrayletLayout(_class, _numberOfIndexedFields, _allocateDescription.getMemorySpace()->getDefaultMemorySubSpace()->largestDesirableArraySpine())) , _alignSpineDataSection(env->getExtensions()->indexableObjectModel.shouldAlignSpineDataSection(_class)) , _numberOfArraylets(env->getExtensions()->indexableObjectModel.numArraylets(_dataSize)) diff --git a/runtime/gc_glue_java/ArrayletObjectModel.cpp b/runtime/gc_glue_java/ArrayletObjectModel.cpp index 37ac858cff1..9aa8470f7c7 100644 --- a/runtime/gc_glue_java/ArrayletObjectModel.cpp +++ b/runtime/gc_glue_java/ArrayletObjectModel.cpp @@ -74,11 +74,12 @@ GC_ArrayletObjectModel::AssertDiscontiguousArrayletLayout(J9IndexableObject *obj } GC_ArrayletObjectModel::ArrayLayout -GC_ArrayletObjectModel::getArrayletLayout(J9Class* clazz, UDATA dataSizeInBytes, UDATA largestDesirableSpine) +GC_ArrayletObjectModel::getArrayletLayout(J9Class* clazz, UDATA numberOfElements, UDATA largestDesirableSpine) { ArrayLayout layout = Illegal; MM_GCExtensionsBase* extensions = MM_GCExtensionsBase::getExtensions(_omrVM); UDATA objectAlignmentInBytes = extensions->getObjectAlignmentInBytes(); + uintptr_t dataSizeInBytes = getDataSizeInBytes(clazz, numberOfElements); /* the spine need not contain a pointer to the data */ const UDATA minimumSpineSize = 0; @@ -94,7 +95,7 @@ GC_ArrayletObjectModel::getArrayletLayout(J9Class* clazz, UDATA dataSizeInBytes, /* CMVC 135307 : when checking for InlineContiguous layout, perform subtraction as adding to dataSizeInBytes could trigger overflow. */ if ((largestDesirableSpine == UDATA_MAX) || (dataSizeInBytes <= (largestDesirableSpine - minimumSpineSizeAfterGrowing - contiguousIndexableHeaderSize()))) { layout = InlineContiguous; - if ((0 == dataSizeInBytes) && (0 < J9ARRAYCLASS_GET_STRIDE(clazz))) { + if (0 == numberOfElements) { /* Zero sized NUA uses the discontiguous shape */ layout = Discontiguous; } diff --git a/runtime/gc_glue_java/ArrayletObjectModel.hpp b/runtime/gc_glue_java/ArrayletObjectModel.hpp index 21c922ac9e0..64d6afa0ab3 100644 --- a/runtime/gc_glue_java/ArrayletObjectModel.hpp +++ b/runtime/gc_glue_java/ArrayletObjectModel.hpp @@ -376,18 +376,33 @@ class GC_ArrayletObjectModel : public GC_ArrayletObjectModelBase } /** - * Get the size from the header for the given indexable object + * Get the size from the header for the given indexable object, + * assuming it is Contiguous * @param objPtr Pointer to an array object * @return the size */ MMINLINE uintptr_t - getArraySize(J9IndexableObject *objPtr) + getContiguousArraySize(J9IndexableObject *objPtr) { return compressObjectReferences() ? ((J9IndexableObjectContiguousCompressed*)objPtr)->size : ((J9IndexableObjectContiguousFull*)objPtr)->size; } + /** + * Get the size from the header for the given indexable object, + * assuming it is Discontiguous + * @param objPtr Pointer to an array object + * @return the size + */ + MMINLINE uintptr_t + getDiscontiguousArraySize(J9IndexableObject *objPtr) + { + return compressObjectReferences() + ? ((J9IndexableObjectDiscontiguousCompressed*)objPtr)->size + : ((J9IndexableObjectDiscontiguousFull*)objPtr)->size; + } + /** * Get the layout for the given indexable object * @param objPtr Pointer to an array object @@ -398,32 +413,31 @@ class GC_ArrayletObjectModel : public GC_ArrayletObjectModelBase { GC_ArrayletObjectModel::ArrayLayout layout = GC_ArrayletObjectModel::InlineContiguous; /* Trivial check for InlineContiguous. */ - if (0 != getArraySize(objPtr)) { + if (0 != getContiguousArraySize(objPtr)) { return GC_ArrayletObjectModel::InlineContiguous; } /* Check if the objPtr is in the allowed arraylet range. */ if (((uintptr_t)objPtr >= (uintptr_t)_arrayletRangeBase) && ((uintptr_t)objPtr < (uintptr_t)_arrayletRangeTop)) { - uintptr_t dataSizeInBytes = getDataSizeInBytes(objPtr); J9Class* clazz = J9GC_J9OBJECT_CLAZZ(objPtr, this); - layout = getArrayletLayout(clazz, dataSizeInBytes); + layout = getArrayletLayout(clazz, getDiscontiguousArraySize(objPtr)); } return layout; } MMINLINE ArrayLayout - getArrayletLayout(J9Class* clazz, uintptr_t dataSizeInBytes) + getArrayletLayout(J9Class* clazz, uintptr_t numberOfElements) { - return getArrayletLayout(clazz, dataSizeInBytes, _largestDesirableArraySpineSize); + return getArrayletLayout(clazz, numberOfElements, _largestDesirableArraySpineSize); } /** * Get the layout of an indexable object given it's class, data size in bytes and the subspace's largestDesirableSpine. * @param clazz The class of the object stored in the array. - * @param dataSizeInBytes the size in bytes of the data of the array. + * @param numberOfElements number of indexed fields * @param largestDesirableSpine The largest desirable spine of the arraylet. */ - ArrayLayout getArrayletLayout(J9Class* clazz, uintptr_t dataSizeInBytes, uintptr_t largestDesirableSpine); + ArrayLayout getArrayletLayout(J9Class* clazz, uintptr_t numberOfElements, uintptr_t largestDesirableSpine); /** * Perform a safe memcpy of one array to another. @@ -1135,11 +1149,7 @@ class GC_ArrayletObjectModel : public GC_ArrayletObjectModelBase if (0 == size) { /* Discontiguous */ - if (compressObjectReferences()) { - size = ((J9IndexableObjectDiscontiguousCompressed *)forwardedHeader->getObject())->size; - } else { - size = ((J9IndexableObjectDiscontiguousFull *)forwardedHeader->getObject())->size; - } + size = getDiscontiguousArraySize((J9IndexableObject *)forwardedHeader->getObject()); } return size; @@ -1172,8 +1182,8 @@ class GC_ArrayletObjectModel : public GC_ArrayletObjectModelBase if (0 == size) { /* we know we are dealing with heap object, so we don't need to check against _arrayletRangeBase/Top, like getArrayLayout does */ - uintptr_t dataSizeInBytes = getDataSizeInBytes(clazz, getPreservedIndexableSize(forwardedHeader)); - layout = getArrayletLayout(clazz, dataSizeInBytes); + uintptr_t numberOfElements = (uintptr_t)getPreservedIndexableSize(forwardedHeader); + layout = getArrayletLayout(clazz, numberOfElements); } return layout; @@ -1192,8 +1202,7 @@ class GC_ArrayletObjectModel : public GC_ArrayletObjectModelBase { J9Class* clazz = getPreservedClass(forwardedHeader); uintptr_t numberOfElements = (uintptr_t)getPreservedIndexableSize(forwardedHeader); - uintptr_t dataSizeInBytes = getDataSizeInBytes(clazz, numberOfElements); - ArrayLayout layout = getArrayletLayout(clazz, dataSizeInBytes); + ArrayLayout layout = getArrayletLayout(clazz, numberOfElements); *hashcodeOffset = getHashcodeOffset(clazz, layout, numberOfElements); return getSizeInBytesWithHeader(clazz, layout, numberOfElements); } diff --git a/runtime/gc_glue_java/ObjectModelDelegate.hpp b/runtime/gc_glue_java/ObjectModelDelegate.hpp index 3dda63405a9..f49a8d8d96f 100644 --- a/runtime/gc_glue_java/ObjectModelDelegate.hpp +++ b/runtime/gc_glue_java/ObjectModelDelegate.hpp @@ -368,8 +368,7 @@ class GC_ObjectModelDelegate } } - uintptr_t dataSize = _arrayObjectModel->getDataSizeInBytes(clazz, elements); - GC_ArrayletObjectModel::ArrayLayout layout = _arrayObjectModel->getArrayletLayout(clazz, dataSize); + GC_ArrayletObjectModel::ArrayLayout layout = _arrayObjectModel->getArrayletLayout(clazz, elements); size = _arrayObjectModel->getSizeInBytesWithHeader(clazz, layout, elements); } else { size = _mixedObjectModel->getSizeInBytesWithoutHeader(clazz) + J9GC_OBJECT_HEADER_SIZE(this);