8233019: java.lang.Class.isPrimitive() (C1) returns wrong result if Klass* is aligned to 32bit

Reviewed-by: mdoerr, dlong, aph
This commit is contained in:
Thomas Stuefe 2019-10-31 07:53:16 +01:00
parent bc8822095f
commit 13cc1154f0
8 changed files with 63 additions and 2 deletions

View File

@ -1978,6 +1978,9 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2,
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);

View File

@ -1817,6 +1817,11 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2,
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();
}

View File

@ -1467,6 +1467,19 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2,
}
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;

View File

@ -1322,6 +1322,15 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2,
} 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();

View File

@ -1511,6 +1511,18 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2,
}
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;

View File

@ -2641,6 +2641,15 @@ void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2,
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();

View File

@ -1301,7 +1301,7 @@ void LIRGenerator::do_isPrimitive(Intrinsic* x) {
}
__ 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);
}

View File

@ -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 @@ public class TestIsPrimitive {
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 @@ public class TestIsPrimitive {
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 @@ public class TestIsPrimitive {
testOK(true, NoConstants::testDouble);
testOK(false, NoConstants::testObject);
testOK(false, NoConstants::testArray);
testOK(false, NoConstants::testBooleanArray);
testNPE( NoConstants::testNull);
}
@ -112,6 +116,7 @@ public class TestIsPrimitive {
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 @@ public class TestIsPrimitive {
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 @@ public class TestIsPrimitive {
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 @@ public class TestIsPrimitive {
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 @@ public class TestIsPrimitive {
static boolean testObject() { return classObject.isPrimitive(); }
static boolean testArray() { return classArray.isPrimitive(); }
static boolean testNull() { return classNull.isPrimitive(); }
static boolean testBooleanArray() { return classBooleanArray.isPrimitive(); }
}
}