diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 07d27295e95..edeba7a7314 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -1485,11 +1485,17 @@ C2V_VMENTRY_NULL(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, job return nullptr; C2V_END -C2V_VMENTRY(void, resolveInvokeDynamicInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index)) +C2V_VMENTRY_0(int, resolveInvokeDynamicInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index)) + if (!ConstantPool::is_invokedynamic_index(index)) { + JVMCI_THROW_MSG_0(IllegalStateException, err_msg("not an invokedynamic index %d", index)); + } + constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp)); CallInfo callInfo; - LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK); - cp->cache()->set_dynamic_call(callInfo, index); // Index already decoded + LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK_0); + int indy_index = cp->decode_invokedynamic_index(index); + cp->cache()->set_dynamic_call(callInfo, indy_index); + return cp->resolved_indy_entry_at(indy_index)->constant_pool_index(); C2V_END C2V_VMENTRY(void, resolveInvokeHandleInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index)) @@ -2889,7 +2895,7 @@ JNINativeMethod CompilerToVM::methods[] = { {CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL2 "I)" JAVACONSTANT, FN_PTR(resolvePossiblyCachedConstantInPool)}, {CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL2 "I)" HS_KLASS, FN_PTR(resolveTypeInPool)}, {CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL2 "I" HS_METHOD2 "B[I)" HS_KLASS, FN_PTR(resolveFieldInPool)}, - {CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL2 "I)V", FN_PTR(resolveInvokeDynamicInPool)}, + {CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL2 "I)I", FN_PTR(resolveInvokeDynamicInPool)}, {CC "resolveInvokeHandleInPool", CC "(" HS_CONSTANT_POOL2 "I)V", FN_PTR(resolveInvokeHandleInPool)}, {CC "isResolvedInvokeHandleInPool", CC "(" HS_CONSTANT_POOL2 "I)I", FN_PTR(isResolvedInvokeHandleInPool)}, {CC "resolveMethod", CC "(" HS_KLASS2 HS_METHOD2 HS_KLASS2 ")" HS_METHOD, FN_PTR(resolveMethod)}, diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java index b4866e2fa43..cbc542a7618 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java @@ -376,14 +376,14 @@ final class CompilerToVM { * Ensures that the type referenced by the specified {@code JVM_CONSTANT_InvokeDynamic} entry at * 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. + * @throws IllegalArgumentException if {@code cpi} is not an invokedynamic index + * @return the invokedynamic index */ - void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi) { - resolveInvokeDynamicInPool(constantPool, constantPool.getConstantPoolPointer(), cpi); + int resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi) { + return resolveInvokeDynamicInPool(constantPool, constantPool.getConstantPoolPointer(), cpi); } - private native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi); + private native int resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi); /** * Resolves the details for invoking the bootstrap method associated with the diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java index 373e2d6dbd2..6821d3f209c 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java @@ -277,22 +277,6 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleO return index; } - /** - * Decode a constant pool cache index to a constant pool index. - * - * See {@code ConstantPool::decode_cpcache_index}. - * - * @param index constant pool cache index - * @return decoded index - */ - private static int decodeConstantPoolCacheIndex(int index) { - if (isInvokedynamicIndex(index)) { - return decodeInvokedynamicIndex(index); - } else { - return index - config().constantPoolCpCacheIndexTag; - } - } - /** * See {@code ConstantPool::is_invokedynamic_index}. */ @@ -877,10 +861,10 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleO break; case Bytecodes.INVOKEDYNAMIC: { // invokedynamic indices are different from constant pool cache indices - index = decodeConstantPoolCacheIndex(cpi); - if (isInvokedynamicIndex(cpi)) { - compilerToVM().resolveInvokeDynamicInPool(this, index); + if (!isInvokedynamicIndex(cpi)) { + throw new IllegalArgumentException("must use invokedynamic index but got " + cpi); } + index = compilerToVM().resolveInvokeDynamicInPool(this, cpi); break; } case Bytecodes.GETSTATIC: diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java index 6da3ce37edc..6f94877b9af 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestDynamicConstant.java @@ -194,7 +194,7 @@ public class TestDynamicConstant implements Opcodes { String sig = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"; Handle handle = new Handle(H_INVOKESTATIC, Type.getInternalName(StringConcatFactory.class), "makeConcatWithConstants", sig, false); String recipe = "var arg=\u0001, const arg=\u0002"; - Object[] bsmArgs = {recipe}; + Object[] bsmArgs = {recipe, condy}; concat.visitLdcInsn(condy); concat.visitInvokeDynamicInsn("do_concat", "(" + desc + ")Ljava/lang/String;", handle, bsmArgs); concat.visitInsn(ARETURN); @@ -316,6 +316,23 @@ public class TestDynamicConstant implements Opcodes { Assert.assertNull(bsmi, String.valueOf(bsmi)); } } + + testLoadReferencedType(concat); + } + + private static int beS4(byte[] data, int bci) { + return (data[bci] << 24) | ((data[bci + 1] & 0xff) << 16) | ((data[bci + 2] & 0xff) << 8) | (data[bci + 3] & 0xff); + } + + private static final int LDC2_W = 20; + private static void testLoadReferencedType(ResolvedJavaMethod method) { + // Make sure that loadReferencedType for an invokedynamic call site works. + byte[] code = method.getCode(); + Assert.assertTrue(code[0] == LDC || code[0] == LDC2_W, "unexpected ldc sequence"); + int bci = code[0] == LDC ? 2 : 3; + Assert.assertTrue((code[bci] & 0xff) == INVOKEDYNAMIC, "unexpected bytecode"); + int cpi = beS4(code, bci + 1); + method.getConstantPool().loadReferencedType(cpi, INVOKEDYNAMIC, false); } // @formatter:off