1.1 --- a/src/share/vm/opto/escape.cpp Wed Dec 07 11:35:03 2011 +0100 1.2 +++ b/src/share/vm/opto/escape.cpp Tue Dec 20 16:56:50 2011 +0100 1.3 @@ -1595,6 +1595,7 @@ 1.4 GrowableArray<Node*> alloc_worklist; 1.5 GrowableArray<Node*> addp_worklist; 1.6 GrowableArray<Node*> ptr_cmp_worklist; 1.7 + GrowableArray<Node*> storestore_worklist; 1.8 PhaseGVN* igvn = _igvn; 1.9 1.10 // Push all useful nodes onto CG list and set their type. 1.11 @@ -1618,6 +1619,11 @@ 1.12 (n->Opcode() == Op_CmpP || n->Opcode() == Op_CmpN)) { 1.13 // Compare pointers nodes 1.14 ptr_cmp_worklist.append(n); 1.15 + } else if (n->is_MemBarStoreStore()) { 1.16 + // Collect all MemBarStoreStore nodes so that depending on the 1.17 + // escape status of the associated Allocate node some of them 1.18 + // may be eliminated. 1.19 + storestore_worklist.append(n); 1.20 } 1.21 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 1.22 Node* m = n->fast_out(i); // Get user 1.23 @@ -1724,11 +1730,20 @@ 1.24 uint alloc_length = alloc_worklist.length(); 1.25 for (uint next = 0; next < alloc_length; ++next) { 1.26 Node* n = alloc_worklist.at(next); 1.27 - if (ptnode_adr(n->_idx)->escape_state() == PointsToNode::NoEscape) { 1.28 + PointsToNode::EscapeState es = ptnode_adr(n->_idx)->escape_state(); 1.29 + if (es == PointsToNode::NoEscape) { 1.30 has_non_escaping_obj = true; 1.31 if (n->is_Allocate()) { 1.32 find_init_values(n, &visited, igvn); 1.33 + // The object allocated by this Allocate node will never be 1.34 + // seen by an other thread. Mark it so that when it is 1.35 + // expanded no MemBarStoreStore is added. 1.36 + n->as_Allocate()->initialization()->set_does_not_escape(); 1.37 } 1.38 + } else if ((es == PointsToNode::ArgEscape) && n->is_Allocate()) { 1.39 + // Same as above. Mark this Allocate node so that when it is 1.40 + // expanded no MemBarStoreStore is added. 1.41 + n->as_Allocate()->initialization()->set_does_not_escape(); 1.42 } 1.43 } 1.44 1.45 @@ -1874,6 +1889,25 @@ 1.46 igvn->hash_delete(_pcmp_eq); 1.47 } 1.48 1.49 + // For MemBarStoreStore nodes added in library_call.cpp, check 1.50 + // escape status of associated AllocateNode and optimize out 1.51 + // MemBarStoreStore node if the allocated object never escapes. 1.52 + while (storestore_worklist.length() != 0) { 1.53 + Node *n = storestore_worklist.pop(); 1.54 + MemBarStoreStoreNode *storestore = n ->as_MemBarStoreStore(); 1.55 + Node *alloc = storestore->in(MemBarNode::Precedent)->in(0); 1.56 + assert (alloc->is_Allocate(), "storestore should point to AllocateNode"); 1.57 + PointsToNode::EscapeState es = ptnode_adr(alloc->_idx)->escape_state(); 1.58 + if (es == PointsToNode::NoEscape || es == PointsToNode::ArgEscape) { 1.59 + MemBarNode* mb = MemBarNode::make(C, Op_MemBarCPUOrder, Compile::AliasIdxBot); 1.60 + mb->init_req(TypeFunc::Memory, storestore->in(TypeFunc::Memory)); 1.61 + mb->init_req(TypeFunc::Control, storestore->in(TypeFunc::Control)); 1.62 + 1.63 + _igvn->register_new_node_with_optimizer(mb); 1.64 + _igvn->replace_node(storestore, mb); 1.65 + } 1.66 + } 1.67 + 1.68 #ifndef PRODUCT 1.69 if (PrintEscapeAnalysis) { 1.70 dump(); // Dump ConnectionGraph