# HG changeset patch # User Christian Wimmer # Date 1323839866 28800 # Node ID b648304ba4ff2333c121f7da22e41e88bfb52a81 # Parent d6a0c46a73b2bbe76500a56abf5817ad10f1891c Change Graal monitor enter and exit from BasicObjectLock to BasicLock diff -r d6a0c46a73b2 -r b648304ba4ff src/cpu/x86/vm/c1_MacroAssembler_x86.cpp --- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Tue Dec 13 21:17:46 2011 -0800 @@ -35,7 +35,7 @@ #include "runtime/os.hpp" #include "runtime/stubRoutines.hpp" -int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case) { +int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case, bool use_basic_object_lock) { const int aligned_mask = BytesPerWord -1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction"); @@ -45,8 +45,10 @@ verify_oop(obj); - // save object being locked into the BasicObjectLock - movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj); + if (use_basic_object_lock) { + // save object being locked into the BasicObjectLock + movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj); + } if (UseBiasedLocking) { assert(scratch != noreg, "should have scratch register at this point"); @@ -98,7 +100,7 @@ } -void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) { +void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case, bool use_basic_object_lock) { const int aligned_mask = BytesPerWord -1; const int hdr_offset = oopDesc::mark_offset_in_bytes(); assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction"); @@ -106,8 +108,10 @@ Label done; if (UseBiasedLocking) { - // load object - movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); + if (use_basic_object_lock) { + // load object + movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); + } biased_locking_exit(obj, hdr, done); } @@ -118,8 +122,10 @@ // if we had recursive locking, we are done jcc(Assembler::zero, done); if (!UseBiasedLocking) { - // load object - movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); + if (use_basic_object_lock) { + // load object + movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes())); + } } verify_oop(obj); // test if object header is pointing to the displaced header, and if so, restore diff -r d6a0c46a73b2 -r b648304ba4ff src/cpu/x86/vm/c1_MacroAssembler_x86.hpp --- a/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp Tue Dec 13 21:17:46 2011 -0800 @@ -51,13 +51,13 @@ // disp_hdr: must point to the displaced header location, contents preserved // scratch : scratch register, contents destroyed // returns code offset at which to add null check debug information - int lock_object (Register swap, Register obj, Register disp_hdr, Register scratch, Label& slow_case); + int lock_object (Register swap, Register obj, Register disp_hdr, Register scratch, Label& slow_case, bool use_basic_object_lock = true); // unlocking // hdr : contents destroyed // obj : must point to the object to lock, contents preserved // disp_hdr: must be eax & must point to the displaced header location, contents destroyed - void unlock_object(Register swap, Register obj, Register lock, Label& slow_case); + void unlock_object(Register swap, Register obj, Register lock, Label& slow_case, bool use_basic_object_lock = true); void initialize_object( Register obj, // result: pointer to object after successful allocation diff -r d6a0c46a73b2 -r b648304ba4ff src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp Tue Dec 13 21:17:46 2011 -0800 @@ -2067,17 +2067,17 @@ // copied from LIR_Assembler::emit_lock if (UseFastLocking) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); - __ lock_object(scratch1, obj, lock, scratch2, slow_case); + __ lock_object(scratch1, obj, lock, scratch2, slow_case, false); __ ret(0); } __ bind(slow_case); { StubFrame f(sasm, "graal_monitorenter", dont_gc_arguments); - OopMap* map = save_live_registers(sasm, 1, save_fpu_registers); + OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); // Called with store_parameter and not C abi - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), obj, lock); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_monitorenter), obj, lock); oop_maps = new OopMapSet(); oop_maps->add_gc_map(call_offset, map); @@ -2101,7 +2101,7 @@ // copied from LIR_Assembler::emit_lock if (UseFastLocking) { assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); - __ unlock_object(scratch1, obj, lock2, slow_case); + __ unlock_object(scratch1, obj, lock2, slow_case, false); __ ret(0); } @@ -2113,7 +2113,7 @@ // note: really a leaf routine but must setup last java sp // => use call_RT for now (speed can be improved by // doing last java sp setup manually) - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), lock); + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_monitorexit), obj, lock); oop_maps = new OopMapSet(); oop_maps->add_gc_map(call_offset, map); diff -r d6a0c46a73b2 -r b648304ba4ff src/share/vm/c1/c1_Runtime1.cpp --- a/src/share/vm/c1/c1_Runtime1.cpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/share/vm/c1/c1_Runtime1.cpp Tue Dec 13 21:17:46 2011 -0800 @@ -658,6 +658,68 @@ JRT_END +JRT_ENTRY_NO_ASYNC(void, Runtime1::graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock)) + NOT_PRODUCT(_monitorenter_slowcase_cnt++;) +#ifdef ASSERT + if (TraceGraal >= 3) { + tty->print_cr("entered locking slow case with obj=" INTPTR_FORMAT " and lock= " INTPTR_FORMAT, obj, lock); + } + if (PrintBiasedLockingStatistics) { + Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); + } +#endif + Handle h_obj(thread, obj); + assert(h_obj()->is_oop(), "must be NULL or an object"); + if (UseBiasedLocking) { + // Retry fast entry if bias is revoked to avoid unnecessary inflation + ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK); + } else { + if (UseFastLocking) { + // When using fast locking, the compiled code has already tried the fast case + ObjectSynchronizer::slow_enter(h_obj, lock, THREAD); + } else { + ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD); + } + } +#ifdef ASSERT + if (TraceGraal >= 3) { + tty->print_cr("exiting locking"); + lock->lock()->print_on(tty); + tty->print_cr(""); + tty->print_cr("done"); + } +#endif +JRT_END + + +JRT_LEAF(void, Runtime1::graal_monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock)) + NOT_PRODUCT(_monitorexit_slowcase_cnt++;) + assert(thread == JavaThread::current(), "threads must correspond"); + assert(thread->last_Java_sp(), "last_Java_sp must be set"); + // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown + EXCEPTION_MARK; + +#ifdef DEBUG + if (!obj->is_oop()) { + ResetNoHandleMark rhm; + nmethod* method = thread->last_frame().cb()->as_nmethod_or_null(); + if (method != NULL) { + tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj); + } + thread->print_stack_on(tty); + assert(false, "invalid lock object pointer dected"); + } +#endif + + if (UseFastLocking) { + // When using fast locking, the compiled code has already tried the fast case + ObjectSynchronizer::slow_exit(obj, lock, THREAD); + } else { + ObjectSynchronizer::fast_exit(obj, lock, THREAD); + } +JRT_END + + JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock)) NOT_PRODUCT(_monitorenter_slowcase_cnt++;) #ifdef ASSERT diff -r d6a0c46a73b2 -r b648304ba4ff src/share/vm/c1/c1_Runtime1.hpp --- a/src/share/vm/c1/c1_Runtime1.hpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/share/vm/c1/c1_Runtime1.hpp Tue Dec 13 21:17:46 2011 -0800 @@ -164,6 +164,9 @@ static void throw_incompatible_class_change_error(JavaThread* thread); static void throw_array_store_exception(JavaThread* thread, oopDesc* object); + static void graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock); + static void graal_monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock); + static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock); static void monitorexit (JavaThread* thread, BasicObjectLock* lock); diff -r d6a0c46a73b2 -r b648304ba4ff src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Dec 13 21:17:46 2011 -0800 @@ -212,6 +212,7 @@ template(CiCodePos_klass, com_sun_cri_ci_CiCodePos, Opt) \ template(CiConstant_klass, com_sun_cri_ci_CiConstant, Opt) \ template(CiVirtualObject_klass, com_sun_cri_ci_CiVirtualObject, Opt) \ + template(CiMonitorValue_klass, com_sun_cri_ci_CiMonitorValue, Opt) \ template(CiKind_klass, com_sun_cri_ci_CiKind, Opt) \ template(CiRuntimeCall_klass, com_sun_cri_ci_CiRuntimeCall, Opt) \ template(RiMethod_klass, com_sun_cri_ri_RiMethod, Opt) \ diff -r d6a0c46a73b2 -r b648304ba4ff src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Dec 13 21:17:46 2011 -0800 @@ -300,6 +300,7 @@ template(com_sun_cri_ci_CiCodePos, "com/sun/cri/ci/CiCodePos") \ template(com_sun_cri_ci_CiConstant, "com/sun/cri/ci/CiConstant") \ template(com_sun_cri_ci_CiVirtualObject, "com/sun/cri/ci/CiVirtualObject") \ + template(com_sun_cri_ci_CiMonitorValue, "com/sun/cri/ci/CiMonitorValue") \ template(com_sun_cri_ci_CiKind, "com/sun/cri/ci/CiKind") \ template(com_sun_cri_ci_CiRuntimeCall, "com/sun/cri/ci/CiRuntimeCall") \ template(startCompiler_name, "startCompiler") \ diff -r d6a0c46a73b2 -r b648304ba4ff src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Tue Dec 13 21:17:46 2011 -0800 @@ -221,6 +221,23 @@ return NULL; } +static MonitorValue* get_monitor_value(oop value, int frame_size, GrowableArray* objects) { + guarantee(value->is_a(CiMonitorValue::klass()), "Monitors must be of type CiMonitorValue"); + + ScopeValue* second = NULL; + ScopeValue* owner_value = get_hotspot_value(CiMonitorValue::owner(value), frame_size, objects, second); + assert(second == NULL, "monitor cannot occupy two stack slots"); + + ScopeValue* lock_data_value = get_hotspot_value(CiMonitorValue::lockData(value), frame_size, objects, second); + assert(second == NULL, "monitor cannot occupy two stack slots"); + assert(lock_data_value->is_location(), "invalid monitor location"); + Location lock_data_loc = ((LocationValue*)lock_data_value)->location(); + + bool eliminated = CiMonitorValue::eliminated(value); + + return new MonitorValue(owner_value, lock_data_loc, eliminated); +} + void CodeInstaller::initialize_assumptions(oop target_method) { _oop_recorder = new OopRecorder(_env->arena()); _env->set_oop_recorder(_oop_recorder); @@ -488,26 +505,22 @@ for (jint i = 0; i < values->length(); i++) { ScopeValue* second = NULL; - ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size, objects, second); + oop value = ((oop*) values->base(T_OBJECT))[i]; if (i < local_count) { + ScopeValue* first = get_hotspot_value(value, _frame_size, objects, second); if (second != NULL) { locals->append(second); } - locals->append(value); + locals->append(first); } else if (i < local_count + expression_count) { + ScopeValue* first = get_hotspot_value(value, _frame_size, objects, second); if (second != NULL) { - expressions->append(value); + expressions->append(second); } - expressions->append(value); + expressions->append(first); } else { - assert(second == NULL, "monitor cannot occupy two stack slots"); - assert(value->is_location(), "invalid monitor location"); - LocationValue* loc = (LocationValue*)value; - int monitor_offset = loc->location().stack_offset(); - LocationValue* obj = new LocationValue(Location::new_stk_loc(Location::oop, monitor_offset + BasicObjectLock::obj_offset_in_bytes())); - bool eliminated = value->is_object(); - monitors->append(new MonitorValue(obj, Location::new_stk_loc(Location::normal, monitor_offset + BasicObjectLock::lock_offset_in_bytes()), eliminated)); + monitors->append(get_monitor_value(value, _frame_size, objects)); } if (second != NULL) { i++; diff -r d6a0c46a73b2 -r b648304ba4ff src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Tue Dec 13 21:16:50 2011 -0800 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Dec 13 21:17:46 2011 -0800 @@ -220,6 +220,11 @@ oop_field(CiVirtualObject, type, "Lcom/sun/cri/ri/RiType;") \ oop_field(CiVirtualObject, values, "[Lcom/sun/cri/ci/CiValue;") \ end_class \ + start_class(CiMonitorValue) \ + oop_field(CiMonitorValue, owner, "Lcom/sun/cri/ci/CiValue;") \ + oop_field(CiMonitorValue, lockData, "Lcom/sun/cri/ci/CiValue;") \ + boolean_field(CiMonitorValue, eliminated) \ + end_class \ start_class(RiTypeProfile) \ int_field(RiTypeProfile, count) \ int_field(RiTypeProfile, morphism) \