changeset 56249:b51bfa6eb39f lworld

8229823: [lworld] ArrayCopyNode::modifies returns incorrect value for inline type arrays
author thartmann
date Fri, 16 Aug 2019 14:38:54 +0200
parents 7f5b8f7cdb42
children a32457198d3e
files src/hotspot/share/opto/arraycopynode.cpp test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java
diffstat 2 files changed, 52 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/opto/arraycopynode.cpp	Fri Aug 16 12:57:40 2019 +0200
+++ b/src/hotspot/share/opto/arraycopynode.cpp	Fri Aug 16 14:38:54 2019 +0200
@@ -821,9 +821,13 @@
     return !must_modify;
   }
 
-  BasicType ary_elem = ary_t->klass()->as_array_klass()->element_type()->basic_type();
+  ciArrayKlass* klass = ary_t->klass()->as_array_klass();
+  BasicType ary_elem = klass->element_type()->basic_type();
   uint header = arrayOopDesc::base_offset_in_bytes(ary_elem);
   uint elemsize = type2aelembytes(ary_elem);
+  if (klass->is_value_array_klass()) {
+    elemsize = klass->as_value_array_klass()->element_byte_size();
+  }
 
   jlong dest_pos_plus_len_lo = (((jlong)dest_pos_t->_lo) + len_t->_lo) * elemsize + header;
   jlong dest_pos_plus_len_hi = (((jlong)dest_pos_t->_hi) + len_t->_hi) * elemsize + header;
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java	Fri Aug 16 12:57:40 2019 +0200
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java	Fri Aug 16 14:38:54 2019 +0200
@@ -2223,4 +2223,51 @@
         test92(a, b);
         verify(a, b);
     }
+
+    // Same as test30 but accessing all elements of the non-escaping array
+    @Test
+    public long test93(MyValue2[] src, boolean flag) {
+        MyValue2[] dst = new MyValue2[10];
+        System.arraycopy(src, 0, dst, 0, 10);
+        if (flag) {  }
+        return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
+               dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
+    }
+
+    @DontCompile
+    public void test93_verifier(boolean warmup) {
+        MyValue2[] src = new MyValue2[10];
+        for (int i = 0; i < 10; ++i) {
+            src[i] = MyValue2.createWithFieldsInline(rI, (rI % 2) == 0);
+        }
+        long res = test93(src, !warmup);
+        long expected = 0;
+        for (int i = 0; i < 10; ++i) {
+            expected += src[i].hash();
+        }
+        Asserts.assertEQ(res, expected);
+    }
+
+    // Same as test93 but with variable source array offset
+    @Test
+    public long test94(MyValue2[] src, int i, boolean flag) {
+        MyValue2[] dst = new MyValue2[10];
+        System.arraycopy(src, i, dst, 0, 1);
+        if (flag) {  }
+        return dst[0].hash() + dst[1].hash() + dst[2].hash() + dst[3].hash() + dst[4].hash() +
+               dst[5].hash() + dst[6].hash() + dst[7].hash() + dst[8].hash() + dst[9].hash();
+    }
+
+    @DontCompile
+    public void test94_verifier(boolean warmup) {
+        MyValue2[] src = new MyValue2[10];
+        for (int i = 0; i < 10; ++i) {
+            src[i] = MyValue2.createWithFieldsInline(i, (i % 2) == 0);
+        }
+        for (int i = 0; i < 10; ++i) {
+            long res = test94(src, i, !warmup);
+            long expected = src[i].hash() + 9*MyValue2.default.hash();
+            Asserts.assertEQ(res, expected);
+        }
+    }
 }