use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class TruffleGraphBuilderPlugins method registerTruffleSafepointPlugins.
private static void registerTruffleSafepointPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, boolean canDelayIntrinsification) {
final ResolvedJavaType truffleSafepoint = getRuntime().resolveType(metaAccess, "com.oracle.truffle.api.TruffleSafepoint");
Registration r = new Registration(plugins, new ResolvedJavaSymbol(truffleSafepoint));
r.register(new RequiredInvocationPlugin("poll", com.oracle.truffle.api.nodes.Node.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode arg) {
if (arg.isConstant()) {
assert TruffleSafepointInsertionPhase.allowsSafepoints(b.getGraph()) : "TruffleSafepoint.poll only expected to be removed in Truffle compilations.";
return true;
} else if (canDelayIntrinsification) {
return false;
} else {
throw failPEConstant(b, arg);
}
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class TruffleGraphBuilderPlugins method registerFrameAccessors.
/**
* We intrinsify the getXxx, setXxx, and isXxx methods for all type tags. The intrinsic nodes
* are lightweight fixed nodes without a {@link FrameState}. No {@link FrameState} is important
* for partial evaluation performance, because creating and later on discarding FrameStates for
* the setXxx methods have a high compile time cost.
*
* Intrinsification requires the following conditions: (1) the accessed frame is directly the
* {@link NewFrameNode}, (2) the accessed FrameSlot is a constant, and (3) the FrameDescriptor
* was never materialized before. All three conditions together guarantee that the escape
* analysis can virtualize the access. The condition (3) is necessary because a possible
* materialization of the frame can prevent escape analysis - so in that case a FrameState for
* setXxx methods is actually necessary since they stores can be state-changing memory
* operations.
*
* Note that we do not register an intrinsification for {@code FrameWithoutBoxing.getValue()}.
* It is a complicated method to intrinsify, and it is not used frequently enough to justify the
* complexity of an intrinsification.
*/
private static void registerFrameAccessors(Registration r, JavaKind accessKind, ConstantReflectionProvider constantReflection, KnownTruffleTypes types) {
TruffleCompilerRuntime runtime = getRuntime();
int accessTag = runtime.getFrameSlotKindTagForJavaKind(accessKind);
String nameSuffix = accessKind.name();
ResolvedJavaSymbol frameSlotType = new ResolvedJavaSymbol(types.classFrameSlot);
r.register(new RequiredInvocationPlugin("get" + nameSuffix, Receiver.class, frameSlotType) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frameNode, ValueNode frameSlotNode) {
int frameSlotIndex = maybeGetConstantFrameSlotIndex(frameNode, frameSlotNode, constantReflection, types);
if (frameSlotIndex >= 0) {
b.addPush(accessKind, new VirtualFrameGetNode(frameNode, frameSlotIndex, accessKind, accessTag, VirtualFrameAccessType.Legacy));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("set" + nameSuffix, Receiver.class, frameSlotType, getJavaClass(accessKind)) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frameNode, ValueNode frameSlotNode, ValueNode value) {
int frameSlotIndex = maybeGetConstantFrameSlotIndex(frameNode, frameSlotNode, constantReflection, types);
if (frameSlotIndex >= 0) {
b.add(new VirtualFrameSetNode(frameNode, frameSlotIndex, accessTag, value, VirtualFrameAccessType.Legacy));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("is" + nameSuffix, Receiver.class, frameSlotType) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver frameNode, ValueNode frameSlotNode) {
int frameSlotIndex = maybeGetConstantFrameSlotIndex(frameNode, frameSlotNode, constantReflection, types);
if (frameSlotIndex >= 0) {
b.addPush(JavaKind.Boolean, new VirtualFrameIsNode(frameNode, frameSlotIndex, accessTag, VirtualFrameAccessType.Legacy));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("get" + nameSuffix, 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(accessKind, new VirtualFrameGetNode(frameNode, frameSlotIndex, accessKind, accessTag, VirtualFrameAccessType.Indexed));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("set" + nameSuffix, Receiver.class, int.class, getJavaClass(accessKind)) {
@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.Indexed));
return true;
}
return false;
}
});
r.register(new RequiredInvocationPlugin("is" + nameSuffix, 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.Boolean, new VirtualFrameIsNode(frameNode, frameSlotIndex, accessTag, VirtualFrameAccessType.Indexed));
return true;
}
return false;
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin 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 org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class ReflectionPlugins method registerClassPlugins.
private void registerClassPlugins(InvocationPlugins plugins) {
registerFoldInvocationPlugins(plugins, Class.class, "getField", "getMethod", "getConstructor", "getDeclaredField", "getDeclaredMethod", "getDeclaredConstructor");
Registration r = new Registration(plugins, Class.class);
r.register(new RequiredInvocationPlugin("forName", String.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode nameNode) {
return processClassForName(b, targetMethod, nameNode, ConstantNode.forBoolean(true));
}
});
r.register(new RequiredInvocationPlugin("forName", String.class, boolean.class, ClassLoader.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode nameNode, ValueNode initializeNode, ValueNode classLoaderNode) {
/*
* For now, we ignore the ClassLoader parameter. We only intrinsify class names that
* are found by the ImageClassLoader, i.e., the application class loader at run
* time. We assume that every class loader used at run time delegates to the
* application class loader.
*/
return processClassForName(b, targetMethod, nameNode, initializeNode);
}
});
r.register(new RequiredInvocationPlugin("getClassLoader", Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
return processClassGetClassLoader(b, targetMethod, receiver);
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.RequiredInvocationPlugin in project graal by oracle.
the class VMThreadSTFeature method registerAccessors.
private void registerAccessors(Registration r, Class<?> valueClass, boolean isVolatile) {
/*
* Volatile accesses do not need memory barriers in single-threaded mode, i.e., we register
* the same plugin for normal and volatile accesses.
*/
String suffix = isVolatile ? "Volatile" : "";
/* get() method without the VMThread parameter. */
r.register(new RequiredInvocationPlugin("get" + suffix, Receiver.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
return handleGet(b, targetMethod, receiver);
}
});
/* get() method with the VMThread parameter. */
r.register(new RequiredInvocationPlugin("get" + suffix, Receiver.class, IsolateThread.class) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode threadNode) {
return handleGet(b, targetMethod, receiver);
}
});
/* set() method without the VMThread parameter. */
r.register(new RequiredInvocationPlugin("set" + suffix, Receiver.class, valueClass) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode valueNode) {
return handleSet(b, receiver, valueNode);
}
});
/* set() method with the VMThread parameter. */
r.register(new RequiredInvocationPlugin("set" + suffix, Receiver.class, IsolateThread.class, valueClass) {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode threadNode, ValueNode valueNode) {
return handleSet(b, receiver, valueNode);
}
});
}
Aggregations