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 (AOTRecompilation) {
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(outputStream* st) {
42 st->print(" load=%lf", _load_average.value());
43 }
44
45 bool RecompilationPolicy::have_recompilation_work() {
46 if (AOTRecompilation && TrainingData::have_data() && RecompilationSchedule::have_schedule() &&
47 RecompilationSchedule::length() > 0 && !_recompilation_done) {
48 if (_load_average.value() <= AOTRecompilationLoadAverageThreshold) {
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() < AOTDelayRecompilation) {
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 (!AOTForceRecompilation && !(nm->is_aot() && 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, 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 AtomicAccess::release_store(&_recompilation_done, true);
115 }
116 return count > 0;
117 }