Merge
diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
index efa25e3..050823d 100644
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
@@ -676,21 +676,6 @@
 }
 
 
-void GraphBuilder::kill_field(ciField* field) {
-  if (UseLocalValueNumbering) {
-    vmap()->kill_field(field);
-  }
-}
-
-
-void GraphBuilder::kill_array(Value value) {
-  if (UseLocalValueNumbering) {
-    vmap()->kill_array(value->type());
-  }
-  _memory->store_value(value);
-}
-
-
 void GraphBuilder::kill_all() {
   if (UseLocalValueNumbering) {
     vmap()->kill_all();
@@ -987,8 +972,8 @@
     length = append(new ArrayLength(array, lock_stack()));
   }
   StoreIndexed* result = new StoreIndexed(array, index, length, type, value, lock_stack());
-  kill_array(value); // invalidate all CSEs that are memory accesses of the same type
   append(result);
+  _memory->store_value(value);
 }
 
 
@@ -1478,9 +1463,6 @@
     case Bytecodes::_putstatic:
       { Value val = pop(type);
         append(new StoreField(append(obj), offset, field, val, true, lock_stack(), state_copy, is_loaded, is_initialized));
-        if (UseLocalValueNumbering) {
-          vmap()->kill_field(field);   // invalidate all CSEs that are memory accesses
-        }
       }
       break;
     case Bytecodes::_getfield :
@@ -1503,7 +1485,6 @@
         if (is_loaded) store = _memory->store(store);
         if (store != NULL) {
           append(store);
-          kill_field(field);   // invalidate all CSEs that are accesses of this field
         }
       }
       break;
@@ -1900,6 +1881,8 @@
       assert(i2->bci() != -1, "should already be linked");
       return i2;
     }
+    ValueNumberingEffects vne(vmap());
+    i1->visit(&vne);
   }
 
   if (i1->as_Phi() == NULL && i1->as_Local() == NULL) {
@@ -1926,14 +1909,8 @@
     assert(_last == i1, "adjust code below");
     StateSplit* s = i1->as_StateSplit();
     if (s != NULL && i1->as_BlockEnd() == NULL) {
-      // Continue CSE across certain intrinsics
-      Intrinsic* intrinsic = s->as_Intrinsic();
-      if (UseLocalValueNumbering) {
-        if (intrinsic == NULL || !intrinsic->preserves_state()) {
-          vmap()->kill_all();      // for now, hopefully we need this only for calls eventually
-          }
-      }
       if (EliminateFieldAccess) {
+        Intrinsic* intrinsic = s->as_Intrinsic();
         if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) {
           _memory->kill();
         }
diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp
index 4678674..7f185ef 100644
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp
@@ -283,8 +283,6 @@
   Dependencies* dependency_recorder() const; // = compilation()->dependencies()
   bool direct_compare(ciKlass* k);
 
-  void kill_field(ciField* field);
-  void kill_array(Value value);
   void kill_all();
 
   ValueStack* lock_stack();
diff --git a/hotspot/src/share/vm/c1/c1_ValueMap.hpp b/hotspot/src/share/vm/c1/c1_ValueMap.hpp
index efc3220..9482324 100644
--- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp
+++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp
@@ -133,53 +133,77 @@
   virtual void kill_array(ValueType* type) = 0;
 
   // visitor functions
-  void do_StoreField     (StoreField*      x) { kill_field(x->field()); };
-  void do_StoreIndexed   (StoreIndexed*    x) { kill_array(x->type()); };
-  void do_MonitorEnter   (MonitorEnter*    x) { kill_memory(); };
-  void do_MonitorExit    (MonitorExit*     x) { kill_memory(); };
-  void do_Invoke         (Invoke*          x) { kill_memory(); };
-  void do_UnsafePutRaw   (UnsafePutRaw*    x) { kill_memory(); };
-  void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); };
-  void do_Intrinsic      (Intrinsic*       x) { if (!x->preserves_state()) kill_memory(); };
+  void do_StoreField     (StoreField*      x) {
+    if (!x->is_initialized()) {
+      kill_memory();
+    } else {
+      kill_field(x->field());
+    }
+  }
+  void do_StoreIndexed   (StoreIndexed*    x) { kill_array(x->type()); }
+  void do_MonitorEnter   (MonitorEnter*    x) { kill_memory(); }
+  void do_MonitorExit    (MonitorExit*     x) { kill_memory(); }
+  void do_Invoke         (Invoke*          x) { kill_memory(); }
+  void do_UnsafePutRaw   (UnsafePutRaw*    x) { kill_memory(); }
+  void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); }
+  void do_Intrinsic      (Intrinsic*       x) { if (!x->preserves_state()) kill_memory(); }
 
