1 /*
2  * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 package org.graalvm.compiler.replacements.test;
26 
27 import jdk.vm.ci.code.InstalledCode;
28 import jdk.vm.ci.meta.JavaConstant;
29 import jdk.vm.ci.meta.JavaType;
30 import jdk.vm.ci.meta.ResolvedJavaMethod;
31 import org.graalvm.compiler.core.test.GraalCompilerTest;
32 import org.graalvm.compiler.nodes.ConstantNode;
33 import org.graalvm.compiler.nodes.ParameterNode;
34 import org.graalvm.compiler.nodes.StructuredGraph;
35 import org.graalvm.compiler.options.OptionValues;
36 import org.graalvm.compiler.phases.PhaseSuite;
37 import org.graalvm.compiler.phases.tiers.HighTierContext;
38 import org.junit.Test;
39 import org.junit.runner.RunWith;
40 import org.junit.runners.Parameterized;
41 import org.junit.runners.Parameterized.Parameter;
42 import org.junit.runners.Parameterized.Parameters;
43 
44 import java.util.ArrayList;
45 import java.util.Collection;
46 
47 import static java.lang.reflect.Modifier.isStatic;
48 
49 @RunWith(Parameterized.class)
50 public class SystemArrayCopyTest extends GraalCompilerTest {
51 
52     @Parameter(0) public Object src;
53     @Parameter(1) public Object dst;
54     @Parameter(2) public int len;
55     @Parameter(3) public String name;
56 
57     @Parameters(name = "{3}")
data()58     public static Collection<Object[]> data() {
59         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()};
60         Object[] dsts = {new int[4], new Number[4]};
61         int[] lens = {-1, 0, 2, 8};
62 
63         ArrayList<Object[]> ret = new ArrayList<>(srcs.length * dsts.length * lens.length);
64         for (Object src : srcs) {
65             for (Object dst : dsts) {
66                 for (int length : lens) {
67                     ret.add(new Object[]{src, dst, length, src.getClass().getSimpleName() + ", 0, " + dst.getClass().getSimpleName() + ", 0, " + length});
68                 }
69             }
70         }
71         return ret;
72     }
73 
testArrayCopySnippet(Object src, Object dst, int length)74     public static void testArrayCopySnippet(Object src, Object dst, int length) {
75         System.arraycopy(src, 0, dst, 0, length);
76     }
77 
78     private static final int PARAMETER_LENGTH = 3;
79     private Object[] argsToBind;
80 
81     @Test
testArrayCopy()82     public void testArrayCopy() {
83         ResolvedJavaMethod method = getResolvedJavaMethod("testArrayCopySnippet");
84         Object receiver = method.isStatic() ? null : this;
85         Object[] args = {src, dst, len};
86 
87         Result expect = executeExpected(method, receiver, args);
88         testAgainstExpected(method, expect, receiver, args);
89 
90         // test composition of constant binding
91         for (int i = 1; i < (1 << PARAMETER_LENGTH); i++) {
92             argsToBind = new Object[PARAMETER_LENGTH];
93             for (int j = 0; j < PARAMETER_LENGTH; j++) {
94                 if ((i & (1 << j)) != 0) {
95                     argsToBind[j] = args[j];
96                 }
97             }
98             testAgainstExpected(method, expect, receiver, args);
99         }
100     }
101 
102     @Override
parse(StructuredGraph.Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite)103     protected StructuredGraph parse(StructuredGraph.Builder builder, PhaseSuite<HighTierContext> graphBuilderSuite) {
104         StructuredGraph graph = super.parse(builder, graphBuilderSuite);
105         if (argsToBind != null) {
106             ResolvedJavaMethod m = graph.method();
107             Object receiver = isStatic(m.getModifiers()) ? null : this;
108             Object[] args = argsWithReceiver(receiver, argsToBind);
109             JavaType[] parameterTypes = m.toParameterTypes();
110             assert parameterTypes.length == args.length;
111             for (ParameterNode param : graph.getNodes(ParameterNode.TYPE)) {
112                 int index = param.index();
113                 if (args[index] != null) {
114                     JavaConstant c = getSnippetReflection().forBoxed(parameterTypes[index].getJavaKind(), args[index]);
115                     ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
116                     param.replaceAtUsages(replacement);
117                 }
118             }
119         }
120         return graph;
121     }
122 
123     @Override
getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options)124     protected InstalledCode getCode(ResolvedJavaMethod method, StructuredGraph graph, boolean forceCompile, boolean installAsDefault, OptionValues options) {
125         return super.getCode(method, graph, true, installAsDefault, options);
126     }
127 
128 }
129