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 "base/trace_event/memory_allocator_dump.h" | 5 #include "base/trace_event/memory_allocator_dump.h" |
6 | 6 |
7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
9 #include "base/trace_event/memory_dump_manager.h" | 9 #include "base/trace_event/memory_dump_manager.h" |
10 #include "base/trace_event/memory_dump_provider.h" | 10 #include "base/trace_event/memory_dump_provider.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 const StringValue* str_value = nullptr; | 25 const StringValue* str_value = nullptr; |
26 if (!dict_value->GetWithoutPathExpansion(key, &value)) | 26 if (!dict_value->GetWithoutPathExpansion(key, &value)) |
27 return false; | 27 return false; |
28 if (!value->GetAsString(&str_value)) | 28 if (!value->GetAsString(&str_value)) |
29 return false; | 29 return false; |
30 *out_cstr = str_value->GetString().c_str(); | 30 *out_cstr = str_value->GetString().c_str(); |
31 return true; | 31 return true; |
32 } | 32 } |
33 } // namespace | 33 } // namespace |
34 | 34 |
| 35 // TODO(primiano): remove kName{Inner,Outer}Size below after all the existing |
| 36 // dump providers have been rewritten. |
| 37 const char MemoryAllocatorDump::kNameSize[] = "size"; |
| 38 const char MemoryAllocatorDump::kNameInnerSize[] = "inner_size"; |
35 const char MemoryAllocatorDump::kNameOuterSize[] = "outer_size"; | 39 const char MemoryAllocatorDump::kNameOuterSize[] = "outer_size"; |
36 const char MemoryAllocatorDump::kNameInnerSize[] = "inner_size"; | |
37 const char MemoryAllocatorDump::kNameObjectsCount[] = "objects_count"; | 40 const char MemoryAllocatorDump::kNameObjectsCount[] = "objects_count"; |
38 const char MemoryAllocatorDump::kTypeScalar[] = "scalar"; | 41 const char MemoryAllocatorDump::kTypeScalar[] = "scalar"; |
39 const char MemoryAllocatorDump::kTypeString[] = "string"; | 42 const char MemoryAllocatorDump::kTypeString[] = "string"; |
40 const char MemoryAllocatorDump::kUnitsBytes[] = "bytes"; | 43 const char MemoryAllocatorDump::kUnitsBytes[] = "bytes"; |
41 const char MemoryAllocatorDump::kUnitsObjects[] = "objects"; | 44 const char MemoryAllocatorDump::kUnitsObjects[] = "objects"; |
42 | 45 |
43 MemoryAllocatorDump::MemoryAllocatorDump(const std::string& absolute_name, | 46 MemoryAllocatorDump::MemoryAllocatorDump(const std::string& absolute_name, |
44 ProcessMemoryDump* process_memory_dump) | 47 ProcessMemoryDump* process_memory_dump, |
45 : absolute_name_(absolute_name), process_memory_dump_(process_memory_dump) { | 48 const MemoryAllocatorDumpGuid& guid) |
| 49 : absolute_name_(absolute_name), |
| 50 process_memory_dump_(process_memory_dump), |
| 51 guid_(guid) { |
46 // The |absolute_name| cannot be empty. | 52 // The |absolute_name| cannot be empty. |
47 DCHECK(!absolute_name.empty()); | 53 DCHECK(!absolute_name.empty()); |
48 | 54 |
49 // The |absolute_name| can contain slash separator, but not leading or | 55 // The |absolute_name| can contain slash separator, but not leading or |
50 // trailing ones. | 56 // trailing ones. |
51 DCHECK(absolute_name[0] != '/' && *absolute_name.rbegin() != '/'); | 57 DCHECK(absolute_name[0] != '/' && *absolute_name.rbegin() != '/'); |
52 | 58 |
53 // Dots are not allowed anywhere as the underlying base::DictionaryValue | 59 // Dots are not allowed anywhere as the underlying base::DictionaryValue |
54 // would treat them magically and split in sub-nodes, which is not intended. | 60 // would treat them magically and split in sub-nodes, which is not intended. |
55 DCHECK_EQ(std::string::npos, absolute_name.find_first_of('.')); | 61 DCHECK_EQ(std::string::npos, absolute_name.find_first_of('.')); |
56 } | 62 } |
57 | 63 |
| 64 // If the caller didn't provide a guid, make one up by hashing the |
| 65 // absolute_name with the current PID. |
| 66 // Rationale: |absolute_name| is already supposed to be unique within a |
| 67 // process, the pid will make it unique among all processes. |
| 68 MemoryAllocatorDump::MemoryAllocatorDump(const std::string& absolute_name, |
| 69 ProcessMemoryDump* process_memory_dump) |
| 70 : MemoryAllocatorDump(absolute_name, |
| 71 process_memory_dump, |
| 72 MemoryAllocatorDumpGuid(StringPrintf( |
| 73 "%d:%s", |
| 74 TraceLog::GetInstance()->process_id(), |
| 75 absolute_name.c_str()))) { |
| 76 } |
| 77 |
58 MemoryAllocatorDump::~MemoryAllocatorDump() { | 78 MemoryAllocatorDump::~MemoryAllocatorDump() { |
59 } | 79 } |
60 | 80 |
61 void MemoryAllocatorDump::Add(const std::string& name, | 81 void MemoryAllocatorDump::Add(const std::string& name, |
62 const char* type, | 82 const char* type, |
63 const char* units, | 83 const char* units, |
64 scoped_ptr<Value> value) { | 84 scoped_ptr<Value> value) { |
65 scoped_ptr<DictionaryValue> attribute(new DictionaryValue()); | 85 scoped_ptr<DictionaryValue> attribute(new DictionaryValue()); |
66 DCHECK(!attributes_.HasKey(name)); | 86 DCHECK(!attributes_.HasKey(name)); |
67 attribute->SetStringWithoutPathExpansion("type", type); | 87 attribute->SetStringWithoutPathExpansion("type", type); |
(...skipping 22 matching lines...) Expand all Loading... |
90 return true; | 110 return true; |
91 } | 111 } |
92 | 112 |
93 void MemoryAllocatorDump::AddScalar(const std::string& name, | 113 void MemoryAllocatorDump::AddScalar(const std::string& name, |
94 const char* units, | 114 const char* units, |
95 uint64 value) { | 115 uint64 value) { |
96 scoped_ptr<Value> hex_value(new StringValue(StringPrintf("%" PRIx64, value))); | 116 scoped_ptr<Value> hex_value(new StringValue(StringPrintf("%" PRIx64, value))); |
97 Add(name, kTypeScalar, units, hex_value.Pass()); | 117 Add(name, kTypeScalar, units, hex_value.Pass()); |
98 } | 118 } |
99 | 119 |
| 120 void MemoryAllocatorDump::AddScalarF(const std::string& name, |
| 121 const char* units, |
| 122 double value) { |
| 123 Add(name, kTypeScalar, units, make_scoped_ptr(new FundamentalValue(value))); |
| 124 } |
| 125 |
100 void MemoryAllocatorDump::AddString(const std::string& name, | 126 void MemoryAllocatorDump::AddString(const std::string& name, |
101 const char* units, | 127 const char* units, |
102 const std::string& value) { | 128 const std::string& value) { |
103 scoped_ptr<Value> str_value(new StringValue(value)); | 129 scoped_ptr<Value> str_value(new StringValue(value)); |
104 Add(name, kTypeString, units, str_value.Pass()); | 130 Add(name, kTypeString, units, str_value.Pass()); |
105 } | 131 } |
106 | 132 |
107 void MemoryAllocatorDump::AsValueInto(TracedValue* value) const { | 133 void MemoryAllocatorDump::AsValueInto(TracedValue* value) const { |
108 value->BeginDictionary(absolute_name_.c_str()); | 134 value->BeginDictionary(absolute_name_.c_str()); |
| 135 value->SetString("guid", guid_.ToString()); |
| 136 |
109 value->BeginDictionary("attrs"); | 137 value->BeginDictionary("attrs"); |
110 | 138 |
111 for (DictionaryValue::Iterator it(attributes_); !it.IsAtEnd(); it.Advance()) | 139 for (DictionaryValue::Iterator it(attributes_); !it.IsAtEnd(); it.Advance()) |
112 value->SetValue(it.key().c_str(), it.value().CreateDeepCopy()); | 140 value->SetValue(it.key().c_str(), it.value().CreateDeepCopy()); |
113 | 141 |
114 value->EndDictionary(); // "attrs": { ... } | 142 value->EndDictionary(); // "attrs": { ... } |
115 value->EndDictionary(); // "allocator_name/heap_subheap": { ... } | 143 value->EndDictionary(); // "allocator_name/heap_subheap": { ... } |
116 } | 144 } |
117 | 145 |
118 } // namespace trace_event | 146 } // namespace trace_event |
119 } // namespace base | 147 } // namespace base |
OLD | NEW |