-  void do_Phi            (Phi*             x) { /* nothing to do */ };
-  void do_Local          (Local*           x) { /* nothing to do */ };
-  void do_Constant       (Constant*        x) { /* nothing to do */ };
-  void do_LoadField      (LoadField*       x) { /* nothing to do */ };
-  void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ };
-  void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ };
-  void do_NegateOp       (NegateOp*        x) { /* nothing to do */ };
-  void do_ArithmeticOp   (ArithmeticOp*    x) { /* nothing to do */ };
-  void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ };
-  void do_LogicOp        (LogicOp*         x) { /* nothing to do */ };
-  void do_CompareOp      (CompareOp*       x) { /* nothing to do */ };
-  void do_IfOp           (IfOp*            x) { /* nothing to do */ };
-  void do_Convert        (Convert*         x) { /* nothing to do */ };
-  void do_NullCheck      (NullCheck*       x) { /* nothing to do */ };
-  void do_NewInstance    (NewInstance*     x) { /* nothing to do */ };
-  void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ };
-  void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ };
-  void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ };
-  void do_CheckCast      (CheckCast*       x) { /* nothing to do */ };
-  void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ };
-  void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ };
-  void do_Goto           (Goto*            x) { /* nothing to do */ };
-  void do_If             (If*              x) { /* nothing to do */ };
-  void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ };
-  void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ };
-  void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ };
-  void do_Return         (Return*          x) { /* nothing to do */ };
-  void do_Throw          (Throw*           x) { /* nothing to do */ };
-  void do_Base           (Base*            x) { /* nothing to do */ };
-  void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ };
-  void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ };
-  void do_RoundFP        (RoundFP*         x) { /* nothing to do */ };
-  void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ };
-  void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ };
-  void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) { /* nothing to do */ };
-  void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ };
-  void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ };
-  void do_ProfileCounter (ProfileCounter*  x) { /* nothing to do */ };
+  void do_Phi            (Phi*             x) { /* nothing to do */ }
+  void do_Local          (Local*           x) { /* nothing to do */ }
+  void do_Constant       (Constant*        x) { /* nothing to do */ }
+  void do_LoadField      (LoadField*       x) {
+    if (!x->is_initialized()) {
+      kill_memory();
+    }
+  }
+  void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ }
+  void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ }
+  void do_NegateOp       (NegateOp*        x) { /* nothing to do */ }
+  void do_ArithmeticOp   (ArithmeticOp*    x) { /* nothing to do */ }
+  void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ }
+  void do_LogicOp        (LogicOp*         x) { /* nothing to do */ }
+  void do_CompareOp      (CompareOp*       x) { /* nothing to do */ }
+  void do_IfOp           (IfOp*            x) { /* nothing to do */ }
+  void do_Convert        (Convert*         x) { /* nothing to do */ }
+  void do_NullCheck      (NullCheck*       x) { /* nothing to do */ }
+  void do_NewInstance    (NewInstance*     x) { /* nothing to do */ }
+  void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ }
+  void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ }
+  void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ }
+  void do_CheckCast      (CheckCast*       x) { /* nothing to do */ }
+  void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ }
+  void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ }
+  void do_Goto           (Goto*            x) { /* nothing to do */ }
+  void do_If             (If*              x) { /* nothing to do */ }
+  void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ }
+  void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ }
+  void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ }
+  void do_Return         (Return*          x) { /* nothing to do */ }
+  void do_Throw          (Throw*           x) { /* nothing to do */ }
+  void do_Base           (Base*            x) { /* nothing to do */ }
+  void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ }
+  void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }
+  void do_RoundFP        (RoundFP*         x) { /* nothing to do */ }
+  void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ }
+  void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }
+  void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) { /* nothing to do */ }
+  void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }
+  void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ }
+  void do_ProfileCounter (ProfileCounter*  x) { /* nothing to do */ }
+};
+
+
+class ValueNumberingEffects: public ValueNumberingVisitor {
+ private:
+  ValueMap*     _map;
+
+ public:
+  // implementation for abstract methods of ValueNumberingVisitor
+  void          kill_memory()                    { _map->kill_memory(); }
+  void          kill_field(ciField* field)       { _map->kill_field(field); }
+  void          kill_array(ValueType* type)      { _map->kill_array(type); }
+
+  ValueNumberingEffects(ValueMap* map): _map(map) {}
 };
 
 
diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp
index b9e9cbd..7dff291 100644
--- a/hotspot/src/share/vm/opto/callnode.cpp
+++ b/hotspot/src/share/vm/opto/callnode.cpp
@@ -395,7 +395,13 @@
                    OptoReg::regname(OptoReg::c_frame_pointer),
                    regalloc->reg2offset(box_reg));
       }
-      format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs );
+      const char* obj_msg = "MON-OBJ[";
+      if (EliminateLocks) {
+        while( !box->is_BoxLock() )  box = box->in(1);
+        if (box->as_BoxLock()->is_eliminated())
+          obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
+      }
+      format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
     }
 
     for (i = 0; i < (uint)scobjs.length(); i++) {
@@ -908,8 +914,9 @@
     add_req(lock->box_node());
     add_req(lock->obj_node());
   } else {
-    add_req(NULL);
-    add_req(NULL);
+    Node* top = Compile::current()->top();
+    add_req(top);
+    add_req(top);
   }
   jvms()->set_scloff(nextmon+MonitorEdges);
   jvms()->set_endoff(req());
@@ -1382,7 +1389,7 @@
     //
     // If we are locking an unescaped object, the lock/unlock is unnecessary
     //
-    ConnectionGraph *cgr = Compile::current()->congraph();
+    ConnectionGraph *cgr = phase->C->congraph();
     PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
     if (cgr != NULL)
       es = cgr->escape_state(obj_node(), phase);
@@ -1450,6 +1457,7 @@
 
           // Mark it eliminated to update any counters
           lock->set_eliminated();
