Thu, 04 Dec 2008 13:21:16 -0800
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 +