Home | History | Annotate | Download | only in src
      1 // Copyright 2013 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_ALLOCATION_TRACKER_H_
      6 #define V8_ALLOCATION_TRACKER_H_
      7 
      8 #include <map>
      9 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 class HeapObjectsMap;
     14 
     15 class AllocationTraceTree;
     16 
     17 class AllocationTraceNode {
     18  public:
     19   AllocationTraceNode(AllocationTraceTree* tree,
     20                       unsigned function_info_index);
     21   ~AllocationTraceNode();
     22   AllocationTraceNode* FindChild(unsigned function_info_index);
     23   AllocationTraceNode* FindOrAddChild(unsigned function_info_index);
     24   void AddAllocation(unsigned size);
     25 
     26   unsigned function_info_index() const { return function_info_index_; }
     27   unsigned allocation_size() const { return total_size_; }
     28   unsigned allocation_count() const { return allocation_count_; }
     29   unsigned id() const { return id_; }
     30   Vector<AllocationTraceNode*> children() const { return children_.ToVector(); }
     31 
     32   void Print(int indent, AllocationTracker* tracker);
     33 
     34  private:
     35   AllocationTraceTree* tree_;
     36   unsigned function_info_index_;
     37   unsigned total_size_;
     38   unsigned allocation_count_;
     39   unsigned id_;
     40   List<AllocationTraceNode*> children_;
     41 
     42   DISALLOW_COPY_AND_ASSIGN(AllocationTraceNode);
     43 };
     44 
     45 
     46 class AllocationTraceTree {
     47  public:
     48   AllocationTraceTree();
     49   ~AllocationTraceTree();
     50   AllocationTraceNode* AddPathFromEnd(const Vector<unsigned>& path);
     51   AllocationTraceNode* root() { return &root_; }
     52   unsigned next_node_id() { return next_node_id_++; }
     53   void Print(AllocationTracker* tracker);
     54 
     55  private:
     56   unsigned next_node_id_;
     57   AllocationTraceNode root_;
     58 
     59   DISALLOW_COPY_AND_ASSIGN(AllocationTraceTree);
     60 };
     61 
     62 
     63 class AddressToTraceMap {
     64  public:
     65   void AddRange(Address addr, int size, unsigned node_id);
     66   unsigned GetTraceNodeId(Address addr);
     67   void MoveObject(Address from, Address to, int size);
     68   void Clear();
     69   size_t size() { return ranges_.size(); }
     70   void Print();
     71 
     72  private:
     73   struct RangeStack {
     74     RangeStack(Address start, unsigned node_id)
     75         : start(start), trace_node_id(node_id) {}
     76     Address start;
     77     unsigned trace_node_id;
     78   };
     79   // [start, end) -> trace
     80   typedef std::map<Address, RangeStack> RangeMap;
     81 
     82   void RemoveRange(Address start, Address end);
     83 
     84   RangeMap ranges_;
     85 };
     86 
     87 class AllocationTracker {
     88  public:
     89   struct FunctionInfo {
     90     FunctionInfo();
     91     const char* name;
     92     SnapshotObjectId function_id;
     93     const char* script_name;
     94     int script_id;
     95     int line;
     96     int column;
     97   };
     98 
     99   AllocationTracker(HeapObjectsMap* ids, StringsStorage* names);
    100   ~AllocationTracker();
    101 
    102   void PrepareForSerialization();
    103   void AllocationEvent(Address addr, int size);
    104 
    105   AllocationTraceTree* trace_tree() { return &trace_tree_; }
    106   const List<FunctionInfo*>& function_info_list() const {
    107     return function_info_list_;
    108   }
    109   AddressToTraceMap* address_to_trace() { return &address_to_trace_; }
    110 
    111  private:
    112   unsigned AddFunctionInfo(SharedFunctionInfo* info, SnapshotObjectId id);
    113   static void DeleteFunctionInfo(FunctionInfo** info);
    114   unsigned functionInfoIndexForVMState(StateTag state);
    115 
    116   class UnresolvedLocation {
    117    public:
    118     UnresolvedLocation(Script* script, int start, FunctionInfo* info);
    119     ~UnresolvedLocation();
    120     void Resolve();
    121 
    122    private:
    123     static void HandleWeakScript(
    124         const v8::WeakCallbackData<v8::Value, void>& data);
    125 
    126     Handle<Script> script_;
    127     int start_position_;
    128     FunctionInfo* info_;
    129   };
    130   static void DeleteUnresolvedLocation(UnresolvedLocation** location);
    131 
    132   static const int kMaxAllocationTraceLength = 64;
    133   HeapObjectsMap* ids_;
    134   StringsStorage* names_;
    135   AllocationTraceTree trace_tree_;
    136   unsigned allocation_trace_buffer_[kMaxAllocationTraceLength];
    137   List<FunctionInfo*> function_info_list_;
    138   HashMap id_to_function_info_index_;
    139   List<UnresolvedLocation*> unresolved_locations_;
    140   unsigned info_index_for_other_state_;
    141   AddressToTraceMap address_to_trace_;
    142 
    143   DISALLOW_COPY_AND_ASSIGN(AllocationTracker);
    144 };
    145 
    146 } }  // namespace v8::internal
    147 
    148 #endif  // V8_ALLOCATION_TRACKER_H_
    149