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 
function_info_index()26   unsigned function_info_index() const { return function_info_index_; }
allocation_size()27   unsigned allocation_size() const { return total_size_; }
allocation_count()28   unsigned allocation_count() const { return allocation_count_; }
id()29   unsigned id() const { return id_; }
children()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);
root()51   AllocationTraceNode* root() { return &root_; }
next_node_id()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();
size()69   size_t size() { return ranges_.size(); }
70   void Print();
71 
72  private:
73   struct RangeStack {
RangeStackRangeStack74     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 
trace_tree()105   AllocationTraceTree* trace_tree() { return &trace_tree_; }
function_info_list()106   const List<FunctionInfo*>& function_info_list() const {
107     return function_info_list_;
108   }
address_to_trace()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