Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(825)

Side by Side Diff: src/allocation-tracker.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/allocation-tracker.h ('k') | src/api.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 18 matching lines...) Expand all
29 29
30 #include "allocation-tracker.h" 30 #include "allocation-tracker.h"
31 31
32 #include "heap-snapshot-generator.h" 32 #include "heap-snapshot-generator.h"
33 #include "frames-inl.h" 33 #include "frames-inl.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 AllocationTraceNode::AllocationTraceNode( 38 AllocationTraceNode::AllocationTraceNode(
39 AllocationTraceTree* tree, SnapshotObjectId shared_function_info_id) 39 AllocationTraceTree* tree, unsigned function_info_index)
40 : tree_(tree), 40 : tree_(tree),
41 function_id_(shared_function_info_id), 41 function_info_index_(function_info_index),
42 total_size_(0), 42 total_size_(0),
43 allocation_count_(0), 43 allocation_count_(0),
44 id_(tree->next_node_id()) { 44 id_(tree->next_node_id()) {
45 } 45 }
46 46
47 47
48 AllocationTraceNode::~AllocationTraceNode() { 48 AllocationTraceNode::~AllocationTraceNode() {
49 for (int i = 0; i < children_.length(); i++) delete children_[i]; 49 for (int i = 0; i < children_.length(); i++) delete children_[i];
50 } 50 }
51 51
52 52
53 AllocationTraceNode* AllocationTraceNode::FindChild(SnapshotObjectId id) { 53 AllocationTraceNode* AllocationTraceNode::FindChild(
54 unsigned function_info_index) {
54 for (int i = 0; i < children_.length(); i++) { 55 for (int i = 0; i < children_.length(); i++) {
55 AllocationTraceNode* node = children_[i]; 56 AllocationTraceNode* node = children_[i];
56 if (node->function_id() == id) return node; 57 if (node->function_info_index() == function_info_index) return node;
57 } 58 }
58 return NULL; 59 return NULL;
59 } 60 }
60 61
61 62
62 AllocationTraceNode* AllocationTraceNode::FindOrAddChild(SnapshotObjectId id) { 63 AllocationTraceNode* AllocationTraceNode::FindOrAddChild(
63 AllocationTraceNode* child = FindChild(id); 64 unsigned function_info_index) {
65 AllocationTraceNode* child = FindChild(function_info_index);
64 if (child == NULL) { 66 if (child == NULL) {
65 child = new AllocationTraceNode(tree_, id); 67 child = new AllocationTraceNode(tree_, function_info_index);
66 children_.Add(child); 68 children_.Add(child);
67 } 69 }
68 return child; 70 return child;
69 } 71 }
70 72
71 73
72 void AllocationTraceNode::AddAllocation(unsigned size) { 74 void AllocationTraceNode::AddAllocation(unsigned size) {
73 total_size_ += size; 75 total_size_ += size;
74 ++allocation_count_; 76 ++allocation_count_;
75 } 77 }
76 78
77 79
78 void AllocationTraceNode::Print(int indent, AllocationTracker* tracker) { 80 void AllocationTraceNode::Print(int indent, AllocationTracker* tracker) {
79 OS::Print("%10u %10u %*c", total_size_, allocation_count_, indent, ' '); 81 OS::Print("%10u %10u %*c", total_size_, allocation_count_, indent, ' ');
80 if (tracker != NULL) { 82 if (tracker != NULL) {
81 const char* name = "<unknown function>"; 83 AllocationTracker::FunctionInfo* info =
82 if (function_id_ != 0) { 84 tracker->function_info_list()[function_info_index_];
83 AllocationTracker::FunctionInfo* info = 85 OS::Print("%s #%u", info->name, id_);
84 tracker->GetFunctionInfo(function_id_);
85 if (info != NULL) {
86 name = info->name;
87 }
88 }
89 OS::Print("%s #%u", name, id_);
90 } else { 86 } else {
91 OS::Print("%u #%u", function_id_, id_); 87 OS::Print("%u #%u", function_info_index_, id_);
92 } 88 }
93 OS::Print("\n"); 89 OS::Print("\n");
94 indent += 2; 90 indent += 2;
95 for (int i = 0; i < children_.length(); i++) { 91 for (int i = 0; i < children_.length(); i++) {
96 children_[i]->Print(indent, tracker); 92 children_[i]->Print(indent, tracker);
97 } 93 }
98 } 94 }
99 95
100 96
101 AllocationTraceTree::AllocationTraceTree() 97 AllocationTraceTree::AllocationTraceTree()
102 : next_node_id_(1), 98 : next_node_id_(1),
103 root_(this, 0) { 99 root_(this, 0) {
104 } 100 }
105 101
106 102
107 AllocationTraceTree::~AllocationTraceTree() { 103 AllocationTraceTree::~AllocationTraceTree() {
108 } 104 }
109 105
110 106
111 AllocationTraceNode* AllocationTraceTree::AddPathFromEnd( 107 AllocationTraceNode* AllocationTraceTree::AddPathFromEnd(
112 const Vector<SnapshotObjectId>& path) { 108 const Vector<unsigned>& path) {
113 AllocationTraceNode* node = root(); 109 AllocationTraceNode* node = root();
114 for (SnapshotObjectId* entry = path.start() + path.length() - 1; 110 for (unsigned* entry = path.start() + path.length() - 1;
115 entry != path.start() - 1; 111 entry != path.start() - 1;
116 --entry) { 112 --entry) {
117 node = node->FindOrAddChild(*entry); 113 node = node->FindOrAddChild(*entry);
118 } 114 }
119 return node; 115 return node;
120 } 116 }
121 117
122 118
123 void AllocationTraceTree::Print(AllocationTracker* tracker) { 119 void AllocationTraceTree::Print(AllocationTracker* tracker) {
124 OS::Print("[AllocationTraceTree:]\n"); 120 OS::Print("[AllocationTraceTree:]\n");
125 OS::Print("Total size | Allocation count | Function id | id\n"); 121 OS::Print("Total size | Allocation count | Function id | id\n");
126 root()->Print(0, tracker); 122 root()->Print(0, tracker);
127 } 123 }
128 124
125
129 void AllocationTracker::DeleteUnresolvedLocation( 126 void AllocationTracker::DeleteUnresolvedLocation(
130 UnresolvedLocation** location) { 127 UnresolvedLocation** location) {
131 delete *location; 128 delete *location;
132 } 129 }
133 130
134 131
135 AllocationTracker::FunctionInfo::FunctionInfo() 132 AllocationTracker::FunctionInfo::FunctionInfo()
136 : name(""), 133 : name(""),
134 function_id(0),
137 script_name(""), 135 script_name(""),
138 script_id(0), 136 script_id(0),
139 line(-1), 137 line(-1),
140 column(-1) { 138 column(-1) {
141 } 139 }
142 140
143 141
142 void AddressToTraceMap::AddRange(Address start, int size,
143 unsigned trace_node_id) {
144 Address end = start + size;
145 RemoveRange(start, end);
146
147 RangeStack new_range(start, trace_node_id);
148 ranges_.insert(RangeMap::value_type(end, new_range));
149 }
150
151
152 unsigned AddressToTraceMap::GetTraceNodeId(Address addr) {
153 RangeMap::const_iterator it = ranges_.upper_bound(addr);
154 if (it == ranges_.end()) return 0;
155 if (it->second.start <= addr) {
156 return it->second.trace_node_id;
157 }
158 return 0;
159 }
160
161
162 void AddressToTraceMap::MoveObject(Address from, Address to, int size) {
163 unsigned trace_node_id = GetTraceNodeId(from);
164 if (trace_node_id == 0) return;
165 RemoveRange(from, from + size);
166 AddRange(to, size, trace_node_id);
167 }
168
169
170 void AddressToTraceMap::Clear() {
171 ranges_.clear();
172 }
173
174
175 void AddressToTraceMap::Print() {
176 PrintF("[AddressToTraceMap (%" V8PRIuPTR "): \n", ranges_.size());
177 for (RangeMap::iterator it = ranges_.begin(); it != ranges_.end(); ++it) {
178 PrintF("[%p - %p] => %u\n", it->second.start, it->first,
179 it->second.trace_node_id);
180 }
181 PrintF("]\n");
182 }
183
184
185 void AddressToTraceMap::RemoveRange(Address start, Address end) {
186 RangeMap::iterator it = ranges_.upper_bound(start);
187 if (it == ranges_.end()) return;
188
189 RangeStack prev_range(0, 0);
190
191 RangeMap::iterator to_remove_begin = it;
192 if (it->second.start < start) {
193 prev_range = it->second;
194 }
195 do {
196 if (it->first > end) {
197 if (it->second.start < end) {
198 it->second.start = end;
199 }
200 break;
201 }
202 ++it;
203 }
204 while (it != ranges_.end());
205
206 ranges_.erase(to_remove_begin, it);
207
208 if (prev_range.start != 0) {
209 ranges_.insert(RangeMap::value_type(start, prev_range));
210 }
211 }
212
213
144 static bool AddressesMatch(void* key1, void* key2) { 214 static bool AddressesMatch(void* key1, void* key2) {
145 return key1 == key2; 215 return key1 == key2;
146 } 216 }
147 217
148 218
219 void AllocationTracker::DeleteFunctionInfo(FunctionInfo** info) {
220 delete *info;
221 }
222
223
149 AllocationTracker::AllocationTracker( 224 AllocationTracker::AllocationTracker(
150 HeapObjectsMap* ids, StringsStorage* names) 225 HeapObjectsMap* ids, StringsStorage* names)
151 : ids_(ids), 226 : ids_(ids),
152 names_(names), 227 names_(names),
153 id_to_function_info_(AddressesMatch) { 228 id_to_function_info_index_(AddressesMatch),
229 info_index_for_other_state_(0) {
230 FunctionInfo* info = new FunctionInfo();
231 info->name = "(root)";
232 function_info_list_.Add(info);
154 } 233 }
155 234
156 235
157 AllocationTracker::~AllocationTracker() { 236 AllocationTracker::~AllocationTracker() {
158 unresolved_locations_.Iterate(DeleteUnresolvedLocation); 237 unresolved_locations_.Iterate(DeleteUnresolvedLocation);
159 for (HashMap::Entry* p = id_to_function_info_.Start(); 238 function_info_list_.Iterate(&DeleteFunctionInfo);
160 p != NULL;
161 p = id_to_function_info_.Next(p)) {
162 delete reinterpret_cast<AllocationTracker::FunctionInfo* >(p->value);
163 }
164 } 239 }
165 240
166 241
167 void AllocationTracker::PrepareForSerialization() { 242 void AllocationTracker::PrepareForSerialization() {
168 List<UnresolvedLocation*> copy(unresolved_locations_.length()); 243 List<UnresolvedLocation*> copy(unresolved_locations_.length());
169 copy.AddAll(unresolved_locations_); 244 copy.AddAll(unresolved_locations_);
170 unresolved_locations_.Clear(); 245 unresolved_locations_.Clear();
171 for (int i = 0; i < copy.length(); i++) { 246 for (int i = 0; i < copy.length(); i++) {
172 copy[i]->Resolve(); 247 copy[i]->Resolve();
173 delete copy[i]; 248 delete copy[i];
(...skipping 12 matching lines...) Expand all
186 ASSERT(FreeListNode::IsFreeListNode(HeapObject::FromAddress(addr))); 261 ASSERT(FreeListNode::IsFreeListNode(HeapObject::FromAddress(addr)));
187 262
188 Isolate* isolate = heap->isolate(); 263 Isolate* isolate = heap->isolate();
189 int length = 0; 264 int length = 0;
190 StackTraceFrameIterator it(isolate); 265 StackTraceFrameIterator it(isolate);
191 while (!it.done() && length < kMaxAllocationTraceLength) { 266 while (!it.done() && length < kMaxAllocationTraceLength) {
192 JavaScriptFrame* frame = it.frame(); 267 JavaScriptFrame* frame = it.frame();
193 SharedFunctionInfo* shared = frame->function()->shared(); 268 SharedFunctionInfo* shared = frame->function()->shared();
194 SnapshotObjectId id = ids_->FindOrAddEntry( 269 SnapshotObjectId id = ids_->FindOrAddEntry(
195 shared->address(), shared->Size(), false); 270 shared->address(), shared->Size(), false);
196 allocation_trace_buffer_[length++] = id; 271 allocation_trace_buffer_[length++] = AddFunctionInfo(shared, id);
197 AddFunctionInfo(shared, id);
198 it.Advance(); 272 it.Advance();
199 } 273 }
274 if (length == 0) {
275 unsigned index = functionInfoIndexForVMState(isolate->current_vm_state());
276 if (index != 0) {
277 allocation_trace_buffer_[length++] = index;
278 }
279 }
200 AllocationTraceNode* top_node = trace_tree_.AddPathFromEnd( 280 AllocationTraceNode* top_node = trace_tree_.AddPathFromEnd(
201 Vector<SnapshotObjectId>(allocation_trace_buffer_, length)); 281 Vector<unsigned>(allocation_trace_buffer_, length));
202 top_node->AddAllocation(size); 282 top_node->AddAllocation(size);
283
284 address_to_trace_.AddRange(addr, size, top_node->id());
203 } 285 }
204 286
205 287
206 static uint32_t SnapshotObjectIdHash(SnapshotObjectId id) { 288 static uint32_t SnapshotObjectIdHash(SnapshotObjectId id) {
207 return ComputeIntegerHash(static_cast<uint32_t>(id), 289 return ComputeIntegerHash(static_cast<uint32_t>(id),
208 v8::internal::kZeroHashSeed); 290 v8::internal::kZeroHashSeed);
209 } 291 }
210 292
211 293
212 AllocationTracker::FunctionInfo* AllocationTracker::GetFunctionInfo( 294 unsigned AllocationTracker::AddFunctionInfo(SharedFunctionInfo* shared,
213 SnapshotObjectId id) { 295 SnapshotObjectId id) {
214 HashMap::Entry* entry = id_to_function_info_.Lookup( 296 HashMap::Entry* entry = id_to_function_info_index_.Lookup(
215 reinterpret_cast<void*>(id), SnapshotObjectIdHash(id), false);
216 if (entry == NULL) {
217 return NULL;
218 }
219 return reinterpret_cast<FunctionInfo*>(entry->value);
220 }
221
222
223 void AllocationTracker::AddFunctionInfo(SharedFunctionInfo* shared,
224 SnapshotObjectId id) {
225 HashMap::Entry* entry = id_to_function_info_.Lookup(
226 reinterpret_cast<void*>(id), SnapshotObjectIdHash(id), true); 297 reinterpret_cast<void*>(id), SnapshotObjectIdHash(id), true);
227 if (entry->value == NULL) { 298 if (entry->value == NULL) {
228 FunctionInfo* info = new FunctionInfo(); 299 FunctionInfo* info = new FunctionInfo();
229 info->name = names_->GetFunctionName(shared->DebugName()); 300 info->name = names_->GetFunctionName(shared->DebugName());
301 info->function_id = id;
230 if (shared->script()->IsScript()) { 302 if (shared->script()->IsScript()) {
231 Script* script = Script::cast(shared->script()); 303 Script* script = Script::cast(shared->script());
232 if (script->name()->IsName()) { 304 if (script->name()->IsName()) {
233 Name* name = Name::cast(script->name()); 305 Name* name = Name::cast(script->name());
234 info->script_name = names_->GetName(name); 306 info->script_name = names_->GetName(name);
235 } 307 }
236 info->script_id = script->id()->value(); 308 info->script_id = script->id()->value();
237 // Converting start offset into line and column may cause heap 309 // Converting start offset into line and column may cause heap
238 // allocations so we postpone them until snapshot serialization. 310 // allocations so we postpone them until snapshot serialization.
239 unresolved_locations_.Add(new UnresolvedLocation( 311 unresolved_locations_.Add(new UnresolvedLocation(
240 script, 312 script,
241 shared->start_position(), 313 shared->start_position(),
242 info)); 314 info));
243 } 315 }
244 entry->value = info; 316 entry->value = reinterpret_cast<void*>(function_info_list_.length());
317 function_info_list_.Add(info);
245 } 318 }
319 return static_cast<unsigned>(reinterpret_cast<intptr_t>((entry->value)));
246 } 320 }
247 321
248 322
323 unsigned AllocationTracker::functionInfoIndexForVMState(StateTag state) {
324 if (state != OTHER) return 0;
325 if (info_index_for_other_state_ == 0) {
326 FunctionInfo* info = new FunctionInfo();
327 info->name = "(V8 API)";
328 info_index_for_other_state_ = function_info_list_.length();
329 function_info_list_.Add(info);
330 }
331 return info_index_for_other_state_;
332 }
333
334
249 AllocationTracker::UnresolvedLocation::UnresolvedLocation( 335 AllocationTracker::UnresolvedLocation::UnresolvedLocation(
250 Script* script, int start, FunctionInfo* info) 336 Script* script, int start, FunctionInfo* info)
251 : start_position_(start), 337 : start_position_(start),
252 info_(info) { 338 info_(info) {
253 script_ = Handle<Script>::cast( 339 script_ = Handle<Script>::cast(
254 script->GetIsolate()->global_handles()->Create(script)); 340 script->GetIsolate()->global_handles()->Create(script));
255 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()), 341 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()),
256 this, 342 this,
257 &HandleWeakScript); 343 &HandleWeakScript);
258 } 344 }
(...skipping 17 matching lines...) Expand all
276 void AllocationTracker::UnresolvedLocation::HandleWeakScript( 362 void AllocationTracker::UnresolvedLocation::HandleWeakScript(
277 const v8::WeakCallbackData<v8::Value, void>& data) { 363 const v8::WeakCallbackData<v8::Value, void>& data) {
278 UnresolvedLocation* loc = 364 UnresolvedLocation* loc =
279 reinterpret_cast<UnresolvedLocation*>(data.GetParameter()); 365 reinterpret_cast<UnresolvedLocation*>(data.GetParameter());
280 GlobalHandles::Destroy(reinterpret_cast<Object**>(loc->script_.location())); 366 GlobalHandles::Destroy(reinterpret_cast<Object**>(loc->script_.location()));
281 loc->script_ = Handle<Script>::null(); 367 loc->script_ = Handle<Script>::null();
282 } 368 }
283 369
284 370
285 } } // namespace v8::internal 371 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/allocation-tracker.h ('k') | src/api.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698