Skip to content

Commit 710725a

Browse files
[GR-53546] Backport to 24.0: Adds profiling to Espresso method resolution from interop.
PullRequest: graal/17836
2 parents 5be53f2 + 1064fd0 commit 710725a

File tree

8 files changed

+523
-234
lines changed

8 files changed

+523
-234
lines changed

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

+36-44
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
import com.oracle.truffle.api.library.ExportMessage;
5858
import com.oracle.truffle.api.nodes.ExplodeLoop;
5959
import com.oracle.truffle.api.nodes.Node;
60-
import com.oracle.truffle.api.profiles.BranchProfile;
60+
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
6161
import com.oracle.truffle.api.utilities.TriState;
6262
import com.oracle.truffle.espresso.EspressoLanguage;
6363
import com.oracle.truffle.espresso.classfile.ConstantPool;
@@ -81,14 +81,10 @@
8181
import com.oracle.truffle.espresso.meta.Meta;
8282
import com.oracle.truffle.espresso.meta.MetaUtil;
8383
import com.oracle.truffle.espresso.meta.ModifiersProvider;
84-
import com.oracle.truffle.espresso.nodes.interop.InvokeEspressoNode;
85-
import com.oracle.truffle.espresso.nodes.interop.InvokeEspressoNodeGen;
8684
import com.oracle.truffle.espresso.nodes.interop.LookupDeclaredMethod;
8785
import com.oracle.truffle.espresso.nodes.interop.LookupDeclaredMethodNodeGen;
8886
import com.oracle.truffle.espresso.nodes.interop.LookupFieldNode;
8987
import com.oracle.truffle.espresso.nodes.interop.LookupFieldNodeGen;
90-
import com.oracle.truffle.espresso.nodes.interop.OverLoadedMethodSelectorNode;
91-
import com.oracle.truffle.espresso.nodes.interop.OverLoadedMethodSelectorNodeGen;
9288
import com.oracle.truffle.espresso.nodes.interop.ToEspressoNode;
9389
import com.oracle.truffle.espresso.nodes.interop.ToEspressoNodeFactory;
9490
import com.oracle.truffle.espresso.nodes.interop.ToPrimitive;
@@ -102,6 +98,8 @@
10298
import com.oracle.truffle.espresso.runtime.MethodHandleIntrinsics;
10399
import com.oracle.truffle.espresso.runtime.dispatch.staticobject.BaseInterop;
104100
import com.oracle.truffle.espresso.runtime.dispatch.staticobject.EspressoInterop;
101+
import com.oracle.truffle.espresso.runtime.dispatch.staticobject.InteropLookupAndInvoke;
102+
import com.oracle.truffle.espresso.runtime.dispatch.staticobject.InteropLookupAndInvokeFactory;
105103
import com.oracle.truffle.espresso.runtime.staticobject.StaticObject;
106104
import com.oracle.truffle.espresso.substitutions.JavaType;
107105
import com.oracle.truffle.espresso.vm.InterpreterToVM;
@@ -179,15 +177,18 @@ abstract static class ReadMember {
179177
@Specialization(guards = "language.isShared()")
180178
static Object doShared(Klass receiver, String member,
181179
@CachedLibrary("receiver") InteropLibrary lib,
180+
@Bind("$node") Node node,
181+
@Cached @Shared InlinedBranchProfile error,
182182
@Bind("getLang(lib)") @SuppressWarnings("unused") EspressoLanguage language) throws UnknownIdentifierException {
183-
return readMember(receiver, member, LookupFieldNodeGen.getUncached(), LookupDeclaredMethodNodeGen.getUncached(), BranchProfile.getUncached(), lib, language);
183+
return readMember(receiver, member, LookupFieldNodeGen.getUncached(), LookupDeclaredMethodNodeGen.getUncached(), node, error, lib, language);
184184
}
185185

186186
@Specialization
187187
static Object readMember(Klass receiver, String member,
188188
@Shared("lookupField") @Cached LookupFieldNode lookupFieldNode,
189189
@Shared("lookupMethod") @Cached LookupDeclaredMethod lookupMethod,
190-
@Shared("error") @Cached BranchProfile error,
190+
@Bind("$node") Node node,
191+
@Cached @Shared InlinedBranchProfile error,
191192
@CachedLibrary("receiver") InteropLibrary lib,
192193
@Bind("getLang(lib)") @SuppressWarnings("unused") EspressoLanguage language) throws UnknownIdentifierException {
193194
EspressoContext ctx = EspressoContext.get(lib);
@@ -229,7 +230,7 @@ static Object readMember(Klass receiver, String member,
229230
return receiver.getSuperKlass();
230231
}
231232

232-
error.enter();
233+
error.enter(node);
233234
throw UnknownIdentifierException.create(member);
234235
}
235236
}
@@ -263,24 +264,26 @@ abstract static class WriteMember {
263264
// Specialization prevents caching a node that would leak the context
264265
@Specialization(guards = "language.isShared()")
265266
static void doShared(Klass receiver, String member, Object value,
266-
@Shared("error") @Cached BranchProfile error,
267+
@Bind("$node") Node node,
268+
@Cached @Shared InlinedBranchProfile error,
267269
@CachedLibrary("receiver") @SuppressWarnings("unused") InteropLibrary lib,
268270
@Bind("getLang(lib)") @SuppressWarnings("unused") EspressoLanguage language) throws UnknownIdentifierException, UnsupportedTypeException {
269-
writeMember(receiver, member, value, LookupFieldNodeGen.getUncached(), ToEspressoNodeFactory.DynamicToEspressoNodeGen.getUncached(), error);
271+
writeMember(receiver, member, value, LookupFieldNodeGen.getUncached(), ToEspressoNodeFactory.DynamicToEspressoNodeGen.getUncached(), node, error);
270272
}
271273

272274
@Specialization
273275
static void writeMember(Klass receiver, String member, Object value,
274276
@Shared("lookupField") @Cached LookupFieldNode lookupFieldNode,
275277
@Exclusive @Cached ToEspressoNode.DynamicToEspresso toEspressoNode,
276-
@Shared("error") @Cached BranchProfile error) throws UnknownIdentifierException, UnsupportedTypeException {
278+
@Bind("$node") Node node,
279+
@Cached @Shared InlinedBranchProfile error) throws UnknownIdentifierException, UnsupportedTypeException {
277280
Field field = lookupFieldNode.execute(receiver, member, true);
278281
// Can only write to non-final fields.
279282
if (field != null && !field.isFinalFlagSet()) {
280283
Object espressoValue = toEspressoNode.execute(value, field.resolveTypeKlass());
281284
field.set(receiver.tryInitializeAndGetStatics(), espressoValue);
282285
} else {
283-
error.enter();
286+
error.enter(node);
284287
throw UnknownIdentifierException.create(member);
285288
}
286289
}
@@ -308,35 +311,27 @@ abstract static class InvokeMember {
308311
// Specialization prevents caching a node that would leak the context
309312
@Specialization(guards = "language.isShared()")
310313
static Object doShared(Klass receiver, String member, Object[] arguments,
314+
@Bind("$node") Node node,
315+
@Cached @Shared InlinedBranchProfile error,
311316
@CachedLibrary("receiver") @SuppressWarnings("unused") InteropLibrary receiverInterop,
312317
@Bind("getLang(receiverInterop)") @SuppressWarnings("unused") EspressoLanguage language) throws ArityException, UnknownIdentifierException, UnsupportedTypeException {
313-
return invokeMember(receiver, member, arguments, receiverInterop, LookupDeclaredMethodNodeGen.getUncached(), OverLoadedMethodSelectorNodeGen.getUncached(),
314-
InvokeEspressoNodeGen.getUncached(),
315-
ToEspressoNodeFactory.DynamicToEspressoNodeGen.getUncached());
318+
return invokeMember(receiver, member, arguments, node, receiverInterop, error, InteropLookupAndInvokeFactory.NonVirtualNodeGen.getUncached());
316319
}
317320

318321
@Specialization
319322
static Object invokeMember(Klass receiver, String member,
320323
Object[] arguments,
324+
@Bind("$node") Node node,
321325
@CachedLibrary("receiver") InteropLibrary receiverInterop,
322-
@Cached LookupDeclaredMethod lookupMethod,
323-
@Cached OverLoadedMethodSelectorNode overloadSelector,
324-
@Exclusive @Cached InvokeEspressoNode invoke,
325-
@Cached ToEspressoNode.DynamicToEspresso toEspressoNode)
326+
@Cached InlinedBranchProfile error,
327+
@Cached InteropLookupAndInvoke.NonVirtual lookupAndInvoke)
326328
throws ArityException, UnknownIdentifierException, UnsupportedTypeException {
327329
if (!receiverInterop.isMemberInvocable(receiver, member)) {
328330
// Not invocable, no matter the arity or argument types.
331+
error.enter(node);
329332
throw UnknownIdentifierException.create(member);
330333
}
331-
// The member (static method) may be invocable only for a certain arity and argument
332-
// types.
333-
Method[] candidates = lookupMethod.execute(receiver, member, true, true, arguments.length);
334-
if (candidates != null) {
335-
return EspressoInterop.invokeEspressoMethodHelper(null, member, arguments, overloadSelector, invoke, toEspressoNode, candidates);
336-
}
337-
// TODO(peterssen): The expected arity is not known, only that the given one is not
338-
// correct.
339-
throw ArityException.create(arguments.length + 1, -1, arguments.length);
334+
return lookupAndInvoke.execute(null, receiver, arguments, member);
340335
}
341336
}
342337

