6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
Tolerate JVMTI_ERROR_WRONG_PHASE return codes so that JLI methods can be called to the end of VM's life. Reviewed-by: ohair, sspitsyn
This commit is contained in:
parent
ff7433606c
commit
43ac52cdce
@ -626,6 +626,7 @@ appendClassPath( JPLISAgent* agent,
|
|||||||
jvmtiError jvmtierr;
|
jvmtiError jvmtierr;
|
||||||
|
|
||||||
jvmtierr = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, jarfile);
|
jvmtierr = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, jarfile);
|
||||||
|
check_phase_ret_1(jvmtierr);
|
||||||
|
|
||||||
if (jvmtierr == JVMTI_ERROR_NONE) {
|
if (jvmtierr == JVMTI_ERROR_NONE) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -634,6 +635,7 @@ appendClassPath( JPLISAgent* agent,
|
|||||||
jvmtiError err;
|
jvmtiError err;
|
||||||
|
|
||||||
err = (*jvmtienv)->GetPhase(jvmtienv, &phase);
|
err = (*jvmtienv)->GetPhase(jvmtienv, &phase);
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(err == JVMTI_ERROR_NONE);
|
jplis_assert(err == JVMTI_ERROR_NONE);
|
||||||
|
|
||||||
if (phase == JVMTI_PHASE_LIVE) {
|
if (phase == JVMTI_PHASE_LIVE) {
|
||||||
@ -805,6 +807,8 @@ appendBootClassPath( JPLISAgent* agent,
|
|||||||
|
|
||||||
/* print warning if boot class path not updated */
|
/* print warning if boot class path not updated */
|
||||||
if (jvmtierr != JVMTI_ERROR_NONE) {
|
if (jvmtierr != JVMTI_ERROR_NONE) {
|
||||||
|
check_phase_blob_ret(jvmtierr, free(path));
|
||||||
|
|
||||||
fprintf(stderr, "WARNING: %s not added to bootstrap class loader search: ", path);
|
fprintf(stderr, "WARNING: %s not added to bootstrap class loader search: ", path);
|
||||||
switch (jvmtierr) {
|
switch (jvmtierr) {
|
||||||
case JVMTI_ERROR_ILLEGAL_ARGUMENT :
|
case JVMTI_ERROR_ILLEGAL_ARGUMENT :
|
||||||
|
@ -179,6 +179,7 @@ getJPLISEnvironment(jvmtiEnv * jvmtienv) {
|
|||||||
jvmtierror = (*jvmtienv)->GetEnvironmentLocalStorage(
|
jvmtierror = (*jvmtienv)->GetEnvironmentLocalStorage(
|
||||||
jvmtienv,
|
jvmtienv,
|
||||||
(void**)&environment);
|
(void**)&environment);
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
|
|
||||||
if (jvmtierror == JVMTI_ERROR_NONE) {
|
if (jvmtierror == JVMTI_ERROR_NONE) {
|
||||||
@ -230,6 +231,7 @@ createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr) {
|
|||||||
/* don't leak envs */
|
/* don't leak envs */
|
||||||
if ( initerror != JPLIS_INIT_ERROR_NONE ) {
|
if ( initerror != JPLIS_INIT_ERROR_NONE ) {
|
||||||
jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv);
|
jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv);
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -277,6 +279,7 @@ initializeJPLISAgent( JPLISAgent * agent,
|
|||||||
jvmtierror = (*jvmtienv)->SetEnvironmentLocalStorage(
|
jvmtierror = (*jvmtienv)->SetEnvironmentLocalStorage(
|
||||||
jvmtienv,
|
jvmtienv,
|
||||||
&(agent->mNormalEnvironment));
|
&(agent->mNormalEnvironment));
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
|
|
||||||
/* check what capabilities are available */
|
/* check what capabilities are available */
|
||||||
@ -284,11 +287,17 @@ initializeJPLISAgent( JPLISAgent * agent,
|
|||||||
|
|
||||||
/* check phase - if live phase then we don't need the VMInit event */
|
/* check phase - if live phase then we don't need the VMInit event */
|
||||||
jvmtierror = (*jvmtienv)->GetPhase(jvmtienv, &phase);
|
jvmtierror = (*jvmtienv)->GetPhase(jvmtienv, &phase);
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
if (phase == JVMTI_PHASE_LIVE) {
|
if (phase == JVMTI_PHASE_LIVE) {
|
||||||
return JPLIS_INIT_ERROR_NONE;
|
return JPLIS_INIT_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (phase != JVMTI_PHASE_ONLOAD) {
|
||||||
|
/* called too early or called too late; either way bail out */
|
||||||
|
return JPLIS_INIT_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
/* now turn on the VMInit event */
|
/* now turn on the VMInit event */
|
||||||
if ( jvmtierror == JVMTI_ERROR_NONE ) {
|
if ( jvmtierror == JVMTI_ERROR_NONE ) {
|
||||||
jvmtiEventCallbacks callbacks;
|
jvmtiEventCallbacks callbacks;
|
||||||
@ -298,6 +307,7 @@ initializeJPLISAgent( JPLISAgent * agent,
|
|||||||
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
|
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
|
||||||
&callbacks,
|
&callbacks,
|
||||||
sizeof(callbacks));
|
sizeof(callbacks));
|
||||||
|
check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +317,7 @@ initializeJPLISAgent( JPLISAgent * agent,
|
|||||||
JVMTI_ENABLE,
|
JVMTI_ENABLE,
|
||||||
JVMTI_EVENT_VM_INIT,
|
JVMTI_EVENT_VM_INIT,
|
||||||
NULL /* all threads */);
|
NULL /* all threads */);
|
||||||
|
check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,6 +633,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
|
|||||||
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
|
jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
|
||||||
&callbacks,
|
&callbacks,
|
||||||
sizeof(callbacks));
|
sizeof(callbacks));
|
||||||
|
check_phase_ret_false(jvmtierror);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
|
|
||||||
|
|
||||||
@ -632,6 +644,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
|
|||||||
JVMTI_DISABLE,
|
JVMTI_DISABLE,
|
||||||
JVMTI_EVENT_VM_INIT,
|
JVMTI_EVENT_VM_INIT,
|
||||||
NULL /* all threads */);
|
NULL /* all threads */);
|
||||||
|
check_phase_ret_false(jvmtierror);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,6 +655,7 @@ setLivePhaseEventHandlers( JPLISAgent * agent) {
|
|||||||
JVMTI_ENABLE,
|
JVMTI_ENABLE,
|
||||||
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
|
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
|
||||||
NULL /* all threads */);
|
NULL /* all threads */);
|
||||||
|
check_phase_ret_false(jvmtierror);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,6 +674,7 @@ checkCapabilities(JPLISAgent * agent) {
|
|||||||
memset(&potentialCapabilities, 0, sizeof(potentialCapabilities));
|
memset(&potentialCapabilities, 0, sizeof(potentialCapabilities));
|
||||||
|
|
||||||
jvmtierror = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &potentialCapabilities);
|
jvmtierror = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &potentialCapabilities);
|
||||||
|
check_phase_ret(jvmtierror);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
|
|
||||||
if ( jvmtierror == JVMTI_ERROR_NONE ) {
|
if ( jvmtierror == JVMTI_ERROR_NONE ) {
|
||||||
@ -681,9 +696,11 @@ enableNativeMethodPrefixCapability(jvmtiEnv * jvmtienv) {
|
|||||||
jvmtiError jvmtierror;
|
jvmtiError jvmtierror;
|
||||||
|
|
||||||
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
desiredCapabilities.can_set_native_method_prefix = 1;
|
desiredCapabilities.can_set_native_method_prefix = 1;
|
||||||
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
||||||
|
check_phase_ret(jvmtierror);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,9 +732,11 @@ addOriginalMethodOrderCapability(JPLISAgent * agent) {
|
|||||||
jvmtiError jvmtierror;
|
jvmtiError jvmtierror;
|
||||||
|
|
||||||
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
desiredCapabilities.can_maintain_original_method_order = 1;
|
desiredCapabilities.can_maintain_original_method_order = 1;
|
||||||
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
||||||
|
check_phase_ret(jvmtierror);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,9 +751,11 @@ addRedefineClassesCapability(JPLISAgent * agent) {
|
|||||||
|
|
||||||
if (agent->mRedefineAvailable && !agent->mRedefineAdded) {
|
if (agent->mRedefineAvailable && !agent->mRedefineAdded) {
|
||||||
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
desiredCapabilities.can_redefine_classes = 1;
|
desiredCapabilities.can_redefine_classes = 1;
|
||||||
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
|
||||||
|
check_phase_ret(jvmtierror);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* With mixed premain/agentmain agents then it's possible that the
|
* With mixed premain/agentmain agents then it's possible that the
|
||||||
@ -1026,6 +1047,7 @@ isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz) {
|
|||||||
jvmtierror = (*jvmtienv)->IsModifiableClass( jvmtienv,
|
jvmtierror = (*jvmtienv)->IsModifiableClass( jvmtienv,
|
||||||
clazz,
|
clazz,
|
||||||
&is_modifiable);
|
&is_modifiable);
|
||||||
|
check_phase_ret_false(jvmtierror);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
|
|
||||||
return is_modifiable;
|
return is_modifiable;
|
||||||
@ -1231,6 +1253,7 @@ redefineClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitio
|
|||||||
if (!errorOccurred) {
|
if (!errorOccurred) {
|
||||||
jvmtiError errorCode = JVMTI_ERROR_NONE;
|
jvmtiError errorCode = JVMTI_ERROR_NONE;
|
||||||
errorCode = (*jvmtienv)->RedefineClasses(jvmtienv, numDefs, classDefs);
|
errorCode = (*jvmtienv)->RedefineClasses(jvmtienv, numDefs, classDefs);
|
||||||
|
check_phase_blob_ret(errorCode, deallocate(jvmtienv, (void*)classDefs));
|
||||||
errorOccurred = (errorCode != JVMTI_ERROR_NONE);
|
errorOccurred = (errorCode != JVMTI_ERROR_NONE);
|
||||||
if ( errorOccurred ) {
|
if ( errorOccurred ) {
|
||||||
createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
|
createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
|
||||||
@ -1264,6 +1287,7 @@ commonGetClassList( JNIEnv * jnienv,
|
|||||||
classLoader,
|
classLoader,
|
||||||
&classCount,
|
&classCount,
|
||||||
&classes);
|
&classes);
|
||||||
|
check_phase_ret_blob(jvmtierror, localArray);
|
||||||
errorOccurred = (jvmtierror != JVMTI_ERROR_NONE);
|
errorOccurred = (jvmtierror != JVMTI_ERROR_NONE);
|
||||||
jplis_assert(!errorOccurred);
|
jplis_assert(!errorOccurred);
|
||||||
|
|
||||||
@ -1325,6 +1349,7 @@ getObjectSize(JNIEnv * jnienv, JPLISAgent * agent, jobject objectToSize) {
|
|||||||
jvmtiError jvmtierror = JVMTI_ERROR_NONE;
|
jvmtiError jvmtierror = JVMTI_ERROR_NONE;
|
||||||
|
|
||||||
jvmtierror = (*jvmtienv)->GetObjectSize(jvmtienv, objectToSize, &objectSize);
|
jvmtierror = (*jvmtienv)->GetObjectSize(jvmtienv, objectToSize, &objectSize);
|
||||||
|
check_phase_ret_0(jvmtierror);
|
||||||
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
|
||||||
if ( jvmtierror != JVMTI_ERROR_NONE ) {
|
if ( jvmtierror != JVMTI_ERROR_NONE ) {
|
||||||
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
|
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
|
||||||
@ -1374,6 +1399,7 @@ appendToClassLoaderSearch(JNIEnv * jnienv, JPLISAgent * agent, jstring jarFile,
|
|||||||
} else {
|
} else {
|
||||||
jvmtierror = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, platformChars);
|
jvmtierror = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, platformChars);
|
||||||
}
|
}
|
||||||
|
check_phase_ret(jvmtierror);
|
||||||
|
|
||||||
if ( jvmtierror != JVMTI_ERROR_NONE ) {
|
if ( jvmtierror != JVMTI_ERROR_NONE ) {
|
||||||
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
|
createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
|
||||||
@ -1464,6 +1490,7 @@ setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefix
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = (*jvmtienv)->SetNativeMethodPrefixes(jvmtienv, inx, (char**)prefixes);
|
err = (*jvmtienv)->SetNativeMethodPrefixes(jvmtienv, inx, (char**)prefixes);
|
||||||
|
/* can be called from any phase */
|
||||||
jplis_assert(err == JVMTI_ERROR_NONE);
|
jplis_assert(err == JVMTI_ERROR_NONE);
|
||||||
|
|
||||||
for (i = 0; i < inx; i++) {
|
for (i = 0; i < inx; i++) {
|
||||||
|
@ -266,6 +266,48 @@ setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefix
|
|||||||
|
|
||||||
#define jvmti(a) a->mNormalEnvironment.mJVMTIEnv
|
#define jvmti(a) a->mNormalEnvironment.mJVMTIEnv
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A set of macros for insulating the JLI method callers from
|
||||||
|
* JVMTI_ERROR_WRONG_PHASE return codes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* for a JLI method where "blob" is executed before simply returning */
|
||||||
|
#define check_phase_blob_ret(ret, blob) \
|
||||||
|
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||||
|
blob; \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for a JLI method where simply returning is benign */
|
||||||
|
#define check_phase_ret(ret) \
|
||||||
|
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||||
|
return; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for a JLI method where returning zero (0) is benign */
|
||||||
|
#define check_phase_ret_0(ret) \
|
||||||
|
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||||
|
return 0; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for a JLI method where returning one (1) is benign */
|
||||||
|
#define check_phase_ret_1(ret) \
|
||||||
|
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||||
|
return 1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for a case where a specific "blob" must be returned */
|
||||||
|
#define check_phase_ret_blob(ret, blob) \
|
||||||
|
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||||
|
return (blob); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* for a JLI method where returning false is benign */
|
||||||
|
#define check_phase_ret_false(ret) \
|
||||||
|
if ((ret) == JVMTI_ERROR_WRONG_PHASE) { \
|
||||||
|
return (jboolean) 0; \
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
@ -74,6 +74,7 @@ confirmingTLSSet( jvmtiEnv * jvmtienv,
|
|||||||
jvmtienv,
|
jvmtienv,
|
||||||
thread,
|
thread,
|
||||||
newValue);
|
newValue);
|
||||||
|
check_phase_ret_blob(error, error);
|
||||||
|
|
||||||
#if JPLISASSERT_ENABLEASSERTIONS
|
#if JPLISASSERT_ENABLEASSERTIONS
|
||||||
assertTLSValue( jvmtienv,
|
assertTLSValue( jvmtienv,
|
||||||
@ -96,6 +97,7 @@ assertTLSValue( jvmtiEnv * jvmtienv,
|
|||||||
jvmtienv,
|
jvmtienv,
|
||||||
thread,
|
thread,
|
||||||
&test);
|
&test);
|
||||||
|
check_phase_ret(error);
|
||||||
jplis_assert(error == JVMTI_ERROR_NONE);
|
jplis_assert(error == JVMTI_ERROR_NONE);
|
||||||
jplis_assert(test == expected);
|
jplis_assert(test == expected);
|
||||||
}
|
}
|
||||||
@ -111,6 +113,7 @@ tryToAcquireReentrancyToken( jvmtiEnv * jvmtienv,
|
|||||||
jvmtienv,
|
jvmtienv,
|
||||||
thread,
|
thread,
|
||||||
&storedValue);
|
&storedValue);
|
||||||
|
check_phase_ret_false(error);
|
||||||
jplis_assert(error == JVMTI_ERROR_NONE);
|
jplis_assert(error == JVMTI_ERROR_NONE);
|
||||||
if ( error == JVMTI_ERROR_NONE ) {
|
if ( error == JVMTI_ERROR_NONE ) {
|
||||||
/* if this thread is already inside, just return false and short-circuit */
|
/* if this thread is already inside, just return false and short-circuit */
|
||||||
|
@ -46,6 +46,7 @@ allocate(jvmtiEnv * jvmtienv, size_t bytecount) {
|
|||||||
error = (*jvmtienv)->Allocate(jvmtienv,
|
error = (*jvmtienv)->Allocate(jvmtienv,
|
||||||
bytecount,
|
bytecount,
|
||||||
(unsigned char**) &resultBuffer);
|
(unsigned char**) &resultBuffer);
|
||||||
|
/* may be called from any phase */
|
||||||
jplis_assert(error == JVMTI_ERROR_NONE);
|
jplis_assert(error == JVMTI_ERROR_NONE);
|
||||||
if ( error != JVMTI_ERROR_NONE ) {
|
if ( error != JVMTI_ERROR_NONE ) {
|
||||||
resultBuffer = NULL;
|
resultBuffer = NULL;
|
||||||
@ -66,6 +67,7 @@ deallocate(jvmtiEnv * jvmtienv, void * buffer) {
|
|||||||
|
|
||||||
error = (*jvmtienv)->Deallocate(jvmtienv,
|
error = (*jvmtienv)->Deallocate(jvmtienv,
|
||||||
(unsigned char*)buffer);
|
(unsigned char*)buffer);
|
||||||
|
/* may be called from any phase */
|
||||||
jplis_assert_msg(error == JVMTI_ERROR_NONE, "Can't deallocate memory");
|
jplis_assert_msg(error == JVMTI_ERROR_NONE, "Can't deallocate memory");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
86
jdk/test/java/lang/instrument/StressGetObjectSizeApp.java
Normal file
86
jdk/test/java/lang/instrument/StressGetObjectSizeApp.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2008 Sun Microsystems, Inc. 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.instrument.Instrumentation;
|
||||||
|
|
||||||
|
public class StressGetObjectSizeApp
|
||||||
|
extends ASimpleInstrumentationTestCase
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for StressGetObjectSizeApp.
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public StressGetObjectSizeApp(String name)
|
||||||
|
{
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void
|
||||||
|
main (String[] args)
|
||||||
|
throws Throwable {
|
||||||
|
ATestCaseScaffold test = new StressGetObjectSizeApp(args[0]);
|
||||||
|
test.runTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void
|
||||||
|
doRunTest()
|
||||||
|
throws Throwable {
|
||||||
|
stressGetObjectSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stressGetObjectSize() {
|
||||||
|
System.out.println("main: an object size=" +
|
||||||
|
fInst.getObjectSize(new Object()));
|
||||||
|
|
||||||
|
RoundAndRound[] threads = new RoundAndRound[10];
|
||||||
|
for (int i = 0; i < threads.length; ++i) {
|
||||||
|
threads[i] = new RoundAndRound(fInst);
|
||||||
|
threads[i].start();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(500); // let all threads get going in their loops
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
}
|
||||||
|
System.out.println("stressGetObjectSize: returning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RoundAndRound extends Thread {
|
||||||
|
private final Instrumentation inst;
|
||||||
|
private final Object anObject;
|
||||||
|
|
||||||
|
public RoundAndRound(Instrumentation inst) {
|
||||||
|
this.inst = inst;
|
||||||
|
this.anObject = new Object();
|
||||||
|
setDaemon(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
long sum = 0;
|
||||||
|
while (true) {
|
||||||
|
sum += inst.getObjectSize(anObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
70
jdk/test/java/lang/instrument/StressGetObjectSizeTest.sh
Normal file
70
jdk/test/java/lang/instrument/StressGetObjectSizeTest.sh
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2008 Sun Microsystems, Inc. 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
|
||||||
|
# under the terms of the GNU General Public License version 2 only, as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
# version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
# accompanied this code).
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License version
|
||||||
|
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
#
|
||||||
|
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
# CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
# have any questions.
|
||||||
|
#
|
||||||
|
|
||||||
|
# @test
|
||||||
|
# @bug 6572160
|
||||||
|
# @summary stress getObjectSize() API
|
||||||
|
# @author Daniel D. Daugherty as modified from the code of fischman@google.com
|
||||||
|
#
|
||||||
|
# @run build StressGetObjectSizeApp
|
||||||
|
# @run shell MakeJAR.sh basicAgent
|
||||||
|
# @run shell StressGetObjectSizeTest.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
if [ "${TESTJAVA}" = "" ]
|
||||||
|
then
|
||||||
|
echo "TESTJAVA not set. Test cannot execute. Failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${TESTSRC}" = "" ]
|
||||||
|
then
|
||||||
|
echo "TESTSRC not set. Test cannot execute. Failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${TESTCLASSES}" = "" ]
|
||||||
|
then
|
||||||
|
echo "TESTCLASSES not set. Test cannot execute. Failed."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
JAVA="${TESTJAVA}"/bin/java
|
||||||
|
|
||||||
|
"${JAVA}" ${TESTVMOPTS} -javaagent:basicAgent.jar \
|
||||||
|
-classpath "${TESTCLASSES}" StressGetObjectSizeApp StressGetObjectSizeApp \
|
||||||
|
> output.log 2>&1
|
||||||
|
cat output.log
|
||||||
|
|
||||||
|
MESG="ASSERTION FAILED"
|
||||||
|
grep "$MESG" output.log
|
||||||
|
result=$?
|
||||||
|
if [ "$result" = 0 ]; then
|
||||||
|
echo "FAIL: found '$MESG' in the test output"
|
||||||
|
result=1
|
||||||
|
else
|
||||||
|
echo "PASS: did NOT find '$MESG' in the test output"
|
||||||
|
result=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $result
|
Loading…
Reference in New Issue
Block a user