Commit a8ed9d6b authored by yurys@chromium.org's avatar yurys@chromium.org

Switching to a custom itoa implementation reduces serialization time at least by the factor of 2.

Review URL: https://chromiumcodereview.appspot.com/9950146

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11223 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 232d9905
...@@ -3353,9 +3353,7 @@ class OutputStreamWriter { ...@@ -3353,9 +3353,7 @@ class OutputStreamWriter {
MaybeWriteChunk(); MaybeWriteChunk();
} }
} }
void AddNumber(int n) { AddNumberImpl<int>(n, "%d"); }
void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); } void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); }
void AddNumber(uint64_t n) { AddNumberImpl<uint64_t>(n, "%llu"); }
void Finalize() { void Finalize() {
if (aborted_) return; if (aborted_) return;
ASSERT(chunk_pos_ < chunk_size_); ASSERT(chunk_pos_ < chunk_size_);
...@@ -3510,6 +3508,31 @@ int HeapSnapshotJSONSerializer::GetStringId(const char* s) { ...@@ -3510,6 +3508,31 @@ int HeapSnapshotJSONSerializer::GetStringId(const char* s) {
} }
// This function won't work correctly for MIN_INT but this is not
// a problem in case of heap snapshots serialization.
static int itoa(int value, Vector<char>& buffer, int buffer_pos) {
if (value < 0) {
buffer[buffer_pos++] = '-';
value = -value;
}
int number_of_digits = 0;
int t = value;
do {
++number_of_digits;
} while (t /= 10);
buffer_pos += number_of_digits;
int result = buffer_pos;
do {
int last_digit = value % 10;
buffer[--buffer_pos] = '0' + last_digit;
value /= 10;
} while (value);
return result;
}
void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) { void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) {
// The buffer needs space for 3 ints, 3 commas and \0 // The buffer needs space for 3 ints, 3 commas and \0
static const int kBufferSize = static const int kBufferSize =
...@@ -3519,13 +3542,14 @@ void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) { ...@@ -3519,13 +3542,14 @@ void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) {
|| edge->type() == HeapGraphEdge::kHidden || edge->type() == HeapGraphEdge::kHidden
|| edge->type() == HeapGraphEdge::kWeak || edge->type() == HeapGraphEdge::kWeak
? edge->index() : GetStringId(edge->name()); ? edge->index() : GetStringId(edge->name());
STATIC_CHECK(sizeof(int) == sizeof(edge->type())); // NOLINT int buffer_pos = 0;
STATIC_CHECK(sizeof(int) == sizeof(edge_name_or_index)); // NOLINT buffer[buffer_pos++] = ',';
STATIC_CHECK(sizeof(int) == sizeof(GetNodeId(edge->to()))); // NOLINT buffer_pos = itoa(edge->type(), buffer, buffer_pos);
int result = OS::SNPrintF(buffer, ",%d,%d,%d", buffer[buffer_pos++] = ',';
edge->type(), edge_name_or_index, GetNodeId(edge->to())); buffer_pos = itoa(edge_name_or_index, buffer, buffer_pos);
USE(result); buffer[buffer_pos++] = ',';
ASSERT(result != -1); buffer_pos = itoa(GetNodeId(edge->to()), buffer, buffer_pos);
buffer[buffer_pos++] = '\0';
writer_->AddString(buffer.start()); writer_->AddString(buffer.start());
} }
...@@ -3538,23 +3562,23 @@ void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { ...@@ -3538,23 +3562,23 @@ void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) {
+ 7 + 1 + 1; + 7 + 1 + 1;
EmbeddedVector<char, kBufferSize> buffer; EmbeddedVector<char, kBufferSize> buffer;
Vector<HeapGraphEdge> children = entry->children(); Vector<HeapGraphEdge> children = entry->children();
STATIC_CHECK(sizeof(int) == sizeof(entry->type())); // NOLINT int buffer_pos = 0;
STATIC_CHECK(sizeof(int) == sizeof(GetStringId(entry->name()))); // NOLINT buffer[buffer_pos++] = '\n';
STATIC_CHECK(sizeof(unsigned) == sizeof(entry->id())); // NOLINT buffer[buffer_pos++] = ',';
STATIC_CHECK(sizeof(int) == sizeof(entry->self_size())); // NOLINT buffer_pos = itoa(entry->type(), buffer, buffer_pos);
STATIC_CHECK(sizeof(int) == sizeof(entry->retained_size())); // NOLINT buffer[buffer_pos++] = ',';
STATIC_CHECK(sizeof(int) == sizeof(GetNodeId(entry->dominator()))); // NOLINT buffer_pos = itoa(GetStringId(entry->name()), buffer, buffer_pos);
STATIC_CHECK(sizeof(int) == sizeof(children.length())); // NOLINT buffer[buffer_pos++] = ',';
int result = OS::SNPrintF(buffer, "\n,%d,%d,%u,%d,%d,%d,%d", buffer_pos = itoa(entry->id(), buffer, buffer_pos);
entry->type(), buffer[buffer_pos++] = ',';
GetStringId(entry->name()), buffer_pos = itoa(entry->self_size(), buffer, buffer_pos);
entry->id(), buffer[buffer_pos++] = ',';
entry->self_size(), buffer_pos = itoa(entry->retained_size(), buffer, buffer_pos);
entry->retained_size(), buffer[buffer_pos++] = ',';
GetNodeId(entry->dominator()), buffer_pos = itoa(GetNodeId(entry->dominator()), buffer, buffer_pos);
children.length()); buffer[buffer_pos++] = ',';
USE(result); buffer_pos = itoa(children.length(), buffer, buffer_pos);
ASSERT(result != -1); buffer[buffer_pos++] = '\0';
writer_->AddString(buffer.start()); writer_->AddString(buffer.start());
for (int i = 0; i < children.length(); ++i) { for (int i = 0; i < children.length(); ++i) {
SerializeEdge(&children[i]); SerializeEdge(&children[i]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment