Skip to content

Commit

Permalink
Merge pull request #18300 from dmitripivkine/master
Browse files Browse the repository at this point in the history
Make 0-length 0-stride array discontiguous
  • Loading branch information
amicic committed Oct 19, 2023
2 parents dc28d58 + c09a73a commit 70705ba
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 24 deletions.
2 changes: 1 addition & 1 deletion runtime/gc_base/IndexableObjectAllocationModel.hpp
Expand Up @@ -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))
Expand Down
5 changes: 3 additions & 2 deletions runtime/gc_glue_java/ArrayletObjectModel.cpp
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
47 changes: 28 additions & 19 deletions runtime/gc_glue_java/ArrayletObjectModel.hpp
Expand Up @@ -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)
MMINLINE uint32_t
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 uint32_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
Expand All @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down
3 changes: 1 addition & 2 deletions runtime/gc_glue_java/ObjectModelDelegate.hpp
Expand Up @@ -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);
Expand Down

0 comments on commit 70705ba

Please sign in to comment.