LCOV - code coverage report
Current view: top level - src/heap - gc-idle-time-handler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 19 31 61.3 %
Date: 2019-04-19 Functions: 5 9 55.6 %

          Line data    Source code
       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             : #include "src/heap/gc-idle-time-handler.h"
       6             : 
       7             : #include "src/flags.h"
       8             : #include "src/heap/gc-tracer.h"
       9             : #include "src/utils.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : const double GCIdleTimeHandler::kConservativeTimeRatio = 0.9;
      15             : const size_t GCIdleTimeHandler::kMaxFinalIncrementalMarkCompactTimeInMs = 1000;
      16             : const double GCIdleTimeHandler::kHighContextDisposalRate = 100;
      17             : const size_t GCIdleTimeHandler::kMinTimeForOverApproximatingWeakClosureInMs = 1;
      18             : 
      19             : 
      20           0 : void GCIdleTimeHeapState::Print() {
      21           0 :   PrintF("contexts_disposed=%d ", contexts_disposed);
      22           0 :   PrintF("contexts_disposal_rate=%f ", contexts_disposal_rate);
      23           0 :   PrintF("size_of_objects=%" PRIuS " ", size_of_objects);
      24           0 :   PrintF("incremental_marking_stopped=%d ", incremental_marking_stopped);
      25           0 : }
      26             : 
      27     1098085 : size_t GCIdleTimeHandler::EstimateMarkingStepSize(
      28             :     double idle_time_in_ms, double marking_speed_in_bytes_per_ms) {
      29             :   DCHECK_LT(0, idle_time_in_ms);
      30             : 
      31     1098085 :   if (marking_speed_in_bytes_per_ms == 0) {
      32             :     marking_speed_in_bytes_per_ms = kInitialConservativeMarkingSpeed;
      33             :   }
      34             : 
      35     1098085 :   double marking_step_size = marking_speed_in_bytes_per_ms * idle_time_in_ms;
      36     1098085 :   if (marking_step_size >= kMaximumMarkingStepSize) {
      37             :     return kMaximumMarkingStepSize;
      38             :   }
      39     1093604 :   return static_cast<size_t>(marking_step_size * kConservativeTimeRatio);
      40             : }
      41             : 
      42           0 : double GCIdleTimeHandler::EstimateFinalIncrementalMarkCompactTime(
      43             :     size_t size_of_objects,
      44             :     double final_incremental_mark_compact_speed_in_bytes_per_ms) {
      45           2 :   if (final_incremental_mark_compact_speed_in_bytes_per_ms == 0) {
      46             :     final_incremental_mark_compact_speed_in_bytes_per_ms =
      47             :         kInitialConservativeFinalIncrementalMarkCompactSpeed;
      48             :   }
      49             :   double result =
      50           2 :       size_of_objects / final_incremental_mark_compact_speed_in_bytes_per_ms;
      51           0 :   return Min<double>(result, kMaxFinalIncrementalMarkCompactTimeInMs);
      52             : }
      53             : 
      54           0 : bool GCIdleTimeHandler::ShouldDoContextDisposalMarkCompact(
      55             :     int contexts_disposed, double contexts_disposal_rate,
      56             :     size_t size_of_objects) {
      57         268 :   return contexts_disposed > 0 && contexts_disposal_rate > 0 &&
      58         455 :          contexts_disposal_rate < kHighContextDisposalRate &&
      59           0 :          size_of_objects <= kMaxHeapSizeForContextDisposalMarkCompact;
      60             : }
      61             : 
      62           2 : bool GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
      63             :     double idle_time_in_ms, size_t size_of_objects,
      64             :     double final_incremental_mark_compact_speed_in_bytes_per_ms) {
      65             :   return idle_time_in_ms >=
      66             :          EstimateFinalIncrementalMarkCompactTime(
      67             :              size_of_objects,
      68           2 :              final_incremental_mark_compact_speed_in_bytes_per_ms);
      69             : }
      70             : 
      71           0 : bool GCIdleTimeHandler::ShouldDoOverApproximateWeakClosure(
      72             :     double idle_time_in_ms) {
      73             :   // TODO(jochen): Estimate the time it will take to build the object groups.
      74           0 :   return idle_time_in_ms >= kMinTimeForOverApproximatingWeakClosureInMs;
      75             : }
      76             : 
      77             : 
      78             : // The following logic is implemented by the controller:
      79             : // (1) If we don't have any idle time, do nothing, unless a context was
      80             : // disposed, incremental marking is stopped, and the heap is small. Then do
      81             : // a full GC.
      82             : // (2) If the context disposal rate is high and we cannot perform a full GC,
      83             : // we do nothing until the context disposal rate becomes lower.
      84             : // (3) If the new space is almost full and we can afford a scavenge or if the
      85             : // next scavenge will very likely take long, then a scavenge is performed.
      86             : // (4) If sweeping is in progress and we received a large enough idle time
      87             : // request, we finalize sweeping here.
      88             : // (5) If incremental marking is in progress, we perform a marking step. Note,
      89             : // that this currently may trigger a full garbage collection.
      90         491 : GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms,
      91             :                                             GCIdleTimeHeapState heap_state) {
      92         491 :   if (static_cast<int>(idle_time_in_ms) <= 0) {
      93         301 :     if (heap_state.incremental_marking_stopped) {
      94         536 :       if (ShouldDoContextDisposalMarkCompact(heap_state.contexts_disposed,
      95             :                                              heap_state.contexts_disposal_rate,
      96             :                                              heap_state.size_of_objects)) {
      97             :         return GCIdleTimeAction::kFullGC;
      98             :       }
      99             :     }
     100             :     return GCIdleTimeAction::kDone;
     101             :   }
     102             : 
     103         190 :   if (FLAG_incremental_marking && !heap_state.incremental_marking_stopped) {
     104             :     return GCIdleTimeAction::kIncrementalStep;
     105             :   }
     106             : 
     107         136 :   return GCIdleTimeAction::kDone;
     108             : }
     109             : 
     110          11 : bool GCIdleTimeHandler::Enabled() { return FLAG_incremental_marking; }
     111             : 
     112             : }  // namespace internal
     113      122036 : }  // namespace v8

Generated by: LCOV version 1.10