// Copyright (c) 2015, 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_SERVICE_H_
#define RUNTIME_VM_PROFILER_SERVICE_H_

#include "vm/allocation.h"
#include "vm/code_observers.h"
#include "vm/globals.h"
#include "vm/growable_array.h"
#include "vm/object.h"
#include "vm/tags.h"
#include "vm/thread_interrupter.h"
#include "vm/token_position.h"

// CPU Profile model and service protocol bits.
// NOTE: For sampling and stack walking related code, see profiler.h.

namespace dart {

// Forward declarations.
class Code;
class Function;
class JSONArray;
class JSONStream;
class ProfileFunctionTable;
class ProfileCodeTable;
class RawCode;
class RawFunction;
class SampleFilter;
class ProcessedSample;
class ProcessedSampleBuffer;

class ProfileFunctionSourcePosition {
 public:
  explicit ProfileFunctionSourcePosition(TokenPosition token_pos);

  void Tick(bool exclusive);

  TokenPosition token_pos() const { return token_pos_; }
  intptr_t exclusive_ticks() const { return exclusive_ticks_; }
  intptr_t inclusive_ticks() const { return inclusive_ticks_; }

 private:
  TokenPosition token_pos_;
  intptr_t exclusive_ticks_;
  intptr_t inclusive_ticks_;

  DISALLOW_ALLOCATION();
};


// Profile data related to a |Function|.
class ProfileFunction : public ZoneAllocated {
 public:
  enum Kind {
    kDartFunction,     // Dart function.
    kNativeFunction,   // Synthetic function for Native (C/C++).
    kTagFunction,      // Synthetic function for a VM or User tag.
    kStubFunction,     // Synthetic function for stub code.
    kUnknownFunction,  // A singleton function for unknown objects.
  };

  ProfileFunction(Kind kind,
                  const char* name,
                  const Function& function,
                  const intptr_t table_index);

  const char* name() const {
    ASSERT(name_ != NULL);
    return name_;
  }

  const char* Name() const;

  const Function* function() const { return &function_; }

  bool is_visible() const;

  intptr_t table_index() const { return table_index_; }

  Kind kind() const { return kind_; }

  intptr_t exclusive_ticks() const { return exclusive_ticks_; }
  intptr_t inclusive_ticks() const { return inclusive_ticks_; }

  void IncInclusiveTicks() { inclusive_ticks_++; }

  void Tick(bool exclusive,
            intptr_t inclusive_serial,
            TokenPosition token_position);

  static const char* KindToCString(Kind kind);

  void PrintToJSONArray(JSONArray* functions);

  // Returns true if the call was successful and |pfsp| is set.
  bool GetSinglePosition(ProfileFunctionSourcePosition* pfsp);

  void TickSourcePosition(TokenPosition token_position, bool exclusive);

  intptr_t NumSourcePositions() const {
    return source_position_ticks_.length();
  }

  const ProfileFunctionSourcePosition& GetSourcePosition(intptr_t i) const {
    return source_position_ticks_.At(i);
  }

 private:
  const Kind kind_;
  const char* name_;
  const Function& function_;
  const intptr_t table_index_;
  ZoneGrowableArray<intptr_t> profile_codes_;
  ZoneGrowableArray<ProfileFunctionSourcePosition> source_position_ticks_;

  intptr_t exclusive_ticks_;
  intptr_t inclusive_ticks_;
  intptr_t inclusive_serial_;

  void PrintToJSONObject(JSONObject* func);
  // A |ProfileCode| that contains this function.
  void AddProfileCode(intptr_t code_table_index);

  friend class ProfileCode;
  friend class ProfileBuilder;
};


class ProfileCodeAddress {
 public:
  explicit ProfileCodeAddress(uword pc);

  void Tick(bool exclusive);

  uword pc() const { return pc_; }
  intptr_t exclusive_ticks() const { return exclusive_ticks_; }
  intptr_t inclusive_ticks() const { return inclusive_ticks_; }

 private:
  uword pc_;
  intptr_t exclusive_ticks_;
  intptr_t inclusive_ticks_;
};


// Profile data related to a |Code|.
class ProfileCode : public ZoneAllocated {
 public:
  enum Kind {
    kDartCode,       // Live Dart code.
    kCollectedCode,  // Dead Dart code.
    kNativeCode,     // Native code.
    kReusedCode,     // Dead Dart code that has been reused by new kDartCode.
    kTagCode,        // A special kind of code representing a tag.
  };

