changeset 22454:76af33d4d504

Make jvmci redefinition safe
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Fri, 21 Aug 2015 11:57:29 -0700
parents d6bbd5d8d81e
children 7ad03bf3d4a9
files jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVM.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVMImpl.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotConstantPool.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIMetaAccessContext.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMemoryAccessProviderImpl.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMetaAccessProvider.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethodData.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethodHandleAccessProvider.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectType.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotStackFrameReference.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVMEventListener.java jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/MetaspaceWrapperObject.java jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIGlobalMetaAccessContext.java jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIMetaAccessContext.java jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIThreadLocalMetaAccessContext.java jvmci/jdk.internal.jvmci.runtime.test/src/jdk/internal/jvmci/runtime/test/RedefineClassTest.java src/share/vm/classfile/metadataOnStackMark.cpp src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/jvmci/jvmciCodeInstaller.cpp src/share/vm/jvmci/jvmciCompiler.cpp src/share/vm/jvmci/jvmciCompilerToVM.cpp src/share/vm/jvmci/jvmciCompilerToVM.hpp src/share/vm/jvmci/jvmciJavaAccess.cpp src/share/vm/jvmci/jvmciJavaAccess.hpp src/share/vm/jvmci/jvmciRuntime.cpp src/share/vm/jvmci/jvmciRuntime.hpp
diffstat 30 files changed, 1113 insertions(+), 714 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVM.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVM.java	Fri Aug 21 11:57:29 2015 -0700
@@ -32,26 +32,26 @@
 
 /**
  * Calls from Java into HotSpot. The behavior of all the methods in this class that take a metaspace
- * pointer as an argument (e.g., {@link #getExceptionTableStart(long)}) is undefined if the argument
- * does not denote a valid metaspace object.
+ * pointer as an argument (e.g., {@link #getExceptionTableStart(HotSpotResolvedJavaMethodImpl)}) is
+ * undefined if the argument does not denote a valid metaspace object.
  */
 public interface CompilerToVM {
 
     /**
-     * Copies the original bytecode of {@code metaspaceMethod} into a new byte array and returns it.
+     * Copies the original bytecode of {@code method} into a new byte array and returns it.
      *
-     * @return a new byte array containing the original bytecode of {@code metaspaceMethod}
+     * @return a new byte array containing the original bytecode of {@code method}
      */
-    byte[] getBytecode(long metaspaceMethod);
+    byte[] getBytecode(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Gets the number of entries in {@code metaspaceMethod}'s exception handler table or 0 if it
-     * has not exception handler table.
+     * Gets the number of entries in {@code method}'s exception handler table or 0 if it has not
+     * exception handler table.
      */
-    int getExceptionTableLength(long metaspaceMethod);
+    int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Gets the address of the first entry in {@code metaspaceMethod}'s exception handler table.
+     * Gets the address of the first entry in {@code method}'s exception handler table.
      *
      * Each entry is a native object described by these fields:
      *
@@ -63,45 +63,44 @@
      * <li>{@link HotSpotVMConfig#exceptionTableElementCatchTypeIndexOffset}
      * </ul>
      *
-     * @return 0 if {@code metaspaceMethod} has no exception handlers (i.e.
-     *         {@code getExceptionTableLength(metaspaceMethod) == 0})
+     * @return 0 if {@code method} has no exception handlers (i.e.
+     *         {@code getExceptionTableLength(method) == 0})
      */
-    long getExceptionTableStart(long metaspaceMethod);
+    long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Determines if {@code metaspaceMethod} has balanced monitors.
+     * Determines if {@code method} has balanced monitors.
      */
-    boolean hasBalancedMonitors(long metaspaceMethod);
+    boolean hasBalancedMonitors(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Determines if {@code metaspaceMethod} can be inlined. A method may not be inlinable for a
-     * number of reasons such as:
+     * Determines if {@code method} can be inlined. A method may not be inlinable for a number of
+     * reasons such as:
      * <ul>
      * <li>a CompileOracle directive may prevent inlining or compilation of methods</li>
      * <li>the method may have a bytecode breakpoint set</li>
      * <li>the method may have other bytecode features that require special handling by the VM</li>
      * </ul>
      */
-    boolean canInlineMethod(long metaspaceMethod);
+    boolean canInlineMethod(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Determines if {@code metaspaceMethod} should be inlined at any cost. This could be because:
+     * Determines if {@code method} should be inlined at any cost. This could be because:
      * <ul>
      * <li>a CompileOracle directive may forces inlining of this methods</li>
      * <li>an annotation forces inlining of this method</li>
      * </ul>
      */
-    boolean shouldInlineMethod(long metaspaceMethod);
+    boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Used to implement {@link ResolvedJavaType#findUniqueConcreteMethod(ResolvedJavaMethod)}.
      *
-     * @param metaspaceMethod the metaspace Method on which to base the search
-     * @param actualHolderMetaspaceKlass the best known type of receiver
-     * @return the metaspace Method result or 0 is there is no unique concrete method for
-     *         {@code metaspaceMethod}
+     * @param method the method on which to base the search
+     * @param actualHolderKlass the best known type of receiver
+     * @return the method result or 0 is there is no unique concrete method for {@code method}
      */
-    long findUniqueConcreteMethod(long actualHolderMetaspaceKlass, long metaspaceMethod);
+    HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl actualHolderKlass, HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Gets the implementor for the interface class {@code metaspaceKlass}.
@@ -109,12 +108,12 @@
      * @return the implementor if there is a single implementor, 0 if there is no implementor, or
      *         {@code metaspaceKlass} itself if there is more than one implementor
      */
-    long getKlassImplementor(long metaspaceKlass);
+    HotSpotResolvedObjectTypeImpl getKlassImplementor(HotSpotResolvedObjectTypeImpl klass);
 
     /**
-     * Determines if {@code metaspaceMethod} is ignored by security stack walks.
+     * Determines if {@code method} is ignored by security stack walks.
      */
-    boolean methodIsIgnoredBySecurityStackWalk(long metaspaceMethod);
+    boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Converts a name to a metaspace Klass.
@@ -127,77 +126,75 @@
      *         {@code resolve == false}
      * @throws LinkageError if {@code resolve == true} and the resolution failed
      */
-    long lookupType(String name, Class<?> accessingClass, boolean resolve);
+    HotSpotResolvedObjectTypeImpl lookupType(String name, Class<?> accessingClass, boolean resolve);
 
     /**
-     * Resolves the entry at index {@code cpi} in {@code metaspaceConstantPool} to an object.
+     * Resolves the entry at index {@code cpi} in {@code constantPool} to an object.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote an entry that can be
      * resolved to an object.
      */
-    Object resolveConstantInPool(long metaspaceConstantPool, int cpi);
+    Object resolveConstantInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
-     * Resolves the entry at index {@code cpi} in {@code metaspaceConstantPool} to an object,
-     * looking in the constant pool cache first.
+     * Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the
+     * constant pool cache first.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote an entry that can be
      * resolved to an object.
      */
-    Object resolvePossiblyCachedConstantInPool(long metaspaceConstantPool, int cpi);
+    Object resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
      * Gets the {@code JVM_CONSTANT_NameAndType} index from the entry at index {@code cpi} in
-     * {@code metaspaceConstantPool}.
+     * {@code constantPool}.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote an entry containing a
      * {@code JVM_CONSTANT_NameAndType} index.
      */
-    int lookupNameAndTypeRefIndexInPool(long metaspaceConstantPool, int cpi);
+    int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
      * Gets the name of the {@code JVM_CONSTANT_NameAndType} entry at index {@code cpi} in
-     * {@code metaspaceConstantPool}.
+     * {@code constantPool}.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote a
      * {@code JVM_CONSTANT_NameAndType} entry.
      */
-    String lookupNameRefInPool(long metaspaceConstantPool, int cpi);
+    String lookupNameRefInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
      * Gets the signature of the {@code JVM_CONSTANT_NameAndType} entry at index {@code cpi} in
-     * {@code metaspaceConstantPool}.
+     * {@code constantPool}.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote a
      * {@code JVM_CONSTANT_NameAndType} entry.
      */
-    String lookupSignatureRefInPool(long metaspaceConstantPool, int cpi);
+    String lookupSignatureRefInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
      * Gets the {@code JVM_CONSTANT_Class} index from the entry at index {@code cpi} in
-     * {@code metaspaceConstantPool}.
+     * {@code constantPool}.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote an entry containing a
      * {@code JVM_CONSTANT_Class} index.
      */
-    int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi);
+    int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
      * Looks up a class denoted by the {@code JVM_CONSTANT_Class} entry at index {@code cpi} in
-     * {@code metaspaceConstantPool}. This method does not perform any resolution.
+     * {@code constantPool}. This method does not perform any resolution.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote a
      * {@code JVM_CONSTANT_Class} entry.
      *
-     * @return a metaspace Klass for a resolved class entry (tagged by
-     *         {@link HotSpotVMConfig#compilerToVMKlassTag}) or a metaspace Symbol otherwise (tagged
-     *         by {@link HotSpotVMConfig#compilerToVMSymbolTag})
+     * @return a HotSpotResolvedObjectTypeImpl for a resolved class entry or a String otherwise
      */
-    long lookupKlassInPool(long metaspaceConstantPool, int cpi);
+    Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
-     * Looks up a method denoted by the entry at index {@code cpi} in {@code metaspaceConstantPool}.
-     * This method does not perform any resolution.
+     * Looks up a method denoted by the entry at index {@code cpi} in {@code constantPool}. This
+     * method does not perform any resolution.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
      * a method.
@@ -208,42 +205,42 @@
      *            checks fail, 0 is returned.
      * @return a metaspace Method for a resolved method entry, 0 otherwise
      */
-    long lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool, int cpi, byte opcode);
 
     /**
      * Ensures that the type referenced by the specified {@code JVM_CONSTANT_InvokeDynamic} entry at
-     * index {@code cpi} in {@code metaspaceConstantPool} is loaded and initialized.
+     * index {@code cpi} in {@code constantPool} is loaded and initialized.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote a
      * {@code JVM_CONSTANT_InvokeDynamic} entry.
      */
-    void resolveInvokeDynamicInPool(long metaspaceConstantPool, int cpi);
+    void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
      * Ensures that the type referenced by the entry for a <a
      * href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
-     * polymorphic</a> method at index {@code cpi} in {@code metaspaceConstantPool} is loaded and
+     * polymorphic</a> method at index {@code cpi} in {@code constantPool} is loaded and
      * initialized.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
      * a signature polymorphic method.
      */
-    void resolveInvokeHandleInPool(long metaspaceConstantPool, int cpi);
+    void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
      * Gets the resolved metaspace Klass denoted by the entry at index {@code cpi} in
-     * {@code metaspaceConstantPool}.
+     * {@code constantPool}.
      *
      * The behavior of this method is undefined if {@code cpi} does not denote an entry representing
      * a class.
      *
      * @throws LinkageError if resolution failed
      */
-    long resolveKlassInPool(long metaspaceConstantPool, int cpi) throws LinkageError;
+    HotSpotResolvedObjectTypeImpl resolveKlassInPool(HotSpotConstantPool constantPool, int cpi) throws LinkageError;
 
     /**
      * Looks up and attempts to resolve the {@code JVM_CONSTANT_Field} entry at index {@code cpi} in
-     * {@code metaspaceConstantPool}. The values returned in {@code info} are:
+     * {@code constantPool}. The values returned in {@code info} are:
      *
      * <pre>
      *     [(int) flags,   // only valid if field is resolved
@@ -256,22 +253,22 @@
      * @param info an array in which the details of the field are returned
      * @return the metaspace Klass defining the field if resolution is successful, 0 otherwise
      */
-    long resolveFieldInPool(long metaspaceConstantPool, int cpi, byte opcode, long[] info);
+    HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int cpi, byte opcode, long[] info);
 
     /**
-     * Converts {@code cpci} from an index into the cache for {@code metaspaceConstantPool} to an
-     * index directly into {@code metaspaceConstantPool}.
+     * Converts {@code cpci} from an index into the cache for {@code constantPool} to an index
+     * directly into {@code constantPool}.
      *
      * The behavior of this method is undefined if {@code ccpi} is an invalid constant pool cache
      * index.
      */
-    int constantPoolRemapInstructionOperandFromCache(long metaspaceConstantPool, int cpci);
+    int constantPoolRemapInstructionOperandFromCache(HotSpotConstantPool constantPool, int cpci);
 
     /**
      * Gets the appendix object (if any) associated with the entry at index {@code cpi} in
-     * {@code metaspaceConstantPool}.
+     * {@code constantPool}.
      */
-    Object lookupAppendixInPool(long metaspaceConstantPool, int cpi);
+    Object lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
      * Installs the result of a compilation into the code cache.
@@ -299,7 +296,7 @@
      * @param timeUnitsPerSecond the granularity of the units for the {@code time} value
      * @param installedCode the nmethod installed as a result of the compilation
      */
-    void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, InstalledCode installedCode);
+    void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethodImpl method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, InstalledCode installedCode);
 
     /**
      * Resets all compilation statistics.
@@ -312,35 +309,35 @@
     void initializeConfiguration(HotSpotVMConfig config);
 
     /**
-     * Resolves the implementation of {@code metaspaceMethod} for virtual dispatches on objects of
-     * dynamic type {@code metaspaceKlassExactReceiver}. This resolution process only searches "up"
-     * the class hierarchy of {@code metaspaceKlassExactReceiver}.
+     * Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic
+     * type {@code metaspaceKlassExactReceiver}. This resolution process only searches "up" the
+     * class hierarchy of {@code metaspaceKlassExactReceiver}.
      *
-     * @param metaspaceKlassCaller the caller or context type used to perform access checks
+     * @param klassCaller the caller or context type used to perform access checks
      * @return the link-time resolved method (might be abstract) or {@code 0} if it can not be
      *         linked
      */
-    long resolveMethod(long metaspaceKlassExactReceiver, long metaspaceMethod, long metaspaceKlassCaller);
+    HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl klassExactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl klassCaller);
 
     /**
      * Gets the static initializer of {@code metaspaceKlass}.
      *
      * @return 0 if {@code metaspaceKlass} has no static initialize
      */
-    long getClassInitializer(long metaspaceKlass);
+    HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl klass);
 
     /**
      * Determines if {@code metaspaceKlass} or any of its currently loaded subclasses overrides
      * {@code Object.finalize()}.
      */
-    boolean hasFinalizableSubclass(long metaspaceKlass);
+    boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl klass);
 
     /**
-     * Gets the metaspace Method corresponding to {@code holder} and slot number {@code slot} (i.e.
+     * Gets the method corresponding to {@code holder} and slot number {@code slot} (i.e.
      * {@link Method#slot} or {@link Constructor#slot}).
      */
     @SuppressWarnings("javadoc")
-    long getMetaspaceMethod(Class<?> holder, int slot);
+    HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot(Class<?> holder, int slot);
 
     /**
      * Gets the maximum absolute offset of a PC relative call to {@code address} from any position
@@ -360,9 +357,9 @@
     String disassembleCodeBlob(long codeBlob);
 
     /**
-     * Gets a stack trace element for {@code metaspaceMethod} at bytecode index {@code bci}.
+     * Gets a stack trace element for {@code method} at bytecode index {@code bci}.
      */
-    StackTraceElement getStackTraceElement(long metaspaceMethod, int bci);
+    StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, int bci);
 
     /**
      * Executes some {@code installedCode} with arguments {@code args}.
@@ -373,22 +370,22 @@
     Object executeInstalledCode(Object[] args, InstalledCode installedCode) throws InvalidInstalledCodeException;
 
     /**
-     * Gets the line number table for {@code metaspaceMethod}. The line number table is encoded as
-     * (bci, source line number) pairs.
+     * Gets the line number table for {@code method}. The line number table is encoded as (bci,
+     * source line number) pairs.
      *
-     * @return the line number table for {@code metaspaceMethod} or null if it doesn't have one
+     * @return the line number table for {@code method} or null if it doesn't have one
      */
-    long[] getLineNumberTable(long metaspaceMethod);
+    long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Gets the number of entries in the local variable table for {@code metaspaceMethod}.
+     * Gets the number of entries in the local variable table for {@code method}.
      *
-     * @return the number of entries in the local variable table for {@code metaspaceMethod}
+     * @return the number of entries in the local variable table for {@code method}
      */
-    int getLocalVariableTableLength(long metaspaceMethod);
+    int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Gets the address of the first entry in the local variable table for {@code metaspaceMethod}.
+     * Gets the address of the first entry in the local variable table for {@code method}.
      *
      * Each entry is a native object described by these fields:
      *
@@ -402,14 +399,14 @@
      * <li>{@link HotSpotVMConfig#localVariableTableElementStartBciOffset}
      * </ul>
      *
-     * @return 0 if {@code metaspaceMethod} does not have a local variable table
+     * @return 0 if {@code method} does not have a local variable table
      */
-    long getLocalVariableTableStart(long metaspaceMethod);
+    long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Gets the {@link Class} mirror associated with {@code metaspaceKlass}.
      */
-    Class<?> getJavaMirror(long metaspaceKlass);
+    Class<?> getJavaMirror(HotSpotResolvedObjectTypeImpl klass);
 
     /**
      * Reads an object pointer within a VM data structure. That is, any {@link HotSpotVMField} whose
@@ -426,15 +423,15 @@
     Object readUncompressedOop(long address);
 
     /**
-     * Determines if {@code metaspaceMethod} should not be inlined or compiled.
+     * Determines if {@code method} should not be inlined or compiled.
      */
-    void doNotInlineOrCompile(long metaspaceMethod);
+    void doNotInlineOrCompile(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Invalidates the profiling information for {@code metaspaceMethod} and (re)initializes it such
-     * that profiling restarts upon its next invocation.
+     * Invalidates the profiling information for {@code method} and (re)initializes it such that
+     * profiling restarts upon its next invocation.
      */
-    void reprofile(long metaspaceMethod);
+    void reprofile(HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be
@@ -455,7 +452,7 @@
     /**
      * Generate a unique id to identify the result of the compile.
      */
-    int allocateCompileId(long metaspaceMethod, int entryBCI);
+    int allocateCompileId(HotSpotResolvedJavaMethodImpl method, int entryBCI);
 
     /**
      * Gets the names of the supported GPU architectures.
@@ -465,10 +462,10 @@
     String getGPUs();
 
     /**
-     * Determines if {@code metaspaceMethod} has OSR compiled code identified by {@code entryBCI}
-     * for compilation level {@code level}.
+     * Determines if {@code method} has OSR compiled code identified by {@code entryBCI} for
+     * compilation level {@code level}.
      */
-    boolean hasCompiledCodeForOSR(long metaspaceMethod, int entryBCI, int level);
+    boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, int entryBCI, int level);
 
     /**
      * Fetch the time stamp used for printing inside hotspot. It's relative to VM start so that all
@@ -491,7 +488,7 @@
      *            returned
      * @return the frame, or {@code null} if the end of the stack was reached during the search
      */
-    HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, long[] methods, int initialSkip);
+    HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, HotSpotResolvedJavaMethodImpl[] methods, int initialSkip);
 
     /**
      * Materializes all virtual objects within {@code stackFrame} updates its locals.
@@ -502,11 +499,11 @@
     void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
 
     /**
-     * Gets the v-table index for interface method {@code metaspaceMethod} in the receiver type
-     * {@code metaspaceKlass} or {@link HotSpotVMConfig#invalidVtableIndex} if
-     * {@code metaspaceMethod} is not in {@code metaspaceKlass}'s v-table.
+     * Gets the v-table index for interface method {@code method} in the receiver type
+     * {@code metaspaceKlass} or {@link HotSpotVMConfig#invalidVtableIndex} if {@code method} is not
+     * in {@code metaspaceKlass}'s v-table.
      */
