use of org.graalvm.compiler.nodes.ConstantNode in project graal by oracle.
the class BytecodeParser method guardIntrinsic.
/**
* Weaves a test of the receiver type to ensure the dispatch will select {@code targetMethod}
* and not another method that overrides it. This should only be called if there is an intrinsic
* (i.e., an {@link InvocationPlugin}) for {@code targetMethod} and the invocation is indirect.
*
* The control flow woven around the intrinsic is as follows:
*
* <pre>
* if (LoadMethod(LoadHub(receiver)) == targetMethod) {
* <intrinsic for targetMethod>
* } else {
* <virtual call to targetMethod>
* }
* </pre>
*
* The {@code else} branch is woven by {@link #afterInvocationPluginExecution}.
*
* @return {@code null} if the intrinsic cannot be used otherwise an object to be used by
* {@link #afterInvocationPluginExecution} to weave code for the non-intrinsic branch
*/
protected IntrinsicGuard guardIntrinsic(ValueNode[] args, ResolvedJavaMethod targetMethod, InvocationPluginReceiver pluginReceiver) {
ValueNode intrinsicReceiver = args[0];
ResolvedJavaType receiverType = StampTool.typeOrNull(intrinsicReceiver);
if (receiverType == null) {
// The verifier guarantees it to be at least type declaring targetMethod
receiverType = targetMethod.getDeclaringClass();
}
ResolvedJavaMethod resolvedMethod = receiverType.resolveMethod(targetMethod, method.getDeclaringClass());
if (resolvedMethod == null || resolvedMethod.equals(targetMethod)) {
assert resolvedMethod == null || targetMethod.getDeclaringClass().isAssignableFrom(resolvedMethod.getDeclaringClass());
Mark mark = graph.getMark();
FixedWithNextNode currentLastInstr = lastInstr;
ValueNode nonNullReceiver = pluginReceiver.get();
Stamp methodStamp = stampProvider.createMethodStamp();
LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
JavaTypeProfile profile = null;
if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
profile = profilingInfo.getTypeProfile(bci());
if (profile != null) {
JavaTypeProfile newProfile = adjustProfileForInvocationPlugin(profile, targetMethod);
if (newProfile != profile) {
if (newProfile.getTypes().length == 0) {
// All profiled types select the intrinsic so
// emit a fixed guard instead of an if-then-else.
lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
}
} else {
// No profiled types select the intrinsic so emit a virtual call
return null;
}
profile = newProfile;
}
}
AbstractBeginNode intrinsicBranch = graph.add(new BeginNode());
AbstractBeginNode nonIntrinsicBranch = graph.add(new BeginNode());
append(new IfNode(compare, intrinsicBranch, nonIntrinsicBranch, FAST_PATH_PROBABILITY));
lastInstr = intrinsicBranch;
return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, nonIntrinsicBranch, profile);
} else {
// Receiver selects an overriding method so emit a virtual call
return null;
}
}
use of org.graalvm.compiler.nodes.ConstantNode in project graal by oracle.
the class BytecodeParser method genConditionalForIf.
private void genConditionalForIf(BciBlock trueBlock, LogicNode condition, int oldBci, int trueBlockInt, int falseBlockInt, boolean genReturn) {
ConstantNode trueValue = graph.unique(ConstantNode.forInt(trueBlockInt));
ConstantNode falseValue = graph.unique(ConstantNode.forInt(falseBlockInt));
ValueNode conditionalNode = ConditionalNode.create(condition, trueValue, falseValue, NodeView.DEFAULT);
if (conditionalNode.graph() == null) {
conditionalNode = graph.addOrUniqueWithInputs(conditionalNode);
}
if (genReturn) {
JavaKind returnKind = method.getSignature().getReturnKind().getStackKind();
this.genReturn(conditionalNode, returnKind);
} else {
frameState.push(JavaKind.Int, conditionalNode);
appendGoto(trueBlock.getSuccessor(0));
stream.setBCI(oldBci);
}
}
use of org.graalvm.compiler.nodes.ConstantNode in project graal by oracle.
the class BytecodeParser method genJsr.
protected void genJsr(int dest) {
BciBlock successor = currentBlock.getJsrSuccessor();
assert successor.startBci == dest : successor.startBci + " != " + dest + " @" + bci();
JsrScope scope = currentBlock.getJsrScope();
int nextBci = getStream().nextBCI();
if (!successor.getJsrScope().pop().equals(scope)) {
throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
}
if (successor.getJsrScope().nextReturnAddress() != nextBci) {
throw new JsrNotSupportedBailout("unstructured control flow (internal limitation)");
}
ConstantNode nextBciNode = getJsrConstant(nextBci);
frameState.push(JavaKind.Object, nextBciNode);
appendGoto(successor);
}
use of org.graalvm.compiler.nodes.ConstantNode in project graal by oracle.
the class BytecodeParser method genRet.
protected void genRet(int localIndex) {
BciBlock successor = currentBlock.getRetSuccessor();
ValueNode local = frameState.loadLocal(localIndex, JavaKind.Object);
JsrScope scope = currentBlock.getJsrScope();
int retAddress = scope.nextReturnAddress();
ConstantNode returnBciNode = getJsrConstant(retAddress);
LogicNode guard = IntegerEqualsNode.create(constantReflection, metaAccess, options, null, local, returnBciNode, NodeView.DEFAULT);
guard = graph.addOrUniqueWithInputs(guard);
append(new FixedGuardNode(guard, JavaSubroutineMismatch, InvalidateReprofile));
if (!successor.getJsrScope().equals(scope.pop())) {
throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)");
}
appendGoto(successor);
}
use of org.graalvm.compiler.nodes.ConstantNode in project graal by oracle.
the class ReflectionGetCallerClassNode method lower.
@Override
public void lower(LoweringTool tool) {
ConstantNode callerClassNode = getCallerClassNode(tool.getMetaAccess(), tool.getConstantReflection());
if (callerClassNode != null) {
graph().replaceFixedWithFloating(this, graph().addOrUniqueWithInputs(callerClassNode));
} else {
InvokeNode invoke = createInvoke();
graph().replaceFixedWithFixed(this, invoke);
invoke.lower(tool);
}
}
Aggregations