| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |