src/share/vm/opto/callnode.cpp

changeset 3406
e9a5e0a812c8
parent 3311
1bd45abaa507
child 3407
35acf8f0a2e4
equal deleted inserted replaced
3405:5da7201222d5 3406:e9a5e0a812c8
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 }

mercurial