1 /* 2 * Copyright (c) 2011, 2021, 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 #include "precompiled.hpp" 25 #include "classfile/vmClasses.hpp" 26 #include "compiler/compileBroker.hpp" 27 #include "classfile/moduleEntry.hpp" 28 #include "classfile/vmSymbols.hpp" 29 #include "jvmci/jvmciEnv.hpp" 30 #include "jvmci/jvmciRuntime.hpp" 31 #include "oops/objArrayOop.inline.hpp" 32 #include "runtime/arguments.hpp" 33 #include "runtime/handles.inline.hpp" 34 35 JVMCICompiler* JVMCICompiler::_instance = NULL; 36 elapsedTimer JVMCICompiler::_codeInstallTimer; 37 elapsedTimer JVMCICompiler::_hostedCodeInstallTimer; 38 39 JVMCICompiler::JVMCICompiler() : AbstractCompiler(compiler_jvmci) { 40 _bootstrapping = false; 41 _bootstrap_compilation_request_handled = false; 42 _methods_compiled = 0; 43 _global_compilation_ticks = 0; 44 assert(_instance == NULL, "only one instance allowed"); 45 _instance = this; 46 } 47 48 JVMCICompiler* JVMCICompiler::instance(bool require_non_null, TRAPS) { 49 if (!EnableJVMCI) { 50 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled") 51 } 52 if (_instance == NULL && require_non_null) { 53 THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "The JVMCI compiler instance has not been created"); 54 } 55 return _instance; 56 } 57 58 // Initialization 59 void JVMCICompiler::initialize() { 60 assert(!CompilerConfig::is_c1_or_interpreter_only_no_jvmci(), "JVMCI is launched, it's not c1/interpreter only mode"); 61 if (!UseCompiler || !EnableJVMCI || !UseJVMCICompiler || !should_perform_init()) { 62 return; 63 } 64 65 set_state(initialized); 66 } 67 68 void JVMCICompiler::bootstrap(TRAPS) { 69 if (Arguments::mode() == Arguments::_int) { 70 // Nothing to do in -Xint mode 71 return; 72 } 73 _bootstrapping = true; 74 ResourceMark rm(THREAD); 75 HandleMark hm(THREAD); 76 if (PrintBootstrap) { 77 tty->print("Bootstrapping JVMCI"); 78 } 79 jlong start = os::javaTimeNanos(); 80 81 Array<Method*>* objectMethods = vmClasses::Object_klass()->methods(); 82 // Initialize compile queue with a selected set of methods. 83 int len = objectMethods->length(); 84 for (int i = 0; i < len; i++) { 85 methodHandle mh(THREAD, objectMethods->at(i)); 86 if (!mh->is_native() && 87 !mh->is_static() && 88 !mh->is_object_constructor() && 89 !mh->is_class_initializer()) { 90 ResourceMark rm; 91 int hot_count = 10; // TODO: what's the appropriate value? 92 CompileBroker::compile_method(mh, InvocationEntryBci, CompLevel_full_optimization, mh, hot_count, CompileTask::Reason_Bootstrap, CHECK); 93 } 94 } 95 96 int qsize; 97 bool first_round = true; 98 int z = 0; 99 do { 100 // Loop until there is something in the queue. 101 do { 102 THREAD->sleep(100); 103 qsize = CompileBroker::queue_size(CompLevel_full_optimization); 104 } while (!_bootstrap_compilation_request_handled && first_round && qsize == 0); 105 first_round = false; 106 if (PrintBootstrap) { 107 while (z < (_methods_compiled / 100)) { 108 ++z; 109 tty->print_raw("."); 110 } 111 } 112 } while (qsize != 0); 113 114 if (PrintBootstrap) { 115 tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", 116 (jlong)nanos_to_millis(os::javaTimeNanos() - start), _methods_compiled); 117 } 118 _bootstrapping = false; 119 JVMCI::java_runtime()->bootstrap_finished(CHECK); 120 } 121 122 bool JVMCICompiler::force_comp_at_level_simple(const methodHandle& method) { 123 if (_bootstrapping) { 124 // When bootstrapping, the JVMCI compiler can compile its own methods. 125 return false; 126 } 127 if (UseJVMCINativeLibrary) { 128 // This mechanism exists to force compilation of a JVMCI compiler by C1 129 // to reduce the compilation time spent on the JVMCI compiler itself. In 130 // +UseJVMCINativeLibrary mode, the JVMCI compiler is AOT compiled. 131 return false; 132 } else { 133 JVMCIRuntime* runtime = JVMCI::java_runtime(); 134 if (runtime != NULL) { 135 JVMCIObject receiver = runtime->probe_HotSpotJVMCIRuntime(); 136 if (receiver.is_null()) { 137 return false; 138 } 139 JVMCIEnv* ignored_env = NULL; 140 objArrayHandle excludeModules(JavaThread::current(), HotSpotJVMCI::HotSpotJVMCIRuntime::excludeFromJVMCICompilation(ignored_env, HotSpotJVMCI::resolve(receiver))); 141 if (excludeModules.not_null()) { 142 ModuleEntry* moduleEntry = method->method_holder()->module(); 143 for (int i = 0; i < excludeModules->length(); i++) { 144 if (excludeModules->obj_at(i) == moduleEntry->module()) { 145 return true; 146 } 147 } 148 } 149 } 150 return false; 151 } 152 } 153 154 // Compilation entry point for methods 155 void JVMCICompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci, bool install_code, DirectiveSet* directive) { 156 ShouldNotReachHere(); 157 } 158 159 // Print CompileBroker compilation timers 160 void JVMCICompiler::print_timers() { 161 double code_install_time = _codeInstallTimer.seconds(); 162 tty->print_cr(" JVMCI CompileBroker Time:"); 163 tty->print_cr(" Compile: %7.3f s", stats()->total_time()); 164 tty->print_cr(" Install Code: %7.3f s", code_install_time); 165 } 166 167 // Print non-CompileBroker compilation timers 168 void JVMCICompiler::print_hosted_timers() { 169 double code_install_time = _hostedCodeInstallTimer.seconds(); 170 tty->print_cr(" JVMCI Hosted Time:"); 171 tty->print_cr(" Install Code: %7.3f s", code_install_time); 172 } 173 174 void JVMCICompiler::inc_methods_compiled() { 175 Atomic::inc(&_methods_compiled); 176 Atomic::inc(&_global_compilation_ticks); 177 } 178 179 void JVMCICompiler::inc_global_compilation_ticks() { 180 Atomic::inc(&_global_compilation_ticks); 181 }