src/share/vm/opto/callnode.cpp

changeset 3406
e9a5e0a812c8
parent 3311
1bd45abaa507
child 3407
35acf8f0a2e4
     1.1 --- a/src/share/vm/opto/callnode.cpp	Sat Jan 07 10:39:23 2012 -0800
     1.2 +++ b/src/share/vm/opto/callnode.cpp	Sat Jan 07 13:26:43 2012 -0800
     1.3 @@ -400,10 +400,10 @@
     1.4        Node *box = mcall->monitor_box(this, i);
     1.5        Node *obj = mcall->monitor_obj(this, i);
     1.6        if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
     1.7 -        while( !box->is_BoxLock() )  box = box->in(1);
     1.8 +        box = BoxLockNode::box_node(box);
     1.9          format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
    1.10        } else {
    1.11 -        OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
    1.12 +        OptoReg::Name box_reg = BoxLockNode::reg(box);
    1.13          st->print(" MON-BOX%d=%s+%d",
    1.14                     i,
    1.15                     OptoReg::regname(OptoReg::c_frame_pointer),
    1.16 @@ -411,8 +411,7 @@
    1.17        }
    1.18        const char* obj_msg = "MON-OBJ[";
    1.19        if (EliminateLocks) {
    1.20 -        while( !box->is_BoxLock() )  box = box->in(1);
    1.21 -        if (box->as_BoxLock()->is_eliminated())
    1.22 +        if (BoxLockNode::box_node(box)->is_eliminated())
    1.23            obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
    1.24        }
    1.25        format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
    1.26 @@ -1388,7 +1387,8 @@
    1.27      if (n != NULL && n->is_Unlock()) {
    1.28        UnlockNode *unlock = n->as_Unlock();
    1.29        if ((lock->obj_node() == unlock->obj_node()) &&
    1.30 -          (lock->box_node() == unlock->box_node()) && !unlock->is_eliminated()) {
    1.31 +          BoxLockNode::same_slot(lock->box_node(), unlock->box_node()) &&
    1.32 +          !unlock->is_eliminated()) {
    1.33          lock_ops.append(unlock);
    1.34          return true;
    1.35        }
    1.36 @@ -1432,7 +1432,7 @@
    1.37    if (ctrl->is_Lock()) {
    1.38      LockNode *lock = ctrl->as_Lock();
    1.39      if ((lock->obj_node() == unlock->obj_node()) &&
    1.40 -            (lock->box_node() == unlock->box_node())) {
    1.41 +        BoxLockNode::same_slot(lock->box_node(), unlock->box_node())) {
    1.42        lock_result = lock;
    1.43      }
    1.44    }
    1.45 @@ -1463,7 +1463,8 @@
    1.46        if (lock1_node != NULL && lock1_node->is_Lock()) {
    1.47          LockNode *lock1 = lock1_node->as_Lock();
    1.48          if ((lock->obj_node() == lock1->obj_node()) &&
    1.49 -            (lock->box_node() == lock1->box_node()) && !lock1->is_eliminated()) {
    1.50 +            BoxLockNode::same_slot(lock->box_node(), lock1->box_node()) &&
    1.51 +            !lock1->is_eliminated()) {
    1.52            lock_ops.append(lock1);
    1.53            return true;
    1.54          }
    1.55 @@ -1507,19 +1508,16 @@
    1.56  void AbstractLockNode::create_lock_counter(JVMState* state) {
    1.57    _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter);
    1.58  }
    1.59 -#endif
    1.60  
    1.61 -void AbstractLockNode::set_eliminated() {
    1.62 -  _eliminate = true;
    1.63 -#ifndef PRODUCT
    1.64 +void AbstractLockNode::set_eliminated_lock_counter() {
    1.65    if (_counter) {
    1.66      // Update the counter to indicate that this lock was eliminated.
    1.67      // The counter update code will stay around even though the
    1.68      // optimizer will eliminate the lock operation itself.
    1.69      _counter->set_tag(NamedCounter::EliminatedLockCounter);
    1.70    }
    1.71 +}
    1.72  #endif
    1.73 -}
    1.74  
    1.75  //=============================================================================
    1.76  Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
    1.77 @@ -1535,7 +1533,7 @@
    1.78    // prevents macro expansion from expanding the lock.  Since we don't
    1.79    // modify the graph, the value returned from this function is the
    1.80    // one computed above.
    1.81 -  if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
    1.82 +  if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
    1.83      //
    1.84      // If we are locking an unescaped object, the lock/unlock is unnecessary
    1.85      //
    1.86 @@ -1544,16 +1542,11 @@
    1.87      if (cgr != NULL)
    1.88        es = cgr->escape_state(obj_node());
    1.89      if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
    1.90 -      if (!is_eliminated()) {
    1.91 -        // Mark it eliminated to update any counters
    1.92 -        this->set_eliminated();
    1.93 -      } else {
    1.94 -        assert(is_coarsened(), "sanity");
    1.95 -        // The lock could be marked eliminated by lock coarsening
    1.96 -        // code during first IGVN before EA. Clear coarsened flag
    1.97 -        // to eliminate all associated locks/unlocks.
    1.98 -        this->clear_coarsened();
    1.99 -      }
   1.100 +      assert(!is_eliminated() || is_coarsened(), "sanity");
   1.101 +      // The lock could be marked eliminated by lock coarsening
   1.102 +      // code during first IGVN before EA. Replace coarsened flag
   1.103 +      // to eliminate all associated locks/unlocks.
   1.104 +      this->set_non_esc_obj();
   1.105        return result;
   1.106      }
   1.107  
   1.108 @@ -1613,8 +1606,7 @@
   1.109          for (int i = 0; i < lock_ops.length(); i++) {
   1.110            AbstractLockNode* lock = lock_ops.at(i);
   1.111  
   1.112 -          // Mark it eliminated to update any counters
   1.113 -          lock->set_eliminated();
   1.114 +          // Mark it eliminated by coarsening and update any counters
   1.115            lock->set_coarsened();
   1.116          }
   1.117        } else if (ctrl->is_Region() &&
   1.118 @@ -1632,6 +1624,41 @@
   1.119  }
   1.120  
   1.121  //=============================================================================
   1.122 +bool LockNode::is_nested_lock_region() {
   1.123 +  Node* box = box_node();
   1.124 +  if (!box->is_BoxLock() || box->as_BoxLock()->stack_slot() <= 0)
   1.125 +    return false; // External lock or it is not Box (Phi node).
   1.126 +
   1.127 +  // Ignore complex cases: merged locks or multiple locks.
   1.128 +  BoxLockNode* box_lock = box->as_BoxLock();
   1.129 +  Node* obj = obj_node();
   1.130 +  LockNode* unique_lock = NULL;
   1.131 +  if (!box_lock->is_simple_lock_region(&unique_lock, obj) ||
   1.132 +      (unique_lock != this)) {
   1.133 +    return false;
   1.134 +  }
   1.135 +
   1.136 +  // Look for external lock for the same object.
   1.137 +  int stk_slot = box_lock->stack_slot();
   1.138 +  SafePointNode* sfn = this->as_SafePoint();
   1.139 +  JVMState* youngest_jvms = sfn->jvms();
   1.140 +  int max_depth = youngest_jvms->depth();
   1.141 +  for (int depth = 1; depth <= max_depth; depth++) {
   1.142 +    JVMState* jvms = youngest_jvms->of_depth(depth);
   1.143 +    int num_mon  = jvms->nof_monitors();
   1.144 +    // Loop over monitors
   1.145 +    for (int idx = 0; idx < num_mon; idx++) {
   1.146 +      Node* obj_node = sfn->monitor_obj(jvms, idx);
   1.147 +      BoxLockNode* box_node = BoxLockNode::box_node(sfn->monitor_box(jvms, idx));
   1.148 +      if ((obj_node == obj) && (box_node->stack_slot() < stk_slot)) {
   1.149 +        return true;
   1.150 +      }
   1.151 +    }
   1.152 +  }
   1.153 +  return false;
   1.154 +}
   1.155 +
   1.156 +//=============================================================================
   1.157  uint UnlockNode::size_of() const { return sizeof(*this); }
   1.158  
   1.159  //=============================================================================
   1.160 @@ -1649,7 +1676,7 @@
   1.161    // modify the graph, the value returned from this function is the
   1.162    // one computed above.
   1.163    // Escape state is defined after Parse phase.
   1.164 -  if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
   1.165 +  if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
   1.166      //
   1.167      // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
   1.168      //
   1.169 @@ -1658,16 +1685,11 @@
   1.170      if (cgr != NULL)
   1.171        es = cgr->escape_state(obj_node());
   1.172      if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
   1.173 -      if (!is_eliminated()) {
   1.174 -        // Mark it eliminated to update any counters
   1.175 -        this->set_eliminated();
   1.176 -      } else {
   1.177 -        assert(is_coarsened(), "sanity");
   1.178 -        // The lock could be marked eliminated by lock coarsening
   1.179 -        // code during first IGVN before EA. Clear coarsened flag
   1.180 -        // to eliminate all associated locks/unlocks.
   1.181 -        this->clear_coarsened();
   1.182 -      }
   1.183 +      assert(!is_eliminated() || is_coarsened(), "sanity");
   1.184 +      // The lock could be marked eliminated by lock coarsening
   1.185 +      // code during first IGVN before EA. Replace coarsened flag
   1.186 +      // to eliminate all associated locks/unlocks.
   1.187 +      this->set_non_esc_obj();
   1.188      }
   1.189    }
   1.190    return result;

mercurial