package com.oracle.graal.pointsto.plugins;
import java.util.Arrays;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.extended.GetClassNode;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin.Receiver;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
import org.graalvm.compiler.replacements.nodes.BasicArrayCopyNode;
import org.graalvm.compiler.replacements.nodes.MacroNode.MacroParams;
import com.oracle.graal.pointsto.nodes.AnalysisArraysCopyOfNode;
import com.oracle.graal.pointsto.nodes.AnalysisObjectCloneNode;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class PointstoGraphBuilderPlugins {
public static void registerArraysPlugins(InvocationPlugins plugins) {
Registration r = new Registration(plugins, Arrays.class).setAllowOverwrite(true);
r.register2("copyOf", Object[].class, int.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode original, ValueNode newLength) {
b.addPush(JavaKind.Object, new AnalysisArraysCopyOfNode(b.getInvokeReturnStamp(b.getAssumptions()).getTrustedStamp(), original, newLength));
return true;
}
});
r.register3("copyOf", Object[].class, int.class, Class.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode original, ValueNode newLength, ValueNode newObjectElementType) {
if (newObjectElementType instanceof GetClassNode || newObjectElementType.isConstant()) {
b.addPush(JavaKind.Object, new AnalysisArraysCopyOfNode(b.getInvokeReturnStamp(b.getAssumptions()).getTrustedStamp(), original, newLength, newObjectElementType));
return true;
}
return false;
}
});
}
public static void registerSystemPlugins(InvocationPlugins plugins) {
Registration r = new Registration(plugins, System.class).setAllowOverwrite(true);
r.register5("arraycopy", Object.class, int.class, Object.class, int.class, int.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode src, ValueNode srcPos, ValueNode dest, ValueNode destPos, ValueNode length) {
b.add(new BasicArrayCopyNode(BasicArrayCopyNode.TYPE, src, srcPos, dest, destPos, length, null, b.bci()));
return true;
}
});
}
public static void registerObjectPlugins(InvocationPlugins plugins) {
Registration r = new Registration(plugins, Object.class);
r.register1("clone", Receiver.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
ValueNode object = receiver.get();
b.addPush(JavaKind.Object, new AnalysisObjectCloneNode(MacroParams.of(b, targetMethod, object)));
return true;
}
});
}
}