changeset 23408:f84a5ac3be22

make JVMCI JDK immutable and sharable among different JVMCI clients minimize diff to jvmci-9, including adding support for EnableJVMCI (default is true in jvmci-8)
author Doug Simon <doug.simon@oracle.com>
date Mon, 30 May 2016 22:56:59 +0200
parents a1d1f1e4817f
children 7e87913eaa75
files .hgtags jvmci/jdk.vm.ci.hotspot.aarch64/src/META-INF/jvmci.services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory jvmci/jdk.vm.ci.hotspot.aarch64/src/META-INF/services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory jvmci/jdk.vm.ci.hotspot.amd64/src/META-INF/jvmci.services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory jvmci/jdk.vm.ci.hotspot.amd64/src/META-INF/services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory jvmci/jdk.vm.ci.hotspot.jfr/src/META-INF/jvmci.services/jdk.vm.ci.hotspot.events.EventProvider jvmci/jdk.vm.ci.hotspot.jfr/src/META-INF/services/jdk.vm.ci.hotspot.events.EventProvider jvmci/jdk.vm.ci.hotspot.sparc/src/META-INF/jvmci.services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory jvmci/jdk.vm.ci.hotspot.sparc/src/META-INF/services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory jvmci/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIClassLoaderFactory.java jvmci/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java mx.jvmci/mx_jvmci.py mx.jvmci/mx_jvmci_makefile.py mx.jvmci/suite.py src/cpu/sparc/vm/interp_masm_sparc.cpp src/cpu/sparc/vm/sharedRuntime_sparc.cpp src/cpu/x86/vm/interp_masm_x86_64.cpp src/cpu/x86/vm/sharedRuntime_x86_64.cpp src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/systemDictionary.cpp src/share/vm/compiler/compileBroker.cpp src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/jvmci/jvmciCodeInstaller.cpp src/share/vm/jvmci/jvmciCompiler.cpp src/share/vm/jvmci/jvmciCompiler.hpp src/share/vm/jvmci/jvmciCompilerToVM.cpp src/share/vm/jvmci/jvmciCompilerToVM.hpp src/share/vm/jvmci/jvmciEnv.cpp src/share/vm/jvmci/jvmciEnv.hpp src/share/vm/jvmci/jvmciRuntime.cpp src/share/vm/jvmci/jvmciRuntime.hpp src/share/vm/jvmci/jvmci_globals.hpp src/share/vm/prims/nativeLookup.cpp src/share/vm/runtime/arguments.cpp src/share/vm/runtime/java.cpp
diffstat 35 files changed, 340 insertions(+), 862 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon May 30 14:11:39 2016 +0200
+++ b/.hgtags	Mon May 30 22:56:59 2016 +0200
@@ -767,3 +767,4 @@
 3c622007e098d8905d8e0947362a3894a629a5f1 graal-0.8
 3c622007e098d8905d8e0947362a3894a629a5f1 jvmci-0.8
 b2ca0db145463b6332c0096eaa68fa03e80ee5e8 jvmci-0.9
+d075baacf6f0f6ffeddbf99d3b87a3e80f7402e5 jvmci-0.10
--- a/jvmci/jdk.vm.ci.hotspot.aarch64/src/META-INF/jvmci.services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory	Mon May 30 14:11:39 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-jdk.vm.ci.hotspot.aarch64.AArch64HotSpotJVMCIBackendFactory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.vm.ci.hotspot.aarch64/src/META-INF/services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory	Mon May 30 22:56:59 2016 +0200
@@ -0,0 +1,1 @@
+jdk.vm.ci.hotspot.aarch64.AArch64HotSpotJVMCIBackendFactory
--- a/jvmci/jdk.vm.ci.hotspot.amd64/src/META-INF/jvmci.services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory	Mon May 30 14:11:39 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-jdk.vm.ci.hotspot.amd64.AMD64HotSpotJVMCIBackendFactory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.vm.ci.hotspot.amd64/src/META-INF/services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory	Mon May 30 22:56:59 2016 +0200
@@ -0,0 +1,1 @@
+jdk.vm.ci.hotspot.amd64.AMD64HotSpotJVMCIBackendFactory
--- a/jvmci/jdk.vm.ci.hotspot.jfr/src/META-INF/jvmci.services/jdk.vm.ci.hotspot.events.EventProvider	Mon May 30 14:11:39 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-jdk.vm.ci.hotspot.jfr.events.JFREventProvider
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.vm.ci.hotspot.jfr/src/META-INF/services/jdk.vm.ci.hotspot.events.EventProvider	Mon May 30 22:56:59 2016 +0200
@@ -0,0 +1,1 @@
+jdk.vm.ci.hotspot.jfr.events.JFREventProvider
--- a/jvmci/jdk.vm.ci.hotspot.sparc/src/META-INF/jvmci.services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory	Mon May 30 14:11:39 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-jdk.vm.ci.hotspot.sparc.SPARCHotSpotJVMCIBackendFactory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.vm.ci.hotspot.sparc/src/META-INF/services/jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory	Mon May 30 22:56:59 2016 +0200
@@ -0,0 +1,1 @@
+jdk.vm.ci.hotspot.sparc.SPARCHotSpotJVMCIBackendFactory
--- a/jvmci/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIClassLoaderFactory.java	Mon May 30 14:11:39 2016 +0200
+++ b/jvmci/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIClassLoaderFactory.java	Mon May 30 22:56:59 2016 +0200
@@ -29,9 +29,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import sun.misc.VM;
+
 /**
  * Utility called from the VM to create and register a separate class loader for loading JVMCI
- * classes (i.e., those in found in lib/jvmci/*.jar).
+ * classes (i.e., those in found in lib/jvmci/*.jar) as well as those available on the class path in
+ * the {@code "jvmci.class.path.append"} system property.
  */
 class JVMCIClassLoaderFactory {
 
@@ -85,6 +88,18 @@
             }
         }
 
+        String append = VM.getSavedProperty("jvmci.class.path.append");
+        if (append != null) {
+            for (String entry : append.split(File.pathSeparator)) {
+                File file = new File(entry);
+                try {
+                    urls.add(file.toURI().toURL());
+                } catch (MalformedURLException e) {
+                    throw new InternalError(e);
+                }
+            }
+        }
+
         return urls.toArray(new URL[urls.size()]);
     }
 }
--- a/jvmci/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java	Mon May 30 14:11:39 2016 +0200
+++ b/jvmci/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java	Mon May 30 22:56:59 2016 +0200
@@ -22,10 +22,11 @@
  */
 package jdk.vm.ci.services;
 
-import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Formatter;
 import java.util.List;
+import java.util.ServiceLoader;
 
 import sun.reflect.Reflection;
 
