mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-05 11:15:13 +00:00
8286580: serviceability/jvmti/vthread/GetSetLocalTest failed with assert: Not supported for heap frames
Reviewed-by: lmesnik, rpressler, cjplummer
This commit is contained in:
parent
3f5e48a44e
commit
4c9ea7e66a
@ -611,7 +611,7 @@ void VM_BaseGetOrSetLocal::doit() {
|
||||
|
||||
frame fr = _jvf->fr();
|
||||
if (_set && _depth != 0 && Continuation::is_frame_in_continuation(_jvf->thread(), fr)) {
|
||||
_result = JVMTI_ERROR_OPAQUE_FRAME; // deferred locals currently unsupported in continuations
|
||||
_result = JVMTI_ERROR_OPAQUE_FRAME; // deferred locals are not fully supported in continuations
|
||||
return;
|
||||
}
|
||||
|
||||
@ -644,6 +644,17 @@ void VM_BaseGetOrSetLocal::doit() {
|
||||
return;
|
||||
}
|
||||
if (_set) {
|
||||
if (fr.is_heap_frame()) { // we want this check after the check for JVMTI_ERROR_INVALID_SLOT
|
||||
assert(Continuation::is_frame_in_continuation(_jvf->thread(), fr), "sanity check");
|
||||
// If the topmost frame is a heap frame, then it hasn't been thawed. This can happen
|
||||
// if we are executing at a return barrier safepoint. The callee frame has been popped,
|
||||
// but the caller frame has not been thawed. We can't support a JVMTI SetLocal in the callee
|
||||
// frame at this point, because we aren't truly in the callee yet.
|
||||
// fr.is_heap_frame() is impossible if a continuation is at a single step or breakpoint.
|
||||
_result = JVMTI_ERROR_OPAQUE_FRAME; // deferred locals are not fully supported in continuations
|
||||
return;
|
||||
}
|
||||
|
||||
// Force deoptimization of frame if compiled because it's
|
||||
// possible the compiler emitted some locals as constant values,
|
||||
// meaning they are not mutable.
|
||||
|
||||
@ -111,6 +111,7 @@ serviceability/sa/sadebugd/DebugdConnectTest.java 8239062,8270326 macosx-x64,mac
|
||||
serviceability/sa/TestRevPtrsForInvokeDynamic.java 8241235 generic-all
|
||||
|
||||
serviceability/jvmti/ModuleAwareAgents/ThreadStart/MAAThreadStart.java 8225354 windows-all
|
||||
serviceability/jvmti/vthread/GetSetLocalTest/GetSetLocalTest.java 8286836 generic-all
|
||||
serviceability/dcmd/gc/RunFinalizationTest.java 8227120 linux-all,windows-x64
|
||||
|
||||
serviceability/sa/ClhsdbCDSCore.java 8269982,8267433 macosx-aarch64,macosx-x64
|
||||
|
||||
@ -35,8 +35,7 @@ import java.util.concurrent.*;
|
||||
public class GetSetLocalTest {
|
||||
private static final String agentLib = "GetSetLocalTest";
|
||||
|
||||
static final int MSG_COUNT = 600*1000;
|
||||
static final SynchronousQueue<String> QUEUE = new SynchronousQueue<>();
|
||||
static SynchronousQueue<String> QUEUE;
|
||||
static native boolean completed();
|
||||
static native void enableEvents(Thread thread);
|
||||
static native void testSuspendedVirtualThreads(Thread thread);
|
||||
@ -56,19 +55,17 @@ public class GetSetLocalTest {
|
||||
|
||||
static final Runnable PRODUCER = () -> {
|
||||
try {
|
||||
for (int i = 0; i < MSG_COUNT; i++) {
|
||||
if (completed()) {
|
||||
consumer.interrupt();
|
||||
break;
|
||||
}
|
||||
while (!completed()) {
|
||||
producer("msg: ");
|
||||
}
|
||||
} catch (InterruptedException e) { }
|
||||
consumer.interrupt();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
};
|
||||
|
||||
static final Runnable CONSUMER = () -> {
|
||||
try {
|
||||
for (int i = 0; i < MSG_COUNT; i++) {
|
||||
while(true) {
|
||||
String s = QUEUE.take();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
@ -77,6 +74,7 @@ public class GetSetLocalTest {
|
||||
};
|
||||
|
||||
public static void test1() throws Exception {
|
||||
QUEUE = new SynchronousQueue<>();
|
||||
producer = Thread.ofVirtual().name("VThread-Producer").start(PRODUCER);
|
||||
consumer = Thread.ofVirtual().name("VThread-Consumer").start(CONSUMER);
|
||||
|
||||
@ -101,6 +99,10 @@ public class GetSetLocalTest {
|
||||
}
|
||||
|
||||
GetSetLocalTest obj = new GetSetLocalTest();
|
||||
obj.runTest();
|
||||
|
||||
for (int i = 0; i < 200; i++) {
|
||||
obj.runTest();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,7 +232,7 @@ test_GetLocal(jvmtiEnv *jvmti, JNIEnv *jni, jthread cthread, jthread vthread,
|
||||
|
||||
static bool
|
||||
test_SetLocal(jvmtiEnv *jvmti, JNIEnv *jni, jthread cthread, jthread vthread,
|
||||
int depth, int frame_count, Values *values) {
|
||||
int depth, int frame_count, Values *values, bool at_event) {
|
||||
jvmtiError err;
|
||||
|
||||
LOG("test_SetLocal: mounted: %d depth: %d fcount: %d\n", cthread != NULL, depth, frame_count);
|
||||
@ -288,7 +288,7 @@ test_SetLocal(jvmtiEnv *jvmti, JNIEnv *jni, jthread cthread, jthread vthread,
|
||||
fatal(jni, "JVMTI SetLocalObject for unmounted vthread pr depth > 0failed to return JVMTI_ERROR_OPAQUE_FRAME");
|
||||
}
|
||||
return false; // skip testing other types for unmounted vthread
|
||||
} else if (err == JVMTI_ERROR_OPAQUE_FRAME) {
|
||||
} else if (!at_event && err == JVMTI_ERROR_OPAQUE_FRAME) {
|
||||
LOG("JVMTI SetLocalObject for mounted vthread at depth=0 returned JVMTI_ERROR_OPAQUE_FRAME: %d\n", err);
|
||||
return false; // skip testing other types for compiled frame that can't be deoptimized
|
||||
}
|
||||
@ -309,7 +309,7 @@ test_SetLocal(jvmtiEnv *jvmti, JNIEnv *jni, jthread cthread, jthread vthread,
|
||||
}
|
||||
|
||||
static void
|
||||
test_GetSetLocal(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, int depth, int frame_count) {
|
||||
test_GetSetLocal(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, int depth, int frame_count, bool at_event) {
|
||||
Values values0 = { NULL, NULL, 1, 2L, (jfloat)3.2F, (jdouble)4.500000047683716 };
|
||||
Values values1 = { NULL, NULL, 2, 3L, (jfloat)4.2F, (jdouble)5.500000047683716 };
|
||||
jthread cthread = get_carrier_thread(jvmti, jni, vthread);
|
||||
@ -319,8 +319,8 @@ test_GetSetLocal(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, int depth, int f
|
||||
|
||||
LOG("test_GetSetLocal: test_GetLocal with values0\n");
|
||||
test_GetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values0);
|
||||
LOG("test_GetSetLocal: test_SetLocal with values1\n");
|
||||
bool success = test_SetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values1);
|
||||
LOG("test_GetSetLocal: test_SetLocal at_event: %d with values1\n", at_event);
|
||||
bool success = test_SetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values1, at_event);
|
||||
|
||||
if (!success) {
|
||||
goto End; // skip testing for compiled frame that can't be deoptimized
|
||||
@ -334,8 +334,8 @@ test_GetSetLocal(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread, int depth, int f
|
||||
} else {
|
||||
LOG("test_GetSetLocal: test_GetLocal with values1\n");
|
||||
test_GetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values1);
|
||||
LOG("test_GetSetLocal: test_SetLocal with values0 to restore original local values\n");
|
||||
test_SetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values0);
|
||||
LOG("test_GetSetLocal: test_SetLocal at_event: %d with values0 to restore original local values\n", at_event);
|
||||
test_SetLocal(jvmti, jni, cthread, vthread, depth, frame_count, &values0, at_event);
|
||||
}
|
||||
End:
|
||||
LOG("test_GetSetLocal: finished\n\n");
|
||||
@ -360,7 +360,7 @@ Breakpoint(jvmtiEnv *jvmti, JNIEnv* jni, jthread vthread,
|
||||
|
||||
{
|
||||
int frame_count = get_frame_count(jvmti, jni, vthread);
|
||||
test_GetSetLocal(jvmti, jni, vthread, depth, frame_count);
|
||||
test_GetSetLocal(jvmti, jni, vthread, depth, frame_count, true /* at_event */);
|
||||
}
|
||||
deallocate(jvmti, jni, (void*)mname);
|
||||
deallocate(jvmti, jni, (void*)tname);
|
||||
@ -470,7 +470,7 @@ Java_GetSetLocalTest_testSuspendedVirtualThreads(JNIEnv *jni, jclass klass, jthr
|
||||
#if 0
|
||||
print_stack_trace(jvmti, jni, vthread);
|
||||
#endif
|
||||
test_GetSetLocal(jvmti, jni, vthread, depth, frame_count);
|
||||
test_GetSetLocal(jvmti, jni, vthread, depth, frame_count, false /* !at_event */);
|
||||
}
|
||||
|
||||
err = jvmti->ResumeThread(vthread);
|
||||
@ -487,7 +487,11 @@ Java_GetSetLocalTest_testSuspendedVirtualThreads(JNIEnv *jni, jclass klass, jthr
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_GetSetLocalTest_completed(JNIEnv *jni, jclass klass) {
|
||||
return completed;
|
||||
if (completed) {
|
||||
completed = JNI_FALSE;
|
||||
return JNI_TRUE;
|
||||
}
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user