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