# HG changeset patch # User kvn # Date 1326493274 28800 # Node ID e504fd26c073a03ae07e832a9f1734a56d6a5ade # Parent 5acd82522540dd4c8bd702824775bec6478593dc# Parent 89d0a5d40008dca192dbcf5e30a4de398b725b8e Merge diff -r 5acd82522540 -r e504fd26c073 src/share/vm/opto/callnode.cpp --- a/src/share/vm/opto/callnode.cpp Fri Jan 13 06:18:47 2012 -0800 +++ b/src/share/vm/opto/callnode.cpp Fri Jan 13 14:21:14 2012 -0800 @@ -1625,21 +1625,20 @@ //============================================================================= bool LockNode::is_nested_lock_region() { - Node* box = box_node(); - if (!box->is_BoxLock() || box->as_BoxLock()->stack_slot() <= 0) + BoxLockNode* box = box_node()->as_BoxLock(); + int stk_slot = box->stack_slot(); + if (stk_slot <= 0) return false; // External lock or it is not Box (Phi node). // Ignore complex cases: merged locks or multiple locks. - BoxLockNode* box_lock = box->as_BoxLock(); Node* obj = obj_node(); LockNode* unique_lock = NULL; - if (!box_lock->is_simple_lock_region(&unique_lock, obj) || + if (!box->is_simple_lock_region(&unique_lock, obj) || (unique_lock != this)) { return false; } // Look for external lock for the same object. - int stk_slot = box_lock->stack_slot(); SafePointNode* sfn = this->as_SafePoint(); JVMState* youngest_jvms = sfn->jvms(); int max_depth = youngest_jvms->depth(); @@ -1649,7 +1648,7 @@ // Loop over monitors for (int idx = 0; idx < num_mon; idx++) { Node* obj_node = sfn->monitor_obj(jvms, idx); - BoxLockNode* box_node = BoxLockNode::box_node(sfn->monitor_box(jvms, idx)); + BoxLockNode* box_node = sfn->monitor_box(jvms, idx)->as_BoxLock(); if ((box_node->stack_slot() < stk_slot) && obj_node->eqv_uncast(obj)) { return true; } diff -r 5acd82522540 -r e504fd26c073 src/share/vm/opto/locknode.cpp --- a/src/share/vm/opto/locknode.cpp Fri Jan 13 06:18:47 2012 -0800 +++ b/src/share/vm/opto/locknode.cpp Fri Jan 13 14:21:14 2012 -0800 @@ -63,7 +63,7 @@ } BoxLockNode* BoxLockNode::box_node(Node* box) { - // Chase down the BoxNode + // Chase down the BoxNode after RA which may spill box nodes. while (!box->is_BoxLock()) { // if (box_node->is_SpillCopy()) { // Node *m = box_node->in(1); @@ -84,18 +84,13 @@ return box_node(box)->in_RegMask(0).find_first_elem(); } -bool BoxLockNode::same_slot(Node* box1, Node* box2) { - return box_node(box1)->_slot == box_node(box2)->_slot; -} - // Is BoxLock node used for one simple lock region (same box and obj)? bool BoxLockNode::is_simple_lock_region(LockNode** unique_lock, Node* obj) { LockNode* lock = NULL; bool has_one_lock = false; for (uint i = 0; i < this->outcnt(); i++) { Node* n = this->raw_out(i); - if (n->is_Phi()) - return false; // Merged regions + assert(!n->is_Phi(), "should not merge BoxLock nodes"); if (n->is_AbstractLock()) { AbstractLockNode* alock = n->as_AbstractLock(); // Check lock's box since box could be referenced by Lock's debug info. @@ -123,23 +118,12 @@ FastLockNode* flock = n->as_FastLock(); assert((flock->box_node() == this) && flock->obj_node()->eqv_uncast(obj),""); } - if (n->is_SafePoint() && n->as_SafePoint()->jvms()) { - SafePointNode* sfn = n->as_SafePoint(); - JVMState* youngest_jvms = sfn->jvms(); - int max_depth = youngest_jvms->depth(); - for (int depth = 1; depth <= max_depth; depth++) { - JVMState* jvms = youngest_jvms->of_depth(depth); - int num_mon = jvms->nof_monitors(); - // Loop over monitors - for (int idx = 0; idx < num_mon; idx++) { - Node* obj_node = sfn->monitor_obj(jvms, idx); - Node* box_node = sfn->monitor_box(jvms, idx); - if (box_node == this) { - assert(obj_node->eqv_uncast(obj),""); - } - } - } - } + // Don't check monitor info in safepoints since the referenced object could + // be different from the locked object. It could be Phi node of different + // cast nodes which point to this locked object. + // We assume that no other objects could be referenced in monitor info + // associated with this BoxLock node because all associated locks and + // unlocks are reference only this one object. } #endif if (unique_lock != NULL && has_one_lock) { diff -r 5acd82522540 -r e504fd26c073 src/share/vm/opto/locknode.hpp --- a/src/share/vm/opto/locknode.hpp Fri Jan 13 06:18:47 2012 -0800 +++ b/src/share/vm/opto/locknode.hpp Fri Jan 13 14:21:14 2012 -0800 @@ -49,9 +49,9 @@ //------------------------------BoxLockNode------------------------------------ class BoxLockNode : public Node { - const int _slot; - RegMask _inmask; - bool _is_eliminated; // indicates this lock was safely eliminated + const int _slot; // stack slot + RegMask _inmask; // OptoReg corresponding to stack slot + bool _is_eliminated; // Associated locks were safely eliminated public: BoxLockNode( int lock ); @@ -68,7 +68,9 @@ static OptoReg::Name reg(Node* box_node); static BoxLockNode* box_node(Node* box_node); - static bool same_slot(Node* box1, Node* box2); + static bool same_slot(Node* box1, Node* box2) { + return box1->as_BoxLock()->_slot == box2->as_BoxLock()->_slot; + } int stack_slot() const { return _slot; } bool is_eliminated() const { return _is_eliminated; } diff -r 5acd82522540 -r e504fd26c073 src/share/vm/opto/macro.cpp --- a/src/share/vm/opto/macro.cpp Fri Jan 13 06:18:47 2012 -0800 +++ b/src/share/vm/opto/macro.cpp Fri Jan 13 14:21:14 2012 -0800 @@ -1802,10 +1802,14 @@ // Mark all associated (same box and obj) lock and unlock nodes for // elimination if some of them marked already. void PhaseMacroExpand::mark_eliminated_box(Node* oldbox, Node* obj) { - if (oldbox->is_BoxLock() && oldbox->as_BoxLock()->is_eliminated()) - return; + if (oldbox->as_BoxLock()->is_eliminated()) + return; // This BoxLock node was processed already. - if (oldbox->is_BoxLock() && + // New implementation (EliminateNestedLocks) has separate BoxLock + // node for each locked region so mark all associated locks/unlocks as + // eliminated even if different objects are referenced in one locked region + // (for example, OSR compilation of nested loop inside locked scope). + if (EliminateNestedLocks || oldbox->as_BoxLock()->is_simple_lock_region(NULL, obj)) { // Box is used only in one lock region. Mark this box as eliminated. _igvn.hash_delete(oldbox); @@ -1818,7 +1822,6 @@ AbstractLockNode* alock = u->as_AbstractLock(); // Check lock's box since box could be referenced by Lock's debug info. if (alock->box_node() == oldbox) { - assert(alock->obj_node()->eqv_uncast(obj), ""); // Mark eliminated all related locks and unlocks. alock->set_non_esc_obj(); } @@ -1829,8 +1832,7 @@ // Create new "eliminated" BoxLock node and use it in monitor debug info // instead of oldbox for the same object. - BoxLockNode* box = BoxLockNode::box_node(oldbox); - BoxLockNode* newbox = box->clone()->as_BoxLock(); + BoxLockNode* newbox = oldbox->clone()->as_BoxLock(); // Note: BoxLock node is marked eliminated only here and it is used // to indicate that all associated lock and unlock nodes are marked @@ -2047,7 +2049,7 @@ Node* box = lock->box_node(); Node* flock = lock->fastlock_node(); - assert(!BoxLockNode::box_node(box)->is_eliminated(), "sanity"); + assert(!box->as_BoxLock()->is_eliminated(), "sanity"); // Make the merge point Node *region; @@ -2283,7 +2285,7 @@ Node* obj = unlock->obj_node(); Node* box = unlock->box_node(); - assert(!BoxLockNode::box_node(box)->is_eliminated(), "sanity"); + assert(!box->as_BoxLock()->is_eliminated(), "sanity"); // No need for a null check on unlock diff -r 5acd82522540 -r e504fd26c073 src/share/vm/opto/parse1.cpp --- a/src/share/vm/opto/parse1.cpp Fri Jan 13 06:18:47 2012 -0800 +++ b/src/share/vm/opto/parse1.cpp Fri Jan 13 14:21:14 2012 -0800 @@ -1604,7 +1604,16 @@ continue; default: // All normal stuff if (phi == NULL) { - if (!check_elide_phi || !target->can_elide_SEL_phi(j)) { + const JVMState* jvms = map()->jvms(); + if (EliminateNestedLocks && + jvms->is_mon(j) && jvms->is_monitor_box(j)) { + // BoxLock nodes are not commoning. + // Use old BoxLock node as merged box. + assert(newin->jvms()->is_monitor_box(j), "sanity"); + // This assert also tests that nodes are BoxLock. + assert(BoxLockNode::same_slot(n, m), "sanity"); + C->gvn_replace_by(n, m); + } else if (!check_elide_phi || !target->can_elide_SEL_phi(j)) { phi = ensure_phi(j, nophi); } } @@ -1819,12 +1828,8 @@ } else if (jvms->is_stk(idx)) { t = block()->stack_type_at(idx - jvms->stkoff()); } else if (jvms->is_mon(idx)) { - if (EliminateNestedLocks && jvms->is_monitor_box(idx)) { - // BoxLock nodes are not commoning. Create Phi. - t = o->bottom_type(); // TypeRawPtr::BOTTOM - } else { - t = TypeInstPtr::BOTTOM; // this is sufficient for a lock object - } + assert(!jvms->is_monitor_box(idx), "no phis for boxes"); + t = TypeInstPtr::BOTTOM; // this is sufficient for a lock object } else if ((uint)idx < TypeFunc::Parms) { t = o->bottom_type(); // Type::RETURN_ADDRESS or such-like. } else {