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