8233019: java.lang.Class.isPrimitive() (C1) returns wrong result if Klass* is aligned to 32bit
authorstuefe
Thu, 31 Oct 2019 07:53:16 +0100
changeset 58925 9bbe560e8131
parent 58924 c41d1303a87c
child 58926 ecb801342b8c
8233019: java.lang.Class.isPrimitive() (C1) returns wrong result if Klass* is aligned to 32bit Reviewed-by: mdoerr, dlong, aph
src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp
src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp
src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
src/hotspot/share/c1/c1_LIRGenerator.cpp
test/hotspot/jtreg/compiler/intrinsics/klass/TestIsPrimitive.java
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Mon Nov 04 13:02:40 2019 -0800
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp	Thu Oct 31 07:53:16 2019 +0100
@@ -1978,6 +1978,9 @@
       case T_ADDRESS:
         imm = opr2->as_constant_ptr()->as_jint();
         break;
+      case T_METADATA:
+        imm = (intptr_t)(opr2->as_constant_ptr()->as_metadata());
+        break;
       case T_OBJECT:
       case T_ARRAY:
         jobject2reg(opr2->as_constant_ptr()->as_jobject(), rscratch1);
--- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp	Mon Nov 04 13:02:40 2019 -0800
+++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp	Thu Oct 31 07:53:16 2019 +0100
@@ -1817,6 +1817,11 @@
           assert(opr2->as_constant_ptr()->as_jobject() == NULL, "cannot handle otherwise");
           __ cmp(opr1->as_register(), 0);
           break;
+        case T_METADATA:
+          assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "Only equality tests");
+          assert(opr2->as_constant_ptr()->as_metadata() == NULL, "cannot handle otherwise");
+          __ cmp(opr1->as_register(), 0);
+          break;
         default:
           ShouldNotReachHere();
       }
--- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp	Mon Nov 04 13:02:40 2019 -0800
+++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp	Thu Oct 31 07:53:16 2019 +0100
@@ -1467,6 +1467,19 @@
           }
           break;
 
+        case T_METADATA:
+          // We only need, for now, comparison with NULL for metadata.
+          {
+            assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops");
+            Metadata* p = opr2->as_constant_ptr()->as_metadata();
+            if (p == NULL) {
+              __ cmpdi(BOOL_RESULT, opr1->as_register(), 0);
+            } else {
+              ShouldNotReachHere();
+            }
+          }
+          break;
+
         default:
           ShouldNotReachHere();
           break;
--- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp	Mon Nov 04 13:02:40 2019 -0800
+++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp	Thu Oct 31 07:53:16 2019 +0100
@@ -1322,6 +1322,15 @@
         } else {
           __ z_cfi(reg1, c->as_jint());
         }
+      } else if (c->type() == T_METADATA) {
+        // We only need, for now, comparison with NULL for metadata.
+        assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops");
+        Metadata* m = c->as_metadata();
+        if (m == NULL) {
+          __ z_cghi(reg1, 0);
+        } else {
+          ShouldNotReachHere();
+        }
       } else if (is_reference_type(c->type())) {
         // In 64bit oops are single register.
         jobject o = c->as_jobject();
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Mon Nov 04 13:02:40 2019 -0800
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp	Thu Oct 31 07:53:16 2019 +0100
@@ -1511,6 +1511,18 @@
           }
           break;
 
+        case T_METADATA:
+          // We only need, for now, comparison with NULL for metadata.
+          { assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops");
+            Metadata* m = opr2->as_constant_ptr()->as_metadata();
+            if (m == NULL) {
+              __ cmp(opr1->as_register(), 0);
+            } else {
+              ShouldNotReachHere();
+            }
+          }
+          break;
+
         default:
           ShouldNotReachHere();
           break;
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp	Mon Nov 04 13:02:40 2019 -0800
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp	Thu Oct 31 07:53:16 2019 +0100
@@ -2641,6 +2641,15 @@
       LIR_Const* c = opr2->as_constant_ptr();
       if (c->type() == T_INT) {
         __ cmpl(reg1, c->as_jint());
+      } else if (c->type() == T_METADATA) {
+        // All we need for now is a comparison with NULL for equality.
+        assert(condition == lir_cond_equal || condition == lir_cond_notEqual, "oops");
+        Metadata* m = c->as_metadata();
+        if (m == NULL) {
+          __ cmpptr(reg1, (int32_t)0);
+        } else {
+          ShouldNotReachHere();
+        }
       } else if (is_reference_type(c->type())) {
         // In 64bit oops are single register
         jobject o = c->as_jobject();
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp	Mon Nov 04 13:02:40 2019 -0800
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp	Thu Oct 31 07:53:16 2019 +0100
@@ -1301,7 +1301,7 @@
   }
 
   __ move(new LIR_Address(rcvr.result(), java_lang_Class::klass_offset_in_bytes(), T_ADDRESS), temp, info);
