Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIGFPE for flattened array of value type that has no fields #17994

Merged
merged 1 commit into from
Aug 31, 2023

Conversation

kangyining
Copy link
Contributor

J9ARRAYCLASS_GET_STRIDE() returns the element size, and could return 0 when flattened is enabled and the class is empty.

We should fix this somehow. Currently we hard set the stride to 1 inside division when it is 0.

@@ -94,7 +94,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) {
if(0 == dataSizeInBytes && 0 < J9ARRAYCLASS_GET_STRIDE(clazz)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please:

  • add extra brackets to not rely on order of operations
  • add space after "if"

@@ -366,7 +366,7 @@ class GC_ArrayletObjectModel : public GC_ArrayletObjectModelBase
uintptr_t stride = J9ARRAYCLASS_GET_STRIDE(clazzPtr);
uintptr_t size = numberOfElements * stride;
uintptr_t alignedSize = UDATA_MAX;
if ((size / stride) == numberOfElements) {
if ((0 == stride) || (size / stride) == numberOfElements) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add extra brackets around (size / stride) == numberOfElements

@@ -450,7 +450,7 @@ class MM_ObjectAllocationAPI
uintptr_t dataSize = ((uintptr_t)size) * J9ARRAYCLASS_GET_STRIDE(arrayClass);
bool validSize = true;
#if !defined(J9VM_ENV_DATA64)
validSize = !sizeCheck || (size < ((uint32_t)J9_MAXIMUM_INDEXABLE_DATA_SIZE / J9ARRAYCLASS_GET_STRIDE(arrayClass)));
validSize = !sizeCheck || (0 == J9ARRAYCLASS_GET_STRIDE(arrayClass)) || (size < ((uint32_t)J9_MAXIMUM_INDEXABLE_DATA_SIZE / J9ARRAYCLASS_GET_STRIDE(arrayClass)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please create another variable for J9ARRAYCLASS_GET_STRIDE(arrayClass) and use it instead of calling macro twice

@@ -91,6 +91,9 @@ class GC_FlattenedContiguousArrayIterator
*/
MMINLINE UDATA getIndex()
{
if(0 == _elementStride){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add spaces after "if" and before "{"

@@ -145,7 +145,7 @@ MM_IndexableObjectAllocationModel::initializeIndexableObject(MM_EnvironmentBase
/* Lay out arraylet and arrayoid pointers */
switch (_layout) {
case GC_ArrayletObjectModel::InlineContiguous:
Assert_MM_true(1 == _numberOfArraylets);
Assert_MM_true((_dataSize == 0) || (1 == _numberOfArraylets));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need comment before this assertion explained (_dataSize == 0) for InlineContiguous is possible for 0-stride elements of Flattened Array

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also please put constant first (0 == _dataSize)

@hangshao0 hangshao0 added project:valhalla Used to track Project Valhalla related work comp:gc labels Aug 22, 2023
@@ -637,6 +640,9 @@ class GC_ArrayletObjectModel : public GC_ArrayletObjectModelBase
void* destData = getDataPointerForContiguous(destObject);
switch(elementSize)
{
case 0:
break;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TobiAjila This function is used for Primitive arrays only and supports element sizes 1, 2, 4, 8 bytes. Can Flattened array be declared Primitive and have different element size (except 0-stride we are adding now)? If so, what size of chunk we should use to copy? We can postpone the implementation and add it in different PR. Currently this function triggers assertion if size of the element is not supported.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a flattened array is declared as primitive it will only have size 1, 2, 4 or 8.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long term, it would be nice if we can deal with zero payload arrays. Where we have a header and no body.

bool validSize = true;
#if !defined(J9VM_ENV_DATA64)
validSize = !sizeCheck || (size < ((uint32_t)J9_MAXIMUM_INDEXABLE_DATA_SIZE / J9ARRAYCLASS_GET_STRIDE(arrayClass)));
validSize = (!sizeCheck) || (0 == stride) || (size < ((uint32_t)J9_MAXIMUM_INDEXABLE_DATA_SIZE / stride));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change is not necessary due we don't support any 32-bit JVM for Java Next. However code is here and it is reasonable to fix it. So, keep this change.

@dmitripivkine
Copy link
Contributor

@kangyining Please update comment and squash commits (except you want to add something else to the change).

Update gc code to support 0-stride flattened array
and get rid of division by 0 exceptions

This is done by adding manually comparison against 0,
might find better alternatives in the future.

Related: eclipse-openj9#14027

Signed-off-by: Frank Kang <[email protected]>
@dmitripivkine dmitripivkine changed the title WIP: SIGFPE for flattened array of value type that has no fields SIGFPE for flattened array of value type that has no fields Aug 24, 2023
@dmitripivkine
Copy link
Contributor

Jenkins test sanity,extended xlinuxval jdknext

@hangshao0
Copy link
Contributor

Will the test case be added ? It can be done in a separate PR though.

@dmitripivkine
Copy link
Contributor

Will the test case be added ? It can be done in a separate PR though.

Yes, I think test can be added as a separate submission. We can use existed issue #14027 to track further work.
Test has been provided by @hzongaro. As I understand from #14027 (comment) there is extra tuning required to run test properly.

@hzongaro
Copy link
Member

Will the test case be added ? It can be done in a separate PR though.

I will open a PR to add a test case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp:gc project:valhalla Used to track Project Valhalla related work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants