--- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 2016-05-10 17:49:00.942747224 +0200 +++ new/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java 2016-05-10 17:49:00.765746619 +0200 @@ -351,6 +351,18 @@ } /** + * Notify on completion of a bootstrap. + * + * Called from the VM. + */ + @SuppressWarnings({"unused"}) + private void bootstrapFinished() throws Exception { + for (HotSpotVMEventListener vmEventListener : vmEventListeners) { + vmEventListener.notifyBootstrapFinished(); + } + } + + /** * Notify on successful install into the CodeCache. * * @param hotSpotCodeCacheProvider --- old/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotVMEventListener.java 2016-05-10 17:49:01.957750694 +0200 +++ new/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotVMEventListener.java 2016-05-10 17:49:01.775750072 +0200 @@ -75,6 +75,12 @@ } /** + * Notify on completion of a bootstrap. + */ + public void notifyBootstrapFinished() { + } + + /** * Create a custom {@link JVMCIMetaAccessContext} to be used for managing the lifetime of loaded * metadata. It a custom one isn't created then the default implementation will be a single * context with globally shared instances of {@link ResolvedJavaType} that are never released. --- old/src/share/vm/classfile/vmSymbols.hpp 2016-05-10 17:49:02.939754052 +0200 +++ new/src/share/vm/classfile/vmSymbols.hpp 2016-05-10 17:49:02.749753402 +0200 @@ -358,6 +358,7 @@ template(nthreads_name, "nthreads") \ template(ngroups_name, "ngroups") \ template(shutdown_method_name, "shutdown") \ + template(bootstrapFinished_method_name, "bootstrapFinished") \ template(finalize_method_name, "finalize") \ template(reference_lock_name, "lock") \ template(reference_discovered_name, "discovered") \ --- old/src/share/vm/jvmci/jvmciCompiler.cpp 2016-05-10 17:49:04.011757717 +0200 +++ new/src/share/vm/jvmci/jvmciCompiler.cpp 2016-05-10 17:49:03.780756927 +0200 @@ -39,6 +39,7 @@ JVMCICompiler::JVMCICompiler() : AbstractCompiler(jvmci) { _bootstrapping = false; + _bootstrap_compilation_request_seen = false; _methods_compiled = 0; assert(_instance == NULL, "only one instance allowed"); _instance = this; @@ -97,7 +98,7 @@ do { os::sleep(THREAD, 100, true); qsize = CompileBroker::queue_size(CompLevel_full_optimization); - } while (first_round && qsize == 0); + } while (!_bootstrap_compilation_request_seen && first_round && qsize == 0); first_round = false; if (PrintBootstrap) { while (z < (_methods_compiled / 100)) { @@ -111,6 +112,7 @@ tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methods_compiled); } _bootstrapping = false; + JVMCIRuntime::bootstrapFinished(); } #define CHECK_ABORT THREAD); \ @@ -187,6 +189,9 @@ assert(false, "JVMCICompiler.compileMethod should always return non-null"); } } + if (_bootstrapping) { + _bootstrap_compilation_request_seen = true; + } } /** --- old/src/share/vm/jvmci/jvmciCompiler.hpp 2016-05-10 17:49:04.990761064 +0200 +++ new/src/share/vm/jvmci/jvmciCompiler.hpp 2016-05-10 17:49:04.811760452 +0200 @@ -33,6 +33,11 @@ bool _bootstrapping; /** + * True if we have seen the a bootstrap compilation request. + */ + volatile bool _bootstrap_compilation_request_seen; + + /** * Number of methods successfully compiled by a call to * JVMCICompiler::compile_method(). */ --- old/src/share/vm/jvmci/jvmciRuntime.cpp 2016-05-10 17:49:05.959764377 +0200 +++ new/src/share/vm/jvmci/jvmciRuntime.cpp 2016-05-10 17:49:05.785763782 +0200 @@ -803,6 +803,18 @@ } } +void JVMCIRuntime::bootstrapFinished() { + if (_HotSpotJVMCIRuntime_instance != NULL) { + JavaThread* THREAD = JavaThread::current(); + HandleMark hm(THREAD); + Handle receiver = get_HotSpotJVMCIRuntime(CHECK); + JavaValue result(T_VOID); + JavaCallArguments args; + args.push_oop(receiver); + JavaCalls::call_special(&result, receiver->klass(), vmSymbols::bootstrapFinished_method_name(), vmSymbols::void_method_signature(), &args, CHECK); + } +} + bool JVMCIRuntime::treat_as_trivial(Method* method) { if (_HotSpotJVMCIRuntime_initialized) { for (int i = 0; i < _trivial_prefixes_count; i++) { --- old/src/share/vm/jvmci/jvmciRuntime.hpp 2016-05-10 17:49:06.996767922 +0200 +++ new/src/share/vm/jvmci/jvmciRuntime.hpp 2016-05-10 17:49:06.814767300 +0200 @@ -120,6 +120,8 @@ static void shutdown(TRAPS); + static void bootstrapFinished(); + static bool shutdown_called() { return _shutdown_called; } --- old/test/compiler/jvmci/common/services/jdk.vm.ci.hotspot.HotSpotVMEventListener 2016-05-10 17:49:08.198772032 +0200 +++ /dev/null 2016-04-27 14:37:27.957220952 +0200 @@ -1 +0,0 @@ -compiler.jvmci.common.JVMCIHelpers$EmptyVMEventListener --- /dev/null 2016-04-27 14:37:27.957220952 +0200 +++ new/test/compiler/jvmci/common/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener 2016-05-10 17:49:07.851770846 +0200 @@ -0,0 +1 @@ +compiler.jvmci.common.JVMCIHelpers$EmptyVMEventListener --- old/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.JVMCICompilerFactory 2016-05-10 17:49:08.973774681 +0200 +++ /dev/null 2016-04-27 14:37:27.957220952 +0200 @@ -1 +0,0 @@ -compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory --- /dev/null 2016-04-27 14:37:27.957220952 +0200 +++ new/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.services.JVMCICompilerFactory 2016-05-10 17:49:08.614773454 +0200 @@ -0,0 +1 @@ +compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory --- /dev/null 2016-04-27 14:37:27.957220952 +0200 +++ new/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.config 2016-05-10 17:49:09.405776158 +0200 @@ -0,0 +1 @@ +compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest --- /dev/null 2016-04-27 14:37:27.957220952 +0200 +++ new/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java 2016-05-10 17:49:10.360779424 +0200 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8156034 + * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64") + * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64") + * @library / /testlibrary + * @library ../common/patches + * @modules java.base/jdk.internal.org.objectweb.asm + * java.base/jdk.internal.org.objectweb.asm.tree + * jdk.vm.ci/jdk.vm.ci.hotspot + * jdk.vm.ci/jdk.vm.ci.code + * jdk.vm.ci/jdk.vm.ci.meta + * jdk.vm.ci/jdk.vm.ci.runtime + * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper + * @build compiler.jvmci.common.JVMCIHelpers + * compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest + * @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/ + * @run main jdk.test.lib.FileInstaller ./JvmciNotifyBootstrapFinishedEventTest.config + * ./META-INF/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener + * @run main ClassFileInstaller + * compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler + * compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory + * compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest + * jdk.test.lib.Asserts + * jdk.test.lib.Utils + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=EmptyCompiler -Xbootclasspath/a:. + * -XX:+UseJVMCICompiler -XX:-BootstrapJVMCI + * -Dcompiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest.bootstrap=false + * compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest + * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI + * -Djvmci.Compiler=EmptyCompiler -Xbootclasspath/a:. + * -XX:+UseJVMCICompiler -XX:+BootstrapJVMCI + * -Dcompiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest.bootstrap=true + * compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest + */ + +package compiler.jvmci.events; + +import jdk.test.lib.Asserts; +import jdk.vm.ci.hotspot.services.HotSpotVMEventListener; + +public class JvmciNotifyBootstrapFinishedEventTest extends HotSpotVMEventListener { + private static final boolean BOOTSTRAP = Boolean + .getBoolean("compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest.bootstrap"); + private static volatile int gotBoostrapNotification = 0; + + public static void main(String args[]) { + if (BOOTSTRAP) { + Asserts.assertEQ(gotBoostrapNotification, 1, "Did not receive expected number of bootstrap events"); + } else { + Asserts.assertEQ(gotBoostrapNotification, 0, "Got unexpected bootstrap event"); + } + } + + @Override + public void notifyBootstrapFinished() { + gotBoostrapNotification++; + } +}