Skip to content

Commit 235efc1

Browse files
committed
[GR-59347] Espresso: Implement Field resolution in LinkResolver.
PullRequest: graal/19276
2 parents 88bc81e + af0350e commit 235efc1

File tree

6 files changed

+322
-272
lines changed

6 files changed

+322
-272
lines changed

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

Lines changed: 34 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,15 @@
2222
*/
2323
package com.oracle.truffle.espresso.constantpool;
2424

25+
import java.util.logging.Level;
26+
2527
import com.oracle.truffle.api.Assumption;
2628
import com.oracle.truffle.api.CompilerAsserts;
2729
import com.oracle.truffle.api.CompilerDirectives;
2830
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
2931
import com.oracle.truffle.espresso.EspressoLanguage;
3032
import com.oracle.truffle.espresso.EspressoOptions;
31-
import com.oracle.truffle.espresso.classfile.descriptors.Signatures;
32-
import com.oracle.truffle.espresso.classfile.descriptors.Symbol;
33-
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Descriptor;
34-
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name;
35-
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature;
36-
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type;
37-
import com.oracle.truffle.espresso.impl.ClassRegistry;
38-
import com.oracle.truffle.espresso.impl.Field;
39-
import com.oracle.truffle.espresso.impl.Klass;
40-
import com.oracle.truffle.espresso.impl.Member;
41-
import com.oracle.truffle.espresso.impl.Method;
42-
import com.oracle.truffle.espresso.impl.ObjectKlass;
43-
import com.oracle.truffle.espresso.meta.Meta;
44-
import com.oracle.truffle.espresso.nodes.methodhandle.MHInvokeGenericNode;
45-
import com.oracle.truffle.espresso.nodes.methodhandle.MHLinkToNode;
4633
import com.oracle.truffle.espresso.classfile.ConstantPool.Tag;
47-
import com.oracle.truffle.espresso.meta.EspressoError;
4834
import com.oracle.truffle.espresso.classfile.attributes.BootstrapMethodsAttribute;
4935
import com.oracle.truffle.espresso.classfile.constantpool.ClassConstant;
5036
import com.oracle.truffle.espresso.classfile.constantpool.ClassMethodRefConstant;
@@ -58,16 +44,30 @@
5844
import com.oracle.truffle.espresso.classfile.constantpool.MethodTypeConstant;
5945
import com.oracle.truffle.espresso.classfile.constantpool.Resolvable;
6046
import com.oracle.truffle.espresso.classfile.constantpool.StringConstant;
47+
import com.oracle.truffle.espresso.classfile.descriptors.Signatures;
48+
import com.oracle.truffle.espresso.classfile.descriptors.Symbol;
49+
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Descriptor;
50+
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Name;
51+
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature;
52+
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type;
6153
import com.oracle.truffle.espresso.classfile.perf.DebugCounter;
54+
import com.oracle.truffle.espresso.impl.ClassRegistry;
55+
import com.oracle.truffle.espresso.impl.Field;
56+
import com.oracle.truffle.espresso.impl.Klass;
57+
import com.oracle.truffle.espresso.impl.Member;
58+
import com.oracle.truffle.espresso.impl.Method;
59+
import com.oracle.truffle.espresso.impl.ObjectKlass;
60+
import com.oracle.truffle.espresso.meta.EspressoError;
61+
import com.oracle.truffle.espresso.meta.Meta;
62+
import com.oracle.truffle.espresso.nodes.methodhandle.MHInvokeGenericNode;
63+
import com.oracle.truffle.espresso.nodes.methodhandle.MHLinkToNode;
6264
import com.oracle.truffle.espresso.redefinition.ClassRedefinition;
6365
import com.oracle.truffle.espresso.resolver.LinkResolver;
6466
import com.oracle.truffle.espresso.runtime.EspressoContext;
6567
import com.oracle.truffle.espresso.runtime.EspressoException;
6668
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
6769
import com.oracle.truffle.espresso.substitutions.JavaType;
6870

69-
import java.util.logging.Level;
70-
7171
public final class Resolution {
7272
static final DebugCounter CLASS_RESOLVE_COUNT = DebugCounter.create("ClassConstant.resolve calls");
7373
static final DebugCounter FIELDREF_RESOLVE_COUNT = DebugCounter.create("FieldRef.resolve calls");
@@ -195,87 +195,32 @@ public static ResolvedClassConstant resolveClassConstant(ClassConstant.WithStrin
195195
}
196196
}
197197

