// 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.

#ifndef RUNTIME_VM_PROFILER_H_
#define RUNTIME_VM_PROFILER_H_

#include "platform/atomic.h"

#include "vm/allocation.h"
#include "vm/bitfield.h"
#include "vm/code_observers.h"
#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/malloc_hooks.h"
#include "vm/native_symbol.h"
#include "vm/object.h"
#include "vm/tags.h"
#include "vm/thread_interrupter.h"

// Profiler sampling and stack walking support.
// NOTE: For service related code, see profile_service.h.

namespace dart {

// Forward declarations.
class ProcessedSample;
class ProcessedSampleBuffer;

class Sample;
class AllocationSampleBuffer;
class SampleBuffer;
class ProfileTrieNode;

#define PROFILER_COUNTERS(V)                                                   \
  V(bail_out_unknown_task)                                                     \
  V(bail_out_jump_to_exception_handler)                                        \
  V(bail_out_check_isolate)                                                    \
  V(single_frame_sample_deoptimizing)                                          \
  V(single_frame_sample_register_check)                                        \
  V(single_frame_sample_get_and_validate_stack_bounds)                         \
  V(stack_walker_native)                                                       \
  V(stack_walker_dart_exit)                                                    \
  V(stack_walker_dart)                                                         \
  V(stack_walker_none)                                                         \
  V(incomplete_sample_fp_bounds)                                               \
  V(incomplete_sample_fp_step)                                                 \
  V(incomplete_sample_bad_pc)                                                  \
  V(failure_native_allocation_sample)

struct ProfilerCounters {
#define DECLARE_PROFILER_COUNTER(name) RelaxedAtomic<int64_t> name;
  PROFILER_COUNTERS(DECLARE_PROFILER_COUNTER)
#undef DECLARE_PROFILER_COUNTER
};

class Profiler : public AllStatic {
 public:
  static void Init();
  static void InitAllocationSampleBuffer();
  static void Cleanup();

  static void SetSampleDepth(intptr_t depth);
  static void SetSamplePeriod(intptr_t period);
  // Restarts sampling with a given profile period. This is called after the
  // profile period is changed via the service protocol.
  static void UpdateSamplePeriod();
  // Starts or shuts down the profiler after --profiler is changed via the
  // service protocol.
  static void UpdateRunningState();

  static SampleBuffer* sample_buffer() { return sample_buffer_; }
  static AllocationSampleBuffer* allocation_sample_buffer() {
    return allocation_sample_buffer_;
  }

  static void DumpStackTrace(void* context);
  static void DumpStackTrace(bool for_crash = true);

  static void SampleAllocation(Thread* thread,
                               intptr_t cid,
                               uint32_t identity_hash);
  static Sample* SampleNativeAllocation(intptr_t skip_count,
                                        uword address,
                                        uintptr_t allocation_size);

  // SampleThread is called from inside the signal handler and hence it is very
  // critical that the implementation of SampleThread does not do any of the
  // following:
  //   * Accessing TLS -- Because on Windows and Fuchsia the callback will be
  //                      running in a different thread.
  //   * Allocating memory -- Because this takes locks which may already be
  //                          held, resulting in a dead lock.
  //   * Taking a lock -- See above.
  static void SampleThread(Thread* thread, const InterruptedThreadState& state);

  static ProfilerCounters counters() {
    // Copies the counter values.
    return counters_;
  }
  inline static intptr_t Size();

 private:
  static void DumpStackTrace(uword sp, uword fp, uword pc, bool for_crash);

  // Calculates the sample buffer capacity. Returns
  // SampleBuffer::kDefaultBufferCapacity if --sample-buffer-duration is not
  // provided. Otherwise, the capacity is based on the sample rate, maximum
  // sample stack depth, and the number of seconds of samples the sample buffer
  // should be able to accomodate.
  static intptr_t CalculateSampleBufferCapacity();

