src/share/vm/opto/escape.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/escape.cpp Tue Nov 2 15:10:07 2010
--- new/src/share/vm/opto/escape.cpp Tue Nov 2 15:10:07 2010
*** 83,92 ****
--- 83,93 ----
ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
_nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()),
_processed(C->comp_arena()),
_collecting(true),
+ _progress(false),
_compile(C),
_igvn(igvn),
_node_map(C->comp_arena()) {
_phantom_object = C->top()->_idx,
*** 111,121 ****
--- 112,122 ----
PointsToNode *t = ptnode_adr(to_i);
assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
assert(f->node_type() == PointsToNode::LocalVar || f->node_type() == PointsToNode::Field, "invalid source of PointsTo edge");
assert(t->node_type() == PointsToNode::JavaObject, "invalid destination of PointsTo edge");
! f->add_edge(to_i, PointsToNode::PointsToEdge);
! add_edge(f, to_i, PointsToNode::PointsToEdge);
}
void ConnectionGraph::add_deferred_edge(uint from_i, uint to_i) {
PointsToNode *f = ptnode_adr(from_i);
PointsToNode *t = ptnode_adr(to_i);
*** 124,134 ****
--- 125,135 ----
assert(f->node_type() == PointsToNode::LocalVar || f->node_type() == PointsToNode::Field, "invalid source of Deferred edge");
assert(t->node_type() == PointsToNode::LocalVar || t->node_type() == PointsToNode::Field, "invalid destination of Deferred edge");
// don't add a self-referential edge, this can occur during removal of
// deferred edges
if (from_i != to_i)
! f->add_edge(to_i, PointsToNode::DeferredEdge);
! add_edge(f, to_i, PointsToNode::DeferredEdge);
}
int ConnectionGraph::address_offset(Node* adr, PhaseTransform *phase) {
const Type *adr_type = phase->type(adr);
if (adr->is_AddP() && adr_type->isa_oopptr() == NULL &&
*** 155,165 ****
--- 156,166 ----
assert(f->node_type() == PointsToNode::JavaObject, "invalid destination of Field edge");
assert(t->node_type() == PointsToNode::Field, "invalid destination of Field edge");
assert (t->offset() == -1 || t->offset() == offset, "conflicting field offsets");
t->set_offset(offset);
! f->add_edge(to_i, PointsToNode::FieldEdge);
! add_edge(f, to_i, PointsToNode::FieldEdge);
}
void ConnectionGraph::set_escape_state(uint ni, PointsToNode::EscapeState es) {
PointsToNode *npt = ptnode_adr(ni);
PointsToNode::EscapeState old_es = npt->escape_state();
*** 993,1003 ****
--- 994,1004 ----
//
void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist) {
GrowableArray<Node *> memnode_worklist;
GrowableArray<PhiNode *> orig_phis;
! PhaseGVN *igvn = _igvn;
! PhaseIterGVN *igvn = _igvn;
uint new_index_start = (uint) _compile->num_alias_types();
Arena* arena = Thread::current()->resource_area();
VectorSet visited(arena);
VectorSet ptset(arena);
*** 1529,1546 ****
--- 1530,1542 ----
if (n->is_Allocate() || n->is_CallStaticJava() &&
ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) {
has_allocations = true;
}
if(n->is_AddP()) {
! // Collect address nodes which directly reference an allocation.
// Use them during stage 3 below to build initial connection graph
// field edges. Other field edges could be added after StoreP/LoadP
// nodes are processed during stage 4 below.
Node* base = get_addp_base(n);
if(base->is_Proj() && base->in(0)->is_Allocate()) {
! // Collect address nodes. Use them during stage 3 below
+ // to build initial connection graph field edges.
cg_worklist.append(n->_idx);
}
} else if (n->is_MergeMem()) {
// Collect all MergeMem nodes to add memory slices for
// scalar replaceable objects in split_unique_types().
_mergemem_worklist.append(n->as_MergeMem());
}
*** 1560,1599 ****
--- 1556,1629 ----
for( uint next = 0; next < delayed_size; ++next ) {
Node* n = _delayed_worklist.at(next);
build_connection_graph(n, igvn);
}
! // 3. Pass to create fields edges (Allocate -F-> AddP).
! // 3. Pass to create initial fields edges (JavaObject -F-> AddP)
+ // to reduce number of iterations during stage 4 below.
uint cg_length = cg_worklist.length();
for( uint next = 0; next < cg_length; ++next ) {
int ni = cg_worklist.at(next);
! build_connection_graph(ptnode_adr(ni)->_node, igvn);
! Node* n = ptnode_adr(ni)->_node;
+ Node* base = get_addp_base(n);
+ if (base->is_Proj())
+ base = base->in(0);
+ PointsToNode::NodeType nt = ptnode_adr(base->_idx)->node_type();
+ if (nt == PointsToNode::JavaObject) {
+ build_connection_graph(n, igvn);
}
+ }
cg_worklist.clear();
cg_worklist.append(_phantom_object);
// 4. Build Connection Graph which need
// to walk the connection graph.
+ _progress = false;
for (uint ni = 0; ni < nodes_size(); ni++) {
PointsToNode* ptn = ptnode_adr(ni);
Node *n = ptn->_node;
if (n != NULL) { // Call, AddP, LoadP, StoreP
build_connection_graph(n, igvn);
if (ptn->node_type() != PointsToNode::UnknownType)
cg_worklist.append(n->_idx); // Collect CG nodes
}
}
+ // After IGVN user nodes may have smaller _idx than
+ // their inputs so they will be processed first in
+ // previous loop. Because of that not all Graph
+ // edges will be created. Walk over interesting
+ // nodes again until no new edges are created.
+ // Set limit on iterations.
+ cg_length = cg_worklist.length();
+ int iterations = 0;
+ while(_progress && (iterations++ < 10)) {
+ _progress = false;
+ for( uint next = 0; next < cg_length; ++next ) {
+ int ni = cg_worklist.at(next);
+ PointsToNode* ptn = ptnode_adr(ni);
+ DEBUG_ONLY(PointsToNode::NodeType nt = ptn->node_type());
+ Node* n = ptn->_node;
+ assert(n != NULL && nt != PointsToNode::UnknownType, "should be known node");
+ build_connection_graph(n, igvn);
+ }
+ }
+ if (iterations >= 10) {
+ // Possible infinit build_connection_graph loop.
+ // Retry compilation without escape analysis.
+ C->record_failure(C2Compiler::retry_no_escape_analysis());
+ _collecting = false;
+ return false;
+ }
Arena* arena = Thread::current()->resource_area();
VectorSet ptset(arena);
GrowableArray<uint> deferred_edges;
VectorSet visited(arena);
// 5. Remove deferred edges from the graph and adjust
// escape state of nonescaping objects.
cg_length = cg_worklist.length();
for( uint next = 0; next < cg_length; ++next ) {
int ni = cg_worklist.at(next);
PointsToNode* ptn = ptnode_adr(ni);
PointsToNode::NodeType nt = ptn->node_type();
if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
src/share/vm/opto/escape.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File