8233019: java.lang.Class.isPrimitive() (C1) returns wrong result if Klass* is aligned to 32bit
Reviewed-by: mdoerr, dlong, aph
--- 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(); }
}
+
}