1.1 --- a/src/share/vm/opto/callnode.cpp Fri Mar 14 15:26:33 2008 -0700 1.2 +++ b/src/share/vm/opto/callnode.cpp Fri Mar 14 16:40:42 2008 -0700 1.3 @@ -1364,7 +1364,7 @@ 1.4 //============================================================================= 1.5 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1.6 1.7 - // perform any generic optimizations first 1.8 + // perform any generic optimizations first (returns 'this' or NULL) 1.9 Node *result = SafePointNode::Ideal(phase, can_reshape); 1.10 1.11 // Now see if we can optimize away this lock. We don't actually 1.12 @@ -1372,7 +1372,20 @@ 1.13 // prevents macro expansion from expanding the lock. Since we don't 1.14 // modify the graph, the value returned from this function is the 1.15 // one computed above. 1.16 - if (EliminateLocks && !is_eliminated()) { 1.17 + if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) { 1.18 + // 1.19 + // If we are locking an unescaped object, the lock/unlock is unnecessary 1.20 + // 1.21 + ConnectionGraph *cgr = Compile::current()->congraph(); 1.22 + PointsToNode::EscapeState es = PointsToNode::GlobalEscape; 1.23 + if (cgr != NULL) 1.24 + es = cgr->escape_state(obj_node(), phase); 1.25 + if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) { 1.26 + // Mark it eliminated to update any counters 1.27 + this->set_eliminated(); 1.28 + return result; 1.29 + } 1.30 + 1.31 // 1.32 // Try lock coarsening 1.33 // 1.34 @@ -1412,8 +1425,10 @@ 1.35 int unlocks = 0; 1.36 for (int i = 0; i < lock_ops.length(); i++) { 1.37 AbstractLockNode* lock = lock_ops.at(i); 1.38 - if (lock->Opcode() == Op_Lock) locks++; 1.39 - else unlocks++; 1.40 + if (lock->Opcode() == Op_Lock) 1.41 + locks++; 1.42 + else 1.43 + unlocks++; 1.44 if (Verbose) { 1.45 lock->dump(1); 1.46 } 1.47 @@ -1450,7 +1465,7 @@ 1.48 //============================================================================= 1.49 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1.50 1.51 - // perform any generic optimizations first 1.52 + // perform any generic optimizations first (returns 'this' or NULL) 1.53 Node * result = SafePointNode::Ideal(phase, can_reshape); 1.54 1.55 // Now see if we can optimize away this unlock. We don't actually 1.56 @@ -1458,66 +1473,18 @@ 1.57 // prevents macro expansion from expanding the unlock. Since we don't 1.58 // modify the graph, the value returned from this function is the 1.59 // one computed above. 1.60 - if (EliminateLocks && !is_eliminated()) { 1.61 + // Escape state is defined after Parse phase. 1.62 + if (result == NULL && can_reshape && EliminateLocks && !is_eliminated()) { 1.63 // 1.64 - // If we are unlocking an unescaped object, the lock/unlock is unnecessary 1.65 - // We can eliminate them if there are no safepoints in the locked region. 1.66 + // If we are unlocking an unescaped object, the lock/unlock is unnecessary. 1.67 // 1.68 ConnectionGraph *cgr = Compile::current()->congraph(); 1.69 - if (cgr != NULL && cgr->escape_state(obj_node(), phase) == PointsToNode::NoEscape) { 1.70 - GrowableArray<AbstractLockNode*> lock_ops; 1.71 - LockNode *lock = find_matching_lock(this); 1.72 - if (lock != NULL) { 1.73 - lock_ops.append(this); 1.74 - lock_ops.append(lock); 1.75 - // find other unlocks which pair with the lock we found and add them 1.76 - // to the list 1.77 - Node * box = box_node(); 1.78 - 1.79 - for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) { 1.80 - Node *use = box->fast_out(i); 1.81 - if (use->is_Unlock() && use != this) { 1.82 - UnlockNode *unlock1 = use->as_Unlock(); 1.83 - if (!unlock1->is_eliminated()) { 1.84 - LockNode *lock1 = find_matching_lock(unlock1); 1.85 - if (lock == lock1) 1.86 - lock_ops.append(unlock1); 1.87 - else if (lock1 == NULL) { 1.88 - // we can't find a matching lock, we must assume the worst 1.89 - lock_ops.trunc_to(0); 1.90 - break; 1.91 - } 1.92 - } 1.93 - } 1.94 - } 1.95 - if (lock_ops.length() > 0) { 1.96 - 1.97 - #ifndef PRODUCT 1.98 - if (PrintEliminateLocks) { 1.99 - int locks = 0; 1.100 - int unlocks = 0; 1.101 - for (int i = 0; i < lock_ops.length(); i++) { 1.102 - AbstractLockNode* lock = lock_ops.at(i); 1.103 - if (lock->Opcode() == Op_Lock) locks++; 1.104 - else unlocks++; 1.105 - if (Verbose) { 1.106 - lock->dump(1); 1.107 - } 1.108 - } 1.109 - tty->print_cr("***Eliminated %d unescaped unlocks and %d unescaped locks", unlocks, locks); 1.110 - } 1.111 - #endif 1.112 - 1.113 - // for each of the identified locks, mark them 1.114 - // as eliminatable 1.115 - for (int i = 0; i < lock_ops.length(); i++) { 1.116 - AbstractLockNode* lock = lock_ops.at(i); 1.117 - 1.118 - // Mark it eliminated to update any counters 1.119 - lock->set_eliminated(); 1.120 - } 1.121 - } 1.122 - } 1.123 + PointsToNode::EscapeState es = PointsToNode::GlobalEscape; 1.124 + if (cgr != NULL) 1.125 + es = cgr->escape_state(obj_node(), phase); 1.126 + if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) { 1.127 + // Mark it eliminated to update any counters 1.128 + this->set_eliminated(); 1.129 } 1.130 } 1.131 return result;