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 }