Index: base/trace_event/trace_event_memory_overhead.cc |
diff --git a/base/trace_event/trace_event_memory_overhead.cc b/base/trace_event/trace_event_memory_overhead.cc |
index d23383f701c095b14edad2f59a419b60daaa485a..02a98bd7c7c4b01c9951fb9aadf1782c40ce729e 100644 |
--- a/base/trace_event/trace_event_memory_overhead.cc |
+++ b/base/trace_event/trace_event_memory_overhead.cc |
@@ -10,60 +10,85 @@ |
#include "base/memory/ref_counted_memory.h" |
#include "base/strings/stringprintf.h" |
#include "base/trace_event/memory_allocator_dump.h" |
+#include "base/trace_event/memory_usage_estimator.h" |
#include "base/trace_event/process_memory_dump.h" |
#include "base/values.h" |
namespace base { |
namespace trace_event { |
-TraceEventMemoryOverhead::TraceEventMemoryOverhead() { |
+namespace { |
+ |
+const char* ObjectTypeToString(TraceEventMemoryOverhead::ObjectType type) { |
+ switch (type) { |
+ case TraceEventMemoryOverhead::kOther: |
+ return "(Other)"; |
+ case TraceEventMemoryOverhead::kTraceBuffer: |
+ return "TraceBuffer"; |
+ case TraceEventMemoryOverhead::kTraceBufferChunk: |
+ return "TraceBufferChunk"; |
+ case TraceEventMemoryOverhead::kTraceEvent: |
+ return "TraceEvent"; |
+ case TraceEventMemoryOverhead::kUnusedTraceEvent: |
+ return "TraceEvent(Unused)"; |
+ case TraceEventMemoryOverhead::kTracedValue: |
+ return "TracedValue"; |
+ case TraceEventMemoryOverhead::kConvertableToTraceFormat: |
+ return "ConvertableToTraceFormat"; |
+ case TraceEventMemoryOverhead::kHeapProfilerAllocationRegister: |
+ return "AllocationRegister"; |
+ case TraceEventMemoryOverhead::kHeapProfilerTypeNameDeduplicator: |
+ return "TypeNameDeduplicator"; |
+ case TraceEventMemoryOverhead::kHeapProfilerStackFrameDeduplicator: |
+ return "StackFrameDeduplicator"; |
+ case TraceEventMemoryOverhead::kStdString: |
+ return "std::string"; |
+ case TraceEventMemoryOverhead::kBaseValue: |
+ return "base::Value"; |
+ case TraceEventMemoryOverhead::kTraceEventMemoryOverhead: |
+ return "TraceEventMemoryOverhead"; |
+ case TraceEventMemoryOverhead::kLast: |
+ NOTREACHED(); |
+ } |
+ NOTREACHED(); |
+ return "BUG"; |
} |
-TraceEventMemoryOverhead::~TraceEventMemoryOverhead() { |
-} |
+} // namespace |
-void TraceEventMemoryOverhead::AddOrCreateInternal( |
- const char* object_type, |
- size_t count, |
- size_t allocated_size_in_bytes, |
- size_t resident_size_in_bytes) { |
- auto it = allocated_objects_.find(object_type); |
- if (it == allocated_objects_.end()) { |
- allocated_objects_.insert(std::make_pair( |
- object_type, |
- ObjectCountAndSize( |
- {count, allocated_size_in_bytes, resident_size_in_bytes}))); |
- return; |
- } |
- it->second.count += count; |
- it->second.allocated_size_in_bytes += allocated_size_in_bytes; |
- it->second.resident_size_in_bytes += resident_size_in_bytes; |
+TraceEventMemoryOverhead::TraceEventMemoryOverhead() : allocated_objects_() {} |
+ |
+TraceEventMemoryOverhead::~TraceEventMemoryOverhead() {} |
+ |
+void TraceEventMemoryOverhead::AddInternal(ObjectType object_type, |
+ size_t count, |
+ size_t allocated_size_in_bytes, |
+ size_t resident_size_in_bytes) { |
+ ObjectCountAndSize& count_and_size = |
+ allocated_objects_[static_cast<uint32_t>(object_type)]; |
+ count_and_size.count += count; |
+ count_and_size.allocated_size_in_bytes += allocated_size_in_bytes; |
+ count_and_size.resident_size_in_bytes += resident_size_in_bytes; |
} |
-void TraceEventMemoryOverhead::Add(const char* object_type, |
+void TraceEventMemoryOverhead::Add(ObjectType object_type, |
size_t allocated_size_in_bytes) { |
Add(object_type, allocated_size_in_bytes, allocated_size_in_bytes); |
} |
-void TraceEventMemoryOverhead::Add(const char* object_type, |
+void TraceEventMemoryOverhead::Add(ObjectType object_type, |
size_t allocated_size_in_bytes, |
size_t resident_size_in_bytes) { |
- AddOrCreateInternal(object_type, 1, allocated_size_in_bytes, |
- resident_size_in_bytes); |
+ AddInternal(object_type, 1, allocated_size_in_bytes, resident_size_in_bytes); |
} |
void TraceEventMemoryOverhead::AddString(const std::string& str) { |
- // The number below are empirical and mainly based on profiling of real-world |
- // std::string implementations: |
- // - even short string end up malloc()-inc at least 32 bytes. |
- // - longer strings seem to malloc() multiples of 16 bytes. |
- const size_t capacity = bits::Align(str.capacity(), 16); |
- Add("std::string", sizeof(std::string) + std::max<size_t>(capacity, 32u)); |
+ Add(kStdString, EstimateMemoryUsage(str)); |
} |
void TraceEventMemoryOverhead::AddRefCountedString( |
const RefCountedString& str) { |
- Add("RefCountedString", sizeof(RefCountedString)); |
+ Add(kOther, sizeof(RefCountedString)); |
AddString(str.data()); |
} |
@@ -73,24 +98,24 @@ void TraceEventMemoryOverhead::AddValue(const Value& value) { |
case Value::Type::BOOLEAN: |
case Value::Type::INTEGER: |
case Value::Type::DOUBLE: |
- Add("FundamentalValue", sizeof(Value)); |
+ Add(kBaseValue, sizeof(Value)); |
break; |
case Value::Type::STRING: { |
const Value* string_value = nullptr; |
value.GetAsString(&string_value); |
- Add("StringValue", sizeof(Value)); |
+ Add(kBaseValue, sizeof(Value)); |
AddString(string_value->GetString()); |
} break; |
case Value::Type::BINARY: { |
- Add("BinaryValue", sizeof(Value) + value.GetBlob().size()); |
+ Add(kBaseValue, sizeof(Value) + value.GetBlob().size()); |
} break; |
case Value::Type::DICTIONARY: { |
const DictionaryValue* dictionary_value = nullptr; |
value.GetAsDictionary(&dictionary_value); |
- Add("DictionaryValue", sizeof(DictionaryValue)); |
+ Add(kBaseValue, sizeof(DictionaryValue)); |
for (DictionaryValue::Iterator it(*dictionary_value); !it.IsAtEnd(); |
it.Advance()) { |
AddString(it.key()); |
@@ -101,7 +126,7 @@ void TraceEventMemoryOverhead::AddValue(const Value& value) { |
case Value::Type::LIST: { |
const ListValue* list_value = nullptr; |
value.GetAsList(&list_value); |
- Add("ListValue", sizeof(ListValue)); |
+ Add(kBaseValue, sizeof(ListValue)); |
for (const auto& v : *list_value) |
AddValue(v); |
} break; |
@@ -112,41 +137,39 @@ void TraceEventMemoryOverhead::AddValue(const Value& value) { |
} |
void TraceEventMemoryOverhead::AddSelf() { |
- size_t estimated_size = sizeof(*this); |
- // If the small_map did overflow its static capacity, its elements will be |
- // allocated on the heap and have to be accounted separately. |
- if (allocated_objects_.UsingFullMap()) |
- estimated_size += sizeof(map_type::value_type) * allocated_objects_.size(); |
- Add("TraceEventMemoryOverhead", estimated_size); |
+ Add(kTraceEventMemoryOverhead, sizeof(*this)); |
} |
-size_t TraceEventMemoryOverhead::GetCount(const char* object_type) const { |
- const auto& it = allocated_objects_.find(object_type); |
- if (it == allocated_objects_.end()) |
- return 0u; |
- return it->second.count; |
+size_t TraceEventMemoryOverhead::GetCount(ObjectType object_type) const { |
+ CHECK(object_type < kLast); |
+ return allocated_objects_[static_cast<uint32_t>(object_type)].count; |
} |
void TraceEventMemoryOverhead::Update(const TraceEventMemoryOverhead& other) { |
- for (const auto& it : other.allocated_objects_) { |
- AddOrCreateInternal(it.first, it.second.count, |
- it.second.allocated_size_in_bytes, |
- it.second.resident_size_in_bytes); |
+ for (uint32_t i = 0; i < kLast; i++) { |
+ const ObjectCountAndSize& other_entry = other.allocated_objects_[i]; |
+ AddInternal(static_cast<ObjectType>(i), other_entry.count, |
+ other_entry.allocated_size_in_bytes, |
+ other_entry.resident_size_in_bytes); |
} |
} |
void TraceEventMemoryOverhead::DumpInto(const char* base_name, |
ProcessMemoryDump* pmd) const { |
- for (const auto& it : allocated_objects_) { |
- std::string dump_name = StringPrintf("%s/%s", base_name, it.first); |
+ for (uint32_t i = 0; i < kLast; i++) { |
+ const ObjectCountAndSize& count_and_size = allocated_objects_[i]; |
+ if (count_and_size.allocated_size_in_bytes == 0) |
+ continue; |
+ std::string dump_name = StringPrintf( |
+ "%s/%s", base_name, ObjectTypeToString(static_cast<ObjectType>(i))); |
MemoryAllocatorDump* mad = pmd->CreateAllocatorDump(dump_name); |
mad->AddScalar(MemoryAllocatorDump::kNameSize, |
MemoryAllocatorDump::kUnitsBytes, |
- it.second.allocated_size_in_bytes); |
+ count_and_size.allocated_size_in_bytes); |
mad->AddScalar("resident_size", MemoryAllocatorDump::kUnitsBytes, |
- it.second.resident_size_in_bytes); |
+ count_and_size.resident_size_in_bytes); |
mad->AddScalar(MemoryAllocatorDump::kNameObjectCount, |
- MemoryAllocatorDump::kUnitsObjects, it.second.count); |
+ MemoryAllocatorDump::kUnitsObjects, count_and_size.count); |
} |
} |