| Index: base/trace_event/memory_allocator_dump.cc | 
| diff --git a/base/trace_event/memory_allocator_dump.cc b/base/trace_event/memory_allocator_dump.cc | 
| index 5d11bb006e8b0aecdcffdfbdfd7d531e6b88e75a..4037f946c9ef046e678ff261af270792a631d67b 100644 | 
| --- a/base/trace_event/memory_allocator_dump.cc | 
| +++ b/base/trace_event/memory_allocator_dump.cc | 
| @@ -15,28 +15,7 @@ | 
| namespace base { | 
| namespace trace_event { | 
|  | 
| -namespace { | 
| -// Returns the c-string pointer from a dictionary value without performing extra | 
| -// std::string copies. The ptr will be valid as long as the value exists. | 
| -bool GetDictionaryValueAsCStr(const DictionaryValue* dict_value, | 
| -                              const std::string& key, | 
| -                              const char** out_cstr) { | 
| -  const Value* value = nullptr; | 
| -  const StringValue* str_value = nullptr; | 
| -  if (!dict_value->GetWithoutPathExpansion(key, &value)) | 
| -    return false; | 
| -  if (!value->GetAsString(&str_value)) | 
| -    return false; | 
| -  *out_cstr = str_value->GetString().c_str(); | 
| -  return true; | 
| -} | 
| -}  // namespace | 
| - | 
| -// TODO(primiano): remove kName{Inner,Outer}Size below after all the existing | 
| -// dump providers have been rewritten. | 
| const char MemoryAllocatorDump::kNameSize[] = "size"; | 
| -const char MemoryAllocatorDump::kNameInnerSize[] = "inner_size"; | 
| -const char MemoryAllocatorDump::kNameOuterSize[] = "outer_size"; | 
| const char MemoryAllocatorDump::kNameObjectsCount[] = "objects_count"; | 
| const char MemoryAllocatorDump::kTypeScalar[] = "scalar"; | 
| const char MemoryAllocatorDump::kTypeString[] = "string"; | 
| @@ -48,6 +27,7 @@ MemoryAllocatorDump::MemoryAllocatorDump(const std::string& absolute_name, | 
| const MemoryAllocatorDumpGuid& guid) | 
| : absolute_name_(absolute_name), | 
| process_memory_dump_(process_memory_dump), | 
| +      attributes_(new TracedValue), | 
| guid_(guid) { | 
| // The |absolute_name| cannot be empty. | 
| DCHECK(!absolute_name.empty()); | 
| @@ -73,73 +53,47 @@ MemoryAllocatorDump::MemoryAllocatorDump(const std::string& absolute_name, | 
| "%d:%s", | 
| TraceLog::GetInstance()->process_id(), | 
| absolute_name.c_str()))) { | 
| +  string_conversion_buffer_.reserve(16); | 
| } | 
|  | 
| MemoryAllocatorDump::~MemoryAllocatorDump() { | 
| } | 
|  | 
| -void MemoryAllocatorDump::Add(const std::string& name, | 
| -                              const char* type, | 
| -                              const char* units, | 
| -                              scoped_ptr<Value> value) { | 
| -  scoped_ptr<DictionaryValue> attribute(new DictionaryValue()); | 
| -  DCHECK(!attributes_.HasKey(name)); | 
| -  attribute->SetStringWithoutPathExpansion("type", type); | 
| -  attribute->SetStringWithoutPathExpansion("units", units); | 
| -  attribute->SetWithoutPathExpansion("value", value.Pass()); | 
| -  attributes_.SetWithoutPathExpansion(name, attribute.Pass()); | 
| -} | 
| - | 
| -bool MemoryAllocatorDump::Get(const std::string& name, | 
| -                              const char** out_type, | 
| -                              const char** out_units, | 
| -                              const Value** out_value) const { | 
| -  const DictionaryValue* attribute = nullptr; | 
| -  if (!attributes_.GetDictionaryWithoutPathExpansion(name, &attribute)) | 
| -    return false; | 
| - | 
| -  if (!GetDictionaryValueAsCStr(attribute, "type", out_type)) | 
| -    return false; | 
| - | 
| -  if (!GetDictionaryValueAsCStr(attribute, "units", out_units)) | 
| -    return false; | 
| - | 
| -  if (!attribute->GetWithoutPathExpansion("value", out_value)) | 
| -    return false; | 
| - | 
| -  return true; | 
| -} | 
| - | 
| -void MemoryAllocatorDump::AddScalar(const std::string& name, | 
| +void MemoryAllocatorDump::AddScalar(const char* name, | 
| const char* units, | 
| uint64 value) { | 
| -  scoped_ptr<Value> hex_value(new StringValue(StringPrintf("%" PRIx64, value))); | 
| -  Add(name, kTypeScalar, units, hex_value.Pass()); | 
| +  SStringPrintf(&string_conversion_buffer_, "%" PRIx64, value); | 
| +  attributes_->BeginDictionary(name); | 
| +  attributes_->SetString("type", kTypeScalar); | 
| +  attributes_->SetString("units", units); | 
| +  attributes_->SetString("value", string_conversion_buffer_); | 
| +  attributes_->EndDictionary(); | 
| } | 
|  | 
| -void MemoryAllocatorDump::AddScalarF(const std::string& name, | 
| +void MemoryAllocatorDump::AddScalarF(const char* name, | 
| const char* units, | 
| double value) { | 
| -  Add(name, kTypeScalar, units, make_scoped_ptr(new FundamentalValue(value))); | 
| +  attributes_->BeginDictionary(name); | 
| +  attributes_->SetString("type", kTypeScalar); | 
| +  attributes_->SetString("units", units); | 
| +  attributes_->SetDouble("value", value); | 
| +  attributes_->EndDictionary(); | 
| } | 
|  | 
| -void MemoryAllocatorDump::AddString(const std::string& name, | 
| +void MemoryAllocatorDump::AddString(const char* name, | 
| const char* units, | 
| const std::string& value) { | 
| -  scoped_ptr<Value> str_value(new StringValue(value)); | 
| -  Add(name, kTypeString, units, str_value.Pass()); | 
| +  attributes_->BeginDictionary(name); | 
| +  attributes_->SetString("type", kTypeString); | 
| +  attributes_->SetString("units", units); | 
| +  attributes_->SetString("value", value); | 
| +  attributes_->EndDictionary(); | 
| } | 
|  | 
| void MemoryAllocatorDump::AsValueInto(TracedValue* value) const { | 
| -  value->BeginDictionary(absolute_name_.c_str()); | 
| +  value->BeginDictionaryWithCopiedName(absolute_name_); | 
| value->SetString("guid", guid_.ToString()); | 
| - | 
| -  value->BeginDictionary("attrs"); | 
| - | 
| -  for (DictionaryValue::Iterator it(attributes_); !it.IsAtEnd(); it.Advance()) | 
| -    value->SetValue(it.key().c_str(), it.value().CreateDeepCopy()); | 
| - | 
| -  value->EndDictionary();  // "attrs": { ... } | 
| +  value->SetValue("attrs", *attributes_); | 
| value->EndDictionary();  // "allocator_name/heap_subheap": { ... } | 
| } | 
|  | 
|  |