use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class TruffleGraphBuilderPlugins method registerFrameAuxiliaryAccessors.
private static void registerFrameAuxiliaryAccessors(Registration r) {
TruffleCompilerRuntime runtime = getRuntime();
int accessTag = runtime.getFrameSlotKindTagForJavaKind(JavaKind.Object);
r.register(new RequiredInvocationPlugin("getAuxiliarySlot", Receiver.class, int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frameNode, ValueNode frameSlotNode) {
int frameSlotIndex = maybeGetConstantNumberedFrameSlotIndex(frameNode, frameSlotNode);
if (frameSlotIndex >= 0) {
b.addPush(JavaKind.Object, new VirtualFrameGetNode(frameNode, frameSlotIndex, JavaKind.Object, accessTag, VirtualFrameAccessType.Auxiliary));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("setAuxiliarySlot", Receiver.class, int.class, Object.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frameNode, ValueNode frameSlotNode, ValueNode value) {
int frameSlotIndex = maybeGetConstantNumberedFrameSlotIndex(frameNode, frameSlotNode);
if (frameSlotIndex >= 0) {
b.add(new VirtualFrameSetNode(frameNode, frameSlotIndex, accessTag, value, VirtualFrameAccessType.Auxiliary));
return true;
}
return false;
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class TruffleGraphBuilderPlugins method registerCompilerDirectivesPlugins.
public static void registerCompilerDirectivesPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, boolean canDelayIntrinsification) {
final ResolvedJavaType compilerDirectivesType = getRuntime().resolveType(metaAccess, "com.oracle.truffle.api.CompilerDirectives");
Registration r = new Registration(plugins, new ResolvedJavaSymbol(compilerDirectivesType));
r.register(new RequiredInvocationPlugin("inInterpreter") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
return true;
}
});
r.register(new RequiredInvocationPlugin("hasNextTier") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
if (!canDelayIntrinsification && b.getGraph().getCancellable() instanceof TruffleCompilationTask) {
TruffleCompilationTask task = (TruffleCompilationTask) b.getGraph().getCancellable();
b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(task.hasNextTier()));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("inCompiledCode") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
return true;
}
});
r.register(new RequiredInvocationPlugin("inCompilationRoot") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
GraphBuilderContext.ExternalInliningContext inliningContext = b.getExternalInliningContext();
if (inliningContext != null) {
b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(inliningContext.getInlinedDepth() == 0));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("transferToInterpreter") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
b.add(new DeoptimizeNode(DeoptimizationAction.None, DeoptimizationReason.TransferToInterpreter));
return true;
}
});
r.register(new RequiredInvocationPlugin("transferToInterpreterAndInvalidate") {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter));
return true;
}
});
r.register(new RequiredInvocationPlugin("interpreterOnly", Runnable.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
return true;
}
});
r.register(new RequiredInvocationPlugin("interpreterOnly", Callable.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
return true;
}
});
r.register(new RequiredInvocationPlugin("injectBranchProbability", double.class, boolean.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode probability, ValueNode condition) {
b.addPush(JavaKind.Boolean, new BranchProbabilityNode(probability, condition));
return true;
}
});
r.register(new RequiredInvocationPlugin("bailout", String.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode message) {
if (canDelayIntrinsification) {
/*
* We do not want to bailout yet, since we are still parsing individual methods
* and constant folding could still eliminate the call to bailout(). However, we
* also want to stop parsing, since we are sure that we will never need the
* graph beyond the bailout point.
*
* Therefore, we manually emit the call to bailout, which will be intrinsified
* later when intrinsifications can no longer be delayed. The call is followed
* by a NeverPartOfCompilationNode, which is a control sink and therefore stops
* any further parsing.
*/
StampPair returnStamp = b.getInvokeReturnStamp(b.getAssumptions());
CallTargetNode callTarget = b.add(new MethodCallTargetNode(InvokeKind.Static, targetMethod, new ValueNode[] { message }, returnStamp, null));
b.add(new InvokeNode(callTarget, b.bci()));
b.add(new NeverPartOfCompilationNode("intrinsification of call to bailout() will abort entire compilation"));
return true;
}
if (message.isConstant()) {
throw b.bailout(message.asConstant().toValueString());
}
throw b.bailout("bailout (message is not compile-time constant, so no additional information is available)");
}
});
r.register(new RequiredInvocationPlugin("isCompilationConstant", Object.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
} else {
b.addPush(JavaKind.Boolean, new IsCompilationConstantNode(value));
}
return true;
}
});
r.register(new RequiredInvocationPlugin("isPartialEvaluationConstant", Object.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
if ((value instanceof BoxNode ? ((BoxNode) value).getValue() : value).isConstant()) {
b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(true));
} else if (canDelayIntrinsification) {
return false;
} else {
b.addPush(JavaKind.Boolean, ConstantNode.forBoolean(false));
}
return true;
}
});
r.register(new RequiredInvocationPlugin("materialize", Object.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
AllowMaterializeNode materializedValue = b.append(new AllowMaterializeNode(value));
b.add(new ForceMaterializeNode(materializedValue));
return true;
}
});
r.register(new RequiredInvocationPlugin("ensureVirtualized", Object.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
b.add(new EnsureVirtualizedNode(object, false));
return true;
}
});
r.register(new RequiredInvocationPlugin("ensureVirtualizedHere", Object.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
b.add(new EnsureVirtualizedNode(object, true));
return true;
}
});
for (JavaKind kind : JavaKind.values()) {
if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
Class<?> javaClass = getJavaClass(kind);
r.register(new RequiredInlineOnlyInvocationPlugin("blackhole", javaClass) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
b.add(new BlackholeNode(value));
return true;
}
});
}
}
r.register(new RequiredInvocationPlugin("castExact", Object.class, Class.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode javaClass) {
ValueNode nullCheckedClass = b.addNonNullCast(javaClass);
LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), nullCheckedClass, object, true, 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, nullCheckedClass, true, true));
}
return true;
}
});
r.register(new RequiredInvocationPlugin("isExact", Object.class, Class.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object, ValueNode javaClass) {
ValueNode nullCheckedClass = b.addNonNullCast(javaClass);
LogicNode condition = b.append(InstanceOfDynamicNode.create(b.getAssumptions(), b.getConstantReflection(), nullCheckedClass, object, false, true));
b.addPush(JavaKind.Boolean, b.append(new ConditionalNode(condition)));
return true;
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class SubstrateGraphBuilderPlugins method registerUnsafePlugins.
private static void registerUnsafePlugins(MetaAccessProvider metaAccess, Registration r, SnippetReflectionProvider snippetReflection, ParsingReason reason, boolean isSunMiscUnsafe) {
r.register(new RequiredInvocationPlugin("staticFieldOffset", Receiver.class, Field.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode fieldNode) {
if (fieldNode.isConstant()) {
Field targetField = snippetReflection.asObject(Field.class, fieldNode.asJavaConstant());
return processFieldOffset(b, targetField, reason, metaAccess, isSunMiscUnsafe);
}
return false;
}
});
r.register(new RequiredInvocationPlugin("staticFieldBase", Receiver.class, Field.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode fieldNode) {
if (fieldNode.isConstant()) {
Field targetField = snippetReflection.asObject(Field.class, fieldNode.asJavaConstant());
return processStaticFieldBase(b, targetField, isSunMiscUnsafe);
}
return false;
}
});
r.register(new RequiredInvocationPlugin("objectFieldOffset", Receiver.class, Field.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode fieldNode) {
if (fieldNode.isConstant()) {
Field targetField = snippetReflection.asObject(Field.class, fieldNode.asJavaConstant());
return processFieldOffset(b, targetField, reason, metaAccess, isSunMiscUnsafe);
}
return false;
}
});
r.register(new RequiredInvocationPlugin("allocateInstance", Receiver.class, Class.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode clazz) {
/* Emits a null-check for the otherwise unused receiver. */
unsafe.get();
/*
* The allocated class must be null-checked already before the class initialization
* check.
*/
ValueNode clazzNonNull = b.nullCheckedValue(clazz, DeoptimizationAction.None);
b.add(new EnsureClassInitializedNode(clazzNonNull));
DynamicNewInstanceNode.createAndPush(b, clazzNonNull);
return true;
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class SubstrateGraphBuilderPlugins method registerArrayPlugins.
private static void registerArrayPlugins(InvocationPlugins plugins, SnippetReflectionProvider snippetReflection, ParsingReason reason) {
Registration r = new Registration(plugins, Array.class).setAllowOverwrite(true);
r.register(new RequiredInvocationPlugin("newInstance", Class.class, int[].class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode clazzNode, ValueNode dimensionsNode) {
if (SubstrateOptions.parseOnce() || reason == ParsingReason.PointsToAnalysis) {
/*
* There is no Graal node for dynamic multi array allocation, and it is also not
* necessary for performance reasons. But when the arguments are constant, we
* can register the array types as instantiated so that the allocation succeeds
* at run time without manual registration.
*/
ValueNode dimensionCountNode = GraphUtil.arrayLength(dimensionsNode, ArrayLengthProvider.FindLengthMode.SEARCH_ONLY, b.getConstantReflection());
if (clazzNode.isConstant() && !clazzNode.isNullConstant() && dimensionCountNode != null && dimensionCountNode.isConstant()) {
Class<?> clazz = snippetReflection.asObject(Class.class, clazzNode.asJavaConstant());
int dimensionCount = dimensionCountNode.asJavaConstant().asInt();
AnalysisType type = (AnalysisType) b.getMetaAccess().lookupJavaType(clazz);
for (int i = 0; i < dimensionCount; i++) {
type = type.getArrayClass();
type.registerAsAllocated(clazzNode);
}
}
}
return false;
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class SubstrateGraphBuilderPlugins method registerStackValuePlugins.
private static void registerStackValuePlugins(SnippetReflectionProvider snippetReflection, InvocationPlugins plugins) {
Registration r = new Registration(plugins, StackValue.class);
r.register(new RequiredInvocationPlugin("get", int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode sizeNode) {
long size = longValue(b, targetMethod, sizeNode, "size");
b.addPush(JavaKind.Object, StackValueNode.create(1, size, b));
return true;
}
});
r.register(new RequiredInvocationPlugin("get", Class.class) {
@SuppressWarnings("unchecked")
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unused, ValueNode classNode) {
Class<? extends PointerBase> clazz = constantObjectParameter(b, snippetReflection, targetMethod, 0, Class.class, classNode);
int size = SizeOf.get(clazz);
b.addPush(JavaKind.Object, StackValueNode.create(1, size, b));
return true;
}
});
r.register(new RequiredInvocationPlugin("get", int.class, int.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode numElementsNode, ValueNode elementSizeNode) {
long numElements = longValue(b, targetMethod, numElementsNode, "numElements");
long elementSize = longValue(b, targetMethod, elementSizeNode, "elementSize");
b.addPush(JavaKind.Object, StackValueNode.create(numElements, elementSize, b));
return true;
}
});
r.register(new RequiredInvocationPlugin("get", int.class, Class.class) {
@SuppressWarnings("unchecked")
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unused, ValueNode numElementsNode, ValueNode classNode) {
long numElements = longValue(b, targetMethod, numElementsNode, "numElements");
Class<? extends PointerBase> clazz = constantObjectParameter(b, snippetReflection, targetMethod, 0, Class.class, classNode);
int size = SizeOf.get(clazz);
b.addPush(JavaKind.Object, StackValueNode.create(numElements, size, b));
return true;
}
});
}
Aggregations