From fb0f2d25d218e64a86995478fd3ea10d619834d5 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Thu, 30 Jan 2025 09:11:13 +0000 Subject: [PATCH] 8300708: Some nsk jvmti tests fail with virtual thread wrapper due to jvmti missing some virtual thread support Reviewed-by: cjplummer, lmesnik --- test/hotspot/jtreg/ProblemList-Virtual.txt | 13 +- .../jvmti/SetLocalVariable/setlocal001.java | 18 ++- .../setlocal001/setlocal001.cpp | 118 ++++-------------- .../setlocal003/setlocal003.cpp | 49 +++----- .../setlocal004/setlocal004.cpp | 49 +++----- 5 files changed, 82 insertions(+), 165 deletions(-) diff --git a/test/hotspot/jtreg/ProblemList-Virtual.txt b/test/hotspot/jtreg/ProblemList-Virtual.txt index 64b281ccc98..2239a10f3e7 100644 --- a/test/hotspot/jtreg/ProblemList-Virtual.txt +++ b/test/hotspot/jtreg/ProblemList-Virtual.txt @@ -37,17 +37,8 @@ vmTestbase/nsk/jvmti/CompiledMethodUnload/compmethunload001/TestDescription.java #### ## Tests for functionality which currently is not supported for virtual threads -vmTestbase/nsk/jvmti/GetCurrentThreadCpuTime/curthrcputime001/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/GetThreadCpuTime/thrcputime001/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/NotifyFramePop/nframepop002/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/NotifyFramePop/nframepop003/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/StopThread/stopthrd006/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/scenarios/events/EM02/em02t012/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/SetLocalVariable/setlocal004/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/SetLocalVariable/setlocal003/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/SetLocalVariable/setlocal002/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001/TestDescription.java 8300708 generic-all -vmTestbase/nsk/jvmti/unit/GetLocalVariable/getlocal003/TestDescription.java 8300708 generic-all +vmTestbase/nsk/jvmti/GetCurrentThreadCpuTime/curthrcputime001/TestDescription.java 8348844 generic-all +vmTestbase/nsk/jvmti/GetThreadCpuTime/thrcputime001/TestDescription.java 8348844 generic-all #### ## Test fails because it expects to find vthreads in GetAllThreads diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001.java b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001.java index 757102f0c1c..8ac20f89eaa 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -80,6 +80,10 @@ public class setlocal001 { float f = 0f; double d = 0; checkPoint(); + if (currThread.isVirtual()) { + out.println("meth01: skipping results check for virtual thread"); + return d + f + 1; // SetLocal* should return OPAQUE_FRAME for a virtual thread + } if (l != 22L || f != floatVal || d != doubleVal) { out.println("meth01: l =" + l + " f = " + f + " d = " + d); result = 2; @@ -97,6 +101,10 @@ public class setlocal001 { meth02(step - 1); } else { checkPoint(); + if (currThread.isVirtual()) { + out.println("meth02: skipping results check for virtual thread"); + return; // SetLocal* should return OPAQUE_FRAME for a virtual thread + } if (i1 != 1 || i2 != 1 || i3 != 1 || i4 != 1 || !i5) { out.println("meth02: i1 =" + i1 + " i2 = " + i2 + " i3 = " + i3 + " i4 = " + i4 + " i5 = " + i5); @@ -109,6 +117,10 @@ public class setlocal001 { setlocal001 ob1 = null; int[] ob2 = null; checkPoint(); + if (currThread.isVirtual()) { + out.println("meth03: skipping results check for virtual thread"); + return; // SetLocalObject for obj1 and obj2 should return OPAQUE_FRAME for a virtual thread + } if (ob1.val != 3 || ob2[2] != 8) { out.println("meth03: ob1.val =" + ob1.val + " ob2[2] = " + ob2[2]); result = 2; @@ -118,6 +130,10 @@ public class setlocal001 { public static void meth04(int i1, long l, short i2, double d, char i3, float f, byte i4, boolean b) { checkPoint(); + if (currThread.isVirtual()) { + out.println("meth04: skipping results check for virtual thread"); + return; // SetLocal* should return OPAQUE_FRAME for a virtual thread + } if (i1 != 1 || i2 != 2 || i3 != 3 || i4 != 4 || l != 22L || f != floatVal || d != doubleVal || !b) { out.println("meth04: i1 =" + i1 + " i2 = " + i2 + diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001/setlocal001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001/setlocal001.cpp index 8193058eba7..9ad953e56f9 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001/setlocal001.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal001/setlocal001.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -44,6 +44,13 @@ static jdouble doubleVal; static jobject objVal; static jobject arrVal; +static void check_error(jvmtiError err, bool is_virtual, const char* func_id) { + if (err != JVMTI_ERROR_NONE && !(is_virtual && err == JVMTI_ERROR_OPAQUE_FRAME)) { + printf("(%s) unexpected error: %s (%d)\n", func_id, TranslateError(err), err); + result = STATUS_FAILED; + } +} + void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID method, jlocation location) { jvmtiError err; @@ -51,6 +58,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jlocation loc; jint entryCount; jvmtiLocalVariableEntry *table = nullptr; + bool is_virtual = env->IsVirtualThread(thr); int i; err = jvmti_env->GetFrameLocation(thr, 1, &mid, &loc); @@ -74,27 +82,15 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, if (strcmp(table[i].name, "l") == 0) { err = jvmti_env->SetLocalLong(thr, 1, table[i].slot, longVal); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalLong) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalLong"); } else if (strcmp(table[i].name, "f") == 0) { err = jvmti_env->SetLocalFloat(thr, 1, table[i].slot, floatVal); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalFloat) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalFloat"); } else if (strcmp(table[i].name, "d") == 0) { err = jvmti_env->SetLocalDouble(thr, 1, table[i].slot, doubleVal); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalDouble) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalDouble"); } } } else if (mid == mid2) { @@ -102,43 +98,23 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, if (strcmp(table[i].name, "i1") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 1); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i1) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i1"); } else if (strcmp(table[i].name, "i2") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 1); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i2) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i2"); } else if (strcmp(table[i].name, "i3") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 1); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i3) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i3"); } else if (strcmp(table[i].name, "i4") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 1); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i4) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i4"); } else if (strcmp(table[i].name, "i5") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 1); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i5) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i5"); } } } else if (mid == mid3) { @@ -146,19 +122,11 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, if (strcmp(table[i].name, "ob1") == 0) { err = jvmti_env->SetLocalObject(thr, 1, table[i].slot, objVal); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalObject#ob1) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalObject#ob1"); } else if (strcmp(table[i].name, "ob2") == 0) { err = jvmti_env->SetLocalObject(thr, 1, table[i].slot, arrVal); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalObject#ob2) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalObject#ob2"); } } } else if (mid == mid4) { @@ -166,67 +134,35 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, if (strcmp(table[i].name, "i1") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 1); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i1,param) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i1,param"); } else if (strcmp(table[i].name, "i2") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 2); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i2,param) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i2,param"); } else if (strcmp(table[i].name, "i3") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 3); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i3,param) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i3,param"); } else if (strcmp(table[i].name, "i4") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, 4); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#i4,param) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#i4,param"); } else if (strcmp(table[i].name, "b") == 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, JNI_TRUE); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalInt#b,param) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalInt#b,param"); } else if (strcmp(table[i].name, "l") == 0) { err = jvmti_env->SetLocalLong(thr, 1, table[i].slot, longVal); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalLong,param) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalLong,param"); } else if (strcmp(table[i].name, "f") == 0) { err = jvmti_env->SetLocalFloat(thr, 1, table[i].slot, floatVal); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalFloat,param) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalFloat,param"); } else if (strcmp(table[i].name, "d") == 0) { err = jvmti_env->SetLocalDouble(thr, 1, table[i].slot, doubleVal); - if (err != JVMTI_ERROR_NONE) { - printf("(SetLocalDouble,param) unexpected error: %s (%d)\n", - TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, "SetLocalDouble,param"); } } } else { diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal003/setlocal003.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal003/setlocal003.cpp index 793f22ec40f..c366655a735 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal003/setlocal003.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal003/setlocal003.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -40,6 +40,15 @@ static jvmtiEventCallbacks callbacks; static jint result = PASSED; static jboolean printdump = JNI_FALSE; +static void check_error(jvmtiError err, bool is_virtual, char* var_name) { + if (err != JVMTI_ERROR_INVALID_SLOT && !(is_virtual && err == JVMTI_ERROR_OPAQUE_FRAME)) { + printf("(%s) ", var_name); + printf("Error expected: JVMTI_ERROR_INVALID_SLOT or JVMTI_ERROR_OPAQUE_FRAME,\n"); + printf("\t actual: %s (%d)\n", TranslateError(err), err); + result = STATUS_FAILED; + } +} + void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID method, jlocation location) { jvmtiError err; @@ -47,6 +56,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jlocation loc; jint entryCount; jvmtiLocalVariableEntry *table; + bool is_virtual = env->IsVirtualThread(thr); int i; err = jvmti_env->GetFrameLocation(thr, 1, &mid, &loc); @@ -71,51 +81,28 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, printf(">>> checking on invalid slot ...\n"); } for (i = 0; i < entryCount; i++) { + char* var_name = table[i].name; + if (strcmp(table[i].name, "o") == 0) { err = jvmti_env->SetLocalObject(thr, 1, INV_SLOT, (jobject)thr); - if (err != JVMTI_ERROR_INVALID_SLOT) { - printf("(%s) ", table[i].name); - printf("Error expected: JVMTI_ERROR_INVALID_SLOT,\n"); - printf("\t actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } else if (strcmp(table[i].name, "i") == 0) { err = jvmti_env->SetLocalInt(thr, 1, INV_SLOT, (jint)0); - if (err != JVMTI_ERROR_INVALID_SLOT) { - printf("(%s) ", table[i].name); - printf("Error expected: JVMTI_ERROR_INVALID_SLOT,\n"); - printf("\t actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } else if (strcmp(table[i].name, "l") == 0) { err = jvmti_env->SetLocalLong(thr, 1, INV_SLOT, (jlong)0); - if (err != JVMTI_ERROR_INVALID_SLOT) { - printf("(%s) ", table[i].name); - printf("Error expected: JVMTI_ERROR_INVALID_SLOT,\n"); - printf("\t actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } else if (strcmp(table[i].name, "f") == 0) { err = jvmti_env->SetLocalFloat(thr, 1, INV_SLOT, (jfloat)0); - if (err != JVMTI_ERROR_INVALID_SLOT) { - printf("(%s) ", table[i].name); - printf("Error expected: JVMTI_ERROR_INVALID_SLOT,\n"); - printf("\t actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } else if (strcmp(table[i].name, "d") == 0) { err = jvmti_env->SetLocalDouble(thr, 1, INV_SLOT, (jdouble)0); - if (err != JVMTI_ERROR_INVALID_SLOT) { - printf("(%s) ", table[i].name); - printf("Error expected: JVMTI_ERROR_INVALID_SLOT,\n"); - printf("\t actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } } diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal004/setlocal004.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal004/setlocal004.cpp index 37598107c45..db10b761ca4 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal004/setlocal004.cpp +++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SetLocalVariable/setlocal004/setlocal004.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -40,6 +40,15 @@ static jvmtiEventCallbacks callbacks; static jint result = PASSED; static jboolean printdump = JNI_FALSE; +static void check_error(jvmtiError err, bool is_virtual, char* var_name) { + if (err != JVMTI_ERROR_TYPE_MISMATCH && !(is_virtual && err == JVMTI_ERROR_OPAQUE_FRAME)) { + printf("(%s) ", var_name); + printf("Error: expected: JVMTI_ERROR_TYPE_MISMATCH or JVMTI_ERROR_OPAQUE_FRAME,\n"); + printf("\t actual: %s (%d)\n", TranslateError(err), err); + result = STATUS_FAILED; + } +} + void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID method, jlocation location) { jvmtiError err; @@ -47,6 +56,7 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, jlocation loc; jint entryCount; jvmtiLocalVariableEntry *table; + bool is_virtual = env->IsVirtualThread(thr); int i; err = jvmti_env->GetFrameLocation(thr, 1, &mid, &loc); @@ -72,56 +82,33 @@ void JNICALL Breakpoint(jvmtiEnv *jvmti_env, JNIEnv *env, printf(">>> checking on type mismatch ...\n"); } for (i = 0; i < entryCount; i++) { + char* var_name = table[i].name; + if (strlen(table[i].name) != 1) continue; if (strcmp(table[i].name, "o") != 0) { err = jvmti_env->SetLocalObject(thr, 1, table[i].slot, (jobject)thr); - if (err != JVMTI_ERROR_TYPE_MISMATCH) { - printf("\"%s\" against SetLocalObject:\n", table[i].name); - printf(" expected: JVMTI_ERROR_TYPE_MISMATCH,"); - printf(" actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } if (strcmp(table[i].name, "i") != 0) { err = jvmti_env->SetLocalInt(thr, 1, table[i].slot, (jint)0); - if (err != JVMTI_ERROR_TYPE_MISMATCH) { - printf("\"%s\" against SetLocalInt:\n", table[i].name); - printf(" expected: JVMTI_ERROR_TYPE_MISMATCH,"); - printf(" actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } if (strcmp(table[i].name, "l") != 0) { err = jvmti_env->SetLocalLong(thr, 1, table[i].slot, (jlong)0); - if (err != JVMTI_ERROR_TYPE_MISMATCH) { - printf("\"%s\" against SetLocalLong:\n", table[i].name); - printf(" expected: JVMTI_ERROR_TYPE_MISMATCH,"); - printf(" actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } if (strcmp(table[i].name, "f") != 0) { err = jvmti_env->SetLocalFloat(thr, 1, table[i].slot, (jfloat)0); - if (err != JVMTI_ERROR_TYPE_MISMATCH) { - printf("\"%s\" against SetLocalFloat:\n", table[i].name); - printf(" expected: JVMTI_ERROR_TYPE_MISMATCH,"); - printf(" actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } if (strcmp(table[i].name, "d") != 0) { err = jvmti_env->SetLocalDouble(thr, 1, table[i].slot, (jdouble)0); - if (err != JVMTI_ERROR_TYPE_MISMATCH) { - printf("\"%s\" against SetLocalDouble:\n", table[i].name); - printf(" expected: JVMTI_ERROR_TYPE_MISMATCH,"); - printf(" actual: %s (%d)\n", TranslateError(err), err); - result = STATUS_FAILED; - } + check_error(err, is_virtual, var_name); } }