+          lock->set_coarsened();
         }
       } else if (result != NULL && ctrl->is_Region() &&
                  iter->_worklist.member(ctrl)) {
@@ -1484,7 +1492,7 @@
     //
     // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
     //
-    ConnectionGraph *cgr = Compile::current()->congraph();
+    ConnectionGraph *cgr = phase->C->congraph();
     PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
     if (cgr != NULL)
       es = cgr->escape_state(obj_node(), phase);
diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp
index 45b6dd2..06c7833 100644
--- a/hotspot/src/share/vm/opto/callnode.hpp
+++ b/hotspot/src/share/vm/opto/callnode.hpp
@@ -780,7 +780,8 @@
 //------------------------------AbstractLockNode-----------------------------------
 class AbstractLockNode: public CallNode {
 private:
- bool _eliminate;    // indicates this lock can be safely eliminated
+  bool _eliminate;    // indicates this lock can be safely eliminated
+  bool _coarsened;    // indicates this lock was coarsened
 #ifndef PRODUCT
   NamedCounter* _counter;
 #endif
@@ -801,6 +802,7 @@
 public:
   AbstractLockNode(const TypeFunc *tf)
     : CallNode(tf, NULL, TypeRawPtr::BOTTOM),
+      _coarsened(false),
       _eliminate(false)
   {
 #ifndef PRODUCT
@@ -819,6 +821,9 @@
   // mark node as eliminated and update the counter if there is one
   void set_eliminated();
 
+  bool is_coarsened()  { return _coarsened; }
+  void set_coarsened() { _coarsened = true; }
+
   // locking does not modify its arguments
   virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
 
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index 42eae30..f9b3392 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -1532,11 +1532,6 @@
 
   if (failing())  return;
 
-  // get rid of the connection graph since it's information is not
-  // updated by optimizations
-  _congraph = NULL;
-
-
   // Loop transforms on the ideal graph.  Range Check Elimination,
   // peeling, unrolling, etc.
 
diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp
index 1c1d5d8..bccfb9c 100644
--- a/hotspot/src/share/vm/opto/escape.cpp
+++ b/hotspot/src/share/vm/opto/escape.cpp
@@ -199,7 +199,8 @@
   es = ptnode_adr(idx)->escape_state();
 
   // if we have already computed a value, return it
-  if (es != PointsToNode::UnknownEscape)
+  if (es != PointsToNode::UnknownEscape &&
+      ptnode_adr(idx)->node_type() == PointsToNode::JavaObject)
     return es;
 
   // PointsTo() calls n->uncast() which can return a new ideal node.
diff --git a/hotspot/src/share/vm/opto/locknode.cpp b/hotspot/src/share/vm/opto/locknode.cpp
index 5a74fd0..0099284 100644
--- a/hotspot/src/share/vm/opto/locknode.cpp
+++ b/hotspot/src/share/vm/opto/locknode.cpp
@@ -44,10 +44,15 @@
   _inmask.Insert(reg);
 }
 
+//-----------------------------hash--------------------------------------------
+uint BoxLockNode::hash() const {
+  return Node::hash() + _slot + (_is_eliminated ? Compile::current()->fixed_slots() : 0);
+}
+
 //------------------------------cmp--------------------------------------------
 uint BoxLockNode::cmp( const Node &n ) const {
   const BoxLockNode &bn = (const BoxLockNode &)n;
-  return bn._slot == _slot;
+  return bn._slot == _slot && bn._is_eliminated == _is_eliminated;
 }
 
 OptoReg::Name BoxLockNode::stack_slot(Node* box_node) {
diff --git a/hotspot/src/share/vm/opto/locknode.hpp b/hotspot/src/share/vm/opto/locknode.hpp
index 113de60..5361933 100644
--- a/hotspot/src/share/vm/opto/locknode.hpp
+++ b/hotspot/src/share/vm/opto/locknode.hpp
@@ -36,7 +36,7 @@
   virtual const RegMask &in_RegMask(uint) const;
   virtual const RegMask &out_RegMask() const;
   virtual uint size_of() const;
-  virtual uint hash() const { return Node::hash() + _slot; }
+  virtual uint hash() const;
   virtual uint cmp( const Node &n ) const;
   virtual const class Type *bottom_type() const { return TypeRawPtr::BOTTOM; }
   virtual uint ideal_reg() const { return Op_RegP; }
diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp
index 37cee06..1152917 100644
--- a/hotspot/src/share/vm/opto/macro.cpp
+++ b/hotspot/src/share/vm/opto/macro.cpp
@@ -59,7 +59,7 @@
   for (uint i = old_dbg_start; i < oldcall->req(); i++) {
     Node* old_in = oldcall->in(i);
     // Clone old SafePointScalarObjectNodes, adjusting their field contents.
-    if (old_in->is_SafePointScalarObject()) {
+    if (old_in != NULL && old_in->is_SafePointScalarObject()) {
       SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject();
       uint old_unique = C->unique();
       Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
@@ -1509,21 +1509,63 @@
   if (!alock->is_eliminated()) {
     return false;
   }
-  // Mark the box lock as eliminated if all correspondent locks are eliminated
-  // to construct correct debug info.
-  BoxLockNode* box = alock->box_node()->as_BoxLock();
-  if (!box->is_eliminated()) {
-    bool eliminate = true;
-    for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) {
-      Node *lck = box->fast_out(i);
-      if (lck->is_Lock() && !lck->as_AbstractLock()->is_eliminated()) {
-        eliminate = false;
-        break;
-      }
-    }
-    if (eliminate)
-      box->set_eliminated();
-  }
+  if (alock->is_Lock() && !alock->is_coarsened()) {
+      // Create new "eliminated" BoxLock node and use it
+      // in monitor debug info for the same object.
+      BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
+      Node* obj = alock->obj_node();
+      if (!oldbox->is_eliminated()) {
+        BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
+        newbox->set_eliminated();
+        transform_later(newbox);
+        // Replace old box node with new box for all users
+        // of the same object.
+        for (uint i = 0; i < oldbox->outcnt();) {
+
+          bool next_edge = true;
+          Node* u = oldbox->raw_out(i);
+          if (u == alock) {
+            i++;
+            continue; // It will be removed below
+          }
+          if (u->is_Lock() &&
+              u->as_Lock()->obj_node() == obj &&
+              // oldbox could be referenced in debug info also
+              u->as_Lock()->box_node() == oldbox) {
+            assert(u->as_Lock()->is_eliminated(), "sanity");
+            _igvn.hash_delete(u);
+            u->set_req(TypeFunc::Parms + 1, newbox);
+            next_edge = false;
+#ifdef ASSERT
+          } else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) {
+            assert(u->as_Unlock()->is_eliminated(), "sanity");
+#endif
+          }
+          // Replace old box in monitor debug info.
+          if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
+            SafePointNode* sfn = u->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 == oldbox && obj_node == obj) {
+                  int j = jvms->monitor_box_offset(idx);
+                  _igvn.hash_delete(u);
+                  u->set_req(j, newbox);
+                  next_edge = false;
+                }
+              } // for (int idx = 0;
+            } // for (int depth = 1;
+          } // if (u->is_SafePoint()
+          if (next_edge) i++;
+        } // for (uint i = 0; i < oldbox->outcnt();)
+      } // if (!oldbox->is_eliminated())
+  } // if (alock->is_Lock() && !lock->is_coarsened())
 
   #ifndef PRODUCT
   if (PrintEliminateLocks) {
@@ -1562,6 +1604,15 @@
     _igvn.subsume_node(ctrlproj, fallthroughproj);
     _igvn.hash_delete(memproj);
     _igvn.subsume_node(memproj, memproj_fallthrough);
+
+    // Delete FastLock node also if this Lock node is unique user
+    // (a loop peeling may clone a Lock node).
+    Node* flock = alock->as_Lock()->fastlock_node();
+    if (flock->outcnt() == 1) {
+      assert(flock->unique_out() == alock, "sanity");
+      _igvn.hash_delete(flock);
+      _igvn.subsume_node(flock, top());
+    }
   }
 
   // Seach for MemBarRelease node and delete it also.
