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 "base/trace_event/memory_allocator_dump.h" 6 7 #include "base/format_macros.h" 8 #include "base/strings/stringprintf.h" 9 #include "base/trace_event/memory_dump_manager.h" 10 #include "base/trace_event/memory_dump_provider.h" 11 #include "base/trace_event/process_memory_dump.h" 12 #include "base/trace_event/trace_event_argument.h" 13 #include "base/values.h" 14 15 namespace base { 16 namespace trace_event { 17 18 const char MemoryAllocatorDump::kNameSize[] = "size"; 19 const char MemoryAllocatorDump::kNameObjectCount[] = "object_count"; 20 const char MemoryAllocatorDump::kTypeScalar[] = "scalar"; 21 const char MemoryAllocatorDump::kTypeString[] = "string"; 22 const char MemoryAllocatorDump::kUnitsBytes[] = "bytes"; 23 const char MemoryAllocatorDump::kUnitsObjects[] = "objects"; 24 25 MemoryAllocatorDump::MemoryAllocatorDump(const std::string& absolute_name, 26 ProcessMemoryDump* process_memory_dump, 27 const MemoryAllocatorDumpGuid& guid) 28 : absolute_name_(absolute_name), 29 process_memory_dump_(process_memory_dump), 30 attributes_(new TracedValue), 31 guid_(guid) { 32 // The |absolute_name| cannot be empty. 33 DCHECK(!absolute_name.empty()); 34 35 // The |absolute_name| can contain slash separator, but not leading or 36 // trailing ones. 37 DCHECK(absolute_name[0] != '/' && *absolute_name.rbegin() != '/'); 38 } 39 40 // If the caller didn't provide a guid, make one up by hashing the 41 // absolute_name with the current PID. 42 // Rationale: |absolute_name| is already supposed to be unique within a 43 // process, the pid will make it unique among all processes. 44 MemoryAllocatorDump::MemoryAllocatorDump(const std::string& absolute_name, 45 ProcessMemoryDump* process_memory_dump) 46 : MemoryAllocatorDump(absolute_name, 47 process_memory_dump, 48 MemoryAllocatorDumpGuid(StringPrintf( 49 "%d:%s", 50 TraceLog::GetInstance()->process_id(), 51 absolute_name.c_str()))) { 52 string_conversion_buffer_.reserve(16); 53 } 54 55 MemoryAllocatorDump::~MemoryAllocatorDump() { 56 } 57 58 void MemoryAllocatorDump::AddScalar(const char* name, 59 const char* units, 60 uint64_t value) { 61 SStringPrintf(&string_conversion_buffer_, "%" PRIx64, value); 62 attributes_->BeginDictionary(name); 63 attributes_->SetString("type", kTypeScalar); 64 attributes_->SetString("units", units); 65 attributes_->SetString("value", string_conversion_buffer_); 66 attributes_->EndDictionary(); 67 } 68 69 void MemoryAllocatorDump::AddScalarF(const char* name, 70 const char* units, 71 double value) { 72 attributes_->BeginDictionary(name); 73 attributes_->SetString("type", kTypeScalar); 74 attributes_->SetString("units", units); 75 attributes_->SetDouble("value", value); 76 attributes_->EndDictionary(); 77 } 78 79 void MemoryAllocatorDump::AddString(const char* name, 80 const char* units, 81 const std::string& value) { 82 attributes_->BeginDictionary(name); 83 attributes_->SetString("type", kTypeString); 84 attributes_->SetString("units", units); 85 attributes_->SetString("value", value); 86 attributes_->EndDictionary(); 87 } 88 89 void MemoryAllocatorDump::AsValueInto(TracedValue* value) const { 90 value->BeginDictionaryWithCopiedName(absolute_name_); 91 value->SetString("guid", guid_.ToString()); 92 value->SetValue("attrs", *attributes_); 93 value->EndDictionary(); // "allocator_name/heap_subheap": { ... } 94 } 95 96 } // namespace trace_event 97 } // namespace base 98