// Copyright (c) 2012 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 "chrome/common/profiling.h"

#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/debug/profiler.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/threading/thread.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/common/content_switches.h"
#include "gin/public/debug.h"
#include "v8/include/v8.h"

namespace {

base::debug::AddDynamicSymbol add_dynamic_symbol_func = NULL;
base::debug::MoveDynamicSymbol move_dynamic_symbol_func = NULL;

void JitCodeEventHandler(const v8::JitCodeEvent* event) {
  DCHECK_NE(static_cast<base::debug::AddDynamicSymbol>(NULL),
            add_dynamic_symbol_func);
  DCHECK_NE(static_cast<base::debug::MoveDynamicSymbol>(NULL),
            move_dynamic_symbol_func);

  switch (event->type) {
    case v8::JitCodeEvent::CODE_ADDED:
      add_dynamic_symbol_func(event->code_start, event->code_len,
                              event->name.str, event->name.len);
      break;

    case v8::JitCodeEvent::CODE_MOVED:
      move_dynamic_symbol_func(event->code_start, event->new_code_start);
      break;

    default:
      break;
  }
}

std::string GetProfileName() {
  static const char kDefaultProfileName[] = "chrome-profile-{type}-{pid}";
  CR_DEFINE_STATIC_LOCAL(std::string, profile_name, ());

  if (profile_name.empty()) {
    const base::CommandLine& command_line =
        *base::CommandLine::ForCurrentProcess();
    if (command_line.HasSwitch(switches::kProfilingFile))
      profile_name = command_line.GetSwitchValueASCII(switches::kProfilingFile);
    else
      profile_name = std::string(kDefaultProfileName);
    std::string process_type =
        command_line.GetSwitchValueASCII(switches::kProcessType);
    std::string type = process_type.empty() ?
        std::string("browser") : std::string(process_type);
    base::ReplaceSubstringsAfterOffset(&profile_name, 0, "{type}", type);
  }
  return profile_name;
}

void FlushProfilingData(base::Thread* thread) {
  static const int kProfilingFlushSeconds = 10;

  if (!Profiling::BeingProfiled())
    return;

  base::debug::FlushProfiling();
  static int flush_seconds;
  if (!flush_seconds) {
    const base::CommandLine& command_line =
        *base::CommandLine::ForCurrentProcess();
    std::string profiling_flush =
        command_line.GetSwitchValueASCII(switches::kProfilingFlush);
    if (!profiling_flush.empty()) {
      flush_seconds = atoi(profiling_flush.c_str());
      DCHECK(flush_seconds > 0);
    } else {
      flush_seconds = kProfilingFlushSeconds;
    }
  }
  thread->task_runner()->PostDelayedTask(
      FROM_HERE, base::Bind(&FlushProfilingData, thread),
      base::TimeDelta::FromSeconds(flush_seconds));
}

class ProfilingThreadControl {
 public:
  ProfilingThreadControl() : thread_(NULL) {}

  void Start() {
    base::AutoLock locked(lock_);

    if (thread_ && thread_->IsRunning())
      return;
    thread_ = new base::Thread("Profiling_Flush");
    thread_->Start();
    thread_->task_runner()->PostTask(FROM_HERE,
                                     base::Bind(&FlushProfilingData, thread_));
  }

  void Stop() {
    base::AutoLock locked(lock_);

    if (!thread_ || !thread_->IsRunning())
      return;
    thread_->Stop();
    delete thread_;
    thread_ = NULL;
  }

 private:
  base::Thread* thread_;
  base::Lock lock_;

  DISALLOW_COPY_AND_ASSIGN(ProfilingThreadControl);
};

base::LazyInstance<ProfilingThreadControl>::Leaky
    g_flush_thread_control = LAZY_INSTANCE_INITIALIZER;

} // namespace

// static
void Profiling::ProcessStarted() {
  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();
  std::string process_type =
      command_line.GetSwitchValueASCII(switches::kProcessType);

  // Establish the V8 profiling hooks if we're an instrumented binary.
  if (base::debug::IsBinaryInstrumented()) {
    base::debug::ReturnAddressLocationResolver resolve_func =
        base::debug::GetProfilerReturnAddrResolutionFunc();

    if (resolve_func != NULL) {
      v8::V8::SetReturnAddressLocationResolver(resolve_func);
    }

    // Set up the JIT code entry handler and the symbol callbacks if the
    // profiler supplies them.
    // TODO(siggi): Maybe add a switch or an environment variable to turn off
    //     V8 profiling?
    base::debug::DynamicFunctionEntryHook entry_hook_func =
        base::debug::GetProfilerDynamicFunctionEntryHookFunc();
    add_dynamic_symbol_func = base::debug::GetProfilerAddDynamicSymbolFunc();
    move_dynamic_symbol_func = base::debug::GetProfilerMoveDynamicSymbolFunc();

    if (entry_hook_func != NULL &&
        add_dynamic_symbol_func != NULL &&
        move_dynamic_symbol_func != NULL) {
      gin::Debug::SetFunctionEntryHook(entry_hook_func);
      gin::Debug::SetJitCodeEventHandler(&JitCodeEventHandler);
    }
  }

  if (command_line.HasSwitch(switches::kProfilingAtStart)) {
    std::string process_type_to_start =
        command_line.GetSwitchValueASCII(switches::kProfilingAtStart);
    if (process_type == process_type_to_start)
      Start();
  }
}

// static
void Profiling::Start() {
  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();
  bool flush = command_line.HasSwitch(switches::kProfilingFlush);
  base::debug::StartProfiling(GetProfileName());

  // Schedule profile data flushing for single process because it doesn't
  // get written out correctly on exit.
  if (flush)
    g_flush_thread_control.Get().Start();
}

// static
void Profiling::Stop() {
  g_flush_thread_control.Get().Stop();
  base::debug::StopProfiling();
}

// static
bool Profiling::BeingProfiled() {
  return base::debug::BeingProfiled();
}

// static
void Profiling::Toggle() {
  if (BeingProfiled())
    Stop();
  else
    Start();
}