  // Does not walk the thread's stack.
  static void SampleThreadSingleFrame(Thread* thread, uintptr_t pc);
  static RelaxedAtomic<bool> initialized_;

  static SampleBuffer* sample_buffer_;
  static AllocationSampleBuffer* allocation_sample_buffer_;

  static ProfilerCounters counters_;

  friend class Thread;
};

class SampleVisitor : public ValueObject {
 public:
  explicit SampleVisitor(Dart_Port port) : port_(port), visited_(0) {}
  virtual ~SampleVisitor() {}

  virtual void VisitSample(Sample* sample) = 0;

  intptr_t visited() const { return visited_; }

  void IncrementVisited() { visited_++; }

  Dart_Port port() const { return port_; }

 private:
  Dart_Port port_;
  intptr_t visited_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor);
};

class SampleFilter : public ValueObject {
 public:
  SampleFilter(Dart_Port port,
               intptr_t thread_task_mask,
               int64_t time_origin_micros,
               int64_t time_extent_micros)
      : port_(port),
        thread_task_mask_(thread_task_mask),
        time_origin_micros_(time_origin_micros),
        time_extent_micros_(time_extent_micros) {
    ASSERT(thread_task_mask != 0);
    ASSERT(time_origin_micros_ >= -1);
    ASSERT(time_extent_micros_ >= -1);
  }
  virtual ~SampleFilter() {}

  // Override this function.
  // Return |true| if |sample| passes the filter.
  virtual bool FilterSample(Sample* sample) { return true; }

  Dart_Port port() const { return port_; }

  // Returns |true| if |sample| passes the time filter.
  bool TimeFilterSample(Sample* sample);

  // Returns |true| if |sample| passes the thread task filter.
  bool TaskFilterSample(Sample* sample);

  static const intptr_t kNoTaskFilter = -1;

 private:
  Dart_Port port_;
  intptr_t thread_task_mask_;
  int64_t time_origin_micros_;
  int64_t time_extent_micros_;
};

class ClearProfileVisitor : public SampleVisitor {
 public:
  explicit ClearProfileVisitor(Isolate* isolate);

  virtual void VisitSample(Sample* sample);
};

// Each Sample holds a stack trace from an isolate.
class Sample {
 public:
  void Init(Dart_Port port, int64_t timestamp, ThreadId tid) {
    Clear();
    timestamp_ = timestamp;
    tid_ = tid;
    port_ = port;
  }

  Dart_Port port() const { return port_; }

  // Thread sample was taken on.
  ThreadId tid() const { return tid_; }

  void Clear() {
    timestamp_ = 0;
    port_ = ILLEGAL_PORT;
    tid_ = OSThread::kInvalidThreadId;
    for (intptr_t i = 0; i < kStackBufferSizeInWords; i++) {
      stack_buffer_[i] = 0;
    }
    for (intptr_t i = 0; i < kPCArraySizeInWords; i++) {
      pc_array_[i] = 0;
    }
    vm_tag_ = VMTag::kInvalidTagId;
    user_tag_ = UserTags::kDefaultUserTag;
    state_ = 0;
    continuation_index_ = -1;
    allocation_identity_hash_ = 0;
#if defined(DART_USE_TCMALLOC) && defined(DEBUG)
    native_allocation_address_ = 0;
    native_allocation_size_bytes_ = 0;
    next_free_ = NULL;
#endif
    set_head_sample(true);
  }

  // Timestamp sample was taken at.
  int64_t timestamp() const { return timestamp_; }

  // Top most pc.
  uword pc() const { return At(0); }

  // Get stack trace entry.
  uword At(intptr_t i) const {
    ASSERT(i >= 0);
    ASSERT(i < kPCArraySizeInWords);
    return pc_array_[i];
  }

  // Set stack trace entry.
  void SetAt(intptr_t i, uword pc) {
    ASSERT(i >= 0);
    ASSERT(i < kPCArraySizeInWords);
    pc_array_[i] = pc;
  }

