// Copyright (c) 2013, 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/utils.h"

#include "vm/allocation.h"
#include "vm/atomic.h"
#include "vm/code_patcher.h"
#include "vm/isolate.h"
#include "vm/json_stream.h"
#include "vm/native_symbol.h"
#include "vm/object.h"
#include "vm/os.h"
#include "vm/profiler.h"
#include "vm/signal_handler.h"
#include "vm/simulator.h"
#include "vm/stack_frame.h"

namespace dart {


#if defined(USING_SIMULATOR) || defined(TARGET_OS_WINDOWS) || \
    defined(TARGET_OS_MACOS) || defined(TARGET_OS_ANDROID)
  DEFINE_FLAG(bool, profile, false, "Enable Sampling Profiler");
#else
  DEFINE_FLAG(bool, profile, true, "Enable Sampling Profiler");
#endif
DEFINE_FLAG(bool, trace_profiled_isolates, false, "Trace profiled isolates.");
DEFINE_FLAG(charp, profile_dir, NULL,
            "Enable writing profile data into specified directory.");
DEFINE_FLAG(int, profile_period, 1000,
            "Time between profiler samples in microseconds. Minimum 250.");
DEFINE_FLAG(int, profile_depth, 8,
            "Maximum number stack frames walked. Minimum 1. Maximum 128.");

bool Profiler::initialized_ = false;
SampleBuffer* Profiler::sample_buffer_ = NULL;

void Profiler::InitOnce() {
  const int kMinimumProfilePeriod = 250;
  const int kMinimumDepth = 1;
  const int kMaximumDepth = 128;
  // Place some sane restrictions on user controlled flags.
  if (FLAG_profile_period < kMinimumProfilePeriod) {
    FLAG_profile_period = kMinimumProfilePeriod;
  }
  if (FLAG_profile_depth < kMinimumDepth) {
    FLAG_profile_depth = kMinimumDepth;
  } else if (FLAG_profile_depth > kMaximumDepth) {
    FLAG_profile_depth = kMaximumDepth;
  }
  Sample::InitOnce();
  if (!FLAG_profile) {
    return;
  }
  ASSERT(!initialized_);
  sample_buffer_ = new SampleBuffer();
  NativeSymbolResolver::InitOnce();
  ThreadInterrupter::InitOnce();
  ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period);
  initialized_ = true;
}


void Profiler::Shutdown() {
  if (!FLAG_profile) {
    return;
  }
  ASSERT(initialized_);
  ThreadInterrupter::Shutdown();
  NativeSymbolResolver::ShutdownOnce();
}


void Profiler::InitProfilingForIsolate(Isolate* isolate, bool shared_buffer) {
  if (!FLAG_profile) {
    return;
  }
  ASSERT(isolate != NULL);
  ASSERT(sample_buffer_ != NULL);
  {
    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
    SampleBuffer* sample_buffer = sample_buffer_;
    if (!shared_buffer) {
      sample_buffer = new SampleBuffer();
    }
    IsolateProfilerData* profiler_data =
        new IsolateProfilerData(sample_buffer, !shared_buffer);
    ASSERT(profiler_data != NULL);
    isolate->set_profiler_data(profiler_data);
    if (FLAG_trace_profiled_isolates) {
      OS::Print("Profiler Setup %p %s\n", isolate, isolate->name());
    }
  }
}


void Profiler::ShutdownProfilingForIsolate(Isolate* isolate) {
  ASSERT(isolate != NULL);
  if (!FLAG_profile) {
    return;
  }
  // We do not have a current isolate.
  ASSERT(Isolate::Current() == NULL);
  {
    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
    IsolateProfilerData* profiler_data = isolate->profiler_data();
    if (profiler_data == NULL) {
      // Already freed.
      return;
    }
    isolate->set_profiler_data(NULL);
    delete profiler_data;
    if (FLAG_trace_profiled_isolates) {
      OS::Print("Profiler Shutdown %p %s\n", isolate, isolate->name());
    }
  }
}


void Profiler::BeginExecution(Isolate* isolate) {
  if (isolate == NULL) {
    return;
  }
  if (!FLAG_profile) {
    return;
  }
  ASSERT(initialized_);
  IsolateProfilerData* profiler_data = isolate->profiler_data();
  if (profiler_data == NULL) {
    return;
  }
  ThreadInterrupter::Register(RecordSampleInterruptCallback, isolate);
}


