Limit test 904 to examining test threads

Test 904 could flake due to capturing allocations from unrelated
android system threads. To fix this we filter the allocations we have
collected for those from threads created for/running the test.

Test: ./test.py --host -j50
Change-Id: Id4636dc153ab5a8208cd5f7bb255e29939dc2b02
diff --git a/test/904-object-allocation/src/art/Test904.java b/test/904-object-allocation/src/art/Test904.java
index fda8985..a2848fb 100644
--- a/test/904-object-allocation/src/art/Test904.java
+++ b/test/904-object-allocation/src/art/Test904.java
@@ -47,7 +47,8 @@
     // Enable actual logging callback.
     setupObjectAllocCallback(true);
 
-    System.out.println(Arrays.toString(getTrackingEventMessages()));
+    System.out.println(Arrays.toString(getTrackingEventMessages(
+            new Thread[] { Thread.currentThread(), })));
 
     enableAllocationTracking(null, true);
 
@@ -66,22 +67,25 @@
 
     l.add(new Byte((byte)0));
 
-    System.out.println(Arrays.toString(getTrackingEventMessages()));
+    System.out.println(Arrays.toString(getTrackingEventMessages(
+            new Thread[] { Thread.currentThread(), })));
     System.out.println("Tracking on same thread");
 
-    testThread(l, true, true);
+    Thread test_thread = testThread(l, true, true);
 
     l.add(new Byte((byte)0));
 
-    System.out.println(Arrays.toString(getTrackingEventMessages()));
+    System.out.println(Arrays.toString(getTrackingEventMessages(
+            new Thread[] { Thread.currentThread(), test_thread, })));
     System.out.println("Tracking on same thread, not disabling tracking");
 
-    testThread(l, true, false);
+    test_thread = testThread(l, true, false);
 
-    System.out.println(Arrays.toString(getTrackingEventMessages()));
+    System.out.println(Arrays.toString(getTrackingEventMessages(
+            new Thread[] { Thread.currentThread(), test_thread, })));
     System.out.println("Tracking on different thread");
 
-    testThread(l, false, true);
+    test_thread = testThread(l, false, true);
 
     l.add(new Byte((byte)0));
 
@@ -89,12 +93,13 @@
     // check that shutdown works correctly.
     setupObjectAllocCallback(false);
 
-    System.out.println(Arrays.toString(getTrackingEventMessages()));
+    System.out.println(Arrays.toString(getTrackingEventMessages(
+            new Thread[] { Thread.currentThread(), test_thread, })));
 
     enableAllocationTracking(null, true);
   }
 