-    int getVtableIndexForInterface(long metaspaceKlass, long metaspaceMethod);
+    int getVtableIndexForInterface(HotSpotResolvedObjectTypeImpl klass, HotSpotResolvedJavaMethodImpl method);
 
     /**
      * Determines if debug info should also be emitted at non-safepoint locations.
@@ -523,4 +520,44 @@
      * Flush HotSpot's log stream.
      */
     void flushDebugOutput();
+
+    /**
+     * Read a value representing a metaspace Method* and return the
+     * {@link HotSpotResolvedJavaMethodImpl} wrapping it. This method does no checking that the
+     * location actually contains a valid Method*. If the {@code base} object is a
+     * {@link MetaspaceWrapperObject} then the metaspace pointer is fetched from that object and
+     * used as the base. Otherwise the object itself is used as the base.
+     *
+     * @param base an object to read from or null
+     * @param displacement
+     * @return null or the resolved method for this location
+     */
+    HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement);
+
+    /**
+     * Read a value representing a metaspace ConstantPool* and return the
+     * {@link HotSpotConstantPool} wrapping it. This method does no checking that the location
+     * actually contains a valid ConstantPool*. If the {@code base} object is a
+     * {@link MetaspaceWrapperObject} then the metaspace pointer is fetched from that object and
+     * used as the base. Otherwise the object itself is used as the base.
+     *
+     * @param base an object to read from or null
+     * @param displacement
+     * @return null or the resolved method for this location
+     */
+    HotSpotConstantPool getConstantPool(Object base, long displacement);
+
+    /**
+     * Read a value representing a metaspace Klass* and return the
+     * {@link HotSpotResolvedObjectTypeImpl} wrapping it. The method does no checking that the
+     * location actually contains a valid Klass*. If the {@code base} object is a
+     * {@link MetaspaceWrapperObject} then the metaspace pointer is fetched from that object and
+     * used as the base. Otherwise the object itself is used as the base.
+     *
+     * @param base an object to read from or null
+     * @param displacement
+     * @param compressed true if the location contains a compressed Klass*
+     * @return null or the resolved method for this location
+     */
+    HotSpotResolvedObjectTypeImpl getResolvedJavaType(Object base, long displacement, boolean compressed);
 }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVMImpl.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVMImpl.java	Fri Aug 21 11:57:29 2015 -0700
@@ -49,104 +49,104 @@
     public native int installCode(HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog);
 
     @Override
-    public native long getMetaspaceMethod(Class<?> holder, int slot);
+    public native HotSpotResolvedJavaMethodImpl getResolvedJavaMethodAtSlot(Class<?> holder, int slot);
 
     @Override
-    public native byte[] getBytecode(long metaspaceMethod);
+    public native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native int getExceptionTableLength(long metaspaceMethod);
+    public native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native long getExceptionTableStart(long metaspaceMethod);
+    public native long getExceptionTableStart(HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native boolean hasBalancedMonitors(long metaspaceMethod);
+    public native boolean hasBalancedMonitors(HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native long findUniqueConcreteMethod(long actualHolderMetaspaceKlass, long metaspaceMethod);
+    public native HotSpotResolvedJavaMethodImpl findUniqueConcreteMethod(HotSpotResolvedObjectTypeImpl actualHolderKlass, HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native long getKlassImplementor(long metaspaceKlass);
+    public native HotSpotResolvedObjectTypeImpl getKlassImplementor(HotSpotResolvedObjectTypeImpl klass);
 
     @Override
-    public native long lookupType(String name, Class<?> accessingClass, boolean eagerResolve);
+    public native HotSpotResolvedObjectTypeImpl lookupType(String name, Class<?> accessingClass, boolean eagerResolve);
 
-    public native Object resolveConstantInPool(long metaspaceConstantPool, int cpi);
+    public native Object resolveConstantInPool(HotSpotConstantPool constantPool, int cpi);
 
-    public Object resolvePossiblyCachedConstantInPool(long metaspaceConstantPool, int cpi) {
+    public Object resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi) {
         JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), "");
-        return resolvePossiblyCachedConstantInPool0(metaspaceConstantPool, cpi);
+        return resolvePossiblyCachedConstantInPool0(constantPool, cpi);
     }
 
-    private native Object resolvePossiblyCachedConstantInPool0(long metaspaceConstantPool, int cpi);
+    private native Object resolvePossiblyCachedConstantInPool0(HotSpotConstantPool constantPool, int cpi);
 
     @Override
-    public native int lookupNameAndTypeRefIndexInPool(long metaspaceConstantPool, int cpi);
+    public native int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int cpi);
 
     @Override
-    public String lookupNameRefInPool(long metaspaceConstantPool, int cpi) {
+    public String lookupNameRefInPool(HotSpotConstantPool constantPool, int cpi) {
         JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), "");
-        return lookupNameRefInPool0(metaspaceConstantPool, cpi);
+        return lookupNameRefInPool0(constantPool, cpi);
     }
 
-    private native String lookupNameRefInPool0(long metaspaceConstantPool, int cpi);
+    private native String lookupNameRefInPool0(HotSpotConstantPool constantPool, int cpi);
 
     @Override
-    public String lookupSignatureRefInPool(long metaspaceConstantPool, int cpi) {
+    public String lookupSignatureRefInPool(HotSpotConstantPool constantPool, int cpi) {
         JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), "");
-        return lookupSignatureRefInPool0(metaspaceConstantPool, cpi);
+        return lookupSignatureRefInPool0(constantPool, cpi);
     }
 
-    private native String lookupSignatureRefInPool0(long metaspaceConstantPool, int cpi);
+    private native String lookupSignatureRefInPool0(HotSpotConstantPool constantPool, int cpi);
 
     @Override
-    public int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi) {
+    public int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int cpi) {
         JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), "");
-        return lookupKlassRefIndexInPool0(metaspaceConstantPool, cpi);
+        return lookupKlassRefIndexInPool0(constantPool, cpi);
     }
 
-    private native int lookupKlassRefIndexInPool0(long metaspaceConstantPool, int cpi);
+    private native int lookupKlassRefIndexInPool0(HotSpotConstantPool constantPool, int cpi);
 
-    public native long resolveKlassInPool(long metaspaceConstantPool, int cpi);
+    public native HotSpotResolvedObjectTypeImpl resolveKlassInPool(HotSpotConstantPool constantPool, int cpi);
 
     @Override
-    public native long lookupKlassInPool(long metaspaceConstantPool, int cpi);
+    public native Object lookupKlassInPool(HotSpotConstantPool constantPool, int cpi);
 
     @Override
-    public native long lookupMethodInPool(long metaspaceConstantPool, int cpi, byte opcode);
+    public native HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantPool constantPool, int cpi, byte opcode);
 
     @Override
-    public native long resolveFieldInPool(long metaspaceConstantPool, int cpi, byte opcode, long[] info);
+    public native HotSpotResolvedObjectTypeImpl resolveFieldInPool(HotSpotConstantPool constantPool, int cpi, byte opcode, long[] info);
 
-    public int constantPoolRemapInstructionOperandFromCache(long metaspaceConstantPool, int cpi) {
+    public int constantPoolRemapInstructionOperandFromCache(HotSpotConstantPool constantPool, int cpi) {
         JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), "");
-        return constantPoolRemapInstructionOperandFromCache0(metaspaceConstantPool, cpi);
+        return constantPoolRemapInstructionOperandFromCache0(constantPool, cpi);
     }
 
-    private native int constantPoolRemapInstructionOperandFromCache0(long metaspaceConstantPool, int cpi);
+    private native int constantPoolRemapInstructionOperandFromCache0(HotSpotConstantPool constantPool, int cpi);
 
     @Override
-    public Object lookupAppendixInPool(long metaspaceConstantPool, int cpi) {
+    public Object lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi) {
         JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), "");
-        return lookupAppendixInPool0(metaspaceConstantPool, cpi);
+        return lookupAppendixInPool0(constantPool, cpi);
     }
 
-    private native Object lookupAppendixInPool0(long metaspaceConstantPool, int cpi);
+    private native Object lookupAppendixInPool0(HotSpotConstantPool constantPool, int cpi);
 
     @Override
     public native void initializeConfiguration(HotSpotVMConfig config);
 
     @Override
-    public native long resolveMethod(long metaspaceKlassExactReceiver, long metaspaceMethod, long metaspaceKlassCaller);
+    public native HotSpotResolvedJavaMethodImpl resolveMethod(HotSpotResolvedObjectTypeImpl klassExactReceiver, HotSpotResolvedJavaMethodImpl method, HotSpotResolvedObjectTypeImpl klassCaller);
 
     @Override
-    public native boolean hasFinalizableSubclass(long metaspaceKlass);
+    public native boolean hasFinalizableSubclass(HotSpotResolvedObjectTypeImpl klass);
 
-    public native boolean methodIsIgnoredBySecurityStackWalk(long metaspaceMethod);
+    public native boolean methodIsIgnoredBySecurityStackWalk(HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native long getClassInitializer(long metaspaceKlass);
+    public native HotSpotResolvedJavaMethodImpl getClassInitializer(HotSpotResolvedObjectTypeImpl klass);
 
     @Override
     public native long getMaxCallTargetOffset(long address);
@@ -156,57 +156,57 @@
     public synchronized native String disassembleCodeBlob(long codeBlob);
 
     @Override
-    public native StackTraceElement getStackTraceElement(long metaspaceMethod, int bci);
+    public native StackTraceElement getStackTraceElement(HotSpotResolvedJavaMethodImpl method, int bci);
 
     @Override
     public native Object executeInstalledCode(Object[] args, InstalledCode hotspotInstalledCode);
 
     @Override
-    public native long[] getLineNumberTable(long metaspaceMethod);
+    public native long[] getLineNumberTable(HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native long getLocalVariableTableStart(long metaspaceMethod);
+    public native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native int getLocalVariableTableLength(long metaspaceMethod);
+    public native int getLocalVariableTableLength(HotSpotResolvedJavaMethodImpl method);
 
     @Override
-    public native void reprofile(long metaspaceMethod);
+    public native void reprofile(HotSpotResolvedJavaMethodImpl method);
 
     @Override
     public native void invalidateInstalledCode(InstalledCode hotspotInstalledCode);
 
     @Override
-    public native Class<?> getJavaMirror(long metaspaceKlass);
+    public native Class<?> getJavaMirror(HotSpotResolvedObjectTypeImpl klass);
 
     @Override
     public native Object readUncompressedOop(long address);
 
     @Override
-    public native void doNotInlineOrCompile(long metaspaceMethod);
+    public native void doNotInlineOrCompile(HotSpotResolvedJavaMethodImpl method);
 
-    public synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond,
+    public synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethodImpl method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond,
                     InstalledCode installedCode);
 
     public native void resetCompilationStatistics();
 
     public native long[] collectCounters();
 
-    public native boolean isMature(long method);
+    public native boolean isMature(long metaspaceMethodData);
 
-    public native int allocateCompileId(long metaspaceMethod, int entryBCI);
+    public native int allocateCompileId(HotSpotResolvedJavaMethodImpl method, int entryBCI);
 
     public String getGPUs() {
         return "";
     }
 
-    public native boolean canInlineMethod(long metaspaceMethod);
+    public native boolean canInlineMethod(HotSpotResolvedJavaMethodImpl method);
 
-    public native boolean shouldInlineMethod(long metaspaceMethod);
+    public native boolean shouldInlineMethod(HotSpotResolvedJavaMethodImpl method);
 
-    public native boolean hasCompiledCodeForOSR(long metaspaceMethod, int entryBCI, int level);
+    public native boolean hasCompiledCodeForOSR(HotSpotResolvedJavaMethodImpl method, int entryBCI, int level);
 
-    public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, long[] methods, int initialSkip);
+    public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, HotSpotResolvedJavaMethodImpl[] methods, int initialSkip);
 
     public native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
 
@@ -219,15 +219,21 @@
 
     private native String getSymbol0(long metaspaceSymbol);
 
-    public native void resolveInvokeDynamicInPool(long metaspaceConstantPool, int index);
+    public native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int index);
 
-    public native void resolveInvokeHandleInPool(long metaspaceConstantPool, int index);
+    public native void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int index);
 
-    public native int getVtableIndexForInterface(long metaspaceKlass, long metaspaceMethod);
+    public native int getVtableIndexForInterface(HotSpotResolvedObjectTypeImpl klass, HotSpotResolvedJavaMethodImpl method);
 
     public native boolean shouldDebugNonSafepoints();
 
     public native void writeDebugOutput(byte[] bytes, int offset, int length);
 
     public native void flushDebugOutput();
+
+    public native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement);
+
+    public native HotSpotConstantPool getConstantPool(Object base, long displacement);
+
+    public native HotSpotResolvedObjectTypeImpl getResolvedJavaType(Object base, long displacement, boolean compressed);
 }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotConstantPool.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotConstantPool.java	Fri Aug 21 11:57:29 2015 -0700
@@ -35,7 +35,7 @@
 /**
  * Implementation of {@link ConstantPool} for HotSpot.
  */
