// 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 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() {
    count_++;
  }

  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_;
  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 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 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_
