Add VMDebug.countInstancesOfClasses
countInstancesOfClasses allows passing multiple classes unlike
countInstanceOfClass instead of needing to do one at a time.
This is going to be used to speed up string mode checking.
Also changed the logic to not do a GC, this was the old Dalvik
behavior. It is the job of the caller to do this.
Added test.
https://code.google.com/p/android/issues/detail?id=177552
Change-Id: Ia85684f40cf59a52aa71a8479c711a994651209b
diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc
index 1078492..8febb62 100644
--- a/runtime/native/dalvik_system_VMDebug.cc
+++ b/runtime/native/dalvik_system_VMDebug.cc
@@ -257,21 +257,45 @@
static jlong VMDebug_countInstancesOfClass(JNIEnv* env, jclass, jclass javaClass,
jboolean countAssignable) {
ScopedObjectAccess soa(env);
- gc::Heap* heap = Runtime::Current()->GetHeap();
- // We only want reachable instances, so do a GC. Heap::VisitObjects visits all of the heap
- // objects in the all spaces and the allocation stack.
- heap->CollectGarbage(false);
+ gc::Heap* const heap = Runtime::Current()->GetHeap();
+ // Caller's responsibility to do GC if desired.
mirror::Class* c = soa.Decode<mirror::Class*>(javaClass);
if (c == nullptr) {
return 0;
}
- std::vector<mirror::Class*> classes;
- classes.push_back(c);
+ std::vector<mirror::Class*> classes {c};
uint64_t count = 0;
heap->CountInstances(classes, countAssignable, &count);
return count;
}
+static jlongArray VMDebug_countInstancesOfClasses(JNIEnv* env, jclass, jobjectArray javaClasses,
+ jboolean countAssignable) {
+ ScopedObjectAccess soa(env);
+ gc::Heap* const heap = Runtime::Current()->GetHeap();
+ // Caller's responsibility to do GC if desired.
+ auto* decoded_classes = soa.Decode<mirror::ObjectArray<mirror::Class>*>(javaClasses);
+ if (decoded_classes == nullptr) {
+ return nullptr;
+ }
+ std::vector<mirror::Class*> classes;
+ for (size_t i = 0, count = decoded_classes->GetLength(); i < count; ++i) {
+ classes.push_back(decoded_classes->Get(i));
+ }
+ std::vector<uint64_t> counts(classes.size(), 0u);
+ // Heap::CountInstances can handle null and will put 0 for these classes.
+ heap->CountInstances(classes, countAssignable, &counts[0]);
+ auto* long_counts = mirror::LongArray::Alloc(soa.Self(), counts.size());
+ if (long_counts == nullptr) {
+ soa.Self()->AssertPendingOOMException();
+ return nullptr;
+ }
+ for (size_t i = 0; i < counts.size(); ++i) {
+ long_counts->Set(i, counts[i]);
+ }
+ return soa.AddLocalReference<jlongArray>(long_counts);
+}
+
// 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
@@ -452,6 +476,7 @@
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(VMDebug, countInstancesOfClass, "(Ljava/lang/Class;Z)J"),
+ NATIVE_METHOD(VMDebug, countInstancesOfClasses, "([Ljava/lang/Class;Z)[J"),
NATIVE_METHOD(VMDebug, crash, "()V"),
NATIVE_METHOD(VMDebug, dumpHprofData, "(Ljava/lang/String;Ljava/io/FileDescriptor;)V"),
NATIVE_METHOD(VMDebug, dumpHprofDataDdms, "()V"),