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