198-
/**
199-
* <h3>5.4.3.2. Field Resolution</h3>
200-
*
201-
* To resolve an unresolved symbolic reference from D to a field in a class or interface C, the
202-
* symbolic reference to C given by the field reference must first be resolved (&sect;5.4.3.1).
203-
* Therefore, any exception that can be thrown as a result of failure of resolution of a class
204-
* or interface reference can be thrown as a result of failure of field resolution. If the
205-
* reference to C can be successfully resolved, an exception relating to the failure of
206-
* resolution of the field reference itself can be thrown.
207-
*
208-
* When resolving a field reference, field resolution first attempts to look up the referenced
209-
* field in C and its superclasses:
210-
* <ol>
211-
* <li>If C declares a field with the name and descriptor specified by the field reference,
212-
* field lookup succeeds. The declared field is the result of the field lookup.
213-
* <li>Otherwise, field lookup is applied recursively to the direct superinterfaces of the
214-
* specified class or interface C.
215-
* <li>Otherwise, if C has a superclass S, field lookup is applied recursively to S.
216-
* <li>Otherwise, field lookup fails.
217-
* </ol>
218-
*
219-
* Then:
220-
* <ul>
221-
* <li>If field lookup fails, field resolution throws a NoSuchFieldError.
222-
* <li>Otherwise, if field lookup succeeds but the referenced field is not accessible
223-
* (&sect;5.4.4) to D, field resolution throws an IllegalAccessError.
224-
* <li>Otherwise, let < E, L1 > be the class or interface in which the referenced field is
225-
* actually declared and let L2 be the defining loader of D.
226-
* <li>Given that the type of the referenced field is Tf, let T be Tf if Tf is not an array
227-
* type, and let T be the element type (&sect;2.4) of Tf otherwise.
228-
* <li>The Java Virtual Machine must impose the loading constraint that TL1 = TL2 (&sect;5.3.4).
229-
* </ul>
230-
*/
231-
private static Field lookupField(Klass seed, Symbol<Name> name, Symbol<Type> type) {
232-
Field f = seed.lookupDeclaredField(name, type);
233-
if (f != null) {
234-
return f;
235-
}
236-
for (Klass i : seed.getSuperInterfaces()) {
237-
f = lookupField(i, name, type);
238-
if (f != null) {
239-
return f;
240-
}
241-
}
242-
if (seed.getSuperKlass() != null) {
243-
return lookupField(seed.getSuperKlass(), name, type);
244-
}
245-
return null;
246-
}
247-
248198
public static Resolvable.ResolvedConstant resolveFieldRefConstant(FieldRefConstant.Indexes thiz, RuntimeConstantPool pool, @SuppressWarnings("unused") int thisIndex, ObjectKlass accessingKlass) {
249199
FIELDREF_RESOLVE_COUNT.inc();
250200
Klass holderKlass = getResolvedHolderKlass(thiz, pool, accessingKlass);
251201
Symbol<Name> name = thiz.getName(pool);
252202
Symbol<Type> type = thiz.getType(pool);
253203

254-
Field field = lookupField(holderKlass, name, type);
255-
if (field == null) {
256-
ClassRedefinition classRedefinition = pool.getContext().getClassRedefinition();
257-
if (classRedefinition != null) {
258-
// could be due to ongoing redefinition
259-
classRedefinition.check();
260-
field = lookupField(holderKlass, name, type);
261-
}
262-
if (field == null) {
263-
Meta meta = pool.getContext().getMeta();
264-
EspressoException failure = EspressoException.wrap(Meta.initExceptionWithMessage(meta.java_lang_NoSuchFieldError, name.toString()), meta);
265-
Assumption missingFieldAssumption;
204+
Meta meta = pool.getContext().getMeta();
205+
Field field;
206+
ClassRedefinition classRedefinition = null;
207+
try {
208+
try {
209+
field = LinkResolver.resolveFieldSymbol(meta, accessingKlass, name, type, holderKlass, true, true);
210+
} catch (EspressoException e) {
211+
classRedefinition = pool.getContext().getClassRedefinition();
266212
if (classRedefinition != null) {
267-
missingFieldAssumption = classRedefinition.getMissingFieldAssumption();
213+
// could be due to ongoing redefinition
214+
classRedefinition.check();
215+
field = LinkResolver.resolveFieldSymbol(meta, accessingKlass, name, type, holderKlass, true, true);
268216
} else {
269-
missingFieldAssumption = Assumption.ALWAYS_VALID;
217+
throw e;
270218
}
271-
return new MissingFieldRefConstant(failure, missingFieldAssumption);
272219
}
220+
} catch (EspressoException e) {
221+
return new MissingFieldRefConstant(e, classRedefinition == null ? Assumption.ALWAYS_VALID : classRedefinition.getMissingFieldAssumption());
273222
}
274223

275-
memberDoAccessCheck(accessingKlass, holderKlass, field, pool.getContext().getMeta());
276-
277-
field.checkLoadingConstraints(accessingKlass.getDefiningClassLoader(), field.getDeclaringKlass().getDefiningClassLoader());
278-
279224
return new ResolvedFieldRefConstant(field);
280225
}
281226

@@ -411,7 +356,7 @@ public static Resolvable.ResolvedConstant resolveInterfaceMethodRefConstant(Inte
411356
Symbol<Name> name = thiz.getName(pool);
412357
Symbol<Signature> signature = thiz.getSignature(pool);
413358

414-
Method method = LinkResolver.resolveSymbol(pool.getContext().getMeta(), accessingKlass, name, signature, holderInterface, true, true, true);
359+
Method method = LinkResolver.resolveMethodSymbol(pool.getContext().getMeta(), accessingKlass, name, signature, holderInterface, true, true, true);
415360

416361
return new ResolvedInterfaceMethodRefConstant(method);
417362
}
@@ -533,7 +478,7 @@ public static Resolvable.ResolvedConstant resolveClassMethodRefConstant(ClassMet
533478
Symbol<Name> name = thiz.getName(pool);
534479
Symbol<Signature> signature = thiz.getSignature(pool);
535480

536-
Method method = LinkResolver.resolveSymbol(meta, accessingKlass, name, signature, holderKlass, false, true, true);
481+
Method method = LinkResolver.resolveMethodSymbol(meta, accessingKlass, name, signature, holderKlass, false, true, true);
537482

538483
if (method.isInvokeIntrinsic()) {
539484
MHInvokeGenericNode.MethodHandleInvoker invoker = MHInvokeGenericNode.linkMethod(meta.getLanguage(), meta, accessingKlass, method, name, signature);

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/jni/JniEnv.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
import com.oracle.truffle.api.interop.UnsupportedMessageException;
5151
import com.oracle.truffle.api.interop.UnsupportedTypeException;
5252
import com.oracle.truffle.espresso.EspressoLanguage;
53-
import com.oracle.truffle.espresso.ffi.NativeAccess;
53+
import com.oracle.truffle.espresso.classfile.JavaKind;
5454
import com.oracle.truffle.espresso.classfile.descriptors.ByteSequence;
5555
import com.oracle.truffle.espresso.classfile.descriptors.ModifiedUtf8;
5656
import com.oracle.truffle.espresso.classfile.descriptors.Signatures;
@@ -59,6 +59,7 @@
5959
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Signature;
6060
import com.oracle.truffle.espresso.classfile.descriptors.Symbol.Type;
6161
import com.oracle.truffle.espresso.classfile.descriptors.Validation;
62+
import com.oracle.truffle.espresso.ffi.NativeAccess;
6263
import com.oracle.truffle.espresso.ffi.NativeSignature;
6364
import com.oracle.truffle.espresso.ffi.NativeType;
6465
import com.oracle.truffle.espresso.ffi.Pointer;
@@ -70,7 +71,6 @@
7071
import com.oracle.truffle.espresso.impl.Method;
7172
import com.oracle.truffle.espresso.impl.ObjectKlass;
7273
import com.oracle.truffle.espresso.meta.EspressoError;
73-
import com.oracle.truffle.espresso.classfile.JavaKind;
7474
import com.oracle.truffle.espresso.meta.Meta;
7575
import com.oracle.truffle.espresso.nodes.EspressoRootNode;
7676
import com.oracle.truffle.espresso.nodes.bytecodes.ArrayLength;
@@ -446,7 +446,7 @@ private WeakHandles<Method> methodIds() {
446446
if (fieldType != null) {
447447
// Lookup only if name and type are known symbols.
448448
klass.safeInitialize();
449-
field = klass.lookupField(fieldName, fieldType);
449+
field = klass.lookupField(fieldName, fieldType, Klass.LookupMode.INSTANCE_ONLY);
450450
assert field == null || field.getType().equals(fieldType);
451451
}
452452
}

0 commit comments

Comments
 (0)