@@ -51,7 +52,11 @@
         @Override
         protected List<?> computeValue(Class<?> type) {
             try {
-                return Arrays.asList(getServiceImpls(type));
+                List<Object> impls = new ArrayList<>();
+                for (Object impl : ServiceLoader.load(type, getJVMCIClassLoader())) {
+                    impls.add(impl);
+                }
+                return impls;
             } catch (NoClassDefFoundError e) {
                 if (SuppressNoClassDefFoundError) {
                     return Collections.emptyList();
@@ -142,9 +147,9 @@
     }
 
     static {
-        Reflection.registerMethodsToFilter(Services.class, "getServiceImpls");
+        Reflection.registerMethodsToFilter(Services.class, "getJVMCIClassLoader");
         Reflection.registerFieldsToFilter(Services.class, "cache");
     }
 
-    private static native <S> S[] getServiceImpls(Class<?> service);
+    private static native ClassLoader getJVMCIClassLoader();
 }
--- a/mx.jvmci/mx_jvmci.py	Mon May 30 14:11:39 2016 +0200
+++ b/mx.jvmci/mx_jvmci.py	Mon May 30 22:56:59 2016 +0200
@@ -36,7 +36,6 @@
 from mx_unittest import unittest
 from mx_gate import Task
 import mx_gate
-import mx_jvmci_makefile
 
 _suite = mx.suite('jvmci')
 
@@ -132,9 +131,8 @@
         self.dist().add_update_listener(_install)
 
 class JarJDKDeployedDist(JDKDeployedDist):
-    def __init__(self, name, partOfHotSpot=False):
+    def __init__(self, name):
         JDKDeployedDist.__init__(self, name)
-        self.partOfHotSpot = partOfHotSpot
 
     def targetDir(self):
         mx.nyi('targetDir', self)
@@ -144,46 +142,33 @@
         dist = self.dist()
         mx.logv('Deploying {} to {}'.format(dist.name, targetDir))
         copyToJdk(dist.path, targetDir)
+        if exists(dist.sourcesPath):
+            copyToJdk(dist.sourcesPath, targetDir)
 
     def deploy(self, jdkDir):
         self._copyToJdk(jdkDir, self.targetDir())
 
 class ExtJDKDeployedDist(JarJDKDeployedDist):
-    def __init__(self, name, partOfHotSpot=False):
-        JarJDKDeployedDist.__init__(self, name, partOfHotSpot)
+    def __init__(self, name):
+        JarJDKDeployedDist.__init__(self, name)
 
     def targetDir(self):
         return join('jre', 'lib', 'ext')
 
 class LibJDKDeployedDist(JarJDKDeployedDist):
-    def __init__(self, name, partOfHotSpot=False):
-        JarJDKDeployedDist.__init__(self, name, partOfHotSpot)
+    def __init__(self, name):
+        JarJDKDeployedDist.__init__(self, name)
 
     def targetDir(self):
         return join('jre', 'lib')
 
 class JvmciJDKDeployedDist(JarJDKDeployedDist):
-    def __init__(self, name, partOfHotSpot=False, compilers=False):
-        JarJDKDeployedDist.__init__(self, name, partOfHotSpot)
-        self._compilers = compilers
+    def __init__(self, name):
+        JarJDKDeployedDist.__init__(self, name)
 
     def targetDir(self):
         return join('jre', 'lib', 'jvmci')
 
-    def deploy(self, jdkDir):
-        JarJDKDeployedDist.deploy(self, jdkDir)
-        _updateJVMCIFiles(jdkDir)
-        if self._compilers:
-            _updateJVMCIProperties(jdkDir, self._compilers)
-
-    def post_parse_cmd_line(self):
-        super(JvmciJDKDeployedDist, self).post_parse_cmd_line()
-        self.set_archiveparticipant()
-
-    def set_archiveparticipant(self):
-        dist = self.dist()
-        dist.set_archiveparticipant(JVMCIArchiveParticipant(dist))
-
 def _exe(l):
     return mx.exe_suffix(l)
 
@@ -225,10 +210,10 @@
 List of distributions that are deployed into a JDK by mx.
 """
 jdkDeployedDists = [
-    LibJDKDeployedDist('JVMCI_SERVICES', partOfHotSpot=True),
-    JvmciJDKDeployedDist('JVMCI_API', partOfHotSpot=True),
-    JvmciJDKDeployedDist('JVMCI_HOTSPOT', partOfHotSpot=True),
-    JvmciJDKDeployedDist('JVMCI_HOTSPOTVMCONFIG', partOfHotSpot=True),
+    LibJDKDeployedDist('JVMCI_SERVICES'),
+    JvmciJDKDeployedDist('JVMCI_API'),
+    JvmciJDKDeployedDist('JVMCI_HOTSPOT'),
+    JvmciJDKDeployedDist('JVMCI_HOTSPOTVMCONFIG'),
     HotSpotVMJDKDeployedDist('JVM_<vmbuild>_<vm>'),
 ]
 
@@ -680,75 +665,6 @@
         shutil.move(tmp, dstLib)
         os.chmod(dstLib, permissions)
 
-def _extractJVMCIFiles(jdkJars, jvmciJars, servicesDir, obsoleteCheck):
-
-    oldServices = os.listdir(servicesDir) if exists(servicesDir) else mx.ensure_dir_exists(servicesDir)
-
-    jvmciServices = {}
-    for jar in jvmciJars:
-        if os.path.isfile(jar):
-            with zipfile.ZipFile(jar) as zf:
-                for member in zf.namelist():
-                    if member.startswith('META-INF/jvmci.services/') and member != 'META-INF/jvmci.services/':
-                        service = basename(member)
-                        assert service != "", member
-                        with zf.open(member) as serviceFile:
-                            providers = jvmciServices.setdefault(service, [])
-                            for line in serviceFile.readlines():
-                                line = line.strip()
-                                if line and line not in providers:
-                                    providers.append(line)
-    for service, providers in jvmciServices.iteritems():
-        if not obsoleteCheck:
-            fd, tmp = tempfile.mkstemp(prefix=service)
-            f = os.fdopen(fd, 'w+')
-            for provider in providers:
-                f.write(provider + os.linesep)
-            target = join(servicesDir, service)
-            f.close()
-            shutil.move(tmp, target)
-            if mx.get_os() != 'windows':
-                os.chmod(target, JDK_UNIX_PERMISSIONS_FILE)
-        if oldServices and service in oldServices:
-            oldServices.remove(service)
-
-    if obsoleteCheck and mx.is_interactive() and oldServices:
-        if mx.ask_yes_no('These files in ' + servicesDir + ' look obsolete:\n  ' + '\n  '.join(oldServices) + '\nDelete them', 'n'):
-            for f in oldServices:
-                path = join(servicesDir, f)
-                os.remove(path)
-                mx.log('Deleted ' + path)
-
-def _updateJVMCIFiles(jdkDir, obsoleteCheck=False):
-    jreJVMCIDir = join(jdkDir, 'jre', 'lib', 'jvmci')
-    jvmciJars = [join(jreJVMCIDir, e) for e in os.listdir(jreJVMCIDir) if e.endswith('.jar')]
-    jreJVMCIServicesDir = join(jreJVMCIDir, 'services')
-    _extractJVMCIFiles(_getJdkDeployedJars(jdkDir), jvmciJars, jreJVMCIServicesDir, obsoleteCheck)
-
-def _updateJVMCIProperties(jdkDir, compilers):
-    jvmciProperties = join(jdkDir, 'jre', 'lib', 'jvmci', 'jvmci.properties')
-    def createFile(lines):
-        with open(jvmciProperties, 'w') as fp:
-            header = "# the last definition of a property wins (i.e., it overwrites any earlier definitions)"
-            if header not in lines:
-                print >> fp, header
-            for line in lines:
-                print >> fp, line
-
-    lines = []
-    if exists(jvmciProperties):
-        with open(jvmciProperties) as fp:
-            for line in fp:
-                if line.startswith('jvmci.Compiler='):
-                    compiler = line.strip().split('=')[1]
-                    if compiler not in compilers:
-                        lines.append(line.strip())
-                else:
-                    lines.append(line.strip())
-    for compiler in compilers:
-        lines.append("jvmci.Compiler=" + compiler)
-    createFile(lines)
-
 def _installDistInJdks(deployableDist):
     """
     Installs the jar(s) for a given Distribution into all existing JVMCI JDKs
@@ -769,13 +685,6 @@
     assert vmbuild in _vmbuildChoices, 'The vmbuild derived from ' + jdkDir + ' is unknown: ' + vmbuild
     return vmbuild
 
-def _check_for_obsolete_jvmci_files():
-    jdks = _jdksDir()
-    if exists(jdks):
-        for e in os.listdir(jdks):
-            jdkDir = join(jdks, e)
-            _updateJVMCIFiles(jdkDir, obsoleteCheck=True)
-
 def _getJdkDeployedJars(jdkDir):
     """
     Gets jar paths for all deployed distributions in the context of
@@ -789,7 +698,6 @@
         jars.append(join(dist.targetDir(), jar))
     return jars
 
-
 # run a command in the windows SDK Debug Shell
 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None):
     if respondTo is None:
@@ -1299,7 +1207,6 @@
     run_vm(vmArgs + [mainClass] + mainClassArgs)
 
 mx_unittest.add_config_participant(_unittest_config_participant)
-mx_unittest.set_vm_launcher('JVMCI VM launcher', _unittest_vm_launcher)
 
 def shortunittest(args):
     """alias for 'unittest --whitelist test/whitelist_shortunittest.txt'"""
@@ -1355,13 +1262,6 @@
 
 
 def _jvmci_gate_runner(args, tasks):
-    if mx.get_arch() != 'sparcv9':
-        with Task('Check jvmci.make in sync with suite.py', tasks) as t:
-            if t:
-                jvmciMake = join(_suite.dir, 'make', 'jvmci.make')
-                if mx_jvmci_makefile.build_makefile(['-o', jvmciMake]) != 0:
-                    t.abort('Rerun "mx makefile -o ' + jvmciMake + ' and check-in the modified ' + jvmciMake)
-
     # Build server-jvmci now so we can run the unit tests
     with Task('BuildHotSpotJVMCI: product', tasks) as t:
         if t: buildvms(['--vms', 'server', '--builds', 'product'])
@@ -1386,8 +1286,6 @@
         with Task('BuildHotSpotVarieties', tasks, disableJacoco=True) as t:
             if t:
                 buildvms(['--vms', 'client,server', '--builds', 'fastdebug,product'])
-                if mx.get_os() not in ['windows', 'cygwin']:
-                    buildvms(['--vms', 'server-nojvmci', '--builds', 'product,optimized'])
 
 mx_gate.add_gate_runner(_suite, _jvmci_gate_runner)
 mx_gate.add_gate_argument('-g', '--only-build-jvmci', action='store_false', dest='buildNonJVMCI', help='only build the JVMCI VM')
@@ -1598,7 +1496,7 @@
         # mx.findclass can be mistaken, don't give up yet
         candidates = args
 
-    run_vm(['-javaagent:' + joljar, '-cp', os.pathsep.join([mx.classpath(), joljar]), "org.openjdk.jol.MainObjectInternals"] + candidates)
+    run_vm(['-javaagent:' + joljar, '-cp', os.pathsep.join([mx.classpath(jdk=get_jvmci_jdk()), joljar]), "org.openjdk.jol.MainObjectInternals"] + candidates)
 
 def deploy_binary(args):
     for vmbuild in ['product', 'fastdebug']:
@@ -1623,7 +1521,6 @@
     'deoptalot' : [deoptalot, '[n]'],
     'longtests' : [longtests, ''],
     'jol' : [jol, ''],
-    'makefile' : [mx_jvmci_makefile.build_makefile, 'build makefiles for JDK build', None, {'keepUnsatisfiedDependencies': True}],
 })
 
 mx.add_argument('--vmcwd', dest='vm_cwd', help='current directory will be changed to <path> before the VM is executed', default=None, metavar='<path>')
@@ -1645,31 +1542,6 @@
 # suite.
 mx.add_ide_envvar('DEFAULT_VM')
 
-class JVMCIArchiveParticipant:
-    def __init__(self, dist):
-        self.dist = dist
-        self.jvmciServices = {}
-
-    def __opened__(self, arc, srcArc, services):
-        self.services = services
-        self.arc = arc
-
-    def __add__(self, arcname, contents):
-        if arcname.startswith('META-INF/jvmci.services/'):
-            service = arcname[len('META-INF/jvmci.services/'):]
-            self.jvmciServices.setdefault(service, []).extend([provider for provider in contents.split('\n')])
-            return True
-        return False
-
-    def __addsrc__(self, arcname, contents):
-        return False
-
-    def __closing__(self):
-        for service, providers in self.jvmciServices.iteritems():
-            arcname = 'META-INF/jvmci.services/' + service
-            # Convert providers to a set before printing to remove duplicates
-            self.arc.zf.writestr(arcname, '\n'.join(frozenset(providers))+ '\n')
-
 _jvmci_bootstrap_jdk = None
 
 def get_jvmci_bootstrap_jdk():
@@ -1708,14 +1580,6 @@
 
         args = ['-Xbootclasspath/p:' + dep.classpath_repr() for dep in _jvmci_bootclasspath_prepends] + args
 
-        # Set the default JVMCI compiler
-        for jdkDist in reversed(jdkDeployedDists):
-            if isinstance(jdkDist, JvmciJDKDeployedDist):
-                if jdkDist._compilers:
-                    jvmciCompiler = jdkDist._compilers[-1]
-                    args = ['-Djvmci.Compiler=' + jvmciCompiler] + args
-                    break
-
         if '-version' in args:
             ignoredArgs = args[args.index('-version') + 1:]
             if  len(ignoredArgs) > 0:
@@ -1762,6 +1626,8 @@
         _jvmci_jdks[vmbuild] = jdk
     return jdk
 
+mx_unittest.set_vm_launcher('JVMCI VM launcher', _unittest_vm_launcher, get_jvmci_jdk)
+
 class JVMCI8JDKFactory(mx.JDKFactory):
     def getJDKConfig(self):
         jdk = get_jvmci_jdk(_vmbuild)
--- a/mx.jvmci/mx_jvmci_makefile.py	Mon May 30 14:11:39 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-#
-# ----------------------------------------------------------------------------------------------------
-#
-# Copyright (c) 2015, 2015, 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.
-#
-# ----------------------------------------------------------------------------------------------------
-#
-import mx, mx_jvmci, os
-from argparse import ArgumentParser, REMAINDER
-
-
-class Makefile:
-    def __init__(self):
-        self.rules = []
-        self.definitions = []
-
-    def add_rule(self, s):
-        self.rules.append(s)
-
-    def add_definition(self, s):
-        self.definitions.append(s)
-
-    def generate(self):
-        return "\n\n".join(self.definitions + self.rules)
-
-
-def build_makefile(args):
-    """Creates a Makefile which is able to build distributions without mx
-
-    The return value indicates how many files were modified"""
-    parser = ArgumentParser(prog='mx makefile')
-    parser.add_argument('-o', action='store', dest='output', help='Write contents to this file.')
-    parser.add_argument('selectedDists', help="Selected distribution names which are going to be built with make.", nargs=REMAINDER)
-    opts = parser.parse_args(args)
-
-    if not opts.selectedDists:
-        opts.selectedDists = [d.dist() for d in mx_jvmci.jdkDeployedDists if isinstance(d, mx_jvmci.JarJDKDeployedDist) and d.partOfHotSpot]
-    else:
-        opts.selectedDists = [mx.distribution(name) for name in opts.selectedDists]
-    mf = Makefile()
-    if do_build_makefile(mf, opts.selectedDists):
-        contents = mf.generate()
-        if opts.output == None:
-            print contents
-        else:
-            if mx.update_file(opts.output, contents, showDiff=True):
-                return 1
-    return 0
-
-def get_jdk_deployed_dists():
-    return [d.dist() for d in mx_jvmci.jdkDeployedDists]
-
-def _get_dependency_check(p):
-    jarFinders = []
-    for dep in p.deps:
-        jar = None
-        if dep.isJreLibrary() and dep.optional:
-            jar = dep.jar
-        if dep.isJdkLibrary() and dep.optional:
-            jar = dep.path
-        if jar:
-            jarFinders.append("$(shell find $(ABS_BOOTDIR)/ -name '%s'; echo $$?)" % jar)
-    return "ifeq ({},'{}')".format("".join(jarFinders), "0" * len(jarFinders)) if len(jarFinders) > 0 else None
-
-def make_dist_rule(dist, mf):
-    def path_dist_relative(p):
-        return os.path.relpath(p, dist.suite.dir)
-    jdkDeployedDists = get_jdk_deployed_dists()
-    jarName = os.path.basename(dist.path)
-    sourcesVariableName = dist.name + "_SRC"
-    depJarVariableName = dist.name + "_DEP_JARS"
-    sources = []
-    resources = []
-    projects = [p for p in dist.archived_deps() if p.isJavaProject()]
-    targetPathPrefix = "$(TARGET)/"
-    annotationProcessorDeps = set()
-
-    classPath = [targetPathPrefix + os.path.basename(e.path) for e in mx.classpath_entries(dist, includeSelf=False, preferProjects=False)]
-    for p in projects:
-        projectDir = path_dist_relative(p.dir)
-        annotationProcessorDeps.update(p.declaredAnnotationProcessors)
-        depCheck = _get_dependency_check(p)
-        if depCheck:
-            sources.append(depCheck)
-        for src in [projectDir + '/' + d for d in p.srcDirs]:
-            sources.append(sourcesVariableName + " += $(shell find {} -type f 2> /dev/null)".format(src))
-            metaInf = src + "/META-INF"
-            if os.path.exists(os.path.join(dist.suite.dir, metaInf)):
-                resources.append(metaInf)
-        if depCheck:
-            sources.append("endif")
-
-    mf.add_definition("\n".join(sources))
-
-    apDistNames = []
-    apDistVariableNames = []
-    apDependencies = []
-    for apd in sorted(annotationProcessorDeps):
-        apDistNames.append(apd.name)
-        apDistVariableNames.append("$(" + apd.name + "_JAR)")
-        apDependencies.append("$(subst  $(space),:,$(" + apd.name + "_DEP_JARS))")
-    shouldExport = dist in jdkDeployedDists
-    props = {
-           "name": dist.name,
-           "jarName": targetPathPrefix + jarName,
-           "depJarsVariableAccess": "$(" + depJarVariableName + ")" if len(classPath) > 0 else "",
-           "depJarsVariable": depJarVariableName,
-           "sourcesVariableName": sourcesVariableName,
-           "annotationProcessors": " ".join(apDistVariableNames),
-           "cpAnnotationProcessors": ":".join(apDistVariableNames + apDependencies),
-           "jarDeps": " ".join(classPath),
-           "copyResources": " ".join(resources)
-           }
-
-    mf.add_definition("{name}_JAR = {jarName}".format(**props))
-    if len(classPath) > 0: mf.add_definition("{depJarsVariable} = {jarDeps}".format(**props))
-    if shouldExport: mf.add_definition("EXPORTED_FILES += $({name}_JAR)".format(**props))
-    mf.add_rule("""$({name}_JAR): $({sourcesVariableName}) {annotationProcessors} {depJarsVariableAccess}
-\t$(call build_and_jar,{cpAnnotationProcessors},$(subst  $(space),:,{depJarsVariableAccess}),{copyResources},$({name}_JAR))
-""".format(**props))
-    return
-
-
-
-def do_build_makefile(mf, selectedDists):
-    jdk = mx.get_jdk()
-    bootClassPath = jdk.bootclasspath(filtered=False)
-    bootClassPath = bootClassPath.replace(os.path.realpath(jdk.home), "$(ABS_BOOTDIR)")
-    jdkBootClassPathVariableName = "JDK_BOOTCLASSPATH"
-
-    mf.add_definition("""# This Makefile is generated automatically, do not edit
-
-TARGET=.
-# Bootstrap JDK to be used (for javac and jar)
-ABS_BOOTDIR=
-
-JAVAC=$(ABS_BOOTDIR)/bin/javac -g -target """ + str(jdk.javaCompliance) + """
-JAR=$(ABS_BOOTDIR)/bin/jar
-
-HS_COMMON_SRC=.
-
-# Directories, where the generated property-files reside within the JAR files
-SERVICES_INF=/META-INF/jvmci.services
-
-JARS = $(foreach dist,$(DISTRIBUTIONS),$($(dist)_JAR))
-
-ifeq ($(ABS_BOOTDIR),)
-    $(error Variable ABS_BOOTDIR must be set to a JDK installation.)
-endif
-ifeq ($(MAKE_VERBOSE),)
-    QUIETLY=@
-endif
-
-# Required to construct a whitespace for use with subst
-space :=
-space +=
-
-# Extracts META-INF/jvmci.services from a JAR file into a given directory
-# Arguments:
-#  1: JAR file to extract
-#  2: target directory (which already exists)
-define extract
-    $(eval TMP := $(shell mktemp -d $(TARGET)/tmp_XXXXX))
-    $(QUIETLY) cd $(TMP) && $(JAR) xf $(abspath $(1)) && \\
-         (test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2)));
-    $(QUIETLY) rm -r $(TMP);
-    $(QUIETLY) cp $(1) $(2)
-endef
-
-# Calls $(JAVAC) with the boot class path $(JDK_BOOTCLASSPATH) and sources taken from the automatic variable $^
-# Arguments:
-#  1: processorpath
-#  2: classpath
-#  3: resources to copy
-#  4: target JAR file
-define build_and_jar
-    $(info Building $(4))
-    $(eval TMP := $(shell mkdir -p $(TARGET) && mktemp -d $(TARGET)/tmp_XXXXX))
-    $(QUIETLY) $(JAVAC) -d $(TMP) -processorpath :$(1) -bootclasspath $(JDK_BOOTCLASSPATH) -cp :$(2) $(filter %.java,$^)
-    $(QUIETLY) test "$(3)" = "" || cp -r $(3) $(TMP)
-
-    @# Since all projects are built together with one javac call we cannot determine
-    @# which project contains HotSpotVMConfig.inline.hpp so we hardcode it.
-    $(eval vmconfig := $(TMP)/hotspot/HotSpotVMConfig.inline.hpp)
-    $(eval vmconfigDest := $(HS_COMMON_SRC)/../mxbuild/jvmci/jdk.vm.ci.hotspot/src_gen/hotspot)
-    $(QUIETLY) test ! -f $(vmconfig) || (mkdir -p $(vmconfigDest) && cp $(vmconfig) $(vmconfigDest))
-
-    $(QUIETLY) mkdir -p $(shell dirname $(4))
-    $(QUIETLY) $(JAR) -0cf $(4) -C $(TMP) .
-    $(QUIETLY) rm -r $(TMP)
-endef
-
-# Verifies that make/defs.make contains an appropriate line for each JVMCI service
-# and that only existing JVMCI services are exported.
-# Arguments:
-#  1: list of service files
-#  2: variable name for directory of service files
-define verify_defs_make
-    $(eval defs := make/defs.make)
-    $(eval uncondPattern := EXPORT_LIST += $$$$($(2))/)
-    $(eval condPattern := CONDITIONAL_EXPORT_LIST += $$$$($(2))/)
-    $(eval unconditionalExports := $(shell grep '^EXPORT_LIST += $$($2)' make/defs.make | sed 's:.*($(2))/::g'))
-    $(eval conditionalExports := $(shell grep '^CONDITIONAL_EXPORT_LIST += $$($2)' make/defs.make | sed 's:.*($(2))/::g'))
-    $(eval allExports := $(unconditionalExports) $(conditionalExports))
-    $(foreach file,$(1),$(if $(findstring $(file),$(allExports)), ,$(error "Line matching '$(uncondPattern)$(file)' or '$(condPattern)$(file)' not found in $(defs)")))
-    $(foreach export,$(unconditionalExports),$(if $(findstring $(export),$(1)), ,$(error "The line '$(uncondPattern)$(export)' should not be in $(defs)")))
-endef
-
-all: default
-\t$(info Put $(EXPORTED_FILES) into SHARED_DIR $(SHARED_DIR))
-\t$(shell mkdir -p $(SHARED_DIR))
-\t$(foreach export,$(EXPORTED_FILES),$(call extract,$(export),$(SHARED_DIR)))
-
-export: all
-\t$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.services/*)),EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)
-.PHONY: export
-
-clean:
-\t$(QUIETLY) rm $(JARS) 2> /dev/null || true
-\t$(QUIETLY) rmdir -p $(dir $(JARS)) 2> /dev/null || true
-.PHONY: export clean
-
-""")
-    assert selectedDists
-    selectedDists = [mx.dependency(s) for s in selectedDists]
-    dists = []
-
-    def _visit(dep, edge):
-        if dep.isDistribution():
-            dists.append(dep)
-
-    mx.walk_deps(roots=selectedDists, visit=_visit, ignoredEdges=[mx.DEP_EXCLUDED])
-
-    mf.add_definition(jdkBootClassPathVariableName + " = " + bootClassPath)
-    for dist in dists: make_dist_rule(dist, mf)
-    mf.add_definition("DISTRIBUTIONS = " + ' '.join([dist.name for dist in dists]))
-    mf.add_rule("default: $({}_JAR)\n.PHONY: default\n".format("_JAR) $(".join([d.name for d in selectedDists])))
-    return True
--- a/mx.jvmci/suite.py	Mon May 30 14:11:39 2016 +0200
+++ b/mx.jvmci/suite.py	Mon May 30 22:56:59 2016 +0200
@@ -1,5 +1,5 @@
 suite = {
-  "mxversion" : "5.27.0",
+  "mxversion" : "5.28.3",
   "name" : "jvmci",
   "url" : "http://openjdk.java.net/projects/graal",
   "developer" : {
@@ -300,7 +300,7 @@
             "path" : "build/<vmbuild>/solaris/sparcv9/<vm>/jvm.tar",
           }
         },
-      }
+      },
     },
 
     "JVMCI_SERVICES" : {
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp	Mon May 30 22:56:59 2016 +0200
@@ -1682,22 +1682,20 @@
       increment_mdp_data_at(in_bytes(CounterData::count_offset()), scratch);
     }
 #if INCLUDE_JVMCI
-    else {
+    else if (EnableJVMCI) {
       increment_mdp_data_at(in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()), scratch);
     }
 #endif
   } else {
-    bool use_non_profiled_counter = !is_virtual_call || IS_JVMCI_DEFINED;
     int non_profiled_offset = -1;
-    if (use_non_profiled_counter) {
-       non_profiled_offset = in_bytes(CounterData::count_offset());
+    if (is_virtual_call) {
+      non_profiled_offset = in_bytes(CounterData::count_offset());
+    }
 #if INCLUDE_JVMCI
-      if (!is_virtual_call) {
-        non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset());
-      }
+    else if (EnableJVMCI) {
+      non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset());
+    }
 #endif
-      assert(non_profiled_offset >= 0, "must be");
-    }
 
     record_item_in_profile_helper(receiver, scratch, 0, done, TypeProfileWidth,
       &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset, non_profiled_offset);
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp	Mon May 30 22:56:59 2016 +0200
@@ -992,17 +992,19 @@
   // Jump to the compiled code just as if compiled code was doing it.
   __ ld_ptr(G5_method, in_bytes(Method::from_compiled_offset()), G3);
 #if INCLUDE_JVMCI
-  // check if this call should be routed towards a specific entry point
-  __ ld_ptr(Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), G1);
-  __ cmp(G0, G1);
-  Label no_alternative_target;
-  __ br(Assembler::equal, false, Assembler::pn, no_alternative_target);
-  __ delayed()->nop();
-
-  __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset()), G3);
-  __ st_ptr(G0, Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
-
-  __ bind(no_alternative_target);
+  if (EnableJVMCI) {
+    // check if this call should be routed towards a specific entry point
+    __ ld_ptr(Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), G1);
+    __ cmp(G0, G1);
+    Label no_alternative_target;
+    __ br(Assembler::equal, false, Assembler::pn, no_alternative_target);
+    __ delayed()->nop();
+
+    __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset()), G3);
+    __ st_ptr(G0, Address(G2_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
+
+    __ bind(no_alternative_target);
+  }
 #endif
 
   // 6243940 We might end up in handle_wrong_method if
@@ -3469,7 +3471,9 @@
   }
 #endif
 #if INCLUDE_JVMCI
-  pad += 512; // Increase the buffer size when compiling for JVMCI
+  if (EnableJVMCI) {
+    pad += 512; // Increase the buffer size when compiling for JVMCI
+  }
 #endif
 #ifdef _LP64
   CodeBuffer buffer("deopt_blob", 2100+pad, 512);
@@ -3539,36 +3543,42 @@
 
 
 #if INCLUDE_JVMCI
-  masm->block_comment("BEGIN implicit_exception_uncommon_trap");
-  int implicit_exception_uncommon_trap_offset = __ offset() - start;
-  __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset()), O7);
-  __ st_ptr(G0, Address(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
-  __ add(O7, -8, O7);
-
-  int uncommon_trap_offset = __ offset() - start;
-
-  // Save everything in sight.
-  (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
-  __ set_last_Java_frame(SP, NULL);
-
-  __ ld(G2_thread, in_bytes(JavaThread::pending_deoptimization_offset()), O1);
-  __ sub(G0, 1, L1);
-  __ st(L1, G2_thread, in_bytes(JavaThread::pending_deoptimization_offset()));
-
-  __ mov((int32_t)Deoptimization::Unpack_reexecute, L0deopt_mode);
-  __ mov(G2_thread, O0);
-  __ mov(L0deopt_mode, O2);
-  __ call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap));
-  __ delayed()->nop();
-  oop_maps->add_gc_map( __ offset()-start, map->deep_copy());
-  __ get_thread();
-  __ add(O7, 8, O7);
-  __ reset_last_Java_frame();
-
   Label after_fetch_unroll_info_call;
-  __ ba(after_fetch_unroll_info_call);
-  __ delayed()->nop(); // Delay slot
-  masm->block_comment("END implicit_exception_uncommon_trap");
+  int implicit_exception_uncommon_trap_offset = 0;
+  int uncommon_trap_offset = 0;
+
+  if (EnableJVMCI) {
+    masm->block_comment("BEGIN implicit_exception_uncommon_trap");
+    implicit_exception_uncommon_trap_offset = __ offset() - start;
+    __ ld_ptr(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset()), O7);
+    __ st_ptr(G0, Address(G2_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
+    __ add(O7, -8, O7);
+
+    uncommon_trap_offset = __ offset() - start;
+
+    // Save everything in sight.
+    (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_words);
+    __ set_last_Java_frame(SP, NULL);
+
+    __ ld(G2_thread, in_bytes(JavaThread::pending_deoptimization_offset()), O1);
+    __ sub(G0, 1, L1);
+    __ st(L1, G2_thread, in_bytes(JavaThread::pending_deoptimization_offset()));
+
+    __ mov((int32_t)Deoptimization::Unpack_reexecute, L0deopt_mode);
+    __ mov(G2_thread, O0);
+    __ mov(L0deopt_mode, O2);
+    __ call(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap));
+    __ delayed()->nop();
+    oop_maps->add_gc_map( __ offset()-start, map->deep_copy());
+    __ get_thread();
+    __ add(O7, 8, O7);
+    __ reset_last_Java_frame();
+
+    after_fetch_unroll_info_call;
+    __ ba(after_fetch_unroll_info_call);
+    __ delayed()->nop(); // Delay slot
+    masm->block_comment("END implicit_exception_uncommon_trap");
+  } // EnableJVMCI
 #endif // INCLUDE_JVMCI
 
   int exception_offset = __ offset() - start;
@@ -3656,7 +3666,9 @@
   __ reset_last_Java_frame();
 
 #if INCLUDE_JVMCI
-  __ bind(after_fetch_unroll_info_call);
+  if (EnableJVMCI) {
+    __ bind(after_fetch_unroll_info_call);
+  }
 #endif
   // NOTE: we know that only O0/O1 will be reloaded by restore_result_registers
   // so this move will survive
@@ -3725,8 +3737,10 @@
   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_words);
   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
 #if INCLUDE_JVMCI
-  _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
-  _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
+  if (EnableJVMCI) {
+    _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
+    _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
+  }
 #endif
 }
 
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp	Mon May 30 22:56:59 2016 +0200
@@ -1179,22 +1179,20 @@
       increment_mdp_data_at(mdp, in_bytes(CounterData::count_offset()));
     }
 #if INCLUDE_JVMCI
-    else {
+    else if (EnableJVMCI) {
       increment_mdp_data_at(mdp, in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset()));
     }
 #endif
   } else {                                      
-    bool use_non_profiled_counter = !is_virtual_call || IS_JVMCI_DEFINED;
     int non_profiled_offset = -1;
-    if (use_non_profiled_counter) {
-       non_profiled_offset = in_bytes(CounterData::count_offset());
+    if (is_virtual_call) {
+      non_profiled_offset = in_bytes(CounterData::count_offset());
+    }
 #if INCLUDE_JVMCI
-      if (!is_virtual_call) {
-        non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset());
-      }
+    else if (EnableJVMCI) {
+      non_profiled_offset = in_bytes(ReceiverTypeData::nonprofiled_receiver_count_offset());
+    }
 #endif
-      assert(non_profiled_offset >= 0, "must be");
-    }
 
     record_item_in_profile_helper(receiver, mdp, reg2, 0, done, TypeProfileWidth,
       &VirtualCallData::receiver_offset, &VirtualCallData::receiver_count_offset, non_profiled_offset);
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp	Mon May 30 22:56:59 2016 +0200
@@ -766,13 +766,15 @@
   __ movptr(r11, Address(rbx, in_bytes(Method::from_compiled_offset())));
 
 #if INCLUDE_JVMCI
-  // check if this call should be routed towards a specific entry point
-  __ cmpptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
-  Label no_alternative_target;
-  __ jcc(Assembler::equal, no_alternative_target);
-  __ movptr(r11, Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
-  __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
-  __ bind(no_alternative_target);
+  if (EnableJVMCI) {
+    // check if this call should be routed towards a specific entry point
+    __ cmpptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
+    Label no_alternative_target;
+    __ jcc(Assembler::equal, no_alternative_target);
+    __ movptr(r11, Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
+    __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())), 0);
+    __ bind(no_alternative_target);
+  }
 #endif
 
   // Now generate the shuffle code.  Pick up all register args and move the
@@ -3396,31 +3398,36 @@
   __ jmp(cont);
 
 #if INCLUDE_JVMCI
-  int implicit_exception_uncommon_trap_offset = __ pc() - start;
-
-  __ pushptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
-  __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())), (int32_t)NULL_WORD);
-
-  int uncommon_trap_offset = __ pc() - start;
-
-  // Save everything in sight.
-  RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
-  // fetch_unroll_info needs to call last_java_frame()
-  __ set_last_Java_frame(noreg, noreg, NULL);
-
-  __ movl(c_rarg1, Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())));
-  __ movl(Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())), -1);
-
-  __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
-  __ mov(c_rarg0, r15_thread);
-  __ movl(c_rarg2, r14); // exec mode
-  __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
-  oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
-
-  __ reset_last_Java_frame(false, false);
-
   Label after_fetch_unroll_info_call;
-  __ jmp(after_fetch_unroll_info_call);
+  int implicit_exception_uncommon_trap_offset = 0;
+  int uncommon_trap_offset = 0;
+
+  if (EnableJVMCI) {
+    implicit_exception_uncommon_trap_offset = __ pc() - start;
+
+    __ pushptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
+    __ movptr(Address(r15_thread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())), (int32_t)NULL_WORD);
+
+    uncommon_trap_offset = __ pc() - start;
+
+    // Save everything in sight.
+    RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
+    // fetch_unroll_info needs to call last_java_frame()
+    __ set_last_Java_frame(noreg, noreg, NULL);
+
+    __ movl(c_rarg1, Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())));
+    __ movl(Address(r15_thread, in_bytes(JavaThread::pending_deoptimization_offset())), -1);
+
+    __ movl(r14, (int32_t)Deoptimization::Unpack_reexecute);
+    __ mov(c_rarg0, r15_thread);
+    __ movl(c_rarg2, r14); // exec mode
+    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap)));
+    oop_maps->add_gc_map( __ pc()-start, map->deep_copy());
+
+    __ reset_last_Java_frame(false, false);
+
+    __ jmp(after_fetch_unroll_info_call);
+  } // EnableJVMCI
 #endif // INCLUDE_JVMCI
 
   int exception_offset = __ pc() - start;
@@ -3510,7 +3517,9 @@
   __ reset_last_Java_frame(false, false);
 
 #if INCLUDE_JVMCI
-  __ bind(after_fetch_unroll_info_call);
+  if (EnableJVMCI) {
+    __ bind(after_fetch_unroll_info_call);
+  }
 #endif
 
   // Load UnrollBlock* into rdi
@@ -3689,8 +3698,10 @@
   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
 #if INCLUDE_JVMCI
-  _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
-  _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
+  if (EnableJVMCI) {
+    _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
+    _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
+  }
 #endif
 }
 
--- a/src/share/vm/classfile/classFileParser.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/classfile/classFileParser.cpp	Mon May 30 22:56:59 2016 +0200
@@ -4222,12 +4222,7 @@
                    InstanceKlass::cast(class_loader->klass())->external_name());
       }
     }
-#if INCLUDE_JVMCI
-    if (TraceClassLoadingStack) {
-      // useful when investigating why a class is loaded
-      JavaThread::current()->print_stack_on(tty);
-    }
-#endif
+
     if (TraceClassResolution) {
       ResourceMark rm;
       // print out the superclass.
--- a/src/share/vm/classfile/systemDictionary.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/classfile/systemDictionary.cpp	Mon May 30 22:56:59 2016 +0200
@@ -1855,17 +1855,16 @@
   int  sid  = (info >> CEIL_LG_OPTION_LIMIT);
   Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
   Klass**    klassp = &_well_known_klasses[id];
-  bool must_load = (init_opt < SystemDictionary::Opt);
   if ((*klassp) == NULL) {
 #if INCLUDE_JVMCI
-    bool is_jvmci = init_opt == SystemDictionary::Jvmci;
-    assert(is_jvmci == (id >= (int)FIRST_JVMCI_WKID && id <= (int)LAST_JVMCI_WKID),
-        "JVMCI WKIDs must be contiguous and separate from non-JVMCI WKIDs");
-    if (is_jvmci) {
+    if (EnableJVMCI && init_opt == SystemDictionary::Jvmci) {
+      assert(id >= (int)FIRST_JVMCI_WKID && id <= (int)LAST_JVMCI_WKID,
+          "JVMCI WKIDs must be contiguous and separate from non-JVMCI WKIDs");
       (*klassp) = resolve_or_fail(symbol, _jvmci_loader, Handle(), true, CHECK_0); // load required JVMCI class
-    } else
+      return ((*klassp) != NULL);
+    }
 #endif
-    if (must_load) {
+    if (init_opt < SystemDictionary::Opt) {
       (*klassp) = resolve_or_fail(symbol, true, CHECK_0); // load required class
     } else {
       (*klassp) = resolve_or_null(symbol,       CHECK_0); // load optional klass
--- a/src/share/vm/compiler/compileBroker.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/compiler/compileBroker.cpp	Mon May 30 22:56:59 2016 +0200
@@ -942,31 +942,35 @@
   int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple);
   int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization);
 #if INCLUDE_JVMCI
-  JVMCICompiler* jvmci = new JVMCICompiler();
-  if (UseJVMCICompiler) {
-    _compilers[1] = jvmci;
-    if (FLAG_IS_DEFAULT(JVMCIThreads)) {
-      if (BootstrapJVMCI) {
-        // JVMCI will bootstrap so give it more threads
-        c2_count = MIN2(32, os::active_processor_count());
+  if (EnableJVMCI) {
+    JVMCICompiler* jvmci = new JVMCICompiler();
+    if (UseJVMCICompiler) {
+      _compilers[1] = jvmci;
+      if (FLAG_IS_DEFAULT(JVMCIThreads)) {
+        if (BootstrapJVMCI) {
+          // JVMCI will bootstrap so give it more threads
+          c2_count = MIN2(32, os::active_processor_count());
+        }
+      } else {
+        c2_count = JVMCIThreads;
+      }
+      if (FLAG_IS_DEFAULT(JVMCIHostThreads)) {
+      } else {
+        c1_count = JVMCIHostThreads;
+      }
+      if (!UseInterpreter || !BackgroundCompilation) {
+        // Force initialization of JVMCI compiler otherwise JVMCI
+        // compilations will not block until JVMCI is initialized
+        JVMCIRuntime::ensure_jvmci_class_loader_is_initialized();
+        ResourceMark rm;
+        TempNewSymbol getCompiler = SymbolTable::new_symbol("getCompiler", CHECK);
+        TempNewSymbol sig = SymbolTable::new_symbol("()Ljdk/vm/ci/runtime/JVMCICompiler;", CHECK);
+        Handle jvmciRuntime = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK);
+        JavaValue result(T_OBJECT);
+        JavaCalls::call_virtual(&result, jvmciRuntime, HotSpotJVMCIRuntime::klass(), getCompiler, sig, CHECK);
       }
     } else {
-      c2_count = JVMCIThreads;
-    }
-    if (FLAG_IS_DEFAULT(JVMCIHostThreads)) {
-    } else {
-      c1_count = JVMCIHostThreads;
-    }
-    if (!UseInterpreter || !BackgroundCompilation) {
-      // Force initialization of JVMCI compiler otherwise JVMCI
-      // compilations will not block until JVMCI is initialized
-      JVMCIRuntime::ensure_jvmci_class_loader_is_initialized();
-      ResourceMark rm;
-      TempNewSymbol getCompiler = SymbolTable::new_symbol("getCompiler", CHECK);
-      TempNewSymbol sig = SymbolTable::new_symbol("()Ljdk/vm/ci/runtime/JVMCICompiler;", CHECK);
-      Handle jvmciRuntime = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK);
-      JavaValue result(T_OBJECT);
-      JavaCalls::call_virtual(&result, jvmciRuntime, HotSpotJVMCIRuntime::klass(), getCompiler, sig, CHECK);
+      c2_count = 0;
     }
   }
 #ifndef COMPILER2
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Mon May 30 22:56:59 2016 +0200
@@ -480,7 +480,7 @@
   } while (should_repeat == true);
 
 #if INCLUDE_JVMCI
-  if (h_method->method_data() != NULL) {
+  if (EnableJVMCI && h_method->method_data() != NULL) {
     ResourceMark rm(thread);
     ProfileData* pdata = h_method->method_data()->allocate_bci_to_data(current_bci, NULL);
     if (pdata != NULL && pdata->is_BitData()) {
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Mon May 30 22:56:59 2016 +0200
@@ -70,6 +70,10 @@
 }
 
 VMReg getVMRegFromLocation(Handle location, int total_frame_size, TRAPS) {
+  if (location.is_null()) {
+    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+  }
+
   Handle reg = code_Location::reg(location);
   jint offset = code_Location::offset(location);
 
@@ -95,6 +99,12 @@
 // creates a HotSpot oop map out of the byte arrays provided by DebugInfo
 OopMap* CodeInstaller::create_oop_map(Handle debug_info, TRAPS) {
   Handle reference_map = DebugInfo::referenceMap(debug_info);
+  if (reference_map.is_null()) {
+    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+  }
+  if (!reference_map->is_a(HotSpotReferenceMap::klass())) {
+    JVMCI_ERROR_NULL("unknown reference map: %s", reference_map->klass()->signature_name());
+  }
   if (HotSpotReferenceMap::maxRegisterSize(reference_map) > 16) {
     _has_wide_vector = true;
   }
@@ -102,6 +112,12 @@
   objArrayHandle objects = HotSpotReferenceMap::objects(reference_map);
   objArrayHandle derivedBase = HotSpotReferenceMap::derivedBase(reference_map);
   typeArrayHandle sizeInBytes = HotSpotReferenceMap::sizeInBytes(reference_map);
+  if (objects.is_null() || derivedBase.is_null() || sizeInBytes.is_null()) {
+    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+  }
+  if (objects->length() != derivedBase->length() || objects->length() != sizeInBytes->length()) {
+    JVMCI_ERROR_NULL("arrays in reference map have different sizes: %d %d %d", objects->length(), derivedBase->length(), sizeInBytes->length());
+  }
   for (int i = 0; i < objects->length(); i++) {
     Handle location = objects->obj_at(i);
     Handle baseLocation = derivedBase->obj_at(i);
@@ -163,8 +179,8 @@
   /*
    * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base
    * class is in general not equal to the pointer of the subclass. When patching metaspace pointers,
-   * the compiler expects a direct pointer to the subclass (Klass*, Method* or Symbol*), not a
-   * pointer to the base class (Metadata* or MetaspaceObj*).
+   * the compiler expects a direct pointer to the subclass (Klass* or Method*), not a pointer to the
+   * base class (Metadata* or MetaspaceObj*).
    */
   oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
   if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