-public class HotSpotConstantPool implements ConstantPool, HotSpotProxified {
+public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
 
     public static class Options {
         // @formatter:off
@@ -212,7 +212,7 @@
          */
         private void queryAddress() {
             if (address == 0) {
-                address = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolCacheOffset);
+                address = unsafe.getAddress(getMetaspaceConstantPool() + runtime().getConfig().constantPoolCacheOffset);
             }
         }
 
@@ -370,7 +370,7 @@
          */
         public Object[] getArray() {
             if (resolvedReferences == null) {
-                final long handle = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolResolvedReferencesOffset);
+                final long handle = unsafe.getAddress(getMetaspaceConstantPool() + runtime().getConfig().constantPoolResolvedReferencesOffset);
                 if (handle != 0) {
                     resolvedReferences = (Object[]) runtime().getCompilerToVM().readUncompressedOop(handle + runtime().getConfig().handleHandleOffset);
                     fillReferenceMap();
@@ -385,7 +385,7 @@
          */
         private void fillReferenceMap() {
             // It is possible there is a resolved references array but no reference map.
-            final long address = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolReferenceMapOffset);
+            final long address = unsafe.getAddress(getMetaspaceConstantPool() + runtime().getConfig().constantPoolReferenceMapOffset);
             if (address != 0) {
                 final int length = unsafe.getInt(null, address + runtime().getConfig().arrayU1LengthOffset);
                 for (int i = 0; i < length; i++) {
@@ -409,7 +409,22 @@
 
     }
 
-    public HotSpotConstantPool(long metaspaceConstantPool) {
+    /**
+     * Gets the JVMCI mirror from a HotSpot constant pool.The VM is responsible for ensuring that
+     * the ConstantPool is kept alive for the duration of this call and the
+     * {@link HotSpotJVMCIMetaAccessContext} keeps it alive after that.
+     *
+     * Called from the VM.
+     *
+     * @param metaspaceConstantPool a metaspace ConstantPool object
+     * @return the {@link HotSpotConstantPool} corresponding to {@code metaspaceConstantPool}
+     */
+    @SuppressWarnings("unused")
+    private static HotSpotConstantPool fromMetaspace(long metaspaceConstantPool) {
+        return new HotSpotConstantPool(metaspaceConstantPool);
+    }
+
+    private HotSpotConstantPool(long metaspaceConstantPool) {
         this.metaspaceConstantPool = metaspaceConstantPool;
 
         // Cache constructor needs metaspaceConstantPool.
@@ -422,8 +437,7 @@
      * @return holder for this constant pool
      */
     private HotSpotResolvedObjectType getHolder() {
-        final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolHolderOffset);
-        return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
+        return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().constantPoolHolderOffset, false);
     }
 
     /**
@@ -479,6 +493,14 @@
         return ~i;
     }
 
+    public long getMetaspaceConstantPool() {
+        return metaspaceConstantPool;
+    }
+
+    public long getMetaspacePointer() {
+        return getMetaspaceConstantPool();
+    }
+
     /**
      * Gets the constant pool tag at index {@code index}.
      *
@@ -488,7 +510,7 @@
     private JVM_CONSTANT getTagAt(int index) {
         assertBounds(index);
         HotSpotVMConfig config = runtime().getConfig();
-        final long metaspaceConstantPoolTags = unsafe.getAddress(metaspaceConstantPool + config.constantPoolTagsOffset);
+        final long metaspaceConstantPoolTags = unsafe.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset);
         final int tag = unsafe.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
         if (tag == 0) {
             return null;
@@ -504,7 +526,7 @@
      */
     private long getEntryAt(int index) {
         assertBounds(index);
-        return unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+        return unsafe.getAddress(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
     }
 
     /**
@@ -515,7 +537,7 @@
      */
     private int getIntAt(int index) {
         assertTag(index, JVM_CONSTANT.Integer);
-        return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+        return unsafe.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
     }
 
     /**
@@ -526,7 +548,7 @@
      */
     private long getLongAt(int index) {
         assertTag(index, JVM_CONSTANT.Long);
-        return unsafe.getLong(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+        return unsafe.getLong(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
     }
 
     /**
@@ -537,7 +559,7 @@
      */
     private float getFloatAt(int index) {
         assertTag(index, JVM_CONSTANT.Float);
-        return unsafe.getFloat(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+        return unsafe.getFloat(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
     }
 
     /**
@@ -548,7 +570,7 @@
      */
     private double getDoubleAt(int index) {
         assertTag(index, JVM_CONSTANT.Double);
-        return unsafe.getDouble(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+        return unsafe.getDouble(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
     }
 
     /**
@@ -559,7 +581,7 @@
      */
     private int getNameAndTypeAt(int index) {
         assertTag(index, JVM_CONSTANT.NameAndType);
-        return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+        return unsafe.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
     }
 
     /**
@@ -570,7 +592,7 @@
      * @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry
      */
     private int getNameAndTypeRefIndexAt(int index) {
-        return runtime().getCompilerToVM().lookupNameAndTypeRefIndexInPool(metaspaceConstantPool, index);
+        return runtime().getCompilerToVM().lookupNameAndTypeRefIndexInPool(this, index);
     }
 
     /**
@@ -585,7 +607,7 @@
             final int nameRefIndex = getNameRefIndexAt(getNameAndTypeRefIndexAt(index));
             return new HotSpotSymbol(getEntryAt(nameRefIndex)).asString();
         } else {
-            return runtime().getCompilerToVM().lookupNameRefInPool(metaspaceConstantPool, index);
+            return runtime().getCompilerToVM().lookupNameRefInPool(this, index);
         }
     }
 
@@ -614,7 +636,7 @@
             final int signatureRefIndex = getSignatureRefIndexAt(getNameAndTypeRefIndexAt(index));
             return new HotSpotSymbol(getEntryAt(signatureRefIndex)).asString();
         } else {
-            return runtime().getCompilerToVM().lookupSignatureRefInPool(metaspaceConstantPool, index);
+            return runtime().getCompilerToVM().lookupSignatureRefInPool(this, index);
         }
     }
 
@@ -646,7 +668,7 @@
             cpi = cache.constantPoolCacheIndexToConstantPoolIndex(index);
         }
         assertTagIsFieldOrMethod(cpi);
-        final int refIndex = unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + cpi * runtime().getHostJVMCIBackend().getTarget().wordSize);
+        final int refIndex = unsafe.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + cpi * runtime().getHostJVMCIBackend().getTarget().wordSize);
         // klass ref index is in the low 16-bits.
         return refIndex & 0xFFFF;
     }
@@ -662,7 +684,7 @@
         if (Options.UseConstantPoolCacheJavaCode.getValue()) {
             return getKlassRefIndexAt(index, true);
         } else {
-            return runtime().getCompilerToVM().lookupKlassRefIndexInPool(metaspaceConstantPool, index);
+            return runtime().getCompilerToVM().lookupKlassRefIndexInPool(this, index);
         }
     }
 
@@ -678,7 +700,7 @@
             return getKlassRefIndexAt(index, false);
         } else {
             assertTagIsFieldOrMethod(index);
-            final int refIndex = unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
+            final int refIndex = unsafe.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
             // klass ref index is in the low 16-bits.
             return refIndex & 0xFFFF;
         }
@@ -717,7 +739,7 @@
 
     @Override
     public int length() {
-        return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolLengthOffset);
+        return unsafe.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolLengthOffset);
     }
 
     @Override
@@ -769,14 +791,14 @@
                         }
                     }
                 } else {
-                    string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(metaspaceConstantPool, cpi);
+                    string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
                 }
                 return HotSpotObjectConstantImpl.forObject(string);
             case MethodHandle:
             case MethodHandleInError:
             case MethodType:
             case MethodTypeInError:
-                Object obj = runtime().getCompilerToVM().resolveConstantInPool(metaspaceConstantPool, cpi);
+                Object obj = runtime().getCompilerToVM().resolveConstantInPool(this, cpi);
                 return HotSpotObjectConstantImpl.forObject(obj);
             default:
                 throw new JVMCIError("Unknown constant pool tag %s", tag);
@@ -821,7 +843,7 @@
             Cache.Entry entry = cache.getEntryAt(cacheIndex);
             appendix = entry.getAppendixIfResolved();
         } else {
-            appendix = runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index);
+            appendix = runtime().getCompilerToVM().lookupAppendixInPool(this, index);
         }
 
         if (appendix == null) {
@@ -832,41 +854,25 @@
     }
 
     /**
-     * Gets a {@link JavaType} corresponding a given metaspace Klass or a metaspace Symbol depending
-     * on the {@link HotSpotVMConfig#compilerToVMKlassTag tag}.
+     * Gets a {@link JavaType} corresponding a given resolved or unresolved type.
      *
-     * @param metaspacePointer either a metaspace Klass or a metaspace Symbol
+     * @param type either a ResolvedJavaType or a String naming a unresolved type.
      */
-    private static JavaType getJavaType(final long metaspacePointer) {
-        HotSpotJVMCIRuntime runtime = runtime();
-        HotSpotVMConfig config = runtime.getConfig();
-        if ((metaspacePointer & config.compilerToVMSymbolTag) != 0) {
-            final long metaspaceSymbol = metaspacePointer & ~config.compilerToVMSymbolTag;
-            String name;
-            if (Options.UseConstantPoolCacheJavaCode.getValue()) {
-                HotSpotSymbol symbol = new HotSpotSymbol(metaspaceSymbol);
-                name = symbol.asString();
-                // It shouldn't but just in case something went wrong...
-                if (name == null) {
-                    throw JVMCIError.shouldNotReachHere("malformed UTF-8 string in constant pool");
-                }
-            } else {
-                name = runtime.getCompilerToVM().getSymbol(metaspaceSymbol);
-            }
+    private static JavaType getJavaType(final Object type) {
+        if (type instanceof String) {
+            String name = (String) type;
             return HotSpotUnresolvedJavaType.create(runtime(), "L" + name + ";");
         } else {
-            assert (metaspacePointer & config.compilerToVMKlassTag) == 0;
-            return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspacePointer);
+            return (JavaType) type;
         }
     }
 
     @Override
     public JavaMethod lookupMethod(int cpi, int opcode) {
         final int index = rawIndexToConstantPoolIndex(cpi, opcode);
-        final long metaspaceMethod = runtime().getCompilerToVM().lookupMethodInPool(metaspaceConstantPool, index, (byte) opcode);
-        if (metaspaceMethod != 0L) {
-            HotSpotResolvedJavaMethod result = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod);
-            return result;
+        final HotSpotResolvedJavaMethod method = runtime().getCompilerToVM().lookupMethodInPool(this, index, (byte) opcode);
+        if (method != null) {
+            return method;
         } else {
             // Get the method's name and signature.
             String name = getNameRefAt(index);
@@ -876,7 +882,7 @@
                 return new HotSpotMethodUnresolved(name, signature, holder);
             } else {
                 final int klassIndex = getKlassRefIndexAt(index);
-                final long metaspacePointer = runtime().getCompilerToVM().lookupKlassInPool(metaspaceConstantPool, klassIndex);
+                final Object metaspacePointer = runtime().getCompilerToVM().lookupKlassInPool(this, klassIndex);
                 JavaType holder = getJavaType(metaspacePointer);
                 return new HotSpotMethodUnresolved(name, signature, holder);
             }
@@ -889,8 +895,8 @@
         if (elem != null && elem.lastCpi == cpi) {
             return elem.javaType;
         } else {
-            final long metaspacePointer = runtime().getCompilerToVM().lookupKlassInPool(metaspaceConstantPool, cpi);
-            JavaType result = getJavaType(metaspacePointer);
+            final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, cpi);
+            JavaType result = getJavaType(type);
             if (result instanceof ResolvedJavaType) {
                 this.lastLookupType = new LookupTypeCacheElement(cpi, result);
             }
@@ -913,9 +919,9 @@
 
         if (holder instanceof HotSpotResolvedObjectTypeImpl) {
             long[] info = new long[2];
-            long metaspaceKlass;
+            HotSpotResolvedObjectTypeImpl metaspaceKlass;
             try {
-                metaspaceKlass = runtime().getCompilerToVM().resolveFieldInPool(metaspaceConstantPool, index, (byte) opcode, info);
+                metaspaceKlass = runtime().getCompilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
             } catch (Throwable t) {
                 /*
                  * If there was an exception resolving the field we give up and return an unresolved
@@ -923,7 +929,7 @@
                  */
                 return new HotSpotUnresolvedField(holder, name, type);
             }
-            HotSpotResolvedObjectTypeImpl resolvedHolder = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
+            HotSpotResolvedObjectTypeImpl resolvedHolder = metaspaceKlass;
             final int flags = (int) info[0];
             final long offset = info[1];
             HotSpotResolvedJavaField result = resolvedHolder.createField(name, type, offset, flags);
@@ -958,7 +964,7 @@
                     // JVMCIError.guarantee(index == x, index + " != " + x);
                 } else {
                     index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag;
-                    index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index);
+                    index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
                 }
                 break;
             }
@@ -979,7 +985,7 @@
                     // JVMCIError.guarantee(index == x, index + " != " + x);
                 } else {
                     index = rawIndexToConstantPoolIndex(cpi, opcode);
-                    index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index);
+                    index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
                 }
                 break;
             }
@@ -1004,8 +1010,8 @@
             case Class:
             case UnresolvedClass:
             case UnresolvedClassInError:
-                final long metaspaceKlass = runtime().getCompilerToVM().resolveKlassInPool(metaspaceConstantPool, index);
-                HotSpotResolvedObjectTypeImpl type = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
+                final HotSpotResolvedObjectTypeImpl metaspaceKlass = runtime().getCompilerToVM().resolveKlassInPool(this, index);
+                HotSpotResolvedObjectTypeImpl type = metaspaceKlass;
                 Class<?> klass = type.mirror();
                 if (!klass.isPrimitive() && !klass.isArray()) {
                     unsafe.ensureClassInitialized(klass);
@@ -1015,14 +1021,14 @@
                         if (Bytecodes.isInvokeHandleAlias(opcode)) {
                             final int methodRefCacheIndex = rawIndexToConstantPoolIndex(cpi, opcode);
                             if (isInvokeHandle(methodRefCacheIndex, type)) {
-                                runtime().getCompilerToVM().resolveInvokeHandleInPool(metaspaceConstantPool, methodRefCacheIndex);
+                                runtime().getCompilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
                             }
                         }
                 }
                 break;
             case InvokeDynamic:
                 if (isInvokedynamicIndex(cpi)) {
-                    runtime().getCompilerToVM().resolveInvokeDynamicInPool(metaspaceConstantPool, cpi);
+                    runtime().getCompilerToVM().resolveInvokeDynamicInPool(this, cpi);
                 }
                 break;
             default:
@@ -1036,7 +1042,7 @@
         if (Options.UseConstantPoolCacheJavaCode.getValue()) {
             index = cache.constantPoolCacheIndexToConstantPoolIndex(methodRefCacheIndex);
         } else {
-            index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, methodRefCacheIndex);
+            index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex);
         }
         assertTag(index, JVM_CONSTANT.MethodRef);
         return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameRefAt(methodRefCacheIndex), runtime().getHostJVMCIBackend().getMetaAccess());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIMetaAccessContext.java	Fri Aug 21 11:57:29 2015 -0700
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.jvmci.hotspot;
+
+import java.lang.ref.*;
+import java.util.*;
+
+import jdk.internal.jvmci.meta.*;
+
+/**
+ * This class manages the set of metadata roots that must be scanned during garbage collection.
+ * Because of class redefinition Method* and ConstantPool* can be freed if they don't appear to be
+ * in use so they must be tracked when there are live references to them from Java.
+ *
+ * The general theory of operation is that all {@link MetaspaceWrapperObject}s are created by
+ * calling into the VM which calls back out to actually create the wrapper instance. During the call
+ * the VM keeps the metadata reference alive through the use of metadata handles. Once the call
+ * completes the wrapper object is registered here and will be scanned during metadata scanning. The
+ * weakness of the reference to the wrapper object allows them to be reclaimed when they are no
+ * longer used.
+ *
+ */
+public class HotSpotJVMCIMetaAccessContext implements JVMCIMetaAccessContext {
+
+    /**
+     * The set of currently live contexts used for tracking of live metadata. Examined from the VM
+     * during garbage collection.
+     */
+    @SuppressWarnings("unchecked") private static WeakReference<HotSpotJVMCIMetaAccessContext>[] allContexts = new WeakReference[0];
+
+    /**
+     * This is a chunked list of metadata roots. It can be read from VM native code so it's been
+     * marked volatile to ensure the order of updates are respected.
+     */
+    private volatile Object[] metadataRoots;
+
+    private ChunkedList<WeakReference<MetaspaceWrapperObject>> list = new ChunkedList<>();
+
+    /**
+     * The number of weak references freed since the last time the list was shrunk.
+     */
+    private int freed;
+
+    /**
+     * The {@link ReferenceQueue} tracking the weak references created by this context.
+     */
+    private final ReferenceQueue<MetaspaceWrapperObject> queue = new ReferenceQueue<>();
+
+    static synchronized void add(HotSpotJVMCIMetaAccessContext context) {
+        for (int i = 0; i < allContexts.length; i++) {
+            if (allContexts[i] == null || allContexts[i].get() == null) {
+                allContexts[i] = new WeakReference<>(context);
+                return;
+            }
+        }
+        int index = allContexts.length;
+        allContexts = Arrays.copyOf(allContexts, index + 2);
+        allContexts[index] = new WeakReference<>(context);
+    }
+
+    HotSpotJVMCIMetaAccessContext() {
+        add(this);
+    }
+
+    /**
+     * Periodically trim the list of tracked metadata. A new list is created to replace the old to
+     * avoid concurrent scanning issues.
+     */
+    private void clean() {
+        Reference<?> ref = queue.poll();
+        if (ref == null) {
+            return;
+        }
+        while (ref != null) {
+            freed++;
+            ref = queue.poll();
+        }
+        if (freed > list.size() / 2) {
+            ChunkedList<WeakReference<MetaspaceWrapperObject>> newList = new ChunkedList<>();
+            for (WeakReference<MetaspaceWrapperObject> element : list) {
+                /*
+                 * The referent could become null anywhere in here but it doesn't matter. It will
+                 * get cleaned up next time.
+                 */
+                if (element != null && element.get() != null) {
+                    newList.add(element);
+                }
+            }
+            list = newList;
+            metadataRoots = list.getHead();
+            freed = 0;
+        }
+    }
+
+    /**
+     * Add a {@link MetaspaceWrapperObject} to tracked by the GC. It's assumed that the caller is
+     * responsible for keeping the reference alive for the duration of the call. Once registration
+     * is complete then the VM will ensure it's kept alive.
+     *
+     * @param metaspaceObject
+     */
+
+    public synchronized void add(MetaspaceWrapperObject metaspaceObject) {
+        clean();
+        list.add(new WeakReference<>(metaspaceObject, queue));
+        if (list.getHead() != metadataRoots) {
+            /*
+             * The list enlarged so update the head.
+             */
+            metadataRoots = list.getHead();
+        }
+    }
+
+    protected ResolvedJavaType createClass(Class<?> javaClass) {
+        if (javaClass.isPrimitive()) {
+            Kind kind = Kind.fromJavaClass(javaClass);
+            return new HotSpotResolvedPrimitiveType(kind);
+        } else {
+            return new HotSpotResolvedObjectTypeImpl(javaClass, this);
+        }
+    }
+
+    private final Map<Class<?>, WeakReference<ResolvedJavaType>> typeMap = new WeakHashMap<>();
+
+    @Override
+    public synchronized ResolvedJavaType fromClass(Class<?> javaClass) {
+        WeakReference<ResolvedJavaType> typeRef = typeMap.get(javaClass);
+        ResolvedJavaType type = typeRef != null ? typeRef.get() : null;
+        if (type == null) {
+            type = createClass(javaClass);
+            typeMap.put(javaClass, new WeakReference<>(type));
+        }
+        return type;
+    }
+
+    /**
+     * A very simple append only chunked list implementation.
+     */
+    static class ChunkedList<T> implements Iterable<T> {
+        private static final int CHUNK_SIZE = 32;
+
+        private static final int NEXT_CHUNK_INDEX = CHUNK_SIZE - 1;
+
+        private Object[] head;
+        private int index;
+        private int size;
+
+        ChunkedList() {
+            head = new Object[CHUNK_SIZE];
+            index = 0;
+        }
+
+        void add(T element) {
+            if (index == NEXT_CHUNK_INDEX) {
+                Object[] newHead = new Object[CHUNK_SIZE];
+                newHead[index] = head;
+                head = newHead;
+                index = 0;
+            }
+            head[index++] = element;
+            size++;
+        }
+
+        Object[] getHead() {
+            return head;
+        }
+
+        public Iterator<T> iterator() {
+            return new ChunkIterator<>();
+        }
+
+        int size() {
+            return size;
+        }
+
+        class ChunkIterator<V> implements Iterator<V> {
+
+            ChunkIterator() {
+                currentChunk = head;
+                currentIndex = -1;
+                findNext();
+            }
+
+            Object[] currentChunk;
+            int currentIndex;
+            V next;
+
+            @SuppressWarnings("unchecked")
+            V findNext() {
+                V result;
+                do {
+                    currentIndex++;
+                    if (currentIndex == NEXT_CHUNK_INDEX) {
+                        currentChunk = (Object[]) currentChunk[currentIndex];
+                        currentIndex = 0;
+                        if (currentChunk == null) {
+                            return null;
+                        }
+                    }
+                    result = (V) currentChunk[currentIndex];
+                } while (result == null);
+                return result;
+            }
+
+            public boolean hasNext() {
+                return next != null;
+            }
+
+            public V next() {
+                V result = next;
+                next = findNext();
+                return result;
+            }
+
+        }
+
+    }
+}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java	Fri Aug 21 11:57:29 2015 -0700
@@ -151,26 +151,17 @@
 
         JVMCIMetaAccessContext context = null;
         for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
-            context = vmEventListener.createMetaAccessContext(this, HotSpotJVMCIRuntime::createClass);
+            context = vmEventListener.createMetaAccessContext(this);
             if (context != null) {
                 break;
             }
         }
         if (context == null) {
-            context = new JVMCIGlobalMetaAccessContext(HotSpotJVMCIRuntime::createClass);
+            context = new HotSpotJVMCIMetaAccessContext();
         }
         metaAccessContext = context;
     }
 
-    private static ResolvedJavaType createClass(Class<?> javaClass) {
-        if (javaClass.isPrimitive()) {
-            Kind kind = Kind.fromJavaClass(javaClass);
-            return new HotSpotResolvedPrimitiveType(kind);
-        } else {
-            return new HotSpotResolvedObjectTypeImpl(javaClass);
-        }
-    }
-
     private JVMCIBackend registerBackend(JVMCIBackend backend) {
         Class<? extends Architecture> arch = backend.getCodeCache().getTarget().arch.getClass();
         JVMCIBackend oldValue = backends.put(arch, backend);
@@ -208,13 +199,13 @@
 
         // Resolve non-primitive types in the VM.
         HotSpotResolvedObjectTypeImpl hsAccessingType = (HotSpotResolvedObjectTypeImpl) accessingType;
-        final long metaspaceKlass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve);
+        final HotSpotResolvedObjectTypeImpl klass = compilerToVm.lookupType(name, hsAccessingType.mirror(), resolve);
 
-        if (metaspaceKlass == 0L) {
+        if (klass == null) {
             assert resolve == false;
             return HotSpotUnresolvedJavaType.create(this, name);
         }
-        return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
+        return klass;
     }
 
     public JVMCIBackend getHostJVMCIBackend() {
@@ -234,8 +225,7 @@
      * Called from the VM.
      */
     @SuppressWarnings({"unused"})
-    private void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long jvmciEnv, int id) {
-        HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod);
+    private void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
         compiler.compileMethod(method, entryBCI, jvmciEnv, id);
     }
 
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMemoryAccessProviderImpl.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMemoryAccessProviderImpl.java	Fri Aug 21 11:57:29 2015 -0700
@@ -199,33 +199,37 @@
         return HotSpotObjectConstantImpl.forObject(readRawObject(base, displacement, true), true);
     }
 
+    private HotSpotResolvedObjectTypeImpl readKlass(Constant base, long displacement, boolean compressed) {
+        assert (base instanceof HotSpotMetaspaceConstantImpl) || (base instanceof HotSpotObjectConstantImpl) : base.getClass();
+        Object baseObject = (base instanceof HotSpotMetaspaceConstantImpl) ? ((HotSpotMetaspaceConstantImpl) base).asResolvedJavaType() : ((HotSpotObjectConstantImpl) base).object();
+        return runtime.getCompilerToVM().getResolvedJavaType(baseObject, displacement, compressed);
+    }
+
     @Override
     public Constant readKlassPointerConstant(Constant base, long displacement) {
-        TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
-        long klass = readRawValue(base, displacement, target.wordSize * 8);
-        if (klass == 0) {
+        HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, false);
+        if (klass == null) {
             return JavaConstant.NULL_POINTER;
         }
-        HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass);
-        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, klass, metaKlass, false);
+        TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
+        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, klass.getMetaspaceKlass(), klass, false);
     }
 
     @Override
     public Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding) {
-        int compressed = (int) readRawValue(base, displacement, 32);
-        long klass = encoding.uncompress(compressed);
-        if (klass == 0) {
+        HotSpotResolvedObjectTypeImpl klass = readKlass(base, displacement, true);
+        if (klass == null) {
             return HotSpotCompressedNullConstant.COMPRESSED_NULL;
         }
-        HotSpotResolvedObjectType metaKlass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(klass);
-        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(Kind.Int, compressed, metaKlass, true);
+        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(Kind.Int, encoding.compress(klass.getMetaspaceKlass()), klass, true);
     }
 
     @Override
     public Constant readMethodPointerConstant(Constant base, long displacement) {
         TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
-        long method = readRawValue(base, displacement, target.wordSize * 8);
-        HotSpotResolvedJavaMethod metaMethod = HotSpotResolvedJavaMethodImpl.fromMetaspace(method);
-        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, method, metaMethod, false);
+        assert (base instanceof HotSpotObjectConstantImpl);
+        Object baseObject = ((HotSpotObjectConstantImpl) base).object();
+        HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
+        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, method.getMetaspaceMethod(), method, false);
     }
 }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMetaAccessProvider.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMetaAccessProvider.java	Fri Aug 21 11:57:29 2015 -0700
