Home | History | Annotate | Download | only in heap
      1 // 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 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 enum GCIdleTimeActionType {
     14   DONE,
     15   DO_NOTHING,
     16   DO_INCREMENTAL_STEP,
     17   DO_FULL_GC,
     18 };
     19 
     20 
     21 class GCIdleTimeAction {
     22  public:
     23   static GCIdleTimeAction Done() {
     24     GCIdleTimeAction result;
     25     result.type = DONE;
     26     result.additional_work = false;
     27     return result;
     28   }
     29 
     30   static GCIdleTimeAction Nothing() {
     31     GCIdleTimeAction result;
     32     result.type = DO_NOTHING;
     33     result.additional_work = false;
     34     return result;
     35   }
     36 
     37   static GCIdleTimeAction IncrementalStep() {
     38     GCIdleTimeAction result;
     39     result.type = DO_INCREMENTAL_STEP;
     40     result.additional_work = false;
     41     return result;
     42   }
     43 
     44   static GCIdleTimeAction FullGC() {
     45     GCIdleTimeAction result;
     46     result.type = DO_FULL_GC;
     47     result.additional_work = false;
     48     return result;
     49   }
     50 
     51   void Print();
     52 
     53   GCIdleTimeActionType type;
     54   bool additional_work;
     55 };
     56 
     57 
     58 class 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 
     68 
     69 // The idle time handler makes decisions about which garbage collection
     70 // operations are executing during IdleNotification.
     71 class V8_EXPORT_PRIVATE 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 
     88   // 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 
     93   // Maximum final incremental mark-compact time returned by
     94   // EstimateFinalIncrementalMarkCompactTime.
     95   static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
     96 
     97   // 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;
    100 
    101   // The maximum idle time when frames are rendered is 16.66ms.
    102   static const size_t kMaxFrameRenderingIdleTime = 17;
    103 
    104   static const int kMinBackgroundIdleTime = 900;
    105 
    106   // An allocation throughput below kLowAllocationThroughput bytes/ms is
    107   // considered low
    108   static const size_t kLowAllocationThroughput = 1000;
    109 
    110   // 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 
    116   static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
    117 
    118   // 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;
    122 
    123   GCIdleTimeHandler() : idle_times_which_made_no_progress_(0) {}
    124 
    125   GCIdleTimeAction Compute(double idle_time_in_ms,
    126                            GCIdleTimeHeapState heap_state);
    127 
    128   bool Enabled();
    129 
    130   void ResetNoProgressCounter() { idle_times_which_made_no_progress_ = 0; }
    131 
    132   static size_t EstimateMarkingStepSize(double idle_time_in_ms,
    133                                         double marking_speed_in_bytes_per_ms);
    134 
    135   static double EstimateFinalIncrementalMarkCompactTime(
    136       size_t size_of_objects, double mark_compact_speed_in_bytes_per_ms);
    137 
    138   static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
    139                                                  double contexts_disposal_rate);
    140 
    141   static bool ShouldDoFinalIncrementalMarkCompact(
    142       double idle_time_in_ms, size_t size_of_objects,
    143       double final_incremental_mark_compact_speed_in_bytes_per_ms);
    144 
    145   static bool ShouldDoOverApproximateWeakClosure(double idle_time_in_ms);
    146 
    147  private:
    148   GCIdleTimeAction NothingOrDone(double idle_time_in_ms);
    149 
    150   // Idle notifications with no progress.
    151   int idle_times_which_made_no_progress_;
    152 
    153   DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
    154 };
    155 
    156 }  // namespace internal
    157 }  // namespace v8
    158 
    159 #endif  // V8_HEAP_GC_IDLE_TIME_HANDLER_H_
    160