  ProfileCode(Kind kind,
              uword start,
              uword end,
              int64_t timestamp,
              const Code& code);

  Kind kind() const { return kind_; }

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

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

  void AdjustExtent(uword start, uword end);

  bool Contains(uword pc) const { return (pc >= start_) && (pc < end_); }

  bool Overlaps(const ProfileCode* other) const;

  int64_t compile_timestamp() const { return compile_timestamp_; }
  void set_compile_timestamp(int64_t timestamp) {
    compile_timestamp_ = timestamp;
  }

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

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

  bool IsOptimizedDart() const;
  RawCode* code() const { return code_.raw(); }

  const char* name() const { return name_; }
  void SetName(const char* name);
  void GenerateAndSetSymbolName(const char* prefix);

  static const char* KindToCString(Kind kind);

  void PrintToJSONArray(JSONArray* codes);

 private:
  void Tick(uword pc, bool exclusive, intptr_t serial);
  void TickAddress(uword pc, bool exclusive);

  ProfileFunction* SetFunctionAndName(ProfileFunctionTable* table);

  ProfileFunction* function() const { return function_; }

  void PrintNativeCode(JSONObject* profile_code_obj);
  void PrintCollectedCode(JSONObject* profile_code_obj);
  void PrintOverwrittenCode(JSONObject* profile_code_obj);
  void PrintTagCode(JSONObject* profile_code_obj);

  void set_code_table_index(intptr_t index) { code_table_index_ = index; }
  intptr_t code_table_index() const { return code_table_index_; }

  const Kind kind_;
  uword start_;
  uword end_;
  intptr_t exclusive_ticks_;
  intptr_t inclusive_ticks_;
  intptr_t inclusive_serial_;

  const Code& code_;
  char* name_;
  int64_t compile_timestamp_;
  ProfileFunction* function_;
  intptr_t code_table_index_;
  ZoneGrowableArray<ProfileCodeAddress> address_ticks_;

  friend class ProfileBuilder;
};


// Stack traces are organized in a trie. This holds information about one node
// in the trie. A node in a tree represents a stack frame and a path in the tree
// represents a stack trace. Each unique stack trace appears in the tree once
// and each node has a count indicating how many times this has been observed.
// The index can be used to look up a |ProfileFunction| or |ProfileCode|.
// A node can have zero or more children. Depending on the kind of trie the
// children are callers or callees of the current node.
class ProfileTrieNode : public ZoneAllocated {
 public:
  explicit ProfileTrieNode(intptr_t index);
  virtual ~ProfileTrieNode();

  virtual void PrintToJSONArray(JSONArray* array) const = 0;

  // Index into function or code tables.
  intptr_t table_index() const { return table_index_; }

  intptr_t count() const { return count_; }

  void Tick(ProcessedSample* sample, bool exclusive = false);

  void IncrementAllocation(intptr_t allocation, bool exclusive) {
    ASSERT(allocation >= 0);
    if (exclusive) {
      exclusive_allocations_ += allocation;
    }
    inclusive_allocations_ += allocation;
  }

  intptr_t inclusive_allocations() const { return inclusive_allocations_; }
  intptr_t exclusive_allocations() const { return exclusive_allocations_; }

  intptr_t NumChildren() const { return children_.length(); }

  ProfileTrieNode* At(intptr_t i) { return children_.At(i); }

  intptr_t IndexOf(ProfileTrieNode* node);

  intptr_t frame_id() const { return frame_id_; }
  void set_frame_id(intptr_t id) {
    ASSERT(frame_id_ == -1);
    frame_id_ = id;
  }

 protected:
  void SortChildren();

  static int ProfileTrieNodeCompare(ProfileTrieNode* const* a,
                                    ProfileTrieNode* const* b) {
    ASSERT(a != NULL);
    ASSERT(b != NULL);
    return (*b)->count() - (*a)->count();
  }


  intptr_t table_index_;
  intptr_t count_;
  intptr_t exclusive_allocations_;
  intptr_t inclusive_allocations_;
  ZoneGrowableArray<ProfileTrieNode*> children_;
  intptr_t frame_id_;

  friend class ProfileBuilder;
};


// The model for a profile. Most of the model is zone allocated, therefore
// a zone must be created that lives longer than this object.
class Profile : public ValueObject {
 public:
  enum TagOrder { kNoTags, kUser, kUserVM, kVM, kVMUser };

  enum TrieKind {
    kExclusiveCode,
    kExclusiveFunction,
    kInclusiveCode,
    kInclusiveFunction,
    kNumTrieKinds,
  };

