diff options
| -rw-r--r-- | runtime/openjdkjvmti/ti_heap.cc | 41 | ||||
| -rw-r--r-- | test/913-heaps/expected.txt | 13 | ||||
| -rw-r--r-- | test/913-heaps/src/Main.java | 4 |
3 files changed, 30 insertions, 28 deletions
diff --git a/runtime/openjdkjvmti/ti_heap.cc b/runtime/openjdkjvmti/ti_heap.cc index 5f18b7cbce..894cec252e 100644 --- a/runtime/openjdkjvmti/ti_heap.cc +++ b/runtime/openjdkjvmti/ti_heap.cc @@ -174,10 +174,11 @@ jvmtiError HeapUtil::IterateThroughHeap(jvmtiEnv* env ATTRIBUTE_UNUSED, class FollowReferencesHelper FINAL { public: FollowReferencesHelper(HeapUtil* h, - art::ObjPtr<art::mirror::Object> initial_object ATTRIBUTE_UNUSED, + art::ObjPtr<art::mirror::Object> initial_object, const jvmtiHeapCallbacks* callbacks, const void* user_data) : tag_table_(h->GetTags()), + initial_object_(initial_object), callbacks_(callbacks), user_data_(user_data), start_(0), @@ -187,13 +188,18 @@ class FollowReferencesHelper FINAL { void Init() REQUIRES_SHARED(art::Locks::mutator_lock_) REQUIRES(!*tag_table_->GetAllowDisallowLock()) { - CollectAndReportRootsVisitor carrv(this, tag_table_, &worklist_, &visited_); - art::Runtime::Current()->VisitRoots(&carrv); - art::Runtime::Current()->VisitImageRoots(&carrv); - stop_reports_ = carrv.IsStopReports(); + if (initial_object_.IsNull()) { + CollectAndReportRootsVisitor carrv(this, tag_table_, &worklist_, &visited_); + art::Runtime::Current()->VisitRoots(&carrv); + art::Runtime::Current()->VisitImageRoots(&carrv); + stop_reports_ = carrv.IsStopReports(); - if (stop_reports_) { - worklist_.clear(); + if (stop_reports_) { + worklist_.clear(); + } + } else { + visited_.insert(initial_object_.Ptr()); + worklist_.push_back(initial_object_.Ptr()); } } @@ -616,6 +622,7 @@ class FollowReferencesHelper FINAL { } ObjectTagTable* tag_table_; + art::ObjPtr<art::mirror::Object> initial_object_; const jvmtiHeapCallbacks* callbacks_; const void* user_data_; @@ -646,20 +653,28 @@ jvmtiError HeapUtil::FollowReferences(jvmtiEnv* env ATTRIBUTE_UNUSED, } art::Thread* self = art::Thread::Current(); - art::ScopedObjectAccess soa(self); // Now we know we have the shared lock. - art::Runtime::Current()->GetHeap()->IncrementDisableMovingGC(self); + art::gc::Heap* heap = art::Runtime::Current()->GetHeap(); + if (heap->IsGcConcurrentAndMoving()) { + // Need to take a heap dump while GC isn't running. See the + // comment in Heap::VisitObjects(). + heap->IncrementDisableMovingGC(self); + } { - art::ObjPtr<art::mirror::Object> o_initial = soa.Decode<art::mirror::Object>(initial_object); - + art::ScopedObjectAccess soa(self); // Now we know we have the shared lock. art::ScopedThreadSuspension sts(self, art::kWaitingForVisitObjects); art::ScopedSuspendAll ssa("FollowReferences"); - FollowReferencesHelper frh(this, o_initial, callbacks, user_data); + FollowReferencesHelper frh(this, + self->DecodeJObject(initial_object), + callbacks, + user_data); frh.Init(); frh.Work(); } - art::Runtime::Current()->GetHeap()->DecrementDisableMovingGC(self); + if (heap->IsGcConcurrentAndMoving()) { + heap->DecrementDisableMovingGC(self); + } return ERR(NONE); } diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt index 8002cfa8c5..aba2a9a718 100644 --- a/test/913-heaps/expected.txt +++ b/test/913-heaps/expected.txt @@ -21,12 +21,6 @@ root@root --(thread)--> 3000@0 [size=132, length=-1] 5@1002 --(field@28)--> 1@1000 [size=16, length=-1] 6@1000 --(class)--> 1000@0 [size=123, length=-1] --- -root@root --(stack-local)--> 1@1000 [size=16, length=-1] -root@root --(stack-local)--> 2@1000 [size=16, length=-1] -root@root --(stack-local)--> 3000@0 [size=132, length=-1] -root@root --(thread)--> 2@1000 [size=16, length=-1] -root@root --(thread)--> 3000@0 [size=132, length=-1] -0@0 --(array-element@0)--> 1@1000 [size=16, length=-1] 1001@0 --(superclass)--> 1000@0 [size=123, length=-1] 1002@0 --(interface)--> 2001@0 [size=132, length=-1] 1002@0 --(superclass)--> 1001@0 [size=123, length=-1] @@ -66,13 +60,6 @@ root@root --(thread)--> 3000@0 [size=132, length=-1] 5@1002 --(field@28)--> 1@1000 [size=16, length=-1] 6@1000 --(class)--> 1000@0 [size=123, 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)--> 1@1000 [size=16, length=-1] -root@root --(stack-local)--> 2@1000 [size=16, length=-1] -root@root --(thread)--> 1@1000 [size=16, length=-1] -root@root --(thread)--> 2@1000 [size=16, length=-1] -root@root --(thread)--> 3000@0 [size=132, length=-1] 1001@0 --(superclass)--> 1000@0 [size=123, length=-1] 1002@0 --(interface)--> 2001@0 [size=132, length=-1] 1002@0 --(superclass)--> 1001@0 [size=123, length=-1] diff --git a/test/913-heaps/src/Main.java b/test/913-heaps/src/Main.java index a6ace9aeba..564596e02b 100644 --- a/test/913-heaps/src/Main.java +++ b/test/913-heaps/src/Main.java @@ -85,7 +85,7 @@ public class Main { v.add("0@0", "1@1000"); // tmpStorage[0] --(array-element)--> a. doFollowReferencesTestImpl(null, Integer.MAX_VALUE, -1, null, v, null); - doFollowReferencesTestImpl(a.foo, Integer.MAX_VALUE, -1, null, v, "2@1000"); + doFollowReferencesTestImpl(a.foo2, Integer.MAX_VALUE, -1, null, v, "3@1001"); tmpStorage.clear(); } @@ -96,7 +96,7 @@ public class Main { A a = createTree(v); doFollowReferencesTestImpl(null, Integer.MAX_VALUE, -1, a, v, null); - doFollowReferencesTestImpl(a.foo, Integer.MAX_VALUE, -1, a, v, "2@1000"); + doFollowReferencesTestImpl(a.foo2, Integer.MAX_VALUE, -1, a, v, "3@1001"); } private static void doFollowReferencesTestImpl(A root, int stopAfter, int followSet, |