001/* 002 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.replacements.test; 024 025import jdk.internal.jvmci.code.*; 026import jdk.internal.jvmci.meta.*; 027 028import org.junit.*; 029 030import com.oracle.graal.compiler.test.*; 031import com.oracle.graal.nodes.*; 032import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; 033import com.oracle.graal.nodes.calc.*; 034import com.oracle.graal.nodes.extended.*; 035import com.oracle.graal.nodes.memory.address.*; 036import com.oracle.graal.phases.*; 037import com.oracle.graal.phases.common.*; 038import com.oracle.graal.phases.tiers.*; 039import com.oracle.graal.replacements.*; 040import com.oracle.graal.word.*; 041import com.oracle.graal.word.nodes.*; 042 043/** 044 * Tests for the {@link Pointer} read and write operations. 045 */ 046public class PointerTest extends GraalCompilerTest implements Snippets { 047 048 private static final LocationIdentity ID = NamedLocationIdentity.mutable("ID"); 049 private static final Kind[] KINDS = new Kind[]{Kind.Byte, Kind.Char, Kind.Short, Kind.Int, Kind.Long, Kind.Float, Kind.Double, Kind.Object}; 050 private final TargetDescription target; 051 private final ReplacementsImpl installer; 052 053 public PointerTest() { 054 target = getCodeCache().getTarget(); 055 installer = (ReplacementsImpl) getProviders().getReplacements(); 056 } 057 058 @Override 059 protected StructuredGraph parseEager(ResolvedJavaMethod m, AllowAssumptions allowAssumptions) { 060 return installer.makeGraph(m, null, null); 061 } 062 063 @Test 064 public void testRead1() { 065 for (Kind kind : KINDS) { 066 assertRead(parseEager("read" + kind.name() + "1", AllowAssumptions.YES), kind, true, ID); 067 } 068 } 069 070 @Test 071 public void testRead2() { 072 for (Kind kind : KINDS) { 073 assertRead(parseEager("read" + kind.name() + "2", AllowAssumptions.YES), kind, true, ID); 074 } 075 } 076 077 @Test 078 public void testRead3() { 079 for (Kind kind : KINDS) { 080 assertRead(parseEager("read" + kind.name() + "3", AllowAssumptions.YES), kind, true, LocationIdentity.any()); 081 } 082 } 083 084 @Test 085 public void testWrite1() { 086 for (Kind kind : KINDS) { 087 assertWrite(parseEager("write" + kind.name() + "1", AllowAssumptions.YES), true, ID); 088 } 089 } 090 091 @Test 092 public void testWrite2() { 093 for (Kind kind : KINDS) { 094 assertWrite(parseEager("write" + kind.name() + "2", AllowAssumptions.YES), true, ID); 095 } 096 } 097 098 @Test 099 public void testWrite3() { 100 for (Kind kind : KINDS) { 101 assertWrite(parseEager("write" + kind.name() + "3", AllowAssumptions.YES), true, LocationIdentity.any()); 102 } 103 } 104 105 private void assertRead(StructuredGraph graph, Kind kind, boolean indexConvert, LocationIdentity locationIdentity) { 106 WordCastNode cast = (WordCastNode) graph.start().next(); 107 108 JavaReadNode read = (JavaReadNode) cast.next(); 109 Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind()); 110 111 OffsetAddressNode address = (OffsetAddressNode) read.getAddress(); 112 Assert.assertEquals(cast, address.getBase()); 113 Assert.assertEquals(graph.getParameter(0), cast.getInput()); 114 Assert.assertEquals(target.wordKind, cast.stamp().getStackKind()); 115 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 void assertWrite(StructuredGraph graph, boolean indexConvert, LocationIdentity locationIdentity) { 132 WordCastNode cast = (WordCastNode) graph.start().next(); 133 134 JavaWriteNode write = (JavaWriteNode) cast.next(); 135 Assert.assertEquals(graph.getParameter(2), write.value()); 136 Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci); 137 138 OffsetAddressNode address = (OffsetAddressNode) write.getAddress(); 139 Assert.assertEquals(cast, address.getBase()); 140 Assert.assertEquals(graph.getParameter(0), cast.getInput()); 141 Assert.assertEquals(target.wordKind, cast.stamp().getStackKind()); 142 143 Assert.assertEquals(locationIdentity, write.getLocationIdentity()); 144 145 if (indexConvert) { 146 SignExtendNode convert = (SignExtendNode) address.getOffset(); 147 Assert.assertEquals(convert.getInputBits(), 32); 148 Assert.assertEquals(convert.getResultBits(), 64); 149 Assert.assertEquals(graph.getParameter(1), convert.getValue()); 150 } else { 151 Assert.assertEquals(graph.getParameter(1), address.getOffset()); 152 } 153 154 ReturnNode ret = (ReturnNode) write.next(); 155 Assert.assertEquals(null, ret.result()); 156 } 157 158 @Snippet 159 public static byte readByte1(Object o, int offset) { 160 return Word.fromObject(o).readByte(offset, ID); 161 } 162 163 @Snippet 164 public static byte readByte2(Object o, int offset) { 165 return Word.fromObject(o).readByte(Word.signed(offset), ID); 166 } 167 168 @Snippet 169 public static byte readByte3(Object o, int offset) { 170 return Word.fromObject(o).readByte(offset); 171 } 172 173 @Snippet 174 public static void writeByte1(Object o, int offset, byte value) { 175 Word.fromObject(o).writeByte(offset, value, ID); 176 } 177 178 @Snippet 179 public static void writeByte2(Object o, int offset, byte value) { 180 Word.fromObject(o).writeByte(Word.signed(offset), value, ID); 181 } 182 183 @Snippet 184 public static void writeByte3(Object o, int offset, byte value) { 185 Word.fromObject(o).writeByte(offset, value); 186 } 187 188 @Snippet 189 public static char readChar1(Object o, int offset) { 190 return Word.fromObject(o).readChar(offset, ID); 191 } 192 193 @Snippet 194 public static char readChar2(Object o, int offset) { 195 return Word.fromObject(o).readChar(Word.signed(offset), ID); 196 } 197 198 @Snippet 199 public static char readChar3(Object o, int offset) { 200 return Word.fromObject(o).readChar(offset); 201 } 202 203 @Snippet 204 public static void writeChar1(Object o, int offset, char value) { 205 Word.fromObject(o).writeChar(offset, value, ID); 206 } 207 208 @Snippet 209 public static void writeChar2(Object o, int offset, char value) { 210 Word.fromObject(o).writeChar(Word.signed(offset), value, ID); 211 } 212 213 @Snippet 214 public static void writeChar3(Object o, int offset, char value) { 215 Word.fromObject(o).writeChar(offset, value); 216 } 217 218 @Snippet 219 public static short readShort1(Object o, int offset) { 220 return Word.fromObject(o).readShort(offset, ID); 221 } 222 223 @Snippet 224 public static short readShort2(Object o, int offset) { 225 return Word.fromObject(o).readShort(Word.signed(offset), ID); 226 } 227 228 @Snippet 229 public static short readShort3(Object o, int offset) { 230 return Word.fromObject(o).readShort(offset); 231 } 232 233 @Snippet 234 public static void writeShort1(Object o, int offset, short value) { 235 Word.fromObject(o).writeShort(offset, value, ID); 236 } 237 238 @Snippet 239 public static void writeShort2(Object o, int offset, short value) { 240 Word.fromObject(o).writeShort(Word.signed(offset), value, ID); 241 } 242 243 @Snippet 244 public static void writeShort3(Object o, int offset, short value) { 245 Word.fromObject(o).writeShort(offset, value); 246 } 247 248 @Snippet 249 public static int readInt1(Object o, int offset) { 250 return Word.fromObject(o).readInt(offset, ID); 251 } 252 253 @Snippet 254 public static int readInt2(Object o, int offset) { 255 return Word.fromObject(o).readInt(Word.signed(offset), ID); 256 } 257 258 @Snippet 259 public static int readInt3(Object o, int offset) { 260 return Word.fromObject(o).readInt(offset); 261 } 262 263 @Snippet 264 public static void writeInt1(Object o, int offset, int value) { 265 Word.fromObject(o).writeInt(offset, value, ID); 266 } 267 268 @Snippet 269 public static void writeInt2(Object o, int offset, int value) { 270 Word.fromObject(o).writeInt(Word.signed(offset), value, ID); 271 } 272 273 @Snippet 274 public static void writeInt3(Object o, int offset, int value) { 275 Word.fromObject(o).writeInt(offset, value); 276 } 277 278 @Snippet 279 public static long readLong1(Object o, int offset) { 280 return Word.fromObject(o).readLong(offset, ID); 281 } 282 283 @Snippet 284 public static long readLong2(Object o, int offset) { 285 return Word.fromObject(o).readLong(Word.signed(offset), ID); 286 } 287 288 @Snippet 289 public static long readLong3(Object o, int offset) { 290 return Word.fromObject(o).readLong(offset); 291 } 292 293 @Snippet 294 public static void writeLong1(Object o, int offset, long value) { 295 Word.fromObject(o).writeLong(offset, value, ID); 296 } 297 298 @Snippet 299 public static void writeLong2(Object o, int offset, long value) { 300 Word.fromObject(o).writeLong(Word.signed(offset), value, ID); 301 } 302 303 @Snippet 304 public static void writeLong3(Object o, int offset, long value) { 305 Word.fromObject(o).writeLong(offset, value); 306 } 307 308 @Snippet 309 public static float readFloat1(Object o, int offset) { 310 return Word.fromObject(o).readFloat(offset, ID); 311 } 312 313 @Snippet 314 public static float readFloat2(Object o, int offset) { 315 return Word.fromObject(o).readFloat(Word.signed(offset), ID); 316 } 317 318 @Snippet 319 public static float readFloat3(Object o, int offset) { 320 return Word.fromObject(o).readFloat(offset); 321 } 322 323 @Snippet 324 public static void writeFloat1(Object o, int offset, float value) { 325 Word.fromObject(o).writeFloat(offset, value, ID); 326 } 327 328 @Snippet 329 public static void writeFloat2(Object o, int offset, float value) { 330 Word.fromObject(o).writeFloat(Word.signed(offset), value, ID); 331 } 332 333 @Snippet 334 public static void writeFloat3(Object o, int offset, float value) { 335 Word.fromObject(o).writeFloat(offset, value); 336 } 337 338 @Snippet 339 public static double readDouble1(Object o, int offset) { 340 return Word.fromObject(o).readDouble(offset, ID); 341 } 342 343 @Snippet 344 public static double readDouble2(Object o, int offset) { 345 return Word.fromObject(o).readDouble(Word.signed(offset), ID); 346 } 347 348 @Snippet 349 public static double readDouble3(Object o, int offset) { 350 return Word.fromObject(o).readDouble(offset); 351 } 352 353 @Snippet 354 public static void writeDouble1(Object o, int offset, double value) { 355 Word.fromObject(o).writeDouble(offset, value, ID); 356 } 357 358 @Snippet 359 public static void writeDouble2(Object o, int offset, double value) { 360 Word.fromObject(o).writeDouble(Word.signed(offset), value, ID); 361 } 362 363 @Snippet 364 public static void writeDouble3(Object o, int offset, double value) { 365 Word.fromObject(o).writeDouble(offset, value); 366 } 367 368 @Snippet 369 public static Object readObject1(Object o, int offset) { 370 return Word.fromObject(o).readObject(offset, ID); 371 } 372 373 @Snippet 374 public static Object readObject2(Object o, int offset) { 375 return Word.fromObject(o).readObject(Word.signed(offset), ID); 376 } 377 378 @Snippet 379 public static Object readObject3(Object o, int offset) { 380 return Word.fromObject(o).readObject(offset); 381 } 382 383 @Snippet 384 public static void writeObject1(Object o, int offset, Object value) { 385 Word.fromObject(o).writeObject(offset, value, ID); 386 } 387 388 @Snippet 389 public static void writeObject2(Object o, int offset, Object value) { 390 Word.fromObject(o).writeObject(Word.signed(offset), value, ID); 391 } 392 393 @Snippet 394 public static void writeObject3(Object o, int offset, Object value) { 395 Word.fromObject(o).writeObject(offset, value); 396 } 397 398 private void assertNumWordCasts(String snippetName, int expectedWordCasts) { 399 HighTierContext context = new HighTierContext(getProviders(), null, OptimisticOptimizations.ALL); 400 401 StructuredGraph graph = parseEager(snippetName, AllowAssumptions.YES); 402 new CanonicalizerPhase().apply(graph, context); 403 Assert.assertEquals(expectedWordCasts, graph.getNodes().filter(WordCastNode.class).count()); 404 } 405 406 @Test 407 public void testUnusedFromObject() { 408 assertNumWordCasts("unusedFromObject", 0); 409 } 410 411 @Snippet 412 public static void unusedFromObject(Object o) { 413 Word.fromObject(o); 414 } 415 416 @Test 417 public void testUnusedRawValue() { 418 assertNumWordCasts("unusedRawValue", 0); 419 } 420 421 @Snippet 422 public static void unusedRawValue(Object o) { 423 Word.fromObject(o).rawValue(); 424 } 425 426 @Test 427 public void testUsedRawValue() { 428 assertNumWordCasts("usedRawValue", 1); 429 } 430 431 @Snippet 432 public static long usedRawValue(Object o) { 433 return Word.fromObject(o).rawValue(); 434 } 435 436 @Test 437 public void testUnusedToObject() { 438 assertNumWordCasts("unusedToObject", 0); 439 } 440 441 @Snippet 442 public static void unusedToObject(Word w) { 443 w.toObject(); 444 } 445 446 @Test 447 public void testUsedToObject() { 448 assertNumWordCasts("usedToObject", 1); 449 } 450 451 @Snippet 452 public static Object usedToObject(Word w) { 453 return w.toObject(); 454 } 455}