11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "src/heap/stress-scavenge-observer.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/base/utils/random-number-generator.h"
81cb0ef41Sopenharmony_ci#include "src/execution/isolate.h"
91cb0ef41Sopenharmony_ci#include "src/heap/heap-inl.h"
101cb0ef41Sopenharmony_ci#include "src/heap/spaces.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_cinamespace v8 {
131cb0ef41Sopenharmony_cinamespace internal {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// TODO(majeski): meaningful step_size
161cb0ef41Sopenharmony_ciStressScavengeObserver::StressScavengeObserver(Heap* heap)
171cb0ef41Sopenharmony_ci    : AllocationObserver(64),
181cb0ef41Sopenharmony_ci      heap_(heap),
191cb0ef41Sopenharmony_ci      has_requested_gc_(false),
201cb0ef41Sopenharmony_ci      max_new_space_size_reached_(0.0) {
211cb0ef41Sopenharmony_ci  limit_percentage_ = NextLimit();
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci  if (FLAG_trace_stress_scavenge && !FLAG_fuzzer_gc_analysis) {
241cb0ef41Sopenharmony_ci    heap_->isolate()->PrintWithTimestamp(
251cb0ef41Sopenharmony_ci        "[StressScavenge] %d%% is the new limit\n", limit_percentage_);
261cb0ef41Sopenharmony_ci  }
271cb0ef41Sopenharmony_ci}
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_civoid StressScavengeObserver::Step(int bytes_allocated, Address soon_object,
301cb0ef41Sopenharmony_ci                                  size_t size) {
311cb0ef41Sopenharmony_ci  if (has_requested_gc_ || heap_->new_space()->Capacity() == 0) {
321cb0ef41Sopenharmony_ci    return;
331cb0ef41Sopenharmony_ci  }
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  double current_percent =
361cb0ef41Sopenharmony_ci      heap_->new_space()->Size() * 100.0 / heap_->new_space()->Capacity();
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  if (FLAG_trace_stress_scavenge) {
391cb0ef41Sopenharmony_ci    heap_->isolate()->PrintWithTimestamp(
401cb0ef41Sopenharmony_ci        "[Scavenge] %.2lf%% of the new space capacity reached\n",
411cb0ef41Sopenharmony_ci        current_percent);
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  if (FLAG_fuzzer_gc_analysis) {
451cb0ef41Sopenharmony_ci    max_new_space_size_reached_ =
461cb0ef41Sopenharmony_ci        std::max(max_new_space_size_reached_, current_percent);
471cb0ef41Sopenharmony_ci    return;
481cb0ef41Sopenharmony_ci  }
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  if (static_cast<int>(current_percent) >= limit_percentage_) {
511cb0ef41Sopenharmony_ci    if (FLAG_trace_stress_scavenge) {
521cb0ef41Sopenharmony_ci      heap_->isolate()->PrintWithTimestamp("[Scavenge] GC requested\n");
531cb0ef41Sopenharmony_ci    }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci    has_requested_gc_ = true;
561cb0ef41Sopenharmony_ci    heap_->isolate()->stack_guard()->RequestGC();
571cb0ef41Sopenharmony_ci  }
581cb0ef41Sopenharmony_ci}
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_cibool StressScavengeObserver::HasRequestedGC() const {
611cb0ef41Sopenharmony_ci  return has_requested_gc_;
621cb0ef41Sopenharmony_ci}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_civoid StressScavengeObserver::RequestedGCDone() {
651cb0ef41Sopenharmony_ci  double current_percent =
661cb0ef41Sopenharmony_ci      heap_->new_space()->Size() * 100.0 / heap_->new_space()->Capacity();
671cb0ef41Sopenharmony_ci  limit_percentage_ = NextLimit(static_cast<int>(current_percent));
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  if (FLAG_trace_stress_scavenge) {
701cb0ef41Sopenharmony_ci    heap_->isolate()->PrintWithTimestamp(
711cb0ef41Sopenharmony_ci        "[Scavenge] %.2lf%% of the new space capacity reached\n",
721cb0ef41Sopenharmony_ci        current_percent);
731cb0ef41Sopenharmony_ci    heap_->isolate()->PrintWithTimestamp("[Scavenge] %d%% is the new limit\n",
741cb0ef41Sopenharmony_ci                                         limit_percentage_);
751cb0ef41Sopenharmony_ci  }
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  has_requested_gc_ = false;
781cb0ef41Sopenharmony_ci}
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_cidouble StressScavengeObserver::MaxNewSpaceSizeReached() const {
811cb0ef41Sopenharmony_ci  return max_new_space_size_reached_;
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciint StressScavengeObserver::NextLimit(int min) {
851cb0ef41Sopenharmony_ci  int max = FLAG_stress_scavenge;
861cb0ef41Sopenharmony_ci  if (min >= max) {
871cb0ef41Sopenharmony_ci    return max;
881cb0ef41Sopenharmony_ci  }
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  return min + heap_->isolate()->fuzzer_rng()->NextInt(max - min + 1);
911cb0ef41Sopenharmony_ci}
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci}  // namespace internal
941cb0ef41Sopenharmony_ci}  // namespace v8
95