use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class InliningUtil method nonNullReceiver.
/**
* Gets the receiver for an invoke, adding a guard if necessary to ensure it is non-null, and
* ensuring that the resulting type is compatible with the method being invoked.
*/
@SuppressWarnings("try")
public static ValueNode nonNullReceiver(Invoke invoke) {
try (DebugCloseable position = invoke.asNode().withNodeSourcePosition()) {
MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
assert !callTarget.isStatic() : callTarget.targetMethod();
StructuredGraph graph = callTarget.graph();
ValueNode oldReceiver = callTarget.arguments().get(0);
ValueNode newReceiver = oldReceiver;
if (newReceiver.getStackKind() == JavaKind.Object) {
if (invoke.getInvokeKind() == InvokeKind.Special) {
Stamp paramStamp = newReceiver.stamp(NodeView.DEFAULT);
Stamp stamp = paramStamp.join(StampFactory.object(TypeReference.create(graph.getAssumptions(), callTarget.targetMethod().getDeclaringClass())));
if (!stamp.equals(paramStamp)) {
// The verifier and previous optimizations guarantee unconditionally that
// the
// receiver is at least of the type of the method holder for a special
// invoke.
newReceiver = graph.unique(new PiNode(newReceiver, stamp));
}
}
if (!StampTool.isPointerNonNull(newReceiver)) {
LogicNode condition = graph.unique(IsNullNode.create(newReceiver));
FixedGuardNode fixedGuard = graph.add(new FixedGuardNode(condition, NullCheckException, InvalidateReprofile, true));
PiNode nonNullReceiver = graph.unique(new PiNode(newReceiver, StampFactory.objectNonNull(), fixedGuard));
graph.addBeforeFixed(invoke.asNode(), fixedGuard);
newReceiver = nonNullReceiver;
}
}
if (newReceiver != oldReceiver) {
callTarget.replaceFirstInput(oldReceiver, newReceiver);
}
return newReceiver;
}
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class HotSpotGraphBuilderPlugins method registerClassPlugins.
private static void registerClassPlugins(Plugins plugins, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
Registration r = new Registration(plugins.getInvocationPlugins(), Class.class, bytecodeProvider);
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "getModifiers", Receiver.class);
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isInterface", Receiver.class);
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isArray", Receiver.class);
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "isPrimitive", Receiver.class);
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "getSuperclass", Receiver.class);
if (config.getFieldOffset("ArrayKlass::_component_mirror", Integer.class, "oop", Integer.MAX_VALUE) != Integer.MAX_VALUE) {
r.registerMethodSubstitution(HotSpotClassSubstitutions.class, "getComponentType", Receiver.class);
}
r.register2("cast", Receiver.class, Object.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
ValueNode javaClass = receiver.get();
LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), javaClass, object, true));
if (condition.isTautology()) {
b.addPush(JavaKind.Object, object);
} else {
FixedGuardNode fixedGuard = b.add(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
b.addPush(JavaKind.Object, DynamicPiNode.create(b.getAssumptions(), b.getConstantReflection(), object, fixedGuard, javaClass));
}
return true;
}
@Override
public boolean inlineOnly() {
return true;
}
});
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class StandardGraphBuilderPlugins method registerClassPlugins.
private static void registerClassPlugins(InvocationPlugins plugins) {
Registration r = new Registration(plugins, Class.class);
r.register2("isInstance", Receiver.class, Object.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver type, ValueNode object) {
LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), type.get(), object, false));
b.push(JavaKind.Boolean, b.append(new ConditionalNode(condition).canonical(null)));
return true;
}
});
r.register2("isAssignableFrom", Receiver.class, Class.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver type, ValueNode otherType) {
ClassIsAssignableFromNode condition = b.append(new ClassIsAssignableFromNode(type.get(), otherType));
b.push(JavaKind.Boolean, b.append(new ConditionalNode(condition).canonical(null)));
return true;
}
});
}
use of org.graalvm.compiler.nodes.LogicNode 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;
JavaConstant speculation = JavaConstant.NULL_POINTER;
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));
adder.add(new ValueAnchorNode(newGuard));
guard = newGuard;
}
ValueNode valueNode = adder.add(PiNode.create(argument, StampFactory.object(targetType), guard.asNode()));
arguments[index] = valueNode;
}
}
}
}
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class IsNullNode method canonicalized.
private static LogicNode canonicalized(IsNullNode isNullNode, ValueNode forValue) {
IsNullNode self = isNullNode;
LogicNode result = tryCanonicalize(forValue);
if (result != null) {
return result;
}
if (forValue instanceof PiNode) {
return IsNullNode.create(GraphUtil.skipPi(forValue));
}
if (forValue instanceof ConvertNode) {
ConvertNode convertNode = (ConvertNode) forValue;
if (convertNode.mayNullCheckSkipConversion()) {
return IsNullNode.create(convertNode.getValue());
}
}
if (self == null) {
self = new IsNullNode(GraphUtil.skipPi(forValue));
}
return self;
}
Aggregations