void Profiler::EndExecution(Isolate* isolate) {
  if (isolate == NULL) {
    return;
  }
  if (!FLAG_profile) {
    return;
  }
  ASSERT(initialized_);
  ThreadInterrupter::Unregister();
}


void Profiler::RecordTickInterruptCallback(const InterruptedThreadState& state,
                                           void* data) {
  Isolate* isolate = reinterpret_cast<Isolate*>(data);
  if (isolate == NULL) {
    return;
  }
  IsolateProfilerData* profiler_data = isolate->profiler_data();
  if (profiler_data == NULL) {
    return;
  }
  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
  if (sample_buffer == NULL) {
    return;
  }
  Sample* sample = sample_buffer->ReserveSample();
  sample->Init(Sample::kIsolateSample, isolate, OS::GetCurrentTimeMicros(),
               state.tid);
}


void Profiler::RecordSampleInterruptCallback(
    const InterruptedThreadState& state,
    void* data) {
  Isolate* isolate = reinterpret_cast<Isolate*>(data);
  if (isolate == NULL) {
    return;
  }
  IsolateProfilerData* profiler_data = isolate->profiler_data();
  if (profiler_data == NULL) {
    return;
  }
  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
  if (sample_buffer == NULL) {
    return;
  }
  Sample* sample = sample_buffer->ReserveSample();
  sample->Init(Sample::kIsolateSample, isolate, OS::GetCurrentTimeMicros(),
               state.tid);
  uintptr_t stack_lower = 0;
  uintptr_t stack_upper = 0;
  isolate->GetStackBounds(&stack_lower, &stack_upper);
  if ((stack_lower == 0) || (stack_upper == 0)) {
    stack_lower = 0;
    stack_upper = 0;
  }
  ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
                                        state.pc, state.fp, state.sp);
  stackWalker.walk();
}


struct AddressEntry {
  uintptr_t pc;
  uintptr_t ticks;
};


// A region of code. Each region is a kind of code (Dart, Collected, or Native).
class CodeRegion : public ZoneAllocated {
 public:
  enum Kind {
    kDartCode,
    kCollectedCode,
    kNativeCode
  };

  CodeRegion(Kind kind, uintptr_t start, uintptr_t end) :
      kind_(kind),
      start_(start),
      end_(end),
      inclusive_ticks_(0),
      exclusive_ticks_(0),
      name_(NULL),
      address_table_(new ZoneGrowableArray<AddressEntry>()) {
  }

  ~CodeRegion() {
  }

  uintptr_t start() const { return start_; }
  void set_start(uintptr_t start) {
    start_ = start;
  }

  uintptr_t end() const { return end_; }
  void set_end(uintptr_t end) {
    end_ = end;
  }

  void AdjustExtent(uintptr_t start, uintptr_t end) {
    if (start < start_) {
      start_ = start;
    }
    if (end > end_) {
      end_ = end;
    }
  }

  bool contains(uintptr_t pc) const {
    return (pc >= start_) && (pc < end_);
  }

  intptr_t inclusive_ticks() const { return inclusive_ticks_; }
  void set_inclusive_ticks(intptr_t inclusive_ticks) {
    inclusive_ticks_ = inclusive_ticks;
  }

  intptr_t exclusive_ticks() const { return exclusive_ticks_; }
  void set_exclusive_ticks(intptr_t exclusive_ticks) {
    exclusive_ticks_ = exclusive_ticks;
  }

  const char* name() const { return name_; }
  void SetName(const char* name) {
    if (name == NULL) {
      name_ = NULL;
    }
    intptr_t len = strlen(name);
    name_ = Isolate::Current()->current_zone()->Alloc<const char>(len + 1);
    strncpy(const_cast<char*>(name_), name, len);
    const_cast<char*>(name_)[len] = '\0';
  }

  Kind kind() const { return kind_; }

  static const char* KindToCString(Kind kind) {
    switch (kind) {
      case kDartCode:
        return "Dart";
      case kCollectedCode:
        return "Collected";
      case kNativeCode:
        return "Native";
    }
    UNREACHABLE();
    return NULL;
  }

  void AddTick(bool exclusive) {
    if (exclusive) {
      exclusive_ticks_++;
    } else {
      inclusive_ticks_++;
    }
  }

  void DebugPrint() {
    printf("%s [%" Px ", %" Px ") %s\n", name_, start(), end(),
           KindToCString(kind_));
  }