-  private static void testThread(final ArrayList<Object> l, final boolean sameThread,
+  private static Thread testThread(final ArrayList<Object> l, final boolean sameThread,
       final boolean disableTracking) throws Exception {
     final SimpleBarrier startBarrier = new SimpleBarrier(1);
     final SimpleBarrier trackBarrier = new SimpleBarrier(1);
@@ -126,6 +131,7 @@
     trackBarrier.dec();
 
     t.join();
+    return t;
   }
 
   private static class SimpleBarrier {
@@ -149,5 +155,5 @@
 
   private static native void setupObjectAllocCallback(boolean enable);
   private static native void enableAllocationTracking(Thread thread, boolean enable);
-  private static native String[] getTrackingEventMessages();
+  private static native String[] getTrackingEventMessages(Thread[] threads);
 }
diff --git a/test/904-object-allocation/tracking.cc b/test/904-object-allocation/tracking.cc
index 9d2592a..f7296b1 100644
--- a/test/904-object-allocation/tracking.cc
+++ b/test/904-object-allocation/tracking.cc
@@ -35,6 +35,8 @@
 namespace art {
 namespace Test904ObjectAllocation {
 
+static JavaVM* vm;
+
 static std::string GetClassName(JNIEnv* jni_env, jclass cls) {
   ScopedLocalRef<jclass> class_class(jni_env, jni_env->GetObjectClass(cls));
   jmethodID mid = jni_env->GetMethodID(class_class.get(), "getName", "()Ljava/lang/String;");
@@ -44,12 +46,45 @@
   return utf_chars.c_str();
 }
 
+template <typename T>
+class ScopedGlobalRef {
+ public:
+  ScopedGlobalRef(JNIEnv* env, T obj) : obj_(env->NewGlobalRef(obj)) {}
+  ScopedGlobalRef(const ScopedGlobalRef<T>& src) noexcept
+      : obj_(GetEnv()->NewGlobalRef(src.obj_)) {}
+  ScopedGlobalRef(ScopedGlobalRef<T>&& src) noexcept : obj_(src.obj_) {
+    src.obj_ = nullptr;
+  }
+
+  ~ScopedGlobalRef() {
+    GetEnv()->DeleteGlobalRef(obj_);
+  }
+
+  T Get(JNIEnv* env) const {
+    return env->NewLocalRef(obj_);
+  }
+
+ private:
+  JNIEnv* GetEnv() const {
+    JNIEnv* env = nullptr;
+    CHECK_EQ(vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6), 0);
+    return env;
+  }
+
+  jobject obj_;
+};
+
+struct EventLog {
+  std::string msg_;
+  ScopedGlobalRef<jthread> thr_;
+};
+
 static std::mutex gEventsMutex;
-static std::vector<std::string> gEvents;
+static std::vector<EventLog> gEvents;
 
 static void JNICALL ObjectAllocated(jvmtiEnv* ti_env ATTRIBUTE_UNUSED,
                                     JNIEnv* jni_env,
-                                    jthread thread ATTRIBUTE_UNUSED,
+                                    jthread thread,
                                     jobject object,
                                     jclass object_klass,
                                     jlong size) {
@@ -58,14 +93,16 @@
   std::string object_klass_descriptor2 = GetClassName(jni_env, object_klass2.get());
 
   std::lock_guard<std::mutex> guard(gEventsMutex);
-  gEvents.push_back(android::base::StringPrintf("ObjectAllocated type %s/%s size %zu",
-                                                object_klass_descriptor.c_str(),
-                                                object_klass_descriptor2.c_str(),
-                                                static_cast<size_t>(size)));
+  gEvents.push_back({android::base::StringPrintf("ObjectAllocated type %s/%s size %zu",
+                                                 object_klass_descriptor.c_str(),
+                                                 object_klass_descriptor2.c_str(),
+                                                 static_cast<size_t>(size)),
+                     ScopedGlobalRef<jthread>(jni_env, thread)});
 }
 
 extern "C" JNIEXPORT void JNICALL Java_art_Test904_setupObjectAllocCallback(
     JNIEnv* env, jclass klass ATTRIBUTE_UNUSED, jboolean enable) {
+  env->GetJavaVM(&vm);
   jvmtiEventCallbacks callbacks;
   memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
   callbacks.VMObjectAlloc = enable ? ObjectAllocated : nullptr;
@@ -84,13 +121,32 @@
 }
 
 extern "C" JNIEXPORT jobjectArray JNICALL Java_art_Test904_getTrackingEventMessages(
-    JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED) {
+    JNIEnv* env, jclass Main_klass ATTRIBUTE_UNUSED, jobjectArray threads) {
   std::lock_guard<std::mutex> guard(gEventsMutex);
+  std::vector<std::string> real_events;
+  std::vector<jthread> thread_lst;
+  jint nthreads = env->GetArrayLength(threads);
+  {
+    env->PushLocalFrame(nthreads + 1);
+    for (jint i = 0; i < nthreads; i++) {
+      thread_lst.push_back(reinterpret_cast<jthread>(env->GetObjectArrayElement(threads, i)));
+    }
+    for (const EventLog& ev : gEvents) {
+      ScopedLocalRef<jthread> thr(env, ev.thr_.Get(env));
+      for (jthread req_thread : thread_lst) {
+        if (env->IsSameObject(req_thread, thr.get())) {
+          real_events.push_back(ev.msg_);
+          break;
+        }
+      }
+    }
+    env->PopLocalFrame(nullptr);
+  }
   jobjectArray ret = CreateObjectArray(env,
-                                       static_cast<jint>(gEvents.size()),
+                                       static_cast<jint>(real_events.size()),
                                        "java/lang/String",
                                        [&](jint i) {
-    return env->NewStringUTF(gEvents[i].c_str());
+    return env->NewStringUTF(real_events[i].c_str());
   });
   gEvents.clear();
   return ret;