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

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

Issue 101393002: Remove HeapSnapshotsCollection class (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years 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/list.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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 time_intervals_.Clear(); 484 time_intervals_.Clear();
496 } 485 }
497 486
498 487
499 void HeapObjectsMap::UpdateHeapObjectsMap() { 488 void HeapObjectsMap::UpdateHeapObjectsMap() {
500 if (FLAG_heap_profiler_trace_objects) { 489 if (FLAG_heap_profiler_trace_objects) {
501 PrintF("Begin HeapObjectsMap::UpdateHeapObjectsMap. map has %d entries.\n", 490 PrintF("Begin HeapObjectsMap::UpdateHeapObjectsMap. map has %d entries.\n",
502 entries_map_.occupancy()); 491 entries_map_.occupancy());
503 } 492 }
504 heap_->CollectAllGarbage(Heap::kMakeHeapIterableMask, 493 heap_->CollectAllGarbage(Heap::kMakeHeapIterableMask,
505 "HeapSnapshotsCollection::UpdateHeapObjectsMap"); 494 "HeapObjectsMap::UpdateHeapObjectsMap");
506 HeapIterator iterator(heap_); 495 HeapIterator iterator(heap_);
507 for (HeapObject* obj = iterator.next(); 496 for (HeapObject* obj = iterator.next();
508 obj != NULL; 497 obj != NULL;
509 obj = iterator.next()) { 498 obj = iterator.next()) {
510 FindOrAddEntry(obj->address(), obj->Size()); 499 FindOrAddEntry(obj->address(), obj->Size());
511 if (FLAG_heap_profiler_trace_objects) { 500 if (FLAG_heap_profiler_trace_objects) {
512 PrintF("Update object : %p %6d. Next address is %p\n", 501 PrintF("Update object : %p %6d. Next address is %p\n",
513 obj->address(), 502 obj->address(),
514 obj->Size(), 503 obj->Size(),
515 obj->address() + obj->Size()); 504 obj->address() + obj->Size());
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 ComputePointerHash(entry_info.addr)); 692 ComputePointerHash(entry_info.addr));
704 } 693 }
705 } 694 }
706 } 695 }
707 entries_.Rewind(first_free_entry); 696 entries_.Rewind(first_free_entry);
708 ASSERT(static_cast<uint32_t>(entries_.length()) - 1 == 697 ASSERT(static_cast<uint32_t>(entries_.length()) - 1 ==
709 entries_map_.occupancy()); 698 entries_map_.occupancy());
710 } 699 }
711 700
712 701
713 SnapshotObjectId HeapObjectsMap::GenerateId(Heap* heap, 702 SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
714 v8::RetainedObjectInfo* info) {
715 SnapshotObjectId id = static_cast<SnapshotObjectId>(info->GetHash()); 703 SnapshotObjectId id = static_cast<SnapshotObjectId>(info->GetHash());
716 const char* label = info->GetLabel(); 704 const char* label = info->GetLabel();
717 id ^= StringHasher::HashSequentialString(label, 705 id ^= StringHasher::HashSequentialString(label,
718 static_cast<int>(strlen(label)), 706 static_cast<int>(strlen(label)),
719 heap->HashSeed()); 707 heap_->HashSeed());
720 intptr_t element_count = info->GetElementCount(); 708 intptr_t element_count = info->GetElementCount();
721 if (element_count != -1) 709 if (element_count != -1)
722 id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count), 710 id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count),
723 v8::internal::kZeroHashSeed); 711 v8::internal::kZeroHashSeed);
724 return id << 1; 712 return id << 1;
725 } 713 }
726 714
727 715
728 size_t HeapObjectsMap::GetUsedMemorySize() const { 716 size_t HeapObjectsMap::GetUsedMemorySize() const {
729 return 717 return
730 sizeof(*this) + 718 sizeof(*this) +
731 sizeof(HashMap::Entry) * entries_map_.capacity() + 719 sizeof(HashMap::Entry) * entries_map_.capacity() +
732 GetMemoryUsedByList(entries_) + 720 GetMemoryUsedByList(entries_) +
733 GetMemoryUsedByList(time_intervals_); 721 GetMemoryUsedByList(time_intervals_);
734 } 722 }
735 723
736 724
737 HeapSnapshotsCollection::HeapSnapshotsCollection(Heap* heap)
738 : names_(heap),
739 ids_(heap),
740 allocation_tracker_(NULL) {
741 }
742
743
744 static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) {
745 delete *snapshot_ptr;
746 }
747
748
749 HeapSnapshotsCollection::~HeapSnapshotsCollection() {
750 delete allocation_tracker_;
751 snapshots_.Iterate(DeleteHeapSnapshot);
752 }
753
754
755 void HeapSnapshotsCollection::StartHeapObjectsTracking(bool track_allocations) {
756 ids_.UpdateHeapObjectsMap();
757 ASSERT(allocation_tracker_ == NULL);
758 if (track_allocations) {
759 allocation_tracker_ = new AllocationTracker(&ids_, names());
760 }
761 }
762
763
764 void HeapSnapshotsCollection::StopHeapObjectsTracking() {
765 ids_.StopHeapObjectsTracking();
766 if (allocation_tracker_ != NULL) {
767 delete allocation_tracker_;
768 allocation_tracker_ = NULL;
769 }
770 }
771
772
773 HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(const char* name,
774 unsigned uid) {
775 return new HeapSnapshot(this, name, uid);
776 }
777
778
779 void HeapSnapshotsCollection::SnapshotGenerationFinished(
780 HeapSnapshot* snapshot) {
781 ids_.SnapshotGenerationFinished();
782 if (snapshot != NULL) {
783 snapshots_.Add(snapshot);
784 }
785 }
786
787
788 void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) {
789 snapshots_.RemoveElement(snapshot);
790 }
791
792
793 Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById(
794 SnapshotObjectId id) {
795 // First perform a full GC in order to avoid dead objects.
796 heap()->CollectAllGarbage(Heap::kMakeHeapIterableMask,
797 "HeapSnapshotsCollection::FindHeapObjectById");
798 DisallowHeapAllocation no_allocation;
799 HeapObject* object = NULL;
800 HeapIterator iterator(heap(), HeapIterator::kFilterUnreachable);
801 // Make sure that object with the given id is still reachable.
802 for (HeapObject* obj = iterator.next();
803 obj != NULL;
804 obj = iterator.next()) {
805 if (ids_.FindEntry(obj->address()) == id) {
806 ASSERT(object == NULL);
807 object = obj;
808 // Can't break -- kFilterUnreachable requires full heap traversal.
809 }
810 }
811 return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>();
812 }
813
814
815 void HeapSnapshotsCollection::AllocationEvent(Address addr, int size) {
816 DisallowHeapAllocation no_allocation;
817 if (allocation_tracker_ != NULL) {
818 allocation_tracker_->AllocationEvent(addr, size);
819 }
820 }
821
822
823 size_t HeapSnapshotsCollection::GetUsedMemorySize() const {
824 size_t size = sizeof(*this);
825 size += names_.GetUsedMemorySize();
826 size += ids_.GetUsedMemorySize();
827 size += GetMemoryUsedByList(snapshots_);
828 for (int i = 0; i < snapshots_.length(); ++i) {
829 size += snapshots_[i]->RawSnapshotSize();
830 }
831 return size;
832 }
833
834
835 HeapEntriesMap::HeapEntriesMap() 725 HeapEntriesMap::HeapEntriesMap()
836 : entries_(HeapThingsMatch) { 726 : entries_(HeapThingsMatch) {
837 } 727 }
838 728
839 729
840 int HeapEntriesMap::Map(HeapThing thing) { 730 int HeapEntriesMap::Map(HeapThing thing) {
841 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false); 731 HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
842 if (cache_entry == NULL) return HeapEntry::kNoEntry; 732 if (cache_entry == NULL) return HeapEntry::kNoEntry;
843 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); 733 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value));
844 } 734 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 static_cast<intptr_t>(HeapObjectsMap::kGcRootsFirstSubrootId)); 795 static_cast<intptr_t>(HeapObjectsMap::kGcRootsFirstSubrootId));
906 HeapObject* const V8HeapExplorer::kLastGcSubrootObject = 796 HeapObject* const V8HeapExplorer::kLastGcSubrootObject =
907 reinterpret_cast<HeapObject*>( 797 reinterpret_cast<HeapObject*>(
908 static_cast<intptr_t>(HeapObjectsMap::kFirstAvailableObjectId)); 798 static_cast<intptr_t>(HeapObjectsMap::kFirstAvailableObjectId));
909 799
910 800
911 V8HeapExplorer::V8HeapExplorer( 801 V8HeapExplorer::V8HeapExplorer(
912 HeapSnapshot* snapshot, 802 HeapSnapshot* snapshot,
913 SnapshottingProgressReportingInterface* progress, 803 SnapshottingProgressReportingInterface* progress,
914 v8::HeapProfiler::ObjectNameResolver* resolver) 804 v8::HeapProfiler::ObjectNameResolver* resolver)
915 : heap_(snapshot->collection()->heap()), 805 : heap_(snapshot->profiler()->heap_object_map()->heap()),
916 snapshot_(snapshot), 806 snapshot_(snapshot),
917 collection_(snapshot_->collection()), 807 names_(snapshot_->profiler()->names()),
808 heap_object_map_(snapshot_->profiler()->heap_object_map()),
918 progress_(progress), 809 progress_(progress),
919 filler_(NULL), 810 filler_(NULL),
920 global_object_name_resolver_(resolver) { 811 global_object_name_resolver_(resolver) {
921 } 812 }
922 813
923 814
924 V8HeapExplorer::~V8HeapExplorer() { 815 V8HeapExplorer::~V8HeapExplorer() {
925 } 816 }
926 817
927 818
928 HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) { 819 HeapEntry* V8HeapExplorer::AllocateEntry(HeapThing ptr) {
929 return AddEntry(reinterpret_cast<HeapObject*>(ptr)); 820 return AddEntry(reinterpret_cast<HeapObject*>(ptr));
930 } 821 }
931 822
932 823
933 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) { 824 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object) {
934 if (object == kInternalRootObject) { 825 if (object == kInternalRootObject) {
935 snapshot_->AddRootEntry(); 826 snapshot_->AddRootEntry();
936 return snapshot_->root(); 827 return snapshot_->root();
937 } else if (object == kGcRootsObject) { 828 } else if (object == kGcRootsObject) {
938 HeapEntry* entry = snapshot_->AddGcRootsEntry(); 829 HeapEntry* entry = snapshot_->AddGcRootsEntry();
939 return entry; 830 return entry;
940 } else if (object >= kFirstGcSubrootObject && object < kLastGcSubrootObject) { 831 } else if (object >= kFirstGcSubrootObject && object < kLastGcSubrootObject) {
941 HeapEntry* entry = snapshot_->AddGcSubrootEntry(GetGcSubrootOrder(object)); 832 HeapEntry* entry = snapshot_->AddGcSubrootEntry(GetGcSubrootOrder(object));
942 return entry; 833 return entry;
943 } else if (object->IsJSFunction()) { 834 } else if (object->IsJSFunction()) {
944 JSFunction* func = JSFunction::cast(object); 835 JSFunction* func = JSFunction::cast(object);
945 SharedFunctionInfo* shared = func->shared(); 836 SharedFunctionInfo* shared = func->shared();
946 const char* name = shared->bound() ? "native_bind" : 837 const char* name = shared->bound() ? "native_bind" :
947 collection_->names()->GetName(String::cast(shared->name())); 838 names_->GetName(String::cast(shared->name()));
948 return AddEntry(object, HeapEntry::kClosure, name); 839 return AddEntry(object, HeapEntry::kClosure, name);
949 } else if (object->IsJSRegExp()) { 840 } else if (object->IsJSRegExp()) {
950 JSRegExp* re = JSRegExp::cast(object); 841 JSRegExp* re = JSRegExp::cast(object);
951 return AddEntry(object, 842 return AddEntry(object,
952 HeapEntry::kRegExp, 843 HeapEntry::kRegExp,
953 collection_->names()->GetName(re->Pattern())); 844 names_->GetName(re->Pattern()));
954 } else if (object->IsJSObject()) { 845 } else if (object->IsJSObject()) {
955 const char* name = collection_->names()->GetName( 846 const char* name = names_->GetName(
956 GetConstructorName(JSObject::cast(object))); 847 GetConstructorName(JSObject::cast(object)));
957 if (object->IsJSGlobalObject()) { 848 if (object->IsJSGlobalObject()) {
958 const char* tag = objects_tags_.GetTag(object); 849 const char* tag = objects_tags_.GetTag(object);
959 if (tag != NULL) { 850 if (tag != NULL) {
960 name = collection_->names()->GetFormatted("%s / %s", name, tag); 851 name = names_->GetFormatted("%s / %s", name, tag);
961 } 852 }
962 } 853 }
963 return AddEntry(object, HeapEntry::kObject, name); 854 return AddEntry(object, HeapEntry::kObject, name);
964 } else if (object->IsString()) { 855 } else if (object->IsString()) {
965 String* string = String::cast(object); 856 String* string = String::cast(object);
966 if (string->IsConsString()) 857 if (string->IsConsString())
967 return AddEntry(object, 858 return AddEntry(object,
968 HeapEntry::kConsString, 859 HeapEntry::kConsString,
969 "(concatenated string)"); 860 "(concatenated string)");
970 if (string->IsSlicedString()) 861 if (string->IsSlicedString())
971 return AddEntry(object, 862 return AddEntry(object,
972 HeapEntry::kSlicedString, 863 HeapEntry::kSlicedString,
973 "(sliced string)"); 864 "(sliced string)");
974 return AddEntry(object, 865 return AddEntry(object,
975 HeapEntry::kString, 866 HeapEntry::kString,
976 collection_->names()->GetName(String::cast(object))); 867 names_->GetName(String::cast(object)));
977 } else if (object->IsCode()) { 868 } else if (object->IsCode()) {
978 return AddEntry(object, HeapEntry::kCode, ""); 869 return AddEntry(object, HeapEntry::kCode, "");
979 } else if (object->IsSharedFunctionInfo()) { 870 } else if (object->IsSharedFunctionInfo()) {
980 String* name = String::cast(SharedFunctionInfo::cast(object)->name()); 871 String* name = String::cast(SharedFunctionInfo::cast(object)->name());
981 return AddEntry(object, 872 return AddEntry(object,
982 HeapEntry::kCode, 873 HeapEntry::kCode,
983 collection_->names()->GetName(name)); 874 names_->GetName(name));
984 } else if (object->IsScript()) { 875 } else if (object->IsScript()) {
985 Object* name = Script::cast(object)->name(); 876 Object* name = Script::cast(object)->name();
986 return AddEntry(object, 877 return AddEntry(object,
987 HeapEntry::kCode, 878 HeapEntry::kCode,
988 name->IsString() 879 name->IsString()
989 ? collection_->names()->GetName(String::cast(name)) 880 ? names_->GetName(String::cast(name))
990 : ""); 881 : "");
991 } else if (object->IsNativeContext()) { 882 } else if (object->IsNativeContext()) {
992 return AddEntry(object, HeapEntry::kHidden, "system / NativeContext"); 883 return AddEntry(object, HeapEntry::kHidden, "system / NativeContext");
993 } else if (object->IsContext()) { 884 } else if (object->IsContext()) {
994 return AddEntry(object, HeapEntry::kObject, "system / Context"); 885 return AddEntry(object, HeapEntry::kObject, "system / Context");
995 } else if (object->IsFixedArray() || 886 } else if (object->IsFixedArray() ||
996 object->IsFixedDoubleArray() || 887 object->IsFixedDoubleArray() ||
997 object->IsByteArray() || 888 object->IsByteArray() ||
998 object->IsExternalArray()) { 889 object->IsExternalArray()) {
999 return AddEntry(object, HeapEntry::kArray, ""); 890 return AddEntry(object, HeapEntry::kArray, "");
1000 } else if (object->IsHeapNumber()) { 891 } else if (object->IsHeapNumber()) {
1001 return AddEntry(object, HeapEntry::kHeapNumber, "number"); 892 return AddEntry(object, HeapEntry::kHeapNumber, "number");
1002 } 893 }
1003 return AddEntry(object, HeapEntry::kHidden, GetSystemEntryName(object)); 894 return AddEntry(object, HeapEntry::kHidden, GetSystemEntryName(object));
1004 } 895 }
1005 896
1006 897
1007 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, 898 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
1008 HeapEntry::Type type, 899 HeapEntry::Type type,
1009 const char* name) { 900 const char* name) {
1010 int object_size = object->Size(); 901 int object_size = object->Size();
1011 SnapshotObjectId object_id = 902 SnapshotObjectId object_id =
1012 collection_->GetObjectId(object->address(), object_size); 903 heap_object_map_->FindOrAddEntry(object->address(), object_size);
1013 return snapshot_->AddEntry(type, name, object_id, object_size); 904 return snapshot_->AddEntry(type, name, object_id, object_size);
1014 } 905 }
1015 906
1016 907
1017 class GcSubrootsEnumerator : public ObjectVisitor { 908 class GcSubrootsEnumerator : public ObjectVisitor {
1018 public: 909 public:
1019 GcSubrootsEnumerator( 910 GcSubrootsEnumerator(
1020 SnapshotFillerInterface* filler, V8HeapExplorer* explorer) 911 SnapshotFillerInterface* filler, V8HeapExplorer* explorer)
1021 : filler_(filler), 912 : filler_(filler),
1022 explorer_(explorer), 913 explorer_(explorer),
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 TagObject(map->dependent_code(), "(dependent code)"); 1240 TagObject(map->dependent_code(), "(dependent code)");
1350 SetInternalReference(map, entry, 1241 SetInternalReference(map, entry,
1351 "dependent_code", map->dependent_code(), 1242 "dependent_code", map->dependent_code(),
1352 Map::kDependentCodeOffset); 1243 Map::kDependentCodeOffset);
1353 } 1244 }
1354 1245
1355 1246
1356 void V8HeapExplorer::ExtractSharedFunctionInfoReferences( 1247 void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
1357 int entry, SharedFunctionInfo* shared) { 1248 int entry, SharedFunctionInfo* shared) {
1358 HeapObject* obj = shared; 1249 HeapObject* obj = shared;
1359 StringsStorage* names = collection_->names();
1360 String* shared_name = shared->DebugName(); 1250 String* shared_name = shared->DebugName();
1361 const char* name = NULL; 1251 const char* name = NULL;
1362 if (shared_name != *heap_->isolate()->factory()->empty_string()) { 1252 if (shared_name != *heap_->isolate()->factory()->empty_string()) {
1363 name = names->GetName(shared_name); 1253 name = names_->GetName(shared_name);
1364 TagObject(shared->code(), names->GetFormatted("(code for %s)", name)); 1254 TagObject(shared->code(), names_->GetFormatted("(code for %s)", name));
1365 } else { 1255 } else {
1366 TagObject(shared->code(), names->GetFormatted("(%s code)", 1256 TagObject(shared->code(), names_->GetFormatted("(%s code)",
1367 Code::Kind2String(shared->code()->kind()))); 1257 Code::Kind2String(shared->code()->kind())));
1368 } 1258 }
1369 1259
1370 SetInternalReference(obj, entry, 1260 SetInternalReference(obj, entry,
1371 "name", shared->name(), 1261 "name", shared->name(),
1372 SharedFunctionInfo::kNameOffset); 1262 SharedFunctionInfo::kNameOffset);
1373 SetInternalReference(obj, entry, 1263 SetInternalReference(obj, entry,
1374 "code", shared->code(), 1264 "code", shared->code(),
1375 SharedFunctionInfo::kCodeOffset); 1265 SharedFunctionInfo::kCodeOffset);
1376 TagObject(shared->scope_info(), "(function scope info)"); 1266 TagObject(shared->scope_info(), "(function scope info)");
1377 SetInternalReference(obj, entry, 1267 SetInternalReference(obj, entry,
1378 "scope_info", shared->scope_info(), 1268 "scope_info", shared->scope_info(),
1379 SharedFunctionInfo::kScopeInfoOffset); 1269 SharedFunctionInfo::kScopeInfoOffset);
1380 SetInternalReference(obj, entry, 1270 SetInternalReference(obj, entry,
1381 "instance_class_name", shared->instance_class_name(), 1271 "instance_class_name", shared->instance_class_name(),
1382 SharedFunctionInfo::kInstanceClassNameOffset); 1272 SharedFunctionInfo::kInstanceClassNameOffset);
1383 SetInternalReference(obj, entry, 1273 SetInternalReference(obj, entry,
1384 "script", shared->script(), 1274 "script", shared->script(),
1385 SharedFunctionInfo::kScriptOffset); 1275 SharedFunctionInfo::kScriptOffset);
1386 const char* construct_stub_name = name ? 1276 const char* construct_stub_name = name ?
1387 names->GetFormatted("(construct stub code for %s)", name) : 1277 names_->GetFormatted("(construct stub code for %s)", name) :
1388 "(construct stub code)"; 1278 "(construct stub code)";
1389 TagObject(shared->construct_stub(), construct_stub_name); 1279 TagObject(shared->construct_stub(), construct_stub_name);
1390 SetInternalReference(obj, entry, 1280 SetInternalReference(obj, entry,
1391 "construct_stub", shared->construct_stub(), 1281 "construct_stub", shared->construct_stub(),
1392 SharedFunctionInfo::kConstructStubOffset); 1282 SharedFunctionInfo::kConstructStubOffset);
1393 SetInternalReference(obj, entry, 1283 SetInternalReference(obj, entry,
1394 "function_data", shared->function_data(), 1284 "function_data", shared->function_data(),
1395 SharedFunctionInfo::kFunctionDataOffset); 1285 SharedFunctionInfo::kFunctionDataOffset);
1396 SetInternalReference(obj, entry, 1286 SetInternalReference(obj, entry,
1397 "debug_info", shared->debug_info(), 1287 "debug_info", shared->debug_info(),
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 "default_cache", code_cache->default_cache(), 1335 "default_cache", code_cache->default_cache(),
1446 CodeCache::kDefaultCacheOffset); 1336 CodeCache::kDefaultCacheOffset);
1447 TagObject(code_cache->normal_type_cache(), "(code type cache)"); 1337 TagObject(code_cache->normal_type_cache(), "(code type cache)");
1448 SetInternalReference(code_cache, entry, 1338 SetInternalReference(code_cache, entry,
1449 "type_cache", code_cache->normal_type_cache(), 1339 "type_cache", code_cache->normal_type_cache(),
1450 CodeCache::kNormalTypeCacheOffset); 1340 CodeCache::kNormalTypeCacheOffset);
1451 } 1341 }
1452 1342
1453 1343
1454 void V8HeapExplorer::TagCodeObject(Code* code, const char* external_name) { 1344 void V8HeapExplorer::TagCodeObject(Code* code, const char* external_name) {
1455 TagObject(code, collection_->names()->GetFormatted("(%s code)", 1345 TagObject(code, names_->GetFormatted("(%s code)", external_name));
1456 external_name));
1457 } 1346 }
1458 1347
1459 1348
1460 void V8HeapExplorer::TagCodeObject(Code* code) { 1349 void V8HeapExplorer::TagCodeObject(Code* code) {
1461 if (code->kind() == Code::STUB) { 1350 if (code->kind() == Code::STUB) {
1462 TagObject(code, collection_->names()->GetFormatted( 1351 TagObject(code, names_->GetFormatted(
1463 "(%s code)", CodeStub::MajorName( 1352 "(%s code)", CodeStub::MajorName(
1464 static_cast<CodeStub::Major>(code->major_key()), true))); 1353 static_cast<CodeStub::Major>(code->major_key()), true)));
1465 } 1354 }
1466 } 1355 }
1467 1356
1468 1357
1469 void V8HeapExplorer::ExtractCodeReferences(int entry, Code* code) { 1358 void V8HeapExplorer::ExtractCodeReferences(int entry, Code* code) {
1470 TagCodeObject(code); 1359 TagCodeObject(code);
1471 TagObject(code->relocation_info(), "(code relocation info)"); 1360 TagObject(code->relocation_info(), "(code relocation info)");
1472 SetInternalReference(code, entry, 1361 SetInternalReference(code, entry,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 1419
1531 JSFunction* func = JSFunction::cast(js_obj); 1420 JSFunction* func = JSFunction::cast(js_obj);
1532 if (func->shared()->bound()) { 1421 if (func->shared()->bound()) {
1533 FixedArray* bindings = func->function_bindings(); 1422 FixedArray* bindings = func->function_bindings();
1534 SetNativeBindReference(js_obj, entry, "bound_this", 1423 SetNativeBindReference(js_obj, entry, "bound_this",
1535 bindings->get(JSFunction::kBoundThisIndex)); 1424 bindings->get(JSFunction::kBoundThisIndex));
1536 SetNativeBindReference(js_obj, entry, "bound_function", 1425 SetNativeBindReference(js_obj, entry, "bound_function",
1537 bindings->get(JSFunction::kBoundFunctionIndex)); 1426 bindings->get(JSFunction::kBoundFunctionIndex));
1538 for (int i = JSFunction::kBoundArgumentsStartIndex; 1427 for (int i = JSFunction::kBoundArgumentsStartIndex;
1539 i < bindings->length(); i++) { 1428 i < bindings->length(); i++) {
1540 const char* reference_name = collection_->names()->GetFormatted( 1429 const char* reference_name = names_->GetFormatted(
1541 "bound_argument_%d", 1430 "bound_argument_%d",
1542 i - JSFunction::kBoundArgumentsStartIndex); 1431 i - JSFunction::kBoundArgumentsStartIndex);
1543 SetNativeBindReference(js_obj, entry, reference_name, 1432 SetNativeBindReference(js_obj, entry, reference_name,
1544 bindings->get(i)); 1433 bindings->get(i));
1545 } 1434 }
1546 } 1435 }
1547 } 1436 }
1548 1437
1549 1438
1550 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
1837 void V8HeapExplorer::SetContextReference(HeapObject* parent_obj, 1726 void V8HeapExplorer::SetContextReference(HeapObject* parent_obj,
1838 int parent_entry, 1727 int parent_entry,
1839 String* reference_name, 1728 String* reference_name,
1840 Object* child_obj, 1729 Object* child_obj,
1841 int field_offset) { 1730 int field_offset) {
1842 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 1731 ASSERT(parent_entry == GetEntry(parent_obj)->index());
1843 HeapEntry* child_entry = GetEntry(child_obj); 1732 HeapEntry* child_entry = GetEntry(child_obj);
1844 if (child_entry != NULL) { 1733 if (child_entry != NULL) {
1845 filler_->SetNamedReference(HeapGraphEdge::kContextVariable, 1734 filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
1846 parent_entry, 1735 parent_entry,
1847 collection_->names()->GetName(reference_name), 1736 names_->GetName(reference_name),
1848 child_entry); 1737 child_entry);
1849 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1738 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
1850 } 1739 }
1851 } 1740 }
1852 1741
1853 1742
1854 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj, 1743 void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj,
1855 int parent_entry, 1744 int parent_entry,
1856 const char* reference_name, 1745 const char* reference_name,
1857 Object* child_obj) { 1746 Object* child_obj) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 int parent_entry, 1792 int parent_entry,
1904 int index, 1793 int index,
1905 Object* child_obj, 1794 Object* child_obj,
1906 int field_offset) { 1795 int field_offset) {
1907 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 1796 ASSERT(parent_entry == GetEntry(parent_obj)->index());
1908 HeapEntry* child_entry = GetEntry(child_obj); 1797 HeapEntry* child_entry = GetEntry(child_obj);
1909 if (child_entry == NULL) return; 1798 if (child_entry == NULL) return;
1910 if (IsEssentialObject(child_obj)) { 1799 if (IsEssentialObject(child_obj)) {
1911 filler_->SetNamedReference(HeapGraphEdge::kInternal, 1800 filler_->SetNamedReference(HeapGraphEdge::kInternal,
1912 parent_entry, 1801 parent_entry,
1913 collection_->names()->GetName(index), 1802 names_->GetName(index),
1914 child_entry); 1803 child_entry);
1915 } 1804 }
1916 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1805 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
1917 } 1806 }
1918 1807
1919 1808
1920 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj, 1809 void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
1921 int parent_entry, 1810 int parent_entry,
1922 int index, 1811 int index,
1923 Object* child_obj) { 1812 Object* child_obj) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1956 Object* child_obj, 1845 Object* child_obj,
1957 const char* name_format_string, 1846 const char* name_format_string,
1958 int field_offset) { 1847 int field_offset) {
1959 ASSERT(parent_entry == GetEntry(parent_obj)->index()); 1848 ASSERT(parent_entry == GetEntry(parent_obj)->index());
1960 HeapEntry* child_entry = GetEntry(child_obj); 1849 HeapEntry* child_entry = GetEntry(child_obj);
1961 if (child_entry != NULL) { 1850 if (child_entry != NULL) {
1962 HeapGraphEdge::Type type = 1851 HeapGraphEdge::Type type =
1963 reference_name->IsSymbol() || String::cast(reference_name)->length() > 0 1852 reference_name->IsSymbol() || String::cast(reference_name)->length() > 0
1964 ? HeapGraphEdge::kProperty : HeapGraphEdge::kInternal; 1853 ? HeapGraphEdge::kProperty : HeapGraphEdge::kInternal;
1965 const char* name = name_format_string != NULL && reference_name->IsString() 1854 const char* name = name_format_string != NULL && reference_name->IsString()
1966 ? collection_->names()->GetFormatted( 1855 ? names_->GetFormatted(
1967 name_format_string, 1856 name_format_string,
1968 *String::cast(reference_name)->ToCString( 1857 *String::cast(reference_name)->ToCString(
1969 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)) : 1858 DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)) :
1970 collection_->names()->GetName(reference_name); 1859 names_->GetName(reference_name);
1971 1860
1972 filler_->SetNamedReference(type, 1861 filler_->SetNamedReference(type,
1973 parent_entry, 1862 parent_entry,
1974 name, 1863 name,
1975 child_entry); 1864 child_entry);
1976 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset); 1865 IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
1977 } 1866 }
1978 } 1867 }
1979 1868
1980 1869
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2136 NativeObjectsExplorer* explorer_; 2025 NativeObjectsExplorer* explorer_;
2137 }; 2026 };
2138 2027
2139 2028
2140 class BasicHeapEntriesAllocator : public HeapEntriesAllocator { 2029 class BasicHeapEntriesAllocator : public HeapEntriesAllocator {
2141 public: 2030 public:
2142 BasicHeapEntriesAllocator( 2031 BasicHeapEntriesAllocator(
2143 HeapSnapshot* snapshot, 2032 HeapSnapshot* snapshot,
2144 HeapEntry::Type entries_type) 2033 HeapEntry::Type entries_type)
2145 : snapshot_(snapshot), 2034 : snapshot_(snapshot),
2146 collection_(snapshot_->collection()), 2035 names_(snapshot_->profiler()->names()),
2036 heap_object_map_(snapshot_->profiler()->heap_object_map()),
2147 entries_type_(entries_type) { 2037 entries_type_(entries_type) {
2148 } 2038 }
2149 virtual HeapEntry* AllocateEntry(HeapThing ptr); 2039 virtual HeapEntry* AllocateEntry(HeapThing ptr);
2150 private: 2040 private:
2151 HeapSnapshot* snapshot_; 2041 HeapSnapshot* snapshot_;
2152 HeapSnapshotsCollection* collection_; 2042 StringsStorage* names_;
2043 HeapObjectsMap* heap_object_map_;
2153 HeapEntry::Type entries_type_; 2044 HeapEntry::Type entries_type_;
2154 }; 2045 };
2155 2046
2156 2047
2157 HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) { 2048 HeapEntry* BasicHeapEntriesAllocator::AllocateEntry(HeapThing ptr) {
2158 v8::RetainedObjectInfo* info = reinterpret_cast<v8::RetainedObjectInfo*>(ptr); 2049 v8::RetainedObjectInfo* info = reinterpret_cast<v8::RetainedObjectInfo*>(ptr);
2159 intptr_t elements = info->GetElementCount(); 2050 intptr_t elements = info->GetElementCount();
2160 intptr_t size = info->GetSizeInBytes(); 2051 intptr_t size = info->GetSizeInBytes();
2161 const char* name = elements != -1 2052 const char* name = elements != -1
2162 ? collection_->names()->GetFormatted( 2053 ? names_->GetFormatted(
2163 "%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements) 2054 "%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements)
2164 : collection_->names()->GetCopy(info->GetLabel()); 2055 : names_->GetCopy(info->GetLabel());
2165 return snapshot_->AddEntry( 2056 return snapshot_->AddEntry(
2166 entries_type_, 2057 entries_type_,
2167 name, 2058 name,
2168 HeapObjectsMap::GenerateId(collection_->heap(), info), 2059 heap_object_map_->GenerateId(info),
2169 size != -1 ? static_cast<int>(size) : 0); 2060 size != -1 ? static_cast<int>(size) : 0);
2170 } 2061 }
2171 2062
2172 2063
2173 NativeObjectsExplorer::NativeObjectsExplorer( 2064 NativeObjectsExplorer::NativeObjectsExplorer(
2174 HeapSnapshot* snapshot, 2065 HeapSnapshot* snapshot,
2175 SnapshottingProgressReportingInterface* progress) 2066 SnapshottingProgressReportingInterface* progress)
2176 : isolate_(snapshot->collection()->heap()->isolate()), 2067 : isolate_(snapshot->profiler()->heap_object_map()->heap()->isolate()),
2177 snapshot_(snapshot), 2068 snapshot_(snapshot),
2178 collection_(snapshot_->collection()), 2069 names_(snapshot_->profiler()->names()),
2179 progress_(progress), 2070 progress_(progress),
2180 embedder_queried_(false), 2071 embedder_queried_(false),
2181 objects_by_info_(RetainedInfosMatch), 2072 objects_by_info_(RetainedInfosMatch),
2182 native_groups_(StringsMatch), 2073 native_groups_(StringsMatch),
2183 filler_(NULL) { 2074 filler_(NULL) {
2184 synthetic_entries_allocator_ = 2075 synthetic_entries_allocator_ =
2185 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic); 2076 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kSynthetic);
2186 native_entries_allocator_ = 2077 native_entries_allocator_ =
2187 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative); 2078 new BasicHeapEntriesAllocator(snapshot, HeapEntry::kNative);
2188 } 2079 }
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2330 2221
2331 private: 2222 private:
2332 bool disposed_; 2223 bool disposed_;
2333 intptr_t hash_; 2224 intptr_t hash_;
2334 const char* label_; 2225 const char* label_;
2335 }; 2226 };
2336 2227
2337 2228
2338 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo( 2229 NativeGroupRetainedObjectInfo* NativeObjectsExplorer::FindOrAddGroupInfo(
2339 const char* label) { 2230 const char* label) {
2340 const char* label_copy = collection_->names()->GetCopy(label); 2231 const char* label_copy = names_->GetCopy(label);
2341 uint32_t hash = StringHasher::HashSequentialString( 2232 uint32_t hash = StringHasher::HashSequentialString(
2342 label_copy, 2233 label_copy,
2343 static_cast<int>(strlen(label_copy)), 2234 static_cast<int>(strlen(label_copy)),
2344 isolate_->heap()->HashSeed()); 2235 isolate_->heap()->HashSeed());
2345 HashMap::Entry* entry = native_groups_.Lookup(const_cast<char*>(label_copy), 2236 HashMap::Entry* entry = native_groups_.Lookup(const_cast<char*>(label_copy),
2346 hash, true); 2237 hash, true);
2347 if (entry->value == NULL) { 2238 if (entry->value == NULL) {
2348 entry->value = new NativeGroupRetainedObjectInfo(label); 2239 entry->value = new NativeGroupRetainedObjectInfo(label);
2349 } 2240 }
2350 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
2408 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); 2299 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p);
2409 if (info == NULL) return; 2300 if (info == NULL) return;
2410 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); 2301 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p));
2411 } 2302 }
2412 2303
2413 2304
2414 class SnapshotFiller : public SnapshotFillerInterface { 2305 class SnapshotFiller : public SnapshotFillerInterface {
2415 public: 2306 public:
2416 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) 2307 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
2417 : snapshot_(snapshot), 2308 : snapshot_(snapshot),
2418 collection_(snapshot->collection()), 2309 names_(snapshot->profiler()->names()),
2419 entries_(entries) { } 2310 entries_(entries) { }
2420 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { 2311 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
2421 HeapEntry* entry = allocator->AllocateEntry(ptr); 2312 HeapEntry* entry = allocator->AllocateEntry(ptr);
2422 entries_->Pair(ptr, entry->index()); 2313 entries_->Pair(ptr, entry->index());
2423 return entry; 2314 return entry;
2424 } 2315 }
2425 HeapEntry* FindEntry(HeapThing ptr) { 2316 HeapEntry* FindEntry(HeapThing ptr) {
2426 int index = entries_->Map(ptr); 2317 int index = entries_->Map(ptr);
2427 return index != HeapEntry::kNoEntry ? &snapshot_->entries()[index] : NULL; 2318 return index != HeapEntry::kNoEntry ? &snapshot_->entries()[index] : NULL;
2428 } 2319 }
(...skipping 22 matching lines...) Expand all
2451 HeapEntry* parent_entry = &snapshot_->entries()[parent]; 2342 HeapEntry* parent_entry = &snapshot_->entries()[parent];
2452 parent_entry->SetNamedReference(type, reference_name, child_entry); 2343 parent_entry->SetNamedReference(type, reference_name, child_entry);
2453 } 2344 }
2454 void SetNamedAutoIndexReference(HeapGraphEdge::Type type, 2345 void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
2455 int parent, 2346 int parent,
2456 HeapEntry* child_entry) { 2347 HeapEntry* child_entry) {
2457 HeapEntry* parent_entry = &snapshot_->entries()[parent]; 2348 HeapEntry* parent_entry = &snapshot_->entries()[parent];
2458 int index = parent_entry->children_count() + 1; 2349 int index = parent_entry->children_count() + 1;
2459 parent_entry->SetNamedReference( 2350 parent_entry->SetNamedReference(
2460 type, 2351 type,
2461 collection_->names()->GetName(index), 2352 names_->GetName(index),
2462 child_entry); 2353 child_entry);
2463 } 2354 }
2464 2355
2465 private: 2356 private:
2466 HeapSnapshot* snapshot_; 2357 HeapSnapshot* snapshot_;
2467 HeapSnapshotsCollection* collection_; 2358 StringsStorage* names_;
2468 HeapEntriesMap* entries_; 2359 HeapEntriesMap* entries_;
2469 }; 2360 };
2470 2361
2471 2362
2472 HeapSnapshotGenerator::HeapSnapshotGenerator( 2363 HeapSnapshotGenerator::HeapSnapshotGenerator(
2473 HeapSnapshot* snapshot, 2364 HeapSnapshot* snapshot,
2474 v8::ActivityControl* control, 2365 v8::ActivityControl* control,
2475 v8::HeapProfiler::ObjectNameResolver* resolver, 2366 v8::HeapProfiler::ObjectNameResolver* resolver,
2476 Heap* heap) 2367 Heap* heap)
2477 : snapshot_(snapshot), 2368 : snapshot_(snapshot),
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2663 }; 2554 };
2664 2555
2665 2556
2666 // type, name|index, to_node. 2557 // type, name|index, to_node.
2667 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3; 2558 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3;
2668 // type, name, id, self_size, children_index. 2559 // type, name, id, self_size, children_index.
2669 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 5; 2560 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 5;
2670 2561
2671 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { 2562 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) {
2672 if (AllocationTracker* allocation_tracker = 2563 if (AllocationTracker* allocation_tracker =
2673 snapshot_->collection()->allocation_tracker()) { 2564 snapshot_->profiler()->allocation_tracker()) {
2674 allocation_tracker->PrepareForSerialization(); 2565 allocation_tracker->PrepareForSerialization();
2675 } 2566 }
2676 ASSERT(writer_ == NULL); 2567 ASSERT(writer_ == NULL);
2677 writer_ = new OutputStreamWriter(stream); 2568 writer_ = new OutputStreamWriter(stream);
2678 SerializeImpl(); 2569 SerializeImpl();
2679 delete writer_; 2570 delete writer_;
2680 writer_ = NULL; 2571 writer_ = NULL;
2681 } 2572 }
2682 2573
2683 2574
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
2882 JSON_S("children")))); 2773 JSON_S("children"))));
2883 #undef JSON_S 2774 #undef JSON_S
2884 #undef JSON_O 2775 #undef JSON_O
2885 #undef JSON_A 2776 #undef JSON_A
2886 writer_->AddString(",\"node_count\":"); 2777 writer_->AddString(",\"node_count\":");
2887 writer_->AddNumber(snapshot_->entries().length()); 2778 writer_->AddNumber(snapshot_->entries().length());
2888 writer_->AddString(",\"edge_count\":"); 2779 writer_->AddString(",\"edge_count\":");
2889 writer_->AddNumber(snapshot_->edges().length()); 2780 writer_->AddNumber(snapshot_->edges().length());
2890 writer_->AddString(",\"trace_function_count\":"); 2781 writer_->AddString(",\"trace_function_count\":");
2891 uint32_t count = 0; 2782 uint32_t count = 0;
2892 AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); 2783 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
2893 if (tracker) { 2784 if (tracker) {
2894 count = tracker->id_to_function_info()->occupancy(); 2785 count = tracker->id_to_function_info()->occupancy();
2895 } 2786 }
2896 writer_->AddNumber(count); 2787 writer_->AddNumber(count);
2897 } 2788 }
2898 2789
2899 2790
2900 static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) { 2791 static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) {
2901 static const char hex_chars[] = "0123456789ABCDEF"; 2792 static const char hex_chars[] = "0123456789ABCDEF";
2902 w->AddString("\\u"); 2793 w->AddString("\\u");
2903 w->AddCharacter(hex_chars[(u >> 12) & 0xf]); 2794 w->AddCharacter(hex_chars[(u >> 12) & 0xf]);
2904 w->AddCharacter(hex_chars[(u >> 8) & 0xf]); 2795 w->AddCharacter(hex_chars[(u >> 8) & 0xf]);
2905 w->AddCharacter(hex_chars[(u >> 4) & 0xf]); 2796 w->AddCharacter(hex_chars[(u >> 4) & 0xf]);
2906 w->AddCharacter(hex_chars[u & 0xf]); 2797 w->AddCharacter(hex_chars[u & 0xf]);
2907 } 2798 }
2908 2799
2909 2800
2910 void HeapSnapshotJSONSerializer::SerializeTraceTree() { 2801 void HeapSnapshotJSONSerializer::SerializeTraceTree() {
2911 AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); 2802 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
2912 if (!tracker) return; 2803 if (!tracker) return;
2913 AllocationTraceTree* traces = tracker->trace_tree(); 2804 AllocationTraceTree* traces = tracker->trace_tree();
2914 SerializeTraceNode(traces->root()); 2805 SerializeTraceNode(traces->root());
2915 } 2806 }
2916 2807
2917 2808
2918 void HeapSnapshotJSONSerializer::SerializeTraceNode(AllocationTraceNode* node) { 2809 void HeapSnapshotJSONSerializer::SerializeTraceNode(AllocationTraceNode* node) {
2919 // 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
2920 const int kBufferSize = 2811 const int kBufferSize =
2921 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT 2812 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT
(...skipping 30 matching lines...) Expand all
2952 buffer[buffer_pos++] = '0'; 2843 buffer[buffer_pos++] = '0';
2953 } else { 2844 } else {
2954 ASSERT(position >= 0); 2845 ASSERT(position >= 0);
2955 buffer_pos = utoa(static_cast<unsigned>(position + 1), buffer, buffer_pos); 2846 buffer_pos = utoa(static_cast<unsigned>(position + 1), buffer, buffer_pos);
2956 } 2847 }
2957 return buffer_pos; 2848 return buffer_pos;
2958 } 2849 }
2959 2850
2960 2851
2961 void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() { 2852 void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() {
2962 AllocationTracker* tracker = snapshot_->collection()->allocation_tracker(); 2853 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker();
2963 if (!tracker) return; 2854 if (!tracker) return;
2964 // 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
2965 const int kBufferSize = 2856 const int kBufferSize =
2966 6 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT 2857 6 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT
2967 + 6 + 1 + 1; 2858 + 6 + 1 + 1;
2968 EmbeddedVector<char, kBufferSize> buffer; 2859 EmbeddedVector<char, kBufferSize> buffer;
2969 HashMap* id_to_function_info = tracker->id_to_function_info(); 2860 HashMap* id_to_function_info = tracker->id_to_function_info();
2970 bool first_entry = true; 2861 bool first_entry = true;
2971 for (HashMap::Entry* p = id_to_function_info->Start(); 2862 for (HashMap::Entry* p = id_to_function_info->Start();
2972 p != NULL; 2863 p != NULL;
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3063 writer_->AddString("\"<dummy>\""); 2954 writer_->AddString("\"<dummy>\"");
3064 for (int i = 1; i < sorted_strings.length(); ++i) { 2955 for (int i = 1; i < sorted_strings.length(); ++i) {
3065 writer_->AddCharacter(','); 2956 writer_->AddCharacter(',');
3066 SerializeString(sorted_strings[i]); 2957 SerializeString(sorted_strings[i]);
3067 if (writer_->aborted()) return; 2958 if (writer_->aborted()) return;
3068 } 2959 }
3069 } 2960 }
3070 2961
3071 2962
3072 } } // namespace v8::internal 2963 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap-snapshot-generator.h ('k') | src/list.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698