OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/profiler/heap-snapshot-generator.h" | 5 #include "src/profiler/heap-snapshot-generator.h" |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/objects-body-descriptors.h" | 10 #include "src/objects-body-descriptors.h" |
(...skipping 2594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2605 } | 2605 } |
2606 | 2606 |
2607 | 2607 |
2608 bool HeapSnapshotGenerator::FillReferences() { | 2608 bool HeapSnapshotGenerator::FillReferences() { |
2609 SnapshotFiller filler(snapshot_, &entries_); | 2609 SnapshotFiller filler(snapshot_, &entries_); |
2610 return v8_heap_explorer_.IterateAndExtractReferences(&filler) | 2610 return v8_heap_explorer_.IterateAndExtractReferences(&filler) |
2611 && dom_explorer_.IterateAndExtractReferences(&filler); | 2611 && dom_explorer_.IterateAndExtractReferences(&filler); |
2612 } | 2612 } |
2613 | 2613 |
2614 | 2614 |
2615 template<int bytes> struct MaxDecimalDigitsIn; | |
2616 template<> struct MaxDecimalDigitsIn<4> { | |
2617 static const int kSigned = 11; | |
2618 static const int kUnsigned = 10; | |
2619 }; | |
2620 template<> struct MaxDecimalDigitsIn<8> { | |
2621 static const int kSigned = 20; | |
2622 static const int kUnsigned = 20; | |
2623 }; | |
2624 | |
2625 | |
2626 class OutputStreamWriter { | |
2627 public: | |
2628 explicit OutputStreamWriter(v8::OutputStream* stream) | |
2629 : stream_(stream), | |
2630 chunk_size_(stream->GetChunkSize()), | |
2631 chunk_(chunk_size_), | |
2632 chunk_pos_(0), | |
2633 aborted_(false) { | |
2634 DCHECK(chunk_size_ > 0); | |
2635 } | |
2636 bool aborted() { return aborted_; } | |
2637 void AddCharacter(char c) { | |
2638 DCHECK(c != '\0'); | |
2639 DCHECK(chunk_pos_ < chunk_size_); | |
2640 chunk_[chunk_pos_++] = c; | |
2641 MaybeWriteChunk(); | |
2642 } | |
2643 void AddString(const char* s) { | |
2644 AddSubstring(s, StrLength(s)); | |
2645 } | |
2646 void AddSubstring(const char* s, int n) { | |
2647 if (n <= 0) return; | |
2648 DCHECK(static_cast<size_t>(n) <= strlen(s)); | |
2649 const char* s_end = s + n; | |
2650 while (s < s_end) { | |
2651 int s_chunk_size = | |
2652 Min(chunk_size_ - chunk_pos_, static_cast<int>(s_end - s)); | |
2653 DCHECK(s_chunk_size > 0); | |
2654 MemCopy(chunk_.start() + chunk_pos_, s, s_chunk_size); | |
2655 s += s_chunk_size; | |
2656 chunk_pos_ += s_chunk_size; | |
2657 MaybeWriteChunk(); | |
2658 } | |
2659 } | |
2660 void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); } | |
2661 void Finalize() { | |
2662 if (aborted_) return; | |
2663 DCHECK(chunk_pos_ < chunk_size_); | |
2664 if (chunk_pos_ != 0) { | |
2665 WriteChunk(); | |
2666 } | |
2667 stream_->EndOfStream(); | |
2668 } | |
2669 | |
2670 private: | |
2671 template<typename T> | |
2672 void AddNumberImpl(T n, const char* format) { | |
2673 // Buffer for the longest value plus trailing \0 | |
2674 static const int kMaxNumberSize = | |
2675 MaxDecimalDigitsIn<sizeof(T)>::kUnsigned + 1; | |
2676 if (chunk_size_ - chunk_pos_ >= kMaxNumberSize) { | |
2677 int result = SNPrintF( | |
2678 chunk_.SubVector(chunk_pos_, chunk_size_), format, n); | |
2679 DCHECK(result != -1); | |
2680 chunk_pos_ += result; | |
2681 MaybeWriteChunk(); | |
2682 } else { | |
2683 EmbeddedVector<char, kMaxNumberSize> buffer; | |
2684 int result = SNPrintF(buffer, format, n); | |
2685 USE(result); | |
2686 DCHECK(result != -1); | |
2687 AddString(buffer.start()); | |
2688 } | |
2689 } | |
2690 void MaybeWriteChunk() { | |
2691 DCHECK(chunk_pos_ <= chunk_size_); | |
2692 if (chunk_pos_ == chunk_size_) { | |
2693 WriteChunk(); | |
2694 } | |
2695 } | |
2696 void WriteChunk() { | |
2697 if (aborted_) return; | |
2698 if (stream_->WriteAsciiChunk(chunk_.start(), chunk_pos_) == | |
2699 v8::OutputStream::kAbort) aborted_ = true; | |
2700 chunk_pos_ = 0; | |
2701 } | |
2702 | |
2703 v8::OutputStream* stream_; | |
2704 int chunk_size_; | |
2705 ScopedVector<char> chunk_; | |
2706 int chunk_pos_; | |
2707 bool aborted_; | |
2708 }; | |
2709 | |
2710 | |
2711 // type, name|index, to_node. | 2615 // type, name|index, to_node. |
2712 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3; | 2616 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3; |
2713 // type, name, id, self_size, edge_count, trace_node_id. | 2617 // type, name, id, self_size, edge_count, trace_node_id. |
2714 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 6; | 2618 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 6; |
2715 | 2619 |
2716 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { | 2620 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { |
2717 if (AllocationTracker* allocation_tracker = | 2621 if (AllocationTracker* allocation_tracker = |
2718 snapshot_->profiler()->allocation_tracker()) { | 2622 snapshot_->profiler()->allocation_tracker()) { |
2719 allocation_tracker->PrepareForSerialization(); | 2623 allocation_tracker->PrepareForSerialization(); |
2720 } | 2624 } |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3161 for (int i = 1; i < sorted_strings.length(); ++i) { | 3065 for (int i = 1; i < sorted_strings.length(); ++i) { |
3162 writer_->AddCharacter(','); | 3066 writer_->AddCharacter(','); |
3163 SerializeString(sorted_strings[i]); | 3067 SerializeString(sorted_strings[i]); |
3164 if (writer_->aborted()) return; | 3068 if (writer_->aborted()) return; |
3165 } | 3069 } |
3166 } | 3070 } |
3167 | 3071 |
3168 | 3072 |
3169 } // namespace internal | 3073 } // namespace internal |
3170 } // namespace v8 | 3074 } // namespace v8 |
OLD | NEW |