package org.graalvm.compiler.nodes;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.CallTargetNode.InvokeKind;
import org.graalvm.compiler.nodes.java.MethodCallTargetNode;
import org.graalvm.compiler.nodes.memory.SingleMemoryKill;
import org.graalvm.compiler.nodes.spi.Lowerable;
import org.graalvm.compiler.nodes.type.StampTool;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
public interface Invoke extends StateSplit, Lowerable, SingleMemoryKill, DeoptimizingNode.DeoptDuring, FixedNodeInterface, Invokable {
enum InlineControl {
Normal(true, true),
BytecodesOnly(true, false),
Never(false, false);
private final boolean allowInlining;
private final boolean allowSubstitution;
InlineControl(boolean allowInlining, boolean allowSubstitution) {
this.allowInlining = allowInlining;
this.allowSubstitution = allowSubstitution;
}
public boolean allowInlining() {
return allowInlining;
}
public boolean allowSubstitution() {
return allowSubstitution;
}
}
FixedNode next();
void setNext(FixedNode x);
CallTargetNode callTarget();
Node predecessor();
ValueNode classInit();
void setClassInit(ValueNode node);
InlineControl getInlineControl();
void setInlineControl(InlineControl control);
default boolean useForInlining() {
return getInlineControl().allowInlining();
}
default void setUseForInlining(boolean useForInlining) {
setInlineControl(useForInlining ? Invoke.InlineControl.Normal : Invoke.InlineControl.Never);
}
boolean isPolymorphic();
void setPolymorphic(boolean value);
@Override
default ResolvedJavaMethod getTargetMethod() {
return callTarget() != null ? callTarget().targetMethod() : null;
}
@Override
default ResolvedJavaMethod getContextMethod() {
FrameState state = stateAfter();
if (state == null) {
state = stateDuring();
}
return state.getMethod();
}
default ResolvedJavaType getContextType() {
ResolvedJavaMethod contextMethod = getContextMethod();
if (contextMethod == null) {
return null;
}
return contextMethod.getDeclaringClass();
}
@Override
default void computeStateDuring(FrameState stateAfter) {
FrameState newStateDuring = stateAfter.duplicateModifiedDuringCall(bci(), asNode().getStackKind());
setStateDuring(newStateDuring);
}
default ValueNode getReceiver() {
assert getInvokeKind().hasReceiver();
return callTarget().arguments().get(0);
}
default ResolvedJavaType getReceiverType() {
ResolvedJavaType receiverType = StampTool.typeOrNull(getReceiver());
if (receiverType == null) {
receiverType = ((MethodCallTargetNode) callTarget()).targetMethod().getDeclaringClass();
}
return receiverType;
}
default InvokeKind getInvokeKind() {
return callTarget().invokeKind();
}
}