Mercurial > hg > graal-compiler
changeset 22236:179db500f6e5
Add Java code for reading the constant pool cache plus sun.reflect.ConstantPool substitutions.
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ConstantPoolSubstitutionsTests.java Thu Jul 16 07:47:07 2015 -0700 @@ -0,0 +1,116 @@ +/* + * 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 com.oracle.graal.hotspot.test; + +import org.junit.*; + +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.*; + +import jdk.internal.jvmci.debug.*; +import jdk.internal.jvmci.debug.Debug.*; +import sun.misc.*; +import sun.reflect.*; + +public class ConstantPoolSubstitutionsTests extends GraalCompilerTest { + + protected StructuredGraph test(final String snippet) { + try (Scope s = Debug.scope("ConstantPoolSubstitutionsTests", getMetaAccess().lookupJavaMethod(getMethod(snippet)))) { + StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES); + compile(graph.method(), graph); + assertNotInGraph(graph, Invoke.class); + Debug.dump(graph, snippet); + return graph; + } catch (Throwable e) { + throw Debug.handle(e); + } + } + + protected static StructuredGraph assertNotInGraph(StructuredGraph graph, Class<?> clazz) { + for (Node node : graph.getNodes()) { + if (clazz.isInstance(node)) { + fail(node.toString()); + } + } + return graph; + } + + @Test + public void testGetSize() { + ConstantPool cp = SharedSecrets.getJavaLangAccess().getConstantPool(Object.class); + test("getSize", cp); + } + + @Test + public void testGetIntAt() { + test("getIntAt"); + } + + @Test + public void testGetLongAt() { + test("getLongAt"); + } + + @Test + public void testGetFloatAt() { + test("getFloatAt"); + } + + @Test + public void testGetDoubleAt() { + test("getDoubleAt"); + } + + // @Test + public void testGetUTF8At() { + test("getUTF8At"); + } + + public int getSize(ConstantPool cp) { + return cp.getSize(); + } + + public int getIntAt(ConstantPool cp) { + return cp.getIntAt(0); + } + + public long getLongAt(ConstantPool cp) { + return cp.getLongAt(0); + } + + public float getFloatAt(ConstantPool cp) { + return cp.getFloatAt(0); + } + + public double getDoubleAt(ConstantPool cp) { + return cp.getDoubleAt(0); + } + + public String getUTF8At(ConstantPool cp) { + return cp.getUTF8At(0); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ConstantPoolSubstitutions.java Thu Jul 16 07:47:07 2015 -0700 @@ -0,0 +1,77 @@ +/* + * 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 com.oracle.graal.hotspot.replacements; + +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; + +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.hotspot.word.*; +import com.oracle.graal.word.*; + +import sun.reflect.*; + +/** + * Substitutions for {@link sun.reflect.ConstantPool} methods. + */ +@ClassSubstitution(sun.reflect.ConstantPool.class) +public class ConstantPoolSubstitutions { + + /** + * Get the metaspace {@code ConstantPool} pointer for the given holder class. + * + * @param constantPoolOop the holder class as {@link Object} + * @return a metaspace {@code ConstantPool} pointer + */ + private static Word metaspaceConstantPool(Object constantPoolOop) { + // ConstantPool.constantPoolOop is in fact the holder class. + Class<?> constantPoolHolder = (Class<?>) constantPoolOop; + KlassPointer klass = ClassGetHubNode.readClass(constantPoolHolder); + return klass.readWord(instanceKlassConstantsOffset(), INSTANCE_KLASS_CONSTANTS); + } + + @MethodSubstitution(isStatic = false) + private static int getSize0(@SuppressWarnings("unused") final ConstantPool thisObj, Object constantPoolOop) { + return metaspaceConstantPool(constantPoolOop).readInt(constantPoolLengthOffset()); + } + + @MethodSubstitution(isStatic = false) + private static int getIntAt0(@SuppressWarnings("unused") final ConstantPool thisObj, Object constantPoolOop, int index) { + return metaspaceConstantPool(constantPoolOop).readInt(constantPoolSize() + index * wordSize()); + } + + @MethodSubstitution(isStatic = false) + private static long getLongAt0(@SuppressWarnings("unused") final ConstantPool thisObj, Object constantPoolOop, int index) { + return metaspaceConstantPool(constantPoolOop).readLong(constantPoolSize() + index * wordSize()); + } + + @MethodSubstitution(isStatic = false) + private static float getFloatAt0(@SuppressWarnings("unused") final ConstantPool thisObj, Object constantPoolOop, int index) { + return metaspaceConstantPool(constantPoolOop).readFloat(constantPoolSize() + index * wordSize()); + } + + @MethodSubstitution(isStatic = false) + private static double getDoubleAt0(@SuppressWarnings("unused") final ConstantPool thisObj, Object constantPoolOop, int index) { + return metaspaceConstantPool(constantPoolOop).readDouble(constantPoolSize() + index * wordSize()); + } + +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Thu Jul 16 13:48:47 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Thu Jul 16 07:47:07 2015 -0700 @@ -620,6 +620,13 @@ return config().instanceKlassStateFullyInitialized; } + public static final LocationIdentity INSTANCE_KLASS_CONSTANTS = NamedLocationIdentity.immutable("InstanceKlass::_constants"); + + @Fold + public static int instanceKlassConstantsOffset() { + return config().instanceKlassConstantsOffset; + } + /** * * @param hub the hub of an InstanceKlass @@ -661,6 +668,21 @@ return config().classMirrorOffset; } + @Fold + public static int constantPoolSize() { + return config().constantPoolSize; + } + + @Fold + public static int constantPoolHolderOffset() { + return config().constantPoolHolderOffset; + } + + @Fold + public static int constantPoolLengthOffset() { + return config().constantPoolLengthOffset; + } + public static final LocationIdentity HEAP_TOP_LOCATION = NamedLocationIdentity.mutable("HeapTop"); @Fold
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Thu Jul 16 13:48:47 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotSubstitutions.java Thu Jul 16 07:47:07 2015 -0700 @@ -27,6 +27,7 @@ import jdk.internal.jvmci.meta.*; import jdk.internal.jvmci.service.*; import sun.reflect.*; +import sun.reflect.ConstantPool; import com.oracle.graal.api.replacements.*; import com.oracle.graal.nodes.spi.*; @@ -39,6 +40,7 @@ replacements.registerSubstitutions(System.class, SystemSubstitutions.class); replacements.registerSubstitutions(Thread.class, ThreadSubstitutions.class); replacements.registerSubstitutions(Reflection.class, ReflectionSubstitutions.class); + replacements.registerSubstitutions(ConstantPool.class, ConstantPoolSubstitutions.class); replacements.registerSubstitutions(CompilerToVMImpl.class, CompilerToVMImplSubstitutions.class); } }
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVMImpl.java Thu Jul 16 13:48:47 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/CompilerToVMImpl.java Thu Jul 16 07:47:07 2015 -0700 @@ -25,6 +25,7 @@ import static jdk.internal.jvmci.hotspot.InitTimer.*; import jdk.internal.jvmci.code.*; +import jdk.internal.jvmci.common.*; import jdk.internal.jvmci.meta.*; /** @@ -72,19 +73,39 @@ public native Object resolveConstantInPool(long metaspaceConstantPool, int cpi); - public native Object resolvePossiblyCachedConstantInPool(long metaspaceConstantPool, int cpi); + public Object resolvePossiblyCachedConstantInPool(long metaspaceConstantPool, int cpi) { + JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), ""); + return resolvePossiblyCachedConstantInPool0(metaspaceConstantPool, cpi); + } + + private native Object resolvePossiblyCachedConstantInPool0(long metaspaceConstantPool, int cpi); @Override public native int lookupNameAndTypeRefIndexInPool(long metaspaceConstantPool, int cpi); @Override - public native String lookupNameRefInPool(long metaspaceConstantPool, int cpi); + public String lookupNameRefInPool(long metaspaceConstantPool, int cpi) { + JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), ""); + return lookupNameRefInPool0(metaspaceConstantPool, cpi); + } + + private native String lookupNameRefInPool0(long metaspaceConstantPool, int cpi); @Override - public native String lookupSignatureRefInPool(long metaspaceConstantPool, int cpi); + public String lookupSignatureRefInPool(long metaspaceConstantPool, int cpi) { + JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), ""); + return lookupSignatureRefInPool0(metaspaceConstantPool, cpi); + } + + private native String lookupSignatureRefInPool0(long metaspaceConstantPool, int cpi); @Override - public native int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi); + public int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi) { + JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), ""); + return lookupKlassRefIndexInPool0(metaspaceConstantPool, cpi); + } + + private native int lookupKlassRefIndexInPool0(long metaspaceConstantPool, int cpi); public native long constantPoolKlassAt(long metaspaceConstantPool, int cpi); @@ -97,10 +118,20 @@ @Override public native long resolveField(long metaspaceConstantPool, int cpi, byte opcode, long[] info); - public native int constantPoolRemapInstructionOperandFromCache(long metaspaceConstantPool, int cpi); + public int constantPoolRemapInstructionOperandFromCache(long metaspaceConstantPool, int cpi) { + JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), ""); + return constantPoolRemapInstructionOperandFromCache0(metaspaceConstantPool, cpi); + } + + private native int constantPoolRemapInstructionOperandFromCache0(long metaspaceConstantPool, int cpi); @Override - public native Object lookupAppendixInPool(long metaspaceConstantPool, int cpi); + public Object lookupAppendixInPool(long metaspaceConstantPool, int cpi) { + JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), ""); + return lookupAppendixInPool0(metaspaceConstantPool, cpi); + } + + private native Object lookupAppendixInPool0(long metaspaceConstantPool, int cpi); @Override public native void initializeConfiguration(HotSpotVMConfig config); @@ -191,7 +222,12 @@ public native long getTimeStamp(); - public native String getSymbol(long metaspaceSymbol); + public String getSymbol(long metaspaceSymbol) { + JVMCIError.guarantee(!HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue(), ""); + return getSymbol0(metaspaceSymbol); + } + + private native String getSymbol0(long metaspaceSymbol); public native void resolveInvokeDynamic(long metaspaceConstantPool, int index);
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotConstantPool.java Thu Jul 16 13:48:47 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotConstantPool.java Thu Jul 16 07:47:07 2015 -0700 @@ -26,15 +26,24 @@ import static jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime.*; import java.lang.invoke.*; +import java.util.*; import jdk.internal.jvmci.common.*; import jdk.internal.jvmci.meta.*; +import jdk.internal.jvmci.options.*; /** * Implementation of {@link ConstantPool} for HotSpot. */ public class HotSpotConstantPool implements ConstantPool, HotSpotProxified { + public static class Options { + // @formatter:off + @Option(help = "Use Java code to access the constant pool cache and resolved references array", type = OptionType.Expert) + public static final OptionValue<Boolean> UseConstantPoolCacheJavaCode = new OptionValue<>(false); + // @formatter:on + } + /** * Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}. */ @@ -179,8 +188,232 @@ private final long metaspaceConstantPool; private volatile LookupTypeCacheElement lastLookupType; + /** + * The constant pool cache of this constant pool. + */ + private final Cache cache; + + /** + * Represents a {@code ConstantPoolCache}. The cache needs to be lazy since the constant pool + * cache is created when the methods of this class are rewritten and rewriting happens when the + * class is linked. + */ + private final class Cache { + + private long address; + + public Cache() { + // Maybe the constant pool cache already exists... + queryAddress(); + } + + /** + * Queries the current value of {@code ConstantPool::_cache} if the current address is null. + */ + private void queryAddress() { + if (address == 0) { + address = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolCacheOffset); + } + } + + /** + * Returns whether a constant pool cache for this constant pool exists. + * + * @return true if it exists, false otherwise + */ + public boolean exists() { + queryAddress(); + return address != 0; + } + + /** + * Represents a {@code ConstantPoolCacheEntry}. + */ + private final class Entry { + + private final long address; + + public Entry(final long address) { + this.address = address; + } + + /** + * {@code ConstantPoolCacheEntry::_indices} is volatile of type {@code intx}. + * + * @return value of field {@code _indices} + */ + private long getIndices() { + assert runtime().getHostJVMCIBackend().getTarget().wordSize == 8 : "port to non-64-bit platform"; + return unsafe.getLongVolatile(null, address + runtime().getConfig().constantPoolCacheEntryIndicesOffset); + } + + /** + * {@code ConstantPoolCacheEntry::_f1} is volatile of type {@code Metadata*}. + * + * @return value of field {@code _f1} + */ + private long getF1() { + assert runtime().getHostJVMCIBackend().getTarget().wordSize == 8 : "port to non-64-bit platform"; + return unsafe.getLongVolatile(null, address + runtime().getConfig().constantPoolCacheEntryF1Offset); + } + + /** + * {@code ConstantPoolCacheEntry::_f2} is volatile of type {@code intx}. + * + * @return value of field {@code _f2} + */ + private long getF2() { + assert runtime().getHostJVMCIBackend().getTarget().wordSize == 8 : "port to non-64-bit platform"; + return unsafe.getLongVolatile(null, address + runtime().getConfig().constantPoolCacheEntryF2Offset); + } + + /** + * {@code ConstantPoolCacheEntry::_flags} is volatile of type {@code intx}. + * + * @return flag bits + */ + private long flags() { + assert runtime().getHostJVMCIBackend().getTarget().wordSize == 8 : "port to non-64-bit platform"; + return unsafe.getLongVolatile(null, address + runtime().getConfig().constantPoolCacheEntryFlagsOffset); + } + + private boolean isF1Null() { + final long f1 = getF1(); + return f1 == 0; + } + + /** + * Returns the constant pool index for this entry. See + * {@code ConstantPoolCacheEntry::constant_pool_index()} + * + * @return the constant pool index for this entry + */ + public int getConstantPoolIndex() { + return ((int) getIndices()) & runtime().getConfig().constantPoolCacheEntryCpIndexMask; + } + + /** + * See {@code ConstantPoolCache::has_appendix()}. + * + * @return true if there is an appendix, false otherwise + */ + private boolean hasAppendix() { + return (!isF1Null()) && (flags() & (1 << runtime().getConfig().constantPoolCacheEntryHasAppendixShift)) != 0; + } + + /** + * See {@code ConstantPoolCache::appendix_if_resolved()}. + */ + public Object getAppendixIfResolved() { + if (!hasAppendix()) { + return null; + } + final int index = ((int) getF2()) + runtime().getConfig().constantPoolCacheEntryIndyResolvedReferencesAppendixOffset; + return resolvedReferences.getArray()[index]; + } + } + + /** + * Get the constant pool cache entry at index {@code index}. + * + * @param index index of entry to return + * @return constant pool cache entry at given index + */ + public Entry getEntryAt(int index) { + queryAddress(); + assert exists(); + HotSpotVMConfig config = runtime().getConfig(); + return new Entry(address + config.constantPoolCacheSize + config.constantPoolCacheEntrySize * index); + } + + /** + * Maps the constant pool cache index back to a constant pool index. See + * {@code ConstantPool::remap_instruction_operand_from_cache}. + * + * @param index the constant pool cache index + * @return constant pool index + */ + public int constantPoolCacheIndexToConstantPoolIndex(int index) { + final int cacheIndex = index - runtime().getConfig().constantPoolCpCacheIndexTag; + return getEntryAt(cacheIndex).getConstantPoolIndex(); + } + + } + + /** + * Resolved references of this constant pool. + */ + private final ResolvedReferences resolvedReferences = new ResolvedReferences(); + + /** + * Hide the resolved references array in a private class so it cannot be accessed directly. The + * reason is the resolved references array is created when the constant pool cache is created. + * + * @see Cache + */ + private final class ResolvedReferences { + + /** + * Pointer to the {@code ConstantPool::_resolved_references} array. + */ + private Object[] resolvedReferences; + + /** + * Map of constant pool indexes to {@code ConstantPool::_resolved_references} indexes. + */ + private final HashMap<Integer, Integer> referenceMap = new HashMap<>(); + + /** + * Returns the {@code ConstantPool::_resolved_references} array for this constant pool. + * + * @return resolved references array if exists, null otherwise + */ + public Object[] getArray() { + if (resolvedReferences == null) { + final long handle = unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolResolvedReferencesOffset); + if (handle != 0) { + resolvedReferences = (Object[]) runtime().getCompilerToVM().readUncompressedOop(handle + runtime().getConfig().handleHandleOffset); + fillReferenceMap(); + } + } + return resolvedReferences; + } + + /** + * Fills the {@link #referenceMap} with all the values from + * {@code ConstantPool::_reference_map} for faster lookup. + */ + 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); + if (address != 0) { + final int length = unsafe.getInt(null, address + runtime().getConfig().arrayU1LengthOffset); + for (int i = 0; i < length; i++) { + final int value = unsafe.getShort(address + runtime().getConfig().arrayU2DataOffset + i * Short.BYTES); + referenceMap.put(value, i); + } + } + } + + /** + * See {@code ConstantPool::cp_to_object_index}. + * + * @param cpi constant pool index + * @return resolved references array index + */ + public int constantPoolIndexToResolvedReferencesIndex(int cpi) { + final Integer index = referenceMap.get(cpi); + // We might not find the index for jsr292 call. + return (index == null) ? -1 : index; + } + + } + public HotSpotConstantPool(long metaspaceConstantPool) { this.metaspaceConstantPool = metaspaceConstantPool; + + // Cache constructor needs metaspaceConstantPool. + cache = new Cache(); } /** @@ -201,7 +434,7 @@ * @param opcode bytecode to convert the index for * @return constant pool index */ - private static int toConstantPoolIndex(int rawIndex, int opcode) { + private static int rawIndexToConstantPoolIndex(int rawIndex, int opcode) { int index; if (opcode == Bytecodes.INVOKEDYNAMIC) { index = rawIndex; @@ -348,7 +581,12 @@ * @return name as {@link String} */ private String getNameRefAt(int index) { - return runtime().getCompilerToVM().lookupNameRefInPool(metaspaceConstantPool, index); + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + final int nameRefIndex = getNameRefIndexAt(getNameAndTypeRefIndexAt(index)); + return new HotSpotSymbol(getEntryAt(nameRefIndex)).asString(); + } else { + return runtime().getCompilerToVM().lookupNameRefInPool(metaspaceConstantPool, index); + } } /** @@ -372,7 +610,12 @@ * @return signature as {@link String} */ private String getSignatureRefAt(int index) { - return runtime().getCompilerToVM().lookupSignatureRefInPool(metaspaceConstantPool, index); + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + final int signatureRefIndex = getSignatureRefIndexAt(getNameAndTypeRefIndexAt(index)); + return new HotSpotSymbol(getEntryAt(signatureRefIndex)).asString(); + } else { + return runtime().getCompilerToVM().lookupSignatureRefInPool(metaspaceConstantPool, index); + } } /** @@ -389,13 +632,38 @@ } /** - * Gets the klass reference index constant pool entry at index {@code index}. + * Gets the klass reference index constant pool entry at index {@code index}. See + * {@code ConstantPool::klass_ref_index_at}. + * + * @param index constant pool index + * @param cached whether to go through the constant pool cache + * @return klass reference index + */ + private int getKlassRefIndexAt(int index, boolean cached) { + int cpi = index; + if (cached && cache.exists()) { + // change byte-ordering and go via cache + cpi = cache.constantPoolCacheIndexToConstantPoolIndex(index); + } + assertTagIsFieldOrMethod(cpi); + final int refIndex = unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + cpi * runtime().getHostJVMCIBackend().getTarget().wordSize); + // klass ref index is in the low 16-bits. + return refIndex & 0xFFFF; + } + + /** + * Gets the klass reference index constant pool entry at index {@code index}. See + * {@code ConstantPool::klass_ref_index_at}. * * @param index constant pool index * @return klass reference index */ private int getKlassRefIndexAt(int index) { - return runtime().getCompilerToVM().lookupKlassRefIndexInPool(metaspaceConstantPool, index); + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + return getKlassRefIndexAt(index, true); + } else { + return runtime().getCompilerToVM().lookupKlassRefIndexInPool(metaspaceConstantPool, index); + } } /** @@ -406,10 +674,14 @@ * @return klass reference index */ private int getUncachedKlassRefIndexAt(int index) { - assert getTagAt(index) == JVM_CONSTANT.Fieldref || getTagAt(index) == JVM_CONSTANT.MethodRef || getTagAt(index) == JVM_CONSTANT.InterfaceMethodref; - final int refIndex = unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize); - // klass ref index is in the low 16-bits. - return refIndex & 0xFFFF; + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + return getKlassRefIndexAt(index, false); + } else { + assertTagIsFieldOrMethod(index); + final int refIndex = unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize); + // klass ref index is in the low 16-bits. + return refIndex & 0xFFFF; + } } /** @@ -428,7 +700,19 @@ * @param tag expected tag */ private void assertTag(int index, JVM_CONSTANT tag) { - assert getTagAt(index) == tag : "constant pool tag at index " + index + " is " + getTagAt(index) + " but expected " + tag; + final JVM_CONSTANT tagAt = getTagAt(index); + assert tagAt == tag : "constant pool tag at index " + index + " is " + tagAt + " but expected " + tag; + } + + /** + * Asserts that the constant pool tag at index {@code index} is a {@link JVM_CONSTANT#Fieldref}, + * or a {@link JVM_CONSTANT#MethodRef}, or a {@link JVM_CONSTANT#InterfaceMethodref}. + * + * @param index constant pool index + */ + private void assertTagIsFieldOrMethod(int index) { + final JVM_CONSTANT tagAt = getTagAt(index); + assert tagAt == JVM_CONSTANT.Fieldref || tagAt == JVM_CONSTANT.MethodRef || tagAt == JVM_CONSTANT.InterfaceMethodref : tagAt; } @Override @@ -455,7 +739,34 @@ final int opcode = -1; // opcode is not used return lookupType(cpi, opcode); case String: - Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(metaspaceConstantPool, cpi); + String string; + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + // See: ConstantPool::resolve_constant_at_impl + /* + * Note: Call getArray() before constantPoolIndexToResolvedReferencesIndex() + * because it fills the map if the array exists. + */ + Object[] localResolvedReferences = resolvedReferences.getArray(); + final int index = resolvedReferences.constantPoolIndexToResolvedReferencesIndex(cpi); + if (index >= 0) { + string = (String) localResolvedReferences[index]; + if (string != null) { + return HotSpotObjectConstantImpl.forObject(string); + } + } + assert index != -1; + // See: ConstantPool::string_at_impl + string = (String) localResolvedReferences[index]; + if (string == null) { + final long metaspaceSymbol = getEntryAt(cpi); + HotSpotSymbol symbol = new HotSpotSymbol(metaspaceSymbol); + string = symbol.asString().intern(); + // See: ConstantPool::string_at_put + localResolvedReferences[index] = string; + } + } else { + string = (String) runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(metaspaceConstantPool, cpi); + } return HotSpotObjectConstantImpl.forObject(string); case MethodHandle: case MethodHandleInError: @@ -471,7 +782,18 @@ @Override public String lookupUtf8(int cpi) { assertTag(cpi, JVM_CONSTANT.Utf8); - return runtime().getCompilerToVM().getSymbol(getEntryAt(cpi)); + String s; + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + HotSpotSymbol symbol = new HotSpotSymbol(getEntryAt(cpi)); + s = symbol.asString(); + // It shouldn't but just in case something went wrong... + if (s == null) { + throw JVMCIError.shouldNotReachHere("malformed UTF-8 string in constant pool"); + } + } else { + s = runtime().getCompilerToVM().getSymbol(getEntryAt(cpi)); + } + return s; } @Override @@ -482,12 +804,26 @@ @Override public JavaConstant lookupAppendix(int cpi, int opcode) { assert Bytecodes.isInvoke(opcode); - final int index = toConstantPoolIndex(cpi, opcode); - Object result = runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index); - if (result == null) { + final int index = rawIndexToConstantPoolIndex(cpi, opcode); + + Object appendix = null; + + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + if (!cache.exists()) { + // Nothing to load yet. + return null; + } + final int cacheIndex = decodeConstantPoolCacheIndex(index); + Cache.Entry entry = cache.getEntryAt(cacheIndex); + appendix = entry.getAppendixIfResolved(); + } else { + appendix = runtime().getCompilerToVM().lookupAppendixInPool(metaspaceConstantPool, index); + } + + if (appendix == null) { return null; } else { - return HotSpotObjectConstantImpl.forObject(result); + return HotSpotObjectConstantImpl.forObject(appendix); } } @@ -502,7 +838,17 @@ HotSpotVMConfig config = runtime.getConfig(); if ((metaspacePointer & config.compilerToVMSymbolTag) != 0) { final long metaspaceSymbol = metaspacePointer & ~config.compilerToVMSymbolTag; - String name = runtime.getCompilerToVM().getSymbol(metaspaceSymbol); + 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); + } return HotSpotUnresolvedJavaType.create(runtime(), "L" + name + ";"); } else { assert (metaspacePointer & config.compilerToVMKlassTag) == 0; @@ -512,7 +858,7 @@ @Override public JavaMethod lookupMethod(int cpi, int opcode) { - final int index = toConstantPoolIndex(cpi, 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); @@ -550,7 +896,7 @@ @Override public JavaField lookupField(int cpi, int opcode) { - final int index = toConstantPoolIndex(cpi, opcode); + final int index = rawIndexToConstantPoolIndex(cpi, opcode); final int nameAndTypeIndex = getNameAndTypeRefIndexAt(index); final int nameIndex = getNameRefIndexAt(nameAndTypeIndex); String name = lookupUtf8(nameIndex); @@ -597,14 +943,44 @@ case Bytecodes.LDC2_W: index = cpi; break; - case Bytecodes.INVOKEDYNAMIC: + case Bytecodes.INVOKEDYNAMIC: { // invokedynamic instructions point to a constant pool cache entry. - index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag; - index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index); + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + // index = decodeConstantPoolCacheIndex(cpi) + + // runtime().getConfig().constantPoolCpCacheIndexTag; + // index = cache.constantPoolCacheIndexToConstantPoolIndex(index); + final int cacheIndex = cpi; + index = cache.getEntryAt(decodeInvokedynamicIndex(cacheIndex)).getConstantPoolIndex(); + // JVMCIError.guarantee(index == x, index + " != " + x); + } else { + index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag; + index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index); + } break; + } + case Bytecodes.GETSTATIC: + case Bytecodes.PUTSTATIC: + case Bytecodes.GETFIELD: + case Bytecodes.PUTFIELD: + case Bytecodes.INVOKEVIRTUAL: + case Bytecodes.INVOKESPECIAL: + case Bytecodes.INVOKESTATIC: + case Bytecodes.INVOKEINTERFACE: { + // invoke and field instructions point to a constant pool cache entry. + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + // index = rawIndexToConstantPoolIndex(cpi, opcode); + // index = cache.constantPoolCacheIndexToConstantPoolIndex(index); + final int cacheIndex = cpi; + index = cache.getEntryAt(cacheIndex).getConstantPoolIndex(); + // JVMCIError.guarantee(index == x, index + " != " + x); + } else { + index = rawIndexToConstantPoolIndex(cpi, opcode); + index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index); + } + break; + } default: - index = toConstantPoolIndex(cpi, opcode); - index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index); + throw JVMCIError.shouldNotReachHere("Unexpected opcode " + opcode); } final JVM_CONSTANT tag = getTagAt(index); @@ -633,7 +1009,7 @@ switch (tag) { case MethodRef: if (Bytecodes.isInvokeHandleAlias(opcode)) { - final int methodRefCacheIndex = toConstantPoolIndex(cpi, opcode); + final int methodRefCacheIndex = rawIndexToConstantPoolIndex(cpi, opcode); if (isInvokeHandle(methodRefCacheIndex, type)) { runtime().getCompilerToVM().resolveInvokeHandle(metaspaceConstantPool, methodRefCacheIndex); } @@ -652,7 +1028,13 @@ } private boolean isInvokeHandle(int methodRefCacheIndex, HotSpotResolvedObjectTypeImpl klass) { - assertTag(runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, methodRefCacheIndex), JVM_CONSTANT.MethodRef); + int index; + if (Options.UseConstantPoolCacheJavaCode.getValue()) { + index = cache.constantPoolCacheIndexToConstantPoolIndex(methodRefCacheIndex); + } else { + index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, methodRefCacheIndex); + } + assertTag(index, JVM_CONSTANT.MethodRef); return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameRefAt(methodRefCacheIndex), runtime().getHostJVMCIBackend().getMetaAccess()); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotSymbol.java Thu Jul 16 07:47:07 2015 -0700 @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013, 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 static jdk.internal.jvmci.common.UnsafeAccess.*; +import static jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime.*; + +import java.io.*; +import java.util.*; + +/** + * Represents a metaspace {@code Symbol}. + */ +public class HotSpotSymbol { + + private final long metaspaceSymbol; + + public HotSpotSymbol(long metaspaceSymbol) { + assert metaspaceSymbol != 0; + this.metaspaceSymbol = metaspaceSymbol; + } + + /** + * Decodes this {@code Symbol} and returns the symbol string as {@link java.lang.String}. + * + * @return the decoded string, or null if there was a decoding error + */ + public String asString() { + return readModifiedUTF8(asByteArray()); + } + + /** + * Reads the modified UTF-8 string in {@code buf} and converts it to a {@link String}. The + * implementation is taken from {@link java.io.DataInputStream#readUTF(DataInput)} and adapted + * to operate on a {@code byte} array directly for performance reasons. + * + * @see java.io.DataInputStream#readUTF(DataInput) + */ + private static String readModifiedUTF8(byte[] buf) { + final int utflen = buf.length; + byte[] bytearr = null; + char[] chararr = new char[utflen]; + + int c; + int char2; + int char3; + int count = 0; + int chararrCount = 0; + + bytearr = buf; + + while (count < utflen) { + c = bytearr[count] & 0xff; + if (c > 127) { + break; + } + count++; + chararr[chararrCount++] = (char) c; + } + + while (count < utflen) { + c = bytearr[count] & 0xff; + switch (c >> 4) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + /* 0xxxxxxx */ + count++; + chararr[chararrCount++] = (char) c; + break; + case 12: + case 13: + /* 110x xxxx 10xx xxxx */ + count += 2; + if (count > utflen) { + // malformed input: partial character at end + return null; + } + char2 = bytearr[count - 1]; + if ((char2 & 0xC0) != 0x80) { + // malformed input around byte + return null; + } + chararr[chararrCount++] = (char) (((c & 0x1F) << 6) | (char2 & 0x3F)); + break; + case 14: + /* 1110 xxxx 10xx xxxx 10xx xxxx */ + count += 3; + if (count > utflen) { + // malformed input: partial character at end + return null; + } + char2 = bytearr[count - 2]; + char3 = bytearr[count - 1]; + if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) { + // malformed input around byte + return null; + } + chararr[chararrCount++] = (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0)); + break; + default: + /* 10xx xxxx, 1111 xxxx */ + // malformed input around byte + return null; + } + } + // The number of chars produced may be less than utflen + char[] value = Arrays.copyOf(chararr, chararrCount); + return new String(value); + } + + private byte[] asByteArray() { + final int length = getLength(); + byte[] result = new byte[length]; + for (int index = 0; index < length; index++) { + result[index] = getByteAt(index); + } + return result; + } + + private int getLength() { + return unsafe.getShort(metaspaceSymbol + runtime().getConfig().symbolLengthOffset); + } + + private byte getByteAt(int index) { + return unsafe.getByte(metaspaceSymbol + runtime().getConfig().symbolBodyOffset + index); + } +}
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVMConfig.java Thu Jul 16 13:48:47 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVMConfig.java Thu Jul 16 07:47:07 2015 -0700 @@ -808,6 +808,8 @@ @HotSpotVMField(name = "oopDesc::_mark", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int markOffset; @HotSpotVMField(name = "oopDesc::_metadata._klass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int hubOffset; + @HotSpotVMField(name = "Handle::_handle", type = "oop*", get = HotSpotVMField.Type.OFFSET) @Stable public int handleHandleOffset; + @HotSpotVMField(name = "Klass::_prototype_header", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int prototypeMarkWordOffset; @HotSpotVMField(name = "Klass::_subklass", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int subklassOffset; @HotSpotVMField(name = "Klass::_next_sibling", type = "Klass*", get = HotSpotVMField.Type.OFFSET) @Stable public int nextSiblingOffset; @@ -1090,11 +1092,29 @@ @HotSpotVMType(name = "ConstantPool", get = HotSpotVMType.Type.SIZE) @Stable public int constantPoolSize; @HotSpotVMField(name = "ConstantPool::_tags", type = "Array<u1>*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolTagsOffset; + @HotSpotVMField(name = "ConstantPool::_cache", type = "ConstantPoolCache*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolCacheOffset; @HotSpotVMField(name = "ConstantPool::_pool_holder", type = "InstanceKlass*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolHolderOffset; @HotSpotVMField(name = "ConstantPool::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolLengthOffset; + @HotSpotVMField(name = "ConstantPool::_resolved_references", type = "jobject", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolResolvedReferencesOffset; + @HotSpotVMField(name = "ConstantPool::_reference_map", type = "Array<u2>*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolReferenceMapOffset; @HotSpotVMConstant(name = "ConstantPool::CPCACHE_INDEX_TAG") @Stable public int constantPoolCpCacheIndexTag; + @HotSpotVMType(name = "ConstantPoolCache", get = HotSpotVMType.Type.SIZE) @Stable public int constantPoolCacheSize; + @HotSpotVMField(name = "ConstantPoolCache::_length", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolCacheLengthOffset; + + @HotSpotVMType(name = "ConstantPoolCacheEntry", get = HotSpotVMType.Type.SIZE) @Stable public int constantPoolCacheEntrySize; + @HotSpotVMField(name = "ConstantPoolCacheEntry::_indices", type = "intx", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolCacheEntryIndicesOffset; + @HotSpotVMField(name = "ConstantPoolCacheEntry::_f1", type = "volatile Metadata*", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolCacheEntryF1Offset; + @HotSpotVMField(name = "ConstantPoolCacheEntry::_f2", type = "intx", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolCacheEntryF2Offset; + @HotSpotVMField(name = "ConstantPoolCacheEntry::_flags", type = "intx", get = HotSpotVMField.Type.OFFSET) @Stable public int constantPoolCacheEntryFlagsOffset; + + @HotSpotVMConstant(name = "ConstantPoolCacheEntry::has_appendix_shift") @Stable public int constantPoolCacheEntryHasAppendixShift; + + @HotSpotVMConstant(name = "ConstantPoolCacheEntry::cp_index_mask") @Stable public int constantPoolCacheEntryCpIndexMask; + + @HotSpotVMConstant(name = "ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset") @Stable public int constantPoolCacheEntryIndyResolvedReferencesAppendixOffset; + @HotSpotVMConstant(name = "JVM_CONSTANT_Utf8") @Stable public int jvmConstantUtf8; @HotSpotVMConstant(name = "JVM_CONSTANT_Integer") @Stable public int jvmConstantInteger; @HotSpotVMConstant(name = "JVM_CONSTANT_Long") @Stable public int jvmConstantLong;
--- a/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVmSymbols.java Thu Jul 16 13:48:47 2015 +0200 +++ b/jvmci/jdk.internal.jvmci.hotspot/src/jdk/internal/jvmci/hotspot/HotSpotVmSymbols.java Thu Jul 16 07:47:07 2015 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -24,6 +24,8 @@ import static jdk.internal.jvmci.common.UnsafeAccess.*; import static jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime.*; + +import jdk.internal.jvmci.common.*; import sun.misc.*; /** @@ -43,6 +45,17 @@ HotSpotVMConfig config = runtime.getConfig(); assert config.vmSymbolsFirstSID <= index && index < config.vmSymbolsSIDLimit : "index " + index + " is out of bounds"; assert config.symbolPointerSize == Unsafe.ADDRESS_SIZE : "the following address read is broken"; - return runtime.getCompilerToVM().getSymbol(unsafe.getAddress(config.vmSymbolsSymbols + index * config.symbolPointerSize)); + final long metaspaceSymbol = unsafe.getAddress(config.vmSymbolsSymbols + index * config.symbolPointerSize); + if (HotSpotConstantPool.Options.UseConstantPoolCacheJavaCode.getValue()) { + HotSpotSymbol symbol = new HotSpotSymbol(metaspaceSymbol); + String s = symbol.asString(); + // It shouldn't but just in case something went wrong... + if (s == null) { + throw JVMCIError.shouldNotReachHere("malformed UTF-8 string in constant pool"); + } + return s; + } else { + return runtime.getCompilerToVM().getSymbol(metaspaceSymbol); + } } }
--- a/make/defs.make Thu Jul 16 13:48:47 2015 +0200 +++ b/make/defs.make Thu Jul 16 07:47:07 2015 -0700 @@ -376,6 +376,7 @@ CONDITIONAL_EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/jdk.internal.jvmci.hotspot.events.EventProvider endif +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotConstantPool EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotConstantReflectionProvider EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotJVMCIRuntime EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/jdk.internal.jvmci.hotspot.HotSpotResolvedJavaFieldImpl
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Jul 16 13:48:47 2015 +0200 +++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp Thu Jul 16 07:47:07 2015 -0700 @@ -1072,16 +1072,16 @@ {CC"shouldInlineMethod", CC"("METASPACE_METHOD")Z", FN_PTR(shouldInlineMethod)}, {CC"lookupType", CC"("STRING CLASS"Z)"METASPACE_KLASS, FN_PTR(lookupType)}, {CC"resolveConstantInPool", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(resolveConstantInPool)}, - {CC"resolvePossiblyCachedConstantInPool", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(resolvePossiblyCachedConstantInPool)}, - {CC"lookupNameRefInPool", CC"("METASPACE_CONSTANT_POOL"I)"STRING, FN_PTR(lookupNameRefInPool)}, + {CC"resolvePossiblyCachedConstantInPool0", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(resolvePossiblyCachedConstantInPool)}, + {CC"lookupNameRefInPool0", CC"("METASPACE_CONSTANT_POOL"I)"STRING, FN_PTR(lookupNameRefInPool)}, {CC"lookupNameAndTypeRefIndexInPool", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)}, - {CC"lookupSignatureRefInPool", CC"("METASPACE_CONSTANT_POOL"I)"STRING, FN_PTR(lookupSignatureRefInPool)}, - {CC"lookupKlassRefIndexInPool", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(lookupKlassRefIndexInPool)}, + {CC"lookupSignatureRefInPool0", CC"("METASPACE_CONSTANT_POOL"I)"STRING, FN_PTR(lookupSignatureRefInPool)}, + {CC"lookupKlassRefIndexInPool0", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(lookupKlassRefIndexInPool)}, {CC"constantPoolKlassAt", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS, FN_PTR(constantPoolKlassAt)}, {CC"lookupKlassInPool", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS, FN_PTR(lookupKlassInPool)}, - {CC"lookupAppendixInPool", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(lookupAppendixInPool)}, + {CC"lookupAppendixInPool0", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(lookupAppendixInPool)}, {CC"lookupMethodInPool", CC"("METASPACE_CONSTANT_POOL"IB)"METASPACE_METHOD, FN_PTR(lookupMethodInPool)}, - {CC"constantPoolRemapInstructionOperandFromCache", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)}, + {CC"constantPoolRemapInstructionOperandFromCache0",CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)}, {CC"resolveField", CC"("METASPACE_CONSTANT_POOL"IB[J)"METASPACE_KLASS, FN_PTR(resolveField)}, {CC"resolveInvokeDynamic", CC"("METASPACE_CONSTANT_POOL"I)V", FN_PTR(resolveInvokeDynamic)}, {CC"resolveInvokeHandle", CC"("METASPACE_CONSTANT_POOL"I)V", FN_PTR(resolveInvokeHandle)}, @@ -1109,7 +1109,7 @@ {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"getSymbol", CC"(J)"STRING, FN_PTR(getSymbol)}, + {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)},
--- a/src/share/vm/runtime/handles.hpp Thu Jul 16 13:48:47 2015 +0200 +++ b/src/share/vm/runtime/handles.hpp Thu Jul 16 07:47:07 2015 -0700 @@ -62,6 +62,7 @@ // used operators for ease of use. class Handle VALUE_OBJ_CLASS_SPEC { + friend class VMStructs; private: oop* _handle;
--- a/src/share/vm/runtime/vmStructs.cpp Thu Jul 16 13:48:47 2015 +0200 +++ b/src/share/vm/runtime/vmStructs.cpp Thu Jul 16 07:47:07 2015 -0700 @@ -1010,6 +1010,9 @@ /*********************************/ \ /* JNIHandles and JNIHandleBlock */ \ /*********************************/ \ + \ + nonstatic_field(Handle, _handle, oop*) \ + \ static_field(JNIHandles, _global_handles, JNIHandleBlock*) \ static_field(JNIHandles, _weak_global_handles, JNIHandleBlock*) \ static_field(JNIHandles, _deleted_handle, oop) \ @@ -1742,6 +1745,8 @@ /* JNIHandles and JNIHandleBlock */ \ /*********************************/ \ \ + declare_toplevel_type(Handle) \ + \ declare_toplevel_type(JNIHandles) \ declare_toplevel_type(JNIHandleBlock) \ declare_toplevel_type(jobject) \ @@ -2538,9 +2543,22 @@ declare_constant(ConstantPoolCacheEntry::is_final_shift) \ declare_constant(ConstantPoolCacheEntry::is_forced_virtual_shift) \ declare_constant(ConstantPoolCacheEntry::is_vfinal_shift) \ + declare_constant(ConstantPoolCacheEntry::has_appendix_shift) \ + declare_constant(ConstantPoolCacheEntry::has_method_type_shift) \ declare_constant(ConstantPoolCacheEntry::is_field_entry_shift) \ declare_constant(ConstantPoolCacheEntry::tos_state_shift) \ \ + declare_constant(ConstantPoolCacheEntry::cp_index_bits) \ + declare_constant(ConstantPoolCacheEntry::cp_index_mask) \ + declare_constant(ConstantPoolCacheEntry::bytecode_1_shift) \ + declare_constant(ConstantPoolCacheEntry::bytecode_1_mask) \ + declare_constant(ConstantPoolCacheEntry::bytecode_2_shift) \ + declare_constant(ConstantPoolCacheEntry::bytecode_2_mask) \ + \ + declare_constant(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset) \ + declare_constant(ConstantPoolCacheEntry::_indy_resolved_references_method_type_offset) \ + declare_constant(ConstantPoolCacheEntry::_indy_resolved_references_entries) \ + \ /***************************************/ \ /* java_lang_Thread::ThreadStatus enum */ \ /***************************************/ \