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