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

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

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