Correctly use handles for JVMTI heap iteration.
We were incorrectly using an ObjPtr to store the filter-class in
IterateThroughHeap and FollowReferences. This could cause issues if GC
was occurring during the early parts of the call. Fix this issues by
properly handlerizing the pointer.
Test: ./test.py --host
Bug: 161574896
Change-Id: I2ed8e3e4b7af8fded69e8d86adf2049e907289e8
diff --git a/openjdkjvmti/ti_heap.cc b/openjdkjvmti/ti_heap.cc
index 905ed95..f4e34dd 100644
--- a/openjdkjvmti/ti_heap.cc
+++ b/openjdkjvmti/ti_heap.cc
@@ -759,7 +759,8 @@
bool stop_reports = false;
const HeapFilter heap_filter(heap_filter_int);
- art::ObjPtr<art::mirror::Class> filter_klass = soa.Decode<art::mirror::Class>(klass);
+ art::StackHandleScope<1> hs(self);
+ art::Handle<art::mirror::Class> filter_klass(hs.NewHandle(soa.Decode<art::mirror::Class>(klass)));
auto visitor = [&](art::mirror::Object* obj) REQUIRES_SHARED(art::Locks::mutator_lock_) {
// Early return, as we can't really stop visiting.
if (stop_reports) {
@@ -781,7 +782,7 @@
}
if (filter_klass != nullptr) {
- if (filter_klass != klass) {
+ if (filter_klass.Get() != klass) {
return;
}
}
diff --git a/test/906-iterate-heap/src/art/Test906.java b/test/906-iterate-heap/src/art/Test906.java
index b782c9b..c65934d 100644
--- a/test/906-iterate-heap/src/art/Test906.java
+++ b/test/906-iterate-heap/src/art/Test906.java
@@ -29,9 +29,15 @@
// the middle of a GC we could incorrectly fail. This is expected to be incredibly rare so 10
// retries should be more than sufficient.
private static final int ITERATE_RETRIES = 10;
+ private static final class Foobar {}
+
private static void testHeapCount() throws Exception {
IllegalStateException lastThrow = new IllegalStateException(
"Failed to get consistent counts after " + ITERATE_RETRIES + " retries");
+ Foobar[] foobars = new Foobar[123];
+ for (int i = 0; i < foobars.length; i++) {
+ foobars[i] = new Foobar();
+ }
for (int i = 0; i < ITERATE_RETRIES; i++) {
try {
int all = iterateThroughHeapCount(0, null, Integer.MAX_VALUE);
@@ -41,6 +47,7 @@
Integer.MAX_VALUE);
int untaggedClass = iterateThroughHeapCount(HEAP_FILTER_OUT_CLASS_TAGGED, null,
Integer.MAX_VALUE);
+ int filteredClass = iterateThroughHeapCount(0, Foobar.class, Integer.MAX_VALUE);
if (all != tagged + untagged) {
throw new IllegalStateException("Instances: " + all + " != " + tagged + " + " + untagged);
@@ -49,6 +56,10 @@
throw new IllegalStateException("By class: " + all + " != " + taggedClass + " + " +
untaggedClass);
}
+ if (filteredClass != foobars.length) {
+ throw new IllegalStateException(
+ "Missed objects of foobar type. " + filteredClass + " != " + foobars.length);
+ }
if (tagged != 6) {
throw new IllegalStateException(tagged + " tagged objects");
}