Skip to content

Commit d26518c

Browse files
committed
Extract link resolver from Espresso, ready to migrate to shared module.
1 parent aa5db3f commit d26518c

21 files changed

+498
-154
lines changed

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/constantpool/Resolution.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -202,18 +202,19 @@ public static Resolvable.ResolvedConstant resolveFieldRefConstant(FieldRefConsta
202202
Symbol<Name> name = thiz.getName(pool);
203203
Symbol<Type> type = thiz.getType(pool);
204204

205-
Meta meta = pool.getContext().getMeta();
205+
EspressoContext context = pool.getContext();
206+
LinkResolver<EspressoContext, Klass, Method, Field> resolver = context.getLinkResolver();
206207
Field field;
207208
ClassRedefinition classRedefinition = null;
208209
try {
209210
try {
210-
field = LinkResolver.resolveFieldSymbol(meta, accessingKlass, name, type, holderKlass, true, true);
211+
field = resolver.resolveFieldSymbol(context, accessingKlass, name, type, holderKlass, true, true);
211212
} catch (EspressoException e) {
212-
classRedefinition = pool.getContext().getClassRedefinition();
213+
classRedefinition = context.getClassRedefinition();
213214
if (classRedefinition != null) {
214215
// could be due to ongoing redefinition
215216
classRedefinition.check();
216-
field = LinkResolver.resolveFieldSymbol(meta, accessingKlass, name, type, holderKlass, true, true);
217+
field = resolver.resolveFieldSymbol(context, accessingKlass, name, type, holderKlass, true, true);
217218
} else {
218219
throw e;
219220
}
@@ -230,7 +231,8 @@ public static Klass getResolvedHolderKlass(MemberRefConstant.Indexes thiz, Runti
230231
}
231232

232233
@TruffleBoundary
233-
public static void memberDoAccessCheck(ObjectKlass accessingKlass, Klass resolvedKlass, Member<? extends Descriptor> member, Meta meta) {
234+
public static void memberDoAccessCheck(Klass accessingKlass, Klass resolvedKlass, Member<? extends Descriptor> member, Meta meta) {
235+
assert accessingKlass != null && resolvedKlass != null && member != null : "pre-conditions failed.";
234236
if (!memberCheckAccess(accessingKlass, resolvedKlass, member)) {
235237
String message = "Class " + accessingKlass.getExternalName() + " cannot access method " + resolvedKlass.getExternalName() + "#" + member.getName();
236238
throw meta.throwExceptionWithMessage(meta.java_lang_IllegalAccessError, meta.toGuestString(message));
@@ -253,7 +255,7 @@ public static void memberDoAccessCheck(ObjectKlass accessingKlass, Klass resolve
253255
* <li>R is private and is declared in D.
254256
* </ul>
255257
*/
256-
static boolean memberCheckAccess(ObjectKlass accessingKlass, Klass resolvedKlass, Member<? extends Descriptor> member) {
258+
static boolean memberCheckAccess(Klass accessingKlass, Klass resolvedKlass, Member<? extends Descriptor> member) {
257259
if (member.isPublic()) {
258260
return true;
259261
}
@@ -354,10 +356,12 @@ public static Resolvable.ResolvedConstant resolveInterfaceMethodRefConstant(Inte
354356
METHODREF_RESOLVE_COUNT.inc();
355357

356358
Klass holderInterface = getResolvedHolderKlass(thiz, pool, accessingKlass);
359+
EspressoContext context = pool.getContext();
360+
LinkResolver<EspressoContext, Klass, Method, Field> resolver = context.getLinkResolver();
357361
Symbol<Name> name = thiz.getName(pool);
358362
Symbol<Signature> signature = thiz.getSignature(pool);
359363

360-
Method method = LinkResolver.resolveMethodSymbol(pool.getContext().getMeta(), accessingKlass, name, signature, holderInterface, true, true, true);
364+
Method method = resolver.resolveMethodSymbol(context, accessingKlass, name, signature, holderInterface, true, true, true);
361365

362366
return new ResolvedInterfaceMethodRefConstant(method);
363367
}
@@ -472,17 +476,18 @@ public static Resolvable.ResolvedConstant resolveInterfaceMethodRefConstant(Inte
472476
public static Resolvable.ResolvedConstant resolveClassMethodRefConstant(ClassMethodRefConstant.Indexes thiz, RuntimeConstantPool pool, @SuppressWarnings("unused") int thisIndex,
473477
ObjectKlass accessingKlass) {
474478
METHODREF_RESOLVE_COUNT.inc();
479+
475480
EspressoContext context = pool.getContext();
476-
Meta meta = context.getMeta();
481+
LinkResolver<EspressoContext, Klass, Method, Field> resolver = context.getLinkResolver();
477482

478483
Klass holderKlass = getResolvedHolderKlass(thiz, pool, accessingKlass);
479484
Symbol<Name> name = thiz.getName(pool);
480485
Symbol<Signature> signature = thiz.getSignature(pool);
481486

482-
Method method = LinkResolver.resolveMethodSymbol(meta, accessingKlass, name, signature, holderKlass, false, true, true);
487+
Method method = resolver.resolveMethodSymbol(context, accessingKlass, name, signature, holderKlass, false, true, true);
483488

484489
if (method.isInvokeIntrinsic()) {
485-
MHInvokeGenericNode.MethodHandleInvoker invoker = MHInvokeGenericNode.linkMethod(meta.getLanguage(), meta, accessingKlass, method, name, signature);
490+
MHInvokeGenericNode.MethodHandleInvoker invoker = MHInvokeGenericNode.linkMethod(context.getMeta().getLanguage(), context.getMeta(), accessingKlass, method, name, signature);
486491
return new ResolvedWithInvokerClassMethodRefConstant(method, invoker);
487492
}
488493

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Field.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.oracle.truffle.espresso.jdwp.api.TagConstants;
4242
import com.oracle.truffle.espresso.meta.EspressoError;
4343
import com.oracle.truffle.espresso.meta.Meta;
44+
import com.oracle.truffle.espresso.resolver.meta.FieldType;
4445
import com.oracle.truffle.espresso.runtime.EspressoException;
4546
import com.oracle.truffle.espresso.runtime.staticobject.FieldStorageObject;
4647
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
@@ -74,7 +75,7 @@
7475
* value (this could be either an Original Field or a Redefine Added Field) a Delegation field is
7576
* assigned the underlying field as a Compatible Field.
7677
*/
77-
public class Field extends Member<Type> implements FieldRef {
78+
public class Field extends Member<Type> implements FieldRef, FieldType<Klass, Method, Field> {
7879

7980
public static final Field[] EMPTY_ARRAY = new Field[0];
8081

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Klass.java

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@
8282
import com.oracle.truffle.espresso.meta.InteropKlassesDispatch;
8383
import com.oracle.truffle.espresso.meta.Meta;
8484
import com.oracle.truffle.espresso.meta.MetaUtil;
85-
import com.oracle.truffle.espresso.meta.ModifiersProvider;
8685
import com.oracle.truffle.espresso.nodes.interop.LookupDeclaredMethod;
8786
import com.oracle.truffle.espresso.nodes.interop.LookupDeclaredMethodNodeGen;
8887
import com.oracle.truffle.espresso.nodes.interop.LookupFieldNode;
@@ -91,6 +90,7 @@
9190
import com.oracle.truffle.espresso.nodes.interop.ToEspressoNodeFactory;
9291
import com.oracle.truffle.espresso.nodes.interop.ToPrimitive;
9392
import com.oracle.truffle.espresso.nodes.interop.ToPrimitiveFactory;
93+
import com.oracle.truffle.espresso.resolver.meta.ClassType;
9494
import com.oracle.truffle.espresso.runtime.EspressoContext;
9595
import com.oracle.truffle.espresso.runtime.EspressoException;
9696
import com.oracle.truffle.espresso.runtime.EspressoFunction;
@@ -107,7 +107,7 @@
107107
import com.oracle.truffle.espresso.vm.VM;
108108

109109
@ExportLibrary(InteropLibrary.class)
110-
public abstract class Klass extends ContextAccessImpl implements ModifiersProvider, KlassRef, TruffleObject, EspressoType {
110+
public abstract class Klass extends ContextAccessImpl implements KlassRef, TruffleObject, EspressoType, ClassType<Klass, Method, Field> {
111111

112112
// region Interop
113113

@@ -886,7 +886,7 @@ public final boolean isArray() {
886886
public final boolean isInterface() {
887887
// conflict between ModifiersProvider and KlassRef interfaces,
888888
// so chose the default implementation in ModifiersProvider.
889-
return ModifiersProvider.super.isInterface();
889+
return ClassType.super.isInterface();
890890
}
891891

892892
/**
@@ -1042,6 +1042,20 @@ public final boolean isPrimitive() {
10421042
return this instanceof PrimitiveKlass;
10431043
}
10441044

1045+
public static ObjectKlass asAccessingObjectKlass(Klass k) {
1046+
if (k == null) {
1047+
return null;
1048+
}
1049+
if (k.isPrimitive()) {
1050+
return null;
1051+
}
1052+
if (k.isArray()) {
1053+
return asAccessingObjectKlass(k.getElementalType());
1054+
}
1055+
assert k instanceof ObjectKlass;
1056+
return (ObjectKlass) k;
1057+
}
1058+
10451059
/*
10461060
* The setting of the final bit for types is a bit confusing since arrays are marked as final.
10471061
* This method provides a semantically equivalent test that appropriate for types.
@@ -1057,7 +1071,7 @@ public final boolean isFinalFlagSet() {
10571071
* never overriden default interface methods. We cirumvent this CHA limitation here by using
10581072
* an invokespecial, which is inlinable.
10591073
*/
1060-
return ModifiersProvider.super.isFinalFlagSet() /* || isLeafAssumption() */;
1074+
return ClassType.super.isFinalFlagSet() /* || isLeafAssumption() */;
10611075
}
10621076

10631077
/**
@@ -1568,6 +1582,11 @@ public final Method lookupMethod(Symbol<Name> methodName, Symbol<Signature> sign
15681582
return lookupMethod(methodName, signature, LookupMode.ALL);
15691583
}
15701584

1585+
@Override
1586+
public Method lookupInstanceMethod(Symbol<Name> name, Symbol<Signature> signature) {
1587+
return lookupMethod(name, signature, LookupMode.INSTANCE_ONLY);
1588+
}
1589+
15711590
public final Method vtableLookup(int vtableIndex) {
15721591
if (this instanceof ObjectKlass) {
15731592
return ((ObjectKlass) this).vtableLookupImpl(vtableIndex);
@@ -1792,7 +1811,7 @@ public int getStatus() {
17921811
}
17931812

17941813
@Override
1795-
public KlassRef getSuperClass() {
1814+
public Klass getSuperClass() {
17961815
return getSuperKlass();
17971816
}
17981817

@@ -1873,4 +1892,19 @@ public Assumption getRedefineAssumption() {
18731892
}
18741893

18751894
// endregion jdwp-specific
1895+
1896+
// ClassType impl
1897+
1898+
@Override
1899+
public String getJavaName() {
1900+
return getExternalName();
1901+
}
1902+
1903+
@Override
1904+
public Method lookupInterfaceMethod(Symbol<Name> name, Symbol<Signature> signature) {
1905+
if (this instanceof ObjectKlass) {
1906+
return ((ObjectKlass) this).resolveInterfaceMethod(name, signature);
1907+
}
1908+
return null;
1909+
}
18761910
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Member.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,15 @@
2727
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name;
2828
import com.oracle.truffle.espresso.meta.ModifiersProvider;
2929

30-
public abstract class Member<T extends Descriptor> implements ModifiersProvider {
30+
public abstract class Member<T extends Descriptor> implements ModifiersProvider,
31+
com.oracle.truffle.espresso.resolver.meta.Member<Klass, Method, Field> {
3132

3233
public abstract Symbol<Name> getName();
3334

3435
public abstract ObjectKlass getDeclaringKlass();
36+
37+
@Override
38+
public final ObjectKlass getDeclaringClass() {
39+
return getDeclaringKlass();
40+
}
3541
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@
116116
import com.oracle.truffle.espresso.nodes.interop.AbstractLookupNode;
117117
import com.oracle.truffle.espresso.nodes.methodhandle.MHInvokeGenericNode.MethodHandleInvoker;
118118
import com.oracle.truffle.espresso.nodes.methodhandle.MethodHandleIntrinsicNode;
119+
import com.oracle.truffle.espresso.resolver.ResolvedCall;
120+
import com.oracle.truffle.espresso.resolver.meta.MethodType;
119121
import com.oracle.truffle.espresso.runtime.EspressoContext;
120122
import com.oracle.truffle.espresso.runtime.EspressoThreadLocalState;
121123
import com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics;
@@ -124,7 +126,8 @@
124126
import com.oracle.truffle.espresso.vm.InterpreterToVM;
125127
import com.oracle.truffle.espresso.vm.VM.EspressoStackElement;
126128

127-
public final class Method extends Member<Signature> implements TruffleObject, ContextAccess {
129+
public final class Method extends Member<Signature> implements TruffleObject, ContextAccess,
130+
MethodType<Klass, Method, Field> {
128131

129132
public static final Method[] EMPTY_ARRAY = new Method[0];
130133
public static final MethodVersion[] EMPTY_VERSION_ARRAY = new MethodVersion[0];
@@ -525,6 +528,19 @@ public Object invokeDirect(Object... args) {
525528
}
526529
}
527530

531+
public static Object call(ResolvedCall<Klass, Method, Field> resolved, Object... args) {
532+
return switch (resolved.getCallKind()) {
533+
case STATIC ->
534+
resolved.getResolvedMethod().invokeDirectStatic(args);
535+
case DIRECT ->
536+
resolved.getResolvedMethod().invokeDirect(args);
537+
case VTABLE_LOOKUP ->
538+
resolved.getResolvedMethod().invokeDirectVirtual(args);
539+
case ITABLE_LOOKUP ->
540+
resolved.getResolvedMethod().invokeDirectInterface(args);
541+
};
542+
}
543+
528544
@TruffleBoundary
529545
public Object invokeDirectStatic(Object... args) {
530546
EspressoThreadLocalState tls = getLanguage().getThreadLocalState();

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/BytecodeNode.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,6 @@
379379
import com.oracle.truffle.espresso.resolver.CallKind;
380380
import com.oracle.truffle.espresso.resolver.CallSiteType;
381381
import com.oracle.truffle.espresso.resolver.FieldAccessType;
382-
import com.oracle.truffle.espresso.resolver.LinkResolver;
383382
import com.oracle.truffle.espresso.resolver.ResolvedCall;
384383
import com.oracle.truffle.espresso.runtime.EspressoContext;
385384
import com.oracle.truffle.espresso.runtime.EspressoException;
@@ -2412,7 +2411,8 @@ private int quickenArrayStore(final VirtualFrame frame, int top, int curBCI, int
24122411
private InvokeQuickNode dispatchQuickened(int top, int curBCI, char cpi, int opcode, int statementIndex, Method resolutionSeed, boolean allowBytecodeInlining) {
24132412

24142413
Klass symbolicRef = Resolution.getResolvedHolderKlass((MethodRefConstant.Indexes) getConstantPool().methodAt(cpi), getConstantPool(), getDeclaringKlass());
2415-
ResolvedCall resolvedCall = LinkResolver.resolveCallSite(getMeta(), getDeclaringKlass(), resolutionSeed, CallSiteType.fromOpCode(opcode), symbolicRef);
2414+
ResolvedCall<Klass, Method, Field> resolvedCall = getContext().getLinkResolver().resolveCallSite(getContext(),
2415+
getDeclaringKlass(), resolutionSeed, CallSiteType.fromOpCode(opcode), symbolicRef);
24162416

24172417
Method resolved = resolvedCall.getResolvedMethod();
24182418
CallKind callKind = resolvedCall.getCallKind();
@@ -2706,7 +2706,7 @@ private int putField(VirtualFrame frame, int top, Field field, int curBCI, int o
27062706
CompilerAsserts.partialEvaluationConstant(field);
27072707
CompilerAsserts.partialEvaluationConstant(mode);
27082708

2709-
LinkResolver.resolveFieldAccess(getMeta(), getDeclaringKlass(), getMethod(), field, mode);
2709+
getContext().getLinkResolver().resolveFieldAccess(getContext(), getDeclaringKlass(), getMethod(), field, mode);
27102710

27112711
byte typeHeader = field.getType().byteAt(0);
27122712
int slotCount = (typeHeader == 'J' || typeHeader == 'D') ? 2 : 1;
@@ -2819,7 +2819,7 @@ private int getField(VirtualFrame frame, int top, Field field, int curBCI, int o
28192819

28202820
CompilerAsserts.partialEvaluationConstant(field);
28212821

2822-
LinkResolver.resolveFieldAccess(getMeta(), getDeclaringKlass(), getMethod(), field, mode);
2822+
getContext().getLinkResolver().resolveFieldAccess(getContext(), getDeclaringKlass(), getMethod(), field, mode);
28232823

28242824
int slot = top - 1;
28252825
StaticObject receiver;

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/inline/ConditionalInlinedMethodNode.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
import com.oracle.truffle.api.CompilerDirectives;
2727
import com.oracle.truffle.api.frame.VirtualFrame;
28+
import com.oracle.truffle.espresso.impl.Field;
29+
import com.oracle.truffle.espresso.impl.Klass;
2830
import com.oracle.truffle.espresso.impl.Method;
2931
import com.oracle.truffle.espresso.meta.EspressoError;
3032
import com.oracle.truffle.espresso.nodes.quick.invoke.InvokeQuickNode;
@@ -46,7 +48,7 @@ public interface Recipes {
4648
@Child protected InvokeQuickNode fallbackNode;
4749
private final InlinedMethodPredicate condition;
4850

49-
public ConditionalInlinedMethodNode(ResolvedCall resolvedCall, int top, int opcode, int callerBCI, int statementIndex, Recipes recipes, InlinedMethodPredicate condition) {
51+
public ConditionalInlinedMethodNode(ResolvedCall<Klass, Method, Field> resolvedCall, int top, int opcode, int callerBCI, int statementIndex, Recipes recipes, InlinedMethodPredicate condition) {
5052
super(resolvedCall.getResolvedMethod().getMethodVersion(), top, opcode, callerBCI, statementIndex, null);
5153
this.fallbackNode = getFallback(resolvedCall, top, callerBCI);
5254
this.condition = condition;
@@ -79,7 +81,7 @@ public static InlinedMethodNode getDefinitiveNode(Recipes recipes,
7981
return replacement;
8082
}
8183

82-
static InvokeQuickNode getFallback(ResolvedCall resolvedCall, int top, int callerBCI) {
84+
static InvokeQuickNode getFallback(ResolvedCall<Klass, Method, Field> resolvedCall, int top, int callerBCI) {
8385
// @formatter:off
8486
switch (resolvedCall.getCallKind()) {
8587
case STATIC : return new InvokeStaticQuickNode(resolvedCall.getResolvedMethod(), top, callerBCI);

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/inline/GuardedConditionalInlinedMethodNode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
import com.oracle.truffle.api.CompilerDirectives;
2929
import com.oracle.truffle.api.frame.VirtualFrame;
30+
import com.oracle.truffle.espresso.impl.Field;
31+
import com.oracle.truffle.espresso.impl.Klass;
3032
import com.oracle.truffle.espresso.impl.Method;
3133
import com.oracle.truffle.espresso.nodes.quick.invoke.InvokeQuickNode;
3234
import com.oracle.truffle.espresso.resolver.ResolvedCall;
@@ -38,7 +40,7 @@ public final class GuardedConditionalInlinedMethodNode extends InlinedMethodNode
3840
private final InlinedMethodPredicate condition;
3941
private final InlinedMethodPredicate guard;
4042

41-
public GuardedConditionalInlinedMethodNode(ResolvedCall resolvedCall, int top, int opcode, int callerBCI, int statementIndex,
43+
public GuardedConditionalInlinedMethodNode(ResolvedCall<Klass, Method, Field> resolvedCall, int top, int opcode, int callerBCI, int statementIndex,
4244
ConditionalInlinedMethodNode.Recipes recipes,
4345
InlinedMethodPredicate condition, InlinedMethodPredicate guard) {
4446
super(resolvedCall.getResolvedMethod().getMethodVersion(), top, opcode, callerBCI, statementIndex, null);

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/nodes/quick/invoke/inline/InlinedMethodNode.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.oracle.truffle.api.CompilerDirectives;
2929
import com.oracle.truffle.api.frame.VirtualFrame;
3030
import com.oracle.truffle.api.source.SourceSection;
31+
import com.oracle.truffle.espresso.impl.Field;
32+
import com.oracle.truffle.espresso.impl.Klass;
3133
import com.oracle.truffle.espresso.impl.Method;
3234
import com.oracle.truffle.espresso.impl.ObjectKlass;
3335
import com.oracle.truffle.espresso.nodes.BytecodeNode;
@@ -108,7 +110,7 @@ public SourceSection getSourceSection() {
108110

109111
@Child BodyNode body;
110112

111-
public static InlinedMethodNode createFor(ResolvedCall resolvedCall, int top, int opcode, int curBCI, int statementIndex) {
113+
public static InlinedMethodNode createFor(ResolvedCall<Klass, Method, Field> resolvedCall, int top, int opcode, int curBCI, int statementIndex) {
112114
if (!isInlineCandidate(resolvedCall)) {
113115
return null;
114116
}
@@ -190,7 +192,7 @@ public final BaseQuickNode revertToGeneric(BytecodeNode parent) {
190192
return parent.generifyInlinedMethodNode(top, opcode, getCallerBCI(), statementIndex, method.getMethod());
191193
}
192194

193-
public static boolean isInlineCandidate(ResolvedCall resolvedCall) {
195+
public static boolean isInlineCandidate(ResolvedCall<Klass, Method, Field> resolvedCall) {
194196
Method resolutionSeed = resolvedCall.getResolvedMethod();
195197
if (resolutionSeed.isSynchronized()) {
196198
return false;
@@ -209,7 +211,7 @@ public static boolean isInlineCandidate(ResolvedCall resolvedCall) {
209211
return false;
210212
}
211213

212-
public static boolean isUnconditionalInlineCandidate(ResolvedCall resolvedCall) {
214+
public static boolean isUnconditionalInlineCandidate(ResolvedCall<Klass, Method, Field> resolvedCall) {
213215
return resolvedCall.getCallKind().isDirectCall();
214216
}
215217
}

0 commit comments

Comments
 (0)