/*
 * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2019, Google and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "gc/shared/gcOverheadChecker.hpp"
#include "gc/shared/softRefPolicy.hpp"
#include "logging/log.hpp"

GCOverheadChecker::GCOverheadChecker() :
  _gc_overhead_limit_exceeded(false),
  _gc_overhead_limit_count(0) {
  assert(GCOverheadLimitThreshold > 0,
    "No opportunity to clear SoftReferences before GC overhead limit");
}

void GCOverheadChecker::check_gc_overhead_limit(GCOverheadTester* time_overhead,
                                                GCOverheadTester* space_overhead,
                                                bool is_full_gc,
                                                GCCause::Cause gc_cause,
                                                SoftRefPolicy* soft_ref_policy) {
  if (is_full_gc) {
    // Explicit Full GC would do the clearing of soft-refs as well
    // So reset in the beginning
    soft_ref_policy->set_should_clear_all_soft_refs(false);
  }
  // Ignore explicit GC's.  Exiting here does not set the flag and
  // does not reset the count.
  if (GCCause::is_user_requested_gc(gc_cause) ||
      GCCause::is_serviceability_requested_gc(gc_cause)) {
    return;
  }

  bool print_gc_overhead_limit_would_be_exceeded = false;
  if (is_full_gc) {
    if (time_overhead->is_exceeded() && space_overhead->is_exceeded()) {
      // Collections, on average, are taking too much time, and
      // we have too little space available after a full gc.
      // At this point the GC overhead limit is being exceeded.
      _gc_overhead_limit_count++;
      if (UseGCOverheadLimit) {
        if (_gc_overhead_limit_count >= GCOverheadLimitThreshold){
          // All conditions have been met for throwing an out-of-memory
          set_gc_overhead_limit_exceeded(true);
          // Avoid consecutive OOM due to the gc time limit by resetting
          // the counter.
          reset_gc_overhead_limit_count();
        } else {
          // The required consecutive collections which exceed the
          // GC time limit may or may not have been reached. We
          // are approaching that condition and so as not to
          // throw an out-of-memory before all SoftRef's have been
          // cleared, set _should_clear_all_soft_refs in SoftRefPolicy.
          // The clearing will be done on the next GC.
          bool near_limit = gc_overhead_limit_near();
          if (near_limit) {
            soft_ref_policy->set_should_clear_all_soft_refs(true);
            log_trace(gc, ergo)("Nearing GC overhead limit, will be clearing all SoftReference");
          }
        }
      }
      // Set this even when the overhead limit will not
      // cause an out-of-memory.  Diagnostic message indicating
      // that the overhead limit is being exceeded is sometimes
      // printed.
      print_gc_overhead_limit_would_be_exceeded = true;

    } else {
      // Did not exceed overhead limits
      reset_gc_overhead_limit_count();
    }
  }

  if (UseGCOverheadLimit) {
    if (gc_overhead_limit_exceeded()) {
      log_trace(gc, ergo)("GC is exceeding overhead limit of %u%%", GCTimeLimit);
      reset_gc_overhead_limit_count();
    } else if (print_gc_overhead_limit_would_be_exceeded) {
      assert(_gc_overhead_limit_count > 0, "Should not be printing");
      log_trace(gc, ergo)("GC would exceed overhead limit of %u%% %d consecutive time(s)",
                          GCTimeLimit, _gc_overhead_limit_count);
    }
  }
}
