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 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 mark-compact time returned by EstimateMarkCompactTime.
     94   static const size_t kMaxMarkCompactTimeInMs;
     95 
     96   // Maximum final incremental mark-compact time returned by
     97   // EstimateFinalIncrementalMarkCompactTime.
     98   static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
     99 
    100   // This is the maximum scheduled idle time. Note that it can be more than
    101   // 16.66 ms when there is currently no rendering going on.
    102   static const size_t kMaxScheduledIdleTime = 50;
    103 
    104   // The maximum idle time when frames are rendered is 16.66ms.
    105   static const size_t kMaxFrameRenderingIdleTime = 17;
    106 
    107   static const int kMinBackgroundIdleTime = 900;
    108 
    109   // An allocation throughput below kLowAllocationThroughput bytes/ms is
    110   // considered low
    111   static const size_t kLowAllocationThroughput = 1000;
    112 
    113   // If contexts are disposed at a higher rate a full gc is triggered.
    114   static const double kHighContextDisposalRate;
    115 
    116   // Incremental marking step time.
    117   static const size_t kIncrementalMarkingStepTimeInMs = 1;
    118 
    119   static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
    120 
    121   // Number of times we will return a Nothing action in the current mode
    122   // despite having idle time available before we returning a Done action to
    123   // ensure we don't keep scheduling idle tasks and making no progress.
    124   static const int kMaxNoProgressIdleTimes = 10;
    125 
    126   GCIdleTimeHandler() : idle_times_which_made_no_progress_(0) {}
    127 
    128   GCIdleTimeAction Compute(double idle_time_in_ms,
    129                            GCIdleTimeHeapState heap_state);
    130 
    131   void ResetNoProgressCounter() { idle_times_which_made_no_progress_ = 0; }
    132 
    133   static size_t EstimateMarkingStepSize(size_t idle_time_in_ms,
    134                                         size_t marking_speed_in_bytes_per_ms);
    135 
    136   static size_t EstimateMarkCompactTime(
    137       size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
    138 
    139   static size_t EstimateFinalIncrementalMarkCompactTime(
    140       size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
    141 
    142   static bool ShouldDoMarkCompact(size_t idle_time_in_ms,
    143                                   size_t size_of_objects,
    144                                   size_t mark_compact_speed_in_bytes_per_ms);
    145 
    146   static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
    147                                                  double contexts_disposal_rate);
    148 
    149   static bool ShouldDoFinalIncrementalMarkCompact(
    150       size_t idle_time_in_ms, size_t size_of_objects,
    151       size_t final_incremental_mark_compact_speed_in_bytes_per_ms);
    152 
    153   static bool ShouldDoOverApproximateWeakClosure(size_t idle_time_in_ms);
    154 
    155  private:
    156   GCIdleTimeAction NothingOrDone(double idle_time_in_ms);
    157 
    158   // Idle notifications with no progress.
    159   int idle_times_which_made_no_progress_;
    160 
    161   DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
    162 };
    163 
    164 }  // namespace internal
    165 }  // namespace v8
    166 
    167 #endif  // V8_HEAP_GC_IDLE_TIME_HANDLER_H_
    168