// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"

#if defined(DART_USE_TCMALLOC) && !defined(PRODUCT) &&                         \
    !defined(TARGET_ARCH_DBC) && !defined(TARGET_OS_FUCHSIA)

#include "platform/assert.h"
#include "vm/globals.h"
#include "vm/malloc_hooks.h"
#include "vm/os.h"
#include "vm/profiler.h"
#include "vm/profiler_service.h"
#include "vm/unit_test.h"

namespace dart {

static void MallocHookTestBufferInitializer(volatile char* buffer,
                                            uintptr_t size) {
  // Run through the buffer and do something. If we don't do this and the memory
  // in buffer isn't touched, the tcmalloc hooks won't be called.
  for (uintptr_t i = 0; i < size; ++i) {
    buffer[i] = i;
  }
}


UNIT_TEST_CASE(BasicMallocHookTest) {
  bool enable_malloc_hooks_saved = FLAG_enable_malloc_hooks;
  FLAG_enable_malloc_hooks = true;

  MallocHooks::InitOnce();
  MallocHooks::ResetStats();
  EXPECT_EQ(0L, MallocHooks::allocation_count());
  EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes());
  const intptr_t buffer_size = 10;
  char* buffer = new char[buffer_size];
  MallocHookTestBufferInitializer(buffer, buffer_size);

  EXPECT_EQ(1L, MallocHooks::allocation_count());
  EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size),
            MallocHooks::heap_allocated_memory_in_bytes());

  delete[] buffer;
  EXPECT_EQ(0L, MallocHooks::allocation_count());
  EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes());
  MallocHooks::TearDown();

  FLAG_enable_malloc_hooks = enable_malloc_hooks_saved;
}


UNIT_TEST_CASE(FreeUnseenMemoryMallocHookTest) {
  bool enable_malloc_hooks_saved = FLAG_enable_malloc_hooks;
  FLAG_enable_malloc_hooks = true;

  MallocHooks::InitOnce();
  const intptr_t pre_hook_buffer_size = 3;
  char* pre_hook_buffer = new char[pre_hook_buffer_size];
  MallocHookTestBufferInitializer(pre_hook_buffer, pre_hook_buffer_size);

  MallocHooks::ResetStats();
  EXPECT_EQ(0L, MallocHooks::allocation_count());
  EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes());

  const intptr_t buffer_size = 10;
  char* buffer = new char[buffer_size];
  MallocHookTestBufferInitializer(buffer, buffer_size);

  EXPECT_EQ(1L, MallocHooks::allocation_count());
  EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size),
            MallocHooks::heap_allocated_memory_in_bytes());

  delete[] pre_hook_buffer;
  EXPECT_EQ(1L, MallocHooks::allocation_count());
  EXPECT_EQ(static_cast<intptr_t>(sizeof(char) * buffer_size),
            MallocHooks::heap_allocated_memory_in_bytes());


  delete[] buffer;
  EXPECT_EQ(0L, MallocHooks::allocation_count());
  EXPECT_EQ(0L, MallocHooks::heap_allocated_memory_in_bytes());
  MallocHooks::TearDown();

  FLAG_enable_malloc_hooks = enable_malloc_hooks_saved;
}


VM_UNIT_TEST_CASE(StackTraceMallocHookSimpleTest) {
  bool enable_malloc_hooks_saved = FLAG_enable_malloc_hooks;
  FLAG_enable_malloc_hooks = true;

  MallocHooks::InitOnce();
  MallocHooks::ResetStats();

  bool enable_stack_traces_saved =
      MallocHooks::stack_trace_collection_enabled();
  MallocHooks::set_stack_trace_collection_enabled(true);

  char* var = static_cast<char*>(malloc(16 * sizeof(char)));
  Sample* sample = MallocHooks::GetSample(var);
  EXPECT(sample != NULL);

  free(var);
  sample = MallocHooks::GetSample(var);
  EXPECT(sample == NULL);
  MallocHooks::TearDown();
  MallocHooks::set_stack_trace_collection_enabled(enable_stack_traces_saved);
  FLAG_enable_malloc_hooks = enable_malloc_hooks_saved;
}


