package org.graalvm.compiler.replacements.test;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import java.util.ArrayList;
import java.util.Collection;
import static java.lang.reflect.Modifier.isStatic;
@RunWith(Parameterized.class)
public class SystemArrayCopyTest extends GraalCompilerTest {
@Parameter(0) public Object src;
@Parameter(1) public Object dst;
@Parameter(2) public int len;
@Parameter(3) public String name;
@Parameters(name = "{3}")
public static Collection<Object[]> data() {
Object[] srcs = {new int[4], new double[4], new Integer[4], new Number[4], new String[4], new Object[]{"Graal", 0, 0, 0}, new Object()};
Object[] dsts = {new int[4], new Number[4]};
int[] lens = {-1, 0, 2, 8};
ArrayList<Object[]> ret = new ArrayList<>(srcs.length * dsts.length * lens.length);
for (Object src : srcs) {
for (Object dst : dsts) {
for (int length : lens) {
ret.add(new Object[]{src, dst, length, src.getClass().getSimpleName() + ", 0, " + dst.getClass().getSimpleName() + ", 0, " + length});
}
}
}
return ret;
}
public static void testArrayCopySnippet(Object src, Object dst, int length) {
System.arraycopy(src, 0, dst, 0, length);
}
private static final int PARAMETER_LENGTH = 3;
private Object[] argsToBind;
@Test
public void testArrayCopy() {
ResolvedJavaMethod method = getResolvedJavaMethod("testArrayCopySnippet");
Object receiver = method.isStatic() ? null : this;
Object[] args = {src, dst, len};
Result expect = executeExpected(method, receiver, args);
testAgainstExpected(method, expect, receiver, args);
for (int i = 1; i < (1 << PARAMETER_LENGTH); i++) {
argsToBind = new Object[PARAMETER_LENGTH];
for (int j = 0; j < PARAMETER_LENGTH; j++) {
if ((i & (1 << j)) != 0) {
argsToBind[j] = args[j];
}
}
testAgainstExpected(method, expect, receiver, args);
}
}
@Override
protected StructuredGraph parse(StructuredGraph.Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite) {
StructuredGraph graph = super.parse(builder, graphBuilderSuite);
if (argsToBind != null) {
ResolvedJavaMethod m = graph.method();
Object receiver = isStatic(m.getModifiers()) ? null : this;
Object[] args = argsWithReceiver(receiver, argsToBind);
JavaType[] parameterTypes = m.toParameterTypes();
assert parameterTypes.length == args.length;
for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
int index = param.index();
if (args[index] != null) {
JavaConstant c = getSnippetReflection().forBoxed(parameterTypes[index].getJavaKind(), args[index]);
ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
param.replaceAtUsages(replacement);
}
}
}
return graph;
}
@Override
protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
return super.getCode(method, graph, true, installAsDefault, options);
}
}