// 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::kFrameMetrics:
      return "FrameMetrics";
    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);
  }
}

#if !defined(STARBOARD)
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);
  }
}
#endif

}  // namespace trace_event
}  // namespace base
