1 /* 2 * Copyright (c) 2013, 2020, 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 org.graalvm.compiler.api.replacements.Snippet; 28 import org.graalvm.compiler.nodes.NamedLocationIdentity; 29 import org.graalvm.compiler.nodes.NodeView; 30 import org.graalvm.compiler.nodes.ReturnNode; 31 import org.graalvm.compiler.nodes.StructuredGraph; 32 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; 33 import org.graalvm.compiler.nodes.ValueNode; 34 import org.graalvm.compiler.nodes.calc.ConvertNode; 35 import org.graalvm.compiler.nodes.calc.SignExtendNode; 36 import org.graalvm.compiler.nodes.extended.JavaReadNode; 37 import org.graalvm.compiler.nodes.extended.JavaWriteNode; 38 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; 39 import org.graalvm.compiler.word.ObjectAccess; 40 import jdk.internal.vm.compiler.word.LocationIdentity; 41 import jdk.internal.vm.compiler.word.Pointer; 42 import jdk.internal.vm.compiler.word.WordFactory; 43 import org.junit.Assert; 44 import org.junit.Test; 45 46 import jdk.vm.ci.code.BytecodeFrame; 47 import jdk.vm.ci.meta.JavaKind; 48 49 /** 50 * Tests for the {@link Pointer} read and write operations. 51 */ 52 public class ObjectAccessTest extends SnippetsTest { 53 54 private static final LocationIdentity ID = NamedLocationIdentity.mutable("ObjectAccessTestID"); 55 private static final JavaKind[] KINDS = new JavaKind[]{JavaKind.Byte, JavaKind.Char, JavaKind.Short, JavaKind.Int, JavaKind.Long, JavaKind.Float, JavaKind.Double, JavaKind.Object}; 56 57 @Test testRead1()58 public void testRead1() { 59 for (JavaKind kind : KINDS) { 60 assertRead(parseEager("read" + kind.name() + "1", AllowAssumptions.YES), kind, true, ID); 61 } 62 } 63 64 @Test testRead2()65 public void testRead2() { 66 for (JavaKind kind : KINDS) { 67 assertRead(parseEager("read" + kind.name() + "2", AllowAssumptions.YES), kind, true, ID); 68 } 69 } 70 71 @Test testRead3()72 public void testRead3() { 73 for (JavaKind kind : KINDS) { 74 assertRead(parseEager("read" + kind.name() + "3", AllowAssumptions.YES), kind, true, LocationIdentity.any()); 75 } 76 } 77 78 @Test testWrite1()79 public void testWrite1() { 80 for (JavaKind kind : KINDS) { 81 assertWrite(parseEager("write" + kind.name() + "1", AllowAssumptions.YES), kind, true, ID); 82 } 83 } 84 85 @Test testWrite2()86 public void testWrite2() { 87 for (JavaKind kind : KINDS) { 88 assertWrite(parseEager("write" + kind.name() + "2", AllowAssumptions.YES), kind, true, ID); 89 } 90 } 91 92 @Test testWrite3()93 public void testWrite3() { 94 for (JavaKind kind : KINDS) { 95 assertWrite(parseEager("write" + kind.name() + "3", AllowAssumptions.YES), kind, true, LocationIdentity.any()); 96 } 97 } 98 assertRead(StructuredGraph graph, JavaKind kind, boolean indexConvert, LocationIdentity locationIdentity)99 private static void assertRead(StructuredGraph graph, JavaKind kind, boolean indexConvert, LocationIdentity locationIdentity) { 100 JavaReadNode read = (JavaReadNode) graph.start().next(); 101 Assert.assertEquals(kind.getStackKind(), read.stamp(NodeView.DEFAULT).getStackKind()); 102 103 OffsetAddressNode address = (OffsetAddressNode) read.getAddress(); 104 Assert.assertEquals(graph.getParameter(0), address.getBase()); 105 Assert.assertEquals(locationIdentity, read.getLocationIdentity()); 106 107 if (indexConvert) { 108 SignExtendNode convert = (SignExtendNode) address.getOffset(); 109 Assert.assertEquals(convert.getInputBits(), 32); 110 Assert.assertEquals(convert.getResultBits(), 64); 111 Assert.assertEquals(graph.getParameter(1), convert.getValue()); 112 } else { 113 Assert.assertEquals(graph.getParameter(1), address.getOffset()); 114 } 115 116 ReturnNode ret = (ReturnNode) read.next(); 117 Assert.assertEquals(read, ret.result()); 118 } 119 assertWrite(StructuredGraph graph, JavaKind kind, boolean indexConvert, LocationIdentity locationIdentity)120 private static void assertWrite(StructuredGraph graph, JavaKind kind, boolean indexConvert, LocationIdentity locationIdentity) { 121 JavaWriteNode write = (JavaWriteNode) graph.start().next(); 122 ValueNode valueNode = write.value(); 123 if (kind != kind.getStackKind()) { 124 while (valueNode instanceof ConvertNode) { 125 valueNode = ((ConvertNode) valueNode).getValue(); 126 } 127 } 128 Assert.assertEquals(graph.getParameter(2), valueNode); 129 OffsetAddressNode address = (OffsetAddressNode) write.getAddress(); 130 Assert.assertEquals(graph.getParameter(0), address.getBase()); 131 Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci); 132 133 Assert.assertEquals(locationIdentity, write.getKilledLocationIdentity()); 134 135 if (indexConvert) { 136 SignExtendNode convert = (SignExtendNode) address.getOffset(); 137 Assert.assertEquals(convert.getInputBits(), 32); 138 Assert.assertEquals(convert.getResultBits(), 64); 139 Assert.assertEquals(graph.getParameter(1), convert.getValue()); 140 } else { 141 Assert.assertEquals(graph.getParameter(1), address.getOffset()); 142 } 143 144 ReturnNode ret = (ReturnNode) write.next(); 145 Assert.assertEquals(null, ret.result()); 146 } 147 148 @Snippet readByte1(Object o, int offset)149 public static byte readByte1(Object o, int offset) { 150 return ObjectAccess.readByte(o, offset, ID); 151 } 152 153 @Snippet readByte2(Object o, int offset)154 public static byte readByte2(Object o, int offset) { 155 return ObjectAccess.readByte(o, WordFactory.signed(offset), ID); 156 } 157 158 @Snippet readByte3(Object o, int offset)159 public static byte readByte3(Object o, int offset) { 160 return ObjectAccess.readByte(o, offset); 161 } 162 163 @Snippet writeByte1(Object o, int offset, byte value)164 public static void writeByte1(Object o, int offset, byte value) { 165 ObjectAccess.writeByte(o, offset, value, ID); 166 } 167 168 @Snippet writeByte2(Object o, int offset, byte value)169 public static void writeByte2(Object o, int offset, byte value) { 170 ObjectAccess.writeByte(o, WordFactory.signed(offset), value, ID); 171 } 172 173 @Snippet writeByte3(Object o, int offset, byte value)174 public static void writeByte3(Object o, int offset, byte value) { 175 ObjectAccess.writeByte(o, offset, value); 176 } 177 178 @Snippet readChar1(Object o, int offset)179 public static char readChar1(Object o, int offset) { 180 return ObjectAccess.readChar(o, offset, ID); 181 } 182 183 @Snippet readChar2(Object o, int offset)184 public static char readChar2(Object o, int offset) { 185 return ObjectAccess.readChar(o, WordFactory.signed(offset), ID); 186 } 187 188 @Snippet readChar3(Object o, int offset)189 public static char readChar3(Object o, int offset) { 190 return ObjectAccess.readChar(o, offset); 191 } 192 193 @Snippet writeChar1(Object o, int offset, char value)194 public static void writeChar1(Object o, int offset, char value) { 195 ObjectAccess.writeChar(o, offset, value, ID); 196 } 197 198 @Snippet writeChar2(Object o, int offset, char value)199 public static void writeChar2(Object o, int offset, char value) { 200 ObjectAccess.writeChar(o, WordFactory.signed(offset), value, ID); 201 } 202 203 @Snippet writeChar3(Object o, int offset, char value)204 public static void writeChar3(Object o, int offset, char value) { 205 ObjectAccess.writeChar(o, offset, value); 206 } 207 208 @Snippet readShort1(Object o, int offset)209 public static short readShort1(Object o, int offset) { 210 return ObjectAccess.readShort(o, offset, ID); 211 } 212 213 @Snippet readShort2(Object o, int offset)214 public static short readShort2(Object o, int offset) { 215 return ObjectAccess.readShort(o, WordFactory.signed(offset), ID); 216 } 217 218 @Snippet readShort3(Object o, int offset)219 public static short readShort3(Object o, int offset) { 220 return ObjectAccess.readShort(o, offset); 221 } 222 223 @Snippet writeShort1(Object o, int offset, short value)224 public static void writeShort1(Object o, int offset, short value) { 225 ObjectAccess.writeShort(o, offset, value, ID); 226 } 227 228 @Snippet writeShort2(Object o, int offset, short value)229 public static void writeShort2(Object o, int offset, short value) { 230 ObjectAccess.writeShort(o, WordFactory.signed(offset), value, ID); 231 } 232 233 @Snippet writeShort3(Object o, int offset, short value)234 public static void writeShort3(Object o, int offset, short value) { 235 ObjectAccess.writeShort(o, offset, value); 236 } 237 238 @Snippet readInt1(Object o, int offset)239 public static int readInt1(Object o, int offset) { 240 return ObjectAccess.readInt(o, offset, ID); 241 } 242 243 @Snippet readInt2(Object o, int offset)244 public static int readInt2(Object o, int offset) { 245 return ObjectAccess.readInt(o, WordFactory.signed(offset), ID); 246 } 247 248 @Snippet readInt3(Object o, int offset)249 public static int readInt3(Object o, int offset) { 250 return ObjectAccess.readInt(o, offset); 251 } 252 253 @Snippet writeInt1(Object o, int offset, int value)254 public static void writeInt1(Object o, int offset, int value) { 255 ObjectAccess.writeInt(o, offset, value, ID); 256 } 257 258 @Snippet writeInt2(Object o, int offset, int value)259 public static void writeInt2(Object o, int offset, int value) { 260 ObjectAccess.writeInt(o, WordFactory.signed(offset), value, ID); 261 } 262 263 @Snippet writeInt3(Object o, int offset, int value)264 public static void writeInt3(Object o, int offset, int value) { 265 ObjectAccess.writeInt(o, offset, value); 266 } 267 268 @Snippet readLong1(Object o, int offset)269 public static long readLong1(Object o, int offset) { 270 return ObjectAccess.readLong(o, offset, ID); 271 } 272 273 @Snippet readLong2(Object o, int offset)274 public static long readLong2(Object o, int offset) { 275 return ObjectAccess.readLong(o, WordFactory.signed(offset), ID); 276 } 277 278 @Snippet readLong3(Object o, int offset)279 public static long readLong3(Object o, int offset) { 280 return ObjectAccess.readLong(o, offset); 281 } 282 283 @Snippet writeLong1(Object o, int offset, long value)284 public static void writeLong1(Object o, int offset, long value) { 285 ObjectAccess.writeLong(o, offset, value, ID); 286 } 287 288 @Snippet writeLong2(Object o, int offset, long value)289 public static void writeLong2(Object o, int offset, long value) { 290 ObjectAccess.writeLong(o, WordFactory.signed(offset), value, ID); 291 } 292 293 @Snippet writeLong3(Object o, int offset, long value)294 public static void writeLong3(Object o, int offset, long value) { 295 ObjectAccess.writeLong(o, offset, value); 296 } 297 298 @Snippet readFloat1(Object o, int offset)299 public static float readFloat1(Object o, int offset) { 300 return ObjectAccess.readFloat(o, offset, ID); 301 } 302 303 @Snippet readFloat2(Object o, int offset)304 public static float readFloat2(Object o, int offset) { 305 return ObjectAccess.readFloat(o, WordFactory.signed(offset), ID); 306 } 307 308 @Snippet readFloat3(Object o, int offset)309 public static float readFloat3(Object o, int offset) { 310 return ObjectAccess.readFloat(o, offset); 311 } 312 313 @Snippet writeFloat1(Object o, int offset, float value)314 public static void writeFloat1(Object o, int offset, float value) { 315 ObjectAccess.writeFloat(o, offset, value, ID); 316 } 317 318 @Snippet writeFloat2(Object o, int offset, float value)319 public static void writeFloat2(Object o, int offset, float value) { 320 ObjectAccess.writeFloat(o, WordFactory.signed(offset), value, ID); 321 } 322 323 @Snippet writeFloat3(Object o, int offset, float value)324 public static void writeFloat3(Object o, int offset, float value) { 325 ObjectAccess.writeFloat(o, offset, value); 326 } 327 328 @Snippet readDouble1(Object o, int offset)329 public static double readDouble1(Object o, int offset) { 330 return ObjectAccess.readDouble(o, offset, ID); 331 } 332 333 @Snippet readDouble2(Object o, int offset)334 public static double readDouble2(Object o, int offset) { 335 return ObjectAccess.readDouble(o, WordFactory.signed(offset), ID); 336 } 337 338 @Snippet readDouble3(Object o, int offset)339 public static double readDouble3(Object o, int offset) { 340 return ObjectAccess.readDouble(o, offset); 341 } 342 343 @Snippet writeDouble1(Object o, int offset, double value)344 public static void writeDouble1(Object o, int offset, double value) { 345 ObjectAccess.writeDouble(o, offset, value, ID); 346 } 347 348 @Snippet writeDouble2(Object o, int offset, double value)349 public static void writeDouble2(Object o, int offset, double value) { 350 ObjectAccess.writeDouble(o, WordFactory.signed(offset), value, ID); 351 } 352 353 @Snippet writeDouble3(Object o, int offset, double value)354 public static void writeDouble3(Object o, int offset, double value) { 355 ObjectAccess.writeDouble(o, offset, value); 356 } 357 358 @Snippet readObject1(Object o, int offset)359 public static Object readObject1(Object o, int offset) { 360 return ObjectAccess.readObject(o, offset, ID); 361 } 362 363 @Snippet readObject2(Object o, int offset)364 public static Object readObject2(Object o, int offset) { 365 return ObjectAccess.readObject(o, WordFactory.signed(offset), ID); 366 } 367 368 @Snippet readObject3(Object o, int offset)369 public static Object readObject3(Object o, int offset) { 370 return ObjectAccess.readObject(o, offset); 371 } 372 373 @Snippet writeObject1(Object o, int offset, Object value)374 public static void writeObject1(Object o, int offset, Object value) { 375 ObjectAccess.writeObject(o, offset, value, ID); 376 } 377 378 @Snippet writeObject2(Object o, int offset, Object value)379 public static void writeObject2(Object o, int offset, Object value) { 380 ObjectAccess.writeObject(o, WordFactory.signed(offset), value, ID); 381 } 382 383 @Snippet writeObject3(Object o, int offset, Object value)384 public static void writeObject3(Object o, int offset, Object value) { 385 ObjectAccess.writeObject(o, offset, value); 386 } 387 } 388