  void DumpStackTrace() {
    for (intptr_t i = 0; i < kPCArraySizeInWords; ++i) {
      uintptr_t start = 0;
      uword pc = At(i);
      char* native_symbol_name =
          NativeSymbolResolver::LookupSymbolName(pc, &start);
      if (native_symbol_name == NULL) {
        OS::PrintErr("  [0x%" Pp "] Unknown symbol\n", pc);
      } else {
        OS::PrintErr("  [0x%" Pp "] %s\n", pc, native_symbol_name);
        NativeSymbolResolver::FreeSymbolName(native_symbol_name);
      }
    }
  }

  uword vm_tag() const { return vm_tag_; }
  void set_vm_tag(uword tag) {
    ASSERT(tag != VMTag::kInvalidTagId);
    vm_tag_ = tag;
  }

  uword user_tag() const { return user_tag_; }
  void set_user_tag(uword tag) { user_tag_ = tag; }

  bool leaf_frame_is_dart() const { return LeafFrameIsDart::decode(state_); }

  void set_leaf_frame_is_dart(bool leaf_frame_is_dart) {
    state_ = LeafFrameIsDart::update(leaf_frame_is_dart, state_);
  }

  bool ignore_sample() const { return IgnoreBit::decode(state_); }

  void set_ignore_sample(bool ignore_sample) {
    state_ = IgnoreBit::update(ignore_sample, state_);
  }

  bool exit_frame_sample() const { return ExitFrameBit::decode(state_); }

  void set_exit_frame_sample(bool exit_frame_sample) {
    state_ = ExitFrameBit::update(exit_frame_sample, state_);
  }

  bool missing_frame_inserted() const {
    return MissingFrameInsertedBit::decode(state_);
  }

  void set_missing_frame_inserted(bool missing_frame_inserted) {
    state_ = MissingFrameInsertedBit::update(missing_frame_inserted, state_);
  }

  bool truncated_trace() const { return TruncatedTraceBit::decode(state_); }

  void set_truncated_trace(bool truncated_trace) {
    state_ = TruncatedTraceBit::update(truncated_trace, state_);
  }

  bool is_allocation_sample() const {
    return ClassAllocationSampleBit::decode(state_);
  }

  void set_is_allocation_sample(bool allocation_sample) {
    state_ = ClassAllocationSampleBit::update(allocation_sample, state_);
  }

  uint32_t allocation_identity_hash() const {
    return allocation_identity_hash_;
  }

  void set_allocation_identity_hash(uint32_t hash) {
    allocation_identity_hash_ = hash;
  }

#if defined(DART_USE_TCMALLOC) && defined(DEBUG)
  uword native_allocation_address() const { return native_allocation_address_; }
  void set_native_allocation_address(uword address) {
    native_allocation_address_ = address;
  }

  uintptr_t native_allocation_size_bytes() const {
    return native_allocation_size_bytes_;
  }
  void set_native_allocation_size_bytes(uintptr_t size) {
    native_allocation_size_bytes_ = size;
  }

  Sample* next_free() const { return next_free_; }
  void set_next_free(Sample* next_free) { next_free_ = next_free; }
#else
  uword native_allocation_address() const { return 0; }
  void set_native_allocation_address(uword address) { UNREACHABLE(); }

  uintptr_t native_allocation_size_bytes() const { return 0; }
  void set_native_allocation_size_bytes(uintptr_t size) { UNREACHABLE(); }

  Sample* next_free() const { return nullptr; }
  void set_next_free(Sample* next_free) { UNREACHABLE(); }
#endif  // defined(DART_USE_TCMALLOC) && defined(DEBUG)

  Thread::TaskKind thread_task() const { return ThreadTaskBit::decode(state_); }

  void set_thread_task(Thread::TaskKind task) {
    state_ = ThreadTaskBit::update(task, state_);
  }

