ART: Add klass filter support
Add support for klass filter to FollowReferences. Update test.
Bug: 31385354
Test: m test-art-host-run-test-913-heaps
Change-Id: If8f0fb67a931fb358d99b49e774a197388796b6e
diff --git a/runtime/openjdkjvmti/ti_heap.cc b/runtime/openjdkjvmti/ti_heap.cc
index 2fbc12b..eb2cbbd 100644
--- a/runtime/openjdkjvmti/ti_heap.cc
+++ b/runtime/openjdkjvmti/ti_heap.cc
@@ -314,11 +314,13 @@
jvmtiEnv* jvmti_env,
art::ObjPtr<art::mirror::Object> initial_object,
const jvmtiHeapCallbacks* callbacks,
+ art::ObjPtr<art::mirror::Class> class_filter,
const void* user_data)
: env(jvmti_env),
tag_table_(h->GetTags()),
initial_object_(initial_object),
callbacks_(callbacks),
+ class_filter_(class_filter),
user_data_(user_data),
start_(0),
stop_reports_(false) {
@@ -760,6 +762,10 @@
return 0;
}
+ if (UNLIKELY(class_filter_ != nullptr) && class_filter_ != referree->GetClass()) {
+ return JVMTI_VISIT_OBJECTS;
+ }
+
const jlong class_tag = tag_table_->GetTagOrZero(referree->GetClass());
const jlong referrer_class_tag =
referrer == nullptr ? 0 : tag_table_->GetTagOrZero(referrer->GetClass());
@@ -779,6 +785,7 @@
referrer_tag_ptr = &referrer_tag;
}
}
+
jint length = -1;
if (referree->IsArrayInstance()) {
length = referree->AsArray()->GetLength();
@@ -808,6 +815,7 @@
ObjectTagTable* tag_table_;
art::ObjPtr<art::mirror::Object> initial_object_;
const jvmtiHeapCallbacks* callbacks_;
+ art::ObjPtr<art::mirror::Class> class_filter_;
const void* user_data_;
std::vector<art::mirror::Object*> worklist_;
@@ -823,7 +831,7 @@
jvmtiError HeapUtil::FollowReferences(jvmtiEnv* env,
jint heap_filter ATTRIBUTE_UNUSED,
- jclass klass ATTRIBUTE_UNUSED,
+ jclass klass,
jobject initial_object,
const jvmtiHeapCallbacks* callbacks,
const void* user_data) {
@@ -844,10 +852,14 @@
art::ScopedThreadSuspension sts(self, art::kWaitingForVisitObjects);
art::ScopedSuspendAll ssa("FollowReferences");
+ art::ObjPtr<art::mirror::Class> class_filter = klass == nullptr
+ ? nullptr
+ : art::ObjPtr<art::mirror::Class>::DownCast(self->DecodeJObject(klass));
FollowReferencesHelper frh(this,
env,
self->DecodeJObject(initial_object),
callbacks,
+ class_filter,
user_data);
frh.Init();
frh.Work();
diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt
index 6432172..ff668df 100644
--- a/test/913-heaps/expected.txt
+++ b/test/913-heaps/expected.txt
@@ -90,3 +90,32 @@
4@0 (18, 3xS '010002000300')
1@0 (14, 2xZ '0001')
23456789
+--- klass ---
+root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
+0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
+1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
+3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
+5@1002 --(field@24)--> 6@1000 [size=16, length=-1]
+5@1002 --(field@28)--> 1@1000 [size=16, length=-1]
+---
+1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
+3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
+5@1002 --(field@24)--> 6@1000 [size=16, length=-1]
+5@1002 --(field@28)--> 1@1000 [size=16, length=-1]
+---
+root@root --(jni-global)--> 1@1000 [size=16, length=-1]
+root@root --(jni-local[id=1,tag=3000,depth=0,method=followReferences])--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=13,location= 10])--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=5,location= 10])--> 1@1000 [size=16, length=-1]
+root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot,vreg=4,location= 19])--> 1@1000 [size=16, length=-1]
+root@root --(thread)--> 1@1000 [size=16, length=-1]
+1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
+3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
+5@1002 --(field@24)--> 6@1000 [size=16, length=-1]
+5@1002 --(field@28)--> 1@1000 [size=16, length=-1]
+---
+1@1000 --(field@8)--> 2@1000 [size=16, length=-1]
+3@1001 --(field@16)--> 4@1000 [size=16, length=-1]
+5@1002 --(field@24)--> 6@1000 [size=16, length=-1]
+5@1002 --(field@28)--> 1@1000 [size=16, length=-1]
+---
diff --git a/test/913-heaps/src/Main.java b/test/913-heaps/src/Main.java
index 9a16196..7a91d1f 100644
--- a/test/913-heaps/src/Main.java
+++ b/test/913-heaps/src/Main.java
@@ -27,6 +27,10 @@
doStringTest();
doPrimitiveArrayTest();
+
+ // Test klass filter.
+ System.out.println("--- klass ---");
+ new TestConfig(A.class, 0).doFollowReferencesTest();
}
public static void doTest() throws Exception {