  void AddTickAtAddress(uintptr_t pc) {
    const intptr_t length = address_table_->length();
    intptr_t i = 0;
    for (; i < length; i++) {
      AddressEntry& entry = (*address_table_)[i];
      if (entry.pc == pc) {
        entry.ticks++;
        return;
      }
      if (entry.pc > pc) {
        break;
      }
    }
    AddressEntry entry;
    entry.pc = pc;
    entry.ticks = 1;
    if (i < length) {
      // Insert at i.
      address_table_->InsertAt(i, entry);
    } else {
      // Add to end.
      address_table_->Add(entry);
    }
  }


  void PrintToJSONArray(JSONArray* events, bool full) {
    JSONObject obj(events);
    obj.AddProperty("type", "ProfileCode");
    obj.AddProperty("kind", KindToCString(kind()));
    obj.AddPropertyF("inclusive_ticks", "%" Pd "", inclusive_ticks());
    obj.AddPropertyF("exclusive_ticks", "%" Pd "", exclusive_ticks());
    if (kind() == kDartCode) {
      // Look up code in Dart heap.
      Code& code = Code::Handle(Code::LookupCode(start()));
      Function& func = Function::Handle();
      ASSERT(!code.IsNull());
      func ^= code.function();
      if (func.IsNull()) {
        if (name() == NULL) {
          GenerateAndSetSymbolName("Stub");
        }
        obj.AddPropertyF("start", "%" Px "", start());
        obj.AddPropertyF("end", "%" Px "", end());
        obj.AddProperty("name", name());
      } else {
        obj.AddProperty("code", code, !full);
      }
    } else if (kind() == kCollectedCode) {
      if (name() == NULL) {
        GenerateAndSetSymbolName("Collected");
      }
      obj.AddPropertyF("start", "%" Px "", start());
      obj.AddPropertyF("end", "%" Px "", end());
      obj.AddProperty("name", name());
    } else {
      ASSERT(kind() == kNativeCode);
      if (name() == NULL) {
        GenerateAndSetSymbolName("Native");
      }
      obj.AddPropertyF("start", "%" Px "", start());
      obj.AddPropertyF("end", "%" Px "", end());
      obj.AddProperty("name", name());
    }
    {
      JSONArray ticks(&obj, "ticks");
      for (intptr_t i = 0; i < address_table_->length(); i++) {
        const AddressEntry& entry = (*address_table_)[i];
        ticks.AddValueF("%" Px "", entry.pc);
        ticks.AddValueF("%" Pd "", entry.ticks);
      }
    }
  }

 private:
  void GenerateAndSetSymbolName(const char* prefix) {
    const intptr_t kBuffSize = 512;
    char buff[kBuffSize];
    OS::SNPrint(&buff[0], kBuffSize-1, "%s [%" Px ", %" Px ")",
                prefix, start(), end());
    SetName(buff);
  }

  Kind kind_;
  uintptr_t start_;
  uintptr_t end_;
  intptr_t inclusive_ticks_;
  intptr_t exclusive_ticks_;
  const char* name_;
  ZoneGrowableArray<AddressEntry>* address_table_;

  DISALLOW_COPY_AND_ASSIGN(CodeRegion);
};


// All code regions. Code region tables are built on demand when a profile
// is requested (through the service or on isolate shutdown).
class ProfilerCodeRegionTable : public ValueObject {
 public:
  explicit ProfilerCodeRegionTable(Isolate* isolate) :
      heap_(isolate->heap()),
      code_region_table_(new ZoneGrowableArray<CodeRegion*>(64)) {
  }

  ~ProfilerCodeRegionTable() {
  }

  void AddTick(uintptr_t pc, bool exclusive, bool tick_address) {
    intptr_t index = FindIndex(pc);
    if (index < 0) {
      CodeRegion* code_region = CreateCodeRegion(pc);
      ASSERT(code_region != NULL);
      index = InsertCodeRegion(code_region);
    }
    ASSERT(index >= 0);
    ASSERT(index < code_region_table_->length());
    (*code_region_table_)[index]->AddTick(exclusive);
    if (tick_address) {
      (*code_region_table_)[index]->AddTickAtAddress(pc);
    }
  }

  intptr_t Length() const { return code_region_table_->length(); }

  CodeRegion* At(intptr_t idx) {
    return (*code_region_table_)[idx];
  }

 private:
  intptr_t FindIndex(uintptr_t pc) {
    const intptr_t length = code_region_table_->length();
    for (intptr_t i = 0; i < length; i++) {
      const CodeRegion* code_region = (*code_region_table_)[i];
      if (code_region->contains(pc)) {
        return i;
      }
    }
    return -1;
  }

