# HG changeset patch # User Tom Rodriguez # Date 1440183449 25200 # Node ID 76af33d4d504c8eae9c3e494ceba79dfb482c8a9 # Parent d6bbd5d8d81ecb942d3b28b2691c13858d6c554d Make jvmci redefinition safe diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVM.java --- 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 @@ *
  • {@link HotSpotVMConfig#exceptionTableElementCatchTypeIndexOffset} * * - * @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: * */ - 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: * */ - 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 signature - * polymorphic method at index {@code cpi} in {@code metaspaceConstantPool} is loaded and + * polymorphic 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: * *
          *     [(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 @@
          * 
  • {@link HotSpotVMConfig#localVariableTableElementStartBciOffset} * * - * @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); } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVMImpl.java --- 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); } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotConstantPool.java --- 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()); diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIMetaAccessContext.java --- /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[] 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> 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 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> newList = new ChunkedList<>(); + for (WeakReference 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, WeakReference> typeMap = new WeakHashMap<>(); + + @Override + public synchronized ResolvedJavaType fromClass(Class javaClass) { + WeakReference 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 implements Iterable { + 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 iterator() { + return new ChunkIterator<>(); + } + + int size() { + return size; + } + + class ChunkIterator implements Iterator { + + 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; + } + + } + + } +} diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotJVMCIRuntime.java --- 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 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); } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMemoryAccessProviderImpl.java --- 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); } } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMetaAccessProvider.java --- 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); } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethodData.java --- 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; diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotMethodHandleAccessProvider.java --- 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()); } } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedJavaMethodImpl.java --- 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); } } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectType.java --- 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 diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotResolvedObjectTypeImpl.java --- 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 fieldCache; - private HashMap methodCache; + private HashMap 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 @@ * *

    * NOTE: 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. *

    * * @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 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 diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotStackFrameReference.java --- 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 diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVMEventListener.java --- 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, ResolvedJavaType> factory) { + default JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime hotSpotJVMCIRuntime) { return null; } } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/MetaspaceWrapperObject.java --- /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(); +} diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIGlobalMetaAccessContext.java --- 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 jvmciMirrors = new ClassValue() { - @Override - protected ResolvedJavaType computeValue(Class javaClass) { - return factory.apply(javaClass); - } - - }; - protected final Function, ResolvedJavaType> factory; - - public JVMCIGlobalMetaAccessContext(Function, 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; - } -} diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIMetaAccessContext.java --- 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(); } diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.meta/src/jdk/internal/jvmci/meta/JVMCIThreadLocalMetaAccessContext.java --- 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, ResolvedJavaType>> threadLocalMap = new ThreadLocal, ResolvedJavaType>>() { - @Override - protected Map, ResolvedJavaType> initialValue() { - return new HashMap<>(); - } - }; - - protected final Function, ResolvedJavaType> factory; - - public JVMCIThreadLocalMetaAccessContext(Function, ResolvedJavaType> factory) { - this.factory = factory; - } - - public ResolvedJavaType fromClass(Class javaClass) { - Map, 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; - } -} diff -r d6bbd5d8d81e -r 76af33d4d504 jvmci/jdk.internal.jvmci.runtime.test/src/jdk/internal/jvmci/runtime/test/RedefineClassTest.java --- 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 { diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/classfile/metadataOnStackMark.cpp --- 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() { diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/classfile/systemDictionary.hpp --- 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)) \ diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/classfile/vmSymbols.hpp --- 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 */ \ diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/jvmci/jvmciCodeInstaller.cpp --- 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) { diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/jvmci/jvmciCompiler.cpp --- 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++; } diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/jvmci/jvmciCompilerToVM.cpp --- 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); } diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/jvmci/jvmciCompilerToVM.hpp --- 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: diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/jvmci/jvmciJavaAccess.cpp --- 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) diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/jvmci/jvmciJavaAccess.hpp --- 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 diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/jvmci/jvmciRuntime.cpp --- 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[] + 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); diff -r d6bbd5d8d81e -r 76af33d4d504 src/share/vm/jvmci/jvmciRuntime.hpp --- 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 { +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() {