@@ -1887,7 +1938,7 @@
 bool PhaseMacroExpand::expand_macro_nodes() {
   if (C->macro_count() == 0)
     return false;
-  // attempt to eliminate allocations
+  // First, attempt to eliminate locks
   bool progress = true;
   while (progress) {
     progress = false;
@@ -1895,6 +1946,26 @@
       Node * n = C->macro_node(i-1);
       bool success = false;
       debug_only(int old_macro_count = C->macro_count(););
+      if (n->is_AbstractLock()) {
+        success = eliminate_locking_node(n->as_AbstractLock());
+      } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
+        _igvn.add_users_to_worklist(n);
+        _igvn.hash_delete(n);
+        _igvn.subsume_node(n, n->in(1));
+        success = true;
+      }
+      assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
+      progress = progress || success;
+    }
+  }
+  // Next, attempt to eliminate allocations
+  progress = true;
+  while (progress) {
+    progress = false;
+    for (int i = C->macro_count(); i > 0; i--) {
+      Node * n = C->macro_node(i-1);
+      bool success = false;
+      debug_only(int old_macro_count = C->macro_count(););
       switch (n->class_id()) {
       case Node::Class_Allocate:
       case Node::Class_AllocateArray:
@@ -1902,17 +1973,10 @@
         break;
       case Node::Class_Lock:
       case Node::Class_Unlock:
-        success = eliminate_locking_node(n->as_AbstractLock());
+        assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
         break;
       default:
-        if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
-          _igvn.add_users_to_worklist(n);
-          _igvn.hash_delete(n);
-          _igvn.subsume_node(n, n->in(1));
-          success = true;
-        } else {
-          assert(false, "unknown node type in macro list");
-        }
+        assert(false, "unknown node type in macro list");
       }
       assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
       progress = progress || success;
diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp
index 604ab75..7d6482c 100644
--- a/hotspot/src/share/vm/opto/output.cpp
+++ b/hotspot/src/share/vm/opto/output.cpp
@@ -849,10 +849,8 @@
     // Loop over monitors and insert into array
     for(idx = 0; idx < num_mon; idx++) {
       // Grab the node that defines this monitor
-      Node* box_node;
-      Node* obj_node;
-      box_node = sfn->monitor_box(jvms, idx);
-      obj_node = sfn->monitor_obj(jvms, idx);
+      Node* box_node = sfn->monitor_box(jvms, idx);
+      Node* obj_node = sfn->monitor_obj(jvms, idx);
 
       // Create ScopeValue for object
       ScopeValue *scval = NULL;
@@ -890,6 +888,7 @@
 
       OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);
       Location basic_lock = Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg));
