// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/trace_event/trace_event_memory_overhead.h"

#include <algorithm>

#include "base/bits.h"
#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 {

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";
}

}  // namespace

TraceEventMemoryOverhead::TraceEventMemoryOverhead() : allocated_objects_() {}

TraceEventMemoryOverhead::~TraceEventMemoryOverhead() = default;

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(ObjectType object_type,
                                   size_t allocated_size_in_bytes) {
  Add(object_type, allocated_size_in_bytes, allocated_size_in_bytes);
}

void TraceEventMemoryOverhead::Add(ObjectType object_type,
                                   size_t allocated_size_in_bytes,
                                   size_t resident_size_in_bytes) {
  AddInternal(object_type, 1, allocated_size_in_bytes, resident_size_in_bytes);
}

void TraceEventMemoryOverhead::AddString(const std::string& str) {
  Add(kStdString, EstimateMemoryUsage(str));
}

void TraceEventMemoryOverhead::AddRefCountedString(
    const RefCountedString& str) {
  Add(kOther, sizeof(RefCountedString));
  AddString(str.data());
}

void TraceEventMemoryOverhead::AddValue(const Value& value) {
  switch (value.type()) {
    case Value::Type::NONE:
    case Value::Type::BOOLEAN:
    case Value::Type::INTEGER:
    case Value::Type::DOUBLE:
      Add(kBaseValue, sizeof(Value));
      break;

    case Value::Type::STRING: {
      const Value* string_value = nullptr;
      value.GetAsString(&string_value);
      Add(kBaseValue, sizeof(Value));
      AddString(string_value->GetString());
    } break;

    case Value::Type::BINARY: {
      Add(kBaseValue, sizeof(Value) + value.GetBlob().size());
    } break;

    case Value::Type::DICTIONARY: {
      const DictionaryValue* dictionary_value = nullptr;
      value.GetAsDictionary(&dictionary_value);
      Add(kBaseValue, sizeof(DictionaryValue));
      for (DictionaryValue::Iterator it(*dictionary_value); !it.IsAtEnd();
           it.Advance()) {
        AddString(it.key());
        AddValue(it.value());
      }
    } break;

    case Value::Type::LIST: {
      const ListValue* list_value = nullptr;
      value.GetAsList(&list_value);
      Add(kBaseValue, sizeof(ListValue));
      for (const auto& v : *list_value)
        AddValue(v);
    } break;

    default:
      NOTREACHED();
  }
}

void TraceEventMemoryOverhead::AddSelf() {
  Add(kTraceEventMemoryOverhead, sizeof(*this));
}

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 (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 (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,
                   count_and_size.allocated_size_in_bytes);
    mad->AddScalar("resident_size", MemoryAllocatorDump::kUnitsBytes,
                   count_and_size.resident_size_in_bytes);
    mad->AddScalar(MemoryAllocatorDump::kNameObjectCount,
                   MemoryAllocatorDump::kUnitsObjects, count_and_size.count);
  }
}

}  // namespace trace_event
}  // namespace base
