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