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