# HG changeset patch # User kamg # Date 1207320523 14400 # Node ID cf4e16e9ca602bd415784a8d494396f0d271f16a # Parent b97de546208ef43b65bc7c4dd0c6e2349693fcf1# Parent d3cd40645d0d4f8554467cf660a995a720049ef3 Merge diff -r b97de546208e -r cf4e16e9ca60 src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Thu Apr 03 12:21:06 2008 -0700 +++ b/src/cpu/sparc/vm/sparc.ad Fri Apr 04 10:48:43 2008 -0400 @@ -6023,7 +6023,7 @@ 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 @@ 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 -r b97de546208e -r cf4e16e9ca60 src/share/vm/opto/memnode.cpp --- a/src/share/vm/opto/memnode.cpp Thu Apr 03 12:21:06 2008 -0700 +++ b/src/share/vm/opto/memnode.cpp Fri Apr 04 10:48:43 2008 -0400 @@ -1122,6 +1122,12 @@ } // 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 -r b97de546208e -r cf4e16e9ca60 src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Thu Apr 03 12:21:06 2008 -0700 +++ b/src/share/vm/runtime/deoptimization.cpp Fri Apr 04 10:48:43 2008 -0400 @@ -143,6 +143,7 @@ // 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 @@ } } 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 @@ // 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 @@ 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 -r b97de546208e -r cf4e16e9ca60 src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Thu Apr 03 12:21:06 2008 -0700 +++ b/src/share/vm/runtime/deoptimization.hpp Fri Apr 04 10:48:43 2008 -0400 @@ -105,7 +105,7 @@ 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 -r b97de546208e -r cf4e16e9ca60 src/share/vm/runtime/vframe.cpp --- a/src/share/vm/runtime/vframe.cpp Thu Apr 03 12:21:06 2008 -0700 +++ b/src/share/vm/runtime/vframe.cpp Fri Apr 04 10:48:43 2008 -0400 @@ -206,7 +206,7 @@ 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 -r b97de546208e -r cf4e16e9ca60 src/share/vm/runtime/vframe.hpp --- a/src/share/vm/runtime/vframe.hpp Thu Apr 03 12:21:06 2008 -0700 +++ b/src/share/vm/runtime/vframe.hpp Fri Apr 04 10:48:43 2008 -0400 @@ -230,15 +230,18 @@ 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 -r b97de546208e -r cf4e16e9ca60 src/share/vm/runtime/vframe_hp.cpp --- a/src/share/vm/runtime/vframe_hp.cpp Thu Apr 03 12:21:06 2008 -0700 +++ b/src/share/vm/runtime/vframe_hp.cpp Fri Apr 04 10:48:43 2008 -0400 @@ -190,7 +190,7 @@ // 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 @@ 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; }