// Copyright 2016 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/debug/thread_heap_usage_tracker.h"

#include <algorithm>
#include <limits>
#include <new>
#include <type_traits>

#include "starboard/types.h"

#include "starboard/memory.h"

#include "base/allocator/allocator_shim.h"
#include "base/allocator/buildflags.h"
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/threading/thread_local_storage.h"
#include "build/build_config.h"

#if !defined(STARBOARD)
#if defined(OS_MACOSX) || defined(OS_IOS)
#include <malloc/malloc.h>
#else
#include <malloc.h>
#endif
#endif

namespace base {
namespace debug {

namespace {

using base::allocator::AllocatorDispatch;

const uintptr_t kSentinelMask = std::numeric_limits<uintptr_t>::max() - 1;
ThreadHeapUsage* const kInitializationSentinel =
    reinterpret_cast<ThreadHeapUsage*>(kSentinelMask);
ThreadHeapUsage* const kTeardownSentinel =
    reinterpret_cast<ThreadHeapUsage*>(kSentinelMask | 1);

ThreadLocalStorage::Slot& ThreadAllocationUsage() {
  static NoDestructor<ThreadLocalStorage::Slot> thread_allocator_usage(
      [](void* thread_heap_usage) {
        // This destructor will be called twice. Once to destroy the actual
        // ThreadHeapUsage instance and a second time, immediately after, for
        // the sentinel. Re-setting the TLS slow (below) does re-initialize the
        // TLS slot. The ThreadLocalStorage code is designed to deal with this
        // use case and will re-call the destructor with the kTeardownSentinel
        // as arg.
        if (thread_heap_usage == kTeardownSentinel)
          return;
        DCHECK_NE(thread_heap_usage, kInitializationSentinel);

        // Deleting the ThreadHeapUsage TLS object will re-enter the shim and
        // hit RecordFree() (see below). The sentinel prevents RecordFree() from
        // re-creating another ThreadHeapUsage object.
        ThreadAllocationUsage().Set(kTeardownSentinel);
        delete static_cast<ThreadHeapUsage*>(thread_heap_usage);
      });
  return *thread_allocator_usage;
}

bool g_heap_tracking_enabled = false;

// Forward declared as it needs to delegate memory allocation to the next
// lower shim.
ThreadHeapUsage* GetOrCreateThreadUsage();

size_t GetAllocSizeEstimate(const AllocatorDispatch* next,
                            void* ptr,
                            void* context) {
  if (ptr == nullptr)
    return 0U;

  return next->get_size_estimate_function(next, ptr, context);
}

void RecordAlloc(const AllocatorDispatch* next,
                 void* ptr,
                 size_t size,
                 void* context) {
  ThreadHeapUsage* usage = GetOrCreateThreadUsage();
  if (usage == nullptr)
    return;

  usage->alloc_ops++;
  size_t estimate = GetAllocSizeEstimate(next, ptr, context);
  if (size && estimate) {
    // Only keep track of the net number of bytes allocated in the scope if the
    // size estimate function returns sane values, e.g. non-zero.
    usage->alloc_bytes += estimate;
    usage->alloc_overhead_bytes += estimate - size;

    // Record the max outstanding number of bytes, but only if the difference
    // is net positive (e.g. more bytes allocated than freed in the scope).
    if (usage->alloc_bytes > usage->free_bytes) {
      uint64_t allocated_bytes = usage->alloc_bytes - usage->free_bytes;
      if (allocated_bytes > usage->max_allocated_bytes)
        usage->max_allocated_bytes = allocated_bytes;
    }
  } else {
    usage->alloc_bytes += size;
  }
}

void RecordFree(const AllocatorDispatch* next, void* ptr, void* context) {
  ThreadHeapUsage* usage = GetOrCreateThreadUsage();
  if (usage == nullptr)
    return;

  size_t estimate = GetAllocSizeEstimate(next, ptr, context);
  usage->free_ops++;
  usage->free_bytes += estimate;
}

void* AllocFn(const AllocatorDispatch* self, size_t size, void* context) {
  void* ret = self->next->alloc_function(self->next, size, context);
  if (ret != nullptr)
    RecordAlloc(self->next, ret, size, context);

  return ret;
}

void* AllocZeroInitializedFn(const AllocatorDispatch* self,
                             size_t n,
                             size_t size,
                             void* context) {
  void* ret =
      self->next->alloc_zero_initialized_function(self->next, n, size, context);
  if (ret != nullptr)
    RecordAlloc(self->next, ret, size, context);

  return ret;
}

void* AllocAlignedFn(const AllocatorDispatch* self,
                     size_t alignment,
                     size_t size,
                     void* context) {
  void* ret =
      self->next->alloc_aligned_function(self->next, alignment, size, context);
  if (ret != nullptr)
    RecordAlloc(self->next, ret, size, context);

  return ret;
}

void* ReallocFn(const AllocatorDispatch* self,
                void* address,
                size_t size,
                void* context) {
  if (address != nullptr)
    RecordFree(self->next, address, context);

  void* ret = self->next->realloc_function(self->next, address, size, context);
  if (ret != nullptr && size != 0)
    RecordAlloc(self->next, ret, size, context);

  return ret;
}

void FreeFn(const AllocatorDispatch* self, void* address, void* context) {
  if (address != nullptr)
    RecordFree(self->next, address, context);
  self->next->free_function(self->next, address, context);
}

size_t GetSizeEstimateFn(const AllocatorDispatch* self,
                         void* address,
                         void* context) {
  return self->next->get_size_estimate_function(self->next, address, context);
}

unsigned BatchMallocFn(const AllocatorDispatch* self,
                       size_t size,
                       void** results,
                       unsigned num_requested,
                       void* context) {
  unsigned count = self->next->batch_malloc_function(self->next, size, results,
                                                     num_requested, context);
  for (unsigned i = 0; i < count; ++i) {
    RecordAlloc(self->next, results[i], size, context);
  }
  return count;
}

void BatchFreeFn(const AllocatorDispatch* self,
                 void** to_be_freed,
                 unsigned num_to_be_freed,
                 void* context) {
  for (unsigned i = 0; i < num_to_be_freed; ++i) {
    if (to_be_freed[i] != nullptr) {
      RecordFree(self->next, to_be_freed[i], context);
    }
  }
  self->next->batch_free_function(self->next, to_be_freed, num_to_be_freed,
                                  context);
}

void FreeDefiniteSizeFn(const AllocatorDispatch* self,
                        void* ptr,
                        size_t size,
                        void* context) {
  if (ptr != nullptr)
    RecordFree(self->next, ptr, context);
  self->next->free_definite_size_function(self->next, ptr, size, context);
}

// The allocator dispatch used to intercept heap operations.
AllocatorDispatch allocator_dispatch = {&AllocFn,
                                        &AllocZeroInitializedFn,
                                        &AllocAlignedFn,
                                        &ReallocFn,
                                        &FreeFn,
                                        &GetSizeEstimateFn,
                                        &BatchMallocFn,
                                        &BatchFreeFn,
                                        &FreeDefiniteSizeFn,
                                        nullptr};

ThreadHeapUsage* GetOrCreateThreadUsage() {
  auto tls_ptr = reinterpret_cast<uintptr_t>(ThreadAllocationUsage().Get());
  if ((tls_ptr & kSentinelMask) == kSentinelMask)
    return nullptr;  // Re-entrancy case.

  auto* allocator_usage = reinterpret_cast<ThreadHeapUsage*>(tls_ptr);
  if (allocator_usage == nullptr) {
    // Prevent reentrancy due to the allocation below.
    ThreadAllocationUsage().Set(kInitializationSentinel);

    allocator_usage = new ThreadHeapUsage();
    static_assert(std::is_pod<ThreadHeapUsage>::value,
                  "AllocatorDispatch must be POD");
    SbMemorySet(allocator_usage, 0, sizeof(*allocator_usage));
    ThreadAllocationUsage().Set(allocator_usage);
  }

  return allocator_usage;
}

}  // namespace

ThreadHeapUsageTracker::ThreadHeapUsageTracker() : thread_usage_(nullptr) {
  static_assert(std::is_pod<ThreadHeapUsage>::value, "Must be POD.");
}

ThreadHeapUsageTracker::~ThreadHeapUsageTracker() {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (thread_usage_ != nullptr) {
    // If this tracker wasn't stopped, make it inclusive so that the
    // usage isn't lost.
    Stop(false);
  }
}

void ThreadHeapUsageTracker::Start() {
  DCHECK(thread_checker_.CalledOnValidThread());

  thread_usage_ = GetOrCreateThreadUsage();
  usage_ = *thread_usage_;

  // Reset the stats for our current scope.
  // The per-thread usage instance now tracks this scope's usage, while this
  // instance persists the outer scope's usage stats. On destruction, this
  // instance will restore the outer scope's usage stats with this scope's
  // usage added.
  SbMemorySet(thread_usage_, 0, sizeof(*thread_usage_));
}

void ThreadHeapUsageTracker::Stop(bool usage_is_exclusive) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK_NE(nullptr, thread_usage_);

