summaryrefslogtreecommitdiff
path: root/runtime/native/dalvik_system_VMDebug.cc
diff options
context:
space:
mode:
author Richard Uhler <ruhler@google.com> 2017-11-22 16:12:29 +0000
committer Richard Uhler <ruhler@google.com> 2017-12-01 09:10:48 +0000
commit660be6ff67870d2512230b13effefdbc5abe43e4 (patch)
tree4a4cde728d6aeb2ea8f1ef63c7e7f82383a9acd0 /runtime/native/dalvik_system_VMDebug.cc
parenta602c56ba1a82d70eb40de35e7c716477a46ee28 (diff)
Add VMDebug.getInstancesOfClasses API.
The API can be used to iterate over instances of a given type on the heap. The GetInstancesOfClassesBenchmark run on bullhead shows the run time of the API grows linearly in the number of classes, C, to get instances of and the number of total instances, N, allocated on the heap. C N=~2^18 N=~2^19 1 13ms 21ms 2 26ms 43ms 4 53ms 87ms Bug: 69729799 Test: ./test/testrunner/testrunner.py -t 099-vmdebug -b --host Change-Id: Ied053d19760e656012e2577776f75a1cc0a14ac3
Diffstat (limited to 'runtime/native/dalvik_system_VMDebug.cc')
-rw-r--r--runtime/native/dalvik_system_VMDebug.cc48
1 files changed, 48 insertions, 0 deletions
diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc
index 2663bea344..88a78ab4be 100644
--- a/runtime/native/dalvik_system_VMDebug.cc
+++ b/runtime/native/dalvik_system_VMDebug.cc
@@ -319,6 +319,53 @@ static jlongArray VMDebug_countInstancesOfClasses(JNIEnv* env,
return soa.AddLocalReference<jlongArray>(long_counts);
}
+static jobjectArray VMDebug_getInstancesOfClasses(JNIEnv* env,
+ jclass,
+ jobjectArray javaClasses,
+ jboolean includeAssignable) {
+ ScopedObjectAccess soa(env);
+ StackHandleScope<2> hs(soa.Self());
+ Handle<mirror::ObjectArray<mirror::Class>> classes = hs.NewHandle(
+ soa.Decode<mirror::ObjectArray<mirror::Class>>(javaClasses));
+ if (classes == nullptr) {
+ return nullptr;
+ }
+
+ jclass object_array_class = env->FindClass("[Ljava/lang/Object;");
+ if (env->ExceptionCheck() == JNI_TRUE) {
+ return nullptr;
+ }
+ CHECK(object_array_class != nullptr);
+
+ size_t num_classes = classes->GetLength();
+ jobjectArray result = env->NewObjectArray(num_classes, object_array_class, nullptr);
+ if (env->ExceptionCheck() == JNI_TRUE) {
+ return nullptr;
+ }
+
+ gc::Heap* const heap = Runtime::Current()->GetHeap();
+ MutableHandle<mirror::Class> h_class(hs.NewHandle<mirror::Class>(nullptr));
+ for (size_t i = 0; i < num_classes; ++i) {
+ h_class.Assign(classes->Get(i));
+
+ VariableSizedHandleScope hs2(soa.Self());
+ std::vector<Handle<mirror::Object>> raw_instances;
+ heap->GetInstances(hs2, h_class, includeAssignable, /* max_count */ 0, raw_instances);
+ jobjectArray array = env->NewObjectArray(raw_instances.size(),
+ WellKnownClasses::java_lang_Object,
+ nullptr);
+ if (env->ExceptionCheck() == JNI_TRUE) {
+ return nullptr;
+ }
+
+ for (size_t j = 0; j < raw_instances.size(); ++j) {
+ env->SetObjectArrayElement(array, j, raw_instances[j].ToJObject());
+ }
+ env->SetObjectArrayElement(result, i, array);
+ }
+ return result;
+}
+
// We export the VM internal per-heap-space size/alloc/free metrics
// for the zygote space, alloc space (application heap), and the large
// object space for dumpsys meminfo. The other memory region data such
@@ -534,6 +581,7 @@ static JNINativeMethod gMethods[] = {
NATIVE_METHOD(VMDebug, dumpReferenceTables, "()V"),
NATIVE_METHOD(VMDebug, getAllocCount, "(I)I"),
NATIVE_METHOD(VMDebug, getHeapSpaceStats, "([J)V"),
+ NATIVE_METHOD(VMDebug, getInstancesOfClasses, "([Ljava/lang/Class;Z)[[Ljava/lang/Object;"),
NATIVE_METHOD(VMDebug, getInstructionCount, "([I)V"),
FAST_NATIVE_METHOD(VMDebug, getLoadedClassCount, "()I"),
NATIVE_METHOD(VMDebug, getVmFeatureList, "()[Ljava/lang/String;"),