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 "skia_memory_dump_provider.h" | 5 #include "skia_memory_dump_provider.h" |
6 | 6 |
| 7 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" |
| 8 #include "base/trace_event/heap_profiler_heap_dump_writer.cc" |
7 #include "base/trace_event/memory_allocator_dump.h" | 9 #include "base/trace_event/memory_allocator_dump.h" |
8 #include "base/trace_event/memory_dump_manager.h" | 10 #include "base/trace_event/memory_dump_manager.h" |
9 #include "base/trace_event/process_memory_dump.h" | 11 #include "base/trace_event/process_memory_dump.h" |
10 #include "skia/ext/skia_trace_memory_dump_impl.h" | 12 #include "skia/ext/skia_trace_memory_dump_impl.h" |
11 #include "third_party/skia/include/core/SkGraphics.h" | 13 #include "third_party/skia/include/core/SkGraphics.h" |
12 | 14 |
13 namespace skia { | 15 namespace skia { |
14 | 16 |
| 17 namespace { |
| 18 |
| 19 void ReportAllocation(void* address, size_t size, const char* type_name) { |
| 20 SkiaMemoryDumpProvider::GetInstance()->Insert(address, size, type_name); |
| 21 } |
| 22 |
| 23 void ReportFree(void* address) { |
| 24 SkiaMemoryDumpProvider::GetInstance()->Remove(address); |
| 25 } |
| 26 |
| 27 } // namespace |
| 28 |
| 29 SkiaAllocHooks::AllocationHook* SkiaAllocHooks::allocation_hook_ = nullptr; |
| 30 SkiaAllocHooks::FreeHook* SkiaAllocHooks::free_hook_ = nullptr; |
| 31 |
15 // static | 32 // static |
16 SkiaMemoryDumpProvider* SkiaMemoryDumpProvider::GetInstance() { | 33 SkiaMemoryDumpProvider* SkiaMemoryDumpProvider::GetInstance() { |
17 return base::Singleton< | 34 return base::Singleton< |
18 SkiaMemoryDumpProvider, | 35 SkiaMemoryDumpProvider, |
19 base::LeakySingletonTraits<SkiaMemoryDumpProvider>>::get(); | 36 base::LeakySingletonTraits<SkiaMemoryDumpProvider>>::get(); |
20 } | 37 } |
21 | 38 |
22 SkiaMemoryDumpProvider::SkiaMemoryDumpProvider() {} | 39 SkiaMemoryDumpProvider::SkiaMemoryDumpProvider() |
| 40 : is_heap_profiling_enabled_(false) { |
| 41 } |
23 | 42 |
24 SkiaMemoryDumpProvider::~SkiaMemoryDumpProvider() {} | 43 SkiaMemoryDumpProvider::~SkiaMemoryDumpProvider() {} |
25 | 44 |
26 bool SkiaMemoryDumpProvider::OnMemoryDump( | 45 bool SkiaMemoryDumpProvider::OnMemoryDump( |
27 const base::trace_event::MemoryDumpArgs& args, | 46 const base::trace_event::MemoryDumpArgs& args, |
28 base::trace_event::ProcessMemoryDump* process_memory_dump) { | 47 base::trace_event::ProcessMemoryDump* process_memory_dump) { |
29 SkiaTraceMemoryDumpImpl skia_dumper(args.level_of_detail, | 48 SkiaTraceMemoryDumpImpl skia_dumper(args.level_of_detail, |
30 process_memory_dump); | 49 process_memory_dump); |
31 SkGraphics::DumpMemoryStatistics(&skia_dumper); | 50 SkGraphics::DumpMemoryStatistics(&skia_dumper); |
32 | 51 |
| 52 if (is_heap_profiling_enabled_) { |
| 53 int total_size = 0; |
| 54 /*if (args.level_of_detail == |
| 55 base::trace_event::MemoryDumpLevelOfDetail::DETAILED) {*/ |
| 56 if (true) { |
| 57 base::trace_event::TraceEventMemoryOverhead overhead; |
| 58 base::hash_map<base::trace_event::AllocationContext, size_t> |
| 59 bytes_by_context; |
| 60 { |
| 61 base::AutoLock scoped_lock(lock_); |
| 62 for (const auto& alloc_size : *allocation_register_) { |
| 63 bytes_by_context[alloc_size.context] += alloc_size.size; |
| 64 total_size += alloc_size.size; |
| 65 } |
| 66 allocation_register_->EstimateTraceMemoryOverhead(&overhead); |
| 67 } |
| 68 |
| 69 // Copied from WebProcessMemoryDumpImpl::dumpHeapUsage |
| 70 const char* allocator_name = "skia"; |
| 71 if (!bytes_by_context.empty()) { |
| 72 scoped_refptr<base::trace_event::MemoryDumpSessionState> session_state = |
| 73 process_memory_dump->session_state(); |
| 74 scoped_ptr<base::trace_event::TracedValue> heap_dump = |
| 75 ExportHeapDump(bytes_by_context, |
| 76 session_state->stack_frame_deduplicator(), |
| 77 session_state->type_name_deduplicator()); |
| 78 process_memory_dump->AddHeapDump(allocator_name, std::move(heap_dump)); |
| 79 } |
| 80 std::string base_name = |
| 81 base::StringPrintf("tracing/heap_profiler_%s", allocator_name); |
| 82 overhead.DumpInto(base_name.c_str(), process_memory_dump); |
| 83 } else { |
| 84 int total_size = 0; |
| 85 { |
| 86 base::AutoLock scoped_lock(lock_); |
| 87 for (const auto& alloc_size : *allocation_register_) { |
| 88 total_size += alloc_size.size; |
| 89 } |
| 90 } |
| 91 } |
| 92 |
| 93 const char* dump_name = "skia/sk_malloc"; |
| 94 skia_dumper.dumpNumericValue(dump_name, "size", "bytes", total_size); |
| 95 skia_dumper.setMemoryBacking(dump_name, "malloc", nullptr); |
| 96 } |
| 97 |
33 return true; | 98 return true; |
34 } | 99 } |
35 | 100 |
| 101 void SkiaMemoryDumpProvider::OnHeapProfilingEnabled(bool enabled) { |
| 102 if (enabled) { |
| 103 { |
| 104 base::AutoLock scoped_lock(lock_); |
| 105 if (!allocation_register_) { |
| 106 allocation_register_ = make_scoped_ptr( |
| 107 new base::trace_event::AllocationRegister()); |
| 108 } |
| 109 } |
| 110 SkiaAllocHooks::SetAllocationHook(ReportAllocation); |
| 111 SkiaAllocHooks::SetFreeHook(ReportFree); |
| 112 } else { |
| 113 SkiaAllocHooks::SetAllocationHook(nullptr); |
| 114 SkiaAllocHooks::SetFreeHook(nullptr); |
| 115 } |
| 116 is_heap_profiling_enabled_ = enabled; |
| 117 } |
| 118 |
| 119 void SkiaMemoryDumpProvider::Insert(void* address, size_t size, |
| 120 const char* type_name) { |
| 121 base::trace_event::AllocationContext context = |
| 122 base::trace_event::AllocationContextTracker::GetInstanceForCurrentThread()->
GetContextSnapshot(); |
| 123 context.type_name = type_name; |
| 124 base::AutoLock scoped_lock(lock_); |
| 125 if (allocation_register_) { |
| 126 allocation_register_->Insert(address, size, context); |
| 127 } |
| 128 } |
| 129 |
| 130 void SkiaMemoryDumpProvider::Remove(void* address) { |
| 131 base::AutoLock scoped_lock(lock_); |
| 132 if (allocation_register_) { |
| 133 allocation_register_->Remove(address); |
| 134 } |
| 135 } |
| 136 |
36 } // namespace skia | 137 } // namespace skia |
OLD | NEW |