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 } |
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 } |