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