| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
| 6 | 6 |
| 7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 2462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2473 table->ElementRemoved(); | 2473 table->ElementRemoved(); |
| 2474 } | 2474 } |
| 2475 } | 2475 } |
| 2476 } | 2476 } |
| 2477 | 2477 |
| 2478 | 2478 |
| 2479 void MarkCompactCollector::ClearSimpleMapTransitions( | 2479 void MarkCompactCollector::ClearSimpleMapTransitions( |
| 2480 Object* non_live_map_list) { | 2480 Object* non_live_map_list) { |
| 2481 Object* the_hole_value = heap()->the_hole_value(); | 2481 Object* the_hole_value = heap()->the_hole_value(); |
| 2482 Object* weak_cell_obj = non_live_map_list; | 2482 Object* weak_cell_obj = non_live_map_list; |
| 2483 while (weak_cell_obj != Smi::FromInt(0)) { | 2483 while (weak_cell_obj != Smi::kZero) { |
| 2484 WeakCell* weak_cell = WeakCell::cast(weak_cell_obj); | 2484 WeakCell* weak_cell = WeakCell::cast(weak_cell_obj); |
| 2485 Map* map = Map::cast(weak_cell->value()); | 2485 Map* map = Map::cast(weak_cell->value()); |
| 2486 DCHECK(Marking::IsWhite(ObjectMarking::MarkBitFrom(map))); | 2486 DCHECK(Marking::IsWhite(ObjectMarking::MarkBitFrom(map))); |
| 2487 Object* potential_parent = map->constructor_or_backpointer(); | 2487 Object* potential_parent = map->constructor_or_backpointer(); |
| 2488 if (potential_parent->IsMap()) { | 2488 if (potential_parent->IsMap()) { |
| 2489 Map* parent = Map::cast(potential_parent); | 2489 Map* parent = Map::cast(potential_parent); |
| 2490 if (Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(parent)) && | 2490 if (Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(parent)) && |
| 2491 parent->raw_transitions() == weak_cell) { | 2491 parent->raw_transitions() == weak_cell) { |
| 2492 ClearSimpleMapTransition(parent, map); | 2492 ClearSimpleMapTransition(parent, map); |
| 2493 } | 2493 } |
| 2494 } | 2494 } |
| 2495 weak_cell->clear(); | 2495 weak_cell->clear(); |
| 2496 weak_cell_obj = weak_cell->next(); | 2496 weak_cell_obj = weak_cell->next(); |
| 2497 weak_cell->clear_next(the_hole_value); | 2497 weak_cell->clear_next(the_hole_value); |
| 2498 } | 2498 } |
| 2499 } | 2499 } |
| 2500 | 2500 |
| 2501 | 2501 |
| 2502 void MarkCompactCollector::ClearSimpleMapTransition(Map* map, | 2502 void MarkCompactCollector::ClearSimpleMapTransition(Map* map, |
| 2503 Map* dead_transition) { | 2503 Map* dead_transition) { |
| 2504 // A previously existing simple transition (stored in a WeakCell) is going | 2504 // A previously existing simple transition (stored in a WeakCell) is going |
| 2505 // to be cleared. Clear the useless cell pointer, and take ownership | 2505 // to be cleared. Clear the useless cell pointer, and take ownership |
| 2506 // of the descriptor array. | 2506 // of the descriptor array. |
| 2507 map->set_raw_transitions(Smi::FromInt(0)); | 2507 map->set_raw_transitions(Smi::kZero); |
| 2508 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); | 2508 int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
| 2509 DescriptorArray* descriptors = map->instance_descriptors(); | 2509 DescriptorArray* descriptors = map->instance_descriptors(); |
| 2510 if (descriptors == dead_transition->instance_descriptors() && | 2510 if (descriptors == dead_transition->instance_descriptors() && |
| 2511 number_of_own_descriptors > 0) { | 2511 number_of_own_descriptors > 0) { |
| 2512 TrimDescriptorArray(map, descriptors); | 2512 TrimDescriptorArray(map, descriptors); |
| 2513 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors); | 2513 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors); |
| 2514 map->set_owns_descriptors(true); | 2514 map->set_owns_descriptors(true); |
| 2515 } | 2515 } |
| 2516 } | 2516 } |
| 2517 | 2517 |
| 2518 | 2518 |
| 2519 void MarkCompactCollector::ClearFullMapTransitions() { | 2519 void MarkCompactCollector::ClearFullMapTransitions() { |
| 2520 HeapObject* undefined = heap()->undefined_value(); | 2520 HeapObject* undefined = heap()->undefined_value(); |
| 2521 Object* obj = heap()->encountered_transition_arrays(); | 2521 Object* obj = heap()->encountered_transition_arrays(); |
| 2522 while (obj != Smi::FromInt(0)) { | 2522 while (obj != Smi::kZero) { |
| 2523 TransitionArray* array = TransitionArray::cast(obj); | 2523 TransitionArray* array = TransitionArray::cast(obj); |
| 2524 int num_transitions = array->number_of_entries(); | 2524 int num_transitions = array->number_of_entries(); |
| 2525 DCHECK_EQ(TransitionArray::NumberOfTransitions(array), num_transitions); | 2525 DCHECK_EQ(TransitionArray::NumberOfTransitions(array), num_transitions); |
| 2526 if (num_transitions > 0) { | 2526 if (num_transitions > 0) { |
| 2527 Map* map = array->GetTarget(0); | 2527 Map* map = array->GetTarget(0); |
| 2528 Map* parent = Map::cast(map->constructor_or_backpointer()); | 2528 Map* parent = Map::cast(map->constructor_or_backpointer()); |
| 2529 bool parent_is_alive = | 2529 bool parent_is_alive = |
| 2530 Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(parent)); | 2530 Marking::IsBlackOrGrey(ObjectMarking::MarkBitFrom(parent)); |
| 2531 DescriptorArray* descriptors = | 2531 DescriptorArray* descriptors = |
| 2532 parent_is_alive ? parent->instance_descriptors() : nullptr; | 2532 parent_is_alive ? parent->instance_descriptors() : nullptr; |
| 2533 bool descriptors_owner_died = | 2533 bool descriptors_owner_died = |
| 2534 CompactTransitionArray(parent, array, descriptors); | 2534 CompactTransitionArray(parent, array, descriptors); |
| 2535 if (descriptors_owner_died) { | 2535 if (descriptors_owner_died) { |
| 2536 TrimDescriptorArray(parent, descriptors); | 2536 TrimDescriptorArray(parent, descriptors); |
| 2537 } | 2537 } |
| 2538 } | 2538 } |
| 2539 obj = array->next_link(); | 2539 obj = array->next_link(); |
| 2540 array->set_next_link(undefined, SKIP_WRITE_BARRIER); | 2540 array->set_next_link(undefined, SKIP_WRITE_BARRIER); |
| 2541 } | 2541 } |
| 2542 heap()->set_encountered_transition_arrays(Smi::FromInt(0)); | 2542 heap()->set_encountered_transition_arrays(Smi::kZero); |
| 2543 } | 2543 } |
| 2544 | 2544 |
| 2545 | 2545 |
| 2546 bool MarkCompactCollector::CompactTransitionArray( | 2546 bool MarkCompactCollector::CompactTransitionArray( |
| 2547 Map* map, TransitionArray* transitions, DescriptorArray* descriptors) { | 2547 Map* map, TransitionArray* transitions, DescriptorArray* descriptors) { |
| 2548 int num_transitions = transitions->number_of_entries(); | 2548 int num_transitions = transitions->number_of_entries(); |
| 2549 bool descriptors_owner_died = false; | 2549 bool descriptors_owner_died = false; |
| 2550 int transition_index = 0; | 2550 int transition_index = 0; |
| 2551 // Compact all live transitions to the left. | 2551 // Compact all live transitions to the left. |
| 2552 for (int i = 0; i < num_transitions; ++i) { | 2552 for (int i = 0; i < num_transitions; ++i) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2636 | 2636 |
| 2637 if (!descriptors->HasEnumIndicesCache()) return; | 2637 if (!descriptors->HasEnumIndicesCache()) return; |
| 2638 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache(); | 2638 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache(); |
| 2639 heap_->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(enum_indices_cache, | 2639 heap_->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(enum_indices_cache, |
| 2640 to_trim); | 2640 to_trim); |
| 2641 } | 2641 } |
| 2642 | 2642 |
| 2643 | 2643 |
| 2644 void MarkCompactCollector::ProcessWeakCollections() { | 2644 void MarkCompactCollector::ProcessWeakCollections() { |
| 2645 Object* weak_collection_obj = heap()->encountered_weak_collections(); | 2645 Object* weak_collection_obj = heap()->encountered_weak_collections(); |
| 2646 while (weak_collection_obj != Smi::FromInt(0)) { | 2646 while (weak_collection_obj != Smi::kZero) { |
| 2647 JSWeakCollection* weak_collection = | 2647 JSWeakCollection* weak_collection = |
| 2648 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); | 2648 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); |
| 2649 DCHECK(MarkCompactCollector::IsMarked(weak_collection)); | 2649 DCHECK(MarkCompactCollector::IsMarked(weak_collection)); |
| 2650 if (weak_collection->table()->IsHashTable()) { | 2650 if (weak_collection->table()->IsHashTable()) { |
| 2651 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); | 2651 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); |
| 2652 for (int i = 0; i < table->Capacity(); i++) { | 2652 for (int i = 0; i < table->Capacity(); i++) { |
| 2653 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { | 2653 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { |
| 2654 Object** key_slot = | 2654 Object** key_slot = |
| 2655 table->RawFieldOfElementAt(ObjectHashTable::EntryToIndex(i)); | 2655 table->RawFieldOfElementAt(ObjectHashTable::EntryToIndex(i)); |
| 2656 RecordSlot(table, key_slot, *key_slot); | 2656 RecordSlot(table, key_slot, *key_slot); |
| 2657 Object** value_slot = | 2657 Object** value_slot = |
| 2658 table->RawFieldOfElementAt(ObjectHashTable::EntryToValueIndex(i)); | 2658 table->RawFieldOfElementAt(ObjectHashTable::EntryToValueIndex(i)); |
| 2659 MarkCompactMarkingVisitor::MarkObjectByPointer(this, table, | 2659 MarkCompactMarkingVisitor::MarkObjectByPointer(this, table, |
| 2660 value_slot); | 2660 value_slot); |
| 2661 } | 2661 } |
| 2662 } | 2662 } |
| 2663 } | 2663 } |
| 2664 weak_collection_obj = weak_collection->next(); | 2664 weak_collection_obj = weak_collection->next(); |
| 2665 } | 2665 } |
| 2666 } | 2666 } |
| 2667 | 2667 |
| 2668 | 2668 |
| 2669 void MarkCompactCollector::ClearWeakCollections() { | 2669 void MarkCompactCollector::ClearWeakCollections() { |
| 2670 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_COLLECTIONS); | 2670 TRACE_GC(heap()->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_COLLECTIONS); |
| 2671 Object* weak_collection_obj = heap()->encountered_weak_collections(); | 2671 Object* weak_collection_obj = heap()->encountered_weak_collections(); |
| 2672 while (weak_collection_obj != Smi::FromInt(0)) { | 2672 while (weak_collection_obj != Smi::kZero) { |
| 2673 JSWeakCollection* weak_collection = | 2673 JSWeakCollection* weak_collection = |
| 2674 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); | 2674 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); |
| 2675 DCHECK(MarkCompactCollector::IsMarked(weak_collection)); | 2675 DCHECK(MarkCompactCollector::IsMarked(weak_collection)); |
| 2676 if (weak_collection->table()->IsHashTable()) { | 2676 if (weak_collection->table()->IsHashTable()) { |
| 2677 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); | 2677 ObjectHashTable* table = ObjectHashTable::cast(weak_collection->table()); |
| 2678 for (int i = 0; i < table->Capacity(); i++) { | 2678 for (int i = 0; i < table->Capacity(); i++) { |
| 2679 HeapObject* key = HeapObject::cast(table->KeyAt(i)); | 2679 HeapObject* key = HeapObject::cast(table->KeyAt(i)); |
| 2680 if (!MarkCompactCollector::IsMarked(key)) { | 2680 if (!MarkCompactCollector::IsMarked(key)) { |
| 2681 table->RemoveEntry(i); | 2681 table->RemoveEntry(i); |
| 2682 } | 2682 } |
| 2683 } | 2683 } |
| 2684 } | 2684 } |
| 2685 weak_collection_obj = weak_collection->next(); | 2685 weak_collection_obj = weak_collection->next(); |
| 2686 weak_collection->set_next(heap()->undefined_value()); | 2686 weak_collection->set_next(heap()->undefined_value()); |
| 2687 } | 2687 } |
| 2688 heap()->set_encountered_weak_collections(Smi::FromInt(0)); | 2688 heap()->set_encountered_weak_collections(Smi::kZero); |
| 2689 } | 2689 } |
| 2690 | 2690 |
| 2691 | 2691 |
| 2692 void MarkCompactCollector::AbortWeakCollections() { | 2692 void MarkCompactCollector::AbortWeakCollections() { |
| 2693 Object* weak_collection_obj = heap()->encountered_weak_collections(); | 2693 Object* weak_collection_obj = heap()->encountered_weak_collections(); |
| 2694 while (weak_collection_obj != Smi::FromInt(0)) { | 2694 while (weak_collection_obj != Smi::kZero) { |
| 2695 JSWeakCollection* weak_collection = | 2695 JSWeakCollection* weak_collection = |
| 2696 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); | 2696 reinterpret_cast<JSWeakCollection*>(weak_collection_obj); |
| 2697 weak_collection_obj = weak_collection->next(); | 2697 weak_collection_obj = weak_collection->next(); |
| 2698 weak_collection->set_next(heap()->undefined_value()); | 2698 weak_collection->set_next(heap()->undefined_value()); |
| 2699 } | 2699 } |
| 2700 heap()->set_encountered_weak_collections(Smi::FromInt(0)); | 2700 heap()->set_encountered_weak_collections(Smi::kZero); |
| 2701 } | 2701 } |
| 2702 | 2702 |
| 2703 | 2703 |
| 2704 void MarkCompactCollector::ClearWeakCells(Object** non_live_map_list, | 2704 void MarkCompactCollector::ClearWeakCells(Object** non_live_map_list, |
| 2705 DependentCode** dependent_code_list) { | 2705 DependentCode** dependent_code_list) { |
| 2706 Heap* heap = this->heap(); | 2706 Heap* heap = this->heap(); |
| 2707 TRACE_GC(heap->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_CELLS); | 2707 TRACE_GC(heap->tracer(), GCTracer::Scope::MC_CLEAR_WEAK_CELLS); |
| 2708 Object* weak_cell_obj = heap->encountered_weak_cells(); | 2708 Object* weak_cell_obj = heap->encountered_weak_cells(); |
| 2709 Object* the_hole_value = heap->the_hole_value(); | 2709 Object* the_hole_value = heap->the_hole_value(); |
| 2710 DependentCode* dependent_code_head = | 2710 DependentCode* dependent_code_head = |
| 2711 DependentCode::cast(heap->empty_fixed_array()); | 2711 DependentCode::cast(heap->empty_fixed_array()); |
| 2712 Object* non_live_map_head = Smi::FromInt(0); | 2712 Object* non_live_map_head = Smi::kZero; |
| 2713 while (weak_cell_obj != Smi::FromInt(0)) { | 2713 while (weak_cell_obj != Smi::kZero) { |
| 2714 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); | 2714 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); |
| 2715 Object* next_weak_cell = weak_cell->next(); | 2715 Object* next_weak_cell = weak_cell->next(); |
| 2716 bool clear_value = true; | 2716 bool clear_value = true; |
| 2717 bool clear_next = true; | 2717 bool clear_next = true; |
| 2718 // We do not insert cleared weak cells into the list, so the value | 2718 // We do not insert cleared weak cells into the list, so the value |
| 2719 // cannot be a Smi here. | 2719 // cannot be a Smi here. |
| 2720 HeapObject* value = HeapObject::cast(weak_cell->value()); | 2720 HeapObject* value = HeapObject::cast(weak_cell->value()); |
| 2721 if (!MarkCompactCollector::IsMarked(value)) { | 2721 if (!MarkCompactCollector::IsMarked(value)) { |
| 2722 // Cells for new-space objects embedded in optimized code are wrapped in | 2722 // Cells for new-space objects embedded in optimized code are wrapped in |
| 2723 // WeakCell and put into Heap::weak_object_to_code_table. | 2723 // WeakCell and put into Heap::weak_object_to_code_table. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2763 clear_value = false; | 2763 clear_value = false; |
| 2764 } | 2764 } |
| 2765 if (clear_value) { | 2765 if (clear_value) { |
| 2766 weak_cell->clear(); | 2766 weak_cell->clear(); |
| 2767 } | 2767 } |
| 2768 if (clear_next) { | 2768 if (clear_next) { |
| 2769 weak_cell->clear_next(the_hole_value); | 2769 weak_cell->clear_next(the_hole_value); |
| 2770 } | 2770 } |
| 2771 weak_cell_obj = next_weak_cell; | 2771 weak_cell_obj = next_weak_cell; |
| 2772 } | 2772 } |
| 2773 heap->set_encountered_weak_cells(Smi::FromInt(0)); | 2773 heap->set_encountered_weak_cells(Smi::kZero); |
| 2774 *non_live_map_list = non_live_map_head; | 2774 *non_live_map_list = non_live_map_head; |
| 2775 *dependent_code_list = dependent_code_head; | 2775 *dependent_code_list = dependent_code_head; |
| 2776 } | 2776 } |
| 2777 | 2777 |
| 2778 | 2778 |
| 2779 void MarkCompactCollector::AbortWeakCells() { | 2779 void MarkCompactCollector::AbortWeakCells() { |
| 2780 Object* the_hole_value = heap()->the_hole_value(); | 2780 Object* the_hole_value = heap()->the_hole_value(); |
| 2781 Object* weak_cell_obj = heap()->encountered_weak_cells(); | 2781 Object* weak_cell_obj = heap()->encountered_weak_cells(); |
| 2782 while (weak_cell_obj != Smi::FromInt(0)) { | 2782 while (weak_cell_obj != Smi::kZero) { |
| 2783 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); | 2783 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj); |
| 2784 weak_cell_obj = weak_cell->next(); | 2784 weak_cell_obj = weak_cell->next(); |
| 2785 weak_cell->clear_next(the_hole_value); | 2785 weak_cell->clear_next(the_hole_value); |
| 2786 } | 2786 } |
| 2787 heap()->set_encountered_weak_cells(Smi::FromInt(0)); | 2787 heap()->set_encountered_weak_cells(Smi::kZero); |
| 2788 } | 2788 } |
| 2789 | 2789 |
| 2790 | 2790 |
| 2791 void MarkCompactCollector::AbortTransitionArrays() { | 2791 void MarkCompactCollector::AbortTransitionArrays() { |
| 2792 HeapObject* undefined = heap()->undefined_value(); | 2792 HeapObject* undefined = heap()->undefined_value(); |
| 2793 Object* obj = heap()->encountered_transition_arrays(); | 2793 Object* obj = heap()->encountered_transition_arrays(); |
| 2794 while (obj != Smi::FromInt(0)) { | 2794 while (obj != Smi::kZero) { |
| 2795 TransitionArray* array = TransitionArray::cast(obj); | 2795 TransitionArray* array = TransitionArray::cast(obj); |
| 2796 obj = array->next_link(); | 2796 obj = array->next_link(); |
| 2797 array->set_next_link(undefined, SKIP_WRITE_BARRIER); | 2797 array->set_next_link(undefined, SKIP_WRITE_BARRIER); |
| 2798 } | 2798 } |
| 2799 heap()->set_encountered_transition_arrays(Smi::FromInt(0)); | 2799 heap()->set_encountered_transition_arrays(Smi::kZero); |
| 2800 } | 2800 } |
| 2801 | 2801 |
| 2802 void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo, | 2802 void MarkCompactCollector::RecordRelocSlot(Code* host, RelocInfo* rinfo, |
| 2803 Object* target) { | 2803 Object* target) { |
| 2804 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); | 2804 Page* target_page = Page::FromAddress(reinterpret_cast<Address>(target)); |
| 2805 Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host)); | 2805 Page* source_page = Page::FromAddress(reinterpret_cast<Address>(host)); |
| 2806 if (target_page->IsEvacuationCandidate() && | 2806 if (target_page->IsEvacuationCandidate() && |
| 2807 (rinfo->host() == NULL || | 2807 (rinfo->host() == NULL || |
| 2808 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { | 2808 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { |
| 2809 RelocInfo::Mode rmode = rinfo->rmode(); | 2809 RelocInfo::Mode rmode = rinfo->rmode(); |
| (...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4008 // The target is always in old space, we don't have to record the slot in | 4008 // The target is always in old space, we don't have to record the slot in |
| 4009 // the old-to-new remembered set. | 4009 // the old-to-new remembered set. |
| 4010 DCHECK(!heap()->InNewSpace(target)); | 4010 DCHECK(!heap()->InNewSpace(target)); |
| 4011 RecordRelocSlot(host, &rinfo, target); | 4011 RecordRelocSlot(host, &rinfo, target); |
| 4012 } | 4012 } |
| 4013 } | 4013 } |
| 4014 } | 4014 } |
| 4015 | 4015 |
| 4016 } // namespace internal | 4016 } // namespace internal |
| 4017 } // namespace v8 | 4017 } // namespace v8 |
| OLD | NEW |