@@ -415,6 +410,7 @@ abstract static class Instantiate {
415410
@Specialization(guards = "language.isShared()")
416411
static Object doShared(Klass receiver, Object[] args,
417412
@CachedLibrary("receiver") @SuppressWarnings("unused") InteropLibrary receiverInterop,
413+
@Bind("$node") Node node,
418414
@Bind("getLang(receiverInterop)") @SuppressWarnings("unused") EspressoLanguage language) throws UnsupportedMessageException, UnsupportedTypeException, ArityException {
419415
if (receiver.isPrimitive()) {
420416
return doPrimitive(receiver, args);
@@ -426,11 +422,10 @@ static Object doShared(Klass receiver, Object[] args,
426422
return doReferenceArray(receiver, args, ToPrimitiveFactory.ToIntNodeGen.getUncached());
427423
}
428424
if (isMultidimensionalArray(receiver)) {
429-
return doMultidimensionalArray(receiver, args, ToPrimitiveFactory.ToIntNodeGen.getUncached());
425+
return doMultidimensionalArray(receiver, args, node, InlinedBranchProfile.getUncached(), ToPrimitiveFactory.ToIntNodeGen.getUncached());
430426
}
431427
if (isObjectKlass(receiver)) {
432-
return doObject(receiver, args, receiverInterop, LookupDeclaredMethodNodeGen.getUncached(), OverLoadedMethodSelectorNodeGen.getUncached(), InvokeEspressoNodeGen.getUncached(),
433-
ToEspressoNodeFactory.DynamicToEspressoNodeGen.getUncached());
428+
return doObject(receiver, args, node, InlinedBranchProfile.getUncached(), receiverInterop, InteropLookupAndInvokeFactory.NonVirtualNodeGen.getUncached());
434429
}
435430
CompilerDirectives.transferToInterpreterAndInvalidate();
436431
throw EspressoError.shouldNotReachHere();
@@ -498,10 +493,13 @@ static StaticObject doReferenceArray(Klass receiver, Object[] arguments,
498493

499494
@Specialization(guards = "isMultidimensionalArray(receiver)")
500495
static StaticObject doMultidimensionalArray(Klass receiver, Object[] arguments,
496+
@Bind("$node") Node node,
497+
@Cached InlinedBranchProfile error,
501498
@Cached ToPrimitive.ToInt toInt) throws ArityException, UnsupportedTypeException {
502499
ArrayKlass arrayKlass = (ArrayKlass) receiver;
503500
assert arrayKlass.getElementalType().getJavaKind() != JavaKind.Void;
504501
if (arrayKlass.getDimension() != arguments.length) {
502+
error.enter(node);
505503
throw ArityException.create(arrayKlass.getDimension(), arrayKlass.getDimension(), arguments.length);
506504
}
507505
EspressoContext context = EspressoContext.get(toInt);
@@ -517,24 +515,18 @@ static StaticObject doMultidimensionalArray(Klass receiver, Object[] arguments,
517515

518516
@Specialization(guards = "isObjectKlass(receiver)")
519517
static Object doObject(Klass receiver, Object[] arguments,
518+
@Bind("$node") Node node,
519+
@Cached InlinedBranchProfile error,
520520
@CachedLibrary("receiver") InteropLibrary receiverInterop,
521-
@Shared("lookupMethod") @Cached LookupDeclaredMethod lookupMethod,
522-
@Cached OverLoadedMethodSelectorNode overloadSelector,
523-
@Exclusive @Cached InvokeEspressoNode invoke,
524-
@Cached ToEspressoNode.DynamicToEspresso toEspressoNode) throws UnsupportedTypeException, ArityException, UnsupportedMessageException {
521+
@Cached InteropLookupAndInvoke.NonVirtual lookupAndInvoke) throws UnsupportedTypeException, ArityException, UnsupportedMessageException {
525522
if (!receiverInterop.isInstantiable(receiver)) {
523+
error.enter(node);
526524
throw UnsupportedMessageException.create();
527525
}
528526
ObjectKlass objectKlass = (ObjectKlass) receiver;
529-
Method[] initCandidates = lookupMethod.execute(receiver, INIT_NAME, true, false, arguments.length);
530-
if (initCandidates != null) {
531-
StaticObject instance = allocateNewInstance(EspressoContext.get(invoke), objectKlass);
532-
EspressoInterop.invokeEspressoMethodHelper(instance, INIT_NAME, arguments, overloadSelector, invoke, toEspressoNode, initCandidates);
533-
return instance;
534-
}
535-
// TODO(peterssen): We don't know the expected arity of this method, only that the given
536-
// arity is incorrect.
537-
throw ArityException.create(arguments.length + 1, -1, arguments.length);
527+
StaticObject instance = allocateNewInstance(EspressoContext.get(lookupAndInvoke), objectKlass);
528+
lookupAndInvoke.execute(instance, objectKlass, arguments, INIT_NAME);
529+
return instance;
538530
}
539531

540532
private static StaticObject allocateNewInstance(EspressoContext context, ObjectKlass objectKlass) {

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/meta/Meta.java

+7-9
Original file line numberDiff line numberDiff line change
@@ -2135,14 +2135,20 @@ public Klass resolveSymbolAndAccessCheck(Symbol<Type> type, Klass accessingKlass
21352135
return klass;
21362136
}
21372137

2138-
@TruffleBoundary
21392138
public String toHostString(StaticObject str) {
21402139
if (StaticObject.isNull(str)) {
21412140
return null;
21422141
}
21432142
return stringConversion.toHost(str, getLanguage(), this);
21442143
}
21452144

2145+
public StaticObject toGuestString(String hostString) {
2146+
if (hostString == null) {
2147+
return StaticObject.NULL;
2148+
}
2149+
return stringConversion.toGuest(hostString, this);
2150+
}
2151+
21462152
@TruffleBoundary
21472153
public static String toHostStringStatic(StaticObject str) {
21482154
if (StaticObject.isNull(str)) {
@@ -2159,14 +2165,6 @@ public StaticObject toGuestString(Symbol<?> hostString) {
21592165
return toGuestString(hostString.toString());
21602166
}
21612167

2162-
@TruffleBoundary
2163-
public StaticObject toGuestString(String hostString) {
2164-
if (hostString == null) {
2165-
return StaticObject.NULL;
2166-
}
2167-
return stringConversion.toGuest(hostString, this);
2168-
}
2169-
21702168
public static boolean isString(Object string) {
21712169
if (string instanceof StaticObject) {
21722170
StaticObject staticObject = (StaticObject) string;

0 commit comments

Comments
 (0)