Skip to content

Commit 86821a7

Browse files
author
Doug Simon
committed
8312235: [JVMCI] ConstantPool should not force eager resolution
Reviewed-by: never, matsaave
1 parent 7cbab1f commit 86821a7

File tree

7 files changed

+161
-58
lines changed

7 files changed

+161
-58
lines changed

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -697,15 +697,24 @@ C2V_VMENTRY_NULL(jobject, getUncachedStringInPool, (JNIEnv* env, jobject, ARGUME
697697
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj));
698698
C2V_END
699699

700-
C2V_VMENTRY_NULL(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index))
700+
C2V_VMENTRY_NULL(jobject, lookupConstantInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint cp_index, bool resolve))
701701
constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
702-
oop obj = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
703-
constantTag tag = cp->tag_at(index);
702+
oop obj;
703+
if (!resolve) {
704+
bool found_it;
705+
obj = cp->find_cached_constant_at(cp_index, found_it, CHECK_NULL);
706+
if (!found_it) {
707+
return nullptr;
708+
}
709+
} else {
710+
obj = cp->resolve_possibly_cached_constant_at(cp_index, CHECK_NULL);
711+
}
712+
constantTag tag = cp->tag_at(cp_index);
704713
if (tag.is_dynamic_constant()) {
705714
if (obj == nullptr) {
706715
return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER());
707716
}
708-
BasicType bt = Signature::basic_type(cp->uncached_signature_ref_at(index));
717+
BasicType bt = Signature::basic_type(cp->uncached_signature_ref_at(cp_index));
709718
if (!is_reference_type(bt)) {
710719
if (!is_java_primitive(bt)) {
711720
return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_ILLEGAL());
@@ -1578,16 +1587,18 @@ C2V_VMENTRY_NULL(jobject, iterateFrames, (JNIEnv* env, jobject compilerToVM, job
15781587
return nullptr;
15791588
C2V_END
15801589

1581-
C2V_VMENTRY_0(int, resolveInvokeDynamicInPool, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint index))
1582-
if (!ConstantPool::is_invokedynamic_index(index)) {
1583-
JVMCI_THROW_MSG_0(IllegalStateException, err_msg("not an invokedynamic index %d", index));
1590+
C2V_VMENTRY_0(int, decodeIndyIndexToCPIndex, (JNIEnv* env, jobject, ARGUMENT_PAIR(cp), jint encoded_indy_index, jboolean resolve))
1591+
if (!ConstantPool::is_invokedynamic_index(encoded_indy_index)) {
1592+
JVMCI_THROW_MSG_0(IllegalStateException, err_msg("not an encoded indy index %d", encoded_indy_index));
15841593
}
15851594

15861595
constantPoolHandle cp(THREAD, UNPACK_PAIR(ConstantPool, cp));
15871596
CallInfo callInfo;
1588-
LinkResolver::resolve_invoke(callInfo, Handle(), cp, index, Bytecodes::_invokedynamic, CHECK_0);
1589-
int indy_index = cp->decode_invokedynamic_index(index);
1590-
cp->cache()->set_dynamic_call(callInfo, indy_index);
1597+
int indy_index = cp->decode_invokedynamic_index(encoded_indy_index);
1598+
if (resolve) {
1599+
LinkResolver::resolve_invoke(callInfo, Handle(), cp, encoded_indy_index, Bytecodes::_invokedynamic, CHECK_0);
1600+
cp->cache()->set_dynamic_call(callInfo, indy_index);
1601+
}
15911602
return cp->resolved_indy_entry_at(indy_index)->constant_pool_index();
15921603
C2V_END
15931604

@@ -3108,13 +3119,13 @@ JNINativeMethod CompilerToVM::methods[] = {
31083119
{CC "lookupKlassInPool", CC "(" HS_CONSTANT_POOL2 "I)Ljava/lang/Object;", FN_PTR(lookupKlassInPool)},
31093120
{CC "lookupAppendixInPool", CC "(" HS_CONSTANT_POOL2 "I)" OBJECTCONSTANT, FN_PTR(lookupAppendixInPool)},
31103121
{CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL2 "IB" HS_METHOD2 ")" HS_METHOD, FN_PTR(lookupMethodInPool)},
3122+
{CC "lookupConstantInPool", CC "(" HS_CONSTANT_POOL2 "IZ)" JAVACONSTANT, FN_PTR(lookupConstantInPool)},
31113123
{CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL2 "I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)},
31123124
{CC "resolveBootstrapMethod", CC "(" HS_CONSTANT_POOL2 "I)[" OBJECT, FN_PTR(resolveBootstrapMethod)},
31133125
{CC "getUncachedStringInPool", CC "(" HS_CONSTANT_POOL2 "I)" JAVACONSTANT, FN_PTR(getUncachedStringInPool)},
3114-
{CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL2 "I)" JAVACONSTANT, FN_PTR(resolvePossiblyCachedConstantInPool)},
31153126
{CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL2 "I)" HS_KLASS, FN_PTR(resolveTypeInPool)},
31163127
{CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL2 "I" HS_METHOD2 "B[I)" HS_KLASS, FN_PTR(resolveFieldInPool)},
3117-
{CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL2 "I)I", FN_PTR(resolveInvokeDynamicInPool)},
3128+
{CC "decodeIndyIndexToCPIndex", CC "(" HS_CONSTANT_POOL2 "IZ)I", FN_PTR(decodeIndyIndexToCPIndex)},
31183129
{CC "resolveInvokeHandleInPool", CC "(" HS_CONSTANT_POOL2 "I)V", FN_PTR(resolveInvokeHandleInPool)},
31193130
{CC "isResolvedInvokeHandleInPool", CC "(" HS_CONSTANT_POOL2 "I)I", FN_PTR(isResolvedInvokeHandleInPool)},
31203131
{CC "resolveMethod", CC "(" HS_KLASS2 HS_METHOD2 HS_KLASS2 ")" HS_METHOD, FN_PTR(resolveMethod)},

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -271,19 +271,22 @@ JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, int cpi)
271271
private native JavaConstant getUncachedStringInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
272272

273273
/**
274-
* Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the
274+
* Gets the entry at index {@code cpi} in {@code constantPool}, looking in the
275275
* constant pool cache first.
276276
*
277277
* The behavior of this method is undefined if {@code cpi} does not denote one of the following
278278
* entry types: {@code JVM_CONSTANT_Dynamic}, {@code JVM_CONSTANT_String},
279279
* {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError},
280280
* {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}.
281+
*
282+
* @param resolve specifies if a resolved entry is expected. If {@code false},
283+
* {@code null} is returned for an unresolved entry.
281284
*/
282-
JavaConstant resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi) {
283-
return resolvePossiblyCachedConstantInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
285+
JavaConstant lookupConstantInPool(HotSpotConstantPool constantPool, int cpi, boolean resolve) {
286+
return lookupConstantInPool(constantPool, constantPool.getConstantPoolPointer(), cpi, resolve);
284287
}
285288

286-
private native JavaConstant resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
289+
private native JavaConstant lookupConstantInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi, boolean resolve);
287290

288291
/**
289292
* Gets the {@code JVM_CONSTANT_NameAndType} index referenced by the {@code rawIndex}.
@@ -387,17 +390,18 @@ private native HotSpotResolvedJavaMethodImpl lookupMethodInPool(HotSpotConstantP
387390
long callerMethodPointer);
388391

389392
/**
390-
* Ensures that the type referenced by the specified {@code JVM_CONSTANT_InvokeDynamic} entry at
391-
* index {@code cpi} in {@code constantPool} is loaded and initialized.
393+
* Converts the encoded indy index operand of an invokedynamic instruction
394+
* to an index directly into {@code constantPool}.
392395
*
393-
* @throws IllegalArgumentException if {@code cpi} is not an invokedynamic index
394-
* @return the invokedynamic index
396+
* @param resolve if {@true}, then resolve the entry (which may call a bootstrap method)
397+
* @throws IllegalArgumentException if {@code encoded_indy_index} is not an encoded indy index
398+
* @return {@code JVM_CONSTANT_InvokeDynamic} constant pool entry index for the invokedynamic
395399
*/
396-
int resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi) {
397-
return resolveInvokeDynamicInPool(constantPool, constantPool.getConstantPoolPointer(), cpi);
400+
int decodeIndyIndexToCPIndex(HotSpotConstantPool constantPool, int encoded_indy_index, boolean resolve) {
401+
return decodeIndyIndexToCPIndex(constantPool, constantPool.getConstantPoolPointer(), encoded_indy_index, resolve);
398402
}
399403

400-
private native int resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int cpi);
404+
private native int decodeIndyIndexToCPIndex(HotSpotConstantPool constantPool, long constantPoolPointer, int encoded_indy_index, boolean resolve);
401405

402406
/**
403407
* Resolves the details for invoking the bootstrap method associated with the
@@ -440,7 +444,7 @@ void resolveInvokeHandleInPool(HotSpotConstantPool constantPool, int cpi) {
440444

441445
/**
442446
* If {@code cpi} denotes an entry representing a resolved dynamic adapter (see
443-
* {@link #resolveInvokeDynamicInPool} and {@link #resolveInvokeHandleInPool}), return the
447+
* {@link #decodeIndyIndexToCPIndex} and {@link #resolveInvokeHandleInPool}), return the
444448
* opcode of the instruction for which the resolution was performed ({@code invokedynamic} or
445449
* {@code invokevirtual}), or {@code -1} otherwise.
446450
*/

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,11 @@ JavaConstant getStaticFieldConstantValue(int cpi) {
637637

638638
@Override
639639
public Object lookupConstant(int cpi) {
640+
return lookupConstant(cpi, true);
641+
}
642+
643+
@Override
644+
public Object lookupConstant(int cpi, boolean resolve) {
640645
final JvmConstant tag = getTagAt(cpi);
641646
switch (tag.name) {
642647
case "Integer":
@@ -658,17 +663,18 @@ public Object lookupConstant(int cpi) {
658663
* "pseudo strings" (arbitrary live objects) patched into a String entry. Such
659664
* entries do not have a symbol in the constant pool slot.
660665
*/
661-
return compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
666+
return compilerToVM().lookupConstantInPool(this, cpi, true);
662667
case "MethodHandle":
663668
case "MethodHandleInError":
664669
case "MethodType":
665670
case "MethodTypeInError":
666671
case "Dynamic":
667672
case "DynamicInError":
668-
return compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
673+
return compilerToVM().lookupConstantInPool(this, cpi, resolve);
669674
default:
670675
throw new JVMCIError("Unknown constant pool tag %s", tag);
671676
}
677+
672678
}
673679

674680
@Override
@@ -822,7 +828,7 @@ public int rawIndexToConstantPoolIndex(int rawIndex, int opcode) {
822828
if (opcode != Bytecodes.INVOKEDYNAMIC) {
823829
throw new IllegalArgumentException("expected INVOKEDYNAMIC at " + rawIndex + ", got " + opcode);
824830
}
825-
return compilerToVM().resolveInvokeDynamicInPool(this, rawIndex);
831+
return compilerToVM().decodeIndyIndexToCPIndex(this, rawIndex, false);
826832
}
827833
if (opcode == Bytecodes.INVOKEDYNAMIC) {
828834
throw new IllegalArgumentException("unexpected INVOKEDYNAMIC at " + rawIndex);
@@ -856,7 +862,7 @@ public void loadReferencedType(int cpi, int opcode, boolean initialize) {
856862
if (!isInvokedynamicIndex(cpi)) {
857863
throw new IllegalArgumentException("must use invokedynamic index but got " + cpi);
858864
}
859-
index = compilerToVM().resolveInvokeDynamicInPool(this, cpi);
865+
index = compilerToVM().decodeIndyIndexToCPIndex(this, cpi, true);
860866
break;
861867
}
862868
case Bytecodes.GETSTATIC:

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ConstantPool.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,20 @@ default BootstrapMethodInvocation lookupBootstrapMethodInvocation(int cpi, int o
220220
*/
221221
Object lookupConstant(int cpi);
222222

223+
/**
224+
* Looks up a constant at the specified index.
225+
*
226+
* If {@code resolve == false} and the denoted constant is of type
227+
* {@code JVM_CONSTANT_Dynamic}, {@code JVM_CONSTANT_MethodHandle} or
228+
* {@code JVM_CONSTANT_MethodType} and it's not yet resolved then
229+
* {@code null} is returned.
230+
*
231+
* @param cpi the constant pool index
232+
* @return the {@code Constant} or {@code JavaType} instance representing the constant pool
233+
* entry
234+
*/
235+
Object lookupConstant(int cpi, boolean resolve);
236+
223237
/**
224238
* Looks up the appendix at the specified index.
225239
*

test/hotspot/jtreg/compiler/jvmci/common/patches/jdk.internal.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ public static HotSpotResolvedObjectType lookupTypeHelper(String name,
101101
}
102102
}
103103

104-
public static Object resolvePossiblyCachedConstantInPool(ConstantPool constantPool, int cpi) {
105-
DirectHotSpotObjectConstantImpl obj = (DirectHotSpotObjectConstantImpl) CTVM.resolvePossiblyCachedConstantInPool((HotSpotConstantPool) constantPool, cpi);
104+
public static Object lookupConstantInPool(ConstantPool constantPool, int cpi, boolean resolve) {
105+
DirectHotSpotObjectConstantImpl obj = (DirectHotSpotObjectConstantImpl) CTVM.lookupConstantInPool((HotSpotConstantPool) constantPool, cpi, resolve);
106106
return obj.object;
107107
}
108108

@@ -132,11 +132,6 @@ public static HotSpotResolvedJavaMethod lookupMethodInPool(
132132
return CTVM.lookupMethodInPool((HotSpotConstantPool) constantPool, cpi, opcode, null);
133133
}
134134

135-
public static void resolveInvokeDynamicInPool(
136-
ConstantPool constantPool, int cpi) {
137-
CTVM.resolveInvokeDynamicInPool((HotSpotConstantPool) constantPool, cpi);
138-
}
139-
140135
public static void resolveInvokeHandleInPool(
141136
ConstantPool constantPool, int cpi) {
142137
CTVM.resolveInvokeHandleInPool((HotSpotConstantPool) constantPool, cpi);
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
4141
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
4242
* -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
4343
* -XX:-UseJVMCICompiler
44-
* compiler.jvmci.compilerToVM.ResolvePossiblyCachedConstantInPoolTest
44+
* compiler.jvmci.compilerToVM.LookupConstantInPoolTest
4545
*/
4646

4747
package compiler.jvmci.compilerToVM;
@@ -64,15 +64,15 @@
6464
import static compiler.jvmci.compilerToVM.ConstantPoolTestCase.ConstantTypes.CONSTANT_STRING;
6565

6666
/**
67-
* Test for {@code jdk.vm.ci.hotspot.CompilerToVM.resolvePossiblyCachedConstantInPool} method
67+
* Test for {@code jdk.vm.ci.hotspot.CompilerToVM.lookupConstantInPool} method
6868
*/
69-
public class ResolvePossiblyCachedConstantInPoolTest {
69+
public class LookupConstantInPoolTest {
7070

7171
public static void main(String[] args) throws Exception {
7272
Map<ConstantTypes, Validator> typeTests = new HashMap<>();
73-
typeTests.put(CONSTANT_STRING, ResolvePossiblyCachedConstantInPoolTest::validateString);
74-
typeTests.put(CONSTANT_METHODHANDLE, ResolvePossiblyCachedConstantInPoolTest::validateMethodHandle);
75-
typeTests.put(CONSTANT_METHODTYPE, ResolvePossiblyCachedConstantInPoolTest::validateMethodType);
73+
typeTests.put(CONSTANT_STRING, LookupConstantInPoolTest::validateString);
74+
typeTests.put(CONSTANT_METHODHANDLE, LookupConstantInPoolTest::validateMethodHandle);
75+
typeTests.put(CONSTANT_METHODTYPE, LookupConstantInPoolTest::validateMethodType);
7676
ConstantPoolTestCase testCase = new ConstantPoolTestCase(typeTests);
7777
testCase.test();
7878
// The next "Class.forName" and repeating "testCase.test()"
@@ -103,7 +103,7 @@ private static void validateString(ConstantPool constantPoolCTVM,
103103
index = cpci;
104104
cached = "cached ";
105105
}
106-
Object constantInPool = CompilerToVMHelper.resolvePossiblyCachedConstantInPool(constantPoolCTVM, index);
106+
Object constantInPool = CompilerToVMHelper.lookupConstantInPool(constantPoolCTVM, index, true);
107107
String stringToVerify = (String) constantInPool;
108108
String stringToRefer = entry.name;
109109
if (stringToRefer.equals("") && cpci != ConstantPoolTestsHelper.NO_CP_CACHE_PRESENT) {
@@ -114,14 +114,14 @@ private static void validateString(ConstantPool constantPoolCTVM,
114114
}
115115

116116
private static final String NOT_NULL_MSG
117-
= "Object returned by resolvePossiblyCachedConstantInPool method should not be null";
117+
= "Object returned by lookupConstantInPool method should not be null";
118118

119119

120120
private static void validateMethodHandle(ConstantPool constantPoolCTVM,
121121
ConstantTypes cpType,
122122
DummyClasses dummyClass,
123123
int index) {
124-
Object constantInPool = CompilerToVMHelper.resolvePossiblyCachedConstantInPool(constantPoolCTVM, index);
124+
Object constantInPool = CompilerToVMHelper.lookupConstantInPool(constantPoolCTVM, index, true);
125125
String msg = String.format("%s for index %d", NOT_NULL_MSG, index);
126126
Asserts.assertNotNull(constantInPool, msg);
127127
if (!(constantInPool instanceof MethodHandle)) {
@@ -138,7 +138,7 @@ private static void validateMethodType(ConstantPool constantPoolCTVM,
138138
ConstantTypes cpType,
139139
DummyClasses dummyClass,
140140
int index) {
141-
Object constantInPool = CompilerToVMHelper.resolvePossiblyCachedConstantInPool(constantPoolCTVM, index);
141+
Object constantInPool = CompilerToVMHelper.lookupConstantInPool(constantPoolCTVM, index, true);
142142
String msg = String.format("%s for index %d", NOT_NULL_MSG, index);
143143
Asserts.assertNotNull(constantInPool, msg);
144144
Class mtToVerify = constantInPool.getClass();

0 commit comments

Comments
 (0)