// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/heap/stress-scavenge-observer.h"

#include "src/base/utils/random-number-generator.h"
#include "src/execution/isolate.h"
#include "src/heap/heap-inl.h"
#include "src/heap/spaces.h"

namespace v8 {
namespace internal {

// TODO(majeski): meaningful step_size
StressScavengeObserver::StressScavengeObserver(Heap* heap)
    : AllocationObserver(64),
      heap_(heap),
      has_requested_gc_(false),
      max_new_space_size_reached_(0.0) {
  limit_percentage_ = NextLimit();

  if (FLAG_trace_stress_scavenge && !FLAG_fuzzer_gc_analysis) {
    heap_->isolate()->PrintWithTimestamp(
        "[StressScavenge] %d%% is the new limit\n", limit_percentage_);
  }
}

void StressScavengeObserver::Step(int bytes_allocated, Address soon_object,
                                  size_t size) {
  if (has_requested_gc_ || heap_->new_space()->Capacity() == 0) {
    return;
  }

  double current_percent =
      heap_->new_space()->Size() * 100.0 / heap_->new_space()->Capacity();

  if (FLAG_trace_stress_scavenge) {
    heap_->isolate()->PrintWithTimestamp(
        "[Scavenge] %.2lf%% of the new space capacity reached\n",
        current_percent);
  }

  if (FLAG_fuzzer_gc_analysis) {
    max_new_space_size_reached_ =
        std::max(max_new_space_size_reached_, current_percent);
    return;
  }

  if (static_cast<int>(current_percent) >= limit_percentage_) {
    if (FLAG_trace_stress_scavenge) {
      heap_->isolate()->PrintWithTimestamp("[Scavenge] GC requested\n");
    }

    has_requested_gc_ = true;
    heap_->isolate()->stack_guard()->RequestGC();
  }
}

bool StressScavengeObserver::HasRequestedGC() const {
  return has_requested_gc_;
}

void StressScavengeObserver::RequestedGCDone() {
  double current_percent =
      heap_->new_space()->Size() * 100.0 / heap_->new_space()->Capacity();
  limit_percentage_ = NextLimit(static_cast<int>(current_percent));

  if (FLAG_trace_stress_scavenge) {
    heap_->isolate()->PrintWithTimestamp(
        "[Scavenge] %.2lf%% of the new space capacity reached\n",
        current_percent);
    heap_->isolate()->PrintWithTimestamp("[Scavenge] %d%% is the new limit\n",
                                         limit_percentage_);
  }

  has_requested_gc_ = false;
}

double StressScavengeObserver::MaxNewSpaceSizeReached() const {
  return max_new_space_size_reached_;
}

int StressScavengeObserver::NextLimit(int min) {
  int max = FLAG_stress_scavenge;
  if (min >= max) {
    return max;
  }

  return min + heap_->isolate()->fuzzer_rng()->NextInt(max - min + 1);
}

}  // namespace internal
}  // namespace v8