  CodeRegion* CreateCodeRegion(uintptr_t pc) {
    Code& code = Code::Handle(Code::LookupCode(pc));
    if (!code.IsNull()) {
      return new CodeRegion(CodeRegion::kDartCode, code.EntryPoint(),
                            code.EntryPoint() + code.Size());
    }
    if (heap_->CodeContains(pc)) {
      const intptr_t kDartCodeAlignment = 0x10;
      const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
      return new CodeRegion(CodeRegion::kCollectedCode,
                            (pc & kDartCodeAlignmentMask),
                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment);
    }
    uintptr_t native_start = 0;
    char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
                                                               &native_start);
    if (native_name == NULL) {
      return new CodeRegion(CodeRegion::kNativeCode, pc, pc + 1);
    }
    ASSERT(pc >= native_start);
    CodeRegion* code_region =
        new CodeRegion(CodeRegion::kNativeCode, native_start, pc + 1);
    code_region->SetName(native_name);
    free(native_name);
    return code_region;
  }

  intptr_t InsertCodeRegion(CodeRegion* code_region) {
    const intptr_t length = code_region_table_->length();
    const uintptr_t start = code_region->start();
    const uintptr_t end = code_region->end();
    intptr_t i = 0;
    for (; i < length; i++) {
      CodeRegion* region = (*code_region_table_)[i];
      if (region->contains(start) || region->contains(end - 1)) {
        // We should only see overlapping native code regions.
        ASSERT(region->kind() == CodeRegion::kNativeCode);
        // When code regions overlap, they should be of the same kind.
        ASSERT(region->kind() == code_region->kind());
        // Overlapping code region.
        region->AdjustExtent(start, end);
        return i;
      } else if (start >= region->end()) {
        // Insert here.
        break;
      }
    }
    if (i != length) {
      code_region_table_->InsertAt(i, code_region);
      return i;
    }
    code_region_table_->Add(code_region);
    return code_region_table_->length() - 1;
  }

  Heap* heap_;
  ZoneGrowableArray<CodeRegion*>* code_region_table_;
};


void Profiler::PrintToJSONStream(Isolate* isolate, JSONStream* stream,
                                 bool full) {
  ASSERT(isolate == Isolate::Current());
  // Disable profile interrupts while processing the buffer.
  EndExecution(isolate);
  MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
  IsolateProfilerData* profiler_data = isolate->profiler_data();
  if (profiler_data == NULL) {
    JSONObject error(stream);
    error.AddProperty("type", "Error");
    error.AddProperty("text", "Isolate does not have profiling enabled.");
    return;
  }
  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
  ASSERT(sample_buffer != NULL);
  {
    StackZone zone(isolate);
    {
      // Build code region table.
      ProfilerCodeRegionTable code_region_table(isolate);
      intptr_t samples =
          ProcessSamples(isolate, &code_region_table, sample_buffer);
      {
        // Serialize to JSON.
        JSONObject obj(stream);
        obj.AddProperty("type", "Profile");
        obj.AddProperty("samples", samples);
        JSONArray codes(&obj, "codes");
        for (intptr_t i = 0; i < code_region_table.Length(); i++) {
          CodeRegion* region = code_region_table.At(i);
          ASSERT(region != NULL);
          region->PrintToJSONArray(&codes, full);
        }
      }
    }
  }
  // Enable profile interrupts.
  BeginExecution(isolate);
}


intptr_t Profiler::ProcessSamples(Isolate* isolate,
                                  ProfilerCodeRegionTable* code_region_table,
                                  SampleBuffer* sample_buffer) {
  int64_t start = OS::GetCurrentTimeMillis();
  intptr_t samples = 0;
  Sample* sample = Sample::Allocate();
  for (intptr_t i = 0; i < sample_buffer->capacity(); i++) {
    sample_buffer->CopySample(i, sample);
    if (sample->isolate() != isolate) {
      continue;
    }
    if (sample->timestamp() == 0) {
      continue;
    }
    samples += ProcessSample(isolate, code_region_table, sample);
  }
  free(sample);
  int64_t end = OS::GetCurrentTimeMillis();
  if (FLAG_trace_profiled_isolates) {
    int64_t delta = end - start;
    OS::Print("Processed %" Pd " samples from %s in %" Pd64 " milliseconds.\n",
        samples,
        isolate->name(),
        delta);
  }
  return samples;
}


