// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "v8.h"

#include "cpu-profiler-inl.h"

#ifdef ENABLE_LOGGING_AND_PROFILING

#include "frames-inl.h"
#include "hashmap.h"
#include "log-inl.h"
#include "vm-state-inl.h"

#include "../include/v8-profiler.h"

namespace v8 {
namespace internal {

static const int kEventsBufferSize = 256*KB;
static const int kTickSamplesBufferChunkSize = 64*KB;
static const int kTickSamplesBufferChunksCount = 16;


ProfilerEventsProcessor::ProfilerEventsProcessor(Isolate* isolate,
                                                 ProfileGenerator* generator)
    : Thread(isolate, "v8:ProfEvntProc"),
      generator_(generator),
      running_(true),
      ticks_buffer_(sizeof(TickSampleEventRecord),
                    kTickSamplesBufferChunkSize,
                    kTickSamplesBufferChunksCount),
      enqueue_order_(0) {
}


void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag,
                                                  const char* prefix,
                                                  String* name,
                                                  Address start) {
  if (FilterOutCodeCreateEvent(tag)) return;
  CodeEventsContainer evt_rec;
  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
  rec->type = CodeEventRecord::CODE_CREATION;
  rec->order = ++enqueue_order_;
  rec->start = start;
  rec->entry = generator_->NewCodeEntry(tag, prefix, name);
  rec->size = 1;
  rec->shared = NULL;
  events_buffer_.Enqueue(evt_rec);
}


void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
                                              String* name,
                                              String* resource_name,
                                              int line_number,
                                              Address start,
                                              unsigned size,
                                              Address shared) {
  if (FilterOutCodeCreateEvent(tag)) return;
  CodeEventsContainer evt_rec;
  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
  rec->type = CodeEventRecord::CODE_CREATION;
  rec->order = ++enqueue_order_;
  rec->start = start;
  rec->entry = generator_->NewCodeEntry(tag, name, resource_name, line_number);
  rec->size = size;
  rec->shared = shared;
  events_buffer_.Enqueue(evt_rec);
}


void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
                                              const char* name,
                                              Address start,
                                              unsigned size) {
  if (FilterOutCodeCreateEvent(tag)) return;
  CodeEventsContainer evt_rec;
  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
  rec->type = CodeEventRecord::CODE_CREATION;
  rec->order = ++enqueue_order_;
  rec->start = start;
  rec->entry = generator_->NewCodeEntry(tag, name);
  rec->size = size;
  rec->shared = NULL;
  events_buffer_.Enqueue(evt_rec);
}


void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
                                              int args_count,
                                              Address start,
                                              unsigned size) {
  if (FilterOutCodeCreateEvent(tag)) return;
  CodeEventsContainer evt_rec;
  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
  rec->type = CodeEventRecord::CODE_CREATION;
  rec->order = ++enqueue_order_;
  rec->start = start;
  rec->entry = generator_->NewCodeEntry(tag, args_count);
  rec->size = size;
  rec->shared = NULL;
  events_buffer_.Enqueue(evt_rec);
}


void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) {
  CodeEventsContainer evt_rec;
  CodeMoveEventRecord* rec = &evt_rec.CodeMoveEventRecord_;
  rec->type = CodeEventRecord::CODE_MOVE;
  rec->order = ++enqueue_order_;
  rec->from = from;
  rec->to = to;
  events_buffer_.Enqueue(evt_rec);
}


void ProfilerEventsProcessor::CodeDeleteEvent(Address from) {
  CodeEventsContainer evt_rec;
  CodeDeleteEventRecord* rec = &evt_rec.CodeDeleteEventRecord_;
  rec->type = CodeEventRecord::CODE_DELETE;
  rec->order = ++enqueue_order_;
  rec->start = from;
  events_buffer_.Enqueue(evt_rec);
}


void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from,
                                                          Address to) {
  CodeEventsContainer evt_rec;
  SharedFunctionInfoMoveEventRecord* rec =
      &evt_rec.SharedFunctionInfoMoveEventRecord_;
  rec->type = CodeEventRecord::SHARED_FUNC_MOVE;
  rec->order = ++enqueue_order_;
  rec->from = from;
  rec->to = to;
  events_buffer_.Enqueue(evt_rec);
}


