V8 Project
allocation-tracker.cc
Go to the documentation of this file.
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 #include "src/v8.h"
6 
8 #include "src/frames-inl.h"
10 
11 namespace v8 {
12 namespace internal {
13 
15  AllocationTraceTree* tree, unsigned function_info_index)
16  : tree_(tree),
17  function_info_index_(function_info_index),
18  total_size_(0),
19  allocation_count_(0),
20  id_(tree->next_node_id()) {
21 }
22 
23 
25  for (int i = 0; i < children_.length(); i++) delete children_[i];
26 }
27 
28 
30  unsigned function_info_index) {
31  for (int i = 0; i < children_.length(); i++) {
33  if (node->function_info_index() == function_info_index) return node;
34  }
35  return NULL;
36 }
37 
38 
40  unsigned function_info_index) {
42  if (child == NULL) {
44  children_.Add(child);
45  }
46  return child;
47 }
48 
49 
51  total_size_ += size;
53 }
54 
55 
56 void AllocationTraceNode::Print(int indent, AllocationTracker* tracker) {
57  base::OS::Print("%10u %10u %*c", total_size_, allocation_count_, indent, ' ');
58  if (tracker != NULL) {
61  base::OS::Print("%s #%u", info->name, id_);
62  } else {
64  }
65  base::OS::Print("\n");
66  indent += 2;
67  for (int i = 0; i < children_.length(); i++) {
68  children_[i]->Print(indent, tracker);
69  }
70 }
71 
72 
74  : next_node_id_(1),
75  root_(this, 0) {
76 }
77 
78 
80 }
81 
82 
84  const Vector<unsigned>& path) {
85  AllocationTraceNode* node = root();
86  for (unsigned* entry = path.start() + path.length() - 1;
87  entry != path.start() - 1;
88  --entry) {
89  node = node->FindOrAddChild(*entry);
90  }
91  return node;
92 }
93 
94 
96  base::OS::Print("[AllocationTraceTree:]\n");
97  base::OS::Print("Total size | Allocation count | Function id | id\n");
98  root()->Print(0, tracker);
99 }
100 
101 
103  UnresolvedLocation** location) {
104  delete *location;
105 }
106 
107 
109  : name(""),
110  function_id(0),
111  script_name(""),
112  script_id(0),
113  line(-1),
114  column(-1) {
115 }
116 
117 
119  unsigned trace_node_id) {
120  Address end = start + size;
121  RemoveRange(start, end);
122 
123  RangeStack new_range(start, trace_node_id);
124  ranges_.insert(RangeMap::value_type(end, new_range));
125 }
126 
127 
129  RangeMap::const_iterator it = ranges_.upper_bound(addr);
130  if (it == ranges_.end()) return 0;
131  if (it->second.start <= addr) {
132  return it->second.trace_node_id;
133  }
134  return 0;
135 }
136 
137 
139  unsigned trace_node_id = GetTraceNodeId(from);
140  if (trace_node_id == 0) return;
141  RemoveRange(from, from + size);
142  AddRange(to, size, trace_node_id);
143 }
144 
145 
147  ranges_.clear();
148 }
149 
150 
152  PrintF("[AddressToTraceMap (%" V8PRIuPTR "): \n", ranges_.size());
153  for (RangeMap::iterator it = ranges_.begin(); it != ranges_.end(); ++it) {
154  PrintF("[%p - %p] => %u\n", it->second.start, it->first,
155  it->second.trace_node_id);
156  }
157  PrintF("]\n");
158 }
159 
160 
162  RangeMap::iterator it = ranges_.upper_bound(start);
163  if (it == ranges_.end()) return;
164 
165  RangeStack prev_range(0, 0);
166 
167  RangeMap::iterator to_remove_begin = it;
168  if (it->second.start < start) {
169  prev_range = it->second;
170  }
171  do {
172  if (it->first > end) {
173  if (it->second.start < end) {
174  it->second.start = end;
175  }
176  break;
177  }
178  ++it;
179  }
180  while (it != ranges_.end());
181 
182  ranges_.erase(to_remove_begin, it);
183 
184  if (prev_range.start != 0) {
185  ranges_.insert(RangeMap::value_type(start, prev_range));
186  }
187 }
188 
189 
191  delete *info;
192 }
193 
194 
196  HeapObjectsMap* ids, StringsStorage* names)
197  : ids_(ids),
198  names_(names),
199  id_to_function_info_index_(HashMap::PointersMatch),
201  FunctionInfo* info = new FunctionInfo();
202  info->name = "(root)";
203  function_info_list_.Add(info);
204 }
205 
206 
210 }
211 
212 
216  unresolved_locations_.Clear();
217  for (int i = 0; i < copy.length(); i++) {
218  copy[i]->Resolve();
219  delete copy[i];
220  }
221 }
222 
223 
225  DisallowHeapAllocation no_allocation;
226  Heap* heap = ids_->heap();
227 
228  // Mark the new block as FreeSpace to make sure the heap is iterable
229  // while we are capturing stack trace.
231  DCHECK_EQ(HeapObject::FromAddress(addr)->Size(), size);
233 
234  Isolate* isolate = heap->isolate();
235  int length = 0;
236  StackTraceFrameIterator it(isolate);
237  while (!it.done() && length < kMaxAllocationTraceLength) {
238  JavaScriptFrame* frame = it.frame();
239  SharedFunctionInfo* shared = frame->function()->shared();
241  shared->address(), shared->Size(), false);
242  allocation_trace_buffer_[length++] = AddFunctionInfo(shared, id);
243  it.Advance();
244  }
245  if (length == 0) {
246  unsigned index = functionInfoIndexForVMState(isolate->current_vm_state());
247  if (index != 0) {
248  allocation_trace_buffer_[length++] = index;
249  }
250  }
253  top_node->AddAllocation(size);
254 
255  address_to_trace_.AddRange(addr, size, top_node->id());
256 }
257 
258 
260  return ComputeIntegerHash(static_cast<uint32_t>(id),
262 }
263 
264 
266  SnapshotObjectId id) {
267  HashMap::Entry* entry = id_to_function_info_index_.Lookup(
268  reinterpret_cast<void*>(id), SnapshotObjectIdHash(id), true);
269  if (entry->value == NULL) {
270  FunctionInfo* info = new FunctionInfo();
271  info->name = names_->GetFunctionName(shared->DebugName());
272  info->function_id = id;
273  if (shared->script()->IsScript()) {
274  Script* script = Script::cast(shared->script());
275  if (script->name()->IsName()) {
276  Name* name = Name::cast(script->name());
277  info->script_name = names_->GetName(name);
278  }
279  info->script_id = script->id()->value();
280  // Converting start offset into line and column may cause heap
281  // allocations so we postpone them until snapshot serialization.
283  script,
284  shared->start_position(),
285  info));
286  }
287  entry->value = reinterpret_cast<void*>(function_info_list_.length());
288  function_info_list_.Add(info);
289  }
290  return static_cast<unsigned>(reinterpret_cast<intptr_t>((entry->value)));
291 }
292 
293 
295  if (state != OTHER) return 0;
296  if (info_index_for_other_state_ == 0) {
297  FunctionInfo* info = new FunctionInfo();
298  info->name = "(V8 API)";
300  function_info_list_.Add(info);
301  }
303 }
304 
305 
307  Script* script, int start, FunctionInfo* info)
308  : start_position_(start),
309  info_(info) {
311  script->GetIsolate()->global_handles()->Create(script));
312  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
313  this,
315 }
316 
317 
319  if (!script_.is_null()) {
320  GlobalHandles::Destroy(reinterpret_cast<Object**>(script_.location()));
321  }
322 }
323 
324 
326  if (script_.is_null()) return;
327  HandleScope scope(script_->GetIsolate());
328  info_->line = Script::GetLineNumber(script_, start_position_);
329  info_->column = Script::GetColumnNumber(script_, start_position_);
330 }
331 
332 
335  UnresolvedLocation* loc =
336  reinterpret_cast<UnresolvedLocation*>(data.GetParameter());
337  GlobalHandles::Destroy(reinterpret_cast<Object**>(loc->script_.location()));
338  loc->script_ = Handle<Script>::null();
339 }
340 
341 
342 } } // namespace v8::internal
P * GetParameter() const
Definition: v8.h:423
static void Print(const char *format,...)
void MoveObject(Address from, Address to, int size)
void AddRange(Address addr, int size, unsigned node_id)
void RemoveRange(Address start, Address end)
unsigned GetTraceNodeId(Address addr)
AllocationTraceNode * FindOrAddChild(unsigned function_info_index)
AllocationTraceNode(AllocationTraceTree *tree, unsigned function_info_index)
void Print(int indent, AllocationTracker *tracker)
List< AllocationTraceNode * > children_
AllocationTraceNode * FindChild(unsigned function_info_index)
void Print(AllocationTracker *tracker)
AllocationTraceNode * AddPathFromEnd(const Vector< unsigned > &path)
static void HandleWeakScript(const v8::WeakCallbackData< v8::Value, void > &data)
UnresolvedLocation(Script *script, int start, FunctionInfo *info)
unsigned AddFunctionInfo(SharedFunctionInfo *info, SnapshotObjectId id)
unsigned functionInfoIndexForVMState(StateTag state)
unsigned allocation_trace_buffer_[kMaxAllocationTraceLength]
const List< FunctionInfo * > & function_info_list() const
List< UnresolvedLocation * > unresolved_locations_
static void DeleteFunctionInfo(FunctionInfo **info)
List< FunctionInfo * > function_info_list_
AllocationTracker(HeapObjectsMap *ids, StringsStorage *names)
static void DeleteUnresolvedLocation(UnresolvedLocation **location)
void AllocationEvent(Address addr, int size)
static FreeListNode * FromAddress(Address address)
Definition: spaces.h:1406
static bool IsFreeListNode(HeapObject *object)
Definition: spaces-inl.h:303
void set_size(Heap *heap, int size_in_bytes)
Definition: spaces.cc:1955
static void MakeWeak(Object **location, void *parameter, WeakCallback weak_callback)
static void Destroy(Object **location)
Handle< Object > Create(Object *value)
static Handle< T > cast(Handle< S > that)
Definition: handles.h:116
static Handle< T > null()
Definition: handles.h:123
Isolate * GetIsolate() const
Definition: objects-inl.h:1387
static HeapObject * FromAddress(Address address)
Definition: objects-inl.h:1464
SnapshotObjectId FindOrAddEntry(Address addr, unsigned int size, bool accessed=true)
Isolate * isolate()
Definition: heap-inl.h:589
GlobalHandles * global_handles()
Definition: isolate.h:917
JSFunction * function() const
Definition: frames-inl.h:265
void AddAll(const List< T, AllocationPolicy > &other, AllocationPolicy allocator=AllocationPolicy())
static int GetColumnNumber(Handle< Script > script, int code_pos)
Definition: objects.cc:9635
static int GetLineNumber(Handle< Script > script, int code_pos)
Definition: objects.cc:9673
const char * GetFunctionName(Name *name)
const char * GetName(Name *name)
Entry * Lookup(void *key, uint32_t hash, bool insert, AllocationPolicy allocator=AllocationPolicy())
Definition: hashmap.h:114
T * start() const
Definition: vector.h:47
int length() const
Definition: vector.h:41
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes to(mksnapshot only)") DEFINE_STRING(raw_context_file
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
#define DCHECK_EQ(v1, v2)
Definition: logging.h:206
#define V8PRIuPTR
Definition: macros.h:365
static const uint32_t kZeroHashSeed
Definition: utils.h:245
byte * Address
Definition: globals.h:101
void PrintF(const char *format,...)
Definition: utils.cc:80
uint32_t ComputeIntegerHash(uint32_t key, uint32_t seed)
Definition: utils.h:249
static uint32_t SnapshotObjectIdHash(SnapshotObjectId id)
ContainedInLattice AddRange(ContainedInLattice containment, const int *ranges, int ranges_length, Interval new_range)
Definition: jsregexp.cc:99
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
uint32_t SnapshotObjectId
Definition: v8-profiler.h:16