Index: vm/include/open/thread_helpers.h =================================================================== --- vm/include/open/thread_helpers.h (revision 448875) +++ vm/include/open/thread_helpers.h (working copy) @@ -44,6 +44,7 @@ char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1); char* gen_monitorenter_slow_path_helper(char *ss, const R_Opnd & input_param1); char* gen_monitor_exit_helper(char *ss, const R_Opnd & input_param1); +char* gen_monitorexit_slow_path_helper(char *ss, const R_Opnd & input_param1); #ifdef __cplusplus } Index: vm/vmcore/include/version_svn_tag.h =================================================================== --- vm/vmcore/include/version_svn_tag.h (revision 448875) +++ vm/vmcore/include/version_svn_tag.h (working copy) @@ -17,6 +17,6 @@ #ifndef _VERSION_SVN_TAG_ #define _VERSION_SVN_TAG_ -#define VERSION_SVN_TAG "448280" +#define VERSION_SVN_TAG "448874" #endif // _VERSION_SVN_TAG_ Index: vm/vmcore/src/jvmti/jvmti_object.cpp =================================================================== --- vm/vmcore/src/jvmti/jvmti_object.cpp (revision 448875) +++ vm/vmcore/src/jvmti/jvmti_object.cpp (working copy) @@ -214,7 +214,7 @@ jthread_iterator_release(&iterator); jthread_get_lock_owner(object, &info_ptr->owner); - info_ptr->entry_count = jthread_get_lock_recursion(object, info_ptr->owner) + 1; + info_ptr->entry_count = jthread_get_lock_recursion(object, info_ptr->owner); info_ptr->waiter_count = enter_wait_count; info_ptr->waiters = enter_wait_array; info_ptr->notify_waiter_count = notify_wait_count; Index: vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp =================================================================== --- vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp (revision 448875) +++ vm/vmcore/src/util/em64t/base/jit_lock_rt_support_em64t.cpp (working copy) @@ -38,7 +38,7 @@ #include "dump.h" static LilCodeStub * rth_get_lil_monitor_enter_generic(LilCodeStub * cs) { - +if(!VM_Global_State::loader_env->TI->isEnabled()) { return lil_parse_onto_end(cs, "out platform:ref:g4;" "o0 = l0;" @@ -55,7 +55,17 @@ vm_monitor_try_enter, TM_ERROR_NONE, vm_monitor_enter); +} else { + return lil_parse_onto_end(cs, + "push_m2n 0, 0;" + "out platform:ref:void;" + "o0 = l0;" + "call %0i;" + "pop_m2n;" + "ret;", + vm_monitor_enter); } +} NativeCodePtr rth_get_lil_monitor_enter_static() { static NativeCodePtr addr = NULL; @@ -172,6 +182,7 @@ /* MONITOR EXIT RUNTIME SUPPORT */ static LilCodeStub * rth_get_lil_monitor_exit_generic(LilCodeStub * cs) { +if(!VM_Global_State::loader_env->TI->isEnabled()) { return lil_parse_onto_end(cs, "call %0i;" "jc r!=%1i, illegal_monitor;" @@ -182,7 +193,17 @@ vm_monitor_try_exit, TM_ERROR_NONE, lil_npc_to_fp(exn_get_rth_throw_illegal_monitor_state())); +}else{ + return lil_parse_onto_end(cs, + "push_m2n 0, 0;" + "out platform:ref:void;" + "o0 = l0;" + "call %0i;" + "pop_m2n;" + "ret;", + vm_monitor_exit); } +} NativeCodePtr rth_get_lil_monitor_exit_static() { static NativeCodePtr addr = NULL; Index: vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp =================================================================== --- vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp (revision 448875) +++ vm/vmcore/src/util/ia32/base/jit_lock_rt_support_ia32.cpp (working copy) @@ -96,6 +96,9 @@ ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); char *backpatch_address__null_pointer = ((char *)ss) - 1; +// skip fast path if ti is enabled +// so all TI events will be generated +if(!VM_Global_State::loader_env->TI->isEnabled()) { ss = alu(ss, add_opc, ecx_opnd, Imm_Opnd(header_offset)); // pop parameters ss = gen_monitorenter_fast_path_helper(ss, ecx_opnd); ss = test(ss, eax_opnd, eax_opnd); @@ -106,7 +109,7 @@ // Slow path: happens when the monitor is busy (contention case) offset = (signed)ss - (signed)backpatch_address__fast_monitor_failed - 1; *backpatch_address__fast_monitor_failed = (char)offset; - +} ss = gen_setup_j2n_frame(ss); ss = push(ss, M_Base_Opnd(esp_reg, m2n_sizeof_m2n_frame)); @@ -186,9 +189,20 @@ ss = test(ss, ecx_opnd, ecx_opnd); ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); char *backpatch_address__null_pointer = ((char *)ss) - 1; - +// skip fast path if ti is enabled +// so all TI events will be generated +if(!VM_Global_State::loader_env->TI->isEnabled()) { ss = alu(ss, add_opc, ecx_opnd, Imm_Opnd(header_offset)); ss = gen_monitor_exit_helper(ss, ecx_opnd); +} else { + ss = gen_setup_j2n_frame(ss); + ss = push(ss, M_Base_Opnd(esp_reg, m2n_sizeof_m2n_frame)); + + ss = call(ss, (char *)oh_convert_to_local_handle); + ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters + ss = gen_monitorexit_slow_path_helper(ss, eax_opnd); + ss = gen_pop_j2n_frame(ss); +} ss = test(ss, eax_opnd, eax_opnd); ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); char *backpatch_address__fast_monitor_failed = ((char *)ss) - 1; Index: vm/thread/src/thread_java_monitors.c =================================================================== --- vm/thread/src/thread_java_monitors.c (revision 448875) +++ vm/thread/src/thread_java_monitors.c (working copy) @@ -312,6 +312,7 @@ if (ti_is_enabled()) { disable_count = reset_suspend_disable(); set_wait_monitor(monitor); + set_contended_monitor(monitor); jvmti_send_wait_monitor_event(monitor, (jlong)millis); set_suspend_disable(disable_count); @@ -422,6 +423,7 @@ suspend_status = reset_suspend_disable(); tm_java_thread->contended_monitor = (*(tm_java_thread->jenv))->NewGlobalRef(tm_java_thread->jenv, monitor); + set_suspend_disable(suspend_status); } Index: vm/thread/src/thread_helpers.cpp =================================================================== --- vm/thread/src/thread_helpers.cpp (revision 448875) +++ vm/thread/src/thread_helpers.cpp (working copy) @@ -225,6 +225,27 @@ return ss; } +/** + * Generates slow path of monitor exit. + * This code could block on monitor and contains safepoint. + * The appropriate m2n frame should be generated and + * + * @param[in] ss buffer to put the assembly code to + * @param[in] input_param1 register should point to the jobject(handle) + * If input_param1 == eax it reduces one register mov. + * the code use and do not restore ecx, edx, eax registers + * @return 0 if success in eax register + */ +char* gen_monitorexit_slow_path_helper(char *ss, const R_Opnd & input_param1) { + if (&input_param1 != &eax_opnd) { + ss = mov(ss, eax_opnd, input_param1); + } + + ss = push(ss, eax_opnd); // push the address of the handle + ss = call(ss, (char *)jthread_monitor_exit); + ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters + return ss; +} /** * Generates fast accessor to the TLS for the given key.
Index: vm/thread/src/thread_ti_monitors.c =================================================================== --- vm/thread/src/thread_ti_monitors.c (revision 448875) +++ vm/thread/src/thread_ti_monitors.c (working copy) @@ -114,11 +114,14 @@ * @param[in] mon_ptr monitor */ IDATA VMCALL jthread_raw_monitor_enter(jrawMonitorID mon_ptr) { - hythread_monitor_t monitor; + hythread_monitor_t monitor; + IDATA stat; if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { return TM_ERROR_INVALID_MONITOR; } - return hythread_monitor_enter(monitor); + stat = hythread_monitor_enter(monitor); + hythread_safe_point(); + return stat; } /** @@ -142,10 +145,13 @@ */ IDATA VMCALL jthread_raw_monitor_exit(jrawMonitorID mon_ptr) { hythread_monitor_t monitor; + IDATA stat; if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { return TM_ERROR_INVALID_MONITOR; } - return hythread_monitor_exit(monitor); + stat = hythread_monitor_exit(monitor); + hythread_safe_point(); + return stat; } /** @@ -171,10 +177,13 @@ */ IDATA VMCALL jthread_raw_monitor_wait(jrawMonitorID mon_ptr, I_64 millis) { hythread_monitor_t monitor; + IDATA stat; if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { return TM_ERROR_INVALID_MONITOR; } - return hythread_monitor_wait_interruptable(monitor, millis, 0); + stat = hythread_monitor_wait_interruptable(monitor, millis, 0); + hythread_safe_point(); + return stat; } /** Index: vm/thread/src/thread_native_thin_monitor.c =================================================================== --- vm/thread/src/thread_native_thin_monitor.c (revision 448875) +++ vm/thread/src/thread_native_thin_monitor.c (working copy) @@ -723,9 +723,17 @@ lockword = *lockword_ptr; if(IS_FAT_LOCK(lockword)) { fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); // find fat_monitor in lock table - return fat_monitor->recursion_count; + return fat_monitor->recursion_count+1; } - return RECURSION(lockword); + if(THREAD_ID(lockword) == 0) { + return 0; + } +#ifdef LOCK_RESERVATION + if (IS_RESERVED(lockword)) { + return RECURSION(lockword); + } +#endif + return RECURSION(lockword)+1; } //@}