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