| 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 "gin/v8_isolate_memory_dump_provider.h" | 5 #include "gin/v8_isolate_memory_dump_provider.h" |
| 6 | 6 |
| 7 #include <inttypes.h> | 7 #include <inttypes.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 const size_t space_size = space_statistics.space_size(); | 105 const size_t space_size = space_statistics.space_size(); |
| 106 const size_t space_used_size = space_statistics.space_used_size(); | 106 const size_t space_used_size = space_statistics.space_used_size(); |
| 107 const size_t space_physical_size = space_statistics.physical_space_size(); | 107 const size_t space_physical_size = space_statistics.physical_space_size(); |
| 108 | 108 |
| 109 known_spaces_size += space_size; | 109 known_spaces_size += space_size; |
| 110 known_spaces_used_size += space_used_size; | 110 known_spaces_used_size += space_used_size; |
| 111 known_spaces_physical_size += space_physical_size; | 111 known_spaces_physical_size += space_physical_size; |
| 112 | 112 |
| 113 std::string space_dump_name = | 113 std::string space_dump_name = |
| 114 space_name_prefix + "/" + space_statistics.space_name(); | 114 space_name_prefix + "/" + space_statistics.space_name(); |
| 115 auto space_dump = process_memory_dump->CreateAllocatorDump(space_dump_name); | 115 auto* space_dump = |
| 116 process_memory_dump->CreateAllocatorDump(space_dump_name); |
| 116 space_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, | 117 space_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, |
| 117 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 118 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 118 space_physical_size); | 119 space_physical_size); |
| 119 | 120 |
| 120 space_dump->AddScalar("virtual_size", | 121 space_dump->AddScalar("virtual_size", |
| 121 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 122 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 122 space_size); | 123 space_size); |
| 123 | 124 |
| 124 space_dump->AddScalar("allocated_objects_size", | 125 space_dump->AddScalar("allocated_objects_size", |
| 125 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 126 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 126 space_used_size); | 127 space_used_size); |
| 127 } | 128 } |
| 128 | 129 |
| 129 // Compute the rest of the memory, not accounted by the spaces above. | 130 // Compute the rest of the memory, not accounted by the spaces above. |
| 130 std::string other_spaces_name = space_name_prefix + "/other_spaces"; | 131 std::string other_spaces_name = space_name_prefix + "/other_spaces"; |
| 131 auto other_dump = process_memory_dump->CreateAllocatorDump(other_spaces_name); | 132 auto* other_dump = |
| 133 process_memory_dump->CreateAllocatorDump(other_spaces_name); |
| 132 | 134 |
| 133 other_dump->AddScalar( | 135 other_dump->AddScalar( |
| 134 base::trace_event::MemoryAllocatorDump::kNameSize, | 136 base::trace_event::MemoryAllocatorDump::kNameSize, |
| 135 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 137 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 136 heap_statistics.total_physical_size() - known_spaces_physical_size); | 138 heap_statistics.total_physical_size() - known_spaces_physical_size); |
| 137 | 139 |
| 138 other_dump->AddScalar( | 140 other_dump->AddScalar( |
| 139 "allocated_objects_size", | 141 "allocated_objects_size", |
| 140 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 142 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 141 heap_statistics.used_heap_size() - known_spaces_used_size); | 143 heap_statistics.used_heap_size() - known_spaces_used_size); |
| 142 | 144 |
| 143 other_dump->AddScalar("virtual_size", | 145 other_dump->AddScalar("virtual_size", |
| 144 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 146 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 145 heap_statistics.total_heap_size() - known_spaces_size); | 147 heap_statistics.total_heap_size() - known_spaces_size); |
| 146 | 148 |
| 147 // If V8 zaps garbage, all the memory mapped regions become resident, | 149 // If V8 zaps garbage, all the memory mapped regions become resident, |
| 148 // so we add an extra dump to avoid mismatches w.r.t. the total | 150 // so we add an extra dump to avoid mismatches w.r.t. the total |
| 149 // resident values. | 151 // resident values. |
| 150 if (heap_statistics.does_zap_garbage()) { | 152 if (heap_statistics.does_zap_garbage()) { |
| 151 auto zap_dump = process_memory_dump->CreateAllocatorDump( | 153 auto* zap_dump = process_memory_dump->CreateAllocatorDump( |
| 152 dump_base_name + "/zapped_for_debug"); | 154 dump_base_name + "/zapped_for_debug"); |
| 153 zap_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, | 155 zap_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, |
| 154 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 156 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 155 heap_statistics.total_heap_size() - | 157 heap_statistics.total_heap_size() - |
| 156 heap_statistics.total_physical_size()); | 158 heap_statistics.total_physical_size()); |
| 157 } | 159 } |
| 158 | 160 |
| 159 // Dump statistics about malloced memory. | 161 // Dump statistics about malloced memory. |
| 160 std::string malloc_name = dump_base_name + "/malloc"; | 162 std::string malloc_name = dump_base_name + "/malloc"; |
| 161 auto malloc_dump = process_memory_dump->CreateAllocatorDump(malloc_name); | 163 auto* malloc_dump = process_memory_dump->CreateAllocatorDump(malloc_name); |
| 162 malloc_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, | 164 malloc_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, |
| 163 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 165 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 164 heap_statistics.malloced_memory()); | 166 heap_statistics.malloced_memory()); |
| 165 const char* system_allocator_name = | 167 const char* system_allocator_name = |
| 166 base::trace_event::MemoryDumpManager::GetInstance() | 168 base::trace_event::MemoryDumpManager::GetInstance() |
| 167 ->system_allocator_pool_name(); | 169 ->system_allocator_pool_name(); |
| 168 if (system_allocator_name) { | 170 if (system_allocator_name) { |
| 169 process_memory_dump->AddSuballocation(malloc_dump->guid(), | 171 process_memory_dump->AddSuballocation(malloc_dump->guid(), |
| 170 system_allocator_name); | 172 system_allocator_name); |
| 171 } | 173 } |
| 172 | 174 |
| 173 // Add an empty row for the heap_spaces. This is to keep the shape of the | 175 // Add an empty row for the heap_spaces. This is to keep the shape of the |
| 174 // dump stable, whether code stats are enabled or not. | 176 // dump stable, whether code stats are enabled or not. |
| 175 auto heap_spaces_dump = | 177 auto* heap_spaces_dump = |
| 176 process_memory_dump->CreateAllocatorDump(space_name_prefix); | 178 process_memory_dump->CreateAllocatorDump(space_name_prefix); |
| 177 | 179 |
| 178 // Dump object statistics only for detailed dumps. | 180 // Dump object statistics only for detailed dumps. |
| 179 if (args.level_of_detail != | 181 if (args.level_of_detail != |
| 180 base::trace_event::MemoryDumpLevelOfDetail::DETAILED) { | 182 base::trace_event::MemoryDumpLevelOfDetail::DETAILED) { |
| 181 return; | 183 return; |
| 182 } | 184 } |
| 183 | 185 |
| 184 // Dump statistics of the heap's live objects from last GC. | 186 // Dump statistics of the heap's live objects from last GC. |
| 185 // TODO(primiano): these should not be tracked in the same trace event as they | 187 // TODO(primiano): these should not be tracked in the same trace event as they |
| 186 // report stats for the last GC (not the current state). See crbug.com/498779. | 188 // report stats for the last GC (not the current state). See crbug.com/498779. |
| 187 std::string object_name_prefix = dump_base_name + "/heap_objects_at_last_gc"; | 189 std::string object_name_prefix = dump_base_name + "/heap_objects_at_last_gc"; |
| 188 bool did_dump_object_stats = false; | 190 bool did_dump_object_stats = false; |
| 189 const size_t object_types = | 191 const size_t object_types = |
| 190 isolate_holder_->isolate()->NumberOfTrackedHeapObjectTypes(); | 192 isolate_holder_->isolate()->NumberOfTrackedHeapObjectTypes(); |
| 191 for (size_t type_index = 0; type_index < object_types; type_index++) { | 193 for (size_t type_index = 0; type_index < object_types; type_index++) { |
| 192 v8::HeapObjectStatistics object_statistics; | 194 v8::HeapObjectStatistics object_statistics; |
| 193 if (!isolate_holder_->isolate()->GetHeapObjectStatisticsAtLastGC( | 195 if (!isolate_holder_->isolate()->GetHeapObjectStatisticsAtLastGC( |
| 194 &object_statistics, type_index)) | 196 &object_statistics, type_index)) |
| 195 continue; | 197 continue; |
| 196 | 198 |
| 197 std::string dump_name = | 199 std::string dump_name = |
| 198 object_name_prefix + "/" + object_statistics.object_type(); | 200 object_name_prefix + "/" + object_statistics.object_type(); |
| 199 if (object_statistics.object_sub_type()[0] != '\0') | 201 if (object_statistics.object_sub_type()[0] != '\0') |
| 200 dump_name += std::string("/") + object_statistics.object_sub_type(); | 202 dump_name += std::string("/") + object_statistics.object_sub_type(); |
| 201 auto object_dump = process_memory_dump->CreateAllocatorDump(dump_name); | 203 auto* object_dump = process_memory_dump->CreateAllocatorDump(dump_name); |
| 202 | 204 |
| 203 object_dump->AddScalar( | 205 object_dump->AddScalar( |
| 204 base::trace_event::MemoryAllocatorDump::kNameObjectCount, | 206 base::trace_event::MemoryAllocatorDump::kNameObjectCount, |
| 205 base::trace_event::MemoryAllocatorDump::kUnitsObjects, | 207 base::trace_event::MemoryAllocatorDump::kUnitsObjects, |
| 206 object_statistics.object_count()); | 208 object_statistics.object_count()); |
| 207 object_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, | 209 object_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, |
| 208 base::trace_event::MemoryAllocatorDump::kUnitsBytes, | 210 base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 209 object_statistics.object_size()); | 211 object_statistics.object_size()); |
| 210 did_dump_object_stats = true; | 212 did_dump_object_stats = true; |
| 211 } | 213 } |
| 212 | 214 |
| 213 if (process_memory_dump->GetAllocatorDump(object_name_prefix + | 215 if (process_memory_dump->GetAllocatorDump(object_name_prefix + |
| 214 "/CODE_TYPE")) { | 216 "/CODE_TYPE")) { |
| 215 auto code_kind_dump = process_memory_dump->CreateAllocatorDump( | 217 auto* code_kind_dump = process_memory_dump->CreateAllocatorDump( |
| 216 object_name_prefix + "/CODE_TYPE/CODE_KIND"); | 218 object_name_prefix + "/CODE_TYPE/CODE_KIND"); |
| 217 auto code_age_dump = process_memory_dump->CreateAllocatorDump( | 219 auto* code_age_dump = process_memory_dump->CreateAllocatorDump( |
| 218 object_name_prefix + "/CODE_TYPE/CODE_AGE"); | 220 object_name_prefix + "/CODE_TYPE/CODE_AGE"); |
| 219 process_memory_dump->AddOwnershipEdge(code_kind_dump->guid(), | 221 process_memory_dump->AddOwnershipEdge(code_kind_dump->guid(), |
| 220 code_age_dump->guid()); | 222 code_age_dump->guid()); |
| 221 } | 223 } |
| 222 | 224 |
| 223 if (did_dump_object_stats) { | 225 if (did_dump_object_stats) { |
| 224 process_memory_dump->AddOwnershipEdge( | 226 process_memory_dump->AddOwnershipEdge( |
| 225 process_memory_dump->CreateAllocatorDump(object_name_prefix)->guid(), | 227 process_memory_dump->CreateAllocatorDump(object_name_prefix)->guid(), |
| 226 heap_spaces_dump->guid()); | 228 heap_spaces_dump->guid()); |
| 227 } | 229 } |
| 228 | 230 |
| 229 // Dump statistics related to code and bytecode if requested. | 231 // Dump statistics related to code and bytecode if requested. |
| 230 DumpCodeStatistics(heap_spaces_dump, isolate_holder_); | 232 DumpCodeStatistics(heap_spaces_dump, isolate_holder_); |
| 231 } | 233 } |
| 232 | 234 |
| 233 } // namespace gin | 235 } // namespace gin |
| OLD | NEW |