Chromium Code Reviews| Index: src/profile-generator.cc |
| diff --git a/src/profile-generator.cc b/src/profile-generator.cc |
| index 8b645ded6833e22a5bce360f99d70617ba6a4519..21dd6741dc4ec9a12c411b0bcc2ce0a24fada348 100644 |
| --- a/src/profile-generator.cc |
| +++ b/src/profile-generator.cc |
| @@ -1083,7 +1083,7 @@ void HeapEntry::Print( |
| for (int i = 0; i < ch.length(); ++i) { |
| HeapGraphEdge& edge = ch[i]; |
| const char* edge_prefix = ""; |
| - ScopedVector<char> index(64); |
| + EmbeddedVector<char, 64> index; |
| const char* edge_name = index.start(); |
| switch (edge.type()) { |
| case HeapGraphEdge::kContextVariable: |
| @@ -1164,6 +1164,7 @@ class RetainedSizeCalculator { |
| int retained_size_; |
| }; |
| + |
| void HeapEntry::CalculateExactRetainedSize() { |
| // To calculate retained size, first we paint all reachable nodes in |
| // one color, then we paint (or re-paint) all nodes reachable from |
| @@ -1243,6 +1244,7 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, |
| } |
| } |
| + |
| HeapSnapshot::~HeapSnapshot() { |
| DeleteArray(raw_entries_); |
| } |
| @@ -1268,6 +1270,7 @@ static void HeapEntryClearPaint(HeapEntry** entry_ptr) { |
| (*entry_ptr)->clear_paint(); |
| } |
| + |
| void HeapSnapshot::ClearPaint() { |
| entries_.Iterate(HeapEntryClearPaint); |
| } |
| @@ -1373,6 +1376,7 @@ static int SortByIds(const T* entry1_ptr, |
| return (*entry1_ptr)->id() < (*entry2_ptr)->id() ? -1 : 1; |
| } |
| + |
| List<HeapEntry*>* HeapSnapshot::GetSortedEntriesList() { |
| if (!entries_sorted_) { |
| entries_.Sort(SortByIds); |
| @@ -3363,6 +3367,17 @@ bool HeapSnapshotGenerator::ApproximateRetainedSizes() { |
| } |
| +template<int bytes> struct MaxDecimalDigitsIn; |
| +template<> struct MaxDecimalDigitsIn<4> { |
| + static const int kSigned = 11; |
| + static const int kUnsigned = 10; |
| +}; |
| +template<> struct MaxDecimalDigitsIn<8> { |
| + static const int kSigned = 20; |
| + static const int kUnsigned = 20; |
| +}; |
| + |
| + |
| class OutputStreamWriter { |
| public: |
| explicit OutputStreamWriter(v8::OutputStream* stream) |
| @@ -3412,23 +3427,34 @@ class OutputStreamWriter { |
| private: |
| template<typename T> |
| void AddNumberImpl(T n, const char* format) { |
| - ScopedVector<char> buffer(32); |
| - int result = OS::SNPrintF(buffer, format, n); |
| - USE(result); |
| - ASSERT(result != -1); |
| - AddString(buffer.start()); |
| + // Buffer for long long value plus trailing \0 |
| + static const int kMaxNumberSize = |
| + MaxDecimalDigitsIn<sizeof(long long)>::kUnsigned + 1; // NOLINT |
|
mnaganov (inactive)
2012/02/21 14:21:54
I will change "long long" to "T" (and update the c
|
| + if (chunk_size_ - chunk_pos_ >= kMaxNumberSize) { |
| + int result = OS::SNPrintF( |
| + chunk_.SubVector(chunk_pos_, chunk_size_), format, n); |
| + ASSERT(result != -1); |
| + chunk_pos_ += result; |
| + MaybeWriteChunk(); |
| + } else { |
| + EmbeddedVector<char, kMaxNumberSize> buffer; |
| + int result = OS::SNPrintF(buffer, format, n); |
| + USE(result); |
| + ASSERT(result != -1); |
| + AddString(buffer.start()); |
| + } |
| } |
| void MaybeWriteChunk() { |
| ASSERT(chunk_pos_ <= chunk_size_); |
| if (chunk_pos_ == chunk_size_) { |
| WriteChunk(); |
| - chunk_pos_ = 0; |
| } |
| } |
| void WriteChunk() { |
| if (aborted_) return; |
| if (stream_->WriteAsciiChunk(chunk_.start(), chunk_pos_) == |
| v8::OutputStream::kAbort) aborted_ = true; |
| + chunk_pos_ = 0; |
| } |
| v8::OutputStream* stream_; |
| @@ -3438,6 +3464,7 @@ class OutputStreamWriter { |
| bool aborted_; |
| }; |
| + |
| void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { |
| ASSERT(writer_ == NULL); |
| writer_ = new OutputStreamWriter(stream); |
| @@ -3543,38 +3570,39 @@ int HeapSnapshotJSONSerializer::GetStringId(const char* s) { |
| void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) { |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(edge->type()); |
| - writer_->AddCharacter(','); |
| - if (edge->type() == HeapGraphEdge::kElement |
| + // The buffer needs space for 3 ints, 3 commas and \0 |
| + static const int kBufferSize = |
| + MaxDecimalDigitsIn<sizeof(int)>::kSigned * 3 + 3 + 1; // NOLINT |
| + EmbeddedVector<char, kBufferSize> buffer; |
| + int edge_name_or_index = edge->type() == HeapGraphEdge::kElement |
| || edge->type() == HeapGraphEdge::kHidden |
| - || edge->type() == HeapGraphEdge::kWeak) { |
| - writer_->AddNumber(edge->index()); |
| - } else { |
| - writer_->AddNumber(GetStringId(edge->name())); |
| - } |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(GetNodeId(edge->to())); |
| + || edge->type() == HeapGraphEdge::kWeak |
| + ? edge->index() : GetStringId(edge->name()); |
| + int result = OS::SNPrintF(buffer, ",%d,%d,%d", |
| + edge->type(), edge_name_or_index, GetNodeId(edge->to())); |
| + USE(result); |
| + ASSERT(result != -1); |
| + writer_->AddString(buffer.start()); |
| } |
| void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { |
| - writer_->AddCharacter('\n'); |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(entry->type()); |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(GetStringId(entry->name())); |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(entry->id()); |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(entry->self_size()); |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(entry->RetainedSize(false)); |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(GetNodeId(entry->dominator())); |
| + // The buffer needs space for 7 ints, 7 commas, \n and \0 |
| + static const int kBufferSize = |
| + MaxDecimalDigitsIn<sizeof(int)>::kSigned * 7 + 7 + 1 + 1; // NOLINT |
| + EmbeddedVector<char, kBufferSize> buffer; |
| Vector<HeapGraphEdge> children = entry->children(); |
| - writer_->AddCharacter(','); |
| - writer_->AddNumber(children.length()); |
| + int result = OS::SNPrintF(buffer, "\n,%d,%d,%d,%d,%d,%d,%d", |
| + entry->type(), |
| + GetStringId(entry->name()), |
| + entry->id(), |
| + entry->self_size(), |
| + entry->RetainedSize(false), |
| + GetNodeId(entry->dominator()), |
| + children.length()); |
| + USE(result); |
| + ASSERT(result != -1); |
| + writer_->AddString(buffer.start()); |
| for (int i = 0; i < children.length(); ++i) { |
| SerializeEdge(&children[i]); |
| if (writer_->aborted()) return; |