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

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: 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
« src/api.cc ('K') | « src/heap-snapshot-generator.h ('k') | no next file » | 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 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 1458
1459 void V8HeapExplorer::ExtractJSArrayBufferReferences( 1459 void V8HeapExplorer::ExtractJSArrayBufferReferences(
1460 int entry, JSArrayBuffer* buffer) { 1460 int entry, JSArrayBuffer* buffer) {
1461 SetWeakReference(buffer, entry, "weak_next", buffer->weak_next(), 1461 SetWeakReference(buffer, entry, "weak_next", buffer->weak_next(),
1462 JSArrayBuffer::kWeakNextOffset); 1462 JSArrayBuffer::kWeakNextOffset);
1463 SetWeakReference(buffer, entry, 1463 SetWeakReference(buffer, entry,
1464 "weak_first_view", buffer->weak_first_view(), 1464 "weak_first_view", buffer->weak_first_view(),
1465 JSArrayBuffer::kWeakFirstViewOffset); 1465 JSArrayBuffer::kWeakFirstViewOffset);
1466 // Setup a reference to a native memory backing_store object. 1466 // Setup a reference to a native memory backing_store object.
1467 size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length()); 1467 size_t data_size = NumberToSize(heap_->isolate(), buffer->byte_length());
1468 CHECK(data_size <= static_cast<size_t>(kMaxInt));
1469 HeapEntry* data_entry = AddEntry( 1468 HeapEntry* data_entry = AddEntry(
1470 static_cast<Address>(buffer->backing_store()), 1469 static_cast<Address>(buffer->backing_store()),
1471 HeapEntry::kNative, "system / ArrayBufferData", 1470 HeapEntry::kNative, "system / ArrayBufferData", data_size);
1472 static_cast<int>(data_size));
1473 filler_->SetNamedReference(HeapGraphEdge::kInternal, 1471 filler_->SetNamedReference(HeapGraphEdge::kInternal,
1474 entry, "backing_store", data_entry); 1472 entry, "backing_store", data_entry);
1475 } 1473 }
1476 1474
1477 1475
1478 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) { 1476 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj, int entry) {
1479 if (!js_obj->IsJSFunction()) return; 1477 if (!js_obj->IsJSFunction()) return;
1480 1478
1481 JSFunction* func = JSFunction::cast(js_obj); 1479 JSFunction* func = JSFunction::cast(js_obj);
1482 if (func->shared()->bound()) { 1480 if (func->shared()->bound()) {
(...skipping 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2677 int HeapSnapshotJSONSerializer::GetStringId(const char* s) { 2675 int HeapSnapshotJSONSerializer::GetStringId(const char* s) {
2678 HashMap::Entry* cache_entry = strings_.Lookup( 2676 HashMap::Entry* cache_entry = strings_.Lookup(
2679 const_cast<char*>(s), StringHash(s), true); 2677 const_cast<char*>(s), StringHash(s), true);
2680 if (cache_entry->value == NULL) { 2678 if (cache_entry->value == NULL) {
2681 cache_entry->value = reinterpret_cast<void*>(next_string_id_++); 2679 cache_entry->value = reinterpret_cast<void*>(next_string_id_++);
2682 } 2680 }
2683 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); 2681 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value));
2684 } 2682 }
2685 2683
2686 2684
2687 static int utoa(unsigned value, const Vector<char>& buffer, int buffer_pos) { 2685 namespace {
2686
2687 template<size_t size> struct ToUnsigned;
2688
2689 template<> struct ToUnsigned<4> {
2690 typedef uint32_t Type;
2691 };
2692
2693 template<> struct ToUnsigned<8> {
2694 typedef uint64_t Type;
2695 };
2696
2697 } // namespace
2698
2699
2700 template<typename T>
2701 static int utoa_impl(T value, const Vector<char>& buffer, int buffer_pos) {
2702 STATIC_CHECK(static_cast<T>(-1) > 0); // Check that T is unsigned
2688 int number_of_digits = 0; 2703 int number_of_digits = 0;
2689 unsigned t = value; 2704 T t = value;
2690 do { 2705 do {
2691 ++number_of_digits; 2706 ++number_of_digits;
2692 } while (t /= 10); 2707 } while (t /= 10);
2693 2708
2694 buffer_pos += number_of_digits; 2709 buffer_pos += number_of_digits;
2695 int result = buffer_pos; 2710 int result = buffer_pos;
2696 do { 2711 do {
2697 int last_digit = value % 10; 2712 int last_digit = static_cast<int>(value % 10);
2698 buffer[--buffer_pos] = '0' + last_digit; 2713 buffer[--buffer_pos] = '0' + last_digit;
2699 value /= 10; 2714 value /= 10;
2700 } while (value); 2715 } while (value);
2701 return result; 2716 return result;
2702 } 2717 }
2703 2718
2704 2719
2720 template<typename T>
2721 static int utoa(T value, const Vector<char>& buffer, int buffer_pos) {
2722 typename ToUnsigned<sizeof(value)>::Type unsigned_value = value;
2723 STATIC_CHECK(sizeof(value) == sizeof(unsigned_value));
2724 return utoa_impl(unsigned_value, buffer, buffer_pos);
2725 }
2726
2727
2705 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge, 2728 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge,
2706 bool first_edge) { 2729 bool first_edge) {
2707 // The buffer needs space for 3 unsigned ints, 3 commas, \n and \0 2730 // The buffer needs space for 3 unsigned ints, 3 commas, \n and \0
2708 static const int kBufferSize = 2731 static const int kBufferSize =
2709 MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned * 3 + 3 + 2; // NOLINT 2732 MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned * 3 + 3 + 2; // NOLINT
2710 EmbeddedVector<char, kBufferSize> buffer; 2733 EmbeddedVector<char, kBufferSize> buffer;
2711 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement 2734 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement
2712 || edge->type() == HeapGraphEdge::kHidden 2735 || edge->type() == HeapGraphEdge::kHidden
2713 ? edge->index() : GetStringId(edge->name()); 2736 ? edge->index() : GetStringId(edge->name());
2714 int buffer_pos = 0; 2737 int buffer_pos = 0;
(...skipping 16 matching lines...) Expand all
2731 for (int i = 0; i < edges.length(); ++i) { 2754 for (int i = 0; i < edges.length(); ++i) {
2732 ASSERT(i == 0 || 2755 ASSERT(i == 0 ||
2733 edges[i - 1]->from()->index() <= edges[i]->from()->index()); 2756 edges[i - 1]->from()->index() <= edges[i]->from()->index());
2734 SerializeEdge(edges[i], i == 0); 2757 SerializeEdge(edges[i], i == 0);
2735 if (writer_->aborted()) return; 2758 if (writer_->aborted()) return;
2736 } 2759 }
2737 } 2760 }
2738 2761
2739 2762
2740 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { 2763 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) {
2741 // The buffer needs space for 5 unsigned ints, 5 commas, \n and \0 2764 // The buffer needs space for 4 unsigned ints, 1 size_t, 5 commas, \n and \0
2742 static const int kBufferSize = 2765 static const int kBufferSize =
2743 5 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT 2766 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT
2767 + MaxDecimalDigitsIn<sizeof(size_t)>::kUnsigned // NOLINT
2744 + 5 + 1 + 1; 2768 + 5 + 1 + 1;
2745 EmbeddedVector<char, kBufferSize> buffer; 2769 EmbeddedVector<char, kBufferSize> buffer;
2746 int buffer_pos = 0; 2770 int buffer_pos = 0;
2747 if (entry_index(entry) != 0) { 2771 if (entry_index(entry) != 0) {
2748 buffer[buffer_pos++] = ','; 2772 buffer[buffer_pos++] = ',';
2749 } 2773 }
2750 buffer_pos = utoa(entry->type(), buffer, buffer_pos); 2774 buffer_pos = utoa(entry->type(), buffer, buffer_pos);
2751 buffer[buffer_pos++] = ','; 2775 buffer[buffer_pos++] = ',';
2752 buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos); 2776 buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos);
2753 buffer[buffer_pos++] = ','; 2777 buffer[buffer_pos++] = ',';
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
3021 writer_->AddString("\"<dummy>\""); 3045 writer_->AddString("\"<dummy>\"");
3022 for (int i = 1; i < sorted_strings.length(); ++i) { 3046 for (int i = 1; i < sorted_strings.length(); ++i) {
3023 writer_->AddCharacter(','); 3047 writer_->AddCharacter(',');
3024 SerializeString(sorted_strings[i]); 3048 SerializeString(sorted_strings[i]);
3025 if (writer_->aborted()) return; 3049 if (writer_->aborted()) return;
3026 } 3050 }
3027 } 3051 }
3028 3052
3029 3053
3030 } } // namespace v8::internal 3054 } } // namespace v8::internal
OLDNEW
« src/api.cc ('K') | « src/heap-snapshot-generator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698