Merge

Thu, 04 Dec 2008 13:21:16 -0800

author
jmasa
date
Thu, 04 Dec 2008 13:21:16 -0800
changeset 899
8a0c882e46d6
parent 898
ab25f609be4a
parent 896
1f54ed41d6ae
child 902
8724fb00c422
child 915
d249b360e026

Merge

     1.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Dec 04 09:04:46 2008 -0800
     1.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Thu Dec 04 13:21:16 2008 -0800
     1.3 @@ -676,21 +676,6 @@
     1.4  }
     1.5  
     1.6  
     1.7 -void GraphBuilder::kill_field(ciField* field) {
     1.8 -  if (UseLocalValueNumbering) {
     1.9 -    vmap()->kill_field(field);
    1.10 -  }
    1.11 -}
    1.12 -
    1.13 -
    1.14 -void GraphBuilder::kill_array(Value value) {
    1.15 -  if (UseLocalValueNumbering) {
    1.16 -    vmap()->kill_array(value->type());
    1.17 -  }
    1.18 -  _memory->store_value(value);
    1.19 -}
    1.20 -
    1.21 -
    1.22  void GraphBuilder::kill_all() {
    1.23    if (UseLocalValueNumbering) {
    1.24      vmap()->kill_all();
    1.25 @@ -987,8 +972,8 @@
    1.26      length = append(new ArrayLength(array, lock_stack()));
    1.27    }
    1.28    StoreIndexed* result = new StoreIndexed(array, index, length, type, value, lock_stack());
    1.29 -  kill_array(value); // invalidate all CSEs that are memory accesses of the same type
    1.30    append(result);
    1.31 +  _memory->store_value(value);
    1.32  }
    1.33  
    1.34  
    1.35 @@ -1478,9 +1463,6 @@
    1.36      case Bytecodes::_putstatic:
    1.37        { Value val = pop(type);
    1.38          append(new StoreField(append(obj), offset, field, val, true, lock_stack(), state_copy, is_loaded, is_initialized));
    1.39 -        if (UseLocalValueNumbering) {
    1.40 -          vmap()->kill_field(field);   // invalidate all CSEs that are memory accesses
    1.41 -        }
    1.42        }
    1.43        break;
    1.44      case Bytecodes::_getfield :
    1.45 @@ -1503,7 +1485,6 @@
    1.46          if (is_loaded) store = _memory->store(store);
    1.47          if (store != NULL) {
    1.48            append(store);
    1.49 -          kill_field(field);   // invalidate all CSEs that are accesses of this field
    1.50          }
    1.51        }
    1.52        break;
    1.53 @@ -1900,6 +1881,8 @@
    1.54        assert(i2->bci() != -1, "should already be linked");
    1.55        return i2;
    1.56      }
    1.57 +    ValueNumberingEffects vne(vmap());
    1.58 +    i1->visit(&vne);
    1.59    }
    1.60  
    1.61    if (i1->as_Phi() == NULL && i1->as_Local() == NULL) {
    1.62 @@ -1926,14 +1909,8 @@
    1.63      assert(_last == i1, "adjust code below");
    1.64      StateSplit* s = i1->as_StateSplit();
    1.65      if (s != NULL && i1->as_BlockEnd() == NULL) {
    1.66 -      // Continue CSE across certain intrinsics
    1.67 -      Intrinsic* intrinsic = s->as_Intrinsic();
    1.68 -      if (UseLocalValueNumbering) {
    1.69 -        if (intrinsic == NULL || !intrinsic->preserves_state()) {
    1.70 -          vmap()->kill_all();      // for now, hopefully we need this only for calls eventually
    1.71 -          }
    1.72 -      }
    1.73        if (EliminateFieldAccess) {
    1.74 +        Intrinsic* intrinsic = s->as_Intrinsic();
    1.75          if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) {
    1.76            _memory->kill();
    1.77          }
     2.1 --- a/src/share/vm/c1/c1_GraphBuilder.hpp	Thu Dec 04 09:04:46 2008 -0800
     2.2 +++ b/src/share/vm/c1/c1_GraphBuilder.hpp	Thu Dec 04 13:21:16 2008 -0800
     2.3 @@ -283,8 +283,6 @@
     2.4    Dependencies* dependency_recorder() const; // = compilation()->dependencies()
     2.5    bool direct_compare(ciKlass* k);
     2.6  
     2.7 -  void kill_field(ciField* field);
     2.8 -  void kill_array(Value value);
     2.9    void kill_all();
    2.10  
    2.11    ValueStack* lock_stack();
     3.1 --- a/src/share/vm/c1/c1_ValueMap.hpp	Thu Dec 04 09:04:46 2008 -0800
     3.2 +++ b/src/share/vm/c1/c1_ValueMap.hpp	Thu Dec 04 13:21:16 2008 -0800
     3.3 @@ -133,53 +133,77 @@
     3.4    virtual void kill_array(ValueType* type) = 0;
     3.5  
     3.6    // visitor functions
     3.7 -  void do_StoreField     (StoreField*      x) { kill_field(x->field()); };
     3.8 -  void do_StoreIndexed   (StoreIndexed*    x) { kill_array(x->type()); };
     3.9 -  void do_MonitorEnter   (MonitorEnter*    x) { kill_memory(); };
    3.10 -  void do_MonitorExit    (MonitorExit*     x) { kill_memory(); };
    3.11 -  void do_Invoke         (Invoke*          x) { kill_memory(); };
    3.12 -  void do_UnsafePutRaw   (UnsafePutRaw*    x) { kill_memory(); };
    3.13 -  void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); };
    3.14 -  void do_Intrinsic      (Intrinsic*       x) { if (!x->preserves_state()) kill_memory(); };
    3.15 +  void do_StoreField     (StoreField*      x) {
    3.16 +    if (!x->is_initialized()) {
    3.17 +      kill_memory();
    3.18 +    } else {
    3.19 +      kill_field(x->field());
    3.20 +    }
    3.21 +  }
    3.22 +  void do_StoreIndexed   (StoreIndexed*    x) { kill_array(x->type()); }
    3.23 +  void do_MonitorEnter   (MonitorEnter*    x) { kill_memory(); }
    3.24 +  void do_MonitorExit    (MonitorExit*     x) { kill_memory(); }
    3.25 +  void do_Invoke         (Invoke*          x) { kill_memory(); }
    3.26 +  void do_UnsafePutRaw   (UnsafePutRaw*    x) { kill_memory(); }
    3.27 +  void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); }
    3.28 +  void do_Intrinsic      (Intrinsic*       x) { if (!x->preserves_state()) kill_memory(); }
    3.29  
    3.30 -  void do_Phi            (Phi*             x) { /* nothing to do */ };
    3.31 -  void do_Local          (Local*           x) { /* nothing to do */ };
    3.32 -  void do_Constant       (Constant*        x) { /* nothing to do */ };
    3.33 -  void do_LoadField      (LoadField*       x) { /* nothing to do */ };
    3.34 -  void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ };
    3.35 -  void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ };
    3.36 -  void do_NegateOp       (NegateOp*        x) { /* nothing to do */ };
    3.37 -  void do_ArithmeticOp   (ArithmeticOp*    x) { /* nothing to do */ };
    3.38 -  void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ };
    3.39 -  void do_LogicOp        (LogicOp*         x) { /* nothing to do */ };
    3.40 -  void do_CompareOp      (CompareOp*       x) { /* nothing to do */ };
    3.41 -  void do_IfOp           (IfOp*            x) { /* nothing to do */ };
    3.42 -  void do_Convert        (Convert*         x) { /* nothing to do */ };
    3.43 -  void do_NullCheck      (NullCheck*       x) { /* nothing to do */ };
    3.44 -  void do_NewInstance    (NewInstance*     x) { /* nothing to do */ };
    3.45 -  void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ };
    3.46 -  void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ };
    3.47 -  void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ };
    3.48 -  void do_CheckCast      (CheckCast*       x) { /* nothing to do */ };
    3.49 -  void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ };
    3.50 -  void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ };
    3.51 -  void do_Goto           (Goto*            x) { /* nothing to do */ };
    3.52 -  void do_If             (If*              x) { /* nothing to do */ };
    3.53 -  void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ };
    3.54 -  void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ };
    3.55 -  void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ };
    3.56 -  void do_Return         (Return*          x) { /* nothing to do */ };
    3.57 -  void do_Throw          (Throw*           x) { /* nothing to do */ };
    3.58 -  void do_Base           (Base*            x) { /* nothing to do */ };
    3.59 -  void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ };
    3.60 -  void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ };
    3.61 -  void do_RoundFP        (RoundFP*         x) { /* nothing to do */ };
    3.62 -  void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ };
    3.63 -  void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ };
    3.64 -  void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) { /* nothing to do */ };
    3.65 -  void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ };
    3.66 -  void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ };
    3.67 -  void do_ProfileCounter (ProfileCounter*  x) { /* nothing to do */ };
    3.68 +  void do_Phi            (Phi*             x) { /* nothing to do */ }
    3.69 +  void do_Local          (Local*           x) { /* nothing to do */ }
    3.70 +  void do_Constant       (Constant*        x) { /* nothing to do */ }
    3.71 +  void do_LoadField      (LoadField*       x) {
    3.72 +    if (!x->is_initialized()) {
    3.73 +      kill_memory();
    3.74 +    }
    3.75 +  }
    3.76 +  void do_ArrayLength    (ArrayLength*     x) { /* nothing to do */ }
    3.77 +  void do_LoadIndexed    (LoadIndexed*     x) { /* nothing to do */ }
    3.78 +  void do_NegateOp       (NegateOp*        x) { /* nothing to do */ }
    3.79 +  void do_ArithmeticOp   (ArithmeticOp*    x) { /* nothing to do */ }
    3.80 +  void do_ShiftOp        (ShiftOp*         x) { /* nothing to do */ }
    3.81 +  void do_LogicOp        (LogicOp*         x) { /* nothing to do */ }
    3.82 +  void do_CompareOp      (CompareOp*       x) { /* nothing to do */ }
    3.83 +  void do_IfOp           (IfOp*            x) { /* nothing to do */ }
    3.84 +  void do_Convert        (Convert*         x) { /* nothing to do */ }
    3.85 +  void do_NullCheck      (NullCheck*       x) { /* nothing to do */ }
    3.86 +  void do_NewInstance    (NewInstance*     x) { /* nothing to do */ }
    3.87 +  void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ }
    3.88 +  void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ }
    3.89 +  void do_NewMultiArray  (NewMultiArray*   x) { /* nothing to do */ }
    3.90 +  void do_CheckCast      (CheckCast*       x) { /* nothing to do */ }
    3.91 +  void do_InstanceOf     (InstanceOf*      x) { /* nothing to do */ }
    3.92 +  void do_BlockBegin     (BlockBegin*      x) { /* nothing to do */ }
    3.93 +  void do_Goto           (Goto*            x) { /* nothing to do */ }
    3.94 +  void do_If             (If*              x) { /* nothing to do */ }
    3.95 +  void do_IfInstanceOf   (IfInstanceOf*    x) { /* nothing to do */ }
    3.96 +  void do_TableSwitch    (TableSwitch*     x) { /* nothing to do */ }
    3.97 +  void do_LookupSwitch   (LookupSwitch*    x) { /* nothing to do */ }
    3.98 +  void do_Return         (Return*          x) { /* nothing to do */ }
    3.99 +  void do_Throw          (Throw*           x) { /* nothing to do */ }
   3.100 +  void do_Base           (Base*            x) { /* nothing to do */ }
   3.101 +  void do_OsrEntry       (OsrEntry*        x) { /* nothing to do */ }
   3.102 +  void do_ExceptionObject(ExceptionObject* x) { /* nothing to do */ }
   3.103 +  void do_RoundFP        (RoundFP*         x) { /* nothing to do */ }
   3.104 +  void do_UnsafeGetRaw   (UnsafeGetRaw*    x) { /* nothing to do */ }
   3.105 +  void do_UnsafeGetObject(UnsafeGetObject* x) { /* nothing to do */ }
   3.106 +  void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) { /* nothing to do */ }
   3.107 +  void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) { /* nothing to do */ }
   3.108 +  void do_ProfileCall    (ProfileCall*     x) { /* nothing to do */ }
   3.109 +  void do_ProfileCounter (ProfileCounter*  x) { /* nothing to do */ }
   3.110 +};
   3.111 +
   3.112 +
   3.113 +class ValueNumberingEffects: public ValueNumberingVisitor {
   3.114 + private:
   3.115 +  ValueMap*     _map;
   3.116 +
   3.117 + public:
   3.118 +  // implementation for abstract methods of ValueNumberingVisitor
   3.119 +  void          kill_memory()                    { _map->kill_memory(); }
   3.120 +  void          kill_field(ciField* field)       { _map->kill_field(field); }
   3.121 +  void          kill_array(ValueType* type)      { _map->kill_array(type); }
   3.122 +
   3.123 +  ValueNumberingEffects(ValueMap* map): _map(map) {}
   3.124  };
   3.125  
   3.126  
     4.1 --- a/src/share/vm/opto/callnode.cpp	Thu Dec 04 09:04:46 2008 -0800
     4.2 +++ b/src/share/vm/opto/callnode.cpp	Thu Dec 04 13:21:16 2008 -0800
     4.3 @@ -395,7 +395,13 @@
     4.4                     OptoReg::regname(OptoReg::c_frame_pointer),
     4.5                     regalloc->reg2offset(box_reg));
     4.6        }
     4.7 -      format_helper( regalloc, st, obj, "MON-OBJ[", i, &scobjs );
     4.8 +      const char* obj_msg = "MON-OBJ[";
     4.9 +      if (EliminateLocks) {
    4.10 +        while( !box->is_BoxLock() )  box = box->in(1);
    4.11 +        if (box->as_BoxLock()->is_eliminated())
    4.12 +          obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
    4.13 +      }
    4.14 +      format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
    4.15      }
    4.16  
    4.17      for (i = 0; i < (uint)scobjs.length(); i++) {
    4.18 @@ -908,8 +914,9 @@
    4.19      add_req(lock->box_node());
    4.20      add_req(lock->obj_node());
    4.21    } else {
    4.22 -    add_req(NULL);
    4.23 -    add_req(NULL);
    4.24 +    Node* top = Compile::current()->top();
    4.25 +    add_req(top);
    4.26 +    add_req(top);
    4.27    }
    4.28    jvms()->set_scloff(nextmon+MonitorEdges);
    4.29    jvms()->set_endoff(req());
    4.30 @@ -1382,7 +1389,7 @@
    4.31      //
    4.32      // If we are locking an unescaped object, the lock/unlock is unnecessary
    4.33      //
    4.34 -    ConnectionGraph *cgr = Compile::current()->congraph();
    4.35 +    ConnectionGraph *cgr = phase->C->congraph();
    4.36      PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
    4.37      if (cgr != NULL)
    4.38        es = cgr->escape_state(obj_node(), phase);
    4.39 @@ -1450,6 +1457,7 @@
    4.40  
    4.41            // Mark it eliminated to update any counters
    4.42            lock->set_eliminated();
    4.43 +          lock->set_coarsened();
    4.44          }
    4.45        } else if (result != NULL && ctrl->is_Region() &&
    4.46                   iter->_worklist.member(ctrl)) {
    4.47 @@ -1484,7 +1492,7 @@
    4.48      //
    4.49      // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
    4.50      //
    4.51 -    ConnectionGraph *cgr = Compile::current()->congraph();
    4.52 +    ConnectionGraph *cgr = phase->C->congraph();
    4.53      PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
    4.54      if (cgr != NULL)
    4.55        es = cgr->escape_state(obj_node(), phase);
     5.1 --- a/src/share/vm/opto/callnode.hpp	Thu Dec 04 09:04:46 2008 -0800
     5.2 +++ b/src/share/vm/opto/callnode.hpp	Thu Dec 04 13:21:16 2008 -0800
     5.3 @@ -780,7 +780,8 @@
     5.4  //------------------------------AbstractLockNode-----------------------------------
     5.5  class AbstractLockNode: public CallNode {
     5.6  private:
     5.7 - bool _eliminate;    // indicates this lock can be safely eliminated
     5.8 +  bool _eliminate;    // indicates this lock can be safely eliminated
     5.9 +  bool _coarsened;    // indicates this lock was coarsened
    5.10  #ifndef PRODUCT
    5.11    NamedCounter* _counter;
    5.12  #endif
    5.13 @@ -801,6 +802,7 @@
    5.14  public:
    5.15    AbstractLockNode(const TypeFunc *tf)
    5.16      : CallNode(tf, NULL, TypeRawPtr::BOTTOM),
    5.17 +      _coarsened(false),
    5.18        _eliminate(false)
    5.19    {
    5.20  #ifndef PRODUCT
    5.21 @@ -819,6 +821,9 @@
    5.22    // mark node as eliminated and update the counter if there is one
    5.23    void set_eliminated();
    5.24  
    5.25 +  bool is_coarsened()  { return _coarsened; }
    5.26 +  void set_coarsened() { _coarsened = true; }
    5.27 +
    5.28    // locking does not modify its arguments
    5.29    virtual bool        may_modify(const TypePtr *addr_t, PhaseTransform *phase){ return false;}
    5.30  
     6.1 --- a/src/share/vm/opto/compile.cpp	Thu Dec 04 09:04:46 2008 -0800
     6.2 +++ b/src/share/vm/opto/compile.cpp	Thu Dec 04 13:21:16 2008 -0800
     6.3 @@ -1532,11 +1532,6 @@
     6.4  
     6.5    if (failing())  return;
     6.6  
     6.7 -  // get rid of the connection graph since it's information is not
     6.8 -  // updated by optimizations
     6.9 -  _congraph = NULL;
    6.10 -
    6.11 -
    6.12    // Loop transforms on the ideal graph.  Range Check Elimination,
    6.13    // peeling, unrolling, etc.
    6.14  
     7.1 --- a/src/share/vm/opto/escape.cpp	Thu Dec 04 09:04:46 2008 -0800
     7.2 +++ b/src/share/vm/opto/escape.cpp	Thu Dec 04 13:21:16 2008 -0800
     7.3 @@ -199,7 +199,8 @@
     7.4    es = ptnode_adr(idx)->escape_state();
     7.5  
     7.6    // if we have already computed a value, return it
     7.7 -  if (es != PointsToNode::UnknownEscape)
     7.8 +  if (es != PointsToNode::UnknownEscape &&
     7.9 +      ptnode_adr(idx)->node_type() == PointsToNode::JavaObject)
    7.10      return es;
    7.11  
    7.12    // PointsTo() calls n->uncast() which can return a new ideal node.
     8.1 --- a/src/share/vm/opto/locknode.cpp	Thu Dec 04 09:04:46 2008 -0800
     8.2 +++ b/src/share/vm/opto/locknode.cpp	Thu Dec 04 13:21:16 2008 -0800
     8.3 @@ -44,10 +44,15 @@
     8.4    _inmask.Insert(reg);
     8.5  }
     8.6  
     8.7 +//-----------------------------hash--------------------------------------------
     8.8 +uint BoxLockNode::hash() const {
     8.9 +  return Node::hash() + _slot + (_is_eliminated ? Compile::current()->fixed_slots() : 0);
    8.10 +}
    8.11 +
    8.12  //------------------------------cmp--------------------------------------------
    8.13  uint BoxLockNode::cmp( const Node &n ) const {
    8.14    const BoxLockNode &bn = (const BoxLockNode &)n;
    8.15 -  return bn._slot == _slot;
    8.16 +  return bn._slot == _slot && bn._is_eliminated == _is_eliminated;
    8.17  }
    8.18  
    8.19  OptoReg::Name BoxLockNode::stack_slot(Node* box_node) {
     9.1 --- a/src/share/vm/opto/locknode.hpp	Thu Dec 04 09:04:46 2008 -0800
     9.2 +++ b/src/share/vm/opto/locknode.hpp	Thu Dec 04 13:21:16 2008 -0800
     9.3 @@ -36,7 +36,7 @@
     9.4    virtual const RegMask &in_RegMask(uint) const;
     9.5    virtual const RegMask &out_RegMask() const;
     9.6    virtual uint size_of() const;
     9.7 -  virtual uint hash() const { return Node::hash() + _slot; }
     9.8 +  virtual uint hash() const;
     9.9    virtual uint cmp( const Node &n ) const;
    9.10    virtual const class Type *bottom_type() const { return TypeRawPtr::BOTTOM; }
    9.11    virtual uint ideal_reg() const { return Op_RegP; }
    10.1 --- a/src/share/vm/opto/macro.cpp	Thu Dec 04 09:04:46 2008 -0800
    10.2 +++ b/src/share/vm/opto/macro.cpp	Thu Dec 04 13:21:16 2008 -0800
    10.3 @@ -59,7 +59,7 @@
    10.4    for (uint i = old_dbg_start; i < oldcall->req(); i++) {
    10.5      Node* old_in = oldcall->in(i);
    10.6      // Clone old SafePointScalarObjectNodes, adjusting their field contents.
    10.7 -    if (old_in->is_SafePointScalarObject()) {
    10.8 +    if (old_in != NULL && old_in->is_SafePointScalarObject()) {
    10.9        SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject();
   10.10        uint old_unique = C->unique();
   10.11        Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
   10.12 @@ -1509,21 +1509,63 @@
   10.13    if (!alock->is_eliminated()) {
   10.14      return false;
   10.15    }
   10.16 -  // Mark the box lock as eliminated if all correspondent locks are eliminated
   10.17 -  // to construct correct debug info.
   10.18 -  BoxLockNode* box = alock->box_node()->as_BoxLock();
   10.19 -  if (!box->is_eliminated()) {
   10.20 -    bool eliminate = true;
   10.21 -    for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) {
   10.22 -      Node *lck = box->fast_out(i);
   10.23 -      if (lck->is_Lock() && !lck->as_AbstractLock()->is_eliminated()) {
   10.24 -        eliminate = false;
   10.25 -        break;
   10.26 -      }
   10.27 -    }
   10.28 -    if (eliminate)
   10.29 -      box->set_eliminated();
   10.30 -  }
   10.31 +  if (alock->is_Lock() && !alock->is_coarsened()) {
   10.32 +      // Create new "eliminated" BoxLock node and use it
   10.33 +      // in monitor debug info for the same object.
   10.34 +      BoxLockNode* oldbox = alock->box_node()->as_BoxLock();
   10.35 +      Node* obj = alock->obj_node();
   10.36 +      if (!oldbox->is_eliminated()) {
   10.37 +        BoxLockNode* newbox = oldbox->clone()->as_BoxLock();
   10.38 +        newbox->set_eliminated();
   10.39 +        transform_later(newbox);
   10.40 +        // Replace old box node with new box for all users
   10.41 +        // of the same object.
   10.42 +        for (uint i = 0; i < oldbox->outcnt();) {
   10.43 +
   10.44 +          bool next_edge = true;
   10.45 +          Node* u = oldbox->raw_out(i);
   10.46 +          if (u == alock) {
   10.47 +            i++;
   10.48 +            continue; // It will be removed below
   10.49 +          }
   10.50 +          if (u->is_Lock() &&
   10.51 +              u->as_Lock()->obj_node() == obj &&
   10.52 +              // oldbox could be referenced in debug info also
   10.53 +              u->as_Lock()->box_node() == oldbox) {
   10.54 +            assert(u->as_Lock()->is_eliminated(), "sanity");
   10.55 +            _igvn.hash_delete(u);
   10.56 +            u->set_req(TypeFunc::Parms + 1, newbox);
   10.57 +            next_edge = false;
   10.58 +#ifdef ASSERT
   10.59 +          } else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) {
   10.60 +            assert(u->as_Unlock()->is_eliminated(), "sanity");
   10.61 +#endif
   10.62 +          }
   10.63 +          // Replace old box in monitor debug info.
   10.64 +          if (u->is_SafePoint() && u->as_SafePoint()->jvms()) {
   10.65 +            SafePointNode* sfn = u->as_SafePoint();
   10.66 +            JVMState* youngest_jvms = sfn->jvms();
   10.67 +            int max_depth = youngest_jvms->depth();
   10.68 +            for (int depth = 1; depth <= max_depth; depth++) {
   10.69 +              JVMState* jvms = youngest_jvms->of_depth(depth);
   10.70 +              int num_mon  = jvms->nof_monitors();
   10.71 +              // Loop over monitors
   10.72 +              for (int idx = 0; idx < num_mon; idx++) {
   10.73 +                Node* obj_node = sfn->monitor_obj(jvms, idx);
   10.74 +                Node* box_node = sfn->monitor_box(jvms, idx);
   10.75 +                if (box_node == oldbox && obj_node == obj) {
   10.76 +                  int j = jvms->monitor_box_offset(idx);
   10.77 +                  _igvn.hash_delete(u);
   10.78 +                  u->set_req(j, newbox);
   10.79 +                  next_edge = false;
   10.80 +                }
   10.81 +              } // for (int idx = 0;
   10.82 +            } // for (int depth = 1;
   10.83 +          } // if (u->is_SafePoint()
   10.84 +          if (next_edge) i++;
   10.85 +        } // for (uint i = 0; i < oldbox->outcnt();)
   10.86 +      } // if (!oldbox->is_eliminated())
   10.87 +  } // if (alock->is_Lock() && !lock->is_coarsened())
   10.88  
   10.89    #ifndef PRODUCT
   10.90    if (PrintEliminateLocks) {
   10.91 @@ -1562,6 +1604,15 @@
   10.92      _igvn.subsume_node(ctrlproj, fallthroughproj);
   10.93      _igvn.hash_delete(memproj);
   10.94      _igvn.subsume_node(memproj, memproj_fallthrough);
   10.95 +
   10.96 +    // Delete FastLock node also if this Lock node is unique user
   10.97 +    // (a loop peeling may clone a Lock node).
   10.98 +    Node* flock = alock->as_Lock()->fastlock_node();
   10.99 +    if (flock->outcnt() == 1) {
  10.100 +      assert(flock->unique_out() == alock, "sanity");
  10.101 +      _igvn.hash_delete(flock);
  10.102 +      _igvn.subsume_node(flock, top());
  10.103 +    }
  10.104    }
  10.105  
  10.106    // Seach for MemBarRelease node and delete it also.
  10.107 @@ -1887,7 +1938,7 @@
  10.108  bool PhaseMacroExpand::expand_macro_nodes() {
  10.109    if (C->macro_count() == 0)
  10.110      return false;
  10.111 -  // attempt to eliminate allocations
  10.112 +  // First, attempt to eliminate locks
  10.113    bool progress = true;
  10.114    while (progress) {
  10.115      progress = false;
  10.116 @@ -1895,6 +1946,26 @@
  10.117        Node * n = C->macro_node(i-1);
  10.118        bool success = false;
  10.119        debug_only(int old_macro_count = C->macro_count(););
  10.120 +      if (n->is_AbstractLock()) {
  10.121 +        success = eliminate_locking_node(n->as_AbstractLock());
  10.122 +      } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
  10.123 +        _igvn.add_users_to_worklist(n);
  10.124 +        _igvn.hash_delete(n);
  10.125 +        _igvn.subsume_node(n, n->in(1));
  10.126 +        success = true;
  10.127 +      }
  10.128 +      assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
  10.129 +      progress = progress || success;
  10.130 +    }
  10.131 +  }
  10.132 +  // Next, attempt to eliminate allocations
  10.133 +  progress = true;
  10.134 +  while (progress) {
  10.135 +    progress = false;
  10.136 +    for (int i = C->macro_count(); i > 0; i--) {
  10.137 +      Node * n = C->macro_node(i-1);
  10.138 +      bool success = false;
  10.139 +      debug_only(int old_macro_count = C->macro_count(););
  10.140        switch (n->class_id()) {
  10.141        case Node::Class_Allocate:
  10.142        case Node::Class_AllocateArray:
  10.143 @@ -1902,17 +1973,10 @@
  10.144          break;
  10.145        case Node::Class_Lock:
  10.146        case Node::Class_Unlock:
  10.147 -        success = eliminate_locking_node(n->as_AbstractLock());
  10.148 +        assert(!n->as_AbstractLock()->is_eliminated(), "sanity");
  10.149          break;
  10.150        default:
  10.151 -        if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
  10.152 -          _igvn.add_users_to_worklist(n);
  10.153 -          _igvn.hash_delete(n);
  10.154 -          _igvn.subsume_node(n, n->in(1));
  10.155 -          success = true;
  10.156 -        } else {
  10.157 -          assert(false, "unknown node type in macro list");
  10.158 -        }
  10.159 +        assert(false, "unknown node type in macro list");
  10.160        }
  10.161        assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
  10.162        progress = progress || success;
    11.1 --- a/src/share/vm/opto/output.cpp	Thu Dec 04 09:04:46 2008 -0800
    11.2 +++ b/src/share/vm/opto/output.cpp	Thu Dec 04 13:21:16 2008 -0800
    11.3 @@ -849,10 +849,8 @@
    11.4      // Loop over monitors and insert into array
    11.5      for(idx = 0; idx < num_mon; idx++) {
    11.6        // Grab the node that defines this monitor
    11.7 -      Node* box_node;
    11.8 -      Node* obj_node;
    11.9 -      box_node = sfn->monitor_box(jvms, idx);
   11.10 -      obj_node = sfn->monitor_obj(jvms, idx);
   11.11 +      Node* box_node = sfn->monitor_box(jvms, idx);
   11.12 +      Node* obj_node = sfn->monitor_obj(jvms, idx);
   11.13  
   11.14        // Create ScopeValue for object
   11.15        ScopeValue *scval = NULL;
   11.16 @@ -890,6 +888,7 @@
   11.17  
   11.18        OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);
   11.19        Location basic_lock = Location::new_stk_loc(Location::normal,_regalloc->reg2offset(box_reg));
   11.20 +      while( !box_node->is_BoxLock() )  box_node = box_node->in(1);
   11.21        monarray->append(new MonitorValue(scval, basic_lock, box_node->as_BoxLock()->is_eliminated()));
   11.22      }
   11.23  
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/compiler/6756768/Test6756768.java	Thu Dec 04 13:21:16 2008 -0800
    12.3 @@ -0,0 +1,55 @@
    12.4 +/*
    12.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.
   12.11 + *
   12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.15 + * version 2 for more details (a copy is included in the LICENSE file that
   12.16 + * accompanied this code).
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License version
   12.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.21 + *
   12.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   12.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   12.24 + * have any questions.
   12.25 + */
   12.26 +
   12.27 +/**
   12.28 + * @test
   12.29 + * @bug 6756768
   12.30 + * @summary C1 generates invalid code
   12.31 + *
   12.32 + * @run main/othervm -Xcomp Test6756768
   12.33 + */
   12.34 +
   12.35 +class Test6756768a
   12.36 +{
   12.37 +    static boolean var_1 = true;
   12.38 +}
   12.39 +
   12.40 +final class Test6756768b
   12.41 +{
   12.42 +    static boolean var_24 = false;
   12.43 +    static int var_25 = 0;
   12.44 +
   12.45 +    static boolean var_temp1 = Test6756768a.var_1 = false;
   12.46 +}
   12.47 +
   12.48 +public final class Test6756768 extends Test6756768a
   12.49 +{
   12.50 +    final static int var = var_1 ^ (Test6756768b.var_24 ? var_1 : var_1) ? Test6756768b.var_25 : 1;
   12.51 +
   12.52 +    static public void main(String[] args) {
   12.53 +        if (var != 0) {
   12.54 +            throw new InternalError("var = " + var);
   12.55 +        }
   12.56 +    }
   12.57 +
   12.58 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/compiler/6756768/Test6756768_2.java	Thu Dec 04 13:21:16 2008 -0800
    13.3 @@ -0,0 +1,55 @@
    13.4 +/*
    13.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.
   13.11 + *
   13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.15 + * version 2 for more details (a copy is included in the LICENSE file that
   13.16 + * accompanied this code).
   13.17 + *
   13.18 + * You should have received a copy of the GNU General Public License version
   13.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.21 + *
   13.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   13.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   13.24 + * have any questions.
   13.25 + */
   13.26 +
   13.27 +/**
   13.28 + * @test
   13.29 + * @bug 6756768
   13.30 + * @summary C1 generates invalid code
   13.31 + *
   13.32 + * @run main/othervm -Xcomp Test6756768_2
   13.33 + */
   13.34 +
   13.35 +class Test6756768_2a {
   13.36 +    static int var = ++Test6756768_2.var;
   13.37 +}
   13.38 +
   13.39 +public class Test6756768_2 {
   13.40 +    static int var = 1;
   13.41 +
   13.42 +    static Object d2 = null;
   13.43 +
   13.44 +    static void test_static_field() {
   13.45 +        int v = var;
   13.46 +        int v2 = Test6756768_2a.var;
   13.47 +        int v3 = var;
   13.48 +        var = v3;
   13.49 +    }
   13.50 +
   13.51 +    public static void main(String[] args) {
   13.52 +        var = 1;
   13.53 +        test_static_field();
   13.54 +        if (var != 2) {
   13.55 +            throw new InternalError();
   13.56 +        }
   13.57 +    }
   13.58 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/compiler/6775880/Test.java	Thu Dec 04 13:21:16 2008 -0800
    14.3 @@ -0,0 +1,67 @@
    14.4 +/*
    14.5 + * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.
   14.11 + *
   14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.15 + * version 2 for more details (a copy is included in the LICENSE file that
   14.16 + * accompanied this code).
   14.17 + *
   14.18 + * You should have received a copy of the GNU General Public License version
   14.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.21 + *
   14.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   14.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   14.24 + * have any questions.
   14.25 + *
   14.26 + */
   14.27 +
   14.28 +/*
   14.29 + * @test
   14.30 + * @bug 6775880
   14.31 + * @summary EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
   14.32 + * @compile -source 1.4 -target 1.4 Test.java
   14.33 + * @run main/othervm -server -Xbatch -XX:+DoEscapeAnalysis -XX:+DeoptimizeALot -XX:CompileCommand=exclude,java.lang.AbstractStringBuilder::append Test
   14.34 + */
   14.35 +
   14.36 +public class Test {
   14.37 +
   14.38 +  int cnt;
   14.39 +  int b[];
   14.40 +  String s;
   14.41 +
   14.42 +  String test() {
   14.43 +    String res="";
   14.44 +    for (int i=0; i < cnt; i++) {
   14.45 +      if (i != 0) {
   14.46 +        res = res +".";
   14.47 +      }
   14.48 +      res = res + b[i];
   14.49 +    }
   14.50 +    return res;
   14.51 +  }
   14.52 +
   14.53 +  public static void main(String[] args) {
   14.54 +    Test t = new Test();
   14.55 +    t.cnt = 3;
   14.56 +    t.b = new int[3];
   14.57 +    t.b[0] = 0;
   14.58 +    t.b[1] = 1;
   14.59 +    t.b[2] = 2;
   14.60 +    int j=0;
   14.61 +    t.s = "";
   14.62 +    for (int i=0; i<10001; i++) {
   14.63 +      t.s = "c";
   14.64 +      t.s = t.test();
   14.65 +    }
   14.66 +    System.out.println("After s=" + t.s);
   14.67 +  }
   14.68 +}
   14.69 +
   14.70 +

mercurial