| 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()); | |
| 774 return; | 773 return; |
| 775 } | 774 } |
| 776 DCHECK(FLAG_overapproximate_weak_closure); | 775 DCHECK(FLAG_overapproximate_weak_closure); |
| 777 if (!incremental_marking()->weak_closure_was_overapproximated()) { | 776 if (!incremental_marking()->weak_closure_was_overapproximated()) { |
| 778 OverApproximateWeakClosure("GC interrupt"); | 777 OverApproximateWeakClosure("GC interrupt"); |
| 779 } | 778 } |
| 780 } | 779 } |
| 781 | 780 |
| 782 | 781 |
| 783 void Heap::OverApproximateWeakClosure(const char* gc_reason) { | 782 void Heap::OverApproximateWeakClosure(const char* gc_reason) { |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 if (collector == MARK_COMPACTOR && | 972 if (collector == MARK_COMPACTOR && |
| 974 (gc_callback_flags & kGCCallbackFlagForced) != 0) { | 973 (gc_callback_flags & kGCCallbackFlagForced) != 0) { |
| 975 isolate()->CountUsage(v8::Isolate::kForcedGC); | 974 isolate()->CountUsage(v8::Isolate::kForcedGC); |
| 976 } | 975 } |
| 977 | 976 |
| 978 // Start incremental marking for the next cycle. The heap snapshot | 977 // Start incremental marking for the next cycle. The heap snapshot |
| 979 // generator needs incremental marking to stay off after it aborted. | 978 // generator needs incremental marking to stay off after it aborted. |
| 980 if (!mark_compact_collector()->abort_incremental_marking() && | 979 if (!mark_compact_collector()->abort_incremental_marking() && |
| 981 incremental_marking()->IsStopped() && | 980 incremental_marking()->IsStopped() && |
| 982 incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { | 981 incremental_marking()->ShouldActivateEvenWithoutIdleNotification()) { |
| 983 incremental_marking()->Start(kNoGCFlags, kNoGCCallbackFlags, "GC epilogue"); | 982 incremental_marking()->Start(kNoGCFlags); |
| 984 } | 983 } |
| 985 | 984 |
| 986 return next_gc_likely_to_collect_more; | 985 return next_gc_likely_to_collect_more; |
| 987 } | 986 } |
| 988 | 987 |
| 989 | 988 |
| 990 int Heap::NotifyContextDisposed(bool dependant_context) { | 989 int Heap::NotifyContextDisposed(bool dependant_context) { |
| 991 if (!dependant_context) { | 990 if (!dependant_context) { |
| 992 tracer()->ResetSurvivalEvents(); | 991 tracer()->ResetSurvivalEvents(); |
| 993 old_generation_size_configured_ = false; | 992 old_generation_size_configured_ = false; |
| 994 } | 993 } |
| 995 if (isolate()->concurrent_recompilation_enabled()) { | 994 if (isolate()->concurrent_recompilation_enabled()) { |
| 996 // Flush the queued recompilation tasks. | 995 // Flush the queued recompilation tasks. |
| 997 isolate()->optimizing_compile_dispatcher()->Flush(); | 996 isolate()->optimizing_compile_dispatcher()->Flush(); |
| 998 } | 997 } |
| 999 AgeInlineCaches(); | 998 AgeInlineCaches(); |
| 1000 set_retained_maps(ArrayList::cast(empty_fixed_array())); | 999 set_retained_maps(ArrayList::cast(empty_fixed_array())); |
| 1001 tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis()); | 1000 tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis()); |
| 1002 MemoryReducer::Event event; | 1001 MemoryReducer::Event event; |
| 1003 event.type = MemoryReducer::kContextDisposed; | 1002 event.type = MemoryReducer::kContextDisposed; |
| 1004 event.time_ms = MonotonicallyIncreasingTimeInMs(); | 1003 event.time_ms = MonotonicallyIncreasingTimeInMs(); |
| 1005 memory_reducer_.NotifyContextDisposed(event); | 1004 memory_reducer_.NotifyContextDisposed(event); |
| 1006 return ++contexts_disposed_; | 1005 return ++contexts_disposed_; |
| 1007 } | 1006 } |
| 1008 | 1007 |
| 1009 | 1008 |
| 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 | |
| 1018 void Heap::StartIdleIncrementalMarking() { | 1009 void Heap::StartIdleIncrementalMarking() { |
| 1019 gc_idle_time_handler_.ResetNoProgressCounter(); | 1010 gc_idle_time_handler_.ResetNoProgressCounter(); |
| 1020 StartIncrementalMarking(kReduceMemoryFootprintMask, kNoGCCallbackFlags, | 1011 incremental_marking()->Start(kReduceMemoryFootprintMask); |
| 1021 "idle"); | |
| 1022 } | 1012 } |
| 1023 | 1013 |
| 1024 | 1014 |
| 1025 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, | 1015 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, |
| 1026 int len) { | 1016 int len) { |
| 1027 if (len == 0) return; | 1017 if (len == 0) return; |
| 1028 | 1018 |
| 1029 DCHECK(array->map() != fixed_cow_array_map()); | 1019 DCHECK(array->map() != fixed_cow_array_map()); |
| 1030 Object** dst_objects = array->data_start() + dst_index; | 1020 Object** dst_objects = array->data_start() + dst_index; |
| 1031 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); | 1021 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); |
| (...skipping 3761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4793 heap_state.used_new_space_size = new_space_.Size(); | 4783 heap_state.used_new_space_size = new_space_.Size(); |
| 4794 heap_state.new_space_capacity = new_space_.Capacity(); | 4784 heap_state.new_space_capacity = new_space_.Capacity(); |
| 4795 heap_state.new_space_allocation_throughput_in_bytes_per_ms = | 4785 heap_state.new_space_allocation_throughput_in_bytes_per_ms = |
| 4796 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); | 4786 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); |
| 4797 return heap_state; | 4787 return heap_state; |
| 4798 } | 4788 } |
| 4799 | 4789 |
| 4800 | 4790 |
| 4801 double Heap::AdvanceIncrementalMarking( | 4791 double Heap::AdvanceIncrementalMarking( |
| 4802 intptr_t step_size_in_bytes, double deadline_in_ms, | 4792 intptr_t step_size_in_bytes, double deadline_in_ms, |
| 4803 IncrementalMarking::StepActions step_actions) { | 4793 IncrementalMarking::ForceCompletionAction completion) { |
| 4804 DCHECK(!incremental_marking()->IsStopped()); | 4794 DCHECK(!incremental_marking()->IsStopped()); |
| 4805 | |
| 4806 if (step_size_in_bytes == 0) { | |
| 4807 step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( | |
| 4808 static_cast<size_t>(GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs), | |
| 4809 static_cast<size_t>( | |
| 4810 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond())); | |
| 4811 } | |
| 4812 | |
| 4813 double remaining_time_in_ms = 0.0; | 4795 double remaining_time_in_ms = 0.0; |
| 4814 do { | 4796 do { |
| 4815 incremental_marking()->Step( | 4797 incremental_marking()->Step(step_size_in_bytes, |
| 4816 step_size_in_bytes, step_actions.completion_action, | 4798 IncrementalMarking::NO_GC_VIA_STACK_GUARD, |
| 4817 step_actions.force_marking, step_actions.force_completion); | 4799 IncrementalMarking::FORCE_MARKING, completion); |
| 4818 remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); | 4800 remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); |
| 4819 } while (remaining_time_in_ms >= | 4801 } while (remaining_time_in_ms >= |
| 4820 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && | 4802 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && |
| 4821 !incremental_marking()->IsComplete() && | 4803 !incremental_marking()->IsComplete() && |
| 4822 !mark_compact_collector_.marking_deque()->IsEmpty()); | 4804 !mark_compact_collector_.marking_deque()->IsEmpty()); |
| 4823 return remaining_time_in_ms; | 4805 return remaining_time_in_ms; |
| 4824 } | 4806 } |
| 4825 | 4807 |
| 4826 | 4808 |
| 4827 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4809 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
| 4828 GCIdleTimeHandler::HeapState heap_state, | 4810 GCIdleTimeHandler::HeapState heap_state, |
| 4829 double deadline_in_ms) { | 4811 double deadline_in_ms) { |
| 4830 bool result = false; | 4812 bool result = false; |
| 4831 switch (action.type) { | 4813 switch (action.type) { |
| 4832 case DONE: | 4814 case DONE: |
| 4833 result = true; | 4815 result = true; |
| 4834 break; | 4816 break; |
| 4835 case DO_INCREMENTAL_MARKING: { | 4817 case DO_INCREMENTAL_MARKING: { |
| 4836 const double remaining_idle_time_in_ms = | 4818 const double remaining_idle_time_in_ms = AdvanceIncrementalMarking( |
| 4837 AdvanceIncrementalMarking(action.parameter, deadline_in_ms, | 4819 action.parameter, deadline_in_ms, |
| 4838 IncrementalMarking::NoForcedStepActions()); | 4820 IncrementalMarking::DO_NOT_FORCE_COMPLETION); |
| 4839 if (remaining_idle_time_in_ms > 0.0) { | 4821 if (remaining_idle_time_in_ms > 0.0) { |
| 4840 action.additional_work = TryFinalizeIdleIncrementalMarking( | 4822 action.additional_work = TryFinalizeIdleIncrementalMarking( |
| 4841 remaining_idle_time_in_ms, heap_state.size_of_objects, | 4823 remaining_idle_time_in_ms, heap_state.size_of_objects, |
| 4842 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); | 4824 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); |
| 4843 } | 4825 } |
| 4844 break; | 4826 break; |
| 4845 } | 4827 } |
| 4846 case DO_FULL_GC: { | 4828 case DO_FULL_GC: { |
| 4847 DCHECK(contexts_disposed_ > 0); | 4829 DCHECK(contexts_disposed_ > 0); |
| 4848 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 4830 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| (...skipping 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6880 *object_type = "CODE_TYPE"; \ | 6862 *object_type = "CODE_TYPE"; \ |
| 6881 *object_sub_type = "CODE_AGE/" #name; \ | 6863 *object_sub_type = "CODE_AGE/" #name; \ |
| 6882 return true; | 6864 return true; |
| 6883 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6865 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
| 6884 #undef COMPARE_AND_RETURN_NAME | 6866 #undef COMPARE_AND_RETURN_NAME |
| 6885 } | 6867 } |
| 6886 return false; | 6868 return false; |
| 6887 } | 6869 } |
| 6888 } // namespace internal | 6870 } // namespace internal |
| 6889 } // namespace v8 | 6871 } // namespace v8 |
| OLD | NEW |