@@ -87,8 +87,7 @@
             Class<?> holder = reflectionMethod.getDeclaringClass();
             Field slotField = reflectionMethod instanceof Constructor ? reflectionConstructorSlot : reflectionMethodSlot;
             final int slot = slotField.getInt(reflectionMethod);
-            final long metaspaceMethod = runtime.getCompilerToVM().getMetaspaceMethod(holder, slot);
-            return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod);
+            return runtime.getCompilerToVM().getResolvedJavaMethodAtSlot(holder, slot);
         } catch (IllegalArgumentException | IllegalAccessException e) {
             throw new JVMCIError(e);
         }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethodData.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethodData.java	Fri Aug 21 11:57:29 2015 -0700
@@ -67,9 +67,11 @@
      * Reference to the C++ MethodData object.
      */
     private final long metaspaceMethodData;
+    @SuppressWarnings("unused") private final HotSpotResolvedJavaMethodImpl method;
 
-    public HotSpotMethodData(long metaspaceMethodData) {
+    public HotSpotMethodData(long metaspaceMethodData, HotSpotResolvedJavaMethodImpl method) {
         this.metaspaceMethodData = metaspaceMethodData;
+        this.method = method;
     }
 
     /**
@@ -189,9 +191,14 @@
         return (int) unsafe.getAddress(metaspaceMethodData + fullOffsetInBytes);
     }
 
-    private long readWord(int position, int offsetInBytes) {
+    private HotSpotResolvedJavaMethod readMethod(int position, int offsetInBytes) {
         long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
-        return unsafe.getAddress(metaspaceMethodData + fullOffsetInBytes);
+        return runtime().compilerToVm.getResolvedJavaMethod(null, metaspaceMethodData + fullOffsetInBytes);
+    }
+
+    private HotSpotResolvedObjectTypeImpl readKlass(int position, int offsetInBytes) {
+        long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
+        return runtime().compilerToVm.getResolvedJavaType(null, metaspaceMethodData + fullOffsetInBytes, false);
     }
 
     private static int truncateLongToInt(long value) {
@@ -491,9 +498,9 @@
             int entries = 0;
 
             outer: for (int i = 0; i < typeProfileWidth; i++) {
-                long receiverKlass = data.readWord(position, getTypeOffset(i));
-                if (receiverKlass != 0) {
-                    HotSpotResolvedObjectTypeImpl klass = HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(receiverKlass);
+                HotSpotResolvedObjectTypeImpl receiverKlass = data.readKlass(position, getTypeOffset(i));
+                if (receiverKlass != null) {
+                    HotSpotResolvedObjectTypeImpl klass = receiverKlass;
                     long count = data.readUnsignedInt(position, getTypeCountOffset(i));
                     /*
                      * Because of races in the profile collection machinery it's possible for a
@@ -629,9 +636,9 @@
             int entries = 0;
 
             for (int i = 0; i < profileWidth; i++) {
-                long method = data.readWord(position, getMethodOffset(i));
-                if (method != 0) {
-                    methods[entries] = HotSpotResolvedJavaMethodImpl.fromMetaspace(method);
+                HotSpotResolvedJavaMethod method = data.readMethod(position, getMethodOffset(i));
+                if (method != null) {
+                    methods[entries] = method;
                     long count = data.readUnsignedInt(position, getMethodCountOffset(i));
                     totalCount += count;
                     counts[entries] = count;
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethodHandleAccessProvider.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethodHandleAccessProvider.java	Fri Aug 21 11:57:29 2015 -0700
@@ -43,7 +43,7 @@
         static final ResolvedJavaField methodHandleFormField;
         static final ResolvedJavaField lambdaFormVmentryField;
         static final ResolvedJavaMethod lambdaFormCompileToBytecodeMethod;
-        static final ResolvedJavaField memberNameVmtargetField;
+        static final HotSpotResolvedJavaField memberNameVmtargetField;
 
         /**
          * Search for an instance field with the given name in a class.
@@ -84,7 +84,7 @@
                 methodHandleFormField = findFieldInClass("java.lang.invoke.MethodHandle", "form");
                 lambdaFormVmentryField = findFieldInClass("java.lang.invoke.LambdaForm", "vmentry");
                 lambdaFormCompileToBytecodeMethod = findMethodInClass("java.lang.invoke.LambdaForm", "compileToBytecode");
-                memberNameVmtargetField = findFieldInClass("java.lang.invoke.MemberName", "vmtarget");
+                memberNameVmtargetField = (HotSpotResolvedJavaField) findFieldInClass("java.lang.invoke.MemberName", "vmtarget");
             } catch (Throwable ex) {
                 throw new JVMCIError(ex);
             }
@@ -147,14 +147,13 @@
     /**
      * Returns the {@link ResolvedJavaMethod} for the vmtarget of a java.lang.invoke.MemberName.
      */
-    private ResolvedJavaMethod getTargetMethod(JavaConstant memberName) {
+    private static ResolvedJavaMethod getTargetMethod(JavaConstant memberName) {
         if (memberName.isNull()) {
             return null;
         }
 
-        /* Load injected field: JVM_Method* MemberName.vmtarget */
-        JavaConstant vmtarget = constantReflection.readFieldValue(LazyInitialization.memberNameVmtargetField, memberName);
-        /* Create a method from the vmtarget method pointer. */
-        return HotSpotResolvedJavaMethodImpl.fromMetaspace(vmtarget.asLong());
+        Object object = ((HotSpotObjectConstantImpl) memberName).object();
+        /* Read the ResolvedJavaMethod from the injected field MemberName.vmtarget */
+        return runtime().compilerToVm.getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
     }
 }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java	Fri Aug 21 11:57:29 2015 -0700
@@ -37,7 +37,7 @@
 /**
  * Implementation of {@link JavaMethod} for resolved HotSpot methods.
  */
-public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified {
+public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
 
     public static class Options {
         // @formatter:off
@@ -65,26 +65,30 @@
      * @return the {@link ResolvedJavaType} corresponding to the holder of the
      *         {@code metaspaceMethod}
      */
-    public static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) {
+    private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) {
         HotSpotVMConfig config = runtime().getConfig();
         final long metaspaceConstMethod = unsafe.getAddress(metaspaceMethod + config.methodConstMethodOffset);
         final long metaspaceConstantPool = unsafe.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
-        final long metaspaceKlass = unsafe.getAddress(metaspaceConstantPool + config.constantPoolHolderOffset);
-        return HotSpotResolvedObjectTypeImpl.fromMetaspaceKlass(metaspaceKlass);
+        return runtime().getCompilerToVM().getResolvedJavaType(null, metaspaceConstantPool + config.constantPoolHolderOffset, false);
     }
 
     /**
-     * Gets the {@link ResolvedJavaMethod} for a HotSpot metaspace method native object.
+     * Gets the JVMCI mirror from a HotSpot method. The VM is responsible for ensuring that the
+     * Method* is kept alive for the duration of this call and the
+     * {@link HotSpotJVMCIMetaAccessContext} keeps it alive after that.
+     *
+     * Called from the VM.
      *
      * @param metaspaceMethod a metaspace Method object
      * @return the {@link ResolvedJavaMethod} corresponding to {@code metaspaceMethod}
      */
-    public static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceMethod) {
+    @SuppressWarnings("unused")
+    private static HotSpotResolvedJavaMethod fromMetaspace(long metaspaceMethod) {
         HotSpotResolvedObjectTypeImpl holder = getHolder(metaspaceMethod);
         return holder.createMethod(metaspaceMethod);
     }
 
-    public HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceMethod) {
+    HotSpotResolvedJavaMethodImpl(HotSpotResolvedObjectTypeImpl holder, long metaspaceMethod) {
         // It would be too much work to get the method name here so we fill it in later.
         super(null);
         this.metaspaceMethod = metaspaceMethod;
@@ -99,7 +103,11 @@
          * one from their holder.
          */
         final long metaspaceConstantPool = unsafe.getAddress(constMethod + config.constMethodConstantsOffset);
-        this.constantPool = new HotSpotConstantPool(metaspaceConstantPool);
+        if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) {
+            this.constantPool = holder.getConstantPool();
+        } else {
+            this.constantPool = runtime().getCompilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
+        }
 
         final int nameIndex = unsafe.getChar(constMethod + config.constMethodNameIndexOffset);
         this.name = constantPool.lookupUtf8(nameIndex);
@@ -110,7 +118,9 @@
 
     /**
      * Returns a pointer to this method's constant method data structure (
-     * {@code Method::_constMethod}).
+     * {@code Method::_constMethod}). This pointer isn't wrapped since it should be safe to use it
+     * within the context of this HotSpotResolvedJavaMethodImpl since the Method* and ConstMethod*
+     * are kept alive as a pair.
      *
      * @return pointer to this method's ConstMethod
      */
@@ -121,6 +131,9 @@
 
     @Override
     public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
         if (obj instanceof HotSpotResolvedJavaMethodImpl) {
             HotSpotResolvedJavaMethodImpl that = (HotSpotResolvedJavaMethodImpl) obj;
             return that.metaspaceMethod == metaspaceMethod;
@@ -167,6 +180,10 @@
         return metaspaceMethod;
     }
 
+    public long getMetaspacePointer() {
+        return getMetaspaceMethod();
+    }
+
     @Override
     public JavaConstant getEncoding() {
         return getMetaspaceMethodConstant();
@@ -196,7 +213,7 @@
             return null;
         }
         if (code == null && holder.isLinked()) {
-            code = runtime().getCompilerToVM().getBytecode(metaspaceMethod);
+            code = runtime().getCompilerToVM().getBytecode(this);
             assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length;
         }
         return code;
@@ -215,9 +232,9 @@
         }
 
         HotSpotVMConfig config = runtime().getConfig();
-        final int exceptionTableLength = runtime().getCompilerToVM().getExceptionTableLength(metaspaceMethod);
+        final int exceptionTableLength = runtime().getCompilerToVM().getExceptionTableLength(this);
         ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength];
-        long exceptionTableElement = runtime().getCompilerToVM().getExceptionTableStart(metaspaceMethod);
+        long exceptionTableElement = runtime().getCompilerToVM().getExceptionTableStart(this);
 
         for (int i = 0; i < exceptionTableLength; i++) {
             final int startPc = unsafe.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset);
@@ -281,7 +298,7 @@
      * Manually adds a DontInline annotation to this method.
      */
     public void setNotInlineable() {
-        runtime().getCompilerToVM().doNotInlineOrCompile(metaspaceMethod);
+        runtime().getCompilerToVM().doNotInlineOrCompile(this);
     }
 
     /**
@@ -291,7 +308,7 @@
      * @return true if special method ignored by security stack walks, false otherwise
      */
     public boolean ignoredBySecurityStackWalk() {
-        return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(metaspaceMethod);
+        return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(this);
     }
 
     public boolean hasBalancedMonitors() {
@@ -309,7 +326,7 @@
         }
 
         // This either happens only once if monitors are balanced or very rarely multiple-times.
-        return runtime().getCompilerToVM().hasBalancedMonitors(metaspaceMethod);
+        return runtime().getCompilerToVM().hasBalancedMonitors(this);
     }
 
     @Override
@@ -344,10 +361,10 @@
     public StackTraceElement asStackTraceElement(int bci) {
         if (bci < 0 || bci >= getCodeSize()) {
             // HotSpot code can only construct stack trace elements for valid bcis
-            StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, 0);
+            StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(this, 0);
             return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
         }
-        return runtime().getCompilerToVM().getStackTraceElement(metaspaceMethod, bci);
+        return runtime().getCompilerToVM().getStackTraceElement(this, bci);
     }
 
     public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
@@ -362,12 +379,7 @@
             // seeing A.foo().
             return null;
         }
-        long metaspaceKlass = ((HotSpotResolvedObjectTypeImpl) receiver).getMetaspaceKlass();
-        final long uniqueConcreteMethod = runtime().getCompilerToVM().findUniqueConcreteMethod(metaspaceKlass, metaspaceMethod);
-        if (uniqueConcreteMethod == 0) {
-            return null;
-        }
-        return fromMetaspace(uniqueConcreteMethod);
+        return runtime().getCompilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this);
     }
 
     @Override
@@ -415,7 +427,7 @@
         if (UseProfilingInformation.getValue() && methodData == null) {
             long metaspaceMethodData = unsafe.getAddress(metaspaceMethod + runtime().getConfig().methodDataOffset);
             if (metaspaceMethodData != 0) {
-                methodData = new HotSpotMethodData(metaspaceMethodData);
+                methodData = new HotSpotMethodData(metaspaceMethodData, this);
                 if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) {
                     System.out.println("Raw method data for " + this.format("%H.%n(%p)") + ":");
                     System.out.println(methodData.toString());
@@ -435,7 +447,7 @@
 
     @Override
     public void reprofile() {
-        runtime().getCompilerToVM().reprofile(metaspaceMethod);
+        runtime().getCompilerToVM().reprofile(this);
     }
 
     @Override
@@ -535,7 +547,7 @@
         if (isDontInline()) {
             return false;
         }
-        return runtime().getCompilerToVM().canInlineMethod(metaspaceMethod);
+        return runtime().getCompilerToVM().canInlineMethod(this);
     }
 
     @Override
@@ -543,7 +555,7 @@
         if (isForceInline()) {
             return true;
         }
-        return runtime().getCompilerToVM().shouldInlineMethod(metaspaceMethod);
+        return runtime().getCompilerToVM().shouldInlineMethod(this);
     }
 
     @Override
@@ -553,7 +565,7 @@
             return null;
         }
 
-        long[] values = runtime().getCompilerToVM().getLineNumberTable(metaspaceMethod);
+        long[] values = runtime().getCompilerToVM().getLineNumberTable(this);
         if (values == null || values.length == 0) {
             // Empty table so treat is as non-existent
             return null;
@@ -578,8 +590,8 @@
         }
 
         HotSpotVMConfig config = runtime().getConfig();
-        long localVariableTableElement = runtime().getCompilerToVM().getLocalVariableTableStart(metaspaceMethod);
-        final int localVariableTableLength = runtime().getCompilerToVM().getLocalVariableTableLength(metaspaceMethod);
+        long localVariableTableElement = runtime().getCompilerToVM().getLocalVariableTableStart(this);
+        final int localVariableTableLength = runtime().getCompilerToVM().getLocalVariableTableLength(this);
         Local[] locals = new Local[localVariableTableLength];
 
         for (int i = 0; i < localVariableTableLength; i++) {
@@ -655,7 +667,7 @@
 
     private int getVtableIndexForInterface(ResolvedJavaType resolved) {
         HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved;
-        return runtime().getCompilerToVM().getVtableIndexForInterface(hotspotType.getMetaspaceKlass(), getMetaspaceMethod());
+        return runtime().getCompilerToVM().getVtableIndexForInterface(hotspotType, this);
     }
 
     /**
@@ -720,13 +732,13 @@
      * @return compile id
      */
     public int allocateCompileId(int entryBCI) {
-        return runtime().getCompilerToVM().allocateCompileId(metaspaceMethod, entryBCI);
+        return runtime().getCompilerToVM().allocateCompileId(this, entryBCI);
     }
 
     public boolean hasCodeAtLevel(int entryBCI, int level) {
         if (entryBCI == runtime().getConfig().invocationEntryBci) {
             return hasCompiledCodeAtLevel(level);
         }
-        return runtime().getCompilerToVM().hasCompiledCodeForOSR(metaspaceMethod, entryBCI, level);
+        return runtime().getCompilerToVM().hasCompiledCodeForOSR(this, entryBCI, level);
     }
 }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectType.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectType.java	Fri Aug 21 11:57:29 2015 -0700
@@ -54,7 +54,7 @@
         return Kind.Object;
     }
 
-    ConstantPool constantPool();
+    ConstantPool getConstantPool();
 
     /**
      * Gets the instance size of this type. If an instance of this type cannot be fast path
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java	Fri Aug 21 11:57:29 2015 -0700
@@ -39,7 +39,7 @@
 /**
  * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
  */