  ThreadHeapUsage current = *thread_usage_;
  if (usage_is_exclusive) {
    // Restore the outer scope.
    *thread_usage_ = usage_;
  } else {
    // Update the outer scope with the accrued inner usage.
    if (thread_usage_->max_allocated_bytes) {
      uint64_t outer_net_alloc_bytes = usage_.alloc_bytes - usage_.free_bytes;

      thread_usage_->max_allocated_bytes =
          std::max(usage_.max_allocated_bytes,
                   outer_net_alloc_bytes + thread_usage_->max_allocated_bytes);
    }

    thread_usage_->alloc_ops += usage_.alloc_ops;
    thread_usage_->alloc_bytes += usage_.alloc_bytes;
    thread_usage_->alloc_overhead_bytes += usage_.alloc_overhead_bytes;
    thread_usage_->free_ops += usage_.free_ops;
    thread_usage_->free_bytes += usage_.free_bytes;
  }

  thread_usage_ = nullptr;
  usage_ = current;
}

ThreadHeapUsage ThreadHeapUsageTracker::GetUsageSnapshot() {
  ThreadHeapUsage* usage = GetOrCreateThreadUsage();
  DCHECK_NE(nullptr, usage);
  return *usage;
}

void ThreadHeapUsageTracker::EnableHeapTracking() {
  EnsureTLSInitialized();

  CHECK_EQ(false, g_heap_tracking_enabled) << "No double-enabling.";
  g_heap_tracking_enabled = true;
#if BUILDFLAG(USE_ALLOCATOR_SHIM)
  base::allocator::InsertAllocatorDispatch(&allocator_dispatch);
#else
  CHECK(false) << "Can't enable heap tracking without the shim.";
#endif  // BUILDFLAG(USE_ALLOCATOR_SHIM)
}

bool ThreadHeapUsageTracker::IsHeapTrackingEnabled() {
  return g_heap_tracking_enabled;
}

void ThreadHeapUsageTracker::DisableHeapTrackingForTesting() {
#if BUILDFLAG(USE_ALLOCATOR_SHIM)
  base::allocator::RemoveAllocatorDispatchForTesting(&allocator_dispatch);
#else
  CHECK(false) << "Can't disable heap tracking without the shim.";
#endif  // BUILDFLAG(USE_ALLOCATOR_SHIM)
  DCHECK_EQ(true, g_heap_tracking_enabled) << "Heap tracking not enabled.";
  g_heap_tracking_enabled = false;
}

base::allocator::AllocatorDispatch*
ThreadHeapUsageTracker::GetDispatchForTesting() {
  return &allocator_dispatch;
}

void ThreadHeapUsageTracker::EnsureTLSInitialized() {
  ignore_result(ThreadAllocationUsage());
}

}  // namespace debug
}  // namespace base
