6681577: PIT: some VM tests fails with -XX:+AggressiveOpts in 6u5p b01
C2 spends > 60% in escape analysis code during test nsk/regression/b4675027. Reviewed-by: never
This commit is contained in:
parent
0d27a8639f
commit
ccaa58c5db
@ -256,39 +256,49 @@ void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionGraph::remove_deferred(uint ni) {
|
void ConnectionGraph::remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited) {
|
||||||
VectorSet visited(Thread::current()->resource_area());
|
// This method is most expensive during ConnectionGraph construction.
|
||||||
|
// Reuse vectorSet and an additional growable array for deferred edges.
|
||||||
|
deferred_edges->clear();
|
||||||
|
visited->Clear();
|
||||||
|
|
||||||
uint i = 0;
|
uint i = 0;
|
||||||
PointsToNode *ptn = ptnode_adr(ni);
|
PointsToNode *ptn = ptnode_adr(ni);
|
||||||
|
|
||||||
while(i < ptn->edge_count()) {
|
// Mark current edges as visited and move deferred edges to separate array.
|
||||||
|
for (; i < ptn->edge_count(); i++) {
|
||||||
uint t = ptn->edge_target(i);
|
uint t = ptn->edge_target(i);
|
||||||
PointsToNode *ptt = ptnode_adr(t);
|
#ifdef ASSERT
|
||||||
if (ptn->edge_type(i) != PointsToNode::DeferredEdge) {
|
assert(!visited->test_set(t), "expecting no duplications");
|
||||||
i++;
|
#else
|
||||||
} else {
|
visited->set(t);
|
||||||
|
#endif
|
||||||
|
if (ptn->edge_type(i) == PointsToNode::DeferredEdge) {
|
||||||
ptn->remove_edge(t, PointsToNode::DeferredEdge);
|
ptn->remove_edge(t, PointsToNode::DeferredEdge);
|
||||||
if(!visited.test_set(t)) {
|
deferred_edges->append(t);
|
||||||
for (uint j = 0; j < ptt->edge_count(); j++) {
|
}
|
||||||
uint n1 = ptt->edge_target(j);
|
}
|
||||||
PointsToNode *pt1 = ptnode_adr(n1);
|
for (int next = 0; next < deferred_edges->length(); ++next) {
|
||||||
switch(ptt->edge_type(j)) {
|
uint t = deferred_edges->at(next);
|
||||||
case PointsToNode::PointsToEdge:
|
PointsToNode *ptt = ptnode_adr(t);
|
||||||
add_pointsto_edge(ni, n1);
|
for (uint j = 0; j < ptt->edge_count(); j++) {
|
||||||
if(n1 == _phantom_object) {
|
uint n1 = ptt->edge_target(j);
|
||||||
// Special case - field set outside (globally escaping).
|
if (visited->test_set(n1))
|
||||||
ptn->set_escape_state(PointsToNode::GlobalEscape);
|
continue;
|
||||||
}
|
switch(ptt->edge_type(j)) {
|
||||||
break;
|
case PointsToNode::PointsToEdge:
|
||||||
case PointsToNode::DeferredEdge:
|
add_pointsto_edge(ni, n1);
|
||||||
add_deferred_edge(ni, n1);
|
if(n1 == _phantom_object) {
|
||||||
break;
|
// Special case - field set outside (globally escaping).
|
||||||
case PointsToNode::FieldEdge:
|
ptn->set_escape_state(PointsToNode::GlobalEscape);
|
||||||
assert(false, "invalid connection graph");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
case PointsToNode::DeferredEdge:
|
||||||
|
deferred_edges->append(n1);
|
||||||
|
break;
|
||||||
|
case PointsToNode::FieldEdge:
|
||||||
|
assert(false, "invalid connection graph");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1236,8 +1246,10 @@ void ConnectionGraph::compute_escape() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VectorSet ptset(Thread::current()->resource_area());
|
VectorSet ptset(Thread::current()->resource_area());
|
||||||
GrowableArray<Node*> alloc_worklist;
|
GrowableArray<Node*> alloc_worklist;
|
||||||
GrowableArray<int> worklist;
|
GrowableArray<int> worklist;
|
||||||
|
GrowableArray<uint> deferred_edges;
|
||||||
|
VectorSet visited(Thread::current()->resource_area());
|
||||||
|
|
||||||
// remove deferred edges from the graph and collect
|
// remove deferred edges from the graph and collect
|
||||||
// information we will need for type splitting
|
// information we will need for type splitting
|
||||||
@ -1247,7 +1259,7 @@ void ConnectionGraph::compute_escape() {
|
|||||||
PointsToNode::NodeType nt = ptn->node_type();
|
PointsToNode::NodeType nt = ptn->node_type();
|
||||||
Node *n = ptn->_node;
|
Node *n = ptn->_node;
|
||||||
if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
|
if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
|
||||||
remove_deferred(ni);
|
remove_deferred(ni, &deferred_edges, &visited);
|
||||||
if (n->is_AddP()) {
|
if (n->is_AddP()) {
|
||||||
// If this AddP computes an address which may point to more that one
|
// If this AddP computes an address which may point to more that one
|
||||||
// object, nothing the address points to can be scalar replaceable.
|
// object, nothing the address points to can be scalar replaceable.
|
||||||
|
@ -269,7 +269,7 @@ private:
|
|||||||
// Remove outgoing deferred edges from the node referenced by "ni".
|
// Remove outgoing deferred edges from the node referenced by "ni".
|
||||||
// Any outgoing edges from the target of the deferred edge are copied
|
// Any outgoing edges from the target of the deferred edge are copied
|
||||||
// to "ni".
|
// to "ni".
|
||||||
void remove_deferred(uint ni);
|
void remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited);
|
||||||
|
|
||||||
Node_Array _node_map; // used for bookeeping during type splitting
|
Node_Array _node_map; // used for bookeeping during type splitting
|
||||||
// Used for the following purposes:
|
// Used for the following purposes:
|
||||||
|
Loading…
Reference in New Issue
Block a user