blob: 39dea7e1ff942c7d4e9c78004c6f184a2b3f9b3f [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_HEAP_GC_IDLE_TIME_HANDLER_H_
6#define V8_HEAP_GC_IDLE_TIME_HANDLER_H_
7
8#include "src/globals.h"
9
10namespace v8 {
11namespace internal {
12
13enum GCIdleTimeActionType {
14 DONE,
15 DO_NOTHING,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000016 DO_INCREMENTAL_STEP,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000017 DO_FULL_GC,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018};
19
20
21class GCIdleTimeAction {
22 public:
23 static GCIdleTimeAction Done() {
24 GCIdleTimeAction result;
25 result.type = DONE;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040026 result.additional_work = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027 return result;
28 }
29
30 static GCIdleTimeAction Nothing() {
31 GCIdleTimeAction result;
32 result.type = DO_NOTHING;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040033 result.additional_work = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034 return result;
35 }
36
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 static GCIdleTimeAction IncrementalStep() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038 GCIdleTimeAction result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039 result.type = DO_INCREMENTAL_STEP;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040040 result.additional_work = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 return result;
42 }
43
44 static GCIdleTimeAction FullGC() {
45 GCIdleTimeAction result;
46 result.type = DO_FULL_GC;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040047 result.additional_work = false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048 return result;
49 }
50
51 void Print();
52
53 GCIdleTimeActionType type;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040054 bool additional_work;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055};
56
57
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058class GCIdleTimeHeapState {
59 public:
60 void Print();
61
62 int contexts_disposed;
63 double contexts_disposal_rate;
64 size_t size_of_objects;
65 bool incremental_marking_stopped;
66};
67
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068
69// The idle time handler makes decisions about which garbage collection
70// operations are executing during IdleNotification.
71class GCIdleTimeHandler {
72 public:
73 // If we haven't recorded any incremental marking events yet, we carefully
74 // mark with a conservative lower bound for the marking speed.
75 static const size_t kInitialConservativeMarkingSpeed = 100 * KB;
76
77 // Maximum marking step size returned by EstimateMarkingStepSize.
78 static const size_t kMaximumMarkingStepSize = 700 * MB;
79
80 // We have to make sure that we finish the IdleNotification before
81 // idle_time_in_ms. Hence, we conservatively prune our workload estimate.
82 static const double kConservativeTimeRatio;
83
84 // If we haven't recorded any mark-compact events yet, we use
85 // conservative lower bound for the mark-compact speed.
86 static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
87
Emily Bernierd0a1eb72015-03-24 16:35:39 -040088 // If we haven't recorded any final incremental mark-compact events yet, we
89 // use conservative lower bound for the mark-compact speed.
90 static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
91 2 * MB;
92
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093 // Maximum final incremental mark-compact time returned by
94 // EstimateFinalIncrementalMarkCompactTime.
95 static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
96
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097 // This is the maximum scheduled idle time. Note that it can be more than
98 // 16.66 ms when there is currently no rendering going on.
99 static const size_t kMaxScheduledIdleTime = 50;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 // The maximum idle time when frames are rendered is 16.66ms.
102 static const size_t kMaxFrameRenderingIdleTime = 17;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000103
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104 static const int kMinBackgroundIdleTime = 900;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 // An allocation throughput below kLowAllocationThroughput bytes/ms is
107 // considered low
108 static const size_t kLowAllocationThroughput = 1000;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110 // If contexts are disposed at a higher rate a full gc is triggered.
111 static const double kHighContextDisposalRate;
112
113 // Incremental marking step time.
114 static const size_t kIncrementalMarkingStepTimeInMs = 1;
115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116 static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400117
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 // Number of times we will return a Nothing action in the current mode
119 // despite having idle time available before we returning a Done action to
120 // ensure we don't keep scheduling idle tasks and making no progress.
121 static const int kMaxNoProgressIdleTimes = 10;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000122
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 GCIdleTimeHandler() : idle_times_which_made_no_progress_(0) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125 GCIdleTimeAction Compute(double idle_time_in_ms,
126 GCIdleTimeHeapState heap_state);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000128 void ResetNoProgressCounter() { idle_times_which_made_no_progress_ = 0; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129
Ben Murdochda12d292016-06-02 14:46:10 +0100130 static size_t EstimateMarkingStepSize(double idle_time_in_ms,
131 double marking_speed_in_bytes_per_ms);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132
Ben Murdochda12d292016-06-02 14:46:10 +0100133 static double EstimateFinalIncrementalMarkCompactTime(
134 size_t size_of_objects, double mark_compact_speed_in_bytes_per_ms);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400135
136 static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
137 double contexts_disposal_rate);
138
139 static bool ShouldDoFinalIncrementalMarkCompact(
Ben Murdochda12d292016-06-02 14:46:10 +0100140 double idle_time_in_ms, size_t size_of_objects,
141 double final_incremental_mark_compact_speed_in_bytes_per_ms);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400142
Ben Murdochda12d292016-06-02 14:46:10 +0100143 static bool ShouldDoOverApproximateWeakClosure(double idle_time_in_ms);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000144
145 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000146 GCIdleTimeAction NothingOrDone(double idle_time_in_ms);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000148 // Idle notifications with no progress.
149 int idle_times_which_made_no_progress_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000150
151 DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
152};
153
154} // namespace internal
155} // namespace v8
156
157#endif // V8_HEAP_GC_IDLE_TIME_HANDLER_H_