// 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/heap/heap-inl.h"
#include "src/heap/spaces.h"
#include "src/isolate.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