  bool is_continuation_sample() const {
    return ContinuationSampleBit::decode(state_);
  }

  void SetContinuationIndex(intptr_t index) {
    ASSERT(!is_continuation_sample());
    ASSERT(continuation_index_ == -1);
    state_ = ContinuationSampleBit::update(true, state_);
    continuation_index_ = index;
    ASSERT(is_continuation_sample());
  }

  intptr_t continuation_index() const {
    ASSERT(is_continuation_sample());
    return continuation_index_;
  }

  intptr_t allocation_cid() const {
    ASSERT(is_allocation_sample());
    return metadata();
  }

  void set_head_sample(bool head_sample) {
    state_ = HeadSampleBit::update(head_sample, state_);
  }

  bool head_sample() const { return HeadSampleBit::decode(state_); }

  intptr_t metadata() const { return MetadataBits::decode(state_); }
  void set_metadata(intptr_t metadata) {
    state_ = MetadataBits::update(metadata, state_);
  }

  void SetAllocationCid(intptr_t cid) {
    set_is_allocation_sample(true);
    set_metadata(cid);
  }

  static constexpr int kPCArraySizeInWords = 8;
  uword* GetPCArray() { return &pc_array_[0]; }

  static constexpr int kStackBufferSizeInWords = 2;
  uword* GetStackBuffer() { return &stack_buffer_[0]; }

 private:
  enum StateBits {
    kHeadSampleBit = 0,
    kLeafFrameIsDartBit = 1,
    kIgnoreBit = 2,
    kExitFrameBit = 3,
    kMissingFrameInsertedBit = 4,
    kTruncatedTraceBit = 5,
    kClassAllocationSampleBit = 6,
    kContinuationSampleBit = 7,
    kThreadTaskBit = 8,  // 6 bits.
    kMetadataBit = 14,   // 16 bits.
    kNextFreeBit = 30,
  };
  class HeadSampleBit : public BitField<uint32_t, bool, kHeadSampleBit, 1> {};
  class LeafFrameIsDart
      : public BitField<uint32_t, bool, kLeafFrameIsDartBit, 1> {};
  class IgnoreBit : public BitField<uint32_t, bool, kIgnoreBit, 1> {};
  class ExitFrameBit : public BitField<uint32_t, bool, kExitFrameBit, 1> {};
  class MissingFrameInsertedBit
      : public BitField<uint32_t, bool, kMissingFrameInsertedBit, 1> {};
  class TruncatedTraceBit
      : public BitField<uint32_t, bool, kTruncatedTraceBit, 1> {};
  class ClassAllocationSampleBit
      : public BitField<uint32_t, bool, kClassAllocationSampleBit, 1> {};
  class ContinuationSampleBit
      : public BitField<uint32_t, bool, kContinuationSampleBit, 1> {};
  class ThreadTaskBit
      : public BitField<uint32_t, Thread::TaskKind, kThreadTaskBit, 6> {};
  class MetadataBits : public BitField<uint32_t, intptr_t, kMetadataBit, 16> {};

  int64_t timestamp_;
  Dart_Port port_;
  ThreadId tid_;
  uword stack_buffer_[kStackBufferSizeInWords];
  uword pc_array_[kPCArraySizeInWords];
  uword vm_tag_;
  uword user_tag_;
  uint32_t state_;
  int32_t continuation_index_;
  uint32_t allocation_identity_hash_;

#if defined(DART_USE_TCMALLOC) && defined(DEBUG)
  uword native_allocation_address_;
  uintptr_t native_allocation_size_bytes_;
  Sample* next_free_;
#endif

  DISALLOW_COPY_AND_ASSIGN(Sample);
};

class NativeAllocationSampleFilter : public SampleFilter {
 public:
  NativeAllocationSampleFilter(int64_t time_origin_micros,
                               int64_t time_extent_micros)
      : SampleFilter(ILLEGAL_PORT,
                     SampleFilter::kNoTaskFilter,
                     time_origin_micros,
                     time_extent_micros) {}

