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 |