  static bool IsCodeTrie(TrieKind kind) {
    return (kind == kExclusiveCode) || (kind == kInclusiveCode);
  }

  static bool IsFunctionTrie(TrieKind kind) { return !IsCodeTrie(kind); }

  explicit Profile(Isolate* isolate);

  // Build a filtered model using |filter| with the specified |tag_order|.
  void Build(Thread* thread,
             SampleFilter* filter,
             TagOrder tag_order,
             intptr_t extra_tags = 0);

  // After building:
  int64_t min_time() const { return min_time_; }
  int64_t max_time() const { return max_time_; }
  int64_t GetTimeSpan() const { return max_time() - min_time(); }
  intptr_t sample_count() const { return sample_count_; }

  intptr_t NumFunctions() const;

  ProfileFunction* GetFunction(intptr_t index);
  ProfileCode* GetCode(intptr_t index);
  ProfileTrieNode* GetTrieRoot(TrieKind trie_kind);

  void PrintProfileJSON(JSONStream* stream);
  void PrintTimelineJSON(JSONStream* stream);

  ProfileFunction* FindFunction(const Function& function);

 private:
  void PrintHeaderJSON(JSONObject* obj);
  void PrintTimelineFrameJSON(JSONObject* frames,
                              ProfileTrieNode* current,
                              ProfileTrieNode* parent,
                              intptr_t* next_id);

  Isolate* isolate_;
  Zone* zone_;
  ProcessedSampleBuffer* samples_;
  ProfileCodeTable* live_code_;
  ProfileCodeTable* dead_code_;
  ProfileCodeTable* tag_code_;
  ProfileFunctionTable* functions_;
  intptr_t dead_code_index_offset_;
  intptr_t tag_code_index_offset_;

  ProfileTrieNode* roots_[kNumTrieKinds];

  int64_t min_time_;
  int64_t max_time_;

  intptr_t sample_count_;

  friend class ProfileBuilder;
};


class ProfileTrieWalker : public ValueObject {
 public:
  explicit ProfileTrieWalker(Profile* profile)
      : profile_(profile), parent_(NULL), current_(NULL), code_trie_(false) {
    ASSERT(profile_ != NULL);
  }

  void Reset(Profile::TrieKind trie_kind);

  const char* CurrentName();
  // Return the current node's peer's inclusive tick count.
  intptr_t CurrentInclusiveTicks();
  // Return the current node's peer's exclusive tick count.
  intptr_t CurrentExclusiveTicks();
  // Return the current node's inclusive allocation count.
  intptr_t CurrentInclusiveAllocations();
  // Return the current node's exclusive allocation count.
  intptr_t CurrentExclusiveAllocations();
  // Return the current node's tick count.
  intptr_t CurrentNodeTickCount();
  // Return the number siblings (including yourself).
  intptr_t SiblingCount();

  // If the following conditions are met returns the current token:
  // 1) This is a function trie.
  // 2) There is only one token position for a given function.
  // Will return NULL otherwise.
  const char* CurrentToken();

  bool Down();
  bool NextSibling();

 private:
  Profile* profile_;
  ProfileTrieNode* parent_;
  ProfileTrieNode* current_;
  bool code_trie_;
};


class ProfilerService : public AllStatic {
 public:
  enum {
    kNoExtraTags = 0,
    kCodeTransitionTagsBit = (1 << 0),
  };

  static void PrintJSON(JSONStream* stream,
                        Profile::TagOrder tag_order,
                        intptr_t extra_tags,
                        int64_t time_origin_micros,
                        int64_t time_extent_micros);

  static void PrintAllocationJSON(JSONStream* stream,
                                  Profile::TagOrder tag_order,
                                  const Class& cls,
                                  int64_t time_origin_micros,
                                  int64_t time_extent_micros);

  static void PrintNativeAllocationJSON(JSONStream* stream,
                                        Profile::TagOrder tag_order,
                                        int64_t time_origin_micros,
                                        int64_t time_extent_micros);

  static void PrintTimelineJSON(JSONStream* stream,
                                Profile::TagOrder tag_order,
                                int64_t time_origin_micros,
                                int64_t time_extent_micros);

  static void ClearSamples();

 private:
  static void PrintJSONImpl(Thread* thread,
                            JSONStream* stream,
                            Profile::TagOrder tag_order,
                            intptr_t extra_tags,
                            SampleFilter* filter,
                            bool as_timline);
};

}  // namespace dart

#endif  // RUNTIME_VM_PROFILER_SERVICE_H_
