8214572: [Graal] nsk/jvmti/unit/ForceEarlyReturn/earlyretbase should not suspend the thread when the top frame executes JVMCI code
Reviewed-by: sspitsyn, dholmes, jcbeyler
This commit is contained in:
parent
b93b62c2c9
commit
cbaebf738e
test/hotspot/jtreg/vmTestbase/nsk
jvmti/unit/ForceEarlyReturn
share/jvmti
@ -54,8 +54,7 @@ public class earlyretbase {
|
||||
}
|
||||
}
|
||||
|
||||
native static int doForceEarlyReturn(Class targCls,
|
||||
Thread earlyretThr, long valToRet);
|
||||
native static int doForceEarlyReturn(Thread earlyretThr, long valToRet);
|
||||
native static int suspThread(earlyretThread earlyretThr);
|
||||
native static int resThread(earlyretThread earlyretThr);
|
||||
native static int check();
|
||||
@ -96,8 +95,7 @@ public class earlyretbase {
|
||||
out.println("Forcing early return...");
|
||||
|
||||
// force return from a top frame of the child thread
|
||||
retCode = doForceEarlyReturn(earlyretThread.class,
|
||||
earlyretThr, JAVA_BIRTH_YEAR);
|
||||
retCode = doForceEarlyReturn(earlyretThr, JAVA_BIRTH_YEAR);
|
||||
earlyretDone = true;
|
||||
earlyretThr.letItGo();
|
||||
if (retCode != Consts.TEST_PASSED) {
|
||||
|
@ -78,22 +78,29 @@ FramePop(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread,
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_suspThread(JNIEnv *env,
|
||||
jclass cls, jobject earlyretThr) {
|
||||
jvmtiError err;
|
||||
|
||||
if (!caps.can_force_early_return || !caps.can_suspend) {
|
||||
return PASSED;
|
||||
}
|
||||
|
||||
printf(">>>>>>>> Invoke SuspendThread()\n");
|
||||
err = jvmti->SuspendThread(earlyretThr);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
printf("%s: Failed to call SuspendThread(): error=%d: %s\n",
|
||||
__FILE__, err, TranslateError(err));
|
||||
return JNI_ERR;
|
||||
jclass clazz = env->GetObjectClass(earlyretThr);
|
||||
if (clazz == NULL) {
|
||||
printf("Cannot get class of thread object\n");
|
||||
RETURN_FAILED;
|
||||
}
|
||||
|
||||
midActiveMethod = env->GetMethodID(clazz, name_exp, sig_exp);
|
||||
if (midActiveMethod == NULL) {
|
||||
printf("Cannot find Method ID for method %s\n", name_exp);
|
||||
RETURN_FAILED;
|
||||
}
|
||||
|
||||
int result = suspendThreadAtMethod(jvmti, cls, earlyretThr, midActiveMethod);
|
||||
if( result == NSK_TRUE) {
|
||||
return PASSED;
|
||||
} else {
|
||||
RETURN_FAILED;
|
||||
}
|
||||
printf("<<<<<<<< SuspendThread() is successfully done\n");
|
||||
fflush(0);
|
||||
return PASSED;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
@ -119,7 +126,7 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_resThread(JNIEnv *env,
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_doForceEarlyReturn(JNIEnv *env,
|
||||
jclass cls, jclass targCls, jthread earlyretThr, jlong valToRet) {
|
||||
jclass cls, jthread earlyretThr, jlong valToRet) {
|
||||
jvmtiError err;
|
||||
|
||||
if (!caps.can_force_early_return || !caps.can_suspend) {
|
||||
@ -160,14 +167,6 @@ Java_nsk_jvmti_unit_ForceEarlyReturn_earlyretbase_doForceEarlyReturn(JNIEnv *env
|
||||
}
|
||||
printf(">>>>>>>> Invoke ForceEarlyReturn()\n");
|
||||
|
||||
printf("Before call to GetMethodID(%s, %s)\n", name_exp, sig_exp);
|
||||
midActiveMethod = env->GetMethodID(targCls, name_exp, sig_exp);
|
||||
if (midActiveMethod == NULL) {
|
||||
printf("Cannot find Method ID for method %s\n", name_exp);
|
||||
RETURN_FAILED;
|
||||
}
|
||||
printf("After call to GetMethodID(%s, %s)\n", name_exp, sig_exp);
|
||||
|
||||
err = jvmti->ForceEarlyReturnLong(earlyretThr, valToRet);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
printf("TEST FAILED: the function ForceEarlyReturn()"
|
||||
|
@ -633,6 +633,69 @@ int isThreadExpected(jvmtiEnv *jvmti, jthread thread) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define SLEEP_DELAY 10L
|
||||
|
||||
int suspendThreadAtMethod(jvmtiEnv *jvmti, jclass cls, jobject thread, jmethodID testMethod) {
|
||||
printf(">>>>>>>> Invoke SuspendThread()\n");
|
||||
|
||||
jvmtiError err = jvmti->SuspendThread(thread);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
printf("%s: Failed to call SuspendThread(): error=%d: %s\n",
|
||||
__FILE__, err, TranslateError(err));
|
||||
return NSK_FALSE;
|
||||
}
|
||||
|
||||
int result = NSK_TRUE;
|
||||
jmethodID method = NULL;
|
||||
jlocation loc;
|
||||
|
||||
// We need to ensure that the thread is suspended at the right place when the top
|
||||
// frame belongs to the test rather than to incidental Java code (classloading,
|
||||
// JVMCI, etc). Below we do resume/suspend in the loop until the target method
|
||||
// is executed in the top frame or the loop counter exceeds the limit.
|
||||
for (int i = 0; i < 10; i++) {
|
||||
err = jvmti->GetFrameLocation(thread, 0, &method, &loc);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
printf("(GetFrameLocation) unexpected error: %s (%d)\n",
|
||||
TranslateError(err), err);
|
||||
result = NSK_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
char *name, *sig, *generic;
|
||||
jvmti->GetMethodName(method, &name, &sig, &generic);
|
||||
printf(">>> Attempt %d to suspend the thread. Top frame: \"%s%s\"\n",
|
||||
i, name, sig);
|
||||
if (method == testMethod) break;
|
||||
|
||||
err = jvmti->ResumeThread(thread);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
printf("(ResumeThread) unexpected error: %s (%d)\n",
|
||||
TranslateError(err), err);
|
||||
result = NSK_FALSE;
|
||||
}
|
||||
|
||||
mssleep(SLEEP_DELAY);
|
||||
|
||||
err = jvmti->SuspendThread(thread);
|
||||
if (err != JVMTI_ERROR_NONE) {
|
||||
printf("(SuspendThread) unexpected error: %s (%d)\n",
|
||||
TranslateError(err), err);
|
||||
result = NSK_FALSE;
|
||||
}
|
||||
}
|
||||
if(method == testMethod) {
|
||||
printf("<<<<<<<< SuspendThread() is successfully done\n");
|
||||
} else {
|
||||
char *name, *sig, *generic;
|
||||
jvmti->GetMethodName(testMethod, &name, &sig, &generic);
|
||||
printf("Failed in the suspendThread: was not able to suspend thread "
|
||||
"with required method \"%s%s\" on the top\n", name, sig);
|
||||
result = NSK_FALSE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
jint createRawMonitor(jvmtiEnv *env, const char *name, jrawMonitorID *monitor) {
|
||||
jvmtiError error = env->CreateRawMonitor(name, monitor);
|
||||
if (!NSK_JVMTI_VERIFY(error)) {
|
||||
|
@ -371,6 +371,12 @@ void nsk_jvmti_agentFailed();
|
||||
|
||||
int isThreadExpected(jvmtiEnv *jvmti, jthread thread);
|
||||
|
||||
/**
|
||||
* This method makes the thread to be suspended at the right place when the top frame
|
||||
* belongs to the test rather than to incidental Java code (classloading, JVMCI, etc).
|
||||
*/
|
||||
int suspendThreadAtMethod(jvmtiEnv *jvmti, jclass cls, jobject thread, jmethodID method);
|
||||
|
||||
jint createRawMonitor(jvmtiEnv *env, const char *name, jrawMonitorID *monitor);
|
||||
|
||||
void exitOnError(jvmtiError error);
|
||||
|
Loading…
x
Reference in New Issue
Block a user