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 1116 matching lines...) Loading... |
1127 const char* title, | 1127 const char* title, |
1128 unsigned uid) | 1128 unsigned uid) |
1129 : collection_(collection), | 1129 : collection_(collection), |
1130 type_(type), | 1130 type_(type), |
1131 title_(title), | 1131 title_(title), |
1132 uid_(uid), | 1132 uid_(uid), |
1133 root_entry_(NULL), | 1133 root_entry_(NULL), |
1134 gc_roots_entry_(NULL), | 1134 gc_roots_entry_(NULL), |
1135 natives_root_entry_(NULL), | 1135 natives_root_entry_(NULL), |
1136 raw_entries_(NULL), | 1136 raw_entries_(NULL), |
| 1137 number_of_edges_(0), |
1137 max_snapshot_js_object_id_(0) { | 1138 max_snapshot_js_object_id_(0) { |
1138 STATIC_CHECK( | 1139 STATIC_CHECK( |
1139 sizeof(HeapGraphEdge) == | 1140 sizeof(HeapGraphEdge) == |
1140 SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize); | 1141 SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize); |
1141 STATIC_CHECK( | 1142 STATIC_CHECK( |
1142 sizeof(HeapEntry) == | 1143 sizeof(HeapEntry) == |
1143 SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize); | 1144 SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize); |
1144 for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) { | 1145 for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) { |
1145 gc_subroot_entries_[i] = NULL; | 1146 gc_subroot_entries_[i] = NULL; |
1146 } | 1147 } |
(...skipping 13 matching lines...) Loading... |
1160 | 1161 |
1161 void HeapSnapshot::RememberLastJSObjectId() { | 1162 void HeapSnapshot::RememberLastJSObjectId() { |
1162 max_snapshot_js_object_id_ = collection_->last_assigned_id(); | 1163 max_snapshot_js_object_id_ = collection_->last_assigned_id(); |
1163 } | 1164 } |
1164 | 1165 |
1165 | 1166 |
1166 void HeapSnapshot::AllocateEntries(int entries_count, | 1167 void HeapSnapshot::AllocateEntries(int entries_count, |
1167 int children_count, | 1168 int children_count, |
1168 int retainers_count) { | 1169 int retainers_count) { |
1169 ASSERT(raw_entries_ == NULL); | 1170 ASSERT(raw_entries_ == NULL); |
| 1171 number_of_edges_ = children_count; |
1170 raw_entries_size_ = | 1172 raw_entries_size_ = |
1171 HeapEntry::EntriesSize(entries_count, children_count, retainers_count); | 1173 HeapEntry::EntriesSize(entries_count, children_count, retainers_count); |
1172 raw_entries_ = NewArray<char>(raw_entries_size_); | 1174 raw_entries_ = NewArray<char>(raw_entries_size_); |
1173 } | 1175 } |
1174 | 1176 |
1175 | 1177 |
1176 static void HeapEntryClearPaint(HeapEntry** entry_ptr) { | 1178 static void HeapEntryClearPaint(HeapEntry** entry_ptr) { |
1177 (*entry_ptr)->clear_paint(); | 1179 (*entry_ptr)->clear_paint(); |
1178 } | 1180 } |
1179 | 1181 |
(...skipping 2283 matching lines...) Loading... |
3463 SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize / MB, | 3465 SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize / MB, |
3464 (snapshot_->raw_entries_size() + MB - 1) / MB); | 3466 (snapshot_->raw_entries_size() + MB - 1) / MB); |
3465 HeapEntry* message = result->AddEntry( | 3467 HeapEntry* message = result->AddEntry( |
3466 HeapEntry::kString, text, 0, 4, 0, 0); | 3468 HeapEntry::kString, text, 0, 4, 0, 0); |
3467 root->SetUnidirElementReference(0, 1, message); | 3469 root->SetUnidirElementReference(0, 1, message); |
3468 result->SetDominatorsToSelf(); | 3470 result->SetDominatorsToSelf(); |
3469 return result; | 3471 return result; |
3470 } | 3472 } |
3471 | 3473 |
3472 | 3474 |
| 3475 void HeapSnapshotJSONSerializer::CalculateNodeIndexes( |
| 3476 const List<HeapEntry*>& nodes) { |
| 3477 // type,name,id,self_size,retained_size,dominator,children_index. |
| 3478 const int node_fields_count = 7; |
| 3479 // Root must be the first. |
| 3480 ASSERT(nodes.first() == snapshot_->root()); |
| 3481 // Rewrite node indexes, so they refer to actual array positions. Do this |
| 3482 // only once. |
| 3483 if (nodes[0]->entry_index() == -1) { |
| 3484 int index = 0; |
| 3485 for (int i = 0; i < nodes.length(); ++i, index += node_fields_count) { |
| 3486 nodes[i]->set_entry_index(index); |
| 3487 } |
| 3488 } |
| 3489 } |
| 3490 |
| 3491 |
3473 void HeapSnapshotJSONSerializer::SerializeImpl() { | 3492 void HeapSnapshotJSONSerializer::SerializeImpl() { |
| 3493 List<HeapEntry*>& nodes = *(snapshot_->entries()); |
| 3494 CalculateNodeIndexes(nodes); |
3474 writer_->AddCharacter('{'); | 3495 writer_->AddCharacter('{'); |
3475 writer_->AddString("\"snapshot\":{"); | 3496 writer_->AddString("\"snapshot\":{"); |
3476 SerializeSnapshot(); | 3497 SerializeSnapshot(); |
3477 if (writer_->aborted()) return; | 3498 if (writer_->aborted()) return; |
3478 writer_->AddString("},\n"); | 3499 writer_->AddString("},\n"); |
3479 writer_->AddString("\"nodes\":["); | 3500 writer_->AddString("\"nodes\":["); |
3480 SerializeNodes(); | 3501 SerializeNodes(nodes); |
| 3502 if (writer_->aborted()) return; |
| 3503 writer_->AddString("],\n"); |
| 3504 writer_->AddString("\"edges\":["); |
| 3505 SerializeEdges(nodes); |
3481 if (writer_->aborted()) return; | 3506 if (writer_->aborted()) return; |
3482 writer_->AddString("],\n"); | 3507 writer_->AddString("],\n"); |
3483 writer_->AddString("\"strings\":["); | 3508 writer_->AddString("\"strings\":["); |
3484 SerializeStrings(); | 3509 SerializeStrings(); |
3485 if (writer_->aborted()) return; | 3510 if (writer_->aborted()) return; |
3486 writer_->AddCharacter(']'); | 3511 writer_->AddCharacter(']'); |
3487 writer_->AddCharacter('}'); | 3512 writer_->AddCharacter('}'); |
3488 writer_->Finalize(); | 3513 writer_->Finalize(); |
3489 } | 3514 } |
3490 | 3515 |
(...skipping 26 matching lines...) Loading... |
3517 int result = buffer_pos; | 3542 int result = buffer_pos; |
3518 do { | 3543 do { |
3519 int last_digit = value % 10; | 3544 int last_digit = value % 10; |
3520 buffer[--buffer_pos] = '0' + last_digit; | 3545 buffer[--buffer_pos] = '0' + last_digit; |
3521 value /= 10; | 3546 value /= 10; |
3522 } while (value); | 3547 } while (value); |
3523 return result; | 3548 return result; |
3524 } | 3549 } |
3525 | 3550 |
3526 | 3551 |
3527 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge) { | 3552 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge, |
| 3553 bool first_edge) { |
3528 // The buffer needs space for 3 ints, 3 commas and \0 | 3554 // The buffer needs space for 3 ints, 3 commas and \0 |
3529 static const int kBufferSize = | 3555 static const int kBufferSize = |
3530 MaxDecimalDigitsIn<sizeof(int)>::kSigned * 3 + 3 + 1; // NOLINT | 3556 MaxDecimalDigitsIn<sizeof(int)>::kSigned * 3 + 3 + 1; // NOLINT |
3531 EmbeddedVector<char, kBufferSize> buffer; | 3557 EmbeddedVector<char, kBufferSize> buffer; |
3532 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement | 3558 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement |
3533 || edge->type() == HeapGraphEdge::kHidden | 3559 || edge->type() == HeapGraphEdge::kHidden |
3534 || edge->type() == HeapGraphEdge::kWeak | 3560 || edge->type() == HeapGraphEdge::kWeak |
3535 ? edge->index() : GetStringId(edge->name()); | 3561 ? edge->index() : GetStringId(edge->name()); |
3536 int buffer_pos = 0; | 3562 int buffer_pos = 0; |
3537 buffer[buffer_pos++] = ','; | 3563 if (!first_edge) { |
| 3564 buffer[buffer_pos++] = ','; |
| 3565 } |
3538 buffer_pos = itoa(edge->type(), buffer, buffer_pos); | 3566 buffer_pos = itoa(edge->type(), buffer, buffer_pos); |
3539 buffer[buffer_pos++] = ','; | 3567 buffer[buffer_pos++] = ','; |
3540 buffer_pos = itoa(edge_name_or_index, buffer, buffer_pos); | 3568 buffer_pos = itoa(edge_name_or_index, buffer, buffer_pos); |
3541 buffer[buffer_pos++] = ','; | 3569 buffer[buffer_pos++] = ','; |
3542 buffer_pos = itoa(edge->to()->entry_index(), buffer, buffer_pos); | 3570 buffer_pos = itoa(edge->to()->entry_index(), buffer, buffer_pos); |
3543 buffer[buffer_pos++] = '\0'; | 3571 buffer[buffer_pos++] = '\0'; |
3544 writer_->AddString(buffer.start()); | 3572 writer_->AddString(buffer.start()); |
3545 } | 3573 } |
3546 | 3574 |
3547 | 3575 |
3548 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { | 3576 void HeapSnapshotJSONSerializer::SerializeEdges(const List<HeapEntry*>& nodes) { |
| 3577 bool first_edge = true; |
| 3578 for (int i = 0; i < nodes.length(); ++i) { |
| 3579 HeapEntry* entry = nodes[i]; |
| 3580 Vector<HeapGraphEdge> children = entry->children(); |
| 3581 for (int j = 0; j < children.length(); ++j) { |
| 3582 SerializeEdge(&children[j], first_edge); |
| 3583 first_edge = false; |
| 3584 if (writer_->aborted()) return; |
| 3585 } |
| 3586 } |
| 3587 } |
| 3588 |
| 3589 |
| 3590 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry, |
| 3591 int edges_index) { |
3549 // The buffer needs space for 6 ints, 1 uint32_t, 7 commas, \n and \0 | 3592 // The buffer needs space for 6 ints, 1 uint32_t, 7 commas, \n and \0 |
3550 static const int kBufferSize = | 3593 static const int kBufferSize = |
3551 6 * MaxDecimalDigitsIn<sizeof(int)>::kSigned // NOLINT | 3594 6 * MaxDecimalDigitsIn<sizeof(int)>::kSigned // NOLINT |
3552 + MaxDecimalDigitsIn<sizeof(uint32_t)>::kUnsigned // NOLINT | 3595 + MaxDecimalDigitsIn<sizeof(uint32_t)>::kUnsigned // NOLINT |
3553 + 7 + 1 + 1; | 3596 + 7 + 1 + 1; |
3554 EmbeddedVector<char, kBufferSize> buffer; | 3597 EmbeddedVector<char, kBufferSize> buffer; |
3555 Vector<HeapGraphEdge> children = entry->children(); | |
3556 int buffer_pos = 0; | 3598 int buffer_pos = 0; |
3557 buffer[buffer_pos++] = '\n'; | 3599 buffer[buffer_pos++] = '\n'; |
3558 buffer[buffer_pos++] = ','; | 3600 if (entry->entry_index() != 0) { |
| 3601 buffer[buffer_pos++] = ','; |
| 3602 } |
3559 buffer_pos = itoa(entry->type(), buffer, buffer_pos); | 3603 buffer_pos = itoa(entry->type(), buffer, buffer_pos); |
3560 buffer[buffer_pos++] = ','; | 3604 buffer[buffer_pos++] = ','; |
3561 buffer_pos = itoa(GetStringId(entry->name()), buffer, buffer_pos); | 3605 buffer_pos = itoa(GetStringId(entry->name()), buffer, buffer_pos); |
3562 buffer[buffer_pos++] = ','; | 3606 buffer[buffer_pos++] = ','; |
3563 buffer_pos = itoa(entry->id(), buffer, buffer_pos); | 3607 buffer_pos = itoa(entry->id(), buffer, buffer_pos); |
3564 buffer[buffer_pos++] = ','; | 3608 buffer[buffer_pos++] = ','; |
3565 buffer_pos = itoa(entry->self_size(), buffer, buffer_pos); | 3609 buffer_pos = itoa(entry->self_size(), buffer, buffer_pos); |
3566 buffer[buffer_pos++] = ','; | 3610 buffer[buffer_pos++] = ','; |
3567 buffer_pos = itoa(entry->retained_size(), buffer, buffer_pos); | 3611 buffer_pos = itoa(entry->retained_size(), buffer, buffer_pos); |
3568 buffer[buffer_pos++] = ','; | 3612 buffer[buffer_pos++] = ','; |
3569 buffer_pos = itoa(entry->dominator()->entry_index(), buffer, buffer_pos); | 3613 buffer_pos = itoa(entry->dominator()->entry_index(), buffer, buffer_pos); |
3570 buffer[buffer_pos++] = ','; | 3614 buffer[buffer_pos++] = ','; |
3571 buffer_pos = itoa(children.length(), buffer, buffer_pos); | 3615 buffer_pos = itoa(edges_index, buffer, buffer_pos); |
3572 buffer[buffer_pos++] = '\0'; | 3616 buffer[buffer_pos++] = '\0'; |
3573 writer_->AddString(buffer.start()); | 3617 writer_->AddString(buffer.start()); |
3574 for (int i = 0; i < children.length(); ++i) { | 3618 } |
3575 SerializeEdge(&children[i]); | 3619 |
| 3620 |
| 3621 void HeapSnapshotJSONSerializer::SerializeNodes(const List<HeapEntry*>& nodes) { |
| 3622 const int edge_fields_count = 3; // type,name|index,to_node. |
| 3623 int edges_index = 0; |
| 3624 for (int i = 0; i < nodes.length(); ++i) { |
| 3625 HeapEntry* entry = nodes[i]; |
| 3626 SerializeNode(entry, edges_index); |
| 3627 edges_index += entry->children().length() * edge_fields_count; |
3576 if (writer_->aborted()) return; | 3628 if (writer_->aborted()) return; |
3577 } | 3629 } |
3578 } | 3630 } |
3579 | |
3580 | |
3581 void HeapSnapshotJSONSerializer::SerializeNodes() { | |
3582 // The first (zero) item of nodes array is an object describing node | |
3583 // serialization layout. We use a set of macros to improve | |
3584 // readability. | |
3585 #define JSON_A(s) "["s"]" | |
3586 #define JSON_O(s) "{"s"}" | |
3587 #define JSON_S(s) "\""s"\"" | |
3588 writer_->AddString(JSON_O( | |
3589 JSON_S("fields") ":" JSON_A( | |
3590 JSON_S("type") | |
3591 "," JSON_S("name") | |
3592 "," JSON_S("id") | |
3593 "," JSON_S("self_size") | |
3594 "," JSON_S("retained_size") | |
3595 "," JSON_S("dominator") | |
3596 "," JSON_S("children_count") | |
3597 "," JSON_S("children")) | |
3598 "," JSON_S("types") ":" JSON_A( | |
3599 JSON_A( | |
3600 JSON_S("hidden") | |
3601 "," JSON_S("array") | |
3602 "," JSON_S("string") | |
3603 "," JSON_S("object") | |
3604 "," JSON_S("code") | |
3605 "," JSON_S("closure") | |
3606 "," JSON_S("regexp") | |
3607 "," JSON_S("number") | |
3608 "," JSON_S("native") | |
3609 "," JSON_S("synthetic")) | |
3610 "," JSON_S("string") | |
3611 "," JSON_S("number") | |
3612 "," JSON_S("number") | |
3613 "," JSON_S("number") | |
3614 "," JSON_S("number") | |
3615 "," JSON_S("number") | |
3616 "," JSON_O( | |
3617 JSON_S("fields") ":" JSON_A( | |
3618 JSON_S("type") | |
3619 "," JSON_S("name_or_index") | |
3620 "," JSON_S("to_node")) | |
3621 "," JSON_S("types") ":" JSON_A( | |
3622 JSON_A( | |
3623 JSON_S("context") | |
3624 "," JSON_S("element") | |
3625 "," JSON_S("property") | |
3626 "," JSON_S("internal") | |
3627 "," JSON_S("hidden") | |
3628 "," JSON_S("shortcut") | |
3629 "," JSON_S("weak")) | |
3630 "," JSON_S("string_or_number") | |
3631 "," JSON_S("node")))))); | |
3632 #undef JSON_S | |
3633 #undef JSON_O | |
3634 #undef JSON_A | |
3635 | |
3636 const int node_fields_count = 7; | |
3637 // type,name,id,self_size,retained_size,dominator,children_count. | |
3638 const int edge_fields_count = 3; // type,name|index,to_node. | |
3639 | |
3640 List<HeapEntry*>& nodes = *(snapshot_->entries()); | |
3641 // Root must be the first. | |
3642 ASSERT(nodes.first() == snapshot_->root()); | |
3643 // Rewrite node indexes, so they refer to actual array positions. Do this | |
3644 // only once. | |
3645 if (nodes[0]->entry_index() == -1) { | |
3646 // Nodes start from array index 1. | |
3647 int index = 1; | |
3648 for (int i = 0; i < nodes.length(); ++i) { | |
3649 HeapEntry* node = nodes[i]; | |
3650 node->set_entry_index(index); | |
3651 index += node_fields_count + | |
3652 node->children().length() * edge_fields_count; | |
3653 } | |
3654 } | |
3655 | |
3656 for (int i = 0; i < nodes.length(); ++i) { | |
3657 SerializeNode(nodes[i]); | |
3658 if (writer_->aborted()) return; | |
3659 } | |
3660 } | |
3661 | 3631 |
3662 | 3632 |
3663 void HeapSnapshotJSONSerializer::SerializeSnapshot() { | 3633 void HeapSnapshotJSONSerializer::SerializeSnapshot() { |
3664 writer_->AddString("\"title\":\""); | 3634 writer_->AddString("\"title\":\""); |
3665 writer_->AddString(snapshot_->title()); | 3635 writer_->AddString(snapshot_->title()); |
3666 writer_->AddString("\""); | 3636 writer_->AddString("\""); |
3667 writer_->AddString(",\"uid\":"); | 3637 writer_->AddString(",\"uid\":"); |
3668 writer_->AddNumber(snapshot_->uid()); | 3638 writer_->AddNumber(snapshot_->uid()); |
| 3639 writer_->AddString(",\"meta\":"); |
| 3640 // The object describing node serialization layout. |
| 3641 // We use a set of macros to improve readability. |
| 3642 #define JSON_A(s) "["s"]" |
| 3643 #define JSON_O(s) "{"s"}" |
| 3644 #define JSON_S(s) "\""s"\"" |
| 3645 writer_->AddString(JSON_O( |
| 3646 JSON_S("node_fields") ":" JSON_A( |
| 3647 JSON_S("type") "," |
| 3648 JSON_S("name") "," |
| 3649 JSON_S("id") "," |
| 3650 JSON_S("self_size") "," |
| 3651 JSON_S("retained_size") "," |
| 3652 JSON_S("dominator") "," |
| 3653 JSON_S("edges_index")) "," |
| 3654 JSON_S("node_types") ":" JSON_A( |
| 3655 JSON_A( |
| 3656 JSON_S("hidden") "," |
| 3657 JSON_S("array") "," |
| 3658 JSON_S("string") "," |
| 3659 JSON_S("object") "," |
| 3660 JSON_S("code") "," |
| 3661 JSON_S("closure") "," |
| 3662 JSON_S("regexp") "," |
| 3663 JSON_S("number") "," |
| 3664 JSON_S("native") "," |
| 3665 JSON_S("synthetic")) "," |
| 3666 JSON_S("string") "," |
| 3667 JSON_S("number") "," |
| 3668 JSON_S("number") "," |
| 3669 JSON_S("number") "," |
| 3670 JSON_S("number") "," |
| 3671 JSON_S("number")) "," |
| 3672 JSON_S("edge_fields") ":" JSON_A( |
| 3673 JSON_S("type") "," |
| 3674 JSON_S("name_or_index") "," |
| 3675 JSON_S("to_node")) "," |
| 3676 JSON_S("edge_types") ":" JSON_A( |
| 3677 JSON_A( |
| 3678 JSON_S("context") "," |
| 3679 JSON_S("element") "," |
| 3680 JSON_S("property") "," |
| 3681 JSON_S("internal") "," |
| 3682 JSON_S("hidden") "," |
| 3683 JSON_S("shortcut") "," |
| 3684 JSON_S("weak")) "," |
| 3685 JSON_S("string_or_number") "," |
| 3686 JSON_S("node")))); |
| 3687 #undef JSON_S |
| 3688 #undef JSON_O |
| 3689 #undef JSON_A |
| 3690 writer_->AddString(",\"node_count\":"); |
| 3691 writer_->AddNumber(snapshot_->entries()->length()); |
| 3692 writer_->AddString(",\"edge_count\":"); |
| 3693 writer_->AddNumber(snapshot_->number_of_edges()); |
3669 } | 3694 } |
3670 | 3695 |
3671 | 3696 |
3672 static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) { | 3697 static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) { |
3673 static const char hex_chars[] = "0123456789ABCDEF"; | 3698 static const char hex_chars[] = "0123456789ABCDEF"; |
3674 w->AddString("\\u"); | 3699 w->AddString("\\u"); |
3675 w->AddCharacter(hex_chars[(u >> 12) & 0xf]); | 3700 w->AddCharacter(hex_chars[(u >> 12) & 0xf]); |
3676 w->AddCharacter(hex_chars[(u >> 8) & 0xf]); | 3701 w->AddCharacter(hex_chars[(u >> 8) & 0xf]); |
3677 w->AddCharacter(hex_chars[(u >> 4) & 0xf]); | 3702 w->AddCharacter(hex_chars[(u >> 4) & 0xf]); |
3678 w->AddCharacter(hex_chars[u & 0xf]); | 3703 w->AddCharacter(hex_chars[u & 0xf]); |
(...skipping 77 matching lines...) Loading... |
3756 | 3781 |
3757 | 3782 |
3758 void HeapSnapshotJSONSerializer::SortHashMap( | 3783 void HeapSnapshotJSONSerializer::SortHashMap( |
3759 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3784 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3760 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3785 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3761 sorted_entries->Add(p); | 3786 sorted_entries->Add(p); |
3762 sorted_entries->Sort(SortUsingEntryValue); | 3787 sorted_entries->Sort(SortUsingEntryValue); |
3763 } | 3788 } |
3764 | 3789 |
3765 } } // namespace v8::internal | 3790 } } // namespace v8::internal |
OLD | NEW |