OSDN Git Service

Fix flaky jit-gcstress tests 93{4,5,8}.
authorAlex Light <allight@google.com>
Wed, 1 Feb 2017 17:41:26 +0000 (09:41 -0800)
committerAlex Light <allight@google.com>
Wed, 1 Feb 2017 18:17:44 +0000 (10:17 -0800)
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
test/935-non-retransformable/src-ex/TestMain.java
test/935-non-retransformable/src/Main.java
test/938-load-transform-bcp/src/Main.java
test/ti-agent/common_helper.cc

index 3bd913b..de312b0 100644 (file)
@@ -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,
index aebcdee..d412fba 100644 (file)
 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);
   }
 }
index 0d103ab..82ba197 100644 (file)
@@ -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);
 }
index 13bc5da..5484899 100644 (file)
@@ -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,
index ed82bb0..ea6359e 100644 (file)
@@ -210,6 +210,7 @@ struct CommonTransformationResult {
 
 // Map from class name to transformation result.
 std::map<std::string, std::deque<CommonTransformationResult>> 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());
   }
 }