intptr_t Profiler::ProcessSample(Isolate* isolate,
                                 ProfilerCodeRegionTable* code_region_table,
                                Sample* sample) {
  if (sample->type() != Sample::kIsolateSample) {
    return 0;
  }
  if (sample->At(0) == 0) {
    // No frames in this sample.
    return 0;
  }
  // i points to the leaf (exclusive) PC sample. Do not tick the address.
  code_region_table->AddTick(sample->At(0), true, false);
  // Give all frames an inclusive tick and tick the address.
  for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
    if (sample->At(i) == 0) {
      break;
    }
    code_region_table->AddTick(sample->At(i), false, true);
  }
  return 1;
}


void Profiler::WriteProfile(Isolate* isolate) {
  if (isolate == NULL) {
    return;
  }
  if (!FLAG_profile) {
    return;
  }
  ASSERT(initialized_);
  if (FLAG_profile_dir == NULL) {
    return;
  }
  Dart_FileOpenCallback file_open = Isolate::file_open_callback();
  Dart_FileCloseCallback file_close = Isolate::file_close_callback();
  Dart_FileWriteCallback file_write = Isolate::file_write_callback();
  if ((file_open == NULL) || (file_close == NULL) || (file_write == NULL)) {
    // Embedder has not provided necessary callbacks.
    return;
  }
  // We will be looking up code objects within the isolate.
  ASSERT(Isolate::Current() == isolate);
  JSONStream stream(10 * MB);
  intptr_t pid = OS::ProcessId();
  PrintToJSONStream(isolate, &stream, true);
  const char* format = "%s/dart-profile-%" Pd "-%" Pd ".json";
  intptr_t len = OS::SNPrint(NULL, 0, format,
                             FLAG_profile_dir, pid, isolate->main_port());
  char* filename = Isolate::Current()->current_zone()->Alloc<char>(len + 1);
  OS::SNPrint(filename, len + 1, format,
              FLAG_profile_dir, pid, isolate->main_port());
  void* f = file_open(filename, true);
  if (f == NULL) {
    // Cannot write.
    return;
  }
  TextBuffer* buffer = stream.buffer();
  ASSERT(buffer != NULL);
  file_write(buffer->buf(), buffer->length(), f);
  file_close(f);
}


IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer,
                                         bool own_sample_buffer) {
  ASSERT(sample_buffer != NULL);
  sample_buffer_ = sample_buffer;
  own_sample_buffer_ = own_sample_buffer;
}


IsolateProfilerData::~IsolateProfilerData() {
  if (own_sample_buffer_) {
    delete sample_buffer_;
    sample_buffer_ = NULL;
    own_sample_buffer_ = false;
  }
}


intptr_t Sample::instance_size_ = 0;

void Sample::InitOnce() {
  ASSERT(FLAG_profile_depth >= 1);
  instance_size_ =
     sizeof(Sample) + (sizeof(intptr_t) * FLAG_profile_depth);  // NOLINT.
}


uintptr_t Sample::At(intptr_t i) const {
  ASSERT(i >= 0);
  ASSERT(i < FLAG_profile_depth);
  return pcs_[i];
}


void Sample::SetAt(intptr_t i, uintptr_t pc) {
  ASSERT(i >= 0);
  ASSERT(i < FLAG_profile_depth);
  pcs_[i] = pc;
}


void Sample::Init(SampleType type, Isolate* isolate, int64_t timestamp,
                  ThreadId tid) {
  timestamp_ = timestamp;
  tid_ = tid;
  isolate_ = isolate;
  type_ = type;
  for (int i = 0; i < FLAG_profile_depth; i++) {
    pcs_[i] = 0;
  }
}


void Sample::CopyInto(Sample* dst) const {
  ASSERT(dst != NULL);
  dst->timestamp_ = timestamp_;
  dst->tid_ = tid_;
  dst->isolate_ = isolate_;
  dst->type_ = type_;
  for (intptr_t i = 0; i < FLAG_profile_depth; i++) {
    dst->pcs_[i] = pcs_[i];
  }
}


Sample* Sample::Allocate() {
  return reinterpret_cast<Sample*>(malloc(instance_size()));
}


SampleBuffer::SampleBuffer(intptr_t capacity) {
  capacity_ = capacity;
  samples_ = reinterpret_cast<Sample*>(
      calloc(capacity, Sample::instance_size()));
  cursor_ = 0;
}


