diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/1941-dispose-stress/dispose_stress.cc | 11 | ||||
| -rw-r--r-- | test/1941-dispose-stress/src/art/Test1941.java | 15 | ||||
| -rw-r--r-- | test/knownfailures.json | 5 | ||||
| -rw-r--r-- | test/ti-agent/trace_helper.cc | 84 |
4 files changed, 84 insertions, 31 deletions
diff --git a/test/1941-dispose-stress/dispose_stress.cc b/test/1941-dispose-stress/dispose_stress.cc index e8fcc775e9..f973abe28b 100644 --- a/test/1941-dispose-stress/dispose_stress.cc +++ b/test/1941-dispose-stress/dispose_stress.cc @@ -30,6 +30,17 @@ namespace art { namespace Test1941DisposeStress { +extern "C" JNIEXPORT void JNICALL Java_art_Test1941_setTracingOn(JNIEnv* env, + jclass, + jthread thr, + jboolean enable) { + JvmtiErrorToException(env, + jvmti_env, + jvmti_env->SetEventNotificationMode(enable ? JVMTI_ENABLE : JVMTI_DISABLE, + JVMTI_EVENT_SINGLE_STEP, + thr)); +} + extern "C" JNIEXPORT jlong JNICALL Java_art_Test1941_AllocEnv(JNIEnv* env, jclass) { JavaVM* vm = nullptr; if (env->GetJavaVM(&vm) != 0) { diff --git a/test/1941-dispose-stress/src/art/Test1941.java b/test/1941-dispose-stress/src/art/Test1941.java index d5a9de6cab..29cea6bdb8 100644 --- a/test/1941-dispose-stress/src/art/Test1941.java +++ b/test/1941-dispose-stress/src/art/Test1941.java @@ -19,6 +19,7 @@ package art; import java.util.Arrays; import java.lang.reflect.Executable; import java.lang.reflect.Method; +import java.util.concurrent.Semaphore; public class Test1941 { public static final boolean PRINT_CNT = false; @@ -41,7 +42,8 @@ public class Test1941 { // Don't bother actually doing anything. } - public static void LoopAllocFreeEnv() { + public static void LoopAllocFreeEnv(Semaphore sem) { + sem.release(); while (!Thread.interrupted()) { CNT++; long env = AllocEnv(); @@ -52,18 +54,25 @@ public class Test1941 { public static native long AllocEnv(); public static native void FreeEnv(long env); + public static native void setTracingOn(Thread thr, boolean enable); + public static void run() throws Exception { - Thread thr = new Thread(Test1941::LoopAllocFreeEnv, "LoopNative"); + final Semaphore sem = new Semaphore(0); + Thread thr = new Thread(() -> { LoopAllocFreeEnv(sem); }, "LoopNative"); thr.start(); + // Make sure the other thread is actually started. + sem.acquire(); Trace.enableSingleStepTracing(Test1941.class, Test1941.class.getDeclaredMethod( "notifySingleStep", Thread.class, Executable.class, Long.TYPE), - null); + thr); + setTracingOn(Thread.currentThread(), true); System.out.println("fib(20) is " + fib(20)); thr.interrupt(); thr.join(); + setTracingOn(Thread.currentThread(), false); Trace.disableTracing(null); if (PRINT_CNT) { System.out.println("Number of envs created/destroyed: " + CNT); diff --git a/test/knownfailures.json b/test/knownfailures.json index dc051d9515..a12510c9dc 100644 --- a/test/knownfailures.json +++ b/test/knownfailures.json @@ -649,11 +649,6 @@ "tests": "661-oat-writer-layout", "variant": "interp-ac | interpreter | jit | no-dex2oat | no-prebuild | no-image | trace", "description": ["Test is designed to only check --compiler-filter=speed"] - }, - { - "tests": ["975-iface-private"], - "variant": "cdex-fast", - "description": ["CompactDex doesn't yet work with 975-iface private"] } ] diff --git a/test/ti-agent/trace_helper.cc b/test/ti-agent/trace_helper.cc index bbc7754a45..b590175d77 100644 --- a/test/ti-agent/trace_helper.cc +++ b/test/ti-agent/trace_helper.cc @@ -27,6 +27,49 @@ namespace art { namespace common_trace { +static bool IsInCallback(JNIEnv* env, jvmtiEnv *jvmti, jthread thr) { + void* data; + ScopedLocalRef<jthrowable> exc(env, env->ExceptionOccurred()); + env->ExceptionClear(); + jvmti->GetThreadLocalStorage(thr, &data); + if (exc.get() != nullptr) { + env->Throw(exc.get()); + } + if (data == nullptr) { + return false; + } else { + return true; + } +} + +static void SetInCallback(JNIEnv* env, jvmtiEnv *jvmti, jthread thr, bool val) { + ScopedLocalRef<jthrowable> exc(env, env->ExceptionOccurred()); + env->ExceptionClear(); + jvmti->SetThreadLocalStorage(thr, (val ? reinterpret_cast<void*>(0x1) + : reinterpret_cast<void*>(0x0))); + if (exc.get() != nullptr) { + env->Throw(exc.get()); + } +} + +class ScopedCallbackState { + public: + ScopedCallbackState(JNIEnv* jnienv, jvmtiEnv* env, jthread thr) + : jnienv_(jnienv), env_(env), thr_(thr) { + CHECK(!IsInCallback(jnienv_, env_, thr_)); + SetInCallback(jnienv_, env_, thr_, true); + } + ~ScopedCallbackState() { + CHECK(IsInCallback(jnienv_, env_, thr_)); + SetInCallback(jnienv_, env_, thr_, false); + } + + private: + JNIEnv* jnienv_; + jvmtiEnv* env_; + jthread thr_; +}; + struct TraceData { jclass test_klass; jmethodID enter_method; @@ -36,7 +79,6 @@ struct TraceData { jmethodID single_step; jmethodID thread_start; jmethodID thread_end; - bool in_callback; bool access_watch_on_load; bool modify_watch_on_load; jrawMonitorID trace_mon; @@ -94,7 +136,7 @@ static void singleStepCB(jvmtiEnv* jvmti, jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) { return; } - if (data->in_callback) { + if (IsInCallback(jnienv, jvmti, thread)) { return; } ScopedLocalRef<jclass> klass(jnienv, data->GetTestClass(jvmti, jnienv)); @@ -102,7 +144,7 @@ static void singleStepCB(jvmtiEnv* jvmti, return; } CHECK(data->single_step != nullptr); - data->in_callback = true; + ScopedCallbackState st(jnienv, jvmti, thread); jobject method_arg = GetJavaMethod(jvmti, jnienv, method); jnienv->CallStaticVoidMethod(klass.get(), data->single_step, @@ -110,12 +152,11 @@ static void singleStepCB(jvmtiEnv* jvmti, method_arg, static_cast<jlong>(location)); jnienv->DeleteLocalRef(method_arg); - data->in_callback = false; } static void fieldAccessCB(jvmtiEnv* jvmti, JNIEnv* jnienv, - jthread thr ATTRIBUTE_UNUSED, + jthread thr, jmethodID method, jlocation location, jclass field_klass, @@ -126,7 +167,7 @@ static void fieldAccessCB(jvmtiEnv* jvmti, jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) { return; } - if (data->in_callback) { + if (IsInCallback(jnienv, jvmti, thr)) { // Don't do callback for either of these to prevent an infinite loop. return; } @@ -135,7 +176,7 @@ static void fieldAccessCB(jvmtiEnv* jvmti, return; } CHECK(data->field_access != nullptr); - data->in_callback = true; + ScopedCallbackState st(jnienv, jvmti, thr); jobject method_arg = GetJavaMethod(jvmti, jnienv, method); jobject field_arg = GetJavaField(jvmti, jnienv, field_klass, field); jnienv->CallStaticVoidMethod(klass.get(), @@ -147,12 +188,11 @@ static void fieldAccessCB(jvmtiEnv* jvmti, field_arg); jnienv->DeleteLocalRef(method_arg); jnienv->DeleteLocalRef(field_arg); - data->in_callback = false; } static void fieldModificationCB(jvmtiEnv* jvmti, JNIEnv* jnienv, - jthread thr ATTRIBUTE_UNUSED, + jthread thr, jmethodID method, jlocation location, jclass field_klass, @@ -165,7 +205,7 @@ static void fieldModificationCB(jvmtiEnv* jvmti, jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) { return; } - if (data->in_callback) { + if (IsInCallback(jnienv, jvmti, thr)) { // Don't do callback recursively to prevent an infinite loop. return; } @@ -174,12 +214,11 @@ static void fieldModificationCB(jvmtiEnv* jvmti, return; } CHECK(data->field_modify != nullptr); - data->in_callback = true; + ScopedCallbackState st(jnienv, jvmti, thr); jobject method_arg = GetJavaMethod(jvmti, jnienv, method); jobject field_arg = GetJavaField(jvmti, jnienv, field_klass, field); jobject value = GetJavaValueByType(jnienv, type_char, new_value); if (jnienv->ExceptionCheck()) { - data->in_callback = false; jnienv->DeleteLocalRef(method_arg); jnienv->DeleteLocalRef(field_arg); return; @@ -194,12 +233,11 @@ static void fieldModificationCB(jvmtiEnv* jvmti, value); jnienv->DeleteLocalRef(method_arg); jnienv->DeleteLocalRef(field_arg); - data->in_callback = false; } static void methodExitCB(jvmtiEnv* jvmti, JNIEnv* jnienv, - jthread thr ATTRIBUTE_UNUSED, + jthread thr, jmethodID method, jboolean was_popped_by_exception, jvalue return_value) { @@ -208,7 +246,9 @@ static void methodExitCB(jvmtiEnv* jvmti, jvmti->GetEnvironmentLocalStorage(reinterpret_cast<void**>(&data)))) { return; } - if (method == data->exit_method || method == data->enter_method || data->in_callback) { + if (method == data->exit_method || + method == data->enter_method || + IsInCallback(jnienv, jvmti, thr)) { // Don't do callback for either of these to prevent an infinite loop. return; } @@ -217,12 +257,11 @@ static void methodExitCB(jvmtiEnv* jvmti, return; } CHECK(data->exit_method != nullptr); - data->in_callback = true; + ScopedCallbackState st(jnienv, jvmti, thr); jobject method_arg = GetJavaMethod(jvmti, jnienv, method); jobject result = was_popped_by_exception ? nullptr : GetJavaValue(jvmti, jnienv, method, return_value); if (jnienv->ExceptionCheck()) { - data->in_callback = false; return; } jnienv->CallStaticVoidMethod(klass.get(), @@ -231,12 +270,11 @@ static void methodExitCB(jvmtiEnv* jvmti, was_popped_by_exception, result); jnienv->DeleteLocalRef(method_arg); - data->in_callback = false; } static void methodEntryCB(jvmtiEnv* jvmti, JNIEnv* jnienv, - jthread thr ATTRIBUTE_UNUSED, + jthread thr, jmethodID method) { TraceData* data = nullptr; if (JvmtiErrorToException(jnienv, jvmti, @@ -244,7 +282,9 @@ static void methodEntryCB(jvmtiEnv* jvmti, return; } CHECK(data->enter_method != nullptr); - if (method == data->exit_method || method == data->enter_method || data->in_callback) { + if (method == data->exit_method || + method == data->enter_method || + IsInCallback(jnienv, jvmti, thr)) { // Don't do callback for either of these to prevent an infinite loop. return; } @@ -252,14 +292,13 @@ static void methodEntryCB(jvmtiEnv* jvmti, if (klass.get() == nullptr) { return; } - data->in_callback = true; + ScopedCallbackState st(jnienv, jvmti, thr); jobject method_arg = GetJavaMethod(jvmti, jnienv, method); if (jnienv->ExceptionCheck()) { return; } jnienv->CallStaticVoidMethod(klass.get(), data->enter_method, method_arg); jnienv->DeleteLocalRef(method_arg); - data->in_callback = false; } static void classPrepareCB(jvmtiEnv* jvmti, @@ -459,7 +498,6 @@ extern "C" JNIEXPORT void JNICALL Java_art_Trace_enableTracing2( data->single_step = single_step != nullptr ? env->FromReflectedMethod(single_step) : nullptr; data->thread_start = thread_start != nullptr ? env->FromReflectedMethod(thread_start) : nullptr; data->thread_end = thread_end != nullptr ? env->FromReflectedMethod(thread_end) : nullptr; - data->in_callback = false; TraceData* old_data = nullptr; if (JvmtiErrorToException(env, jvmti_env, |