hotspot/src/share/vm/opto/callnode.cpp
changeset 11445 3c768dca60f5
parent 11191 d54ab5dcba83
child 11446 fd87432a895b
equal deleted inserted replaced
11444:8a2619fd3fca 11445:3c768dca60f5
   398     }
   398     }
   399     for (i = 0; (int)i < nof_monitors(); i++) {
   399     for (i = 0; (int)i < nof_monitors(); i++) {
   400       Node *box = mcall->monitor_box(this, i);
   400       Node *box = mcall->monitor_box(this, i);
   401       Node *obj = mcall->monitor_obj(this, i);
   401       Node *obj = mcall->monitor_obj(this, i);
   402       if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
   402       if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
   403         while( !box->is_BoxLock() )  box = box->in(1);
   403         box = BoxLockNode::box_node(box);
   404         format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
   404         format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
   405       } else {
   405       } else {
   406         OptoReg::Name box_reg = BoxLockNode::stack_slot(box);
   406         OptoReg::Name box_reg = BoxLockNode::reg(box);
   407         st->print(" MON-BOX%d=%s+%d",
   407         st->print(" MON-BOX%d=%s+%d",
   408                    i,
   408                    i,
   409                    OptoReg::regname(OptoReg::c_frame_pointer),
   409                    OptoReg::regname(OptoReg::c_frame_pointer),
   410                    regalloc->reg2offset(box_reg));
   410                    regalloc->reg2offset(box_reg));
   411       }
   411       }
   412       const char* obj_msg = "MON-OBJ[";
   412       const char* obj_msg = "MON-OBJ[";
   413       if (EliminateLocks) {
   413       if (EliminateLocks) {
   414         while( !box->is_BoxLock() )  box = box->in(1);
   414         if (BoxLockNode::box_node(box)->is_eliminated())
   415         if (box->as_BoxLock()->is_eliminated())
       
   416           obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
   415           obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
   417       }
   416       }
   418       format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
   417       format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
   419     }
   418     }
   420 
   419 
  1386   if (ctrl_proj != NULL && ctrl_proj->_con == TypeFunc::Control) {
  1385   if (ctrl_proj != NULL && ctrl_proj->_con == TypeFunc::Control) {
  1387     Node *n = ctrl_proj->in(0);
  1386     Node *n = ctrl_proj->in(0);
  1388     if (n != NULL && n->is_Unlock()) {
  1387     if (n != NULL && n->is_Unlock()) {
  1389       UnlockNode *unlock = n->as_Unlock();
  1388       UnlockNode *unlock = n->as_Unlock();
  1390       if ((lock->obj_node() == unlock->obj_node()) &&
  1389       if ((lock->obj_node() == unlock->obj_node()) &&
  1391           (lock->box_node() == unlock->box_node()) && !unlock->is_eliminated()) {
  1390           BoxLockNode::same_slot(lock->box_node(), unlock->box_node()) &&
       
  1391           !unlock->is_eliminated()) {
  1392         lock_ops.append(unlock);
  1392         lock_ops.append(unlock);
  1393         return true;
  1393         return true;
  1394       }
  1394       }
  1395     }
  1395     }
  1396   }
  1396   }
  1430     }
  1430     }
  1431   }
  1431   }
  1432   if (ctrl->is_Lock()) {
  1432   if (ctrl->is_Lock()) {
  1433     LockNode *lock = ctrl->as_Lock();
  1433     LockNode *lock = ctrl->as_Lock();
  1434     if ((lock->obj_node() == unlock->obj_node()) &&
  1434     if ((lock->obj_node() == unlock->obj_node()) &&
  1435             (lock->box_node() == unlock->box_node())) {
  1435         BoxLockNode::same_slot(lock->box_node(), unlock->box_node())) {
  1436       lock_result = lock;
  1436       lock_result = lock;
  1437     }
  1437     }
  1438   }
  1438   }
  1439   return lock_result;
  1439   return lock_result;
  1440 }
  1440 }
  1461         }
  1461         }
  1462       }
  1462       }
  1463       if (lock1_node != NULL && lock1_node->is_Lock()) {
  1463       if (lock1_node != NULL && lock1_node->is_Lock()) {
  1464         LockNode *lock1 = lock1_node->as_Lock();
  1464         LockNode *lock1 = lock1_node->as_Lock();
  1465         if ((lock->obj_node() == lock1->obj_node()) &&
  1465         if ((lock->obj_node() == lock1->obj_node()) &&
  1466             (lock->box_node() == lock1->box_node()) && !lock1->is_eliminated()) {
  1466             BoxLockNode::same_slot(lock->box_node(), lock1->box_node()) &&
       
  1467             !lock1->is_eliminated()) {
  1467           lock_ops.append(lock1);
  1468           lock_ops.append(lock1);
  1468           return true;
  1469           return true;
  1469         }
  1470         }
  1470       }
  1471       }
  1471     }
  1472     }
  1505 // Create a counter which counts the number of times this lock is acquired
  1506 // Create a counter which counts the number of times this lock is acquired
  1506 //
  1507 //
  1507 void AbstractLockNode::create_lock_counter(JVMState* state) {
  1508 void AbstractLockNode::create_lock_counter(JVMState* state) {
  1508   _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter);
  1509   _counter = OptoRuntime::new_named_counter(state, NamedCounter::LockCounter);
  1509 }
  1510 }
  1510 #endif
  1511 
  1511 
  1512 void AbstractLockNode::set_eliminated_lock_counter() {
  1512 void AbstractLockNode::set_eliminated() {
       
  1513   _eliminate = true;
       
  1514 #ifndef PRODUCT
       
  1515   if (_counter) {
  1513   if (_counter) {
  1516     // Update the counter to indicate that this lock was eliminated.
  1514     // Update the counter to indicate that this lock was eliminated.
  1517     // The counter update code will stay around even though the
  1515     // The counter update code will stay around even though the
  1518     // optimizer will eliminate the lock operation itself.
  1516     // optimizer will eliminate the lock operation itself.
  1519     _counter->set_tag(NamedCounter::EliminatedLockCounter);
  1517     _counter->set_tag(NamedCounter::EliminatedLockCounter);
  1520   }
  1518   }
       
  1519 }
  1521 #endif
  1520 #endif
  1522 }
       
  1523 
  1521 
  1524 //=============================================================================
  1522 //=============================================================================
  1525 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  1523 Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  1526 
  1524 
  1527   // perform any generic optimizations first (returns 'this' or NULL)
  1525   // perform any generic optimizations first (returns 'this' or NULL)
  1533   // Now see if we can optimize away this lock.  We don't actually
  1531   // Now see if we can optimize away this lock.  We don't actually
  1534   // remove the locking here, we simply set the _eliminate flag which
  1532   // remove the locking here, we simply set the _eliminate flag which
  1535   // prevents macro expansion from expanding the lock.  Since we don't
  1533   // prevents macro expansion from expanding the lock.  Since we don't
  1536   // modify the graph, the value returned from this function is the
  1534   // modify the graph, the value returned from this function is the
  1537   // one computed above.
  1535   // one computed above.
  1538   if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
  1536   if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
  1539     //
  1537     //
  1540     // If we are locking an unescaped object, the lock/unlock is unnecessary
  1538     // If we are locking an unescaped object, the lock/unlock is unnecessary
  1541     //
  1539     //
  1542     ConnectionGraph *cgr = phase->C->congraph();
  1540     ConnectionGraph *cgr = phase->C->congraph();
  1543     PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
  1541     PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
  1544     if (cgr != NULL)
  1542     if (cgr != NULL)
  1545       es = cgr->escape_state(obj_node());
  1543       es = cgr->escape_state(obj_node());
  1546     if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
  1544     if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
  1547       if (!is_eliminated()) {
  1545       assert(!is_eliminated() || is_coarsened(), "sanity");
  1548         // Mark it eliminated to update any counters
  1546       // The lock could be marked eliminated by lock coarsening
  1549         this->set_eliminated();
  1547       // code during first IGVN before EA. Replace coarsened flag
  1550       } else {
  1548       // to eliminate all associated locks/unlocks.
  1551         assert(is_coarsened(), "sanity");
  1549       this->set_non_esc_obj();
  1552         // The lock could be marked eliminated by lock coarsening
       
  1553         // code during first IGVN before EA. Clear coarsened flag
       
  1554         // to eliminate all associated locks/unlocks.
       
  1555         this->clear_coarsened();
       
  1556       }
       
  1557       return result;
  1550       return result;
  1558     }
  1551     }
  1559 
  1552 
  1560     //
  1553     //
  1561     // Try lock coarsening
  1554     // Try lock coarsening
  1611         // for each of the identified locks, mark them
  1604         // for each of the identified locks, mark them
  1612         // as eliminatable
  1605         // as eliminatable
  1613         for (int i = 0; i < lock_ops.length(); i++) {
  1606         for (int i = 0; i < lock_ops.length(); i++) {
  1614           AbstractLockNode* lock = lock_ops.at(i);
  1607           AbstractLockNode* lock = lock_ops.at(i);
  1615 
  1608 
  1616           // Mark it eliminated to update any counters
  1609           // Mark it eliminated by coarsening and update any counters
  1617           lock->set_eliminated();
       
  1618           lock->set_coarsened();
  1610           lock->set_coarsened();
  1619         }
  1611         }
  1620       } else if (ctrl->is_Region() &&
  1612       } else if (ctrl->is_Region() &&
  1621                  iter->_worklist.member(ctrl)) {
  1613                  iter->_worklist.member(ctrl)) {
  1622         // We weren't able to find any opportunities but the region this
  1614         // We weren't able to find any opportunities but the region this
  1630 
  1622 
  1631   return result;
  1623   return result;
  1632 }
  1624 }
  1633 
  1625 
  1634 //=============================================================================
  1626 //=============================================================================
       
  1627 bool LockNode::is_nested_lock_region() {
       
  1628   Node* box = box_node();
       
  1629   if (!box->is_BoxLock() || box->as_BoxLock()->stack_slot() <= 0)
       
  1630     return false; // External lock or it is not Box (Phi node).
       
  1631 
       
  1632   // Ignore complex cases: merged locks or multiple locks.
       
  1633   BoxLockNode* box_lock = box->as_BoxLock();
       
  1634   Node* obj = obj_node();
       
  1635   LockNode* unique_lock = NULL;
       
  1636   if (!box_lock->is_simple_lock_region(&unique_lock, obj) ||
       
  1637       (unique_lock != this)) {
       
  1638     return false;
       
  1639   }
       
  1640 
       
  1641   // Look for external lock for the same object.
       
  1642   int stk_slot = box_lock->stack_slot();
       
  1643   SafePointNode* sfn = this->as_SafePoint();
       
  1644   JVMState* youngest_jvms = sfn->jvms();
       
  1645   int max_depth = youngest_jvms->depth();
       
  1646   for (int depth = 1; depth <= max_depth; depth++) {
       
  1647     JVMState* jvms = youngest_jvms->of_depth(depth);
       
  1648     int num_mon  = jvms->nof_monitors();
       
  1649     // Loop over monitors
       
  1650     for (int idx = 0; idx < num_mon; idx++) {
       
  1651       Node* obj_node = sfn->monitor_obj(jvms, idx);
       
  1652       BoxLockNode* box_node = BoxLockNode::box_node(sfn->monitor_box(jvms, idx));
       
  1653       if ((obj_node == obj) && (box_node->stack_slot() < stk_slot)) {
       
  1654         return true;
       
  1655       }
       
  1656     }
       
  1657   }
       
  1658   return false;
       
  1659 }
       
  1660 
       
  1661 //=============================================================================
  1635 uint UnlockNode::size_of() const { return sizeof(*this); }
  1662 uint UnlockNode::size_of() const { return sizeof(*this); }
  1636 
  1663 
  1637 //=============================================================================
  1664 //=============================================================================
  1638 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  1665 Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  1639 
  1666 
  1647   // remove the unlocking here, we simply set the _eliminate flag which
  1674   // remove the unlocking here, we simply set the _eliminate flag which
  1648   // prevents macro expansion from expanding the unlock.  Since we don't
  1675   // prevents macro expansion from expanding the unlock.  Since we don't
  1649   // modify the graph, the value returned from this function is the
  1676   // modify the graph, the value returned from this function is the
  1650   // one computed above.
  1677   // one computed above.
  1651   // Escape state is defined after Parse phase.
  1678   // Escape state is defined after Parse phase.
  1652   if (can_reshape && EliminateLocks && (!is_eliminated() || is_coarsened())) {
  1679   if (can_reshape && EliminateLocks && !is_non_esc_obj()) {
  1653     //
  1680     //
  1654     // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
  1681     // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
  1655     //
  1682     //
  1656     ConnectionGraph *cgr = phase->C->congraph();
  1683     ConnectionGraph *cgr = phase->C->congraph();
  1657     PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
  1684     PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
  1658     if (cgr != NULL)
  1685     if (cgr != NULL)
  1659       es = cgr->escape_state(obj_node());
  1686       es = cgr->escape_state(obj_node());
  1660     if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
  1687     if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
  1661       if (!is_eliminated()) {
  1688       assert(!is_eliminated() || is_coarsened(), "sanity");
  1662         // Mark it eliminated to update any counters
  1689       // The lock could be marked eliminated by lock coarsening
  1663         this->set_eliminated();
  1690       // code during first IGVN before EA. Replace coarsened flag
  1664       } else {
  1691       // to eliminate all associated locks/unlocks.
  1665         assert(is_coarsened(), "sanity");
  1692       this->set_non_esc_obj();
  1666         // The lock could be marked eliminated by lock coarsening
       
  1667         // code during first IGVN before EA. Clear coarsened flag
       
  1668         // to eliminate all associated locks/unlocks.
       
  1669         this->clear_coarsened();
       
  1670       }
       
  1671     }
  1693     }
  1672   }
  1694   }
  1673   return result;
  1695   return result;
  1674 }
  1696 }