+      while( !box_node->is_BoxLock() )  box_node = box_node->in(1);
       monarray->append(new MonitorValue(scval, basic_lock, box_node->as_BoxLock()->is_eliminated()));
     }
 
diff --git a/hotspot/test/compiler/6756768/Test6756768.java b/hotspot/test/compiler/6756768/Test6756768.java
new file mode 100644
index 0000000..8321538
--- /dev/null
+++ b/hotspot/test/compiler/6756768/Test6756768.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6756768
+ * @summary C1 generates invalid code
+ *
+ * @run main/othervm -Xcomp Test6756768
+ */
+
+class Test6756768a
+{
+    static boolean var_1 = true;
+}
+
+final class Test6756768b
+{
+    static boolean var_24 = false;
+    static int var_25 = 0;
+
+    static boolean var_temp1 = Test6756768a.var_1 = false;
+}
+
+public final class Test6756768 extends Test6756768a
+{
+    final static int var = var_1 ^ (Test6756768b.var_24 ? var_1 : var_1) ? Test6756768b.var_25 : 1;
+
+    static public void main(String[] args) {
+        if (var != 0) {
+            throw new InternalError("var = " + var);
+        }
+    }
+
+}
diff --git a/hotspot/test/compiler/6756768/Test6756768_2.java b/hotspot/test/compiler/6756768/Test6756768_2.java
new file mode 100644
index 0000000..fbf9c03
--- /dev/null
+++ b/hotspot/test/compiler/6756768/Test6756768_2.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6756768
+ * @summary C1 generates invalid code
+ *
+ * @run main/othervm -Xcomp Test6756768_2
+ */
+
+class Test6756768_2a {
+    static int var = ++Test6756768_2.var;
+}
+
+public class Test6756768_2 {
+    static int var = 1;
+
+    static Object d2 = null;
+
+    static void test_static_field() {
+        int v = var;
+        int v2 = Test6756768_2a.var;
+        int v3 = var;
+        var = v3;
+    }
+
+    public static void main(String[] args) {
+        var = 1;
+        test_static_field();
+        if (var != 2) {
+            throw new InternalError();
+        }
+    }
+}
diff --git a/hotspot/test/compiler/6775880/Test.java b/hotspot/test/compiler/6775880/Test.java
new file mode 100644
index 0000000..7c952ec
--- /dev/null
+++ b/hotspot/test/compiler/6775880/Test.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6775880
+ * @summary EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
+ * @compile -source 1.4 -target 1.4 Test.java
+ * @run main/othervm -server -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
+ */
+
+public class Test {
+
+  int cnt;
+  int b[];
+  String s;
+
+  String test() {
+    String res="";
+    for (int i=0; i < cnt; i++) {
+      if (i != 0) {
+        res = res +".";
+      }
+      res = res + b[i];
+    }
+    return res;
+  }
+
+  public static void main(String[] args) {
+    Test t = new Test();
+    t.cnt = 3;
+    t.b = new int[3];
+    t.b[0] = 0;
+    t.b[1] = 1;
+    t.b[2] = 2;
+    int j=0;
+    t.s = "";
+    for (int i=0; i<10001; i++) {
+      t.s = "c";
+      t.s = t.test();
+    }
+    System.out.println("After s=" + t.s);
+  }
+}
+
+