1 /* 2 * Copyright (c) 2012, 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.word; 24 25 import static org.graalvm.compiler.word.UnsafeAccess.UNSAFE; 26 27 import java.lang.annotation.ElementType; 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.lang.annotation.Target; 31 32 import org.graalvm.compiler.core.common.LocationIdentity; 33 import org.graalvm.compiler.core.common.calc.Condition; 34 import org.graalvm.compiler.core.common.calc.UnsignedMath; 35 import org.graalvm.compiler.debug.GraalError; 36 import org.graalvm.compiler.nodes.ValueNode; 37 import org.graalvm.compiler.nodes.calc.AddNode; 38 import org.graalvm.compiler.nodes.calc.AndNode; 39 import org.graalvm.compiler.nodes.calc.LeftShiftNode; 40 import org.graalvm.compiler.nodes.calc.MulNode; 41 import org.graalvm.compiler.nodes.calc.OrNode; 42 import org.graalvm.compiler.nodes.calc.RightShiftNode; 43 import org.graalvm.compiler.nodes.calc.SignedDivNode; 44 import org.graalvm.compiler.nodes.calc.SignedRemNode; 45 import org.graalvm.compiler.nodes.calc.SubNode; 46 import org.graalvm.compiler.nodes.calc.UnsignedDivNode; 47 import org.graalvm.compiler.nodes.calc.UnsignedRemNode; 48 import org.graalvm.compiler.nodes.calc.UnsignedRightShiftNode; 49 import org.graalvm.compiler.nodes.calc.XorNode; 50 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; 51 import org.graalvm.compiler.nodes.memory.address.AddressNode.Address; 52 53 public abstract class Word implements Signed, Unsigned, Pointer { 54 55 /** 56 * Links a method to a canonical operation represented by an {@link Opcode} val. 57 */ 58 @Retention(RetentionPolicy.RUNTIME) 59 @Target(ElementType.METHOD) 60 public @interface Operation { 61 62 Class<? extends ValueNode> node() default ValueNode.class; 63 64 boolean rightOperandIsInt() default false; 65 66 Opcode opcode() default Opcode.NODE_CLASS; 67 68 Condition condition() default Condition.EQ; 69 } 70 71 /** 72 * The canonical {@link Operation} represented by a method in the {@link Word} class. 73 */ 74 // @formatter:off 75 public enum Opcode { 76 NODE_CLASS, 77 COMPARISON, 78 NOT, 79 READ_POINTER, 80 READ_OBJECT, 81 READ_BARRIERED, 82 READ_HEAP, 83 WRITE_POINTER, 84 WRITE_OBJECT, 85 WRITE_BARRIERED, 86 INITIALIZE, 87 ZERO, 88 FROM_UNSIGNED, 89 FROM_SIGNED, 90 FROM_ADDRESS, 91 OBJECT_TO_TRACKED, 92 OBJECT_TO_UNTRACKED, 93 TO_OBJECT, 94 TO_RAW_VALUE, 95 } 96 // @formatter:on 97 98 /* 99 * Outside users should use the different signed() and unsigned() methods to ensure proper 100 * expansion of 32-bit values on 64-bit systems. 101 */ 102 private static Word box(long val) { 103 return HostedWord.boxLong(val); 104 } 105 106 protected abstract long unbox(); 107 108 private static Word intParam(int val) { 109 return box(val); 110 } 111 112 /** 113 * The constant 0, i.e., the word with no bits set. There is no difference between a signed and 114 * unsigned zero. 115 * 116 * @return the constant 0. 117 */ 118 @Operation(opcode = Opcode.ZERO) 119 public static Word zero() { 120 return box(0L); 121 } 122 123 /** 124 * Unsafe conversion from a Java long value to a Word. The parameter is treated as an unsigned 125 * 64-bit value (in contrast to the semantics of a Java long). 126 * 127 * @param val a 64 bit unsigned value 128 * @return the value cast to Word 129 */ 130 @Operation(opcode = Opcode.FROM_UNSIGNED) 131 public static Word unsigned(long val) { 132 return box(val); 133 } 134 135 /** 136 * Unsafe conversion from a Java long value to a {@link PointerBase pointer}. The parameter is 137 * treated as an unsigned 64-bit value (in contrast to the semantics of a Java long). 138 * 139 * @param val a 64 bit unsigned value 140 * @return the value cast to PointerBase 141 */ 142 @Operation(opcode = Opcode.FROM_UNSIGNED) 143 @SuppressWarnings("unchecked") 144 public static <T extends PointerBase> T pointer(long val) { 145 return (T) box(val); 146 } 147 148 /** 149 * Unsafe conversion from a Java int value to a Word. The parameter is treated as an unsigned 150 * 32-bit value (in contrast to the semantics of a Java int). 151 * 152 * @param val a 32 bit unsigned value 153 * @return the value cast to Word 154 */ 155 @Operation(opcode = Opcode.FROM_UNSIGNED) 156 public static Word unsigned(int val) { 157 return box(val & 0xffffffffL); 158 } 159 160 /** 161 * Unsafe conversion from a Java long value to a Word. The parameter is treated as a signed 162 * 64-bit value (unchanged semantics of a Java long). 163 * 164 * @param val a 64 bit signed value 165 * @return the value cast to Word 166 */ 167 @Operation(opcode = Opcode.FROM_SIGNED) 168 public static Word signed(long val) { 169 return box(val); 170 } 171 172 /** 173 * Unsafe conversion from a Java int value to a Word. The parameter is treated as a signed 174 * 32-bit value (unchanged semantics of a Java int). 175 * 176 * @param val a 32 bit signed value 177 * @return the value cast to Word 178 */ 179 @Operation(opcode = Opcode.FROM_SIGNED) 180 public static Word signed(int val) { 181 return box(val); 182 } 183 184 @Override 185 @Operation(opcode = Opcode.TO_RAW_VALUE) 186 public long rawValue() { 187 return unbox(); 188 } 189 190 /** 191 * Convert an {@link Object} to a {@link Pointer}, keeping the reference information. If the 192 * returned pointer or any value derived from it is alive across a safepoint, it will be 193 * tracked. Depending on the arithmetic on the pointer and the capabilities of the backend to 194 * deal with derived references, this may work correctly, or result in a compiler error. 195 */ 196 @Operation(opcode = Opcode.OBJECT_TO_TRACKED) 197 public static native Pointer objectToTrackedPointer(Object val); 198 199 /** 200 * Convert an {@link Object} to a {@link Pointer}, dropping the reference information. If the 201 * returned pointer or any value derived from it is alive across a safepoint, it will be treated 202 * as a simple integer and not tracked by the garbage collector. 203 * <p> 204 * This is a dangerous operation, the GC could move the object without updating the pointer! Use 205 * only in combination with some mechanism to prevent the GC from moving or freeing the object 206 * as long as the pointer is in use. 207 * <p> 208 * If the result value should not be alive across a safepoint, it's better to use 209 * {@link #objectToTrackedPointer(Object)} instead. 210 */ 211 @Operation(opcode = Opcode.OBJECT_TO_UNTRACKED) 212 public static native Pointer objectToUntrackedPointer(Object val); 213 214 @Operation(opcode = Opcode.FROM_ADDRESS) 215 public static native Pointer fromAddress(Address address); 216 217 @Override 218 @Operation(opcode = Opcode.TO_OBJECT) 219 public native Object toObject(); 220 221 @Override 222 @Operation(node = AddNode.class) 223 public Word add(Signed val) { 224 return add((Word) val); 225 } 226 227 @Override 228 @Operation(node = AddNode.class) 229 public Word add(Unsigned val) { 230 return add((Word) val); 231 } 232 233 @Override 234 @Operation(node = AddNode.class) 235 public Word add(int val) { 236 return add(intParam(val)); 237 } 238 239 @Operation(node = AddNode.class) 240 public Word add(Word val) { 241 return box(unbox() + val.unbox()); 242 } 243 244 @Override 245 @Operation(node = SubNode.class) 246 public Word subtract(Signed val) { 247 return subtract((Word) val); 248 } 249 250 @Override 251 @Operation(node = SubNode.class) 252 public Word subtract(Unsigned val) { 253 return subtract((Word) val); 254 } 255 256 @Override 257 @Operation(node = SubNode.class) 258 public Word subtract(int val) { 259 return subtract(intParam(val)); 260 } 261 262 @Operation(node = SubNode.class) 263 public Word subtract(Word val) { 264 return box(unbox() - val.unbox()); 265 } 266 267 @Override 268 @Operation(node = MulNode.class) 269 public Word multiply(Signed val) { 270 return multiply((Word) val); 271 } 272 273 @Override 274 @Operation(node = MulNode.class) 275 public Word multiply(Unsigned val) { 276 return multiply((Word) val); 277 } 278 279 @Override 280 @Operation(node = MulNode.class) 281 public Word multiply(int val) { 282 return multiply(intParam(val)); 283 } 284 285 @Operation(node = MulNode.class) 286 public Word multiply(Word val) { 287 return box(unbox() * val.unbox()); 288 } 289 290 @Override 291 @Operation(node = SignedDivNode.class) 292 public Word signedDivide(Signed val) { 293 return signedDivide((Word) val); 294 } 295 296 @Override 297 @Operation(node = SignedDivNode.class) 298 public Word signedDivide(int val) { 299 return signedDivide(intParam(val)); 300 } 301 302 @Operation(node = SignedDivNode.class) 303 public Word signedDivide(Word val) { 304 return box(unbox() / val.unbox()); 305 } 306 307 @Override 308 @Operation(node = UnsignedDivNode.class) 309 public Word unsignedDivide(Unsigned val) { 310 return unsignedDivide((Word) val); 311 } 312 313 @Override 314 @Operation(node = UnsignedDivNode.class) 315 public Word unsignedDivide(int val) { 316 return signedDivide(intParam(val)); 317 } 318 319 @Operation(node = UnsignedDivNode.class) 320 public Word unsignedDivide(Word val) { 321 return box(Long.divideUnsigned(unbox(), val.unbox())); 322 } 323 324 @Override 325 @Operation(node = SignedRemNode.class) 326 public Word signedRemainder(Signed val) { 327 return signedRemainder((Word) val); 328 } 329 330 @Override 331 @Operation(node = SignedRemNode.class) 332 public Word signedRemainder(int val) { 333 return signedRemainder(intParam(val)); 334 } 335 336 @Operation(node = SignedRemNode.class) 337 public Word signedRemainder(Word val) { 338 return box(unbox() % val.unbox()); 339 } 340 341 @Override 342 @Operation(node = UnsignedRemNode.class) 343 public Word unsignedRemainder(Unsigned val) { 344 return unsignedRemainder((Word) val); 345 } 346 347 @Override 348 @Operation(node = UnsignedRemNode.class) 349 public Word unsignedRemainder(int val) { 350 return signedRemainder(intParam(val)); 351 } 352 353 @Operation(node = UnsignedRemNode.class) 354 public Word unsignedRemainder(Word val) { 355 return box(Long.remainderUnsigned(unbox(), val.unbox())); 356 } 357 358 @Override 359 @Operation(node = LeftShiftNode.class, rightOperandIsInt = true) 360 public Word shiftLeft(Unsigned val) { 361 return shiftLeft((Word) val); 362 } 363 364 @Override 365 @Operation(node = LeftShiftNode.class, rightOperandIsInt = true) 366 public Word shiftLeft(int val) { 367 return shiftLeft(intParam(val)); 368 } 369 370 @Operation(node = LeftShiftNode.class, rightOperandIsInt = true) 371 public Word shiftLeft(Word val) { 372 return box(unbox() << val.unbox()); 373 } 374 375 @Override 376 @Operation(node = RightShiftNode.class, rightOperandIsInt = true) 377 public Word signedShiftRight(Unsigned val) { 378 return signedShiftRight((Word) val); 379 } 380 381 @Override 382 @Operation(node = RightShiftNode.class, rightOperandIsInt = true) 383 public Word signedShiftRight(int val) { 384 return signedShiftRight(intParam(val)); 385 } 386 387 @Operation(node = RightShiftNode.class, rightOperandIsInt = true) 388 public Word signedShiftRight(Word val) { 389 return box(unbox() >> val.unbox()); 390 } 391 392 @Override 393 @Operation(node = UnsignedRightShiftNode.class, rightOperandIsInt = true) 394 public Word unsignedShiftRight(Unsigned val) { 395 return unsignedShiftRight((Word) val); 396 } 397 398 @Override 399 @Operation(node = UnsignedRightShiftNode.class, rightOperandIsInt = true) 400 public Word unsignedShiftRight(int val) { 401 return unsignedShiftRight(intParam(val)); 402 } 403 404 @Operation(node = UnsignedRightShiftNode.class, rightOperandIsInt = true) 405 public Word unsignedShiftRight(Word val) { 406 return box(unbox() >>> val.unbox()); 407 } 408 409 @Override 410 @Operation(node = AndNode.class) 411 public Word and(Signed val) { 412 return and((Word) val); 413 } 414 415 @Override 416 @Operation(node = AndNode.class) 417 public Word and(Unsigned val) { 418 return and((Word) val); 419 } 420 421 @Override 422 @Operation(node = AndNode.class) 423 public Word and(int val) { 424 return and(intParam(val)); 425 } 426 427 @Operation(node = AndNode.class) 428 public Word and(Word val) { 429 return box(unbox() & val.unbox()); 430 } 431 432 @Override 433 @Operation(node = OrNode.class) 434 public Word or(Signed val) { 435 return or((Word) val); 436 } 437 438 @Override 439 @Operation(node = OrNode.class) 440 public Word or(Unsigned val) { 441 return or((Word) val); 442 } 443 444 @Override 445 @Operation(node = OrNode.class) 446 public Word or(int val) { 447 return or(intParam(val)); 448 } 449 450 @Operation(node = OrNode.class) 451 public Word or(Word val) { 452 return box(unbox() | val.unbox()); 453 } 454 455 @Override 456 @Operation(node = XorNode.class) 457 public Word xor(Signed val) { 458 return xor((Word) val); 459 } 460 461 @Override 462 @Operation(node = XorNode.class) 463 public Word xor(Unsigned val) { 464 return xor((Word) val); 465 } 466 467 @Override 468 @Operation(node = XorNode.class) 469 public Word xor(int val) { 470 return xor(intParam(val)); 471 } 472 473 @Operation(node = XorNode.class) 474 public Word xor(Word val) { 475 return box(unbox() ^ val.unbox()); 476 } 477 478 @Override 479 @Operation(opcode = Opcode.NOT) 480 public Word not() { 481 return box(~unbox()); 482 } 483 484 @Override 485 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 486 public boolean equal(ComparableWord val) { 487 return equal((Word) val); 488 } 489 490 @Override 491 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 492 public boolean equal(Signed val) { 493 return equal((Word) val); 494 } 495 496 @Override 497 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 498 public boolean equal(Unsigned val) { 499 return equal((Word) val); 500 } 501 502 @Override 503 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 504 public boolean equal(int val) { 505 return equal(intParam(val)); 506 } 507 508 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 509 public boolean equal(Word val) { 510 return unbox() == val.unbox(); 511 } 512 513 @Override 514 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 515 public boolean notEqual(ComparableWord val) { 516 return notEqual((Word) val); 517 } 518 519 @Override 520 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 521 public boolean notEqual(Signed val) { 522 return notEqual((Word) val); 523 } 524 525 @Override 526 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 527 public boolean notEqual(Unsigned val) { 528 return notEqual((Word) val); 529 } 530 531 @Override 532 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 533 public boolean notEqual(int val) { 534 return notEqual(intParam(val)); 535 } 536 537 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 538 public boolean notEqual(Word val) { 539 return unbox() != val.unbox(); 540 } 541 542 @Override 543 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LT) 544 public boolean lessThan(Signed val) { 545 return lessThan((Word) val); 546 } 547 548 @Override 549 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LT) 550 public boolean lessThan(int val) { 551 return lessThan(intParam(val)); 552 } 553 554 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LT) 555 public boolean lessThan(Word val) { 556 return unbox() < val.unbox(); 557 } 558 559 @Override 560 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LE) 561 public boolean lessOrEqual(Signed val) { 562 return lessOrEqual((Word) val); 563 } 564 565 @Override 566 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LE) 567 public boolean lessOrEqual(int val) { 568 return lessOrEqual(intParam(val)); 569 } 570 571 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LE) 572 public boolean lessOrEqual(Word val) { 573 return unbox() <= val.unbox(); 574 } 575 576 @Override 577 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GT) 578 public boolean greaterThan(Signed val) { 579 return greaterThan((Word) val); 580 } 581 582 @Override 583 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GT) 584 public boolean greaterThan(int val) { 585 return greaterThan(intParam(val)); 586 } 587 588 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GT) 589 public boolean greaterThan(Word val) { 590 return unbox() > val.unbox(); 591 } 592 593 @Override 594 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GE) 595 public boolean greaterOrEqual(Signed val) { 596 return greaterOrEqual((Word) val); 597 } 598 599 @Override 600 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GE) 601 public boolean greaterOrEqual(int val) { 602 return greaterOrEqual(intParam(val)); 603 } 604 605 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GE) 606 public boolean greaterOrEqual(Word val) { 607 return unbox() >= val.unbox(); 608 } 609 610 @Override 611 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BT) 612 public boolean belowThan(Unsigned val) { 613 return belowThan((Word) val); 614 } 615 616 @Override 617 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BT) 618 public boolean belowThan(int val) { 619 return belowThan(intParam(val)); 620 } 621 622 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BT) 623 public boolean belowThan(Word val) { 624 return UnsignedMath.belowThan(unbox(), val.unbox()); 625 } 626 627 @Override 628 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BE) 629 public boolean belowOrEqual(Unsigned val) { 630 return belowOrEqual((Word) val); 631 } 632 633 @Override 634 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BE) 635 public boolean belowOrEqual(int val) { 636 return belowOrEqual(intParam(val)); 637 } 638 639 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BE) 640 public boolean belowOrEqual(Word val) { 641 return UnsignedMath.belowOrEqual(unbox(), val.unbox()); 642 } 643 644 @Override 645 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AT) 646 public boolean aboveThan(Unsigned val) { 647 return aboveThan((Word) val); 648 } 649 650 @Override 651 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AT) 652 public boolean aboveThan(int val) { 653 return aboveThan(intParam(val)); 654 } 655 656 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AT) 657 public boolean aboveThan(Word val) { 658 return UnsignedMath.aboveThan(unbox(), val.unbox()); 659 } 660 661 @Override 662 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AE) 663 public boolean aboveOrEqual(Unsigned val) { 664 return aboveOrEqual((Word) val); 665 } 666 667 @Override 668 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AE) 669 public boolean aboveOrEqual(int val) { 670 return aboveOrEqual(intParam(val)); 671 } 672 673 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AE) 674 public boolean aboveOrEqual(Word val) { 675 return UnsignedMath.aboveOrEqual(unbox(), val.unbox()); 676 } 677 678 @Override 679 @Operation(opcode = Opcode.READ_POINTER) 680 public byte readByte(WordBase offset, LocationIdentity locationIdentity) { 681 return UNSAFE.getByte(add((Word) offset).unbox()); 682 } 683 684 @Override 685 @Operation(opcode = Opcode.READ_POINTER) 686 public char readChar(WordBase offset, LocationIdentity locationIdentity) { 687 return UNSAFE.getChar(add((Word) offset).unbox()); 688 } 689 690 @Override 691 @Operation(opcode = Opcode.READ_POINTER) 692 public short readShort(WordBase offset, LocationIdentity locationIdentity) { 693 return UNSAFE.getShort(add((Word) offset).unbox()); 694 } 695 696 @Override 697 @Operation(opcode = Opcode.READ_POINTER) 698 public int readInt(WordBase offset, LocationIdentity locationIdentity) { 699 return UNSAFE.getInt(add((Word) offset).unbox()); 700 } 701 702 @Override 703 @Operation(opcode = Opcode.READ_POINTER) 704 public long readLong(WordBase offset, LocationIdentity locationIdentity) { 705 return UNSAFE.getLong(add((Word) offset).unbox()); 706 } 707 708 @Override 709 @Operation(opcode = Opcode.READ_POINTER) 710 public float readFloat(WordBase offset, LocationIdentity locationIdentity) { 711 return UNSAFE.getFloat(add((Word) offset).unbox()); 712 } 713 714 @Override 715 @Operation(opcode = Opcode.READ_POINTER) 716 public double readDouble(WordBase offset, LocationIdentity locationIdentity) { 717 return UNSAFE.getDouble(add((Word) offset).unbox()); 718 } 719 720 @Override 721 @Operation(opcode = Opcode.READ_POINTER) 722 public Word readWord(WordBase offset, LocationIdentity locationIdentity) { 723 return box(UNSAFE.getAddress(add((Word) offset).unbox())); 724 } 725 726 @Override 727 @Operation(opcode = Opcode.READ_POINTER) 728 public native Object readObject(WordBase offset, LocationIdentity locationIdentity); 729 730 @Override 731 @Operation(opcode = Opcode.READ_POINTER) 732 public byte readByte(int offset, LocationIdentity locationIdentity) { 733 return readByte(signed(offset), locationIdentity); 734 } 735 736 @Override 737 @Operation(opcode = Opcode.READ_POINTER) 738 public char readChar(int offset, LocationIdentity locationIdentity) { 739 return readChar(signed(offset), locationIdentity); 740 } 741 742 @Override 743 @Operation(opcode = Opcode.READ_POINTER) 744 public short readShort(int offset, LocationIdentity locationIdentity) { 745 return readShort(signed(offset), locationIdentity); 746 } 747 748 @Override 749 @Operation(opcode = Opcode.READ_POINTER) 750 public int readInt(int offset, LocationIdentity locationIdentity) { 751 return readInt(signed(offset), locationIdentity); 752 } 753 754 @Override 755 @Operation(opcode = Opcode.READ_POINTER) 756 public long readLong(int offset, LocationIdentity locationIdentity) { 757 return readLong(signed(offset), locationIdentity); 758 } 759 760 @Override 761 @Operation(opcode = Opcode.READ_POINTER) 762 public float readFloat(int offset, LocationIdentity locationIdentity) { 763 return readFloat(signed(offset), locationIdentity); 764 } 765 766 @Override 767 @Operation(opcode = Opcode.READ_POINTER) 768 public double readDouble(int offset, LocationIdentity locationIdentity) { 769 return readDouble(signed(offset), locationIdentity); 770 } 771 772 @Override 773 @Operation(opcode = Opcode.READ_POINTER) 774 public Word readWord(int offset, LocationIdentity locationIdentity) { 775 return readWord(signed(offset), locationIdentity); 776 } 777 778 @Override 779 @Operation(opcode = Opcode.READ_POINTER) 780 public Object readObject(int offset, LocationIdentity locationIdentity) { 781 return readObject(signed(offset), locationIdentity); 782 } 783 784 @Override 785 @Operation(opcode = Opcode.WRITE_POINTER) 786 public void writeByte(WordBase offset, byte val, LocationIdentity locationIdentity) { 787 UNSAFE.putByte(add((Word) offset).unbox(), val); 788 } 789 790 @Override 791 @Operation(opcode = Opcode.WRITE_POINTER) 792 public void writeChar(WordBase offset, char val, LocationIdentity locationIdentity) { 793 UNSAFE.putChar(add((Word) offset).unbox(), val); 794 } 795 796 @Override 797 @Operation(opcode = Opcode.WRITE_POINTER) 798 public void writeShort(WordBase offset, short val, LocationIdentity locationIdentity) { 799 UNSAFE.putShort(add((Word) offset).unbox(), val); 800 } 801 802 @Override 803 @Operation(opcode = Opcode.WRITE_POINTER) 804 public void writeInt(WordBase offset, int val, LocationIdentity locationIdentity) { 805 UNSAFE.putInt(add((Word) offset).unbox(), val); 806 } 807 808 @Override 809 @Operation(opcode = Opcode.WRITE_POINTER) 810 public void writeLong(WordBase offset, long val, LocationIdentity locationIdentity) { 811 UNSAFE.putLong(add((Word) offset).unbox(), val); 812 } 813 814 @Override 815 @Operation(opcode = Opcode.WRITE_POINTER) 816 public void writeFloat(WordBase offset, float val, LocationIdentity locationIdentity) { 817 UNSAFE.putFloat(add((Word) offset).unbox(), val); 818 } 819 820 @Override 821 @Operation(opcode = Opcode.WRITE_POINTER) 822 public void writeDouble(WordBase offset, double val, LocationIdentity locationIdentity) { 823 UNSAFE.putDouble(add((Word) offset).unbox(), val); 824 } 825 826 @Override 827 @Operation(opcode = Opcode.WRITE_POINTER) 828 public void writeWord(WordBase offset, WordBase val, LocationIdentity locationIdentity) { 829 UNSAFE.putAddress(add((Word) offset).unbox(), ((Word) val).unbox()); 830 } 831 832 @Override 833 @Operation(opcode = Opcode.INITIALIZE) 834 public void initializeLong(WordBase offset, long val, LocationIdentity locationIdentity) { 835 UNSAFE.putLong(add((Word) offset).unbox(), val); 836 } 837 838 @Override 839 @Operation(opcode = Opcode.WRITE_POINTER) 840 public native void writeObject(WordBase offset, Object val, LocationIdentity locationIdentity); 841 842 @Override 843 @Operation(opcode = Opcode.WRITE_POINTER) 844 public void writeByte(int offset, byte val, LocationIdentity locationIdentity) { 845 writeByte(signed(offset), val, locationIdentity); 846 } 847 848 @Override 849 @Operation(opcode = Opcode.WRITE_POINTER) 850 public void writeChar(int offset, char val, LocationIdentity locationIdentity) { 851 writeChar(signed(offset), val, locationIdentity); 852 } 853 854 @Override 855 @Operation(opcode = Opcode.WRITE_POINTER) 856 public void writeShort(int offset, short val, LocationIdentity locationIdentity) { 857 writeShort(signed(offset), val, locationIdentity); 858 } 859 860 @Override 861 @Operation(opcode = Opcode.WRITE_POINTER) 862 public void writeInt(int offset, int val, LocationIdentity locationIdentity) { 863 writeInt(signed(offset), val, locationIdentity); 864 } 865 866 @Override 867 @Operation(opcode = Opcode.WRITE_POINTER) 868 public void writeLong(int offset, long val, LocationIdentity locationIdentity) { 869 writeLong(signed(offset), val, locationIdentity); 870 } 871 872 @Override 873 @Operation(opcode = Opcode.WRITE_POINTER) 874 public void writeFloat(int offset, float val, LocationIdentity locationIdentity) { 875 writeFloat(signed(offset), val, locationIdentity); 876 } 877 878 @Override 879 @Operation(opcode = Opcode.WRITE_POINTER) 880 public void writeDouble(int offset, double val, LocationIdentity locationIdentity) { 881 writeDouble(signed(offset), val, locationIdentity); 882 } 883 884 @Override 885 @Operation(opcode = Opcode.WRITE_POINTER) 886 public void writeWord(int offset, WordBase val, LocationIdentity locationIdentity) { 887 writeWord(signed(offset), val, locationIdentity); 888 } 889 890 @Override 891 @Operation(opcode = Opcode.INITIALIZE) 892 public void initializeLong(int offset, long val, LocationIdentity locationIdentity) { 893 initializeLong(signed(offset), val, locationIdentity); 894 } 895 896 @Override 897 @Operation(opcode = Opcode.WRITE_POINTER) 898 public void writeObject(int offset, Object val, LocationIdentity locationIdentity) { 899 writeObject(signed(offset), val, locationIdentity); 900 } 901 902 @Override 903 @Operation(opcode = Opcode.READ_POINTER) 904 public byte readByte(WordBase offset) { 905 return UNSAFE.getByte(add((Word) offset).unbox()); 906 } 907 908 @Override 909 @Operation(opcode = Opcode.READ_POINTER) 910 public char readChar(WordBase offset) { 911 return UNSAFE.getChar(add((Word) offset).unbox()); 912 } 913 914 @Override 915 @Operation(opcode = Opcode.READ_POINTER) 916 public short readShort(WordBase offset) { 917 return UNSAFE.getShort(add((Word) offset).unbox()); 918 } 919 920 @Override 921 @Operation(opcode = Opcode.READ_POINTER) 922 public int readInt(WordBase offset) { 923 return UNSAFE.getInt(add((Word) offset).unbox()); 924 } 925 926 @Override 927 @Operation(opcode = Opcode.READ_POINTER) 928 public long readLong(WordBase offset) { 929 return UNSAFE.getLong(add((Word) offset).unbox()); 930 } 931 932 @Override 933 @Operation(opcode = Opcode.READ_POINTER) 934 public float readFloat(WordBase offset) { 935 return UNSAFE.getFloat(add((Word) offset).unbox()); 936 } 937 938 @Override 939 @Operation(opcode = Opcode.READ_POINTER) 940 public double readDouble(WordBase offset) { 941 return UNSAFE.getDouble(add((Word) offset).unbox()); 942 } 943 944 @Override 945 @Operation(opcode = Opcode.READ_POINTER) 946 public Word readWord(WordBase offset) { 947 return box(UNSAFE.getAddress(add((Word) offset).unbox())); 948 } 949 950 @Override 951 @Operation(opcode = Opcode.READ_POINTER) 952 public native Object readObject(WordBase offset); 953 954 @Override 955 @Operation(opcode = Opcode.READ_HEAP) 956 public native Object readObject(WordBase offset, BarrierType barrierType); 957 958 @Override 959 @Operation(opcode = Opcode.READ_POINTER) 960 public byte readByte(int offset) { 961 return readByte(signed(offset)); 962 } 963 964 @Override 965 @Operation(opcode = Opcode.READ_POINTER) 966 public char readChar(int offset) { 967 return readChar(signed(offset)); 968 } 969 970 @Override 971 @Operation(opcode = Opcode.READ_POINTER) 972 public short readShort(int offset) { 973 return readShort(signed(offset)); 974 } 975 976 @Override 977 @Operation(opcode = Opcode.READ_POINTER) 978 public int readInt(int offset) { 979 return readInt(signed(offset)); 980 } 981 982 @Override 983 @Operation(opcode = Opcode.READ_POINTER) 984 public long readLong(int offset) { 985 return readLong(signed(offset)); 986 } 987 988 @Override 989 @Operation(opcode = Opcode.READ_POINTER) 990 public float readFloat(int offset) { 991 return readFloat(signed(offset)); 992 } 993 994 @Override 995 @Operation(opcode = Opcode.READ_POINTER) 996 public double readDouble(int offset) { 997 return readDouble(signed(offset)); 998 } 999 1000 @Override 1001 @Operation(opcode = Opcode.READ_POINTER) 1002 public Word readWord(int offset) { 1003 return readWord(signed(offset)); 1004 } 1005 1006 @Override 1007 @Operation(opcode = Opcode.READ_POINTER) 1008 public Object readObject(int offset) { 1009 return readObject(signed(offset)); 1010 } 1011 1012 @Override 1013 @Operation(opcode = Opcode.READ_HEAP) 1014 public Object readObject(int offset, BarrierType barrierType) { 1015 return readObject(signed(offset), barrierType); 1016 } 1017 1018 @Override 1019 @Operation(opcode = Opcode.WRITE_POINTER) 1020 public void writeByte(WordBase offset, byte val) { 1021 UNSAFE.putByte(add((Word) offset).unbox(), val); 1022 } 1023 1024 @Override 1025 @Operation(opcode = Opcode.WRITE_POINTER) 1026 public void writeChar(WordBase offset, char val) { 1027 UNSAFE.putChar(add((Word) offset).unbox(), val); 1028 } 1029 1030 @Override 1031 @Operation(opcode = Opcode.WRITE_POINTER) 1032 public void writeShort(WordBase offset, short val) { 1033 UNSAFE.putShort(add((Word) offset).unbox(), val); 1034 } 1035 1036 @Override 1037 @Operation(opcode = Opcode.WRITE_POINTER) 1038 public void writeInt(WordBase offset, int val) { 1039 UNSAFE.putInt(add((Word) offset).unbox(), val); 1040 } 1041 1042 @Override 1043 @Operation(opcode = Opcode.WRITE_POINTER) 1044 public void writeLong(WordBase offset, long val) { 1045 UNSAFE.putLong(add((Word) offset).unbox(), val); 1046 } 1047 1048 @Override 1049 @Operation(opcode = Opcode.WRITE_POINTER) 1050 public void writeFloat(WordBase offset, float val) { 1051 UNSAFE.putFloat(add((Word) offset).unbox(), val); 1052 } 1053 1054 @Override 1055 @Operation(opcode = Opcode.WRITE_POINTER) 1056 public void writeDouble(WordBase offset, double val) { 1057 UNSAFE.putDouble(add((Word) offset).unbox(), val); 1058 } 1059 1060 @Override 1061 @Operation(opcode = Opcode.WRITE_POINTER) 1062 public void writeWord(WordBase offset, WordBase val) { 1063 UNSAFE.putAddress(add((Word) offset).unbox(), ((Word) val).unbox()); 1064 } 1065 1066 @Override 1067 @Operation(opcode = Opcode.WRITE_POINTER) 1068 public native void writeObject(WordBase offset, Object val); 1069 1070 @Override 1071 @Operation(opcode = Opcode.WRITE_POINTER) 1072 public void writeByte(int offset, byte val) { 1073 writeByte(signed(offset), val); 1074 } 1075 1076 @Override 1077 @Operation(opcode = Opcode.WRITE_POINTER) 1078 public void writeChar(int offset, char val) { 1079 writeChar(signed(offset), val); 1080 } 1081 1082 @Override 1083 @Operation(opcode = Opcode.WRITE_POINTER) 1084 public void writeShort(int offset, short val) { 1085 writeShort(signed(offset), val); 1086 } 1087 1088 @Override 1089 @Operation(opcode = Opcode.WRITE_POINTER) 1090 public void writeInt(int offset, int val) { 1091 writeInt(signed(offset), val); 1092 } 1093 1094 @Override 1095 @Operation(opcode = Opcode.WRITE_POINTER) 1096 public void writeLong(int offset, long val) { 1097 writeLong(signed(offset), val); 1098 } 1099 1100 @Override 1101 @Operation(opcode = Opcode.WRITE_POINTER) 1102 public void writeFloat(int offset, float val) { 1103 writeFloat(signed(offset), val); 1104 } 1105 1106 @Override 1107 @Operation(opcode = Opcode.WRITE_POINTER) 1108 public void writeDouble(int offset, double val) { 1109 writeDouble(signed(offset), val); 1110 } 1111 1112 @Override 1113 @Operation(opcode = Opcode.WRITE_POINTER) 1114 public void writeWord(int offset, WordBase val) { 1115 writeWord(signed(offset), val); 1116 } 1117 1118 @Override 1119 @Operation(opcode = Opcode.WRITE_POINTER) 1120 public void writeObject(int offset, Object val) { 1121 writeObject(signed(offset), val); 1122 } 1123 1124 @Override 1125 public final boolean equals(Object obj) { 1126 throw GraalError.shouldNotReachHere("equals must not be called on words"); 1127 } 1128 1129 @Override 1130 public final int hashCode() { 1131 throw GraalError.shouldNotReachHere("hashCode must not be called on words"); 1132 } 1133 1134 @Override 1135 public String toString() { 1136 throw GraalError.shouldNotReachHere("toString must not be called on words"); 1137 } 1138 } 1139 1140 final class HostedWord extends Word { 1141 1142 private static final int SMALL_FROM = -1; 1143 private static final int SMALL_TO = 100; 1144 1145 private static final HostedWord[] smallCache = new HostedWord[SMALL_TO - SMALL_FROM + 1]; 1146 1147 static { 1148 for (int i = SMALL_FROM; i <= SMALL_TO; i++) { 1149 smallCache[i - SMALL_FROM] = new HostedWord(i); 1150 } 1151 } 1152 1153 private final long rawValue; 1154 1155 private HostedWord(long rawValue) { 1156 this.rawValue = rawValue; 1157 } 1158 1159 protected static Word boxLong(long val) { 1160 if (val >= SMALL_FROM && val <= SMALL_TO) { 1161 return smallCache[(int) val - SMALL_FROM]; 1162 } 1163 return new HostedWord(val); 1164 } 1165 1166 @Override 1167 protected long unbox() { 1168 return rawValue; 1169 } 1170 1171 @Override 1172 public String toString() { 1173 return "Word<" + rawValue + ">"; 1174 } 1175 }