-public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified {
+public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
 
     /**
      * The Java class this type represents.
@@ -47,10 +47,11 @@
     private final Class<?> javaClass;
 
     private HashMap<Long, HotSpotResolvedJavaField> fieldCache;
-    private HashMap<Long, HotSpotResolvedJavaMethod> methodCache;
+    private HashMap<Long, HotSpotResolvedJavaMethodImpl> methodCache;
     private HotSpotResolvedJavaField[] instanceFields;
     private HotSpotResolvedObjectTypeImpl[] interfaces;
-    private ConstantPool constantPool;
+    private HotSpotConstantPool constantPool;
+    final HotSpotJVMCIMetaAccessContext context;
     private HotSpotResolvedObjectType arrayOfType;
 
     /**
@@ -63,15 +64,16 @@
     }
 
     /**
-     * Gets the JVMCI mirror from a HotSpot metaspace Klass native object.
+     * Gets the JVMCI mirror from a HotSpot type. Since {@link Class} is already a proxy for the
+     * underlying Klass*, it is used instead of the raw Klass*.
      *
-     * @param metaspaceKlass a metaspace Klass object
+     * Called from the VM.
+     *
+     * @param javaClass a metaspace Klass object
      * @return the {@link ResolvedJavaType} corresponding to {@code metaspaceKlass}
      */
-    public static HotSpotResolvedObjectTypeImpl fromMetaspaceKlass(long metaspaceKlass) {
-        assert metaspaceKlass != 0;
-        Class<?> javaClass = runtime().getCompilerToVM().getJavaMirror(metaspaceKlass);
-        assert javaClass != null;
+    @SuppressWarnings("unused")
+    private static HotSpotResolvedObjectTypeImpl fromMetaspace(Class<?> javaClass) {
         return fromObjectClass(javaClass);
     }
 
@@ -80,15 +82,17 @@
      *
      * <p>
      * <b>NOTE</b>: Creating an instance of this class does not install the mirror for the
-     * {@link Class} type. Use {@link #fromObjectClass(Class)} or {@link #fromMetaspaceKlass(long)}
+     * {@link Class} type. Use {@link #fromObjectClass(Class)} or {@link #fromMetaspace(Class)}
      * instead.
      * </p>
      *
      * @param javaClass the Class to create the mirror for
+     * @param context
      */
-    public HotSpotResolvedObjectTypeImpl(Class<?> javaClass) {
+    HotSpotResolvedObjectTypeImpl(Class<?> javaClass, HotSpotJVMCIMetaAccessContext context) {
         super(getSignatureName(javaClass));
         this.javaClass = javaClass;
+        this.context = context;
         assert getName().charAt(0) != '[' || isArray() : getName();
     }
 
@@ -112,6 +116,10 @@
         return unsafe.getInt(javaClass, (long) runtime().getConfig().klassOffset) & 0xFFFFFFFFL;
     }
 
+    public long getMetaspacePointer() {
+        return getMetaspaceKlass();
+    }
+
     @Override
     public int getModifiers() {
         if (isArray()) {
@@ -172,11 +180,11 @@
         } else {
             HotSpotResolvedObjectTypeImpl type = this;
             while (type.isAbstract()) {
-                long subklass = type.getSubklass();
-                if (subklass == 0 || unsafe.getAddress(subklass + config.nextSiblingOffset) != 0) {
+                HotSpotResolvedObjectTypeImpl subklass = type.getSubklass();
+                if (subklass == null || unsafe.getAddress(subklass.getMetaspaceKlass() + config.nextSiblingOffset) != 0) {
                     return null;
                 }
-                type = fromMetaspaceKlass(subklass);
+                type = subklass;
             }
             if (type.isAbstract() || type.isInterface() || !type.isLeafClass()) {
                 return null;
@@ -197,7 +205,7 @@
      * @return true if the type is a leaf class
      */
     private boolean isLeafClass() {
-        return getSubklass() == 0;
+        return getSubklass() == null;
     }
 
     /**
@@ -206,8 +214,8 @@
      *
      * @return value of the subklass field as metaspace klass pointer
      */
-    private long getSubklass() {
-        return unsafe.getAddress(getMetaspaceKlass() + runtime().getConfig().subklassOffset);
+    private HotSpotResolvedObjectTypeImpl getSubklass() {
+        return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().subklassOffset, false);
     }
 
     @Override
@@ -234,14 +242,7 @@
         if (!isInterface()) {
             throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this);
         }
-        final long implementorMetaspaceKlass = runtime().getCompilerToVM().getKlassImplementor(getMetaspaceKlass());
-
-        // No implementor.
-        if (implementorMetaspaceKlass == 0) {
-            return null;
-        }
-
-        return fromMetaspaceKlass(implementorMetaspaceKlass);
+        return runtime().getCompilerToVM().getKlassImplementor(this);
     }
 
     public HotSpotResolvedObjectTypeImpl getSupertype() {
@@ -296,7 +297,7 @@
     @Override
     public AssumptionResult<Boolean> hasFinalizableSubclass() {
         assert !isArray();
-        if (!runtime().getCompilerToVM().hasFinalizableSubclass(getMetaspaceKlass())) {
+        if (!runtime().getCompilerToVM().hasFinalizableSubclass(this)) {
             return new AssumptionResult<>(false, new NoFinalizableSubclass(this));
         }
         return new AssumptionResult<>(true);
@@ -405,17 +406,12 @@
         }
         HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method;
         HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType;
-        final long resolvedMetaspaceMethod = runtime().getCompilerToVM().resolveMethod(getMetaspaceKlass(), hotSpotMethod.getMetaspaceMethod(), hotSpotCallerType.getMetaspaceKlass());
-        if (resolvedMetaspaceMethod == 0) {
-            return null;
-        }
-        return HotSpotResolvedJavaMethodImpl.fromMetaspace(resolvedMetaspaceMethod);
+        return runtime().getCompilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType);
     }
 
-    public ConstantPool constantPool() {
+    public HotSpotConstantPool getConstantPool() {
         if (constantPool == null) {
-            final long metaspaceConstantPool = unsafe.getAddress(getMetaspaceKlass() + runtime().getConfig().instanceKlassConstantsOffset);
-            constantPool = new HotSpotConstantPool(metaspaceConstantPool);
+            constantPool = runtime().getCompilerToVM().getConstantPool(this, runtime().getConfig().instanceKlassConstantsOffset);
         }
         return constantPool;
     }
@@ -447,8 +443,8 @@
         return unsafe.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset);
     }
 
-    public synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) {
-        HotSpotResolvedJavaMethod method = null;
+    synchronized HotSpotResolvedJavaMethod createMethod(long metaspaceMethod) {
+        HotSpotResolvedJavaMethodImpl method = null;
         if (methodCache == null) {
             methodCache = new HashMap<>(8);
         } else {
@@ -457,6 +453,7 @@
         if (method == null) {
             method = new HotSpotResolvedJavaMethodImpl(this, metaspaceMethod);
             methodCache.put(metaspaceMethod, method);
+            context.add(method);
         }
         return method;
     }
@@ -592,7 +589,7 @@
          */
         public String getName() {
             final int nameIndex = getNameIndex();
-            return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : constantPool().lookupUtf8(nameIndex);
+            return isInternal() ? HotSpotVmSymbols.symbolAt(nameIndex) : getConstantPool().lookupUtf8(nameIndex);
         }
 
         /**
@@ -601,7 +598,7 @@
          */
         public String getSignature() {
             final int signatureIndex = getSignatureIndex();
-            return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : constantPool().lookupUtf8(signatureIndex);
+            return isInternal() ? HotSpotVmSymbols.symbolAt(signatureIndex) : getConstantPool().lookupUtf8(signatureIndex);
         }
 
         public JavaType getType() {
@@ -738,7 +735,7 @@
         if (sourceFileNameIndex == 0) {
             return null;
         }
-        return constantPool().lookupUtf8(sourceFileNameIndex);
+        return getConstantPool().lookupUtf8(sourceFileNameIndex);
     }
 
     @Override
@@ -878,11 +875,7 @@
     }
 
     public ResolvedJavaMethod getClassInitializer() {
-        final long metaspaceMethod = runtime().getCompilerToVM().getClassInitializer(getMetaspaceKlass());
-        if (metaspaceMethod != 0L) {
-            return createMethod(metaspaceMethod);
-        }
-        return null;
+        return runtime().getCompilerToVM().getClassInitializer(this);
     }
 
     @Override
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotStackFrameReference.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotStackFrameReference.java	Fri Aug 21 11:57:29 2015 -0700
@@ -37,7 +37,7 @@
 
     // information about the stack frame's contents
     private int bci;
-    private long metaspaceMethod;
+    private HotSpotResolvedJavaMethod method;
     private Object[] locals;
     private boolean[] localIsVirtual;
 
@@ -71,12 +71,12 @@
 
     @Override
     public ResolvedJavaMethod getMethod() {
-        return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod);
+        return method;
     }
 
     @Override
-    public boolean isMethod(ResolvedJavaMethod method) {
-        return metaspaceMethod == ((HotSpotResolvedJavaMethodImpl) method).getMetaspaceMethod();
+    public boolean isMethod(ResolvedJavaMethod otherMethod) {
+        return method.equals(otherMethod);
     }
 
     @Override
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVMEventListener.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVMEventListener.java	Fri Aug 21 11:57:29 2015 -0700
@@ -22,8 +22,6 @@
  */
 package jdk.internal.jvmci.hotspot;
 
-import java.util.function.*;
-
 import jdk.internal.jvmci.code.*;
 import jdk.internal.jvmci.meta.*;
 
@@ -62,10 +60,9 @@
      * context with globally shared instances of {@link ResolvedJavaType} that are never released.
      *
      * @param hotSpotJVMCIRuntime
-     * @param factory the factory function to create new ResolvedJavaTypes
      * @return a custom context or null
      */
-    default JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime hotSpotJVMCIRuntime, Function<Class<?>, ResolvedJavaType> factory) {
+    default JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime hotSpotJVMCIRuntime) {
         return null;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/MetaspaceWrapperObject.java	Fri Aug 21 11:57:29 2015 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.jvmci.hotspot;
+
+/**
+ * A tag interface indicating that this type is a wrapper around a HotSpot metaspace object. It
+ * would preferable if this were the base class containing the pointer but that would require mixins
+ * since most of the wrapper types have complex supertype hierarchies.
+ */
+public interface MetaspaceWrapperObject {
+
+    long getMetaspacePointer();
+}
--- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIGlobalMetaAccessContext.java	Fri Aug 21 16:35:29 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.internal.jvmci.meta;
-
-import java.util.function.*;
-
-/**
- * Caches the {@link ResolvedJavaType} for a class in a {@link ClassValue}. The instances live
- * forever with no way to clean them up once they are no longer in use.
- */
-
-public class JVMCIGlobalMetaAccessContext implements JVMCIMetaAccessContext {
-
-    /**
-     * JVMCI mirrors are stored as a {@link ClassValue} associated with the {@link Class} of the
-     * type.
-     */
-    protected final ClassValue<ResolvedJavaType> jvmciMirrors = new ClassValue<ResolvedJavaType>() {
-        @Override
-        protected ResolvedJavaType computeValue(Class<?> javaClass) {
-            return factory.apply(javaClass);
-        }
-
-    };
-    protected final Function<Class<?>, ResolvedJavaType> factory;
-
-    public JVMCIGlobalMetaAccessContext(Function<Class<?>, ResolvedJavaType> factory) {
-        this.factory = factory;
-    }
-
-    public ResolvedJavaType fromClass(Class<?> javaClass) {
-        return jvmciMirrors.get(javaClass);
-    }
-
-    public boolean flush() {
-        // There is no mechanism to flush all data.
-        return false;
-    }
-}
--- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIMetaAccessContext.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIMetaAccessContext.java	Fri Aug 21 11:57:29 2015 -0700
@@ -35,11 +35,4 @@
      */
 
     ResolvedJavaType fromClass(Class<?> clazz);
-
-    /**
-     * An optional operation which drops all currently cached information.
-     *
-     * @return true if any work was performed
-     */
-    boolean flush();
 }
--- a/jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIThreadLocalMetaAccessContext.java	Fri Aug 21 16:35:29 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.internal.jvmci.meta;
-
-import java.util.*;
-import java.util.function.*;
-
-/**
- * A per thread cache of {@link ResolvedJavaType}s. The per thread cache can be flushed by using
- * {@link #flush()} but there is no way to globally flush all caches.
- */
-public class JVMCIThreadLocalMetaAccessContext implements JVMCIMetaAccessContext {
-
-    protected final ThreadLocal<Map<Class<?>, ResolvedJavaType>> threadLocalMap = new ThreadLocal<Map<Class<?>, ResolvedJavaType>>() {
-        @Override
-        protected Map<Class<?>, ResolvedJavaType> initialValue() {
-            return new HashMap<>();
-        }
-    };
-
-    protected final Function<Class<?>, ResolvedJavaType> factory;
-
-    public JVMCIThreadLocalMetaAccessContext(Function<Class<?>, ResolvedJavaType> factory) {
-        this.factory = factory;
-    }
-
-    public ResolvedJavaType fromClass(Class<?> javaClass) {
-        Map<Class<?>, ResolvedJavaType> map = threadLocalMap.get();
-        ResolvedJavaType type = map.get(javaClass);
-        if (type == null) {
-            type = factory.apply(javaClass);
-            map.put(javaClass, type);
-        }
-        return type;
-    }
-
-    /**
-     * Drop all current cached state.
-     */
-    public boolean flush() {
-        threadLocalMap.remove();
-        return true;
-    }
-}
--- a/jvmci/jdk.internal.jvmci.runtime.test/src/jdk/internal/jvmci/runtime/test/RedefineClassTest.java	Fri Aug 21 16:35:29 2015 +0200
+++ b/jvmci/jdk.internal.jvmci.runtime.test/src/jdk/internal/jvmci/runtime/test/RedefineClassTest.java	Fri Aug 21 11:57:29 2015 -0700
@@ -51,7 +51,6 @@
         }
     }
 
-    @Ignore("JVMCI is not yet class redefinition safe")
     @Test
     public void test() throws Throwable {
 
--- a/src/share/vm/classfile/metadataOnStackMark.cpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/classfile/metadataOnStackMark.cpp	Fri Aug 21 11:57:29 2015 -0700
@@ -32,6 +32,9 @@
 #include "runtime/thread.hpp"
 #include "services/threadService.hpp"
 #include "utilities/chunkedList.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 
 volatile MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL;
 volatile MetadataOnStackBuffer* MetadataOnStackMark::_free_buffers = NULL;
@@ -53,6 +56,9 @@
   CompileBroker::mark_on_stack();
   JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
   ThreadService::metadata_do(Metadata::mark_on_stack);
+#if INCLUDE_JVMCI
+  JVMCIRuntime::metadata_do(Metadata::mark_on_stack);
+#endif
 }
 
 MetadataOnStackMark::~MetadataOnStackMark() {
--- a/src/share/vm/classfile/systemDictionary.hpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Fri Aug 21 11:57:29 2015 -0700
@@ -210,8 +210,10 @@
   JVMCI_ONLY(do_klass(HotSpotObjectConstantImpl_klass,       jdk_internal_jvmci_hotspot_HotSpotObjectConstantImpl,           Jvmci)) \
   JVMCI_ONLY(do_klass(HotSpotMetaspaceConstantImpl_klass,    jdk_internal_jvmci_hotspot_HotSpotMetaspaceConstantImpl,        Jvmci)) \
   JVMCI_ONLY(do_klass(HotSpotStackFrameReference_klass,      jdk_internal_jvmci_hotspot_HotSpotStackFrameReference,          Jvmci)) \
+  JVMCI_ONLY(do_klass(HotSpotConstantPool_klass,             jdk_internal_jvmci_hotspot_HotSpotConstantPool,                 Jvmci)) \
+  JVMCI_ONLY(do_klass(HotSpotJVMCIMetaAccessContext_klass,   jdk_internal_jvmci_hotspot_HotSpotJVMCIMetaAccessContext,       Jvmci)) \
   JVMCI_ONLY(do_klass(Assumptions_ConcreteMethod_klass,      jdk_internal_jvmci_meta_Assumptions_ConcreteMethod,             Jvmci)) \
-  JVMCI_ONLY(do_klass(Assumptions_NoFinalizableSubclass_klass, jdk_internal_jvmci_meta_Assumptions_NoFinalizableSubclass,    Jvmci))\
+  JVMCI_ONLY(do_klass(Assumptions_NoFinalizableSubclass_klass, jdk_internal_jvmci_meta_Assumptions_NoFinalizableSubclass,    Jvmci)) \
   JVMCI_ONLY(do_klass(Assumptions_ConcreteSubtype_klass,     jdk_internal_jvmci_meta_Assumptions_ConcreteSubtype,            Jvmci)) \
   JVMCI_ONLY(do_klass(Assumptions_LeafType_klass,            jdk_internal_jvmci_meta_Assumptions_LeafType,                   Jvmci)) \
   JVMCI_ONLY(do_klass(Assumptions_CallSiteTargetValue_klass, jdk_internal_jvmci_meta_Assumptions_CallSiteTargetValue,        Jvmci)) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Aug 21 11:57:29 2015 -0700
@@ -314,6 +314,8 @@
   JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_HotSpotObjectConstantImpl,       "jdk/internal/jvmci/hotspot/HotSpotObjectConstantImpl"))            \
   JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_HotSpotMetaspaceConstantImpl,    "jdk/internal/jvmci/hotspot/HotSpotMetaspaceConstantImpl"))         \
   JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_HotSpotStackFrameReference,      "jdk/internal/jvmci/hotspot/HotSpotStackFrameReference"))           \
+  JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_HotSpotConstantPool,             "jdk/internal/jvmci/hotspot/HotSpotConstantPool"))                  \
+  JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_HotSpotJVMCIMetaAccessContext,   "jdk/internal/jvmci/hotspot/HotSpotJVMCIMetaAccessContext"))        \
   JVMCI_ONLY(template(jdk_internal_jvmci_meta_JavaConstant,                       "jdk/internal/jvmci/meta/JavaConstant"))                            \
   JVMCI_ONLY(template(jdk_internal_jvmci_meta_PrimitiveConstant,                  "jdk/internal/jvmci/meta/PrimitiveConstant"))                       \
   JVMCI_ONLY(template(jdk_internal_jvmci_meta_RawConstant,                        "jdk/internal/jvmci/meta/RawConstant"))                             \
@@ -349,8 +351,12 @@
   JVMCI_ONLY(template(jdk_internal_jvmci_code_VirtualObject,                      "jdk/internal/jvmci/code/VirtualObject"))                           \
   JVMCI_ONLY(template(jdk_internal_jvmci_code_RegisterSaveLayout,                 "jdk/internal/jvmci/code/RegisterSaveLayout"))                      \
   JVMCI_ONLY(template(jdk_internal_jvmci_code_InvalidInstalledCodeException,      "jdk/internal/jvmci/code/InvalidInstalledCodeException"))           \
-  JVMCI_ONLY(template(compileMetaspaceMethod_name,                     "compileMetaspaceMethod"))                                                 \
-  JVMCI_ONLY(template(compileMetaspaceMethod_signature,                "(JIJI)V"))                                                                \
+  JVMCI_ONLY(template(compileMethod_name,                                         "compileMethod"))                                                   \
+  JVMCI_ONLY(template(compileMethod_signature,                                    "(Ljdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethod;IJI)V"))    \
+  JVMCI_ONLY(template(fromMetaspace_name,                                         "fromMetaspace"))                                                   \
+  JVMCI_ONLY(template(method_fromMetaspace_signature,                             "(J)Ljdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethod;"))       \
+  JVMCI_ONLY(template(constantPool_fromMetaspace_signature,                       "(J)Ljdk/internal/jvmci/hotspot/HotSpotConstantPool;"))             \
+  JVMCI_ONLY(template(klass_fromMetaspace_signature,                              "(Ljava/lang/Class;)Ljdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl;"))   \
   JVMCI_ONLY(template(jdk_internal_jvmci_hotspot_Stable_signature, "Ljdk/internal/jvmci/hotspot/Stable;"))                                            \
                                                                                                   \
   /* common method and field names */                                                             \
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Fri Aug 21 11:57:29 2015 -0700
@@ -66,7 +66,7 @@
 
 Method* getMethodFromHotSpotMethod(oop hotspot_method) {
   assert(hotspot_method != NULL && hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass()), "sanity");
-  return asMethod(HotSpotResolvedJavaMethodImpl::metaspaceMethod(hotspot_method));
+  return CompilerToVM::asMethod(hotspot_method);
 }
 
 VMReg getVMRegFromLocation(oop location, int total_frame_size) {
--- a/src/share/vm/jvmci/jvmciCompiler.cpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/jvmci/jvmciCompiler.cpp	Fri Aug 21 11:57:29 2015 -0700
@@ -24,6 +24,7 @@
 #include "precompiled.hpp"
 #include "memory/oopFactory.hpp"
 #include "runtime/javaCalls.hpp"
+#include "jvmci/jvmciJavaAccess.hpp"
 #include "jvmci/jvmciCompiler.hpp"
 #include "jvmci/jvmciEnv.hpp"
 #include "jvmci/jvmciRuntime.hpp"
@@ -123,17 +124,26 @@
   }
 
   JVMCIRuntime::ensure_jvmci_class_loader_is_initialized();
+  jvmci_compute_offsets();
   HandleMark hm;
   ResourceMark rm;
+  Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime();
+
+  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, CHECK_ABORT);
+  }
+
   JavaValue result(T_VOID);
   JavaCallArguments args;
-  Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime();
   args.push_oop(receiver);