@@ -203,7 +219,7 @@
 Location::Type CodeInstaller::get_oop_type(Handle value) {
   Handle valueKind = Value::valueKind(value);
   Handle platformKind = ValueKind::platformKind(valueKind);
-  
+
   if (platformKind == word_kind()) {
     return Location::oop;
   } else {
@@ -213,7 +229,9 @@
 
 ScopeValue* CodeInstaller::get_scope_value(Handle value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, TRAPS) {
   second = NULL;
-  if (value == Value::ILLEGAL()) {
+  if (value.is_null()) {
+    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+  } else if (value == Value::ILLEGAL()) {
     if (type != T_ILLEGAL) {
       JVMCI_ERROR_NULL("unexpected illegal value, expected %s", basictype_to_str(type));
     }
@@ -283,7 +301,7 @@
         jlong prim = PrimitiveConstant::primitive(value);
         return new ConstantLongValue(prim);
       } else {
-        BasicType constantType = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(PrimitiveConstant::kind(value)), CHECK_NULL);
+        BasicType constantType = JVMCIRuntime::kindToBasicType(PrimitiveConstant::kind(value), CHECK_NULL);
         if (type != constantType) {
           JVMCI_ERROR_NULL("primitive constant type doesn't match, expected %s but got %s", basictype_to_str(type), basictype_to_str(constantType));
         }
@@ -351,7 +369,7 @@
   for (jint i = 0; i < values->length(); i++) {
     ScopeValue* cur_second = NULL;
     Handle object = values->obj_at(i);
-    BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(slotKinds->obj_at(i)), CHECK);
+    BasicType type = JVMCIRuntime::kindToBasicType(slotKinds->obj_at(i), CHECK);
     ScopeValue* value = get_scope_value(object, type, objects, cur_second, CHECK);
 
     if (isLongArray && cur_second == NULL) {
@@ -369,6 +387,9 @@
 }
 
 MonitorValue* CodeInstaller::get_monitor_value(Handle value, GrowableArray<ScopeValue*>* objects, TRAPS) {
+  if (value.is_null()) {
+    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+  }
   if (!value->is_a(StackLockValue::klass())) {
     JVMCI_ERROR_NULL("Monitors must be of type StackLockValue, got %s", value->klass()->signature_name());
   }
@@ -540,7 +561,7 @@
   objArrayOop sites = this->sites();
   for (int i = 0; i < sites->length(); i++) {
     oop site = sites->obj_at(i);
-    if (site->is_a(site_Mark::klass())) {
+    if (site != NULL && site->is_a(site_Mark::klass())) {
       oop id_obj = site_Mark::id(site);
       if (id_obj != NULL) {
         if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) {
@@ -598,11 +619,20 @@
 
   for (int i = 0; i < data_section_patches()->length(); i++) {
     Handle patch = data_section_patches()->obj_at(i);
+    if (patch.is_null()) {
+      THROW_(vmSymbols::java_lang_NullPointerException(), JVMCIEnv::ok);
+    }
     Handle reference = site_DataPatch::reference(patch);
+    if (reference.is_null()) {
+      THROW_(vmSymbols::java_lang_NullPointerException(), JVMCIEnv::ok);
+    }
     if (!reference->is_a(site_ConstantReference::klass())) {
       JVMCI_ERROR_OK("invalid patch in data section: %s", reference->klass()->signature_name());
     }
     Handle constant = site_ConstantReference::constant(reference);
+    if (constant.is_null()) {
+      THROW_(vmSymbols::java_lang_NullPointerException(), JVMCIEnv::ok);
+    }
     address dest = _constants->start() + site_Site::pcOffset(patch);
     if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
       if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
@@ -635,6 +665,10 @@
   jint last_pc_offset = -1;
   for (int i = 0; i < sites->length(); i++) {
     Handle site = sites->obj_at(i);
+    if (site.is_null()) {
+      THROW_(vmSymbols::java_lang_NullPointerException(), JVMCIEnv::ok);
+    }
+
     jint pc_offset = site_Site::pcOffset(site);
 
     if (site->is_a(site_Call::klass())) {
@@ -848,6 +882,9 @@
     objArrayHandle values = BytecodeFrame::values(frame);
     objArrayHandle slotKinds = BytecodeFrame::slotKinds(frame);
 
+    if (values.is_null() || slotKinds.is_null()) {
+      THROW(vmSymbols::java_lang_NullPointerException());
+    }
     if (local_count + expression_count + monitor_count != values->length()) {
       JVMCI_ERROR("unexpected values length %d in scope (%d locals, %d expressions, %d monitors)", values->length(), local_count, expression_count, monitor_count);
     }
@@ -866,14 +903,14 @@
       ScopeValue* second = NULL;
       Handle value = values->obj_at(i);
       if (i < local_count) {
-        BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(slotKinds->obj_at(i)), CHECK);
+        BasicType type = JVMCIRuntime::kindToBasicType(slotKinds->obj_at(i), CHECK);
         ScopeValue* first = get_scope_value(value, type, objects, second, CHECK);
         if (second != NULL) {
           locals->append(second);
         }
         locals->append(first);
       } else if (i < local_count + expression_count) {
-        BasicType type = JVMCIRuntime::kindToBasicType(JavaKind::typeChar(slotKinds->obj_at(i)), CHECK);
+        BasicType type = JVMCIRuntime::kindToBasicType(slotKinds->obj_at(i), CHECK);
         ScopeValue* first = get_scope_value(value, type, objects, second, CHECK);
         if (second != NULL) {
           expressions->append(second);
@@ -982,9 +1019,13 @@
 
 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
   Handle reference = site_DataPatch::reference(site);
-  if (reference->is_a(site_ConstantReference::klass())) {
+  if (reference.is_null()) {
+    THROW(vmSymbols::java_lang_NullPointerException());
+  } else if (reference->is_a(site_ConstantReference::klass())) {
     Handle constant = site_ConstantReference::constant(reference);
-    if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
+    if (constant.is_null()) {
+      THROW(vmSymbols::java_lang_NullPointerException());
+    } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
       pd_patch_OopConstant(pc_offset, constant, CHECK);
     } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
       pd_patch_MetaspaceConstant(pc_offset, constant, CHECK);
--- a/src/share/vm/jvmci/jvmciCompiler.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciCompiler.cpp	Mon May 30 22:56:59 2016 +0200
@@ -162,7 +162,7 @@
       oop failure_message = HotSpotCompilationRequestResult::failureMessage(result_object);
       if (failure_message != NULL) {
         const char* failure_reason = java_lang_String::as_utf8_string(failure_message);
-        env->set_failure(failure_reason, HotSpotCompilationRequestResult::retry(result_object));
+        env->set_failure(failure_reason, HotSpotCompilationRequestResult::retry(result_object) != 0);
       } else {
         if (env->task()->code() == NULL) {
           env->set_failure("no nmethod produced", true);
--- a/src/share/vm/jvmci/jvmciCompiler.hpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciCompiler.hpp	Mon May 30 22:56:59 2016 +0200
@@ -28,9 +28,7 @@
 #include "jvmci/jvmciEnv.hpp"
 
 class JVMCICompiler : public AbstractCompiler {
-
 private:
-
   bool _bootstrapping;
 
   /**
@@ -42,17 +40,21 @@
    * Number of methods successfully compiled by a call to
    * JVMCICompiler::compile_method().
    */
-  volatile int  _methods_compiled;
+  volatile int _methods_compiled;
 
   static JVMCICompiler* _instance;
- 
+
   static elapsedTimer _codeInstallTimer;
 
 public:
-
   JVMCICompiler();
 
-  static JVMCICompiler* instance(TRAPS) { return _instance; }
+  static JVMCICompiler* instance(TRAPS) {
+    if (!EnableJVMCI) {
+      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled")
+    }
+    return _instance;
+  }
 
   virtual const char* name() { return "JVMCI"; }
 
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Mon May 30 22:56:59 2016 +0200
@@ -275,7 +275,7 @@
 C2V_VMENTRY(jobject, getImplementor, (JNIEnv *, jobject, jobject jvmci_type))
   InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
   oop implementor = CompilerToVM::get_jvmci_type(klass->implementor(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, implementor); 
+  return JNIHandles::make_local(THREAD, implementor);
 C2V_END
 
 C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, jobject jvmci_method))
@@ -285,13 +285,9 @@
 
 C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
   methodHandle method = CompilerToVM::asMethod(jvmci_method);
-#ifdef COMPILER_JVMCI
-  bool is_compilable = !method->is_not_compilable(CompLevel_full_optimization);
-#else
   // In hosted mode ignore the not_compilable flags since they are never set by
   // the JVMCI compiler.
-  bool is_compilable = true;
-#endif
+  bool is_compilable = UseJVMCICompiler ? !method->is_not_compilable(CompLevel_full_optimization) : true;
   return is_compilable && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
 C2V_END
 
--- a/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Mon May 30 22:56:59 2016 +0200
@@ -48,31 +48,31 @@
 
   static JNINativeMethod methods[];
   static int methods_count();
-  
+
   static inline Method* asMethod(jobject jvmci_method) {
     return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
   }
-  
+
   static inline Method* asMethod(Handle jvmci_method) {
     return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
   }
-  
+
   static inline Method* asMethod(oop jvmci_method) {
     return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
   }
-  
+
   static inline ConstantPool* asConstantPool(jobject jvmci_constant_pool) {
     return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
   }
-  
+
   static inline ConstantPool* asConstantPool(Handle jvmci_constant_pool) {
     return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
   }
-  
+
   static inline ConstantPool* asConstantPool(oop jvmci_constant_pool) {
     return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
   }
-  
+
   static inline Klass* asKlass(jobject jvmci_type) {
     return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
   }
@@ -80,15 +80,15 @@
   static inline Klass* asKlass(Handle jvmci_type) {
     return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
   }
-  
+
   static inline Klass* asKlass(oop jvmci_type) {
     return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
   }
-  
+
   static inline MethodData* asMethodData(jlong metaspaceMethodData) {
     return (MethodData*) (address) metaspaceMethodData;
   }
-  
+
   static oop get_jvmci_method(const methodHandle& method, TRAPS);
 
   static oop get_jvmci_type(KlassHandle klass, TRAPS);
--- a/src/share/vm/jvmci/jvmciEnv.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciEnv.cpp	Mon May 30 22:56:59 2016 +0200
@@ -83,7 +83,7 @@
 }
 
 // ------------------------------------------------------------------
-KlassHandle JVMCIEnv::get_klass_by_name_impl(KlassHandle accessing_klass,
+KlassHandle JVMCIEnv::get_klass_by_name_impl(KlassHandle& accessing_klass,
                                           const constantPoolHandle& cpool,
                                           Symbol* sym,
                                           bool require_local) {
--- a/src/share/vm/jvmci/jvmciEnv.hpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciEnv.hpp	Mon May 30 22:56:59 2016 +0200
@@ -109,7 +109,7 @@
   bool  _jvmti_can_post_on_exceptions;
 
   // Implementation methods for loading and constant pool access.
-  static KlassHandle get_klass_by_name_impl(KlassHandle accessing_klass,
+  static KlassHandle get_klass_by_name_impl(KlassHandle& accessing_klass,
                                   const constantPoolHandle& cpool,
                                   Symbol* klass_name,
                                   bool require_local);
--- a/src/share/vm/jvmci/jvmciRuntime.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciRuntime.cpp	Mon May 30 22:56:59 2016 +0200
@@ -52,7 +52,11 @@
 JVMCIRuntime::CompLevelAdjustment JVMCIRuntime::_comp_level_adjustment = JVMCIRuntime::none;
 bool JVMCIRuntime::_shutdown_called = false;
 
-BasicType JVMCIRuntime::kindToBasicType(jchar ch, TRAPS) {
+BasicType JVMCIRuntime::kindToBasicType(Handle kind, TRAPS) {
+  if (kind.is_null()) {
+    THROW_(vmSymbols::java_lang_NullPointerException(), T_ILLEGAL);
+  }
+  jchar ch = JavaKind::typeChar(kind);
   switch(ch) {
     case 'Z': return T_BOOLEAN;
     case 'B': return T_BYTE;
@@ -96,6 +100,7 @@
 JRT_BLOCK_ENTRY(void, JVMCIRuntime::new_instance(JavaThread* thread, Klass* klass))
   JRT_BLOCK;
   assert(klass->is_klass(), "not a class");
+  Handle holder(THREAD, klass->klass_holder()); // keep the klass alive
   instanceKlassHandle h(thread, klass);
   h->check_valid_for_instantiation(true, CHECK);
   // make sure klass is initialized
@@ -121,6 +126,7 @@
     BasicType elt_type = TypeArrayKlass::cast(array_klass)->element_type();
     obj = oopFactory::new_typeArray(elt_type, length, CHECK);
   } else {
+    Handle holder(THREAD, array_klass->klass_holder()); // keep the klass alive
     Klass* elem_klass = ObjArrayKlass::cast(array_klass)->element_klass();
     obj = oopFactory::new_objArray(elem_klass, length, CHECK);
   }
@@ -164,6 +170,7 @@
 JRT_ENTRY(void, JVMCIRuntime::new_multi_array(JavaThread* thread, Klass* klass, int rank, jint* dims))
   assert(klass->is_klass(), "not a class");
   assert(rank >= 1, "rank must be nonzero");
+  Handle holder(THREAD, klass->klass_holder()); // keep the klass alive
   oop obj = ArrayKlass::cast(klass)->multi_allocate(rank, dims, CHECK);
   thread->set_vm_result(obj);
 JRT_END
@@ -605,17 +612,19 @@
 
 // private static JVMCIRuntime JVMCI.initializeRuntime()
 JVM_ENTRY(jobject, JVM_GetJVMCIRuntime(JNIEnv *env, jclass c))
+  if (!EnableJVMCI) {
+    THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled")
+  }
   JVMCIRuntime::initialize_HotSpotJVMCIRuntime(CHECK_NULL);
   return JVMCIRuntime::get_HotSpotJVMCIRuntime_jobject(CHECK_NULL);
 JVM_END
 
-// private static Object[] Services.getServiceImpls(String serviceClass)
-JVM_ENTRY(jobject, JVM_GetJVMCIServiceImpls(JNIEnv *env, jclass c, jclass serviceClass))
-  HandleMark hm;
-  ResourceMark rm;
-  JVMCIRuntime::ensure_jvmci_class_loader_is_initialized();
-  KlassHandle serviceKlass(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(serviceClass)));
-  return JNIHandles::make_local(THREAD, JVMCIRuntime::get_service_impls(serviceKlass, THREAD)());
+// private static ClassLoader Services.getJVMCIClassLoader()
+JVM_ENTRY(jobject, JVM_GetJVMCIClassLoader(JNIEnv *env, jclass c))
+  if (!EnableJVMCI) {
+    THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled")
+  }
+  return JNIHandles::make_local(THREAD, SystemDictionary::jvmci_loader());
 JVM_END
 
 Handle JVMCIRuntime::callStatic(const char* className, const char* methodName, const char* signature, JavaCallArguments* args, TRAPS) {
@@ -752,6 +761,10 @@
 
 // private static void CompilerToVM.registerNatives()
 JVM_ENTRY(void, JVM_RegisterJVMCINatives(JNIEnv *env, jclass c2vmClass))
+  if (!EnableJVMCI) {
+    THROW_MSG(vmSymbols::java_lang_InternalError(), "JVMCI is not enabled");
+  }
+
 #ifdef _LP64
 #ifndef TARGET_ARCH_sparc
   uintptr_t heap_end = (uintptr_t) Universe::heap()->reserved_region().end();
@@ -824,66 +837,6 @@
   }
 }
 
-/**
- * Closure for parsing a line from a *.properties file in jre/lib/jvmci/properties.
- * The line must match the regular expression "[^=]+=.*". That is one or more
- * characters other than '=' followed by '=' followed by zero or more characters.
- * Everything before the '=' is the property name and everything after '=' is the value.
- * Lines that start with '#' are treated as comments and ignored.
- * No special processing of whitespace or any escape characters is performed.
- * The last definition of a property "wins" (i.e., it overrides all earlier
- * definitions of the property).
- */
-class JVMCIPropertiesFileClosure : public ParseClosure {
-  SystemProperty** _plist;
-public:
-  JVMCIPropertiesFileClosure(SystemProperty** plist) : _plist(plist) {}
-  void do_line(char* line) {
-    if (line[0] == '#') {
-      // skip comment
-      return;
-    }
-    size_t len = strlen(line);
-    char* sep = strchr(line, '=');
-    if (sep == NULL) {
-      warn_and_abort("invalid format: could not find '=' character");
-      return;
-    }
-    if (sep == line) {
-      warn_and_abort("invalid format: name cannot be empty");
-      return;
-    }
-    *sep = '\0';
-    const char* name = line;
-    char* value = sep + 1;
-    Arguments::PropertyList_unique_add(_plist, name, value);
-  }
-};
-
-void JVMCIRuntime::init_system_properties(SystemProperty** plist) {
-  char jvmciDir[JVM_MAXPATHLEN];
-  const char* fileSep = os::file_separator();
-  jio_snprintf(jvmciDir, sizeof(jvmciDir), "%s%slib%sjvmci",
-               Arguments::get_java_home(), fileSep, fileSep, fileSep);
-  DIR* dir = os::opendir(jvmciDir);
-  if (dir != NULL) {
-    struct dirent *entry;
-    char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(jvmciDir), mtInternal);
-    JVMCIPropertiesFileClosure closure(plist);
-    const unsigned suffix_len = (unsigned)strlen(".properties");
-    while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL && !closure.is_aborted()) {
-      const char* name = entry->d_name;
-      if (strlen(name) > suffix_len && strcmp(name + strlen(name) - suffix_len, ".properties") == 0) {
-        char propertiesFilePath[JVM_MAXPATHLEN];
-        jio_snprintf(propertiesFilePath, sizeof(propertiesFilePath), "%s%s%s",jvmciDir, fileSep, name);
-        JVMCIRuntime::parse_lines(propertiesFilePath, &closure, false);
-      }
-    }
-    FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
-    os::closedir(dir);
-  }
-}
-
 #define CHECK_WARN_ABORT_(message) THREAD); \
   if (HAS_PENDING_EXCEPTION) { \
     warning(message); \
@@ -894,28 +847,15 @@
   } \
   (void)(0
 
-Handle JVMCIRuntime::create_Service(const char* name, TRAPS) {
-  TempNewSymbol kname = SymbolTable::new_symbol(name, CHECK_NH);
-  Klass* k = resolve_or_fail(kname, CHECK_NH);
-  instanceKlassHandle klass(THREAD, k);
-  klass->initialize(CHECK_NH);
-  klass->check_valid_for_instantiation(true, CHECK_NH);
-  JavaValue result(T_VOID);
-  instanceHandle service = klass->allocate_instance_handle(CHECK_NH);
-  JavaCalls::call_special(&result, service, klass, vmSymbols::object_initializer_name(), vmSymbols::void_method_signature(), THREAD);
-  return service;
-}
-
-void JVMCIRuntime::shutdown() {
+void JVMCIRuntime::shutdown(TRAPS) {
   if (_HotSpotJVMCIRuntime_instance != NULL) {
     _shutdown_called = true;
-    JavaThread* THREAD = JavaThread::current();
     HandleMark hm(THREAD);
-    Handle receiver = get_HotSpotJVMCIRuntime(CHECK_ABORT);
+    Handle receiver = get_HotSpotJVMCIRuntime(CHECK);
     JavaValue result(T_VOID);
     JavaCallArguments args;
     args.push_oop(receiver);
-    JavaCalls::call_special(&result, receiver->klass(), vmSymbols::shutdown_method_name(), vmSymbols::void_method_signature(), &args, CHECK_ABORT);
+    JavaCalls::call_special(&result, receiver->klass(), vmSymbols::shutdown_method_name(), vmSymbols::void_method_signature(), &args, CHECK);
   }
 }
 
@@ -979,6 +919,7 @@
 } \
 (void)(0
 
+
   Thread* THREAD = thread;
   HandleMark hm;
   Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_RETURN);
@@ -1072,119 +1013,3 @@
   }
   return klass;
 }
-
-void JVMCIRuntime::parse_lines(char* path, ParseClosure* closure, bool warnStatFailure) {
-  struct stat st;
-  if (::stat(path, &st) == 0 && (st.st_mode & S_IFREG) == S_IFREG) { // exists & is regular file
-    int file_handle = ::open(path, os::default_file_open_flags(), 0);
-    if (file_handle != -1) {
-      char* buffer = NEW_C_HEAP_ARRAY(char, st.st_size + 1, mtInternal);
-      int num_read;
-      num_read = (int) ::read(file_handle, (char*) buffer, st.st_size);
-      if (num_read == -1) {
-        warning("Error reading file %s due to %s", path, strerror(errno));
-      } else if (num_read != st.st_size) {
-        warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, (size_t) st.st_size, path);
-      }
-      ::close(file_handle);
-      closure->set_filename(path);
-      if (num_read == st.st_size) {
-        buffer[num_read] = '\0';
-
-        char* line = buffer;
-        while (line - buffer < num_read && !closure->is_aborted()) {
-          // find line end (\r, \n or \r\n)
-          char* nextline = NULL;
-          char* cr = strchr(line, '\r');
-          char* lf = strchr(line, '\n');
-          if (cr != NULL && lf != NULL) {
-            char* min = MIN2(cr, lf);
-            *min = '\0';
-            if (lf == cr + 1) {
-              nextline = lf + 1;
-            } else {
-              nextline = min + 1;
-            }
-          } else if (cr != NULL) {
-            *cr = '\0';
-            nextline = cr + 1;
-          } else if (lf != NULL) {
-            *lf = '\0';
-            nextline = lf + 1;
-          }
-          // trim left
-          while (*line == ' ' || *line == '\t') line++;
-          char* end = line + strlen(line);
-          // trim right
-          while (end > line && (*(end -1) == ' ' || *(end -1) == '\t')) end--;
-          *end = '\0';
-          // skip comments and empty lines
-          if (*line != '#' && strlen(line) > 0) {
-            closure->parse_line(line);
-          }
-          if (nextline != NULL) {
-            line = nextline;
-          } else {
-            // File without newline at the end
-            break;
-          }
-        }
-      }
-      FREE_C_HEAP_ARRAY(char, buffer, mtInternal);
-    } else {
-      warning("Error opening file %s due to %s", path, strerror(errno));
-    }
-  } else if (warnStatFailure) {
-    warning("Could not stat file %s due to %s", path, strerror(errno));
-  }
-}
-
-class ServiceParseClosure : public ParseClosure {
-  GrowableArray<char*> _implNames;
-public:
-  ServiceParseClosure() : _implNames() {}
-  void do_line(char* line) {
-    size_t lineLen = strlen(line);
-    char* implName = NEW_RESOURCE_ARRAY(char, lineLen + 1);
-    // Turn all '.'s into '/'s
-    for (size_t index = 0; index < lineLen; ++index) {
-      if (line[index] == '.') {
-        implName[index] = '/';
-      } else {
-        implName[index] = line[index];
-      }
-    }
-    implName[lineLen] = '\0';
-    _implNames.append(implName);
-  }
-  GrowableArray<char*>* implNames() {return &_implNames;}
-};
-
-
-objArrayHandle JVMCIRuntime::get_service_impls(KlassHandle serviceKlass, TRAPS) {
-  const char* home = Arguments::get_java_home();
-  const char* serviceName = serviceKlass->external_name();
-  char* path;
-  char sep = os::file_separator()[0];
-  if (JVMCIServicesDir == NULL) {
-    size_t path_len = strlen(home) + strlen("/lib/jvmci/services/") + strlen(serviceName) + 1;
-    path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len);
-    sprintf(path, "%s%clib%cjvmci%cservices%c%s", home, sep, sep, sep, sep, serviceName);
-  } else {
-    size_t path_len = strlen(JVMCIServicesDir) + strlen(serviceName) + 1;
-    path = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, path_len);
-    sprintf(path, "%s%c%s", JVMCIServicesDir, sep, serviceName);
-  }
-  ServiceParseClosure closure;
-  parse_lines(path, &closure, false);
-
-  GrowableArray<char*>* implNames = closure.implNames();
-  objArrayOop servicesOop = oopFactory::new_objArray(serviceKlass(), implNames->length(), CHECK_(objArrayHandle()));
-  objArrayHandle services(THREAD, servicesOop);
-  for (int i = 0; i < implNames->length(); ++i) {
-    char* implName = implNames->at(i);
-    Handle service = create_Service(implName, CHECK_(objArrayHandle()));
-    services->obj_at_put(i, service());
-  }
-  return services;
-}
--- a/src/share/vm/jvmci/jvmciRuntime.hpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmciRuntime.hpp	Mon May 30 22:56:59 2016 +0200
@@ -29,8 +29,6 @@
 #include "runtime/arguments.hpp"
 #include "runtime/deoptimization.hpp"
 
-
-
 #define JVMCI_ERROR(...)       \
   { JVMCIRuntime::fthrow_error(THREAD_AND_LOCATION, __VA_ARGS__); return; }
 
@@ -42,31 +40,6 @@
 #define JVMCI_ERROR_OK(...)   JVMCI_ERROR_(JVMCIEnv::ok, __VA_ARGS__)
 #define CHECK_OK              CHECK_(JVMCIEnv::ok)
 
-class ParseClosure : public StackObj {
-  int _lineNo;
-  char* _filename;
-  bool _abort;
-protected:
-  void abort() { _abort = true; }
-  void warn_and_abort(const char* message) {
-    warn(message);
-    abort();
-  }
-  void warn(const char* message) {
-    warning("Error at line %d while parsing %s: %s", _lineNo, _filename == NULL ? "?" : _filename, message);
-  }
- public:
-  ParseClosure() : _lineNo(0), _filename(NULL), _abort(false) {}
-  void parse_line(char* line) {
-    _lineNo++;
-    do_line(line);
-  }
-  virtual void do_line(char* line) = 0;
-  int lineNo() { return _lineNo; }
-  bool is_aborted() { return _abort; }
-  void set_filename(char* path) {_filename = path; _lineNo = 0;}
-};
-
 class JVMCIRuntime: public AllStatic {
  public:
   // Constants describing whether JVMCI wants to be able to adjust the compilation
@@ -76,7 +49,7 @@
      none = 0,             // no adjustment
      by_holder = 1,        // adjust based on declaring class of method
      by_full_signature = 2 // adjust based on declaring class, name and signature of method
-   };
+  };
 
  private:
   static jobject _HotSpotJVMCIRuntime_instance;
@@ -89,20 +62,9 @@
 
   static bool _shutdown_called;
 
-  /**
-   * Instantiates a service object, calls its default constructor and returns it.
-   *
-   * @param name the name of a service provider class
-   */
-  static Handle create_Service(const char* name, TRAPS);
-
   static CompLevel adjust_comp_level_inner(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread);
 
  public:
-  /**
-   * Parses *.properties files in jre/lib/jvmci/ and adds the properties to plist.
-   */
-  static void init_system_properties(SystemProperty** plist);
 
   /**
    * Ensures that the JVMCI class loader is initialized and the well known JVMCI classes are loaded.
@@ -141,7 +103,7 @@
 
   static void metadata_do(void f(Metadata*));
 
-  static void shutdown();
+  static void shutdown(TRAPS);
 
   static void bootstrap_finished(TRAPS);
 
@@ -164,14 +126,6 @@
   static CompLevel adjust_comp_level(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread);
 
   /**
-   * Given an interface representing a JVMCI service, gets an array of objects, one per
-   * known implementation of the service.
-   */
-  static objArrayHandle get_service_impls(KlassHandle serviceKlass, TRAPS);
-
-  static void parse_lines(char* path, ParseClosure* closure, bool warnStatFailure);
-
-  /**
    * Throws a JVMCIError with a formatted error message. Ideally we would use
    * a variation of Exceptions::fthrow that takes a class loader argument but alas,
    * no such variation exists.
@@ -216,7 +170,7 @@
    */
   static Klass* load_required_class(Symbol* name);
 
-  static BasicType kindToBasicType(jchar ch, TRAPS);
+  static BasicType kindToBasicType(Handle kind, TRAPS);
 
   // The following routines are all called from compiled JVMCI code
 
--- a/src/share/vm/jvmci/jvmci_globals.hpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/jvmci/jvmci_globals.hpp	Mon May 30 22:56:59 2016 +0200
@@ -55,9 +55,6 @@
   product(bool, UseJVMCIClassLoader, true,                                  \
           "Load JVMCI classes with separate class loader")                  \
                                                                             \
-  product(ccstr, JVMCIServicesDir, NULL,                                    \
-          "Alternate directory to use for JVMCI services")                  \
-                                                                            \
   product(bool, BootstrapJVMCI, false,                                      \
           "Bootstrap JVMCI before running Java main method")                \
                                                                             \
@@ -98,10 +95,7 @@
           "Maximum size of a compiled method.")                             \
                                                                             \
   develop(bool, TraceUncollectedSpeculations, false,                        \
-          "Print message when a failed speculation was not collected")      \
-  product(bool, TraceClassLoadingStack, false,                              \
-          "Print stack when loading a class")                               \
-                                                                            \
+          "Print message when a failed speculation was not collected")
 
 
 // Read default values for JVMCI globals
--- a/src/share/vm/prims/nativeLookup.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/prims/nativeLookup.cpp	Mon May 30 22:56:59 2016 +0200
@@ -130,7 +130,7 @@
   void     JNICALL JVM_InitJVMCIClassLoader(JNIEnv *env, jclass c, jobject loader);
   void     JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);
   jobject  JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
-  jobject  JNICALL JVM_GetJVMCIServiceImpls(JNIEnv *env, jclass c, jclass serviceClass);
+  jobject  JNICALL JVM_GetJVMCIClassLoader(JNIEnv *env, jclass c);
 #endif
 }
 
@@ -145,7 +145,7 @@
 #if INCLUDE_JVMCI
   { CC"Java_jdk_vm_ci_services_JVMCIClassLoaderFactory_init", NULL, FN_PTR(JVM_InitJVMCIClassLoader)     },
   { CC"Java_jdk_vm_ci_runtime_JVMCI_initializeRuntime",       NULL, FN_PTR(JVM_GetJVMCIRuntime)          },
-  { CC"Java_jdk_vm_ci_services_Services_getServiceImpls",     NULL, FN_PTR(JVM_GetJVMCIServiceImpls)     },
+  { CC"Java_jdk_vm_ci_services_Services_getJVMCIClassLoader", NULL, FN_PTR(JVM_GetJVMCIClassLoader)      },
   { CC"Java_jdk_vm_ci_hotspot_CompilerToVM_registerNatives",  NULL, FN_PTR(JVM_RegisterJVMCINatives)     },
 #endif
 };
--- a/src/share/vm/runtime/arguments.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/runtime/arguments.cpp	Mon May 30 22:56:59 2016 +0200
@@ -44,9 +44,6 @@
 #include "utilities/macros.hpp"
 #include "utilities/stringUtils.hpp"
 #include "utilities/taskqueue.hpp"
-#if INCLUDE_JVMCI
-#include "jvmci/jvmciRuntime.hpp"
-#endif
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
 #endif
@@ -212,10 +209,6 @@
 
   // Set OS specific system properties values
   os::init_system_properties_values();
-
-#if INCLUDE_JVMCI
-  JVMCIRuntime::init_system_properties(&_system_properties);
-#endif
 }
 
 
@@ -2445,14 +2438,25 @@
   }
 #if INCLUDE_JVMCI
   if (!EnableJVMCI) {
-    warning("ignoring flag -EnableJVMCI, JVMCI can not be disabled in this VM");
-  }
-  if (BootstrapJVMCI && !UseJVMCICompiler) {
-    warning("BootstrapJVMCI has no effect if UseJVMCICompiler is disabled");
-  }
-  if (!ScavengeRootsInCode) {
-    warning("forcing ScavengeRootsInCode non-zero because JVMCI is enabled");
-    ScavengeRootsInCode = 1;
+#define JVMCI_CHECK3(type, name, doc)        JVMCI_CHECK_FLAG(name)
+#define JVMCI_CHECK4(type, name, value, doc) JVMCI_CHECK_FLAG(name)
+#define JVMCI_CHECK_FLAG(FLAG)                         \
+    if (!FLAG_IS_DEFAULT(FLAG)) {                                   \
+      jio_fprintf(defaultStream::error_stream(), "EnableJVMCI must be enabled to use VM option '%s'\n", #FLAG); \
+      status = false; \
+    }
+    JVMCI_FLAGS(JVMCI_CHECK4, JVMCI_CHECK3, JVMCI_CHECK4, JVMCI_CHECK3, JVMCI_CHECK4)
+#undef JVMCI_CHECK3
+#undef JVMCI_CHECK4
+#undef JVMCI_CHECK_FLAG
+  } else {
+    if (BootstrapJVMCI && !UseJVMCICompiler) {
+      warning("BootstrapJVMCI has no effect if UseJVMCICompiler is disabled");
+    }
+    if (!ScavengeRootsInCode) {
+      warning("forcing ScavengeRootsInCode non-zero because JVMCI is enabled");
+      ScavengeRootsInCode = 1;
+    }
   }
 #endif
 
@@ -3611,7 +3615,11 @@
       FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
       os::closedir(dir);
     }
-
+    const char* path = Arguments::get_property("jvmci.class.path.append");
+    if (path != NULL) {
+      scp_p->add_suffix(path);
+      scp_assembly_required = true;
+    }
   }
 #endif
 
--- a/src/share/vm/runtime/java.cpp	Mon May 30 14:11:39 2016 +0200
+++ b/src/share/vm/runtime/java.cpp	Mon May 30 22:56:59 2016 +0200
@@ -491,7 +491,16 @@
   }
 
 #if INCLUDE_JVMCI
-  JVMCIRuntime::shutdown();
+  // We are not using CATCH here because we want the exit to continue normally.
+  Thread* THREAD = thread;
+  JVMCIRuntime::shutdown(THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    Handle exception(THREAD, PENDING_EXCEPTION);
+    CLEAR_PENDING_EXCEPTION;
+    java_lang_Throwable::print(exception, tty);
+    tty->cr();
+    java_lang_Throwable::print_stack_trace(exception(), tty);
+  }
 #endif
 
   // The only difference between this and Win32's _onexit procs is that