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

Side by Side Diff: src/heap-snapshot-generator.cc

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 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/heap-snapshot-generator.h ('k') | src/heap-snapshot-generator-inl.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/heap-snapshot-generator-inl.h" 7 #include "src/heap-snapshot-generator-inl.h"
8 8
9 #include "src/allocation-tracker.h" 9 #include "src/allocation-tracker.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
11 #include "src/conversions.h" 11 #include "src/conversions.h"
12 #include "src/debug.h" 12 #include "src/debug.h"
13 #include "src/heap-profiler.h" 13 #include "src/heap-profiler.h"
14 #include "src/types.h" 14 #include "src/types.h"
15 15
16 namespace v8 { 16 namespace v8 {
17 namespace internal { 17 namespace internal {
18 18
19 19
20 HeapGraphEdge::HeapGraphEdge(Type type, const char* name, int from, int to) 20 HeapGraphEdge::HeapGraphEdge(Type type, const char* name, int from, int to)
21 : type_(type), 21 : type_(type),
22 from_index_(from), 22 from_index_(from),
23 to_index_(to), 23 to_index_(to),
24 name_(name) { 24 name_(name) {
25 ASSERT(type == kContextVariable 25 DCHECK(type == kContextVariable
26 || type == kProperty 26 || type == kProperty
27 || type == kInternal 27 || type == kInternal
28 || type == kShortcut 28 || type == kShortcut
29 || type == kWeak); 29 || type == kWeak);
30 } 30 }
31 31
32 32
33 HeapGraphEdge::HeapGraphEdge(Type type, int index, int from, int to) 33 HeapGraphEdge::HeapGraphEdge(Type type, int index, int from, int to)
34 : type_(type), 34 : type_(type),
35 from_index_(from), 35 from_index_(from),
36 to_index_(to), 36 to_index_(to),
37 index_(index) { 37 index_(index) {
38 ASSERT(type == kElement || type == kHidden); 38 DCHECK(type == kElement || type == kHidden);
39 } 39 }
40 40
41 41
42 void HeapGraphEdge::ReplaceToIndexWithEntry(HeapSnapshot* snapshot) { 42 void HeapGraphEdge::ReplaceToIndexWithEntry(HeapSnapshot* snapshot) {
43 to_entry_ = &snapshot->entries()[to_index_]; 43 to_entry_ = &snapshot->entries()[to_index_];
44 } 44 }
45 45
46 46
47 const int HeapEntry::kNoEntry = -1; 47 const int HeapEntry::kNoEntry = -1;
48 48
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 delete this; 211 delete this;
212 } 212 }
213 213
214 214
215 void HeapSnapshot::RememberLastJSObjectId() { 215 void HeapSnapshot::RememberLastJSObjectId() {
216 max_snapshot_js_object_id_ = profiler_->heap_object_map()->last_assigned_id(); 216 max_snapshot_js_object_id_ = profiler_->heap_object_map()->last_assigned_id();
217 } 217 }
218 218
219 219
220 HeapEntry* HeapSnapshot::AddRootEntry() { 220 HeapEntry* HeapSnapshot::AddRootEntry() {
221 ASSERT(root_index_ == HeapEntry::kNoEntry); 221 DCHECK(root_index_ == HeapEntry::kNoEntry);
222 ASSERT(entries_.is_empty()); // Root entry must be the first one. 222 DCHECK(entries_.is_empty()); // Root entry must be the first one.
223 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, 223 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic,
224 "", 224 "",
225 HeapObjectsMap::kInternalRootObjectId, 225 HeapObjectsMap::kInternalRootObjectId,
226 0, 226 0,
227 0); 227 0);
228 root_index_ = entry->index(); 228 root_index_ = entry->index();
229 ASSERT(root_index_ == 0); 229 DCHECK(root_index_ == 0);
230 return entry; 230 return entry;
231 } 231 }
232 232
233 233
234 HeapEntry* HeapSnapshot::AddGcRootsEntry() { 234 HeapEntry* HeapSnapshot::AddGcRootsEntry() {
235 ASSERT(gc_roots_index_ == HeapEntry::kNoEntry); 235 DCHECK(gc_roots_index_ == HeapEntry::kNoEntry);
236 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, 236 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic,
237 "(GC roots)", 237 "(GC roots)",
238 HeapObjectsMap::kGcRootsObjectId, 238 HeapObjectsMap::kGcRootsObjectId,
239 0, 239 0,
240 0); 240 0);
241 gc_roots_index_ = entry->index(); 241 gc_roots_index_ = entry->index();
242 return entry; 242 return entry;
243 } 243 }
244 244
245 245
246 HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag) { 246 HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag) {
247 ASSERT(gc_subroot_indexes_[tag] == HeapEntry::kNoEntry); 247 DCHECK(gc_subroot_indexes_[tag] == HeapEntry::kNoEntry);
248 ASSERT(0 <= tag && tag < VisitorSynchronization::kNumberOfSyncTags); 248 DCHECK(0 <= tag && tag < VisitorSynchronization::kNumberOfSyncTags);
249 HeapEntry* entry = AddEntry( 249 HeapEntry* entry = AddEntry(
250 HeapEntry::kSynthetic, 250 HeapEntry::kSynthetic,
251 VisitorSynchronization::kTagNames[tag], 251 VisitorSynchronization::kTagNames[tag],
252 HeapObjectsMap::GetNthGcSubrootId(tag), 252 HeapObjectsMap::GetNthGcSubrootId(tag),
253 0, 253 0,
254 0); 254 0);
255 gc_subroot_indexes_[tag] = entry->index(); 255 gc_subroot_indexes_[tag] = entry->index();
256 return entry; 256 return entry;
257 } 257 }
258 258
259 259
260 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, 260 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type,
261 const char* name, 261 const char* name,
262 SnapshotObjectId id, 262 SnapshotObjectId id,
263 size_t size, 263 size_t size,
264 unsigned trace_node_id) { 264 unsigned trace_node_id) {
265 HeapEntry entry(this, type, name, id, size, trace_node_id); 265 HeapEntry entry(this, type, name, id, size, trace_node_id);
266 entries_.Add(entry); 266 entries_.Add(entry);
267 return &entries_.last(); 267 return &entries_.last();
268 } 268 }
269 269
270 270
271 void HeapSnapshot::FillChildren() { 271 void HeapSnapshot::FillChildren() {
272 ASSERT(children().is_empty()); 272 DCHECK(children().is_empty());
273 children().Allocate(edges().length()); 273 children().Allocate(edges().length());
274 int children_index = 0; 274 int children_index = 0;
275 for (int i = 0; i < entries().length(); ++i) { 275 for (int i = 0; i < entries().length(); ++i) {
276 HeapEntry* entry = &entries()[i]; 276 HeapEntry* entry = &entries()[i];
277 children_index = entry->set_children_index(children_index); 277 children_index = entry->set_children_index(children_index);
278 } 278 }
279 ASSERT(edges().length() == children_index); 279 DCHECK(edges().length() == children_index);
280 for (int i = 0; i < edges().length(); ++i) { 280 for (int i = 0; i < edges().length(); ++i) {
281 HeapGraphEdge* edge = &edges()[i]; 281 HeapGraphEdge* edge = &edges()[i];
282 edge->ReplaceToIndexWithEntry(this); 282 edge->ReplaceToIndexWithEntry(this);
283 edge->from()->add_child(edge); 283 edge->from()->add_child(edge);
284 } 284 }
285 } 285 }
286 286
287 287
288 class FindEntryById { 288 class FindEntryById {
289 public: 289 public:
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 // it has an entry with NULL as the value or it has created 368 // it has an entry with NULL as the value or it has created
369 // a new entry on the fly with NULL as the default value. 369 // a new entry on the fly with NULL as the default value.
370 // With such dummy element we have a guaranty that all entries_map_ entries 370 // With such dummy element we have a guaranty that all entries_map_ entries
371 // will have the value field grater than 0. 371 // will have the value field grater than 0.
372 // This fact is using in MoveObject method. 372 // This fact is using in MoveObject method.
373 entries_.Add(EntryInfo(0, NULL, 0)); 373 entries_.Add(EntryInfo(0, NULL, 0));
374 } 374 }
375 375
376 376
377 bool HeapObjectsMap::MoveObject(Address from, Address to, int object_size) { 377 bool HeapObjectsMap::MoveObject(Address from, Address to, int object_size) {
378 ASSERT(to != NULL); 378 DCHECK(to != NULL);
379 ASSERT(from != NULL); 379 DCHECK(from != NULL);
380 if (from == to) return false; 380 if (from == to) return false;
381 void* from_value = entries_map_.Remove(from, ComputePointerHash(from)); 381 void* from_value = entries_map_.Remove(from, ComputePointerHash(from));
382 if (from_value == NULL) { 382 if (from_value == NULL) {
383 // It may occur that some untracked object moves to an address X and there 383 // It may occur that some untracked object moves to an address X and there
384 // is a tracked object at that address. In this case we should remove the 384 // is a tracked object at that address. In this case we should remove the
385 // entry as we know that the object has died. 385 // entry as we know that the object has died.
386 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); 386 void* to_value = entries_map_.Remove(to, ComputePointerHash(to));
387 if (to_value != NULL) { 387 if (to_value != NULL) {
388 int to_entry_info_index = 388 int to_entry_info_index =
389 static_cast<int>(reinterpret_cast<intptr_t>(to_value)); 389 static_cast<int>(reinterpret_cast<intptr_t>(to_value));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 FindOrAddEntry(addr, size, false); 426 FindOrAddEntry(addr, size, false);
427 } 427 }
428 428
429 429
430 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { 430 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) {
431 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), 431 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr),
432 false); 432 false);
433 if (entry == NULL) return 0; 433 if (entry == NULL) return 0;
434 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); 434 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
435 EntryInfo& entry_info = entries_.at(entry_index); 435 EntryInfo& entry_info = entries_.at(entry_index);
436 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); 436 DCHECK(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy());
437 return entry_info.id; 437 return entry_info.id;
438 } 438 }
439 439
440 440
441 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, 441 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr,
442 unsigned int size, 442 unsigned int size,
443 bool accessed) { 443 bool accessed) {
444 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); 444 DCHECK(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy());
445 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), 445 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr),
446 true); 446 true);
447 if (entry->value != NULL) { 447 if (entry->value != NULL) {
448 int entry_index = 448 int entry_index =
449 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); 449 static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
450 EntryInfo& entry_info = entries_.at(entry_index); 450 EntryInfo& entry_info = entries_.at(entry_index);
451 entry_info.accessed = accessed; 451 entry_info.accessed = accessed;
452 if (FLAG_heap_profiler_trace_objects) { 452 if (FLAG_heap_profiler_trace_objects) {
453 PrintF("Update object size : %p with old size %d and new size %d\n", 453 PrintF("Update object size : %p with old size %d and new size %d\n",
454 addr, 454 addr,
455 entry_info.size, 455 entry_info.size,
456 size); 456 size);
457 } 457 }
458 entry_info.size = size; 458 entry_info.size = size;
459 return entry_info.id; 459 return entry_info.id;
460 } 460 }
461 entry->value = reinterpret_cast<void*>(entries_.length()); 461 entry->value = reinterpret_cast<void*>(entries_.length());
462 SnapshotObjectId id = next_id_; 462 SnapshotObjectId id = next_id_;
463 next_id_ += kObjectIdStep; 463 next_id_ += kObjectIdStep;
464 entries_.Add(EntryInfo(id, addr, size, accessed)); 464 entries_.Add(EntryInfo(id, addr, size, accessed));
465 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); 465 DCHECK(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy());
466 return id; 466 return id;
467 } 467 }
468 468
469 469
470 void HeapObjectsMap::StopHeapObjectsTracking() { 470 void HeapObjectsMap::StopHeapObjectsTracking() {
471 time_intervals_.Clear(); 471 time_intervals_.Clear();
472 } 472 }
473 473
474 474
475 void HeapObjectsMap::UpdateHeapObjectsMap() { 475 void HeapObjectsMap::UpdateHeapObjectsMap() {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 } 608 }
609 return untracked; 609 return untracked;
610 } 610 }
611 611
612 612
613 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { 613 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) {
614 UpdateHeapObjectsMap(); 614 UpdateHeapObjectsMap();
615 time_intervals_.Add(TimeInterval(next_id_)); 615 time_intervals_.Add(TimeInterval(next_id_));
616 int prefered_chunk_size = stream->GetChunkSize(); 616 int prefered_chunk_size = stream->GetChunkSize();
617 List<v8::HeapStatsUpdate> stats_buffer; 617 List<v8::HeapStatsUpdate> stats_buffer;
618 ASSERT(!entries_.is_empty()); 618 DCHECK(!entries_.is_empty());
619 EntryInfo* entry_info = &entries_.first(); 619 EntryInfo* entry_info = &entries_.first();
620 EntryInfo* end_entry_info = &entries_.last() + 1; 620 EntryInfo* end_entry_info = &entries_.last() + 1;
621 for (int time_interval_index = 0; 621 for (int time_interval_index = 0;
622 time_interval_index < time_intervals_.length(); 622 time_interval_index < time_intervals_.length();
623 ++time_interval_index) { 623 ++time_interval_index) {
624 TimeInterval& time_interval = time_intervals_[time_interval_index]; 624 TimeInterval& time_interval = time_intervals_[time_interval_index];
625 SnapshotObjectId time_interval_id = time_interval.id; 625 SnapshotObjectId time_interval_id = time_interval.id;
626 uint32_t entries_size = 0; 626 uint32_t entries_size = 0;
627 EntryInfo* start_entry_info = entry_info; 627 EntryInfo* start_entry_info = entry_info;
628 while (entry_info < end_entry_info && entry_info->id < time_interval_id) { 628 while (entry_info < end_entry_info && entry_info->id < time_interval_id) {
629 entries_size += entry_info->size; 629 entries_size += entry_info->size;
630 ++entry_info; 630 ++entry_info;
631 } 631 }
632 uint32_t entries_count = 632 uint32_t entries_count =
633 static_cast<uint32_t>(entry_info - start_entry_info); 633 static_cast<uint32_t>(entry_info - start_entry_info);
634 if (time_interval.count != entries_count || 634 if (time_interval.count != entries_count ||
635 time_interval.size != entries_size) { 635 time_interval.size != entries_size) {
636 stats_buffer.Add(v8::HeapStatsUpdate( 636 stats_buffer.Add(v8::HeapStatsUpdate(
637 time_interval_index, 637 time_interval_index,
638 time_interval.count = entries_count, 638 time_interval.count = entries_count,
639 time_interval.size = entries_size)); 639 time_interval.size = entries_size));
640 if (stats_buffer.length() >= prefered_chunk_size) { 640 if (stats_buffer.length() >= prefered_chunk_size) {
641 OutputStream::WriteResult result = stream->WriteHeapStatsChunk( 641 OutputStream::WriteResult result = stream->WriteHeapStatsChunk(
642 &stats_buffer.first(), stats_buffer.length()); 642 &stats_buffer.first(), stats_buffer.length());
643 if (result == OutputStream::kAbort) return last_assigned_id(); 643 if (result == OutputStream::kAbort) return last_assigned_id();
644 stats_buffer.Clear(); 644 stats_buffer.Clear();
645 } 645 }
646 } 646 }
647 } 647 }
648 ASSERT(entry_info == end_entry_info); 648 DCHECK(entry_info == end_entry_info);
649 if (!stats_buffer.is_empty()) { 649 if (!stats_buffer.is_empty()) {
650 OutputStream::WriteResult result = stream->WriteHeapStatsChunk( 650 OutputStream::WriteResult result = stream->WriteHeapStatsChunk(
651 &stats_buffer.first(), stats_buffer.length()); 651 &stats_buffer.first(), stats_buffer.length());
652 if (result == OutputStream::kAbort) return last_assigned_id(); 652 if (result == OutputStream::kAbort) return last_assigned_id();
653 } 653 }
654 stream->EndOfStream(); 654 stream->EndOfStream();
655 return last_assigned_id(); 655 return last_assigned_id();
656 } 656 }
657 657
658 658
659 void HeapObjectsMap::RemoveDeadEntries() { 659 void HeapObjectsMap::RemoveDeadEntries() {
660 ASSERT(entries_.length() > 0 && 660 DCHECK(entries_.length() > 0 &&
661 entries_.at(0).id == 0 && 661 entries_.at(0).id == 0 &&
662 entries_.at(0).addr == NULL); 662 entries_.at(0).addr == NULL);
663 int first_free_entry = 1; 663 int first_free_entry = 1;
664 for (int i = 1; i < entries_.length(); ++i) { 664 for (int i = 1; i < entries_.length(); ++i) {
665 EntryInfo& entry_info = entries_.at(i); 665 EntryInfo& entry_info = entries_.at(i);
666 if (entry_info.accessed) { 666 if (entry_info.accessed) {
667 if (first_free_entry != i) { 667 if (first_free_entry != i) {
668 entries_.at(first_free_entry) = entry_info; 668 entries_.at(first_free_entry) = entry_info;
669 } 669 }
670 entries_.at(first_free_entry).accessed = false; 670 entries_.at(first_free_entry).accessed = false;
671 HashMap::Entry* entry = entries_map_.Lookup( 671 HashMap::Entry* entry = entries_map_.Lookup(
672 entry_info.addr, ComputePointerHash(entry_info.addr), false); 672 entry_info.addr, ComputePointerHash(entry_info.addr), false);
673 ASSERT(entry); 673 DCHECK(entry);
674 entry->value = reinterpret_cast<void*>(first_free_entry); 674 entry->value = reinterpret_cast<void*>(first_free_entry);
675 ++first_free_entry; 675 ++first_free_entry;
676 } else { 676 } else {
677 if (entry_info.addr) { 677 if (entry_info.addr) {
678 entries_map_.Remove(entry_info.addr, 678 entries_map_.Remove(entry_info.addr,
679 ComputePointerHash(entry_info.addr)); 679 ComputePointerHash(entry_info.addr));
680 } 680 }
681 } 681 }
682 } 682 }
683 entries_.Rewind(first_free_entry); 683 entries_.Rewind(first_free_entry);
684 ASSERT(static_cast<uint32_t>(entries_.length()) - 1 == 684 DCHECK(static_cast<uint32_t>(entries_.length()) - 1 ==
685 entries_map_.occupancy()); 685 entries_map_.occupancy());
686 } 686 }
687 687
688 688
689 SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) { 689 SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
690 SnapshotObjectId id = static_cast<SnapshotObjectId>(info->GetHash()); 690 SnapshotObjectId id = static_cast<SnapshotObjectId>(info->GetHash());
691 const char* label = info->GetLabel(); 691 const char* label = info->GetLabel();
692 id ^= StringHasher::HashSequentialString(label, 692 id ^= StringHasher::HashSequentialString(label,
693 static_cast<int>(strlen(label)), 693 static_cast<int>(strlen(label)),
694 heap_->HashSeed()); 694 heap_->HashSeed());
(...skipping 21 matching lines...) Expand all
716 716
717 int HeapEntriesMap::Map(HeapThing thing) { 717 int HeapEntriesMap::Map(HeapThing thing) {
718 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false); 718 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
719 if (cache_entry == NULL) return HeapEntry::kNoEntry; 719 if (cache_entry == NULL) return HeapEntry::kNoEntry;
720 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); 720 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value));
721 } 721 }
722 722
723 723
724 void HeapEntriesMap::Pair(HeapThing thing, int entry) { 724 void HeapEntriesMap::Pair(HeapThing thing, int entry) {
725 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), true); 725 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), true);
726 ASSERT(cache_entry->value == NULL); 726 DCHECK(cache_entry->value == NULL);
727 cache_entry->value = reinterpret_cast<void*>(static_cast<intptr_t>(entry)); 727 cache_entry->value = reinterpret_cast<void*>(static_cast<intptr_t>(entry));
728 } 728 }
729 729
730 730
731 HeapObjectsSet::HeapObjectsSet() 731 HeapObjectsSet::HeapObjectsSet()
732 : entries_(HashMap::PointersMatch) { 732 : entries_(HashMap::PointersMatch) {
733 } 733 }
734 734
735 735
736 void HeapObjectsSet::Clear() { 736 void HeapObjectsSet::Clear() {
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 void VisitPointers(Object** start, Object** end) { 1052 void VisitPointers(Object** start, Object** end) {
1053 for (Object** p = start; p < end; p++) { 1053 for (Object** p = start; p < end; p++) {
1054 ++next_index_; 1054 ++next_index_;
1055 if (CheckVisitedAndUnmark(p)) continue; 1055 if (CheckVisitedAndUnmark(p)) continue;
1056 generator_->SetHiddenReference(parent_obj_, parent_, next_index_, *p); 1056 generator_->SetHiddenReference(parent_obj_, parent_, next_index_, *p);
1057 } 1057 }
1058 } 1058 }
1059 static void MarkVisitedField(HeapObject* obj, int offset) { 1059 static void MarkVisitedField(HeapObject* obj, int offset) {
1060 if (offset < 0) return; 1060 if (offset < 0) return;
1061 Address field = obj->address() + offset; 1061 Address field = obj->address() + offset;
1062 ASSERT(Memory::Object_at(field)->IsHeapObject()); 1062 DCHECK(Memory::Object_at(field)->IsHeapObject());
1063 intptr_t p = reinterpret_cast<intptr_t>(Memory::Object_at(field)); 1063 intptr_t p = reinterpret_cast<intptr_t>(Memory::Object_at(field));
1064 ASSERT(!IsMarked(p)); 1064 DCHECK(!IsMarked(p));
1065 intptr_t p_tagged = p | kTag; 1065 intptr_t p_tagged = p | kTag;
1066 Memory::Object_at(field) = reinterpret_cast<Object*>(p_tagged); 1066 Memory::Object_at(field) = reinterpret_cast<Object*>(p_tagged);
1067 } 1067 }
1068 1068
1069 private: 1069 private:
1070 bool CheckVisitedAndUnmark(Object** field) { 1070 bool CheckVisitedAndUnmark(Object** field) {
1071 intptr_t p = reinterpret_cast<intptr_t>(*field); 1071 intptr_t p = reinterpret_cast<intptr_t>(*field);
1072 if (IsMarked(p)) { 1072 if (IsMarked(p)) {
1073 intptr_t p_untagged = (p & ~kTaggingMask) | kHeapObjectTag; 1073 intptr_t p_untagged = (p & ~kTaggingMask) | kHeapObjectTag;
1074 *field = reinterpret_cast<Object*>(p_untagged); 1074 *field = reinterpret_cast<Object*>(p_untagged);
1075 ASSERT((*field)->IsHeapObject()); 1075 DCHECK((*field)->IsHeapObject());
1076 return true; 1076 return true;
1077 } 1077 }
1078 return false; 1078 return false;
1079 } 1079 }
1080 1080
1081 static const intptr_t kTaggingMask = 3; 1081 static const intptr_t kTaggingMask = 3;
1082 static const intptr_t kTag = 3; 1082 static const intptr_t kTag = 3;
1083 1083
1084 static bool IsMarked(intptr_t p) { return (p & kTaggingMask) == kTag; } 1084 static bool IsMarked(intptr_t p) { return (p & kTaggingMask) == kTag; }
1085 1085
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
1755 if (!elements->get(i)->IsTheHole()) { 1755 if (!elements->get(i)->IsTheHole()) {
1756 SetElementReference(js_obj, entry, i, elements->get(i)); 1756 SetElementReference(js_obj, entry, i, elements->get(i));
1757 } 1757 }
1758 } 1758 }
1759 } else if (js_obj->HasDictionaryElements()) { 1759 } else if (js_obj->HasDictionaryElements()) {
1760 SeededNumberDictionary* dictionary = js_obj->element_dictionary(); 1760 SeededNumberDictionary* dictionary = js_obj->element_dictionary();
1761 int length = dictionary->Capacity(); 1761 int length = dictionary->Capacity();
1762 for (int i = 0; i < length; ++i) { 1762 for (int i = 0; i < length; ++i) {
1763 Object* k = dictionary->KeyAt(i); 1763 Object* k = dictionary->KeyAt(i);
1764 if (dictionary->IsKey(k)) { 1764 if (dictionary->IsKey(k)) {
1765 ASSERT(k->IsNumber()); 1765 DCHECK(k->IsNumber());
1766 uint32_t index = static_cast<uint32_t>(k->Number()); 1766 uint32_t index = static_cast<uint32_t>(k->Number());
1767 SetElementReference(js_obj, entry, index, dictionary->ValueAt(i)); 1767 SetElementReference(js_obj, entry, index, dictionary->ValueAt(i));
1768 } 1768 }
1769 } 1769 }
1770 } 1770 }
1771 } 1771 }
1772 1772
1773 1773
1774 void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj, int entry) { 1774 void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj, int entry) {
1775 int length = js_obj->GetInternalFieldCount(); 1775 int length = js_obj->GetInternalFieldCount();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 if (collecting_all_references_) { 1836 if (collecting_all_references_) {
1837 for (Object** p = start; p < end; p++) all_references_.Add(*p); 1837 for (Object** p = start; p < end; p++) all_references_.Add(*p);
1838 } else { 1838 } else {
1839 for (Object** p = start; p < end; p++) strong_references_.Add(*p); 1839 for (Object** p = start; p < end; p++) strong_references_.Add(*p);
1840 } 1840 }
1841 } 1841 }
1842 1842
1843 void SetCollectingAllReferences() { collecting_all_references_ = true; } 1843 void SetCollectingAllReferences() { collecting_all_references_ = true; }
1844 1844
1845 void FillReferences(V8HeapExplorer* explorer) { 1845 void FillReferences(V8HeapExplorer* explorer) {
1846 ASSERT(strong_references_.length() <= all_references_.length()); 1846 DCHECK(strong_references_.length() <= all_references_.length());
1847 Builtins* builtins = heap_->isolate()->builtins(); 1847 Builtins* builtins = heap_->isolate()->builtins();
1848 for (int i = 0; i < reference_tags_.length(); ++i) { 1848 for (int i = 0; i < reference_tags_.length(); ++i) {
1849 explorer->SetGcRootsReference(reference_tags_[i].tag); 1849 explorer->SetGcRootsReference(reference_tags_[i].tag);
1850 } 1850 }
1851 int strong_index = 0, all_index = 0, tags_index = 0, builtin_index = 0; 1851 int strong_index = 0, all_index = 0, tags_index = 0, builtin_index = 0;
1852 while (all_index < all_references_.length()) { 1852 while (all_index < all_references_.length()) {
1853 bool is_strong = strong_index < strong_references_.length() 1853 bool is_strong = strong_index < strong_references_.length()
1854 && strong_references_[strong_index] == all_references_[all_index]; 1854 && strong_references_[strong_index] == all_references_[all_index];
1855 explorer->SetGcSubrootReference(reference_tags_[tags_index].tag, 1855 explorer->SetGcSubrootReference(reference_tags_[tags_index].tag,
1856 !is_strong, 1856 !is_strong,
1857 all_references_[all_index]); 1857 all_references_[all_index]);
1858 if (reference_tags_[tags_index].tag == 1858 if (reference_tags_[tags_index].tag ==
1859 VisitorSynchronization::kBuiltins) { 1859 VisitorSynchronization::kBuiltins) {
1860 ASSERT(all_references_[all_index]->IsCode()); 1860 DCHECK(all_references_[all_index]->IsCode());
1861 explorer->TagBuiltinCodeObject( 1861 explorer->TagBuiltinCodeObject(
1862 Code::cast(all_references_[all_index]), 1862 Code::cast(all_references_[all_index]),
1863 builtins->name(builtin_index++)); 1863 builtins->name(builtin_index++));
1864 } 1864 }
1865 ++all_index; 1865 ++all_index;
1866 if (is_strong) ++strong_index; 1866 if (is_strong) ++strong_index;
1867 if (reference_tags_[tags_index].index == all_index) ++tags_index; 1867 if (reference_tags_[tags_index].index == all_index) ++tags_index;
1868 } 1868 }
1869 } 1869 }
1870 1870
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 && object != heap_->one_pointer_filler_map() 1959 && object != heap_->one_pointer_filler_map()
1960 && object != heap_->two_pointer_filler_map(); 1960 && object != heap_->two_pointer_filler_map();
1961 } 1961 }
1962 1962
1963 1963
1964 void V8HeapExplorer::SetContextReference(HeapObject* parent_obj, 1964 void V8HeapExplorer::SetContextReference(HeapObject* parent_obj,
1965 int parent_entry, 1965 int parent_entry,
1966 String* reference_name, 1966 String* reference_name,
1967 Object* child_obj, 1967 Object* child_obj,
1968 int field_offset) { 1968 int field_offset) {
1969 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 1969 DCHECK(parent_entry == GetEntry(parent_obj)->index());
1970 HeapEntry* child_entry = GetEntry(child_obj); 1970 HeapEntry* child_entry = GetEntry(child_obj);
1971 if (child_entry != NULL) { 1971 if (child_entry != NULL) {
1972 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, 1972 filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
1973 parent_entry, 1973 parent_entry,
1974 names_->GetName(reference_name), 1974 names_->GetName(reference_name),
1975 child_entry); 1975 child_entry);
1976 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1976 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
1977 } 1977 }
1978 } 1978 }
1979 1979
1980 1980
1981 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj, 1981 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj,
1982 int parent_entry, 1982 int parent_entry,
1983 const char* reference_name, 1983 const char* reference_name,
1984 Object* child_obj) { 1984 Object* child_obj) {
1985 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 1985 DCHECK(parent_entry == GetEntry(parent_obj)->index());
1986 HeapEntry* child_entry = GetEntry(child_obj); 1986 HeapEntry* child_entry = GetEntry(child_obj);
1987 if (child_entry != NULL) { 1987 if (child_entry != NULL) {
1988 filler_->SetNamedReference(HeapGraphEdge::kShortcut, 1988 filler_->SetNamedReference(HeapGraphEdge::kShortcut,
1989 parent_entry, 1989 parent_entry,
1990 reference_name, 1990 reference_name,
1991 child_entry); 1991 child_entry);
1992 } 1992 }
1993 } 1993 }
1994 1994
1995 1995
1996 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj, 1996 void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
1997 int parent_entry, 1997 int parent_entry,
1998 int index, 1998 int index,
1999 Object* child_obj) { 1999 Object* child_obj) {
2000 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 2000 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2001 HeapEntry* child_entry = GetEntry(child_obj); 2001 HeapEntry* child_entry = GetEntry(child_obj);
2002 if (child_entry != NULL) { 2002 if (child_entry != NULL) {
2003 filler_->SetIndexedReference(HeapGraphEdge::kElement, 2003 filler_->SetIndexedReference(HeapGraphEdge::kElement,
2004 parent_entry, 2004 parent_entry,
2005 index, 2005 index,
2006 child_entry); 2006 child_entry);
2007 } 2007 }
2008 } 2008 }
2009 2009
2010 2010
2011 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, 2011 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
2012 int parent_entry, 2012 int parent_entry,
2013 const char* reference_name, 2013 const char* reference_name,
2014 Object* child_obj, 2014 Object* child_obj,
2015 int field_offset) { 2015 int field_offset) {
2016 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 2016 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2017 HeapEntry* child_entry = GetEntry(child_obj); 2017 HeapEntry* child_entry = GetEntry(child_obj);
2018 if (child_entry == NULL) return; 2018 if (child_entry == NULL) return;
2019 if (IsEssentialObject(child_obj)) { 2019 if (IsEssentialObject(child_obj)) {
2020 filler_->SetNamedReference(HeapGraphEdge::kInternal, 2020 filler_->SetNamedReference(HeapGraphEdge::kInternal,
2021 parent_entry, 2021 parent_entry,
2022 reference_name, 2022 reference_name,
2023 child_entry); 2023 child_entry);
2024 } 2024 }
2025 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 2025 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
2026 } 2026 }
2027 2027
2028 2028
2029 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj, 2029 void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
2030 int parent_entry, 2030 int parent_entry,
2031 int index, 2031 int index,
2032 Object* child_obj, 2032 Object* child_obj,
2033 int field_offset) { 2033 int field_offset) {
2034 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 2034 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2035 HeapEntry* child_entry = GetEntry(child_obj); 2035 HeapEntry* child_entry = GetEntry(child_obj);
2036 if (child_entry == NULL) return; 2036 if (child_entry == NULL) return;
2037 if (IsEssentialObject(child_obj)) { 2037 if (IsEssentialObject(child_obj)) {
2038 filler_->SetNamedReference(HeapGraphEdge::kInternal, 2038 filler_->SetNamedReference(HeapGraphEdge::kInternal,
2039 parent_entry, 2039 parent_entry,
2040 names_->GetName(index), 2040 names_->GetName(index),
2041 child_entry); 2041 child_entry);
2042 } 2042 }
2043 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 2043 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
2044 } 2044 }
2045 2045
2046 2046
2047 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, 2047 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
2048 int parent_entry, 2048 int parent_entry,
2049 int index, 2049 int index,
2050 Object* child_obj) { 2050 Object* child_obj) {
2051 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 2051 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2052 HeapEntry* child_entry = GetEntry(child_obj); 2052 HeapEntry* child_entry = GetEntry(child_obj);
2053 if (child_entry != NULL && IsEssentialObject(child_obj)) { 2053 if (child_entry != NULL && IsEssentialObject(child_obj)) {
2054 filler_->SetIndexedReference(HeapGraphEdge::kHidden, 2054 filler_->SetIndexedReference(HeapGraphEdge::kHidden,
2055 parent_entry, 2055 parent_entry,
2056 index, 2056 index,
2057 child_entry); 2057 child_entry);
2058 } 2058 }
2059 } 2059 }
2060 2060
2061 2061
2062 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj, 2062 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
2063 int parent_entry, 2063 int parent_entry,
2064 const char* reference_name, 2064 const char* reference_name,
2065 Object* child_obj, 2065 Object* child_obj,
2066 int field_offset) { 2066 int field_offset) {
2067 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 2067 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2068 HeapEntry* child_entry = GetEntry(child_obj); 2068 HeapEntry* child_entry = GetEntry(child_obj);
2069 if (child_entry == NULL) return; 2069 if (child_entry == NULL) return;
2070 if (IsEssentialObject(child_obj)) { 2070 if (IsEssentialObject(child_obj)) {
2071 filler_->SetNamedReference(HeapGraphEdge::kWeak, 2071 filler_->SetNamedReference(HeapGraphEdge::kWeak,
2072 parent_entry, 2072 parent_entry,
2073 reference_name, 2073 reference_name,
2074 child_entry); 2074 child_entry);
2075 } 2075 }
2076 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 2076 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
2077 } 2077 }
2078 2078
2079 2079
2080 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj, 2080 void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
2081 int parent_entry, 2081 int parent_entry,
2082 int index, 2082 int index,
2083 Object* child_obj, 2083 Object* child_obj,
2084 int field_offset) { 2084 int field_offset) {
2085 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 2085 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2086 HeapEntry* child_entry = GetEntry(child_obj); 2086 HeapEntry* child_entry = GetEntry(child_obj);
2087 if (child_entry == NULL) return; 2087 if (child_entry == NULL) return;
2088 if (IsEssentialObject(child_obj)) { 2088 if (IsEssentialObject(child_obj)) {
2089 filler_->SetNamedReference(HeapGraphEdge::kWeak, 2089 filler_->SetNamedReference(HeapGraphEdge::kWeak,
2090 parent_entry, 2090 parent_entry,
2091 names_->GetFormatted("%d", index), 2091 names_->GetFormatted("%d", index),
2092 child_entry); 2092 child_entry);
2093 } 2093 }
2094 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 2094 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
2095 } 2095 }
2096 2096
2097 2097
2098 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj, 2098 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
2099 int parent_entry, 2099 int parent_entry,
2100 Name* reference_name, 2100 Name* reference_name,
2101 Object* child_obj, 2101 Object* child_obj,
2102 const char* name_format_string, 2102 const char* name_format_string,
2103 int field_offset) { 2103 int field_offset) {
2104 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 2104 DCHECK(parent_entry == GetEntry(parent_obj)->index());
2105 HeapEntry* child_entry = GetEntry(child_obj); 2105 HeapEntry* child_entry = GetEntry(child_obj);
2106 if (child_entry != NULL) { 2106 if (child_entry != NULL) {
2107 HeapGraphEdge::Type type = 2107 HeapGraphEdge::Type type =
2108 reference_name->IsSymbol() || String::cast(reference_name)->length() > 0 2108 reference_name->IsSymbol() || String::cast(reference_name)->length() > 0
2109 ? HeapGraphEdge::kProperty : HeapGraphEdge::kInternal; 2109 ? HeapGraphEdge::kProperty : HeapGraphEdge::kInternal;
2110 const char* name = name_format_string != NULL && reference_name->IsString() 2110 const char* name = name_format_string != NULL && reference_name->IsString()
2111 ? names_->GetFormatted( 2111 ? names_->GetFormatted(
2112 name_format_string, 2112 name_format_string,
2113 String::cast(reference_name)->ToCString( 2113 String::cast(reference_name)->ToCString(
2114 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).get()) : 2114 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).get()) :
(...skipping 11 matching lines...) Expand all
2126 void V8HeapExplorer::SetRootGcRootsReference() { 2126 void V8HeapExplorer::SetRootGcRootsReference() {
2127 filler_->SetIndexedAutoIndexReference( 2127 filler_->SetIndexedAutoIndexReference(
2128 HeapGraphEdge::kElement, 2128 HeapGraphEdge::kElement,
2129 snapshot_->root()->index(), 2129 snapshot_->root()->index(),
2130 snapshot_->gc_roots()); 2130 snapshot_->gc_roots());
2131 } 2131 }
2132 2132
2133 2133
2134 void V8HeapExplorer::SetUserGlobalReference(Object* child_obj) { 2134 void V8HeapExplorer::SetUserGlobalReference(Object* child_obj) {
2135 HeapEntry* child_entry = GetEntry(child_obj); 2135 HeapEntry* child_entry = GetEntry(child_obj);
2136 ASSERT(child_entry != NULL); 2136 DCHECK(child_entry != NULL);
2137 filler_->SetNamedAutoIndexReference( 2137 filler_->SetNamedAutoIndexReference(
2138 HeapGraphEdge::kShortcut, 2138 HeapGraphEdge::kShortcut,
2139 snapshot_->root()->index(), 2139 snapshot_->root()->index(),
2140 child_entry); 2140 child_entry);
2141 } 2141 }
2142 2142
2143 2143
2144 void V8HeapExplorer::SetGcRootsReference(VisitorSynchronization::SyncTag tag) { 2144 void V8HeapExplorer::SetGcRootsReference(VisitorSynchronization::SyncTag tag) {
2145 filler_->SetIndexedAutoIndexReference( 2145 filler_->SetIndexedAutoIndexReference(
2146 HeapGraphEdge::kElement, 2146 HeapGraphEdge::kElement,
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
2407 2407
2408 void NativeObjectsExplorer::FillImplicitReferences() { 2408 void NativeObjectsExplorer::FillImplicitReferences() {
2409 Isolate* isolate = isolate_; 2409 Isolate* isolate = isolate_;
2410 List<ImplicitRefGroup*>* groups = 2410 List<ImplicitRefGroup*>* groups =
2411 isolate->global_handles()->implicit_ref_groups(); 2411 isolate->global_handles()->implicit_ref_groups();
2412 for (int i = 0; i < groups->length(); ++i) { 2412 for (int i = 0; i < groups->length(); ++i) {
2413 ImplicitRefGroup* group = groups->at(i); 2413 ImplicitRefGroup* group = groups->at(i);
2414 HeapObject* parent = *group->parent; 2414 HeapObject* parent = *group->parent;
2415 int parent_entry = 2415 int parent_entry =
2416 filler_->FindOrAddEntry(parent, native_entries_allocator_)->index(); 2416 filler_->FindOrAddEntry(parent, native_entries_allocator_)->index();
2417 ASSERT(parent_entry != HeapEntry::kNoEntry); 2417 DCHECK(parent_entry != HeapEntry::kNoEntry);
2418 Object*** children = group->children; 2418 Object*** children = group->children;
2419 for (size_t j = 0; j < group->length; ++j) { 2419 for (size_t j = 0; j < group->length; ++j) {
2420 Object* child = *children[j]; 2420 Object* child = *children[j];
2421 HeapEntry* child_entry = 2421 HeapEntry* child_entry =
2422 filler_->FindOrAddEntry(child, native_entries_allocator_); 2422 filler_->FindOrAddEntry(child, native_entries_allocator_);
2423 filler_->SetNamedReference( 2423 filler_->SetNamedReference(
2424 HeapGraphEdge::kInternal, 2424 HeapGraphEdge::kInternal,
2425 parent_entry, 2425 parent_entry,
2426 "native", 2426 "native",
2427 child_entry); 2427 child_entry);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
2508 entry->value = new NativeGroupRetainedObjectInfo(label); 2508 entry->value = new NativeGroupRetainedObjectInfo(label);
2509 } 2509 }
2510 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value); 2510 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value);
2511 } 2511 }
2512 2512
2513 2513
2514 void NativeObjectsExplorer::SetNativeRootReference( 2514 void NativeObjectsExplorer::SetNativeRootReference(
2515 v8::RetainedObjectInfo* info) { 2515 v8::RetainedObjectInfo* info) {
2516 HeapEntry* child_entry = 2516 HeapEntry* child_entry =
2517 filler_->FindOrAddEntry(info, native_entries_allocator_); 2517 filler_->FindOrAddEntry(info, native_entries_allocator_);
2518 ASSERT(child_entry != NULL); 2518 DCHECK(child_entry != NULL);
2519 NativeGroupRetainedObjectInfo* group_info = 2519 NativeGroupRetainedObjectInfo* group_info =
2520 FindOrAddGroupInfo(info->GetGroupLabel()); 2520 FindOrAddGroupInfo(info->GetGroupLabel());
2521 HeapEntry* group_entry = 2521 HeapEntry* group_entry =
2522 filler_->FindOrAddEntry(group_info, synthetic_entries_allocator_); 2522 filler_->FindOrAddEntry(group_info, synthetic_entries_allocator_);
2523 filler_->SetNamedAutoIndexReference( 2523 filler_->SetNamedAutoIndexReference(
2524 HeapGraphEdge::kInternal, 2524 HeapGraphEdge::kInternal,
2525 group_entry->index(), 2525 group_entry->index(),
2526 child_entry); 2526 child_entry);
2527 } 2527 }
2528 2528
2529 2529
2530 void NativeObjectsExplorer::SetWrapperNativeReferences( 2530 void NativeObjectsExplorer::SetWrapperNativeReferences(
2531 HeapObject* wrapper, v8::RetainedObjectInfo* info) { 2531 HeapObject* wrapper, v8::RetainedObjectInfo* info) {
2532 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper); 2532 HeapEntry* wrapper_entry = filler_->FindEntry(wrapper);
2533 ASSERT(wrapper_entry != NULL); 2533 DCHECK(wrapper_entry != NULL);
2534 HeapEntry* info_entry = 2534 HeapEntry* info_entry =
2535 filler_->FindOrAddEntry(info, native_entries_allocator_); 2535 filler_->FindOrAddEntry(info, native_entries_allocator_);
2536 ASSERT(info_entry != NULL); 2536 DCHECK(info_entry != NULL);
2537 filler_->SetNamedReference(HeapGraphEdge::kInternal, 2537 filler_->SetNamedReference(HeapGraphEdge::kInternal,
2538 wrapper_entry->index(), 2538 wrapper_entry->index(),
2539 "native", 2539 "native",
2540 info_entry); 2540 info_entry);
2541 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement, 2541 filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement,
2542 info_entry->index(), 2542 info_entry->index(),
2543 wrapper_entry); 2543 wrapper_entry);
2544 } 2544 }
2545 2545
2546 2546
2547 void NativeObjectsExplorer::SetRootNativeRootsReference() { 2547 void NativeObjectsExplorer::SetRootNativeRootsReference() {
2548 for (HashMap::Entry* entry = native_groups_.Start(); 2548 for (HashMap::Entry* entry = native_groups_.Start();
2549 entry; 2549 entry;
2550 entry = native_groups_.Next(entry)) { 2550 entry = native_groups_.Next(entry)) {
2551 NativeGroupRetainedObjectInfo* group_info = 2551 NativeGroupRetainedObjectInfo* group_info =
2552 static_cast<NativeGroupRetainedObjectInfo*>(entry->value); 2552 static_cast<NativeGroupRetainedObjectInfo*>(entry->value);
2553 HeapEntry* group_entry = 2553 HeapEntry* group_entry =
2554 filler_->FindOrAddEntry(group_info, native_entries_allocator_); 2554 filler_->FindOrAddEntry(group_info, native_entries_allocator_);
2555 ASSERT(group_entry != NULL); 2555 DCHECK(group_entry != NULL);
2556 filler_->SetIndexedAutoIndexReference( 2556 filler_->SetIndexedAutoIndexReference(
2557 HeapGraphEdge::kElement, 2557 HeapGraphEdge::kElement,
2558 snapshot_->root()->index(), 2558 snapshot_->root()->index(),
2559 group_entry); 2559 group_entry);
2560 } 2560 }
2561 } 2561 }
2562 2562
2563 2563
2564 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { 2564 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) {
2565 if (in_groups_.Contains(*p)) return; 2565 if (in_groups_.Contains(*p)) return;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 2676
2677 2677
2678 class OutputStreamWriter { 2678 class OutputStreamWriter {
2679 public: 2679 public:
2680 explicit OutputStreamWriter(v8::OutputStream* stream) 2680 explicit OutputStreamWriter(v8::OutputStream* stream)
2681 : stream_(stream), 2681 : stream_(stream),
2682 chunk_size_(stream->GetChunkSize()), 2682 chunk_size_(stream->GetChunkSize()),
2683 chunk_(chunk_size_), 2683 chunk_(chunk_size_),
2684 chunk_pos_(0), 2684 chunk_pos_(0),
2685 aborted_(false) { 2685 aborted_(false) {
2686 ASSERT(chunk_size_ > 0); 2686 DCHECK(chunk_size_ > 0);
2687 } 2687 }
2688 bool aborted() { return aborted_; } 2688 bool aborted() { return aborted_; }
2689 void AddCharacter(char c) { 2689 void AddCharacter(char c) {
2690 ASSERT(c != '\0'); 2690 DCHECK(c != '\0');
2691 ASSERT(chunk_pos_ < chunk_size_); 2691 DCHECK(chunk_pos_ < chunk_size_);
2692 chunk_[chunk_pos_++] = c; 2692 chunk_[chunk_pos_++] = c;
2693 MaybeWriteChunk(); 2693 MaybeWriteChunk();
2694 } 2694 }
2695 void AddString(const char* s) { 2695 void AddString(const char* s) {
2696 AddSubstring(s, StrLength(s)); 2696 AddSubstring(s, StrLength(s));
2697 } 2697 }
2698 void AddSubstring(const char* s, int n) { 2698 void AddSubstring(const char* s, int n) {
2699 if (n <= 0) return; 2699 if (n <= 0) return;
2700 ASSERT(static_cast<size_t>(n) <= strlen(s)); 2700 DCHECK(static_cast<size_t>(n) <= strlen(s));
2701 const char* s_end = s + n; 2701 const char* s_end = s + n;
2702 while (s < s_end) { 2702 while (s < s_end) {
2703 int s_chunk_size = 2703 int s_chunk_size =
2704 Min(chunk_size_ - chunk_pos_, static_cast<int>(s_end - s)); 2704 Min(chunk_size_ - chunk_pos_, static_cast<int>(s_end - s));
2705 ASSERT(s_chunk_size > 0); 2705 DCHECK(s_chunk_size > 0);
2706 MemCopy(chunk_.start() + chunk_pos_, s, s_chunk_size); 2706 MemCopy(chunk_.start() + chunk_pos_, s, s_chunk_size);
2707 s += s_chunk_size; 2707 s += s_chunk_size;
2708 chunk_pos_ += s_chunk_size; 2708 chunk_pos_ += s_chunk_size;
2709 MaybeWriteChunk(); 2709 MaybeWriteChunk();
2710 } 2710 }
2711 } 2711 }
2712 void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); } 2712 void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); }
2713 void Finalize() { 2713 void Finalize() {
2714 if (aborted_) return; 2714 if (aborted_) return;
2715 ASSERT(chunk_pos_ < chunk_size_); 2715 DCHECK(chunk_pos_ < chunk_size_);
2716 if (chunk_pos_ != 0) { 2716 if (chunk_pos_ != 0) {
2717 WriteChunk(); 2717 WriteChunk();
2718 } 2718 }
2719 stream_->EndOfStream(); 2719 stream_->EndOfStream();
2720 } 2720 }
2721 2721
2722 private: 2722 private:
2723 template<typename T> 2723 template<typename T>
2724 void AddNumberImpl(T n, const char* format) { 2724 void AddNumberImpl(T n, const char* format) {
2725 // Buffer for the longest value plus trailing \0 2725 // Buffer for the longest value plus trailing \0
2726 static const int kMaxNumberSize = 2726 static const int kMaxNumberSize =
2727 MaxDecimalDigitsIn<sizeof(T)>::kUnsigned + 1; 2727 MaxDecimalDigitsIn<sizeof(T)>::kUnsigned + 1;
2728 if (chunk_size_ - chunk_pos_ >= kMaxNumberSize) { 2728 if (chunk_size_ - chunk_pos_ >= kMaxNumberSize) {
2729 int result = SNPrintF( 2729 int result = SNPrintF(
2730 chunk_.SubVector(chunk_pos_, chunk_size_), format, n); 2730 chunk_.SubVector(chunk_pos_, chunk_size_), format, n);
2731 ASSERT(result != -1); 2731 DCHECK(result != -1);
2732 chunk_pos_ += result; 2732 chunk_pos_ += result;
2733 MaybeWriteChunk(); 2733 MaybeWriteChunk();
2734 } else { 2734 } else {
2735 EmbeddedVector<char, kMaxNumberSize> buffer; 2735 EmbeddedVector<char, kMaxNumberSize> buffer;
2736 int result = SNPrintF(buffer, format, n); 2736 int result = SNPrintF(buffer, format, n);
2737 USE(result); 2737 USE(result);
2738 ASSERT(result != -1); 2738 DCHECK(result != -1);
2739 AddString(buffer.start()); 2739 AddString(buffer.start());
2740 } 2740 }
2741 } 2741 }
2742 void MaybeWriteChunk() { 2742 void MaybeWriteChunk() {
2743 ASSERT(chunk_pos_ <= chunk_size_); 2743 DCHECK(chunk_pos_ <= chunk_size_);
2744 if (chunk_pos_ == chunk_size_) { 2744 if (chunk_pos_ == chunk_size_) {
2745 WriteChunk(); 2745 WriteChunk();
2746 } 2746 }
2747 } 2747 }
2748 void WriteChunk() { 2748 void WriteChunk() {
2749 if (aborted_) return; 2749 if (aborted_) return;
2750 if (stream_->WriteAsciiChunk(chunk_.start(), chunk_pos_) == 2750 if (stream_->WriteAsciiChunk(chunk_.start(), chunk_pos_) ==
2751 v8::OutputStream::kAbort) aborted_ = true; 2751 v8::OutputStream::kAbort) aborted_ = true;
2752 chunk_pos_ = 0; 2752 chunk_pos_ = 0;
2753 } 2753 }
2754 2754
2755 v8::OutputStream* stream_; 2755 v8::OutputStream* stream_;
2756 int chunk_size_; 2756 int chunk_size_;
2757 ScopedVector<char> chunk_; 2757 ScopedVector<char> chunk_;
2758 int chunk_pos_; 2758 int chunk_pos_;
2759 bool aborted_; 2759 bool aborted_;
2760 }; 2760 };
2761 2761
2762 2762
2763 // type, name|index, to_node. 2763 // type, name|index, to_node.
2764 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3; 2764 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3;
2765 // type, name, id, self_size, edge_count, trace_node_id. 2765 // type, name, id, self_size, edge_count, trace_node_id.
2766 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 6; 2766 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 6;
2767 2767
2768 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { 2768 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) {
2769 if (AllocationTracker* allocation_tracker = 2769 if (AllocationTracker* allocation_tracker =
2770 snapshot_->profiler()->allocation_tracker()) { 2770 snapshot_->profiler()->allocation_tracker()) {
2771 allocation_tracker->PrepareForSerialization(); 2771 allocation_tracker->PrepareForSerialization();
2772 } 2772 }
2773 ASSERT(writer_ == NULL); 2773 DCHECK(writer_ == NULL);
2774 writer_ = new OutputStreamWriter(stream); 2774 writer_ = new OutputStreamWriter(stream);
2775 SerializeImpl(); 2775 SerializeImpl();
2776 delete writer_; 2776 delete writer_;
2777 writer_ = NULL; 2777 writer_ = NULL;
2778 } 2778 }
2779 2779
2780 2780
2781 void HeapSnapshotJSONSerializer::SerializeImpl() { 2781 void HeapSnapshotJSONSerializer::SerializeImpl() {
2782 ASSERT(0 == snapshot_->root()->index()); 2782 DCHECK(0 == snapshot_->root()->index());
2783 writer_->AddCharacter('{'); 2783 writer_->AddCharacter('{');
2784 writer_->AddString("\"snapshot\":{"); 2784 writer_->AddString("\"snapshot\":{");
2785 SerializeSnapshot(); 2785 SerializeSnapshot();
2786 if (writer_->aborted()) return; 2786 if (writer_->aborted()) return;
2787 writer_->AddString("},\n"); 2787 writer_->AddString("},\n");
2788 writer_->AddString("\"nodes\":["); 2788 writer_->AddString("\"nodes\":[");
2789 SerializeNodes(); 2789 SerializeNodes();
2790 if (writer_->aborted()) return; 2790 if (writer_->aborted()) return;
2791 writer_->AddString("],\n"); 2791 writer_->AddString("],\n");
2792 writer_->AddString("\"edges\":["); 2792 writer_->AddString("\"edges\":[");
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2885 buffer_pos = utoa(entry_index(edge->to()), buffer, buffer_pos); 2885 buffer_pos = utoa(entry_index(edge->to()), buffer, buffer_pos);
2886 buffer[buffer_pos++] = '\n'; 2886 buffer[buffer_pos++] = '\n';
2887 buffer[buffer_pos++] = '\0'; 2887 buffer[buffer_pos++] = '\0';
2888 writer_->AddString(buffer.start()); 2888 writer_->AddString(buffer.start());
2889 } 2889 }
2890 2890
2891 2891
2892 void HeapSnapshotJSONSerializer::SerializeEdges() { 2892 void HeapSnapshotJSONSerializer::SerializeEdges() {
2893 List<HeapGraphEdge*>& edges = snapshot_->children(); 2893 List<HeapGraphEdge*>& edges = snapshot_->children();
2894 for (int i = 0; i < edges.length(); ++i) { 2894 for (int i = 0; i < edges.length(); ++i) {
2895 ASSERT(i == 0 || 2895 DCHECK(i == 0 ||
2896 edges[i - 1]->from()->index() <= edges[i]->from()->index()); 2896 edges[i - 1]->from()->index() <= edges[i]->from()->index());
2897 SerializeEdge(edges[i], i == 0); 2897 SerializeEdge(edges[i], i == 0);
2898 if (writer_->aborted()) return; 2898 if (writer_->aborted()) return;
2899 } 2899 }
2900 } 2900 }
2901 2901
2902 2902
2903 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { 2903 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) {
2904 // The buffer needs space for 4 unsigned ints, 1 size_t, 5 commas, \n and \0 2904 // The buffer needs space for 4 unsigned ints, 1 size_t, 5 commas, \n and \0
2905 static const int kBufferSize = 2905 static const int kBufferSize =
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
3069 writer_->AddCharacter(']'); 3069 writer_->AddCharacter(']');
3070 } 3070 }
3071 3071
3072 3072
3073 // 0-based position is converted to 1-based during the serialization. 3073 // 0-based position is converted to 1-based during the serialization.
3074 static int SerializePosition(int position, const Vector<char>& buffer, 3074 static int SerializePosition(int position, const Vector<char>& buffer,
3075 int buffer_pos) { 3075 int buffer_pos) {
3076 if (position == -1) { 3076 if (position == -1) {
3077 buffer[buffer_pos++] = '0'; 3077 buffer[buffer_pos++] = '0';
3078 } else { 3078 } else {
3079 ASSERT(position >= 0); 3079 DCHECK(position >= 0);
3080 buffer_pos = utoa(static_cast<unsigned>(position + 1), buffer, buffer_pos); 3080 buffer_pos = utoa(static_cast<unsigned>(position + 1), buffer, buffer_pos);
3081 } 3081 }
3082 return buffer_pos; 3082 return buffer_pos;
3083 } 3083 }
3084 3084
3085 3085
3086 void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() { 3086 void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() {
3087 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker(); 3087 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
3088 if (!tracker) return; 3088 if (!tracker) return;
3089 // The buffer needs space for 6 unsigned ints, 6 commas, \n and \0 3089 // The buffer needs space for 6 unsigned ints, 6 commas, \n and \0
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
3153 } else if (*s <= 31) { 3153 } else if (*s <= 31) {
3154 // Special character with no dedicated literal. 3154 // Special character with no dedicated literal.
3155 WriteUChar(writer_, *s); 3155 WriteUChar(writer_, *s);
3156 } else { 3156 } else {
3157 // Convert UTF-8 into \u UTF-16 literal. 3157 // Convert UTF-8 into \u UTF-16 literal.
3158 unsigned length = 1, cursor = 0; 3158 unsigned length = 1, cursor = 0;
3159 for ( ; length <= 4 && *(s + length) != '\0'; ++length) { } 3159 for ( ; length <= 4 && *(s + length) != '\0'; ++length) { }
3160 unibrow::uchar c = unibrow::Utf8::CalculateValue(s, length, &cursor); 3160 unibrow::uchar c = unibrow::Utf8::CalculateValue(s, length, &cursor);
3161 if (c != unibrow::Utf8::kBadChar) { 3161 if (c != unibrow::Utf8::kBadChar) {
3162 WriteUChar(writer_, c); 3162 WriteUChar(writer_, c);
3163 ASSERT(cursor != 0); 3163 DCHECK(cursor != 0);
3164 s += cursor - 1; 3164 s += cursor - 1;
3165 } else { 3165 } else {
3166 writer_->AddCharacter('?'); 3166 writer_->AddCharacter('?');
3167 } 3167 }
3168 } 3168 }
3169 } 3169 }
3170 } 3170 }
3171 writer_->AddCharacter('\"'); 3171 writer_->AddCharacter('\"');
3172 } 3172 }
3173 3173
(...skipping 10 matching lines...) Expand all
3184 writer_->AddString("\"<dummy>\""); 3184 writer_->AddString("\"<dummy>\"");
3185 for (int i = 1; i < sorted_strings.length(); ++i) { 3185 for (int i = 1; i < sorted_strings.length(); ++i) {
3186 writer_->AddCharacter(','); 3186 writer_->AddCharacter(',');
3187 SerializeString(sorted_strings[i]); 3187 SerializeString(sorted_strings[i]);
3188 if (writer_->aborted()) return; 3188 if (writer_->aborted()) return;
3189 } 3189 }
3190 } 3190 }
3191 3191
3192 3192
3193 } } // namespace v8::internal 3193 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap-snapshot-generator.h ('k') | src/heap-snapshot-generator-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698