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