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

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

Issue 166383002: Allow self_size to be larger than 2GB in heap snapshots. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Added casts Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap-snapshot-generator.h ('k') | test/cctest/test-heap-profiler.cc » ('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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 to_entry_ = &snapshot->entries()[to_index_]; 66 to_entry_ = &snapshot->entries()[to_index_];
67 } 67 }
68 68
69 69
70 const int HeapEntry::kNoEntry = -1; 70 const int HeapEntry::kNoEntry = -1;
71 71
72 HeapEntry::HeapEntry(HeapSnapshot* snapshot, 72 HeapEntry::HeapEntry(HeapSnapshot* snapshot,
73 Type type, 73 Type type,
74 const char* name, 74 const char* name,
75 SnapshotObjectId id, 75 SnapshotObjectId id,
76 int self_size) 76 size_t self_size)
77 : type_(type), 77 : type_(type),
78 children_count_(0), 78 children_count_(0),
79 children_index_(-1), 79 children_index_(-1),
80 self_size_(self_size), 80 self_size_(self_size),
81 id_(id), 81 id_(id),
82 snapshot_(snapshot), 82 snapshot_(snapshot),
83 name_(name) { } 83 name_(name) { }
84 84
85 85
86 void HeapEntry::SetNamedReference(HeapGraphEdge::Type type, 86 void HeapEntry::SetNamedReference(HeapGraphEdge::Type type,
(...skipping 10 matching lines...) Expand all
97 HeapEntry* entry) { 97 HeapEntry* entry) {
98 HeapGraphEdge edge(type, index, this->index(), entry->index()); 98 HeapGraphEdge edge(type, index, this->index(), entry->index());
99 snapshot_->edges().Add(edge); 99 snapshot_->edges().Add(edge);
100 ++children_count_; 100 ++children_count_;
101 } 101 }
102 102
103 103
104 void HeapEntry::Print( 104 void HeapEntry::Print(
105 const char* prefix, const char* edge_name, int max_depth, int indent) { 105 const char* prefix, const char* edge_name, int max_depth, int indent) {
106 STATIC_CHECK(sizeof(unsigned) == sizeof(id())); 106 STATIC_CHECK(sizeof(unsigned) == sizeof(id()));
107 OS::Print("%6d @%6u %*c %s%s: ", 107 OS::Print("%6"V8PRIuPTR" @%6u %*c %s%s: ",
108 self_size(), id(), indent, ' ', prefix, edge_name); 108 self_size(), id(), indent, ' ', prefix, edge_name);
109 if (type() != kString) { 109 if (type() != kString) {
110 OS::Print("%s %.40s\n", TypeAsString(), name_); 110 OS::Print("%s %.40s\n", TypeAsString(), name_);
111 } else { 111 } else {
112 OS::Print("\""); 112 OS::Print("\"");
113 const char* c = name_; 113 const char* c = name_;
114 while (*c && (c - name_) <= 40) { 114 while (*c && (c - name_) <= 40) {
115 if (*c != '\n') 115 if (*c != '\n')
116 OS::Print("%c", *c); 116 OS::Print("%c", *c);
117 else 117 else
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 187
188 template <size_t ptr_size> struct SnapshotSizeConstants; 188 template <size_t ptr_size> struct SnapshotSizeConstants;
189 189
190 template <> struct SnapshotSizeConstants<4> { 190 template <> struct SnapshotSizeConstants<4> {
191 static const int kExpectedHeapGraphEdgeSize = 12; 191 static const int kExpectedHeapGraphEdgeSize = 12;
192 static const int kExpectedHeapEntrySize = 24; 192 static const int kExpectedHeapEntrySize = 24;
193 }; 193 };
194 194
195 template <> struct SnapshotSizeConstants<8> { 195 template <> struct SnapshotSizeConstants<8> {
196 static const int kExpectedHeapGraphEdgeSize = 24; 196 static const int kExpectedHeapGraphEdgeSize = 24;
197 static const int kExpectedHeapEntrySize = 32; 197 static const int kExpectedHeapEntrySize = 40;
198 }; 198 };
199 199
200 } // namespace 200 } // namespace
201 201
202 202
203 HeapSnapshot::HeapSnapshot(HeapProfiler* profiler, 203 HeapSnapshot::HeapSnapshot(HeapProfiler* profiler,
204 const char* title, 204 const char* title,
205 unsigned uid) 205 unsigned uid)
206 : profiler_(profiler), 206 : profiler_(profiler),
207 title_(title), 207 title_(title),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 HeapObjectsMap::GetNthGcSubrootId(tag), 270 HeapObjectsMap::GetNthGcSubrootId(tag),
271 0); 271 0);
272 gc_subroot_indexes_[tag] = entry->index(); 272 gc_subroot_indexes_[tag] = entry->index();
273 return entry; 273 return entry;
274 } 274 }
275 275
276 276
277 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, 277 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type,
278 const char* name, 278 const char* name,
279 SnapshotObjectId id, 279 SnapshotObjectId id,
280 int size) { 280 size_t size) {
281 HeapEntry entry(this, type, name, id, size); 281 HeapEntry entry(this, type, name, id, size);
282 entries_.Add(entry); 282 entries_.Add(entry);
283 return &entries_.last(); 283 return &entries_.last();
284 } 284 }
285 285
286 286
287 void HeapSnapshot::FillChildren() { 287 void HeapSnapshot::FillChildren() {
288 ASSERT(children().is_empty()); 288 ASSERT(children().is_empty());
289 children().Allocate(edges().length()); 289 children().Allocate(edges().length());
290 int children_index = 0; 290 int children_index = 0;
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
900 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object, 900 HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
901 HeapEntry::Type type, 901 HeapEntry::Type type,
902 const char* name) { 902 const char* name) {
903 return AddEntry(object->address(), type, name, object->Size()); 903 return AddEntry(object->address(), type, name, object->Size());
904 } 904 }
905 905
906 906
907 HeapEntry* V8HeapExplorer::AddEntry(Address address, 907 HeapEntry* V8HeapExplorer::AddEntry(Address address,
908 HeapEntry::Type type, 908 HeapEntry::Type type,
909 const char* name, 909 const char* name,
910 int size) { 910 size_t size) {
911 SnapshotObjectId object_id = heap_object_map_->FindOrAddEntry(address, size); 911 SnapshotObjectId object_id = heap_object_map_->FindOrAddEntry(address, size);
912 return snapshot_->AddEntry(type, name, object_id, size); 912 return snapshot_->AddEntry(type, name, object_id, size);
913 } 913 }
914 914
915 915
916 class GcSubrootsEnumerator : public ObjectVisitor { 916 class GcSubrootsEnumerator : public ObjectVisitor {
917 public: 917 public:
918 GcSubrootsEnumerator( 918 GcSubrootsEnumerator(
919 SnapshotFillerInterface* filler, V8HeapExplorer* explorer) 919 SnapshotFillerInterface* filler, V8HeapExplorer* explorer)
920 : filler_(filler), 920 : filler_(filler),
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 AllocationSite::kDependentCodeOffset); 1451 AllocationSite::kDependentCodeOffset);
1452 // Do not visit weak_next as it is not visited by the StaticVisitor, 1452 // Do not visit weak_next as it is not visited by the StaticVisitor,
1453 // and we're not very interested in weak_next field here. 1453 // and we're not very interested in weak_next field here.
1454 STATIC_CHECK(AllocationSite::kWeakNextOffset >= 1454 STATIC_CHECK(AllocationSite::kWeakNextOffset >=
1455 AllocationSite::BodyDescriptor::kEndOffset); 1455 AllocationSite::BodyDescriptor::kEndOffset);
1456 } 1456 }
1457 1457
1458 1458
1459 class JSArrayBufferDataEntryAllocator : public HeapEntriesAllocator { 1459 class JSArrayBufferDataEntryAllocator : public HeapEntriesAllocator {
1460 public: 1460 public:
1461 JSArrayBufferDataEntryAllocator(int size, V8HeapExplorer* explorer) 1461 JSArrayBufferDataEntryAllocator(size_t size, V8HeapExplorer* explorer)
1462 : size_(size) 1462 : size_(size)
1463 , explorer_(explorer) { 1463 , explorer_(explorer) {
1464 } 1464 }
1465 virtual HeapEntry* AllocateEntry(HeapThing ptr) { 1465 virtual HeapEntry* AllocateEntry(HeapThing ptr) {
1466 return explorer_->AddEntry( 1466 return explorer_->AddEntry(
1467 static_cast<Address>(ptr), 1467 static_cast<Address>(ptr),
1468 HeapEntry::kNative, "system / JSArrayBufferData", size_); 1468 HeapEntry::kNative, "system / JSArrayBufferData", size_);
1469 } 1469 }
1470 private: 1470 private:
1471 int size_; 1471 size_t size_;
1472 V8HeapExplorer* explorer_; 1472 V8HeapExplorer* explorer_;
1473 }; 1473 };
1474 1474
1475 1475
1476 void V8HeapExplorer::ExtractJSArrayBufferReferences( 1476 void V8HeapExplorer::ExtractJSArrayBufferReferences(
1477 int entry, JSArrayBuffer* buffer) { 1477 int entry, JSArrayBuffer* buffer) {
1478 SetWeakReference(buffer, entry, "weak_next", buffer->weak_next(), 1478 SetWeakReference(buffer, entry, "weak_next", buffer->weak_next(),
1479 JSArrayBuffer::kWeakNextOffset); 1479 JSArrayBuffer::kWeakNextOffset);
1480 SetWeakReference(buffer, entry, 1480 SetWeakReference(buffer, entry,
1481 "weak_first_view", buffer->weak_first_view(), 1481 "weak_first_view", buffer->weak_first_view(),
1482 JSArrayBuffer::kWeakFirstViewOffset); 1482 JSArrayBuffer::kWeakFirstViewOffset);
1483 // Setup a reference to a native memory backing_store object. 1483 // Setup a reference to a native memory backing_store object.
1484 if (!buffer->backing_store()) 1484 if (!buffer->backing_store())
1485 return; 1485 return;
1486 size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length()); 1486 size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length());
1487 CHECK(data_size <= static_cast<size_t>(kMaxInt)); 1487 JSArrayBufferDataEntryAllocator allocator(data_size, this);
1488 JSArrayBufferDataEntryAllocator allocator(static_cast<int>(data_size), this);
1489 HeapEntry* data_entry = 1488 HeapEntry* data_entry =
1490 filler_->FindOrAddEntry(buffer->backing_store(), &allocator); 1489 filler_->FindOrAddEntry(buffer->backing_store(), &allocator);
1491 filler_->SetNamedReference(HeapGraphEdge::kInternal, 1490 filler_->SetNamedReference(HeapGraphEdge::kInternal,
1492 entry, "backing_store", data_entry); 1491 entry, "backing_store", data_entry);
1493 } 1492 }
1494 1493
1495 1494
1496 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) { 1495 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) {
1497 if (!js_obj->IsJSFunction()) return; 1496 if (!js_obj->IsJSFunction()) return;
1498 1497
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2695 int HeapSnapshotJSONSerializer::GetStringId(const char* s) { 2694 int HeapSnapshotJSONSerializer::GetStringId(const char* s) {
2696 HashMap::Entry* cache_entry = strings_.Lookup( 2695 HashMap::Entry* cache_entry = strings_.Lookup(
2697 const_cast<char*>(s), StringHash(s), true); 2696 const_cast<char*>(s), StringHash(s), true);
2698 if (cache_entry->value == NULL) { 2697 if (cache_entry->value == NULL) {
2699 cache_entry->value = reinterpret_cast<void*>(next_string_id_++); 2698 cache_entry->value = reinterpret_cast<void*>(next_string_id_++);
2700 } 2699 }
2701 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); 2700 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value));
2702 } 2701 }
2703 2702
2704 2703
2705 static int utoa(unsigned value, const Vector<char>& buffer, int buffer_pos) { 2704 namespace {
2705
2706 template<size_t size> struct ToUnsigned;
2707
2708 template<> struct ToUnsigned<4> {
2709 typedef uint32_t Type;
2710 };
2711
2712 template<> struct ToUnsigned<8> {
2713 typedef uint64_t Type;
2714 };
2715
2716 } // namespace
2717
2718
2719 template<typename T>
2720 static int utoa_impl(T value, const Vector<char>& buffer, int buffer_pos) {
2721 STATIC_CHECK(static_cast<T>(-1) > 0); // Check that T is unsigned
2706 int number_of_digits = 0; 2722 int number_of_digits = 0;
2707 unsigned t = value; 2723 T t = value;
2708 do { 2724 do {
2709 ++number_of_digits; 2725 ++number_of_digits;
2710 } while (t /= 10); 2726 } while (t /= 10);
2711 2727
2712 buffer_pos += number_of_digits; 2728 buffer_pos += number_of_digits;
2713 int result = buffer_pos; 2729 int result = buffer_pos;
2714 do { 2730 do {
2715 int last_digit = value % 10; 2731 int last_digit = static_cast<int>(value % 10);
2716 buffer[--buffer_pos] = '0' + last_digit; 2732 buffer[--buffer_pos] = '0' + last_digit;
2717 value /= 10; 2733 value /= 10;
2718 } while (value); 2734 } while (value);
2719 return result; 2735 return result;
2720 } 2736 }
2721 2737
2722 2738
2739 template<typename T>
2740 static int utoa(T value, const Vector<char>& buffer, int buffer_pos) {
2741 typename ToUnsigned<sizeof(value)>::Type unsigned_value = value;
2742 STATIC_CHECK(sizeof(value) == sizeof(unsigned_value));
2743 return utoa_impl(unsigned_value, buffer, buffer_pos);
2744 }
2745
2746
2723 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge, 2747 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge,
2724 bool first_edge) { 2748 bool first_edge) {
2725 // The buffer needs space for 3 unsigned ints, 3 commas, \n and \0 2749 // The buffer needs space for 3 unsigned ints, 3 commas, \n and \0
2726 static const int kBufferSize = 2750 static const int kBufferSize =
2727 MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned * 3 + 3 + 2; // NOLINT 2751 MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned * 3 + 3 + 2; // NOLINT
2728 EmbeddedVector<char, kBufferSize> buffer; 2752 EmbeddedVector<char, kBufferSize> buffer;
2729 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement 2753 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement
2730 || edge->type() == HeapGraphEdge::kHidden 2754 || edge->type() == HeapGraphEdge::kHidden
2731 ? edge->index() : GetStringId(edge->name()); 2755 ? edge->index() : GetStringId(edge->name());
2732 int buffer_pos = 0; 2756 int buffer_pos = 0;
(...skipping 16 matching lines...) Expand all
2749 for (int i = 0; i < edges.length(); ++i) { 2773 for (int i = 0; i < edges.length(); ++i) {
2750 ASSERT(i == 0 || 2774 ASSERT(i == 0 ||
2751 edges[i - 1]->from()->index() <= edges[i]->from()->index()); 2775 edges[i - 1]->from()->index() <= edges[i]->from()->index());
2752 SerializeEdge(edges[i], i == 0); 2776 SerializeEdge(edges[i], i == 0);
2753 if (writer_->aborted()) return; 2777 if (writer_->aborted()) return;
2754 } 2778 }
2755 } 2779 }
2756 2780
2757 2781
2758 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { 2782 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) {
2759 // The buffer needs space for 5 unsigned ints, 5 commas, \n and \0 2783 // The buffer needs space for 4 unsigned ints, 1 size_t, 5 commas, \n and \0
2760 static const int kBufferSize = 2784 static const int kBufferSize =
2761 5 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT 2785 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT
2786 + MaxDecimalDigitsIn<sizeof(size_t)>::kUnsigned // NOLINT
2762 + 5 + 1 + 1; 2787 + 5 + 1 + 1;
2763 EmbeddedVector<char, kBufferSize> buffer; 2788 EmbeddedVector<char, kBufferSize> buffer;
2764 int buffer_pos = 0; 2789 int buffer_pos = 0;
2765 if (entry_index(entry) != 0) { 2790 if (entry_index(entry) != 0) {
2766 buffer[buffer_pos++] = ','; 2791 buffer[buffer_pos++] = ',';
2767 } 2792 }
2768 buffer_pos = utoa(entry->type(), buffer, buffer_pos); 2793 buffer_pos = utoa(entry->type(), buffer, buffer_pos);
2769 buffer[buffer_pos++] = ','; 2794 buffer[buffer_pos++] = ',';
2770 buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos); 2795 buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos);
2771 buffer[buffer_pos++] = ','; 2796 buffer[buffer_pos++] = ',';
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
3039 writer_->AddString("\"<dummy>\""); 3064 writer_->AddString("\"<dummy>\"");
3040 for (int i = 1; i < sorted_strings.length(); ++i) { 3065 for (int i = 1; i < sorted_strings.length(); ++i) {
3041 writer_->AddCharacter(','); 3066 writer_->AddCharacter(',');
3042 SerializeString(sorted_strings[i]); 3067 SerializeString(sorted_strings[i]);
3043 if (writer_->aborted()) return; 3068 if (writer_->aborted()) return;
3044 } 3069 }
3045 } 3070 }
3046 3071
3047 3072
3048 } } // namespace v8::internal 3073 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap-snapshot-generator.h ('k') | test/cctest/test-heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698