-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8314249: Refactor handling of invokedynamic in JVMCI ConstantPool #15297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
iklam
wants to merge
7
commits into
openjdk:master
from
iklam:8314249-refactor-jvmci-constantpool-handling-of-invokedynamic
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
bee008c
8314249: Refactor handling of invokedynamic in JVMCI ConstantPool
iklam e50483a
Added docs about the names we use for indices: cpi, rawIndex, cpci an…
iklam 30020de
fixed comments
iklam 5b09aed
added test case for ConstantPool.lookupAppendix; other code touch by …
iklam 2c05936
fixed test
iklam 337895c
fixed whitespace
iklam e09f65f
@dougxc comments - fixed typos
iklam File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,6 +47,19 @@ | |
|
|
||
| /** | ||
| * Implementation of {@link ConstantPool} for HotSpot. | ||
| * | ||
| * The following convention is used in the jdk.vm.ci.hotspot package when accessing the ConstantPool with an index: | ||
| * <ul> | ||
| * <li>rawIndex - Index in the bytecode stream after the opcode (could be rewritten for some opcodes)</li> | ||
| * <li>cpi - The constant pool index (as specified in JVM Spec)</li> | ||
| * <li>cpci - The constant pool cache index, used only by the four bytecodes INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}. | ||
| * It's the same as {@code rawIndex + HotSpotVMConfig::constantPoolCpCacheIndexTag}. </li> | ||
| * <li>which - May be either a {@code rawIndex} or a {@code cpci}.</li> | ||
| * </ul> | ||
| * | ||
| * Note that {@code cpci} and {@code which} are used only in the HotSpot-specific implementation. They | ||
| * are not used by the public interface in jdk.vm.ci.meta.*. | ||
| * After JDK-8301993, all uses of {@code cpci} and {@code which} will be replaced with {@code rawIndex}. | ||
| */ | ||
| public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleObject { | ||
|
|
||
|
|
@@ -252,25 +265,15 @@ private HotSpotResolvedObjectType getHolder() { | |
| * @return constant pool cache index | ||
| */ | ||
| private static int rawIndexToConstantPoolCacheIndex(int rawIndex, int opcode) { | ||
| int index; | ||
| if (opcode == Bytecodes.INVOKEDYNAMIC) { | ||
| index = rawIndex; | ||
| // See: ConstantPool::is_invokedynamic_index | ||
| if (index >= 0) { | ||
| throw new IllegalArgumentException("not an invokedynamic constant pool index " + index); | ||
| } | ||
| if (opcode == Bytecodes.INVOKEINTERFACE || | ||
| opcode == Bytecodes.INVOKEVIRTUAL || | ||
| opcode == Bytecodes.INVOKESPECIAL || | ||
| opcode == Bytecodes.INVOKESTATIC) { | ||
| return rawIndex + config().constantPoolCpCacheIndexTag; | ||
| } else { | ||
| if (opcode == Bytecodes.INVOKEINTERFACE || | ||
| opcode == Bytecodes.INVOKEVIRTUAL || | ||
| opcode == Bytecodes.INVOKESPECIAL || | ||
| opcode == Bytecodes.INVOKESTATIC) { | ||
| index = rawIndex + config().constantPoolCpCacheIndexTag; | ||
| } else { | ||
| throw new IllegalArgumentException("unexpected opcode " + opcode); | ||
|
|
||
| } | ||
| // Only the above 4 bytecodes use ConstantPoolCacheIndex | ||
| throw new IllegalArgumentException("unexpected opcode " + opcode); | ||
| } | ||
| return index; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -581,8 +584,8 @@ private static String argumentAsString(JavaConstant arg) { | |
| } | ||
|
|
||
| @Override | ||
| public BootstrapMethodInvocation lookupBootstrapMethodInvocation(int rawCpi, int opcode) { | ||
| int cpi = opcode == -1 ? rawCpi : rawIndexToConstantPoolIndex(rawCpi, opcode); | ||
| public BootstrapMethodInvocation lookupBootstrapMethodInvocation(int index, int opcode) { | ||
| int cpi = opcode == -1 ? index : indyIndexConstantPoolIndex(index, opcode); | ||
| final JvmConstant tag = getTagAt(cpi); | ||
| switch (tag.name) { | ||
| case "InvokeDynamic": | ||
|
|
@@ -685,13 +688,19 @@ public Signature lookupSignature(int cpi) { | |
| } | ||
|
|
||
| @Override | ||
| public JavaConstant lookupAppendix(int cpi, int opcode) { | ||
| public JavaConstant lookupAppendix(int rawIndex, int opcode) { | ||
| if (!Bytecodes.isInvoke(opcode)) { | ||
| throw new IllegalArgumentException("expected an invoke bytecode at " + cpi + ", got " + opcode); | ||
| throw new IllegalArgumentException("expected an invoke bytecode for " + rawIndex + ", got " + opcode); | ||
| } | ||
|
|
||
| final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); | ||
| return compilerToVM().lookupAppendixInPool(this, index); | ||
| if (opcode == Bytecodes.INVOKEDYNAMIC) { | ||
| if (!isInvokedynamicIndex(rawIndex)) { | ||
| throw new IllegalArgumentException("expected a raw index for INVOKEDYNAMIC but got " + rawIndex); | ||
| } | ||
| return compilerToVM().lookupAppendixInPool(this, rawIndex); | ||
| } else { | ||
| return compilerToVM().lookupAppendixInPool(this, rawIndexToConstantPoolCacheIndex(rawIndex, opcode)); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -709,19 +718,19 @@ private static JavaType getJavaType(final Object type) { | |
| } | ||
|
|
||
| @Override | ||
| public JavaMethod lookupMethod(int cpi, int opcode, ResolvedJavaMethod caller) { | ||
| final int index = rawIndexToConstantPoolCacheIndex(cpi, opcode); | ||
| final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, index, (byte) opcode, (HotSpotResolvedJavaMethodImpl) caller); | ||
| public JavaMethod lookupMethod(int rawIndex, int opcode, ResolvedJavaMethod caller) { | ||
| final int cpci = rawIndexToConstantPoolCacheIndex(rawIndex, opcode); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @iklam we need to support when building libgraal. The following patch seems to fix it: |
||
| final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, cpci, (byte) opcode, (HotSpotResolvedJavaMethodImpl) caller); | ||
| if (method != null) { | ||
| return method; | ||
| } else { | ||
| // Get the method's name and signature. | ||
| String name = getNameOf(index, opcode); | ||
| HotSpotSignature signature = new HotSpotSignature(runtime(), getSignatureOf(index, opcode)); | ||
| String name = getNameOf(cpci, opcode); | ||
| HotSpotSignature signature = new HotSpotSignature(runtime(), getSignatureOf(cpci, opcode)); | ||
| if (opcode == Bytecodes.INVOKEDYNAMIC) { | ||
| return new UnresolvedJavaMethod(name, signature, runtime().getMethodHandleClass()); | ||
| } else { | ||
| final int klassIndex = getKlassRefIndexAt(index, opcode); | ||
| final int klassIndex = getKlassRefIndexAt(cpci, opcode); | ||
| final Object type = compilerToVM().lookupKlassInPool(this, klassIndex); | ||
| return new UnresolvedJavaMethod(name, signature, getJavaType(type)); | ||
| } | ||
|
|
@@ -780,7 +789,6 @@ public JavaType lookupReferencedType(int rawIndex, int opcode) { | |
|
|
||
| @Override | ||
| public JavaField lookupField(int rawIndex, ResolvedJavaMethod method, int opcode) { | ||
| final int cpi = compilerToVM().decodeFieldIndexToCPIndex(this, rawIndex); | ||
| final int nameAndTypeIndex = getNameAndTypeRefIndexAt(rawIndex, opcode); | ||
| final int typeIndex = getSignatureRefIndexAt(nameAndTypeIndex); | ||
| String typeName = lookupUtf8(typeIndex); | ||
|
|
@@ -813,32 +821,23 @@ public JavaField lookupField(int rawIndex, ResolvedJavaMethod method, int opcode | |
| } | ||
|
|
||
| /** | ||
| * Converts a raw index from the bytecodes to a constant pool index (not a cache index). | ||
| * Converts a raw index for the INVOKEDYNAMIC bytecode to a constant pool index. | ||
| * | ||
| * @param rawIndex index from the bytecode | ||
| * | ||
| * @param opcode bytecode to convert the index for | ||
| * @param opcode bytecode to convert the index for. Must be INVOKEDYNAMIC. | ||
| * | ||
| * @return constant pool index | ||
| */ | ||
| public int rawIndexToConstantPoolIndex(int rawIndex, int opcode) { | ||
| private int indyIndexConstantPoolIndex(int rawIndex, int opcode) { | ||
| if (isInvokedynamicIndex(rawIndex)) { | ||
| if (opcode != Bytecodes.INVOKEDYNAMIC) { | ||
| throw new IllegalArgumentException("expected INVOKEDYNAMIC at " + rawIndex + ", got " + opcode); | ||
| } | ||
| return compilerToVM().decodeIndyIndexToCPIndex(this, rawIndex, false); | ||
| } else { | ||
| throw new IllegalArgumentException("expected a raw index for INVOKEDYNAMIC but got " + rawIndex); | ||
| } | ||
| if (opcode == Bytecodes.INVOKEDYNAMIC) { | ||
| throw new IllegalArgumentException("unexpected INVOKEDYNAMIC at " + rawIndex); | ||
| } | ||
| if (opcode == Bytecodes.GETSTATIC || | ||
| opcode == Bytecodes.PUTSTATIC || | ||
| opcode == Bytecodes.GETFIELD || | ||
| opcode == Bytecodes.PUTFIELD) { | ||
| return compilerToVM().decodeFieldIndexToCPIndex(this, rawIndex); | ||
| } | ||
| int index = rawIndexToConstantPoolCacheIndex(rawIndex, opcode); | ||
| return compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index); | ||
| } | ||
|
|
||
| @Override | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would opcode be -1 here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that tests such as TestDynamicConstant.java can iterate through the constant pool, looking for invokedynamic related entries.