diff --git a/build/build.bat b/build/build.bat old mode 100644 new mode 100755 diff --git a/vm/interpreter/src/interpreter.cpp b/vm/interpreter/src/interpreter.cpp index 21971ac..ca94dbb 100644 --- a/vm/interpreter/src/interpreter.cpp +++ b/vm/interpreter/src/interpreter.cpp @@ -3624,13 +3624,15 @@ interpreterGetNativeMethodAddr(Method* m return (GenericFunctionPointer) method->get_code_addr(); } - GenericFunctionPointer f = interp_find_native(method); + NativeCodePtr f = (NativeCodePtr)interp_find_native(method); + + jvmti_process_native_method_bind_event( (jmethodID) method, f, &f); // TODO: check if we need synchronization here if( f ) { - method->set_code_addr((NativeCodePtr) f); + method->set_code_addr(f); method->set_state( Method::ST_Linked ); } - return f; + return (GenericFunctionPointer)f; } diff --git a/vm/vmcore/include/jvmti_direct.h b/vm/vmcore/include/jvmti_direct.h index 7555164..b2f750b 100644 --- a/vm/vmcore/include/jvmti_direct.h +++ b/vm/vmcore/include/jvmti_direct.h @@ -113,6 +113,8 @@ void jvmti_send_class_prepare_event(Clas VMEXPORT void jvmti_send_thread_start_end_event(int is_start); void jvmti_send_vm_death_event(); bool jvmti_jit_breakpoint_handler(Registers *regs); +VMEXPORT void jvmti_process_native_method_bind_event(jmethodID method, + NativeCodePtr address, NativeCodePtr* new_address_ptr); #ifdef __cplusplus } diff --git a/vm/vmcore/src/class_support/Class.cpp b/vm/vmcore/src/class_support/Class.cpp index b5f1f1c..fc227ab 100644 --- a/vm/vmcore/src/class_support/Class.cpp +++ b/vm/vmcore/src/class_support/Class.cpp @@ -690,9 +690,13 @@ class_register_methods(Class_Handle klas // found method not_found = false; + // Calling callback for NativeMethodBind event + NativeCodePtr native_addr = methods[index].fnPtr; + jvmti_process_native_method_bind_event( (jmethodID) class_method, native_addr, &native_addr); + // lock class klass->m_lock->_lock(); - class_method->set_code_addr( methods[index].fnPtr ); + class_method->set_code_addr( native_addr ); class_method->set_registered( true ); klass->m_lock->_unlock(); break; diff --git a/vm/vmcore/src/jit/compile.cpp b/vm/vmcore/src/jit/compile.cpp index 4659285..b204b6f 100644 --- a/vm/vmcore/src/jit/compile.cpp +++ b/vm/vmcore/src/jit/compile.cpp @@ -653,8 +653,10 @@ #endif if (!func) return JIT_FAILURE; - Class* cl = method->get_class(); + // Calling callback for NativeMethodBind event + jvmti_process_native_method_bind_event( (jmethodID) method, (NativeCodePtr)func, (NativeCodePtr*)&func); + Class* cl = method->get_class(); NativeStubOverride nso = nso_find_method_override(VM_Global_State::loader_env, cl->name, method->get_name(), method->get_descriptor()); @@ -663,7 +665,6 @@ #endif if (!stub) return JIT_FAILURE; - cl->m_lock->_lock(); method->set_code_addr(stub); cl->m_lock->_unlock(); diff --git a/vm/vmcore/src/jvmti/jvmti_capability.cpp b/vm/vmcore/src/jvmti/jvmti_capability.cpp index 1a7b4bc..026b20b 100644 --- a/vm/vmcore/src/jvmti/jvmti_capability.cpp +++ b/vm/vmcore/src/jvmti/jvmti_capability.cpp @@ -61,7 +61,7 @@ static const jvmtiCapabilities jvmti_sup 1, // can_generate_compiled_method_load_events 1, // can_generate_monitor_events 0, // can_generate_vm_object_alloc_events - 0, // can_generate_native_method_bind_events + 1, // can_generate_native_method_bind_events 0, // can_generate_garbage_collection_events 0 // can_generate_object_free_events }; @@ -98,7 +98,7 @@ static const jvmtiCapabilities jvmti_sup 1, // can_generate_compiled_method_load_events 1, // can_generate_monitor_events 0, // can_generate_vm_object_alloc_events - 0, // can_generate_native_method_bind_events + 1, // can_generate_native_method_bind_events 0, // can_generate_garbage_collection_events 0 // can_generate_object_free_events }; @@ -137,7 +137,7 @@ static const jvmtiCapabilities jvmti_ena 1, // can_generate_compiled_method_load_events 0, // can_generate_monitor_events 0, // can_generate_vm_object_alloc_events - 0, // can_generate_native_method_bind_events + 1, // can_generate_native_method_bind_events 0, // can_generate_garbage_collection_events 0 // can_generate_object_free_events }; diff --git a/vm/vmcore/src/jvmti/jvmti_event.cpp b/vm/vmcore/src/jvmti/jvmti_event.cpp index aec614c..a059d29 100644 --- a/vm/vmcore/src/jvmti/jvmti_event.cpp +++ b/vm/vmcore/src/jvmti/jvmti_event.cpp @@ -856,6 +856,39 @@ jvmti_process_frame_pop_event(jvmtiEnv * } VMEXPORT void +jvmti_process_native_method_bind_event(jmethodID method, NativeCodePtr address, NativeCodePtr* new_address_ptr) +{ + DebugUtilsTI *ti = VM_Global_State::loader_env->TI; + if( !ti->isEnabled() ) + return; + + //Checking current phase + jvmtiPhase phase = ti->getPhase(); + if( phase != JVMTI_PHASE_START && phase != JVMTI_PHASE_LIVE && phase != JVMTI_PHASE_PRIMORDIAL) + return; + + assert(hythread_is_suspend_enabled()); + TRACE2("jvmti.event.bind", "Native method bind event is called for method:" + << (method ? class_get_name(method_get_class((Method*)method)) : "(nil)") << "." + << (method ? method_get_name((Method*)method) : "(nil)") + << (method ? method_get_descriptor((Method*)method) : "" ) ); + + jthread thread = getCurrentThread(); + JNIEnv *jni_env = p_TLS_vmthread->jni_env; + + for( TIEnv *ti_env = ti->getEnvironments(); ti_env; ti_env = ti_env->next ) { + //Must possess capability + jvmtiCapabilities capa; + if( JVMTI_ERROR_NONE != ((jvmtiEnv *)ti_env)->GetCapabilities(&capa) ) + return; + if( !capa.can_generate_native_method_bind_events ) + return; + if (NULL != ti_env->event_table.NativeMethodBind) + ti_env->event_table.NativeMethodBind((jvmtiEnv *)ti_env, jni_env, thread, method, address, new_address_ptr); + } +} + +VMEXPORT void jvmti_process_single_step_event(jmethodID method, jlocation location) { DebugUtilsTI *ti = VM_Global_State::loader_env->TI; if ( !ti->isEnabled() ) return; diff --git a/vm/vmcore/src/jvmti/jvmti_stack.cpp b/vm/vmcore/src/jvmti/jvmti_stack.cpp index 75c355c..6481de1 100644 --- a/vm/vmcore/src/jvmti/jvmti_stack.cpp +++ b/vm/vmcore/src/jvmti/jvmti_stack.cpp @@ -42,7 +42,12 @@ #define jvmti_test_jenv (p_TLS_vmthread- jthread getCurrentThread() { tmn_suspend_disable(); ObjectHandle hThread = oh_allocate_local_handle(); - hThread->object = (Java_java_lang_Thread *)jthread_get_java_thread(hythread_self())->object; + jthread thread = jthread_get_java_thread(hythread_self()); + if(thread) { + hThread->object = (Java_java_lang_Thread *)thread->object; + } else { + hThread->object = NULL; + } tmn_suspend_enable(); return (jthread) hThread; }