ART: Add object reclaim support
Add support for the object free callback.
Refactor code in support. Add test.
Bug: 31384923
Test: m test-art-host
Test: m test-art-host-run-test-905-object-free
Test: m ART_USE_READ_BARRIER=true test-art-host-run-test-905-object-free
Change-Id: Icde40ad464c723cfe2f7660c07cd2f79b6dc2032
diff --git a/test/902-hello-transformation/transform.cc b/test/902-hello-transformation/transform.cc
index e0d623e..5b0d219 100644
--- a/test/902-hello-transformation/transform.cc
+++ b/test/902-hello-transformation/transform.cc
@@ -23,6 +23,7 @@
#include "base/logging.h"
#include "jni.h"
#include "openjdkjvmti/jvmti.h"
+#include "ti-agent/common_load.h"
#include "utils.h"
namespace art {
@@ -30,7 +31,6 @@
static bool RuntimeIsJvm = false;
-jvmtiEnv* jvmti_env;
bool IsJVM() {
return RuntimeIsJvm;
}
diff --git a/test/903-hello-tagging/tagging.cc b/test/903-hello-tagging/tagging.cc
index 8ccdf49..7d692fb 100644
--- a/test/903-hello-tagging/tagging.cc
+++ b/test/903-hello-tagging/tagging.cc
@@ -25,13 +25,12 @@
#include "base/logging.h"
#include "jni.h"
#include "openjdkjvmti/jvmti.h"
+#include "ti-agent/common_load.h"
#include "utils.h"
namespace art {
namespace Test903HelloTagging {
-static jvmtiEnv* jvmti_env;
-
extern "C" JNIEXPORT void JNICALL Java_Main_setTag(JNIEnv* env ATTRIBUTE_UNUSED,
jclass,
jobject obj,
diff --git a/test/904-object-allocation/src/Main.java b/test/904-object-allocation/src/Main.java
index f15c1c2..9a089bd 100644
--- a/test/904-object-allocation/src/Main.java
+++ b/test/904-object-allocation/src/Main.java
@@ -40,7 +40,7 @@
}
public static void doTest(ArrayList<Object> l) throws Exception {
- setupCallback();
+ setupObjectAllocCallback();
enableAllocationTracking(null, true);
@@ -127,6 +127,6 @@
}
}
- private static native void setupCallback();
+ private static native void setupObjectAllocCallback();
private static native void enableAllocationTracking(Thread thread, boolean enable);
}
diff --git a/test/904-object-allocation/tracking.cc b/test/904-object-allocation/tracking.cc
index c392cd4..b22fc6c 100644
--- a/test/904-object-allocation/tracking.cc
+++ b/test/904-object-allocation/tracking.cc
@@ -26,13 +26,12 @@
#include "openjdkjvmti/jvmti.h"
#include "ScopedLocalRef.h"
#include "ScopedUtfChars.h"
+#include "ti-agent/common_load.h"
#include "utils.h"
namespace art {
namespace Test904ObjectAllocation {
-static jvmtiEnv* jvmti_env;
-
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;");
@@ -58,7 +57,8 @@
static_cast<size_t>(size));
}
-extern "C" JNIEXPORT void JNICALL Java_Main_setupCallback(JNIEnv* env ATTRIBUTE_UNUSED, jclass) {
+extern "C" JNIEXPORT void JNICALL Java_Main_setupObjectAllocCallback(
+ JNIEnv* env ATTRIBUTE_UNUSED, jclass klass ATTRIBUTE_UNUSED) {
jvmtiEventCallbacks callbacks;
memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
callbacks.VMObjectAlloc = ObjectAllocated;
@@ -82,7 +82,7 @@
if (ret != JVMTI_ERROR_NONE) {
char* err;
jvmti_env->GetErrorName(ret, &err);
- printf("Error getting tag: %s\n", err);
+ printf("Error enabling/disabling allocation tracking: %s\n", err);
}
}
diff --git a/test/905-object-free/build b/test/905-object-free/build
new file mode 100755
index 0000000..898e2e5
--- /dev/null
+++ b/test/905-object-free/build
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+./default-build "$@" --experimental agents
diff --git a/test/905-object-free/expected.txt b/test/905-object-free/expected.txt
new file mode 100644
index 0000000..31b7318
--- /dev/null
+++ b/test/905-object-free/expected.txt
@@ -0,0 +1,10 @@
+ObjectFree tag=1
+---
+ObjectFree tag=10
+ObjectFree tag=100
+ObjectFree tag=1000
+---
+---
+---
+---
+---
diff --git a/test/905-object-free/info.txt b/test/905-object-free/info.txt
new file mode 100644
index 0000000..875a5f6
--- /dev/null
+++ b/test/905-object-free/info.txt
@@ -0,0 +1 @@
+Tests basic functions in the jvmti plugin.
diff --git a/test/905-object-free/run b/test/905-object-free/run
new file mode 100755
index 0000000..753b742
--- /dev/null
+++ b/test/905-object-free/run
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# Copyright 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+plugin=libopenjdkjvmtid.so
+agent=libtiagentd.so
+lib=tiagentd
+if [[ "$@" == *"-O"* ]]; then
+ agent=libtiagent.so
+ plugin=libopenjdkjvmti.so
+ lib=tiagent
+fi
+
+if [[ "$@" == *"--jvm"* ]]; then
+ arg="jvm"
+else
+ arg="art"
+fi
+
+if [[ "$@" != *"--debuggable"* ]]; then
+ other_args=" -Xcompiler-option --debuggable "
+else
+ other_args=""
+fi
+
+./default-run "$@" --experimental agents \
+ --experimental runtime-plugins \
+ --runtime-option -agentpath:${agent}=905-object-free,${arg} \
+ --android-runtime-option -Xplugin:${plugin} \
+ ${other_args} \
+ --args ${lib}
diff --git a/test/905-object-free/src/Main.java b/test/905-object-free/src/Main.java
new file mode 100644
index 0000000..7b52e29
--- /dev/null
+++ b/test/905-object-free/src/Main.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.ArrayList;
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[1]);
+
+ doTest();
+ }
+
+ public static void doTest() throws Exception {
+ // Use a list to ensure objects must be allocated.
+ ArrayList<Object> l = new ArrayList<>(100);
+
+ setupObjectFreeCallback();
+
+ enableFreeTracking(true);
+ run(l);
+
+ enableFreeTracking(false);
+ run(l);
+ }
+
+ private static void run(ArrayList<Object> l) {
+ allocate(l, 1);
+ l.clear();
+
+ Runtime.getRuntime().gc();
+
+ System.out.println("---");
+
+ // Note: the reporting will not depend on the heap layout (which could be unstable). Walking
+ // the tag table should give us a stable output order.
+ for (int i = 10; i <= 1000; i *= 10) {
+ allocate(l, i);
+ }
+ l.clear();
+
+ Runtime.getRuntime().gc();
+
+ System.out.println("---");
+
+ Runtime.getRuntime().gc();
+
+ System.out.println("---");
+ }
+
+ private static void allocate(ArrayList<Object> l, long tag) {
+ Object obj = new Object();
+ l.add(obj);
+ setTag(obj, tag);
+ }
+
+ private static native void setupObjectFreeCallback();
+ private static native void enableFreeTracking(boolean enable);
+ private static native void setTag(Object o, long tag);
+}
diff --git a/test/905-object-free/tracking_free.cc b/test/905-object-free/tracking_free.cc
new file mode 100644
index 0000000..5905d48
--- /dev/null
+++ b/test/905-object-free/tracking_free.cc
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tracking_free.h"
+
+#include <iostream>
+#include <pthread.h>
+#include <stdio.h>
+#include <vector>
+
+#include "base/logging.h"
+#include "jni.h"
+#include "openjdkjvmti/jvmti.h"
+#include "ScopedLocalRef.h"
+#include "ScopedUtfChars.h"
+#include "ti-agent/common_load.h"
+#include "utils.h"
+
+namespace art {
+namespace Test905ObjectFree {
+
+static void JNICALL ObjectFree(jvmtiEnv* ti_env ATTRIBUTE_UNUSED, jlong tag) {
+ printf("ObjectFree tag=%zu\n", static_cast<size_t>(tag));
+}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_setupObjectFreeCallback(
+ JNIEnv* env ATTRIBUTE_UNUSED, jclass klass ATTRIBUTE_UNUSED) {
+ jvmtiEventCallbacks callbacks;
+ memset(&callbacks, 0, sizeof(jvmtiEventCallbacks));
+ callbacks.ObjectFree = ObjectFree;
+
+ jvmtiError ret = jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
+ if (ret != JVMTI_ERROR_NONE) {
+ char* err;
+ jvmti_env->GetErrorName(ret, &err);
+ printf("Error setting callbacks: %s\n", err);
+ }
+}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_enableFreeTracking(JNIEnv* env ATTRIBUTE_UNUSED,
+ jclass klass ATTRIBUTE_UNUSED,
+ jboolean enable) {
+ jvmtiError ret = jvmti_env->SetEventNotificationMode(
+ enable ? JVMTI_ENABLE : JVMTI_DISABLE,
+ JVMTI_EVENT_OBJECT_FREE,
+ nullptr);
+ if (ret != JVMTI_ERROR_NONE) {
+ char* err;
+ jvmti_env->GetErrorName(ret, &err);
+ printf("Error enabling/disabling object-free callbacks: %s\n", err);
+ }
+}
+
+// Don't do anything
+jint OnLoad(JavaVM* vm,
+ char* options ATTRIBUTE_UNUSED,
+ void* reserved ATTRIBUTE_UNUSED) {
+ if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
+ printf("Unable to get jvmti env!\n");
+ return 1;
+ }
+ return 0;
+}
+
+} // namespace Test905ObjectFree
+} // namespace art
diff --git a/test/905-object-free/tracking_free.h b/test/905-object-free/tracking_free.h
new file mode 100644
index 0000000..ba4aa43
--- /dev/null
+++ b/test/905-object-free/tracking_free.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_TEST_905_OBJECT_FREE_TRACKING_FREE_H_
+#define ART_TEST_905_OBJECT_FREE_TRACKING_FREE_H_
+
+#include <jni.h>
+
+namespace art {
+namespace Test905ObjectFree {
+
+jint OnLoad(JavaVM* vm, char* options, void* reserved);
+
+} // namespace Test905ObjectFree
+} // namespace art
+
+#endif // ART_TEST_905_OBJECT_FREE_TRACKING_FREE_H_
diff --git a/test/Android.bp b/test/Android.bp
index b2152e8..4457e8a 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -247,6 +247,7 @@
"902-hello-transformation/transform.cc",
"903-hello-tagging/tagging.cc",
"904-object-allocation/tracking.cc",
+ "905-object-free/tracking_free.cc",
],
shared_libs: [
"libart",
@@ -267,6 +268,7 @@
"902-hello-transformation/transform.cc",
"903-hello-tagging/tagging.cc",
"904-object-allocation/tracking.cc",
+ "905-object-free/tracking_free.cc",
],
shared_libs: [
"libartd",
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 935d6ad..29000f0 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -263,7 +263,7 @@
# 147-stripped-dex-fallback isn't supported on device because --strip-dex
# requires the zip command.
# 569-checker-pattern-replacement tests behaviour present only on host.
-# 90{2,3,4} are not supported in current form due to linker
+# 90{2,3,4,5} are not supported in current form due to linker
# restrictions. See b/31681198
TEST_ART_BROKEN_TARGET_TESTS := \
147-stripped-dex-fallback \
@@ -271,6 +271,7 @@
902-hello-transformation \
903-hello-tagging \
904-object-allocation \
+ 905-object-free \
ifneq (,$(filter target,$(TARGET_TYPES)))
ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,target,$(RUN_TYPES),$(PREBUILD_TYPES), \
diff --git a/test/ti-agent/common_load.cc b/test/ti-agent/common_load.cc
index fde3c6b..2b8947e 100644
--- a/test/ti-agent/common_load.cc
+++ b/test/ti-agent/common_load.cc
@@ -22,14 +22,18 @@
#include "art_method-inl.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "common_load.h"
#include "901-hello-ti-agent/basics.h"
#include "902-hello-transformation/transform.h"
#include "903-hello-tagging/tagging.h"
#include "904-object-allocation/tracking.h"
+#include "905-object-free/tracking_free.h"
namespace art {
+jvmtiEnv* jvmti_env;
+
using OnLoad = jint (*)(JavaVM* vm, char* options, void* reserved);
using OnAttach = jint (*)(JavaVM* vm, char* options, void* reserved);
@@ -45,6 +49,7 @@
{ "902-hello-transformation", Test902HelloTransformation::OnLoad, nullptr },
{ "903-hello-tagging", Test903HelloTagging::OnLoad, nullptr },
{ "904-object-allocation", Test904ObjectAllocation::OnLoad, nullptr },
+ { "905-object-free", Test905ObjectFree::OnLoad, nullptr },
};
static AgentLib* FindAgent(char* name) {
diff --git a/test/ti-agent/common_load.h b/test/ti-agent/common_load.h
new file mode 100644
index 0000000..fac94b4
--- /dev/null
+++ b/test/ti-agent/common_load.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_TEST_TI_AGENT_COMMON_LOAD_H_
+#define ART_TEST_TI_AGENT_COMMON_LOAD_H_
+
+#include "openjdkjvmti/jvmti.h"
+
+namespace art {
+
+extern jvmtiEnv* jvmti_env;
+
+} // namespace art
+
+#endif // ART_TEST_TI_AGENT_COMMON_LOAD_H_