1 /* 2 * Copyright (c) 2011, 2015, 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 package org.graalvm.compiler.core.test.ea; 24 25 import org.graalvm.compiler.core.test.GraalCompilerTest; 26 import org.junit.Test; 27 28 import sun.misc.Unsafe; 29 30 import org.graalvm.compiler.nodes.StructuredGraph; 31 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 32 import org.graalvm.compiler.nodes.extended.RawLoadNode; 33 import org.graalvm.compiler.nodes.java.LoadIndexedNode; 34 import org.graalvm.compiler.nodes.java.StoreIndexedNode; 35 import org.graalvm.compiler.phases.common.CanonicalizerPhase; 36 import org.graalvm.compiler.phases.common.inlining.InliningPhase; 37 import org.graalvm.compiler.phases.tiers.HighTierContext; 38 import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase; 39 40 public class PEAReadEliminationTest extends GraalCompilerTest { 41 42 public static int testIndexed1Snippet(int[] array) { 43 array[1] = 1; 44 array[2] = 2; 45 array[3] = 3; 46 array[4] = 4; 47 array[5] = 5; 48 array[6] = 6; 49 return array[1] + array[2] + array[3] + array[4] + array[5] + array[6]; 50 } 51 52 @Test 53 public void testIndexed1() { 54 StructuredGraph graph = processMethod("testIndexed1Snippet"); 55 assertDeepEquals(0, graph.getNodes().filter(LoadIndexedNode.class).count()); 56 } 57 58 public static int testIndexed2Snippet(int v, int[] array) { 59 array[1] = 1; 60 array[2] = 2; 61 array[3] = 3; 62 array[v] = 0; 63 array[4] = 4; 64 array[5] = 5; 65 array[6] = 6; 66 array[4] = 4; 67 array[5] = 5; 68 array[6] = 6; 69 return array[1] + array[2] + array[3] + array[4] + array[5] + array[6]; 70 } 71 72 @Test 73 public void testIndexed2() { 74 StructuredGraph graph = processMethod("testIndexed2Snippet"); 75 assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count()); 76 assertDeepEquals(7, graph.getNodes().filter(StoreIndexedNode.class).count()); 77 } 78 79 public static int testIndexed3Snippet(int v, int[] array, short[] array2) { 80 array[1] = 1; 81 array2[1] = 1; 82 array[2] = 2; 83 array2[2] = 2; 84 array[3] = 3; 85 array2[3] = 3; 86 array[v] = 0; 87 array[4] = 4; 88 array2[4] = 4; 89 array[5] = 5; 90 array2[5] = 5; 91 array[6] = 6; 92 array2[6] = 6; 93 return array[1] + array[2] + array[3] + array[4] + array[5] + array[6] + array2[1] + array2[2] + array2[3] + array2[4] + array2[5] + array2[6]; 94 } 95 96 @Test 97 public void testIndexed3() { 98 StructuredGraph graph = processMethod("testIndexed3Snippet"); 99 assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count()); 100 } 101 102 private static native void nonInlineable(); 103 104 public static int testIndexed4Snippet(int[] array) { 105 array[1] = 1; 106 array[2] = 2; 107 array[3] = 3; 108 nonInlineable(); 109 array[4] = 4; 110 array[5] = 5; 111 array[6] = 6; 112 return array[1] + array[2] + array[3] + array[4] + array[5] + array[6]; 113 } 114 115 @Test 116 public void testIndexed4() { 117 StructuredGraph graph = processMethod("testIndexed4Snippet"); 118 assertDeepEquals(3, graph.getNodes().filter(LoadIndexedNode.class).count()); 119 } 120 121 private static final long offsetInt1 = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * 1; 122 private static final long offsetInt2 = Unsafe.ARRAY_INT_BASE_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * 2; 123 124 public static int testUnsafe1Snippet(int v, int[] array) { 125 int s = UNSAFE.getInt(array, offsetInt1); 126 UNSAFE.putInt(array, offsetInt1, v); 127 UNSAFE.putInt(array, offsetInt2, v); 128 return s + UNSAFE.getInt(array, offsetInt1) + UNSAFE.getInt(array, offsetInt2); 129 } 130 131 @Test 132 public void testUnsafe1() { 133 StructuredGraph graph = processMethod("testUnsafe1Snippet"); 134 assertDeepEquals(1, graph.getNodes().filter(RawLoadNode.class).count()); 135 } 136 137 public static int testUnsafe2Snippet(int v, Object array) { 138 int s = UNSAFE.getInt(array, offsetInt1); 139 UNSAFE.putInt(array, offsetInt1, v); 140 UNSAFE.putInt(array, offsetInt2, v); 141 return s + UNSAFE.getInt(array, offsetInt1) + UNSAFE.getInt(array, offsetInt2); 142 } 143 144 @Test 145 public void testUnsafe2() { 146 StructuredGraph graph = processMethod("testUnsafe2Snippet"); 147 assertDeepEquals(3, graph.getNodes().filter(RawLoadNode.class).count()); 148 } 149 150 private static final long offsetObject1 = Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * 1; 151 private static final long offsetObject2 = Unsafe.ARRAY_OBJECT_BASE_OFFSET + Unsafe.ARRAY_OBJECT_INDEX_SCALE * 2; 152 153 public static int testUnsafe3Snippet(int v, Object[] array) { 154 int s = (Integer) UNSAFE.getObject(array, offsetObject1); 155 UNSAFE.putObject(array, offsetObject1, v); 156 UNSAFE.putObject(array, offsetObject2, v); 157 return s + (Integer) UNSAFE.getObject(array, offsetObject1) + (Integer) UNSAFE.getObject(array, offsetObject2); 158 } 159 160 @Test 161 public void testUnsafe3() { 162 StructuredGraph graph = processMethod("testUnsafe3Snippet"); 163 assertDeepEquals(1, graph.getNodes().filter(RawLoadNode.class).count()); 164 } 165 166 public static int testUnsafe4Snippet(int v, Object[] array) { 167 int s = (Integer) UNSAFE.getObject(array, offsetObject1); 168 UNSAFE.putObject(array, offsetObject1, v); 169 UNSAFE.putObject(array, offsetObject2, v); 170 array[v] = null; 171 return s + (Integer) UNSAFE.getObject(array, offsetObject1) + (Integer) UNSAFE.getObject(array, offsetObject2); 172 } 173 174 @Test 175 public void testUnsafe4() { 176 StructuredGraph graph = processMethod("testUnsafe4Snippet"); 177 assertDeepEquals(3, graph.getNodes().filter(RawLoadNode.class).count()); 178 } 179 180 protected StructuredGraph processMethod(final String snippet) { 181 StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO); 182 HighTierContext context = getDefaultHighTierContext(); 183 new InliningPhase(new CanonicalizerPhase()).apply(graph, context); 184 new PartialEscapePhase(false, true, new CanonicalizerPhase(), null, graph.getOptions()).apply(graph, context); 185 return graph; 186 } 187 }