mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-19 04:13:07 +00:00
Fix escape at store
This commit is contained in:
parent
5a34377d29
commit
06fb10fecf
@ -1506,34 +1506,21 @@ MemNode::LocalEA::EscapeStatus MemNode::LocalEA::check_escape_status(Node* ctl)
|
||||
} else if (out->is_Mem()) {
|
||||
// A Store or a LoadStore
|
||||
if (n == out->in(MemNode::ValueIn)) {
|
||||
Node* ptr = out->in(MemNode::Address);
|
||||
if (ptr->is_AddP()) {
|
||||
Node* ptr_base = ptr->as_AddP()->base_node();
|
||||
if (!_phase->type(ptr_base)->isa_oopptr()) {
|
||||
// Maybe a store to raw memory
|
||||
res = ESCAPED;
|
||||
break;
|
||||
}
|
||||
|
||||
// If an object o is stored into a field of a holder h and h has not escaped, we can
|
||||
// say that o has not escaped, too
|
||||
LocalEA store_base_ea(_phase, ptr->as_AddP()->base_node());
|
||||
if (!store_base_ea.is_candidate()) {
|
||||
res = ESCAPED;
|
||||
break;
|
||||
}
|
||||
|
||||
// This is similar to store_base_ea.check_escape_status(ctl), the differences are that
|
||||
// it avoids the drawbacks of recursion and does not unnecessarily collect
|
||||
// _not_escaped_controls again
|
||||
for (uint i = 0; i < store_base_ea.aliases().size(); i++) {
|
||||
dependencies.push(store_base_ea.aliases().at(i));
|
||||
}
|
||||
} else {
|
||||
// Do not know into where n is stored, give up
|
||||
res = ESCAPED;
|
||||
break;
|
||||
}
|
||||
// You may wonder if we can reason about the escape status of the destination memory
|
||||
// here so that we can determine that an object has not escaped if the object into which
|
||||
// it is stored has not escaped. Unfortunately, this store breaks _aliases, because there
|
||||
// is now a memory that can alias the object we are analyzed, and a load from such memory
|
||||
// is not visited by this analysis. For example:
|
||||
// Object o = new Object;
|
||||
// Holder h = new Holder;
|
||||
// h.o = o;
|
||||
// do_something();
|
||||
// Object p = h.o;
|
||||
// escape(p);
|
||||
// Then, o escapes at escape(p), but we will not visit that. In order for this to work,
|
||||
// the constructor needs to be more conservative when it collects _aliases.
|
||||
res = ESCAPED;
|
||||
break;
|
||||
} else if (n == out->in(MemNode::Address) && (!out->is_Store() || out->as_Store()->is_mismatched_access())) {
|
||||
// Mismatched accesses can lie in a different alias class and are protected by memory
|
||||
// barriers, so we cannot be aggressive and walk past memory barriers if there is a
|
||||
|
||||
@ -241,7 +241,7 @@ public class TestLoadFolding {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(applyIf = {"DoLocalEscapeAnalysis", "true"}, failOn = IRNode.LOAD_I, counts = {IRNode.ALLOC, "1"})
|
||||
@IR(applyIf = {"DoLocalEscapeAnalysis", "true"}, counts = {IRNode.ALLOC, "1"})
|
||||
public int test112() {
|
||||
// The object has been stored into memory but the destination does not escape
|
||||
PointHolder h = new PointHolder();
|
||||
@ -254,7 +254,7 @@ public class TestLoadFolding {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(applyIf = {"DoLocalEscapeAnalysis", "true"}, failOn = IRNode.LOAD_I, counts = {IRNode.ALLOC, "2"})
|
||||
@IR(applyIf = {"DoLocalEscapeAnalysis", "true"}, counts = {IRNode.ALLOC, "2"})
|
||||
public int test113() {
|
||||
// The object has been stored into memory but the destination has not escaped
|
||||
PointHolder h = new PointHolder();
|
||||
@ -267,7 +267,7 @@ public class TestLoadFolding {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(applyIf = {"DoLocalEscapeAnalysis", "true"}, failOn = IRNode.LOAD_I, counts = {IRNode.ALLOC, "3"})
|
||||
@IR(applyIf = {"DoLocalEscapeAnalysis", "true"}, counts = {IRNode.ALLOC, "3"})
|
||||
public int test114(boolean b) {
|
||||
// A Phi has been stored into memory but the destination has not escaped
|
||||
PointHolder h = new PointHolder();
|
||||
@ -281,7 +281,7 @@ public class TestLoadFolding {
|
||||
}
|
||||
|
||||
@Test
|
||||
@IR(applyIf = {"DoLocalEscapeAnalysis", "true"}, failOn = IRNode.LOAD_I, counts = {IRNode.ALLOC, "3"})
|
||||
@IR(applyIf = {"DoLocalEscapeAnalysis", "true"}, counts = {IRNode.ALLOC, "3"})
|
||||
public int test115(boolean b) {
|
||||
// The object has been stored into a Phi but the destination has not escaped
|
||||
PointHolder h1 = new PointHolder();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user