src/share/vm/opto/callnode.cpp

changeset 501
6dbf1a175d6b
parent 500
99269dbf4ba8
child 509
2a9af0b9cb1c
     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;

mercurial