SampleBuffer::~SampleBuffer() {
  if (samples_ != NULL) {
    free(samples_);
    samples_ = NULL;
    cursor_ = 0;
    capacity_ = 0;
  }
}


Sample* SampleBuffer::ReserveSample() {
  ASSERT(samples_ != NULL);
  uintptr_t cursor = AtomicOperations::FetchAndIncrement(&cursor_);
  // Map back into sample buffer range.
  cursor = cursor % capacity_;
  return At(cursor);
}


void SampleBuffer::CopySample(intptr_t i, Sample* sample) const {
  At(i)->CopyInto(sample);
}


Sample* SampleBuffer::At(intptr_t idx) const {
  ASSERT(idx >= 0);
  ASSERT(idx < capacity_);
  intptr_t offset = idx * Sample::instance_size();
  uint8_t* samples = reinterpret_cast<uint8_t*>(samples_);
  return reinterpret_cast<Sample*>(samples + offset);
}


ProfilerSampleStackWalker::ProfilerSampleStackWalker(Sample* sample,
                                                     uintptr_t stack_lower,
                                                     uintptr_t stack_upper,
                                                     uintptr_t pc,
                                                     uintptr_t fp,
                                                     uintptr_t sp) :
    sample_(sample),
    stack_lower_(stack_lower),
    stack_upper_(stack_upper),
    original_pc_(pc),
    original_fp_(fp),
    original_sp_(sp),
    lower_bound_(stack_lower) {
  ASSERT(sample_ != NULL);
}


// Notes on stack frame walking:
//
// The sampling profiler will collect up to Sample::kNumStackFrames stack frames
// The stack frame walking code uses the frame pointer to traverse the stack.
// If the VM is compiled without frame pointers (which is the default on
// recent GCC versions with optimizing enabled) the stack walking code may
// fail (sometimes leading to a crash).
//

int ProfilerSampleStackWalker::walk() {
  const intptr_t kMaxStep = 0x1000;  // 4K.
  const bool kWalkStack = true;  // Walk the stack.
  // Always store the exclusive PC.
  sample_->SetAt(0, original_pc_);
  if (!kWalkStack) {
    // Not walking the stack, only took exclusive sample.
    return 1;
  }
  uword* pc = reinterpret_cast<uword*>(original_pc_);
  uword* fp = reinterpret_cast<uword*>(original_fp_);
  uword* previous_fp = fp;
  if (original_sp_ > original_fp_) {
    // Stack pointer should not be above frame pointer.
    return 1;
  }
  intptr_t gap = original_fp_ - original_sp_;
  if (gap >= kMaxStep) {
    // Gap between frame pointer and stack pointer is
    // too large.
    return 1;
  }
  if (original_sp_ < lower_bound_) {
    // The stack pointer gives us a better lower bound than
    // the isolates stack limit.
    lower_bound_ = original_sp_;
  }
  int i = 0;
  for (; i < FLAG_profile_depth; i++) {
    sample_->SetAt(i, reinterpret_cast<uintptr_t>(pc));
    if (!ValidFramePointer(fp)) {
      return i + 1;
    }
    pc = CallerPC(fp);
    previous_fp = fp;
    fp = CallerFP(fp);
    intptr_t step = fp - previous_fp;
    if ((step >= kMaxStep) || (fp <= previous_fp) || !ValidFramePointer(fp)) {
      // Frame pointer step is too large.
      // Frame pointer did not move to a higher address.
      // Frame pointer is outside of isolate stack bounds.
      return i + 1;
    }
    // Move the lower bound up.
    lower_bound_ = reinterpret_cast<uintptr_t>(fp);
  }
  return i;
}


uword* ProfilerSampleStackWalker::CallerPC(uword* fp) {
  ASSERT(fp != NULL);
  return reinterpret_cast<uword*>(*(fp + kSavedCallerPcSlotFromFp));
}


uword* ProfilerSampleStackWalker::CallerFP(uword* fp) {
  ASSERT(fp != NULL);
  return reinterpret_cast<uword*>(*(fp + kSavedCallerFpSlotFromFp));
}


bool ProfilerSampleStackWalker::ValidFramePointer(uword* fp) {
  if (fp == NULL) {
    return false;
  }
  uintptr_t cursor = reinterpret_cast<uintptr_t>(fp);
  cursor += sizeof(fp);
  bool r = cursor >= lower_bound_ && cursor < stack_upper_;
  return r;
}


}  // namespace dart
