From 209e563f5c014dacd62317e1920887d91dea0ec8 Mon Sep 17 00:00:00 2001 From: Salikh Zakirov Date: Thu, 30 Nov 2006 14:40:33 +0300 Subject: [PATCH] configure TM_LOCK_RESERVATION from -Dthread.lock_reservation --- vm/thread/src/hythr.def | 1 + vm/thread/src/hythr.exp | 1 + vm/thread/src/thread_helpers.cpp | 24 ++++++-- vm/thread/src/thread_init.c | 3 + vm/thread/src/thread_java_monitors.c | 4 + vm/thread/src/thread_native_thin_monitor.c | 84 ++++++++++++++++++---------- vm/thread/src/thread_private.h | 1 - vm/vmcore/src/init/parse_arguments.cpp | 3 + vm/vmcore/src/init/vm_init.cpp | 5 ++ vm/vmcore/src/init/vm_properties.cpp | 1 + vm/vmcore/src/thread/mon_enter_exit.cpp | 1 + 11 files changed, 92 insertions(+), 36 deletions(-) diff --git a/vm/thread/src/hythr.def b/vm/thread/src/hythr.def index 09eb9b9..8829955 100644 --- a/vm/thread/src/hythr.def +++ b/vm/thread/src/hythr.def @@ -148,3 +148,4 @@ array_delete array_get get_local_pool get_java_thread_group +TM_LOCK_RESERVATION diff --git a/vm/thread/src/hythr.exp b/vm/thread/src/hythr.exp index a9dc440..d225033 100644 --- a/vm/thread/src/hythr.exp +++ b/vm/thread/src/hythr.exp @@ -159,6 +159,7 @@ array_delete; array_get; get_local_pool; get_java_thread_group; +TM_LOCK_RESERVATION; local: *; diff --git a/vm/thread/src/thread_helpers.cpp b/vm/thread/src/thread_helpers.cpp index df52fa8..7bad03c 100644 --- a/vm/thread/src/thread_helpers.cpp +++ b/vm/thread/src/thread_helpers.cpp @@ -37,6 +37,8 @@ #include +//XXX: hack +extern "C" __declspec(dllimport) unsigned TM_LOCK_RESERVATION; /** * Generates tmn_self() call. @@ -83,6 +85,9 @@ char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) { ss = gen_hythread_self_helper(ss); ss = mov(ss, edx_opnd, M_Base_Opnd(eax_reg, (uint32)&((HyThread *)0)->thread_id) ); #ifdef LOCK_RESERVATION + char *backpatch_address__recursion_inc = NULL; + char *backpatch_address__inline_monitor_failed = NULL; + if (TM_LOCK_RESERVATION) { //get lock_id ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 0)); // move thread_id to AX @@ -91,14 +96,17 @@ char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) { // test this recursion call ss = alu(ss, cmp_opc, edx_opnd, eax_opnd, size_16); ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); - char *backpatch_address__recursion_inc = ((char *)ss) - 1; + backpatch_address__recursion_inc = ((char *)ss) - 1; // test the lock is busy ss = test(ss, eax_opnd, eax_opnd, size_16); ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); - char *backpatch_address__inline_monitor_failed = ((char *)ss) - 1; -#else + backpatch_address__inline_monitor_failed = ((char *)ss) - 1; + } else { +#endif ss = alu(ss, xor_opc, eax_opnd, eax_opnd); +#ifdef LOCK_RESERVATION + } #endif // the lock is free or not reserved ss = prefix(ss, lock_prefix); @@ -107,17 +115,22 @@ char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) { char *backpatch_address__inline_monitor_failed2 = ((char *)ss) - 1; #ifdef LOCK_RESERVATION + char *backpatch_address__recursion_inc2 = NULL; + if (TM_LOCK_RESERVATION) { // if this is initial reservation also increase the recursion ss = mov(ss, edx_opnd, eax_opnd); // eax stil ROR so ROR the mask ss = alu(ss, and_opc, edx_opnd, Imm_Opnd(0x0400ffff)); ss = test(ss, edx_opnd, edx_opnd); ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); - char *backpatch_address__recursion_inc2 = ((char *)ss) - 1; + backpatch_address__recursion_inc2 = ((char *)ss) - 1; + } #endif ss = ret(ss, Imm_Opnd(4)); #ifdef LOCK_RESERVATION + char *backpatch_address__inline_monitor_failed3 = NULL; + if (TM_LOCK_RESERVATION) { // increase recurison branch signed offset = (signed)ss - (signed)backpatch_address__recursion_inc - 1; *backpatch_address__recursion_inc = (char)offset; @@ -126,7 +139,7 @@ char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) { // eax stil ROR so ROR the mask ss = alu(ss, cmp_opc, eax_opnd, Imm_Opnd(0xf4000000)); ss = branch8(ss, Condition_A, Imm_Opnd(size_8, 0)); - char *backpatch_address__inline_monitor_failed3 = ((char *)ss) - 1; + backpatch_address__inline_monitor_failed3 = ((char *)ss) - 1; offset2 = (signed)ss - (signed)backpatch_address__recursion_inc2 - 1; *backpatch_address__recursion_inc2 = (char)offset2; @@ -142,6 +155,7 @@ char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) { *backpatch_address__inline_monitor_failed = (char)offset; offset = (signed)ss - (signed)backpatch_address__inline_monitor_failed3 - 1; *backpatch_address__inline_monitor_failed3 = (char)offset; + } #endif offset2 = (signed)ss - (signed)backpatch_address__inline_monitor_failed2 - 1; *backpatch_address__inline_monitor_failed2 = (char)offset2; diff --git a/vm/thread/src/thread_init.c b/vm/thread/src/thread_init.c index 3f2e119..40a4ec0 100644 --- a/vm/thread/src/thread_init.c +++ b/vm/thread/src/thread_init.c @@ -58,6 +58,9 @@ int table_size = 8024; IDATA groups_count; +/// global switch to disable lock reservation algorithm +unsigned TM_LOCK_RESERVATION = 1; + static IDATA init_group_list(); static IDATA destroy_group_list(); diff --git a/vm/thread/src/thread_java_monitors.c b/vm/thread/src/thread_java_monitors.c index 9d125d0..99a7639 100644 --- a/vm/thread/src/thread_java_monitors.c +++ b/vm/thread/src/thread_java_monitors.c @@ -60,6 +60,8 @@ IDATA VMCALL jthread_monitor_init(jobject monitor) { } +/// global switch to enable lock reservation +extern unsigned TM_LOCK_RESERVATION; /** * Gains the ownership over monitor. @@ -88,6 +90,7 @@ IDATA VMCALL jthread_monitor_enter(jobject monitor) { ///////// #ifdef LOCK_RESERVATION + if (TM_LOCK_RESERVATION) { // busy unreserve lock before blocking and inflating while (TM_ERROR_NONE !=unreserve_lock(lockword)) { hythread_yield(); @@ -98,6 +101,7 @@ IDATA VMCALL jthread_monitor_enter(jobject monitor) { if (status != TM_ERROR_EBUSY) { goto entered; } + } #endif //LOCK_RESERVATION tm_native_thread = hythread_self(); tm_native_thread->state &= ~TM_THREAD_STATE_RUNNABLE; diff --git a/vm/thread/src/thread_native_thin_monitor.c b/vm/thread/src/thread_native_thin_monitor.c index 5dbd2f3..fe1eecc 100644 --- a/vm/thread/src/thread_native_thin_monitor.c +++ b/vm/thread/src/thread_native_thin_monitor.c @@ -62,21 +62,27 @@ #define RECURSION_DEC(lockword_ptr, lockword) (*lockword_ptr=lockword - (1<<11)) #define MAX_RECURSION 31 +/// global switch to enable lock reservation +extern unsigned TM_LOCK_RESERVATION; + IDATA owns_thin_lock(hythread_t thread, I_32 lockword) { IDATA this_id = thread->thread_id; assert(!IS_FAT_LOCK(lockword)); #ifdef LOCK_RESERVATION + if (TM_LOCK_RESERVATION) { return THREAD_ID(lockword) == this_id && (!IS_RESERVED(lockword) || RECURSION(lockword) !=0); -#else - return THREAD_ID(lockword) == this_id; + } #endif + return THREAD_ID(lockword) == this_id; } void set_fat_lock_id(hythread_thin_monitor_t *lockword_ptr, IDATA monitor_id) { I_32 lockword = *lockword_ptr; #ifdef LOCK_RESERVATION + if (TM_LOCK_RESERVATION) { assert(!IS_RESERVED(lockword)); + } #endif lockword&=0x7FF; lockword|=(monitor_id << 11) | 0x80000000; @@ -112,7 +118,7 @@ extern hymutex_t TM_LOCK; /* * Unreserves the lock already owned by this thread */ -void unreserve_self_lock(hythread_thin_monitor_t *lockword_ptr) { +static void unreserve_self_lock(hythread_thin_monitor_t *lockword_ptr) { I_32 lockword = *lockword_ptr; I_32 lockword_new; TRACE(("unreserve self_id %d lock owner %d", hythread_get_id(hythread_self()), THREAD_ID(lockword))); @@ -142,6 +148,10 @@ IDATA unreserve_lock(hythread_thin_monitor_t *lockword_ptr) { uint16 lock_id; hythread_t owner; IDATA status; + + if (!TM_LOCK_RESERVATION) + return TM_ERROR_NONE; + // trylock used to prevent cyclic suspend deadlock // the java_monitor_enter calls safe_point between attempts. /* status = hymutex_trylock(TM_LOCK); @@ -293,10 +303,12 @@ IDATA hythread_thin_monitor_try_enter(hythread_thin_monitor_t *lockword_ptr) { } #ifdef LOCK_RESERVATION - //lockword = *lockword_ptr; // this reloading of lockword may be odd, need to investigate; - if (IS_RESERVED(lockword)) { - TRACE(("initialy reserve lock %x count: %d ", *lockword_ptr, init_reserve_cout++)); - RECURSION_INC(lockword_ptr, *lockword_ptr); + if (TM_LOCK_RESERVATION) { + //lockword = *lockword_ptr; // this reloading of lockword may be odd, need to investigate; + if (IS_RESERVED(lockword)) { + TRACE(("initialy reserve lock %x count: %d ", *lockword_ptr, init_reserve_cout++)); + RECURSION_INC(lockword_ptr, *lockword_ptr); + } } #endif TRACE(("CAS lock %x count: %d ", *lockword_ptr, cas_cout++)); @@ -318,19 +330,21 @@ IDATA hythread_thin_monitor_try_enter(hythread_thin_monitor_t *lockword_ptr) { } #ifdef LOCK_RESERVATION - // unreserved busy lock - else if (IS_RESERVED(lockword)) { - status = unreserve_lock(lockword_ptr); - if (status != TM_ERROR_NONE) { + else if (TM_LOCK_RESERVATION) { + // unreserved busy lock + if (IS_RESERVED(lockword)) { + status = unreserve_lock(lockword_ptr); + if (status != TM_ERROR_NONE) { #ifdef SPIN_COUNT - if (status == TM_ERROR_EBUSY) { - continue; - } + if (status == TM_ERROR_EBUSY) { + continue; + } #endif //SPIN_COUNT - return status; + return status; + } + assert(!IS_RESERVED(*lockword_ptr)); + return hythread_thin_monitor_try_enter(lockword_ptr); } - assert(!IS_RESERVED(*lockword_ptr)); - return hythread_thin_monitor_try_enter(lockword_ptr); } #endif #ifdef SPIN_COUNT @@ -393,9 +407,11 @@ IDATA VMCALL hythread_thin_monitor_exit(hythread_thin_monitor_t *lockword_ptr) { if (THREAD_ID(lockword) == this_id) { if (RECURSION(lockword)==0) { #ifdef LOCK_RESERVATION - if (IS_RESERVED(lockword)) { - TRACE(("ILLEGAL_STATE %x\n", lockword)); - return TM_ERROR_ILLEGAL_STATE; + if (TM_LOCK_RESERVATION) { + if (IS_RESERVED(lockword)) { + TRACE(("ILLEGAL_STATE %x\n", lockword)); + return TM_ERROR_ILLEGAL_STATE; + } } #endif *lockword_ptr = lockword & 0xffff; @@ -571,12 +587,14 @@ hythread_monitor_t VMCALL inflate_lock(hythread_thin_monitor_t *lockword_ptr) { return locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); } #ifdef LOCK_RESERVATION - // unreserve lock first - if (IS_RESERVED(lockword)) { - unreserve_self_lock(lockword_ptr); - lockword = *lockword_ptr; + if (TM_LOCK_RESERVATION) { + // unreserve lock first + if (IS_RESERVED(lockword)) { + unreserve_self_lock(lockword_ptr); + lockword = *lockword_ptr; + } + assert(!IS_RESERVED(lockword)); } - assert(!IS_RESERVED(lockword)); #endif assert(owns_thin_lock(tm_self_tls, lockword)); @@ -606,7 +624,9 @@ hythread_monitor_t VMCALL inflate_lock(hythread_thin_monitor_t *lockword_ptr) { status=hymutex_unlock(FAT_MONITOR_TABLE_LOCK); assert (status == TM_ERROR_NONE); #ifdef LOCK_RESERVATION - assert(!IS_RESERVED(*lockword_ptr)); + if (TM_LOCK_RESERVATION) { + assert(!IS_RESERVED(*lockword_ptr)); + } #endif return fat_monitor; } @@ -710,8 +730,10 @@ hythread_t VMCALL hythread_thin_monitor_get_owner(hythread_thin_monitor_t *lockw } #ifdef LOCK_RESERVATION - if (RECURSION(lockword)==0 && IS_RESERVED(lockword)) { - return NULL; + if (TM_LOCK_RESERVATION) { + if (RECURSION(lockword)==0 && IS_RESERVED(lockword)) { + return NULL; + } } #endif return hythread_get_thread(THREAD_ID(lockword)); @@ -736,8 +758,10 @@ IDATA VMCALL hythread_thin_monitor_get_recursion(hythread_thin_monitor_t *lockwo return 0; } #ifdef LOCK_RESERVATION - if (IS_RESERVED(lockword)) { - return RECURSION(lockword); + if (TM_LOCK_RESERVATION) { + if (IS_RESERVED(lockword)) { + return RECURSION(lockword); + } } #endif return RECURSION(lockword)+1; diff --git a/vm/thread/src/thread_private.h b/vm/thread/src/thread_private.h index f3b5354..ce7912d 100644 --- a/vm/thread/src/thread_private.h +++ b/vm/thread/src/thread_private.h @@ -150,7 +150,6 @@ extern int16 tm_tls_capacity; */ extern int16 tm_tls_size; - typedef struct HyThreadLibrary { IDATA a; hymutex_t TM_LOCK; diff --git a/vm/vmcore/src/init/parse_arguments.cpp b/vm/vmcore/src/init/parse_arguments.cpp index a798e55..c370b1c 100644 --- a/vm/vmcore/src/init/parse_arguments.cpp +++ b/vm/vmcore/src/init/parse_arguments.cpp @@ -220,6 +220,9 @@ void print_vm_standard_properties() #endif // PLATFORM_POSIX ECHO("Boolean-valued properties (set to one of {on,true,1,off,false,0} through -XD=):\n\n" + " thread.lock_reservation (default TRUE):\n" + " If false, disables lock reservation optimization on the platforms where\n" + " lock reservation is implemented. Has no effect on other platforms.\n" " vm.assert_dialog (default TRUE):\n" " If false, prevent assertion failures from popping up a dialog box.\n" PLATFORM_POSIX_STANDARD_PROPERTIES diff --git a/vm/vmcore/src/init/vm_init.cpp b/vm/vmcore/src/init/vm_init.cpp index 3082a8c..83e94f2 100644 --- a/vm/vmcore/src/init/vm_init.cpp +++ b/vm/vmcore/src/init/vm_init.cpp @@ -628,6 +628,8 @@ jint vm_attach_internal(JNIEnv ** p_jni_env, jthread * java_thread, JavaVM * jav return status; } +extern "C" __declspec(dllimport) unsigned TM_LOCK_RESERVATION; + /** * First VM initialization step. At that moment neither JNI is available * nor main thread is attached to VM. @@ -675,6 +677,9 @@ int vm_init1(JavaVM_Internal * java_vm, JavaVMInitArgs * vm_arguments) { initialize_properties(vm_env); + // FIXME: move this check to appropriate place + TM_LOCK_RESERVATION = get_boolean_property("thread.lock_reservation", TRUE, VM_PROPERTIES); + parse_vm_arguments(vm_env); // "Tool Interface" enabling. diff --git a/vm/vmcore/src/init/vm_properties.cpp b/vm/vmcore/src/init/vm_properties.cpp index 92c0236..553b859 100644 --- a/vm/vmcore/src/init/vm_properties.cpp +++ b/vm/vmcore/src/init/vm_properties.cpp @@ -261,6 +261,7 @@ static void init_java_properties(Properties & properties) //vm part static void init_vm_properties(Properties & properties) { + properties.set("thread.lock_reservation", "true"); properties.set("vm.assert_dialog", "true"); properties.set("vm.crash_handler", "false"); properties.set("vm.finalize", "true"); diff --git a/vm/vmcore/src/thread/mon_enter_exit.cpp b/vm/vmcore/src/thread/mon_enter_exit.cpp index 3444933..4dd83d0 100644 --- a/vm/vmcore/src/thread/mon_enter_exit.cpp +++ b/vm/vmcore/src/thread/mon_enter_exit.cpp @@ -69,6 +69,7 @@ void vm_enumerate_root_set_mon_arrays() { } + void vm_monitor_init() { vm_monitor_enter = vm_monitor_enter_default; -- 1.4.4.1.gc94a