1 /*
   2  * Copyright (c) 2011, 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 "memory/oopFactory.hpp"
  26 #include "oops/oop.inline.hpp"
  27 #include "runtime/javaCalls.hpp"
  28 #include "runtime/handles.hpp"
  29 #include "jvmci/jvmciJavaClasses.hpp"
  30 #include "jvmci/jvmciCompiler.hpp"
  31 #include "jvmci/jvmciEnv.hpp"
  32 #include "jvmci/jvmciRuntime.hpp"
  33 #include "runtime/compilationPolicy.hpp"
  34 #include "runtime/globals_extension.hpp"
  35 
  36 JVMCICompiler* JVMCICompiler::_instance = NULL;
  37 elapsedTimer JVMCICompiler::_codeInstallTimer;
  38 
  39 JVMCICompiler::JVMCICompiler() : AbstractCompiler(jvmci) {
  40   _bootstrapping = false;
  41   _methodsCompiled = 0;
  42   assert(_instance == NULL, "only one instance allowed");
  43   _instance = this;
  44 }
  45 
  46 // Initialization
  47 void JVMCICompiler::initialize() {
  48   if (!UseCompiler || !EnableJVMCI || !UseJVMCICompiler || !should_perform_init()) {
  49     return;
  50   }
  51 
  52   set_state(initialized);
  53 
  54   // JVMCI is considered as application code so we need to
  55   // stop the VM deferring compilation now.
  56   CompilationPolicy::completed_vm_startup();
  57 }
  58 
  59 void JVMCICompiler::bootstrap() {
  60 #ifndef PRODUCT
  61   // We turn off CompileTheWorld so that compilation requests are not
  62   // ignored during bootstrap or that JVMCI can be compiled by C1/C2.
  63   FlagSetting ctwOff(CompileTheWorld, false);
  64 #endif
  65 
  66   JavaThread* THREAD = JavaThread::current();
  67   _bootstrapping = true;
  68   ResourceMark rm;
  69   HandleMark hm;
  70   if (PrintBootstrap) {
  71     tty->print("Bootstrapping JVMCI");
  72   }
  73   jlong start = os::javaTimeMillis();
  74 
  75   Array<Method*>* objectMethods = InstanceKlass::cast(SystemDictionary::Object_klass())->methods();
  76   // Initialize compile queue with a selected set of methods.
  77   int len = objectMethods->length();
  78   for (int i = 0; i < len; i++) {
  79     methodHandle mh = objectMethods->at(i);
  80     if (!mh->is_native() && !mh->is_static() && !mh->is_initializer()) {
  81       ResourceMark rm;
  82       int hot_count = 10; // TODO: what's the appropriate value?
  83       CompileBroker::compile_method(mh, InvocationEntryBci, CompLevel_full_optimization, mh, hot_count, "bootstrap", THREAD);
  84     }
  85   }
  86 
  87   int qsize;
  88   bool first_round = true;
  89   int z = 0;
  90   do {
  91     // Loop until there is something in the queue.
  92     do {
  93       os::sleep(THREAD, 100, true);
  94       qsize = CompileBroker::queue_size(CompLevel_full_optimization);
  95     } while (first_round && qsize == 0);
  96     first_round = false;
  97     if (PrintBootstrap) {
  98       while (z < (_methodsCompiled / 100)) {
  99         ++z;
 100         tty->print_raw(".");
 101       }
 102     }
 103   } while (qsize != 0);
 104 
 105   if (PrintBootstrap) {
 106     tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methodsCompiled);
 107   }
 108   _bootstrapping = false;
 109 }
 110 
 111 void JVMCICompiler::compile_method(methodHandle method, int entry_bci, JVMCIEnv* env) {
 112   JVMCI_EXCEPTION_CONTEXT
 113 
 114   bool is_osr = entry_bci != InvocationEntryBci;
 115   if (_bootstrapping && is_osr) {
 116       // no OSR compilations during bootstrap - the compiler is just too slow at this point,
 117       // and we know that there are no endless loops
 118       return;
 119   }
 120 
 121   JVMCIRuntime::initialize_well_known_classes(CHECK_ABORT);
 122 
 123   HandleMark hm;
 124   ResourceMark rm;
 125   Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_ABORT);
 126 
 127   JavaValue method_result(T_OBJECT);
 128   {
 129     JavaCallArguments args;
 130     args.push_long((jlong) (address) method());
 131     JavaCalls::call_static(&method_result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, CHECK_ABORT);
 132   }
 133 
 134   JavaValue result(T_VOID);
 135   JavaCallArguments args;
 136   args.push_oop(receiver);
 137   args.push_oop((oop)method_result.get_jobject());
 138   args.push_int(entry_bci);
 139   args.push_long((jlong) (address) env);
 140   args.push_int(env->task()->compile_id());
 141   JavaCalls::call_special(&result, receiver->klass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, CHECK_ABORT);
 142 
 143   _methodsCompiled++;
 144 }
 145 
 146 
 147 // Compilation entry point for methods
 148 void JVMCICompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci, DirectiveSet* directive) {
 149   ShouldNotReachHere();
 150 }
 151 
 152 // Print compilation timers and statistics
 153 void JVMCICompiler::print_timers() {
 154   print_compilation_timers();
 155 }
 156 
 157 // Print compilation timers and statistics
 158 void JVMCICompiler::print_compilation_timers() {
 159   TRACE_jvmci_1("JVMCICompiler::print_timers");
 160   tty->print_cr("       JVMCI code install time:        %6.3f s",    _codeInstallTimer.seconds());
 161 }