-  args.push_long((jlong) (address) method());
+  args.push_oop((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::compileMetaspaceMethod_name(), vmSymbols::compileMetaspaceMethod_signature(), &args, CHECK_ABORT);
+  JavaCalls::call_special(&result, receiver->klass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, CHECK_ABORT);
 
   _methodsCompiled++;
 }
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Fri Aug 21 11:57:29 2015 -0700
@@ -53,42 +53,36 @@
 
 #define C2V_END }
 
-extern "C" {
-extern VMStructEntry* gHotSpotVMStructs;
-extern uint64_t gHotSpotVMStructEntryTypeNameOffset;
-extern uint64_t gHotSpotVMStructEntryFieldNameOffset;
-extern uint64_t gHotSpotVMStructEntryTypeStringOffset;
-extern uint64_t gHotSpotVMStructEntryIsStaticOffset;
-extern uint64_t gHotSpotVMStructEntryOffsetOffset;
-extern uint64_t gHotSpotVMStructEntryAddressOffset;
-extern uint64_t gHotSpotVMStructEntryArrayStride;
+oop CompilerToVM::get_jvmci_method(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);
 
-extern VMTypeEntry* gHotSpotVMTypes;
-extern uint64_t gHotSpotVMTypeEntryTypeNameOffset;
-extern uint64_t gHotSpotVMTypeEntrySuperclassNameOffset;
-extern uint64_t gHotSpotVMTypeEntryIsOopTypeOffset;
-extern uint64_t gHotSpotVMTypeEntryIsIntegerTypeOffset;
-extern uint64_t gHotSpotVMTypeEntryIsUnsignedOffset;
-extern uint64_t gHotSpotVMTypeEntrySizeOffset;
-extern uint64_t gHotSpotVMTypeEntryArrayStride;
+    return (oop)result.get_jobject();
+  }
+  return NULL;
+}
 
-extern VMIntConstantEntry* gHotSpotVMIntConstants;
-extern uint64_t gHotSpotVMIntConstantEntryNameOffset;
-extern uint64_t gHotSpotVMIntConstantEntryValueOffset;
-extern uint64_t gHotSpotVMIntConstantEntryArrayStride;
+oop CompilerToVM::get_jvmci_type(KlassHandle klass, TRAPS) {
+  if (klass() != NULL) {
+    JavaValue result(T_OBJECT);
+    JavaCallArguments args;
+    args.push_oop(klass->java_mirror());
+    JavaCalls::call_static(&result, SystemDictionary::HotSpotResolvedObjectTypeImpl_klass(), vmSymbols::fromMetaspace_name(), vmSymbols::klass_fromMetaspace_signature(), &args, CHECK_NULL);
 
-extern VMLongConstantEntry* gHotSpotVMLongConstants;
-extern uint64_t gHotSpotVMLongConstantEntryNameOffset;
-extern uint64_t gHotSpotVMLongConstantEntryValueOffset;
-extern uint64_t gHotSpotVMLongConstantEntryArrayStride;
+    return (oop)result.get_jobject();
+  }
+  return NULL;
 }
 
 C2V_VMENTRY(void, initializeConfiguration, (JNIEnv *, jobject, jobject config))
   VMStructs::initHotSpotVMConfig(JNIHandles::resolve(config));
 C2V_END
 
-C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv *, jobject, jlong metaspace_method))
-  methodHandle method = asMethod(metaspace_method);
+C2V_VMENTRY(jbyteArray, getBytecode, (JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
   ResourceMark rm;
 
   int code_size = method->code_size();
@@ -157,24 +151,24 @@
   return (jbyteArray) JNIHandles::make_local(THREAD, reconstituted_code);
 C2V_END
 
-C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv *, jobject, jlong metaspace_method))
+C2V_VMENTRY(jint, getExceptionTableLength, (JNIEnv *, jobject, jobject jvmci_method))
   ResourceMark rm;
-  methodHandle method = asMethod(metaspace_method);
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
   return method->exception_table_length();
 C2V_END
 
-C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv *, jobject, jlong metaspace_method))
+C2V_VMENTRY(jlong, getExceptionTableStart, (JNIEnv *, jobject, jobject jvmci_method))
   ResourceMark rm;
-  methodHandle method = asMethod(metaspace_method);
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
   if (method->exception_table_length() == 0) {
     return 0L;
   }
   return (jlong) (address) method->exception_table_start();
 C2V_END
 
-C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jlong metaspace_method))
+C2V_VMENTRY(jint, hasBalancedMonitors, (JNIEnv *, jobject, jobject jvmci_method))
   // Analyze the method to see if monitors are used properly.
-  methodHandle method(THREAD, asMethod(metaspace_method));
+  methodHandle method(THREAD, CompilerToVM::asMethod(jvmci_method));
   {
     EXCEPTION_MARK;
     ResourceMark rm(THREAD);
@@ -188,44 +182,126 @@
   return true;
 C2V_END
 
-C2V_VMENTRY(jlong, getMetaspaceMethod, (JNIEnv *, jobject, jclass holder_handle, jint slot))
+C2V_VMENTRY(jobject, getResolvedJavaMethodAtSlot, (JNIEnv *, jobject, jclass holder_handle, jint slot))
   oop java_class = JNIHandles::resolve(holder_handle);
   Klass* holder = java_lang_Class::as_Klass(java_class);
   methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot);
-  return (jlong) (address) method();
+  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+}
+
+C2V_VMENTRY(jobject, getResolvedJavaMethod, (JNIEnv *, jobject, jobject base, jlong offset))
+  methodHandle method;
+  oop base_object = JNIHandles::resolve(base);
+  if (base_object == NULL) {
+    method = *((Method**)(offset));
+  } else if (base_object->is_a(SystemDictionary::MemberName_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()));
+  }
+  assert (method.is_null() || method->is_method(), "invalid read");
+  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
 }
 
-C2V_VMENTRY(jlong, findUniqueConcreteMethod, (JNIEnv *, jobject, jlong metaspace_klass, jlong metaspace_method))
-  methodHandle method = asMethod(metaspace_method);
-  KlassHandle holder = asKlass(metaspace_klass);
+C2V_VMENTRY(jobject, getConstantPool, (JNIEnv *, jobject, jobject base, jlong offset))
+  constantPoolHandle cp;
+  oop base_object = JNIHandles::resolve(base);
+  jlong base_address = 0;
+  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 {
+      THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+                  err_msg("Unexpected type: %s", base_object->klass()->external_name()));
+    }
+  }
+  cp = *((ConstantPool**) (intptr_t) (base_address + offset));
+  if (!cp.is_null()) {
+    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());
+  }
+  return NULL;
+}
+
+C2V_VMENTRY(jobject, getResolvedJavaType, (JNIEnv *, jobject, jobject base, jlong offset, jboolean compressed))
+  KlassHandle klass;
+  oop base_object = JNIHandles::resolve(base);
+  jlong base_address = 0;
+  if (base_object != NULL && offset == oopDesc::klass_offset_in_bytes()) {
+    klass = base_object->klass();
+  } 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"));
+      }
+    }
+    klass = *((Klass**) (intptr_t) (base_address + offset));
+  } 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"));
+  }
+  assert (klass.is_null() || klass->is_klass(), "invalid read");
+  oop result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
+}
+
+C2V_VMENTRY(jobject, findUniqueConcreteMethod, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
+  KlassHandle holder = CompilerToVM::asKlass(jvmci_type);
   assert(!holder->is_interface(), "should be handled in Java code");
   ResourceMark rm;
-  MutexLocker locker(Compile_lock);
-  Method* ucm = Dependencies::find_unique_concrete_method(holder(), method());
-  return (jlong) (address) ucm;
+  methodHandle ucm;
+  {
+    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);
 C2V_END
 
-C2V_VMENTRY(jlong, getKlassImplementor, (JNIEnv *, jobject, jlong metaspace_klass))
-  InstanceKlass* klass = (InstanceKlass*) asKlass(metaspace_klass);
-  return (jlong) (address) klass->implementor();
+C2V_VMENTRY(jobject, getKlassImplementor, (JNIEnv *, jobject, jobject jvmci_type))
+  InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
+  oop implementor = CompilerToVM::get_jvmci_type(klass->implementor(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, implementor); 
 C2V_END
 
-C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, jlong metaspace_method))
-  methodHandle method = asMethod(metaspace_method);
+C2V_VMENTRY(jboolean, methodIsIgnoredBySecurityStackWalk,(JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
   return method->is_ignored_by_security_stack_walk();
 C2V_END
 
-C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jlong metaspace_method))
-  methodHandle method = asMethod(metaspace_method);
+C2V_VMENTRY(jboolean, canInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
   return !method->is_not_compilable() && !CompilerOracle::should_not_inline(method) && !method->dont_inline();
 C2V_END
 
-C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jlong metaspace_method))
-  methodHandle method = asMethod(metaspace_method);
+C2V_VMENTRY(jboolean, shouldInlineMethod,(JNIEnv *, jobject, jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
   return CompilerOracle::should_inline(method) || method->force_inline();
 C2V_END
 
-C2V_VMENTRY(jlong, lookupType, (JNIEnv*, jobject, jstring jname, jclass accessing_class, jboolean resolve))
+C2V_VMENTRY(jobject, lookupType, (JNIEnv*, jobject, jstring jname, jclass accessing_class, jboolean resolve))
   ResourceMark rm;
   Handle name = JNIHandles::resolve(jname);
   Symbol* class_name = java_lang_String::as_symbol(name, THREAD);
@@ -276,53 +352,57 @@
       }
     }
   }
-  return (jlong) (address) resolved_klass;
+  Handle result = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result());
 C2V_END
 
-C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   oop result = cp->resolve_constant_at(index, CHECK_NULL);
   return JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
   return JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   return cp->name_and_type_ref_index_at(index);
 C2V_END
 
-C2V_VMENTRY(jobject, lookupNameRefInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jobject, lookupNameRefInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   Handle sym = java_lang_String::create_from_symbol(cp->name_ref_at(index), CHECK_NULL);
   return JNIHandles::make_local(THREAD, sym());
 C2V_END
 
-C2V_VMENTRY(jobject, lookupSignatureRefInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jobject, lookupSignatureRefInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   Handle sym = java_lang_String::create_from_symbol(cp->signature_ref_at(index), CHECK_NULL);
   return JNIHandles::make_local(THREAD, sym());
 C2V_END
 
-C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   return cp->klass_ref_index_at(index);
 C2V_END
 
-C2V_VMENTRY(jlong, resolveKlassInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
-  return (jlong) (address) cp->klass_at(index, THREAD);
+C2V_VMENTRY(jobject, resolveKlassInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
+  Klass* resolved_klass = cp->klass_at(index, CHECK_NULL);
+  Handle klass = CompilerToVM::get_jvmci_type(resolved_klass, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, klass());
 C2V_END
 
-C2V_VMENTRY(jlong, lookupKlassInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
-  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jobject, lookupKlassInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   KlassHandle loading_klass(cp->pool_holder());
   bool is_accessible = false;
   KlassHandle klass = JVMCIEnv::get_klass_by_index(cp, index, is_accessible, loading_klass);
+  Symbol* symbol = NULL;
   if (klass.is_null()) {
     // We have to lock the cpool to keep the oop from being resolved
     // while we are accessing it.
@@ -331,39 +411,46 @@
     if (tag.is_klass()) {
       // The klass has been inserted into the constant pool
       // very recently.
-      return (jlong) CompilerToVM::tag_pointer(cp->resolved_klass_at(index));
+      klass = cp->resolved_klass_at(index);
     } else if (tag.is_symbol()) {
-      return (jlong) CompilerToVM::tag_pointer(cp->symbol_at(index));
+      symbol = cp->symbol_at(index);
     } else {
       assert(cp->tag_at(index).is_unresolved_klass(), "wrong tag");
-      return (jlong) CompilerToVM::tag_pointer(cp->unresolved_klass_at(index));
+      symbol = cp->unresolved_klass_at(index);
     }
   }
-  return (jlong) CompilerToVM::tag_pointer(klass());
+  Handle result;
+  if (!klass.is_null()) {
+    result = CompilerToVM::get_jvmci_type(klass, CHECK_NULL);
+  } else {
+    result = java_lang_String::create_from_symbol(symbol, CHECK_NULL);
+  }
+  return JNIHandles::make_local(THREAD, result());
 C2V_END
 
-C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jobject, lookupAppendixInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   oop appendix_oop = ConstantPool::appendix_at_if_loaded(cp, index);
   return JNIHandles::make_local(THREAD, appendix_oop);
 C2V_END
 
-C2V_VMENTRY(jlong, lookupMethodInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode))
-  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jobject, lookupMethodInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   instanceKlassHandle 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);
-  return (jlong) (address) method();
+  oop result = CompilerToVM::get_jvmci_method(method, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  ConstantPool* cp = (ConstantPool*) metaspace_constant_pool;
+C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   return cp->remap_instruction_operand_from_cache(index);
 C2V_END
 
-C2V_VMENTRY(jlong, resolveFieldInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
+C2V_VMENTRY(jobject, resolveFieldInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index, jbyte opcode, jlongArray info_handle))
   ResourceMark rm;
-  constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   Bytecodes::Code code = (Bytecodes::Code)(((int) opcode) & 0xFF);
   fieldDescriptor result;
   LinkResolver::resolve_field_access(result, cp, index, Bytecodes::java_code(code), true, false, CHECK_0);
@@ -371,20 +458,21 @@
   assert(info != NULL && info->length() == 2, "must be");
   info->long_at_put(0, (jlong) result.access_flags().as_int());
   info->long_at_put(1, (jlong) result.offset());
-  return (jlong) (address) result.field_holder();
+  oop field_holder = CompilerToVM::get_jvmci_type(result.field_holder(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, field_holder);
 C2V_END
 
-C2V_VMENTRY(jint, getVtableIndexForInterface, (JNIEnv *, jobject, jlong metaspace_klass, jlong metaspace_method))
-  Klass* klass = (Klass*) metaspace_klass;
-  Method* method = (Method*) metaspace_method;
+C2V_VMENTRY(jint, getVtableIndexForInterface, (JNIEnv *, jobject, jobject jvmci_type, jobject jvmci_method))
+  Klass* klass = CompilerToVM::asKlass(jvmci_type);
+  Method* method = CompilerToVM::asMethod(jvmci_method);
   assert(!klass->is_interface(), "");
   return LinkResolver::vtable_index_of_interface_method(klass, method);
 C2V_END
 
-C2V_VMENTRY(jlong, resolveMethod, (JNIEnv *, jobject, jlong metaspace_klass_receiver, jlong metaspace_method, jlong metaspace_klass_caller))
-  Klass* recv_klass = (Klass*) metaspace_klass_receiver;
-  Klass* caller_klass = (Klass*) metaspace_klass_caller;
-  Method* method = (Method*) metaspace_method;
+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);
+  Method* method = CompilerToVM::asMethod(jvmci_method);
 
   if (recv_klass->oop_is_array() || (InstanceKlass::cast(recv_klass)->is_linked())) {
     Klass* holder_klass = method->method_holder();
@@ -397,7 +485,7 @@
       methodHandle resolved_method;
       LinkResolver::linktime_resolve_interface_method(resolved_method, holder_klass, method_name, method_signature, caller_klass, true, CHECK_AND_CLEAR_0);
       if (resolved_method->is_private()) {
-        return (jlong) (address) NULL;
+        return NULL;
       }
       assert(recv_klass->is_subtype_of(holder_klass), "");
       // do actual lookup
@@ -405,7 +493,8 @@
       LinkResolver::lookup_instance_method_in_klasses(sel_method, recv_klass,
                 resolved_method->name(),
                 resolved_method->signature(), CHECK_AND_CLEAR_0);
-      return (jlong) (address) sel_method();
+      oop result = CompilerToVM::get_jvmci_method(sel_method, CHECK_NULL);
+      return JNIHandles::make_local(THREAD, result);
     } else {
       // do link-time resolution to check all access rules.
       methodHandle resolved_method;
@@ -440,21 +529,23 @@
           selected_method = inst->method_at_vtable(vtable_index);
         }
       }
-      return (jlong) (address) selected_method;
+      oop result = CompilerToVM::get_jvmci_method(selected_method, CHECK_NULL);
+      return JNIHandles::make_local(THREAD, result);
     }
   }
-  return (jlong) (address) NULL;
+  return NULL;
 C2V_END
 
-C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jlong metaspace_klass))
-  Klass* klass = (Klass*) metaspace_klass;
+C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type))
+  Klass* klass = CompilerToVM::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(jlong, getClassInitializer, (JNIEnv *, jobject, jlong metaspace_klass))
-  InstanceKlass* klass = (InstanceKlass*) metaspace_klass;
-  return (jlong) (address) klass->class_initializer();
+C2V_VMENTRY(jobject, getClassInitializer, (JNIEnv *, jobject, jobject jvmci_type))
+  InstanceKlass* klass = (InstanceKlass*) CompilerToVM::asKlass(jvmci_type);
+  oop result = CompilerToVM::get_jvmci_method(klass->class_initializer(), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, result);
 C2V_END
 
 C2V_VMENTRY(jlong, getMaxCallTargetOffset, (JNIEnv*, jobject, jlong addr))
@@ -467,8 +558,8 @@
   return -1;
 C2V_END
 
-C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject,  jlong metaspace_method))
-  methodHandle method = asMethod(metaspace_method);
+C2V_VMENTRY(void, doNotInlineOrCompile,(JNIEnv *, jobject,  jobject jvmci_method))
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
   method->set_not_c1_compilable();
   method->set_not_c2_compilable();
   method->set_dont_inline(true);
@@ -537,7 +628,7 @@
   }
 
   if (CITimeEach) {
-    methodHandle method = asMethod(HotSpotResolvedJavaMethodImpl::metaspaceMethod(hotspot_method));
+    methodHandle method = CompilerToVM::asMethod(hotspot_method);
     float bytes_per_sec = 1.0 * processedBytecodes / timer.seconds();
     tty->print_cr("%3d   seconds: %f bytes/sec: %f (bytes %d)",
                   id, timer.seconds(), bytes_per_sec, processedBytecodes);
@@ -585,11 +676,11 @@
   return JNIHandles::make_local(THREAD, result());
 C2V_END
 
-C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv*, jobject, jlong metaspace_method, int bci))
+C2V_VMENTRY(jobject, getStackTraceElement, (JNIEnv*, jobject, jobject jvmci_method, int bci))
   ResourceMark rm;
   HandleMark hm;
 
-  methodHandle method = asMethod(metaspace_method);
+  methodHandle method = CompilerToVM::asMethod(jvmci_method);
   oop element = java_lang_StackTraceElement::create(method, bci, CHECK_NULL);
   return JNIHandles::make_local(THREAD, element);
 C2V_END
@@ -638,8 +729,8 @@
   }
 C2V_END
 
-C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv *, jobject, jlong metaspace_method))
-  Method* method = (Method*) metaspace_method;
+C2V_VMENTRY(jlongArray, getLineNumberTable, (JNIEnv *, jobject, jobject jvmci_method))
+  Method* method = CompilerToVM::asMethod(jvmci_method);
   if (!method->has_linenumber_table()) {
     return NULL;
   }
@@ -665,23 +756,23 @@
   return (jlongArray) JNIHandles::make_local(THREAD, result);
 C2V_END
 
-C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv *, jobject, jlong metaspace_method))
+C2V_VMENTRY(jlong, getLocalVariableTableStart, (JNIEnv *, jobject, jobject jvmci_method))
   ResourceMark rm;
