-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8315771: [JVMCI] Resolution of bootstrap methods with int[] static arguments #15588
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
Changes from 1 commit
b0940de
2cdc0b4
b33ffed
093d0ce
4ec0a7b
079969c
d6aa593
d75e092
f4377fc
9e0627a
ea4aa98
7c27481
7a8d9f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -27,6 +27,8 @@ | |
| import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; | ||
| import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE; | ||
|
|
||
| import java.util.AbstractList; | ||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.stream.Collectors; | ||
|
|
@@ -38,6 +40,7 @@ | |
| import jdk.vm.ci.meta.JavaField; | ||
| import jdk.vm.ci.meta.JavaMethod; | ||
| import jdk.vm.ci.meta.JavaType; | ||
| import jdk.vm.ci.meta.PrimitiveConstant; | ||
| import jdk.vm.ci.meta.ResolvedJavaMethod; | ||
| import jdk.vm.ci.meta.ResolvedJavaType; | ||
| import jdk.vm.ci.meta.Signature; | ||
|
|
@@ -526,6 +529,37 @@ private int flags() { | |
| return UNSAFE.getInt(getConstantPoolPointer() + config().constantPoolFlagsOffset); | ||
| } | ||
|
|
||
| static class CachedBSMArgs extends AbstractList<JavaConstant> { | ||
| private final JavaConstant[] cache; | ||
| private final HotSpotConstantPool cp; | ||
| private final int bssIndex; | ||
|
|
||
| CachedBSMArgs(HotSpotConstantPool cp, int bssIndex, int size) { | ||
| this.cp = cp; | ||
| this.bssIndex = bssIndex; | ||
| this.cache = new JavaConstant[size]; | ||
| } | ||
|
|
||
| @Override | ||
| public JavaConstant get(int index) { | ||
| JavaConstant res = cache[index]; | ||
| if (res == null) { | ||
| int argCpi = compilerToVM().bootstrapArgumentIndexAt(cp, bssIndex, index); | ||
| res = compilerToVM().lookupConstantInPool(cp, argCpi, false); | ||
| if (res == null) { | ||
| res = JavaConstant.forInt(argCpi); | ||
|
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. Based on my understanding and my testing, this can only be reached for 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. I think that's right based on the spec for |
||
| } | ||
| cache[index] = res; | ||
| } | ||
| return res; | ||
| } | ||
|
|
||
| @Override | ||
| public int size() { | ||
| return cache.length; | ||
| } | ||
| } | ||
|
|
||
| static class BootstrapMethodInvocationImpl implements BootstrapMethodInvocation { | ||
| private final boolean indy; | ||
| private final ResolvedJavaMethod method; | ||
|
|
@@ -583,11 +617,6 @@ private static String argumentAsString(JavaConstant arg) { | |
| } | ||
| } | ||
|
|
||
| @Override | ||
| public int bootstrapArgumentIndexAt(int cpi, int index) { | ||
| return compilerToVM().bootstrapArgumentIndexAt(this, cpi, index); | ||
| } | ||
|
|
||
| @Override | ||
| public BootstrapMethodInvocation lookupBootstrapMethodInvocation(int index, int opcode) { | ||
| int cpi = opcode == -1 ? index : indyIndexConstantPoolIndex(index, opcode); | ||
|
|
@@ -609,7 +638,9 @@ public BootstrapMethodInvocation lookupBootstrapMethodInvocation(int index, int | |
| staticArgumentsList = List.of((JavaConstant[]) staticArguments); | ||
| } else { | ||
| int[] bsciArgs = (int[]) staticArguments; | ||
| staticArgumentsList = List.of(Arrays.stream(bsciArgs).mapToObj(i -> JavaConstant.forInt(i)).toArray(JavaConstant[]::new)); | ||
| int argCount = bsciArgs[0]; | ||
| int bss_index = bsciArgs[1]; | ||
| staticArgumentsList = new CachedBSMArgs(this, bss_index, argCount); | ||
| } | ||
| return new BootstrapMethodInvocationImpl(tag.name.equals("InvokeDynamic"), method, name, type, staticArgumentsList); | ||
| default: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -133,24 +133,6 @@ default JavaMethod lookupMethod(int cpi, int opcode) { | |
| * The details for invoking a bootstrap method associated with a {@code CONSTANT_Dynamic_info} | ||
| * or {@code CONSTANT_InvokeDynamic_info} pool entry. | ||
| * | ||
| * The procedure to obtain and use a {@link BootstrapMethodInvocation} is the following: | ||
| * | ||
| * <pre> | ||
| * bsmInvocation = constantpool.lookupBootstrapMethodInvocation(index, opcode); | ||
| * staticArguments = bsmInvocation.getStaticArguments(); | ||
| * if staticArguments are PrimitiveConstant { | ||
| * argCount = staticArguments.get(0).asInt(); | ||
| * cpi = staticArguments.get(1).asInt(); | ||
| * for (int i = 0; i < argCount; ++i) { | ||
| * argCpi = constantpool.bootstrapArgumentIndexAt(cpi, i); | ||
| * arguments[i] = constantpool.lookupConstant(argCpi, resolve); | ||
| * } | ||
| * call bootstrap method with newly resolved arguments | ||
| * } else { | ||
| * call bootstrap method with provided arguments | ||
| * } | ||
| * </pre> | ||
| * | ||
| * @jvms 4.4.10 The {@code CONSTANT_Dynamic_info} and {@code CONSTANT_InvokeDynamic_info} | ||
| * Structures | ||
| * @jvms 4.7.23 The {@code BootstrapMethods} Attribute | ||
|
|
@@ -183,27 +165,28 @@ interface BootstrapMethodInvocation { | |
| /** | ||
| * Gets the static arguments with which the bootstrap method will be invoked. | ||
| * | ||
| * An argument of type {@link PrimitiveConstant} represents a {@code CONSTANT_Dynamic_info} | ||
|
||
| * entry. To resolve this entry, the corresponding bootstrap method has to be called first: | ||
| * | ||
| * <pre> | ||
| * resolveIndyOrCondy(int index, int opcode) { | ||
| * bsmInvocation = cp.lookupBootstrapMethodInvocation(index, opcode); | ||
| * staticArguments = bsmInvocation.getStaticArguments(); | ||
| * for each argument in staticArguments { | ||
| * if argument is PrimitiveArgument { | ||
| * // argument is a condy, so opcode becomes -1 | ||
| * resolveIndyOrCondy(argument.asInt(), -1); | ||
| * } | ||
| * } | ||
| * call original boostrap method with resolved arguments | ||
| * } | ||
| * </pre> | ||
| * | ||
| * @jvms 5.4.3.6 | ||
| */ | ||
| List<JavaConstant> getStaticArguments(); | ||
| } | ||
|
|
||
| /** | ||
| * Gets the constant pool index of a static argument of a {@code CONSTANT_Dynamic_info} or | ||
| * @{code CONSTANT_InvokeDynamic_info} entry. Used when the list of static arguments in the | ||
| * {@link BootstrapMethodInvocation} is a {@code List<PrimitiveConstant>} of the form | ||
| * {{@code arg_count}, {@code pool_index}}, meaning the arguments are not already resolved and that | ||
| * the JDK has to lookup the arguments when they are needed. The {@code cpi} corresponds to | ||
| * {@code pool_index} and the {@code index} has to be smaller than {@code arg_count}. | ||
| * | ||
| * @param cpi the index of a {@code CONSTANT_Dynamic_info} or @{code CONSTANT_InvokeDynamic_info} entry | ||
| * @param index the index of the static argument in the list of static arguments | ||
| * @return the constant pool index associated with the static argument | ||
| */ | ||
| default int bootstrapArgumentIndexAt(int cpi, int index) { | ||
| throw new UnsupportedOperationException(); | ||
| } | ||
|
|
||
| /** | ||
|
||
| * Gets the details for invoking a bootstrap method associated with the | ||
| * {@code CONSTANT_Dynamic_info} or {@code CONSTANT_InvokeDynamic_info} pool entry | ||
|
|
||
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.
This class needs documentation.