// 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 "gin/v8_isolate_memory_dump_provider.h"

#include <memory>

#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "gin/public/isolate_holder.h"
#include "gin/test/v8_test.h"

namespace gin {

typedef V8Test V8MemoryDumpProviderTest;

class V8MemoryDumpProviderWorkerTest : public V8MemoryDumpProviderTest {
 protected:
  std::unique_ptr<IsolateHolder> CreateIsolateHolder() const override {
    return std::make_unique<gin::IsolateHolder>(
        base::ThreadTaskRunnerHandle::Get(),
        gin::IsolateHolder::IsolateType::kBlinkWorkerThread);
  }
};

// Checks if the dump provider runs without crashing and dumps root objects.
TEST_F(V8MemoryDumpProviderTest, DumpStatistics) {
  // Sets the track objects flag for dumping object statistics. Since this is
  // not set before V8::InitializePlatform the sizes will not be accurate, but
  // this serves the purpose of this test.
  const char track_objects_flag[] = "--track-gc-object-stats";
  v8::V8::SetFlagsFromString(track_objects_flag,
                             static_cast<int>(strlen(track_objects_flag)));

  base::trace_event::MemoryDumpArgs dump_args = {
      base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
  std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
      new base::trace_event::ProcessMemoryDump(dump_args));
  instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
      dump_args, process_memory_dump.get());
  const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
      allocator_dumps = process_memory_dump->allocator_dumps();

  bool did_dump_isolate_stats = false;
  bool did_dump_space_stats = false;
  bool did_dump_objects_stats = false;
  for (const auto& name_dump : allocator_dumps) {
    const std::string& name = name_dump.first;
    if (name.find("v8/main") != std::string::npos) {
      did_dump_isolate_stats = true;
    }
    if (name.find("v8/main/heap") != std::string::npos) {
      did_dump_space_stats = true;
    }
    if (name.find("v8/main/heap_objects") != std::string::npos) {
      did_dump_objects_stats = true;
    }
  }

  ASSERT_TRUE(did_dump_isolate_stats);
  ASSERT_TRUE(did_dump_space_stats);
  ASSERT_TRUE(did_dump_objects_stats);
}

TEST_F(V8MemoryDumpProviderTest, DumpContextStatistics) {
  base::trace_event::MemoryDumpArgs dump_args = {
      base::trace_event::MemoryDumpLevelOfDetail::LIGHT};
  std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
      new base::trace_event::ProcessMemoryDump(dump_args));
  instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
      dump_args, process_memory_dump.get());
  const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
      allocator_dumps = process_memory_dump->allocator_dumps();

  bool did_dump_detached_contexts = false;
  bool did_dump_native_contexts = false;
  for (const auto& name_dump : allocator_dumps) {
    const std::string& name = name_dump.first;
    if (name.find("main/contexts/detached_context") != std::string::npos) {
      did_dump_detached_contexts = true;
    }
    if (name.find("main/contexts/native_context") != std::string::npos) {
      did_dump_native_contexts = true;
    }
  }

  ASSERT_TRUE(did_dump_detached_contexts);
  ASSERT_TRUE(did_dump_native_contexts);
}

TEST_F(V8MemoryDumpProviderWorkerTest, DumpContextStatistics) {
  base::trace_event::MemoryDumpArgs dump_args = {
      base::trace_event::MemoryDumpLevelOfDetail::LIGHT};
  std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
      new base::trace_event::ProcessMemoryDump(dump_args));
  instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
      dump_args, process_memory_dump.get());
  const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
      allocator_dumps = process_memory_dump->allocator_dumps();

  bool did_dump_detached_contexts = false;
  bool did_dump_native_contexts = false;
  for (const auto& name_dump : allocator_dumps) {
    const std::string& name = name_dump.first;
    if (name.find("workers/contexts/detached_context/isolate_0x") !=
        std::string::npos) {
      did_dump_detached_contexts = true;
    }
    if (name.find("workers/contexts/native_context/isolate_0x") !=
        std::string::npos) {
      did_dump_native_contexts = true;
    }
  }

  ASSERT_TRUE(did_dump_detached_contexts);
  ASSERT_TRUE(did_dump_native_contexts);
}

TEST_F(V8MemoryDumpProviderTest, DumpCodeStatistics) {
  // Code stats are disabled unless this category is enabled.
  base::trace_event::TraceLog::GetInstance()->SetEnabled(
      base::trace_event::TraceConfig(
          TRACE_DISABLED_BY_DEFAULT("memory-infra.v8.code_stats"), ""),
      base::trace_event::TraceLog::RECORDING_MODE);

  base::trace_event::MemoryDumpArgs dump_args = {
      base::trace_event::MemoryDumpLevelOfDetail::LIGHT};
  std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump(
      new base::trace_event::ProcessMemoryDump(dump_args));
  instance_->isolate_memory_dump_provider_for_testing()->OnMemoryDump(
      dump_args, process_memory_dump.get());
  const base::trace_event::ProcessMemoryDump::AllocatorDumpsMap&
      allocator_dumps = process_memory_dump->allocator_dumps();

  bool did_dump_bytecode_size = false;
  bool did_dump_code_size = false;
  bool did_dump_external_scripts_size = false;

  for (const auto& name_dump : allocator_dumps) {
    const std::string& name = name_dump.first;
    if (name.find("code_stats") != std::string::npos) {
      for (const base::trace_event::MemoryAllocatorDump::Entry& entry :
           name_dump.second->entries()) {
        if (entry.name == "bytecode_and_metadata_size") {
          did_dump_bytecode_size = true;
        } else if (entry.name == "code_and_metadata_size") {
          did_dump_code_size = true;
        } else if (entry.name == "external_script_source_size") {
          did_dump_external_scripts_size = true;
        }
      }
    }
  }
  base::trace_event::TraceLog::GetInstance()->SetDisabled();

  ASSERT_TRUE(did_dump_bytecode_size);
  ASSERT_TRUE(did_dump_code_size);
  ASSERT_TRUE(did_dump_external_scripts_size);
}

}  // namespace gin