-  Method* method = (Method*) metaspace_method;
+  Method* method = CompilerToVM::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, jlong metaspace_method))
+C2V_VMENTRY(jint, getLocalVariableTableLength, (JNIEnv *, jobject, jobject jvmci_method))
   ResourceMark rm;
-  Method* method = (Method*) metaspace_method;
+  Method* method = CompilerToVM::asMethod(jvmci_method);
   return method->localvariable_table_length();
 C2V_END
 
-C2V_VMENTRY(void, reprofile, (JNIEnv*, jobject, jlong metaspace_method))
-  Method* method = asMethod(metaspace_method);
+C2V_VMENTRY(void, reprofile, (JNIEnv*, jobject, jobject jvmci_method))
+  Method* method = CompilerToVM::asMethod(jvmci_method);
   MethodCounters* mcs = method->method_counters();
   if (mcs != NULL) {
     mcs->clear_counters();
@@ -715,8 +806,8 @@
   InstalledCode::set_address(hotspotInstalledCode, 0);
 C2V_END
 
-C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv* env, jobject, jlong metaspace_klass))
-  Klass* klass = asKlass(metaspace_klass);
+C2V_VMENTRY(jobject, getJavaMirror, (JNIEnv* env, jobject, jobject jvmci_type))
+  Klass* klass = CompilerToVM::asKlass(jvmci_type);
   return JNIHandles::make_local(THREAD, klass->java_mirror());
 C2V_END
 
@@ -731,21 +822,21 @@
   return (jlongArray) JNIHandles::make_local(THREAD, arrayOop);
 C2V_END
 
-C2V_VMENTRY(int, allocateCompileId, (JNIEnv*, jobject, jlong metaspace_method, int entry_bci))
+C2V_VMENTRY(int, allocateCompileId, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci))
   HandleMark hm;
   ResourceMark rm;
-  Method* method = (Method*) metaspace_method;
+  Method* method = CompilerToVM::asMethod(jvmci_method);
   return CompileBroker::assign_compile_id_unlocked(THREAD, method, entry_bci);
 C2V_END
 
 
 C2V_VMENTRY(jboolean, isMature, (JNIEnv*, jobject, jlong metaspace_method_data))
-  MethodData* mdo = asMethodData(metaspace_method_data);
+  MethodData* mdo = CompilerToVM::asMethodData(metaspace_method_data);
   return mdo != NULL && mdo->is_mature();
 C2V_END
 
-C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv*, jobject, jlong metaspace_method, int entry_bci, int comp_level))
-  Method* method = asMethod(metaspace_method);
+C2V_VMENTRY(jboolean, hasCompiledCodeForOSR, (JNIEnv*, jobject, jobject jvmci_method, int entry_bci, int comp_level))
+  Method* method = CompilerToVM::asMethod(jvmci_method);
   return method->lookup_osr_nmethod_for(entry_bci, comp_level, true) != NULL;
 C2V_END
 
@@ -760,18 +851,18 @@
   return JNIHandles::make_local(THREAD, sym());
 C2V_END
 
-bool matches(jlongArray methods, Method* method) {
-  typeArrayOop methods_oop = (typeArrayOop) JNIHandles::resolve(methods);
+bool matches(jobjectArray methods, Method* method) {
+  objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
 
   for (int i = 0; i < methods_oop->length(); i++) {
-    if (methods_oop->long_at(i) == (jlong) method) {
+    if (CompilerToVM::asMethod(methods_oop->obj_at(i)) == method) {
       return true;
     }
   }
   return false;
 }
 
-C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject hs_frame, jlongArray methods, jint initialSkip))
+C2V_VMENTRY(jobject, getNextStackFrame, (JNIEnv*, jobject compilerToVM, jobject hs_frame, jobjectArray methods, jint initialSkip))
   ResourceMark rm;
 
   if (!thread->has_last_Java_frame()) return NULL;
@@ -848,7 +939,8 @@
 
             locals = cvf->locals();
             HotSpotStackFrameReference::set_bci(result, cvf->bci());
-            HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) cvf->method());
+            oop method = CompilerToVM::get_jvmci_method(cvf->method(), CHECK_NULL);
+            HotSpotStackFrameReference::set_method(result, method);
           }
         }
       } else if (vf->is_interpreted_frame()) {
@@ -860,7 +952,8 @@
           } else {
             locals = ivf->locals();
             HotSpotStackFrameReference::set_bci(result, ivf->bci());
-            HotSpotStackFrameReference::set_metaspaceMethod(result, (jlong) ivf->method());
+            oop method = CompilerToVM::get_jvmci_method(ivf->method(), CHECK_NULL);
+            HotSpotStackFrameReference::set_method(result, method);
             HotSpotStackFrameReference::set_localIsVirtual(result, NULL);
           }
         }
@@ -904,16 +997,16 @@
   return NULL;
 C2V_END
 
-C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
-  ConstantPool* cp = (ConstantPool*)metaspace_constant_pool;
+C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   CallInfo callInfo;
   LinkResolver::resolve_invokedynamic(callInfo, cp, index, 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, jlong metaspace_constant_pool, jint index))
-  ConstantPool* cp = (ConstantPool*)metaspace_constant_pool;
+C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv*, jobject, jobject jvmci_constant_pool, jint index))
+  constantPoolHandle cp = CompilerToVM::asConstantPool(jvmci_constant_pool);
   CallInfo callInfo;
   LinkResolver::resolve_invokehandle(callInfo, cp, index, CHECK);
   ConstantPoolCacheEntry* cp_cache_entry = cp_cache_entry = cp->cache()->entry_at(cp->decode_cpcache_index(index));
@@ -1042,75 +1135,77 @@
 #define STACK_TRACE_ELEMENT   "Ljava/lang/StackTraceElement;"
 #define INSTALLED_CODE        "Ljdk/internal/jvmci/code/InstalledCode;"
 #define RESOLVED_METHOD       "Ljdk/internal/jvmci/meta/ResolvedJavaMethod;"
-#define HS_RESOLVED_METHOD    "Ljdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethod;"
+#define HS_RESOLVED_METHOD    "Ljdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl;"
+#define HS_RESOLVED_KLASS     "Ljdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl;"
+#define HS_CONSTANT_POOL      "Ljdk/internal/jvmci/hotspot/HotSpotConstantPool;"
 #define HS_COMPILED_CODE      "Ljdk/internal/jvmci/hotspot/HotSpotCompiledCode;"
 #define HS_CONFIG             "Ljdk/internal/jvmci/hotspot/HotSpotVMConfig;"
 #define HS_STACK_FRAME_REF    "Ljdk/internal/jvmci/hotspot/HotSpotStackFrameReference;"
-#define METASPACE_KLASS       "J"
-#define METASPACE_METHOD      "J"
 #define METASPACE_METHOD_DATA "J"
-#define METASPACE_CONSTANT_POOL "J"
 
-JNINativeMethod CompilerToVM_methods[] = {
-  {CC"getBytecode",                                  CC"("METASPACE_METHOD")[B",                                               FN_PTR(getBytecode)},
-  {CC"getExceptionTableStart",                       CC"("METASPACE_METHOD")J",                                                FN_PTR(getExceptionTableStart)},
-  {CC"getExceptionTableLength",                      CC"("METASPACE_METHOD")I",                                                FN_PTR(getExceptionTableLength)},
-  {CC"hasBalancedMonitors",                          CC"("METASPACE_METHOD")Z",                                                FN_PTR(hasBalancedMonitors)},
-  {CC"findUniqueConcreteMethod",                     CC"("METASPACE_KLASS METASPACE_METHOD")"METASPACE_METHOD,                 FN_PTR(findUniqueConcreteMethod)},
-  {CC"getKlassImplementor",                          CC"("METASPACE_KLASS")"METASPACE_KLASS,                                   FN_PTR(getKlassImplementor)},
-  {CC"getStackTraceElement",                         CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT,                             FN_PTR(getStackTraceElement)},
-  {CC"methodIsIgnoredBySecurityStackWalk",           CC"("METASPACE_METHOD")Z",                                                FN_PTR(methodIsIgnoredBySecurityStackWalk)},
-  {CC"doNotInlineOrCompile",                         CC"("METASPACE_METHOD")V",                                                FN_PTR(doNotInlineOrCompile)},
-  {CC"canInlineMethod",                              CC"("METASPACE_METHOD")Z",                                                FN_PTR(canInlineMethod)},
-  {CC"shouldInlineMethod",                           CC"("METASPACE_METHOD")Z",                                                FN_PTR(shouldInlineMethod)},
-  {CC"lookupType",                                   CC"("STRING CLASS"Z)"METASPACE_KLASS,                                     FN_PTR(lookupType)},
-  {CC"lookupNameRefInPool0",                         CC"("METASPACE_CONSTANT_POOL"I)"STRING,                                   FN_PTR(lookupNameRefInPool)},
-  {CC"lookupNameAndTypeRefIndexInPool",              CC"("METASPACE_CONSTANT_POOL"I)I",                                        FN_PTR(lookupNameAndTypeRefIndexInPool)},
-  {CC"lookupSignatureRefInPool0",                    CC"("METASPACE_CONSTANT_POOL"I)"STRING,                                   FN_PTR(lookupSignatureRefInPool)},
-  {CC"lookupKlassRefIndexInPool0",                   CC"("METASPACE_CONSTANT_POOL"I)I",                                        FN_PTR(lookupKlassRefIndexInPool)},
-  {CC"lookupKlassInPool",                            CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS,                          FN_PTR(lookupKlassInPool)},
-  {CC"lookupAppendixInPool0",                        CC"("METASPACE_CONSTANT_POOL"I)"OBJECT,                                   FN_PTR(lookupAppendixInPool)},
-  {CC"lookupMethodInPool",                           CC"("METASPACE_CONSTANT_POOL"IB)"METASPACE_METHOD,                        FN_PTR(lookupMethodInPool)},
-  {CC"constantPoolRemapInstructionOperandFromCache0",CC"("METASPACE_CONSTANT_POOL"I)I",                                        FN_PTR(constantPoolRemapInstructionOperandFromCache)},
-  {CC"resolveConstantInPool",                        CC"("METASPACE_CONSTANT_POOL"I)"OBJECT,                                   FN_PTR(resolveConstantInPool)},
-  {CC"resolvePossiblyCachedConstantInPool0",         CC"("METASPACE_CONSTANT_POOL"I)"OBJECT,                                   FN_PTR(resolvePossiblyCachedConstantInPool)},
-  {CC"resolveKlassInPool",                           CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS,                          FN_PTR(resolveKlassInPool)},
-  {CC"resolveFieldInPool",                           CC"("METASPACE_CONSTANT_POOL"IB[J)"METASPACE_KLASS,                       FN_PTR(resolveFieldInPool)},
-  {CC"resolveInvokeDynamicInPool",                   CC"("METASPACE_CONSTANT_POOL"I)V",                                        FN_PTR(resolveInvokeDynamicInPool)},
-  {CC"resolveInvokeHandleInPool",                    CC"("METASPACE_CONSTANT_POOL"I)V",                                        FN_PTR(resolveInvokeHandleInPool)},
-  {CC"resolveMethod",                                CC"("METASPACE_KLASS METASPACE_METHOD METASPACE_KLASS")"METASPACE_METHOD, FN_PTR(resolveMethod)},
-  {CC"getVtableIndexForInterface",                   CC"("METASPACE_KLASS METASPACE_METHOD")I",                                FN_PTR(getVtableIndexForInterface)},
-  {CC"getClassInitializer",                          CC"("METASPACE_KLASS")"METASPACE_METHOD,                                  FN_PTR(getClassInitializer)},
-  {CC"hasFinalizableSubclass",                       CC"("METASPACE_KLASS")Z",                                                 FN_PTR(hasFinalizableSubclass)},
-  {CC"getMaxCallTargetOffset",                       CC"(J)J",                                                                 FN_PTR(getMaxCallTargetOffset)},
-  {CC"getMetaspaceMethod",                           CC"("CLASS"I)"METASPACE_METHOD,                                           FN_PTR(getMetaspaceMethod)},
-  {CC"initializeConfiguration",                      CC"("HS_CONFIG")V",                                                       FN_PTR(initializeConfiguration)},
-  {CC"installCode",                                  CC"("HS_COMPILED_CODE INSTALLED_CODE SPECULATION_LOG")I",                 FN_PTR(installCode)},
-  {CC"notifyCompilationStatistics",                  CC"(I"HS_RESOLVED_METHOD"ZIJJ"INSTALLED_CODE")V",                         FN_PTR(notifyCompilationStatistics)},
-  {CC"resetCompilationStatistics",                   CC"()V",                                                                  FN_PTR(resetCompilationStatistics)},
-  {CC"disassembleCodeBlob",                          CC"(J)"STRING,                                                            FN_PTR(disassembleCodeBlob)},
-  {CC"executeInstalledCode",                         CC"(["OBJECT INSTALLED_CODE")"OBJECT,                                     FN_PTR(executeInstalledCode)},
-  {CC"getLineNumberTable",                           CC"("METASPACE_METHOD")[J",                                               FN_PTR(getLineNumberTable)},
-  {CC"getLocalVariableTableStart",                   CC"("METASPACE_METHOD")J",                                                FN_PTR(getLocalVariableTableStart)},
-  {CC"getLocalVariableTableLength",                  CC"("METASPACE_METHOD")I",                                                FN_PTR(getLocalVariableTableLength)},
-  {CC"reprofile",                                    CC"("METASPACE_METHOD")V",                                                FN_PTR(reprofile)},
-  {CC"invalidateInstalledCode",                      CC"("INSTALLED_CODE")V",                                                  FN_PTR(invalidateInstalledCode)},
-  {CC"getJavaMirror",                                CC"("METASPACE_KLASS")"CLASS,                                             FN_PTR(getJavaMirror)},
-  {CC"readUncompressedOop",                          CC"(J)"OBJECT,                                                            FN_PTR(readUncompressedOop)},
-  {CC"collectCounters",                              CC"()[J",                                                                 FN_PTR(collectCounters)},
-  {CC"allocateCompileId",                            CC"("METASPACE_METHOD"I)I",                                               FN_PTR(allocateCompileId)},
-  {CC"isMature",                                     CC"("METASPACE_METHOD_DATA")Z",                                           FN_PTR(isMature)},
-  {CC"hasCompiledCodeForOSR",                        CC"("METASPACE_METHOD"II)Z",                                              FN_PTR(hasCompiledCodeForOSR)},
-  {CC"getSymbol0",                                   CC"(J)"STRING,                                                            FN_PTR(getSymbol)},
-  {CC"getTimeStamp",                                 CC"()J",                                                                  FN_PTR(getTimeStamp)},
-  {CC"getNextStackFrame",                            CC"("HS_STACK_FRAME_REF "[JI)"HS_STACK_FRAME_REF,                         FN_PTR(getNextStackFrame)},
-  {CC"materializeVirtualObjects",                    CC"("HS_STACK_FRAME_REF"Z)V",                                             FN_PTR(materializeVirtualObjects)},
-  {CC"shouldDebugNonSafepoints",                     CC"()Z",                                                                  FN_PTR(shouldDebugNonSafepoints)},
-  {CC"writeDebugOutput",                             CC"([BII)V",                                                              FN_PTR(writeDebugOutput)},
-  {CC"flushDebugOutput",                             CC"()V",                                                                  FN_PTR(flushDebugOutput)},
+JNINativeMethod CompilerToVM::methods[] = {
+  {CC"getBytecode",                                  CC"("HS_RESOLVED_METHOD")[B",                                                     FN_PTR(getBytecode)},
+  {CC"getExceptionTableStart",                       CC"("HS_RESOLVED_METHOD")J",                                                      FN_PTR(getExceptionTableStart)},
+  {CC"getExceptionTableLength",                      CC"("HS_RESOLVED_METHOD")I",                                                      FN_PTR(getExceptionTableLength)},
+  {CC"hasBalancedMonitors",                          CC"("HS_RESOLVED_METHOD")Z",                                                      FN_PTR(hasBalancedMonitors)},
+  {CC"findUniqueConcreteMethod",                     CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD")"HS_RESOLVED_METHOD,                   FN_PTR(findUniqueConcreteMethod)},
+  {CC"getKlassImplementor",                          CC"("HS_RESOLVED_KLASS")"HS_RESOLVED_KLASS,                                       FN_PTR(getKlassImplementor)},
+  {CC"getStackTraceElement",                         CC"("HS_RESOLVED_METHOD"I)"STACK_TRACE_ELEMENT,                                   FN_PTR(getStackTraceElement)},
+  {CC"methodIsIgnoredBySecurityStackWalk",           CC"("HS_RESOLVED_METHOD")Z",                                                      FN_PTR(methodIsIgnoredBySecurityStackWalk)},
+  {CC"doNotInlineOrCompile",                         CC"("HS_RESOLVED_METHOD")V",                                                      FN_PTR(doNotInlineOrCompile)},
+  {CC"canInlineMethod",                              CC"("HS_RESOLVED_METHOD")Z",                                                      FN_PTR(canInlineMethod)},
+  {CC"shouldInlineMethod",                           CC"("HS_RESOLVED_METHOD")Z",                                                      FN_PTR(shouldInlineMethod)},
+  {CC"lookupType",                                   CC"("STRING CLASS"Z)"HS_RESOLVED_KLASS,                                           FN_PTR(lookupType)},
+  {CC"lookupNameRefInPool0",                         CC"("HS_CONSTANT_POOL"I)"STRING,                                                  FN_PTR(lookupNameRefInPool)},
+  {CC"lookupNameAndTypeRefIndexInPool",              CC"("HS_CONSTANT_POOL"I)I",                                                       FN_PTR(lookupNameAndTypeRefIndexInPool)},
+  {CC"lookupSignatureRefInPool0",                    CC"("HS_CONSTANT_POOL"I)"STRING,                                                  FN_PTR(lookupSignatureRefInPool)},
+  {CC"lookupKlassRefIndexInPool0",                   CC"("HS_CONSTANT_POOL"I)I",                                                       FN_PTR(lookupKlassRefIndexInPool)},
+  {CC"lookupKlassInPool",                            CC"("HS_CONSTANT_POOL"I)Ljava/lang/Object;",                                      FN_PTR(lookupKlassInPool)},
+  {CC"lookupAppendixInPool0",                        CC"("HS_CONSTANT_POOL"I)"OBJECT,                                                  FN_PTR(lookupAppendixInPool)},
+  {CC"lookupMethodInPool",                           CC"("HS_CONSTANT_POOL"IB)"HS_RESOLVED_METHOD,                                     FN_PTR(lookupMethodInPool)},
+  {CC"constantPoolRemapInstructionOperandFromCache0",CC"("HS_CONSTANT_POOL"I)I",                                                       FN_PTR(constantPoolRemapInstructionOperandFromCache)},
+  {CC"resolveConstantInPool",                        CC"("HS_CONSTANT_POOL"I)"OBJECT,                                                  FN_PTR(resolveConstantInPool)},
+  {CC"resolvePossiblyCachedConstantInPool0",         CC"("HS_CONSTANT_POOL"I)"OBJECT,                                                  FN_PTR(resolvePossiblyCachedConstantInPool)},
+  {CC"resolveKlassInPool",                           CC"("HS_CONSTANT_POOL"I)"HS_RESOLVED_KLASS,                                       FN_PTR(resolveKlassInPool)},
+  {CC"resolveFieldInPool",                           CC"("HS_CONSTANT_POOL"IB[J)"HS_RESOLVED_KLASS,                                    FN_PTR(resolveFieldInPool)},
+  {CC"resolveInvokeDynamicInPool",                   CC"("HS_CONSTANT_POOL"I)V",                                                       FN_PTR(resolveInvokeDynamicInPool)},
+  {CC"resolveInvokeHandleInPool",                    CC"("HS_CONSTANT_POOL"I)V",                                                       FN_PTR(resolveInvokeHandleInPool)},
+  {CC"resolveMethod",                                CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD HS_RESOLVED_KLASS")"HS_RESOLVED_METHOD, FN_PTR(resolveMethod)},
+  {CC"getVtableIndexForInterface",                   CC"("HS_RESOLVED_KLASS HS_RESOLVED_METHOD")I",                                    FN_PTR(getVtableIndexForInterface)},
+  {CC"getClassInitializer",                          CC"("HS_RESOLVED_KLASS")"HS_RESOLVED_METHOD,                                      FN_PTR(getClassInitializer)},
+  {CC"hasFinalizableSubclass",                       CC"("HS_RESOLVED_KLASS")Z",                                                       FN_PTR(hasFinalizableSubclass)},
+  {CC"getMaxCallTargetOffset",                       CC"(J)J",                                                                         FN_PTR(getMaxCallTargetOffset)},
+  {CC"getResolvedJavaMethodAtSlot",                  CC"("CLASS"I)"HS_RESOLVED_METHOD,                                                 FN_PTR(getResolvedJavaMethodAtSlot)},
+  {CC"getResolvedJavaMethod",                        CC"(Ljava/lang/Object;J)"HS_RESOLVED_METHOD,                                      FN_PTR(getResolvedJavaMethod)},
+  {CC"getConstantPool",                              CC"(Ljava/lang/Object;J)"HS_CONSTANT_POOL,                                        FN_PTR(getConstantPool)},
+  {CC"getResolvedJavaType",                          CC"(Ljava/lang/Object;JZ)"HS_RESOLVED_KLASS,                                      FN_PTR(getResolvedJavaType)},
+  {CC"initializeConfiguration",                      CC"("HS_CONFIG")V",                                                               FN_PTR(initializeConfiguration)},
+  {CC"installCode",                                  CC"("HS_COMPILED_CODE INSTALLED_CODE SPECULATION_LOG")I",                         FN_PTR(installCode)},
+  {CC"notifyCompilationStatistics",                  CC"(I"HS_RESOLVED_METHOD"ZIJJ"INSTALLED_CODE")V",                                 FN_PTR(notifyCompilationStatistics)},
+  {CC"resetCompilationStatistics",                   CC"()V",                                                                          FN_PTR(resetCompilationStatistics)},
+  {CC"disassembleCodeBlob",                          CC"(J)"STRING,                                                                    FN_PTR(disassembleCodeBlob)},
+  {CC"executeInstalledCode",                         CC"(["OBJECT INSTALLED_CODE")"OBJECT,                                             FN_PTR(executeInstalledCode)},
+  {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"getJavaMirror",                                CC"("HS_RESOLVED_KLASS")"CLASS,                                                   FN_PTR(getJavaMirror)},
+  {CC"readUncompressedOop",                          CC"(J)"OBJECT,                                                                    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)},
+  {CC"hasCompiledCodeForOSR",                        CC"("HS_RESOLVED_METHOD"II)Z",                                                    FN_PTR(hasCompiledCodeForOSR)},
+  {CC"getSymbol0",                                   CC"(J)"STRING,                                                                    FN_PTR(getSymbol)},
+  {CC"getTimeStamp",                                 CC"()J",                                                                          FN_PTR(getTimeStamp)},
+  {CC"getNextStackFrame",                            CC"("HS_STACK_FRAME_REF "["HS_RESOLVED_METHOD"I)"HS_STACK_FRAME_REF,              FN_PTR(getNextStackFrame)},
+  {CC"materializeVirtualObjects",                    CC"("HS_STACK_FRAME_REF"Z)V",                                                     FN_PTR(materializeVirtualObjects)},
+  {CC"shouldDebugNonSafepoints",                     CC"()Z",                                                                          FN_PTR(shouldDebugNonSafepoints)},
+  {CC"writeDebugOutput",                             CC"([BII)V",                                                                      FN_PTR(writeDebugOutput)},
+  {CC"flushDebugOutput",                             CC"()V",                                                                          FN_PTR(flushDebugOutput)},
 };
 
