Skip to content

Commit 56a6556

Browse files
committed
[GR-63375] Support boxing overloads with generic replaces.
PullRequest: graal/20364
2 parents c51dedc + 51ec8ea commit 56a6556

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

truffle/src/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/RewriteUnexpectedResultTest.java

+55
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import com.oracle.truffle.api.dsl.UnsupportedSpecializationException;
6060
import com.oracle.truffle.api.dsl.test.RewriteUnexpectedResultTestFactory.DoubleReplaceNodeGen;
6161
import com.oracle.truffle.api.dsl.test.RewriteUnexpectedResultTestFactory.InlineCacheBoxingOverloadNodeGen;
62+
import com.oracle.truffle.api.dsl.test.RewriteUnexpectedResultTestFactory.InlineCacheWithGenericBoxingOverloadNodeGen;
6263
import com.oracle.truffle.api.dsl.test.RewriteUnexpectedResultTestFactory.InlinedBoxingOverloadNodeGen;
6364
import com.oracle.truffle.api.dsl.test.RewriteUnexpectedResultTestFactory.PrimitiveOverloadNodeGen;
6465
import com.oracle.truffle.api.dsl.test.RewriteUnexpectedResultTestFactory.RewriteUnexpected3NodeGen;
@@ -370,6 +371,60 @@ public void testInlinedBoxingOverloadNode() throws UnexpectedResultException {
370371
assertThrows(UnsupportedSpecializationException.class, () -> node.executeGeneric(44));
371372
}
372373

374+
@GenerateInline(false)
375+
@SuppressWarnings("unused")
376+
abstract static class InlineCacheWithGenericBoxingOverloadNode extends BaseNode {
377+
378+
@Specialization(guards = "arg == cachedArg", limit = "3", rewriteOn = UnexpectedResultException.class)
379+
static int doIntCached(Object arg, @Cached("arg") Object cachedArg) throws UnexpectedResultException {
380+
if (cachedArg instanceof Integer i) {
381+
return 42;
382+
}
383+
throw new UnexpectedResultException(cachedArg);
384+
}
385+
386+
@Specialization(guards = "arg == cachedArg", limit = "3", replaces = {"doIntCached"})
387+
static Object doObjectCached(Object arg, @Cached("arg") Object cachedArg) {
388+
return cachedArg;
389+
}
390+
391+
@Specialization(replaces = {"doIntCached", "doObjectCached"}, rewriteOn = UnexpectedResultException.class)
392+
static int doIntGeneric(Object arg) throws UnexpectedResultException {
393+
if (arg instanceof Integer i) {
394+
return 43;
395+
}
396+
throw new UnexpectedResultException(arg);
397+
}
398+
399+
@Specialization(replaces = {"doIntGeneric", "doIntCached", "doObjectCached"})
400+
static Object doGeneric(Object arg) {
401+
return 44;
402+
}
403+
}
404+
405+
@Test
406+
public void testInlineCacheWithGenericBoxingOverloadNode() throws UnexpectedResultException {
407+
InlineCacheWithGenericBoxingOverloadNode node = InlineCacheWithGenericBoxingOverloadNodeGen.create();
408+
409+
Object o1 = 42;
410+
Object o2 = "43";
411+
Object o3 = 43;
412+
413+
assertEquals(o1, node.executeGeneric(o1));
414+
assertEquals(o2, node.executeGeneric(o2));
415+
assertEquals(o1, node.executeInt(o1));
416+
UnexpectedResultException e = assertThrows(UnexpectedResultException.class, () -> node.executeInt(o2));
417+
assertEquals(o2, e.getResult());
418+
assertEquals(o2, node.executeGeneric(o2));
419+
assertEquals(o3, node.executeInt(o3));
420+
421+
// inline cache full -> generic executeAndSpecialize
422+
assertEquals(44, node.executeGeneric(44));
423+
424+
assertEquals(43, node.executeInt(44));
425+
assertEquals(44, node.executeGeneric(44));
426+
}
427+
373428
@GenerateInline(false)
374429
@SuppressWarnings("unused")
375430
abstract static class InlinedBoxingOverloadNode extends BaseNode {

truffle/src/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java

+10
Original file line numberDiff line numberDiff line change
@@ -3023,6 +3023,16 @@ public static void removeSpecializations(NodeData node, Map<CacheExpression, Str
30233023
boolean allReplaced = true;
30243024
for (SpecializationData replacedBy : overload.getReplacedBy()) {
30253025
if (!replacedBy.getBoxingOverloads().contains(overload)) {
3026+
// not a boxing overload
3027+
3028+
if (replacedBy.getReplaces().containsAll(cur.getBoxingOverloads()) && replacedBy.getReplaces().contains(cur)) {
3029+
/*
3030+
* It is fine to use as boxing overload as the replacer replaces the
3031+
* specialization and all boxing overloads.
3032+
*/
3033+
continue;
3034+
}
3035+
30263036
allReplaced = false;
30273037
}
30283038
}

0 commit comments

Comments
 (0)