| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 3335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3346 while (s < s_end) { | 3346 while (s < s_end) { |
| 3347 int s_chunk_size = Min( | 3347 int s_chunk_size = Min( |
| 3348 chunk_size_ - chunk_pos_, static_cast<int>(s_end - s)); | 3348 chunk_size_ - chunk_pos_, static_cast<int>(s_end - s)); |
| 3349 ASSERT(s_chunk_size > 0); | 3349 ASSERT(s_chunk_size > 0); |
| 3350 memcpy(chunk_.start() + chunk_pos_, s, s_chunk_size); | 3350 memcpy(chunk_.start() + chunk_pos_, s, s_chunk_size); |
| 3351 s += s_chunk_size; | 3351 s += s_chunk_size; |
| 3352 chunk_pos_ += s_chunk_size; | 3352 chunk_pos_ += s_chunk_size; |
| 3353 MaybeWriteChunk(); | 3353 MaybeWriteChunk(); |
| 3354 } | 3354 } |
| 3355 } | 3355 } |
| 3356 void AddNumber(int n) { AddNumberImpl<int>(n, "%d"); } | |
| 3357 void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); } | 3356 void AddNumber(unsigned n) { AddNumberImpl<unsigned>(n, "%u"); } |
| 3358 void AddNumber(uint64_t n) { AddNumberImpl<uint64_t>(n, "%llu"); } | |
| 3359 void Finalize() { | 3357 void Finalize() { |
| 3360 if (aborted_) return; | 3358 if (aborted_) return; |
| 3361 ASSERT(chunk_pos_ < chunk_size_); | 3359 ASSERT(chunk_pos_ < chunk_size_); |
| 3362 if (chunk_pos_ != 0) { | 3360 if (chunk_pos_ != 0) { |
| 3363 WriteChunk(); | 3361 WriteChunk(); |
| 3364 } | 3362 } |
| 3365 stream_->EndOfStream(); | 3363 stream_->EndOfStream(); |
| 3366 } | 3364 } |
| 3367 | 3365 |
| 3368 private: | 3366 private: |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3503 int HeapSnapshotJSONSerializer::GetStringId(const char* s) { | 3501 int HeapSnapshotJSONSerializer::GetStringId(const char* s) { |
| 3504 HashMap::Entry* cache_entry = strings_.Lookup( | 3502 HashMap::Entry* cache_entry = strings_.Lookup( |
| 3505 const_cast<char*>(s), ObjectHash(s), true); | 3503 const_cast<char*>(s), ObjectHash(s), true); |
| 3506 if (cache_entry->value == NULL) { | 3504 if (cache_entry->value == NULL) { |
| 3507 cache_entry->value = reinterpret_cast<void*>(next_string_id_++); | 3505 cache_entry->value = reinterpret_cast<void*>(next_string_id_++); |
| 3508 } | 3506 } |
| 3509 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); | 3507 return static_cast<int>(reinterpret_cast<intptr_t>(cache_entry->value)); |
| 3510 } | 3508 } |
| 3511 | 3509 |
| 3512 | 3510 |
| 3511 // This function won't work correctly for MIN_INT but this is not |
| 3512 // a problem in case of heap snapshots serialization. |
| 3513 static int itoa(int value, Vector<char>& buffer, int buffer_pos) { |
| 3514 if (value < 0) { |
| 3515 buffer[buffer_pos++] = '-'; |
| 3516 value = -value; |
| 3517 } |
| 3518 |
| 3519 int number_of_digits = 0; |
| 3520 int t = value; |
| 3521 do { |
| 3522 ++number_of_digits; |
| 3523 } while (t /= 10); |
| 3524 |
| 3525 buffer_pos += number_of_digits; |
| 3526 int result = buffer_pos; |
| 3527 do { |
| 3528 int last_digit = value % 10; |
| 3529 buffer[--buffer_pos] = '0' + last_digit; |
| 3530 value /= 10; |
| 3531 } while (value); |
| 3532 return result; |
| 3533 } |
| 3534 |
| 3535 |
| 3513 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) { | 3536 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) { |
| 3514 // The buffer needs space for 3 ints, 3 commas and \0 | 3537 // The buffer needs space for 3 ints, 3 commas and \0 |
| 3515 static const int kBufferSize = | 3538 static const int kBufferSize = |
| 3516 MaxDecimalDigitsIn<sizeof(int)>::kSigned * 3 + 3 + 1; // NOLINT | 3539 MaxDecimalDigitsIn<sizeof(int)>::kSigned * 3 + 3 + 1; // NOLINT |
| 3517 EmbeddedVector<char, kBufferSize> buffer; | 3540 EmbeddedVector<char, kBufferSize> buffer; |
| 3518 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement | 3541 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement |
| 3519 || edge->type() == HeapGraphEdge::kHidden | 3542 || edge->type() == HeapGraphEdge::kHidden |
| 3520 || edge->type() == HeapGraphEdge::kWeak | 3543 || edge->type() == HeapGraphEdge::kWeak |
| 3521 ? edge->index() : GetStringId(edge->name()); | 3544 ? edge->index() : GetStringId(edge->name()); |
| 3522 STATIC_CHECK(sizeof(int) == sizeof(edge->type())); // NOLINT | 3545 int buffer_pos = 0; |
| 3523 STATIC_CHECK(sizeof(int) == sizeof(edge_name_or_index)); // NOLINT | 3546 buffer[buffer_pos++] = ','; |
| 3524 STATIC_CHECK(sizeof(int) == sizeof(GetNodeId(edge->to()))); // NOLINT | 3547 buffer_pos = itoa(edge->type(), buffer, buffer_pos); |
| 3525 int result = OS::SNPrintF(buffer, ",%d,%d,%d", | 3548 buffer[buffer_pos++] = ','; |
| 3526 edge->type(), edge_name_or_index, GetNodeId(edge->to())); | 3549 buffer_pos = itoa(edge_name_or_index, buffer, buffer_pos); |
| 3527 USE(result); | 3550 buffer[buffer_pos++] = ','; |
| 3528 ASSERT(result != -1); | 3551 buffer_pos = itoa(GetNodeId(edge->to()), buffer, buffer_pos); |
| 3552 buffer[buffer_pos++] = '\0'; |
| 3529 writer_->AddString(buffer.start()); | 3553 writer_->AddString(buffer.start()); |
| 3530 } | 3554 } |
| 3531 | 3555 |
| 3532 | 3556 |
| 3533 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { | 3557 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { |
| 3534 // The buffer needs space for 6 ints, 1 uint32_t, 7 commas, \n and \0 | 3558 // The buffer needs space for 6 ints, 1 uint32_t, 7 commas, \n and \0 |
| 3535 static const int kBufferSize = | 3559 static const int kBufferSize = |
| 3536 6 * MaxDecimalDigitsIn<sizeof(int)>::kSigned // NOLINT | 3560 6 * MaxDecimalDigitsIn<sizeof(int)>::kSigned // NOLINT |
| 3537 + MaxDecimalDigitsIn<sizeof(uint32_t)>::kUnsigned // NOLINT | 3561 + MaxDecimalDigitsIn<sizeof(uint32_t)>::kUnsigned // NOLINT |
| 3538 + 7 + 1 + 1; | 3562 + 7 + 1 + 1; |
| 3539 EmbeddedVector<char, kBufferSize> buffer; | 3563 EmbeddedVector<char, kBufferSize> buffer; |
| 3540 Vector<HeapGraphEdge> children = entry->children(); | 3564 Vector<HeapGraphEdge> children = entry->children(); |
| 3541 STATIC_CHECK(sizeof(int) == sizeof(entry->type())); // NOLINT | 3565 int buffer_pos = 0; |
| 3542 STATIC_CHECK(sizeof(int) == sizeof(GetStringId(entry->name()))); // NOLINT | 3566 buffer[buffer_pos++] = '\n'; |
| 3543 STATIC_CHECK(sizeof(unsigned) == sizeof(entry->id())); // NOLINT | 3567 buffer[buffer_pos++] = ','; |
| 3544 STATIC_CHECK(sizeof(int) == sizeof(entry->self_size())); // NOLINT | 3568 buffer_pos = itoa(entry->type(), buffer, buffer_pos); |
| 3545 STATIC_CHECK(sizeof(int) == sizeof(entry->retained_size())); // NOLINT | 3569 buffer[buffer_pos++] = ','; |
| 3546 STATIC_CHECK(sizeof(int) == sizeof(GetNodeId(entry->dominator()))); // NOLINT | 3570 buffer_pos = itoa(GetStringId(entry->name()), buffer, buffer_pos); |
| 3547 STATIC_CHECK(sizeof(int) == sizeof(children.length())); // NOLINT | 3571 buffer[buffer_pos++] = ','; |
| 3548 int result = OS::SNPrintF(buffer, "\n,%d,%d,%u,%d,%d,%d,%d", | 3572 buffer_pos = itoa(entry->id(), buffer, buffer_pos); |
| 3549 entry->type(), | 3573 buffer[buffer_pos++] = ','; |
| 3550 GetStringId(entry->name()), | 3574 buffer_pos = itoa(entry->self_size(), buffer, buffer_pos); |
| 3551 entry->id(), | 3575 buffer[buffer_pos++] = ','; |
| 3552 entry->self_size(), | 3576 buffer_pos = itoa(entry->retained_size(), buffer, buffer_pos); |
| 3553 entry->retained_size(), | 3577 buffer[buffer_pos++] = ','; |
| 3554 GetNodeId(entry->dominator()), | 3578 buffer_pos = itoa(GetNodeId(entry->dominator()), buffer, buffer_pos); |
| 3555 children.length()); | 3579 buffer[buffer_pos++] = ','; |
| 3556 USE(result); | 3580 buffer_pos = itoa(children.length(), buffer, buffer_pos); |
| 3557 ASSERT(result != -1); | 3581 buffer[buffer_pos++] = '\0'; |
| 3558 writer_->AddString(buffer.start()); | 3582 writer_->AddString(buffer.start()); |
| 3559 for (int i = 0; i < children.length(); ++i) { | 3583 for (int i = 0; i < children.length(); ++i) { |
| 3560 SerializeEdge(&children[i]); | 3584 SerializeEdge(&children[i]); |
| 3561 if (writer_->aborted()) return; | 3585 if (writer_->aborted()) return; |
| 3562 } | 3586 } |
| 3563 } | 3587 } |
| 3564 | 3588 |
| 3565 | 3589 |
| 3566 void HeapSnapshotJSONSerializer::SerializeNodes() { | 3590 void HeapSnapshotJSONSerializer::SerializeNodes() { |
| 3567 // The first (zero) item of nodes array is an object describing node | 3591 // The first (zero) item of nodes array is an object describing node |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3739 | 3763 |
| 3740 | 3764 |
| 3741 void HeapSnapshotJSONSerializer::SortHashMap( | 3765 void HeapSnapshotJSONSerializer::SortHashMap( |
| 3742 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3766 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
| 3743 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3767 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
| 3744 sorted_entries->Add(p); | 3768 sorted_entries->Add(p); |
| 3745 sorted_entries->Sort(SortUsingEntryValue); | 3769 sorted_entries->Sort(SortUsingEntryValue); |
| 3746 } | 3770 } |
| 3747 | 3771 |
| 3748 } } // namespace v8::internal | 3772 } } // namespace v8::internal |
| OLD | NEW |