From e41cad6f2a989a80f58dec18c99bb36b0ce8ae23 Mon Sep 17 00:00:00 2001 From: Alex Light Date: Wed, 1 Feb 2017 09:41:26 -0800 Subject: Fix flaky jit-gcstress tests 93{4,5,8}. We were letting the jit and the main thread race on class definition. If the 'leader' changes then we would end up with the test class having an unexpected definition, causing the test to fail. We fixed this by making sure all threads get the same definition regardless of speed. Bug: 34799243 Test: mma -j40 test-art-host Test: stress --cpu 60 &; \ while ./test/run-test --host --jit --gcstress --64 934 ; do ; done Test: stress --cpu 60 &; \ while ./test/run-test --host --jit --gcstress --64 935 ; do ; done Test: stress --cpu 60 &; \ while ./test/run-test --host --jit --gcstress --64 938 ; do ; done Change-Id: I0d6785b4c3c41db1d655cf1ff22be60809923a7a --- test/934-load-transform/src/Main.java | 4 ++++ test/935-non-retransformable/src-ex/TestMain.java | 21 +++++++----------- test/935-non-retransformable/src/Main.java | 5 +++++ test/938-load-transform-bcp/src/Main.java | 3 ++- test/ti-agent/common_helper.cc | 26 +++++++++++++++++++++++ 5 files changed, 45 insertions(+), 14 deletions(-) diff --git a/test/934-load-transform/src/Main.java b/test/934-load-transform/src/Main.java index 3bd913bfe0..de312b03da 100644 --- a/test/934-load-transform/src/Main.java +++ b/test/934-load-transform/src/Main.java @@ -66,6 +66,9 @@ class Main { } public static void main(String[] args) { + // Don't pop transformations. Make sure that even if 2 threads race to define the class both + // will get the same result. + setPopRetransformations(false); addCommonTransformationResult("Transform", CLASS_BYTES, DEX_BYTES); enableCommonRetransformation(true); try { @@ -83,6 +86,7 @@ class Main { } } + private static native void setPopRetransformations(boolean should_pop); // Transforms the class private static native void enableCommonRetransformation(boolean enable); private static native void addCommonTransformationResult(String target_name, diff --git a/test/935-non-retransformable/src-ex/TestMain.java b/test/935-non-retransformable/src-ex/TestMain.java index aebcdee851..d412fba37a 100644 --- a/test/935-non-retransformable/src-ex/TestMain.java +++ b/test/935-non-retransformable/src-ex/TestMain.java @@ -17,19 +17,14 @@ import java.lang.reflect.Method; public class TestMain { - public static void runTest() { + public static void runTest() throws Exception { Transform t = new Transform(); - try { - // Call functions with reflection. Since the sayGoodbye function does not exist in the - // LTransform; when we compile this for the first time we need to use reflection. - Method hi = Transform.class.getMethod("sayHi"); - Method bye = Transform.class.getMethod("sayGoodbye"); - hi.invoke(t); - t.sayHi(); - bye.invoke(t); - } catch (Exception e) { - System.out.println("Unexpected error occured! " + e.toString()); - e.printStackTrace(); - } + // Call functions with reflection. Since the sayGoodbye function does not exist in the + // LTransform; when we compile this for the first time we need to use reflection. + Method hi = Transform.class.getMethod("sayHi"); + Method bye = Transform.class.getMethod("sayGoodbye"); + hi.invoke(t); + t.sayHi(); + bye.invoke(t); } } diff --git a/test/935-non-retransformable/src/Main.java b/test/935-non-retransformable/src/Main.java index 0d103ab86d..82ba197b7e 100644 --- a/test/935-non-retransformable/src/Main.java +++ b/test/935-non-retransformable/src/Main.java @@ -74,6 +74,7 @@ class Main { } public static void main(String[] args) { + setPopRetransformations(false); addCommonTransformationResult("Transform", CLASS_BYTES, DEX_BYTES); enableCommonRetransformation(true); try { @@ -86,6 +87,8 @@ class Main { Method run_test = klass.getMethod("runTest"); run_test.invoke(null); + // Remove the original transformation. It has been used by now. + popTransformationFor("Transform"); // Make sure we don't get called for transformation again. addCommonTransformationResult("Transform", new byte[0], new byte[0]); doCommonClassRetransformation(new_loader.loadClass("Transform")); @@ -102,4 +105,6 @@ class Main { private static native void addCommonTransformationResult(String target_name, byte[] class_bytes, byte[] dex_bytes); + private static native void setPopRetransformations(boolean should_pop); + private static native void popTransformationFor(String target_name); } diff --git a/test/938-load-transform-bcp/src/Main.java b/test/938-load-transform-bcp/src/Main.java index 13bc5da461..548489939e 100644 --- a/test/938-load-transform-bcp/src/Main.java +++ b/test/938-load-transform-bcp/src/Main.java @@ -96,7 +96,7 @@ class Main { } public static void main(String[] args) { - // TODO WHAT TO TRANSFORM + setPopRetransformations(false); addCommonTransformationResult("java/util/OptionalLong", CLASS_BYTES, DEX_BYTES); enableCommonRetransformation(true); try { @@ -114,6 +114,7 @@ class Main { } } + private static native void setPopRetransformations(boolean should_pop); // Transforms the class private static native void enableCommonRetransformation(boolean enable); private static native void addCommonTransformationResult(String target_name, diff --git a/test/ti-agent/common_helper.cc b/test/ti-agent/common_helper.cc index ed82bb04cf..ea6359e5e0 100644 --- a/test/ti-agent/common_helper.cc +++ b/test/ti-agent/common_helper.cc @@ -210,6 +210,7 @@ struct CommonTransformationResult { // Map from class name to transformation result. std::map> gTransformations; +bool gPopTransformations = true; extern "C" JNIEXPORT void JNICALL Java_Main_addCommonTransformationResult(JNIEnv* env, jclass, @@ -266,7 +267,32 @@ void JNICALL CommonClassFileLoadHookRetransformable(jvmtiEnv* jvmti_env, memcpy(new_data, desired_array.data(), desired_array.size()); *new_class_data = new_data; *new_class_data_len = desired_array.size(); + if (gPopTransformations) { + gTransformations[name_str].pop_front(); + } + } +} + +extern "C" JNIEXPORT void Java_Main_setPopRetransformations(JNIEnv*, + jclass, + jboolean enable) { + gPopTransformations = enable; +} + +extern "C" JNIEXPORT void Java_Main_popTransformationFor(JNIEnv* env, + jclass, + jstring class_name) { + const char* name_chrs = env->GetStringUTFChars(class_name, nullptr); + std::string name_str(name_chrs); + env->ReleaseStringUTFChars(class_name, name_chrs); + if (gTransformations.find(name_str) != gTransformations.end() && + gTransformations[name_str].size() > 0) { gTransformations[name_str].pop_front(); + } else { + std::stringstream err; + err << "No transformations found for class " << name_str; + std::string message = err.str(); + env->ThrowNew(env->FindClass("java/lang/Exception"), message.c_str()); } } -- cgit v1.2.3-59-g8ed1b