changeset 56022:ad45b3802d4e

8220623: [JVMCI] Update JVMCI to support JVMCI based Compiler compiled into shared library Reviewed-by: dnsimon, never, stefank, rehn, neliasso, dholmes, kbarrett, coleenp
author kvn
date Wed, 01 May 2019 12:31:29 -0700
parents 0bda2308eded
children a38438fcbbd2
files make/autoconf/hotspot.m4 src/hotspot/.mx.jvmci/suite.py src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp src/hotspot/cpu/sparc/jvmciCodeInstaller_sparc.cpp src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp src/hotspot/share/aot/aotCompiledMethod.cpp src/hotspot/share/aot/aotLoader.cpp src/hotspot/share/classfile/javaClasses.cpp src/hotspot/share/classfile/javaClasses.hpp src/hotspot/share/classfile/metadataOnStackMark.cpp src/hotspot/share/classfile/systemDictionary.cpp src/hotspot/share/classfile/systemDictionary.hpp src/hotspot/share/classfile/vmSymbols.hpp src/hotspot/share/code/nmethod.cpp src/hotspot/share/code/nmethod.hpp src/hotspot/share/compiler/abstractCompiler.hpp src/hotspot/share/compiler/compileBroker.cpp src/hotspot/share/compiler/compileTask.cpp src/hotspot/share/compiler/compilerDefinitions.cpp src/hotspot/share/compiler/disassembler.cpp src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp src/hotspot/share/gc/g1/g1RootProcessor.cpp src/hotspot/share/gc/g1/g1RootProcessor.hpp src/hotspot/share/gc/parallel/pcTasks.cpp src/hotspot/share/gc/parallel/pcTasks.hpp src/hotspot/share/gc/parallel/psMarkSweep.cpp src/hotspot/share/gc/parallel/psParallelCompact.cpp src/hotspot/share/gc/parallel/psScavenge.cpp src/hotspot/share/gc/parallel/psTasks.cpp src/hotspot/share/gc/parallel/psTasks.hpp src/hotspot/share/gc/serial/genMarkSweep.cpp src/hotspot/share/gc/shared/genCollectedHeap.cpp src/hotspot/share/gc/shared/genCollectedHeap.hpp src/hotspot/share/gc/shared/parallelCleaning.cpp src/hotspot/share/gc/shared/parallelCleaning.hpp src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp src/hotspot/share/jvmci/jniAccessMark.inline.hpp src/hotspot/share/jvmci/jvmci.cpp src/hotspot/share/jvmci/jvmci.hpp src/hotspot/share/jvmci/jvmciCodeInstaller.cpp src/hotspot/share/jvmci/jvmciCodeInstaller.hpp src/hotspot/share/jvmci/jvmciCompiler.cpp src/hotspot/share/jvmci/jvmciCompiler.hpp src/hotspot/share/jvmci/jvmciCompilerToVM.cpp src/hotspot/share/jvmci/jvmciCompilerToVM.hpp src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp src/hotspot/share/jvmci/jvmciEnv.cpp src/hotspot/share/jvmci/jvmciEnv.hpp src/hotspot/share/jvmci/jvmciExceptions.hpp src/hotspot/share/jvmci/jvmciJavaClasses.cpp src/hotspot/share/jvmci/jvmciJavaClasses.hpp src/hotspot/share/jvmci/jvmciObject.hpp src/hotspot/share/jvmci/jvmciRuntime.cpp src/hotspot/share/jvmci/jvmciRuntime.hpp src/hotspot/share/jvmci/jvmci_globals.cpp src/hotspot/share/jvmci/jvmci_globals.hpp src/hotspot/share/jvmci/metadataHandleBlock.cpp src/hotspot/share/jvmci/metadataHandleBlock.hpp src/hotspot/share/jvmci/systemDictionary_jvmci.hpp src/hotspot/share/jvmci/vmStructs_jvmci.cpp src/hotspot/share/jvmci/vmSymbols_jvmci.hpp src/hotspot/share/memory/allocation.hpp src/hotspot/share/oops/method.cpp src/hotspot/share/oops/methodData.cpp src/hotspot/share/oops/methodData.hpp src/hotspot/share/opto/chaitin.cpp src/hotspot/share/prims/jni.cpp src/hotspot/share/prims/jvmtiTagMap.cpp src/hotspot/share/prims/nativeLookup.hpp src/hotspot/share/runtime/arguments.cpp src/hotspot/share/runtime/deoptimization.cpp src/hotspot/share/runtime/frame.cpp src/hotspot/share/runtime/init.cpp src/hotspot/share/runtime/java.cpp src/hotspot/share/runtime/javaCalls.cpp src/hotspot/share/runtime/mutexLocker.cpp src/hotspot/share/runtime/mutexLocker.hpp src/hotspot/share/runtime/thread.cpp src/hotspot/share/runtime/thread.hpp src/hotspot/share/runtime/tieredThresholdPolicy.cpp src/hotspot/share/runtime/vmOperations.cpp src/java.base/share/classes/module-info.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Architecture.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodePosition.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeCacheProvider.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InstalledCode.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/InvalidInstalledCodeException.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/InitTimer.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/NativeImageReinitialize.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotVMConfig.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotVMConfig.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Cleaner.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HandleCleaner.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequest.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPoolObject.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJDKReflection.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIReflection.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIUnsupportedOperationError.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodDataAccessor.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotNmethod.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaType.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotRuntimeStub.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationEncoding.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfigAccess.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceHandleObject.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceObject.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/MetaspaceWrapperObject.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SharedLibraryJVMCIReflection.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/TranslatedException.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMEntryPoint.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMField.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMFlag.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/VMIntrinsicMethod.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaTypeProfile.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PrimitiveConstant.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCI.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/.checkstyle_checks.xml src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/VMEntryPoint.java src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.sparc/src/jdk/vm/ci/sparc/SPARC.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.amd64/src/org/graalvm/compiler/hotspot/amd64/AMD64HotSpotLoweringProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.serviceprovider/src/org/graalvm/compiler/serviceprovider/GraalServices.java test/hotspot/jtreg/compiler/jvmci/SecurityRestrictionsTest.java test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/PublicMetaspaceWrapperObject.java test/hotspot/jtreg/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java test/hotspot/jtreg/compiler/jvmci/compilerToVM/ExecuteInstalledCodeTest.java test/hotspot/jtreg/compiler/jvmci/compilerToVM/GetConstantPoolTest.java test/hotspot/jtreg/compiler/jvmci/compilerToVM/GetResolvedJavaMethodTest.java test/hotspot/jtreg/compiler/jvmci/compilerToVM/GetResolvedJavaTypeTest.java test/hotspot/jtreg/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java test/hotspot/jtreg/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java test/hotspot/jtreg/compiler/jvmci/errors/CodeInstallerTest.java test/hotspot/jtreg/compiler/jvmci/events/JvmciNotifyInstallEventTest.java test/hotspot/jtreg/compiler/jvmci/events/JvmciShutdownEventListener.java test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHotSpotSpeculationLog.java test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaMethod.java test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestSpeculationLog.java test/hotspot/jtreg/runtime/NMT/MallocSiteTypeChange.java
diffstat 174 files changed, 12893 insertions(+), 5309 deletions(-) [+]
line wrap: on
line diff
--- a/make/autoconf/hotspot.m4	Wed May 01 12:41:26 2019 -0400
+++ b/make/autoconf/hotspot.m4	Wed May 01 12:31:29 2019 -0700
@@ -392,9 +392,8 @@
     JVM_FEATURES_jvmci=""
     INCLUDE_JVMCI="false"
   else
-    # Only enable jvmci on x86_64, sparcv9 and aarch64
+    # Only enable jvmci on x86_64 and aarch64
     if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
-       test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \
        test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
       AC_MSG_RESULT([yes])
       JVM_FEATURES_jvmci="jvmci"
--- a/src/hotspot/.mx.jvmci/suite.py	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/.mx.jvmci/suite.py	Wed May 01 12:31:29 2019 -0700
@@ -56,6 +56,9 @@
     "jdk.vm.ci.common" : {
       "subDir" : "../jdk.internal.vm.ci/share/classes",
       "sourceDirs" : ["src"],
+      "dependencies" : [
+        "jdk.vm.ci.services",
+      ],
       "checkstyle" : "jdk.vm.ci.services",
       "javaCompliance" : "9+",
       "workingSets" : "API,JVMCI",
@@ -258,9 +261,11 @@
       "subDir" : "../../test/hotspot/jtreg/compiler/jvmci",
       "dependencies" : [
         "jdk.vm.ci.runtime.test",
+        "jdk.vm.ci.hotspot.test",
       ],
       "distDependencies" : [
         "JVMCI_API",
+        "JVMCI_HOTSPOT",
       ],
       "exclude" : ["mx:JUNIT"],
     },
--- a/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/cpu/aarch64/jvmciCodeInstaller_aarch64.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -30,7 +30,7 @@
 #include "runtime/sharedRuntime.hpp"
 #include "vmreg_aarch64.inline.hpp"
 
-jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) {
+jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS) {
   if (inst->is_call() || inst->is_jump() || inst->is_blr()) {
     return pc_offset + NativeCall::instruction_size;
   } else if (inst->is_general_jump()) {
@@ -43,12 +43,12 @@
   }
 }
 
-void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) {
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
 #ifdef ASSERT
   {
     NativeInstruction *insn = nativeInstruction_at(pc);
-    if (HotSpotObjectConstantImpl::compressed(constant)) {
+    if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) {
       // Mov narrow constant: movz n << 16, movk
       assert(Instruction_aarch64::extract(insn->encoding(), 31, 21) == 0b11010010101 &&
              nativeInstruction_at(pc+4)->is_movk(), "wrong insn in patch");
@@ -59,7 +59,7 @@
     }
   }
 #endif // ASSERT
-  Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant));
+  Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK);
   jobject value = JNIHandles::make_local(obj());
   MacroAssembler::patch_oop(pc, (address)obj());
   int oop_index = _oop_recorder->find_index(value);
@@ -67,21 +67,21 @@
   _instructions->relocate(pc, rspec);
 }
 
-void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
+void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
-  if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
-    narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, CHECK);
+  if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) {
+    narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, JVMCI_CHECK);
     MacroAssembler::patch_narrow_klass(pc, narrowOop);
     TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop);
   } else {
     NativeMovConstReg* move = nativeMovConstReg_at(pc);
-    void* reference = record_metadata_reference(_instructions, pc, constant, CHECK);
+    void* reference = record_metadata_reference(_instructions, pc, constant, JVMCI_CHECK);
     move->set_data((intptr_t) reference);
     TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference));
   }
 }
 
-void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
   NativeInstruction* inst = nativeInstruction_at(pc);
   if (inst->is_adr_aligned() || inst->is_ldr_literal()
@@ -94,7 +94,7 @@
   }
 }
 
-void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) {
+void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS) {
   address pc = (address) inst;
   if (inst->is_call()) {
     NativeCall* call = nativeCall_at(pc);
@@ -118,12 +118,12 @@
   TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst));
 }
 
-void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &cbuf, Handle hotspot_method, jint pc_offset, TRAPS) {
+void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &cbuf, JVMCIObject hotspot_method, jint pc_offset, JVMCI_TRAPS) {
 #ifdef ASSERT
   Method* method = NULL;
   // we need to check, this might also be an unresolved method
-  if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
-    method = getMethodFromHotSpotMethod(hotspot_method());
+  if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(hotspot_method)) {
+    method = JVMCIENV->asMethod(hotspot_method);
   }
 #endif
   switch (_next_call_type) {
@@ -157,7 +157,7 @@
   }
 }
 
-void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
+void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
   switch (mark) {
     case POLL_NEAR:
       JVMCI_ERROR("unimplemented");
@@ -178,7 +178,7 @@
 }
 
 // convert JVMCI register indices (as used in oop maps) to HotSpot registers
-VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
+VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
   if (jvmci_reg < RegisterImpl::number_of_registers) {
     return as_Register(jvmci_reg)->as_VMReg();
   } else {
--- a/src/hotspot/cpu/sparc/jvmciCodeInstaller_sparc.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/cpu/sparc/jvmciCodeInstaller_sparc.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -31,7 +31,7 @@
 #include "utilities/align.hpp"
 #include "vmreg_sparc.inline.hpp"
 
-jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) {
+jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS) {
   if (inst->is_call() || inst->is_jump()) {
     return pc_offset + NativeCall::instruction_size;
   } else if (inst->is_call_reg()) {
@@ -44,11 +44,11 @@
   }
 }
 
-void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) {
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
-  Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant));
+  Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK);
   jobject value = JNIHandles::make_local(obj());
-  if (HotSpotObjectConstantImpl::compressed(constant)) {
+  if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) {
     int oop_index = _oop_recorder->find_index(value);
     RelocationHolder rspec = oop_Relocation::spec(oop_index);
     _instructions->relocate(pc, rspec, 1);
@@ -64,22 +64,22 @@
   }
 }
 
-void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
+void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
-  if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
+  if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) {
     NativeMovConstReg32* move = nativeMovConstReg32_at(pc);
-    narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, CHECK);
+    narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, JVMCI_CHECK);
     move->set_data((intptr_t)narrowOop);
     TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop);
   } else {
     NativeMovConstReg* move = nativeMovConstReg_at(pc);
-    void* reference = record_metadata_reference(_instructions, pc, constant, CHECK);
+    void* reference = record_metadata_reference(_instructions, pc, constant, JVMCI_CHECK);
     move->set_data((intptr_t)reference);
     TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference));
   }
 }
 
-void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
   NativeInstruction* inst = nativeInstruction_at(pc);
   NativeInstruction* inst1 = nativeInstruction_at(pc + 4);
@@ -100,7 +100,7 @@
   }
 }
 
-void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) {
+void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS) {
   address pc = (address) inst;
   if (inst->is_call()) {
     NativeCall* call = nativeCall_at(pc);
@@ -116,12 +116,12 @@
   TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst));
 }
 
-void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, Handle hotspot_method, jint pc_offset, TRAPS) {
+void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_method, jint pc_offset, JVMCI_TRAPS) {
 #ifdef ASSERT
   Method* method = NULL;
   // we need to check, this might also be an unresolved method
-  if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
-    method = getMethodFromHotSpotMethod(hotspot_method());
+  if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(hotspot_method)) {
+    method = JVMCIENV->asMethod(hotspot_method);
   }
 #endif
   switch (_next_call_type) {
@@ -155,7 +155,7 @@
   }
 }
 
-void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
+void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
   switch (mark) {
     case POLL_NEAR:
       JVMCI_ERROR("unimplemented");
@@ -176,7 +176,7 @@
 }
 
 // convert JVMCI register indices (as used in oop maps) to HotSpot registers
-VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
+VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
   // JVMCI Registers are numbered as follows:
   //   0..31: Thirty-two General Purpose registers (CPU Registers)
   //   32..63: Thirty-two single precision float registers
--- a/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/cpu/x86/jvmciCodeInstaller_x86.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -37,7 +37,7 @@
 #include "code/vmreg.hpp"
 #include "vmreg_x86.inline.hpp"
 
-jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) {
+jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS) {
   if (inst->is_call() || inst->is_jump()) {
     assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
     return (pc_offset + NativeCall::instruction_size);
@@ -54,7 +54,7 @@
     return (offset);
   } else if (inst->is_call_reg()) {
     // the inlined vtable stub contains a "call register" instruction
-    assert(method.not_null(), "only valid for virtual calls");
+    assert(method.is_non_null(), "only valid for virtual calls");
     return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
   } else if (inst->is_cond_jump()) {
     address pc = (address) (inst);
@@ -64,11 +64,12 @@
   }
 }
 
-void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) {
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
-  Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant));
+  Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK);
+  Thread* THREAD = Thread::current();
   jobject value = JNIHandles::make_local(obj());
-  if (HotSpotObjectConstantImpl::compressed(constant)) {
+  if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) {
 #ifdef _LP64
     address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
     int oop_index = _oop_recorder->find_index(value);
@@ -85,24 +86,24 @@
   }
 }
 
-void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
+void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
-  if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
+  if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) {
 #ifdef _LP64
     address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
-    *((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, constant, CHECK);
+    *((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, constant, JVMCI_CHECK);
     TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
 #else
     JVMCI_ERROR("compressed Klass* on 32bit");
 #endif
   } else {
     address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
-    *((void**) operand) = record_metadata_reference(_instructions, operand, constant, CHECK);
+    *((void**) operand) = record_metadata_reference(_instructions, operand, constant, JVMCI_CHECK);
     TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
   }
 }
 
-void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS) {
   address pc = _instructions->start() + pc_offset;
 
   address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
@@ -117,7 +118,7 @@
   TRACE_jvmci_3("relocating at " PTR_FORMAT "/" PTR_FORMAT " with destination at " PTR_FORMAT " (%d)", p2i(pc), p2i(operand), p2i(dest), data_offset);
 }
 
-void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) {
+void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS) {
   address pc = (address) inst;
   if (inst->is_call()) {
     // NOTE: for call without a mov, the offset must fit a 32-bit immediate
@@ -145,12 +146,12 @@
   TRACE_jvmci_3("relocating (foreign call)  at " PTR_FORMAT, p2i(inst));
 }
 
-void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, Handle hotspot_method, jint pc_offset, TRAPS) {
+void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_method, jint pc_offset, JVMCI_TRAPS) {
 #ifdef ASSERT
   Method* method = NULL;
   // we need to check, this might also be an unresolved method
-  if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
-    method = getMethodFromHotSpotMethod(hotspot_method());
+  if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(hotspot_method)) {
+    method = JVMCIENV->asMethod(hotspot_method);
   }
 #endif
   switch (_next_call_type) {
@@ -199,7 +200,7 @@
 }
 
 
-void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
+void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
   switch (mark) {
     case POLL_NEAR: {
       relocate_poll_near(pc);
@@ -229,7 +230,7 @@
 }
 
 // convert JVMCI register indices (as used in oop maps) to HotSpot registers
-VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
+VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
   if (jvmci_reg < RegisterImpl::number_of_registers) {
     return as_Register(jvmci_reg)->as_VMReg();
   } else {
--- a/src/hotspot/share/aot/aotCompiledMethod.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/aot/aotCompiledMethod.cpp	Wed May 01 12:31:29 2019 -0700
@@ -32,8 +32,6 @@
 #include "compiler/compilerOracle.hpp"
 #include "gc/shared/cardTableBarrierSet.hpp"
 #include "gc/shared/collectedHeap.hpp"
-#include "jvmci/compilerRuntime.hpp"
-#include "jvmci/jvmciRuntime.hpp"
 #include "oops/method.inline.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/aot/aotLoader.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/aot/aotLoader.cpp	Wed May 01 12:31:29 2019 -0700
@@ -26,8 +26,8 @@
 
 #include "aot/aotCodeHeap.hpp"
 #include "aot/aotLoader.inline.hpp"
-#include "jvmci/jvmciRuntime.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/resourceArea.hpp"
 #include "oops/method.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/os.inline.hpp"
--- a/src/hotspot/share/classfile/javaClasses.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Wed May 01 12:31:29 2019 -0700
@@ -2607,6 +2607,45 @@
   }
 }
 
+#if INCLUDE_JVMCI
+void java_lang_StackTraceElement::decode(Handle mirror, methodHandle method, int bci, Symbol*& methodname, Symbol*& filename, int& line_number) {
+  int method_id = method->orig_method_idnum();
+  int cpref = method->name_index();
+  decode(mirror, method_id, method->constants()->version(), bci, cpref, methodname, filename, line_number);
+}
+
+void java_lang_StackTraceElement::decode(Handle mirror, int method_id, int version, int bci, int cpref, Symbol*& methodname, Symbol*& filename, int& line_number) {
+  // Fill in class name
+  InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
+  Method* method = holder->method_with_orig_idnum(method_id, version);
+
+  // The method can be NULL if the requested class version is gone
+  Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
+
+  // Fill in method name
+  methodname = sym;
+
+  if (!version_matches(method, version)) {
+    // If the method was redefined, accurate line number information isn't available
+    filename = NULL;
+    line_number = -1;
+  } else {
+    // Fill in source file name and line number.
+    // Use a specific ik version as a holder since the mirror might
+    // refer to a version that is now obsolete and no longer accessible
+    // via the previous versions list.
+    holder = holder->get_klass_version(version);
+    assert(holder != NULL, "sanity check");
+    Symbol* source = holder->source_file_name();
+    if (ShowHiddenFrames && source == NULL) {
+      source = vmSymbols::unknown_class_name();
+    }
+    filename = source;
+    line_number = Backtrace::get_line_number(method, bci);
+  }
+}
+#endif // INCLUDE_JVMCI
+
 Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) {
   HandleMark hm(THREAD);
   Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));
--- a/src/hotspot/share/classfile/javaClasses.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Wed May 01 12:31:29 2019 -0700
@@ -1368,6 +1368,11 @@
   static void compute_offsets();
   static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
 
+#if INCLUDE_JVMCI
+  static void decode(Handle mirror, int method, int version, int bci, int cpref, Symbol*& methodName, Symbol*& fileName, int& lineNumber);
+  static void decode(Handle mirror, methodHandle method, int bci, Symbol*& methodName, Symbol*& fileName, int& lineNumber);
+#endif
+
   // Debugging
   friend class JavaClasses;
 };
--- a/src/hotspot/share/classfile/metadataOnStackMark.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/classfile/metadataOnStackMark.cpp	Wed May 01 12:31:29 2019 -0700
@@ -33,7 +33,7 @@
 #include "services/threadService.hpp"
 #include "utilities/chunkedList.hpp"
 #if INCLUDE_JVMCI
-#include "jvmci/jvmciRuntime.hpp"
+#include "jvmci/jvmci.hpp"
 #endif
 
 MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL;
@@ -73,7 +73,7 @@
     JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
     ThreadService::metadata_do(Metadata::mark_on_stack);
 #if INCLUDE_JVMCI
-    JVMCIRuntime::metadata_do(Metadata::mark_on_stack);
+    JVMCI::metadata_do(Metadata::mark_on_stack);
 #endif
   }
 }
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Wed May 01 12:31:29 2019 -0700
@@ -86,9 +86,6 @@
 #if INCLUDE_CDS
 #include "classfile/systemDictionaryShared.hpp"
 #endif
-#if INCLUDE_JVMCI
-#include "jvmci/jvmciRuntime.hpp"
-#endif
 #if INCLUDE_JFR
 #include "jfr/jfr.hpp"
 #endif
@@ -1922,13 +1919,6 @@
   Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
   InstanceKlass** klassp = &_well_known_klasses[id];
 
-
-#if INCLUDE_JVMCI
-  if (id >= FIRST_JVMCI_WKID) {
-    assert(EnableJVMCI, "resolve JVMCI classes only when EnableJVMCI is true");
-  }
-#endif
-
   if ((*klassp) == NULL) {
     Klass* k = resolve_or_fail(symbol, true, CHECK_0);
     (*klassp) = InstanceKlass::cast(k);
@@ -2017,7 +2007,7 @@
   WKID jsr292_group_end   = WK_KLASS_ENUM_NAME(VolatileCallSite_klass);
   resolve_wk_klasses_until(jsr292_group_start, scan, CHECK);
   resolve_wk_klasses_through(jsr292_group_end, scan, CHECK);
-  WKID last = NOT_JVMCI(WKID_LIMIT) JVMCI_ONLY(FIRST_JVMCI_WKID);
+  WKID last = WKID_LIMIT;
   resolve_wk_klasses_until(last, scan, CHECK);
 
   _box_klasses[T_BOOLEAN] = WK_KLASS(Boolean_klass);
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Wed May 01 12:31:29 2019 -0700
@@ -26,7 +26,6 @@
 #define SHARE_CLASSFILE_SYSTEMDICTIONARY_HPP
 
 #include "classfile/classLoaderData.hpp"
-#include "jvmci/systemDictionary_jvmci.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/java.hpp"
@@ -215,9 +214,6 @@
   do_klass(Integer_klass,                               java_lang_Integer                                     ) \
   do_klass(Long_klass,                                  java_lang_Long                                        ) \
                                                                                                                 \
-  /* JVMCI classes. These are loaded on-demand. */                                                              \
-  JVMCI_WK_KLASSES_DO(do_klass)                                                                                 \
-                                                                                                                \
   /*end*/
 
 
@@ -236,11 +232,6 @@
 
     WKID_LIMIT,
 
-#if INCLUDE_JVMCI
-    FIRST_JVMCI_WKID = WK_KLASS_ENUM_NAME(JVMCI_klass),
-    LAST_JVMCI_WKID  = WK_KLASS_ENUM_NAME(Value_klass),
-#endif
-
     FIRST_WKID = NO_WKID + 1
   };
 
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Wed May 01 12:31:29 2019 -0700
@@ -358,8 +358,7 @@
   template(destroyed_name,                            "destroyed")                                \
   template(nthreads_name,                             "nthreads")                                 \
   template(ngroups_name,                              "ngroups")                                  \
-  template(shutdown_method_name,                      "shutdown")                                 \
-  template(bootstrapFinished_method_name,             "bootstrapFinished")                        \
+  template(shutdown_name,                             "shutdown")                                 \
   template(finalize_method_name,                      "finalize")                                 \
   template(reference_lock_name,                       "lock")                                     \
   template(reference_discovered_name,                 "discovered")                               \
--- a/src/hotspot/share/code/nmethod.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/code/nmethod.cpp	Wed May 01 12:31:29 2019 -0700
@@ -64,7 +64,7 @@
 #include "utilities/resourceHash.hpp"
 #include "utilities/xmlstream.hpp"
 #if INCLUDE_JVMCI
-#include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciRuntime.hpp"
 #endif
 
 #ifdef DTRACE_ENABLED
@@ -112,6 +112,10 @@
   int dependencies_size;
   int handler_table_size;
   int nul_chk_table_size;
+#if INCLUDE_JVMCI
+  int speculations_size;
+  int jvmci_data_size;
+#endif
   int oops_size;
   int metadata_size;
 
@@ -129,6 +133,10 @@
     dependencies_size   += nm->dependencies_size();
     handler_table_size  += nm->handler_table_size();
     nul_chk_table_size  += nm->nul_chk_table_size();
+#if INCLUDE_JVMCI
+    speculations_size   += nm->speculations_size();
+    jvmci_data_size     += nm->jvmci_data_size();
+#endif
   }
   void print_nmethod_stats(const char* name) {
     if (nmethod_count == 0)  return;
@@ -146,6 +154,10 @@
     if (dependencies_size != 0)   tty->print_cr(" dependencies   = %d", dependencies_size);
     if (handler_table_size != 0)  tty->print_cr(" handler table  = %d", handler_table_size);
     if (nul_chk_table_size != 0)  tty->print_cr(" nul chk table  = %d", nul_chk_table_size);
+#if INCLUDE_JVMCI
+    if (speculations_size != 0)   tty->print_cr(" speculations   = %d", speculations_size);
+    if (jvmci_data_size != 0)     tty->print_cr(" JVMCI data     = %d", jvmci_data_size);
+#endif
   }
 };
 
@@ -426,11 +438,6 @@
 #if INCLUDE_RTM_OPT
   _rtm_state               = NoRTM;
 #endif
-#if INCLUDE_JVMCI
-  _jvmci_installed_code   = NULL;
-  _speculation_log        = NULL;
-  _jvmci_installed_code_triggers_invalidation = false;
-#endif
 }
 
 nmethod* nmethod::new_native_nmethod(const methodHandle& method,
@@ -483,8 +490,11 @@
   AbstractCompiler* compiler,
   int comp_level
 #if INCLUDE_JVMCI
-  , jweak installed_code,
-  jweak speculationLog
+  , char* speculations,
+  int speculations_len,
+  int nmethod_mirror_index,
+  const char* nmethod_mirror_name,
+  FailedSpeculation** failed_speculations
 #endif
 )
 {
@@ -493,12 +503,19 @@
   // create nmethod
   nmethod* nm = NULL;
   { MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+#if INCLUDE_JVMCI
+    int jvmci_data_size = !compiler->is_jvmci() ? 0 : JVMCINMethodData::compute_size(nmethod_mirror_name);
+#endif
     int nmethod_size =
       CodeBlob::allocation_size(code_buffer, sizeof(nmethod))
       + adjust_pcs_size(debug_info->pcs_size())
       + align_up((int)dependencies->size_in_bytes(), oopSize)
       + align_up(handler_table->size_in_bytes()    , oopSize)
       + align_up(nul_chk_table->size_in_bytes()    , oopSize)
+#if INCLUDE_JVMCI
+      + align_up(speculations_len                  , oopSize)
+      + align_up(jvmci_data_size                   , oopSize)
+#endif
       + align_up(debug_info->data_size()           , oopSize);
 
     nm = new (nmethod_size, comp_level)
@@ -510,12 +527,19 @@
             compiler,
             comp_level
 #if INCLUDE_JVMCI
-            , installed_code,
-            speculationLog
+            , speculations,
+            speculations_len,
+            jvmci_data_size
 #endif
             );
 
     if (nm != NULL) {
+#if INCLUDE_JVMCI
+      if (compiler->is_jvmci()) {
+        // Initialize the JVMCINMethodData object inlined into nm
+        nm->jvmci_nmethod_data()->initialize(nmethod_mirror_index, nmethod_mirror_name, failed_speculations);
+      }
+#endif
       // To make dependency checking during class loading fast, record
       // the nmethod dependencies in the classes it is dependent on.
       // This allows the dependency checking code to simply walk the
@@ -591,7 +615,13 @@
     _dependencies_offset     = _scopes_pcs_offset;
     _handler_table_offset    = _dependencies_offset;
     _nul_chk_table_offset    = _handler_table_offset;
+#if INCLUDE_JVMCI
+    _speculations_offset     = _nul_chk_table_offset;
+    _jvmci_data_offset       = _speculations_offset;
+    _nmethod_end_offset      = _jvmci_data_offset;
+#else
     _nmethod_end_offset      = _nul_chk_table_offset;
+#endif
     _compile_id              = compile_id;
     _comp_level              = CompLevel_none;
     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
@@ -667,8 +697,9 @@
   AbstractCompiler* compiler,
   int comp_level
 #if INCLUDE_JVMCI
-  , jweak installed_code,
-  jweak speculation_log
+  , char* speculations,
+  int speculations_len,
+  int jvmci_data_size
 #endif
   )
   : CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
@@ -697,15 +728,6 @@
     set_ctable_begin(header_begin() + _consts_offset);
 
 #if INCLUDE_JVMCI
-    _jvmci_installed_code = installed_code;
-    _speculation_log = speculation_log;
-    oop obj = JNIHandles::resolve(installed_code);
-    if (obj == NULL || (obj->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(obj))) {
-      _jvmci_installed_code_triggers_invalidation = false;
-    } else {
-      _jvmci_installed_code_triggers_invalidation = true;
-    }
-
     if (compiler->is_jvmci()) {
       // JVMCI might not produce any stub sections
       if (offsets->value(CodeOffsets::Exceptions) != -1) {
@@ -735,10 +757,10 @@
       _deopt_mh_handler_begin  = (address) this + _stub_offset          + offsets->value(CodeOffsets::DeoptMH);
     } else {
       _deopt_mh_handler_begin  = NULL;
+    }
 #if INCLUDE_JVMCI
     }
 #endif
-    }
     if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
       _unwind_handler_offset = code_offset()         + offsets->value(CodeOffsets::UnwindHandler);
     } else {
@@ -753,7 +775,13 @@
     _dependencies_offset     = _scopes_pcs_offset    + adjust_pcs_size(debug_info->pcs_size());
     _handler_table_offset    = _dependencies_offset  + align_up((int)dependencies->size_in_bytes (), oopSize);
     _nul_chk_table_offset    = _handler_table_offset + align_up(handler_table->size_in_bytes(), oopSize);
+#if INCLUDE_JVMCI
+    _speculations_offset     = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize);
+    _jvmci_data_offset       = _speculations_offset  + align_up(speculations_len, oopSize);
+    _nmethod_end_offset      = _jvmci_data_offset    + align_up(jvmci_data_size, oopSize);
+#else
     _nmethod_end_offset      = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize);
+#endif
     _entry_point             = code_begin()          + offsets->value(CodeOffsets::Entry);
     _verified_entry_point    = code_begin()          + offsets->value(CodeOffsets::Verified_Entry);
     _osr_entry_point         = code_begin()          + offsets->value(CodeOffsets::OSR_Entry);
@@ -779,6 +807,13 @@
     handler_table->copy_to(this);
     nul_chk_table->copy_to(this);
 
+#if INCLUDE_JVMCI
+    // Copy speculations to nmethod
+    if (speculations_size() != 0) {
+      memcpy(speculations_begin(), speculations, speculations_len);
+    }
+#endif
+
     // we use the information of entry points to find out if a method is
     // static or non static
     assert(compiler->is_c2() || compiler->is_jvmci() ||
@@ -798,13 +833,14 @@
     log->print(" level='%d'", comp_level());
   }
 #if INCLUDE_JVMCI
-    char buffer[O_BUFLEN];
-    char* jvmci_name = jvmci_installed_code_name(buffer, O_BUFLEN);
+  if (jvmci_nmethod_data() != NULL) {
+    const char* jvmci_name = jvmci_nmethod_data()->name();
     if (jvmci_name != NULL) {
-      log->print(" jvmci_installed_code_name='");
+      log->print(" jvmci_mirror_name='");
       log->text("%s", jvmci_name);
       log->print("'");
     }
+  }
 #endif
 }
 
@@ -1115,13 +1151,6 @@
   // Log the unloading.
   log_state_change();
 
-#if INCLUDE_JVMCI
-  // The method can only be unloaded after the pointer to the installed code
-  // Java wrapper is no longer alive. Here we need to clear out this weak
-  // reference to the dead object.
-  maybe_invalidate_installed_code();
-#endif
-
   // The Method* is gone at this point
   assert(_method == NULL, "Tautology");
 
@@ -1134,6 +1163,15 @@
   // concurrent nmethod unloading. Therefore, there is no need for
   // acquire on the loader side.
   OrderAccess::release_store(&_state, (signed char)unloaded);
+
+#if INCLUDE_JVMCI
+  // Clear the link between this nmethod and a HotSpotNmethod mirror
+  JVMCINMethodData* nmethod_data = jvmci_nmethod_data();
+  if (nmethod_data != NULL) {
+    nmethod_data->invalidate_nmethod_mirror(this);
+    nmethod_data->clear_nmethod_mirror(this);
+  }
+#endif
 }
 
 void nmethod::invalidate_osr_method() {
@@ -1265,13 +1303,18 @@
     // Log the transition once
     log_state_change();
 
-    // Invalidate while holding the patching lock
-    JVMCI_ONLY(maybe_invalidate_installed_code());
-
     // Remove nmethod from method.
     unlink_from_method(false /* already owns Patching_lock */);
   } // leave critical region under Patching_lock
 
+#if INCLUDE_JVMCI
+  // Invalidate can't occur while holding the Patching lock
+  JVMCINMethodData* nmethod_data = jvmci_nmethod_data();
+  if (nmethod_data != NULL) {
+    nmethod_data->invalidate_nmethod_mirror(this);
+  }
+#endif
+
 #ifdef ASSERT
   if (is_osr_method() && method() != NULL) {
     // Make sure osr nmethod is invalidated, i.e. not on the list
@@ -1297,6 +1340,14 @@
       flush_dependencies(/*delete_immediately*/true);
     }
 
+#if INCLUDE_JVMCI
+    // Now that the nmethod has been unregistered, it's
+    // safe to clear the HotSpotNmethod mirror oop.
+    if (nmethod_data != NULL) {
+      nmethod_data->clear_nmethod_mirror(this);
+    }
+#endif
+
     // Clear ICStubs to prevent back patching stubs of zombie or flushed
     // nmethods during the next safepoint (see ICStub::finalize), as well
     // as to free up CompiledICHolder resources.
@@ -1324,7 +1375,7 @@
     assert(state == not_entrant, "other cases may need to be handled differently");
   }
 
-  if (TraceCreateZombies) {
+  if (TraceCreateZombies && state == zombie) {
     ResourceMark m;
     tty->print_cr("nmethod <" INTPTR_FORMAT "> %s code made %s", p2i(this), this->method() ? this->method()->name_and_sig_as_C_string() : "null", (state == not_entrant) ? "not entrant" : "zombie");
   }
@@ -1362,11 +1413,6 @@
     ec = next;
   }
 
-#if INCLUDE_JVMCI
-  assert(_jvmci_installed_code == NULL, "should have been nulled out when transitioned to zombie");
-  assert(_speculation_log == NULL, "should have been nulled out when transitioned to zombie");
-#endif
-
   Universe::heap()->flush_nmethod(this);
 
   CodeBlob::flush();
@@ -1660,17 +1706,6 @@
   if (is_unloading()) {
     make_unloaded();
   } else {
-#if INCLUDE_JVMCI
-    if (_jvmci_installed_code != NULL) {
-      if (JNIHandles::is_global_weak_cleared(_jvmci_installed_code)) {
-        if (_jvmci_installed_code_triggers_invalidation) {
-          make_not_entrant();
-        }
-        clear_jvmci_installed_code();
-      }
-    }
-#endif
-
     guarantee(unload_nmethod_caches(unloading_occurred),
               "Should not need transition stubs");
   }
@@ -2066,7 +2101,7 @@
   if (cm->is_aot()) return;  // FIXME: Revisit once _lock_count is added to aot_method
   nmethod* nm = cm->as_nmethod();
   Atomic::inc(&nm->_lock_count);
-  assert(zombie_ok || !nm->is_zombie(), "cannot lock a zombie method");
+  assert(zombie_ok || !nm->is_zombie(), "cannot lock a zombie method: %p", nm);
 }
 
 void nmethodLocker::unlock_nmethod(CompiledMethod* cm) {
@@ -2275,6 +2310,16 @@
                                               p2i(nul_chk_table_begin()),
                                               p2i(nul_chk_table_end()),
                                               nul_chk_table_size());
+#if INCLUDE_JVMCI
+  if (speculations_size () > 0) tty->print_cr(" speculations   [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                              p2i(speculations_begin()),
+                                              p2i(speculations_end()),
+                                              speculations_size());
+  if (jvmci_data_size   () > 0) tty->print_cr(" JVMCI data     [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
+                                              p2i(jvmci_data_begin()),
+                                              p2i(jvmci_data_end()),
+                                              jvmci_data_size());
+#endif
 }
 
 #ifndef PRODUCT
@@ -2857,115 +2902,18 @@
 #endif // !PRODUCT
 
 #if INCLUDE_JVMCI
-void nmethod::clear_jvmci_installed_code() {
-  assert_locked_or_safepoint(Patching_lock);
-  if (_jvmci_installed_code != NULL) {
-    JNIHandles::destroy_weak_global(_jvmci_installed_code);
-    _jvmci_installed_code = NULL;
+void nmethod::update_speculation(JavaThread* thread) {
+  jlong speculation = thread->pending_failed_speculation();
+  if (speculation != 0) {
+    guarantee(jvmci_nmethod_data() != NULL, "failed speculation in nmethod without failed speculation list");
+    jvmci_nmethod_data()->add_failed_speculation(this, speculation);
+    thread->set_pending_failed_speculation(0);
   }
 }
 
-void nmethod::clear_speculation_log() {
-  assert_locked_or_safepoint(Patching_lock);
-  if (_speculation_log != NULL) {
-    JNIHandles::destroy_weak_global(_speculation_log);
-    _speculation_log = NULL;
-  }
-}
-
-void nmethod::maybe_invalidate_installed_code() {
-  if (!is_compiled_by_jvmci()) {
-    return;
-  }
-
-  assert(Patching_lock->is_locked() ||
-         SafepointSynchronize::is_at_safepoint(), "should be performed under a lock for consistency");
-  oop installed_code = JNIHandles::resolve(_jvmci_installed_code);
-  if (installed_code != NULL) {
-    // Update the values in the InstalledCode instance if it still refers to this nmethod
-    nmethod* nm = (nmethod*)InstalledCode::address(installed_code);
-    if (nm == this) {
-      if (!is_alive() || is_unloading()) {
-        // Break the link between nmethod and InstalledCode such that the nmethod
-        // can subsequently be flushed safely.  The link must be maintained while
-        // the method could have live activations since invalidateInstalledCode
-        // might want to invalidate all existing activations.
-        InstalledCode::set_address(installed_code, 0);
-        InstalledCode::set_entryPoint(installed_code, 0);
-      } else if (is_not_entrant()) {
-        // Remove the entry point so any invocation will fail but keep
-        // the address link around that so that existing activations can
-        // be invalidated.
-        InstalledCode::set_entryPoint(installed_code, 0);
-      }
-    }
-  }
-  if (!is_alive() || is_unloading()) {
-    // Clear these out after the nmethod has been unregistered and any
-    // updates to the InstalledCode instance have been performed.
-    clear_jvmci_installed_code();
-    clear_speculation_log();
-  }
-}
-
-void nmethod::invalidate_installed_code(Handle installedCode, TRAPS) {
-  if (installedCode() == NULL) {
-    THROW(vmSymbols::java_lang_NullPointerException());
-  }
-  jlong nativeMethod = InstalledCode::address(installedCode);
-  nmethod* nm = (nmethod*)nativeMethod;
-  if (nm == NULL) {
-    // Nothing to do
-    return;
-  }
-
-  nmethodLocker nml(nm);
-#ifdef ASSERT
-  {
-    MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
-    // This relationship can only be checked safely under a lock
-    assert(!nm->is_alive() || nm->is_unloading() || nm->jvmci_installed_code() == installedCode(), "sanity check");
-  }
-#endif
-
-  if (nm->is_alive()) {
-    // Invalidating the InstalledCode means we want the nmethod
-    // to be deoptimized.
-    nm->mark_for_deoptimization();
-    VM_Deoptimize op;
-    VMThread::execute(&op);
-  }
-
-  // Multiple threads could reach this point so we now need to
-  // lock and re-check the link to the nmethod so that only one
-  // thread clears it.
-  MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
-  if (InstalledCode::address(installedCode) == nativeMethod) {
-      InstalledCode::set_address(installedCode, 0);
-  }
-}
-
-oop nmethod::jvmci_installed_code() {
-  return JNIHandles::resolve(_jvmci_installed_code);
-}
-
-oop nmethod::speculation_log() {
-  return JNIHandles::resolve(_speculation_log);
-}
-
-char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) const {
-  if (!this->is_compiled_by_jvmci()) {
-    return NULL;
-  }
-  oop installed_code = JNIHandles::resolve(_jvmci_installed_code);
-  if (installed_code != NULL) {
-    oop installed_code_name = NULL;
-    if (installed_code->is_a(InstalledCode::klass())) {
-      installed_code_name = InstalledCode::name(installed_code);
-    }
-    if (installed_code_name != NULL) {
-      return java_lang_String::as_utf8_string(installed_code_name, buf, (int)buflen);
-    }
+const char* nmethod::jvmci_name() {
+  if (jvmci_nmethod_data() != NULL) {
+    return jvmci_nmethod_data()->name();
   }
   return NULL;
 }
--- a/src/hotspot/share/code/nmethod.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/code/nmethod.hpp	Wed May 01 12:31:29 2019 -0700
@@ -51,37 +51,28 @@
 //  - handler entry point array
 //  [Implicit Null Pointer exception table]
 //  - implicit null table array
+//  [Speculations]
+//  - encoded speculations array
+//  [JVMCINMethodData]
+//  - meta data for JVMCI compiled nmethod
+
+#if INCLUDE_JVMCI
+class FailedSpeculation;
+class JVMCINMethodData;
+#endif
 
 class nmethod : public CompiledMethod {
   friend class VMStructs;
   friend class JVMCIVMStructs;
   friend class NMethodSweeper;
   friend class CodeCache;  // scavengable oops
+  friend class JVMCINMethodData;
  private:
 
   // Shared fields for all nmethod's
   int       _entry_bci;        // != InvocationEntryBci if this nmethod is an on-stack replacement method
   jmethodID _jmethod_id;       // Cache of method()->jmethod_id()
 
-#if INCLUDE_JVMCI
-  // A weak reference to an InstalledCode object associated with
-  // this nmethod.
-  jweak     _jvmci_installed_code;
-
-  // A weak reference to a SpeculationLog object associated with
-  // this nmethod.
-  jweak     _speculation_log;
-
-  // Determines whether this nmethod is unloaded when the
-  // referent in _jvmci_installed_code is cleared. This
-  // will be false if the referent is initialized to a
-  // HotSpotNMethod object whose isDefault field is true.
-  // That is, installed code other than a "default"
-  // HotSpotNMethod causes nmethod unloading.
-  // This field is ignored once _jvmci_installed_code is NULL.
-  bool _jvmci_installed_code_triggers_invalidation;
-#endif
-
   // To support simple linked-list chaining of nmethods:
   nmethod*  _osr_link;         // from InstanceKlass::osr_nmethods_head
 
@@ -107,6 +98,10 @@
   int _dependencies_offset;
   int _handler_table_offset;
   int _nul_chk_table_offset;
+#if INCLUDE_JVMCI
+  int _speculations_offset;
+  int _jvmci_data_offset;
+#endif
   int _nmethod_end_offset;
 
   int code_offset() const { return (address) code_begin() - header_begin(); }
@@ -207,8 +202,9 @@
           AbstractCompiler* compiler,
           int comp_level
 #if INCLUDE_JVMCI
-          , jweak installed_code,
-          jweak speculation_log
+          , char* speculations,
+          int speculations_len,
+          int jvmci_data_size
 #endif
           );
 
@@ -251,8 +247,11 @@
                               AbstractCompiler* compiler,
                               int comp_level
 #if INCLUDE_JVMCI
-                              , jweak installed_code = NULL,
-                              jweak speculation_log = NULL
+                              , char* speculations = NULL,
+                              int speculations_len = 0,
+                              int nmethod_mirror_index = -1,
+                              const char* nmethod_mirror_name = NULL,
+                              FailedSpeculation** failed_speculations = NULL
 #endif
   );
 
@@ -299,12 +298,24 @@
   address handler_table_begin   () const          { return           header_begin() + _handler_table_offset ; }
   address handler_table_end     () const          { return           header_begin() + _nul_chk_table_offset ; }
   address nul_chk_table_begin   () const          { return           header_begin() + _nul_chk_table_offset ; }
+#if INCLUDE_JVMCI
+  address nul_chk_table_end     () const          { return           header_begin() + _speculations_offset  ; }
+  address speculations_begin    () const          { return           header_begin() + _speculations_offset  ; }
+  address speculations_end      () const          { return           header_begin() + _jvmci_data_offset   ; }
+  address jvmci_data_begin      () const          { return           header_begin() + _jvmci_data_offset    ; }
+  address jvmci_data_end        () const          { return           header_begin() + _nmethod_end_offset   ; }
+#else
   address nul_chk_table_end     () const          { return           header_begin() + _nmethod_end_offset   ; }
+#endif
 
   // Sizes
   int oops_size         () const                  { return (address)  oops_end         () - (address)  oops_begin         (); }
   int metadata_size     () const                  { return (address)  metadata_end     () - (address)  metadata_begin     (); }
   int dependencies_size () const                  { return            dependencies_end () -            dependencies_begin (); }
+#if INCLUDE_JVMCI
+  int speculations_size () const                  { return            speculations_end () -            speculations_begin (); }
+  int jvmci_data_size   () const                  { return            jvmci_data_end   () -            jvmci_data_begin   (); }
+#endif
 
   int     oops_count() const { assert(oops_size() % oopSize == 0, "");  return (oops_size() / oopSize) + 1; }
   int metadata_count() const { assert(metadata_size() % wordSize == 0, ""); return (metadata_size() / wordSize) + 1; }
@@ -446,39 +457,19 @@
   void set_method(Method* method) { _method = method; }
 
 #if INCLUDE_JVMCI
-  // Gets the InstalledCode object associated with this nmethod
-  // which may be NULL if this nmethod was not compiled by JVMCI
-  // or the weak reference has been cleared.
-  oop jvmci_installed_code();
+  // Gets the JVMCI name of this nmethod.
+  const char* jvmci_name();
 
-  // Copies the value of the name field in the InstalledCode
-  // object (if any) associated with this nmethod into buf.
-  // Returns the value of buf if it was updated otherwise NULL.
-  char* jvmci_installed_code_name(char* buf, size_t buflen) const;
+  // Records the pending failed speculation in the
+  // JVMCI speculation log associated with this nmethod.
+  void update_speculation(JavaThread* thread);
 
-  // Updates the state of the InstalledCode (if any) associated with
-  // this nmethod based on the current value of _state.
-  void maybe_invalidate_installed_code();
-
-  // Deoptimizes the nmethod (if any) in the address field of a given
-  // InstalledCode object. The address field is zeroed upon return.
-  static void invalidate_installed_code(Handle installed_code, TRAPS);
-
-  // Gets the SpeculationLog object associated with this nmethod
-  // which may be NULL if this nmethod was not compiled by JVMCI
-  // or the weak reference has been cleared.
-  oop speculation_log();
-
- private:
-  // Deletes the weak reference (if any) to the InstalledCode object
-  // associated with this nmethod.
-  void clear_jvmci_installed_code();
-
-  // Deletes the weak reference (if any) to the SpeculationLog object
-  // associated with this nmethod.
-  void clear_speculation_log();
-
- public:
+  // Gets the data specific to a JVMCI compiled method.
+  // This returns a non-NULL value iff this nmethod was
+  // compiled by the JVMCI compiler.
+  JVMCINMethodData* jvmci_nmethod_data() const {
+    return jvmci_data_size() == 0 ? NULL : (JVMCINMethodData*) jvmci_data_begin();
+  }
 #endif
 
  public:
--- a/src/hotspot/share/compiler/abstractCompiler.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/compiler/abstractCompiler.hpp	Wed May 01 12:31:29 2019 -0700
@@ -154,9 +154,6 @@
   const bool is_jvmci()                          { return _type == compiler_jvmci; }
   const CompilerType type()                      { return _type; }
 
-  // Extra tests to identify trivial methods for the tiered compilation policy.
-  virtual bool is_trivial(Method* method) { return false; }
-
   // Customization
   virtual void initialize () = 0;
 
--- a/src/hotspot/share/compiler/compileBroker.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/compiler/compileBroker.cpp	Wed May 01 12:31:29 2019 -0700
@@ -68,9 +68,8 @@
 #include "c1/c1_Compiler.hpp"
 #endif
 #if INCLUDE_JVMCI
-#include "jvmci/jvmciCompiler.hpp"
+#include "jvmci/jvmciEnv.hpp"
 #include "jvmci/jvmciRuntime.hpp"
-#include "jvmci/jvmciJavaClasses.hpp"
 #include "runtime/vframe.hpp"
 #endif
 #ifdef COMPILER2
@@ -1064,36 +1063,34 @@
     }
 
 #if INCLUDE_JVMCI
-    if (UseJVMCICompiler) {
-      if (blocking) {
-        // Don't allow blocking compiles for requests triggered by JVMCI.
-        if (thread->is_Compiler_thread()) {
+    if (UseJVMCICompiler && blocking && !UseJVMCINativeLibrary) {
+      // Don't allow blocking compiles for requests triggered by JVMCI.
+      if (thread->is_Compiler_thread()) {
+        blocking = false;
+      }
+
+      // Don't allow blocking compiles if inside a class initializer or while performing class loading
+      vframeStream vfst((JavaThread*) thread);
+      for (; !vfst.at_end(); vfst.next()) {
+        if (vfst.method()->is_static_initializer() ||
+            (vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) &&
+                vfst.method()->name() == vmSymbols::loadClass_name())) {
           blocking = false;
+          break;
         }
+      }
 
-        // Don't allow blocking compiles if inside a class initializer or while performing class loading
-        vframeStream vfst((JavaThread*) thread);
-        for (; !vfst.at_end(); vfst.next()) {
-          if (vfst.method()->is_static_initializer() ||
-              (vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) &&
-                  vfst.method()->name() == vmSymbols::loadClass_name())) {
-            blocking = false;
-            break;
-          }
-        }
+      // Don't allow blocking compilation requests to JVMCI
+      // if JVMCI itself is not yet initialized
+      if (!JVMCI::is_compiler_initialized() && compiler(comp_level)->is_jvmci()) {
+        blocking = false;
+      }
 
-        // Don't allow blocking compilation requests to JVMCI
-        // if JVMCI itself is not yet initialized
-        if (!JVMCIRuntime::is_HotSpotJVMCIRuntime_initialized() && compiler(comp_level)->is_jvmci()) {
-          blocking = false;
-        }
-
-        // Don't allow blocking compilation requests if we are in JVMCIRuntime::shutdown
-        // to avoid deadlock between compiler thread(s) and threads run at shutdown
-        // such as the DestroyJavaVM thread.
-        if (JVMCIRuntime::shutdown_called()) {
-          blocking = false;
-        }
+      // Don't allow blocking compilation requests if we are in JVMCIRuntime::shutdown
+      // to avoid deadlock between compiler thread(s) and threads run at shutdown
+      // such as the DestroyJavaVM thread.
+      if (JVMCI::shutdown_called()) {
+        blocking = false;
       }
     }
 #endif // INCLUDE_JVMCI
@@ -1193,7 +1190,7 @@
   }
 
 #if INCLUDE_JVMCI
-  if (comp->is_jvmci() && !JVMCIRuntime::can_initialize_JVMCI()) {
+  if (comp->is_jvmci() && !JVMCI::can_initialize_JVMCI()) {
     return NULL;
   }
 #endif
@@ -2061,20 +2058,24 @@
 
     // Skip redefined methods
     if (target_handle->is_old()) {
-        failure_reason = "redefined method";
+      failure_reason = "redefined method";
+      retry_message = "not retryable";
+      compilable = ciEnv::MethodCompilable_never;
+    } else {
+      JVMCICompileState compile_state(task, system_dictionary_modification_counter);
+      JVMCIEnv env(&compile_state, __FILE__, __LINE__);
+      methodHandle method(thread, target_handle);
+      env.runtime()->compile_method(&env, jvmci, method, osr_bci);
+
+      failure_reason = compile_state.failure_reason();
+      failure_reason_on_C_heap = compile_state.failure_reason_on_C_heap();
+      if (!compile_state.retryable()) {
         retry_message = "not retryable";
-        compilable = ciEnv::MethodCompilable_never;
-    } else {
-        JVMCIEnv env(task, system_dictionary_modification_counter);
-        methodHandle method(thread, target_handle);
-        jvmci->compile_method(method, osr_bci, &env);
-
-        failure_reason = env.failure_reason();
-        failure_reason_on_C_heap = env.failure_reason_on_C_heap();
-        if (!env.retryable()) {
-          retry_message = "not retryable";
-          compilable = ciEnv::MethodCompilable_not_at_tier;
-        }
+        compilable = ciEnv::MethodCompilable_not_at_tier;
+      }
+      if (task->code() == NULL) {
+        assert(failure_reason != NULL, "must specify failure_reason");
+      }
     }
     post_compile(thread, task, task->code() != NULL, NULL, compilable, failure_reason);
     if (event.should_commit()) {
--- a/src/hotspot/share/compiler/compileTask.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/compiler/compileTask.cpp	Wed May 01 12:31:29 2019 -0700
@@ -396,6 +396,7 @@
   ResourceMark rm(thread);
 
   if (!_is_success) {
+    assert(_failure_reason != NULL, "missing");
     const char* reason = _failure_reason != NULL ? _failure_reason : "unknown";
     log->elem("failure reason='%s'", reason);
   }
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp	Wed May 01 12:31:29 2019 -0700
@@ -253,22 +253,6 @@
     if (FLAG_IS_DEFAULT(TypeProfileWidth)) {
       FLAG_SET_DEFAULT(TypeProfileWidth, 8);
     }
-    if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) {
-      FLAG_SET_DEFAULT(OnStackReplacePercentage, 933);
-    }
-    // JVMCI needs values not less than defaults
-    if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
-      FLAG_SET_DEFAULT(ReservedCodeCacheSize, MAX2(64*M, ReservedCodeCacheSize));
-    }
-    if (FLAG_IS_DEFAULT(InitialCodeCacheSize)) {
-      FLAG_SET_DEFAULT(InitialCodeCacheSize, MAX2(16*M, InitialCodeCacheSize));
-    }
-    if (FLAG_IS_DEFAULT(MetaspaceSize)) {
-      FLAG_SET_DEFAULT(MetaspaceSize, MIN2(MAX2(12*M, MetaspaceSize), MaxMetaspaceSize));
-    }
-    if (FLAG_IS_DEFAULT(NewSizeThreadIncrease)) {
-      FLAG_SET_DEFAULT(NewSizeThreadIncrease, MAX2(4*K, NewSizeThreadIncrease));
-    }
     if (TieredStopAtLevel != CompLevel_full_optimization) {
       // Currently JVMCI compiler can only work at the full optimization level
       warning("forcing TieredStopAtLevel to full optimization because JVMCI is enabled");
@@ -277,7 +261,43 @@
     if (FLAG_IS_DEFAULT(TypeProfileLevel)) {
       FLAG_SET_DEFAULT(TypeProfileLevel, 0);
     }
-  }
+
+    if (UseJVMCINativeLibrary) {
+      // SVM compiled code requires more stack space
+      if (FLAG_IS_DEFAULT(CompilerThreadStackSize)) {
+        // Duplicate logic in the implementations of os::create_thread
+        // so that we can then double the computed stack size. Once
+        // the stack size requirements of SVM are better understood,
+        // this logic can be pushed down into os::create_thread.
+        int stack_size = CompilerThreadStackSize;
+        if (stack_size == 0) {
+          stack_size = VMThreadStackSize;
+        }
+        if (stack_size != 0) {
+          FLAG_SET_DEFAULT(CompilerThreadStackSize, stack_size * 2);
+        }
+      }
+    } else {
+      // Adjust the on stack replacement percentage to avoid early
+      // OSR compilations while JVMCI itself is warming up
+      if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) {
+        FLAG_SET_DEFAULT(OnStackReplacePercentage, 933);
+      }
+      // JVMCI needs values not less than defaults
+      if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
+        FLAG_SET_DEFAULT(ReservedCodeCacheSize, MAX2(64*M, ReservedCodeCacheSize));
+      }
+      if (FLAG_IS_DEFAULT(InitialCodeCacheSize)) {
+        FLAG_SET_DEFAULT(InitialCodeCacheSize, MAX2(16*M, InitialCodeCacheSize));
+      }
+      if (FLAG_IS_DEFAULT(MetaspaceSize)) {
+        FLAG_SET_DEFAULT(MetaspaceSize, MIN2(MAX2(12*M, MetaspaceSize), MaxMetaspaceSize));
+      }
+      if (FLAG_IS_DEFAULT(NewSizeThreadIncrease)) {
+        FLAG_SET_DEFAULT(NewSizeThreadIncrease, MAX2(4*K, NewSizeThreadIncrease));
+      }
+    } // !UseJVMCINativeLibrary
+  } // UseJVMCICompiler
 }
 #endif // INCLUDE_JVMCI
 
@@ -392,6 +412,8 @@
   // Check that JVMCI compiler supports selested GC.
   // Should be done after GCConfig::initialize() was called.
   JVMCIGlobals::check_jvmci_supported_gc();
+
+  // Do JVMCI specific settings
   set_jvmci_specific_flags();
 #endif
 
--- a/src/hotspot/share/compiler/disassembler.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/compiler/disassembler.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, 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
@@ -672,8 +672,7 @@
   nm->method()->signature()->print_symbol_on(env.output());
 #if INCLUDE_JVMCI
   {
-    char buffer[O_BUFLEN];
-    char* jvmciName = nm->jvmci_installed_code_name(buffer, O_BUFLEN);
+    const char* jvmciName = nm->jvmci_name();
     if (jvmciName != NULL) {
       env.output()->print(" (%s)", jvmciName);
     }
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed May 01 12:31:29 2019 -0700
@@ -82,6 +82,9 @@
 #include "services/runtimeService.hpp"
 #include "utilities/align.hpp"
 #include "utilities/stack.inline.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 // statics
 CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL;
@@ -5258,6 +5261,9 @@
 
       // Prune dead klasses from subklass/sibling/implementor lists.
       Klass::clean_weak_klass_links(purged_class);
+
+      // Clean JVMCI metadata handles.
+      JVMCI_ONLY(JVMCI::do_unloading(purged_class));
     }
   }
 
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Wed May 01 12:31:29 2019 -0700
@@ -60,9 +60,8 @@
   _gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms):");
   _gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms):");
   _gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms):");
-#if INCLUDE_AOT
-  _gc_par_phases[AOTCodeRoots] = new WorkerDataArray<double>(max_gc_threads, "AOT Root Scan (ms):");
-#endif
+  AOT_ONLY(_gc_par_phases[AOTCodeRoots] = new WorkerDataArray<double>(max_gc_threads, "AOT Root Scan (ms):");)
+  JVMCI_ONLY(_gc_par_phases[JVMCIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMCI Root Scan (ms):");)
   _gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms):");
   _gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms):");
   _gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms):");
@@ -527,9 +526,8 @@
       "SystemDictionaryRoots",
       "CLDGRoots",
       "JVMTIRoots",
-#if INCLUDE_AOT
-      "AOTCodeRoots",
-#endif
+      AOT_ONLY("AOTCodeRoots" COMMA)
+      JVMCI_ONLY("JVMCIRoots" COMMA)
       "CMRefRoots",
       "WaitForStrongCLD",
       "WeakCLDRoots",
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp	Wed May 01 12:31:29 2019 -0700
@@ -55,9 +55,8 @@
     SystemDictionaryRoots,
     CLDGRoots,
     JVMTIRoots,
-#if INCLUDE_AOT
-    AOTCodeRoots,
-#endif
+    AOT_ONLY(AOTCodeRoots COMMA)
+    JVMCI_ONLY(JVMCIRoots COMMA)
     CMRefRoots,
     WaitForStrongCLD,
     WeakCLDRoots,
--- a/src/hotspot/share/gc/g1/g1RootProcessor.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.cpp	Wed May 01 12:31:29 2019 -0700
@@ -43,6 +43,9 @@
 #include "runtime/mutex.hpp"
 #include "services/management.hpp"
 #include "utilities/macros.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 void G1RootProcessor::worker_has_discovered_all_strong_classes() {
   assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
@@ -267,6 +270,15 @@
   }
 #endif
 
+#if INCLUDE_JVMCI
+  if (EnableJVMCI) {
+    G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMCIRoots, worker_i);
+    if (_process_strong_tasks.try_claim_task(G1RP_PS_JVMCI_oops_do)) {
+      JVMCI::oops_do(strong_roots);
+    }
+  }
+#endif
+
   {
     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
     if (_process_strong_tasks.try_claim_task(G1RP_PS_SystemDictionary_oops_do)) {
--- a/src/hotspot/share/gc/g1/g1RootProcessor.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RootProcessor.hpp	Wed May 01 12:31:29 2019 -0700
@@ -63,7 +63,8 @@
     G1RP_PS_ClassLoaderDataGraph_oops_do,
     G1RP_PS_jvmti_oops_do,
     G1RP_PS_CodeCache_oops_do,
-    G1RP_PS_aot_oops_do,
+    AOT_ONLY(G1RP_PS_aot_oops_do COMMA)
+    JVMCI_ONLY(G1RP_PS_JVMCI_oops_do COMMA)
     G1RP_PS_filter_satb_buffers,
     G1RP_PS_refProcessor_oops_do,
     // Leave this one last.
--- a/src/hotspot/share/gc/parallel/pcTasks.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/parallel/pcTasks.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, 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
@@ -46,6 +46,9 @@
 #include "runtime/vmThread.hpp"
 #include "services/management.hpp"
 #include "utilities/stack.inline.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 //
 // ThreadRootsMarkingTask
@@ -121,6 +124,12 @@
       AOTLoader::oops_do(&mark_and_push_closure);
       break;
 
+#if INCLUDE_JVMCI
+    case jvmci:
+      JVMCI::oops_do(&mark_and_push_closure);
+      break;
+#endif
+
     default:
       fatal("Unknown root type");
   }
--- a/src/hotspot/share/gc/parallel/pcTasks.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/parallel/pcTasks.hpp	Wed May 01 12:31:29 2019 -0700
@@ -98,6 +98,7 @@
     system_dictionary     = 7,
     class_loader_data     = 8,
     code_cache            = 9
+    JVMCI_ONLY(COMMA jvmci = 10)
   };
  private:
   RootType _root_type;
--- a/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/parallel/psMarkSweep.cpp	Wed May 01 12:31:29 2019 -0700
@@ -62,6 +62,9 @@
 #include "utilities/align.hpp"
 #include "utilities/events.hpp"
 #include "utilities/stack.inline.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 elapsedTimer        PSMarkSweep::_accumulated_time;
 jlong               PSMarkSweep::_time_of_last_gc   = 0;
@@ -524,7 +527,8 @@
     ClassLoaderDataGraph::always_strong_cld_do(follow_cld_closure());
     // Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
     //ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
-    AOTLoader::oops_do(mark_and_push_closure());
+    AOT_ONLY(AOTLoader::oops_do(mark_and_push_closure());)
+    JVMCI_ONLY(JVMCI::oops_do(mark_and_push_closure());)
   }
 
   // Flush marking stack.
@@ -562,6 +566,9 @@
 
     // Prune dead klasses from subklass/sibling/implementor lists.
     Klass::clean_weak_klass_links(purged_class);
+
+    // Clean JVMCI metadata handles.
+    JVMCI_ONLY(JVMCI::do_unloading(purged_class));
   }
 
   _gc_tracer->report_object_count_after_gc(is_alive_closure());
@@ -615,7 +622,10 @@
 
   CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
   CodeCache::blobs_do(&adjust_from_blobs);
-  AOTLoader::oops_do(adjust_pointer_closure());
+  AOT_ONLY(AOTLoader::oops_do(adjust_pointer_closure());)
+
+  JVMCI_ONLY(JVMCI::oops_do(adjust_pointer_closure());)
+
   ref_processor()->weak_oops_do(adjust_pointer_closure());
   PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());
 
--- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp	Wed May 01 12:31:29 2019 -0700
@@ -77,6 +77,9 @@
 #include "utilities/formatBuffer.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/stack.inline.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 #include <math.h>
 
@@ -2123,6 +2126,7 @@
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::class_loader_data));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
     q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
+    JVMCI_ONLY(q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmci));)
 
     if (active_gc_threads > 1) {
       for (uint j = 0; j < active_gc_threads; j++) {
@@ -2176,6 +2180,9 @@
 
     // Prune dead klasses from subklass/sibling/implementor lists.
     Klass::clean_weak_klass_links(purged_class);
+
+    // Clean JVMCI metadata handles.
+    JVMCI_ONLY(JVMCI::do_unloading(purged_class));
   }
 
   _gc_tracer.report_object_count_after_gc(is_alive_closure());
@@ -2207,7 +2214,10 @@
 
   CodeBlobToOopClosure adjust_from_blobs(&oop_closure, CodeBlobToOopClosure::FixRelocations);
   CodeCache::blobs_do(&adjust_from_blobs);
-  AOTLoader::oops_do(&oop_closure);
+  AOT_ONLY(AOTLoader::oops_do(&oop_closure);)
+
+  JVMCI_ONLY(JVMCI::oops_do(&oop_closure);)
+
   ref_processor()->weak_oops_do(&oop_closure);
   // Roots were visited so references into the young gen in roots
   // may have been scanned.  Process them also.
--- a/src/hotspot/share/gc/parallel/psScavenge.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/parallel/psScavenge.cpp	Wed May 01 12:31:29 2019 -0700
@@ -379,6 +379,7 @@
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
       q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
+      JVMCI_ONLY(q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmci));)
 
       TaskTerminator terminator(active_workers,
                                 (TaskQueueSetSuper*) promotion_manager->stack_array_depth());
--- a/src/hotspot/share/gc/parallel/psTasks.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/parallel/psTasks.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, 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
@@ -44,6 +44,9 @@
 #include "runtime/thread.hpp"
 #include "runtime/vmThread.hpp"
 #include "services/management.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 //
 // ScavengeRootsTask
@@ -95,7 +98,6 @@
       JvmtiExport::oops_do(&roots_closure);
       break;
 
-
     case code_cache:
       {
         MarkingCodeBlobClosure code_closure(&roots_to_old_closure, CodeBlobToOopClosure::FixRelocations);
@@ -104,6 +106,12 @@
       }
       break;
 
+#if INCLUDE_JVMCI
+    case jvmci:
+      JVMCI::oops_do(&roots_closure);
+      break;
+#endif
+
     default:
       fatal("Unknown root type");
   }
--- a/src/hotspot/share/gc/parallel/psTasks.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/parallel/psTasks.hpp	Wed May 01 12:31:29 2019 -0700
@@ -61,6 +61,7 @@
     management            = 7,
     jvmti                 = 8,
     code_cache            = 9
+    JVMCI_ONLY(COMMA jvmci = 10)
   };
  private:
   RootType _root_type;
--- a/src/hotspot/share/gc/serial/genMarkSweep.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/serial/genMarkSweep.cpp	Wed May 01 12:31:29 2019 -0700
@@ -56,6 +56,9 @@
 #include "utilities/copy.hpp"
 #include "utilities/events.hpp"
 #include "utilities/stack.inline.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_softrefs) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
@@ -233,6 +236,9 @@
 
     // Prune dead klasses from subklass/sibling/implementor lists.
     Klass::clean_weak_klass_links(purged_class);
+
+    // Clean JVMCI metadata handles.
+    JVMCI_ONLY(JVMCI::do_unloading(purged_class));
   }
 
   gc_tracer()->report_object_count_after_gc(&is_alive);
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Wed May 01 12:31:29 2019 -0700
@@ -69,6 +69,9 @@
 #include "utilities/macros.hpp"
 #include "utilities/stack.inline.hpp"
 #include "utilities/vmError.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy,
                                    Generation::Name young,
@@ -857,10 +860,16 @@
   if (_process_strong_tasks->try_claim_task(GCH_PS_jvmti_oops_do)) {
     JvmtiExport::oops_do(strong_roots);
   }
+#if INCLUDE_AOT
   if (UseAOT && _process_strong_tasks->try_claim_task(GCH_PS_aot_oops_do)) {
     AOTLoader::oops_do(strong_roots);
   }
-
+#endif
+#if INCLUDE_JVMCI
+  if (EnableJVMCI && _process_strong_tasks->try_claim_task(GCH_PS_jvmci_oops_do)) {
+    JVMCI::oops_do(strong_roots);
+  }
+#endif
   if (_process_strong_tasks->try_claim_task(GCH_PS_SystemDictionary_oops_do)) {
     SystemDictionary::oops_do(strong_roots);
   }
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Wed May 01 12:31:29 2019 -0700
@@ -117,7 +117,8 @@
     GCH_PS_ClassLoaderDataGraph_oops_do,
     GCH_PS_jvmti_oops_do,
     GCH_PS_CodeCache_oops_do,
-    GCH_PS_aot_oops_do,
+    AOT_ONLY(GCH_PS_aot_oops_do COMMA)
+    JVMCI_ONLY(GCH_PS_jvmci_oops_do COMMA)
     GCH_PS_younger_gens,
     // Leave this one last.
     GCH_PS_NumElements
--- a/src/hotspot/share/gc/shared/parallelCleaning.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/shared/parallelCleaning.cpp	Wed May 01 12:31:29 2019 -0700
@@ -30,6 +30,9 @@
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "logging/log.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 StringDedupCleaningTask::StringDedupCleaningTask(BoolObjectClosure* is_alive,
                                                  OopClosure* keep_alive,
@@ -158,6 +161,27 @@
   }
 }
 
+#if INCLUDE_JVMCI
+JVMCICleaningTask::JVMCICleaningTask() :
+  _cleaning_claimed(0) {
+}
+
+bool JVMCICleaningTask::claim_cleaning_task() {
+  if (_cleaning_claimed) {
+    return false;
+  }
+
+  return Atomic::cmpxchg(1, &_cleaning_claimed, 0) == 0;
+}
+
+void JVMCICleaningTask::work(bool unloading_occurred) {
+  // One worker will clean JVMCI metadata handles.
+  if (unloading_occurred && EnableJVMCI && claim_cleaning_task()) {
+    JVMCI::do_unloading(unloading_occurred);
+  }
+}
+#endif // INCLUDE_JVMCI
+
 ParallelCleaningTask::ParallelCleaningTask(BoolObjectClosure* is_alive,
                                            uint num_workers,
                                            bool unloading_occurred,
@@ -166,11 +190,16 @@
   _unloading_occurred(unloading_occurred),
   _string_dedup_task(is_alive, NULL, resize_dedup_table),
   _code_cache_task(num_workers, is_alive, unloading_occurred),
+  JVMCI_ONLY(_jvmci_cleaning_task() COMMA)
   _klass_cleaning_task() {
 }
 
 // The parallel work done by all worker threads.
 void ParallelCleaningTask::work(uint worker_id) {
+  // Clean JVMCI metadata handles.
+  // Execute this task first because it is serial task.
+  JVMCI_ONLY(_jvmci_cleaning_task.work(_unloading_occurred);)
+
   // Do first pass of code cache cleaning.
   _code_cache_task.work(worker_id);
 
--- a/src/hotspot/share/gc/shared/parallelCleaning.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/gc/shared/parallelCleaning.hpp	Wed May 01 12:31:29 2019 -0700
@@ -87,6 +87,20 @@
   void work();
 };
 
+#if INCLUDE_JVMCI
+class JVMCICleaningTask : public StackObj {
+  volatile int       _cleaning_claimed;
+
+public:
+  JVMCICleaningTask();
+  // Clean JVMCI metadata handles.
+  void work(bool unloading_occurred);
+
+private:
+  bool claim_cleaning_task();
+};
+#endif
+
 // Do cleanup of some weakly held data in the same parallel task.
 // Assumes a non-moving context.
 class ParallelCleaningTask : public AbstractGangTask {
@@ -94,6 +108,9 @@
   bool                    _unloading_occurred;
   StringDedupCleaningTask _string_dedup_task;
   CodeCacheUnloadingTask  _code_cache_task;
+#if INCLUDE_JVMCI
+  JVMCICleaningTask       _jvmci_cleaning_task;
+#endif
   KlassCleaningTask       _klass_cleaning_task;
 
 public:
--- a/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jfr/leakprofiler/chains/rootSetClosure.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -40,6 +40,9 @@
 #include "runtime/thread.hpp"
 #include "services/management.hpp"
 #include "utilities/align.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 RootSetClosure::RootSetClosure(EdgeQueue* edge_queue) :
   _edge_queue(edge_queue) {
@@ -104,4 +107,5 @@
   Management::oops_do(closure);
   StringTable::oops_do(closure);
   AOTLoader::oops_do(closure);
+  JVMCI_ONLY(JVMCI::oops_do(closure);)
 }
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -40,6 +40,9 @@
 #include "runtime/vframe_hp.hpp"
 #include "services/management.hpp"
 #include "utilities/growableArray.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci.hpp"
+#endif
 
 class ReferenceLocateClosure : public OopClosure {
  protected:
@@ -102,6 +105,7 @@
   bool do_management_roots();
   bool do_string_table_roots();
   bool do_aot_loader_roots();
+  JVMCI_ONLY(bool do_jvmci_roots();)
 
   bool do_roots();
 
@@ -188,6 +192,15 @@
   return rcl.complete();
 }
 
+#if INCLUDE_JVMCI
+bool ReferenceToRootClosure::do_jvmci_roots() {
+  assert(!complete(), "invariant");
+  ReferenceLocateClosure rcl(_callback, OldObjectRoot::_jvmci, OldObjectRoot::_type_undetermined, NULL);
+  JVMCI::oops_do(&rcl);
+  return rcl.complete();
+}
+#endif
+
 bool ReferenceToRootClosure::do_roots() {
   assert(!complete(), "invariant");
   assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");
@@ -238,6 +251,13 @@
     return true;
   }
 
+#if INCLUDE_JVMCI
+  if (do_jvmci_roots()) {
+   _complete = true;
+    return true;
+  }
+#endif
+
   return false;
 }
 
--- a/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jfr/leakprofiler/utilities/rootType.hpp	Wed May 01 12:31:29 2019 -0700
@@ -43,6 +43,7 @@
     _code_cache,
     _string_table,
     _aot,
+    JVMCI_ONLY(_jvmci COMMA)
     _number_of_systems
   };
 
@@ -81,6 +82,10 @@
         return "String Table";
       case _aot:
         return "AOT";
+#if INCLUDE_JVMCI
+      case _jvmci:
+        return "JVMCI";
+#endif
       default:
         ShouldNotReachHere();
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/jvmci/jniAccessMark.inline.hpp	Wed May 01 12:31:29 2019 -0700
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, 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.
+ *
+ */
+
+#ifndef SHARE_JVMCI_JNIACCESSMARK_INLINE_HPP
+#define SHARE_JVMCI_JNIACCESSMARK_INLINE_HPP
+
+#include "jvmci/jvmciEnv.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+
+// Wrapper for a JNI call into the JVMCI shared library.
+// This performs a ThreadToNativeFromVM transition so that the VM
+// will not be blocked if the call takes a long time (e.g., due
+// to a GC in the shared library).
+class JNIAccessMark : public StackObj {
+ private:
+  ThreadToNativeFromVM ttnfv;
+  HandleMark hm;
+  JNIEnv* _env;
+ public:
+  inline JNIAccessMark(JVMCIEnv* jvmci_env) :
+    ttnfv(JavaThread::current()), hm(JavaThread::current()) {
+    _env = jvmci_env->_env;
+  }
+  JNIEnv* env() const { return _env; }
+  JNIEnv* operator () () const { return _env; }
+};
+
+#endif // SHARE_JVMCI_JNIACCESSMARK_INLINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/jvmci/jvmci.cpp	Wed May 01 12:31:29 2019 -0700
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+#include "precompiled.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/oopStorage.inline.hpp"
+#include "jvmci/jvmci.hpp"
+#include "jvmci/jvmci_globals.hpp"
+#include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciRuntime.hpp"
+#include "jvmci/metadataHandleBlock.hpp"
+
+OopStorage* JVMCI::_object_handles = NULL;
+MetadataHandleBlock* JVMCI::_metadata_handles = NULL;
+JVMCIRuntime* JVMCI::_compiler_runtime = NULL;
+JVMCIRuntime* JVMCI::_java_runtime = NULL;
+
+bool JVMCI::can_initialize_JVMCI() {
+  // Initializing JVMCI requires the module system to be initialized past phase 3.
+  // The JVMCI API itself isn't available until phase 2 and ServiceLoader (which
+  // JVMCI initialization requires) isn't usable until after phase 3. Testing
+  // whether the system loader is initialized satisfies all these invariants.
+  if (SystemDictionary::java_system_loader() == NULL) {
+    return false;
+  }
+  assert(Universe::is_module_initialized(), "must be");
+  return true;
+}
+
+void JVMCI::initialize_compiler(TRAPS) {
+  if (JVMCILibDumpJNIConfig) {
+    JNIJVMCI::initialize_ids(NULL);
+    ShouldNotReachHere();
+  }
+
+  JVMCI::compiler_runtime()->call_getCompiler(CHECK);
+}
+
+void JVMCI::initialize_globals() {
+  _object_handles = new OopStorage("JVMCI Global Oop Handles",
+                                   JVMCIGlobalAlloc_lock,
+                                   JVMCIGlobalActive_lock);
+  _metadata_handles = MetadataHandleBlock::allocate_block();
+  if (UseJVMCINativeLibrary) {
+    // There are two runtimes.
+    _compiler_runtime = new JVMCIRuntime();
+    _java_runtime = new JVMCIRuntime();
+  } else {
+    // There is only a single runtime
+    _java_runtime = _compiler_runtime = new JVMCIRuntime();
+  }
+}
+
+OopStorage* JVMCI::object_handles() {
+  assert(_object_handles != NULL, "Uninitialized");
+  return _object_handles;
+}
+
+jobject JVMCI::make_global(const Handle& obj) {
+  assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
+  assert(oopDesc::is_oop(obj()), "not an oop");
+  oop* ptr = object_handles()->allocate();
+  jobject res = NULL;
+  if (ptr != NULL) {
+    assert(*ptr == NULL, "invariant");
+    NativeAccess<>::oop_store(ptr, obj());
+    res = reinterpret_cast<jobject>(ptr);
+  } else {
+    vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
+                          "Cannot create JVMCI oop handle");
+  }
+  return res;
+}
+
+bool JVMCI::is_global_handle(jobject handle) {
+  const oop* ptr = reinterpret_cast<oop*>(handle);
+  return object_handles()->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY;
+}
+
+jmetadata JVMCI::allocate_handle(const methodHandle& handle) {
+  assert(_metadata_handles != NULL, "uninitialized");
+  MutexLocker ml(JVMCI_lock);
+  return _metadata_handles->allocate_handle(handle);
+}
+
+jmetadata JVMCI::allocate_handle(const constantPoolHandle& handle) {
+  assert(_metadata_handles != NULL, "uninitialized");
+  MutexLocker ml(JVMCI_lock);
+  return _metadata_handles->allocate_handle(handle);
+}
+
+void JVMCI::release_handle(jmetadata handle) {
+  MutexLocker ml(JVMCI_lock);
+  _metadata_handles->chain_free_list(handle);
+}
+
+void JVMCI::oops_do(OopClosure* f) {
+  if (_object_handles != NULL) {
+    _object_handles->oops_do(f);
+  }
+}
+
+void JVMCI::metadata_do(void f(Metadata*)) {
+  if (_metadata_handles != NULL) {
+    _metadata_handles->metadata_do(f);
+  }
+}
+
+void JVMCI::do_unloading(bool unloading_occurred) {
+  if (_metadata_handles != NULL && unloading_occurred) {
+    _metadata_handles->do_unloading();
+  }
+}
+
+bool JVMCI::is_compiler_initialized() {
+  return compiler_runtime()->is_HotSpotJVMCIRuntime_initialized();
+}
+
+void JVMCI::shutdown() {
+  if (compiler_runtime() != NULL) {
+    compiler_runtime()->shutdown();
+  }
+}
+
+bool JVMCI::shutdown_called() {
+  if (compiler_runtime() != NULL) {
+    return compiler_runtime()->shutdown_called();
+  }
+  return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/jvmci/jvmci.hpp	Wed May 01 12:31:29 2019 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2017, 2019, 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.
+ */
+
+#ifndef SHARE_JVMCI_JVMCI_HPP
+#define SHARE_JVMCI_JVMCI_HPP
+
+#include "compiler/compilerDefinitions.hpp"
+#include "utilities/exceptions.hpp"
+
+class BoolObjectClosure;
+class constantPoolHandle;
+class JavaThread;
+class JVMCIEnv;
+class JVMCIRuntime;
+class Metadata;
+class MetadataHandleBlock;
+class OopClosure;
+class OopStorage;
+
+struct _jmetadata;
+typedef struct _jmetadata *jmetadata;
+
+class JVMCI : public AllStatic {
+  friend class JVMCIRuntime;
+  friend class JVMCIEnv;
+
+ private:
+  // Handles to objects in the HotSpot heap.
+  static OopStorage* _object_handles;
+
+  static OopStorage* object_handles();
+
+  // Handles to Metadata objects.
+  static MetadataHandleBlock* _metadata_handles;
+
+  // Access to the HotSpotJVMCIRuntime used by the CompileBroker.
+  static JVMCIRuntime* _compiler_runtime;
+
+  // Access to the HotSpotJVMCIRuntime used by Java code running on the
+  // HotSpot heap. It will be the same as _compiler_runtime if
+  // UseJVMCINativeLibrary is false
+  static JVMCIRuntime* _java_runtime;
+
+ public:
+  enum CodeInstallResult {
+     ok,
+     dependencies_failed,
+     dependencies_invalid,
+     cache_full,
+     code_too_large
+  };
+
+  static void do_unloading(bool unloading_occurred);
+
+  static void metadata_do(void f(Metadata*));
+
+  static void oops_do(OopClosure* f);
+
+  static void shutdown();
+
+  static bool shutdown_called();
+
+  static bool is_compiler_initialized();
+
+  /**
+   * Determines if the VM is sufficiently booted to initialize JVMCI.
+   */
+  static bool can_initialize_JVMCI();
+
+  static void initialize_globals();
+
+  static void initialize_compiler(TRAPS);
+
+  static jobject make_global(const Handle& obj);
+  static bool is_global_handle(jobject handle);
+
+  static jmetadata allocate_handle(const methodHandle& handle);
+  static jmetadata allocate_handle(const constantPoolHandle& handle);
+
+  static void release_handle(jmetadata handle);
+
+  static JVMCIRuntime* compiler_runtime() { return _compiler_runtime; }
+  static JVMCIRuntime* java_runtime()     { return _java_runtime; }
+};
+
+#endif // SHARE_JVMCI_JVMCI_HPP
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.cpp	Wed May 01 12:31:29 2019 -0700
@@ -22,28 +22,13 @@
  */
 
 #include "precompiled.hpp"
-#include "asm/register.hpp"
-#include "classfile/vmSymbols.hpp"
 #include "code/compiledIC.hpp"
-#include "code/vmreg.inline.hpp"
 #include "compiler/compileBroker.hpp"
-#include "compiler/disassembler.hpp"
-#include "jvmci/jvmciEnv.hpp"
-#include "jvmci/jvmciCompiler.hpp"
 #include "jvmci/jvmciCodeInstaller.hpp"
-#include "jvmci/jvmciJavaClasses.hpp"
 #include "jvmci/jvmciCompilerToVM.hpp"
 #include "jvmci/jvmciRuntime.hpp"
-#include "memory/allocation.inline.hpp"
-#include "oops/arrayOop.inline.hpp"
-#include "oops/oop.inline.hpp"
-#include "oops/objArrayOop.inline.hpp"
-#include "oops/typeArrayOop.inline.hpp"
-#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
-#include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.inline.hpp"
-#include "runtime/safepointMechanism.inline.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "utilities/align.hpp"
 
@@ -51,30 +36,25 @@
 // Allocate them with new so they are never destroyed (otherwise, a
 // forced exit could destroy these objects while they are still in
 // use).
-ConstantOopWriteValue* CodeInstaller::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL);
-ConstantIntValue*      CodeInstaller::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1);
-ConstantIntValue*      CodeInstaller::_int_0_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue((jint)0);
-ConstantIntValue*      CodeInstaller::_int_1_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1);
-ConstantIntValue*      CodeInstaller::_int_2_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2);
-LocationValue*         CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location());
+ConstantOopWriteValue* CodeInstaller::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantOopWriteValue(NULL);
+ConstantIntValue*      CodeInstaller::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue(-1);
+ConstantIntValue*      CodeInstaller::_int_0_scope_value =  new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue((jint)0);
+ConstantIntValue*      CodeInstaller::_int_1_scope_value =  new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue(1);
+ConstantIntValue*      CodeInstaller::_int_2_scope_value =  new (ResourceObj::C_HEAP, mtJVMCI) ConstantIntValue(2);
+LocationValue*         CodeInstaller::_illegal_value = new (ResourceObj::C_HEAP, mtJVMCI) LocationValue(Location());
 
-Method* getMethodFromHotSpotMethod(oop hotspot_method) {
-  assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass()), "sanity");
-  return CompilerToVM::asMethod(hotspot_method);
-}
-
-VMReg getVMRegFromLocation(Handle location, int total_frame_size, TRAPS) {
+VMReg CodeInstaller::getVMRegFromLocation(JVMCIObject location, int total_frame_size, JVMCI_TRAPS) {
   if (location.is_null()) {
-    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+    JVMCI_THROW_NULL(NullPointerException);
   }
 
-  Handle reg(THREAD, code_Location::reg(location));
-  jint offset = code_Location::offset(location);
+  JVMCIObject reg = jvmci_env()->get_code_Location_reg(location);
+  jint offset = jvmci_env()->get_code_Location_offset(location);
 
-  if (reg.not_null()) {
+  if (reg.is_non_null()) {
     // register
-    jint number = code_Register::number(reg);
-    VMReg vmReg = CodeInstaller::get_hotspot_reg(number, CHECK_NULL);
+    jint number = jvmci_env()->get_code_Register_number(reg);
+    VMReg vmReg = CodeInstaller::get_hotspot_reg(number, JVMCI_CHECK_NULL);
     if (offset % 4 == 0) {
       return vmReg->next(offset / 4);
     } else {
@@ -102,71 +82,45 @@
   }
 }
 
-objArrayOop CodeInstaller::sites() {
-  return (objArrayOop) JNIHandles::resolve(_sites_handle);
-}
-
-arrayOop CodeInstaller::code() {
-  return (arrayOop) JNIHandles::resolve(_code_handle);
-}
-
-arrayOop CodeInstaller::data_section() {
-  return (arrayOop) JNIHandles::resolve(_data_section_handle);
-}
-
-objArrayOop CodeInstaller::data_section_patches() {
-  return (objArrayOop) JNIHandles::resolve(_data_section_patches_handle);
-}
-
-#ifndef PRODUCT
-objArrayOop CodeInstaller::comments() {
-  return (objArrayOop) JNIHandles::resolve(_comments_handle);
-}
-#endif
-
-oop CodeInstaller::word_kind() {
-  return JNIHandles::resolve(_word_kind_handle);
-}
-
 // 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(THREAD, DebugInfo::referenceMap(debug_info));
+OopMap* CodeInstaller::create_oop_map(JVMCIObject debug_info, JVMCI_TRAPS) {
+  JVMCIObject reference_map = jvmci_env()->get_DebugInfo_referenceMap(debug_info);
   if (reference_map.is_null()) {
-    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+    JVMCI_THROW_NULL(NullPointerException);
   }
-  if (!reference_map->is_a(HotSpotReferenceMap::klass())) {
-    JVMCI_ERROR_NULL("unknown reference map: %s", reference_map->klass()->signature_name());
+  if (!jvmci_env()->isa_HotSpotReferenceMap(reference_map)) {
+    JVMCI_ERROR_NULL("unknown reference map: %s", jvmci_env()->klass_name(reference_map));
   }
-  if (!_has_wide_vector && SharedRuntime::is_wide_vector(HotSpotReferenceMap::maxRegisterSize(reference_map))) {
+  if (!_has_wide_vector && SharedRuntime::is_wide_vector(jvmci_env()->get_HotSpotReferenceMap_maxRegisterSize(reference_map))) {
     if (SharedRuntime::polling_page_vectors_safepoint_handler_blob() == NULL) {
       JVMCI_ERROR_NULL("JVMCI is producing code using vectors larger than the runtime supports");
     }
     _has_wide_vector = true;
   }
   OopMap* map = new OopMap(_total_frame_size, _parameter_count);
-  objArrayHandle objects(THREAD, HotSpotReferenceMap::objects(reference_map));
-  objArrayHandle derivedBase(THREAD, HotSpotReferenceMap::derivedBase(reference_map));
-  typeArrayHandle sizeInBytes(THREAD, HotSpotReferenceMap::sizeInBytes(reference_map));
+  JVMCIObjectArray objects = jvmci_env()->get_HotSpotReferenceMap_objects(reference_map);
+  JVMCIObjectArray derivedBase = jvmci_env()->get_HotSpotReferenceMap_derivedBase(reference_map);
+  JVMCIPrimitiveArray sizeInBytes = jvmci_env()->get_HotSpotReferenceMap_sizeInBytes(reference_map);
   if (objects.is_null() || derivedBase.is_null() || sizeInBytes.is_null()) {
-    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+    JVMCI_THROW_NULL(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());
+  if (JVMCIENV->get_length(objects) != JVMCIENV->get_length(derivedBase) || JVMCIENV->get_length(objects) != JVMCIENV->get_length(sizeInBytes)) {
+    JVMCI_ERROR_NULL("arrays in reference map have different sizes: %d %d %d", JVMCIENV->get_length(objects), JVMCIENV->get_length(derivedBase), JVMCIENV->get_length(sizeInBytes));
   }
-  for (int i = 0; i < objects->length(); i++) {
-    Handle location(THREAD, objects->obj_at(i));
-    Handle baseLocation(THREAD, derivedBase->obj_at(i));
-    int bytes = sizeInBytes->int_at(i);
+  for (int i = 0; i < JVMCIENV->get_length(objects); i++) {
+    JVMCIObject location = JVMCIENV->get_object_at(objects, i);
+    JVMCIObject baseLocation = JVMCIENV->get_object_at(derivedBase, i);
+    jint bytes = JVMCIENV->get_int_at(sizeInBytes, i);
 
-    VMReg vmReg = getVMRegFromLocation(location, _total_frame_size, CHECK_NULL);
-    if (baseLocation.not_null()) {
+    VMReg vmReg = getVMRegFromLocation(location, _total_frame_size, JVMCI_CHECK_NULL);
+    if (baseLocation.is_non_null()) {
       // derived oop
 #ifdef _LP64
       if (bytes == 8) {
 #else
       if (bytes == 4) {
 #endif
-        VMReg baseReg = getVMRegFromLocation(baseLocation, _total_frame_size, CHECK_NULL);
+        VMReg baseReg = getVMRegFromLocation(baseLocation, _total_frame_size, JVMCI_CHECK_NULL);
         map->set_derived_oop(vmReg, baseReg);
       } else {
         JVMCI_ERROR_NULL("invalid derived oop size in ReferenceMap: %d", bytes);
@@ -187,16 +141,16 @@
     }
   }
 
-  Handle callee_save_info(THREAD, (oop) DebugInfo::calleeSaveInfo(debug_info));
-  if (callee_save_info.not_null()) {
-    objArrayHandle registers(THREAD, RegisterSaveLayout::registers(callee_save_info));
-    typeArrayHandle slots(THREAD, RegisterSaveLayout::slots(callee_save_info));
-    for (jint i = 0; i < slots->length(); i++) {
-      Handle jvmci_reg (THREAD, registers->obj_at(i));
-      jint jvmci_reg_number = code_Register::number(jvmci_reg);
-      VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number, CHECK_NULL);
+  JVMCIObject callee_save_info = jvmci_env()->get_DebugInfo_calleeSaveInfo(debug_info);
+  if (callee_save_info.is_non_null()) {
+    JVMCIObjectArray registers = jvmci_env()->get_RegisterSaveLayout_registers(callee_save_info);
+    JVMCIPrimitiveArray slots = jvmci_env()->get_RegisterSaveLayout_slots(callee_save_info);
+    for (jint i = 0; i < JVMCIENV->get_length(slots); i++) {
+      JVMCIObject jvmci_reg = JVMCIENV->get_object_at(registers, i);
+      jint jvmci_reg_number = jvmci_env()->get_code_Register_number(jvmci_reg);
+      VMReg hotspot_reg = CodeInstaller::get_hotspot_reg(jvmci_reg_number, JVMCI_CHECK_NULL);
       // HotSpot stack slots are 4 bytes
-      jint jvmci_slot = slots->int_at(i);
+      jint jvmci_slot = JVMCIENV->get_int_at(slots, i);
       jint hotspot_slot = jvmci_slot * VMRegImpl::slots_per_word;
       VMReg hotspot_slot_as_reg = VMRegImpl::stack2reg(hotspot_slot);
       map->set_callee_saved(hotspot_slot_as_reg, hotspot_reg);
@@ -211,7 +165,8 @@
 }
 
 #if INCLUDE_AOT
-AOTOopRecorder::AOTOopRecorder(Arena* arena, bool deduplicate) : OopRecorder(arena, deduplicate) {
+AOTOopRecorder::AOTOopRecorder(CodeInstaller* code_inst, Arena* arena, bool deduplicate) : OopRecorder(arena, deduplicate) {
+  _code_inst = code_inst;
   _meta_refs = new GrowableArray<jobject>();
 }
 
@@ -225,6 +180,7 @@
 
 int AOTOopRecorder::find_index(Metadata* h) {
   JavaThread* THREAD = JavaThread::current();
+  JVMCIEnv* JVMCIENV = _code_inst->jvmci_env();
   int oldCount = metadata_count();
   int index =  this->OopRecorder::find_index(h);
   int newCount = metadata_count();
@@ -237,18 +193,18 @@
   vmassert(index + 1 == newCount, "must be last");
 
   JVMCIKlassHandle klass(THREAD);
-  oop result = NULL;
+  JVMCIObject result;
   guarantee(h != NULL,
             "If DebugInformationRecorder::describe_scope passes NULL oldCount == newCount must hold.");
   if (h->is_klass()) {
     klass = (Klass*) h;
-    result = CompilerToVM::get_jvmci_type(klass, CATCH);
+    result = JVMCIENV->get_jvmci_type(klass, JVMCI_CATCH);
   } else if (h->is_method()) {
     Method* method = (Method*) h;
     methodHandle mh(method);
-    result = CompilerToVM::get_jvmci_method(method, CATCH);
+    result = JVMCIENV->get_jvmci_method(method, JVMCI_CATCH);
   }
-  jobject ref = JNIHandles::make_local(THREAD, result);
+  jobject ref = JVMCIENV->get_jobject(result);
   record_meta_ref(ref, index);
 
   return index;
@@ -272,43 +228,43 @@
 }
 #endif // INCLUDE_AOT
 
-void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) {
+void* CodeInstaller::record_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS) {
   /*
    * 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* or Method*), not a pointer to the
    * base class (Metadata* or MetaspaceObj*).
    */
-  oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
-  if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
-    Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
-    assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed klass pointer %s @ " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass));
+  JVMCIObject obj = jvmci_env()->get_HotSpotMetaspaceConstantImpl_metaspaceObject(constant);
+  if (jvmci_env()->isa_HotSpotResolvedObjectTypeImpl(obj)) {
+    Klass* klass = JVMCIENV->asKlass(obj);
+    assert(!jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant), "unexpected compressed klass pointer %s @ " INTPTR_FORMAT, klass->name()->as_C_string(), p2i(klass));
     int index = _oop_recorder->find_index(klass);
     section->relocate(dest, metadata_Relocation::spec(index));
     TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
     return klass;
-  } else if (obj->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
-    Method* method = (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(obj);
-    assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed method pointer %s @ " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method));
+  } else if (jvmci_env()->isa_HotSpotResolvedJavaMethodImpl(obj)) {
+    Method* method = jvmci_env()->asMethod(obj);
+    assert(!jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant), "unexpected compressed method pointer %s @ " INTPTR_FORMAT, method->name()->as_C_string(), p2i(method));
     int index = _oop_recorder->find_index(method);
     section->relocate(dest, metadata_Relocation::spec(index));
     TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string());
     return method;
   } else {
-    JVMCI_ERROR_NULL("unexpected metadata reference for constant of type %s", obj->klass()->signature_name());
+    JVMCI_ERROR_NULL("unexpected metadata reference for constant of type %s", jvmci_env()->klass_name(obj));
   }
 }
 
 #ifdef _LP64
-narrowKlass CodeInstaller::record_narrow_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS) {
-  oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
-  assert(HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected uncompressed pointer");
+narrowKlass CodeInstaller::record_narrow_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS) {
+  JVMCIObject obj = jvmci_env()->get_HotSpotMetaspaceConstantImpl_metaspaceObject(constant);
+  assert(jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant), "unexpected uncompressed pointer");
 
-  if (!obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
-    JVMCI_ERROR_0("unexpected compressed pointer of type %s", obj->klass()->signature_name());
+  if (!jvmci_env()->isa_HotSpotResolvedObjectTypeImpl(obj)) {
+    JVMCI_ERROR_0("unexpected compressed pointer of type %s", jvmci_env()->klass_name(obj));
   }
 
-  Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(obj));
+  Klass* klass = JVMCIENV->asKlass(obj);
   int index = _oop_recorder->find_index(klass);
   section->relocate(dest, metadata_Relocation::spec(index));
   TRACE_jvmci_3("narrowKlass[%d of %d] = %s", index, _oop_recorder->metadata_count(), klass->name()->as_C_string());
@@ -316,34 +272,34 @@
 }
 #endif
 
-Location::Type CodeInstaller::get_oop_type(Thread* thread, Handle value) {
-  Handle valueKind(thread, Value::valueKind(value));
-  Handle platformKind(thread, ValueKind::platformKind(valueKind));
+Location::Type CodeInstaller::get_oop_type(JVMCIObject value) {
+  JVMCIObject valueKind = jvmci_env()->get_Value_valueKind(value);
+  JVMCIObject platformKind = jvmci_env()->get_ValueKind_platformKind(valueKind);
 
-  if (platformKind == word_kind()) {
+  if (jvmci_env()->equals(platformKind, word_kind())) {
     return Location::oop;
   } else {
     return Location::narrowoop;
   }
 }
 
-ScopeValue* CodeInstaller::get_scope_value(Handle value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, TRAPS) {
+ScopeValue* CodeInstaller::get_scope_value(JVMCIObject value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, JVMCI_TRAPS) {
   second = NULL;
   if (value.is_null()) {
-    THROW_NULL(vmSymbols::java_lang_NullPointerException());
-  } else if (value == Value::ILLEGAL()) {
+    JVMCI_THROW_NULL(NullPointerException);
+  } else if (JVMCIENV->equals(value, jvmci_env()->get_Value_ILLEGAL())) {
     if (type != T_ILLEGAL) {
       JVMCI_ERROR_NULL("unexpected illegal value, expected %s", basictype_to_str(type));
     }
     return _illegal_value;
-  } else if (value->is_a(RegisterValue::klass())) {
-    Handle reg(THREAD, RegisterValue::reg(value));
-    jint number = code_Register::number(reg);
-    VMReg hotspotRegister = get_hotspot_reg(number, CHECK_NULL);
+  } else if (jvmci_env()->isa_RegisterValue(value)) {
+    JVMCIObject reg = jvmci_env()->get_RegisterValue_reg(value);
+    jint number = jvmci_env()->get_code_Register_number(reg);
+    VMReg hotspotRegister = get_hotspot_reg(number, JVMCI_CHECK_NULL);
     if (is_general_purpose_reg(hotspotRegister)) {
       Location::Type locationType;
       if (type == T_OBJECT) {
-        locationType = get_oop_type(THREAD, value);
+        locationType = get_oop_type(value);
       } else if (type == T_LONG) {
         locationType = Location::lng;
       } else if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BYTE || type == T_BOOLEAN) {
@@ -372,15 +328,15 @@
       }
       return value;
     }
-  } else if (value->is_a(StackSlot::klass())) {
-    jint offset = StackSlot::offset(value);
-    if (StackSlot::addFrameSize(value)) {
+  } else if (jvmci_env()->isa_StackSlot(value)) {
+    jint offset = jvmci_env()->get_StackSlot_offset(value);
+    if (jvmci_env()->get_StackSlot_addFrameSize(value)) {
       offset += _total_frame_size;
     }
 
     Location::Type locationType;
     if (type == T_OBJECT) {
-      locationType = get_oop_type(THREAD, value);
+      locationType = get_oop_type(value);
     } else if (type == T_LONG) {
       locationType = Location::lng;
     } else if (type == T_DOUBLE) {
@@ -395,19 +351,18 @@
       second = value;
     }
     return value;
-  } else if (value->is_a(JavaConstant::klass())) {
-    if (value->is_a(PrimitiveConstant::klass())) {
-      if (value->is_a(RawConstant::klass())) {
-        jlong prim = PrimitiveConstant::primitive(value);
+  } else if (jvmci_env()->isa_JavaConstant(value)) {
+    if (jvmci_env()->isa_PrimitiveConstant(value)) {
+      if (jvmci_env()->isa_RawConstant(value)) {
+        jlong prim = jvmci_env()->get_PrimitiveConstant_primitive(value);
         return new ConstantLongValue(prim);
       } else {
-        Handle primitive_constant_kind(THREAD, PrimitiveConstant::kind(value));
-        BasicType constantType = JVMCIRuntime::kindToBasicType(primitive_constant_kind, CHECK_NULL);
+        BasicType constantType = jvmci_env()->kindToBasicType(jvmci_env()->get_PrimitiveConstant_kind(value), JVMCI_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));
         }
         if (type == T_INT || type == T_FLOAT) {
-          jint prim = (jint)PrimitiveConstant::primitive(value);
+          jint prim = (jint)jvmci_env()->get_PrimitiveConstant_primitive(value);
           switch (prim) {
             case -1: return _int_m1_scope_value;
             case  0: return _int_0_scope_value;
@@ -416,33 +371,33 @@
             default: return new ConstantIntValue(prim);
           }
         } else if (type == T_LONG || type == T_DOUBLE) {
-          jlong prim = PrimitiveConstant::primitive(value);
+          jlong prim = jvmci_env()->get_PrimitiveConstant_primitive(value);
           second = _int_1_scope_value;
           return new ConstantLongValue(prim);
         } else {
           JVMCI_ERROR_NULL("unexpected primitive constant type %s", basictype_to_str(type));
         }
       }
-    } else if (value->is_a(NullConstant::klass()) || value->is_a(HotSpotCompressedNullConstant::klass())) {
+    } else if (jvmci_env()->isa_NullConstant(value) || jvmci_env()->isa_HotSpotCompressedNullConstant(value)) {
       if (type == T_OBJECT) {
         return _oop_null_scope_value;
       } else {
         JVMCI_ERROR_NULL("unexpected null constant, expected %s", basictype_to_str(type));
       }
-    } else if (value->is_a(HotSpotObjectConstantImpl::klass())) {
+    } else if (jvmci_env()->isa_HotSpotObjectConstantImpl(value)) {
       if (type == T_OBJECT) {
-        oop obj = HotSpotObjectConstantImpl::object(value);
+        Handle obj = jvmci_env()->asConstant(value, JVMCI_CHECK_NULL);
         if (obj == NULL) {
           JVMCI_ERROR_NULL("null value must be in NullConstant");
         }
-        return new ConstantOopWriteValue(JNIHandles::make_local(obj));
+        return new ConstantOopWriteValue(JNIHandles::make_local(obj()));
       } else {
         JVMCI_ERROR_NULL("unexpected object constant, expected %s", basictype_to_str(type));
       }
     }
-  } else if (value->is_a(VirtualObject::klass())) {
+  } else if (jvmci_env()->isa_VirtualObject(value)) {
     if (type == T_OBJECT) {
-      int id = VirtualObject::id(value);
+      int id = jvmci_env()->get_VirtualObject_id(value);
       if (0 <= id && id < objects->length()) {
         ScopeValue* object = objects->at(id);
         if (object != NULL) {
@@ -455,26 +410,22 @@
     }
   }
 
-  JVMCI_ERROR_NULL("unexpected value in scope: %s", value->klass()->signature_name())
+  JVMCI_ERROR_NULL("unexpected value in scope: %s", jvmci_env()->klass_name(value))
 }
 
-void CodeInstaller::record_object_value(ObjectValue* sv, Handle value, GrowableArray<ScopeValue*>* objects, TRAPS) {
-  // Might want a HandleMark here.
-  Handle type(THREAD, VirtualObject::type(value));
-  int id = VirtualObject::id(value);
-  oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type);
-  Klass* klass = java_lang_Class::as_Klass(javaMirror);
+void CodeInstaller::record_object_value(ObjectValue* sv, JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS) {
+  JVMCIObject type = jvmci_env()->get_VirtualObject_type(value);
+  int id = jvmci_env()->get_VirtualObject_id(value);
+  Klass* klass = JVMCIENV->asKlass(type);
   bool isLongArray = klass == Universe::longArrayKlassObj();
 
-  objArrayHandle values(THREAD, VirtualObject::values(value));
-  objArrayHandle slotKinds(THREAD, VirtualObject::slotKinds(value));
-  for (jint i = 0; i < values->length(); i++) {
-    HandleMark hm(THREAD);
+  JVMCIObjectArray values = jvmci_env()->get_VirtualObject_values(value);
+  JVMCIObjectArray slotKinds = jvmci_env()->get_VirtualObject_slotKinds(value);
+  for (jint i = 0; i < JVMCIENV->get_length(values); i++) {
     ScopeValue* cur_second = NULL;
-    Handle object(THREAD, values->obj_at(i));
-    Handle slot_kind (THREAD, slotKinds->obj_at(i));
-    BasicType type = JVMCIRuntime::kindToBasicType(slot_kind, CHECK);
-    ScopeValue* value = get_scope_value(object, type, objects, cur_second, CHECK);
+    JVMCIObject object = JVMCIENV->get_object_at(values, i);
+    BasicType type = jvmci_env()->kindToBasicType(JVMCIENV->get_object_at(slotKinds, i), JVMCI_CHECK);
+    ScopeValue* value = get_scope_value(object, type, objects, cur_second, JVMCI_CHECK);
 
     if (isLongArray && cur_second == NULL) {
       // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
@@ -490,68 +441,65 @@
   }
 }
 
-MonitorValue* CodeInstaller::get_monitor_value(Handle value, GrowableArray<ScopeValue*>* objects, TRAPS) {
+MonitorValue* CodeInstaller::get_monitor_value(JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS) {
   if (value.is_null()) {
-    THROW_NULL(vmSymbols::java_lang_NullPointerException());
+    JVMCI_THROW_NULL(NullPointerException);
   }
-  if (!value->is_a(StackLockValue::klass())) {
-    JVMCI_ERROR_NULL("Monitors must be of type StackLockValue, got %s", value->klass()->signature_name());
+  if (!jvmci_env()->isa_StackLockValue(value)) {
+    JVMCI_ERROR_NULL("Monitors must be of type StackLockValue, got %s", jvmci_env()->klass_name(value));
   }
 
   ScopeValue* second = NULL;
-  Handle stack_lock_owner(THREAD, StackLockValue::owner(value));
-  ScopeValue* owner_value = get_scope_value(stack_lock_owner, T_OBJECT, objects, second, CHECK_NULL);
+  ScopeValue* owner_value = get_scope_value(jvmci_env()->get_StackLockValue_owner(value), T_OBJECT, objects, second, JVMCI_CHECK_NULL);
   assert(second == NULL, "monitor cannot occupy two stack slots");
 
-  Handle stack_lock_slot(THREAD, StackLockValue::slot(value));
-  ScopeValue* lock_data_value = get_scope_value(stack_lock_slot, T_LONG, objects, second, CHECK_NULL);
+  ScopeValue* lock_data_value = get_scope_value(jvmci_env()->get_StackLockValue_slot(value), T_LONG, objects, second, JVMCI_CHECK_NULL);
   assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");
   assert(lock_data_value->is_location(), "invalid monitor location");
   Location lock_data_loc = ((LocationValue*)lock_data_value)->location();
 
   bool eliminated = false;
-  if (StackLockValue::eliminated(value)) {
+  if (jvmci_env()->get_StackLockValue_eliminated(value)) {
     eliminated = true;
   }
 
   return new MonitorValue(owner_value, lock_data_loc, eliminated);
 }
 
-void CodeInstaller::initialize_dependencies(oop compiled_code, OopRecorder* recorder, TRAPS) {
+void CodeInstaller::initialize_dependencies(JVMCIObject compiled_code, OopRecorder* oop_recorder, JVMCI_TRAPS) {
   JavaThread* thread = JavaThread::current();
-  assert(THREAD == thread, "");
   CompilerThread* compilerThread = thread->is_Compiler_thread() ? thread->as_CompilerThread() : NULL;
-  _oop_recorder = recorder;
+  _oop_recorder = oop_recorder;
   _dependencies = new Dependencies(&_arena, _oop_recorder, compilerThread != NULL ? compilerThread->log() : NULL);
-  objArrayHandle assumptions(THREAD, HotSpotCompiledCode::assumptions(compiled_code));
-  if (!assumptions.is_null()) {
-    int length = assumptions->length();
+  JVMCIObjectArray assumptions = jvmci_env()->get_HotSpotCompiledCode_assumptions(compiled_code);
+  if (assumptions.is_non_null()) {
+    int length = JVMCIENV->get_length(assumptions);
     for (int i = 0; i < length; ++i) {
-      Handle assumption(THREAD, assumptions->obj_at(i));
-      if (!assumption.is_null()) {
-        if (assumption->klass() == Assumptions_NoFinalizableSubclass::klass()) {
-          assumption_NoFinalizableSubclass(THREAD, assumption);
-        } else if (assumption->klass() == Assumptions_ConcreteSubtype::klass()) {
-          assumption_ConcreteSubtype(THREAD, assumption);
-        } else if (assumption->klass() == Assumptions_LeafType::klass()) {
-          assumption_LeafType(THREAD, assumption);
-        } else if (assumption->klass() == Assumptions_ConcreteMethod::klass()) {
-          assumption_ConcreteMethod(THREAD, assumption);
-        } else if (assumption->klass() == Assumptions_CallSiteTargetValue::klass()) {
-          assumption_CallSiteTargetValue(THREAD, assumption);
+      JVMCIObject assumption = JVMCIENV->get_object_at(assumptions, i);
+      if (assumption.is_non_null()) {
+        if (jvmci_env()->isa_Assumptions_NoFinalizableSubclass(assumption)) {
+          assumption_NoFinalizableSubclass(assumption);
+        } else if (jvmci_env()->isa_Assumptions_ConcreteSubtype(assumption)) {
+          assumption_ConcreteSubtype(assumption);
+        } else if (jvmci_env()->isa_Assumptions_LeafType(assumption)) {
+          assumption_LeafType(assumption);
+        } else if (jvmci_env()->isa_Assumptions_ConcreteMethod(assumption)) {
+          assumption_ConcreteMethod(assumption);
+        } else if (jvmci_env()->isa_Assumptions_CallSiteTargetValue(assumption)) {
+          assumption_CallSiteTargetValue(assumption, JVMCI_CHECK);
         } else {
-          JVMCI_ERROR("unexpected Assumption subclass %s", assumption->klass()->signature_name());
+          JVMCI_ERROR("unexpected Assumption subclass %s", jvmci_env()->klass_name(assumption));
         }
       }
     }
   }
   if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
-    objArrayHandle methods(THREAD, HotSpotCompiledCode::methods(compiled_code));
-    if (!methods.is_null()) {
-      int length = methods->length();
+    JVMCIObjectArray methods = jvmci_env()->get_HotSpotCompiledCode_methods(compiled_code);
+    if (methods.is_non_null()) {
+      int length = JVMCIENV->get_length(methods);
       for (int i = 0; i < length; ++i) {
-        Handle method_handle(THREAD, methods->obj_at(i));
-        methodHandle method = getMethodFromHotSpotMethod(method_handle());
+        JVMCIObject method_handle = JVMCIENV->get_object_at(methods, i);
+        methodHandle method = jvmci_env()->asMethod(method_handle);
         _dependencies->assert_evol_method(method());
       }
     }
@@ -581,16 +529,16 @@
   assert(_buffer == NULL, "can only be used once");
   assert(_size == 0, "can only be used once");
   if (bytes >= RelocBuffer::stack_size) {
-    _buffer = NEW_C_HEAP_ARRAY(char, bytes, mtInternal);
+    _buffer = NEW_C_HEAP_ARRAY(char, bytes, mtJVMCI);
   }
   _size = bytes;
 }
 
-JVMCIEnv::CodeInstallResult CodeInstaller::gather_metadata(Handle target, Handle compiled_code, CodeMetadata& metadata, TRAPS) {
+JVMCI::CodeInstallResult CodeInstaller::gather_metadata(JVMCIObject target, JVMCIObject compiled_code, CodeMetadata& metadata, JVMCI_TRAPS) {
+  assert(JVMCIENV->is_hotspot(), "AOT code is executed only in HotSpot mode");
   CodeBuffer buffer("JVMCI Compiler CodeBuffer for Metadata");
-  jobject compiled_code_obj = JNIHandles::make_local(compiled_code());
-  AOTOopRecorder* recorder = new AOTOopRecorder(&_arena, true);
-  initialize_dependencies(JNIHandles::resolve(compiled_code_obj), recorder, CHECK_OK);
+  AOTOopRecorder* recorder = new AOTOopRecorder(this, &_arena, true);
+  initialize_dependencies(compiled_code, recorder, JVMCI_CHECK_OK);
 
   metadata.set_oop_recorder(recorder);
 
@@ -599,9 +547,9 @@
   _constants = buffer.consts();
   buffer.set_immutable_PIC(_immutable_pic_compilation);
 
-  initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK);
-  JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, false, CHECK_OK);
-  if (result != JVMCIEnv::ok) {
+  initialize_fields(target, compiled_code, JVMCI_CHECK_OK);
+  JVMCI::CodeInstallResult result = initialize_buffer(buffer, false, JVMCI_CHECK_OK);
+  if (result != JVMCI::ok) {
     return result;
   }
 
@@ -618,16 +566,24 @@
   reloc_buffer->ensure_size(buffer.total_relocation_size());
   size_t size = (size_t) buffer.copy_relocations_to(reloc_buffer->begin(), (CodeBuffer::csize_t) reloc_buffer->size(), true);
   reloc_buffer->set_size(size);
-  return JVMCIEnv::ok;
+  return JVMCI::ok;
 }
 #endif // INCLUDE_AOT
 
 // constructor used to create a method
-JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Handle target, Handle compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log, TRAPS) {
+JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler,
+    JVMCIObject target,
+    JVMCIObject compiled_code,
+    CodeBlob*& cb,
+    JVMCIObject installed_code,
+    FailedSpeculation** failed_speculations,
+    char* speculations,
+    int speculations_len,
+    JVMCI_TRAPS) {
+
   CodeBuffer buffer("JVMCI Compiler CodeBuffer");
-  jobject compiled_code_obj = JNIHandles::make_local(compiled_code());
   OopRecorder* recorder = new OopRecorder(&_arena, true);
-  initialize_dependencies(JNIHandles::resolve(compiled_code_obj), recorder, CHECK_OK);
+  initialize_dependencies(compiled_code, recorder, JVMCI_CHECK_OK);
 
   // Get instructions and constants CodeSections early because we need it.
   _instructions = buffer.insts();
@@ -636,44 +592,55 @@
   buffer.set_immutable_PIC(_immutable_pic_compilation);
 #endif
 
-  initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK);
-  JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, true, CHECK_OK);
-  if (result != JVMCIEnv::ok) {
+  initialize_fields(target, compiled_code, JVMCI_CHECK_OK);
+  JVMCI::CodeInstallResult result = initialize_buffer(buffer, true, JVMCI_CHECK_OK);
+  if (result != JVMCI::ok) {
     return result;
   }
 
   int stack_slots = _total_frame_size / HeapWordSize; // conversion to words
 
-  if (!compiled_code->is_a(HotSpotCompiledNmethod::klass())) {
-    oop stubName = HotSpotCompiledCode::name(compiled_code_obj);
-    if (stubName == NULL) {
+  if (!jvmci_env()->isa_HotSpotCompiledNmethod(compiled_code)) {
+    JVMCIObject stubName = jvmci_env()->get_HotSpotCompiledCode_name(compiled_code);
+    if (stubName.is_null()) {
       JVMCI_ERROR_OK("stub should have a name");
     }
-    char* name = strdup(java_lang_String::as_utf8_string(stubName));
+    char* name = strdup(jvmci_env()->as_utf8_string(stubName));
     cb = RuntimeStub::new_runtime_stub(name,
                                        &buffer,
                                        CodeOffsets::frame_never_safe,
                                        stack_slots,
                                        _debug_recorder->_oopmaps,
                                        false);
-    result = JVMCIEnv::ok;
+    result = JVMCI::ok;
   } else {
-    nmethod* nm = NULL;
-    methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code));
-    jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code);
-    jint id = HotSpotCompiledNmethod::id(compiled_code);
-    bool has_unsafe_access = HotSpotCompiledNmethod::hasUnsafeAccess(compiled_code) == JNI_TRUE;
-    JVMCIEnv* env = (JVMCIEnv*) (address) HotSpotCompiledNmethod::jvmciEnv(compiled_code);
+    JVMCICompileState* compile_state = (JVMCICompileState*) (address) jvmci_env()->get_HotSpotCompiledNmethod_compileState(compiled_code);
+    if (compile_state != NULL) {
+      jvmci_env()->set_compile_state(compile_state);
+    }
+
+    methodHandle method = jvmci_env()->asMethod(jvmci_env()->get_HotSpotCompiledNmethod_method(compiled_code));
+    jint entry_bci = jvmci_env()->get_HotSpotCompiledNmethod_entryBCI(compiled_code);
+    bool has_unsafe_access = jvmci_env()->get_HotSpotCompiledNmethod_hasUnsafeAccess(compiled_code) == JNI_TRUE;
+    jint id = jvmci_env()->get_HotSpotCompiledNmethod_id(compiled_code);
     if (id == -1) {
       // Make sure a valid compile_id is associated with every compile
       id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
+      jvmci_env()->set_HotSpotCompiledNmethod_id(compiled_code, id);
     }
-    result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer,
-                                       stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
-                                       compiler, _debug_recorder, _dependencies, env, id,
-                                       has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log);
+    if (!jvmci_env()->isa_HotSpotNmethod(installed_code)) {
+      JVMCI_THROW_MSG_(IllegalArgumentException, "InstalledCode object must be a HotSpotNmethod when installing a HotSpotCompiledNmethod", JVMCI::ok);
+    }
+
+    JVMCIObject mirror = installed_code;
+    nmethod* nm = NULL;
+    result = runtime()->register_method(jvmci_env(), method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer,
+                                        stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
+                                        compiler, _debug_recorder, _dependencies, id,
+                                        has_unsafe_access, _has_wide_vector, compiled_code, mirror,
+                                        failed_speculations, speculations, speculations_len);
     cb = nm->as_codeblob_or_null();
-    if (nm != NULL && env == NULL) {
+    if (nm != NULL && compile_state == NULL) {
       DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);
       bool printnmethods = directive->PrintAssemblyOption || directive->PrintNMethodsOption;
       if (!printnmethods && (PrintDebugInfo || PrintRelocations || PrintDependencies || PrintExceptionHandlers)) {
@@ -690,10 +657,10 @@
   return result;
 }
 
-void CodeInstaller::initialize_fields(oop target, oop compiled_code, TRAPS) {
-  if (compiled_code->is_a(HotSpotCompiledNmethod::klass())) {
-    Handle hotspotJavaMethod(THREAD, HotSpotCompiledNmethod::method(compiled_code));
-    methodHandle method = getMethodFromHotSpotMethod(hotspotJavaMethod());
+void CodeInstaller::initialize_fields(JVMCIObject target, JVMCIObject compiled_code, JVMCI_TRAPS) {
+  if (jvmci_env()->isa_HotSpotCompiledNmethod(compiled_code)) {
+    JVMCIObject hotspotJavaMethod = jvmci_env()->get_HotSpotCompiledNmethod_method(compiled_code);
+    methodHandle method = jvmci_env()->asMethod(hotspotJavaMethod);
     _parameter_count = method->size_of_parameters();
     TRACE_jvmci_2("installing code for %s", method->name_and_sig_as_C_string());
   } else {
@@ -701,18 +668,18 @@
     // Only used in OopMap constructor for non-product builds
     _parameter_count = 0;
   }
-  _sites_handle = JNIHandles::make_local(HotSpotCompiledCode::sites(compiled_code));
+  _sites_handle = jvmci_env()->get_HotSpotCompiledCode_sites(compiled_code);
 
-  _code_handle = JNIHandles::make_local(HotSpotCompiledCode::targetCode(compiled_code));
-  _code_size = HotSpotCompiledCode::targetCodeSize(compiled_code);
-  _total_frame_size = HotSpotCompiledCode::totalFrameSize(compiled_code);
+  _code_handle = jvmci_env()->get_HotSpotCompiledCode_targetCode(compiled_code);
+  _code_size = jvmci_env()->get_HotSpotCompiledCode_targetCodeSize(compiled_code);
+  _total_frame_size = jvmci_env()->get_HotSpotCompiledCode_totalFrameSize(compiled_code);
 
-  oop deoptRescueSlot = HotSpotCompiledCode::deoptRescueSlot(compiled_code);
-  if (deoptRescueSlot == NULL) {
+  JVMCIObject deoptRescueSlot = jvmci_env()->get_HotSpotCompiledCode_deoptRescueSlot(compiled_code);
+  if (deoptRescueSlot.is_null()) {
     _orig_pc_offset = -1;
   } else {
-    _orig_pc_offset = StackSlot::offset(deoptRescueSlot);
-    if (StackSlot::addFrameSize(deoptRescueSlot)) {
+    _orig_pc_offset = jvmci_env()->get_StackSlot_offset(deoptRescueSlot);
+    if (jvmci_env()->get_StackSlot_addFrameSize(deoptRescueSlot)) {
       _orig_pc_offset += _total_frame_size;
     }
     if (_orig_pc_offset < 0) {
@@ -721,62 +688,61 @@
   }
 
   // Pre-calculate the constants section size.  This is required for PC-relative addressing.
-  _data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code));
-  if ((_constants->alignment() % HotSpotCompiledCode::dataSectionAlignment(compiled_code)) != 0) {
-    JVMCI_ERROR("invalid data section alignment: %d", HotSpotCompiledCode::dataSectionAlignment(compiled_code));
+  _data_section_handle = jvmci_env()->get_HotSpotCompiledCode_dataSection(compiled_code);
+  if ((_constants->alignment() % jvmci_env()->get_HotSpotCompiledCode_dataSectionAlignment(compiled_code)) != 0) {
+    JVMCI_ERROR("invalid data section alignment: %d", jvmci_env()->get_HotSpotCompiledCode_dataSectionAlignment(compiled_code));
   }
-  _constants_size = data_section()->length();
+  _constants_size = JVMCIENV->get_length(data_section());
 
-  _data_section_patches_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSectionPatches(compiled_code));
+  _data_section_patches_handle = jvmci_env()->get_HotSpotCompiledCode_dataSectionPatches(compiled_code);
 
 #ifndef PRODUCT
-  _comments_handle = JNIHandles::make_local(HotSpotCompiledCode::comments(compiled_code));
+  _comments_handle = jvmci_env()->get_HotSpotCompiledCode_comments(compiled_code);
 #endif
 
   _next_call_type = INVOKE_INVALID;
 
   _has_wide_vector = false;
 
-  oop arch = TargetDescription::arch(target);
-  _word_kind_handle = JNIHandles::make_local(Architecture::wordKind(arch));
+  JVMCIObject arch = jvmci_env()->get_TargetDescription_arch(target);
+  _word_kind_handle = jvmci_env()->get_Architecture_wordKind(arch);
 }
 
-int CodeInstaller::estimate_stubs_size(TRAPS) {
+int CodeInstaller::estimate_stubs_size(JVMCI_TRAPS) {
   // Estimate the number of static and aot call stubs that might be emitted.
   int static_call_stubs = 0;
   int aot_call_stubs = 0;
   int trampoline_stubs = 0;
-  objArrayOop sites = this->sites();
-  for (int i = 0; i < sites->length(); i++) {
-    oop site = sites->obj_at(i);
-    if (site != NULL) {
-      if (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)) {
-            JVMCI_ERROR_0("expected Integer id, got %s", id_obj->klass()->signature_name());
+  JVMCIObjectArray sites = this->sites();
+  for (int i = 0; i < JVMCIENV->get_length(sites); i++) {
+    JVMCIObject site = JVMCIENV->get_object_at(sites, i);
+    if (!site.is_null()) {
+      if (jvmci_env()->isa_site_Mark(site)) {
+        JVMCIObject id_obj = jvmci_env()->get_site_Mark_id(site);
+        if (id_obj.is_non_null()) {
+          if (!jvmci_env()->is_boxing_object(T_INT, id_obj)) {
+            JVMCI_ERROR_0("expected Integer id, got %s", jvmci_env()->klass_name(id_obj));
           }
-          jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT));
+          jint id = jvmci_env()->get_boxed_value(T_INT, id_obj).i;
           switch (id) {
-          case INVOKEINTERFACE:
-          case INVOKEVIRTUAL:
-            trampoline_stubs++;
-            break;
-          case INVOKESTATIC:
-          case INVOKESPECIAL:
-            static_call_stubs++;
-            trampoline_stubs++;
-            break;
-          default:
-            break;
+            case INVOKEINTERFACE:
+            case INVOKEVIRTUAL:
+              trampoline_stubs++;
+              break;
+            case INVOKESTATIC:
+            case INVOKESPECIAL:
+              static_call_stubs++;
+              trampoline_stubs++;
+              break;
+            default:
+              break;
           }
         }
       }
 #if INCLUDE_AOT
-      if (UseAOT && site->is_a(site_Call::klass())) {
-        oop target = site_Call::target(site);
-        InstanceKlass* target_klass = InstanceKlass::cast(target->klass());
-        if (!target_klass->is_subclass_of(SystemDictionary::HotSpotForeignCallTarget_klass())) {
+      if (UseAOT && jvmci_env()->isa_site_Call(site)) {
+        JVMCIObject target = jvmci_env()-> get_site_Call_target(site);
+        if (!jvmci_env()->isa_HotSpotForeignCallTarget(target)) {
           // Add far aot trampolines.
           aot_call_stubs++;
         }
@@ -793,25 +759,25 @@
 }
 
 // perform data and call relocation on the CodeBuffer
-JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, bool check_size, TRAPS) {
+JVMCI::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer, bool check_size, JVMCI_TRAPS) {
   HandleMark hm;
-  objArrayHandle sites(THREAD, this->sites());
-  int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo));
+  JVMCIObjectArray sites = this->sites();
+  int locs_buffer_size = JVMCIENV->get_length(sites) * (relocInfo::length_limit + sizeof(relocInfo));
 
   // Allocate enough space in the stub section for the static call
   // stubs.  Stubs have extra relocs but they are managed by the stub
   // section itself so they don't need to be accounted for in the
   // locs_buffer above.
-  int stubs_size = estimate_stubs_size(CHECK_OK);
+  int stubs_size = estimate_stubs_size(JVMCI_CHECK_OK);
   int total_size = align_up(_code_size, buffer.insts()->alignment()) + align_up(_constants_size, buffer.consts()->alignment()) + align_up(stubs_size, buffer.stubs()->alignment());
 
   if (check_size && total_size > JVMCINMethodSizeLimit) {
-    return JVMCIEnv::code_too_large;
+    return JVMCI::code_too_large;
   }
 
   buffer.initialize(total_size, locs_buffer_size);
   if (buffer.blob() == NULL) {
-    return JVMCIEnv::cache_full;
+    return JVMCI::cache_full;
   }
   buffer.initialize_stubs_size(stubs_size);
   buffer.initialize_consts_size(_constants_size);
@@ -823,49 +789,49 @@
 
   // copy the constant data into the newly created CodeBuffer
   address end_data = _constants->start() + _constants_size;
-  memcpy(_constants->start(), data_section()->base(T_BYTE), _constants_size);
+  JVMCIENV->copy_bytes_to(data_section(), (jbyte*) _constants->start(), 0, _constants_size);
   _constants->set_end(end_data);
 
   // copy the code into the newly created CodeBuffer
   address end_pc = _instructions->start() + _code_size;
   guarantee(_instructions->allocates2(end_pc), "initialize should have reserved enough space for all the code");
-  memcpy(_instructions->start(), code()->base(T_BYTE), _code_size);
+  JVMCIENV->copy_bytes_to(code(), (jbyte*) _instructions->start(), 0, _code_size);
   _instructions->set_end(end_pc);
 
-  for (int i = 0; i < data_section_patches()->length(); i++) {
-    HandleMark hm(THREAD);
-    Handle patch(THREAD, data_section_patches()->obj_at(i));
+  for (int i = 0; i < JVMCIENV->get_length(data_section_patches()); i++) {
+    // HandleMark hm(THREAD);
+    JVMCIObject patch = JVMCIENV->get_object_at(data_section_patches(), i);
     if (patch.is_null()) {
-      THROW_(vmSymbols::java_lang_NullPointerException(), JVMCIEnv::ok);
+      JVMCI_THROW_(NullPointerException, JVMCI::ok);
     }
-    Handle reference(THREAD, site_DataPatch::reference(patch));
+    JVMCIObject reference = jvmci_env()->get_site_DataPatch_reference(patch);
     if (reference.is_null()) {
-      THROW_(vmSymbols::java_lang_NullPointerException(), JVMCIEnv::ok);
+      JVMCI_THROW_(NullPointerException, JVMCI::ok);
     }
-    if (!reference->is_a(site_ConstantReference::klass())) {
-      JVMCI_ERROR_OK("invalid patch in data section: %s", reference->klass()->signature_name());
+    if (!jvmci_env()->isa_site_ConstantReference(reference)) {
+      JVMCI_ERROR_OK("invalid patch in data section: %s", jvmci_env()->klass_name(reference));
     }
-    Handle constant(THREAD, site_ConstantReference::constant(reference));
+    JVMCIObject constant = jvmci_env()->get_site_ConstantReference_constant(reference);
     if (constant.is_null()) {
-      THROW_(vmSymbols::java_lang_NullPointerException(), JVMCIEnv::ok);
+      JVMCI_THROW_(NullPointerException, JVMCI::ok);
     }
-    address dest = _constants->start() + site_Site::pcOffset(patch);
-    if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
-      if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
+    address dest = _constants->start() + jvmci_env()->get_site_Site_pcOffset(patch);
+    if (jvmci_env()->isa_HotSpotMetaspaceConstantImpl(constant)) {
+      if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) {
 #ifdef _LP64
-        *((narrowKlass*) dest) = record_narrow_metadata_reference(_constants, dest, constant, CHECK_OK);
+        *((narrowKlass*) dest) = record_narrow_metadata_reference(_constants, dest, constant, JVMCI_CHECK_OK);
 #else
         JVMCI_ERROR_OK("unexpected compressed Klass* in 32-bit mode");
 #endif
       } else {
-        *((void**) dest) = record_metadata_reference(_constants, dest, constant, CHECK_OK);
+        *((void**) dest) = record_metadata_reference(_constants, dest, constant, JVMCI_CHECK_OK);
       }
-    } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
-      Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant));
+    } else if (jvmci_env()->isa_HotSpotObjectConstantImpl(constant)) {
+      Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK_OK);
       jobject value = JNIHandles::make_local(obj());
       int oop_index = _oop_recorder->find_index(value);
 
-      if (HotSpotObjectConstantImpl::compressed(constant)) {
+      if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) {
 #ifdef _LP64
         _constants->relocate(dest, oop_Relocation::spec(oop_index), relocInfo::narrow_oop_in_const);
 #else
@@ -875,46 +841,48 @@
         _constants->relocate(dest, oop_Relocation::spec(oop_index));
       }
     } else {
-      JVMCI_ERROR_OK("invalid constant in data section: %s", constant->klass()->signature_name());
+      JVMCI_ERROR_OK("invalid constant in data section: %s", jvmci_env()->klass_name(constant));
     }
   }
   jint last_pc_offset = -1;
-  for (int i = 0; i < sites->length(); i++) {
-    HandleMark hm(THREAD);
-    Handle site(THREAD, sites->obj_at(i));
+  for (int i = 0; i < JVMCIENV->get_length(sites); i++) {
+    // HandleMark hm(THREAD);
+    JVMCIObject site = JVMCIENV->get_object_at(sites, i);
     if (site.is_null()) {
-      THROW_(vmSymbols::java_lang_NullPointerException(), JVMCIEnv::ok);
+      JVMCI_THROW_(NullPointerException, JVMCI::ok);
     }
 
-    jint pc_offset = site_Site::pcOffset(site);
+    jint pc_offset = jvmci_env()->get_site_Site_pcOffset(site);
 
-    if (site->is_a(site_Call::klass())) {
+    if (jvmci_env()->isa_site_Call(site)) {
       TRACE_jvmci_4("call at %i", pc_offset);
-      site_Call(buffer, pc_offset, site, CHECK_OK);
-    } else if (site->is_a(site_Infopoint::klass())) {
+      site_Call(buffer, pc_offset, site, JVMCI_CHECK_OK);
+    } else if (jvmci_env()->isa_site_Infopoint(site)) {
       // three reasons for infopoints denote actual safepoints
-      oop reason = site_Infopoint::reason(site);
-      if (site_InfopointReason::SAFEPOINT() == reason || site_InfopointReason::CALL() == reason || site_InfopointReason::IMPLICIT_EXCEPTION() == reason) {
+      JVMCIObject reason = jvmci_env()->get_site_Infopoint_reason(site);
+      if (JVMCIENV->equals(reason, jvmci_env()->get_site_InfopointReason_SAFEPOINT()) ||
+          JVMCIENV->equals(reason, jvmci_env()->get_site_InfopointReason_CALL()) ||
+          JVMCIENV->equals(reason, jvmci_env()->get_site_InfopointReason_IMPLICIT_EXCEPTION())) {
         TRACE_jvmci_4("safepoint at %i", pc_offset);
-        site_Safepoint(buffer, pc_offset, site, CHECK_OK);
+        site_Safepoint(buffer, pc_offset, site, JVMCI_CHECK_OK);
         if (_orig_pc_offset < 0) {
           JVMCI_ERROR_OK("method contains safepoint, but has no deopt rescue slot");
         }
       } else {
         TRACE_jvmci_4("infopoint at %i", pc_offset);
-        site_Infopoint(buffer, pc_offset, site, CHECK_OK);
+        site_Infopoint(buffer, pc_offset, site, JVMCI_CHECK_OK);
       }
-    } else if (site->is_a(site_DataPatch::klass())) {
+    } else if (jvmci_env()->isa_site_DataPatch(site)) {
       TRACE_jvmci_4("datapatch at %i", pc_offset);
-      site_DataPatch(buffer, pc_offset, site, CHECK_OK);
-    } else if (site->is_a(site_Mark::klass())) {
+      site_DataPatch(buffer, pc_offset, site, JVMCI_CHECK_OK);
+    } else if (jvmci_env()->isa_site_Mark(site)) {
       TRACE_jvmci_4("mark at %i", pc_offset);
-      site_Mark(buffer, pc_offset, site, CHECK_OK);
-    } else if (site->is_a(site_ExceptionHandler::klass())) {
+      site_Mark(buffer, pc_offset, site, JVMCI_CHECK_OK);
+    } else if (jvmci_env()->isa_site_ExceptionHandler(site)) {
       TRACE_jvmci_4("exceptionhandler at %i", pc_offset);
       site_ExceptionHandler(pc_offset, site);
     } else {
-      JVMCI_ERROR_OK("unexpected site subclass: %s", site->klass()->signature_name());
+      JVMCI_ERROR_OK("unexpected site subclass: %s", jvmci_env()->klass_name(site));
     }
     last_pc_offset = pc_offset;
 
@@ -926,61 +894,62 @@
   }
 
 #ifndef PRODUCT
-  if (comments() != NULL) {
-    for (int i = 0; i < comments()->length(); i++) {
-      oop comment = comments()->obj_at(i);
-      assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce");
-      jint offset = HotSpotCompiledCode_Comment::pcOffset(comment);
-      char* text = java_lang_String::as_utf8_string(HotSpotCompiledCode_Comment::text(comment));
+  if (comments().is_non_null()) {
+    for (int i = 0; i < JVMCIENV->get_length(comments()); i++) {
+      JVMCIObject comment = JVMCIENV->get_object_at(comments(), i);
+      assert(jvmci_env()->isa_HotSpotCompiledCode_Comment(comment), "cce");
+      jint offset = jvmci_env()->get_HotSpotCompiledCode_Comment_pcOffset(comment);
+      const char* text = jvmci_env()->as_utf8_string(jvmci_env()->get_HotSpotCompiledCode_Comment_text(comment));
       buffer.block_comment(offset, text);
     }
   }
 #endif
-  return JVMCIEnv::ok;
+  return JVMCI::ok;
 }
 
-void CodeInstaller::assumption_NoFinalizableSubclass(Thread* thread, Handle assumption) {
-  Handle receiverType_handle (thread, Assumptions_NoFinalizableSubclass::receiverType(assumption()));
-  Klass* receiverType = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(receiverType_handle));
+void CodeInstaller::assumption_NoFinalizableSubclass(JVMCIObject assumption) {
+  JVMCIObject receiverType_handle = jvmci_env()->get_Assumptions_NoFinalizableSubclass_receiverType(assumption);
+  Klass* receiverType = jvmci_env()->asKlass(receiverType_handle);
   _dependencies->assert_has_no_finalizable_subclasses(receiverType);
 }
 
-void CodeInstaller::assumption_ConcreteSubtype(Thread* thread, Handle assumption) {
-  Handle context_handle (thread, Assumptions_ConcreteSubtype::context(assumption()));
-  Handle subtype_handle (thread, Assumptions_ConcreteSubtype::subtype(assumption()));
-  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle));
-  Klass* subtype = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(subtype_handle));
+void CodeInstaller::assumption_ConcreteSubtype(JVMCIObject assumption) {
+  JVMCIObject context_handle = jvmci_env()->get_Assumptions_ConcreteSubtype_context(assumption);
+  JVMCIObject subtype_handle = jvmci_env()->get_Assumptions_ConcreteSubtype_subtype(assumption);
+  Klass* context = jvmci_env()->asKlass(context_handle);
+  Klass* subtype = jvmci_env()->asKlass(subtype_handle);
 
   assert(context->is_abstract(), "");
   _dependencies->assert_abstract_with_unique_concrete_subtype(context, subtype);
 }
 
-void CodeInstaller::assumption_LeafType(Thread* thread, Handle assumption) {
-  Handle context_handle (thread, Assumptions_LeafType::context(assumption()));
-  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle));
+void CodeInstaller::assumption_LeafType(JVMCIObject assumption) {
+  JVMCIObject context_handle = jvmci_env()->get_Assumptions_LeafType_context(assumption);
+  Klass* context = jvmci_env()->asKlass(context_handle);
 
   _dependencies->assert_leaf_type(context);
 }
 
-void CodeInstaller::assumption_ConcreteMethod(Thread* thread, Handle assumption) {
-  Handle impl_handle (thread, Assumptions_ConcreteMethod::impl(assumption()));
-  Handle context_handle (thread, Assumptions_ConcreteMethod::context(assumption()));
+void CodeInstaller::assumption_ConcreteMethod(JVMCIObject assumption) {
+  JVMCIObject impl_handle = jvmci_env()->get_Assumptions_ConcreteMethod_impl(assumption);
+  JVMCIObject context_handle = jvmci_env()->get_Assumptions_ConcreteMethod_context(assumption);
 
-  methodHandle impl = getMethodFromHotSpotMethod(impl_handle());
-  Klass* context = java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(context_handle));
+  methodHandle impl = jvmci_env()->asMethod(impl_handle);
+  Klass* context = jvmci_env()->asKlass(context_handle);
 
   _dependencies->assert_unique_concrete_method(context, impl());
 }
 
-void CodeInstaller::assumption_CallSiteTargetValue(Thread* thread, Handle assumption) {
-  Handle callSite(thread, HotSpotObjectConstantImpl::object(Assumptions_CallSiteTargetValue::callSite(assumption())));
-  Handle methodHandle(thread, HotSpotObjectConstantImpl::object(Assumptions_CallSiteTargetValue::methodHandle(assumption())));
-
+void CodeInstaller::assumption_CallSiteTargetValue(JVMCIObject assumption, JVMCI_TRAPS) {
+  JVMCIObject callSiteConstant = jvmci_env()->get_Assumptions_CallSiteTargetValue_callSite(assumption);
+  Handle callSite = jvmci_env()->asConstant(callSiteConstant, JVMCI_CHECK);
+  JVMCIObject methodConstant = jvmci_env()->get_Assumptions_CallSiteTargetValue_methodHandle(assumption);
+  Handle methodHandle = jvmci_env()->asConstant(methodConstant, JVMCI_CHECK);
   _dependencies->assert_call_site_target_value(callSite(), methodHandle());
 }
 
-void CodeInstaller::site_ExceptionHandler(jint pc_offset, Handle exc) {
-  jint handler_offset = site_ExceptionHandler::handlerPos(exc);
+void CodeInstaller::site_ExceptionHandler(jint pc_offset, JVMCIObject exc) {
+  jint handler_offset = jvmci_env()->get_site_ExceptionHandler_handlerPos(exc);
 
   // Subtable header
   _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0));
@@ -1005,19 +974,20 @@
   return true;
 }
 
-GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(Handle debug_info, TRAPS) {
-  objArrayHandle virtualObjects(THREAD, DebugInfo::virtualObjectMapping(debug_info));
+GrowableArray<ScopeValue*>* CodeInstaller::record_virtual_objects(JVMCIObject debug_info, JVMCI_TRAPS) {
+  JVMCIObjectArray virtualObjects = jvmci_env()->get_DebugInfo_virtualObjectMapping(debug_info);
   if (virtualObjects.is_null()) {
     return NULL;
   }
-  GrowableArray<ScopeValue*>* objects = new GrowableArray<ScopeValue*>(virtualObjects->length(), virtualObjects->length(), NULL);
+  GrowableArray<ScopeValue*>* objects = new GrowableArray<ScopeValue*>(JVMCIENV->get_length(virtualObjects), JVMCIENV->get_length(virtualObjects), NULL);
   // Create the unique ObjectValues
-  for (int i = 0; i < virtualObjects->length(); i++) {
-    HandleMark hm(THREAD);
-    Handle value(THREAD, virtualObjects->obj_at(i));
-    int id = VirtualObject::id(value);
-    Handle type(THREAD, VirtualObject::type(value));
-    oop javaMirror = HotSpotResolvedObjectTypeImpl::javaClass(type);
+  for (int i = 0; i < JVMCIENV->get_length(virtualObjects); i++) {
+    // HandleMark hm(THREAD);
+    JVMCIObject value = JVMCIENV->get_object_at(virtualObjects, i);
+    int id = jvmci_env()->get_VirtualObject_id(value);
+    JVMCIObject type = jvmci_env()->get_VirtualObject_type(value);
+    Klass* klass = jvmci_env()->asKlass(type);
+    oop javaMirror = klass->java_mirror();
     ObjectValue* sv = new ObjectValue(id, new ConstantOopWriteValue(JNIHandles::make_local(Thread::current(), javaMirror)));
     if (id < 0 || id >= objects->length()) {
       JVMCI_ERROR_NULL("virtual object id %d out of bounds", id);
@@ -1029,18 +999,18 @@
   }
   // All the values which could be referenced by the VirtualObjects
   // exist, so now describe all the VirtualObjects themselves.
-  for (int i = 0; i < virtualObjects->length(); i++) {
-    HandleMark hm(THREAD);
-    Handle value(THREAD, virtualObjects->obj_at(i));
-    int id = VirtualObject::id(value);
-    record_object_value(objects->at(id)->as_ObjectValue(), value, objects, CHECK_NULL);
+  for (int i = 0; i < JVMCIENV->get_length(virtualObjects); i++) {
+    // HandleMark hm(THREAD);
+    JVMCIObject value = JVMCIENV->get_object_at(virtualObjects, i);
+    int id = jvmci_env()->get_VirtualObject_id(value);
+    record_object_value(objects->at(id)->as_ObjectValue(), value, objects, JVMCI_CHECK_NULL);
   }
   _debug_recorder->dump_object_pool(objects);
   return objects;
 }
 
-void CodeInstaller::record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, bool return_oop, TRAPS) {
-  Handle position(THREAD, DebugInfo::bytecodePosition(debug_info));
+void CodeInstaller::record_scope(jint pc_offset, JVMCIObject debug_info, ScopeMode scope_mode, bool return_oop, JVMCI_TRAPS) {
+  JVMCIObject position = jvmci_env()->get_DebugInfo_bytecodePosition(debug_info);
   if (position.is_null()) {
     // Stubs do not record scope info, just oop maps
     return;
@@ -1048,26 +1018,26 @@
 
   GrowableArray<ScopeValue*>* objectMapping;
   if (scope_mode == CodeInstaller::FullFrame) {
-    objectMapping = record_virtual_objects(debug_info, CHECK);
+    objectMapping = record_virtual_objects(debug_info, JVMCI_CHECK);
   } else {
     objectMapping = NULL;
   }
-  record_scope(pc_offset, position, scope_mode, objectMapping, return_oop, CHECK);
+  record_scope(pc_offset, position, scope_mode, objectMapping, return_oop, JVMCI_CHECK);
 }
 
 int CodeInstaller::map_jvmci_bci(int bci) {
   if (bci < 0) {
-    if (bci == BytecodeFrame::BEFORE_BCI()) {
+    if (bci == jvmci_env()->get_BytecodeFrame_BEFORE_BCI()) {
       return BeforeBci;
-    } else if (bci == BytecodeFrame::AFTER_BCI()) {
+    } else if (bci == jvmci_env()->get_BytecodeFrame_AFTER_BCI()) {
       return AfterBci;
-    } else if (bci == BytecodeFrame::UNWIND_BCI()) {
+    } else if (bci == jvmci_env()->get_BytecodeFrame_UNWIND_BCI()) {
       return UnwindBci;
-    } else if (bci == BytecodeFrame::AFTER_EXCEPTION_BCI()) {
+    } else if (bci == jvmci_env()->get_BytecodeFrame_AFTER_EXCEPTION_BCI()) {
       return AfterExceptionBci;
-    } else if (bci == BytecodeFrame::UNKNOWN_BCI()) {
+    } else if (bci == jvmci_env()->get_BytecodeFrame_UNKNOWN_BCI()) {
       return UnknownBci;
-    } else if (bci == BytecodeFrame::INVALID_FRAMESTATE_BCI()) {
+    } else if (bci == jvmci_env()->get_BytecodeFrame_INVALID_FRAMESTATE_BCI()) {
       return InvalidFrameStateBci;
     }
     ShouldNotReachHere();
@@ -1075,34 +1045,37 @@
   return bci;
 }
 
-void CodeInstaller::record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, TRAPS) {
-  Handle frame;
+void CodeInstaller::record_scope(jint pc_offset, JVMCIObject position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, JVMCI_TRAPS) {
+  JVMCIObject frame;
   if (scope_mode == CodeInstaller::FullFrame) {
-    if (!position->is_a(BytecodeFrame::klass())) {
+    if (!jvmci_env()->isa_BytecodeFrame(position)) {
       JVMCI_ERROR("Full frame expected for debug info at %i", pc_offset);
     }
     frame = position;
   }
-  Handle caller_frame (THREAD, BytecodePosition::caller(position));
-  if (caller_frame.not_null()) {
-    record_scope(pc_offset, caller_frame, scope_mode, objects, return_oop, CHECK);
+  JVMCIObject caller_frame = jvmci_env()->get_BytecodePosition_caller(position);
+  if (caller_frame.is_non_null()) {
+    record_scope(pc_offset, caller_frame, scope_mode, objects, return_oop, JVMCI_CHECK);
   }
 
-  Handle hotspot_method (THREAD, BytecodePosition::method(position));
-  Method* method = getMethodFromHotSpotMethod(hotspot_method());
-  jint bci = map_jvmci_bci(BytecodePosition::bci(position));
+  JVMCIObject hotspot_method = jvmci_env()->get_BytecodePosition_method(position);
+  Method* method = jvmci_env()->asMethod(hotspot_method);
+  jint bci = map_jvmci_bci(jvmci_env()->get_BytecodePosition_bci(position));
+  if (bci == jvmci_env()->get_BytecodeFrame_BEFORE_BCI()) {
+    bci = SynchronizationEntryBCI;
+  }
 
   TRACE_jvmci_2("Recording scope pc_offset=%d bci=%d method=%s", pc_offset, bci, method->name_and_sig_as_C_string());
 
   bool reexecute = false;
-  if (frame.not_null()) {
-    if (bci < 0) {
+  if (frame.is_non_null()) {
+    if (bci < 0){
        reexecute = false;
     } else {
       Bytecodes::Code code = Bytecodes::java_code_at(method, method->bcp_from(bci));
       reexecute = bytecode_should_reexecute(code);
-      if (frame.not_null()) {
-        reexecute = (BytecodeFrame::duringCall(frame) == JNI_FALSE);
+      if (frame.is_non_null()) {
+        reexecute = (jvmci_env()->get_BytecodeFrame_duringCall(frame) == JNI_FALSE);
       }
     }
   }
@@ -1112,55 +1085,55 @@
   DebugToken* monitors_token = NULL;
   bool throw_exception = false;
 
-  if (frame.not_null()) {
-    jint local_count = BytecodeFrame::numLocals(frame);
-    jint expression_count = BytecodeFrame::numStack(frame);
-    jint monitor_count = BytecodeFrame::numLocks(frame);
-    objArrayHandle values(THREAD, BytecodeFrame::values(frame));
-    objArrayHandle slotKinds(THREAD, BytecodeFrame::slotKinds(frame));
+  if (frame.is_non_null()) {
+    jint local_count = jvmci_env()->get_BytecodeFrame_numLocals(frame);
+    jint expression_count = jvmci_env()->get_BytecodeFrame_numStack(frame);
+    jint monitor_count = jvmci_env()->get_BytecodeFrame_numLocks(frame);
+    JVMCIObjectArray values = jvmci_env()->get_BytecodeFrame_values(frame);
+    JVMCIObjectArray slotKinds = jvmci_env()->get_BytecodeFrame_slotKinds(frame);
 
     if (values.is_null() || slotKinds.is_null()) {
-      THROW(vmSymbols::java_lang_NullPointerException());
+      JVMCI_THROW(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);
+    if (local_count + expression_count + monitor_count != JVMCIENV->get_length(values)) {
+      JVMCI_ERROR("unexpected values length %d in scope (%d locals, %d expressions, %d monitors)", JVMCIENV->get_length(values), local_count, expression_count, monitor_count);
     }
-    if (local_count + expression_count != slotKinds->length()) {
-      JVMCI_ERROR("unexpected slotKinds length %d in scope (%d locals, %d expressions)", slotKinds->length(), local_count, expression_count);
+    if (local_count + expression_count != JVMCIENV->get_length(slotKinds)) {
+      JVMCI_ERROR("unexpected slotKinds length %d in scope (%d locals, %d expressions)", JVMCIENV->get_length(slotKinds), local_count, expression_count);
     }
 
     GrowableArray<ScopeValue*>* locals = local_count > 0 ? new GrowableArray<ScopeValue*> (local_count) : NULL;
     GrowableArray<ScopeValue*>* expressions = expression_count > 0 ? new GrowableArray<ScopeValue*> (expression_count) : NULL;
     GrowableArray<MonitorValue*>* monitors = monitor_count > 0 ? new GrowableArray<MonitorValue*> (monitor_count) : NULL;
 
-    TRACE_jvmci_2("Scope at bci %d with %d values", bci, values->length());
+    TRACE_jvmci_2("Scope at bci %d with %d values", bci, JVMCIENV->get_length(values));
     TRACE_jvmci_2("%d locals %d expressions, %d monitors", local_count, expression_count, monitor_count);
 
-    for (jint i = 0; i < values->length(); i++) {
-      HandleMark hm(THREAD);
+    for (jint i = 0; i < JVMCIENV->get_length(values); i++) {
+      // HandleMark hm(THREAD);
       ScopeValue* second = NULL;
-      Handle value(THREAD, values->obj_at(i));
+      JVMCIObject value = JVMCIENV->get_object_at(values, i);
       if (i < local_count) {
-        BasicType type = JVMCIRuntime::kindToBasicType(Handle(THREAD, slotKinds->obj_at(i)), CHECK);
-        ScopeValue* first = get_scope_value(value, type, objects, second, CHECK);
+        BasicType type = jvmci_env()->kindToBasicType(JVMCIENV->get_object_at(slotKinds, i), JVMCI_CHECK);
+        ScopeValue* first = get_scope_value(value, type, objects, second, JVMCI_CHECK);
         if (second != NULL) {
           locals->append(second);
         }
         locals->append(first);
       } else if (i < local_count + expression_count) {
-        BasicType type = JVMCIRuntime::kindToBasicType(Handle(THREAD, slotKinds->obj_at(i)), CHECK);
-        ScopeValue* first = get_scope_value(value, type, objects, second, CHECK);
+        BasicType type = jvmci_env()->kindToBasicType(JVMCIENV->get_object_at(slotKinds, i), JVMCI_CHECK);
+        ScopeValue* first = get_scope_value(value, type, objects, second, JVMCI_CHECK);
         if (second != NULL) {
           expressions->append(second);
         }
         expressions->append(first);
       } else {
-        MonitorValue *monitor = get_monitor_value(value, objects, CHECK);
+        MonitorValue *monitor = get_monitor_value(value, objects, JVMCI_CHECK);
         monitors->append(monitor);
       }
       if (second != NULL) {
         i++;
-        if (i >= values->length() || values->obj_at(i) != Value::ILLEGAL()) {
+        if (i >= JVMCIENV->get_length(values) || !JVMCIENV->equals(JVMCIENV->get_object_at(values, i), jvmci_env()->get_Value_ILLEGAL())) {
           JVMCI_ERROR("double-slot value not followed by Value.ILLEGAL");
         }
       }
@@ -1170,29 +1143,29 @@
     expressions_token = _debug_recorder->create_scope_values(expressions);
     monitors_token = _debug_recorder->create_monitor_values(monitors);
 
-    throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE;
+    throw_exception = jvmci_env()->get_BytecodeFrame_rethrowException(frame) == JNI_TRUE;
   }
 
   _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, return_oop,
                                   locals_token, expressions_token, monitors_token);
 }
 
-void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
-  Handle debug_info (THREAD, site_Infopoint::debugInfo(site));
+void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {
+  JVMCIObject debug_info = jvmci_env()->get_site_Infopoint_debugInfo(site);
   if (debug_info.is_null()) {
     JVMCI_ERROR("debug info expected at safepoint at %i", pc_offset);
   }
 
   // address instruction = _instructions->start() + pc_offset;
   // jint next_pc_offset = Assembler::locate_next_instruction(instruction) - _instructions->start();
-  OopMap *map = create_oop_map(debug_info, CHECK);
+  OopMap *map = create_oop_map(debug_info, JVMCI_CHECK);
   _debug_recorder->add_safepoint(pc_offset, map);
-  record_scope(pc_offset, debug_info, CodeInstaller::FullFrame, CHECK);
+  record_scope(pc_offset, debug_info, CodeInstaller::FullFrame, JVMCI_CHECK);
   _debug_recorder->end_safepoint(pc_offset);
 }
 
-void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
-  Handle debug_info (THREAD, site_Infopoint::debugInfo(site));
+void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {
+  JVMCIObject debug_info = jvmci_env()->get_site_Infopoint_debugInfo(site);
   if (debug_info.is_null()) {
     JVMCI_ERROR("debug info expected at infopoint at %i", pc_offset);
   }
@@ -1202,53 +1175,51 @@
   // but DebugInformationRecorder doesn't have sufficient public API.
 
   _debug_recorder->add_non_safepoint(pc_offset);
-  record_scope(pc_offset, debug_info, CodeInstaller::BytecodePosition, CHECK);
+  record_scope(pc_offset, debug_info, CodeInstaller::BytecodePosition, JVMCI_CHECK);
   _debug_recorder->end_non_safepoint(pc_offset);
 }
 
-void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
-  Handle target(THREAD, site_Call::target(site));
-  InstanceKlass* target_klass = InstanceKlass::cast(target->klass());
+void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {
+  JVMCIObject target = jvmci_env()->get_site_Call_target(site);
+  JVMCIObject hotspot_method; // JavaMethod
+  JVMCIObject foreign_call;
 
-  Handle hotspot_method; // JavaMethod
-  Handle foreign_call;
-
-  if (target_klass->is_subclass_of(SystemDictionary::HotSpotForeignCallTarget_klass())) {
+  if (jvmci_env()->isa_HotSpotForeignCallTarget(target)) {
     foreign_call = target;
   } else {
     hotspot_method = target;
   }
 
-  Handle debug_info (THREAD, site_Call::debugInfo(site));
+  JVMCIObject debug_info = jvmci_env()->get_site_Infopoint_debugInfo(site);
 
-  assert(hotspot_method.not_null() ^ foreign_call.not_null(), "Call site needs exactly one type");
+  assert(hotspot_method.is_non_null() ^ foreign_call.is_non_null(), "Call site needs exactly one type");
 
   NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
-  jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method, CHECK);
+  jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method, JVMCI_CHECK);
 
-  if (debug_info.not_null()) {
-    OopMap *map = create_oop_map(debug_info, CHECK);
+  if (debug_info.is_non_null()) {
+    OopMap *map = create_oop_map(debug_info, JVMCI_CHECK);
     _debug_recorder->add_safepoint(next_pc_offset, map);
 
-    bool return_oop = hotspot_method.not_null() && getMethodFromHotSpotMethod(hotspot_method())->is_returning_oop();
+    bool return_oop = hotspot_method.is_non_null() && jvmci_env()->asMethod(hotspot_method)->is_returning_oop();
 
-    record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, return_oop, CHECK);
+    record_scope(next_pc_offset, debug_info, CodeInstaller::FullFrame, return_oop, JVMCI_CHECK);
   }
 
-  if (foreign_call.not_null()) {
-    jlong foreign_call_destination = HotSpotForeignCallTarget::address(foreign_call);
+  if (foreign_call.is_non_null()) {
+    jlong foreign_call_destination = jvmci_env()->get_HotSpotForeignCallTarget_address(foreign_call);
     if (_immutable_pic_compilation) {
       // Use fake short distance during PIC compilation.
       foreign_call_destination = (jlong)(_instructions->start() + pc_offset);
     }
-    CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, CHECK);
+    CodeInstaller::pd_relocate_ForeignCall(inst, foreign_call_destination, JVMCI_CHECK);
   } else { // method != NULL
     if (debug_info.is_null()) {
       JVMCI_ERROR("debug info expected at call at %i", pc_offset);
     }
 
     TRACE_jvmci_3("method call");
-    CodeInstaller::pd_relocate_JavaMethod(buffer, hotspot_method, pc_offset, CHECK);
+    CodeInstaller::pd_relocate_JavaMethod(buffer, hotspot_method, pc_offset, JVMCI_CHECK);
     if (_next_call_type == INVOKESTATIC || _next_call_type == INVOKESPECIAL) {
       // Need a static call stub for transitions from compiled to interpreted.
       CompiledStaticCall::emit_to_interp_stub(buffer, _instructions->start() + pc_offset);
@@ -1261,57 +1232,67 @@
 
   _next_call_type = INVOKE_INVALID;
 
-  if (debug_info.not_null()) {
+  if (debug_info.is_non_null()) {
     _debug_recorder->end_safepoint(next_pc_offset);
   }
 }
 
-void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
-  Handle reference(THREAD, site_DataPatch::reference(site));
+void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {
+  JVMCIObject reference = jvmci_env()->get_site_DataPatch_reference(site);
   if (reference.is_null()) {
-    THROW(vmSymbols::java_lang_NullPointerException());
-  } else if (reference->is_a(site_ConstantReference::klass())) {
-    Handle constant(THREAD, site_ConstantReference::constant(reference));
+    JVMCI_THROW(NullPointerException);
+  } else if (jvmci_env()->isa_site_ConstantReference(reference)) {
+    JVMCIObject constant = jvmci_env()->get_site_ConstantReference_constant(reference);
     if (constant.is_null()) {
-      THROW(vmSymbols::java_lang_NullPointerException());
-    } else if (constant->is_a(HotSpotObjectConstantImpl::klass())) {
+      JVMCI_THROW(NullPointerException);
+    } else if (jvmci_env()->isa_DirectHotSpotObjectConstantImpl(constant)) {
+      if (!JVMCIENV->is_hotspot()) {
+        JVMCIObject string = JVMCIENV->call_HotSpotJVMCIRuntime_callToString(constant, JVMCI_CHECK);
+        const char* to_string = JVMCIENV->as_utf8_string(string);
+        JVMCI_THROW_MSG(IllegalArgumentException, err_msg("Direct object constant reached the backend: %s", to_string));
+      }
       if (!_immutable_pic_compilation) {
         // Do not patch during PIC compilation.
-        pd_patch_OopConstant(pc_offset, constant, CHECK);
+        pd_patch_OopConstant(pc_offset, constant, JVMCI_CHECK);
       }
-    } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) {
+    } else if (jvmci_env()->isa_IndirectHotSpotObjectConstantImpl(constant)) {
       if (!_immutable_pic_compilation) {
-        pd_patch_MetaspaceConstant(pc_offset, constant, CHECK);
+        // Do not patch during PIC compilation.
+        pd_patch_OopConstant(pc_offset, constant, JVMCI_CHECK);
+      }
+    } else if (jvmci_env()->isa_HotSpotMetaspaceConstantImpl(constant)) {
+      if (!_immutable_pic_compilation) {
+        pd_patch_MetaspaceConstant(pc_offset, constant, JVMCI_CHECK);
       }
 #if INCLUDE_AOT
-    } else if (constant->is_a(HotSpotSentinelConstant::klass())) {
+    } else if (jvmci_env()->isa_HotSpotSentinelConstant(constant)) {
       if (!_immutable_pic_compilation) {
-        JVMCI_ERROR("sentinel constant not supported for normal compiles: %s", constant->klass()->signature_name());
+        JVMCI_ERROR("sentinel constant not supported for normal compiles: %s", jvmci_env()->klass_name(constant));
       }
 #endif
     } else {
-      JVMCI_ERROR("unknown constant type in data patch: %s", constant->klass()->signature_name());
+      JVMCI_ERROR("unknown constant type in data patch: %s", jvmci_env()->klass_name(constant));
     }
-  } else if (reference->is_a(site_DataSectionReference::klass())) {
-    int data_offset = site_DataSectionReference::offset(reference);
+  } else if (jvmci_env()->isa_site_DataSectionReference(reference)) {
+    int data_offset = jvmci_env()->get_site_DataSectionReference_offset(reference);
     if (0 <= data_offset && data_offset < _constants_size) {
-      pd_patch_DataSectionReference(pc_offset, data_offset, CHECK);
+      pd_patch_DataSectionReference(pc_offset, data_offset, JVMCI_CHECK);
     } else {
       JVMCI_ERROR("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size);
     }
   } else {
-    JVMCI_ERROR("unknown data patch type: %s", reference->klass()->signature_name());
+    JVMCI_ERROR("unknown data patch type: %s", jvmci_env()->klass_name(reference));
   }
 }
 
-void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) {
-  Handle id_obj (THREAD, site_Mark::id(site));
+void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS) {
+  JVMCIObject id_obj = jvmci_env()->get_site_Mark_id(site);
 
-  if (id_obj.not_null()) {
-    if (!java_lang_boxing_object::is_instance(id_obj(), T_INT)) {
-      JVMCI_ERROR("expected Integer id, got %s", id_obj->klass()->signature_name());
+  if (id_obj.is_non_null()) {
+    if (!jvmci_env()->is_boxing_object(T_INT, id_obj)) {
+      JVMCI_ERROR("expected Integer id, got %s", jvmci_env()->klass_name(id_obj));
     }
-    jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT));
+    jint id = jvmci_env()->get_boxed_value(T_INT, id_obj).i;
 
     address pc = _instructions->start() + pc_offset;
 
@@ -1343,7 +1324,7 @@
       case POLL_FAR:
       case POLL_RETURN_NEAR:
       case POLL_RETURN_FAR:
-        pd_relocate_poll(pc, id, CHECK);
+        pd_relocate_poll(pc, id, JVMCI_CHECK);
         break;
       case CARD_TABLE_SHIFT:
       case CARD_TABLE_ADDRESS:
--- a/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCodeInstaller.hpp	Wed May 01 12:31:29 2019 -0700
@@ -24,9 +24,11 @@
 #ifndef SHARE_JVMCI_JVMCICODEINSTALLER_HPP
 #define SHARE_JVMCI_JVMCICODEINSTALLER_HPP
 
-#include "jvmci/jvmciCompiler.hpp"
+#include "code/debugInfoRec.hpp"
+#include "code/exceptionHandlerTable.hpp"
+#include "code/nativeInst.hpp"
+#include "jvmci/jvmci.hpp"
 #include "jvmci/jvmciEnv.hpp"
-#include "code/nativeInst.hpp"
 
 #if INCLUDE_AOT
 class RelocBuffer : public StackObj {
@@ -44,9 +46,11 @@
   char *_buffer;
 };
 
+class CodeInstaller;
+
 class AOTOopRecorder : public OopRecorder {
 public:
-  AOTOopRecorder(Arena* arena = NULL, bool deduplicate = false);
+  AOTOopRecorder(CodeInstaller* code_inst, Arena* arena = NULL, bool deduplicate = false);
 
   virtual int find_index(Metadata* h);
   virtual int find_index(jobject h);
@@ -57,7 +61,10 @@
   void record_meta_ref(jobject ref, int index);
 
   GrowableArray<jobject>* _meta_refs;
+
+  CodeInstaller* _code_inst;
 };
+#endif // INCLUDE_AOT
 
 class CodeMetadata {
 public:
@@ -71,9 +78,10 @@
   u_char* get_scopes_desc() const { return _scopes_desc; }
   int get_scopes_size() const { return _nr_scopes_desc; }
 
+#if INCLUDE_AOT
   RelocBuffer* get_reloc_buffer() { return &_reloc_buffer; }
-
   AOTOopRecorder* get_oop_recorder() { return _oop_recorder; }
+#endif
 
   ExceptionHandlerTable* get_exception_table() { return _exception_table; }
 
@@ -87,9 +95,11 @@
     _nr_scopes_desc = size;
   }
 
+#if INCLUDE_AOT
   void set_oop_recorder(AOTOopRecorder* recorder) {
     _oop_recorder = recorder;
   }
+#endif
 
   void set_exception_table(ExceptionHandlerTable* table) {
     _exception_table = table;
@@ -103,11 +113,12 @@
   u_char* _scopes_desc;
   int _nr_scopes_desc;
 
+#if INCLUDE_AOT
   RelocBuffer _reloc_buffer;
   AOTOopRecorder* _oop_recorder;
+#endif
   ExceptionHandlerTable* _exception_table;
 };
-#endif // INCLUDE_AOT
 
 /*
  * This class handles the conversion from a InstalledCode to a CodeBlob or an nmethod.
@@ -143,24 +154,26 @@
   };
 
   Arena         _arena;
+  JVMCIEnv*     _jvmci_env;
 
-  jobject       _data_section_handle;
-  jobject       _data_section_patches_handle;
-  jobject       _sites_handle;
+  JVMCIPrimitiveArray    _data_section_handle;
+  JVMCIObjectArray       _data_section_patches_handle;
+  JVMCIObjectArray       _sites_handle;
+#ifndef PRODUCT
+  JVMCIObjectArray       _comments_handle;
+#endif
+  JVMCIPrimitiveArray    _code_handle;
+  JVMCIObject            _word_kind_handle;
+
   CodeOffsets   _offsets;
 
-  jobject       _code_handle;
   jint          _code_size;
   jint          _total_frame_size;
   jint          _orig_pc_offset;
   jint          _parameter_count;
   jint          _constants_size;
-#ifndef PRODUCT
-  jobject       _comments_handle;
-#endif
 
   bool          _has_wide_vector;
-  jobject       _word_kind_handle;
 
   MarkId        _next_call_type;
   address       _invoke_mark_pc;
@@ -182,72 +195,84 @@
   static ConstantIntValue*    _int_2_scope_value;
   static LocationValue*       _illegal_value;
 
-  jint pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS);
-  void pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS);
-  void pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS);
-  void pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS);
-  void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS);
-  void pd_relocate_JavaMethod(CodeBuffer &cbuf, Handle method, jint pc_offset, TRAPS);
-  void pd_relocate_poll(address pc, jint mark, TRAPS);
+  jint pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS);
+  void pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS);
+  void pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS);
+  void pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS);
+  void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS);
+  void pd_relocate_JavaMethod(CodeBuffer &cbuf, JVMCIObject method, jint pc_offset, JVMCI_TRAPS);
+  void pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS);
 
-  objArrayOop sites();
-  arrayOop code();
-  arrayOop data_section();
-  objArrayOop data_section_patches();
+  JVMCIObjectArray sites()                { return _sites_handle; }
+  JVMCIPrimitiveArray code()              { return _code_handle; }
+  JVMCIPrimitiveArray  data_section()     { return _data_section_handle; }
+  JVMCIObjectArray data_section_patches() { return _data_section_patches_handle; }
 #ifndef PRODUCT
-  objArrayOop comments();
+  JVMCIObjectArray comments()             { return _comments_handle; }
 #endif
-
-  oop word_kind();
+  JVMCIObject word_kind()                 { return _word_kind_handle; }
 
 public:
 
-  CodeInstaller(bool immutable_pic_compilation) : _arena(mtCompiler), _immutable_pic_compilation(immutable_pic_compilation) {}
+  CodeInstaller(JVMCIEnv* jvmci_env, bool immutable_pic_compilation) : _arena(mtJVMCI), _jvmci_env(jvmci_env), _immutable_pic_compilation(immutable_pic_compilation) {}
 
 #if INCLUDE_AOT
-  JVMCIEnv::CodeInstallResult gather_metadata(Handle target, Handle compiled_code, CodeMetadata& metadata, TRAPS);
+  JVMCI::CodeInstallResult gather_metadata(JVMCIObject target, JVMCIObject compiled_code, CodeMetadata& metadata, JVMCI_TRAPS);
 #endif
-  JVMCIEnv::CodeInstallResult install(JVMCICompiler* compiler, Handle target, Handle compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log, TRAPS);
+  JVMCI::CodeInstallResult install(JVMCICompiler* compiler,
+                                   JVMCIObject target,
+                                   JVMCIObject compiled_code,
+                                   CodeBlob*& cb,
+                                   JVMCIObject installed_code,
+                                   FailedSpeculation** failed_speculations,
+                                   char* speculations,
+                                   int speculations_len,
+                                   JVMCI_TRAPS);
+
+  JVMCIEnv* jvmci_env() { return _jvmci_env; }
+  JVMCIRuntime* runtime() { return _jvmci_env->runtime(); }
 
   static address runtime_call_target_address(oop runtime_call);
-  static VMReg get_hotspot_reg(jint jvmciRegisterNumber, TRAPS);
+  static VMReg get_hotspot_reg(jint jvmciRegisterNumber, JVMCI_TRAPS);
   static bool is_general_purpose_reg(VMReg hotspotRegister);
 
   const OopMapSet* oopMapSet() const { return _debug_recorder->_oopmaps; }
 
 protected:
-  Location::Type get_oop_type(Thread* thread, Handle value);
-  ScopeValue* get_scope_value(Handle value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, TRAPS);
-  MonitorValue* get_monitor_value(Handle value, GrowableArray<ScopeValue*>* objects, TRAPS);
+  Location::Type get_oop_type(JVMCIObject value);
+  ScopeValue* get_scope_value(JVMCIObject value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, JVMCI_TRAPS);
+  MonitorValue* get_monitor_value(JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS);
 
-  void* record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS);
+  void* record_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS);
 #ifdef _LP64
-  narrowKlass record_narrow_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS);
+  narrowKlass record_narrow_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS);
 #endif
 
   // extract the fields of the HotSpotCompiledCode
-  void initialize_fields(oop target, oop target_method, TRAPS);
-  void initialize_dependencies(oop target_method, OopRecorder* oop_recorder, TRAPS);
+  void initialize_fields(JVMCIObject target, JVMCIObject compiled_code, JVMCI_TRAPS);
+  void initialize_dependencies(JVMCIObject compiled_code, OopRecorder* oop_recorder, JVMCI_TRAPS);
 
-  int estimate_stubs_size(TRAPS);
+  int estimate_stubs_size(JVMCI_TRAPS);
 
   // perform data and call relocation on the CodeBuffer
-  JVMCIEnv::CodeInstallResult initialize_buffer(CodeBuffer& buffer, bool check_size, TRAPS);
+  JVMCI::CodeInstallResult initialize_buffer(CodeBuffer& buffer, bool check_size, JVMCI_TRAPS);
 
-  void assumption_NoFinalizableSubclass(Thread* thread, Handle assumption);
-  void assumption_ConcreteSubtype(Thread* thread, Handle assumption);
-  void assumption_LeafType(Thread* thread, Handle assumption);
-  void assumption_ConcreteMethod(Thread* thread, Handle assumption);
-  void assumption_CallSiteTargetValue(Thread* thread, Handle assumption);
+  void assumption_NoFinalizableSubclass(JVMCIObject assumption);
+  void assumption_ConcreteSubtype(JVMCIObject assumption);
+  void assumption_LeafType(JVMCIObject assumption);
+  void assumption_ConcreteMethod(JVMCIObject assumption);
+  void assumption_CallSiteTargetValue(JVMCIObject assumption, JVMCI_TRAPS);
 
-  void site_Safepoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
-  void site_Infopoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
-  void site_Call(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
-  void site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
-  void site_Mark(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
-  void site_ExceptionHandler(jint pc_offset, Handle site);
+  void site_Safepoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
+  void site_Infopoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
+  void site_Call(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
+  void site_DataPatch(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
+  void site_Mark(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
+  void site_ExceptionHandler(jint pc_offset, JVMCIObject site);
 
-  OopMap* create_oop_map(Handle debug_info, TRAPS);
+  OopMap* create_oop_map(JVMCIObject debug_info, JVMCI_TRAPS);
+
+  VMReg getVMRegFromLocation(JVMCIObject location, int total_frame_size, JVMCI_TRAPS);
 
   /**
    * Specifies the level of detail to record for a scope.
@@ -260,23 +285,17 @@
   };
 
   int map_jvmci_bci(int bci);
-  void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, bool return_oop, TRAPS);
-  void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS) {
-    record_scope(pc_offset, debug_info, scope_mode, false /* return_oop */, THREAD);
+
+  void record_scope(jint pc_offset, JVMCIObject debug_info, ScopeMode scope_mode, bool return_oop, JVMCI_TRAPS);
+  void record_scope(jint pc_offset, JVMCIObject debug_info, ScopeMode scope_mode, JVMCI_TRAPS) {
+    record_scope(pc_offset, debug_info, scope_mode, false /* return_oop */, JVMCIENV);
   }
-  void record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, TRAPS);
-  void record_object_value(ObjectValue* sv, Handle value, GrowableArray<ScopeValue*>* objects, TRAPS);
+  void record_scope(jint pc_offset, JVMCIObject position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, JVMCI_TRAPS);
+  void record_object_value(ObjectValue* sv, JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS);
 
-  GrowableArray<ScopeValue*>* record_virtual_objects(Handle debug_info, TRAPS);
+  GrowableArray<ScopeValue*>* record_virtual_objects(JVMCIObject debug_info, JVMCI_TRAPS);
 
   int estimateStubSpace(int static_call_stubs);
 };
 
-/**
- * Gets the Method metaspace object from a HotSpotResolvedJavaMethodImpl Java object.
- */
-Method* getMethodFromHotSpotMethod(oop hotspot_method);
-
-
-
 #endif // SHARE_JVMCI_JVMCICODEINSTALLER_HPP
--- a/src/hotspot/share/jvmci/jvmciCompiler.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp	Wed May 01 12:31:29 2019 -0700
@@ -22,19 +22,10 @@
  */
 
 #include "precompiled.hpp"
-#include "jvm.h"
+#include "compiler/compileBroker.hpp"
 #include "classfile/moduleEntry.hpp"
-#include "memory/oopFactory.hpp"
-#include "memory/resourceArea.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/javaCalls.hpp"
-#include "runtime/handles.hpp"
-#include "jvmci/jvmciJavaClasses.hpp"
-#include "jvmci/jvmciCompiler.hpp"
 #include "jvmci/jvmciEnv.hpp"
 #include "jvmci/jvmciRuntime.hpp"
-#include "runtime/compilationPolicy.hpp"
-#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 
 JVMCICompiler* JVMCICompiler::_instance = NULL;
@@ -104,112 +95,39 @@
     tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methods_compiled);
   }
   _bootstrapping = false;
-  JVMCIRuntime::bootstrap_finished(CHECK);
+  JVMCI::compiler_runtime()->bootstrap_finished(CHECK);
 }
 
-#define CHECK_EXIT THREAD); \
-if (HAS_PENDING_EXCEPTION) { \
-  char buf[256]; \
-  jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
-  JVMCICompiler::exit_on_pending_exception(PENDING_EXCEPTION, buf); \
-  return; \
-} \
-(void)(0
-
-void JVMCICompiler::compile_method(const methodHandle& method, int entry_bci, JVMCIEnv* env) {
-  JVMCI_EXCEPTION_CONTEXT
-
-  bool is_osr = entry_bci != InvocationEntryBci;
-  if (_bootstrapping && is_osr) {
-      // no OSR compilations during bootstrap - the compiler is just too slow at this point,
-      // and we know that there are no endless loops
-      env->set_failure(true, "No OSR during boostrap");
-      return;
+bool JVMCICompiler::force_comp_at_level_simple(Method *method) {
+  if (UseJVMCINativeLibrary) {
+    // This mechanism exists to force compilation of a JVMCI compiler by C1
+    // to reduces the compilation time spent on the JVMCI compiler itself. In
+    // +UseJVMCINativeLibrary mode, the JVMCI compiler is AOT compiled.
+    return false;
   }
 
-  JVMCIRuntime::initialize_well_known_classes(CHECK_EXIT);
-
-  HandleMark hm;
-  Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_EXIT);
-
-  JavaValue method_result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_long((jlong) (address) method());
-  JavaCalls::call_static(&method_result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(),
-                         vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
-
-  JavaValue result(T_OBJECT);
-  if (!HAS_PENDING_EXCEPTION) {
-    JavaCallArguments args;
-    args.push_oop(receiver);
-    args.push_oop(Handle(THREAD, (oop)method_result.get_jobject()));
-    args.push_int(entry_bci);
-    args.push_long((jlong) (address) env);
-    args.push_int(env->task()->compile_id());
-    JavaCalls::call_special(&result, receiver->klass(),
-                            vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
+  if (_bootstrapping) {
+    // When bootstrapping, the JVMCI compiler can compile its own methods.
+    return false;
   }
 
-  // An uncaught exception was thrown during compilation.  Generally these
-  // should be handled by the Java code in some useful way but if they leak
-  // through to here report them instead of dying or silently ignoring them.
-  if (HAS_PENDING_EXCEPTION) {
-    Handle exception(THREAD, PENDING_EXCEPTION);
-    CLEAR_PENDING_EXCEPTION;
-
-    java_lang_Throwable::java_printStackTrace(exception, THREAD);
-    if (HAS_PENDING_EXCEPTION) {
-      CLEAR_PENDING_EXCEPTION;
-    }
-
-    env->set_failure(false, "unexpected exception thrown");
-  } else {
-    oop result_object = (oop) result.get_jobject();
-    if (result_object != NULL) {
-      oop failure_message = HotSpotCompilationRequestResult::failureMessage(result_object);
-      if (failure_message != NULL) {
-        // Copy failure reason into resource memory first ...
-        const char* failure_reason = java_lang_String::as_utf8_string(failure_message);
-        // ... and then into the C heap.
-        failure_reason = os::strdup(failure_reason, mtCompiler);
-        bool retryable = HotSpotCompilationRequestResult::retry(result_object) != 0;
-        env->set_failure(retryable, failure_reason, true);
-      } else {
-        if (env->task()->code() == NULL) {
-          env->set_failure(true, "no nmethod produced");
-        } else {
-          env->task()->set_num_inlined_bytecodes(HotSpotCompilationRequestResult::inlinedBytecodes(result_object));
-          Atomic::inc(&_methods_compiled);
+  JVMCIRuntime* runtime = JVMCI::compiler_runtime();
+  if (runtime != NULL && runtime->is_HotSpotJVMCIRuntime_initialized()) {
+    JavaThread* thread = JavaThread::current();
+    HandleMark hm(thread);
+    THREAD_JVMCIENV(thread);
+    JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(JVMCIENV);
+    objArrayHandle excludeModules(thread, HotSpotJVMCI::HotSpotJVMCIRuntime::excludeFromJVMCICompilation(JVMCIENV, HotSpotJVMCI::resolve(receiver)));
+    if (excludeModules.not_null()) {
+      ModuleEntry* moduleEntry = method->method_holder()->module();
+      for (int i = 0; i < excludeModules->length(); i++) {
+        if (oopDesc::equals(excludeModules->obj_at(i), moduleEntry->module())) {
+          return true;
         }
       }
-    } else {
-      assert(false, "JVMCICompiler.compileMethod should always return non-null");
     }
   }
-  if (_bootstrapping) {
-    _bootstrap_compilation_request_handled = true;
-  }
-}
-
-void JVMCICompiler::exit_on_pending_exception(oop exception, const char* message) {
-  JavaThread* THREAD = JavaThread::current();
-  CLEAR_PENDING_EXCEPTION;
-
-  static volatile int report_error = 0;
-  if (!report_error && Atomic::cmpxchg(1, &report_error, 0) == 0) {
-    // Only report an error once
-    tty->print_raw_cr(message);
-    Handle ex(THREAD, exception);
-    java_lang_Throwable::java_printStackTrace(ex, THREAD);
-  } else {
-    // Allow error reporting thread to print the stack trace.  Windows
-    // doesn't allow uninterruptible wait for JavaThreads
-    const bool interruptible = true;
-    os::sleep(THREAD, 200, interruptible);
-  }
-
-  before_exit(THREAD);
-  vm_exit(-1);
+  return false;
 }
 
 // Compilation entry point for methods
@@ -227,33 +145,3 @@
   TRACE_jvmci_1("JVMCICompiler::print_timers");
   tty->print_cr("       JVMCI code install time:        %6.3f s",    _codeInstallTimer.seconds());
 }
-
-bool JVMCICompiler::force_comp_at_level_simple(Method *method) {
-  JVMCI_EXCEPTION_CONTEXT
-
-  if (_bootstrapping) {
-    // When bootstrapping, the JVMCI compiler can compile its own methods.
-    return false;
-  }
-
-  if (!JVMCIRuntime::is_HotSpotJVMCIRuntime_initialized()) {
-    // JVMCI cannot participate in compilation scheduling until
-    // JVMCI is initialized and indicates it wants to participate.
-    return false;
-  }
-  // Support for graal.CompileGraalWithC1Only
-  HandleMark hm(thread);
-  jobject runtime = JVMCIRuntime::get_HotSpotJVMCIRuntime_jobject(CATCH);
-  objArrayHandle excludeFromJVMCICompilation(thread, HotSpotJVMCIRuntime::excludeFromJVMCICompilation(runtime));
-  if (excludeFromJVMCICompilation.is_null()) {
-    return false;
-  }
-  ModuleEntry *module = method->method_holder()->module();
-  for (int i = 0; i < excludeFromJVMCICompilation->length(); ++i) {
-    if (module->module() == excludeFromJVMCICompilation->obj_at(i)) {
-      return true;
-    }
-  }
-
-  return false;
-}
--- a/src/hotspot/share/jvmci/jvmciCompiler.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompiler.hpp	Wed May 01 12:31:29 2019 -0700
@@ -25,8 +25,6 @@
 #define SHARE_JVMCI_JVMCICOMPILER_HPP
 
 #include "compiler/abstractCompiler.hpp"
-#include "jvmci/jvmciEnv.hpp"
-#include "utilities/exceptions.hpp"
 
 class JVMCICompiler : public AbstractCompiler {
 private:
@@ -65,7 +63,7 @@
     return _instance;
   }
 
-  virtual const char* name() { return "JVMCI"; }
+  virtual const char* name() { return UseJVMCINativeLibrary ? "JVMCI-native" : "JVMCI"; }
 
   virtual bool supports_native()                 { return true; }
   virtual bool supports_osr   ()                 { return true; }
@@ -90,11 +88,13 @@
 
   bool is_bootstrapping() const { return _bootstrapping; }
 
+  void set_bootstrap_compilation_request_handled() {
+    _instance->_bootstrap_compilation_request_handled = true;
+  }
+
   // Compilation entry point for methods
   virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci, DirectiveSet* directive);
 
-  void compile_method(const methodHandle& target, int entry_bci, JVMCIEnv* env);
-
   // Print compilation timers and statistics
   virtual void print_timers();
 
@@ -104,6 +104,10 @@
    */
   int methods_compiled() { return _methods_compiled; }
 
+  void inc_methods_compiled() {
+    Atomic::inc(&_methods_compiled);
+  }
+
   // Print compilation timers and statistics
   static void print_compilation_timers();
 
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed May 01 12:31:29 2019 -0700
@@ -22,25 +22,25 @@
  */
 
 #include "precompiled.hpp"
-#include "ci/ciUtilities.inline.hpp"
 #include "classfile/javaClasses.inline.hpp"
+#include "classfile/stringTable.hpp"
+#include "classfile/symbolTable.hpp"
 #include "code/scopeDesc.hpp"
-#include "interpreter/linkResolver.hpp"
-#include "memory/oopFactory.hpp"
-#include "oops/cpCache.inline.hpp"
-#include "oops/generateOopMap.hpp"
-#include "oops/method.inline.hpp"
-#include "oops/objArrayOop.inline.hpp"
-#include "oops/typeArrayOop.inline.hpp"
 #include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
+#include "interpreter/linkResolver.hpp"
+#include "interpreter/bytecodeStream.hpp"
 #include "jvmci/jvmciCompilerToVM.hpp"
 #include "jvmci/jvmciCodeInstaller.hpp"
 #include "jvmci/jvmciRuntime.hpp"
+#include "memory/oopFactory.hpp"
+#include "oops/constantPool.inline.hpp"
+#include "oops/method.inline.hpp"
+#include "oops/typeArrayOop.inline.hpp"
+#include "prims/nativeLookup.hpp"
+#include "runtime/deoptimization.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
-#include "runtime/flags/jvmFlag.hpp"
 #include "runtime/frame.inline.hpp"
-#include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/timerTrace.hpp"
@@ -87,38 +87,22 @@
   }
 }
 
-// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
-#define C2V_VMENTRY(result_type, name, signature) \
-  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
-  TRACE_jvmci_1("CompilerToVM::" #name); \
-  TRACE_CALL(result_type, jvmci_ ## name signature) \
-  JVMCI_VM_ENTRY_MARK; \
+class JVMCITraceMark : public StackObj {
+  const char* _msg;
+ public:
+  JVMCITraceMark(const char* msg) {
+    _msg = msg;
+    if (JVMCITraceLevel >= 1) {
+      tty->print_cr(PTR_FORMAT " JVMCITrace-1: Enter %s", p2i(JavaThread::current()), _msg);
+    }
+  }
+  ~JVMCITraceMark() {
+    if (JVMCITraceLevel >= 1) {
+      tty->print_cr(PTR_FORMAT " JVMCITrace-1: Exit %s", p2i(JavaThread::current()), _msg);
+    }
+  }
+};
 
-#define C2V_END }
-
-oop CompilerToVM::get_jvmci_method(const methodHandle& method, TRAPS) {
-  if (method() != NULL) {
-    JavaValue result(T_OBJECT);
-    JavaCallArguments args;
-    args.push_long((jlong) (address) method());
-    JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, CHECK_NULL);
-
-    return (oop)result.get_jobject();
-  }
-  return NULL;
-}
-
-oop CompilerToVM::get_jvmci_type(JVMCIKlassHandle& klass, TRAPS) {
-  if (!klass.is_null()) {
-    JavaValue result(T_OBJECT);
-    JavaCallArguments args;
-    args.push_oop(Handle(THREAD, klass->java_mirror()));
-    JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedObjectTypeImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::klass_fromMetaspace_signature(), &args, CHECK_NULL);
-
-    return (oop)result.get_jobject();
-  }
-  return NULL;
-}
 
 Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
   assert(_index < _args->length(), "out of bounds");
@@ -127,22 +111,32 @@
   return Handle(Thread::current(), arg);
 }
 
-jobjectArray readConfiguration0(JNIEnv *env, TRAPS);
+// Entry to native method implementation that transitions current thread to '_thread_in_vm'.
+#define C2V_VMENTRY(result_type, name, signature)        \
+  JNIEXPORT result_type JNICALL c2v_ ## name signature { \
+  JVMCITraceMark jtm("CompilerToVM::" #name);            \
+  TRACE_CALL(result_type, jvmci_ ## name signature)      \
+  JVMCI_VM_ENTRY_MARK;                                   \
+  ResourceMark rm;                                       \
+  JNI_JVMCIENV(env);
 
-C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv *env))
-   jobjectArray config = readConfiguration0(env, CHECK_NULL);
-   return config;
-C2V_END
+#define C2V_END }
 
-C2V_VMENTRY(jobject, getFlagValue, (JNIEnv *, jobject c2vm, jobject name_handle))
-#define RETURN_BOXED_LONG(value) oop box; jvalue p; p.j = (jlong) (value); box = java_lang_boxing_object::create(T_LONG, &p, CHECK_NULL); return JNIHandles::make_local(THREAD, box);
-#define RETURN_BOXED_DOUBLE(value) oop box; jvalue p; p.d = (jdouble) (value); box = java_lang_boxing_object::create(T_DOUBLE, &p, CHECK_NULL); return JNIHandles::make_local(THREAD, box);
-  Handle name(THREAD, JNIHandles::resolve(name_handle));
+jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS);
+
+C2V_VMENTRY(jobjectArray, readConfiguration, (JNIEnv* env))
+  jobjectArray config = readConfiguration0(env, JVMCI_CHECK_NULL);
+  return config;
+}
+
+C2V_VMENTRY(jobject, getFlagValue, (JNIEnv* env, jobject c2vm, jobject name_handle))
+#define RETURN_BOXED_LONG(value) jvalue p; p.j = (jlong) (value); JVMCIObject box = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); return box.as_jobject();
+#define RETURN_BOXED_DOUBLE(value) jvalue p; p.d = (jdouble) (value); JVMCIObject box = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL); return box.as_jobject();
+  JVMCIObject name = JVMCIENV->wrap(name_handle);
   if (name.is_null()) {
-    THROW_0(vmSymbols::java_lang_NullPointerException());
+    JVMCI_THROW_NULL(NullPointerException);
   }
-  ResourceMark rm;
-  const char* cstring = java_lang_String::as_utf8_string(name());
+  const char* cstring = JVMCIENV->as_utf8_string(name);
   JVMFlag* flag = JVMFlag::find_flag(cstring, strlen(cstring), /* allow_locked */ true, /* return_flag */ true);
   if (flag == NULL) {
     return c2vm;
@@ -150,11 +144,11 @@
   if (flag->is_bool()) {
     jvalue prim;
     prim.z = flag->get_bool();
-    oop box = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK_NULL);
-    return JNIHandles::make_local(THREAD, box);
+    JVMCIObject box = JVMCIENV->create_box(T_BOOLEAN, &prim, JVMCI_CHECK_NULL);
+    return JVMCIENV->get_jobject(box);
   } else if (flag->is_ccstr()) {
-    Handle value = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_NULL);
-    return JNIHandles::make_local(THREAD, value());
+    JVMCIObject value = JVMCIENV->create_string(flag->get_ccstr(), JVMCI_CHECK_NULL);
+    return JVMCIENV->get_jobject(value);
   } else if (flag->is_intx()) {
     RETURN_BOXED_LONG(flag->get_intx());
   } else if (flag->is_int()) {
@@ -176,12 +170,25 @@
 #undef RETURN_BOXED_DOUBLE
 C2V_END
 
-C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv *, jobject, jobject jvmci_method))
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
-  ResourceMark rm;
+C2V_VMENTRY(jobject, getObjectAtAddress, (JNIEnv* env, jobject c2vm, jlong oop_address))
+  if (env != JavaThread::current()->jni_environment()) {
+    JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
+  }
+  if (oop_address == 0) {
+    JVMCI_THROW_MSG_NULL(InternalError, "Handle must be non-zero");
+  }
+  oop obj = *((oopDesc**) oop_address);
+  if (obj != NULL) {
+    oopDesc::verify(obj);
+  }
+  return JNIHandles::make_local(obj);
+C2V_END
+
+C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv* env, jobject, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
 
   int code_size = method->code_size();
-  typeArrayOop reconstituted_code = oopFactory::new_byteArray(code_size, CHECK_NULL);
+  jbyte* reconstituted_code = NEW_RESOURCE_ARRAY(jbyte, code_size);
 
   guarantee(method->method_holder()->is_rewritten(), "Method's holder should be rewritten");
   // iterate over all bytecodes and replace non-Java bytecodes
@@ -193,9 +200,9 @@
     int len = s.instruction_size();
 
     // Restore original byte code.
-    reconstituted_code->byte_at_put(bci, (jbyte) (s.is_wide()? Bytecodes::_wide : code));
+    reconstituted_code[bci] =  (jbyte) (s.is_wide()? Bytecodes::_wide : code);
     if (len > 1) {
-      memcpy(reconstituted_code->byte_at_addr(bci + 1), s.bcp()+1, len-1);
+      memcpy(reconstituted_code + (bci + 1), s.bcp()+1, len-1);
     }
 
     if (len > 1) {
@@ -211,14 +218,14 @@
         case Bytecodes::_invokestatic:
         case Bytecodes::_invokeinterface:
         case Bytecodes::_invokehandle: {
-          int cp_index = Bytes::get_native_u2((address) reconstituted_code->byte_at_addr(bci + 1));
-          Bytes::put_Java_u2((address) reconstituted_code->byte_at_addr(bci + 1), (u2) cp_index);
+          int cp_index = Bytes::get_native_u2((address) reconstituted_code + (bci + 1));
+          Bytes::put_Java_u2((address) reconstituted_code + (bci + 1), (u2) cp_index);
           break;
         }
 
         case Bytecodes::_invokedynamic: {
-          int cp_index = Bytes::get_native_u4((address) reconstituted_code->byte_at_addr(bci + 1));
-          Bytes::put_Java_u4((address) reconstituted_code->byte_at_addr(bci + 1), (u4) cp_index);
+          int cp_index = Bytes::get_native_u4((address) reconstituted_code + (bci + 1));
+          Bytes::put_Java_u4((address) reconstituted_code + (bci + 1), (u4) cp_index);
           break;
         }
 
@@ -229,18 +236,18 @@
       // Not all ldc byte code are rewritten.
       switch (raw_code) {
         case Bytecodes::_fast_aldc: {
-          int cpc_index = reconstituted_code->byte_at(bci + 1) & 0xff;
+          int cpc_index = reconstituted_code[bci + 1] & 0xff;
           int cp_index = method->constants()->object_to_cp_index(cpc_index);
           assert(cp_index < method->constants()->length(), "sanity check");
-          reconstituted_code->byte_at_put(bci + 1, (jbyte) cp_index);
+          reconstituted_code[bci + 1] = (jbyte) cp_index;
           break;
         }
 
         case Bytecodes::_fast_aldc_w: {
-          int cpc_index = Bytes::get_native_u2((address) reconstituted_code->byte_at_addr(bci + 1));
+          int cpc_index = Bytes::get_native_u2((address) reconstituted_code + (bci + 1));
           int cp_index = method->constants()->object_to_cp_index(cpc_index);
           assert(cp_index < method->constants()->length(), "sanity check");
-          Bytes::put_Java_u2((address) reconstituted_code->byte_at_addr(bci + 1), (u2) cp_index);
+          Bytes::put_Java_u2((address) reconstituted_code + (bci + 1), (u2) cp_index);
           break;
         }
 
@@ -250,25 +257,29 @@
     }
   }
 
-  return (jbyteArray) JNIHandles::make_local(THREAD, reconstituted_code);
+  JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
+  JVMCIENV->copy_bytes_from(reconstituted_code, result, 0, code_size);
+  return JVMCIENV->get_jbyteArray(result);
 C2V_END
 
-C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv *, jobject, jobject jvmci_method))
-  ResourceMark rm;
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
   return method->exception_table_length();
 C2V_END
 
-C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv *, jobject, jobject jvmci_method))
-  ResourceMark rm;
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
   if (method->exception_table_length() == 0) {
     return 0L;
   }
   return (jlong) (address) method->exception_table_start();
 C2V_END
 
-C2V_VMENTRY(jobject, asResolvedJavaMethod, (JNIEnv *, jobject, jobject executable_handle))
+C2V_VMENTRY(jobject, asResolvedJavaMethod, (JNIEnv* env, jobject, jobject executable_handle))
+  if (env != JavaThread::current()->jni_environment()) {
+    JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
+  }
+
   oop executable = JNIHandles::resolve(executable_handle);
   oop mirror = NULL;
   int slot = 0;
@@ -283,89 +294,101 @@
   }
   Klass* holder = java_lang_Class::as_Klass(mirror);
   methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
-  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 }
 
-C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv *, jobject, jobject base, jlong offset))
+C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv* env, jobject, jobject base, jlong offset))
   methodHandle method;
-  oop base_object = JNIHandles::resolve(base);
-  if (base_object == NULL) {
+  JVMCIObject base_object = JVMCIENV->wrap(base);
+  if (base_object.is_null()) {
     method = *((Method**)(offset));
-  } else if (base_object->is_a(SystemDictionary::ResolvedMethodName_klass())) {
-    method = (Method*) (intptr_t) base_object->long_field(offset);
-  } else if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
-    method = *((Method**)(HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object) + offset));
-  } else {
-    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                err_msg("Unexpected type: %s", base_object->klass()->external_name()));
+  } else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
+    Handle obj = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);
+    if (obj->is_a(SystemDictionary::ResolvedMethodName_klass())) {
+      method = (Method*) (intptr_t) obj->long_field(offset);
+    } else {
+      JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", obj->klass()->external_name()));
+    }
+  } else if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) {
+    method = JVMCIENV->asMethod(base_object);
+  }
+  if (method.is_null()) {
+    JVMCI_THROW_MSG_NULL(IllegalArgumentException, err_msg("Unexpected type: %s", JVMCIENV->klass_name(base_object)));
   }
   assert (method.is_null() || method->is_method(), "invalid read");
-  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 }
 
-C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject object_handle))
+C2V_VMENTRY(jobject, getConstantPool, (JNIEnv* env, jobject, jobject object_handle))
   constantPoolHandle cp;
-  oop object = JNIHandles::resolve(object_handle);
-  if (object == NULL) {
-    THROW_0(vmSymbols::java_lang_NullPointerException());
+  JVMCIObject object = JVMCIENV->wrap(object_handle);
+  if (object.is_null()) {
+    JVMCI_THROW_NULL(NullPointerException);
   }
-  if (object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
-    cp = CompilerToVM::asMethod(object)->constMethod()->constants();
-  } else if (object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
-    cp = InstanceKlass::cast(CompilerToVM::asKlass(object))->constants();
+  if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(object)) {
+    cp = JVMCIENV->asMethod(object)->constMethod()->constants();
+  } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(object)) {
+    cp = InstanceKlass::cast(JVMCIENV->asKlass(object))->constants();
   } else {
-    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                err_msg("Unexpected type: %s", object->klass()->external_name()));
+    JVMCI_THROW_MSG_NULL(IllegalArgumentException,
+                err_msg("Unexpected type: %s", JVMCIENV->klass_name(object)));
   }
   assert(!cp.is_null(), "npe");
-  JavaValue method_result(T_OBJECT);
-  JavaCallArguments args;
-  args.push_long((jlong) (address) cp());
-  JavaCalls::call_static(&method_result, SystemDictionary::HotSpotConstantPool_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::constantPool_fromMetaspace_signature(), &args, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, (oop)method_result.get_jobject());
+
+  JVMCIObject result = JVMCIENV->get_jvmci_constant_pool(cp, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 }
 
-C2V_VMENTRY(jobject, getResolvedJavaType, (JNIEnv *, jobject, jobject base, jlong offset, jboolean compressed))
+C2V_VMENTRY(jobject, getResolvedJavaType0, (JNIEnv* env, jobject, jobject base, jlong offset, jboolean compressed))
   JVMCIKlassHandle klass(THREAD);
-  oop base_object = JNIHandles::resolve(base);
+  JVMCIObject base_object = JVMCIENV->wrap(base);
   jlong base_address = 0;
-  if (base_object != NULL && offset == oopDesc::klass_offset_in_bytes()) {
-    klass = base_object->klass();
+  if (base_object.is_non_null() && offset == oopDesc::klass_offset_in_bytes()) {
+    // klass = JVMCIENV->unhandle(base_object)->klass();
+    if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
+      Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);
+      klass = base_oop->klass();
+    } else {
+      assert(false, "What types are we actually expecting here?");
+    }
   } else if (!compressed) {
-    if (base_object != NULL) {
-      if (base_object->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
-        base_address = HotSpotResolvedJavaMethodImpl::metaspaceMethod(base_object);
-      } else if (base_object->is_a(SystemDictionary::HotSpotConstantPool_klass())) {
-        base_address = HotSpotConstantPool::metaspaceConstantPool(base_object);
-      } else if (base_object->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
-        base_address = (jlong) CompilerToVM::asKlass(base_object);
-      } else if (base_object->is_a(SystemDictionary::Class_klass())) {
-        base_address = (jlong) (address) base_object;
-      } else {
-        THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-                    err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", base_object->klass()->external_name(), offset, compressed ? "true" : "false"));
+    if (base_object.is_non_null()) {
+      if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(base_object)) {
+        base_address = (intptr_t) JVMCIENV->asMethod(base_object);
+      } else if (JVMCIENV->isa_HotSpotConstantPool(base_object)) {
+        base_address = (intptr_t) JVMCIENV->asConstantPool(base_object);
+      } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) {
+        base_address = (intptr_t) JVMCIENV->asKlass(base_object);
+      } else if (JVMCIENV->isa_HotSpotObjectConstantImpl(base_object)) {
+        Handle base_oop = JVMCIENV->asConstant(base_object, JVMCI_CHECK_NULL);
+        if (base_oop->is_a(SystemDictionary::Class_klass())) {
+          base_address = (jlong) (address) base_oop();
+        }
+      }
+      if (base_address == 0) {
+        JVMCI_THROW_MSG_NULL(IllegalArgumentException,
+                    err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s", JVMCIENV->klass_name(base_object), offset, compressed ? "true" : "false"));
       }
     }
     klass = *((Klass**) (intptr_t) (base_address + offset));
   } else {
-    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+    JVMCI_THROW_MSG_NULL(IllegalArgumentException,
                 err_msg("Unexpected arguments: %s " JLONG_FORMAT " %s",
-                        base_object != NULL ? base_object->klass()->external_name() : "null",
+                        base_object.is_non_null() ? JVMCIENV->klass_name(base_object) : "null",
                         offset, compressed ? "true" : "false"));
   }
   assert (klass == NULL || klass->is_klass(), "invalid read");
-  oop result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 }
 
-C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
-  ResourceMark rm;
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
-  Klass* holder = CompilerToVM::asKlass(jvmci_type);
+C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
+  Klass* holder = JVMCIENV->asKlass(jvmci_type);
   if (holder->is_interface()) {
-    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", holder->external_name()));
+    JVMCI_THROW_MSG_NULL(InternalError, err_msg("Interface %s should be handled in Java code", holder->external_name()));
   }
 
   methodHandle ucm;
@@ -373,12 +396,12 @@
     MutexLocker locker(Compile_lock);
     ucm = Dependencies::find_unique_concrete_method(holder, method());
   }
-  oop result = CompilerToVM::get_jvmci_method(ucm, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  JVMCIObject result = JVMCIENV->get_jvmci_method(ucm, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(jobject, getImplementor, (JNIEnv *, jobject, jobject jvmci_type))
-  Klass* klass = CompilerToVM::asKlass(jvmci_type);
+C2V_VMENTRY(jobject, getImplementor, (JNIEnv* env, jobject, jobject jvmci_type))
+  Klass* klass = JVMCIENV->asKlass(jvmci_type);
   if (!klass->is_interface()) {
     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
         err_msg("Expected interface type, got %s", klass->external_name()));
@@ -390,48 +413,55 @@
     MutexLocker locker(Compile_lock);
     handle = iklass->implementor();
   }
-  oop implementor = CompilerToVM::get_jvmci_type(handle, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, implementor);
+  JVMCIObject implementor = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(implementor);
 C2V_END
 
-C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, jobject jvmci_method))
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv* env, jobject, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
   return method->is_ignored_by_security_stack_walk();
 C2V_END
 
-C2V_VMENTRY(jboolean, isCompilable,(JNIEnv *, jobject, jobject jvmci_method))
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jboolean, isCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
   constantPoolHandle cp = method->constMethod()->constants();
   assert(!cp.is_null(), "npe");
   // don't inline method when constant pool contains a CONSTANT_Dynamic
   return !method->is_not_compilable(CompLevel_full_optimization) && !cp->has_dynamic_constant();
 C2V_END
 
-C2V_VMENTRY(jboolean, hasNeverInlineDirective,(JNIEnv *, jobject, jobject jvmci_method))
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
   return !Inline || CompilerOracle::should_not_inline(method) || method->dont_inline();
 C2V_END
 
-C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv* env, jobject, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
   return CompilerOracle::should_inline(method) || method->force_inline();
 C2V_END
 
-C2V_VMENTRY(jobject, lookupType, (JNIEnv*, jobject, jstring jname, jclass accessing_class, jboolean resolve))
-  ResourceMark rm;
-  Handle name(THREAD, JNIHandles::resolve(jname));
-  Symbol* class_name = java_lang_String::as_symbol(name(), CHECK_0);
-  if (java_lang_String::length(name()) <= 1) {
-    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string()));
+C2V_VMENTRY(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
+  JVMCIObject name = JVMCIENV->wrap(jname);
+  const char* str = JVMCIENV->as_utf8_string(name);
+  TempNewSymbol class_name = SymbolTable::new_symbol(str, CHECK_NULL);
+
+  if (class_name->utf8_length() <= 1) {
+    JVMCI_THROW_MSG_0(InternalError, err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string()));
   }
 
   JVMCIKlassHandle resolved_klass(THREAD);
-  if (JNIHandles::resolve(accessing_class) == NULL) {
-    THROW_0(vmSymbols::java_lang_NullPointerException());
+  Klass* accessing_klass = NULL;
+  Handle class_loader;
+  Handle protection_domain;
+  if (accessing_class != NULL) {
+    accessing_klass = JVMCIENV->asKlass(accessing_class);
+    class_loader = Handle(THREAD, accessing_klass->class_loader());
+    protection_domain = Handle(THREAD, accessing_klass->protection_domain());
+  } else {
+    // Use the System class loader
+    class_loader = Handle(THREAD, SystemDictionary::java_system_loader());
+    JVMCIENV->runtime()->initialize(JVMCIENV);
   }
-  Klass* accessing_klass = java_lang_Class::as_Klass(JNIHandles::resolve(accessing_class));
-  Handle class_loader(THREAD, accessing_klass->class_loader());
-  Handle protection_domain(THREAD, accessing_klass->protection_domain());
 
   if (resolve) {
     resolved_klass = SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK_0);
@@ -464,135 +494,163 @@
       } else {
         resolved_klass = TypeArrayKlass::cast(Universe::typeArrayKlassObj(t))->array_klass(fd.dimension(), CHECK_0);
       }
+    } else {
+      resolved_klass = SystemDictionary::find(class_name, class_loader, protection_domain, CHECK_0);
     }
   }
-  oop result = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  JVMCIObject result = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
+  if (env != JavaThread::current()->jni_environment()) {
+    JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
+  }
+  if (mirror == NULL) {
+    return NULL;
+  }
+  JVMCIKlassHandle klass(THREAD);
+  klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));
+  if (klass == NULL) {
+    JVMCI_THROW_MSG_NULL(IllegalArgumentException, "Primitive classes are unsupported");
+  }
+  JVMCIObject result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
+}
+
+C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   oop result = cp->resolve_constant_at(index, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
 C2V_END
 
-C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
 C2V_END
 
-C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   return cp->name_and_type_ref_index_at(index);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupNameInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint which))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
-  Handle sym = java_lang_String::create_from_symbol(cp->name_ref_at(which), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, sym());
+C2V_VMENTRY(jobject, lookupNameInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
+  JVMCIObject sym = JVMCIENV->create_string(cp->name_ref_at(which), JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(sym);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupSignatureInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint which))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
-  Handle sym = java_lang_String::create_from_symbol(cp->signature_ref_at(which), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, sym());
+C2V_VMENTRY(jobject, lookupSignatureInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint which))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
+  JVMCIObject sym = JVMCIENV->create_string(cp->signature_ref_at(which), JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(sym);
 C2V_END
 
-C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   return cp->klass_ref_index_at(index);
 C2V_END
 
-C2V_VMENTRY(jobject, resolveTypeInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jobject, resolveTypeInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   Klass* klass = cp->klass_at(index, CHECK_NULL);
   JVMCIKlassHandle resolved_klass(THREAD, klass);
   if (resolved_klass->is_instance_klass()) {
     InstanceKlass::cast(resolved_klass())->link_class_or_fail(THREAD);
   }
-  oop jvmci_type = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, jvmci_type);
+  JVMCIObject klassObject = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(klassObject);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupKlassInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jobject, lookupKlassInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   Klass* loading_klass = cp->pool_holder();
   bool is_accessible = false;
-  JVMCIKlassHandle klass(THREAD, JVMCIEnv::get_klass_by_index(cp, index, is_accessible, loading_klass));
+  JVMCIKlassHandle klass(THREAD, JVMCIRuntime::get_klass_by_index(cp, index, is_accessible, loading_klass));
   Symbol* symbol = NULL;
-  if (klass == NULL) {
-    symbol = cp->klass_name_at(index);
+  if (klass.is_null()) {
+    constantTag tag = cp->tag_at(index);
+    if (tag.is_klass()) {
+      // The klass has been inserted into the constant pool
+      // very recently.
+      klass = cp->resolved_klass_at(index);
+    } else if (tag.is_symbol()) {
+      symbol = cp->symbol_at(index);
+    } else {
+      assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");
+      symbol = cp->klass_name_at(index);
+    }
   }
-  oop result_oop;
+  JVMCIObject result;
   if (!klass.is_null()) {
-    result_oop = CompilerToVM::get_jvmci_type(klass, CHECK_NULL);
+    result = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
   } else {
-    Handle result = java_lang_String::create_from_symbol(symbol, CHECK_NULL);
-    result_oop = result();
+    result = JVMCIENV->create_string(symbol, JVMCI_CHECK_NULL);
   }
-  return JNIHandles::make_local(THREAD, result_oop);
+  return JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
-  return JNIHandles::make_local(THREAD, appendix_oop);
+  return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(appendix_oop));
 C2V_END
 
-C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   InstanceKlass* pool_holder = cp->pool_holder();
   Bytecodes::Code bc = (Bytecodes::Code) (((int) opcode) & 0xFF);
-  methodHandle method = JVMCIEnv::get_method_by_index(cp, index, bc, pool_holder);
-  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  methodHandle method = JVMCIRuntime::get_method_by_index(cp, index, bc, pool_holder);
+  JVMCIObject result = JVMCIENV->get_jvmci_method(method, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   return cp->remap_instruction_operand_from_cache(index);
 C2V_END
 
-C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))
-  ResourceMark rm;
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index, jobject jvmci_method, jbyte opcode, jintArray info_handle))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
   fieldDescriptor fd;
-  LinkInfo link_info(cp, index, (jvmci_method != NULL) ? CompilerToVM::asMethod(jvmci_method) : NULL, CHECK_0);
+  LinkInfo link_info(cp, index, (jvmci_method != NULL) ? JVMCIENV->asMethod(jvmci_method) : NULL, CHECK_0);
   LinkResolver::resolve_field(fd, link_info, Bytecodes::java_code(code), false, CHECK_0);
-  typeArrayOop info = (typeArrayOop) JNIHandles::resolve(info_handle);
-  if (info == NULL || info->length() != 3) {
+  JVMCIPrimitiveArray info = JVMCIENV->wrap(info_handle);
+  if (info.is_null() || JVMCIENV->get_length(info) != 3) {
     JVMCI_ERROR_NULL("info must not be null and have a length of 3");
   }
-  info->int_at_put(0, fd.access_flags().as_int());
-  info->int_at_put(1, fd.offset());
-  info->int_at_put(2, fd.index());
+  JVMCIENV->put_int_at(info, 0, fd.access_flags().as_int());
+  JVMCIENV->put_int_at(info, 1, fd.offset());
+  JVMCIENV->put_int_at(info, 2, fd.index());
   JVMCIKlassHandle handle(THREAD, fd.field_holder());
-  oop field_holder = CompilerToVM::get_jvmci_type(handle, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, field_holder);
+  JVMCIObject field_holder = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(field_holder);
 C2V_END
 
-C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
-  ResourceMark rm;
-  Klass* klass = CompilerToVM::asKlass(jvmci_type);
-  Method* method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jint, getVtableIndexForInterfaceMethod, (JNIEnv* env, jobject, jobject jvmci_type, jobject jvmci_method))
+  Klass* klass = JVMCIENV->asKlass(jvmci_type);
+  Method* method = JVMCIENV->asMethod(jvmci_method);
   if (klass->is_interface()) {
-    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Interface %s should be handled in Java code", klass->external_name()));
+    JVMCI_THROW_MSG_0(InternalError, err_msg("Interface %s should be handled in Java code", klass->external_name()));
   }
   if (!method->method_holder()->is_interface()) {
-    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string()));
+    JVMCI_THROW_MSG_0(InternalError, err_msg("Method %s is not held by an interface, this case should be handled in Java code", method->name_and_sig_as_C_string()));
+  }
+  if (!klass->is_instance_klass()) {
+    JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));
   }
   if (!InstanceKlass::cast(klass)->is_linked()) {
-    THROW_MSG_0(vmSymbols::java_lang_InternalError(), err_msg("Class %s must be linked", klass->external_name()));
+    JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be linked", klass->external_name()));
   }
   return LinkResolver::vtable_index_of_interface_method(klass, method);
 C2V_END
 
-C2V_VMENTRY(jobject, resolveMethod, (JNIEnv *, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
-  Klass* recv_klass = CompilerToVM::asKlass(receiver_jvmci_type);
-  Klass* caller_klass = CompilerToVM::asKlass(caller_jvmci_type);
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jobject, resolveMethod, (JNIEnv* env, jobject, jobject receiver_jvmci_type, jobject jvmci_method, jobject caller_jvmci_type))
+  Klass* recv_klass = JVMCIENV->asKlass(receiver_jvmci_type);
+  Klass* caller_klass = JVMCIENV->asKlass(caller_jvmci_type);
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
 
   Klass* resolved     = method->method_holder();
   Symbol* h_name      = method->name();
@@ -632,27 +690,27 @@
     return NULL;
   }
 
-  oop result = CompilerToVM::get_jvmci_method(m, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  JVMCIObject result = JVMCIENV->get_jvmci_method(m, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type))
-  Klass* klass = CompilerToVM::asKlass(jvmci_type);
+C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv* env, jobject, jobject jvmci_type))
+  Klass* klass = JVMCIENV->asKlass(jvmci_type);
   assert(klass != NULL, "method must not be called for primitive types");
   return Dependencies::find_finalizable_subclass(klass) != NULL;
 C2V_END
 
-C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type))
-  Klass* klass = CompilerToVM::asKlass(jvmci_type);
+C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv* env, jobject, jobject jvmci_type))
+  Klass* klass = JVMCIENV->asKlass(jvmci_type);
   if (!klass->is_instance_klass()) {
     return NULL;
   }
   InstanceKlass* iklass = InstanceKlass::cast(klass);
-  oop result = CompilerToVM::get_jvmci_method(iklass->class_initializer(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  JVMCIObject result = JVMCIENV->get_jvmci_method(iklass->class_initializer(), JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv*, jobject, jlong addr))
+C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv* env, jobject, jlong addr))
   address target_addr = (address) addr;
   if (target_addr != 0x0) {
     int64_t off_low = (int64_t)target_addr - ((int64_t)CodeCache::low_bound() + sizeof(int));
@@ -662,34 +720,47 @@
   return -1;
 C2V_END
 
-C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv *, jobject,  jobject jvmci_method))
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv* env, jobject,  jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
   method->set_not_c1_compilable();
   method->set_not_c2_compilable();
   method->set_dont_inline(true);
 C2V_END
 
-C2V_VMENTRY(jint, installCode, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject installed_code, jobject speculation_log))
-  ResourceMark rm;
+C2V_VMENTRY(jint, installCode, (JNIEnv *env, jobject, jobject target, jobject compiled_code,
+            jobject installed_code, jlong failed_speculations_address, jbyteArray speculations_obj))
   HandleMark hm;
   JNIHandleMark jni_hm;
 
-  Handle target_handle(THREAD, JNIHandles::resolve(target));
-  Handle compiled_code_handle(THREAD, JNIHandles::resolve(compiled_code));
+  JVMCIObject target_handle = JVMCIENV->wrap(target);
+  JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);
   CodeBlob* cb = NULL;
-  Handle installed_code_handle(THREAD, JNIHandles::resolve(installed_code));
-  Handle speculation_log_handle(THREAD, JNIHandles::resolve(speculation_log));
+  JVMCIObject installed_code_handle = JVMCIENV->wrap(installed_code);
+  JVMCIPrimitiveArray speculations_handle = JVMCIENV->wrap(speculations_obj);
+
+  int speculations_len = JVMCIENV->get_length(speculations_handle);
+  char* speculations = NEW_RESOURCE_ARRAY(char, speculations_len);
+  JVMCIENV->copy_bytes_to(speculations_handle, (jbyte*) speculations, 0, speculations_len);
 
   JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK_JNI_ERR);
 
   TraceTime install_time("installCode", JVMCICompiler::codeInstallTimer());
-  bool is_immutable_PIC = HotSpotCompiledCode::isImmutablePIC(compiled_code_handle) > 0;
-  CodeInstaller installer(is_immutable_PIC);
-  JVMCIEnv::CodeInstallResult result = installer.install(compiler, target_handle, compiled_code_handle, cb, installed_code_handle, speculation_log_handle, CHECK_0);
+  bool is_immutable_PIC = JVMCIENV->get_HotSpotCompiledCode_isImmutablePIC(compiled_code_handle) > 0;
+
+  CodeInstaller installer(JVMCIENV, is_immutable_PIC);
+  JVMCI::CodeInstallResult result = installer.install(compiler,
+      target_handle,
+      compiled_code_handle,
+      cb,
+      installed_code_handle,
+      (FailedSpeculation**)(address) failed_speculations_address,
+      speculations,
+      speculations_len,
+      JVMCI_CHECK_0);
 
   if (PrintCodeCacheOnCompilation) {
     stringStream s;
-    // Dump code cache  into a buffer before locking the tty,
+    // Dump code cache into a buffer before locking the tty,
     {
       MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
       CodeCache::print_summary(&s, false);
@@ -698,130 +769,115 @@
     tty->print_raw_cr(s.as_string());
   }
 
-  if (result != JVMCIEnv::ok) {
+  if (result != JVMCI::ok) {
     assert(cb == NULL, "should be");
   } else {
-    if (installed_code_handle.not_null()) {
-      assert(installed_code_handle->is_a(InstalledCode::klass()), "wrong type");
-      nmethod::invalidate_installed_code(installed_code_handle, CHECK_0);
-      {
-        // Ensure that all updates to the InstalledCode fields are consistent.
-        MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
-        InstalledCode::set_address(installed_code_handle, (jlong) cb);
-        InstalledCode::set_version(installed_code_handle, InstalledCode::version(installed_code_handle) + 1);
-        if (cb->is_nmethod()) {
-          InstalledCode::set_entryPoint(installed_code_handle, (jlong) cb->as_nmethod_or_null()->verified_entry_point());
-        } else {
-          InstalledCode::set_entryPoint(installed_code_handle, (jlong) cb->code_begin());
-        }
-        if (installed_code_handle->is_a(HotSpotInstalledCode::klass())) {
-          HotSpotInstalledCode::set_size(installed_code_handle, cb->size());
-          HotSpotInstalledCode::set_codeStart(installed_code_handle, (jlong) cb->code_begin());
-          HotSpotInstalledCode::set_codeSize(installed_code_handle, cb->code_size());
-        }
+    if (installed_code_handle.is_non_null()) {
+      if (cb->is_nmethod()) {
+        assert(JVMCIENV->isa_HotSpotNmethod(installed_code_handle), "wrong type");
+        // Clear the link to an old nmethod first
+        JVMCIObject nmethod_mirror = installed_code_handle;
+        JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK_0);
+      } else {
+        assert(JVMCIENV->isa_InstalledCode(installed_code_handle), "wrong type");
       }
+      // Initialize the link to the new code blob
+      JVMCIENV->initialize_installed_code(installed_code_handle, cb, JVMCI_CHECK_0);
     }
   }
   return result;
 C2V_END
 
-C2V_VMENTRY(jint, getMetadata, (JNIEnv *jniEnv, jobject, jobject target, jobject compiled_code, jobject metadata))
+C2V_VMENTRY(jint, getMetadata, (JNIEnv *env, jobject, jobject target, jobject compiled_code, jobject metadata))
 #if INCLUDE_AOT
-  ResourceMark rm;
   HandleMark hm;
+  assert(JVMCIENV->is_hotspot(), "AOT code is executed only in HotSpot mode");
 
-  Handle target_handle(THREAD, JNIHandles::resolve(target));
-  Handle compiled_code_handle(THREAD, JNIHandles::resolve(compiled_code));
-  Handle metadata_handle(THREAD, JNIHandles::resolve(metadata));
+  JVMCIObject target_handle = JVMCIENV->wrap(target);
+  JVMCIObject compiled_code_handle = JVMCIENV->wrap(compiled_code);
+  JVMCIObject metadata_handle = JVMCIENV->wrap(metadata);
 
   CodeMetadata code_metadata;
-  CodeBlob *cb = NULL;
-  CodeInstaller installer(true /* immutable PIC compilation */);
 
-  JVMCIEnv::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata, CHECK_0);
-  if (result != JVMCIEnv::ok) {
+  CodeInstaller installer(JVMCIENV, true /* immutable PIC compilation */);
+  JVMCI::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata, JVMCI_CHECK_0);
+  if (result != JVMCI::ok) {
     return result;
   }
 
   if (code_metadata.get_nr_pc_desc() > 0) {
-    typeArrayHandle pcArrayOop = oopFactory::new_byteArray_handle(sizeof(PcDesc) * code_metadata.get_nr_pc_desc(), CHECK_(JVMCIEnv::cache_full));
-    memcpy(pcArrayOop->byte_at_addr(0), code_metadata.get_pc_desc(), sizeof(PcDesc) * code_metadata.get_nr_pc_desc());
-    HotSpotMetaData::set_pcDescBytes(metadata_handle, pcArrayOop());
+    int size = sizeof(PcDesc) * code_metadata.get_nr_pc_desc();
+    JVMCIPrimitiveArray array = JVMCIENV->new_byteArray(size, JVMCI_CHECK_(JVMCI::cache_full));
+    JVMCIENV->copy_bytes_from((jbyte*) code_metadata.get_pc_desc(), array, 0, size);
+    HotSpotJVMCI::HotSpotMetaData::set_pcDescBytes(JVMCIENV, metadata_handle, array);
   }
 
   if (code_metadata.get_scopes_size() > 0) {
-    typeArrayHandle scopesArrayOop = oopFactory::new_byteArray_handle(code_metadata.get_scopes_size(), CHECK_(JVMCIEnv::cache_full));
-    memcpy(scopesArrayOop->byte_at_addr(0), code_metadata.get_scopes_desc(), code_metadata.get_scopes_size());
-    HotSpotMetaData::set_scopesDescBytes(metadata_handle, scopesArrayOop());
+    int size = code_metadata.get_scopes_size();
+    JVMCIPrimitiveArray array = JVMCIENV->new_byteArray(size, JVMCI_CHECK_(JVMCI::cache_full));
+    JVMCIENV->copy_bytes_from((jbyte*) code_metadata.get_scopes_desc(), array, 0, size);
+    HotSpotJVMCI::HotSpotMetaData::set_scopesDescBytes(JVMCIENV, metadata_handle, array);
   }
 
   RelocBuffer* reloc_buffer = code_metadata.get_reloc_buffer();
-  typeArrayHandle relocArrayOop = oopFactory::new_byteArray_handle((int) reloc_buffer->size(), CHECK_(JVMCIEnv::cache_full));
-  if (reloc_buffer->size() > 0) {
-    memcpy(relocArrayOop->byte_at_addr(0), reloc_buffer->begin(), reloc_buffer->size());
-  }
-  HotSpotMetaData::set_relocBytes(metadata_handle, relocArrayOop());
+  int size = (int) reloc_buffer->size();
+  JVMCIPrimitiveArray array = JVMCIENV->new_byteArray(size, JVMCI_CHECK_(JVMCI::cache_full));
+  JVMCIENV->copy_bytes_from((jbyte*) reloc_buffer->begin(), array, 0, size);
+  HotSpotJVMCI::HotSpotMetaData::set_relocBytes(JVMCIENV, metadata_handle, array);
 
   const OopMapSet* oopMapSet = installer.oopMapSet();
   {
     ResourceMark mark;
     ImmutableOopMapBuilder builder(oopMapSet);
-    int oopmap_size = builder.heap_size();
-    typeArrayHandle oopMapArrayHandle = oopFactory::new_byteArray_handle(oopmap_size, CHECK_(JVMCIEnv::cache_full));
-    builder.generate_into((address) oopMapArrayHandle->byte_at_addr(0));
-    HotSpotMetaData::set_oopMaps(metadata_handle, oopMapArrayHandle());
+    int size = builder.heap_size();
+    JVMCIPrimitiveArray array = JVMCIENV->new_byteArray(size, JVMCI_CHECK_(JVMCI::cache_full));
+    builder.generate_into((address) HotSpotJVMCI::resolve(array)->byte_at_addr(0));
+    HotSpotJVMCI::HotSpotMetaData::set_oopMaps(JVMCIENV, metadata_handle, array);
   }
 
   AOTOopRecorder* recorder = code_metadata.get_oop_recorder();
 
   int nr_meta_refs = recorder->nr_meta_refs();
-  objArrayOop metadataArray = oopFactory::new_objectArray(nr_meta_refs, CHECK_(JVMCIEnv::cache_full));
-  objArrayHandle metadataArrayHandle(THREAD, metadataArray);
+  JVMCIObjectArray metadataArray = JVMCIENV->new_Object_array(nr_meta_refs, JVMCI_CHECK_(JVMCI::cache_full));
   for (int i = 0; i < nr_meta_refs; ++i) {
     jobject element = recorder->meta_element(i);
     if (element == NULL) {
-      return JVMCIEnv::cache_full;
+      return JVMCI::cache_full;
     }
-    metadataArrayHandle->obj_at_put(i, JNIHandles::resolve(element));
+    JVMCIENV->put_object_at(metadataArray, i, JVMCIENV->wrap(element));
   }
-  HotSpotMetaData::set_metadata(metadata_handle, metadataArrayHandle());
+  HotSpotJVMCI::HotSpotMetaData::set_metadata(JVMCIENV, metadata_handle, metadataArray);
 
   ExceptionHandlerTable* handler = code_metadata.get_exception_table();
   int table_size = handler->size_in_bytes();
-  typeArrayHandle exceptionArrayOop = oopFactory::new_byteArray_handle(table_size, CHECK_(JVMCIEnv::cache_full));
-
+  JVMCIPrimitiveArray exceptionArray = JVMCIENV->new_byteArray(table_size, JVMCI_CHECK_(JVMCI::cache_full));
   if (table_size > 0) {
-    handler->copy_bytes_to((address) exceptionArrayOop->byte_at_addr(0));
+    handler->copy_bytes_to((address) HotSpotJVMCI::resolve(exceptionArray)->byte_at_addr(0));
   }
-  HotSpotMetaData::set_exceptionBytes(metadata_handle, exceptionArrayOop());
+  HotSpotJVMCI::HotSpotMetaData::set_exceptionBytes(JVMCIENV, metadata_handle, exceptionArray);
 
   return result;
 #else
-  THROW_MSG_0(vmSymbols::java_lang_InternalError(), "unimplemented");
+  JVMCI_THROW_MSG_0(InternalError, "unimplemented");
 #endif
 C2V_END
 
-C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv *jniEnv, jobject))
+C2V_VMENTRY(void, resetCompilationStatistics, (JNIEnv* env, jobject))
   JVMCICompiler* compiler = JVMCICompiler::instance(true, CHECK);
   CompilerStatistics* stats = compiler->stats();
   stats->_standard.reset();
   stats->_osr.reset();
 C2V_END
 
-C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv *jniEnv, jobject, jobject installedCode))
-  ResourceMark rm;
+C2V_VMENTRY(jobject, disassembleCodeBlob, (JNIEnv* env, jobject, jobject installedCode))
   HandleMark hm;
 
   if (installedCode == NULL) {
-    THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(), "installedCode is null");
+    JVMCI_THROW_MSG_NULL(NullPointerException, "installedCode is null");
   }
 
-  jlong codeBlob = InstalledCode::address(installedCode);
-  if (codeBlob == 0L) {
-    return NULL;
-  }
-
-  CodeBlob* cb = (CodeBlob*) (address) codeBlob;
+  JVMCIObject installedCodeObject = JVMCIENV->wrap(installedCode);
+  CodeBlob* cb = JVMCIENV->asCodeBlob(installedCodeObject);
   if (cb == NULL) {
     return NULL;
   }
@@ -846,28 +902,32 @@
     return NULL;
   }
 
-  Handle result = java_lang_String::create_from_platform_dependent_str(st.as_string(), CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result());
+  JVMCIObject result = JVMCIENV->create_string(st.as_string(), JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv*, jobject, jobject jvmci_method, int bci))
-  ResourceMark rm;
+C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv* env, jobject, jobject jvmci_method, int bci))
   HandleMark hm;
 
-  methodHandle method = CompilerToVM::asMethod(jvmci_method);
-  oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, element);
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
+  JVMCIObject element = JVMCIENV->new_StackTraceElement(method, bci, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(element);
 C2V_END
 
-C2V_VMENTRY(jobject, executeInstalledCode, (JNIEnv*, jobject, jobject args, jobject hotspotInstalledCode))
-  ResourceMark rm;
+C2V_VMENTRY(jobject, executeHotSpotNmethod, (JNIEnv* env, jobject, jobject args, jobject hs_nmethod))
+  if (env != JavaThread::current()->jni_environment()) {
+    // The incoming arguments array would have to contain JavaConstants instead of regular objects
+    // and the return value would have to be wrapped as a JavaConstant.
+    JVMCI_THROW_MSG_NULL(InternalError, "Wrapping of arguments is currently unsupported");
+  }
+
   HandleMark hm;
 
-  jlong nmethodValue = InstalledCode::address(hotspotInstalledCode);
-  if (nmethodValue == 0L) {
-    THROW_NULL(vmSymbols::jdk_vm_ci_code_InvalidInstalledCodeException());
+  JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
+  nmethod* nm = JVMCIENV->asNmethod(nmethod_mirror);
+  if (nm == NULL) {
+    JVMCI_THROW_NULL(InvalidInstalledCodeException);
   }
-  nmethod* nm = (nmethod*) (address) nmethodValue;
   methodHandle mh = nm->method();
   Symbol* signature = mh->signature();
   JavaCallArguments jca(mh->size_of_parameters());
@@ -880,7 +940,7 @@
   if (jap.get_ret_type() == T_VOID) {
     return NULL;
   } else if (jap.get_ret_type() == T_OBJECT || jap.get_ret_type() == T_ARRAY) {
-    return JNIHandles::make_local(THREAD, (oop) result.get_jobject());
+    return JNIHandles::make_local((oop) result.get_jobject());
   } else {
     jvalue *value = (jvalue *) result.get_value_addr();
     // Narrow the value down if required (Important on big endian machines)
@@ -900,13 +960,13 @@
       default:
         break;
     }
-    oop o = java_lang_boxing_object::create(jap.get_ret_type(), value, CHECK_NULL);
-    return JNIHandles::make_local(THREAD, o);
+    JVMCIObject o = JVMCIENV->create_box(jap.get_ret_type(), value, JVMCI_CHECK_NULL);
+    return JVMCIENV->get_jobject(o);
   }
 C2V_END
 
-C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv *, jobject, jobject jvmci_method))
-  Method* method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv* env, jobject, jobject jvmci_method))
+  Method* method = JVMCIENV->asMethod(jvmci_method);
   if (!method->has_linenumber_table()) {
     return NULL;
   }
@@ -917,38 +977,36 @@
   }
 
   CompressedLineNumberReadStream stream(method->compressed_linenumber_table());
-  typeArrayOop result = oopFactory::new_longArray(2 * num_entries, CHECK_NULL);
+  JVMCIPrimitiveArray result = JVMCIENV->new_longArray(2 * num_entries, JVMCI_CHECK_NULL);
 
   int i = 0;
   jlong value;
   while (stream.read_pair()) {
     value = ((long) stream.bci());
-    result->long_at_put(i, value);
+    JVMCIENV->put_long_at(result, i, value);
     value = ((long) stream.line());
-    result->long_at_put(i + 1, value);
+    JVMCIENV->put_long_at(result, i + 1, value);
     i += 2;
   }
 
-  return (jlongArray) JNIHandles::make_local(THREAD, result);
+  return (jlongArray) JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv *, jobject, jobject jvmci_method))
-  ResourceMark rm;
-  Method* method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv* env, jobject, jobject jvmci_method))
+  Method* method = JVMCIENV->asMethod(jvmci_method);
   if (!method->has_localvariable_table()) {
     return 0;
   }
   return (jlong) (address) method->localvariable_table_start();
 C2V_END
 
-C2V_VMENTRY(jint, getLocalVariableTableLength, (JNIEnv *, jobject, jobject jvmci_method))
-  ResourceMark rm;
-  Method* method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jint, getLocalVariableTableLength, (JNIEnv* env, jobject, jobject jvmci_method))
+  Method* method = JVMCIENV->asMethod(jvmci_method);
   return method->localvariable_table_length();
 C2V_END
 
-C2V_VMENTRY(void, reprofile, (JNIEnv*, jobject, jobject jvmci_method))
-  Method* method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(void, reprofile, (JNIEnv* env, jobject, jobject jvmci_method))
+  Method* method = JVMCIENV->asMethod(jvmci_method);
   MethodCounters* mcs = method->method_counters();
   if (mcs != NULL) {
     mcs->clear_counters();
@@ -971,52 +1029,56 @@
 C2V_END
 
 
-C2V_VMENTRY(void, invalidateInstalledCode, (JNIEnv*, jobject, jobject installed_code))
-  Handle installed_code_handle(THREAD, JNIHandles::resolve(installed_code));
-  nmethod::invalidate_installed_code(installed_code_handle, CHECK);
+C2V_VMENTRY(void, invalidateHotSpotNmethod, (JNIEnv* env, jobject, jobject hs_nmethod))
+  JVMCIObject nmethod_mirror = JVMCIENV->wrap(hs_nmethod);
+  JVMCIENV->invalidate_nmethod_mirror(nmethod_mirror, JVMCI_CHECK);
 C2V_END
 
-C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv*, jobject))
-  typeArrayOop arrayOop = oopFactory::new_longArray(JVMCICounterSize, CHECK_NULL);
-  JavaThread::collect_counters(arrayOop);
-  return (jlongArray) JNIHandles::make_local(THREAD, arrayOop);
+C2V_VMENTRY(jobject, readUncompressedOop, (JNIEnv* env, jobject, jlong addr))
+  oop ret = RawAccess<>::oop_load((oop*)(address)addr);
+  return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(ret));
+ C2V_END
+
+C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv* env, jobject))
+  JVMCIPrimitiveArray array = JVMCIENV->new_longArray(JVMCICounterSize, JVMCI_CHECK_NULL);
+  JavaThread::collect_counters(JVMCIENV, array);
+  return (jlongArray) JVMCIENV->get_jobject(array);
 C2V_END
 
-C2V_VMENTRY(int, allocateCompileId, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci))
+C2V_VMENTRY(int, allocateCompileId, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci))
   HandleMark hm;
-  ResourceMark rm;
-  if (JNIHandles::resolve(jvmci_method) == NULL) {
-    THROW_0(vmSymbols::java_lang_NullPointerException());
+  if (jvmci_method == NULL) {
+    JVMCI_THROW_0(NullPointerException);
   }
-  Method* method = CompilerToVM::asMethod(jvmci_method);
+  Method* method = JVMCIENV->asMethod(jvmci_method);
   if (entry_bci >= method->code_size() || entry_bci < -1) {
-    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Unexpected bci %d", entry_bci));
+    JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Unexpected bci %d", entry_bci));
   }
   return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);
 C2V_END
 
 
-C2V_VMENTRY(jboolean, isMature, (JNIEnv*, jobject, jlong metaspace_method_data))
-  MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data);
+C2V_VMENTRY(jboolean, isMature, (JNIEnv* env, jobject, jlong metaspace_method_data))
+  MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
   return mdo != NULL && mdo->is_mature();
 C2V_END
 
-C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci, int comp_level))
-  Method* method = CompilerToVM::asMethod(jvmci_method);
+C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv* env, jobject, jobject jvmci_method, int entry_bci, int comp_level))
+  Method* method = JVMCIENV->asMethod(jvmci_method);
   return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
 C2V_END
 
-C2V_VMENTRY(jobject, getSymbol, (JNIEnv*, jobject, jlong symbol))
-  Handle sym = java_lang_String::create_from_symbol((Symbol*)(address)symbol, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, sym());
+C2V_VMENTRY(jobject, getSymbol, (JNIEnv* env, jobject, jlong symbol))
+  JVMCIObject sym = JVMCIENV->create_string((Symbol*)(address)symbol, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(sym);
 C2V_END
 
-bool matches(jobjectArray methods, Method* method) {
+bool matches(jobjectArray methods, Method* method, JVMCIEnv* JVMCIENV) {
   objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
 
   for (int i = 0; i < methods_oop->length(); i++) {
     oop resolved = methods_oop->obj_at(i);
-    if (resolved->is_a(HotSpotResolvedJavaMethodImpl::klass()) && CompilerToVM::asMethod(resolved) == method) {
+    if ((resolved->klass() == HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass()) && HotSpotJVMCI::asMethod(JVMCIENV, resolved) == method) {
       return true;
     }
   }
@@ -1037,18 +1099,21 @@
   JavaCalls::call(result, method, args, CHECK);
 }
 
-C2V_VMENTRY(jobject, iterateFrames, (JNIEnv*, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))
-  ResourceMark rm;
+C2V_VMENTRY(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, jobjectArray initial_methods, jobjectArray match_methods, jint initialSkip, jobject visitor_handle))
 
   if (!thread->has_last_Java_frame()) {
     return NULL;
   }
   Handle visitor(THREAD, JNIHandles::resolve_non_null(visitor_handle));
-  Handle frame_reference = HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
-  HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
+
+  if (env != JavaThread::current()->jni_environment()) {
+    JVMCI_THROW_MSG_NULL(InternalError, "getNextStackFrame is only supported for HotSpot stack walking");
+  }
+
+  HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
+  Handle frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
 
   StackFrameStream fst(thread);
-
   jobjectArray methods = initial_methods;
 
   int frame_number = 0;
@@ -1062,7 +1127,7 @@
       if (vf->is_compiled_frame()) {
         // compiled method frame
         compiledVFrame* cvf = compiledVFrame::cast(vf);
-        if (methods == NULL || matches(methods, cvf->method())) {
+        if (methods == NULL || matches(methods, cvf->method(), JVMCIENV)) {
           if (initialSkip > 0) {
             initialSkip--;
           } else {
@@ -1096,29 +1161,29 @@
                   array->bool_at_put(i, true);
                 }
               }
-              HotSpotStackFrameReference::set_localIsVirtual(frame_reference, array());
+              HotSpotJVMCI::HotSpotStackFrameReference::set_localIsVirtual(JVMCIENV, frame_reference(), array());
             } else {
-              HotSpotStackFrameReference::set_localIsVirtual(frame_reference, NULL);
+              HotSpotJVMCI::HotSpotStackFrameReference::set_localIsVirtual(JVMCIENV, frame_reference(), NULL);
             }
 
             locals = cvf->locals();
-            HotSpotStackFrameReference::set_bci(frame_reference, cvf->bci());
-            oop method = CompilerToVM::get_jvmci_method(cvf->method(), CHECK_NULL);
-            HotSpotStackFrameReference::set_method(frame_reference, method);
+            HotSpotJVMCI::HotSpotStackFrameReference::set_bci(JVMCIENV, frame_reference(), cvf->bci());
+            JVMCIObject method = JVMCIENV->get_jvmci_method(cvf->method(), JVMCI_CHECK_NULL);
+            HotSpotJVMCI::HotSpotStackFrameReference::set_method(JVMCIENV, frame_reference(), JNIHandles::resolve(method.as_jobject()));
           }
         }
       } else if (vf->is_interpreted_frame()) {
         // interpreted method frame
         interpretedVFrame* ivf = interpretedVFrame::cast(vf);
-        if (methods == NULL || matches(methods, ivf->method())) {
+        if (methods == NULL || matches(methods, ivf->method(), JVMCIENV)) {
           if (initialSkip > 0) {
             initialSkip--;
           } else {
             locals = ivf->locals();
-            HotSpotStackFrameReference::set_bci(frame_reference, ivf->bci());
-            oop method = CompilerToVM::get_jvmci_method(ivf->method(), CHECK_NULL);
-            HotSpotStackFrameReference::set_method(frame_reference, method);
-            HotSpotStackFrameReference::set_localIsVirtual(frame_reference, NULL);
+            HotSpotJVMCI::HotSpotStackFrameReference::set_bci(JVMCIENV, frame_reference(), ivf->bci());
+            JVMCIObject method = JVMCIENV->get_jvmci_method(ivf->method(), JVMCI_CHECK_NULL);
+            HotSpotJVMCI::HotSpotStackFrameReference::set_method(JVMCIENV, frame_reference(), JNIHandles::resolve(method.as_jobject()));
+            HotSpotJVMCI::HotSpotStackFrameReference::set_localIsVirtual(JVMCIENV, frame_reference(), NULL);
           }
         }
       }
@@ -1126,9 +1191,9 @@
       // locals != NULL means that we found a matching frame and result is already partially initialized
       if (locals != NULL) {
         methods = match_methods;
-        HotSpotStackFrameReference::set_compilerToVM(frame_reference, JNIHandles::resolve(compilerToVM));
-        HotSpotStackFrameReference::set_stackPointer(frame_reference, (jlong) fst.current()->sp());
-        HotSpotStackFrameReference::set_frameNumber(frame_reference, frame_number);
+        HotSpotJVMCI::HotSpotStackFrameReference::set_compilerToVM(JVMCIENV, frame_reference(), JNIHandles::resolve(compilerToVM));
+        HotSpotJVMCI::HotSpotStackFrameReference::set_stackPointer(JVMCIENV, frame_reference(), (jlong) fst.current()->sp());
+        HotSpotJVMCI::HotSpotStackFrameReference::set_frameNumber(JVMCIENV, frame_reference(), frame_number);
 
         // initialize the locals array
         objArrayOop array_oop = oopFactory::new_objectArray(locals->size(), CHECK_NULL);
@@ -1139,20 +1204,20 @@
             array->obj_at_put(i, locals->at(i)->get_obj()());
           }
         }
-        HotSpotStackFrameReference::set_locals(frame_reference, array());
-        HotSpotStackFrameReference::set_objectsMaterialized(frame_reference, JNI_FALSE);
+        HotSpotJVMCI::HotSpotStackFrameReference::set_locals(JVMCIENV, frame_reference(), array());
+        HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, frame_reference(), JNI_FALSE);
 
         JavaValue result(T_OBJECT);
         JavaCallArguments args(visitor);
         args.push_oop(frame_reference);
-        call_interface(&result, SystemDictionary::InspectedFrameVisitor_klass(), vmSymbols::visitFrame_name(), vmSymbols::visitFrame_signature(), &args, CHECK_NULL);
+        call_interface(&result, HotSpotJVMCI::InspectedFrameVisitor::klass(), vmSymbols::visitFrame_name(), vmSymbols::visitFrame_signature(), &args, CHECK_NULL);
         if (result.get_jobject() != NULL) {
           return JNIHandles::make_local(thread, (oop) result.get_jobject());
         }
         assert(initialSkip == 0, "There should be no match before initialSkip == 0");
-        if (HotSpotStackFrameReference::objectsMaterialized(frame_reference) == JNI_TRUE) {
+        if (HotSpotJVMCI::HotSpotStackFrameReference::objectsMaterialized(JVMCIENV, frame_reference()) == JNI_TRUE) {
           // the frame has been deoptimized, we need to re-synchronize the frame and vframe
-          intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(frame_reference);
+          intptr_t* stack_pointer = (intptr_t*) HotSpotJVMCI::HotSpotStackFrameReference::stackPointer(JVMCIENV, frame_reference());
           fst = StackFrameStream(thread);
           while (fst.current()->sp() != stack_pointer && !fst.is_done()) {
             fst.next();
@@ -1172,8 +1237,8 @@
             assert(vf->is_compiled_frame(), "Wrong frame type");
           }
         }
-        frame_reference = HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
-        HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
+        frame_reference = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance_handle(CHECK_NULL);
+        HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_NULL);
       }
 
       if (vf->is_top()) {
@@ -1195,16 +1260,16 @@
   return NULL;
 C2V_END
 
-C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   CallInfo callInfo;
   LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK);
   ConstantPoolCacheEntry* cp_cache_entry = cp->invokedynamic_cp_cache_entry_at(index);
   cp_cache_entry->set_dynamic_call(cp, callInfo);
 C2V_END
 
-C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   Klass* holder = cp->klass_ref_at(index, CHECK);
   Symbol* name = cp->name_ref_at(index);
   if (MethodHandles::is_signature_polymorphic_name(holder, name)) {
@@ -1215,8 +1280,8 @@
   }
 C2V_END
 
-C2V_VMENTRY(jint, isResolvedInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
-  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+C2V_VMENTRY(jint, isResolvedInvokeHandleInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = JVMCIENV->asConstantPool(jvmci_constant_pool);
   ConstantPoolCacheEntry* cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
   if (cp_cache_entry->is_resolved(Bytecodes::_invokehandle)) {
     // MethodHandle.invoke* --> LambdaForm?
@@ -1256,16 +1321,16 @@
 C2V_END
 
 
-C2V_VMENTRY(jobject, getSignaturePolymorphicHolders, (JNIEnv*, jobject))
-  objArrayHandle holders = oopFactory::new_objArray_handle(SystemDictionary::String_klass(), 2, CHECK_NULL);
-  Handle mh = java_lang_String::create_from_str("Ljava/lang/invoke/MethodHandle;", CHECK_NULL);
-  Handle vh = java_lang_String::create_from_str("Ljava/lang/invoke/VarHandle;", CHECK_NULL);
-  holders->obj_at_put(0, mh());
-  holders->obj_at_put(1, vh());
-  return JNIHandles::make_local(THREAD, holders());
+C2V_VMENTRY(jobject, getSignaturePolymorphicHolders, (JNIEnv* env, jobject))
+  JVMCIObjectArray holders = JVMCIENV->new_String_array(2, JVMCI_CHECK_NULL);
+  JVMCIObject mh = JVMCIENV->create_string("Ljava/lang/invoke/MethodHandle;", JVMCI_CHECK_NULL);
+  JVMCIObject vh = JVMCIENV->create_string("Ljava/lang/invoke/VarHandle;", JVMCI_CHECK_NULL);
+  JVMCIENV->put_object_at(holders, 0, mh);
+  JVMCIENV->put_object_at(holders, 1, vh);
+  return JVMCIENV->get_jobject(holders);
 C2V_END
 
-C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv*, jobject))
+C2V_VMENTRY(jboolean, shouldDebugNonSafepoints, (JNIEnv* env, jobject))
   //see compute_recording_non_safepoints in debugInfroRec.cpp
   if (JvmtiExport::should_post_compiled_method_load() && FLAG_IS_DEFAULT(DebugNonSafepoints)) {
     return true;
@@ -1274,28 +1339,31 @@
 C2V_END
 
 // public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
-C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv*, jobject, jobject hs_frame, bool invalidate))
-  ResourceMark rm;
-
-  if (hs_frame == NULL) {
-    THROW_MSG(vmSymbols::java_lang_NullPointerException(), "stack frame is null")
+C2V_VMENTRY(void, materializeVirtualObjects, (JNIEnv* env, jobject, jobject _hs_frame, bool invalidate))
+  JVMCIObject hs_frame = JVMCIENV->wrap(_hs_frame);
+  if (hs_frame.is_null()) {
+    JVMCI_THROW_MSG(NullPointerException, "stack frame is null");
   }
 
-  HotSpotStackFrameReference::klass()->initialize(CHECK);
+  if (env != JavaThread::current()->jni_environment()) {
+    JVMCI_THROW_MSG(InternalError, "getNextStackFrame is only supported for HotSpot stack walking");
+  }
+
+  JVMCIENV->HotSpotStackFrameReference_initialize(JVMCI_CHECK);
 
   // look for the given stack frame
   StackFrameStream fst(thread);
-  intptr_t* stack_pointer = (intptr_t*) HotSpotStackFrameReference::stackPointer(hs_frame);
+  intptr_t* stack_pointer = (intptr_t*) JVMCIENV->get_HotSpotStackFrameReference_stackPointer(hs_frame);
   while (fst.current()->sp() != stack_pointer && !fst.is_done()) {
     fst.next();
   }
   if (fst.current()->sp() != stack_pointer) {
-    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found")
+    JVMCI_THROW_MSG(IllegalStateException, "stack frame not found");
   }
 
   if (invalidate) {
     if (!fst.current()->is_compiled_frame()) {
-      THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected")
+      JVMCI_THROW_MSG(IllegalStateException, "compiled stack frame expected");
     }
     assert(fst.current()->cb()->is_nmethod(), "nmethod expected");
     ((nmethod*) fst.current()->cb())->make_not_entrant();
@@ -1307,12 +1375,12 @@
     fstAfterDeopt.next();
   }
   if (fstAfterDeopt.current()->sp() != stack_pointer) {
-    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "stack frame not found after deopt")
+    JVMCI_THROW_MSG(IllegalStateException, "stack frame not found after deopt");
   }
 
   vframe* vf = vframe::new_vframe(fstAfterDeopt.current(), fstAfterDeopt.register_map(), thread);
   if (!vf->is_compiled_frame()) {
-    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "compiled stack frame expected")
+    JVMCI_THROW_MSG(IllegalStateException, "compiled stack frame expected");
   }
 
   GrowableArray<compiledVFrame*>* virtualFrames = new GrowableArray<compiledVFrame*>(10);
@@ -1325,9 +1393,9 @@
     vf = vf->sender();
   }
 
-  int last_frame_number = HotSpotStackFrameReference::frameNumber(hs_frame);
+  int last_frame_number = JVMCIENV->get_HotSpotStackFrameReference_frameNumber(hs_frame);
   if (last_frame_number >= virtualFrames->length()) {
-    THROW_MSG(vmSymbols::java_lang_IllegalStateException(), "invalid frame number")
+    JVMCI_THROW_MSG(IllegalStateException, "invalid frame number");
   }
 
   // Reallocate the non-escaping objects and restore their fields.
@@ -1381,49 +1449,50 @@
   }
 
   // all locals are materialized by now
-  HotSpotStackFrameReference::set_localIsVirtual(hs_frame, NULL);
-
+  JVMCIENV->set_HotSpotStackFrameReference_localIsVirtual(hs_frame, NULL);
   // update the locals array
-  objArrayHandle array(THREAD, HotSpotStackFrameReference::locals(hs_frame));
+  JVMCIObjectArray array = JVMCIENV->get_HotSpotStackFrameReference_locals(hs_frame);
   StackValueCollection* locals = virtualFrames->at(last_frame_number)->locals();
   for (int i = 0; i < locals->size(); i++) {
     StackValue* var = locals->at(i);
     if (var->type() == T_OBJECT) {
-      array->obj_at_put(i, locals->at(i)->get_obj()());
+      JVMCIENV->put_object_at(array, i, HotSpotJVMCI::wrap(locals->at(i)->get_obj()()));
     }
   }
-  HotSpotStackFrameReference::set_objectsMaterialized(hs_frame, JNI_TRUE);
+  HotSpotJVMCI::HotSpotStackFrameReference::set_objectsMaterialized(JVMCIENV, hs_frame, JNI_TRUE);
 C2V_END
 
-C2V_VMENTRY(void, writeDebugOutput, (JNIEnv*, jobject, jbyteArray bytes, jint offset, jint length))
+C2V_VMENTRY(void, writeDebugOutput, (JNIEnv* env, jobject, jbyteArray bytes, jint offset, jint length))
   if (bytes == NULL) {
-    THROW(vmSymbols::java_lang_NullPointerException());
+    JVMCI_THROW(NullPointerException);
   }
-  typeArrayOop array = (typeArrayOop) JNIHandles::resolve(bytes);
+  JVMCIPrimitiveArray array = JVMCIENV->wrap(bytes);
 
   // Check if offset and length are non negative.
   if (offset < 0 || length < 0) {
-    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
+    JVMCI_THROW(ArrayIndexOutOfBoundsException);
   }
   // Check if the range is valid.
-  if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array->length())) {
-    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException());
+  int array_length = JVMCIENV->get_length(array);
+  if ((((unsigned int) length + (unsigned int) offset) > (unsigned int) array_length)) {
+    JVMCI_THROW(ArrayIndexOutOfBoundsException);
   }
+  jbyte buffer[O_BUFLEN];
   while (length > 0) {
-    jbyte* start = array->byte_at_addr(offset);
-    tty->write((char*) start, MIN2(length, (jint)O_BUFLEN));
+    int copy_len = MIN2(length, (jint)O_BUFLEN);
+    JVMCIENV->copy_bytes_to(array, buffer, offset, copy_len);
+    tty->write((char*) buffer, copy_len);
     length -= O_BUFLEN;
     offset += O_BUFLEN;
   }
 C2V_END
 
-C2V_VMENTRY(void, flushDebugOutput, (JNIEnv*, jobject))
+C2V_VMENTRY(void, flushDebugOutput, (JNIEnv* env, jobject))
   tty->flush();
 C2V_END
 
-C2V_VMENTRY(int, methodDataProfileDataSize, (JNIEnv*, jobject, jlong metaspace_method_data, jint position))
-  ResourceMark rm;
-  MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data);
+C2V_VMENTRY(int, methodDataProfileDataSize, (JNIEnv* env, jobject, jlong metaspace_method_data, jint position))
+  MethodData* mdo = JVMCIENV->asMethodData(metaspace_method_data);
   ProfileData* profile_data = mdo->data_at(position);
   if (mdo->is_valid(profile_data)) {
     return profile_data->size_in_bytes();
@@ -1437,48 +1506,115 @@
       return profile_data->size_in_bytes();
     }
   }
-  THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), err_msg("Invalid profile data position %d", position));
+  JVMCI_THROW_MSG_0(IllegalArgumentException, err_msg("Invalid profile data position %d", position));
 C2V_END
 
-C2V_VMENTRY(jlong, getFingerprint, (JNIEnv*, jobject, jlong metaspace_klass))
+C2V_VMENTRY(jlong, getFingerprint, (JNIEnv* env, jobject, jlong metaspace_klass))
 #if INCLUDE_AOT
-  Klass *k = CompilerToVM::asKlass(metaspace_klass);
+  Klass *k = (Klass*) (address) metaspace_klass;
   if (k->is_instance_klass()) {
     return InstanceKlass::cast(k)->get_stored_fingerprint();
   } else {
     return 0;
   }
 #else
-  THROW_MSG_0(vmSymbols::java_lang_InternalError(), "unimplemented");
+  JVMCI_THROW_MSG_0(InternalError, "unimplemented");
 #endif
 C2V_END
 
-C2V_VMENTRY(jobject, getHostClass, (JNIEnv*, jobject, jobject jvmci_type))
-  InstanceKlass* k = InstanceKlass::cast(CompilerToVM::asKlass(jvmci_type));
+C2V_VMENTRY(jobject, getHostClass, (JNIEnv* env, jobject, jobject jvmci_type))
+  InstanceKlass* k = InstanceKlass::cast(JVMCIENV->asKlass(jvmci_type));
   InstanceKlass* host = k->unsafe_anonymous_host();
   JVMCIKlassHandle handle(THREAD, host);
-  oop result = CompilerToVM::get_jvmci_type(handle, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, result);
+  JVMCIObject result = JVMCIENV->get_jvmci_type(handle, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
 C2V_END
 
-C2V_VMENTRY(int, interpreterFrameSize, (JNIEnv*, jobject, jobject bytecode_frame_handle))
-  if (bytecode_frame_handle == NULL) {
-    THROW_0(vmSymbols::java_lang_NullPointerException());
+C2V_VMENTRY(jobject, getInterfaces, (JNIEnv* env, jobject, jobject jvmci_type))
+  if (jvmci_type == NULL) {
+    JVMCI_THROW_0(NullPointerException);
   }
 
-  oop top_bytecode_frame = JNIHandles::resolve_non_null(bytecode_frame_handle);
-  oop bytecode_frame = top_bytecode_frame;
+  Klass* klass = JVMCIENV->asKlass(jvmci_type);
+  if (klass == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  if (!klass->is_instance_klass()) {
+    JVMCI_THROW_MSG_0(InternalError, err_msg("Class %s must be instance klass", klass->external_name()));
+  }
+  InstanceKlass* iklass = InstanceKlass::cast(klass);
+
+  // Regular instance klass, fill in all local interfaces
+  int size = iklass->local_interfaces()->length();
+  JVMCIObjectArray interfaces = JVMCIENV->new_HotSpotResolvedObjectTypeImpl_array(size, JVMCI_CHECK_NULL);
+  for (int index = 0; index < size; index++) {
+    JVMCIKlassHandle klass(THREAD);
+    Klass* k = iklass->local_interfaces()->at(index);
+    klass = k;
+    JVMCIObject type = JVMCIENV->get_jvmci_type(klass, JVMCI_CHECK_NULL);
+    JVMCIENV->put_object_at(interfaces, index, type);
+  }
+  return JVMCIENV->get_jobject(interfaces);
+C2V_END
+
+C2V_VMENTRY(jobject, getComponentType, (JNIEnv* env, jobject, jobject jvmci_type))
+  if (jvmci_type == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+
+  Klass* klass = JVMCIENV->asKlass(jvmci_type);
+  oop mirror = klass->java_mirror();
+  if (java_lang_Class::is_primitive(mirror) ||
+      !java_lang_Class::as_Klass(mirror)->is_array_klass()) {
+    return NULL;
+  }
+
+  oop component_mirror = java_lang_Class::component_mirror(mirror);
+  if (component_mirror == NULL) {
+    return NULL;
+  }
+  Klass* component_klass = java_lang_Class::as_Klass(component_mirror);
+  if (component_klass != NULL) {
+    JVMCIKlassHandle klass_handle(THREAD);
+    klass_handle = component_klass;
+    JVMCIObject result = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
+    return JVMCIENV->get_jobject(result);
+  }
+  BasicType type = java_lang_Class::primitive_type(component_mirror);
+  JVMCIObject result = JVMCIENV->get_jvmci_primitive_type(type);
+  return JVMCIENV->get_jobject(result);
+C2V_END
+
+C2V_VMENTRY(void, ensureInitialized, (JNIEnv* env, jobject, jobject jvmci_type))
+  if (jvmci_type == NULL) {
+    JVMCI_THROW(NullPointerException);
+  }
+
+  Klass* klass = JVMCIENV->asKlass(jvmci_type);
+  if (klass != NULL && klass->should_be_initialized()) {
+    InstanceKlass* k = InstanceKlass::cast(klass);
+    k->initialize(CHECK);
+  }
+C2V_END
+
+C2V_VMENTRY(int, interpreterFrameSize, (JNIEnv* env, jobject, jobject bytecode_frame_handle))
+  if (bytecode_frame_handle == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+
+  JVMCIObject top_bytecode_frame = JVMCIENV->wrap(bytecode_frame_handle);
+  JVMCIObject bytecode_frame = top_bytecode_frame;
   int size = 0;
   int callee_parameters = 0;
   int callee_locals = 0;
-  Method* method = getMethodFromHotSpotMethod(BytecodePosition::method(bytecode_frame));
-  int extra_args = method->max_stack() - BytecodeFrame::numStack(bytecode_frame);
+  Method* method = JVMCIENV->asMethod(JVMCIENV->get_BytecodePosition_method(bytecode_frame));
+  int extra_args = method->max_stack() - JVMCIENV->get_BytecodeFrame_numStack(bytecode_frame);
 
-  while (bytecode_frame != NULL) {
-    int locks = BytecodeFrame::numLocks(bytecode_frame);
-    int temps = BytecodeFrame::numStack(bytecode_frame);
-    bool is_top_frame = (bytecode_frame == top_bytecode_frame);
-    Method* method = getMethodFromHotSpotMethod(BytecodePosition::method(bytecode_frame));
+  while (bytecode_frame.is_non_null()) {
+    int locks = JVMCIENV->get_BytecodeFrame_numLocks(bytecode_frame);
+    int temps = JVMCIENV->get_BytecodeFrame_numStack(bytecode_frame);
+    bool is_top_frame = (JVMCIENV->equals(bytecode_frame, top_bytecode_frame));
+    Method* method = JVMCIENV->asMethod(JVMCIENV->get_BytecodePosition_method(bytecode_frame));
 
     int frame_size = BytesPerWord * Interpreter::size_activation(method->max_stack(),
                                                                  temps + callee_parameters,
@@ -1492,48 +1628,652 @@
     callee_parameters = method->size_of_parameters();
     callee_locals = method->max_locals();
     extra_args = 0;
-    bytecode_frame = BytecodePosition::caller(bytecode_frame);
+    bytecode_frame = JVMCIENV->get_BytecodePosition_caller(bytecode_frame);
   }
   return size + Deoptimization::last_frame_adjust(0, callee_locals) * BytesPerWord;
 C2V_END
 
-C2V_VMENTRY(void, compileToBytecode, (JNIEnv*, jobject, jobject lambda_form_handle))
-  Handle lambda_form(THREAD, JNIHandles::resolve_non_null(lambda_form_handle));
+C2V_VMENTRY(void, compileToBytecode, (JNIEnv* env, jobject, jobject lambda_form_handle))
+  Handle lambda_form = JVMCIENV->asConstant(JVMCIENV->wrap(lambda_form_handle), JVMCI_CHECK);
   if (lambda_form->is_a(SystemDictionary::LambdaForm_klass())) {
     TempNewSymbol compileToBytecode = SymbolTable::new_symbol("compileToBytecode", CHECK);
     JavaValue result(T_VOID);
     JavaCalls::call_special(&result, lambda_form, SystemDictionary::LambdaForm_klass(), compileToBytecode, vmSymbols::void_method_signature(), CHECK);
   } else {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-                err_msg("Unexpected type: %s", lambda_form->klass()->external_name()));
+    JVMCI_THROW_MSG(IllegalArgumentException,
+                    err_msg("Unexpected type: %s", lambda_form->klass()->external_name()))
   }
 C2V_END
 
+C2V_VMENTRY(int, getIdentityHashCode, (JNIEnv* env, jobject, jobject object))
+  Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
+  return obj->identity_hash();
+C2V_END
+
+C2V_VMENTRY(jboolean, isInternedString, (JNIEnv* env, jobject, jobject object))
+  Handle str = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
+  if (!java_lang_String::is_instance(str())) {
+    return false;
+  }
+  int len;
+  jchar* name = java_lang_String::as_unicode_string(str(), len, CHECK_0);
+  return (StringTable::lookup(name, len) != NULL);
+C2V_END
+
+
+C2V_VMENTRY(jobject, unboxPrimitive, (JNIEnv* env, jobject, jobject object))
+  if (object == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle box = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
+  BasicType type = java_lang_boxing_object::basic_type(box());
+  jvalue result;
+  if (java_lang_boxing_object::get_value(box(), &result) == T_ILLEGAL) {
+    return NULL;
+  }
+  JVMCIObject boxResult = JVMCIENV->create_box(type, &result, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(boxResult);
+C2V_END
+
+C2V_VMENTRY(jobject, boxPrimitive, (JNIEnv* env, jobject, jobject object))
+  if (object == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  JVMCIObject box = JVMCIENV->wrap(object);
+  BasicType type = JVMCIENV->get_box_type(box);
+  if (type == T_ILLEGAL) {
+    return NULL;
+  }
+  jvalue value = JVMCIENV->get_boxed_value(type, box);
+  JavaValue box_result(T_OBJECT);
+  JavaCallArguments jargs;
+  Klass* box_klass = NULL;
+  Symbol* box_signature = NULL;
+#define BOX_CASE(bt, v, argtype, name)           \
+  case bt: \
+    jargs.push_##argtype(value.v); \
+    box_klass = SystemDictionary::name##_klass(); \
+    box_signature = vmSymbols::name##_valueOf_signature(); \
+    break
+
+  switch (type) {
+    BOX_CASE(T_BOOLEAN, z, int, Boolean);
+    BOX_CASE(T_BYTE, b, int, Byte);
+    BOX_CASE(T_CHAR, c, int, Character);
+    BOX_CASE(T_SHORT, s, int, Short);
+    BOX_CASE(T_INT, i, int, Integer);
+    BOX_CASE(T_LONG, j, long, Long);
+    BOX_CASE(T_FLOAT, f, float, Float);
+    BOX_CASE(T_DOUBLE, d, double, Double);
+    default:
+      ShouldNotReachHere();
+  }
+#undef BOX_CASE
+
+  JavaCalls::call_static(&box_result,
+                         box_klass,
+                         vmSymbols::valueOf_name(),
+                         box_signature, &jargs, CHECK_NULL);
+  oop hotspot_box = (oop) box_result.get_jobject();
+  JVMCIObject result = JVMCIENV->get_object_constant(hotspot_box, false);
+  return JVMCIENV->get_jobject(result);
+C2V_END
+
+C2V_VMENTRY(jobjectArray, getDeclaredConstructors, (JNIEnv* env, jobject, jobject holder))
+  if (holder == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Klass* klass = JVMCIENV->asKlass(holder);
+  if (!klass->is_instance_klass()) {
+    JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
+    return JVMCIENV->get_jobjectArray(methods);
+  }
+
+  InstanceKlass* iklass = InstanceKlass::cast(klass);
+  // Ensure class is linked
+  iklass->link_class(CHECK_NULL);
+
+  GrowableArray<Method*> constructors_array;
+  for (int i = 0; i < iklass->methods()->length(); i++) {
+    Method* m = iklass->methods()->at(i);
+    if (m->is_initializer() && !m->is_static()) {
+      constructors_array.append(m);
+    }
+  }
+  JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(constructors_array.length(), JVMCI_CHECK_NULL);
+  for (int i = 0; i < constructors_array.length(); i++) {
+    JVMCIObject method = JVMCIENV->get_jvmci_method(constructors_array.at(i), JVMCI_CHECK_NULL);
+    JVMCIENV->put_object_at(methods, i, method);
+  }
+  return JVMCIENV->get_jobjectArray(methods);
+C2V_END
+
+C2V_VMENTRY(jobjectArray, getDeclaredMethods, (JNIEnv* env, jobject, jobject holder))
+  if (holder == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Klass* klass = JVMCIENV->asKlass(holder);
+  if (!klass->is_instance_klass()) {
+    JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(0, JVMCI_CHECK_NULL);
+    return JVMCIENV->get_jobjectArray(methods);
+  }
+
+  InstanceKlass* iklass = InstanceKlass::cast(klass);
+  // Ensure class is linked
+  iklass->link_class(CHECK_NULL);
+
+  GrowableArray<Method*> methods_array;
+  for (int i = 0; i < iklass->methods()->length(); i++) {
+    Method* m = iklass->methods()->at(i);
+    if (!m->is_initializer() && !m->is_overpass()) {
+      methods_array.append(m);
+    }
+  }
+  JVMCIObjectArray methods = JVMCIENV->new_ResolvedJavaMethod_array(methods_array.length(), JVMCI_CHECK_NULL);
+  for (int i = 0; i < methods_array.length(); i++) {
+    JVMCIObject method = JVMCIENV->get_jvmci_method(methods_array.at(i), JVMCI_CHECK_NULL);
+    JVMCIENV->put_object_at(methods, i, method);
+  }
+  return JVMCIENV->get_jobjectArray(methods);
+C2V_END
+
+C2V_VMENTRY(jobject, readFieldValue, (JNIEnv* env, jobject, jobject object, jobject field, jboolean is_volatile))
+  if (object == NULL || field == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  JVMCIObject field_object = JVMCIENV->wrap(field);
+  JVMCIObject java_type = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_type(field_object);
+  int modifiers = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_modifiers(field_object);
+  Klass* holder = JVMCIENV->asKlass(JVMCIENV->get_HotSpotResolvedJavaFieldImpl_holder(field_object));
+  if (!holder->is_instance_klass()) {
+    JVMCI_THROW_MSG_0(InternalError, err_msg("Holder %s must be instance klass", holder->external_name()));
+  }
+  InstanceKlass* ik = InstanceKlass::cast(holder);
+  BasicType constant_type;
+  if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(java_type)) {
+    constant_type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(java_type), JVMCI_CHECK_NULL);
+  } else {
+    constant_type = T_OBJECT;
+  }
+  int displacement = JVMCIENV->get_HotSpotResolvedJavaFieldImpl_offset(field_object);
+  fieldDescriptor fd;
+  if (!ik->find_local_field_from_offset(displacement, (modifiers & JVM_ACC_STATIC) != 0, &fd)) {
+    JVMCI_THROW_MSG_0(InternalError, err_msg("Can't find field with displacement %d", displacement));
+  }
+  JVMCIObject base = JVMCIENV->wrap(object);
+  Handle obj;
+  if (JVMCIENV->isa_HotSpotObjectConstantImpl(base)) {
+    obj = JVMCIENV->asConstant(base, JVMCI_CHECK_NULL);
+  } else if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base)) {
+    Klass* klass = JVMCIENV->asKlass(base);
+    obj = Handle(THREAD, klass->java_mirror());
+  } else {
+    JVMCI_THROW_MSG_NULL(IllegalArgumentException,
+                         err_msg("Unexpected type: %s", JVMCIENV->klass_name(base)));
+  }
+  jlong value = 0;
+  JVMCIObject kind;
+  switch (constant_type) {
+    case T_OBJECT: {
+      oop object = is_volatile ? obj->obj_field_acquire(displacement) : obj->obj_field(displacement);
+      JVMCIObject result = JVMCIENV->get_object_constant(object);
+      if (result.is_null()) {
+        return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER());
+      }
+      return JVMCIENV->get_jobject(result);
+    }
+    case T_FLOAT: {
+      float f = is_volatile ? obj->float_field_acquire(displacement) : obj->float_field(displacement);
+      JVMCIObject result = JVMCIENV->call_JavaConstant_forFloat(f, JVMCI_CHECK_NULL);
+      return JVMCIENV->get_jobject(result);
+    }
+    case T_DOUBLE: {
+      double f = is_volatile ? obj->double_field_acquire(displacement) : obj->double_field(displacement);
+      JVMCIObject result = JVMCIENV->call_JavaConstant_forDouble(f, JVMCI_CHECK_NULL);
+      return JVMCIENV->get_jobject(result);
+    }
+    case T_BOOLEAN: value = is_volatile ? obj->bool_field_acquire(displacement) : obj->bool_field(displacement); break;
+    case T_BYTE: value = is_volatile ? obj->byte_field_acquire(displacement) : obj->byte_field(displacement); break;
+    case T_SHORT: value = is_volatile ? obj->short_field_acquire(displacement) : obj->short_field(displacement); break;
+    case T_CHAR: value = is_volatile ? obj->char_field_acquire(displacement) : obj->char_field(displacement); break;
+    case T_INT: value = is_volatile ? obj->int_field_acquire(displacement) : obj->int_field(displacement); break;
+    case T_LONG: value = is_volatile ? obj->long_field_acquire(displacement) : obj->long_field(displacement); break;
+    default:
+      ShouldNotReachHere();
+  }
+  JVMCIObject result = JVMCIENV->call_PrimitiveConstant_forTypeChar(type2char(constant_type), value, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
+C2V_END
+
+C2V_VMENTRY(jboolean, isInstance, (JNIEnv* env, jobject, jobject holder, jobject object))
+  if (object == NULL || holder == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_0);
+  Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));
+  return obj->is_a(klass);
+C2V_END
+
+C2V_VMENTRY(jboolean, isAssignableFrom, (JNIEnv* env, jobject, jobject holder, jobject otherHolder))
+  if (holder == NULL || otherHolder == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Klass* klass = JVMCIENV->asKlass(JVMCIENV->wrap(holder));
+  Klass* otherKlass = JVMCIENV->asKlass(JVMCIENV->wrap(otherHolder));
+  return otherKlass->is_subtype_of(klass);
+C2V_END
+
+C2V_VMENTRY(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, jobject holder))
+  if (holder == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  InstanceKlass* ik = InstanceKlass::cast(JVMCIENV->asKlass(JVMCIENV->wrap(holder)));
+  if (ik->class_loader_data()->is_builtin_class_loader_data()) {
+    return true;
+  }
+  return false;
+C2V_END
+
+C2V_VMENTRY(jobject, asJavaType, (JNIEnv* env, jobject, jobject object))
+  if (object == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
+  if (java_lang_Class::is_instance(obj())) {
+    if (java_lang_Class::is_primitive(obj())) {
+      JVMCIObject type = JVMCIENV->get_jvmci_primitive_type(java_lang_Class::primitive_type(obj()));
+      return JVMCIENV->get_jobject(type);
+    }
+    Klass* klass = java_lang_Class::as_Klass(obj());
+    JVMCIKlassHandle klass_handle(THREAD);
+    klass_handle = klass;
+    JVMCIObject type = JVMCIENV->get_jvmci_type(klass_handle, JVMCI_CHECK_NULL);
+    return JVMCIENV->get_jobject(type);
+  }
+  return NULL;
+C2V_END
+
+
+C2V_VMENTRY(jobject, asString, (JNIEnv* env, jobject, jobject object))
+  if (object == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle obj = JVMCIENV->asConstant(JVMCIENV->wrap(object), JVMCI_CHECK_NULL);
+  const char* str = java_lang_String::as_utf8_string(obj());
+  JVMCIObject result = JVMCIENV->create_string(str, JVMCI_CHECK_NULL);
+  return JVMCIENV->get_jobject(result);
+C2V_END
+
+
+C2V_VMENTRY(jboolean, equals, (JNIEnv* env, jobject, jobject x, jlong xHandle, jobject y, jlong yHandle))
+  if (x == NULL || y == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  return JVMCIENV->resolve_handle(xHandle) == JVMCIENV->resolve_handle(yHandle);
+C2V_END
+
+C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv* env, jobject, jobject object))
+  if (object == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  JVMCIObject base_object = JVMCIENV->wrap(object);
+  Handle mirror;
+  if (JVMCIENV->isa_HotSpotResolvedObjectTypeImpl(base_object)) {
+    mirror = Handle(THREAD, JVMCIENV->asKlass(base_object)->java_mirror());
+  } else if (JVMCIENV->isa_HotSpotResolvedPrimitiveType(base_object)) {
+    mirror = JVMCIENV->asConstant(JVMCIENV->get_HotSpotResolvedPrimitiveType_mirror(base_object), JVMCI_CHECK_NULL);
+  } else {
+    JVMCI_THROW_MSG_NULL(IllegalArgumentException,
+                         err_msg("Unexpected type: %s", JVMCIENV->klass_name(base_object)));
+ }
+  JVMCIObject result = JVMCIENV->get_object_constant(mirror());
+  return JVMCIENV->get_jobject(result);
+C2V_END
+
+
+C2V_VMENTRY(jint, getArrayLength, (JNIEnv* env, jobject, jobject x))
+  if (x == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
+  if (xobj->klass()->is_array_klass()) {
+    return arrayOop(xobj())->length();
+  }
+  return -1;
+ C2V_END
+
+
+C2V_VMENTRY(jobject, readArrayElement, (JNIEnv* env, jobject, jobject x, int index))
+  if (x == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_NULL);
+  if (xobj->klass()->is_array_klass()) {
+    arrayOop array = arrayOop(xobj());
+    BasicType element_type = ArrayKlass::cast(array->klass())->element_type();
+    if (index < 0 || index >= array->length()) {
+      return NULL;
+    }
+    JVMCIObject result;
+
+    if (element_type == T_OBJECT) {
+      result = JVMCIENV->get_object_constant(objArrayOop(xobj())->obj_at(index));
+      if (result.is_null()) {
+        result = JVMCIENV->get_JavaConstant_NULL_POINTER();
+      }
+    } else {
+      jvalue value;
+      switch (element_type) {
+        case T_DOUBLE:        value.d = typeArrayOop(xobj())->double_at(index);        break;
+        case T_FLOAT:         value.f = typeArrayOop(xobj())->float_at(index);         break;
+        case T_LONG:          value.j = typeArrayOop(xobj())->long_at(index);          break;
+        case T_INT:           value.i = typeArrayOop(xobj())->int_at(index);            break;
+        case T_SHORT:         value.s = typeArrayOop(xobj())->short_at(index);          break;
+        case T_CHAR:          value.c = typeArrayOop(xobj())->char_at(index);           break;
+        case T_BYTE:          value.b = typeArrayOop(xobj())->byte_at(index);           break;
+        case T_BOOLEAN:       value.z = typeArrayOop(xobj())->byte_at(index) & 1;       break;
+        default:              ShouldNotReachHere();
+      }
+      result = JVMCIENV->create_box(element_type, &value, JVMCI_CHECK_NULL);
+    }
+    assert(!result.is_null(), "must have a value");
+    return JVMCIENV->get_jobject(result);
+  }
+  return NULL;;
+C2V_END
+
+
+C2V_VMENTRY(jint, arrayBaseOffset, (JNIEnv* env, jobject, jobject kind))
+  if (kind == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);
+  return arrayOopDesc::header_size(type) * HeapWordSize;
+C2V_END
+
+C2V_VMENTRY(jint, arrayIndexScale, (JNIEnv* env, jobject, jobject kind))
+  if (kind == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->wrap(kind), JVMCI_CHECK_0);
+  return type2aelembytes(type);
+C2V_END
+
+C2V_VMENTRY(jbyte, getByte, (JNIEnv* env, jobject, jobject x, long displacement))
+  if (x == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
+  return xobj->byte_field(displacement);
+}
+
+C2V_VMENTRY(jshort, getShort, (JNIEnv* env, jobject, jobject x, long displacement))
+  if (x == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
+  return xobj->short_field(displacement);
+}
+
+C2V_VMENTRY(jint, getInt, (JNIEnv* env, jobject, jobject x, long displacement))
+  if (x == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
+  return xobj->int_field(displacement);
+}
+
+C2V_VMENTRY(jlong, getLong, (JNIEnv* env, jobject, jobject x, long displacement))
+  if (x == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
+  return xobj->long_field(displacement);
+}
+
+C2V_VMENTRY(jobject, getObject, (JNIEnv* env, jobject, jobject x, long displacement))
+  if (x == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Handle xobj = JVMCIENV->asConstant(JVMCIENV->wrap(x), JVMCI_CHECK_0);
+  oop res = xobj->obj_field(displacement);
+  JVMCIObject result = JVMCIENV->get_object_constant(res);
+  return JVMCIENV->get_jobject(result);
+}
+
+C2V_VMENTRY(void, deleteGlobalHandle, (JNIEnv* env, jobject, jlong h))
+  jobject handle = (jobject)(address)h;
+  if (handle != NULL) {
+    assert(JVMCI::is_global_handle(handle), "Invalid delete of global JNI handle");
+    *((oop*)handle) = NULL; // Mark the handle as deleted, allocate will reuse it
+  }
+}
+
+C2V_VMENTRY(jlongArray, registerNativeMethods, (JNIEnv* env, jobject, jclass mirror))
+  if (!UseJVMCINativeLibrary) {
+    JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "JVMCI shared library is not enabled (requires -XX:+UseJVMCINativeLibrary)");
+  }
+  if (!JVMCIENV->is_hotspot()) {
+    JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "Cannot call registerNativeMethods from JVMCI shared library");
+  }
+  void* shared_library = JVMCIEnv::get_shared_library_handle();
+  if (shared_library == NULL) {
+    // Ensure the JVMCI shared library runtime is initialized.
+    JVMCIEnv __peer_jvmci_env__(false, __FILE__, __LINE__);
+    JVMCIEnv* peerEnv = &__peer_jvmci_env__;
+    HandleMark hm;
+    JVMCIRuntime* runtime = JVMCI::compiler_runtime();
+    JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(peerEnv);
+    if (peerEnv->has_pending_exception()) {
+      peerEnv->describe_pending_exception(true);
+      JVMCI_THROW_MSG_0(InternalError, "Error initializing JVMCI runtime");
+    }
+    shared_library = JVMCIEnv::get_shared_library_handle();
+  }
+
+  if (shared_library == NULL) {
+    JVMCI_THROW_MSG_0(UnsatisfiedLinkError, "JVMCI shared library is unavailable");
+  }
+
+  if (mirror == NULL) {
+    JVMCI_THROW_0(NullPointerException);
+  }
+  Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));
+  if (klass == NULL || !klass->is_instance_klass()) {
+    JVMCI_THROW_MSG_0(IllegalArgumentException, "clazz is for primitive type");
+  }
+
+  InstanceKlass* iklass = InstanceKlass::cast(klass);
+  for (int i = 0; i < iklass->methods()->length(); i++) {
+    Method* method = iklass->methods()->at(i);
+    if (method->is_native()) {
+
+      // Compute argument size
+      int args_size = 1                             // JNIEnv
+                    + (method->is_static() ? 1 : 0) // class for static methods
+                    + method->size_of_parameters(); // actual parameters
+
+      // 1) Try JNI short style
+      stringStream st;
+      char* pure_name = NativeLookup::pure_jni_name(method);
+      os::print_jni_name_prefix_on(&st, args_size);
+      st.print_raw(pure_name);
+      os::print_jni_name_suffix_on(&st, args_size);
+      char* jni_name = st.as_string();
+
+      address entry = (address) os::dll_lookup(shared_library, jni_name);
+      if (entry == NULL) {
+        // 2) Try JNI long style
+        st.reset();
+        char* long_name = NativeLookup::long_jni_name(method);
+        os::print_jni_name_prefix_on(&st, args_size);
+        st.print_raw(pure_name);
+        st.print_raw(long_name);
+        os::print_jni_name_suffix_on(&st, args_size);
+        jni_name = st.as_string();
+        entry = (address) os::dll_lookup(shared_library, jni_name);
+      }
+      if (entry == NULL) {
+        JVMCI_THROW_MSG_0(UnsatisfiedLinkError, method->name_and_sig_as_C_string());
+      }
+      if (method->has_native_function() && entry != method->native_function()) {
+        JVMCI_THROW_MSG_0(UnsatisfiedLinkError, err_msg("Cannot overwrite existing native implementation for %s",
+            method->name_and_sig_as_C_string()));
+      }
+      method->set_native_function(entry, Method::native_bind_event_is_interesting);
+      if (PrintJNIResolving) {
+        tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
+          method->method_holder()->external_name(),
+          method->name()->as_C_string());
+      }
+    }
+  }
+
+  JavaVM* javaVM = JVMCIEnv::get_shared_library_javavm();
+  JVMCIPrimitiveArray result = JVMCIENV->new_longArray(4, JVMCI_CHECK_NULL);
+  JVMCIENV->put_long_at(result, 0, (jlong) (address) javaVM);
+  JVMCIENV->put_long_at(result, 1, (jlong) (address) javaVM->functions->reserved0);
+  JVMCIENV->put_long_at(result, 2, (jlong) (address) javaVM->functions->reserved1);
+  JVMCIENV->put_long_at(result, 3, (jlong) (address) javaVM->functions->reserved2);
+  return (jlongArray) JVMCIENV->get_jobject(result);
+}
+
+C2V_VMENTRY(jlong, translate, (JNIEnv* env, jobject, jobject obj_handle))
+  if (obj_handle == NULL) {
+    return 0L;
+  }
+  JVMCIEnv __peer_jvmci_env__(!JVMCIENV->is_hotspot(), __FILE__, __LINE__);
+  JVMCIEnv* peerEnv = &__peer_jvmci_env__;
+  JVMCIEnv* thisEnv = JVMCIENV;
+
+  JVMCIObject obj = thisEnv->wrap(obj_handle);
+  JVMCIObject result;
+  if (thisEnv->isa_HotSpotResolvedJavaMethodImpl(obj)) {
+    Method* method = thisEnv->asMethod(obj);
+    result = peerEnv->get_jvmci_method(method, JVMCI_CHECK_0);
+  } else if (thisEnv->isa_HotSpotResolvedObjectTypeImpl(obj)) {
+    Klass* klass = thisEnv->asKlass(obj);
+    JVMCIKlassHandle klass_handle(THREAD);
+    klass_handle = klass;
+    result = peerEnv->get_jvmci_type(klass_handle, JVMCI_CHECK_0);
+  } else if (thisEnv->isa_HotSpotResolvedPrimitiveType(obj)) {
+    BasicType type = JVMCIENV->kindToBasicType(JVMCIENV->get_HotSpotResolvedPrimitiveType_kind(obj), JVMCI_CHECK_0);
+    result = peerEnv->get_jvmci_primitive_type(type);
+  } else if (thisEnv->isa_IndirectHotSpotObjectConstantImpl(obj) ||
+             thisEnv->isa_DirectHotSpotObjectConstantImpl(obj)) {
+    Handle constant = thisEnv->asConstant(obj, JVMCI_CHECK_0);
+    result = peerEnv->get_object_constant(constant());
+  } else if (thisEnv->isa_HotSpotNmethod(obj)) {
+    nmethod* nm = thisEnv->asNmethod(obj);
+    if (nm != NULL) {
+      JVMCINMethodData* data = nm->jvmci_nmethod_data();
+      if (data != NULL) {
+        if (peerEnv->is_hotspot()) {
+          // Only the mirror in the HotSpot heap is accessible
+          // through JVMCINMethodData
+          oop nmethod_mirror = data->get_nmethod_mirror(nm);
+          if (nmethod_mirror != NULL) {
+            result = HotSpotJVMCI::wrap(nmethod_mirror);
+          }
+        }
+      }
+    }
+    if (result.is_null()) {
+      JVMCIObject methodObject = thisEnv->get_HotSpotNmethod_method(obj);
+      methodHandle mh = thisEnv->asMethod(methodObject);
+      jboolean isDefault = thisEnv->get_HotSpotNmethod_isDefault(obj);
+      jlong compileIdSnapshot = thisEnv->get_HotSpotNmethod_compileIdSnapshot(obj);
+      JVMCIObject name_string = thisEnv->get_InstalledCode_name(obj);
+      const char* cstring = name_string.is_null() ? NULL : thisEnv->as_utf8_string(name_string);
+      // Create a new HotSpotNmethod instance in the peer runtime
+      result = peerEnv->new_HotSpotNmethod(mh(), cstring, isDefault, compileIdSnapshot, JVMCI_CHECK_0);
+      if (nm == NULL) {
+        // nmethod must have been unloaded
+      } else {
+        // Link the new HotSpotNmethod to the nmethod
+        peerEnv->initialize_installed_code(result, nm, JVMCI_CHECK_0);
+        // Only HotSpotNmethod instances in the HotSpot heap are tracked directly by the runtime.
+        if (peerEnv->is_hotspot()) {
+          JVMCINMethodData* data = nm->jvmci_nmethod_data();
+          if (data == NULL) {
+            JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot set HotSpotNmethod mirror for default nmethod");
+          }
+          if (data->get_nmethod_mirror(nm) != NULL) {
+            JVMCI_THROW_MSG_0(IllegalArgumentException, "Cannot overwrite existing HotSpotNmethod mirror for nmethod");
+          }
+          oop nmethod_mirror = HotSpotJVMCI::resolve(result);
+          data->set_nmethod_mirror(nm, nmethod_mirror);
+        }
+      }
+    }
+  } else {
+    JVMCI_THROW_MSG_0(IllegalArgumentException,
+                err_msg("Cannot translate object of type: %s", thisEnv->klass_name(obj)));
+  }
+  return (jlong) peerEnv->make_global(result).as_jobject();
+}
+
+C2V_VMENTRY(jobject, unhand, (JNIEnv* env, jobject, jlong obj_handle))
+  if (obj_handle == 0L) {
+    return NULL;
+  }
+  jobject global_handle = (jobject) obj_handle;
+  JVMCIObject global_handle_obj = JVMCIENV->wrap((jobject) obj_handle);
+  jobject result = JVMCIENV->make_local(global_handle_obj).as_jobject();
+
+  JVMCIENV->destroy_global(global_handle_obj);
+  return result;
+}
+
+C2V_VMENTRY(void, updateHotSpotNmethod, (JNIEnv* env, jobject, jobject code_handle))
+  JVMCIObject code = JVMCIENV->wrap(code_handle);
+  // Execute this operation for the side effect of updating the InstalledCode state
+  JVMCIENV->asNmethod(code);
+}
+
+C2V_VMENTRY(jbyteArray, getCode, (JNIEnv* env, jobject, jobject code_handle))
+  JVMCIObject code = JVMCIENV->wrap(code_handle);
+  CodeBlob* cb = JVMCIENV->asCodeBlob(code);
+  if (cb == NULL) {
+    return NULL;
+  }
+  int code_size = cb->code_size();
+  JVMCIPrimitiveArray result = JVMCIENV->new_byteArray(code_size, JVMCI_CHECK_NULL);
+  JVMCIENV->copy_bytes_from((jbyte*) cb->code_begin(), result, 0, code_size);
+  return JVMCIENV->get_jbyteArray(result);
+}
+
 C2V_VMENTRY(jobject, asReflectionExecutable, (JNIEnv* env, jobject, jobject jvmci_method))
-  methodHandle m = CompilerToVM::asMethod(jvmci_method);
+  if (env != JavaThread::current()->jni_environment()) {
+    JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
+  }
+  methodHandle m = JVMCIENV->asMethod(jvmci_method);
   oop executable;
   if (m->is_initializer()) {
     if (m->is_static_initializer()) {
-      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
-        "Cannot create java.lang.reflect.Method for class initializer");
+      JVMCI_THROW_MSG_NULL(IllegalArgumentException,
+          "Cannot create java.lang.reflect.Method for class initializer");
     }
     executable = Reflection::new_constructor(m, CHECK_NULL);
   } else {
     executable = Reflection::new_method(m, false, CHECK_NULL);
   }
-  return JNIHandles::make_local(thread, executable);
+  return JNIHandles::make_local(THREAD, executable);
 }
 
 C2V_VMENTRY(jobject, asReflectionField, (JNIEnv* env, jobject, jobject jvmci_type, jint index))
-  Klass* klass = CompilerToVM::asKlass(jvmci_type);
+  if (env != JavaThread::current()->jni_environment()) {
+    JVMCI_THROW_MSG_NULL(InternalError, "Only supported when running in HotSpot");
+  }
+  Klass* klass = JVMCIENV->asKlass(jvmci_type);
   if (!klass->is_instance_klass()) {
-    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+    JVMCI_THROW_MSG_NULL(IllegalArgumentException,
         err_msg("Expected non-primitive type, got %s", klass->external_name()));
   }
   InstanceKlass* iklass = InstanceKlass::cast(klass);
   Array<u2>* fields = iklass->fields();
-  if (index < 0 || index > fields->length()) {
-    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+  if (index < 0 ||index > fields->length()) {
+    JVMCI_THROW_MSG_NULL(IllegalArgumentException,
         err_msg("Field index %d out of bounds for %s", index, klass->external_name()));
   }
   fieldDescriptor fd(iklass, index);
@@ -1541,27 +2281,90 @@
   return JNIHandles::make_local(env, reflected);
 }
 
+C2V_VMENTRY(jobjectArray, getFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address, jobjectArray current))
+  FailedSpeculation* head = *((FailedSpeculation**)(address) failed_speculations_address);
+  int result_length = 0;
+  for (FailedSpeculation* fs = head; fs != NULL; fs = fs->next()) {
+    result_length++;
+  }
+  int current_length = 0;
+  JVMCIObjectArray current_array = NULL;
+  if (current != NULL) {
+    current_array = JVMCIENV->wrap(current);
+    current_length = JVMCIENV->get_length(current_array);
+    if (current_length == result_length) {
+      // No new failures
+      return current;
+    }
+  }
+  JVMCIObjectArray result = JVMCIENV->new_byte_array_array(result_length, JVMCI_CHECK_NULL);
+  int result_index = 0;
+  for (FailedSpeculation* fs = head; result_index < result_length; fs = fs->next()) {
+    assert(fs != NULL, "npe");
+    JVMCIPrimitiveArray entry;
+    if (result_index < current_length) {
+      entry = (JVMCIPrimitiveArray) JVMCIENV->get_object_at(current_array, result_index);
+    } else {
+      entry = JVMCIENV->new_byteArray(fs->data_len(), JVMCI_CHECK_NULL);
+      JVMCIENV->copy_bytes_from((jbyte*) fs->data(), entry, 0, fs->data_len());
+    }
+    JVMCIENV->put_object_at(result, result_index++, entry);
+  }
+  return JVMCIENV->get_jobjectArray(result);
+}
+
+C2V_VMENTRY(jlong, getFailedSpeculationsAddress, (JNIEnv* env, jobject, jobject jvmci_method))
+  methodHandle method = JVMCIENV->asMethod(jvmci_method);
+  MethodData* method_data = method->method_data();
+  if (method_data == NULL) {
+    ClassLoaderData* loader_data = method->method_holder()->class_loader_data();
+    method_data = MethodData::allocate(loader_data, method, CHECK_0);
+    method->set_method_data(method_data);
+  }
+  return (jlong) method_data->get_failed_speculations_address();
+}
+
+C2V_VMENTRY(void, releaseFailedSpeculations, (JNIEnv* env, jobject, jlong failed_speculations_address))
+  FailedSpeculation::free_failed_speculations((FailedSpeculation**)(address) failed_speculations_address);
+}
+
+C2V_VMENTRY(bool, addFailedSpeculation, (JNIEnv* env, jobject, jlong failed_speculations_address, jbyteArray speculation_obj))
+  JVMCIPrimitiveArray speculation_handle = JVMCIENV->wrap(speculation_obj);
+  int speculation_len = JVMCIENV->get_length(speculation_handle);
+  char* speculation = NEW_RESOURCE_ARRAY(char, speculation_len);
+  JVMCIENV->copy_bytes_to(speculation_handle, (jbyte*) speculation, 0, speculation_len);
+  return FailedSpeculation::add_failed_speculation(NULL, (FailedSpeculation**)(address) failed_speculations_address, (address) speculation, speculation_len);
+}
+
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
 #define STRING                  "Ljava/lang/String;"
 #define OBJECT                  "Ljava/lang/Object;"
 #define CLASS                   "Ljava/lang/Class;"
+#define OBJECTCONSTANT          "Ljdk/vm/ci/hotspot/HotSpotObjectConstantImpl;"
+#define HANDLECONSTANT          "Ljdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl;"
 #define EXECUTABLE              "Ljava/lang/reflect/Executable;"
 #define STACK_TRACE_ELEMENT     "Ljava/lang/StackTraceElement;"
 #define INSTALLED_CODE          "Ljdk/vm/ci/code/InstalledCode;"
 #define TARGET_DESCRIPTION      "Ljdk/vm/ci/code/TargetDescription;"
 #define BYTECODE_FRAME          "Ljdk/vm/ci/code/BytecodeFrame;"
+#define JAVACONSTANT            "Ljdk/vm/ci/meta/JavaConstant;"
 #define INSPECTED_FRAME_VISITOR "Ljdk/vm/ci/code/stack/InspectedFrameVisitor;"
 #define RESOLVED_METHOD         "Ljdk/vm/ci/meta/ResolvedJavaMethod;"
 #define HS_RESOLVED_METHOD      "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;"
 #define HS_RESOLVED_KLASS       "Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;"
+#define HS_RESOLVED_TYPE        "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaType;"
+#define HS_RESOLVED_FIELD       "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaField;"
+#define HS_INSTALLED_CODE       "Ljdk/vm/ci/hotspot/HotSpotInstalledCode;"
+#define HS_NMETHOD              "Ljdk/vm/ci/hotspot/HotSpotNmethod;"
 #define HS_CONSTANT_POOL        "Ljdk/vm/ci/hotspot/HotSpotConstantPool;"
 #define HS_COMPILED_CODE        "Ljdk/vm/ci/hotspot/HotSpotCompiledCode;"
 #define HS_CONFIG               "Ljdk/vm/ci/hotspot/HotSpotVMConfig;"
 #define HS_METADATA             "Ljdk/vm/ci/hotspot/HotSpotMetaData;"
 #define HS_STACK_FRAME_REF      "Ljdk/vm/ci/hotspot/HotSpotStackFrameReference;"
 #define HS_SPECULATION_LOG      "Ljdk/vm/ci/hotspot/HotSpotSpeculationLog;"
+#define METASPACE_OBJECT        "Ljdk/vm/ci/hotspot/MetaspaceObject;"
 #define REFLECTION_EXECUTABLE   "Ljava/lang/reflect/Executable;"
 #define REFLECTION_FIELD        "Ljava/lang/reflect/Field;"
 #define METASPACE_METHOD_DATA   "J"
@@ -1578,17 +2381,18 @@
   {CC "isCompilable",                                 CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(isCompilable)},
   {CC "hasNeverInlineDirective",                      CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(hasNeverInlineDirective)},
   {CC "shouldInlineMethod",                           CC "(" HS_RESOLVED_METHOD ")Z",                                                       FN_PTR(shouldInlineMethod)},
-  {CC "lookupType",                                   CC "(" STRING CLASS "Z)" HS_RESOLVED_KLASS,                                           FN_PTR(lookupType)},
+  {CC "lookupType",                                   CC "(" STRING HS_RESOLVED_KLASS "Z)" HS_RESOLVED_TYPE,                                FN_PTR(lookupType)},
+  {CC "lookupClass",                                  CC "(" CLASS ")" HS_RESOLVED_TYPE,                                                    FN_PTR(lookupClass)},
   {CC "lookupNameInPool",                             CC "(" HS_CONSTANT_POOL "I)" STRING,                                                  FN_PTR(lookupNameInPool)},
   {CC "lookupNameAndTypeRefIndexInPool",              CC "(" HS_CONSTANT_POOL "I)I",                                                        FN_PTR(lookupNameAndTypeRefIndexInPool)},
   {CC "lookupSignatureInPool",                        CC "(" HS_CONSTANT_POOL "I)" STRING,                                                  FN_PTR(lookupSignatureInPool)},
   {CC "lookupKlassRefIndexInPool",                    CC "(" HS_CONSTANT_POOL "I)I",                                                        FN_PTR(lookupKlassRefIndexInPool)},
   {CC "lookupKlassInPool",                            CC "(" HS_CONSTANT_POOL "I)Ljava/lang/Object;",                                       FN_PTR(lookupKlassInPool)},
-  {CC "lookupAppendixInPool",                         CC "(" HS_CONSTANT_POOL "I)" OBJECT,                                                  FN_PTR(lookupAppendixInPool)},
+  {CC "lookupAppendixInPool",                         CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT,                                          FN_PTR(lookupAppendixInPool)},
   {CC "lookupMethodInPool",                           CC "(" HS_CONSTANT_POOL "IB)" HS_RESOLVED_METHOD,                                     FN_PTR(lookupMethodInPool)},
   {CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL "I)I",                                                        FN_PTR(constantPoolRemapInstructionOperandFromCache)},
-  {CC "resolveConstantInPool",                        CC "(" HS_CONSTANT_POOL "I)" OBJECT,                                                  FN_PTR(resolveConstantInPool)},
-  {CC "resolvePossiblyCachedConstantInPool",          CC "(" HS_CONSTANT_POOL "I)" OBJECT,                                                  FN_PTR(resolvePossiblyCachedConstantInPool)},
+  {CC "resolveConstantInPool",                        CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT,                                          FN_PTR(resolveConstantInPool)},
+  {CC "resolvePossiblyCachedConstantInPool",          CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT,                                          FN_PTR(resolvePossiblyCachedConstantInPool)},
   {CC "resolveTypeInPool",                            CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS,                                       FN_PTR(resolveTypeInPool)},
   {CC "resolveFieldInPool",                           CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[I)" HS_RESOLVED_KLASS,              FN_PTR(resolveFieldInPool)},
   {CC "resolveInvokeDynamicInPool",                   CC "(" HS_CONSTANT_POOL "I)V",                                                        FN_PTR(resolveInvokeDynamicInPool)},
@@ -1601,20 +2405,21 @@
   {CC "hasFinalizableSubclass",                       CC "(" HS_RESOLVED_KLASS ")Z",                                                        FN_PTR(hasFinalizableSubclass)},
   {CC "getMaxCallTargetOffset",                       CC "(J)J",                                                                            FN_PTR(getMaxCallTargetOffset)},
   {CC "asResolvedJavaMethod",                         CC "(" EXECUTABLE ")" HS_RESOLVED_METHOD,                                             FN_PTR(asResolvedJavaMethod)},
-  {CC "getResolvedJavaMethod",                        CC "(Ljava/lang/Object;J)" HS_RESOLVED_METHOD,                                        FN_PTR(getResolvedJavaMethod)},
-  {CC "getConstantPool",                              CC "(Ljava/lang/Object;)" HS_CONSTANT_POOL,                                           FN_PTR(getConstantPool)},
-  {CC "getResolvedJavaType",                          CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS,                                        FN_PTR(getResolvedJavaType)},
+  {CC "getResolvedJavaMethod",                        CC "(" OBJECTCONSTANT "J)" HS_RESOLVED_METHOD,                                        FN_PTR(getResolvedJavaMethod)},
+  {CC "getConstantPool",                              CC "(" METASPACE_OBJECT ")" HS_CONSTANT_POOL,                                         FN_PTR(getConstantPool)},
+  {CC "getResolvedJavaType0",                         CC "(Ljava/lang/Object;JZ)" HS_RESOLVED_KLASS,                                        FN_PTR(getResolvedJavaType0)},
   {CC "readConfiguration",                            CC "()[" OBJECT,                                                                      FN_PTR(readConfiguration)},
-  {CC "installCode",                                  CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG ")I",    FN_PTR(installCode)},
+  {CC "installCode",                                  CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE "J[B)I",                    FN_PTR(installCode)},
   {CC "getMetadata",                                  CC "(" TARGET_DESCRIPTION HS_COMPILED_CODE HS_METADATA ")I",                          FN_PTR(getMetadata)},
   {CC "resetCompilationStatistics",                   CC "()V",                                                                             FN_PTR(resetCompilationStatistics)},
   {CC "disassembleCodeBlob",                          CC "(" INSTALLED_CODE ")" STRING,                                                     FN_PTR(disassembleCodeBlob)},
-  {CC "executeInstalledCode",                         CC "([" OBJECT INSTALLED_CODE ")" OBJECT,                                             FN_PTR(executeInstalledCode)},
+  {CC "executeHotSpotNmethod",                        CC "([" OBJECT HS_NMETHOD ")" OBJECT,                                                 FN_PTR(executeHotSpotNmethod)},
   {CC "getLineNumberTable",                           CC "(" HS_RESOLVED_METHOD ")[J",                                                      FN_PTR(getLineNumberTable)},
   {CC "getLocalVariableTableStart",                   CC "(" HS_RESOLVED_METHOD ")J",                                                       FN_PTR(getLocalVariableTableStart)},
   {CC "getLocalVariableTableLength",                  CC "(" HS_RESOLVED_METHOD ")I",                                                       FN_PTR(getLocalVariableTableLength)},
   {CC "reprofile",                                    CC "(" HS_RESOLVED_METHOD ")V",                                                       FN_PTR(reprofile)},
-  {CC "invalidateInstalledCode",                      CC "(" INSTALLED_CODE ")V",                                                           FN_PTR(invalidateInstalledCode)},
+  {CC "invalidateHotSpotNmethod",                     CC "(" HS_NMETHOD ")V",                                                               FN_PTR(invalidateHotSpotNmethod)},
+  {CC "readUncompressedOop",                          CC "(J)" OBJECTCONSTANT,                                                              FN_PTR(readUncompressedOop)},
   {CC "collectCounters",                              CC "()[J",                                                                            FN_PTR(collectCounters)},
   {CC "allocateCompileId",                            CC "(" HS_RESOLVED_METHOD "I)I",                                                      FN_PTR(allocateCompileId)},
   {CC "isMature",                                     CC "(" METASPACE_METHOD_DATA ")Z",                                                    FN_PTR(isMature)},
@@ -1629,10 +2434,48 @@
   {CC "getFingerprint",                               CC "(J)J",                                                                            FN_PTR(getFingerprint)},
   {CC "getHostClass",                                 CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_KLASS,                                       FN_PTR(getHostClass)},
   {CC "interpreterFrameSize",                         CC "(" BYTECODE_FRAME ")I",                                                           FN_PTR(interpreterFrameSize)},
-  {CC "compileToBytecode",                            CC "(" OBJECT ")V",                                                                   FN_PTR(compileToBytecode)},
+  {CC "compileToBytecode",                            CC "(" OBJECTCONSTANT ")V",                                                           FN_PTR(compileToBytecode)},
   {CC "getFlagValue",                                 CC "(" STRING ")" OBJECT,                                                             FN_PTR(getFlagValue)},
+  {CC "getObjectAtAddress",                           CC "(J)" OBJECT,                                                                      FN_PTR(getObjectAtAddress)},
+  {CC "getInterfaces",                                CC "(" HS_RESOLVED_KLASS ")[" HS_RESOLVED_KLASS,                                      FN_PTR(getInterfaces)},
+  {CC "getComponentType",                             CC "(" HS_RESOLVED_KLASS ")" HS_RESOLVED_TYPE,                                        FN_PTR(getComponentType)},
+  {CC "ensureInitialized",                            CC "(" HS_RESOLVED_KLASS ")V",                                                        FN_PTR(ensureInitialized)},
+  {CC "getIdentityHashCode",                          CC "(" OBJECTCONSTANT ")I",                                                           FN_PTR(getIdentityHashCode)},
+  {CC "isInternedString",                             CC "(" OBJECTCONSTANT ")Z",                                                           FN_PTR(isInternedString)},
+  {CC "unboxPrimitive",                               CC "(" OBJECTCONSTANT ")" OBJECT,                                                     FN_PTR(unboxPrimitive)},
+  {CC "boxPrimitive",                                 CC "(" OBJECT ")" OBJECTCONSTANT,                                                     FN_PTR(boxPrimitive)},
+  {CC "getDeclaredConstructors",                      CC "(" HS_RESOLVED_KLASS ")[" RESOLVED_METHOD,                                        FN_PTR(getDeclaredConstructors)},
+  {CC "getDeclaredMethods",                           CC "(" HS_RESOLVED_KLASS ")[" RESOLVED_METHOD,                                        FN_PTR(getDeclaredMethods)},
+  {CC "readFieldValue",                               CC "(" HS_RESOLVED_KLASS HS_RESOLVED_FIELD "Z)" JAVACONSTANT,                         FN_PTR(readFieldValue)},
+  {CC "readFieldValue",                               CC "(" OBJECTCONSTANT HS_RESOLVED_FIELD "Z)" JAVACONSTANT,                            FN_PTR(readFieldValue)},
+  {CC "isInstance",                                   CC "(" HS_RESOLVED_KLASS OBJECTCONSTANT ")Z",                                         FN_PTR(isInstance)},
+  {CC "isAssignableFrom",                             CC "(" HS_RESOLVED_KLASS HS_RESOLVED_KLASS ")Z",                                      FN_PTR(isAssignableFrom)},
+  {CC "isTrustedForIntrinsics",                       CC "(" HS_RESOLVED_KLASS ")Z",                                                        FN_PTR(isTrustedForIntrinsics)},
+  {CC "asJavaType",                                   CC "(" OBJECTCONSTANT ")" HS_RESOLVED_TYPE,                                           FN_PTR(asJavaType)},
+  {CC "asString",                                     CC "(" OBJECTCONSTANT ")" STRING,                                                     FN_PTR(asString)},
+  {CC "equals",                                       CC "(" OBJECTCONSTANT "J" OBJECTCONSTANT "J)Z",                                       FN_PTR(equals)},
+  {CC "getJavaMirror",                                CC "(" HS_RESOLVED_TYPE ")" OBJECTCONSTANT,                                           FN_PTR(getJavaMirror)},
+  {CC "getArrayLength",                               CC "(" OBJECTCONSTANT ")I",                                                           FN_PTR(getArrayLength)},
+  {CC "readArrayElement",                             CC "(" OBJECTCONSTANT "I)Ljava/lang/Object;",                                         FN_PTR(readArrayElement)},
+  {CC "arrayBaseOffset",                              CC "(Ljdk/vm/ci/meta/JavaKind;)I",                                                    FN_PTR(arrayBaseOffset)},
+  {CC "arrayIndexScale",                              CC "(Ljdk/vm/ci/meta/JavaKind;)I",                                                    FN_PTR(arrayIndexScale)},
+  {CC "getByte",                                      CC "(" OBJECTCONSTANT "J)B",                                                          FN_PTR(getByte)},
+  {CC "getShort",                                     CC "(" OBJECTCONSTANT "J)S",                                                          FN_PTR(getShort)},
+  {CC "getInt",                                       CC "(" OBJECTCONSTANT "J)I",                                                          FN_PTR(getInt)},
+  {CC "getLong",                                      CC "(" OBJECTCONSTANT "J)J",                                                          FN_PTR(getLong)},
+  {CC "getObject",                                    CC "(" OBJECTCONSTANT "J)" OBJECTCONSTANT,                                            FN_PTR(getObject)},
+  {CC "deleteGlobalHandle",                           CC "(J)V",                                                                            FN_PTR(deleteGlobalHandle)},
+  {CC "registerNativeMethods",                        CC "(" CLASS ")[J",                                                                   FN_PTR(registerNativeMethods)},
+  {CC "translate",                                    CC "(" OBJECT ")J",                                                                   FN_PTR(translate)},
+  {CC "unhand",                                       CC "(J)" OBJECT,                                                                      FN_PTR(unhand)},
+  {CC "updateHotSpotNmethod",                         CC "(" HS_NMETHOD ")V",                                                               FN_PTR(updateHotSpotNmethod)},
+  {CC "getCode",                                      CC "(" HS_INSTALLED_CODE ")[B",                                                       FN_PTR(getCode)},
   {CC "asReflectionExecutable",                       CC "(" HS_RESOLVED_METHOD ")" REFLECTION_EXECUTABLE,                                  FN_PTR(asReflectionExecutable)},
   {CC "asReflectionField",                            CC "(" HS_RESOLVED_KLASS "I)" REFLECTION_FIELD,                                       FN_PTR(asReflectionField)},
+  {CC "getFailedSpeculations",                        CC "(J[[B)[[B",                                                                       FN_PTR(getFailedSpeculations)},
+  {CC "getFailedSpeculationsAddress",                 CC "(" HS_RESOLVED_METHOD ")J",                                                       FN_PTR(getFailedSpeculationsAddress)},
+  {CC "releaseFailedSpeculations",                    CC "(J)V",                                                                            FN_PTR(releaseFailedSpeculations)},
+  {CC "addFailedSpeculation",                         CC "(J[B)Z",                                                                          FN_PTR(addFailedSpeculation)},
 };
 
 int CompilerToVM::methods_count() {
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.hpp	Wed May 01 12:31:29 2019 -0700
@@ -24,40 +24,12 @@
 #ifndef SHARE_JVMCI_JVMCICOMPILERTOVM_HPP
 #define SHARE_JVMCI_JVMCICOMPILERTOVM_HPP
 
-#include "jni.h"
+#include "gc/shared/cardTable.hpp"
+#include "jvmci/jvmciExceptions.hpp"
 #include "runtime/javaCalls.hpp"
-#include "jvmci/jvmciJavaClasses.hpp"
+#include "runtime/signature.hpp"
 
-// Helper class to ensure that references to Klass* are kept alive for G1
-class JVMCIKlassHandle : public StackObj {
- private:
-  Klass*     _klass;
-  Handle     _holder;
-  Thread*    _thread;
-
-  Klass*        klass() const                     { return _klass; }
-  Klass*        non_null_klass() const            { assert(_klass != NULL, "resolving NULL _klass"); return _klass; }
-
- public:
-  /* Constructors */
-  JVMCIKlassHandle (Thread* thread) : _klass(NULL), _thread(thread) {}
-  JVMCIKlassHandle (Thread* thread, Klass* klass);
-
-  JVMCIKlassHandle (const JVMCIKlassHandle &h): _klass(h._klass), _holder(h._holder), _thread(h._thread) {}
-  JVMCIKlassHandle& operator=(const JVMCIKlassHandle &s);
-  JVMCIKlassHandle& operator=(Klass* klass);
-
-  /* Operators for ease of use */
-  Klass*        operator () () const            { return klass(); }
-  Klass*        operator -> () const            { return non_null_klass(); }
-
-  bool    operator == (Klass* o) const          { return klass() == o; }
-  bool    operator == (const JVMCIKlassHandle& h) const  { return klass() == h.klass(); }
-
-  /* Null checks */
-  bool    is_null() const                      { return _klass == NULL; }
-  bool    not_null() const                     { return _klass != NULL; }
-};
+class JVMCIObjectArray;
 
 class CompilerToVM {
  public:
@@ -118,7 +90,7 @@
     static address symbol_clinit;
 
    public:
-    static void initialize(TRAPS);
+     static void initialize(JVMCI_TRAPS);
 
     static int max_oop_map_stack_offset() {
       assert(_max_oop_map_stack_offset > 0, "must be initialized");
@@ -141,59 +113,14 @@
   }
 
   static JNINativeMethod methods[];
+  static JNINativeMethod jni_methods[];
 
-  static objArrayHandle initialize_intrinsics(TRAPS);
+  static JVMCIObjectArray initialize_intrinsics(JVMCI_TRAPS);
  public:
   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));
-  }
-
-  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 Klass* asKlass(jlong metaspaceKlass) {
-    return (Klass*) (address) metaspaceKlass;
-  }
-
-  static inline MethodData* asMethodData(jlong metaspaceMethodData) {
-    return (MethodData*) (address) metaspaceMethodData;
-  }
-
-  static oop get_jvmci_method(const methodHandle& method, TRAPS);
-
-  static oop get_jvmci_type(JVMCIKlassHandle& klass, TRAPS);
-};
 
 class JavaArgumentUnboxer : public SignatureIterator {
  protected:
--- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp	Wed May 01 12:31:29 2019 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, 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
@@ -25,13 +25,10 @@
 #include "ci/ciUtilities.hpp"
 #include "gc/shared/barrierSet.hpp"
 #include "gc/shared/cardTable.hpp"
-#include "memory/oopFactory.hpp"
-#include "oops/objArrayOop.inline.hpp"
-#include "jvmci/jvmciRuntime.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "jvmci/jvmciEnv.hpp"
 #include "jvmci/jvmciCompilerToVM.hpp"
 #include "jvmci/vmStructs_jvmci.hpp"
-#include "runtime/flags/jvmFlag.hpp"
-#include "runtime/handles.inline.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "utilities/resourceHash.hpp"
 
@@ -88,7 +85,7 @@
 address CompilerToVM::Data::symbol_init;
 address CompilerToVM::Data::symbol_clinit;
 
-void CompilerToVM::Data::initialize(TRAPS) {
+void CompilerToVM::Data::initialize(JVMCI_TRAPS) {
   Klass_vtable_start_offset = in_bytes(Klass::vtable_start_offset());
   Klass_vtable_length_offset = in_bytes(Klass::vtable_length_offset());
 
@@ -157,29 +154,23 @@
 #undef SET_TRIGFUNC
 }
 
-objArrayHandle CompilerToVM::initialize_intrinsics(TRAPS) {
-  objArrayHandle vmIntrinsics = oopFactory::new_objArray_handle(VMIntrinsicMethod::klass(), (vmIntrinsics::ID_LIMIT - 1), CHECK_(objArrayHandle()));
+JVMCIObjectArray CompilerToVM::initialize_intrinsics(JVMCI_TRAPS) {
+  JVMCIObjectArray vmIntrinsics = JVMCIENV->new_VMIntrinsicMethod_array(vmIntrinsics::ID_LIMIT - 1, JVMCI_CHECK_NULL);
   int index = 0;
-  // The intrinsics for a class are usually adjacent to each other.
-  // When they are, the string for the class name can be reused.
   vmSymbols::SID kls_sid = vmSymbols::NO_SID;
-  Handle kls_str;
+  JVMCIObject kls_str;
 #define VM_SYMBOL_TO_STRING(s) \
-  java_lang_String::create_from_symbol(vmSymbols::symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(s)), CHECK_(objArrayHandle()))
+  JVMCIENV->create_string(vmSymbols::symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(s)), JVMCI_CHECK_NULL)
 #define VM_INTRINSIC_INFO(id, kls, name, sig, ignore_fcode) {             \
-    instanceHandle vmIntrinsicMethod = InstanceKlass::cast(VMIntrinsicMethod::klass())->allocate_instance_handle(CHECK_(objArrayHandle())); \
     vmSymbols::SID sid = vmSymbols::VM_SYMBOL_ENUM_NAME(kls);             \
     if (kls_sid != sid) {                                                 \
       kls_str = VM_SYMBOL_TO_STRING(kls);                                 \
       kls_sid = sid;                                                      \
     }                                                                     \
-    Handle name_str = VM_SYMBOL_TO_STRING(name);                          \
-    Handle sig_str = VM_SYMBOL_TO_STRING(sig);                            \
-    VMIntrinsicMethod::set_declaringClass(vmIntrinsicMethod, kls_str());  \
-    VMIntrinsicMethod::set_name(vmIntrinsicMethod, name_str());           \
-    VMIntrinsicMethod::set_descriptor(vmIntrinsicMethod, sig_str());      \
-    VMIntrinsicMethod::set_id(vmIntrinsicMethod, vmIntrinsics::id);       \
-      vmIntrinsics->obj_at_put(index++, vmIntrinsicMethod());             \
+    JVMCIObject name_str = VM_SYMBOL_TO_STRING(name);                    \
+    JVMCIObject sig_str = VM_SYMBOL_TO_STRING(sig);                      \
+    JVMCIObject vmIntrinsicMethod = JVMCIENV->new_VMIntrinsicMethod(kls_str, name_str, sig_str, (jint) vmIntrinsics::id, JVMCI_CHECK_NULL); \
+    JVMCIENV->put_object_at(vmIntrinsics, index++, vmIntrinsicMethod);   \
   }
 
   VM_INTRINSICS_DO(VM_INTRINSIC_INFO, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
@@ -190,9 +181,6 @@
   return vmIntrinsics;
 }
 
-/**
- * The set of VM flags known to be used.
- */
 #define PREDEFINED_CONFIG_FLAGS(do_bool_flag, do_intx_flag, do_uintx_flag) \
   do_intx_flag(AllocateInstancePrefetchLines)                              \
   do_intx_flag(AllocatePrefetchDistance)                                   \
@@ -258,30 +246,28 @@
   do_bool_flag(UseTLAB)                                                    \
   do_bool_flag(VerifyOops)                                                 \
 
-#define BOXED_BOOLEAN(name, value) oop name = ((jboolean)(value) ? boxedTrue() : boxedFalse())
-#define BOXED_DOUBLE(name, value) oop name; do { jvalue p; p.d = (jdouble) (value); name = java_lang_boxing_object::create(T_DOUBLE, &p, CHECK_NULL);} while(0)
+#define BOXED_BOOLEAN(name, value) name = ((jboolean)(value) ? boxedTrue : boxedFalse)
+#define BOXED_DOUBLE(name, value) do { jvalue p; p.d = (jdouble) (value); name = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL);} while(0)
 #define BOXED_LONG(name, value) \
-  oop name; \
   do { \
     jvalue p; p.j = (jlong) (value); \
-    Handle* e = longs.get(p.j); \
+    JVMCIObject* e = longs.get(p.j); \
     if (e == NULL) { \
-      oop o = java_lang_boxing_object::create(T_LONG, &p, CHECK_NULL); \
-      Handle h(THREAD, o); \
+      JVMCIObject h = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); \
       longs.put(p.j, h); \
-      name = h(); \
+      name = h; \
     } else { \
-      name = (*e)(); \
+      name = (*e); \
     } \
   } while (0)
 
 #define CSTRING_TO_JSTRING(name, value) \
-  Handle name; \
+  JVMCIObject name; \
   do { \
     if (value != NULL) { \
-      Handle* e = strings.get(value); \
+      JVMCIObject* e = strings.get(value); \
       if (e == NULL) { \
-        Handle h = java_lang_String::create_from_str(value, CHECK_NULL); \
+        JVMCIObject h = JVMCIENV->create_string(value, JVMCI_CHECK_NULL); \
         strings.put(value, h); \
         name = h; \
       } else { \
@@ -290,51 +276,42 @@
     } \
   } while (0)
 
-jobjectArray readConfiguration0(JNIEnv *env, TRAPS) {
-  ResourceMark rm;
-  HandleMark hm;
-
-  // Used to canonicalize Long and String values.
-  ResourceHashtable<jlong, Handle> longs;
-  ResourceHashtable<const char*, Handle, &CompilerToVM::cstring_hash, &CompilerToVM::cstring_equals> strings;
+jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS) {
+  Thread* THREAD = Thread::current();
+  ResourceHashtable<jlong, JVMCIObject> longs;
+  ResourceHashtable<const char*, JVMCIObject, &CompilerToVM::cstring_hash, &CompilerToVM::cstring_equals> strings;
 
   jvalue prim;
-  prim.z = true;  oop boxedTrueOop =  java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK_NULL);
-  Handle boxedTrue(THREAD, boxedTrueOop);
-  prim.z = false; oop boxedFalseOop = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK_NULL);
-  Handle boxedFalse(THREAD, boxedFalseOop);
+  prim.z = true;  JVMCIObject boxedTrue =  JVMCIENV->create_box(T_BOOLEAN, &prim, JVMCI_CHECK_NULL);
+  prim.z = false; JVMCIObject boxedFalse = JVMCIENV->create_box(T_BOOLEAN, &prim, JVMCI_CHECK_NULL);
 
-  CompilerToVM::Data::initialize(CHECK_NULL);
+  CompilerToVM::Data::initialize(JVMCI_CHECK_NULL);
 
-  VMField::klass()->initialize(CHECK_NULL);
-  VMFlag::klass()->initialize(CHECK_NULL);
-  VMIntrinsicMethod::klass()->initialize(CHECK_NULL);
+  JVMCIENV->VMField_initialize(JVMCI_CHECK_NULL);
+  JVMCIENV->VMFlag_initialize(JVMCI_CHECK_NULL);
+  JVMCIENV->VMIntrinsicMethod_initialize(JVMCI_CHECK_NULL);
 
   int len = JVMCIVMStructs::localHotSpotVMStructs_count();
-  objArrayHandle vmFields = oopFactory::new_objArray_handle(VMField::klass(), len, CHECK_NULL);
+  JVMCIObjectArray vmFields = JVMCIENV->new_VMField_array(len, JVMCI_CHECK_NULL);
   for (int i = 0; i < len ; i++) {
     VMStructEntry vmField = JVMCIVMStructs::localHotSpotVMStructs[i];
-    instanceHandle vmFieldObj = InstanceKlass::cast(VMField::klass())->allocate_instance_handle(CHECK_NULL);
     size_t name_buf_len = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 /* "::" */;
     char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_len + 1);
     sprintf(name_buf, "%s::%s", vmField.typeName, vmField.fieldName);
     CSTRING_TO_JSTRING(name, name_buf);
     CSTRING_TO_JSTRING(type, vmField.typeString);
-    VMField::set_name(vmFieldObj, name());
-    VMField::set_type(vmFieldObj, type());
-    VMField::set_offset(vmFieldObj, vmField.offset);
-    VMField::set_address(vmFieldObj, (jlong) vmField.address);
+    JVMCIObject box;
     if (vmField.isStatic && vmField.typeString != NULL) {
       if (strcmp(vmField.typeString, "bool") == 0) {
         BOXED_BOOLEAN(box, *(jbyte*) vmField.address);
-        VMField::set_value(vmFieldObj, box);
+        assert(box.is_non_null(), "must have a box");
       } else if (strcmp(vmField.typeString, "int") == 0 ||
                  strcmp(vmField.typeString, "jint") == 0) {
         BOXED_LONG(box, *(jint*) vmField.address);
-        VMField::set_value(vmFieldObj, box);
+        assert(box.is_non_null(), "must have a box");
       } else if (strcmp(vmField.typeString, "uint64_t") == 0) {
         BOXED_LONG(box, *(uint64_t*) vmField.address);
-        VMField::set_value(vmFieldObj, box);
+        assert(box.is_non_null(), "must have a box");
       } else if (strcmp(vmField.typeString, "address") == 0 ||
                  strcmp(vmField.typeString, "intptr_t") == 0 ||
                  strcmp(vmField.typeString, "uintptr_t") == 0 ||
@@ -343,43 +320,47 @@
                  // All foo* types are addresses.
                  vmField.typeString[strlen(vmField.typeString) - 1] == '*') {
         BOXED_LONG(box, *((address*) vmField.address));
-        VMField::set_value(vmFieldObj, box);
+        assert(box.is_non_null(), "must have a box");
       } else {
         JVMCI_ERROR_NULL("VM field %s has unsupported type %s", name_buf, vmField.typeString);
       }
     }
-    vmFields->obj_at_put(i, vmFieldObj());
+    JVMCIObject vmFieldObj = JVMCIENV->new_VMField(name, type, vmField.offset, (jlong) vmField.address, box, JVMCI_CHECK_NULL);
+    JVMCIENV->put_object_at(vmFields, i, vmFieldObj);
   }
 
   int ints_len = JVMCIVMStructs::localHotSpotVMIntConstants_count();
   int longs_len = JVMCIVMStructs::localHotSpotVMLongConstants_count();
   len = ints_len + longs_len;
-  objArrayHandle vmConstants = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
+  JVMCIObjectArray vmConstants = JVMCIENV->new_Object_array(len * 2, JVMCI_CHECK_NULL);
   int insert = 0;
   for (int i = 0; i < ints_len ; i++) {
     VMIntConstantEntry c = JVMCIVMStructs::localHotSpotVMIntConstants[i];
     CSTRING_TO_JSTRING(name, c.name);
+    JVMCIObject value;
     BOXED_LONG(value, c.value);
-    vmConstants->obj_at_put(insert++, name());
-    vmConstants->obj_at_put(insert++, value);
+    JVMCIENV->put_object_at(vmConstants, insert++, name);
+    JVMCIENV->put_object_at(vmConstants, insert++, value);
   }
   for (int i = 0; i < longs_len ; i++) {
     VMLongConstantEntry c = JVMCIVMStructs::localHotSpotVMLongConstants[i];
     CSTRING_TO_JSTRING(name, c.name);
+    JVMCIObject value;
     BOXED_LONG(value, c.value);
-    vmConstants->obj_at_put(insert++, name());
-    vmConstants->obj_at_put(insert++, value);
+    JVMCIENV->put_object_at(vmConstants, insert++, name);
+    JVMCIENV->put_object_at(vmConstants, insert++, value);
   }
   assert(insert == len * 2, "must be");
 
   len = JVMCIVMStructs::localHotSpotVMAddresses_count();
-  objArrayHandle vmAddresses = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
+  JVMCIObjectArray vmAddresses = JVMCIENV->new_Object_array(len * 2, JVMCI_CHECK_NULL);
   for (int i = 0; i < len ; i++) {
     VMAddressEntry a = JVMCIVMStructs::localHotSpotVMAddresses[i];
     CSTRING_TO_JSTRING(name, a.name);
+    JVMCIObject value;
     BOXED_LONG(value, a.value);
-    vmAddresses->obj_at_put(i * 2, name());
-    vmAddresses->obj_at_put(i * 2 + 1, value);
+    JVMCIENV->put_object_at(vmAddresses, i * 2, name);
+    JVMCIENV->put_object_at(vmAddresses, i * 2 + 1, value);
   }
 
 #define COUNT_FLAG(ignore) +1
@@ -393,40 +374,32 @@
 #define CHECK_FLAG(type, name)
 #endif
 
-#define ADD_FLAG(type, name, convert) { \
-  CHECK_FLAG(type, name) \
-  instanceHandle vmFlagObj = InstanceKlass::cast(VMFlag::klass())->allocate_instance_handle(CHECK_NULL); \
-  CSTRING_TO_JSTRING(fname, #name); \
-  CSTRING_TO_JSTRING(ftype, #type); \
-  VMFlag::set_name(vmFlagObj, fname()); \
-  VMFlag::set_type(vmFlagObj, ftype()); \
-  convert(value, name); \
-  VMFlag::set_value(vmFlagObj, value); \
-  vmFlags->obj_at_put(i++, vmFlagObj()); \
+#define ADD_FLAG(type, name, convert) {                                                \
+  CHECK_FLAG(type, name)                                                               \
+  CSTRING_TO_JSTRING(fname, #name);                                                    \
+  CSTRING_TO_JSTRING(ftype, #type);                                                    \
+  convert(value, name);                                                                \
+  JVMCIObject vmFlagObj = JVMCIENV->new_VMFlag(fname, ftype, value, JVMCI_CHECK_NULL); \
+  JVMCIENV->put_object_at(vmFlags, i++, vmFlagObj);                                    \
 }
 #define ADD_BOOL_FLAG(name)  ADD_FLAG(bool, name, BOXED_BOOLEAN)
 #define ADD_INTX_FLAG(name)  ADD_FLAG(intx, name, BOXED_LONG)
 #define ADD_UINTX_FLAG(name) ADD_FLAG(uintx, name, BOXED_LONG)
 
   len = 0 + PREDEFINED_CONFIG_FLAGS(COUNT_FLAG, COUNT_FLAG, COUNT_FLAG);
-  objArrayHandle vmFlags = oopFactory::new_objArray_handle(VMFlag::klass(), len, CHECK_NULL);
+  JVMCIObjectArray vmFlags = JVMCIENV->new_VMFlag_array(len, JVMCI_CHECK_NULL);
   int i = 0;
+  JVMCIObject value;
   PREDEFINED_CONFIG_FLAGS(ADD_BOOL_FLAG, ADD_INTX_FLAG, ADD_UINTX_FLAG)
 
-  objArrayHandle vmIntrinsics = CompilerToVM::initialize_intrinsics(CHECK_NULL);
+  JVMCIObjectArray vmIntrinsics = CompilerToVM::initialize_intrinsics(JVMCI_CHECK_NULL);
 
-  objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 5, CHECK_NULL);
-  data->obj_at_put(0, vmFields());
-  data->obj_at_put(1, vmConstants());
-  data->obj_at_put(2, vmAddresses());
-  data->obj_at_put(3, vmFlags());
-  data->obj_at_put(4, vmIntrinsics());
+  JVMCIObjectArray data = JVMCIENV->new_Object_array(5, JVMCI_CHECK_NULL);
+  JVMCIENV->put_object_at(data, 0, vmFields);
+  JVMCIENV->put_object_at(data, 1, vmConstants);
+  JVMCIENV->put_object_at(data, 2, vmAddresses);
+  JVMCIENV->put_object_at(data, 3, vmFlags);
+  JVMCIENV->put_object_at(data, 4, vmIntrinsics);
 
-  return (jobjectArray) JNIHandles::make_local(THREAD, data);
-#undef COUNT_FLAG
-#undef ADD_FLAG
-#undef ADD_BOOL_FLAG
-#undef ADD_INTX_FLAG
-#undef ADD_UINTX_FLAG
-#undef CHECK_FLAG
+  return JVMCIENV->get_jobjectArray(data);
 }
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp	Wed May 01 12:41:26 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp	Wed May 01 12:31:29 2019 -0700
@@ -23,44 +23,22 @@
  */
 
 #include "precompiled.hpp"
-#include "jvmci/jvmciEnv.hpp"
-#include "classfile/javaAssertions.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "classfile/vmSymbols.hpp"
+#include "classfile/stringTable.hpp"
 #include "code/codeCache.hpp"
-#include "code/scopeDesc.hpp"
-#include "compiler/compileBroker.hpp"
-#include "compiler/compileLog.hpp"
-#include "compiler/compilerOracle.hpp"
-#include "interpreter/linkResolver.hpp"
-#include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
-#include "memory/universe.hpp"
-#include "oops/constantPool.inline.hpp"
-#include "oops/cpCache.inline.hpp"
-#include "oops/method.inline.hpp"
-#include "oops/methodData.hpp"
-#include "oops/objArrayKlass.hpp"
-#include "oops/oop.inline.hpp"
-#include "prims/jvmtiExport.hpp"
-#include "runtime/fieldDescriptor.inline.hpp"
-#include "runtime/handles.inline.hpp"
-#include "runtime/init.hpp"
-#include "runtime/reflection.hpp"
-#include "runtime/sharedRuntime.hpp"
-#include "runtime/sweeper.hpp"
-#include "utilities/dtrace.hpp"
+#include "oops/typeArrayOop.inline.hpp"
+#include "runtime/jniHandles.inline.hpp"
+#include "runtime/javaCalls.hpp"
+#include "jvmci/jniAccessMark.inline.hpp"
 #include "jvmci/jvmciRuntime.hpp"
-#include "jvmci/jvmciJavaClasses.hpp"
 
-JVMCIEnv::JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter):
+JVMCICompileState::JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter):
   _task(task),
   _system_dictionary_modification_counter(system_dictionary_modification_counter),
   _retryable(true),
   _failure_reason(NULL),
-  _failure_reason_on_C_heap(false)
-{
+  _failure_reason_on_C_heap(false) {
   // Get Jvmti capabilities under lock to get consistent values.
   MutexLocker mu(JvmtiThreadState_lock);
   _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0;
@@ -69,7 +47,7 @@
   _jvmti_can_pop_frame                  = JvmtiExport::can_pop_frame() ? 1 : 0;
 }
 
-bool JVMCIEnv::jvmti_state_changed() const {
+bool JVMCICompileState::jvmti_state_changed() const {
   if (!jvmti_can_access_local_variables() &&
       JvmtiExport::can_access_local_variables()) {
     return true;
@@ -89,532 +67,1587 @@
   return false;
 }
 
-// ------------------------------------------------------------------
-// Note: the logic of this method should mirror the logic of
-// constantPoolOopDesc::verify_constant_pool_resolve.
-bool JVMCIEnv::check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass) {
-  if (accessing_klass->is_objArray_klass()) {
-    accessing_klass = ObjArrayKlass::cast(accessing_klass)->bottom_klass();
+JavaVM* JVMCIEnv::_shared_library_javavm = NULL;
+void* JVMCIEnv::_shared_library_handle = NULL;
+char* JVMCIEnv::_shared_library_path = NULL;
+
+void JVMCIEnv::copy_saved_properties() {
+  assert(!is_hotspot(), "can only copy saved properties from HotSpot to native image");
+
+  JavaThread* THREAD = JavaThread::current();
+
+  Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_services_Services(), Handle(), Handle(), true, THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services");
   }
-  if (!accessing_klass->is_instance_klass()) {
-    return true;
-  }
-
-  if (resolved_klass->is_objArray_klass()) {
-    // Find the element klass, if this is an array.
-    resolved_klass = ObjArrayKlass::cast(resolved_klass)->bottom_klass();
-  }
-  if (resolved_klass->is_instance_klass()) {
-    Reflection::VerifyClassAccessResults result =
-      Reflection::verify_class_access(accessing_klass, InstanceKlass::cast(resolved_klass), true);
-    return result == Reflection::ACCESS_OK;
-  }
-  return true;
-}
-
-// ------------------------------------------------------------------
-Klass* JVMCIEnv::get_klass_by_name_impl(Klass* accessing_klass,
-                                        const constantPoolHandle& cpool,
-                                        Symbol* sym,
-                                        bool require_local) {
-  JVMCI_EXCEPTION_CONTEXT;
-
-  // Now we need to check the SystemDictionary
-  if (sym->char_at(0) == 'L' &&
-    sym->char_at(sym->utf8_length()-1) == ';') {
-    // This is a name from a signature.  Strip off the trimmings.
-    // Call recursive to keep scope of strippedsym.
-    TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
-                    sym->utf8_length()-2,
-                    CHECK_NULL);
-    return get_klass_by_name_impl(accessing_klass, cpool, strippedsym, require_local);
-  }
-
-  Handle loader(THREAD, (oop)NULL);
-  Handle domain(THREAD, (oop)NULL);
-  if (accessing_klass != NULL) {
-    loader = Handle(THREAD, accessing_klass->class_loader());
-    domain = Handle(THREAD, accessing_klass->protection_domain());
-  }
-
-  Klass* found_klass = NULL;
-  {
-    ttyUnlocker ttyul;  // release tty lock to avoid ordering problems
-    MutexLocker ml(Compile_lock);
-    if (!require_local) {
-      found_klass = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader, CHECK_NULL);
-    } else {
-      found_klass = SystemDictionary::find_instance_or_array_klass(sym, loader, domain, CHECK_NULL);
+  InstanceKlass* ik = InstanceKlass::cast(k);
+  if (ik->should_be_initialized()) {
+    ik->initialize(THREAD);
+    if (HAS_PENDING_EXCEPTION) {
+      JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services");
     }
   }
 
-  // If we fail to find an array klass, look again for its element type.
-  // The element type may be available either locally or via constraints.
-  // In either case, if we can find the element type in the system dictionary,
-  // we must build an array type around it.  The CI requires array klasses
-  // to be loaded if their element klasses are loaded, except when memory
-  // is exhausted.
-  if (sym->char_at(0) == '[' &&
-      (sym->char_at(1) == '[' || sym->char_at(1) == 'L')) {
-    // We have an unloaded array.
-    // Build it on the fly if the element class exists.
-    TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
-                                                 sym->utf8_length()-1,
-                                                 CHECK_NULL);
+  // Get the serialized saved properties from HotSpot
+  TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties", CHECK_EXIT);
+  JavaValue result(T_OBJECT);
+  JavaCallArguments args;
+  JavaCalls::call_static(&result, ik, serializeSavedProperties, vmSymbols::serializePropertiesToByteArray_signature(), &args, THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    JVMCIRuntime::exit_on_pending_exception(NULL, "Error calling jdk.vm.ci.services.Services.serializeSavedProperties");
+  }
+  oop res = (oop) result.get_jobject();
+  assert(res->is_typeArray(), "must be");
+  assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "must be");
+  typeArrayOop ba = typeArrayOop(res);
+  int serialized_properties_len = ba->length();
 
-    // Get element Klass recursively.
-    Klass* elem_klass =
-      get_klass_by_name_impl(accessing_klass,
-                             cpool,
-                             elem_sym,
-                             require_local);
-    if (elem_klass != NULL) {
-      // Now make an array for it
-      return elem_klass->array_klass(THREAD);
+  // Copy serialized saved properties from HotSpot object into native buffer
+  jbyte* serialized_properties = NEW_RESOURCE_ARRAY(jbyte, serialized_properties_len);
+  memcpy(serialized_properties, ba->byte_at_addr(0), serialized_properties_len);
+
+  // Copy native buffer into shared library object
+  JVMCIPrimitiveArray buf = new_byteArray(serialized_properties_len, this);
+  if (has_pending_exception()) {
+    describe_pending_exception(true);
+    fatal("Error in copy_saved_properties");
+  }
+  copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len);
+  if (has_pending_exception()) {
+    describe_pending_exception(true);
+    fatal("Error in copy_saved_properties");
+  }
+
+  // Initialize saved properties in shared library
+  jclass servicesClass = JNIJVMCI::Services::clazz();
+  jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method();
+  JNIAccessMark jni(this);
+  jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject());
+  if (jni()->ExceptionCheck()) {
+    jni()->ExceptionDescribe();
+    fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties");
+  }
+}
+
+JNIEnv* JVMCIEnv::attach_shared_library() {
+  if (_shared_library_javavm == NULL) {
+    MutexLocker locker(JVMCI_lock);
+    if (_shared_library_javavm == NULL) {
+
+      char path[JVM_MAXPATHLEN];
+      char ebuf[1024];
+      if (JVMCILibPath != NULL) {
+        if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) {
+          vm_exit_during_initialization("Unable to create JVMCI shared library path from -XX:JVMCILibPath value", JVMCILibPath);
+        }
+      } else {
+        if (!os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) {
+          vm_exit_during_initialization("Unable to create path to JVMCI shared library");
+        }
+      }
+
+      void* handle = os::dll_load(path, ebuf, sizeof ebuf);
+      if (handle == NULL) {
+        vm_exit_during_initialization("Unable to load JVMCI shared library", ebuf);
+      }
+      _shared_library_handle = handle;
+      _shared_library_path = strdup(path);
+      jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args);
+      typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args);
+
+      JNI_CreateJavaVM = CAST_TO_FN_PTR(JNI_CreateJavaVM_t, os::dll_lookup(handle, "JNI_CreateJavaVM"));
+      JNIEnv* env;
+      if (JNI_CreateJavaVM == NULL) {
+        vm_exit_during_initialization("Unable to find JNI_CreateJavaVM", path);
+      }
+
+      ResourceMark rm;
+      JavaVMInitArgs vm_args;
+      vm_args.version = JNI_VERSION_1_2;
+      vm_args.ignoreUnrecognized = JNI_TRUE;
+      vm_args.options = NULL;
+      vm_args.nOptions = 0;
+
+      JavaVM* the_javavm = NULL;
+      int result = (*JNI_CreateJavaVM)(&the_javavm, (void**) &env, &vm_args);
+      if (result == JNI_OK) {
+        guarantee(env != NULL, "missing env");
+        _shared_library_javavm = the_javavm;
+        return env;
+      } else {
+        vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path);
+      }
+    }
+  }
+  JNIEnv* env;
+  if (_shared_library_javavm->AttachCurrentThread((void**)&env, NULL) == JNI_OK) {
+    guarantee(env != NULL, "missing env");
+    return env;
+  }
+  fatal("Error attaching current thread to JVMCI shared library JNI interface");
+  return NULL;
+}
+
+void JVMCIEnv::init_env_mode_runtime(JNIEnv* parent_env) {
+  // By default there is only one runtime which is the compiler runtime.
+  _runtime = JVMCI::compiler_runtime();
+  if (!UseJVMCINativeLibrary) {
+    // In HotSpot mode, JNI isn't used at all.
+    _is_hotspot = true;
+    _env = NULL;
+    return;
+  }
+
+  if (parent_env != NULL) {
+    // If the parent JNI environment is non-null then figure out whether it
+    // is a HotSpot or shared library JNIEnv and set the state appropriately.
+    JavaThread* thread = JavaThread::current();
+    if (thread->jni_environment() == parent_env) {
+      // Select the Java runtime
+      _runtime = JVMCI::java_runtime();
+      _is_hotspot = true;
+      _env = NULL;
+      return;
     }
   }
 
-  if (found_klass == NULL && !cpool.is_null() && cpool->has_preresolution()) {
-    // Look inside the constant pool for pre-resolved class entries.
-    for (int i = cpool->length() - 1; i >= 1; i--) {
-      if (cpool->tag_at(i).is_klass()) {
-        Klass*  kls = cpool->resolved_klass_at(i);
-        if (kls->name() == sym) {
-          return kls;
+  // Running in JVMCI shared library mode so get a shared library JNIEnv
+  _is_hotspot = false;
+  _env = attach_shared_library();
+  assert(parent_env == NULL || _env == parent_env, "must be");
+
+  if (parent_env == NULL) {
+    // There is no parent shared library JNI env so push
+    // a JNI local frame to release all local handles in
+    // this JVMCIEnv scope when it's closed.
+    assert(_throw_to_caller == false, "must be");
+    JNIAccessMark jni(this);
+    jint result = _env->PushLocalFrame(32);
+    if (result != JNI_OK) {
+      char message[256];
+      jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line);
+      JVMCIRuntime::exit_on_pending_exception(this, message);
+    }
+  }
+}
+
+JVMCIEnv::JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line):
+    _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) {
+  init_env_mode_runtime(NULL);
+}
+
+JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line):
+    _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) {
+  init_env_mode_runtime(NULL);
+}
+
+JVMCIEnv::JVMCIEnv(JNIEnv* parent_env, const char* file, int line):
+    _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) {
+  init_env_mode_runtime(parent_env);
+  assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment");
+}
+
+void JVMCIEnv::init(bool is_hotspot, const char* file, int line) {
+  _compile_state = NULL;
+  _throw_to_caller = false;
+  _file = file;
+  _line = line;
+  if (is_hotspot) {
+    _env = NULL;
+    _is_hotspot = true;
+    _runtime = JVMCI::java_runtime();
+  } else {
+    init_env_mode_runtime(NULL);
+  }
+}
+
+// Prints a pending exception (if any) and its stack trace.
+void JVMCIEnv::describe_pending_exception(bool clear) {
+  if (!is_hotspot()) {
+    JNIAccessMark jni(this);
+    if (jni()->ExceptionCheck()) {
+      jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL;
+      jni()->ExceptionDescribe();
+      if (ex != NULL) {
+        jni()->Throw(ex);
+      }
+    }
+  } else {
+    Thread* THREAD = Thread::current();
+    if (HAS_PENDING_EXCEPTION) {
+      JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear);
+    }
+  }
+}
+
+void JVMCIEnv::translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, const Handle& throwable) {
+  assert(!is_hotspot(), "must_be");
+  // Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets
+  // may not have been called.
+  Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK);
+  JavaCallArguments jargs;
+  jargs.push_oop(throwable);
+  JavaValue result(T_OBJECT);
+  JavaCalls::call_static(&result,
+                          runtimeKlass,
+                          vmSymbols::encodeThrowable_name(),
+                          vmSymbols::encodeThrowable_signature(), &jargs, THREAD);
+  if (HAS_PENDING_EXCEPTION) {
+    JVMCIRuntime::exit_on_pending_exception(this, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception");
+  }
+
+  oop encoded_throwable_string = (oop) result.get_jobject();
+
+  ResourceMark rm;
+  const char* encoded_throwable_chars = java_lang_String::as_utf8_string(encoded_throwable_string);
+
+  JNIAccessMark jni(this);
+  jobject jni_encoded_throwable_string = jni()->NewStringUTF(encoded_throwable_chars);
+  jthrowable jni_throwable = (jthrowable) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
+                                JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(),
+                                jni_encoded_throwable_string);
+  jni()->Throw(jni_throwable);
+}
+
+JVMCIEnv::~JVMCIEnv() {
+  if (_throw_to_caller) {
+    if (is_hotspot()) {
+      // Nothing to do
+    } else {
+      if (Thread::current()->is_Java_thread()) {
+        JavaThread* THREAD = JavaThread::current();
+        if (HAS_PENDING_EXCEPTION) {
+          Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
+          CLEAR_PENDING_EXCEPTION;
+          translate_hotspot_exception_to_jni_exception(THREAD, throwable);
         }
       }
     }
+  } else {
+    if (!is_hotspot()) {
+      // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope.
+      JNIAccessMark jni(this);
+      jni()->PopLocalFrame(NULL);
+    }
+
+    if (has_pending_exception()) {
+      char message[256];
+      jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line);
+      JVMCIRuntime::exit_on_pending_exception(this, message);
+    }
+  }
+}
+
+jboolean JVMCIEnv::has_pending_exception() {
+  if (is_hotspot()) {
+    Thread* THREAD = Thread::current();
+    return HAS_PENDING_EXCEPTION;
+  } else {
+    JNIAccessMark jni(this);
+    return jni()->ExceptionCheck();
+  }
+}
+
+void JVMCIEnv::clear_pending_exception() {
+  if (is_hotspot()) {
+    Thread* THREAD = Thread::current();
+    CLEAR_PENDING_EXCEPTION;
+  } else {
+    JNIAccessMark jni(this);
+    jni()->ExceptionClear();
+  }
+}
+
+int JVMCIEnv::get_length(JVMCIArray array) {
+  if (is_hotspot()) {
+    return HotSpotJVMCI::resolve(array)->length();
+  } else {
+    JNIAccessMark jni(this);
+    return jni()->GetArrayLength(get_jarray(array));
+  }
+}
+
+JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) {
+  if (is_hotspot()) {
+    oop result = HotSpotJVMCI::resolve(array)->obj_at(index);
+    return wrap(result);
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index);
+    return wrap(result);
+  }
+}
+
+void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) {
+  if (is_hotspot()) {
+    HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value));
+  } else {
+    JNIAccessMark jni(this);
+    jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value));
+  }
+}
+
+jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) {
+  if (is_hotspot()) {
+    return HotSpotJVMCI::resolve(array)->bool_at(index);
+  } else {
+    JNIAccessMark jni(this);
+    jboolean result;
+    jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result);
+    return result;
+  }
+}
+void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) {
+  if (is_hotspot()) {
+    HotSpotJVMCI::resolve(array)->bool_at_put(index, value);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value);
+  }
+}
+
+jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) {
+  if (is_hotspot()) {
+    return HotSpotJVMCI::resolve(array)->byte_at(index);
+  } else {
+    JNIAccessMark jni(this);
+    jbyte result;
+    jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result);
+    return result;
+  }
+}
+void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) {
+  if (is_hotspot()) {
+    HotSpotJVMCI::resolve(array)->byte_at_put(index, value);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value);
+  }
+}
+
+jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) {
+  if (is_hotspot()) {
+    return HotSpotJVMCI::resolve(array)->int_at(index);
+  } else {
+    JNIAccessMark jni(this);
+    jint result;
+    jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result);
+    return result;
+  }
+}
+void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) {
+  if (is_hotspot()) {
+    HotSpotJVMCI::resolve(array)->int_at_put(index, value);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value);
+  }
+}
+
+long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) {
+  if (is_hotspot()) {
+    return HotSpotJVMCI::resolve(array)->long_at(index);
+  } else {
+    JNIAccessMark jni(this);
+    jlong result;
+    jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result);
+    return result;
+  }
+}
+void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) {
+  if (is_hotspot()) {
+    HotSpotJVMCI::resolve(array)->long_at_put(index, value);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value);
+  }
+}
+
+void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes) {
+  if (size_in_bytes == 0) {
+    return;
+  }
+  if (is_hotspot()) {
+    memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), size_in_bytes);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, size_in_bytes, dest);
+  }
+}
+void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes) {
+  if (size_in_bytes == 0) {
+    return;
+  }
+  if (is_hotspot()) {
+    memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, size_in_bytes);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, size_in_bytes, src);
+  }
+}
+
+jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) {
+  if (is_hotspot()) {
+    return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type);
+  } else {
+    JNIAccessMark jni(this);
+    return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type));
+  }
+}
+
+// Get the primitive value from a Java boxing object.  It's hard error to
+// pass a non-primitive BasicType.
+jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) {
+  jvalue result;
+  if (is_hotspot()) {
+    if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) {
+      ShouldNotReachHere();
+    }
+  } else {
+    JNIAccessMark jni(this);
+    jfieldID field = JNIJVMCI::box_field(type);
+    switch (type) {
+      case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break;
+      case T_BYTE:    result.b = jni()->GetByteField(get_jobject(object), field); break;
+      case T_SHORT:   result.s = jni()->GetShortField(get_jobject(object), field); break;
+      case T_CHAR:    result.c = jni()->GetCharField(get_jobject(object), field); break;
+      case T_INT:     result.i = jni()->GetIntField(get_jobject(object), field); break;
+      case T_LONG:    result.j = jni()->GetLongField(get_jobject(object), field); break;
+      case T_FLOAT:   result.f = jni()->GetFloatField(get_jobject(object), field); break;
+      case T_DOUBLE:  result.d = jni()->GetDoubleField(get_jobject(object), field); break;
+      default:
+        ShouldNotReachHere();
+    }
+  }
+  return result;
+}
+
+// Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.
+BasicType JVMCIEnv::get_box_type(JVMCIObject object) {
+  if (is_hotspot()) {
+    return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object));
+  } else {
+    JNIAccessMark jni(this);
+    jclass clazz = jni()->GetObjectClass(get_jobject(object));
+    if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN;
+    if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE;
+    if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT;
+    if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR;
+    if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT;
+    if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG;
+    if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT;
+    if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE;
+    return T_ILLEGAL;
+  }
+}
+
+// Create a boxing object of the appropriate primitive type.
+JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) {
+  switch (type) {
+    case T_BOOLEAN:
+    case T_BYTE:
+    case T_CHAR:
+    case T_SHORT:
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+      break;
+    default:
+      JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject());
+  }
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject()));
+    return HotSpotJVMCI::wrap(box);
+  } else {
+    JNIAccessMark jni(this);
+    jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value);
+    assert(box != NULL, "");
+    return wrap(box);
+  }
+}
+
+const char* JVMCIEnv::as_utf8_string(JVMCIObject str) {
+  if (is_hotspot()) {
+    return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str));
+  } else {
+    JNIAccessMark jni(this);
+    int length = jni()->GetStringLength(str.as_jstring());
+    char* result = NEW_RESOURCE_ARRAY(char, length + 1);
+    jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result);
+    return result;
+  }
+}
+
+char* JVMCIEnv::as_utf8_string(JVMCIObject str, char* buf, int buflen) {
+  if (is_hotspot()) {
+    return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str), buf, buflen);
+  } else {
+    JNIAccessMark jni(this);
+    int length = jni()->GetStringLength(str.as_jstring());
+    if (length >= buflen) {
+      length = buflen;
+    }
+    jni()->GetStringUTFRegion(str.as_jstring(), 0, length, buf);
+    return buf;
+  }
+}
+
+#define DO_THROW(name)                             \
+void JVMCIEnv::throw_##name(const char* msg) {     \
+  if (is_hotspot()) {                              \
+    JavaThread* THREAD = JavaThread::current();    \
+    THROW_MSG(HotSpotJVMCI::name::symbol(), msg);  \
+  } else {                                         \
+    JNIAccessMark jni(this);                       \
+    jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \
+  }                                                \
+}
+
+DO_THROW(InternalError)
+DO_THROW(ArrayIndexOutOfBoundsException)
+DO_THROW(IllegalStateException)
+DO_THROW(NullPointerException)
+DO_THROW(IllegalArgumentException)
+DO_THROW(InvalidInstalledCodeException)
+DO_THROW(UnsatisfiedLinkError)
+
+#undef DO_THROW
+
+void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) {
+  const int max_msg_size = 1024;
+  va_list ap;
+  va_start(ap, format);
+  char msg[max_msg_size];
+  vsnprintf(msg, max_msg_size, format, ap);
+  msg[max_msg_size-1] = '\0';
+  va_end(ap);
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    Handle h_loader = Handle();
+    Handle h_protection_domain = Handle();
+    Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg);
+  }
+}
+
+JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
+                                                              jlong compile_state, int id) {
+  if (is_hotspot()) {
+    Thread* THREAD = Thread::current();
+    JavaCallArguments jargs;
+    jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
+    jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
+    jargs.push_int(entry_bci);
+    jargs.push_long(compile_state);
+    jargs.push_int(id);
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_special(&result,
+                            HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
+                            vmSymbols::compileMethod_name(),
+                            vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
+    return wrap((oop) result.get_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
+                                                     JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
+                                                     JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
+                                                     method.as_jobject(), entry_bci, compile_state, id);
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    return wrap(result);
+  }
+}
+
+void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
+  if (is_hotspot()) {
+    Thread* THREAD = Thread::current();
+    JavaCallArguments jargs;
+    jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
+    JavaValue result(T_VOID);
+    JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
+
+  }
+}
+
+void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
+  HandleMark hm;
+  JavaThread* THREAD = JavaThread::current();
+  if (is_hotspot()) {
+    JavaCallArguments jargs;
+    jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
+    JavaValue result(T_VOID);
+    JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD);
+  } else {
+    JNIAccessMark jni(this);
+    jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method());
+  }
+  if (has_pending_exception()) {
+    // This should never happen as HotSpotJVMCIRuntime.shutdown() should
+    // handle all exceptions.
+    describe_pending_exception(true);
+  }
+}
+
+JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
+  JavaThread* THREAD = JavaThread::current();
+  if (is_hotspot()) {
+    JavaCallArguments jargs;
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject()));
+    return wrap((oop) result.get_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method());
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    return wrap(result);
+  }
+}
+
+JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
+  JavaThread* THREAD = JavaThread::current();
+  if (is_hotspot()) {
+    JavaCallArguments jargs;
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject()));
+    return wrap((oop) result.get_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method());
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    return wrap(result);
+  }
+}
+
+JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
+  JavaThread* THREAD = JavaThread::current();
+  if (is_hotspot()) {
+    JavaCallArguments jargs;
+    jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject()));
+    return wrap((oop) result.get_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method());
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    return wrap(result);
+  }
+}
+
+
+JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
+  JavaThread* THREAD = JavaThread::current();
+  if (is_hotspot()) {
+    JavaCallArguments jargs;
+    jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_static(&result,
+                           HotSpotJVMCI::HotSpotJVMCIRuntime::klass(),
+                           vmSymbols::callToString_name(),
+                           vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject()));
+    return wrap((oop) result.get_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
+                                                     JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(),
+                                                     object.as_jobject());
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    return wrap(result);
+  }
+}
+
+
+JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) {
+  JavaThread* THREAD = JavaThread::current();
+  if (is_hotspot()) {
+    JavaCallArguments jargs;
+    jargs.push_int(kind);
+    jargs.push_long(value);
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_static(&result,
+                           HotSpotJVMCI::PrimitiveConstant::klass(),
+                           vmSymbols::forTypeChar_name(),
+                           vmSymbols::forTypeChar_signature(), &jargs, CHECK_(JVMCIObject()));
+    return wrap((oop) result.get_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::PrimitiveConstant::clazz(),
+                                                     JNIJVMCI::PrimitiveConstant::forTypeChar_method(),
+                                                     kind, value);
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    return wrap(result);
+  }
+}
+
+JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
+  JavaThread* THREAD = JavaThread::current();
+  if (is_hotspot()) {
+    JavaCallArguments jargs;
+    jargs.push_float(value);
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_static(&result,
+                           HotSpotJVMCI::JavaConstant::klass(),
+                           vmSymbols::forFloat_name(),
+                           vmSymbols::forFloat_signature(), &jargs, CHECK_(JVMCIObject()));
+    return wrap((oop) result.get_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
+                                                     JNIJVMCI::JavaConstant::forFloat_method(),
+                                                     value);
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    return wrap(result);
+  }
+}
+
+JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) {
+  JavaThread* THREAD = JavaThread::current();
+  if (is_hotspot()) {
+    JavaCallArguments jargs;
+    jargs.push_double(value);
+    JavaValue result(T_OBJECT);
+    JavaCalls::call_static(&result,
+                           HotSpotJVMCI::JavaConstant::klass(),
+                           vmSymbols::forDouble_name(),
+                           vmSymbols::forDouble_signature(), &jargs, CHECK_(JVMCIObject()));
+    return wrap((oop) result.get_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(),
+                                                     JNIJVMCI::JavaConstant::forDouble_method(),
+                                                     value);
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    return wrap(result);
+  }
+}
+
+JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) {
+  JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives();
+  JVMCIObject result = get_object_at(primitives, type);
+  return result;
+}
+
+JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) {
+  JavaThread* THREAD = JavaThread::current();
+  Symbol* method_name_sym;
+  Symbol* file_name_sym;
+  int line_number;
+  Handle mirror (THREAD, method->method_holder()->java_mirror());
+  java_lang_StackTraceElement::decode(mirror, method, bci, method_name_sym, file_name_sym, line_number);
+
+  InstanceKlass* holder = method->method_holder();
+  const char* declaring_class_str = holder->external_name();
+
+  if (is_hotspot()) {
+    HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject()));
+    oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject()));
+    Handle obj = Handle(THREAD, objOop);
+
+    oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject()));
+    HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class);
+
+    oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject()));
+    HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name);
+
+    if (file_name_sym != NULL) {
+      oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject()));
+      HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name);
+    }
+    HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number);
+    return wrap(obj());
+  } else {
+    JNIAccessMark jni(this);
+    jobject declaring_class = jni()->NewStringUTF(declaring_class_str);
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string());
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+    jobject file_name = NULL;
+    if (file_name != NULL) {
+      file_name = jni()->NewStringUTF(file_name_sym->as_C_string());
+      if (jni()->ExceptionCheck()) {
+        return JVMCIObject();
+      }
+    }
+
+    jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(),
+                                      JNIJVMCI::StackTraceElement::constructor(),
+                                      declaring_class, method_name, file_name, line_number);
+    return wrap(result);
+  }
+}
+
+JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
+  JavaThread* THREAD = JavaThread::current();
+
+  JVMCIObject methodObject = get_jvmci_method(method(), JVMCI_CHECK_(JVMCIObject()));
+
+  if (is_hotspot()) {
+    InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass());
+    if (ik->should_be_initialized()) {
+      ik->initialize(CHECK_(JVMCIObject()));
+    }
+    oop obj = ik->allocate_instance(CHECK_(JVMCIObject()));
+    Handle obj_h(THREAD, obj);
+    Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject()));
+
+    // Call constructor
+    JavaCallArguments jargs;
+    jargs.push_oop(obj_h);
+    jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject)));
+    jargs.push_oop(nameStr);
+    jargs.push_int(isDefault);
+    jargs.push_long(compileId);
+    JavaValue result(T_VOID);
+    JavaCalls::call_special(&result, ik,
+                            vmSymbols::object_initializer_name(),
+                            vmSymbols::method_string_bool_long_signature(),
+                            &jargs, CHECK_(JVMCIObject()));
+    return wrap(obj_h());
+  } else {
+    JNIAccessMark jni(this);
+    jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name);
+    if (jni()->ExceptionCheck()) {
+      return JVMCIObject();
+    }
+
+    jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(),
+                                      JNIJVMCI::HotSpotNmethod::constructor(),
+                                      methodObject.as_jobject(), nameStr, isDefault);
+    return wrap(result);
+  }
+}
+
+JVMCIObject JVMCIEnv::make_local(JVMCIObject object) {
+  if (object.is_null()) {
+    return JVMCIObject();
+  }
+  if (is_hotspot()) {
+    return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object)));
+  } else {
+    JNIAccessMark jni(this);
+    return wrap(jni()->NewLocalRef(object.as_jobject()));
+  }
+}
+
+JVMCIObject JVMCIEnv::make_global(JVMCIObject object) {
+  if (object.is_null()) {
+    return JVMCIObject();
+  }
+  if (is_hotspot()) {
+    return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
+  } else {
+    JNIAccessMark jni(this);
+    return wrap(jni()->NewGlobalRef(object.as_jobject()));
+  }
+}
+
+JVMCIObject JVMCIEnv::make_weak(JVMCIObject object) {
+  if (object.is_null()) {
+    return JVMCIObject();
+  }
+  if (is_hotspot()) {
+    return wrap(JNIHandles::make_weak_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object))));
+  } else {
+    JNIAccessMark jni(this);
+    return wrap(jni()->NewWeakGlobalRef(object.as_jobject()));
+  }
+}
+
+void JVMCIEnv::destroy_local(JVMCIObject object) {
+  if (is_hotspot()) {
+    JNIHandles::destroy_local(object.as_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jni()->DeleteLocalRef(object.as_jobject());
+  }
+}
+
+void JVMCIEnv::destroy_global(JVMCIObject object) {
+  if (is_hotspot()) {
+    JNIHandles::destroy_global(object.as_jobject());
+  } else {
+    JNIAccessMark jni(this);
+    jni()->DeleteGlobalRef(object.as_jobject());
+  }
+}
+
+void JVMCIEnv::destroy_weak(JVMCIObject object) {
+  if (is_hotspot()) {
+    JNIHandles::destroy_weak_global(object.as_jweak());
+  } else {
+    JNIAccessMark jni(this);
+    jni()->DeleteWeakGlobalRef(object.as_jweak());
+  }
+}
+
+const char* JVMCIEnv::klass_name(JVMCIObject object) {
+  if (is_hotspot()) {
+    return HotSpotJVMCI::resolve(object)->klass()->signature_name();
+  } else {
+    JVMCIObject name;
+    {
+      JNIAccessMark jni(this);
+      jclass jcl = jni()->GetObjectClass(object.as_jobject());
+      jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method());
+      name = JVMCIObject::create(result, is_hotspot());
+    }
+    return as_utf8_string(name);
+  }
+}
+
+JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) {
+  JVMCIObject method_object;
+  if (method() == NULL) {
+    return method_object;
   }
 
-  return found_klass;
+  Thread* THREAD = Thread::current();
+  jmetadata handle = JVMCI::allocate_handle(method);
+  jboolean exception = false;
+  if (is_hotspot()) {
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args;
+    args.push_long((jlong) handle);
+    JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(),
+                           vmSymbols::fromMetaspace_name(),
+                           vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
+    if (HAS_PENDING_EXCEPTION) {
+      exception = true;
+    } else {
+      method_object = wrap((oop)result.get_jobject());
+    }
+  } else {
+    JNIAccessMark jni(this);
+    method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
+                                                                  JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
+                                                                  (jlong) handle));
+    exception = jni()->ExceptionCheck();
+  }
+
+  if (exception) {
+    JVMCI::release_handle(handle);
+    return JVMCIObject();
+  }
+
+  assert(asMethod(method_object) == method(), "must be");
+  if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) {
+    JVMCI::release_handle(handle);
+  }
+  assert(!method_object.is_null(), "must be");
+  return method_object;
 }
 
-// ------------------------------------------------------------------
-Klass* JVMCIEnv::get_klass_by_name(Klass* accessing_klass,
-                                  Symbol* klass_name,
-                                  bool require_local) {
-  ResourceMark rm;
-  constantPoolHandle cpool;
-  return get_klass_by_name_impl(accessing_klass,
-                                cpool,
-                                klass_name,
-                                require_local);
+JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) {
+  JVMCIObject type;
+  if (klass.is_null()) {
+    return type;
+  }
+#ifdef INCLUDE_ALL_GCS
+    if (UseG1GC) {
+      // The klass might have come from a weak location so enqueue
+      // the Class to make sure it's noticed by G1
+      G1SATBCardTableModRefBS::enqueue(klass()->java_mirror());
+    }
+#endif  // Klass* don't require tracking as Metadata*
+
+  jlong pointer = (jlong) klass();
+  JavaThread* THREAD = JavaThread::current();
+  JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));
+  jboolean exception = false;
+  if (is_hotspot()) {
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args;
+    args.push_long(pointer);
+    args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature)));
+    JavaCalls::call_static(&result,
+                           HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(),
+                           vmSymbols::fromMetaspace_name(),
+                           vmSymbols::klass_fromMetaspace_signature(), &args, THREAD);
+
+    if (HAS_PENDING_EXCEPTION) {
+      exception = true;
+    } else {
+      type = wrap((oop)result.get_jobject());
+    }
+  } else {
+    JNIAccessMark jni(this);
+
+    HandleMark hm(THREAD);
+    type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(),
+                                                        JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(),
+                                                        pointer, signature.as_jstring()));
+    exception = jni()->ExceptionCheck();
+  }
+  if (exception) {
+    return JVMCIObject();
+  }
+
+  assert(type.is_non_null(), "must have result");
+  return type;
 }
 
-// ------------------------------------------------------------------
-// Implementation of get_klass_by_index.
-Klass* JVMCIEnv::get_klass_by_index_impl(const constantPoolHandle& cpool,
-                                        int index,
-                                        bool& is_accessible,
-                                        Klass* accessor) {
-  JVMCI_EXCEPTION_CONTEXT;
-  Klass* klass = ConstantPool::klass_at_if_loaded(cpool, index);
-  Symbol* klass_name = NULL;
-  if (klass == NULL) {
-    klass_name = cpool->klass_name_at(index);
+JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) {
+  JVMCIObject cp_object;
+  jmetadata handle = JVMCI::allocate_handle(cp);
+  jboolean exception = false;
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args;
+    args.push_long((jlong) handle);
+    JavaCalls::call_static(&result,
+                           HotSpotJVMCI::HotSpotConstantPool::klass(),
+                           vmSymbols::fromMetaspace_name(),
+                           vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD);
+    if (HAS_PENDING_EXCEPTION) {
+      exception = true;
+    } else {
+      cp_object = wrap((oop)result.get_jobject());
+    }
+  } else {
+    JNIAccessMark jni(this);
+    cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(),
+                                                             JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(),
+                                                             (jlong) handle));
+    exception = jni()->ExceptionCheck();
   }
 
-  if (klass == NULL) {
-    // Not found in constant pool.  Use the name to do the lookup.
-    Klass* k = get_klass_by_name_impl(accessor,
-                                      cpool,
-                                      klass_name,
-                                      false);
-    // Calculate accessibility the hard way.
-    if (k == NULL) {
-      is_accessible = false;
-    } else if (k->class_loader() != accessor->class_loader() &&
-               get_klass_by_name_impl(accessor, cpool, k->name(), true) == NULL) {
-      // Loaded only remotely.  Not linked yet.
-      is_accessible = false;
-    } else {
-      // Linked locally, and we must also check public/private, etc.
-      is_accessible = check_klass_accessibility(accessor, k);
-    }
-    if (!is_accessible) {
-      return NULL;
-    }
-    return k;
+  if (exception) {
+    JVMCI::release_handle(handle);
+    return JVMCIObject();
   }
 
-  // It is known to be accessible, since it was found in the constant pool.
-  is_accessible = true;
-  return klass;
+  assert(!cp_object.is_null(), "must be");
+  // Constant pools aren't cached so this is always a newly created object using the handle
+  assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle");
+  return cp_object;
 }
 
-// ------------------------------------------------------------------
-// Get a klass from the constant pool.
-Klass* JVMCIEnv::get_klass_by_index(const constantPoolHandle& cpool,
-                                    int index,
-                                    bool& is_accessible,
-                                    Klass* accessor) {
-  ResourceMark rm;
-  return get_klass_by_index_impl(cpool, index, is_accessible, accessor);
+JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) {
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject()));
+    return wrap(result);
+  } else {
+    JNIAccessMark jni(this);
+    jbooleanArray result = jni()->NewBooleanArray(length);
+    return wrap(result);
+  }
 }
 
-// ------------------------------------------------------------------
-// Implementation of get_field_by_index.
-//
-// Implementation note: the results of field lookups are cached
-// in the accessor klass.
-void JVMCIEnv::get_field_by_index_impl(InstanceKlass* klass, fieldDescriptor& field_desc,
-                                        int index) {
-  JVMCI_EXCEPTION_CONTEXT;
+JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) {
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject()));
+    return wrap(result);
+  } else {
+    JNIAccessMark jni(this);
+    jbyteArray result = jni()->NewByteArray(length);
+    return wrap(result);
+  }
+}
 
-  assert(klass->is_linked(), "must be linked before using its constant-pool");
+JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) {
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj  ())->array_klass(CHECK_(JVMCIObject()));
+    objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject()));
+    return wrap(result);
+  } else {
+    JNIAccessMark jni(this);
+    jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL);
+    return wrap(result);
+  }
+}
 
-  constantPoolHandle cpool(thread, klass->constants());
+JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) {
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject()));
+    return wrap(result);
+  } else {
+    JNIAccessMark jni(this);
+    jintArray result = jni()->NewIntArray(length);
+    return wrap(result);
+  }
+}
 
-  // Get the field's name, signature, and type.
-  Symbol* name  = cpool->name_ref_at(index);
+JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) {
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject()));
+    return wrap(result);
+  } else {
+    JNIAccessMark jni(this);
+    jlongArray result = jni()->NewLongArray(length);
+    return wrap(result);
+  }
+}
 
-  int nt_index = cpool->name_and_type_ref_index_at(index);
-  int sig_index = cpool->signature_ref_index_at(nt_index);
-  Symbol* signature = cpool->symbol_at(sig_index);
+JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) {
+  if (is_hotspot()) {
+    JavaThread* THREAD = JavaThread::current();
+    HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject()));
+    oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject()));
+    HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name));
+    HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type));
+    HotSpotJVMCI::VMField::set_offset(this, obj, offset);