8189731: Disable CFLH when there are no transformers
authorsspitsyn
Fri, 03 Nov 2017 17:09:25 -0700
changeset 47777 d85284ccd1bd
parent 47776 52e85a3fa0ab
child 47778 46cb6af585d4
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
make/mapfiles/libinstrument/mapfile-vers
src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java
src/java.instrument/share/native/libinstrument/InstrumentationImplNativeMethods.c
src/java.instrument/share/native/libinstrument/InvocationAdapter.c
src/java.instrument/share/native/libinstrument/JPLISAgent.c
src/java.instrument/share/native/libinstrument/JPLISAgent.h
--- 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