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

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

Issue 136643008: A64: Synchronize with r18256. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/hydrogen.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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type, 93 void HeapEntry::SetIndexedReference(HeapGraphEdge::Type type,
94 int index, 94 int index,
95 HeapEntry* entry) { 95 HeapEntry* entry) {
96 HeapGraphEdge edge(type, index, this->index(), entry->index()); 96 HeapGraphEdge edge(type, index, this->index(), entry->index());
97 snapshot_->edges().Add(edge); 97 snapshot_->edges().Add(edge);
98 ++children_count_; 98 ++children_count_;
99 } 99 }
100 100
101 101
102 Handle<HeapObject> HeapEntry::GetHeapObject() { 102 Handle<HeapObject> HeapEntry::GetHeapObject() {
103 return snapshot_->collection()->FindHeapObjectById(id()); 103 return snapshot_->profiler()->FindHeapObjectById(id());
104 } 104 }
105 105
106 106
107 void HeapEntry::Print( 107 void HeapEntry::Print(
108 const char* prefix, const char* edge_name, int max_depth, int indent) { 108 const char* prefix, const char* edge_name, int max_depth, int indent) {
109 STATIC_CHECK(sizeof(unsigned) == sizeof(id())); 109 STATIC_CHECK(sizeof(unsigned) == sizeof(id()));
110 OS::Print("%6d @%6u %*c %s%s: ", 110 OS::Print("%6d @%6u %*c %s%s: ",
111 self_size(), id(), indent, ' ', prefix, edge_name); 111 self_size(), id(), indent, ' ', prefix, edge_name);
112 if (type() != kString) { 112 if (type() != kString) {
113 OS::Print("%s %.40s\n", TypeAsString(), name_); 113 OS::Print("%s %.40s\n", TypeAsString(), name_);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 static const int kExpectedHeapEntrySize = 24; 195 static const int kExpectedHeapEntrySize = 24;
196 }; 196 };
197 197
198 template <> struct SnapshotSizeConstants<8> { 198 template <> struct SnapshotSizeConstants<8> {
199 static const int kExpectedHeapGraphEdgeSize = 24; 199 static const int kExpectedHeapGraphEdgeSize = 24;
200 static const int kExpectedHeapEntrySize = 32; 200 static const int kExpectedHeapEntrySize = 32;
201 }; 201 };
202 202
203 } // namespace 203 } // namespace
204 204
205 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, 205 HeapSnapshot::HeapSnapshot(HeapProfiler* profiler,
206 const char* title, 206 const char* title,
207 unsigned uid) 207 unsigned uid)
208 : collection_(collection), 208 : profiler_(profiler),
209 title_(title), 209 title_(title),
210 uid_(uid), 210 uid_(uid),
211 root_index_(HeapEntry::kNoEntry), 211 root_index_(HeapEntry::kNoEntry),
212 gc_roots_index_(HeapEntry::kNoEntry), 212 gc_roots_index_(HeapEntry::kNoEntry),
213 natives_root_index_(HeapEntry::kNoEntry), 213 natives_root_index_(HeapEntry::kNoEntry),
214 max_snapshot_js_object_id_(0) { 214 max_snapshot_js_object_id_(0) {
215 STATIC_CHECK( 215 STATIC_CHECK(
216 sizeof(HeapGraphEdge) == 216 sizeof(HeapGraphEdge) ==
217 SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize); 217 SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize);
218 STATIC_CHECK( 218 STATIC_CHECK(
219 sizeof(HeapEntry) == 219 sizeof(HeapEntry) ==
220 SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize); 220 SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize);
221 for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) { 221 for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) {
222 gc_subroot_indexes_[i] = HeapEntry::kNoEntry; 222 gc_subroot_indexes_[i] = HeapEntry::kNoEntry;
223 } 223 }
224 } 224 }
225 225
226 226
227 void HeapSnapshot::Delete() { 227 void HeapSnapshot::Delete() {
228 collection_->RemoveSnapshot(this); 228 profiler_->RemoveSnapshot(this);
229 delete this; 229 delete this;
230 } 230 }
231 231
232 232
233 void HeapSnapshot::RememberLastJSObjectId() { 233 void HeapSnapshot::RememberLastJSObjectId() {
234 max_snapshot_js_object_id_ = collection_->last_assigned_id(); 234 max_snapshot_js_object_id_ = profiler_->heap_object_map()->last_assigned_id();
235 } 235 }
236 236
237 237
238 HeapEntry* HeapSnapshot::AddRootEntry() { 238 HeapEntry* HeapSnapshot::AddRootEntry() {
239 ASSERT(root_index_ == HeapEntry::kNoEntry); 239 ASSERT(root_index_ == HeapEntry::kNoEntry);
240 ASSERT(entries_.is_empty()); // Root entry must be the first one. 240 ASSERT(entries_.is_empty()); // Root entry must be the first one.
241 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, 241 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic,
242 "", 242 "",
243 HeapObjectsMap::kInternalRootObjectId, 243 HeapObjectsMap::kInternalRootObjectId,
244 0); 244 0);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 } 339 }
340 return &sorted_entries_; 340 return &sorted_entries_;
341 } 341 }
342 342
343 343
344 void HeapSnapshot::Print(int max_depth) { 344 void HeapSnapshot::Print(int max_depth) {
345 root()->Print("", "", max_depth, 0); 345 root()->Print("", "", max_depth, 0);
346 } 346 }
347 347
348 348
349 template<typename T, class P>
350 static size_t GetMemoryUsedByList(const List<T, P>& list) {
351 return list.length() * sizeof(T) + sizeof(list);
352 }
353
354
355 size_t HeapSnapshot::RawSnapshotSize() const { 349 size_t HeapSnapshot::RawSnapshotSize() const {
356 return 350 return
357 sizeof(*this) + 351 sizeof(*this) +
358 GetMemoryUsedByList(entries_) + 352 GetMemoryUsedByList(entries_) +
359 GetMemoryUsedByList(edges_) + 353 GetMemoryUsedByList(edges_) +
360 GetMemoryUsedByList(children_) + 354 GetMemoryUsedByList(children_) +
361 GetMemoryUsedByList(sorted_entries_); 355 GetMemoryUsedByList(sorted_entries_);
362 } 356 }
363 357
364 358
(...skipping 22 matching lines...) Expand all
387 // When we do lookup in HashMap we see no difference between two cases: 381 // When we do lookup in HashMap we see no difference between two cases:
388 // it has an entry with NULL as the value or it has created 382 // it has an entry with NULL as the value or it has created
389 // a new entry on the fly with NULL as the default value. 383 // a new entry on the fly with NULL as the default value.
390 // With such dummy element we have a guaranty that all entries_map_ entries 384 // With such dummy element we have a guaranty that all entries_map_ entries
391 // will have the value field grater than 0. 385 // will have the value field grater than 0.
392 // This fact is using in MoveObject method. 386 // This fact is using in MoveObject method.
393 entries_.Add(EntryInfo(0, NULL, 0)); 387 entries_.Add(EntryInfo(0, NULL, 0));
394 } 388 }
395 389
396 390
397 void HeapObjectsMap::SnapshotGenerationFinished() {
398 RemoveDeadEntries();
399 }
400
401
402 void HeapObjectsMap::MoveObject(Address from, Address to, int object_size) { 391 void HeapObjectsMap::MoveObject(Address from, Address to, int object_size) {
403 ASSERT(to != NULL); 392 ASSERT(to != NULL);
404 ASSERT(from != NULL); 393 ASSERT(from != NULL);
405 if (from == to) return; 394 if (from == to) return;
406 void* from_value = entries_map_.Remove(from, ComputePointerHash(from)); 395 void* from_value = entries_map_.Remove(from, ComputePointerHash(from));
407 if (from_value == NULL) { 396 if (from_value == NULL) {
408 // It may occur that some untracked object moves to an address X and there 397 // It may occur that some untracked object moves to an address X and there
409 // is a tracked object at that address. In this case we should remove the 398 // is a tracked object at that address. In this case we should remove the
410 // entry as we know that the object has died. 399 // entry as we know that the object has died.
411 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); 400 void* to_value = entries_map_.Remove(to, ComputePointerHash(to));
(...skipping 27 matching lines...) Expand all
439 to, 428 to,
440 entries_.at(from_entry_info_index).size, 429 entries_.at(from_entry_info_index).size,
441 object_size); 430 object_size);
442 } 431 }
443 entries_.at(from_entry_info_index).size = object_size; 432 entries_.at(from_entry_info_index).size = object_size;
444 to_entry->value = from_value; 433 to_entry->value = from_value;
445 } 434 }
446 } 435 }
447 436
448 437
449 void HeapObjectsMap::NewObject(Address addr, int size) {
450 if (FLAG_heap_profiler_trace_objects) {
451 PrintF("New object : %p %6d. Next address is %p\n",
452 addr,
453 size,
454 addr + size);
455 }
456 ASSERT(addr != NULL);
457 FindOrAddEntry(addr, size, false);
458 }
459
460
461 void HeapObjectsMap::UpdateObjectSize(Address addr, int size) { 438 void HeapObjectsMap::UpdateObjectSize(Address addr, int size) {
462 FindOrAddEntry(addr, size, false); 439 FindOrAddEntry(addr, size, false);
463 } 440 }
464 441
465 442
466 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { 443 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) {
467 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), 444 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr),
468 false); 445 false);
469 if (entry == NULL) return 0; 446 if (entry == NULL) return 0;
470 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); 447 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 time_intervals_.Clear(); 484 time_intervals_.Clear();
508 } 485 }
509 486
510 487
511 void HeapObjectsMap::UpdateHeapObjectsMap() { 488 void HeapObjectsMap::UpdateHeapObjectsMap() {
512 if (FLAG_heap_profiler_trace_objects) { 489 if (FLAG_heap_profiler_trace_objects) {
513 PrintF("Begin HeapObjectsMap::UpdateHeapObjectsMap. map has %d entries.\n", 490 PrintF("Begin HeapObjectsMap::UpdateHeapObjectsMap. map has %d entries.\n",
514 entries_map_.occupancy()); 491 entries_map_.occupancy());
515 } 492 }
516 heap_->CollectAllGarbage(Heap::kMakeHeapIterableMask, 493 heap_->CollectAllGarbage(Heap::kMakeHeapIterableMask,
517 "HeapSnapshotsCollection::UpdateHeapObjectsMap"); 494 "HeapObjectsMap::UpdateHeapObjectsMap");
518 HeapIterator iterator(heap_); 495 HeapIterator iterator(heap_);
519 for (HeapObject* obj = iterator.next(); 496 for (HeapObject* obj = iterator.next();
520 obj != NULL; 497 obj != NULL;
521 obj = iterator.next()) { 498 obj = iterator.next()) {
522 FindOrAddEntry(obj->address(), obj->Size()); 499 FindOrAddEntry(obj->address(), obj->Size());
523 if (FLAG_heap_profiler_trace_objects) { 500 if (FLAG_heap_profiler_trace_objects) {
524 PrintF("Update object : %p %6d. Next address is %p\n", 501 PrintF("Update object : %p %6d. Next address is %p\n",
525 obj->address(), 502 obj->address(),
526 obj->Size(), 503 obj->Size(),
527 obj->address() + obj->Size()); 504 obj->address() + obj->Size());
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 ComputePointerHash(entry_info.addr)); 692 ComputePointerHash(entry_info.addr));
716 } 693 }
717 } 694 }
718 } 695 }
719 entries_.Rewind(first_free_entry); 696 entries_.Rewind(first_free_entry);
720 ASSERT(static_cast<uint32_t>(entries_.length()) - 1 == 697 ASSERT(static_cast<uint32_t>(entries_.length()) - 1 ==
721 entries_map_.occupancy()); 698 entries_map_.occupancy());
722 } 699 }
723 700
724 701
725 SnapshotObjectId HeapObjectsMap::GenerateId(Heap* heap, 702 SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
726 v8::RetainedObjectInfo* info) {
727 SnapshotObjectId id = static_cast<SnapshotObjectId>(info->GetHash()); 703 SnapshotObjectId id = static_cast<SnapshotObjectId>(info->GetHash());
728 const char* label = info->GetLabel(); 704 const char* label = info->GetLabel();
729 id ^= StringHasher::HashSequentialString(label, 705 id ^= StringHasher::HashSequentialString(label,
730 static_cast<int>(strlen(label)), 706 static_cast<int>(strlen(label)),
731 heap->HashSeed()); 707 heap_->HashSeed());
732 intptr_t element_count = info->GetElementCount(); 708 intptr_t element_count = info->GetElementCount();
733 if (element_count != -1) 709 if (element_count != -1)
734 id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count), 710 id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count),
735 v8::internal::kZeroHashSeed); 711 v8::internal::kZeroHashSeed);
736 return id << 1; 712 return id << 1;
737 } 713 }
738 714
739 715
740 size_t HeapObjectsMap::GetUsedMemorySize() const { 716 size_t HeapObjectsMap::GetUsedMemorySize() const {
741 return 717 return
742 sizeof(*this) + 718 sizeof(*this) +
743 sizeof(HashMap::Entry) * entries_map_.capacity() + 719 sizeof(HashMap::Entry) * entries_map_.capacity() +
744 GetMemoryUsedByList(entries_) + 720 GetMemoryUsedByList(entries_) +
745 GetMemoryUsedByList(time_intervals_); 721 GetMemoryUsedByList(time_intervals_);
746 } 722 }
747 723
748 724
749 HeapSnapshotsCollection::HeapSnapshotsCollection(Heap* heap)
750 : is_tracking_objects_(false),
751 names_(heap),
752 ids_(heap),
753 allocation_tracker_(NULL) {
754 }
755
756
757 static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) {
758 delete *snapshot_ptr;
759 }
760
761
762 HeapSnapshotsCollection::~HeapSnapshotsCollection() {
763 delete allocation_tracker_;
764 snapshots_.Iterate(DeleteHeapSnapshot);
765 }
766
767
768 void HeapSnapshotsCollection::StartHeapObjectsTracking() {
769 ids_.UpdateHeapObjectsMap();
770 if (allocation_tracker_ == NULL) {
771 allocation_tracker_ = new AllocationTracker(&ids_, names());
772 }
773 is_tracking_objects_ = true;
774 }
775
776
777 void HeapSnapshotsCollection::StopHeapObjectsTracking() {
778 ids_.StopHeapObjectsTracking();
779 if (allocation_tracker_ != NULL) {
780 delete allocation_tracker_;
781 allocation_tracker_ = NULL;
782 }
783 }
784
785
786 HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(const char* name,
787 unsigned uid) {
788 is_tracking_objects_ = true; // Start watching for heap objects moves.
789 return new HeapSnapshot(this, name, uid);
790 }
791
792
793 void HeapSnapshotsCollection::SnapshotGenerationFinished(
794 HeapSnapshot* snapshot) {
795 ids_.SnapshotGenerationFinished();
796 if (snapshot != NULL) {
797 snapshots_.Add(snapshot);
798 }
799 }
800
801
802 void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) {
803 snapshots_.RemoveElement(snapshot);
804 }
805
806
807 Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(
808 SnapshotObjectId id) {
809 // First perform a full GC in order to avoid dead objects.
810 heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
811 "HeapSnapshotsCollection::FindHeapObjectById");
812 DisallowHeapAllocation no_allocation;
813 HeapObject* object = NULL;
814 HeapIterator iterator(heap(), HeapIterator::kFilterUnreachable);
815 // Make sure that object with the given id is still reachable.
816 for (HeapObject* obj = iterator.next();
817 obj != NULL;
818 obj = iterator.next()) {
819 if (ids_.FindEntry(obj->address()) == id) {
820 ASSERT(object == NULL);
821 object = obj;
822 // Can't break -- kFilterUnreachable requires full heap traversal.
823 }
824 }
825 return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>();
826 }
827
828
829 void HeapSnapshotsCollection::NewObjectEvent(Address addr, int size) {
830 DisallowHeapAllocation no_allocation;
831 ids_.NewObject(addr, size);
832 if (allocation_tracker_ != NULL) {
833 allocation_tracker_->NewObjectEvent(addr, size);
834 }
835 }
836
837
838 size_t HeapSnapshotsCollection::GetUsedMemorySize() const {
839 size_t size = sizeof(*this);
840 size += names_.GetUsedMemorySize();
841 size += ids_.GetUsedMemorySize();
842 size += GetMemoryUsedByList(snapshots_);
843 for (int i = 0; i < snapshots_.length(); ++i) {
844 size += snapshots_[i]->RawSnapshotSize();
845 }
846 return size;
847 }
848
849
850 HeapEntriesMap::HeapEntriesMap() 725 HeapEntriesMap::HeapEntriesMap()
851 : entries_(HeapThingsMatch) { 726 : entries_(HeapThingsMatch) {
852 } 727 }
853 728
854 729
855 int HeapEntriesMap::Map(HeapThing thing) { 730 int HeapEntriesMap::Map(HeapThing thing) {
856 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false); 731 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
857 if (cache_entry == NULL) return HeapEntry::kNoEntry; 732 if (cache_entry == NULL) return HeapEntry::kNoEntry;
858 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); 733 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value));
859 } 734 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 static_cast<intptr_t>(HeapObjectsMap::kGcRootsFirstSubrootId)); 795 static_cast<intptr_t>(HeapObjectsMap::kGcRootsFirstSubrootId));
921 HeapObject* const V8HeapExplorer::kLastGcSubrootObject = 796 HeapObject* const V8HeapExplorer::kLastGcSubrootObject =
922 reinterpret_cast<HeapObject*>( 797 reinterpret_cast<HeapObject*>(
923 static_cast<intptr_t>(HeapObjectsMap::kFirstAvailableObjectId)); 798 static_cast<intptr_t>(HeapObjectsMap::kFirstAvailableObjectId));
924 799
925 800
926 V8HeapExplorer::V8HeapExplorer( 801 V8HeapExplorer::V8HeapExplorer(
927 HeapSnapshot* snapshot, 802 HeapSnapshot* snapshot,
928 SnapshottingProgressReportingInterface* progress, 803 SnapshottingProgressReportingInterface* progress,
929 v8::HeapProfiler::ObjectNameResolver* resolver) 804 v8::HeapProfiler::ObjectNameResolver* resolver)
930 : heap_(snapshot->collection()->heap()), 805 : heap_(snapshot->profiler()->heap_object_map()->heap()),
931 snapshot_(snapshot), 806 snapshot_(snapshot),
932 collection_(snapshot_->collection()), 807 names_(snapshot_->profiler()->names()),
808 heap_object_map_(snapshot_->profiler()->heap_object_map()),
933 progress_(progress), 809 progress_(progress),
934 filler_(NULL), 810 filler_(NULL),
935 global_object_name_resolver_(resolver) { 811 global_object_name_resolver_(resolver) {
936 } 812 }
937 813
938 814
939 V8HeapExplorer::~V8HeapExplorer() { 815 V8HeapExplorer::~V8HeapExplorer() {
940 } 816 }
941 817
942 818
943 HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) { 819 HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) {
944 return AddEntry(reinterpret_cast<HeapObject*>(ptr)); 820 return AddEntry(reinterpret_cast<HeapObject*>(ptr));
945 } 821 }
946 822
947 823
948 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { 824 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
949 if (object == kInternalRootObject) { 825 if (object == kInternalRootObject) {
950 snapshot_->AddRootEntry(); 826 snapshot_->AddRootEntry();
951 return snapshot_->root(); 827 return snapshot_->root();
952 } else if (object == kGcRootsObject) { 828 } else if (object == kGcRootsObject) {
953 HeapEntry* entry = snapshot_->AddGcRootsEntry(); 829 HeapEntry* entry = snapshot_->AddGcRootsEntry();
954 return entry; 830 return entry;
955 } else if (object >= kFirstGcSubrootObject && object < kLastGcSubrootObject) { 831 } else if (object >= kFirstGcSubrootObject && object < kLastGcSubrootObject) {
956 HeapEntry* entry = snapshot_->AddGcSubrootEntry(GetGcSubrootOrder(object)); 832 HeapEntry* entry = snapshot_->AddGcSubrootEntry(GetGcSubrootOrder(object));
957 return entry; 833 return entry;
958 } else if (object->IsJSFunction()) { 834 } else if (object->IsJSFunction()) {
959 JSFunction* func = JSFunction::cast(object); 835 JSFunction* func = JSFunction::cast(object);
960 SharedFunctionInfo* shared = func->shared(); 836 SharedFunctionInfo* shared = func->shared();
961 const char* name = shared->bound() ? "native_bind" : 837 const char* name = shared->bound() ? "native_bind" :
962 collection_->names()->GetName(String::cast(shared->name())); 838 names_->GetName(String::cast(shared->name()));
963 return AddEntry(object, HeapEntry::kClosure, name); 839 return AddEntry(object, HeapEntry::kClosure, name);
964 } else if (object->IsJSRegExp()) { 840 } else if (object->IsJSRegExp()) {
965 JSRegExp* re = JSRegExp::cast(object); 841 JSRegExp* re = JSRegExp::cast(object);
966 return AddEntry(object, 842 return AddEntry(object,
967 HeapEntry::kRegExp, 843 HeapEntry::kRegExp,
968 collection_->names()->GetName(re->Pattern())); 844 names_->GetName(re->Pattern()));
969 } else if (object->IsJSObject()) { 845 } else if (object->IsJSObject()) {
970 const char* name = collection_->names()->GetName( 846 const char* name = names_->GetName(
971 GetConstructorName(JSObject::cast(object))); 847 GetConstructorName(JSObject::cast(object)));
972 if (object->IsJSGlobalObject()) { 848 if (object->IsJSGlobalObject()) {
973 const char* tag = objects_tags_.GetTag(object); 849 const char* tag = objects_tags_.GetTag(object);
974 if (tag != NULL) { 850 if (tag != NULL) {
975 name = collection_->names()->GetFormatted("%s / %s", name, tag); 851 name = names_->GetFormatted("%s / %s", name, tag);
976 } 852 }
977 } 853 }
978 return AddEntry(object, HeapEntry::kObject, name); 854 return AddEntry(object, HeapEntry::kObject, name);
979 } else if (object->IsString()) { 855 } else if (object->IsString()) {
980 String* string = String::cast(object); 856 String* string = String::cast(object);
981 if (string->IsConsString()) 857 if (string->IsConsString())
982 return AddEntry(object, 858 return AddEntry(object,
983 HeapEntry::kConsString, 859 HeapEntry::kConsString,
984 "(concatenated string)"); 860 "(concatenated string)");
985 if (string->IsSlicedString()) 861 if (string->IsSlicedString())
986 return AddEntry(object, 862 return AddEntry(object,
987 HeapEntry::kSlicedString, 863 HeapEntry::kSlicedString,
988 "(sliced string)"); 864 "(sliced string)");
989 return AddEntry(object, 865 return AddEntry(object,
990 HeapEntry::kString, 866 HeapEntry::kString,
991 collection_->names()->GetName(String::cast(object))); 867 names_->GetName(String::cast(object)));
992 } else if (object->IsCode()) { 868 } else if (object->IsCode()) {
993 return AddEntry(object, HeapEntry::kCode, ""); 869 return AddEntry(object, HeapEntry::kCode, "");
994 } else if (object->IsSharedFunctionInfo()) { 870 } else if (object->IsSharedFunctionInfo()) {
995 String* name = String::cast(SharedFunctionInfo::cast(object)->name()); 871 String* name = String::cast(SharedFunctionInfo::cast(object)->name());
996 return AddEntry(object, 872 return AddEntry(object,
997 HeapEntry::kCode, 873 HeapEntry::kCode,
998 collection_->names()->GetName(name)); 874 names_->GetName(name));
999 } else if (object->IsScript()) { 875 } else if (object->IsScript()) {
1000 Object* name = Script::cast(object)->name(); 876 Object* name = Script::cast(object)->name();
1001 return AddEntry(object, 877 return AddEntry(object,
1002 HeapEntry::kCode, 878 HeapEntry::kCode,
1003 name->IsString() 879 name->IsString()
1004 ? collection_->names()->GetName(String::cast(name)) 880 ? names_->GetName(String::cast(name))
1005 : ""); 881 : "");
1006 } else if (object->IsNativeContext()) { 882 } else if (object->IsNativeContext()) {
1007 return AddEntry(object, HeapEntry::kHidden, "system / NativeContext"); 883 return AddEntry(object, HeapEntry::kHidden, "system / NativeContext");
1008 } else if (object->IsContext()) { 884 } else if (object->IsContext()) {
1009 return AddEntry(object, HeapEntry::kObject, "system / Context"); 885 return AddEntry(object, HeapEntry::kObject, "system / Context");
1010 } else if (object->IsFixedArray() || 886 } else if (object->IsFixedArray() ||
1011 object->IsFixedDoubleArray() || 887 object->IsFixedDoubleArray() ||
1012 object->IsByteArray() || 888 object->IsByteArray() ||
1013 object->IsExternalArray()) { 889 object->IsExternalArray()) {
1014 return AddEntry(object, HeapEntry::kArray, ""); 890 return AddEntry(object, HeapEntry::kArray, "");
1015 } else if (object->IsHeapNumber()) { 891 } else if (object->IsHeapNumber()) {
1016 return AddEntry(object, HeapEntry::kHeapNumber, "number"); 892 return AddEntry(object, HeapEntry::kHeapNumber, "number");
1017 } 893 }
1018 return AddEntry(object, HeapEntry::kHidden, GetSystemEntryName(object)); 894 return AddEntry(object, HeapEntry::kHidden, GetSystemEntryName(object));
1019 } 895 }
1020 896
1021 897
1022 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, 898 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
1023 HeapEntry::Type type, 899 HeapEntry::Type type,
1024 const char* name) { 900 const char* name) {
1025 int object_size = object->Size(); 901 int object_size = object->Size();
1026 SnapshotObjectId object_id = 902 SnapshotObjectId object_id =
1027 collection_->GetObjectId(object->address(), object_size); 903 heap_object_map_->FindOrAddEntry(object->address(), object_size);
1028 return snapshot_->AddEntry(type, name, object_id, object_size); 904 return snapshot_->AddEntry(type, name, object_id, object_size);
1029 } 905 }
1030 906
1031 907
1032 class GcSubrootsEnumerator : public ObjectVisitor { 908 class GcSubrootsEnumerator : public ObjectVisitor {
1033 public: 909 public:
1034 GcSubrootsEnumerator( 910 GcSubrootsEnumerator(
1035 SnapshotFillerInterface* filler, V8HeapExplorer* explorer) 911 SnapshotFillerInterface* filler, V8HeapExplorer* explorer)
1036 : filler_(filler), 912 : filler_(filler),
1037 explorer_(explorer), 913 explorer_(explorer),
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 TagObject(map->dependent_code(), "(dependent code)"); 1240 TagObject(map->dependent_code(), "(dependent code)");
1365 SetInternalReference(map, entry, 1241 SetInternalReference(map, entry,
1366 "dependent_code", map->dependent_code(), 1242 "dependent_code", map->dependent_code(),
1367 Map::kDependentCodeOffset); 1243 Map::kDependentCodeOffset);
1368 } 1244 }
1369 1245
1370 1246
1371 void V8HeapExplorer::ExtractSharedFunctionInfoReferences( 1247 void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
1372 int entry, SharedFunctionInfo* shared) { 1248 int entry, SharedFunctionInfo* shared) {
1373 HeapObject* obj = shared; 1249 HeapObject* obj = shared;
1374 StringsStorage* names = collection_->names();
1375 String* shared_name = shared->DebugName(); 1250 String* shared_name = shared->DebugName();
1376 const char* name = NULL; 1251 const char* name = NULL;
1377 if (shared_name != *heap_->isolate()->factory()->empty_string()) { 1252 if (shared_name != *heap_->isolate()->factory()->empty_string()) {
1378 name = names->GetName(shared_name); 1253 name = names_->GetName(shared_name);
1379 TagObject(shared->code(), names->GetFormatted("(code for %s)", name)); 1254 TagObject(shared->code(), names_->GetFormatted("(code for %s)", name));
1380 } else { 1255 } else {
1381 TagObject(shared->code(), names->GetFormatted("(%s code)", 1256 TagObject(shared->code(), names_->GetFormatted("(%s code)",
1382 Code::Kind2String(shared->code()->kind()))); 1257 Code::Kind2String(shared->code()->kind())));
1383 } 1258 }
1384 1259
1385 SetInternalReference(obj, entry, 1260 SetInternalReference(obj, entry,
1386 "name", shared->name(), 1261 "name", shared->name(),
1387 SharedFunctionInfo::kNameOffset); 1262 SharedFunctionInfo::kNameOffset);
1388 SetInternalReference(obj, entry, 1263 SetInternalReference(obj, entry,
1389 "code", shared->code(), 1264 "code", shared->code(),
1390 SharedFunctionInfo::kCodeOffset); 1265 SharedFunctionInfo::kCodeOffset);
1391 TagObject(shared->scope_info(), "(function scope info)"); 1266 TagObject(shared->scope_info(), "(function scope info)");
1392 SetInternalReference(obj, entry, 1267 SetInternalReference(obj, entry,
1393 "scope_info", shared->scope_info(), 1268 "scope_info", shared->scope_info(),
1394 SharedFunctionInfo::kScopeInfoOffset); 1269 SharedFunctionInfo::kScopeInfoOffset);
1395 SetInternalReference(obj, entry, 1270 SetInternalReference(obj, entry,
1396 "instance_class_name", shared->instance_class_name(), 1271 "instance_class_name", shared->instance_class_name(),
1397 SharedFunctionInfo::kInstanceClassNameOffset); 1272 SharedFunctionInfo::kInstanceClassNameOffset);
1398 SetInternalReference(obj, entry, 1273 SetInternalReference(obj, entry,
1399 "script", shared->script(), 1274 "script", shared->script(),
1400 SharedFunctionInfo::kScriptOffset); 1275 SharedFunctionInfo::kScriptOffset);
1401 const char* construct_stub_name = name ? 1276 const char* construct_stub_name = name ?
1402 names->GetFormatted("(construct stub code for %s)", name) : 1277 names_->GetFormatted("(construct stub code for %s)", name) :
1403 "(construct stub code)"; 1278 "(construct stub code)";
1404 TagObject(shared->construct_stub(), construct_stub_name); 1279 TagObject(shared->construct_stub(), construct_stub_name);
1405 SetInternalReference(obj, entry, 1280 SetInternalReference(obj, entry,
1406 "construct_stub", shared->construct_stub(), 1281 "construct_stub", shared->construct_stub(),
1407 SharedFunctionInfo::kConstructStubOffset); 1282 SharedFunctionInfo::kConstructStubOffset);
1408 SetInternalReference(obj, entry, 1283 SetInternalReference(obj, entry,
1409 "function_data", shared->function_data(), 1284 "function_data", shared->function_data(),
1410 SharedFunctionInfo::kFunctionDataOffset); 1285 SharedFunctionInfo::kFunctionDataOffset);
1411 SetInternalReference(obj, entry, 1286 SetInternalReference(obj, entry,
1412 "debug_info", shared->debug_info(), 1287 "debug_info", shared->debug_info(),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 "default_cache", code_cache->default_cache(), 1335 "default_cache", code_cache->default_cache(),
1461 CodeCache::kDefaultCacheOffset); 1336 CodeCache::kDefaultCacheOffset);
1462 TagObject(code_cache->normal_type_cache(), "(code type cache)"); 1337 TagObject(code_cache->normal_type_cache(), "(code type cache)");
1463 SetInternalReference(code_cache, entry, 1338 SetInternalReference(code_cache, entry,
1464 "type_cache", code_cache->normal_type_cache(), 1339 "type_cache", code_cache->normal_type_cache(),
1465 CodeCache::kNormalTypeCacheOffset); 1340 CodeCache::kNormalTypeCacheOffset);
1466 } 1341 }
1467 1342
1468 1343
1469 void V8HeapExplorer::TagCodeObject(Code* code, const char* external_name) { 1344 void V8HeapExplorer::TagCodeObject(Code* code, const char* external_name) {
1470 TagObject(code, collection_->names()->GetFormatted("(%s code)", 1345 TagObject(code, names_->GetFormatted("(%s code)", external_name));
1471 external_name));
1472 } 1346 }
1473 1347
1474 1348
1475 void V8HeapExplorer::TagCodeObject(Code* code) { 1349 void V8HeapExplorer::TagCodeObject(Code* code) {
1476 if (code->kind() == Code::STUB) { 1350 if (code->kind() == Code::STUB) {
1477 TagObject(code, collection_->names()->GetFormatted( 1351 TagObject(code, names_->GetFormatted(
1478 "(%s code)", CodeStub::MajorName( 1352 "(%s code)", CodeStub::MajorName(
1479 static_cast<CodeStub::Major>(code->major_key()), true))); 1353 static_cast<CodeStub::Major>(code->major_key()), true)));
1480 } 1354 }
1481 } 1355 }
1482 1356
1483 1357
1484 void V8HeapExplorer::ExtractCodeReferences(int entry, Code* code) { 1358 void V8HeapExplorer::ExtractCodeReferences(int entry, Code* code) {
1485 TagCodeObject(code); 1359 TagCodeObject(code);
1486 TagObject(code->relocation_info(), "(code relocation info)"); 1360 TagObject(code->relocation_info(), "(code relocation info)");
1487 SetInternalReference(code, entry, 1361 SetInternalReference(code, entry,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1545 1419
1546 JSFunction* func = JSFunction::cast(js_obj); 1420 JSFunction* func = JSFunction::cast(js_obj);
1547 if (func->shared()->bound()) { 1421 if (func->shared()->bound()) {
1548 FixedArray* bindings = func->function_bindings(); 1422 FixedArray* bindings = func->function_bindings();
1549 SetNativeBindReference(js_obj, entry, "bound_this", 1423 SetNativeBindReference(js_obj, entry, "bound_this",
1550 bindings->get(JSFunction::kBoundThisIndex)); 1424 bindings->get(JSFunction::kBoundThisIndex));
1551 SetNativeBindReference(js_obj, entry, "bound_function", 1425 SetNativeBindReference(js_obj, entry, "bound_function",
1552 bindings->get(JSFunction::kBoundFunctionIndex)); 1426 bindings->get(JSFunction::kBoundFunctionIndex));
1553 for (int i = JSFunction::kBoundArgumentsStartIndex; 1427 for (int i = JSFunction::kBoundArgumentsStartIndex;
1554 i < bindings->length(); i++) { 1428 i < bindings->length(); i++) {
1555 const char* reference_name = collection_->names()->GetFormatted( 1429 const char* reference_name = names_->GetFormatted(
1556 "bound_argument_%d", 1430 "bound_argument_%d",
1557 i - JSFunction::kBoundArgumentsStartIndex); 1431 i - JSFunction::kBoundArgumentsStartIndex);
1558 SetNativeBindReference(js_obj, entry, reference_name, 1432 SetNativeBindReference(js_obj, entry, reference_name,
1559 bindings->get(i)); 1433 bindings->get(i));
1560 } 1434 }
1561 } 1435 }
1562 } 1436 }
1563 1437
1564 1438
1565 void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) { 1439 void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, int entry) {
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 void V8HeapExplorer::SetContextReference(HeapObject* parent_obj, 1726 void V8HeapExplorer::SetContextReference(HeapObject* parent_obj,
1853 int parent_entry, 1727 int parent_entry,
1854 String* reference_name, 1728 String* reference_name,
1855 Object* child_obj, 1729 Object* child_obj,
1856 int field_offset) { 1730 int field_offset) {
1857 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 1731 ASSERT(parent_entry == GetEntry(parent_obj)->index());
1858 HeapEntry* child_entry = GetEntry(child_obj); 1732 HeapEntry* child_entry = GetEntry(child_obj);
1859 if (child_entry != NULL) { 1733 if (child_entry != NULL) {
1860 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, 1734 filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
1861 parent_entry, 1735 parent_entry,
1862 collection_->names()->GetName(reference_name), 1736 names_->GetName(reference_name),
1863 child_entry); 1737 child_entry);
1864 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1738 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
1865 } 1739 }
1866 } 1740 }
1867 1741
1868 1742
1869 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj, 1743 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj,
1870 int parent_entry, 1744 int parent_entry,
1871 const char* reference_name, 1745 const char* reference_name,
1872 Object* child_obj) { 1746 Object* child_obj) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1918 int parent_entry, 1792 int parent_entry,
1919 int index, 1793 int index,
1920 Object* child_obj, 1794 Object* child_obj,
1921 int field_offset) { 1795 int field_offset) {
1922 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 1796 ASSERT(parent_entry == GetEntry(parent_obj)->index());
1923 HeapEntry* child_entry = GetEntry(child_obj); 1797 HeapEntry* child_entry = GetEntry(child_obj);
1924 if (child_entry == NULL) return; 1798 if (child_entry == NULL) return;
1925 if (IsEssentialObject(child_obj)) { 1799 if (IsEssentialObject(child_obj)) {
1926 filler_->SetNamedReference(HeapGraphEdge::kInternal, 1800 filler_->SetNamedReference(HeapGraphEdge::kInternal,
1927 parent_entry, 1801 parent_entry,
1928 collection_->names()->GetName(index), 1802 names_->GetName(index),
1929 child_entry); 1803 child_entry);
1930 } 1804 }
1931 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1805 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
1932 } 1806 }
1933 1807
1934 1808
1935 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, 1809 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
1936 int parent_entry, 1810 int parent_entry,
1937 int index, 1811 int index,
1938 Object* child_obj) { 1812 Object* child_obj) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1971 Object* child_obj, 1845 Object* child_obj,
1972 const char* name_format_string, 1846 const char* name_format_string,
1973 int field_offset) { 1847 int field_offset) {
1974 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 1848 ASSERT(parent_entry == GetEntry(parent_obj)->index());
1975 HeapEntry* child_entry = GetEntry(child_obj); 1849 HeapEntry* child_entry = GetEntry(child_obj);
1976 if (child_entry != NULL) { 1850 if (child_entry != NULL) {
1977 HeapGraphEdge::Type type = 1851 HeapGraphEdge::Type type =
1978 reference_name->IsSymbol() || String::cast(reference_name)->length() > 0 1852 reference_name->IsSymbol() || String::cast(reference_name)->length() > 0
1979 ? HeapGraphEdge::kProperty : HeapGraphEdge::kInternal; 1853 ? HeapGraphEdge::kProperty : HeapGraphEdge::kInternal;
1980 const char* name = name_format_string != NULL && reference_name->IsString() 1854 const char* name = name_format_string != NULL && reference_name->IsString()
1981 ? collection_->names()->GetFormatted( 1855 ? names_->GetFormatted(
1982 name_format_string, 1856 name_format_string,
1983 *String::cast(reference_name)->ToCString( 1857 *String::cast(reference_name)->ToCString(
1984 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)) : 1858 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)) :
1985 collection_->names()->GetName(reference_name); 1859 names_->GetName(reference_name);
1986 1860
1987 filler_->SetNamedReference(type, 1861 filler_->SetNamedReference(type,
1988 parent_entry, 1862 parent_entry,
1989 name, 1863 name,
1990 child_entry); 1864 child_entry);
1991 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1865 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
1992 } 1866 }
1993 } 1867 }
1994 1868
1995 1869
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2151 NativeObjectsExplorer* explorer_; 2025 NativeObjectsExplorer* explorer_;
2152 }; 2026 };
2153 2027
2154 2028
2155 class BasicHeapEntriesAllocator : public HeapEntriesAllocator { 2029 class BasicHeapEntriesAllocator : public HeapEntriesAllocator {
2156 public: 2030 public:
2157 BasicHeapEntriesAllocator( 2031 BasicHeapEntriesAllocator(
2158 HeapSnapshot* snapshot, 2032 HeapSnapshot* snapshot,
2159 HeapEntry::Type entries_type) 2033 HeapEntry::Type entries_type)
2160 : snapshot_(snapshot), 2034 : snapshot_(snapshot),
2161 collection_(snapshot_->collection()), 2035 names_(snapshot_->profiler()->names()),
2036 heap_object_map_(snapshot_->profiler()->heap_object_map()),
2162 entries_type_(entries_type) { 2037 entries_type_(entries_type) {
2163 } 2038 }
2164 virtual HeapEntry* AllocateEntry(HeapThing ptr); 2039 virtual HeapEntry* AllocateEntry(HeapThing ptr);
2165 private: 2040 private:
2166 HeapSnapshot* snapshot_; 2041 HeapSnapshot* snapshot_;
2167 HeapSnapshotsCollection* collection_; 2042 StringsStorage* names_;
2043 HeapObjectsMap* heap_object_map_;
2168 HeapEntry::Type entries_type_; 2044 HeapEntry::Type entries_type_;
2169 }; 2045 };
2170 2046
2171 2047
2172 HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) { 2048 HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) {
2173 v8::RetainedObjectInfo* info = reinterpret_cast<v8::RetainedObjectInfo*>(ptr); 2049 v8::RetainedObjectInfo* info = reinterpret_cast<v8::RetainedObjectInfo*>(ptr);
2174 intptr_t elements = info->GetElementCount(); 2050 intptr_t elements = info->GetElementCount();
2175 intptr_t size = info->GetSizeInBytes(); 2051 intptr_t size = info->GetSizeInBytes();
2176 const char* name = elements != -1 2052 const char* name = elements != -1
2177 ? collection_->names()->GetFormatted( 2053 ? names_->GetFormatted(
2178 "%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements) 2054 "%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements)
2179 : collection_->names()->GetCopy(info->GetLabel()); 2055 : names_->GetCopy(info->GetLabel());
2180 return snapshot_->AddEntry( 2056 return snapshot_->AddEntry(
2181 entries_type_, 2057 entries_type_,
2182 name, 2058 name,
2183 HeapObjectsMap::GenerateId(collection_->heap(), info), 2059 heap_object_map_->GenerateId(info),
2184 size != -1 ? static_cast<int>(size) : 0); 2060 size != -1 ? static_cast<int>(size) : 0);
2185 } 2061 }
2186 2062
2187 2063
2188 NativeObjectsExplorer::NativeObjectsExplorer( 2064 NativeObjectsExplorer::NativeObjectsExplorer(
2189 HeapSnapshot* snapshot, 2065 HeapSnapshot* snapshot,
2190 SnapshottingProgressReportingInterface* progress) 2066 SnapshottingProgressReportingInterface* progress)
2191 : isolate_(snapshot->collection()->heap()->isolate()), 2067 : isolate_(snapshot->profiler()->heap_object_map()->heap()->isolate()),
2192 snapshot_(snapshot), 2068 snapshot_(snapshot),
2193 collection_(snapshot_->collection()), 2069 names_(snapshot_->profiler()->names()),
2194 progress_(progress), 2070 progress_(progress),
2195 embedder_queried_(false), 2071 embedder_queried_(false),
2196 objects_by_info_(RetainedInfosMatch), 2072 objects_by_info_(RetainedInfosMatch),
2197 native_groups_(StringsMatch), 2073 native_groups_(StringsMatch),
2198 filler_(NULL) { 2074 filler_(NULL) {
2199 synthetic_entries_allocator_ = 2075 synthetic_entries_allocator_ =
2200 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic); 2076 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic);
2201 native_entries_allocator_ = 2077 native_entries_allocator_ =
2202 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative); 2078 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative);
2203 } 2079 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2345 2221
2346 private: 2222 private:
2347 bool disposed_; 2223 bool disposed_;
2348 intptr_t hash_; 2224 intptr_t hash_;
2349 const char* label_; 2225 const char* label_;
2350 }; 2226 };
2351 2227
2352 2228
2353 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( 2229 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo(
2354 const char* label) { 2230 const char* label) {
2355 const char* label_copy = collection_->names()->GetCopy(label); 2231 const char* label_copy = names_->GetCopy(label);
2356 uint32_t hash = StringHasher::HashSequentialString( 2232 uint32_t hash = StringHasher::HashSequentialString(
2357 label_copy, 2233 label_copy,
2358 static_cast<int>(strlen(label_copy)), 2234 static_cast<int>(strlen(label_copy)),
2359 isolate_->heap()->HashSeed()); 2235 isolate_->heap()->HashSeed());
2360 HashMap::Entry* entry = native_groups_.Lookup(const_cast<char*>(label_copy), 2236 HashMap::Entry* entry = native_groups_.Lookup(const_cast<char*>(label_copy),
2361 hash, true); 2237 hash, true);
2362 if (entry->value == NULL) { 2238 if (entry->value == NULL) {
2363 entry->value = new NativeGroupRetainedObjectInfo(label); 2239 entry->value = new NativeGroupRetainedObjectInfo(label);
2364 } 2240 }
2365 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value); 2241 return static_cast<NativeGroupRetainedObjectInfo*>(entry->value);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); 2299 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p);
2424 if (info == NULL) return; 2300 if (info == NULL) return;
2425 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); 2301 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p));
2426 } 2302 }
2427 2303
2428 2304
2429 class SnapshotFiller : public SnapshotFillerInterface { 2305 class SnapshotFiller : public SnapshotFillerInterface {
2430 public: 2306 public:
2431 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) 2307 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
2432 : snapshot_(snapshot), 2308 : snapshot_(snapshot),
2433 collection_(snapshot->collection()), 2309 names_(snapshot->profiler()->names()),
2434 entries_(entries) { } 2310 entries_(entries) { }
2435 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { 2311 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
2436 HeapEntry* entry = allocator->AllocateEntry(ptr); 2312 HeapEntry* entry = allocator->AllocateEntry(ptr);
2437 entries_->Pair(ptr, entry->index()); 2313 entries_->Pair(ptr, entry->index());
2438 return entry; 2314 return entry;
2439 } 2315 }
2440 HeapEntry* FindEntry(HeapThing ptr) { 2316 HeapEntry* FindEntry(HeapThing ptr) {
2441 int index = entries_->Map(ptr); 2317 int index = entries_->Map(ptr);
2442 return index != HeapEntry::kNoEntry ? &snapshot_->entries()[index] : NULL; 2318 return index != HeapEntry::kNoEntry ? &snapshot_->entries()[index] : NULL;
2443 } 2319 }
(...skipping 22 matching lines...) Expand all
2466 HeapEntry* parent_entry = &snapshot_->entries()[parent]; 2342 HeapEntry* parent_entry = &snapshot_->entries()[parent];
2467 parent_entry->SetNamedReference(type, reference_name, child_entry); 2343 parent_entry->SetNamedReference(type, reference_name, child_entry);
2468 } 2344 }
2469 void SetNamedAutoIndexReference(HeapGraphEdge::Type type, 2345 void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
2470 int parent, 2346 int parent,
2471 HeapEntry* child_entry) { 2347 HeapEntry* child_entry) {
2472 HeapEntry* parent_entry = &snapshot_->entries()[parent]; 2348 HeapEntry* parent_entry = &snapshot_->entries()[parent];
2473 int index = parent_entry->children_count() + 1; 2349 int index = parent_entry->children_count() + 1;
2474 parent_entry->SetNamedReference( 2350 parent_entry->SetNamedReference(
2475 type, 2351 type,
2476 collection_->names()->GetName(index), 2352 names_->GetName(index),
2477 child_entry); 2353 child_entry);
2478 } 2354 }
2479 2355
2480 private: 2356 private:
2481 HeapSnapshot* snapshot_; 2357 HeapSnapshot* snapshot_;
2482 HeapSnapshotsCollection* collection_; 2358 StringsStorage* names_;
2483 HeapEntriesMap* entries_; 2359 HeapEntriesMap* entries_;
2484 }; 2360 };
2485 2361
2486 2362
2487 HeapSnapshotGenerator::HeapSnapshotGenerator( 2363 HeapSnapshotGenerator::HeapSnapshotGenerator(
2488 HeapSnapshot* snapshot, 2364 HeapSnapshot* snapshot,
2489 v8::ActivityControl* control, 2365 v8::ActivityControl* control,
2490 v8::HeapProfiler::ObjectNameResolver* resolver, 2366 v8::HeapProfiler::ObjectNameResolver* resolver,
2491 Heap* heap) 2367 Heap* heap)
2492 : snapshot_(snapshot), 2368 : snapshot_(snapshot),
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 }; 2554 };
2679 2555
2680 2556
2681 // type, name|index, to_node. 2557 // type, name|index, to_node.
2682 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3; 2558 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3;
2683 // type, name, id, self_size, children_index. 2559 // type, name, id, self_size, children_index.
2684 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 5; 2560 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 5;
2685 2561
2686 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { 2562 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) {
2687 if (AllocationTracker* allocation_tracker = 2563 if (AllocationTracker* allocation_tracker =
2688 snapshot_->collection()->allocation_tracker()) { 2564 snapshot_->profiler()->allocation_tracker()) {
2689 allocation_tracker->PrepareForSerialization(); 2565 allocation_tracker->PrepareForSerialization();
2690 } 2566 }
2691 ASSERT(writer_ == NULL); 2567 ASSERT(writer_ == NULL);
2692 writer_ = new OutputStreamWriter(stream); 2568 writer_ = new OutputStreamWriter(stream);
2693 SerializeImpl(); 2569 SerializeImpl();
2694 delete writer_; 2570 delete writer_;
2695 writer_ = NULL; 2571 writer_ = NULL;
2696 } 2572 }
2697 2573
2698 2574
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
2897 JSON_S("children")))); 2773 JSON_S("children"))));
2898 #undef JSON_S 2774 #undef JSON_S
2899 #undef JSON_O 2775 #undef JSON_O
2900 #undef JSON_A 2776 #undef JSON_A
2901 writer_->AddString(",\"node_count\":"); 2777 writer_->AddString(",\"node_count\":");
2902 writer_->AddNumber(snapshot_->entries().length()); 2778 writer_->AddNumber(snapshot_->entries().length());
2903 writer_->AddString(",\"edge_count\":"); 2779 writer_->AddString(",\"edge_count\":");
2904 writer_->AddNumber(snapshot_->edges().length()); 2780 writer_->AddNumber(snapshot_->edges().length());
2905 writer_->AddString(",\"trace_function_count\":"); 2781 writer_->AddString(",\"trace_function_count\":");
2906 uint32_t count = 0; 2782 uint32_t count = 0;
2907 AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); 2783 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
2908 if (tracker) { 2784 if (tracker) {
2909 count = tracker->id_to_function_info()->occupancy(); 2785 count = tracker->id_to_function_info()->occupancy();
2910 } 2786 }
2911 writer_->AddNumber(count); 2787 writer_->AddNumber(count);
2912 } 2788 }
2913 2789
2914 2790
2915 static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) { 2791 static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) {
2916 static const char hex_chars[] = "0123456789ABCDEF"; 2792 static const char hex_chars[] = "0123456789ABCDEF";
2917 w->AddString("\\u"); 2793 w->AddString("\\u");
2918 w->AddCharacter(hex_chars[(u >> 12) & 0xf]); 2794 w->AddCharacter(hex_chars[(u >> 12) & 0xf]);
2919 w->AddCharacter(hex_chars[(u >> 8) & 0xf]); 2795 w->AddCharacter(hex_chars[(u >> 8) & 0xf]);
2920 w->AddCharacter(hex_chars[(u >> 4) & 0xf]); 2796 w->AddCharacter(hex_chars[(u >> 4) & 0xf]);
2921 w->AddCharacter(hex_chars[u & 0xf]); 2797 w->AddCharacter(hex_chars[u & 0xf]);
2922 } 2798 }
2923 2799
2924 2800
2925 void HeapSnapshotJSONSerializer::SerializeTraceTree() { 2801 void HeapSnapshotJSONSerializer::SerializeTraceTree() {
2926 AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); 2802 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
2927 if (!tracker) return; 2803 if (!tracker) return;
2928 AllocationTraceTree* traces = tracker->trace_tree(); 2804 AllocationTraceTree* traces = tracker->trace_tree();
2929 SerializeTraceNode(traces->root()); 2805 SerializeTraceNode(traces->root());
2930 } 2806 }
2931 2807
2932 2808
2933 void HeapSnapshotJSONSerializer::SerializeTraceNode(AllocationTraceNode* node) { 2809 void HeapSnapshotJSONSerializer::SerializeTraceNode(AllocationTraceNode* node) {
2934 // The buffer needs space for 4 unsigned ints, 4 commas, [ and \0 2810 // The buffer needs space for 4 unsigned ints, 4 commas, [ and \0
2935 const int kBufferSize = 2811 const int kBufferSize =
2936 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT 2812 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT
(...skipping 30 matching lines...) Expand all
2967 buffer[buffer_pos++] = '0'; 2843 buffer[buffer_pos++] = '0';
2968 } else { 2844 } else {
2969 ASSERT(position >= 0); 2845 ASSERT(position >= 0);
2970 buffer_pos = utoa(static_cast<unsigned>(position + 1), buffer, buffer_pos); 2846 buffer_pos = utoa(static_cast<unsigned>(position + 1), buffer, buffer_pos);
2971 } 2847 }
2972 return buffer_pos; 2848 return buffer_pos;
2973 } 2849 }
2974 2850
2975 2851
2976 void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() { 2852 void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() {
2977 AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); 2853 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
2978 if (!tracker) return; 2854 if (!tracker) return;
2979 // The buffer needs space for 6 unsigned ints, 6 commas, \n and \0 2855 // The buffer needs space for 6 unsigned ints, 6 commas, \n and \0
2980 const int kBufferSize = 2856 const int kBufferSize =
2981 6 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT 2857 6 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT
2982 + 6 + 1 + 1; 2858 + 6 + 1 + 1;
2983 EmbeddedVector<char, kBufferSize> buffer; 2859 EmbeddedVector<char, kBufferSize> buffer;
2984 HashMap* id_to_function_info = tracker->id_to_function_info(); 2860 HashMap* id_to_function_info = tracker->id_to_function_info();
2985 bool first_entry = true; 2861 bool first_entry = true;
2986 for (HashMap::Entry* p = id_to_function_info->Start(); 2862 for (HashMap::Entry* p = id_to_function_info->Start();
2987 p != NULL; 2863 p != NULL;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3078 writer_->AddString("\"<dummy>\""); 2954 writer_->AddString("\"<dummy>\"");
3079 for (int i = 1; i < sorted_strings.length(); ++i) { 2955 for (int i = 1; i < sorted_strings.length(); ++i) {
3080 writer_->AddCharacter(','); 2956 writer_->AddCharacter(',');
3081 SerializeString(sorted_strings[i]); 2957 SerializeString(sorted_strings[i]);
3082 if (writer_->aborted()) return; 2958 if (writer_->aborted()) return;
3083 } 2959 }
3084 } 2960 }
3085 2961
3086 2962
3087 } } // namespace v8::internal 2963 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap-snapshot-generator.h ('k') | src/hydrogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698