Skip to content

Commit

Permalink
8255045: [lworld] LoadNode::Value() use of markWord::prototype() may …
Browse files Browse the repository at this point in the history
…strip type bits
  • Loading branch information
TobiHartmann committed Feb 16, 2021
1 parent 9a601e0 commit b9d9ca4
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 4 deletions.
9 changes: 9 additions & 0 deletions src/hotspot/share/ci/ciKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,15 @@ jint ciKlass::access_flags() {
)
}

// ------------------------------------------------------------------
// ciKlass::prototype_header
markWord ciKlass::prototype_header() const {
assert(is_loaded(), "not loaded");
GUARDED_VM_ENTRY(
return get_Klass()->prototype_header();
)
}

// ------------------------------------------------------------------
// ciKlass::print_impl
//
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/ci/ciKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ class ciKlass : public ciType {
// Fetch Klass::access_flags.
jint access_flags();

markWord prototype_header() const;

// What kind of ciObject is this?
bool is_klass() const { return true; }

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/locknode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void Parse::do_monitor_enter() {

Node* obj = peek();
const Type* obj_type = gvn().type(obj);
if (obj_type->isa_inlinetype() && !obj_type->is_inlinetypeptr()) {
if (obj_type->isa_inlinetype() || obj_type->is_inlinetypeptr()) {
uncommon_trap(Deoptimization::Reason_class_check,
Deoptimization::Action_none);
return;
Expand Down
14 changes: 11 additions & 3 deletions src/hotspot/share/opto/memnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2132,9 +2132,17 @@ const Type* LoadNode::Value(PhaseGVN* phase) const {
return Type::get_zero_type(_type->basic_type());
}
}
if (!EnableValhalla) { // CMH: Fix JDK-8255045
Node* alloc = is_new_object_mark_load(phase);
if (alloc != NULL && !(alloc->Opcode() == Op_Allocate && UseBiasedLocking)) {
Node* alloc = is_new_object_mark_load(phase);
if (alloc != NULL && !(alloc->Opcode() == Op_Allocate && UseBiasedLocking)) {
if (EnableValhalla) {
// The mark word may contain property bits (inline, flat, null-free)
Node* klass_node = alloc->in(AllocateNode::KlassNode);
const TypeKlassPtr* tkls = phase->type(klass_node)->is_klassptr();
ciKlass* klass = tkls->klass();
if (klass != NULL && klass->is_loaded() && tkls->klass_is_exact()) {
return TypeX::make(klass->prototype_header().value());
}
} else {
return TypeX::make(markWord::prototype().value());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1075,4 +1075,59 @@ public void test57() {
public void test57_verifier(boolean warmup) {
test57();
}

// Test unsafe allocation
@Test()
public boolean test58(Class<?> c1, Class<?> c2) throws Exception {
Object obj1 = U.allocateInstance(c1);
Object obj2 = U.allocateInstance(c2);
return obj1 == obj2;
}

@DontCompile
public void test58_verifier(boolean warmup) throws Exception {
boolean res = test58(MyValue1.class, MyValue1.class);
Asserts.assertTrue(res);
res = test58(Object.class, MyValue1.class);
Asserts.assertFalse(res);
res = test58(MyValue1.class, Object.class);
Asserts.assertFalse(res);
}

// Test synchronization on unsafe inline type allocation
@Test()
public void test59(Class<?> c) throws Exception {
Object obj = U.allocateInstance(c);
synchronized (obj) {

}
}

@DontCompile
public void test59_verifier(boolean warmup) throws Exception {
test59(Integer.class);
try {
test59(MyValue1.class);
throw new RuntimeException("test59 failed: synchronization on inline type should not succeed");
} catch (IllegalMonitorStateException e) {

}
}

// Test mark word load optimization on unsafe inline type allocation
@Test()
public boolean test60(Class<?> c1, Class<?> c2, boolean b1, boolean b2) throws Exception {
Object obj1 = b1 ? new Object() : U.allocateInstance(c1);
Object obj2 = b2 ? new Object() : U.allocateInstance(c2);
return obj1 == obj2;
}

@DontCompile
public void test60_verifier(boolean warmup) throws Exception {
Asserts.assertTrue(test60(MyValue1.class, MyValue1.class, false, false));
Asserts.assertFalse(test60(MyValue1.class, MyValue2.class, false, false));
Asserts.assertFalse(test60(MyValue1.class, MyValue1.class, false, true));
Asserts.assertFalse(test60(MyValue1.class, MyValue1.class, true, false));
Asserts.assertFalse(test60(MyValue1.class, MyValue1.class, true, true));
}
}
22 changes: 22 additions & 0 deletions test/hotspot/jtreg/compiler/valhalla/inlinetypes/TestLWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -3623,4 +3623,26 @@ public void test133_verifier(boolean warmup) {
// Expected
}
}

// Variant with non-scalarized inline type
@Test()
public static void test134(boolean b) {
Object obj = null;
if (b) {
obj = MyValue2.createWithFieldsInline(rI, rD);
}
synchronized (obj) {

}
}

@DontCompile
public void test134_verifier(boolean warmup) {
try {
test134(true);
throw new RuntimeException("test134 failed: no exception thrown");
} catch (IllegalMonitorStateException ex) {
// Expected
}
}
}

0 comments on commit b9d9ca4

Please sign in to comment.