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 |