@Test public void testJoin9() { Stamp bExact = StampFactory.exact(getType(B.class)); Stamp dExact = StampFactory.exact(getType(D.class)); Stamp join = join(bExact, dExact); Assert.assertTrue(StampTool.isPointerAlwaysNull(join)); Assert.assertNull(StampTool.typeOrNull(join)); Assert.assertNull(StampTool.typeOrNull(join)); }
@Test public void testJoin7() { Stamp aExact = StampFactory.exact(getType(A.class)); Stamp e = StampFactory.declared(getType(E.class)); Stamp join = join(aExact, e); Assert.assertTrue(StampTool.isPointerAlwaysNull(join)); Assert.assertNull(StampTool.typeOrNull(join)); Assert.assertFalse(StampTool.isExactType(join)); }
@Test public void testJoin5() { Stamp dExact = StampFactory.exact(getType(D.class)); Stamp c = StampFactory.declared(getType(C.class)); Stamp join = join(c, dExact); Assert.assertTrue(StampTool.isPointerAlwaysNull(join)); Assert.assertNull(StampTool.typeOrNull(join)); Assert.assertFalse(StampTool.isExactType(join)); }
/** * For one or more `invoke` arguments, flow-sensitive information may suggest their narrowing or * simplification. In those cases, a new {@link com.oracle.graal.nodes.java.MethodCallTargetNode * MethodCallTargetNode} is prepared just for this callsite, consuming reduced arguments. * * <p>Specializing the {@link com.oracle.graal.nodes.java.MethodCallTargetNode * MethodCallTargetNode} as described above may enable two optimizations: * * <ul> * <li>devirtualization of an {@link com.oracle.graal.nodes.CallTargetNode.InvokeKind#Interface} * or {@link com.oracle.graal.nodes.CallTargetNode.InvokeKind#Virtual} callsite * (devirtualization made possible after narrowing the type of the receiver) * <li>(future work) actual-argument-aware inlining, ie, to specialize callees on the types of * arguments other than the receiver (examples: multi-methods, the inlining problem, lambdas * as arguments). * </ul> * * <p>Precondition: inputs haven't been deverbosified yet. */ private void visitInvoke(Invoke invoke) { if (invoke.asNode().stamp() instanceof IllegalStamp) { return; // just to be safe } boolean isMethodCallTarget = invoke.callTarget() instanceof MethodCallTargetNode; if (!isMethodCallTarget) { return; } FlowUtil.replaceInPlace( invoke.asNode(), invoke.callTarget(), deverbosifyInputsCopyOnWrite((MethodCallTargetNode) invoke.callTarget())); MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget(); if (callTarget.invokeKind() != CallTargetNode.InvokeKind.Interface && callTarget.invokeKind() != CallTargetNode.InvokeKind.Virtual) { return; } ValueNode receiver = callTarget.receiver(); if (receiver == null) { return; } if (!FlowUtil.hasLegalObjectStamp(receiver)) { return; } Witness w = state.typeInfo(receiver); ResolvedJavaType type; ResolvedJavaType stampType = StampTool.typeOrNull(receiver); if (w == null || w.cluelessAboutType()) { // can't improve on stamp but wil try to devirtualize anyway type = stampType; } else { type = FlowUtil.tighten(w.type(), stampType); } if (type == null) { return; } ResolvedJavaMethod method = type.resolveMethod(callTarget.targetMethod(), invoke.getContextType()); if (method == null) { return; } if (method.canBeStaticallyBound() || Modifier.isFinal(type.getModifiers())) { metricMethodResolved.increment(); callTarget.setInvokeKind(CallTargetNode.InvokeKind.Special); callTarget.setTargetMethod(method); } }