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/incremental-marking.h" | 5 #include "src/heap/incremental-marking.h" |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/compilation-cache.h" | 8 #include "src/compilation-cache.h" |
9 #include "src/conversions.h" | 9 #include "src/conversions.h" |
10 #include "src/heap/gc-idle-time-handler.h" | 10 #include "src/heap/gc-idle-time-handler.h" |
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 } | 676 } |
677 prev_weak_cell_obj = weak_cell; | 677 prev_weak_cell_obj = weak_cell; |
678 weak_cell_obj = weak_cell->next(); | 678 weak_cell_obj = weak_cell->next(); |
679 } | 679 } |
680 } | 680 } |
681 // Top may have changed. | 681 // Top may have changed. |
682 heap()->set_encountered_weak_cells(weak_cell_head); | 682 heap()->set_encountered_weak_cells(weak_cell_head); |
683 } | 683 } |
684 | 684 |
685 | 685 |
| 686 bool ShouldRetainMap(Map* map, int age) { |
| 687 if (age == 0) { |
| 688 // The map has aged. Do not retain this map. |
| 689 return false; |
| 690 } |
| 691 Object* constructor = map->GetConstructor(); |
| 692 if (!constructor->IsHeapObject() || |
| 693 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(constructor)))) { |
| 694 // The constructor is dead, no new objects with this map can |
| 695 // be created. Do not retain this map. |
| 696 return false; |
| 697 } |
| 698 return true; |
| 699 } |
| 700 |
| 701 |
| 702 void IncrementalMarking::RetainMaps() { |
| 703 // Do not retain dead maps if flag disables it or there is |
| 704 // - memory pressure (reduce_memory_footprint_), |
| 705 // - GC is requested by tests or dev-tools (abort_incremental_marking_). |
| 706 bool map_retaining_is_disabled = heap()->ShouldReduceMemory() || |
| 707 heap()->ShouldAbortIncrementalMarking() || |
| 708 FLAG_retain_maps_for_n_gc == 0; |
| 709 ArrayList* retained_maps = heap()->retained_maps(); |
| 710 int length = retained_maps->Length(); |
| 711 // The number_of_disposed_maps separates maps in the retained_maps |
| 712 // array that were created before and after context disposal. |
| 713 // We do not age and retain disposed maps to avoid memory leaks. |
| 714 int number_of_disposed_maps = heap()->number_of_disposed_maps_; |
| 715 for (int i = 0; i < length; i += 2) { |
| 716 DCHECK(retained_maps->Get(i)->IsWeakCell()); |
| 717 WeakCell* cell = WeakCell::cast(retained_maps->Get(i)); |
| 718 if (cell->cleared()) continue; |
| 719 int age = Smi::cast(retained_maps->Get(i + 1))->value(); |
| 720 int new_age; |
| 721 Map* map = Map::cast(cell->value()); |
| 722 MarkBit map_mark = Marking::MarkBitFrom(map); |
| 723 if (i >= number_of_disposed_maps && !map_retaining_is_disabled && |
| 724 Marking::IsWhite(map_mark)) { |
| 725 if (ShouldRetainMap(map, age)) { |
| 726 MarkObject(heap(), map); |
| 727 } |
| 728 Object* prototype = map->prototype(); |
| 729 if (age > 0 && prototype->IsHeapObject() && |
| 730 Marking::IsWhite(Marking::MarkBitFrom(HeapObject::cast(prototype)))) { |
| 731 // The prototype is not marked, age the map. |
| 732 new_age = age - 1; |
| 733 } else { |
| 734 // The prototype and the constructor are marked, this map keeps only |
| 735 // transition tree alive, not JSObjects. Do not age the map. |
| 736 new_age = age; |
| 737 } |
| 738 } else { |
| 739 new_age = FLAG_retain_maps_for_n_gc; |
| 740 } |
| 741 // Compact the array and update the age. |
| 742 if (new_age != age) { |
| 743 retained_maps->Set(i + 1, Smi::FromInt(new_age)); |
| 744 } |
| 745 } |
| 746 } |
| 747 |
| 748 |
686 void IncrementalMarking::FinalizeIncrementally() { | 749 void IncrementalMarking::FinalizeIncrementally() { |
687 DCHECK(!finalize_marking_completed_); | 750 DCHECK(!finalize_marking_completed_); |
688 DCHECK(IsMarking()); | 751 DCHECK(IsMarking()); |
689 | 752 |
690 double start = heap_->MonotonicallyIncreasingTimeInMs(); | 753 double start = heap_->MonotonicallyIncreasingTimeInMs(); |
691 | 754 |
692 int old_marking_deque_top = | 755 int old_marking_deque_top = |
693 heap_->mark_compact_collector()->marking_deque()->top(); | 756 heap_->mark_compact_collector()->marking_deque()->top(); |
694 | 757 |
695 // After finishing incremental marking, we try to discover all unmarked | 758 // After finishing incremental marking, we try to discover all unmarked |
696 // objects to reduce the marking load in the final pause. | 759 // objects to reduce the marking load in the final pause. |
697 // 1) We scan and mark the roots again to find all changes to the root set. | 760 // 1) We scan and mark the roots again to find all changes to the root set. |
698 // 2) We mark the object groups. | 761 // 2) We mark the object groups. |
699 // 3) Remove weak cell with live values from the list of weak cells, they | 762 // 3) Age and retain maps embedded in optimized code. |
| 763 // 4) Remove weak cell with live values from the list of weak cells, they |
700 // do not need processing during GC. | 764 // do not need processing during GC. |
701 MarkRoots(); | 765 MarkRoots(); |
702 MarkObjectGroups(); | 766 MarkObjectGroups(); |
| 767 if (incremental_marking_finalization_rounds_ == 0) { |
| 768 // Map retaining is needed for perfromance, not correctness, |
| 769 // so we can do it only once at the beginning of the finalization. |
| 770 RetainMaps(); |
| 771 } |
703 ProcessWeakCells(); | 772 ProcessWeakCells(); |
704 | 773 |
705 int marking_progress = | 774 int marking_progress = |
706 abs(old_marking_deque_top - | 775 abs(old_marking_deque_top - |
707 heap_->mark_compact_collector()->marking_deque()->top()); | 776 heap_->mark_compact_collector()->marking_deque()->top()); |
708 | 777 |
709 double end = heap_->MonotonicallyIncreasingTimeInMs(); | 778 double end = heap_->MonotonicallyIncreasingTimeInMs(); |
710 double delta = end - start; | 779 double delta = end - start; |
711 heap_->tracer()->AddMarkingTime(delta); | 780 heap_->tracer()->AddMarkingTime(delta); |
712 heap_->tracer()->AddIncrementalMarkingFinalizationStep(delta); | 781 heap_->tracer()->AddIncrementalMarkingFinalizationStep(delta); |
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { | 1273 void IncrementalMarking::IncrementIdleMarkingDelayCounter() { |
1205 idle_marking_delay_counter_++; | 1274 idle_marking_delay_counter_++; |
1206 } | 1275 } |
1207 | 1276 |
1208 | 1277 |
1209 void IncrementalMarking::ClearIdleMarkingDelayCounter() { | 1278 void IncrementalMarking::ClearIdleMarkingDelayCounter() { |
1210 idle_marking_delay_counter_ = 0; | 1279 idle_marking_delay_counter_ = 0; |
1211 } | 1280 } |
1212 } // namespace internal | 1281 } // namespace internal |
1213 } // namespace v8 | 1282 } // namespace v8 |
OLD | NEW |