use of org.graalvm.compiler.nodes.CallTargetNode in project graal by oracle.
the class CInterfaceInvocationPlugin method replaceFunctionPointerInvoke.
private boolean replaceFunctionPointerInvoke(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, CallingConvention.Type callType) {
if (!functionPointerType.isAssignableFrom(method.getDeclaringClass())) {
throw UserError.abort(new CInterfaceError("function pointer invocation method " + method.format("%H.%n(%p)") + " must be in a type that extends " + CFunctionPointer.class.getSimpleName(), method).getMessage());
}
assert b.getInvokeKind() == InvokeKind.Interface;
JavaType[] parameterTypes = method.getSignature().toParameterTypes(null);
if (callType == SubstrateCallingConventionType.NativeCall) {
Predicate<JavaType> isValid = t -> t.getJavaKind().isPrimitive() || wordTypes.isWord(t);
UserError.guarantee(Stream.of(parameterTypes).allMatch(isValid) && isValid.test(method.getSignature().getReturnType(null)), "C function pointer invocation method must have only primitive types or word types for its parameters and return value: " + method.format("%H.%n(%p)"));
/*
* We currently do not support automatic conversions for @CEnum because it entails
* introducing additional invokes without real BCIs in a BytecodeParser context, which
* does not work too well.
*/
}
// We "discard" the receiver from the signature by pretending we are a static method
assert args.length >= 1;
ValueNode methodAddress = args[0];
ValueNode[] argsWithoutReceiver = Arrays.copyOfRange(args, 1, args.length);
assert argsWithoutReceiver.length == parameterTypes.length;
Stamp returnStamp;
if (wordTypes.isWord(b.getInvokeReturnType())) {
returnStamp = wordTypes.getWordStamp((ResolvedJavaType) b.getInvokeReturnType());
} else {
returnStamp = b.getInvokeReturnStamp(null).getTrustedStamp();
}
CallTargetNode indirectCallTargetNode = b.add(new IndirectCallTargetNode(methodAddress, argsWithoutReceiver, StampPair.createSingle(returnStamp), parameterTypes, method, callType, InvokeKind.Static));
if (callType == SubstrateCallingConventionType.JavaCall) {
b.handleReplacedInvoke(indirectCallTargetNode, b.getInvokeReturnType().getJavaKind());
} else if (callType == SubstrateCallingConventionType.NativeCall) {
// Native code cannot throw exceptions, omit exception edge
InvokeNode invokeNode = new InvokeNode(indirectCallTargetNode, b.bci());
if (pushKind(method) != JavaKind.Void) {
b.addPush(pushKind(method), invokeNode);
} else {
b.add(invokeNode);
}
} else {
throw shouldNotReachHere("Unsupported type of call: " + callType);
}
return true;
}
use of org.graalvm.compiler.nodes.CallTargetNode in project graal by oracle.
the class PEGraphDecoder method handleInvoke.
@Override
protected LoopScope handleInvoke(MethodScope s, LoopScope loopScope, InvokeData invokeData) {
PEMethodScope methodScope = (PEMethodScope) s;
/*
* Decode the call target, but do not add it to the graph yet. This avoids adding usages for
* all the arguments, which are expensive to remove again when we can inline the method.
*/
assert invokeData.invoke.callTarget() == null : "callTarget edge is ignored during decoding of Invoke";
CallTargetNode callTarget = (CallTargetNode) decodeFloatingNode(methodScope, loopScope, invokeData.callTargetOrderId);
if (callTarget instanceof MethodCallTargetNode) {
MethodCallTargetNode methodCall = (MethodCallTargetNode) callTarget;
if (methodCall.invokeKind().hasReceiver()) {
invokeData.constantReceiver = methodCall.arguments().get(0).asJavaConstant();
NodeSourcePosition invokePosition = invokeData.invoke.asNode().getNodeSourcePosition();
if (invokeData.constantReceiver != null && invokePosition != null) {
// new NodeSourcePosition(invokeData.constantReceiver,
// invokePosition.getCaller(), invokePosition.getMethod(),
// invokePosition.getBCI());
}
}
LoopScope inlineLoopScope = trySimplifyInvoke(methodScope, loopScope, invokeData, (MethodCallTargetNode) callTarget);
if (inlineLoopScope != null) {
return inlineLoopScope;
}
}
/* We know that we need an invoke, so now we can add the call target to the graph. */
graph.add(callTarget);
registerNode(loopScope, invokeData.callTargetOrderId, callTarget, false, false);
return super.handleInvoke(methodScope, loopScope, invokeData);
}
use of org.graalvm.compiler.nodes.CallTargetNode in project graal by oracle.
the class InliningUtil method inlineMacroNode.
public static FixedWithNextNode inlineMacroNode(Invoke invoke, ResolvedJavaMethod concrete, Class<? extends FixedWithNextNode> macroNodeClass) throws GraalError {
StructuredGraph graph = invoke.asNode().graph();
if (!concrete.equals(((MethodCallTargetNode) invoke.callTarget()).targetMethod())) {
assert ((MethodCallTargetNode) invoke.callTarget()).invokeKind().hasReceiver();
InliningUtil.replaceInvokeCallTarget(invoke, graph, InvokeKind.Special, concrete);
}
FixedWithNextNode macroNode = createMacroNodeInstance(macroNodeClass, invoke);
CallTargetNode callTarget = invoke.callTarget();
if (invoke instanceof InvokeNode) {
graph.replaceFixedWithFixed((InvokeNode) invoke, graph.add(macroNode));
} else {
InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
invokeWithException.killExceptionEdge();
graph.replaceSplitWithFixed(invokeWithException, graph.add(macroNode), invokeWithException.next());
}
GraphUtil.killWithUnusedFloatingInputs(callTarget);
return macroNode;
}
Aggregations