1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_HEAP_GC_IDLE_TIME_HANDLER_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_HEAP_GC_IDLE_TIME_HANDLER_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/globals.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum GCIdleTimeActionType {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DONE,
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DO_NOTHING,
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DO_INCREMENTAL_STEP,
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DO_FULL_GC,
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass GCIdleTimeAction {
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static GCIdleTimeAction Done() {
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction result;
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.type = DONE;
26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result.additional_work = false;
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static GCIdleTimeAction Nothing() {
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction result;
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.type = DO_NOTHING;
33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result.additional_work = false;
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static GCIdleTimeAction IncrementalStep() {
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction result;
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result.type = DO_INCREMENTAL_STEP;
40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result.additional_work = false;
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static GCIdleTimeAction FullGC() {
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GCIdleTimeAction result;
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result.type = DO_FULL_GC;
47958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result.additional_work = false;
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result;
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Print();
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  GCIdleTimeActionType type;
54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool additional_work;
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass GCIdleTimeHeapState {
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Print();
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int contexts_disposed;
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  double contexts_disposal_rate;
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t size_of_objects;
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool incremental_marking_stopped;
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The idle time handler makes decisions about which garbage collection
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// operations are executing during IdleNotification.
71c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE GCIdleTimeHandler {
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If we haven't recorded any incremental marking events yet, we carefully
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // mark with a conservative lower bound for the marking speed.
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kInitialConservativeMarkingSpeed = 100 * KB;
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Maximum marking step size returned by EstimateMarkingStepSize.
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kMaximumMarkingStepSize = 700 * MB;
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We have to make sure that we finish the IdleNotification before
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // idle_time_in_ms. Hence, we conservatively prune our workload estimate.
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const double kConservativeTimeRatio;
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If we haven't recorded any mark-compact events yet, we use
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // conservative lower bound for the mark-compact speed.
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // If we haven't recorded any final incremental mark-compact events yet, we
89958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // use conservative lower bound for the mark-compact speed.
90958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
91958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      2 * MB;
92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
93958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Maximum final incremental mark-compact time returned by
94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // EstimateFinalIncrementalMarkCompactTime.
95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This is the maximum scheduled idle time. Note that it can be more than
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // 16.66 ms when there is currently no rendering going on.
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const size_t kMaxScheduledIdleTime = 50;
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // The maximum idle time when frames are rendered is 16.66ms.
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const size_t kMaxFrameRenderingIdleTime = 17;
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kMinBackgroundIdleTime = 900;
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // An allocation throughput below kLowAllocationThroughput bytes/ms is
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // considered low
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const size_t kLowAllocationThroughput = 1000;
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // If contexts are disposed at a higher rate a full gc is triggered.
111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static const double kHighContextDisposalRate;
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Incremental marking step time.
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static const size_t kIncrementalMarkingStepTimeInMs = 1;
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Number of times we will return a Nothing action in the current mode
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // despite having idle time available before we returning a Done action to
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ensure we don't keep scheduling idle tasks and making no progress.
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static const int kMaxNoProgressIdleTimes = 10;
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeHandler() : idle_times_which_made_no_progress_(0) {}
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeAction Compute(double idle_time_in_ms,
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                           GCIdleTimeHeapState heap_state);
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
12862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  bool Enabled();
12962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void ResetNoProgressCounter() { idle_times_which_made_no_progress_ = 0; }
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static size_t EstimateMarkingStepSize(double idle_time_in_ms,
1333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                        double marking_speed_in_bytes_per_ms);
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static double EstimateFinalIncrementalMarkCompactTime(
1363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      size_t size_of_objects, double mark_compact_speed_in_bytes_per_ms);
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                 double contexts_disposal_rate);
140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static bool ShouldDoFinalIncrementalMarkCompact(
1423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      double idle_time_in_ms, size_t size_of_objects,
1433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      double final_incremental_mark_compact_speed_in_bytes_per_ms);
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  static bool ShouldDoOverApproximateWeakClosure(double idle_time_in_ms);
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  GCIdleTimeAction NothingOrDone(double idle_time_in_ms);
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Idle notifications with no progress.
151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int idle_times_which_made_no_progress_;
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace internal
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_HEAP_GC_IDLE_TIME_HANDLER_H_
160