| 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 <unordered_map> |    7 #include <unordered_map> | 
|    8  |    8  | 
|    9 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |    9 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 
|   10 #include "base/trace_event/heap_profiler_allocation_register.h" |  | 
|   11 #include "base/trace_event/memory_allocator_dump.h" |   10 #include "base/trace_event/memory_allocator_dump.h" | 
|   12 #include "base/trace_event/process_memory_dump.h" |   11 #include "base/trace_event/process_memory_dump.h" | 
|   13 #include "base/trace_event/trace_event_memory_overhead.h" |   12 #include "base/trace_event/trace_event_memory_overhead.h" | 
|   14 #include "platform/heap/Handle.h" |   13 #include "platform/heap/Handle.h" | 
|   15 #include "platform/instrumentation/tracing/web_memory_allocator_dump.h" |   14 #include "platform/instrumentation/tracing/web_memory_allocator_dump.h" | 
|   16 #include "platform/wtf/StdLibExtras.h" |   15 #include "platform/wtf/StdLibExtras.h" | 
|   17 #include "platform/wtf/Threading.h" |   16 #include "platform/wtf/Threading.h" | 
|   18 #include "public/platform/Platform.h" |   17 #include "public/platform/Platform.h" | 
|   19  |   18  | 
|   20 namespace blink { |   19 namespace blink { | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   59   using base::trace_event::MemoryDumpLevelOfDetail; |   58   using base::trace_event::MemoryDumpLevelOfDetail; | 
|   60   MemoryDumpLevelOfDetail level_of_detail = args.level_of_detail; |   59   MemoryDumpLevelOfDetail level_of_detail = args.level_of_detail; | 
|   61   // 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 | 
|   62   // more detailed stats. |   61   // more detailed stats. | 
|   63   if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) |   62   if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) | 
|   64     ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack, |   63     ThreadState::Current()->CollectGarbage(BlinkGC::kNoHeapPointersOnStack, | 
|   65                                            BlinkGC::kTakeSnapshot, |   64                                            BlinkGC::kTakeSnapshot, | 
|   66                                            BlinkGC::kForcedGC); |   65                                            BlinkGC::kForcedGC); | 
|   67   DumpMemoryTotals(memory_dump); |   66   DumpMemoryTotals(memory_dump); | 
|   68  |   67  | 
|   69   if (is_heap_profiling_enabled_) { |   68   if (allocation_register_.is_enabled()) { | 
|   70     // Overhead should always be reported, regardless of light vs. heavy. |   69     // Overhead should always be reported, regardless of light vs. heavy. | 
|   71     base::trace_event::TraceEventMemoryOverhead overhead; |   70     base::trace_event::TraceEventMemoryOverhead overhead; | 
|   72     std::unordered_map<base::trace_event::AllocationContext, |   71     std::unordered_map<base::trace_event::AllocationContext, | 
|   73                        base::trace_event::AllocationMetrics> |   72                        base::trace_event::AllocationMetrics> | 
|   74         metrics_by_context; |   73         metrics_by_context; | 
|   75     { |   74     if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { | 
|   76       MutexLocker locker(allocation_register_mutex_); |   75       allocation_register_.UpdateAndReturnsMetrics(metrics_by_context); | 
|   77       if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { |  | 
|   78         for (const auto& alloc_size : *allocation_register_) { |  | 
|   79           base::trace_event::AllocationMetrics& metrics = |  | 
|   80               metrics_by_context[alloc_size.context]; |  | 
|   81           metrics.size += alloc_size.size; |  | 
|   82           metrics.count++; |  | 
|   83         } |  | 
|   84       } |  | 
|   85       allocation_register_->EstimateTraceMemoryOverhead(&overhead); |  | 
|   86     } |   76     } | 
 |   77     allocation_register_.EstimateTraceMemoryOverhead(&overhead); | 
|   87     memory_dump->DumpHeapUsage(metrics_by_context, overhead, "blink_gc"); |   78     memory_dump->DumpHeapUsage(metrics_by_context, overhead, "blink_gc"); | 
|   88   } |   79   } | 
|   89  |   80  | 
|   90   // Merge all dumps collected by ThreadHeap::collectGarbage. |   81   // Merge all dumps collected by ThreadHeap::collectGarbage. | 
|   91   if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) |   82   if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) | 
|   92     memory_dump->TakeAllDumpsFrom(current_process_memory_dump_.get()); |   83     memory_dump->TakeAllDumpsFrom(current_process_memory_dump_.get()); | 
|   93   return true; |   84   return true; | 
|   94 } |   85 } | 
|   95  |   86  | 
|   96 void BlinkGCMemoryDumpProvider::OnHeapProfilingEnabled(bool enabled) { |   87 void BlinkGCMemoryDumpProvider::OnHeapProfilingEnabled(bool enabled) { | 
|   97   if (enabled) { |   88   if (enabled) { | 
|   98     { |   89     allocation_register_.SetEnabled(); | 
|   99       MutexLocker locker(allocation_register_mutex_); |  | 
|  100       if (!allocation_register_) |  | 
|  101         allocation_register_.reset(new base::trace_event::AllocationRegister()); |  | 
|  102     } |  | 
|  103     HeapAllocHooks::SetAllocationHook(ReportAllocation); |   90     HeapAllocHooks::SetAllocationHook(ReportAllocation); | 
|  104     HeapAllocHooks::SetFreeHook(ReportFree); |   91     HeapAllocHooks::SetFreeHook(ReportFree); | 
|  105   } else { |   92   } else { | 
|  106     HeapAllocHooks::SetAllocationHook(nullptr); |   93     HeapAllocHooks::SetAllocationHook(nullptr); | 
|  107     HeapAllocHooks::SetFreeHook(nullptr); |   94     HeapAllocHooks::SetFreeHook(nullptr); | 
 |   95     allocation_register_.SetDisabled(); | 
|  108   } |   96   } | 
|  109   is_heap_profiling_enabled_ = enabled; |  | 
|  110 } |   97 } | 
|  111  |   98  | 
|  112 base::trace_event::MemoryAllocatorDump* |   99 base::trace_event::MemoryAllocatorDump* | 
|  113 BlinkGCMemoryDumpProvider::CreateMemoryAllocatorDumpForCurrentGC( |  100 BlinkGCMemoryDumpProvider::CreateMemoryAllocatorDumpForCurrentGC( | 
|  114     const String& absolute_name) { |  101     const String& absolute_name) { | 
|  115   // TODO(bashi): Change type name of |absoluteName|. |  102   // TODO(bashi): Change type name of |absoluteName|. | 
|  116   return current_process_memory_dump_->CreateAllocatorDump( |  103   return current_process_memory_dump_->CreateAllocatorDump( | 
|  117       absolute_name.Utf8().data()); |  104       absolute_name.Utf8().data()); | 
|  118 } |  105 } | 
|  119  |  106  | 
|  120 void BlinkGCMemoryDumpProvider::ClearProcessDumpForCurrentGC() { |  107 void BlinkGCMemoryDumpProvider::ClearProcessDumpForCurrentGC() { | 
|  121   current_process_memory_dump_->Clear(); |  108   current_process_memory_dump_->Clear(); | 
|  122 } |  109 } | 
|  123  |  110  | 
|  124 BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider() |  111 BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider() | 
|  125     : current_process_memory_dump_(new base::trace_event::ProcessMemoryDump( |  112     : current_process_memory_dump_(new base::trace_event::ProcessMemoryDump( | 
|  126           nullptr, |  113           nullptr, | 
|  127           {base::trace_event::MemoryDumpLevelOfDetail::DETAILED})), |  114           {base::trace_event::MemoryDumpLevelOfDetail::DETAILED})) {} | 
|  128       is_heap_profiling_enabled_(false) {} |  | 
|  129  |  115  | 
|  130 void BlinkGCMemoryDumpProvider::insert(Address address, |  116 void BlinkGCMemoryDumpProvider::insert(Address address, | 
|  131                                        size_t size, |  117                                        size_t size, | 
|  132                                        const char* type_name) { |  118                                        const char* type_name) { | 
|  133   base::trace_event::AllocationContext context; |  119   base::trace_event::AllocationContext context; | 
|  134   if (!base::trace_event::AllocationContextTracker:: |  120   if (!base::trace_event::AllocationContextTracker:: | 
|  135            GetInstanceForCurrentThread() |  121            GetInstanceForCurrentThread() | 
|  136                ->GetContextSnapshot(&context)) |  122                ->GetContextSnapshot(&context)) | 
|  137     return; |  123     return; | 
|  138   context.type_name = type_name; |  124   context.type_name = type_name; | 
|  139   MutexLocker locker(allocation_register_mutex_); |  125   if (!allocation_register_.is_enabled()) | 
|  140   if (allocation_register_) |  126     return; | 
|  141     allocation_register_->Insert(address, size, context); |  127   allocation_register_.Insert(address, size, context); | 
|  142 } |  128 } | 
|  143  |  129  | 
|  144 void BlinkGCMemoryDumpProvider::Remove(Address address) { |  130 void BlinkGCMemoryDumpProvider::Remove(Address address) { | 
|  145   MutexLocker locker(allocation_register_mutex_); |  131   if (!allocation_register_.is_enabled()) | 
|  146   if (allocation_register_) |  132     return; | 
|  147     allocation_register_->Remove(address); |  133   allocation_register_.Remove(address); | 
|  148 } |  134 } | 
|  149  |  135  | 
|  150 }  // namespace blink |  136 }  // namespace blink | 
| OLD | NEW |