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