8189731: Disable CFLH when there are no transformers

Enable CFLH only when there are transformers

Reviewed-by: sspitsyn, alanb
This commit is contained in:
Ben Walsh 2017-11-03 17:09:25 -07:00 committed by Serguei Spitsyn
parent c39d2071f0
commit c07d8e1981
6 changed files with 57 additions and 19 deletions

View File

@ -31,6 +31,7 @@ SUNWprivate_1.1 {
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;

View File

@ -103,6 +103,9 @@ public class InstrumentationImpl implements Instrumentation {
}
} else {
mTransformerManager.addTransformer(transformer);
if (mTransformerManager.getTransformerCount() == 1) {
setHasTransformers(mNativeAgent, true);
}
}
}
@ -114,8 +117,12 @@ public class InstrumentationImpl implements Instrumentation {
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;
}
@ -361,6 +368,9 @@ public class InstrumentationImpl implements Instrumentation {
private native boolean
isRetransformClassesSupported0(long nativeAgent);
private native void
setHasTransformers(long nativeAgent, boolean has);
private native void
setHasRetransformableTransformers(long nativeAgent, boolean has);

View File

@ -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
@ -76,6 +76,17 @@ Java_sun_instrument_InstrumentationImpl_isRetransformClassesSupported0
return isRetransformClassesSupported(jnienv, (JPLISAgent*)(intptr_t)agent);
}
/*
* 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

View File

@ -395,7 +395,7 @@ DEF_Agent_OnAttach(JavaVM* vm, char *args, void * reserved) {
jplis_assert(success);
/*
* Turn on the ClassFileLoadHook.
* Setup ClassFileLoadHook handler.
*/
if (success) {
success = setLivePhaseEventHandlers(agent);

View File

@ -404,8 +404,8 @@ processJavaStart( JPLISAgent * agent,
/*
* 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 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
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);
}
@ -1096,6 +1085,21 @@ isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent) {
return agent->mRetransformEnvironment.mIsRetransformer;
}
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);
@ -1107,6 +1111,7 @@ setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean
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 @@ retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes) {
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);
}

View File

@ -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 @@ eventHandlerVMInit( jvmtiEnv * jvmtienv,
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,
@ -240,6 +244,9 @@ isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz);
extern jboolean
isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent);
extern void
setHasTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);
extern void
setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has);