use of jdk.vm.ci.meta.SpeculationLog.Speculation in project graal by oracle.
the class MethodHandleNode method maybeCastArgument.
/**
* Inserts a node to cast the argument at index to the given type if the given type is more
* concrete than the argument type.
*
* @param adder
* @param index of the argument to be cast
* @param type the type the argument should be cast to
*/
private static void maybeCastArgument(GraphAdder adder, ValueNode[] arguments, int index, JavaType type) {
ValueNode argument = arguments[index];
if (type instanceof ResolvedJavaType && !((ResolvedJavaType) type).isJavaLangObject()) {
Assumptions assumptions = adder.getAssumptions();
TypeReference targetType = TypeReference.create(assumptions, (ResolvedJavaType) type);
/*
* When an argument is a Word type, we can have a mismatch of primitive/object types
* here. Not inserting a PiNode is a safe fallback, and Word types need no additional
* type information anyway.
*/
if (targetType != null && !targetType.getType().isPrimitive() && !argument.getStackKind().isPrimitive()) {
ResolvedJavaType argumentType = StampTool.typeOrNull(argument.stamp(NodeView.DEFAULT));
if (argumentType == null || (argumentType.isAssignableFrom(targetType.getType()) && !argumentType.equals(targetType.getType()))) {
LogicNode inst = InstanceOfNode.createAllowNull(targetType, argument, null, null);
assert !inst.isAlive();
if (!inst.isTautology()) {
inst = adder.add(inst);
AnchoringNode guardAnchor = adder.getGuardAnchor();
DeoptimizationReason reason = DeoptimizationReason.ClassCastException;
DeoptimizationAction action = DeoptimizationAction.InvalidateRecompile;
Speculation speculation = SpeculationLog.NO_SPECULATION;
GuardingNode guard;
if (guardAnchor == null) {
FixedGuardNode fixedGuard = adder.add(new FixedGuardNode(inst, reason, action, speculation, false));
guard = fixedGuard;
} else {
GuardNode newGuard = adder.add(new GuardNode(inst, guardAnchor, reason, action, false, speculation, null));
adder.add(new ValueAnchorNode(newGuard));
guard = newGuard;
}
ValueNode valueNode = adder.add(PiNode.create(argument, StampFactory.object(targetType), guard.asNode()));
arguments[index] = valueNode;
}
}
}
}
}
use of jdk.vm.ci.meta.SpeculationLog.Speculation in project graal by oracle.
the class VirtualFrameAccessorNode method insertDeoptimization.
protected final void insertDeoptimization(VirtualizerTool tool) {
/*
* Escape analysis does not allow insertion of a DeoptimizeNode. We work around this
* restriction by inserting an always-failing guard, which will be canonicalized to a
* DeoptimizeNode later on.
*/
LogicNode condition = LogicConstantNode.contradiction();
tool.addNode(condition);
Speculation speculation = graph().getSpeculationLog().speculate(frame.getIntrinsifyAccessorsSpeculation());
tool.addNode(new FixedGuardNode(condition, DeoptimizationReason.RuntimeConstraint, DeoptimizationAction.InvalidateReprofile, speculation, false));
if (getStackKind() == JavaKind.Void) {
tool.delete();
} else {
/*
* Even though all usages will be eventually dead, we need to provide a valid
* replacement value for now.
*/
ConstantNode unusedValue = ConstantNode.forConstant(JavaConstant.defaultForKind(getStackKind()), tool.getMetaAccess());
tool.addNode(unusedValue);
tool.replaceWith(unusedValue);
}
}
use of jdk.vm.ci.meta.SpeculationLog.Speculation in project graal by oracle.
the class TruffleBoundaryPhase method addDeoptimizeNode.
private static void addDeoptimizeNode(StructuredGraph graph, FixedNode originalNext, ResolvedJavaMethod targetMethod) {
SpeculationLog speculationLog = graph.getSpeculationLog();
if (speculationLog != null) {
SpeculationReason speculationReason = PartialEvaluator.createTruffleBoundaryExceptionSpeculation(targetMethod);
if (speculationLog.maySpeculate(speculationReason)) {
Speculation exceptionSpeculation = speculationLog.speculate(speculationReason);
DeoptimizeNode deoptimize = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.TransferToInterpreter, exceptionSpeculation));
originalNext.replaceAtPredecessor(deoptimize);
GraphUtil.killCFG(originalNext);
}
}
}
use of jdk.vm.ci.meta.SpeculationLog.Speculation in project graal by oracle.
the class TruffleGraphBuilderPlugins method registerFrameMethods.
private static void registerFrameMethods(Registration r, ConstantReflectionProvider constantReflection, KnownTruffleTypes types) {
r.register(new RequiredInvocationPlugin("getArguments", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frame) {
if (frame.get(false) instanceof NewFrameNode) {
b.push(JavaKind.Object, ((NewFrameNode) frame.get()).getArguments());
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("getFrameDescriptor", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frame) {
if (frame.get(false) instanceof NewFrameNode) {
b.push(JavaKind.Object, ((NewFrameNode) frame.get()).getDescriptor());
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("materialize", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
ValueNode frame = receiver.get();
if (frame instanceof NewFrameNode && ((NewFrameNode) frame).getIntrinsifyAccessors()) {
Speculation speculation = b.getGraph().getSpeculationLog().speculate(((NewFrameNode) frame).getIntrinsifyAccessorsSpeculation());
b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.RuntimeConstraint, speculation));
return true;
}
b.addPush(JavaKind.Object, new AllowMaterializeNode(frame));
return true;
}
});
r.register(new RequiredInvocationPlugin("clear", Receiver.class, new ResolvedJavaSymbol(types.classFrameSlot)) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode frameSlot) {
int frameSlotIndex = maybeGetConstantFrameSlotIndex(receiver, frameSlot, constantReflection, types);
if (frameSlotIndex >= 0) {
TruffleCompilerRuntime runtime = getRuntime();
b.add(new VirtualFrameClearNode(receiver, frameSlotIndex, runtime.getFrameSlotKindTagForJavaKind(JavaKind.Illegal), VirtualFrameAccessType.Legacy));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("clear", Receiver.class, int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode frameSlot) {
int frameSlotIndex = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot);
if (frameSlotIndex >= 0) {
TruffleCompilerRuntime runtime = getRuntime();
b.add(new VirtualFrameClearNode(receiver, frameSlotIndex, runtime.getFrameSlotKindTagForJavaKind(JavaKind.Illegal), VirtualFrameAccessType.Indexed));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("swap", Receiver.class, int.class, int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode frameSlot1, ValueNode frameSlot2) {
int frameSlot1Index = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot1);
int frameSlot2Index = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot2);
if (frameSlot1Index >= 0 && frameSlot2Index >= 0) {
b.add(new VirtualFrameSwapNode(receiver, frameSlot1Index, frameSlot2Index, VirtualFrameAccessType.Indexed));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("copy", Receiver.class, int.class, int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode frameSlot1, ValueNode frameSlot2) {
int frameSlot1Index = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot1);
int frameSlot2Index = maybeGetConstantNumberedFrameSlotIndex(receiver, frameSlot2);
if (frameSlot1Index >= 0 && frameSlot2Index >= 0) {
b.add(new VirtualFrameCopyNode(receiver, frameSlot1Index, frameSlot2Index, VirtualFrameAccessType.Indexed));
return true;
}
return false;
}
});
}
use of jdk.vm.ci.meta.SpeculationLog.Speculation in project graal by oracle.
the class UseTrappingNullChecksPhase method tryUseTrappingNullCheck.
private static void tryUseTrappingNullCheck(MetaAccessProvider metaAccessProvider, DynamicDeoptimizeNode deopt, long implicitNullCheckLimit) {
Node predecessor = deopt.predecessor();
if (predecessor instanceof AbstractMergeNode) {
AbstractMergeNode merge = (AbstractMergeNode) predecessor;
// Process each predecessor at the merge, unpacking the reasons and speculations as
// needed.
ValueNode reason = deopt.getActionAndReason();
ValuePhiNode reasonPhi = null;
List<ValueNode> reasons = null;
int expectedPhis = 0;
if (reason instanceof ValuePhiNode) {
reasonPhi = (ValuePhiNode) reason;
if (reasonPhi.merge() != merge) {
return;
}
reasons = reasonPhi.values().snapshot();
expectedPhis++;
} else if (!reason.isConstant()) {
merge.getDebug().log("Non constant reason %s", merge);
return;
}
ValueNode speculation = deopt.getSpeculation();
ValuePhiNode speculationPhi = null;
List<ValueNode> speculations = null;
if (speculation instanceof ValuePhiNode) {
speculationPhi = (ValuePhiNode) speculation;
if (speculationPhi.merge() != merge) {
return;
}
speculations = speculationPhi.values().snapshot();
expectedPhis++;
}
if (merge.phis().count() != expectedPhis) {
return;
}
int index = 0;
List<EndNode> predecessors = merge.cfgPredecessors().snapshot();
for (AbstractEndNode end : predecessors) {
Node endPredecesssor = end.predecessor();
ValueNode thisReason = reasons != null ? reasons.get(index) : reason;
ValueNode thisSpeculation = speculations != null ? speculations.get(index) : speculation;
if (!merge.isAlive()) {
// must be handled specially.
assert predecessors.get(predecessors.size() - 1) == end : "must be last end";
endPredecesssor = deopt.predecessor();
thisSpeculation = deopt.getSpeculation();
thisReason = deopt.getActionAndReason();
}
index++;
if (!thisReason.isConstant() || !thisSpeculation.isConstant()) {
end.getDebug().log("Non constant deopt %s", end);
continue;
}
DeoptimizationReason deoptimizationReason = metaAccessProvider.decodeDeoptReason(thisReason.asJavaConstant());
Speculation speculationConstant = metaAccessProvider.decodeSpeculation(thisSpeculation.asJavaConstant(), deopt.graph().getSpeculationLog());
tryUseTrappingNullCheck(deopt, endPredecesssor, deoptimizationReason, speculationConstant, implicitNullCheckLimit, thisReason.asJavaConstant(), thisSpeculation.asJavaConstant());
}
}
}
Aggregations