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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 } | 762 } |
763 // We must not compact the weak fixed list here, as we may be in the middle | 763 // We must not compact the weak fixed list here, as we may be in the middle |
764 // of writing to it, when the GC triggered. Instead, we reset the root value. | 764 // of writing to it, when the GC triggered. Instead, we reset the root value. |
765 set_weak_stack_trace_list(Smi::FromInt(0)); | 765 set_weak_stack_trace_list(Smi::FromInt(0)); |
766 } | 766 } |
767 | 767 |
768 | 768 |
769 void Heap::HandleGCRequest() { | 769 void Heap::HandleGCRequest() { |
770 if (incremental_marking()->request_type() == | 770 if (incremental_marking()->request_type() == |
771 IncrementalMarking::COMPLETE_MARKING) { | 771 IncrementalMarking::COMPLETE_MARKING) { |
772 CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt"); | 772 CollectAllGarbage(Heap::kNoGCFlags, "GC interrupt", |
| 773 incremental_marking()->CallbackFlags()); |
773 return; | 774 return; |
774 } | 775 } |
775 DCHECK(FLAG_overapproximate_weak_closure); | 776 DCHECK(FLAG_overapproximate_weak_closure); |
776 if (!incremental_marking()->weak_closure_was_overapproximated()) { | 777 if (!incremental_marking()->weak_closure_was_overapproximated()) { |
777 OverApproximateWeakClosure("GC interrupt"); | 778 OverApproximateWeakClosure("GC interrupt"); |
778 } | 779 } |
779 } | 780 } |
780 | 781 |
781 | 782 |
782 void Heap::OverApproximateWeakClosure(const char* gc_reason) { | 783 void Heap::OverApproximateWeakClosure(const char* gc_reason) { |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 if (collector == MARK_COMPACTOR && | 973 if (collector == MARK_COMPACTOR && |
973 (gc_callback_flags & kGCCallbackFlagForced) != 0) { | 974 (gc_callback_flags & kGCCallbackFlagForced) != 0) { |
974 isolate()->CountUsage(v8::Isolate::kForcedGC); | 975 isolate()->CountUsage(v8::Isolate::kForcedGC); |
975 } | 976 } |
976 | 977 |
977 // Start incremental marking for the next cycle. The heap snapshot | 978 // Start incremental marking for the next cycle. The heap snapshot |
978 // generator needs incremental marking to stay off after it aborted. | 979 // generator needs incremental marking to stay off after it aborted. |
979 if (!mark_compact_collector()->abort_incremental_marking() && | 980 if (!mark_compact_collector()->abort_incremental_marking() && |
980 incremental_marking()->IsStopped() && | 981 incremental_marking()->IsStopped() && |
981 incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { | 982 incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { |
982 incremental_marking()->Start(kNoGCFlags); | 983 incremental_marking()->Start(kNoGCFlags, kNoGCCallbackFlags, "GC epilogue"); |
983 } | 984 } |
984 | 985 |
985 return next_gc_likely_to_collect_more; | 986 return next_gc_likely_to_collect_more; |
986 } | 987 } |
987 | 988 |
988 | 989 |
989 int Heap::NotifyContextDisposed(bool dependant_context) { | 990 int Heap::NotifyContextDisposed(bool dependant_context) { |
990 if (!dependant_context) { | 991 if (!dependant_context) { |
991 tracer()->ResetSurvivalEvents(); | 992 tracer()->ResetSurvivalEvents(); |
992 old_generation_size_configured_ = false; | 993 old_generation_size_configured_ = false; |
993 } | 994 } |
994 if (isolate()->concurrent_recompilation_enabled()) { | 995 if (isolate()->concurrent_recompilation_enabled()) { |
995 // Flush the queued recompilation tasks. | 996 // Flush the queued recompilation tasks. |
996 isolate()->optimizing_compile_dispatcher()->Flush(); | 997 isolate()->optimizing_compile_dispatcher()->Flush(); |
997 } | 998 } |
998 AgeInlineCaches(); | 999 AgeInlineCaches(); |
999 set_retained_maps(ArrayList::cast(empty_fixed_array())); | 1000 set_retained_maps(ArrayList::cast(empty_fixed_array())); |
1000 tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis()); | 1001 tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis()); |
1001 MemoryReducer::Event event; | 1002 MemoryReducer::Event event; |
1002 event.type = MemoryReducer::kContextDisposed; | 1003 event.type = MemoryReducer::kContextDisposed; |
1003 event.time_ms = MonotonicallyIncreasingTimeInMs(); | 1004 event.time_ms = MonotonicallyIncreasingTimeInMs(); |
1004 memory_reducer_.NotifyContextDisposed(event); | 1005 memory_reducer_.NotifyContextDisposed(event); |
1005 return ++contexts_disposed_; | 1006 return ++contexts_disposed_; |
1006 } | 1007 } |
1007 | 1008 |
1008 | 1009 |
| 1010 void Heap::StartIncrementalMarking(int gc_flags, |
| 1011 const GCCallbackFlags gc_callback_flags, |
| 1012 const char* reason) { |
| 1013 DCHECK(incremental_marking()->IsStopped()); |
| 1014 incremental_marking()->Start(gc_flags, gc_callback_flags, reason); |
| 1015 } |
| 1016 |
| 1017 |
1009 void Heap::StartIdleIncrementalMarking() { | 1018 void Heap::StartIdleIncrementalMarking() { |
1010 gc_idle_time_handler_.ResetNoProgressCounter(); | 1019 gc_idle_time_handler_.ResetNoProgressCounter(); |
1011 incremental_marking()->Start(kReduceMemoryFootprintMask); | 1020 StartIncrementalMarking(kReduceMemoryFootprintMask, kNoGCCallbackFlags, |
| 1021 "idle"); |
1012 } | 1022 } |
1013 | 1023 |
1014 | 1024 |
1015 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, | 1025 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, |
1016 int len) { | 1026 int len) { |
1017 if (len == 0) return; | 1027 if (len == 0) return; |
1018 | 1028 |
1019 DCHECK(array->map() != fixed_cow_array_map()); | 1029 DCHECK(array->map() != fixed_cow_array_map()); |
1020 Object** dst_objects = array->data_start() + dst_index; | 1030 Object** dst_objects = array->data_start() + dst_index; |
1021 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); | 1031 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); |
(...skipping 3783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4805 heap_state.used_new_space_size = new_space_.Size(); | 4815 heap_state.used_new_space_size = new_space_.Size(); |
4806 heap_state.new_space_capacity = new_space_.Capacity(); | 4816 heap_state.new_space_capacity = new_space_.Capacity(); |
4807 heap_state.new_space_allocation_throughput_in_bytes_per_ms = | 4817 heap_state.new_space_allocation_throughput_in_bytes_per_ms = |
4808 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); | 4818 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); |
4809 return heap_state; | 4819 return heap_state; |
4810 } | 4820 } |
4811 | 4821 |
4812 | 4822 |
4813 double Heap::AdvanceIncrementalMarking( | 4823 double Heap::AdvanceIncrementalMarking( |
4814 intptr_t step_size_in_bytes, double deadline_in_ms, | 4824 intptr_t step_size_in_bytes, double deadline_in_ms, |
4815 IncrementalMarking::ForceCompletionAction completion) { | 4825 IncrementalMarking::StepActions step_actions) { |
4816 DCHECK(!incremental_marking()->IsStopped()); | 4826 DCHECK(!incremental_marking()->IsStopped()); |
| 4827 |
| 4828 if (step_size_in_bytes == 0) { |
| 4829 step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( |
| 4830 static_cast<size_t>(GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs), |
| 4831 static_cast<size_t>( |
| 4832 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond())); |
| 4833 } |
| 4834 |
4817 double remaining_time_in_ms = 0.0; | 4835 double remaining_time_in_ms = 0.0; |
4818 do { | 4836 do { |
4819 incremental_marking()->Step(step_size_in_bytes, | 4837 incremental_marking()->Step( |
4820 IncrementalMarking::NO_GC_VIA_STACK_GUARD, | 4838 step_size_in_bytes, step_actions.completion_action, |
4821 IncrementalMarking::FORCE_MARKING, completion); | 4839 step_actions.force_marking, step_actions.force_completion); |
4822 remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); | 4840 remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); |
4823 } while (remaining_time_in_ms >= | 4841 } while (remaining_time_in_ms >= |
4824 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && | 4842 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && |
4825 !incremental_marking()->IsComplete() && | 4843 !incremental_marking()->IsComplete() && |
4826 !mark_compact_collector_.marking_deque()->IsEmpty()); | 4844 !mark_compact_collector_.marking_deque()->IsEmpty()); |
4827 return remaining_time_in_ms; | 4845 return remaining_time_in_ms; |
4828 } | 4846 } |
4829 | 4847 |
4830 | 4848 |
4831 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4849 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
4832 GCIdleTimeHandler::HeapState heap_state, | 4850 GCIdleTimeHandler::HeapState heap_state, |
4833 double deadline_in_ms) { | 4851 double deadline_in_ms) { |
4834 bool result = false; | 4852 bool result = false; |
4835 switch (action.type) { | 4853 switch (action.type) { |
4836 case DONE: | 4854 case DONE: |
4837 result = true; | 4855 result = true; |
4838 break; | 4856 break; |
4839 case DO_INCREMENTAL_MARKING: { | 4857 case DO_INCREMENTAL_MARKING: { |
4840 const double remaining_idle_time_in_ms = AdvanceIncrementalMarking( | 4858 const double remaining_idle_time_in_ms = |
4841 action.parameter, deadline_in_ms, | 4859 AdvanceIncrementalMarking(action.parameter, deadline_in_ms, |
4842 IncrementalMarking::DO_NOT_FORCE_COMPLETION); | 4860 IncrementalMarking::NoForcedStepActions()); |
4843 if (remaining_idle_time_in_ms > 0.0) { | 4861 if (remaining_idle_time_in_ms > 0.0) { |
4844 action.additional_work = TryFinalizeIdleIncrementalMarking( | 4862 action.additional_work = TryFinalizeIdleIncrementalMarking( |
4845 remaining_idle_time_in_ms, heap_state.size_of_objects, | 4863 remaining_idle_time_in_ms, heap_state.size_of_objects, |
4846 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); | 4864 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); |
4847 } | 4865 } |
4848 break; | 4866 break; |
4849 } | 4867 } |
4850 case DO_FULL_GC: { | 4868 case DO_FULL_GC: { |
4851 DCHECK(contexts_disposed_ > 0); | 4869 DCHECK(contexts_disposed_ > 0); |
4852 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 4870 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
(...skipping 2028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6881 *object_type = "CODE_TYPE"; \ | 6899 *object_type = "CODE_TYPE"; \ |
6882 *object_sub_type = "CODE_AGE/" #name; \ | 6900 *object_sub_type = "CODE_AGE/" #name; \ |
6883 return true; | 6901 return true; |
6884 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6902 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6885 #undef COMPARE_AND_RETURN_NAME | 6903 #undef COMPARE_AND_RETURN_NAME |
6886 } | 6904 } |
6887 return false; | 6905 return false; |
6888 } | 6906 } |
6889 } // namespace internal | 6907 } // namespace internal |
6890 } // namespace v8 | 6908 } // namespace v8 |
OLD | NEW |