  bool FilterSample(Sample* sample) {
    // If the sample is an allocation sample, we need to check that the
    // memory at the address hasn't been freed, and if the address associated
    // with the allocation has been freed and then reissued.
    void* alloc_address =
        reinterpret_cast<void*>(sample->native_allocation_address());
    ASSERT(alloc_address != NULL);
    Sample* recorded_sample = MallocHooks::GetSample(alloc_address);
    return (sample == recorded_sample);
  }
};

class AbstractCode {
 public:
  explicit AbstractCode(ObjectPtr code) : code_(Object::Handle(code)) {
    ASSERT(code_.IsNull() || code_.IsCode());
  }

  ObjectPtr ptr() const { return code_.ptr(); }
  const Object* handle() const { return &code_; }

  uword PayloadStart() const {
    ASSERT(code_.IsCode());
    return Code::Cast(code_).PayloadStart();
  }

  uword Size() const {
    ASSERT(code_.IsCode());
    return Code::Cast(code_).Size();
  }

  int64_t compile_timestamp() const {
    if (code_.IsCode()) {
      return Code::Cast(code_).compile_timestamp();
    } else {
      return 0;
    }
  }

  const char* Name() const {
    if (code_.IsCode()) {
      return Code::Cast(code_).Name();
    } else {
      return "";
    }
  }

  const char* QualifiedName() const {
    if (code_.IsCode()) {
      return Code::Cast(code_).QualifiedName(
          NameFormattingParams(Object::kUserVisibleName));
    } else {
      return "";
    }
  }

  bool IsStubCode() const {
    if (code_.IsCode()) {
      return Code::Cast(code_).IsStubCode();
    } else {
      return false;
    }
  }

  bool IsAllocationStubCode() const {
    if (code_.IsCode()) {
      return Code::Cast(code_).IsAllocationStubCode();
    } else {
      return false;
    }
  }

  bool IsTypeTestStubCode() const {
    if (code_.IsCode()) {
      return Code::Cast(code_).IsTypeTestStubCode();
    } else {
      return false;
    }
  }

  ObjectPtr owner() const {
    if (code_.IsCode()) {
      return Code::Cast(code_).owner();
    } else {
      return Object::null();
    }
  }

  bool IsNull() const { return code_.IsNull(); }
  bool IsCode() const { return code_.IsCode(); }

  bool is_optimized() const {
    if (code_.IsCode()) {
      return Code::Cast(code_).is_optimized();
    } else {
      return false;
    }
  }

 private:
  const Object& code_;
};

// A Code object descriptor.
class CodeDescriptor : public ZoneAllocated {
 public:
  explicit CodeDescriptor(const AbstractCode code);

  uword Start() const;

  uword Size() const;

  int64_t CompileTimestamp() const;

  const AbstractCode code() const { return code_; }

  const char* Name() const { return code_.Name(); }

  bool Contains(uword pc) const {
    uword end = Start() + Size();
    return (pc >= Start()) && (pc < end);
  }

  static int Compare(CodeDescriptor* const* a, CodeDescriptor* const* b) {
    ASSERT(a != NULL);
    ASSERT(b != NULL);

    uword a_start = (*a)->Start();
    uword b_start = (*b)->Start();

    if (a_start < b_start) {
      return -1;
    } else if (a_start > b_start) {
      return 1;
    } else {
      return 0;
    }
  }

 private:
  const AbstractCode code_;

  DISALLOW_COPY_AND_ASSIGN(CodeDescriptor);
};

// Fast lookup of Dart code objects.
class CodeLookupTable : public ZoneAllocated {
 public:
  explicit CodeLookupTable(Thread* thread);

  intptr_t length() const { return code_objects_.length(); }

  const CodeDescriptor* At(intptr_t index) const {
    return code_objects_.At(index);
  }

  const CodeDescriptor* FindCode(uword pc) const;

