Home | History | Annotate | Download | only in heap
      1 // Copyright 2017 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/stress-scavenge-observer.h"
      6 
      7 #include "src/base/utils/random-number-generator.h"
      8 #include "src/heap/heap-inl.h"
      9 #include "src/heap/spaces.h"
     10 #include "src/isolate.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 
     15 // TODO(majeski): meaningful step_size
     16 StressScavengeObserver::StressScavengeObserver(Heap& heap)
     17     : AllocationObserver(64),
     18       heap_(heap),
     19       has_requested_gc_(false),
     20       max_new_space_size_reached_(0.0) {
     21   limit_percentage_ = NextLimit();
     22 
     23   if (FLAG_trace_stress_scavenge && !FLAG_fuzzer_gc_analysis) {
     24     heap_.isolate()->PrintWithTimestamp(
     25         "[StressScavenge] %d%% is the new limit\n", limit_percentage_);
     26   }
     27 }
     28 
     29 void StressScavengeObserver::Step(int bytes_allocated, Address soon_object,
     30                                   size_t size) {
     31   if (has_requested_gc_ || heap_.new_space()->Capacity() == 0) {
     32     return;
     33   }
     34 
     35   double current_percent =
     36       heap_.new_space()->Size() * 100.0 / heap_.new_space()->Capacity();
     37 
     38   if (FLAG_trace_stress_scavenge) {
     39     heap_.isolate()->PrintWithTimestamp(
     40         "[Scavenge] %.2lf%% of the new space capacity reached\n",
     41         current_percent);
     42   }
     43 
     44   if (FLAG_fuzzer_gc_analysis) {
     45     max_new_space_size_reached_ =
     46         std::max(max_new_space_size_reached_, current_percent);
     47     return;
     48   }
     49 
     50   if (static_cast<int>(current_percent) >= limit_percentage_) {
     51     if (FLAG_trace_stress_scavenge) {
     52       heap_.isolate()->PrintWithTimestamp("[Scavenge] GC requested\n");
     53     }
     54 
     55     has_requested_gc_ = true;
     56     heap_.isolate()->stack_guard()->RequestGC();
     57   }
     58 }
     59 
     60 bool StressScavengeObserver::HasRequestedGC() const {
     61   return has_requested_gc_;
     62 }
     63 
     64 void StressScavengeObserver::RequestedGCDone() {
     65   double current_percent =
     66       heap_.new_space()->Size() * 100.0 / heap_.new_space()->Capacity();
     67   limit_percentage_ = NextLimit(static_cast<int>(current_percent));
     68 
     69   if (FLAG_trace_stress_scavenge) {
     70     heap_.isolate()->PrintWithTimestamp(
     71         "[Scavenge] %.2lf%% of the new space capacity reached\n",
     72         current_percent);
     73     heap_.isolate()->PrintWithTimestamp("[Scavenge] %d%% is the new limit\n",
     74                                         limit_percentage_);
     75   }
     76 
     77   has_requested_gc_ = false;
     78 }
     79 
     80 double StressScavengeObserver::MaxNewSpaceSizeReached() const {
     81   return max_new_space_size_reached_;
     82 }
     83 
     84 int StressScavengeObserver::NextLimit(int min) {
     85   int max = FLAG_stress_scavenge;
     86   if (min >= max) {
     87     return max;
     88   }
     89 
     90   return min + heap_.isolate()->fuzzer_rng()->NextInt(max - min + 1);
     91 }
     92 
     93 }  // namespace internal
     94 }  // namespace v8
     95