changeset 3286:e504fd26c073

Merge
author kvn
date Fri, 13 Jan 2012 14:21:14 -0800
parents 5acd82522540 89d0a5d40008
children 513351373923
files
diffstat 5 files changed, 41 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- 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;
       }
--- 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) {
--- 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; }
--- 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
 
--- 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 {