 private:
  void Build(Thread* thread);

  void Add(const Object& code);

  // Code objects sorted by entry.
  ZoneGrowableArray<CodeDescriptor*> code_objects_;

  friend class CodeLookupTableBuilder;

  DISALLOW_COPY_AND_ASSIGN(CodeLookupTable);
};

// Ring buffer of Samples that is (usually) shared by many isolates.
class SampleBuffer {
 public:
  // Up to 1 minute @ 1000Hz, less if samples are deep.
  static const intptr_t kDefaultBufferCapacity = 60000;

  explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity);
  virtual ~SampleBuffer();

  intptr_t capacity() const { return capacity_; }

  Sample* At(intptr_t idx) const;
  intptr_t ReserveSampleSlot();
  virtual Sample* ReserveSample();
  virtual Sample* ReserveSampleAndLink(Sample* previous);

  void VisitSamples(SampleVisitor* visitor) {
    ASSERT(visitor != NULL);
    const intptr_t length = capacity();
    for (intptr_t i = 0; i < length; i++) {
      Sample* sample = At(i);
      if (!sample->head_sample()) {
        // An inner sample in a chain of samples.
        continue;
      }
      if (sample->ignore_sample()) {
        // Bad sample.
        continue;
      }
      if (sample->port() != visitor->port()) {
        // Another isolate.
        continue;
      }
      if (sample->timestamp() == 0) {
        // Empty.
        continue;
      }
      if (sample->At(0) == 0) {
        // No frames.
        continue;
      }
      visitor->IncrementVisited();
      visitor->VisitSample(sample);
    }
  }

  ProcessedSampleBuffer* BuildProcessedSampleBuffer(SampleFilter* filter);

  intptr_t Size() { return memory_->size(); }

 protected:
  ProcessedSample* BuildProcessedSample(Sample* sample,
                                        const CodeLookupTable& clt);
  Sample* Next(Sample* sample);

  VirtualMemory* memory_;
  Sample* samples_;
  intptr_t capacity_;
  RelaxedAtomic<uintptr_t> cursor_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SampleBuffer);
};

class AllocationSampleBuffer : public SampleBuffer {
 public:
  explicit AllocationSampleBuffer(intptr_t capacity = kDefaultBufferCapacity);
  virtual ~AllocationSampleBuffer();

  intptr_t ReserveSampleSlotLocked();
  virtual Sample* ReserveSample();
  virtual Sample* ReserveSampleAndLink(Sample* previous);
  void FreeAllocationSample(Sample* sample);

 private:
  Mutex mutex_;
  Sample* free_sample_list_;

  DISALLOW_COPY_AND_ASSIGN(AllocationSampleBuffer);
};

intptr_t Profiler::Size() {
  intptr_t size = 0;
  if (sample_buffer_ != nullptr) {
    size += sample_buffer_->Size();
  }
  if (allocation_sample_buffer_ != nullptr) {
    size += allocation_sample_buffer_->Size();
  }
  return size;
}

// A |ProcessedSample| is a combination of 1 (or more) |Sample|(s) that have
// been merged into a logical sample. The raw data may have been processed to
// improve the quality of the stack trace.
class ProcessedSample : public ZoneAllocated {
 public:
  ProcessedSample();

  // Add |pc| to stack trace.
  void Add(uword pc) { pcs_.Add(pc); }

  // Insert |pc| at |index|.
  void InsertAt(intptr_t index, uword pc) { pcs_.InsertAt(index, pc); }

  // Number of pcs in stack trace.
  intptr_t length() const { return pcs_.length(); }

  // Get |pc| at |index|.
  uword At(intptr_t index) const {
    ASSERT(index >= 0);
    ASSERT(index < length());
    return pcs_[index];
  }

  // Timestamp sample was taken at.
  int64_t timestamp() const { return timestamp_; }
  void set_timestamp(int64_t timestamp) { timestamp_ = timestamp; }

