From: Richard Uhler Date: Tue, 26 Apr 2016 20:28:59 +0000 (-0700) Subject: Deduplicate simple roots in hprof. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=4b76755d37f29ddb1a752b70ef1e81550f639b6e;p=android-x86%2Fart.git Deduplicate simple roots in hprof. Bug: 28311991 (cherry picked from commit e792305f5238df71a1928faf142cd35713aa3e47) Change-Id: Icfb646ff62965daee51f65f46f4911cf0751bf8d --- diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc index 3885c605b..989539516 100644 --- a/runtime/hprof/hprof.cc +++ b/runtime/hprof/hprof.cc @@ -505,6 +505,7 @@ class Hprof : public SingleRootVisitor { // Walk the roots and the heap. output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); + simple_roots_.clear(); runtime->VisitRoots(this); runtime->VisitImageRoots(this); runtime->GetHeap()->VisitObjectsPaused(VisitObjectCallback, this); @@ -884,6 +885,14 @@ class Hprof : public SingleRootVisitor { gc::EqAllocRecordTypesPtr> frames_; std::unordered_map allocation_records_; + // Set used to keep track of what simple root records we have already + // emitted, to avoid emitting duplicate entries. The simple root records are + // those that contain no other information than the root type and the object + // id. A pair of root type and object id is packed into a uint64_t, with + // the root type in the upper 32 bits and the object id in the lower 32 + // bits. + std::unordered_set simple_roots_; + friend class GcRootVisitor; DISALLOW_COPY_AND_ASSIGN(Hprof); }; @@ -962,10 +971,14 @@ void Hprof::MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeap case HPROF_ROOT_MONITOR_USED: case HPROF_ROOT_INTERNED_STRING: case HPROF_ROOT_DEBUGGER: - case HPROF_ROOT_VM_INTERNAL: - __ AddU1(heap_tag); - __ AddObjectId(obj); + case HPROF_ROOT_VM_INTERNAL: { + uint64_t key = (static_cast(heap_tag) << 32) | PointerToLowMemUInt32(obj); + if (simple_roots_.insert(key).second) { + __ AddU1(heap_tag); + __ AddObjectId(obj); + } break; + } // ID: object ID // ID: JNI global ref ID