1 /*
  2  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "compiler/compilationPolicy.hpp"
 26 #include "compiler/recompilationPolicy.hpp"
 27 #include "oops/method.inline.hpp"
 28 #include "oops/recompilationSchedule.hpp"
 29 #include "runtime/handles.inline.hpp"
 30 
 31 RecompilationPolicy::LoadAverage RecompilationPolicy::_load_average;
 32 volatile bool RecompilationPolicy::_recompilation_done = false;
 33 
 34 void RecompilationPolicy::sample_load_average() {
 35   if (UseRecompilation) {
 36     const int c2_queue_size = CompileBroker::queue_size(CompLevel_full_optimization);
 37     _load_average.sample(c2_queue_size);
 38   }
 39 }
 40 
 41 void RecompilationPolicy::print_load_average() {
 42   tty->print(" load=%lf", _load_average.value());
 43 }
 44 
 45 bool RecompilationPolicy::have_recompilation_work() {
 46   if (UseRecompilation && TrainingData::have_data() && RecompilationSchedule::have_schedule() &&
 47                           RecompilationSchedule::length() > 0 && !_recompilation_done) {
 48     if (_load_average.value() <= RecompilationLoadAverageThreshold) {
 49       return true;
 50     }
 51   }
 52   return false;
 53 }
 54 
 55 bool RecompilationPolicy::recompilation_step(int step, TRAPS) {
 56   if (!have_recompilation_work() || os::elapsedTime() < DelayRecompilation) {
 57     return false;
 58   }
 59 
 60   const int size = RecompilationSchedule::length();
 61   int i = 0;
 62   int count = 0;
 63   bool repeat = false;
 64   for (; i < size && count < step; i++) {
 65     if (!RecompilationSchedule::status_at(i)) {
 66       MethodTrainingData* mtd = RecompilationSchedule::at(i);
 67       if (!mtd->has_holder()) {
 68         RecompilationSchedule::set_status_at(i, true);
 69         continue;
 70       }
 71       const Method* method = mtd->holder();
 72       InstanceKlass* klass = method->method_holder();
 73       if (klass->is_not_initialized()) {
 74         repeat = true;
 75         continue;
 76       }
 77       nmethod *nm = method->code();
 78       if (nm == nullptr) {
 79         repeat = true;
 80         continue;
 81       }
 82 
 83       if (!ForceRecompilation && !(nm->is_scc() && nm->comp_level() == CompLevel_full_optimization)) {
 84         // If it's already online-compiled at level 4, mark it as done.
 85         if (nm->comp_level() == CompLevel_full_optimization) {
 86           RecompilationSchedule::set_status_at(i, true);
 87         } else {
 88           repeat = true;
 89         }
 90         continue;
 91       }
 92       if (RecompilationSchedule::claim_at(i)) {
 93         const methodHandle m(THREAD, const_cast<Method*>(method));
 94         CompLevel next_level = CompLevel_full_optimization;
 95 
 96         if (method->method_data() == nullptr) {
 97           CompilationPolicy::create_mdo(m, THREAD);
 98         }
 99 
100         if (PrintTieredEvents) {
101           CompilationPolicy::print_event(CompilationPolicy::FORCE_RECOMPILE, m(), m(), InvocationEntryBci, next_level);
102         }
103         CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization, methodHandle(), 0,
104                                       true /*requires_online_compilation*/, CompileTask::Reason_MustBeCompiled, THREAD);
105         if (HAS_PENDING_EXCEPTION) {
106           CLEAR_PENDING_EXCEPTION;
107         }
108         count++;
109       }
110     }
111   }
112 
113   if (i == size && !repeat) {
114     Atomic::release_store(&_recompilation_done, true);
115   }
116   return count > 0;
117 }