  ThreadId tid() const { return tid_; }
  void set_tid(ThreadId tid) { tid_ = tid; }

  // The VM tag.
  uword vm_tag() const { return vm_tag_; }
  void set_vm_tag(uword tag) { vm_tag_ = tag; }

  // The user tag.
  uword user_tag() const { return user_tag_; }
  void set_user_tag(uword tag) { user_tag_ = tag; }

  // The class id if this is an allocation profile sample. -1 otherwise.
  intptr_t allocation_cid() const { return allocation_cid_; }
  void set_allocation_cid(intptr_t cid) { allocation_cid_ = cid; }

  // The identity hash code of the allocated object if this is an allocation
  // profile sample. -1 otherwise.
  uint32_t allocation_identity_hash() const {
    return allocation_identity_hash_;
  }
  void set_allocation_identity_hash(uint32_t hash) {
    allocation_identity_hash_ = hash;
  }

  bool IsAllocationSample() const { return allocation_cid_ > 0; }

  bool is_native_allocation_sample() const {
    return native_allocation_size_bytes_ != 0;
  }

  uintptr_t native_allocation_size_bytes() const {
    return native_allocation_size_bytes_;
  }
  void set_native_allocation_size_bytes(uintptr_t allocation_size) {
    native_allocation_size_bytes_ = allocation_size;
  }

  // Was the stack trace truncated?
  bool truncated() const { return truncated_; }
  void set_truncated(bool truncated) { truncated_ = truncated; }

  // Was the first frame in the stack trace executing?
  bool first_frame_executing() const { return first_frame_executing_; }
  void set_first_frame_executing(bool first_frame_executing) {
    first_frame_executing_ = first_frame_executing;
  }

  ProfileTrieNode* timeline_code_trie() const { return timeline_code_trie_; }
  void set_timeline_code_trie(ProfileTrieNode* trie) {
    ASSERT(timeline_code_trie_ == NULL);
    timeline_code_trie_ = trie;
  }

  ProfileTrieNode* timeline_function_trie() const {
    return timeline_function_trie_;
  }
  void set_timeline_function_trie(ProfileTrieNode* trie) {
    ASSERT(timeline_function_trie_ == NULL);
    timeline_function_trie_ = trie;
  }

 private:
  void FixupCaller(const CodeLookupTable& clt,
                   uword pc_marker,
                   uword* stack_buffer);

  void CheckForMissingDartFrame(const CodeLookupTable& clt,
                                const CodeDescriptor* code,
                                uword pc_marker,
                                uword* stack_buffer);

  ZoneGrowableArray<uword> pcs_;
  int64_t timestamp_;
  ThreadId tid_;
  uword vm_tag_;
  uword user_tag_;
  intptr_t allocation_cid_;
  uint32_t allocation_identity_hash_;
  bool truncated_;
  bool first_frame_executing_;
  uword native_allocation_address_;
  uintptr_t native_allocation_size_bytes_;
  ProfileTrieNode* timeline_code_trie_;
  ProfileTrieNode* timeline_function_trie_;

  friend class SampleBuffer;
  DISALLOW_COPY_AND_ASSIGN(ProcessedSample);
};

// A collection of |ProcessedSample|s.
class ProcessedSampleBuffer : public ZoneAllocated {
 public:
  ProcessedSampleBuffer();

  void Add(ProcessedSample* sample) { samples_.Add(sample); }

  intptr_t length() const { return samples_.length(); }

  ProcessedSample* At(intptr_t index) { return samples_.At(index); }

  const CodeLookupTable& code_lookup_table() const {
    return *code_lookup_table_;
  }

 private:
  ZoneGrowableArray<ProcessedSample*> samples_;
  CodeLookupTable* code_lookup_table_;

  DISALLOW_COPY_AND_ASSIGN(ProcessedSampleBuffer);
};

}  // namespace dart

#endif  // RUNTIME_VM_PROFILER_H_
