8189731: Disable CFLH when there are no transformers
Summary: Enable CFLH only when there are transformers
Reviewed-by: sspitsyn, alanb
Contributed-by: ben_walsh@uk.ibm.com
--- a/make/mapfiles/libinstrument/mapfile-vers Fri Nov 03 10:48:26 2017 -0700
+++ b/make/mapfiles/libinstrument/mapfile-vers Fri Nov 03 17:09:25 2017 -0700
@@ -31,6 +31,7 @@
Agent_OnAttach;
Java_sun_instrument_InstrumentationImpl_isModifiableClass0;
Java_sun_instrument_InstrumentationImpl_isRetransformClassesSupported0;
+ Java_sun_instrument_InstrumentationImpl_setHasTransformers;
Java_sun_instrument_InstrumentationImpl_setHasRetransformableTransformers;
Java_sun_instrument_InstrumentationImpl_retransformClasses0;
Java_sun_instrument_InstrumentationImpl_getAllLoadedClasses0;
--- a/src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java Fri Nov 03 10:48:26 2017 -0700
+++ b/src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java Fri Nov 03 17:09:25 2017 -0700
@@ -103,6 +103,9 @@
}
} else {
mTransformerManager.addTransformer(transformer);
+ if (mTransformerManager.getTransformerCount() == 1) {
+ setHasTransformers(mNativeAgent, true);
+ }
}
}
@@ -114,8 +117,12 @@
TransformerManager mgr = findTransformerManager(transformer);
if (mgr != null) {
mgr.removeTransformer(transformer);
- if (mgr.isRetransformable() && mgr.getTransformerCount() == 0) {
- setHasRetransformableTransformers(mNativeAgent, false);
+ if (mgr.getTransformerCount() == 0) {
+ if (mgr.isRetransformable()) {
+ setHasRetransformableTransformers(mNativeAgent, false);
+ } else {
+ setHasTransformers(mNativeAgent, false);
+ }
}
return true;
}
@@ -362,6 +369,9 @@
isRetransformClassesSupported0(long nativeAgent);
private native void
+ setHasTransformers(long nativeAgent, boolean has);
+
+ private native void
setHasRetransformableTransformers(long nativeAgent, boolean has);
private native void
--- a/src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c Fri Nov 03 10:48:26 2017 -0700
+++ b/src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c Fri Nov 03 17:09:25 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,6 +78,17 @@
/*
* Class: sun_instrument_InstrumentationImpl
+ * Method: setHasTransformers
+ * Signature: (Z)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_instrument_InstrumentationImpl_setHasTransformers
+ (JNIEnv * jnienv, jobject implThis, jlong agent, jboolean has) {
+ setHasTransformers(jnienv, (JPLISAgent*)(intptr_t)agent, has);
+}
+
+/*
+ * Class: sun_instrument_InstrumentationImpl
* Method: setHasRetransformableTransformers
* Signature: (Z)V
*/
--- a/src/java.instrument/share/native/libinstrument/InvocationAdapter.c Fri Nov 03 10:48:26 2017 -0700
+++ b/src/java.instrument/share/native/libinstrument/InvocationAdapter.c Fri Nov 03 17:09:25 2017 -0700
@@ -395,7 +395,7 @@
jplis_assert(success);
/*
- * Turn on the ClassFileLoadHook.
+ * Setup ClassFileLoadHook handler.
*/
if (success) {
success = setLivePhaseEventHandlers(agent);
--- a/src/java.instrument/share/native/libinstrument/JPLISAgent.c Fri Nov 03 10:48:26 2017 -0700
+++ b/src/java.instrument/share/native/libinstrument/JPLISAgent.c Fri Nov 03 17:09:25 2017 -0700
@@ -404,8 +404,8 @@
/*
- * Then turn off the VMInit handler and turn on the ClassFileLoadHook.
- * This way it is on before anyone registers a transformer.
+ * Register a handler for ClassFileLoadHook (without enabling this event).
+ * Turn off the VMInit handler.
*/
if ( result ) {
result = setLivePhaseEventHandlers(agent);
@@ -649,17 +649,6 @@
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
- if ( jvmtierror == JVMTI_ERROR_NONE ) {
- /* turn on ClassFileLoadHook */
- jvmtierror = (*jvmtienv)->SetEventNotificationMode(
- jvmtienv,
- JVMTI_ENABLE,
- JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
- NULL /* all threads */);
- check_phase_ret_false(jvmtierror);
- jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
- }
-
return (jvmtierror == JVMTI_ERROR_NONE);
}
@@ -1097,6 +1086,21 @@
}
void
+setHasTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has) {
+ jvmtiEnv * jvmtienv = jvmti(agent);
+ jvmtiError jvmtierror;
+
+ jplis_assert(jvmtienv != NULL);
+ jvmtierror = (*jvmtienv)->SetEventNotificationMode(
+ jvmtienv,
+ has? JVMTI_ENABLE : JVMTI_DISABLE,
+ JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
+ NULL /* all threads */);
+ check_phase_ret(jvmtierror);
+ jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
+}
+
+void
setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has) {
jvmtiEnv * retransformerEnv = retransformableEnvironment(agent);
jvmtiError jvmtierror;
@@ -1107,6 +1111,7 @@
has? JVMTI_ENABLE : JVMTI_DISABLE,
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
NULL /* all threads */);
+ check_phase_ret(jvmtierror);
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
}
@@ -1185,6 +1190,10 @@
deallocate(retransformerEnv, (void*)classArray);
}
+ /* Return back if we executed the JVMTI API in a wrong phase
+ */
+ check_phase_ret(errorCode);
+
if (errorCode != JVMTI_ERROR_NONE) {
createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
}
--- a/src/java.instrument/share/native/libinstrument/JPLISAgent.h Fri Nov 03 10:48:26 2017 -0700
+++ b/src/java.instrument/share/native/libinstrument/JPLISAgent.h Fri Nov 03 17:09:25 2017 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -120,7 +120,11 @@
JNIEnv * jnienv,
jthread thread);
-/* ClassFileLoadHook event handler. Installed during VMInit, then left in place forever. */
+/*
+ * ClassFileLoadHook event handler.
+ * Enabled when the first transformer is added;
+ * Disabled when the last transformer is removed.
+ */
extern void JNICALL
eventHandlerClassFileLoadHook( jvmtiEnv * jvmtienv,
JNIEnv * jnienv,
@@ -241,6 +245,9 @@
isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent);
extern void
+setHasTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);
+
+extern void
setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);
extern void