void ProfilerEventsProcessor::RegExpCodeCreateEvent(
    Logger::LogEventsAndTags tag,
    const char* prefix,
    String* name,
    Address start,
    unsigned size) {
  if (FilterOutCodeCreateEvent(tag)) return;
  CodeEventsContainer evt_rec;
  CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
  rec->type = CodeEventRecord::CODE_CREATION;
  rec->order = ++enqueue_order_;
  rec->start = start;
  rec->entry = generator_->NewCodeEntry(tag, prefix, name);
  rec->size = size;
  events_buffer_.Enqueue(evt_rec);
}


void ProfilerEventsProcessor::AddCurrentStack() {
  TickSampleEventRecord record;
  TickSample* sample = &record.sample;
  Isolate* isolate = Isolate::Current();
  sample->state = isolate->current_vm_state();
  sample->pc = reinterpret_cast<Address>(sample);  // Not NULL.
  sample->tos = NULL;
  sample->has_external_callback = false;
  sample->frames_count = 0;
  for (StackTraceFrameIterator it(isolate);
       !it.done() && sample->frames_count < TickSample::kMaxFramesCount;
       it.Advance()) {
    sample->stack[sample->frames_count++] = it.frame()->pc();
  }
  record.order = enqueue_order_;
  ticks_from_vm_buffer_.Enqueue(record);
}


bool ProfilerEventsProcessor::ProcessCodeEvent(unsigned* dequeue_order) {
  if (!events_buffer_.IsEmpty()) {
    CodeEventsContainer record;
    events_buffer_.Dequeue(&record);
    switch (record.generic.type) {
#define PROFILER_TYPE_CASE(type, clss)                          \
      case CodeEventRecord::type:                               \
        record.clss##_.UpdateCodeMap(generator_->code_map());   \
        break;

      CODE_EVENTS_TYPE_LIST(PROFILER_TYPE_CASE)

#undef PROFILER_TYPE_CASE
      default: return true;  // Skip record.
    }
    *dequeue_order = record.generic.order;
    return true;
  }
  return false;
}


bool ProfilerEventsProcessor::ProcessTicks(unsigned dequeue_order) {
  while (true) {
    if (!ticks_from_vm_buffer_.IsEmpty()
        && ticks_from_vm_buffer_.Peek()->order == dequeue_order) {
      TickSampleEventRecord record;
      ticks_from_vm_buffer_.Dequeue(&record);
      generator_->RecordTickSample(record.sample);
    }

    const TickSampleEventRecord* rec =
        TickSampleEventRecord::cast(ticks_buffer_.StartDequeue());
    if (rec == NULL) return !ticks_from_vm_buffer_.IsEmpty();
    // Make a local copy of tick sample record to ensure that it won't
    // be modified as we are processing it. This is possible as the
    // sampler writes w/o any sync to the queue, so if the processor
    // will get far behind, a record may be modified right under its
    // feet.
    TickSampleEventRecord record = *rec;
    if (record.order == dequeue_order) {
      // A paranoid check to make sure that we don't get a memory overrun
      // in case of frames_count having a wild value.
      if (record.sample.frames_count < 0
          || record.sample.frames_count > TickSample::kMaxFramesCount)
        record.sample.frames_count = 0;
      generator_->RecordTickSample(record.sample);
      ticks_buffer_.FinishDequeue();
    } else {
      return true;
    }
  }
}


void ProfilerEventsProcessor::Run() {
  unsigned dequeue_order = 0;

  while (running_) {
    // Process ticks until we have any.
    if (ProcessTicks(dequeue_order)) {
      // All ticks of the current dequeue_order are processed,
      // proceed to the next code event.
      ProcessCodeEvent(&dequeue_order);
    }
    YieldCPU();
  }

  // Process remaining tick events.
  ticks_buffer_.FlushResidualRecords();
  // Perform processing until we have tick events, skip remaining code events.
  while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { }
}


void CpuProfiler::StartProfiling(const char* title) {
  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
  Isolate::Current()->cpu_profiler()->StartCollectingProfile(title);
}


void CpuProfiler::StartProfiling(String* title) {
  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
  Isolate::Current()->cpu_profiler()->StartCollectingProfile(title);
}


CpuProfile* CpuProfiler::StopProfiling(const char* title) {
  return is_profiling() ?
      Isolate::Current()->cpu_profiler()->StopCollectingProfile(title) : NULL;
}


CpuProfile* CpuProfiler::StopProfiling(Object* security_token, String* title) {
  return is_profiling() ?
      Isolate::Current()->cpu_profiler()->StopCollectingProfile(
          security_token, title) : NULL;
}


