diff --git a/src/cpu/sparc/vm/sparc.ad b/src/cpu/sparc/vm/sparc.ad index d940498efa53448a9d399cb0cf46d86c7615ae32..9360631b077cd0eedcf36ba9e62966602143c47c 100644 --- a/src/cpu/sparc/vm/sparc.ad +++ b/src/cpu/sparc/vm/sparc.ad @@ -6023,7 +6023,7 @@ instruct cmovII_imm(cmpOp cmp, flagsReg icc, iRegI dst, immI11 src) %{ ins_pipe(ialu_imm); %} -instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{ +instruct cmovII_U_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{ match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); ins_cost(150); size(4); @@ -6032,7 +6032,7 @@ instruct cmovII_U_reg(cmpOp cmp, flagsRegU icc, iRegI dst, iRegI src) %{ ins_pipe(ialu_reg); %} -instruct cmovII_U_imm(cmpOp cmp, flagsRegU icc, iRegI dst, immI11 src) %{ +instruct cmovII_U_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{ match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); ins_cost(140); size(4); diff --git a/src/share/vm/opto/memnode.cpp b/src/share/vm/opto/memnode.cpp index d3027cec71597c462a41a9fc651cf6f8a5567b2c..df47ccb0e9665961243f24bf60e2bfeb4a1e1fb2 100644 --- a/src/share/vm/opto/memnode.cpp +++ b/src/share/vm/opto/memnode.cpp @@ -1122,6 +1122,12 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { } // Split through Phi (see original code in loopopts.cpp). assert(phase->C->have_alias_type(addr_t), "instance should have alias type"); + + // Do nothing here if Identity will find a value + // (to avoid infinite chain of value phis generation). + if ( !phase->eqv(this, this->Identity(phase)) ) + return NULL; + const Type* this_type = this->bottom_type(); int this_index = phase->C->get_alias_index(addr_t); int this_offset = addr_t->offset(); diff --git a/src/share/vm/runtime/deoptimization.cpp b/src/share/vm/runtime/deoptimization.cpp index 444925938bee0f1378a0fd8467913142a1bb143b..ccca77a5e137435532454f2a8032250ccd39d039 100644 --- a/src/share/vm/runtime/deoptimization.cpp +++ b/src/share/vm/runtime/deoptimization.cpp @@ -143,6 +143,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread // relock objects if synchronization on them was eliminated. if (DoEscapeAnalysis) { if (EliminateAllocations) { + assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); GrowableArray* objects = chunk->at(0)->scope()->objects(); bool reallocated = false; if (objects != NULL) { @@ -162,19 +163,26 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread } } if (EliminateLocks) { +#ifndef PRODUCT + bool first = true; +#endif for (int i = 0; i < chunk->length(); i++) { - GrowableArray* monitors = chunk->at(i)->scope()->monitors(); - if (monitors != NULL) { - relock_objects(&deoptee, &map, monitors); + compiledVFrame* cvf = chunk->at(i); + assert (cvf->scope() != NULL,"expect only compiled java frames"); + GrowableArray* monitors = cvf->monitors(); + if (monitors->is_nonempty()) { + relock_objects(monitors, thread); #ifndef PRODUCT if (TraceDeoptimization) { ttyLocker ttyl; - tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); for (int j = 0; j < monitors->length(); j++) { - MonitorValue* mv = monitors->at(j); - if (mv->eliminated()) { - StackValue* owner = StackValue::create_stack_value(&deoptee, &map, mv->owner()); - tty->print_cr(" object <" INTPTR_FORMAT "> locked", owner->get_obj()()); + MonitorInfo* mi = monitors->at(j); + if (mi->eliminated()) { + if (first) { + first = false; + tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); + } + tty->print_cr(" object <" INTPTR_FORMAT "> locked", mi->owner()); } } } @@ -799,18 +807,27 @@ void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableAr // relock objects for which synchronization was eliminated -void Deoptimization::relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray* monitors) { +void Deoptimization::relock_objects(GrowableArray* monitors, JavaThread* thread) { for (int i = 0; i < monitors->length(); i++) { - MonitorValue* mv = monitors->at(i); - StackValue* owner = StackValue::create_stack_value(fr, reg_map, mv->owner()); - if (mv->eliminated()) { - Handle obj = owner->get_obj(); - assert(obj.not_null(), "reallocation was missed"); - BasicLock* lock = StackValue::resolve_monitor_lock(fr, mv->basic_lock()); - lock->set_displaced_header(obj->mark()); - obj->set_mark((markOop) lock); + MonitorInfo* mon_info = monitors->at(i); + if (mon_info->eliminated()) { + assert(mon_info->owner() != NULL, "reallocation was missed"); + Handle obj = Handle(mon_info->owner()); + markOop mark = obj->mark(); + if (UseBiasedLocking && mark->has_bias_pattern()) { + // New allocated objects may have the mark set to anonymously biased. + // Also the deoptimized method may called methods with synchronization + // where the thread-local object is bias locked to the current thread. + assert(mark->is_biased_anonymously() || + mark->biased_locker() == thread, "should be locked to current thread"); + // Reset mark word to unbiased prototype. + markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); + obj->set_mark(unbiased_prototype); + } + BasicLock* lock = mon_info->lock(); + ObjectSynchronizer::slow_enter(obj, lock, thread); } - assert(owner->get_obj()->is_locked(), "object must be locked now"); + assert(mon_info->owner()->is_locked(), "object must be locked now"); } } @@ -916,7 +933,7 @@ static void collect_monitors(compiledVFrame* cvf, GrowableArray* objects GrowableArray* monitors = cvf->monitors(); for (int i = 0; i < monitors->length(); i++) { MonitorInfo* mon_info = monitors->at(i); - if (mon_info->owner() != NULL) { + if (mon_info->owner() != NULL && !mon_info->eliminated()) { objects_to_revoke->append(Handle(mon_info->owner())); } } diff --git a/src/share/vm/runtime/deoptimization.hpp b/src/share/vm/runtime/deoptimization.hpp index 63565704a6938c8583c00e42b377e89eb5a1a8e2..6edb6a089364aa3ee0c70f9849d2f5cb7fdca13f 100644 --- a/src/share/vm/runtime/deoptimization.hpp +++ b/src/share/vm/runtime/deoptimization.hpp @@ -105,7 +105,7 @@ class Deoptimization : AllStatic { static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj); static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects); - static void relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray* monitors); + static void relock_objects(GrowableArray* monitors, JavaThread* thread); NOT_PRODUCT(static void print_objects(GrowableArray* objects);) #endif // COMPILER2 diff --git a/src/share/vm/runtime/vframe.cpp b/src/share/vm/runtime/vframe.cpp index fdb2864df39f36a180d152be95bba3e835b277cb..3e9b65bfc03927e2b44e502c3ba99a5f4555cd7a 100644 --- a/src/share/vm/runtime/vframe.cpp +++ b/src/share/vm/runtime/vframe.cpp @@ -206,7 +206,7 @@ GrowableArray* interpretedVFrame::monitors() const { for (BasicObjectLock* current = (fr().previous_monitor_in_interpreter_frame(fr().interpreter_frame_monitor_begin())); current >= fr().interpreter_frame_monitor_end(); current = fr().previous_monitor_in_interpreter_frame(current)) { - result->push(new MonitorInfo(current->obj(), current->lock())); + result->push(new MonitorInfo(current->obj(), current->lock(), false)); } return result; } diff --git a/src/share/vm/runtime/vframe.hpp b/src/share/vm/runtime/vframe.hpp index b62a6f76ffb2407a8c4dfabf7591ae317798abfb..2b1b827b1fda6eb177f5a06578e191841d7c7971 100644 --- a/src/share/vm/runtime/vframe.hpp +++ b/src/share/vm/runtime/vframe.hpp @@ -230,15 +230,18 @@ class MonitorInfo : public ResourceObj { private: oop _owner; // the object owning the monitor BasicLock* _lock; + bool _eliminated; public: // Constructor - MonitorInfo(oop owner, BasicLock* lock) { + MonitorInfo(oop owner, BasicLock* lock, bool eliminated) { _owner = owner; _lock = lock; + _eliminated = eliminated; } // Accessors oop owner() const { return _owner; } BasicLock* lock() const { return _lock; } + bool eliminated() const { return _eliminated; } }; class vframeStreamCommon : StackObj { diff --git a/src/share/vm/runtime/vframe_hp.cpp b/src/share/vm/runtime/vframe_hp.cpp index 3399e23a5d84d26ea1446b35d4b00434679368bd..35f0713a23f31052f17614a5c541e0bbaedffe8c 100644 --- a/src/share/vm/runtime/vframe_hp.cpp +++ b/src/share/vm/runtime/vframe_hp.cpp @@ -190,7 +190,7 @@ GrowableArray* compiledVFrame::monitors() const { // Casting away const frame& fr = (frame&) _fr; MonitorInfo* info = new MonitorInfo(fr.compiled_synchronized_native_monitor_owner(nm), - fr.compiled_synchronized_native_monitor(nm)); + fr.compiled_synchronized_native_monitor(nm), false); monitors->push(info); return monitors; } @@ -202,7 +202,7 @@ GrowableArray* compiledVFrame::monitors() const { for (int index = 0; index < monitors->length(); index++) { MonitorValue* mv = monitors->at(index); StackValue *owner_sv = create_stack_value(mv->owner()); // it is an oop - result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()))); + result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()), mv->eliminated())); } return result; }