| OLD | NEW | 
|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "platform/heap/BlinkGCMemoryDumpProvider.h" | 5 #include "platform/heap/BlinkGCMemoryDumpProvider.h" | 
| 6 | 6 | 
| 7 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 7 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 
| 8 #include "base/trace_event/heap_profiler_allocation_register.h" | 8 #include "base/trace_event/heap_profiler_allocation_register.h" | 
|  | 9 #include "base/trace_event/memory_allocator_dump.h" | 
|  | 10 #include "base/trace_event/process_memory_dump.h" | 
| 9 #include "base/trace_event/trace_event_memory_overhead.h" | 11 #include "base/trace_event/trace_event_memory_overhead.h" | 
| 10 #include "platform/heap/Handle.h" | 12 #include "platform/heap/Handle.h" | 
| 11 #include "platform/web_process_memory_dump_impl.h" | 13 #include "platform/web_process_memory_dump_impl.h" | 
| 12 #include "public/platform/Platform.h" | 14 #include "public/platform/Platform.h" | 
| 13 #include "public/platform/WebMemoryAllocatorDump.h" | 15 #include "public/platform/WebMemoryAllocatorDump.h" | 
| 14 #include "wtf/StdLibExtras.h" | 16 #include "wtf/StdLibExtras.h" | 
| 15 #include "wtf/Threading.h" | 17 #include "wtf/Threading.h" | 
| 16 | 18 | 
| 17 namespace blink { | 19 namespace blink { | 
| 18 namespace { | 20 namespace { | 
| 19 | 21 | 
| 20 void dumpMemoryTotals(blink::WebProcessMemoryDump* memoryDump) | 22 void dumpMemoryTotals(base::trace_event::ProcessMemoryDump* memoryDump) | 
| 21 { | 23 { | 
| 22     String dumpName = String::format("blink_gc"); | 24     base::trace_event::MemoryAllocatorDump* allocatorDump = memoryDump->CreateAl
     locatorDump("blink_gc"); | 
| 23     WebMemoryAllocatorDump* allocatorDump = memoryDump->createMemoryAllocatorDum
     p(dumpName); | 25     allocatorDump->AddScalar("size", "bytes", ProcessHeap::totalAllocatedSpace()
     ); | 
| 24     allocatorDump->addScalar("size", "bytes", ProcessHeap::totalAllocatedSpace()
     ); |  | 
| 25 | 26 | 
| 26     dumpName.append("/allocated_objects"); | 27     base::trace_event::MemoryAllocatorDump* objectsDump = memoryDump->CreateAllo
     catorDump("blink_gc/allocated_objects"); | 
| 27     WebMemoryAllocatorDump* objectsDump = memoryDump->createMemoryAllocatorDump(
     dumpName); |  | 
| 28 | 28 | 
| 29     // ThreadHeap::markedObjectSize() can be underestimated if we're still in th
     e | 29     // ThreadHeap::markedObjectSize() can be underestimated if we're still in th
     e | 
| 30     // process of lazy sweeping. | 30     // process of lazy sweeping. | 
| 31     objectsDump->addScalar("size", "bytes", ProcessHeap::totalAllocatedObjectSiz
     e() + ProcessHeap::totalMarkedObjectSize()); | 31     objectsDump->AddScalar("size", "bytes", ProcessHeap::totalAllocatedObjectSiz
     e() + ProcessHeap::totalMarkedObjectSize()); | 
| 32 } | 32 } | 
| 33 | 33 | 
| 34 void reportAllocation(Address address, size_t size, const char* typeName) | 34 void reportAllocation(Address address, size_t size, const char* typeName) | 
| 35 { | 35 { | 
| 36     BlinkGCMemoryDumpProvider::instance()->insert(address, size, typeName); | 36     BlinkGCMemoryDumpProvider::instance()->insert(address, size, typeName); | 
| 37 } | 37 } | 
| 38 | 38 | 
| 39 void reportFree(Address address) | 39 void reportFree(Address address) | 
| 40 { | 40 { | 
| 41     BlinkGCMemoryDumpProvider::instance()->remove(address); | 41     BlinkGCMemoryDumpProvider::instance()->remove(address); | 
| 42 } | 42 } | 
| 43 | 43 | 
| 44 } // namespace | 44 } // namespace | 
| 45 | 45 | 
| 46 BlinkGCMemoryDumpProvider* BlinkGCMemoryDumpProvider::instance() | 46 BlinkGCMemoryDumpProvider* BlinkGCMemoryDumpProvider::instance() | 
| 47 { | 47 { | 
| 48     DEFINE_STATIC_LOCAL(BlinkGCMemoryDumpProvider, instance, ()); | 48     DEFINE_STATIC_LOCAL(BlinkGCMemoryDumpProvider, instance, ()); | 
| 49     return &instance; | 49     return &instance; | 
| 50 } | 50 } | 
| 51 | 51 | 
| 52 BlinkGCMemoryDumpProvider::~BlinkGCMemoryDumpProvider() | 52 BlinkGCMemoryDumpProvider::~BlinkGCMemoryDumpProvider() | 
| 53 { | 53 { | 
| 54 } | 54 } | 
| 55 | 55 | 
| 56 bool BlinkGCMemoryDumpProvider::onMemoryDump(WebMemoryDumpLevelOfDetail levelOfD
     etail, blink::WebProcessMemoryDump* memoryDump) | 56 bool BlinkGCMemoryDumpProvider::OnMemoryDump(const base::trace_event::MemoryDump
     Args& args, base::trace_event::ProcessMemoryDump* memoryDump) | 
| 57 { | 57 { | 
|  | 58     using base::trace_event::MemoryDumpLevelOfDetail; | 
|  | 59     MemoryDumpLevelOfDetail levelOfDetail = args.level_of_detail; | 
| 58     // In the case of a detailed dump perform a mark-only GC pass to collect | 60     // In the case of a detailed dump perform a mark-only GC pass to collect | 
| 59     // more detailed stats. | 61     // more detailed stats. | 
| 60     if (levelOfDetail == WebMemoryDumpLevelOfDetail::Detailed) | 62     if (levelOfDetail == MemoryDumpLevelOfDetail::DETAILED) | 
| 61         ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::Take
     Snapshot, BlinkGC::ForcedGC); | 63         ThreadHeap::collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::Take
     Snapshot, BlinkGC::ForcedGC); | 
| 62     dumpMemoryTotals(memoryDump); | 64     dumpMemoryTotals(memoryDump); | 
| 63 | 65 | 
| 64     if (m_isHeapProfilingEnabled) { | 66     if (m_isHeapProfilingEnabled) { | 
| 65         // Overhead should always be reported, regardless of light vs. heavy. | 67         // Overhead should always be reported, regardless of light vs. heavy. | 
| 66         base::trace_event::TraceEventMemoryOverhead overhead; | 68         base::trace_event::TraceEventMemoryOverhead overhead; | 
| 67         base::hash_map<base::trace_event::AllocationContext, base::trace_event::
     AllocationMetrics> metricsByContext; | 69         base::hash_map<base::trace_event::AllocationContext, base::trace_event::
     AllocationMetrics> metricsByContext; | 
| 68         { | 70         { | 
| 69             MutexLocker locker(m_allocationRegisterMutex); | 71             MutexLocker locker(m_allocationRegisterMutex); | 
| 70             if (levelOfDetail == WebMemoryDumpLevelOfDetail::Detailed) { | 72             if (levelOfDetail == MemoryDumpLevelOfDetail::DETAILED) { | 
| 71                 for (const auto& allocSize : *m_allocationRegister) { | 73                 for (const auto& allocSize : *m_allocationRegister) { | 
| 72                     base::trace_event::AllocationMetrics& metrics = metricsByCon
     text[allocSize.context]; | 74                     base::trace_event::AllocationMetrics& metrics = metricsByCon
     text[allocSize.context]; | 
| 73                     metrics.size += allocSize.size; | 75                     metrics.size += allocSize.size; | 
| 74                     metrics.count++; | 76                     metrics.count++; | 
| 75                 } | 77                 } | 
| 76             } | 78             } | 
| 77             m_allocationRegister->EstimateTraceMemoryOverhead(&overhead); | 79             m_allocationRegister->EstimateTraceMemoryOverhead(&overhead); | 
| 78         } | 80         } | 
| 79         memoryDump->dumpHeapUsage(metricsByContext, overhead, "blink_gc"); | 81         memoryDump->DumpHeapUsage(metricsByContext, overhead, "blink_gc"); | 
| 80     } | 82     } | 
| 81 | 83 | 
| 82     // Merge all dumps collected by ThreadHeap::collectGarbage. | 84     // Merge all dumps collected by ThreadHeap::collectGarbage. | 
| 83     if (levelOfDetail == WebMemoryDumpLevelOfDetail::Detailed) | 85     if (levelOfDetail == MemoryDumpLevelOfDetail::DETAILED) | 
| 84         memoryDump->takeAllDumpsFrom(m_currentProcessMemoryDump.get()); | 86         memoryDump->TakeAllDumpsFrom(m_currentProcessMemoryDump.get()); | 
| 85     return true; | 87     return true; | 
| 86 } | 88 } | 
| 87 | 89 | 
| 88 void BlinkGCMemoryDumpProvider::onHeapProfilingEnabled(bool enabled) | 90 void BlinkGCMemoryDumpProvider::OnHeapProfilingEnabled(bool enabled) | 
| 89 { | 91 { | 
| 90     if (enabled) { | 92     if (enabled) { | 
| 91         { | 93         { | 
| 92             MutexLocker locker(m_allocationRegisterMutex); | 94             MutexLocker locker(m_allocationRegisterMutex); | 
| 93             if (!m_allocationRegister) | 95             if (!m_allocationRegister) | 
| 94                 m_allocationRegister = adoptPtr(new base::trace_event::Allocatio
     nRegister()); | 96                 m_allocationRegister.reset(new base::trace_event::AllocationRegi
     ster()); | 
| 95         } | 97         } | 
| 96         HeapAllocHooks::setAllocationHook(reportAllocation); | 98         HeapAllocHooks::setAllocationHook(reportAllocation); | 
| 97         HeapAllocHooks::setFreeHook(reportFree); | 99         HeapAllocHooks::setFreeHook(reportFree); | 
| 98     } else { | 100     } else { | 
| 99         HeapAllocHooks::setAllocationHook(nullptr); | 101         HeapAllocHooks::setAllocationHook(nullptr); | 
| 100         HeapAllocHooks::setFreeHook(nullptr); | 102         HeapAllocHooks::setFreeHook(nullptr); | 
| 101     } | 103     } | 
| 102     m_isHeapProfilingEnabled = enabled; | 104     m_isHeapProfilingEnabled = enabled; | 
| 103 } | 105 } | 
| 104 | 106 | 
| 105 WebMemoryAllocatorDump* BlinkGCMemoryDumpProvider::createMemoryAllocatorDumpForC
     urrentGC(const String& absoluteName) | 107 base::trace_event::MemoryAllocatorDump* BlinkGCMemoryDumpProvider::createMemoryA
     llocatorDumpForCurrentGC(const String& absoluteName) | 
| 106 { | 108 { | 
| 107     return m_currentProcessMemoryDump->createMemoryAllocatorDump(absoluteName); | 109     // TODO(bashi): Change type name of |absoluteName|. | 
|  | 110     return m_currentProcessMemoryDump->CreateAllocatorDump(absoluteName.utf8().d
     ata()); | 
| 108 } | 111 } | 
| 109 | 112 | 
| 110 void BlinkGCMemoryDumpProvider::clearProcessDumpForCurrentGC() | 113 void BlinkGCMemoryDumpProvider::clearProcessDumpForCurrentGC() | 
| 111 { | 114 { | 
| 112     m_currentProcessMemoryDump->clear(); | 115     m_currentProcessMemoryDump->Clear(); | 
| 113 } | 116 } | 
| 114 | 117 | 
| 115 BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider() | 118 BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider() | 
| 116     : m_currentProcessMemoryDump(adoptPtr(new WebProcessMemoryDumpImpl())) | 119     : m_currentProcessMemoryDump(new base::trace_event::ProcessMemoryDump(nullpt
     r)) | 
| 117     , m_isHeapProfilingEnabled(false) | 120     , m_isHeapProfilingEnabled(false) | 
| 118 { | 121 { | 
| 119 } | 122 } | 
| 120 | 123 | 
| 121 void BlinkGCMemoryDumpProvider::insert(Address address, size_t size, const char*
      typeName) | 124 void BlinkGCMemoryDumpProvider::insert(Address address, size_t size, const char*
      typeName) | 
| 122 { | 125 { | 
| 123     base::trace_event::AllocationContext context = base::trace_event::Allocation
     ContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot(); | 126     base::trace_event::AllocationContext context = base::trace_event::Allocation
     ContextTracker::GetInstanceForCurrentThread()->GetContextSnapshot(); | 
| 124     context.type_name = typeName; | 127     context.type_name = typeName; | 
| 125     MutexLocker locker(m_allocationRegisterMutex); | 128     MutexLocker locker(m_allocationRegisterMutex); | 
| 126     if (m_allocationRegister) | 129     if (m_allocationRegister) | 
| 127         m_allocationRegister->Insert(address, size, context); | 130         m_allocationRegister->Insert(address, size, context); | 
| 128 } | 131 } | 
| 129 | 132 | 
| 130 void BlinkGCMemoryDumpProvider::remove(Address address) | 133 void BlinkGCMemoryDumpProvider::remove(Address address) | 
| 131 { | 134 { | 
| 132     MutexLocker locker(m_allocationRegisterMutex); | 135     MutexLocker locker(m_allocationRegisterMutex); | 
| 133     if (m_allocationRegister) | 136     if (m_allocationRegister) | 
| 134         m_allocationRegister->Remove(address); | 137         m_allocationRegister->Remove(address); | 
| 135 } | 138 } | 
| 136 | 139 | 
| 137 } // namespace blink | 140 } // namespace blink | 
| OLD | NEW | 
|---|