int CpuProfiler::GetProfilesCount() {
  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
  // The count of profiles doesn't depend on a security token.
  return Isolate::Current()->cpu_profiler()->profiles_->Profiles(
      TokenEnumerator::kNoSecurityToken)->length();
}


CpuProfile* CpuProfiler::GetProfile(Object* security_token, int index) {
  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
  const int token = profiler->token_enumerator_->GetTokenId(security_token);
  return profiler->profiles_->Profiles(token)->at(index);
}


CpuProfile* CpuProfiler::FindProfile(Object* security_token, unsigned uid) {
  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
  const int token = profiler->token_enumerator_->GetTokenId(security_token);
  return profiler->profiles_->GetProfile(token, uid);
}


TickSample* CpuProfiler::TickSampleEvent(Isolate* isolate) {
  if (CpuProfiler::is_profiling(isolate)) {
    return isolate->cpu_profiler()->processor_->TickSampleEvent();
  } else {
    return NULL;
  }
}


void CpuProfiler::DeleteAllProfiles() {
  Isolate* isolate = Isolate::Current();
  ASSERT(isolate->cpu_profiler() != NULL);
  if (is_profiling())
    isolate->cpu_profiler()->StopProcessor();
  isolate->cpu_profiler()->ResetProfiles();
}


void CpuProfiler::DeleteProfile(CpuProfile* profile) {
  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
  Isolate::Current()->cpu_profiler()->profiles_->RemoveProfile(profile);
  delete profile;
}


bool CpuProfiler::HasDetachedProfiles() {
  ASSERT(Isolate::Current()->cpu_profiler() != NULL);
  return Isolate::Current()->cpu_profiler()->profiles_->HasDetachedProfiles();
}


void CpuProfiler::CallbackEvent(String* name, Address entry_point) {
  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
      Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
}


void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                           Code* code, const char* comment) {
  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
      tag, comment, code->address(), code->ExecutableSize());
}


void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                           Code* code, String* name) {
  Isolate* isolate = Isolate::Current();
  isolate->cpu_profiler()->processor_->CodeCreateEvent(
      tag,
      name,
      isolate->heap()->empty_string(),
      v8::CpuProfileNode::kNoLineNumberInfo,
      code->address(),
      code->ExecutableSize(),
      NULL);
}


void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                                  Code* code,
                                  SharedFunctionInfo* shared,
                                  String* name) {
  Isolate* isolate = Isolate::Current();
  isolate->cpu_profiler()->processor_->CodeCreateEvent(
      tag,
      name,
      isolate->heap()->empty_string(),
      v8::CpuProfileNode::kNoLineNumberInfo,
      code->address(),
      code->ExecutableSize(),
      shared->address());
}


void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                                  Code* code,
                                  SharedFunctionInfo* shared,
                                  String* source, int line) {
  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
      tag,
      shared->DebugName(),
      source,
      line,
      code->address(),
      code->ExecutableSize(),
      shared->address());
}


void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
                           Code* code, int args_count) {
  Isolate::Current()->cpu_profiler()->processor_->CodeCreateEvent(
      tag,
      args_count,
      code->address(),
      code->ExecutableSize());
}


void CpuProfiler::CodeMoveEvent(Address from, Address to) {
  Isolate::Current()->cpu_profiler()->processor_->CodeMoveEvent(from, to);
}


void CpuProfiler::CodeDeleteEvent(Address from) {
  Isolate::Current()->cpu_profiler()->processor_->CodeDeleteEvent(from);
}


void CpuProfiler::SharedFunctionInfoMoveEvent(Address from, Address to) {
  CpuProfiler* profiler = Isolate::Current()->cpu_profiler();
  profiler->processor_->SharedFunctionInfoMoveEvent(from, to);
}


void CpuProfiler::GetterCallbackEvent(String* name, Address entry_point) {
  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
      Logger::CALLBACK_TAG, "get ", name, entry_point);
}


void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
  Isolate::Current()->cpu_profiler()->processor_->RegExpCodeCreateEvent(
      Logger::REG_EXP_TAG,
      "RegExp: ",
      source,
      code->address(),
      code->ExecutableSize());
}


void CpuProfiler::SetterCallbackEvent(String* name, Address entry_point) {
  Isolate::Current()->cpu_profiler()->processor_->CallbackCreateEvent(
      Logger::CALLBACK_TAG, "set ", name, entry_point);
}


