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