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

Value Types: java.lang.ArrayStoreException with null-restricted array with -Xint #20223

Closed
a7ehuo opened this issue Sep 24, 2024 · 6 comments · Fixed by #20250
Closed

Value Types: java.lang.ArrayStoreException with null-restricted array with -Xint #20223

a7ehuo opened this issue Sep 24, 2024 · 6 comments · Fixed by #20250
Assignees
Labels
comp:vm project:valhalla Used to track Project Valhalla related work

Comments

@a7ehuo
Copy link
Contributor

a7ehuo commented Sep 24, 2024

I'm running the following test with the latest openj9-openjdk-jdk.valuetypes with -Xint

public class TestNullRestrictedArray {

	public static int ARRAY_SIZE = 100;

	static private void test1(int x) {
	   SomeValueClass1[] array1 = (SomeValueClass1[])ValueClass.newArrayInstance(NullRestrictedCheckedType.of(SomeValueClass1.class), ARRAY_SIZE);
	   SomeValueClass1[] array2 = new SomeValueClass1[ARRAY_SIZE];

		for (int i=0; i < ARRAY_SIZE; i++) {
			array1[i] = new SomeValueClass1(i*x);
			array2[i] = new SomeValueClass1(i*x);
		}

		System.arraycopy(array2, 0, array1, 0, ARRAY_SIZE);
	}

	static private void test2(int x) {
	   SomeValueClass1[] array1 = (SomeValueClass1[])ValueClass.newArrayInstance(NullRestrictedCheckedType.of(SomeValueClass1.class), ARRAY_SIZE);
	   SomeValueClass1[] array2 = new SomeValueClass1[ARRAY_SIZE];

		for (int i=0; i < ARRAY_SIZE; i++) {
			array1[i] = new SomeValueClass1(i*x);
			array2[i] = new SomeValueClass1(i*x);
		}

		System.arraycopy(array1, 0, array2, 0, ARRAY_SIZE);
	}

   public static void main(String[] args) {
     test1(1);
     test2(1);
   }
}

java.lang.ArrayStoreException happens with both test1 and test2. These two tests copy between a null-restricted array and a regular array with array flattening enabled.

java --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.value=ALL-UNNAMED --add-exports java.base/jdk.internal.vm.annotation=ALL-UNNAMED --enable-preview -XX:ValueTypeFlatteningThreshold=99999 -XX:+EnableArrayFlattening -Xint TestNullRestrictedArray 
Exception in thread "main" java.lang.ArrayStoreException
	at java.base/java.lang.System.arraycopy(Native Method)
	at TestNullRestrictedArray.test1(TestNullRestrictedArray.java:32)
	at TestNullRestrictedArray.main(TestNullRestrictedArray.java:54)
java --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.value=ALL-UNNAMED --add-exports java.base/jdk.internal.vm.annotation=ALL-UNNAMED --enable-preview -XX:ValueTypeFlatteningThreshold=99999 -XX:+EnableArrayFlattening -Xint TestNullRestrictedArray 
Exception in thread "main" java.lang.ArrayStoreException
	at java.base/java.lang.System.arraycopy(Native Method)
	at TestNullRestrictedArray.test2(TestNullRestrictedArray.java:46)
	at TestNullRestrictedArray.main(TestNullRestrictedArray.java:56)
@a7ehuo a7ehuo added the project:valhalla Used to track Project Valhalla related work label Sep 24, 2024
@a7ehuo
Copy link
Contributor Author

a7ehuo commented Sep 24, 2024

@hangshao0 @theresa-m If I'm not mistaken, I'm under the impression that null restricted array should work with the latest code with the interpreter. Could you take a look? Thank you!

@hzongaro fyi

@hangshao0
Copy link
Contributor

@hzongaro
Copy link
Member

hzongaro commented Oct 2, 2024

In testing OpenJ9 pull request #20291 and OMR pull request eclipse-omr/omr#7477, I removed the <disables> element from test/functional/Valhalla/playlist.xml for ValueTypeArrayTestsJIT. I encountered a failure with _ValueTypeArrayTestsJIT_3 that I was able to reproduce with this reduced test:

import jdk.internal.vm.annotation.ImplicitlyConstructible;

public class Foo {
        private Foo() {}
  
        interface SomeInterface1WithSingleImplementer {}
  
        @ImplicitlyConstructible
        static value class SomePrimitiveClassImplIf implements SomeInterface1WithSingleImplementer {
                public int d;
                public long l;
  
                SomePrimitiveClassImplIf(int val1, long val2) {
                        this.d = val1;
                        this.l = val2;
                }
        }
  
        static class SomeClassHolder {
                public static int ARRAY_LENGTH = 10;
                public SomeInterface1WithSingleImplementer[] data_1;
  
                SomeClassHolder() {
                        data_1 = new SomePrimitiveClassImplIf[ARRAY_LENGTH];
                        for (int i = 0; i < ARRAY_LENGTH; i++) {
                                data_1[i] = new SomePrimitiveClassImplIf((int)i, (long)i);
                        }
                }
        }
  
        public static final void main(String[] args) {
                SomeClassHolder h = new SomeClassHolder();
                h = new SomeClassHolder();
                for (int i = 0; i < SomeClassHolder.ARRAY_LENGTH; i++) {
                        System.out.println(h.data_1[i] == new SomePrimitiveClassImplIf((int)i, (long)i));
                        System.out.println(Integer.toHexString(((SomePrimitiveClassImplIf) h.data_1[i]).d));
                        System.out.println(Long.toHexString(((SomePrimitiveClassImplIf) h.data_1[i]).l));
                }
        }
}
$ java --enable-preview --add-exports java.base/jdk.internal.vm.annotation=ALL-UNNAMED -Xjit:count=1,disableAsyncCompilation,optLevel=cold,{Foo?SomeClassHolder*}\(traceFull,log=/tmp/holder.log\) -XX:ValueTypeFlatteningThreshold=99999 -XX:+EnableArrayFlattening -cp /tmp Foo

The output that results begins

false
ffea2150
ffea2170ffea2160
false
ffea2190
ffea21b0ffea21a0
false
ffea21d0
ffea21e0
false
0 
0 
...

but the expected output was:

true
0
0
true
1
1
true
2
2
true
3 
3 
true
4 
4 
...

What I was wondering was, is the array that's stored in data_1 being flattened even though it's not non-nullable? I believe the JIT-compiled code for the SomeClassHolder constructor is storing references to the value instances it's constructing into the SomePrimitiveClassImplIf array that it's creating, but it looks like the JVM thinks the array is flattened.

If so, is the array expected to be flattened? If it's not expected, is that another instance of the problem that @a7ehuo reported above, or is this a distinct problem, in which case I will open a separate issue?

@a7ehuo
Copy link
Contributor Author

a7ehuo commented Oct 3, 2024

@hzongaro Does the above issue happen with #20250 and also my change eclipse-omr/omr#7452 and #20112?

@hangshao0
Copy link
Contributor

Re #20223 (comment)

It looks like the same problem #20250 is addressing.

Copy link

github-actions bot commented Oct 4, 2024

Issue Number: 20223
Status: Closed
Actual Components: comp:vm, project:valhalla
Actual Assignees: No one :(
PR Assignees: theresa-m

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

Successfully merging a pull request may close this issue.

4 participants