use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin in project graal by oracle.
the class StandardGraphBuilderPlugins method registerObjectPlugins.
private static void registerObjectPlugins(InvocationPlugins plugins) {
Registration r = new Registration(plugins, Object.class);
r.register1("<init>", Receiver.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
/*
* Object.<init> is a common instrumentation point so only perform this rewrite if
* the current definition is the normal empty method with a single return bytecode.
* The finalizer registration will instead be performed by the BytecodeParser.
*/
if (targetMethod.getCodeSize() == 1) {
ValueNode object = receiver.get();
if (RegisterFinalizerNode.mayHaveFinalizer(object, b.getAssumptions())) {
b.add(new RegisterFinalizerNode(object));
}
return true;
}
return false;
}
});
r.register1("getClass", Receiver.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
ValueNode object = receiver.get();
ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), NodeView.DEFAULT, GraphUtil.originalValue(object));
if (folded != null) {
b.addPush(JavaKind.Object, folded);
} else {
Stamp stamp = StampFactory.objectNonNull(TypeReference.createTrusted(b.getAssumptions(), b.getMetaAccess().lookupJavaType(Class.class)));
b.addPush(JavaKind.Object, new GetClassNode(stamp, object));
}
return true;
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin in project graal by oracle.
the class StandardGraphBuilderPlugins method registerUnsafePlugins.
private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
Registration r;
if (Java8OrEarlier) {
r = new Registration(plugins, Unsafe.class);
} else {
r = new Registration(plugins, "jdk.internal.misc.Unsafe", bytecodeProvider);
}
for (JavaKind kind : JavaKind.values()) {
if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
Class<?> javaClass = kind == JavaKind.Object ? Object.class : kind.toJavaClass();
String kindName = kind.name();
String getName = "get" + kindName;
String putName = "put" + kindName;
// Object-based accesses
r.register3(getName, Receiver.class, Object.class, long.class, new UnsafeGetPlugin(kind, false));
r.register4(putName, Receiver.class, Object.class, long.class, javaClass, new UnsafePutPlugin(kind, false));
// Volatile object-based accesses
r.register3(getName + "Volatile", Receiver.class, Object.class, long.class, new UnsafeGetPlugin(kind, true));
r.register4(putName + "Volatile", Receiver.class, Object.class, long.class, javaClass, new UnsafePutPlugin(kind, true));
// Ordered object-based accesses
if (Java8OrEarlier) {
if (kind == JavaKind.Int || kind == JavaKind.Long || kind == JavaKind.Object) {
r.register4("putOrdered" + kindName, Receiver.class, Object.class, long.class, javaClass, UnsafePutPlugin.putOrdered(kind));
}
} else {
r.register4("put" + kindName + "Release", Receiver.class, Object.class, long.class, javaClass, UnsafePutPlugin.putOrdered(kind));
}
if (kind != JavaKind.Boolean && kind != JavaKind.Object) {
// Raw accesses to memory addresses
r.register2(getName, Receiver.class, long.class, new UnsafeGetPlugin(kind, false));
r.register3(putName, Receiver.class, long.class, kind.toJavaClass(), new UnsafePutPlugin(kind, false));
}
}
}
// Accesses to native memory addresses.
r.register2("getAddress", Receiver.class, long.class, new UnsafeGetPlugin(JavaKind.Long, false));
r.register3("putAddress", Receiver.class, long.class, long.class, new UnsafePutPlugin(JavaKind.Long, false));
for (JavaKind kind : new JavaKind[] { JavaKind.Int, JavaKind.Long, JavaKind.Object }) {
Class<?> javaClass = kind == JavaKind.Object ? Object.class : kind.toJavaClass();
String casName;
if (Java8OrEarlier) {
casName = "compareAndSwap";
} else {
casName = "compareAndSet";
}
r.register5(casName + kind.name(), Receiver.class, Object.class, long.class, javaClass, javaClass, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode expected, ValueNode x) {
// Emits a null-check for the otherwise unused receiver
unsafe.get();
b.addPush(JavaKind.Int, new UnsafeCompareAndSwapNode(object, offset, expected, x, kind, LocationIdentity.any()));
b.getGraph().markUnsafeAccess();
return true;
}
});
}
r.register2("allocateInstance", Receiver.class, Class.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode clazz) {
// Emits a null-check for the otherwise unused receiver
unsafe.get();
b.addPush(JavaKind.Object, new DynamicNewInstanceNode(b.nullCheckedValue(clazz, DeoptimizationAction.None), true));
return true;
}
});
r.register1("loadFence", Receiver.class, new UnsafeFencePlugin(LOAD_LOAD | LOAD_STORE));
r.register1("storeFence", Receiver.class, new UnsafeFencePlugin(STORE_STORE | LOAD_STORE));
r.register1("fullFence", Receiver.class, new UnsafeFencePlugin(LOAD_LOAD | STORE_STORE | LOAD_STORE | STORE_LOAD));
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin in project graal by oracle.
the class StandardGraphBuilderPlugins method registerJcovCollectPlugins.
/**
* Registers a plugin to ignore {@code com.sun.tdk.jcov.runtime.Collect.hit} within an
* intrinsic.
*/
private static void registerJcovCollectPlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
Registration r = new Registration(plugins, "com.sun.tdk.jcov.runtime.Collect", bytecodeProvider);
r.register1("hit", int.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode object) {
if (b.parsingIntrinsic()) {
return true;
}
return false;
}
});
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin in project graal by oracle.
the class StandardGraphBuilderPlugins method registerJMHBlackholePlugins.
private static void registerJMHBlackholePlugins(InvocationPlugins plugins, BytecodeProvider bytecodeProvider) {
InvocationPlugin blackholePlugin = new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver blackhole, ValueNode value) {
blackhole.get();
b.add(new BlackholeNode(value));
return true;
}
};
String[] names = { "org.openjdk.jmh.infra.Blackhole", "org.openjdk.jmh.logic.BlackHole" };
for (String name : names) {
Registration r = new Registration(plugins, name, bytecodeProvider);
for (JavaKind kind : JavaKind.values()) {
if ((kind.isPrimitive() && kind != JavaKind.Void) || kind == JavaKind.Object) {
Class<?> javaClass = kind == JavaKind.Object ? Object.class : kind.toJavaClass();
r.registerOptional2("consume", Receiver.class, javaClass, blackholePlugin);
}
}
r.registerOptional2("consume", Receiver.class, Object[].class, blackholePlugin);
}
}
use of org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin in project graal by oracle.
the class StandardGraphBuilderPlugins method registerMethodHandleImplPlugins.
private static void registerMethodHandleImplPlugins(InvocationPlugins plugins, SnippetReflectionProvider snippetReflection, BytecodeProvider bytecodeProvider) {
Registration r = new Registration(plugins, "java.lang.invoke.MethodHandleImpl", bytecodeProvider);
r.register2("profileBoolean", boolean.class, int[].class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode result, ValueNode counters) {
if (result.isConstant()) {
b.push(JavaKind.Boolean, result);
return true;
}
if (counters.isConstant()) {
ValueNode newResult = result;
int[] ctrs = snippetReflection.asObject(int[].class, (JavaConstant) counters.asConstant());
if (ctrs != null && ctrs.length == 2) {
int falseCount = ctrs[0];
int trueCount = ctrs[1];
int totalCount = trueCount + falseCount;
if (totalCount == 0) {
b.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TransferToInterpreter));
} else if (falseCount == 0 || trueCount == 0) {
boolean expected = falseCount == 0;
LogicNode condition = b.addWithInputs(IntegerEqualsNode.create(b.getConstantReflection(), b.getMetaAccess(), b.getOptions(), null, result, b.add(ConstantNode.forBoolean(!expected)), NodeView.DEFAULT));
b.append(new FixedGuardNode(condition, DeoptimizationReason.UnreachedCode, DeoptimizationAction.InvalidateReprofile, true));
newResult = b.add(ConstantNode.forBoolean(expected));
} else {
// We cannot use BranchProbabilityNode here since there's no guarantee
// the result of MethodHandleImpl.profileBoolean() is used as the
// test in an `if` statement (as required by BranchProbabilityNode).
}
}
b.addPush(JavaKind.Boolean, newResult);
return true;
}
return false;
}
});
}
Aggregations