-int CompilerToVM_methods_count() {
-  return sizeof(CompilerToVM_methods) / sizeof(JNINativeMethod);
+int CompilerToVM::methods_count() {
+  return sizeof(methods) / sizeof(JNINativeMethod);
 }
 
--- a/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.hpp	Fri Aug 21 11:57:29 2015 -0700
@@ -26,6 +26,7 @@
 
 #include "prims/jni.h"
 #include "runtime/javaCalls.hpp"
+#include "jvmci/jvmciJavaAccess.hpp"
 
 class CompilerToVM {
 public:
@@ -45,23 +46,53 @@
     return ((intptr_t) symbol) | SYMBOL_TAG;
   }
 
-  // nothing here - no need to define the jni method implementations in a header file
-};
-
-extern JNINativeMethod CompilerToVM_methods[];
-int CompilerToVM_methods_count();
+  static JNINativeMethod methods[];
+  static int methods_count();
+  
+  static inline Method* asMethod(jobject jvmci_method) {
+    return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
+  }
+  
+  static inline Method* asMethod(Handle jvmci_method) {
+    return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
+  }
+  
+  static inline Method* asMethod(oop jvmci_method) {
+    return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
+  }
+  
+  static inline ConstantPool* asConstantPool(jobject jvmci_constant_pool) {
+    return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
+  }
+  
+  static inline ConstantPool* asConstantPool(Handle jvmci_constant_pool) {
+    return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
+  }
+  
+  static inline ConstantPool* asConstantPool(oop jvmci_constant_pool) {
+    return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
+  }
+  
+  static inline Klass* asKlass(jobject jvmci_type) {
+    return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
+  }
 
-inline Method* asMethod(jlong metaspaceMethod) {
-  return (Method*) (address) metaspaceMethod;
-}
+  static inline Klass* asKlass(Handle jvmci_type) {
+    return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
+  }
+  
+  static inline Klass* asKlass(oop jvmci_type) {
+    return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
+  }
+  
+  static inline MethodData* asMethodData(jlong metaspaceMethodData) {
+    return (MethodData*) (address) metaspaceMethodData;
+  }
+  
+  static oop get_jvmci_method(methodHandle method, TRAPS);
 
-inline MethodData* asMethodData(jlong metaspaceMethodData) {
-  return (MethodData*) (address) metaspaceMethodData;
-}
-
-inline Klass* asKlass(jlong metaspaceKlass) {
-  return (Klass*) (address) metaspaceKlass;
-}
+  static oop get_jvmci_type(KlassHandle klass, TRAPS);
+};
 
 class JavaArgumentUnboxer : public SignatureIterator {
  protected:
--- a/src/share/vm/jvmci/jvmciJavaAccess.cpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/jvmci/jvmciJavaAccess.cpp	Fri Aug 21 11:57:29 2015 -0700
@@ -46,6 +46,7 @@
   }
   guarantee(fd.is_static() == static_field, "static/instance mismatch");
   dest_offset = fd.offset();
+  assert(dest_offset != 0, "must be valid offset");
 }
 
 // This piece of macro magic creates the contents of the jvmci_compute_offsets method that initializes the field indices of all the access classes.
@@ -67,7 +68,7 @@
 
 
 void jvmci_compute_offsets() {
-  COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
+  COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
   guarantee(InstalledCode::_address_offset == sizeof(oopDesc), "codeBlob must be first field!");
 }
 
@@ -77,7 +78,7 @@
 #define FIELD2(klass, name) int klass::_##name##_offset = 0;
 #define FIELD3(klass, name, sig) FIELD2(klass, name)
 
-COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2)
+COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2)
 
 
 
--- a/src/share/vm/jvmci/jvmciJavaAccess.hpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/jvmci/jvmciJavaAccess.hpp	Fri Aug 21 11:57:29 2015 -0700
@@ -47,7 +47,7 @@
  *
  */
 
-#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_int_field, static_boolean_field) \
+#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_objArrayOop_field, static_int_field, static_boolean_field) \
   start_class(HotSpotResolvedObjectTypeImpl)                                                                                                                   \
     oop_field(HotSpotResolvedObjectTypeImpl, javaClass, "Ljava/lang/Class;")                                                                                   \
   end_class                                                                                                                                                    \
@@ -94,6 +94,10 @@
     long_field(HotSpotCompiledNmethod, jvmciEnv)                                                                                                               \
     boolean_field(HotSpotCompiledNmethod, hasUnsafeAccess)                                                                                                     \
   end_class                                                                                                                                                    \
+  start_class(HotSpotJVMCIMetaAccessContext)                                                                                                                      \
+    static_objArrayOop_field(HotSpotJVMCIMetaAccessContext, allContexts, "[Ljava/lang/ref/WeakReference;")                                                        \
+    objArrayOop_field(HotSpotJVMCIMetaAccessContext, metadataRoots, "[Ljava/lang/Object;")                                                                        \
+  end_class                                                                                                                                                    \
   start_class(HotSpotForeignCallTarget)                                                                                                                        \
     long_field(HotSpotForeignCallTarget, address)                                                                                                              \
   end_class                                                                                                                                                    \
@@ -253,20 +257,23 @@
     long_field(HotSpotStackFrameReference, stackPointer)                                                                                                       \
     int_field(HotSpotStackFrameReference, frameNumber)                                                                                                         \
     int_field(HotSpotStackFrameReference, bci)                                                                                                                 \
-    long_field(HotSpotStackFrameReference, metaspaceMethod)                                                                                                    \
+    oop_field(HotSpotStackFrameReference, method, "Ljdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethod;")                                                    \
     objArrayOop_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;")                                                                               \
     typeArrayOop_field(HotSpotStackFrameReference, localIsVirtual, "[Z")                                                                                       \
-  end_class                                                                                                                                      
-              \
+  end_class                                                                                                                                                    \
+  start_class(HotSpotConstantPool)                                                                                                                             \
+    long_field(HotSpotConstantPool, metaspaceConstantPool)                                                                                                     \
+  end_class                                                                                                                                                    \
   /* end*/
 
 #define START_CLASS(name)                                                                                                                                      \
 class name : AllStatic {                                                                                                                                       \
   private:                                                                                                                                                     \
     friend class JVMCICompiler;                                                                                                                                \
-    static void check(oop obj, const char* field_name) {                                                                                                       \
+    static void check(oop obj, const char* field_name, int offset) {                                                                                           \
         assert(obj != NULL, err_msg("NULL field access of %s.%s", #name, field_name));                                                                         \
-        assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected");                                                                \
+        assert(obj->is_a(SystemDictionary::name##_klass()), err_msg("wrong class, " #name " expected, found %s", obj->klass()->external_name())); \
+        assert(offset != 0, "must be valid offset");                                                                                                           \
     }                                                                                                                                                          \
     static void compute_offsets();                                                                                                                             \
   public:                                                                                                                                                      \
@@ -276,12 +283,12 @@
 
 #define FIELD(name, type, accessor, cast)                                                                                                                         \
     static int _##name##_offset;                                                                                                                                  \
-    static type name(oop obj)                   { check(obj, #name); return cast obj->accessor(_##name##_offset); }                                               \
-    static type name(Handle& obj)                { check(obj(), #name); return cast obj->accessor(_##name##_offset); }                                            \
-    static type name(jobject obj)               { check(JNIHandles::resolve(obj), #name); return cast JNIHandles::resolve(obj)->accessor(_##name##_offset); }     \
-    static void set_##name(oop obj, type x)     { check(obj, #name); obj->accessor##_put(_##name##_offset, x); }                                                  \
-    static void set_##name(Handle& obj, type x)  { check(obj(), #name); obj->accessor##_put(_##name##_offset, x); }                                               \
-    static void set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj), #name); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); }
+    static type name(oop obj)                   { check(obj, #name, _##name##_offset); return cast obj->accessor(_##name##_offset); }                                               \
+    static type name(Handle& obj)                { check(obj(), #name, _##name##_offset); return cast obj->accessor(_##name##_offset); }                                            \
+    static type name(jobject obj)               { check(JNIHandles::resolve(obj), #name, _##name##_offset); return cast JNIHandles::resolve(obj)->accessor(_##name##_offset); }     \
+    static void set_##name(oop obj, type x)     { check(obj, #name, _##name##_offset); obj->accessor##_put(_##name##_offset, x); }                                                  \
+    static void set_##name(Handle& obj, type x)  { check(obj(), #name, _##name##_offset); obj->accessor##_put(_##name##_offset, x); }                                               \
+    static void set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj), #name, _##name##_offset); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); }
 
 #define EMPTY_CAST 
 #define CHAR_FIELD(klass, name) FIELD(name, jchar, char_field, EMPTY_CAST)
@@ -292,18 +299,20 @@
 #define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field, EMPTY_CAST)
 #define OBJARRAYOOP_FIELD(klass, name, signature) FIELD(name, objArrayOop, obj_field, (objArrayOop))
 #define TYPEARRAYOOP_FIELD(klass, name, signature) FIELD(name, typeArrayOop, obj_field, (typeArrayOop))
-#define STATIC_OOP_FIELD(klassName, name, signature)                                                           \
+#define STATIC_OOP_FIELD(klassName, name, signature) STATIC_OOPISH_FIELD(klassName, name, oop, signature)
+#define STATIC_OBJARRAYOOP_FIELD(klassName, name, signature) STATIC_OOPISH_FIELD(klassName, name, objArrayOop, signature)
+#define STATIC_OOPISH_FIELD(klassName, name, type, signature)                                                  \
     static int _##name##_offset;                                                                               \
-    static oop name() {                                                                                        \
+    static type name() {                                                                                       \
       InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                             \
       address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
       if (UseCompressedOops) {                                                                                 \
-        return oopDesc::load_decode_heap_oop((narrowOop *)addr);                                               \
+        return (type) oopDesc::load_decode_heap_oop((narrowOop *)addr);  \
       } else {                                                                                                 \
-        return oopDesc::load_decode_heap_oop((oop*)addr);                                                      \
+        return (type) oopDesc::load_decode_heap_oop((oop*)addr);         \
       }                                                                                                        \
     }                                                                                                          \
-    static void set_##name(oop x) {                                                                            \
+    static void set_##name(type x) {                                                                           \
       InstanceKlass* ik = InstanceKlass::cast(klassName::klass());                                             \
       address addr = ik->static_field_addr(_##name##_offset - InstanceMirrorKlass::offset_of_static_fields()); \
       if (UseCompressedOops) {                                                                                 \
@@ -328,7 +337,7 @@
 #define STATIC_INT_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jint)
 #define STATIC_BOOLEAN_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jboolean)
 
-COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
+COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_OBJARRAYOOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
 #undef START_CLASS
 #undef END_CLASS
 #undef FIELD
@@ -340,7 +349,9 @@
 #undef OOP_FIELD
 #undef TYPEARRAYOOP_FIELD
 #undef OBJARRAYOOP_FIELD
+#undef STATIC_OOPISH_FIELD
 #undef STATIC_OOP_FIELD
+#undef STATIC_OBJARRAYOOP_FIELD
 #undef STATIC_INT_FIELD
 #undef STATIC_BOOLEAN_FIELD
 #undef EMPTY_CAST
--- a/src/share/vm/jvmci/jvmciRuntime.cpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/jvmci/jvmciRuntime.cpp	Fri Aug 21 11:57:29 2015 -0700
@@ -68,7 +68,7 @@
     // Ensure _non_oop_bits is initialized
     Universe::non_oop_word();
 
-    env->RegisterNatives(c2vmClass, CompilerToVM_methods, CompilerToVM_methods_count());
+    env->RegisterNatives(c2vmClass, CompilerToVM::methods, CompilerToVM::methods_count());
   }
   if (HAS_PENDING_EXCEPTION) {
     abort_on_pending_exception(PENDING_EXCEPTION, "Could not register natives");
@@ -706,6 +706,51 @@
   assert(_HotSpotJVMCIRuntime_initialized == true, "what?");
 }
 
+void JVMCIRuntime::metadata_do(void f(Metadata*)) {
+  // WeakReference<HotSpotJVMCIMetaAccessContext>[]
+  objArrayOop allContexts = HotSpotJVMCIMetaAccessContext::allContexts();
+  if (allContexts == NULL) {
+    return;
+  }
+  for (int i = 0; i < allContexts->length(); i++) {
+    oop ref = allContexts->obj_at(i);
+    if (ref != NULL) {
+      oop referent = java_lang_ref_Reference::referent(ref);
+      if (referent != NULL) {
+        // Chunked Object[] with last element pointing to next chunk
+        objArrayOop metadataRoots = HotSpotJVMCIMetaAccessContext::metadataRoots(referent);
+        while (metadataRoots != NULL) {
+          for (int typeIndex = 0; typeIndex < metadataRoots->length() - 1; typeIndex++) {
+            oop reference = metadataRoots->obj_at(typeIndex);
+            if (reference == NULL) {
+              continue;
+            }
+            oop metadataRoot = java_lang_ref_Reference::referent(reference);
+            if (metadataRoot == NULL) {
+              continue;
+            }
+            if (metadataRoot->is_a(SystemDictionary::HotSpotResolvedJavaMethodImpl_klass())) {
+              Method* method = CompilerToVM::asMethod(metadataRoot);
+              f(method);
+            } else if (metadataRoot->is_a(SystemDictionary::HotSpotConstantPool_klass())) {
+              ConstantPool* constantPool = CompilerToVM::asConstantPool(metadataRoot);
+              f(constantPool);
+            } else if (metadataRoot->is_a(SystemDictionary::HotSpotResolvedObjectTypeImpl_klass())) {
+              Klass* klass = CompilerToVM::asKlass(metadataRoot);
+              f(klass);
+            } else {
+              metadataRoot->print();
+              ShouldNotReachHere();
+            }
+          }
+          metadataRoots = (objArrayOop)metadataRoots->obj_at(metadataRoots->length() - 1);
+          assert(metadataRoots == NULL || metadataRoots->is_objArray(), "wrong type");
+        }
+      }
+    }
+  }
+}
+
 // private static void CompilerToVMImpl.init()
 JVM_ENTRY(void, JVM_InitializeJVMCINatives(JNIEnv *env, jclass c2vmClass))
   JVMCIRuntime::initialize_natives(env, c2vmClass);
--- a/src/share/vm/jvmci/jvmciRuntime.hpp	Fri Aug 21 16:35:29 2015 +0200
+++ b/src/share/vm/jvmci/jvmciRuntime.hpp	Fri Aug 21 11:57:29 2015 -0700
@@ -54,7 +54,7 @@
   void set_filename(char* path) {_filename = path; _lineNo = 0;}
 };
 
-class JVMCIRuntime: public CHeapObj<mtCompiler> {
+class JVMCIRuntime: public AllStatic {
  private:
   static jobject _HotSpotJVMCIRuntime_instance;
   static bool _HotSpotJVMCIRuntime_initialized;
@@ -124,6 +124,8 @@
    */
   static void initialize_HotSpotJVMCIRuntime();
 
+  static void metadata_do(void f(Metadata*));
+
   static void shutdown();
 
   static bool shutdown_called() {