-  __ cmp(lir_cond_notEqual, temp, LIR_OprFact::intConst(0));
+  __ cmp(lir_cond_notEqual, temp, LIR_OprFact::metadataConst(0));
   __ cmove(lir_cond_notEqual, LIR_OprFact::intConst(0), LIR_OprFact::intConst(1), result, T_BOOLEAN);
 }
 
--- a/test/hotspot/jtreg/compiler/intrinsics/klass/TestIsPrimitive.java	Mon Nov 04 13:02:40 2019 -0800
+++ b/test/hotspot/jtreg/compiler/intrinsics/klass/TestIsPrimitive.java	Thu Oct 31 07:53:16 2019 +0100
@@ -24,12 +24,13 @@
 /*
  * @test
  * @bug 8150669
+ * @bug 8233019
  * @summary C1 intrinsic for Class.isPrimitive
  * @modules java.base/jdk.internal.misc
  *
  * @run main/othervm -ea -Diters=200   -Xint
  *      compiler.intrinsics.klass.TestIsPrimitive
- * @run main/othervm -ea -Diters=30000 -XX:TieredStopAtLevel=1
+ * @run main/othervm -ea -XX:-UseSharedSpaces -Diters=30000 -XX:TieredStopAtLevel=1
  *      compiler.intrinsics.klass.TestIsPrimitive
  * @run main/othervm -ea -Diters=30000 -XX:TieredStopAtLevel=4
  *      compiler.intrinsics.klass.TestIsPrimitive
@@ -53,6 +54,7 @@
         testOK(true,  InlineConstants::testDouble);
         testOK(false, InlineConstants::testObject);
         testOK(false, InlineConstants::testArray);
+        testOK(false, InlineConstants::testBooleanArray);
 
         testOK(true,  StaticConstants::testBoolean);
         testOK(true,  StaticConstants::testByte);
@@ -64,6 +66,7 @@
         testOK(true,  StaticConstants::testDouble);
         testOK(false, StaticConstants::testObject);
         testOK(false, StaticConstants::testArray);
+        testOK(false, StaticConstants::testBooleanArray);
         testNPE(      StaticConstants::testNull);
 
         testOK(true,  NoConstants::testBoolean);
@@ -76,6 +79,7 @@
         testOK(true,  NoConstants::testDouble);
         testOK(false, NoConstants::testObject);
         testOK(false, NoConstants::testArray);
+        testOK(false, NoConstants::testBooleanArray);
         testNPE(      NoConstants::testNull);
     }
 
@@ -112,6 +116,7 @@
     static volatile Class<?> classObject  = Object.class;
     static volatile Class<?> classArray   = Object[].class;
     static volatile Class<?> classNull    = null;
+    static volatile Class<?> classBooleanArray = boolean[].class;
 
     static final Class<?> staticClassBoolean = boolean.class;
     static final Class<?> staticClassByte    = byte.class;
@@ -124,6 +129,7 @@
     static final Class<?> staticClassObject  = Object.class;
     static final Class<?> staticClassArray   = Object[].class;
     static final Class<?> staticClassNull    = null;
+    static final Class<?> staticClassBooleanArray = boolean[].class;
 
     static class InlineConstants {
         static boolean testBoolean() { return boolean.class.isPrimitive();  }
@@ -136,6 +142,7 @@
         static boolean testDouble()  { return double.class.isPrimitive();   }
         static boolean testObject()  { return Object.class.isPrimitive();   }
         static boolean testArray()   { return Object[].class.isPrimitive(); }
+        static boolean testBooleanArray() { return boolean[].class.isPrimitive(); }
     }
 
     static class StaticConstants {
@@ -150,6 +157,7 @@
         static boolean testObject()  { return staticClassObject.isPrimitive();  }
         static boolean testArray()   { return staticClassArray.isPrimitive();   }
         static boolean testNull()    { return staticClassNull.isPrimitive();    }
+        static boolean testBooleanArray() { return staticClassBooleanArray.isPrimitive(); }
     }
 
     static class NoConstants {
@@ -164,7 +172,9 @@
         static boolean testObject()  { return classObject.isPrimitive();  }
         static boolean testArray()   { return classArray.isPrimitive();   }
         static boolean testNull()    { return classNull.isPrimitive();    }
+        static boolean testBooleanArray() { return classBooleanArray.isPrimitive();    }
     }
 
+
 }