ssid | 83aa5be | 2015-05-08 12:03:26 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "gin/v8_isolate_memory_dump_provider.h" |
| 6 | |
| 7 | #include "base/message_loop/message_loop.h" |
| 8 | #include "base/strings/stringprintf.h" |
| 9 | #include "base/thread_task_runner_handle.h" |
| 10 | #include "base/trace_event/memory_dump_manager.h" |
| 11 | #include "base/trace_event/process_memory_dump.h" |
| 12 | #include "gin/public/isolate_holder.h" |
| 13 | #include "v8/include/v8.h" |
| 14 | |
| 15 | namespace gin { |
| 16 | |
| 17 | namespace { |
| 18 | const char kRootDumpName[] = "v8"; |
| 19 | const char kIsolateDumpName[] = "isolate"; |
| 20 | const char kHeapSpacesDumpName[] = "heap_spaces"; |
| 21 | const char kAvailableSizeAttribute[] = "available_size_in_bytes"; |
| 22 | } // namespace |
| 23 | |
| 24 | V8IsolateMemoryDumpProvider::V8IsolateMemoryDumpProvider( |
| 25 | IsolateHolder* isolate_holder) |
| 26 | : isolate_holder_(isolate_holder) { |
| 27 | base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| 28 | this, base::ThreadTaskRunnerHandle::Get()); |
| 29 | } |
| 30 | |
| 31 | V8IsolateMemoryDumpProvider::~V8IsolateMemoryDumpProvider() { |
| 32 | base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
| 33 | this); |
| 34 | } |
| 35 | |
| 36 | // Called at trace dump point time. Creates a snapshot with the memory counters |
| 37 | // for the current isolate. |
| 38 | bool V8IsolateMemoryDumpProvider::OnMemoryDump( |
| 39 | base::trace_event::ProcessMemoryDump* pmd) { |
| 40 | if (isolate_holder_->access_mode() == IsolateHolder::kUseLocker) { |
| 41 | v8::Locker locked(isolate_holder_->isolate()); |
| 42 | DumpMemoryStatistics(pmd); |
| 43 | } else { |
| 44 | DumpMemoryStatistics(pmd); |
| 45 | } |
| 46 | return true; |
| 47 | } |
| 48 | |
| 49 | void V8IsolateMemoryDumpProvider::DumpMemoryStatistics( |
| 50 | base::trace_event::ProcessMemoryDump* pmd) { |
| 51 | v8::HeapStatistics heap_statistics; |
| 52 | isolate_holder_->isolate()->GetHeapStatistics(&heap_statistics); |
| 53 | |
| 54 | size_t known_spaces_used_size = 0; |
| 55 | size_t known_spaces_size = 0; |
ssid | 49aa14c7 | 2015-05-29 13:03:59 | [diff] [blame^] | 56 | size_t known_spaces_available_size = 0; |
ssid | 83aa5be | 2015-05-08 12:03:26 | [diff] [blame] | 57 | size_t number_of_spaces = isolate_holder_->isolate()->NumberOfHeapSpaces(); |
| 58 | for (size_t space = 0; space < number_of_spaces; space++) { |
| 59 | v8::HeapSpaceStatistics space_statistics; |
| 60 | isolate_holder_->isolate()->GetHeapSpaceStatistics(&space_statistics, |
| 61 | space); |
| 62 | const size_t space_size = space_statistics.space_size(); |
| 63 | const size_t space_used_size = space_statistics.space_used_size(); |
ssid | 49aa14c7 | 2015-05-29 13:03:59 | [diff] [blame^] | 64 | const size_t space_available_size = space_statistics.space_available_size(); |
ssid | 83aa5be | 2015-05-08 12:03:26 | [diff] [blame] | 65 | |
| 66 | known_spaces_size += space_size; |
| 67 | known_spaces_used_size += space_used_size; |
ssid | 49aa14c7 | 2015-05-29 13:03:59 | [diff] [blame^] | 68 | known_spaces_available_size += space_available_size; |
ssid | 83aa5be | 2015-05-08 12:03:26 | [diff] [blame] | 69 | |
| 70 | std::string allocator_name = |
| 71 | base::StringPrintf("%s/%s_%p/%s/%s", kRootDumpName, kIsolateDumpName, |
| 72 | isolate_holder_->isolate(), kHeapSpacesDumpName, |
| 73 | space_statistics.space_name()); |
| 74 | base::trace_event::MemoryAllocatorDump* space_dump = |
| 75 | pmd->CreateAllocatorDump(allocator_name); |
| 76 | space_dump->AddScalar( |
| 77 | base::trace_event::MemoryAllocatorDump::kNameOuterSize, |
| 78 | base::trace_event::MemoryAllocatorDump::kUnitsBytes, space_size); |
| 79 | |
ssid | b765e2a | 2015-05-12 20:46:19 | [diff] [blame] | 80 | // TODO(ssid): Fix crbug.com/481504 to get the objects count of live objects |
| 81 | // after the last GC. |
ssid | 83aa5be | 2015-05-08 12:03:26 | [diff] [blame] | 82 | space_dump->AddScalar( |
| 83 | base::trace_event::MemoryAllocatorDump::kNameInnerSize, |
| 84 | base::trace_event::MemoryAllocatorDump::kUnitsBytes, space_used_size); |
| 85 | space_dump->AddScalar(kAvailableSizeAttribute, |
| 86 | base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
ssid | 49aa14c7 | 2015-05-29 13:03:59 | [diff] [blame^] | 87 | space_available_size); |
ssid | 83aa5be | 2015-05-08 12:03:26 | [diff] [blame] | 88 | } |
| 89 | // Compute the rest of the memory, not accounted by the spaces above. |
| 90 | std::string allocator_name = base::StringPrintf( |
| 91 | "%s/%s_%p/%s/%s", kRootDumpName, kIsolateDumpName, |
| 92 | isolate_holder_->isolate(), kHeapSpacesDumpName, "other_spaces"); |
| 93 | base::trace_event::MemoryAllocatorDump* other_spaces_dump = |
| 94 | pmd->CreateAllocatorDump(allocator_name); |
| 95 | other_spaces_dump->AddScalar( |
| 96 | base::trace_event::MemoryAllocatorDump::kNameOuterSize, |
| 97 | base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 98 | heap_statistics.total_heap_size() - known_spaces_size); |
| 99 | other_spaces_dump->AddScalar( |
| 100 | base::trace_event::MemoryAllocatorDump::kNameInnerSize, |
| 101 | base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 102 | heap_statistics.used_heap_size() - known_spaces_used_size); |
| 103 | |
ssid | 83aa5be | 2015-05-08 12:03:26 | [diff] [blame] | 104 | other_spaces_dump->AddScalar( |
| 105 | kAvailableSizeAttribute, |
ssid | 49aa14c7 | 2015-05-29 13:03:59 | [diff] [blame^] | 106 | base::trace_event::MemoryAllocatorDump::kUnitsBytes, |
| 107 | heap_statistics.total_available_size() - known_spaces_available_size); |
ssid | 83aa5be | 2015-05-08 12:03:26 | [diff] [blame] | 108 | } |
| 109 | |
| 110 | } // namespace gin |