OpenJDK / amber / amber
changeset 53865:f6005102c6ef
8214572: [Graal] nsk/jvmti/unit/ForceEarlyReturn/earlyretbase should not suspend the thread when the top frame executes JVMCI code
Reviewed-by: sspitsyn, dholmes, jcbeyler
author | dtitov |
---|---|
date | Tue, 04 Dec 2018 21:13:45 -0800 |
parents | 5261951acd41 |
children | af52abc1f61e |
files | test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase.java test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.h |
diffstat | 4 files changed, 89 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase.java Tue Dec 04 17:18:11 2018 -0800 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase.java Tue Dec 04 21:13:45 2018 -0800 @@ -54,8 +54,7 @@ } } - 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 @@ 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) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp Tue Dec 04 17:18:11 2018 -0800 +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/unit/ForceEarlyReturn/earlyretbase/earlyretbase.cpp Tue Dec 04 21:13:45 2018 -0800 @@ -78,22 +78,29 @@ 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; } - printf("<<<<<<<< SuspendThread() is successfully done\n"); - fflush(0); - return PASSED; + + 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; + } } JNIEXPORT jint JNICALL @@ -119,7 +126,7 @@ 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 @@ } 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()"
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp Tue Dec 04 17:18:11 2018 -0800 +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.cpp Tue Dec 04 21:13:45 2018 -0800 @@ -633,6 +633,69 @@ 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)) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.h Tue Dec 04 17:18:11 2018 -0800 +++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jvmti/jvmti_tools.h Tue Dec 04 21:13:45 2018 -0800 @@ -371,6 +371,12 @@ 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);