1.1 --- a/src/share/vm/opto/macro.cpp Fri Jun 03 22:31:43 2011 -0700 1.2 +++ b/src/share/vm/opto/macro.cpp Sat Jun 04 10:36:22 2011 -0700 1.3 @@ -1693,25 +1693,31 @@ 1.4 OptoRuntime::new_array_Java()); 1.5 } 1.6 1.7 - 1.8 -// we have determined that this lock/unlock can be eliminated, we simply 1.9 -// eliminate the node without expanding it. 1.10 -// 1.11 -// Note: The membar's associated with the lock/unlock are currently not 1.12 -// eliminated. This should be investigated as a future enhancement. 1.13 -// 1.14 -bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { 1.15 - 1.16 +//-----------------------mark_eliminated_locking_nodes----------------------- 1.17 +// During EA obj may point to several objects but after few ideal graph 1.18 +// transformations (CCP) it may point to only one non escaping object 1.19 +// (but still using phi), corresponding locks and unlocks will be marked 1.20 +// for elimination. Later obj could be replaced with a new node (new phi) 1.21 +// and which does not have escape information. And later after some graph 1.22 +// reshape other locks and unlocks (which were not marked for elimination 1.23 +// before) are connected to this new obj (phi) but they still will not be 1.24 +// marked for elimination since new obj has no escape information. 1.25 +// Mark all associated (same box and obj) lock and unlock nodes for 1.26 +// elimination if some of them marked already. 1.27 +void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) { 1.28 if (!alock->is_eliminated()) { 1.29 - return false; 1.30 + return; 1.31 } 1.32 - if (alock->is_Lock() && !alock->is_coarsened()) { 1.33 + if (!alock->is_coarsened()) { // Eliminated by EA 1.34 // Create new "eliminated" BoxLock node and use it 1.35 // in monitor debug info for the same object. 1.36 BoxLockNode* oldbox = alock->box_node()->as_BoxLock(); 1.37 Node* obj = alock->obj_node(); 1.38 if (!oldbox->is_eliminated()) { 1.39 BoxLockNode* newbox = oldbox->clone()->as_BoxLock(); 1.40 + // Note: BoxLock node is marked eliminated only here 1.41 + // and it is used to indicate that all associated lock 1.42 + // and unlock nodes are marked for elimination. 1.43 newbox->set_eliminated(); 1.44 transform_later(newbox); 1.45 // Replace old box node with new box for all users 1.46 @@ -1720,22 +1726,14 @@ 1.47 1.48 bool next_edge = true; 1.49 Node* u = oldbox->raw_out(i); 1.50 - if (u == alock) { 1.51 - i++; 1.52 - continue; // It will be removed below 1.53 - } 1.54 - if (u->is_Lock() && 1.55 - u->as_Lock()->obj_node() == obj && 1.56 - // oldbox could be referenced in debug info also 1.57 - u->as_Lock()->box_node() == oldbox) { 1.58 - assert(u->as_Lock()->is_eliminated(), "sanity"); 1.59 + if (u->is_AbstractLock() && 1.60 + u->as_AbstractLock()->obj_node() == obj && 1.61 + u->as_AbstractLock()->box_node() == oldbox) { 1.62 + // Mark all associated locks and unlocks. 1.63 + u->as_AbstractLock()->set_eliminated(); 1.64 _igvn.hash_delete(u); 1.65 u->set_req(TypeFunc::Parms + 1, newbox); 1.66 next_edge = false; 1.67 -#ifdef ASSERT 1.68 - } else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) { 1.69 - assert(u->as_Unlock()->is_eliminated(), "sanity"); 1.70 -#endif 1.71 } 1.72 // Replace old box in monitor debug info. 1.73 if (u->is_SafePoint() && u->as_SafePoint()->jvms()) { 1.74 @@ -1761,8 +1759,27 @@ 1.75 if (next_edge) i++; 1.76 } // for (uint i = 0; i < oldbox->outcnt();) 1.77 } // if (!oldbox->is_eliminated()) 1.78 - } // if (alock->is_Lock() && !lock->is_coarsened()) 1.79 + } // if (!alock->is_coarsened()) 1.80 +} 1.81 1.82 +// we have determined that this lock/unlock can be eliminated, we simply 1.83 +// eliminate the node without expanding it. 1.84 +// 1.85 +// Note: The membar's associated with the lock/unlock are currently not 1.86 +// eliminated. This should be investigated as a future enhancement. 1.87 +// 1.88 +bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { 1.89 + 1.90 + if (!alock->is_eliminated()) { 1.91 + return false; 1.92 + } 1.93 +#ifdef ASSERT 1.94 + if (alock->is_Lock() && !alock->is_coarsened()) { 1.95 + // Check that new "eliminated" BoxLock node is created. 1.96 + BoxLockNode* oldbox = alock->box_node()->as_BoxLock(); 1.97 + assert(oldbox->is_eliminated(), "should be done already"); 1.98 + } 1.99 +#endif 1.100 CompileLog* log = C->log(); 1.101 if (log != NULL) { 1.102 log->head("eliminate_lock lock='%d'", 1.103 @@ -2145,6 +2162,15 @@ 1.104 if (C->macro_count() == 0) 1.105 return false; 1.106 // First, attempt to eliminate locks 1.107 + int cnt = C->macro_count(); 1.108 + for (int i=0; i < cnt; i++) { 1.109 + Node *n = C->macro_node(i); 1.110 + if (n->is_AbstractLock()) { // Lock and Unlock nodes 1.111 + // Before elimination mark all associated (same box and obj) 1.112 + // lock and unlock nodes. 1.113 + mark_eliminated_locking_nodes(n->as_AbstractLock()); 1.114 + } 1.115 + } 1.116 bool progress = true; 1.117 while (progress) { 1.118 progress = false;