static char* DART_NOINLINE StackTraceLengthHelper(uintptr_t* end_address) {
  char* var = static_cast<char*>(malloc(16 * sizeof(char)));
  *end_address = OS::GetProgramCounter();
  return var;
}


VM_UNIT_TEST_CASE(StackTraceMallocHookLengthTest) {
  bool enable_malloc_hooks_saved = FLAG_enable_malloc_hooks;
  FLAG_enable_malloc_hooks = true;

  uintptr_t test_start_address =
      reinterpret_cast<uintptr_t>(Dart_TestStackTraceMallocHookLengthTest);
  uintptr_t helper_start_address =
      reinterpret_cast<uintptr_t>(StackTraceLengthHelper);
  uintptr_t helper_end_address = 0;

  MallocHooks::InitOnce();
  MallocHooks::ResetStats();

  bool enable_stack_traces_saved =
      MallocHooks::stack_trace_collection_enabled();
  MallocHooks::set_stack_trace_collection_enabled(true);

  char* var = StackTraceLengthHelper(&helper_end_address);
  Sample* sample = MallocHooks::GetSample(var);
  EXPECT(sample != NULL);
  uintptr_t test_end_address = OS::GetProgramCounter();

  // Ensure that all stack frames are where we expect them to be in the sample.
  // If they aren't, the kSkipCount constant in malloc_hooks.cc is likely
  // incorrect.
  uword address = sample->At(0);
  bool first_result =
      (helper_start_address <= address) && (helper_end_address >= address);
  EXPECT(first_result);
  address = sample->At(1);
  bool second_result =
      (test_start_address <= address) && (test_end_address >= address);
  EXPECT(second_result);

  if (!(first_result && second_result)) {
    OS::PrintErr(
        "If this test is failing, it's likely that the value set for"
        "the number of frames to skip in malloc_hooks.cc is "
        "incorrect for this configuration/platform. This value can be"
        " found in malloc_hooks.cc in the AllocationInfo class, and "
        "is stored in the kSkipCount constant.");
  }

  free(var);
  MallocHooks::TearDown();
  MallocHooks::set_stack_trace_collection_enabled(enable_stack_traces_saved);
  FLAG_enable_malloc_hooks = enable_malloc_hooks_saved;
}


ISOLATE_UNIT_TEST_CASE(StackTraceMallocHookSimpleJSONTest) {
  bool enable_malloc_hooks_saved = FLAG_enable_malloc_hooks;
  FLAG_enable_malloc_hooks = true;

  MallocHooks::InitOnce();
  MallocHooks::ResetStats();

  bool enable_stack_traces_saved =
      MallocHooks::stack_trace_collection_enabled();
  MallocHooks::set_stack_trace_collection_enabled(true);

  ClearProfileVisitor cpv(Isolate::Current());
  Profiler::sample_buffer()->VisitSamples(&cpv);

  char* var = static_cast<char*>(malloc(16 * sizeof(char)));
  JSONStream js;
  ProfilerService::PrintNativeAllocationJSON(&js, Profile::kNoTags, -1, -1);
  const char* json = js.ToCString();

  // Check that all the stack frames from the current down to main are actually
  // present in the profile. This is just a simple sanity check to make sure
  // that the ProfileTrie has a representation of the stack trace collected when
  // var is allocated. More intense testing is already done in profiler_test.cc.
  EXPECT_SUBSTRING("\"dart::Dart_TestStackTraceMallocHookSimpleJSONTest()\"",
                   json);
  EXPECT_SUBSTRING("\"dart::TestCase::Run()\"", json);
  EXPECT_SUBSTRING("\"dart::TestCaseBase::RunTest()\"", json);
  EXPECT_SUBSTRING("\"main\"", json);

  free(var);
  MallocHooks::TearDown();
  MallocHooks::set_stack_trace_collection_enabled(enable_stack_traces_saved);
  FLAG_enable_malloc_hooks = enable_malloc_hooks_saved;
}

};  // namespace dart

#endif  // defined(DART_USE_TCMALLOC) && !defined(PRODUCT)