CpuProfiler::CpuProfiler()
    : profiles_(new CpuProfilesCollection()),
      next_profile_uid_(1),
      token_enumerator_(new TokenEnumerator()),
      generator_(NULL),
      processor_(NULL),
      need_to_stop_sampler_(false),
      is_profiling_(false) {
}


CpuProfiler::~CpuProfiler() {
  delete token_enumerator_;
  delete profiles_;
}


void CpuProfiler::ResetProfiles() {
  delete profiles_;
  profiles_ = new CpuProfilesCollection();
}

void CpuProfiler::StartCollectingProfile(const char* title) {
  if (profiles_->StartProfiling(title, next_profile_uid_++)) {
    StartProcessorIfNotStarted();
  }
  processor_->AddCurrentStack();
}


void CpuProfiler::StartCollectingProfile(String* title) {
  StartCollectingProfile(profiles_->GetName(title));
}


void CpuProfiler::StartProcessorIfNotStarted() {
  if (processor_ == NULL) {
    Isolate* isolate = Isolate::Current();

    // Disable logging when using the new implementation.
    saved_logging_nesting_ = isolate->logger()->logging_nesting_;
    isolate->logger()->logging_nesting_ = 0;
    generator_ = new ProfileGenerator(profiles_);
    processor_ = new ProfilerEventsProcessor(isolate, generator_);
    NoBarrier_Store(&is_profiling_, true);
    processor_->Start();
    // Enumerate stuff we already have in the heap.
    if (isolate->heap()->HasBeenSetup()) {
      if (!FLAG_prof_browser_mode) {
        bool saved_log_code_flag = FLAG_log_code;
        FLAG_log_code = true;
        isolate->logger()->LogCodeObjects();
        FLAG_log_code = saved_log_code_flag;
      }
      isolate->logger()->LogCompiledFunctions();
      isolate->logger()->LogAccessorCallbacks();
    }
    // Enable stack sampling.
    Sampler* sampler = reinterpret_cast<Sampler*>(isolate->logger()->ticker_);
    if (!sampler->IsActive()) {
      sampler->Start();
      need_to_stop_sampler_ = true;
    }
    sampler->IncreaseProfilingDepth();
  }
}


CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) {
  const double actual_sampling_rate = generator_->actual_sampling_rate();
  StopProcessorIfLastProfile(title);
  CpuProfile* result =
      profiles_->StopProfiling(TokenEnumerator::kNoSecurityToken,
                               title,
                               actual_sampling_rate);
  if (result != NULL) {
    result->Print();
  }
  return result;
}


CpuProfile* CpuProfiler::StopCollectingProfile(Object* security_token,
                                               String* title) {
  const double actual_sampling_rate = generator_->actual_sampling_rate();
  const char* profile_title = profiles_->GetName(title);
  StopProcessorIfLastProfile(profile_title);
  int token = token_enumerator_->GetTokenId(security_token);
  return profiles_->StopProfiling(token, profile_title, actual_sampling_rate);
}


void CpuProfiler::StopProcessorIfLastProfile(const char* title) {
  if (profiles_->IsLastProfile(title)) StopProcessor();
}


void CpuProfiler::StopProcessor() {
  Logger* logger = Isolate::Current()->logger();
  Sampler* sampler = reinterpret_cast<Sampler*>(logger->ticker_);
  sampler->DecreaseProfilingDepth();
  if (need_to_stop_sampler_) {
    sampler->Stop();
    need_to_stop_sampler_ = false;
  }
  processor_->Stop();
  processor_->Join();
  delete processor_;
  delete generator_;
  processor_ = NULL;
  NoBarrier_Store(&is_profiling_, false);
  generator_ = NULL;
  logger->logging_nesting_ = saved_logging_nesting_;
}

} }  // namespace v8::internal

#endif  // ENABLE_LOGGING_AND_PROFILING

namespace v8 {
namespace internal {

void CpuProfiler::Setup() {
#ifdef ENABLE_LOGGING_AND_PROFILING
  Isolate* isolate = Isolate::Current();
  if (isolate->cpu_profiler() == NULL) {
    isolate->set_cpu_profiler(new CpuProfiler());
  }
#endif
}


void CpuProfiler::TearDown() {
#ifdef ENABLE_LOGGING_AND_PROFILING
  Isolate* isolate = Isolate::Current();
  if (isolate->cpu_profiler() != NULL) {
    delete isolate->cpu_profiler();
  }
  isolate->set_cpu_profiler(NULL);
#endif
}

} }  // namespace v8::internal
