|
27 | 27 | import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
|
28 | 28 | import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
|
29 | 29 |
|
| 30 | +import java.util.AbstractList; |
| 31 | +import java.util.ArrayList; |
30 | 32 | import java.util.Arrays;
|
31 | 33 | import java.util.List;
|
32 | 34 | import java.util.stream.Collectors;
|
|
38 | 40 | import jdk.vm.ci.meta.JavaField;
|
39 | 41 | import jdk.vm.ci.meta.JavaMethod;
|
40 | 42 | import jdk.vm.ci.meta.JavaType;
|
| 43 | +import jdk.vm.ci.meta.PrimitiveConstant; |
41 | 44 | import jdk.vm.ci.meta.ResolvedJavaMethod;
|
42 | 45 | import jdk.vm.ci.meta.ResolvedJavaType;
|
43 | 46 | import jdk.vm.ci.meta.Signature;
|
@@ -504,6 +507,60 @@ private int flags() {
|
504 | 507 | return UNSAFE.getInt(getConstantPoolPointer() + config().constantPoolFlagsOffset);
|
505 | 508 | }
|
506 | 509 |
|
| 510 | + /** |
| 511 | + * Represents a list of static arguments from a {@link BootstrapMethodInvocation} of the form |
| 512 | + * {{@code arg_count}, {@code pool_index}}, meaning the arguments are not already resolved |
| 513 | + * and that the JDK has to lookup the arguments when they are needed. The {@code bssIndex} |
| 514 | + * corresponds to {@code pool_index} and the {@code size} corresponds to {@code arg_count}. |
| 515 | + */ |
| 516 | + static class CachedBSMArgs extends AbstractList<JavaConstant> { |
| 517 | + private final JavaConstant[] cache; |
| 518 | + private final HotSpotConstantPool cp; |
| 519 | + private final int bssIndex; |
| 520 | + |
| 521 | + CachedBSMArgs(HotSpotConstantPool cp, int bssIndex, int size) { |
| 522 | + this.cp = cp; |
| 523 | + this.bssIndex = bssIndex; |
| 524 | + this.cache = new JavaConstant[size]; |
| 525 | + } |
| 526 | + |
| 527 | + /** |
| 528 | + * Lazily resolves and caches the argument at the given index and returns it. The method |
| 529 | + * {@link CompilerToVM#bootstrapArgumentIndexAt} is used to obtain the constant pool |
| 530 | + * index of the entry and the method {@link ConstantPool#lookupConstant} is used to |
| 531 | + * resolve it. If the resolution failed, the index is returned as a |
| 532 | + * {@link PrimitiveConstant}. |
| 533 | + * |
| 534 | + * @param index index of the element to return |
| 535 | + * @return A {@link JavaConstant} corresponding to the static argument requested. A return |
| 536 | + * value of type {@link PrimitiveConstant} represents an unresolved constant pool entry |
| 537 | + */ |
| 538 | + @Override |
| 539 | + public JavaConstant get(int index) { |
| 540 | + JavaConstant res = cache[index]; |
| 541 | + if (res == null) { |
| 542 | + int argCpi = compilerToVM().bootstrapArgumentIndexAt(cp, bssIndex, index); |
| 543 | + Object object = cp.lookupConstant(argCpi, false); |
| 544 | + if (object instanceof PrimitiveConstant primitiveConstant) { |
| 545 | + res = runtime().getReflection().boxPrimitive(primitiveConstant); |
| 546 | + } else if (object instanceof JavaConstant javaConstant) { |
| 547 | + res = javaConstant; |
| 548 | + } else if (object instanceof JavaType type) { |
| 549 | + res = runtime().getReflection().forObject(type); |
| 550 | + } else { |
| 551 | + res = JavaConstant.forInt(argCpi); |
| 552 | + } |
| 553 | + cache[index] = res; |
| 554 | + } |
| 555 | + return res; |
| 556 | + } |
| 557 | + |
| 558 | + @Override |
| 559 | + public int size() { |
| 560 | + return cache.length; |
| 561 | + } |
| 562 | + } |
| 563 | + |
507 | 564 | static class BootstrapMethodInvocationImpl implements BootstrapMethodInvocation {
|
508 | 565 | private final boolean indy;
|
509 | 566 | private final ResolvedJavaMethod method;
|
@@ -582,8 +639,9 @@ public BootstrapMethodInvocation lookupBootstrapMethodInvocation(int index, int
|
582 | 639 | staticArgumentsList = List.of((JavaConstant[]) staticArguments);
|
583 | 640 | } else {
|
584 | 641 | int[] bsciArgs = (int[]) staticArguments;
|
585 |
| - String message = String.format("Resolving bootstrap static arguments for %s using BootstrapCallInfo %s not supported", method.format("%H.%n(%p)"), Arrays.toString(bsciArgs)); |
586 |
| - throw new IllegalArgumentException(message); |
| 642 | + int argCount = bsciArgs[0]; |
| 643 | + int bss_index = bsciArgs[1]; |
| 644 | + staticArgumentsList = new CachedBSMArgs(this, bss_index, argCount); |
587 | 645 | }
|
588 | 646 | return new BootstrapMethodInvocationImpl(tag.name.equals("InvokeDynamic"), method, name, type, staticArgumentsList);
|
589 | 647 | default:
|
|
0 commit comments