Merge
This commit is contained in:
commit
dd80e77a74
@ -676,21 +676,6 @@ GraphBuilder::ScopeData::ScopeData(ScopeData* parent)
|
||||
}
|
||||
|
||||
|
||||
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 @@ void GraphBuilder::store_indexed(BasicType type) {
|
||||
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 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
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 @@ void GraphBuilder::access_field(Bytecodes::Code code) {
|
||||
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 @@ Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
|
||||
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 @@ Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
|
||||
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();
|
||||
}
|
||||
|
@ -283,8 +283,6 @@ class GraphBuilder VALUE_OBJ_CLASS_SPEC {
|
||||
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();
|
||||
|
@ -133,53 +133,77 @@ class ValueNumberingVisitor: public InstructionVisitor {
|
||||
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) {}
|
||||
};
|
||||
|
||||
|
||||
|
@ -395,7 +395,13 @@ void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st)
|
||||
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 @@ void SafePointNode::push_monitor(const FastLockNode *lock) {
|
||||
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 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
//
|
||||
// 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 @@ Node *LockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
|
||||
// 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 @@ Node *UnlockNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
//
|
||||
// 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);
|
||||
|
@ -780,7 +780,8 @@ public:
|
||||
//------------------------------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 @@ protected:
|
||||
public:
|
||||
AbstractLockNode(const TypeFunc *tf)
|
||||
: CallNode(tf, NULL, TypeRawPtr::BOTTOM),
|
||||
_coarsened(false),
|
||||
_eliminate(false)
|
||||
{
|
||||
#ifndef PRODUCT
|
||||
@ -819,6 +821,9 @@ public:
|
||||
// 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;}
|
||||
|
||||
|
@ -1532,11 +1532,6 @@ void Compile::Optimize() {
|
||||
|
||||
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.
|
||||
|
||||
|
@ -199,7 +199,8 @@ PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n, PhaseTransform
|
||||
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.
|
||||
|
@ -44,10 +44,15 @@ BoxLockNode::BoxLockNode( int slot ) : Node( Compile::current()->root() ),
|
||||
_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) {
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
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; }
|
||||
|
@ -59,7 +59,7 @@ void PhaseMacroExpand::copy_call_debug_info(CallNode *oldcall, CallNode * newcal
|
||||
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 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
|
||||
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 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
|
||||
_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,8 +1938,28 @@ void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) {
|
||||
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;
|
||||
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(););
|
||||
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--) {
|
||||
@ -1902,17 +1973,10 @@ bool PhaseMacroExpand::expand_macro_nodes() {
|
||||
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;
|
||||
|
@ -849,10 +849,8 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
|
||||
// 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 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
|
55
hotspot/test/compiler/6756768/Test6756768.java
Normal file
55
hotspot/test/compiler/6756768/Test6756768.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
55
hotspot/test/compiler/6756768/Test6756768_2.java
Normal file
55
hotspot/test/compiler/6756768/Test6756768_2.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
67
hotspot/test/compiler/6775880/Test.java
Normal file
67
hotspot/test/compiler/6775880/Test.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user