001/* 002 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.word; 024 025import static jdk.internal.jvmci.common.UnsafeAccess.*; 026 027import java.lang.annotation.*; 028 029import jdk.internal.jvmci.code.*; 030import jdk.internal.jvmci.common.*; 031import jdk.internal.jvmci.meta.*; 032 033import com.oracle.graal.compiler.common.calc.*; 034import com.oracle.graal.nodes.*; 035import com.oracle.graal.nodes.calc.*; 036import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; 037import com.oracle.graal.nodes.memory.address.AddressNode.Address; 038 039public abstract class Word implements Signed, Unsigned, Pointer { 040 041 /** 042 * Links a method to a canonical operation represented by an {@link Opcode} val. 043 */ 044 @Retention(RetentionPolicy.RUNTIME) 045 @Target(ElementType.METHOD) 046 public @interface Operation { 047 048 Class<? extends ValueNode> node() default ValueNode.class; 049 050 boolean rightOperandIsInt() default false; 051 052 Opcode opcode() default Opcode.NODE_CLASS; 053 054 Condition condition() default Condition.EQ; 055 } 056 057 /** 058 * The canonical {@link Operation} represented by a method in the {@link Word} class. 059 */ 060 // @formatter:off 061 public enum Opcode { 062 NODE_CLASS, 063 COMPARISON, 064 NOT, 065 READ_POINTER, 066 READ_OBJECT, 067 READ_BARRIERED, 068 READ_HEAP, 069 WRITE_POINTER, 070 WRITE_OBJECT, 071 WRITE_BARRIERED, 072 INITIALIZE, 073 ZERO, 074 FROM_UNSIGNED, 075 FROM_SIGNED, 076 FROM_OBJECT, 077 FROM_WORDBASE, 078 FROM_ADDRESS, 079 TO_OBJECT, 080 TO_RAW_VALUE, 081 } 082 // @formatter:on 083 084 /* 085 * Outside users should use the different signed() and unsigned() methods to ensure proper 086 * expansion of 32-bit values on 64-bit systems. 087 */ 088 private static Word box(long val) { 089 return HostedWord.boxLong(val); 090 } 091 092 protected abstract long unbox(); 093 094 private static Word intParam(int val) { 095 return box(val); 096 } 097 098 /** 099 * The constant 0, i.e., the word with no bits set. There is no difference between a signed and 100 * unsigned zero. 101 * 102 * @return the constant 0. 103 */ 104 @Operation(opcode = Opcode.ZERO) 105 public static Word zero() { 106 return box(0L); 107 } 108 109 /** 110 * Unsafe conversion from a Java long value to a Word. The parameter is treated as an unsigned 111 * 64-bit value (in contrast to the semantics of a Java long). 112 * 113 * @param val a 64 bit unsigned value 114 * @return the value cast to Word 115 */ 116 @Operation(opcode = Opcode.FROM_UNSIGNED) 117 public static Word unsigned(long val) { 118 return box(val); 119 } 120 121 /** 122 * Unsafe conversion from a Java long value to a {@link PointerBase pointer}. The parameter is 123 * treated as an unsigned 64-bit value (in contrast to the semantics of a Java long). 124 * 125 * @param val a 64 bit unsigned value 126 * @return the value cast to PointerBase 127 */ 128 @Operation(opcode = Opcode.FROM_UNSIGNED) 129 @SuppressWarnings("unchecked") 130 public static <T extends PointerBase> T pointer(long val) { 131 return (T) box(val); 132 } 133 134 /** 135 * Unsafe conversion from a Java int value to a Word. The parameter is treated as an unsigned 136 * 32-bit value (in contrast to the semantics of a Java int). 137 * 138 * @param val a 32 bit unsigned value 139 * @return the value cast to Word 140 */ 141 @Operation(opcode = Opcode.FROM_UNSIGNED) 142 public static Word unsigned(int val) { 143 return box(val & 0xffffffffL); 144 } 145 146 /** 147 * Unsafe conversion from a Java long value to a Word. The parameter is treated as a signed 148 * 64-bit value (unchanged semantics of a Java long). 149 * 150 * @param val a 64 bit signed value 151 * @return the value cast to Word 152 */ 153 @Operation(opcode = Opcode.FROM_SIGNED) 154 public static Word signed(long val) { 155 return box(val); 156 } 157 158 /** 159 * Unsafe conversion from a Java int value to a Word. The parameter is treated as a signed 160 * 32-bit value (unchanged semantics of a Java int). 161 * 162 * @param val a 32 bit signed value 163 * @return the value cast to Word 164 */ 165 @Operation(opcode = Opcode.FROM_SIGNED) 166 public static Word signed(int val) { 167 return box(val); 168 } 169 170 @Override 171 @Operation(opcode = Opcode.TO_RAW_VALUE) 172 public long rawValue() { 173 return unbox(); 174 } 175 176 @Operation(opcode = Opcode.FROM_WORDBASE) 177 public static native Word fromWordBase(WordBase val); 178 179 @Operation(opcode = Opcode.FROM_OBJECT) 180 public static native Pointer fromObject(Object val); 181 182 @Operation(opcode = Opcode.FROM_ADDRESS) 183 public static native Pointer fromAddress(Address address); 184 185 @Override 186 @Operation(opcode = Opcode.TO_OBJECT) 187 public native Object toObject(); 188 189 @Override 190 @Operation(node = AddNode.class) 191 public Word add(Signed val) { 192 return add((Word) val); 193 } 194 195 @Override 196 @Operation(node = AddNode.class) 197 public Word add(Unsigned val) { 198 return add((Word) val); 199 } 200 201 @Override 202 @Operation(node = AddNode.class) 203 public Word add(int val) { 204 return add(intParam(val)); 205 } 206 207 @Operation(node = AddNode.class) 208 public Word add(Word val) { 209 return box(unbox() + val.unbox()); 210 } 211 212 @Override 213 @Operation(node = SubNode.class) 214 public Word subtract(Signed val) { 215 return subtract((Word) val); 216 } 217 218 @Override 219 @Operation(node = SubNode.class) 220 public Word subtract(Unsigned val) { 221 return subtract((Word) val); 222 } 223 224 @Override 225 @Operation(node = SubNode.class) 226 public Word subtract(int val) { 227 return subtract(intParam(val)); 228 } 229 230 @Operation(node = SubNode.class) 231 public Word subtract(Word val) { 232 return box(unbox() - val.unbox()); 233 } 234 235 @Override 236 @Operation(node = MulNode.class) 237 public Word multiply(Signed val) { 238 return multiply((Word) val); 239 } 240 241 @Override 242 @Operation(node = MulNode.class) 243 public Word multiply(Unsigned val) { 244 return multiply((Word) val); 245 } 246 247 @Override 248 @Operation(node = MulNode.class) 249 public Word multiply(int val) { 250 return multiply(intParam(val)); 251 } 252 253 @Operation(node = MulNode.class) 254 public Word multiply(Word val) { 255 return box(unbox() * val.unbox()); 256 } 257 258 @Override 259 @Operation(node = IntegerDivNode.class) 260 public Word signedDivide(Signed val) { 261 return signedDivide((Word) val); 262 } 263 264 @Override 265 @Operation(node = IntegerDivNode.class) 266 public Word signedDivide(int val) { 267 return signedDivide(intParam(val)); 268 } 269 270 @Operation(node = IntegerDivNode.class) 271 public Word signedDivide(Word val) { 272 return box(unbox() / val.unbox()); 273 } 274 275 @Override 276 @Operation(node = UnsignedDivNode.class) 277 public Word unsignedDivide(Unsigned val) { 278 return unsignedDivide((Word) val); 279 } 280 281 @Override 282 @Operation(node = UnsignedDivNode.class) 283 public Word unsignedDivide(int val) { 284 return signedDivide(intParam(val)); 285 } 286 287 @Operation(node = UnsignedDivNode.class) 288 public Word unsignedDivide(Word val) { 289 return box(UnsignedMath.divide(unbox(), val.unbox())); 290 } 291 292 @Override 293 @Operation(node = IntegerRemNode.class) 294 public Word signedRemainder(Signed val) { 295 return signedRemainder((Word) val); 296 } 297 298 @Override 299 @Operation(node = IntegerRemNode.class) 300 public Word signedRemainder(int val) { 301 return signedRemainder(intParam(val)); 302 } 303 304 @Operation(node = IntegerRemNode.class) 305 public Word signedRemainder(Word val) { 306 return box(unbox() % val.unbox()); 307 } 308 309 @Override 310 @Operation(node = UnsignedRemNode.class) 311 public Word unsignedRemainder(Unsigned val) { 312 return unsignedRemainder((Word) val); 313 } 314 315 @Override 316 @Operation(node = UnsignedRemNode.class) 317 public Word unsignedRemainder(int val) { 318 return signedRemainder(intParam(val)); 319 } 320 321 @Operation(node = UnsignedRemNode.class) 322 public Word unsignedRemainder(Word val) { 323 return box(UnsignedMath.remainder(unbox(), val.unbox())); 324 } 325 326 @Override 327 @Operation(node = LeftShiftNode.class, rightOperandIsInt = true) 328 public Word shiftLeft(Unsigned val) { 329 return shiftLeft((Word) val); 330 } 331 332 @Override 333 @Operation(node = LeftShiftNode.class, rightOperandIsInt = true) 334 public Word shiftLeft(int val) { 335 return shiftLeft(intParam(val)); 336 } 337 338 @Operation(node = LeftShiftNode.class, rightOperandIsInt = true) 339 public Word shiftLeft(Word val) { 340 return box(unbox() << val.unbox()); 341 } 342 343 @Override 344 @Operation(node = RightShiftNode.class, rightOperandIsInt = true) 345 public Word signedShiftRight(Unsigned val) { 346 return signedShiftRight((Word) val); 347 } 348 349 @Override 350 @Operation(node = RightShiftNode.class, rightOperandIsInt = true) 351 public Word signedShiftRight(int val) { 352 return signedShiftRight(intParam(val)); 353 } 354 355 @Operation(node = RightShiftNode.class, rightOperandIsInt = true) 356 public Word signedShiftRight(Word val) { 357 return box(unbox() >> val.unbox()); 358 } 359 360 @Override 361 @Operation(node = UnsignedRightShiftNode.class, rightOperandIsInt = true) 362 public Word unsignedShiftRight(Unsigned val) { 363 return unsignedShiftRight((Word) val); 364 } 365 366 @Override 367 @Operation(node = UnsignedRightShiftNode.class, rightOperandIsInt = true) 368 public Word unsignedShiftRight(int val) { 369 return unsignedShiftRight(intParam(val)); 370 } 371 372 @Operation(node = UnsignedRightShiftNode.class, rightOperandIsInt = true) 373 public Word unsignedShiftRight(Word val) { 374 return box(unbox() >>> val.unbox()); 375 } 376 377 @Override 378 @Operation(node = AndNode.class) 379 public Word and(Signed val) { 380 return and((Word) val); 381 } 382 383 @Override 384 @Operation(node = AndNode.class) 385 public Word and(Unsigned val) { 386 return and((Word) val); 387 } 388 389 @Override 390 @Operation(node = AndNode.class) 391 public Word and(int val) { 392 return and(intParam(val)); 393 } 394 395 @Operation(node = AndNode.class) 396 public Word and(Word val) { 397 return box(unbox() & val.unbox()); 398 } 399 400 @Override 401 @Operation(node = OrNode.class) 402 public Word or(Signed val) { 403 return or((Word) val); 404 } 405 406 @Override 407 @Operation(node = OrNode.class) 408 public Word or(Unsigned val) { 409 return or((Word) val); 410 } 411 412 @Override 413 @Operation(node = OrNode.class) 414 public Word or(int val) { 415 return or(intParam(val)); 416 } 417 418 @Operation(node = OrNode.class) 419 public Word or(Word val) { 420 return box(unbox() | val.unbox()); 421 } 422 423 @Override 424 @Operation(node = XorNode.class) 425 public Word xor(Signed val) { 426 return xor((Word) val); 427 } 428 429 @Override 430 @Operation(node = XorNode.class) 431 public Word xor(Unsigned val) { 432 return xor((Word) val); 433 } 434 435 @Override 436 @Operation(node = XorNode.class) 437 public Word xor(int val) { 438 return xor(intParam(val)); 439 } 440 441 @Operation(node = XorNode.class) 442 public Word xor(Word val) { 443 return box(unbox() ^ val.unbox()); 444 } 445 446 @Override 447 @Operation(opcode = Opcode.NOT) 448 public Word not() { 449 return box(~unbox()); 450 } 451 452 @Override 453 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 454 public boolean equal(ComparableWord val) { 455 return equal((Word) val); 456 } 457 458 @Override 459 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 460 public boolean equal(Signed val) { 461 return equal((Word) val); 462 } 463 464 @Override 465 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 466 public boolean equal(Unsigned val) { 467 return equal((Word) val); 468 } 469 470 @Override 471 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 472 public boolean equal(int val) { 473 return equal(intParam(val)); 474 } 475 476 @Operation(opcode = Opcode.COMPARISON, condition = Condition.EQ) 477 public boolean equal(Word val) { 478 return unbox() == val.unbox(); 479 } 480 481 @Override 482 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 483 public boolean notEqual(ComparableWord val) { 484 return notEqual((Word) val); 485 } 486 487 @Override 488 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 489 public boolean notEqual(Signed val) { 490 return notEqual((Word) val); 491 } 492 493 @Override 494 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 495 public boolean notEqual(Unsigned val) { 496 return notEqual((Word) val); 497 } 498 499 @Override 500 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 501 public boolean notEqual(int val) { 502 return notEqual(intParam(val)); 503 } 504 505 @Operation(opcode = Opcode.COMPARISON, condition = Condition.NE) 506 public boolean notEqual(Word val) { 507 return unbox() != val.unbox(); 508 } 509 510 @Override 511 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LT) 512 public boolean lessThan(Signed val) { 513 return lessThan((Word) val); 514 } 515 516 @Override 517 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LT) 518 public boolean lessThan(int val) { 519 return lessThan(intParam(val)); 520 } 521 522 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LT) 523 public boolean lessThan(Word val) { 524 return unbox() < val.unbox(); 525 } 526 527 @Override 528 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LE) 529 public boolean lessOrEqual(Signed val) { 530 return lessOrEqual((Word) val); 531 } 532 533 @Override 534 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LE) 535 public boolean lessOrEqual(int val) { 536 return lessOrEqual(intParam(val)); 537 } 538 539 @Operation(opcode = Opcode.COMPARISON, condition = Condition.LE) 540 public boolean lessOrEqual(Word val) { 541 return unbox() <= val.unbox(); 542 } 543 544 @Override 545 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GT) 546 public boolean greaterThan(Signed val) { 547 return greaterThan((Word) val); 548 } 549 550 @Override 551 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GT) 552 public boolean greaterThan(int val) { 553 return greaterThan(intParam(val)); 554 } 555 556 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GT) 557 public boolean greaterThan(Word val) { 558 return unbox() > val.unbox(); 559 } 560 561 @Override 562 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GE) 563 public boolean greaterOrEqual(Signed val) { 564 return greaterOrEqual((Word) val); 565 } 566 567 @Override 568 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GE) 569 public boolean greaterOrEqual(int val) { 570 return greaterOrEqual(intParam(val)); 571 } 572 573 @Operation(opcode = Opcode.COMPARISON, condition = Condition.GE) 574 public boolean greaterOrEqual(Word val) { 575 return unbox() >= val.unbox(); 576 } 577 578 @Override 579 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BT) 580 public boolean belowThan(Unsigned val) { 581 return belowThan((Word) val); 582 } 583 584 @Override 585 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BT) 586 public boolean belowThan(int val) { 587 return belowThan(intParam(val)); 588 } 589 590 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BT) 591 public boolean belowThan(Word val) { 592 return UnsignedMath.belowThan(unbox(), val.unbox()); 593 } 594 595 @Override 596 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BE) 597 public boolean belowOrEqual(Unsigned val) { 598 return belowOrEqual((Word) val); 599 } 600 601 @Override 602 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BE) 603 public boolean belowOrEqual(int val) { 604 return belowOrEqual(intParam(val)); 605 } 606 607 @Operation(opcode = Opcode.COMPARISON, condition = Condition.BE) 608 public boolean belowOrEqual(Word val) { 609 return UnsignedMath.belowOrEqual(unbox(), val.unbox()); 610 } 611 612 @Override 613 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AT) 614 public boolean aboveThan(Unsigned val) { 615 return aboveThan((Word) val); 616 } 617 618 @Override 619 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AT) 620 public boolean aboveThan(int val) { 621 return aboveThan(intParam(val)); 622 } 623 624 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AT) 625 public boolean aboveThan(Word val) { 626 return UnsignedMath.aboveThan(unbox(), val.unbox()); 627 } 628 629 @Override 630 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AE) 631 public boolean aboveOrEqual(Unsigned val) { 632 return aboveOrEqual((Word) val); 633 } 634 635 @Override 636 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AE) 637 public boolean aboveOrEqual(int val) { 638 return aboveOrEqual(intParam(val)); 639 } 640 641 @Operation(opcode = Opcode.COMPARISON, condition = Condition.AE) 642 public boolean aboveOrEqual(Word val) { 643 return UnsignedMath.aboveOrEqual(unbox(), val.unbox()); 644 } 645 646 @Override 647 @Operation(opcode = Opcode.READ_POINTER) 648 public byte readByte(WordBase offset, LocationIdentity locationIdentity) { 649 return unsafe.getByte(add((Word) offset).unbox()); 650 } 651 652 @Override 653 @Operation(opcode = Opcode.READ_POINTER) 654 public char readChar(WordBase offset, LocationIdentity locationIdentity) { 655 return unsafe.getChar(add((Word) offset).unbox()); 656 } 657 658 @Override 659 @Operation(opcode = Opcode.READ_POINTER) 660 public short readShort(WordBase offset, LocationIdentity locationIdentity) { 661 return unsafe.getShort(add((Word) offset).unbox()); 662 } 663 664 @Override 665 @Operation(opcode = Opcode.READ_POINTER) 666 public int readInt(WordBase offset, LocationIdentity locationIdentity) { 667 return unsafe.getInt(add((Word) offset).unbox()); 668 } 669 670 @Override 671 @Operation(opcode = Opcode.READ_POINTER) 672 public long readLong(WordBase offset, LocationIdentity locationIdentity) { 673 return unsafe.getLong(add((Word) offset).unbox()); 674 } 675 676 @Override 677 @Operation(opcode = Opcode.READ_POINTER) 678 public float readFloat(WordBase offset, LocationIdentity locationIdentity) { 679 return unsafe.getFloat(add((Word) offset).unbox()); 680 } 681 682 @Override 683 @Operation(opcode = Opcode.READ_POINTER) 684 public double readDouble(WordBase offset, LocationIdentity locationIdentity) { 685 return unsafe.getDouble(add((Word) offset).unbox()); 686 } 687 688 @Override 689 @Operation(opcode = Opcode.READ_POINTER) 690 public Word readWord(WordBase offset, LocationIdentity locationIdentity) { 691 return box(unsafe.getAddress(add((Word) offset).unbox())); 692 } 693 694 @Override 695 @Operation(opcode = Opcode.READ_POINTER) 696 public native Object readObject(WordBase offset, LocationIdentity locationIdentity); 697 698 @Override 699 @Operation(opcode = Opcode.READ_POINTER) 700 public byte readByte(int offset, LocationIdentity locationIdentity) { 701 return readByte(signed(offset), locationIdentity); 702 } 703 704 @Override 705 @Operation(opcode = Opcode.READ_POINTER) 706 public char readChar(int offset, LocationIdentity locationIdentity) { 707 return readChar(signed(offset), locationIdentity); 708 } 709 710 @Override 711 @Operation(opcode = Opcode.READ_POINTER) 712 public short readShort(int offset, LocationIdentity locationIdentity) { 713 return readShort(signed(offset), locationIdentity); 714 } 715 716 @Override 717 @Operation(opcode = Opcode.READ_POINTER) 718 public int readInt(int offset, LocationIdentity locationIdentity) { 719 return readInt(signed(offset), locationIdentity); 720 } 721 722 @Override 723 @Operation(opcode = Opcode.READ_POINTER) 724 public long readLong(int offset, LocationIdentity locationIdentity) { 725 return readLong(signed(offset), locationIdentity); 726 } 727 728 @Override 729 @Operation(opcode = Opcode.READ_POINTER) 730 public float readFloat(int offset, LocationIdentity locationIdentity) { 731 return readFloat(signed(offset), locationIdentity); 732 } 733 734 @Override 735 @Operation(opcode = Opcode.READ_POINTER) 736 public double readDouble(int offset, LocationIdentity locationIdentity) { 737 return readDouble(signed(offset), locationIdentity); 738 } 739 740 @Override 741 @Operation(opcode = Opcode.READ_POINTER) 742 public Word readWord(int offset, LocationIdentity locationIdentity) { 743 return readWord(signed(offset), locationIdentity); 744 } 745 746 @Override 747 @Operation(opcode = Opcode.READ_POINTER) 748 public Object readObject(int offset, LocationIdentity locationIdentity) { 749 return readObject(signed(offset), locationIdentity); 750 } 751 752 @Override 753 @Operation(opcode = Opcode.WRITE_POINTER) 754 public void writeByte(WordBase offset, byte val, LocationIdentity locationIdentity) { 755 unsafe.putByte(add((Word) offset).unbox(), val); 756 } 757 758 @Override 759 @Operation(opcode = Opcode.WRITE_POINTER) 760 public void writeChar(WordBase offset, char val, LocationIdentity locationIdentity) { 761 unsafe.putChar(add((Word) offset).unbox(), val); 762 } 763 764 @Override 765 @Operation(opcode = Opcode.WRITE_POINTER) 766 public void writeShort(WordBase offset, short val, LocationIdentity locationIdentity) { 767 unsafe.putShort(add((Word) offset).unbox(), val); 768 } 769 770 @Override 771 @Operation(opcode = Opcode.WRITE_POINTER) 772 public void writeInt(WordBase offset, int val, LocationIdentity locationIdentity) { 773 unsafe.putInt(add((Word) offset).unbox(), val); 774 } 775 776 @Override 777 @Operation(opcode = Opcode.WRITE_POINTER) 778 public void writeLong(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 void writeFloat(WordBase offset, float val, LocationIdentity locationIdentity) { 785 unsafe.putFloat(add((Word) offset).unbox(), val); 786 } 787 788 @Override 789 @Operation(opcode = Opcode.WRITE_POINTER) 790 public void writeDouble(WordBase offset, double val, LocationIdentity locationIdentity) { 791 unsafe.putDouble(add((Word) offset).unbox(), val); 792 } 793 794 @Override 795 @Operation(opcode = Opcode.WRITE_POINTER) 796 public void writeWord(WordBase offset, WordBase val, LocationIdentity locationIdentity) { 797 unsafe.putAddress(add((Word) offset).unbox(), ((Word) val).unbox()); 798 } 799 800 @Override 801 @Operation(opcode = Opcode.INITIALIZE) 802 public void initializeLong(WordBase offset, long val, LocationIdentity locationIdentity) { 803 unsafe.putLong(add((Word) offset).unbox(), val); 804 } 805 806 @Override 807 @Operation(opcode = Opcode.WRITE_POINTER) 808 public native void writeObject(WordBase offset, Object val, LocationIdentity locationIdentity); 809 810 @Override 811 @Operation(opcode = Opcode.WRITE_POINTER) 812 public void writeByte(int offset, byte val, LocationIdentity locationIdentity) { 813 writeByte(signed(offset), val, locationIdentity); 814 } 815 816 @Override 817 @Operation(opcode = Opcode.WRITE_POINTER) 818 public void writeChar(int offset, char val, LocationIdentity locationIdentity) { 819 writeChar(signed(offset), val, locationIdentity); 820 } 821 822 @Override 823 @Operation(opcode = Opcode.WRITE_POINTER) 824 public void writeShort(int offset, short val, LocationIdentity locationIdentity) { 825 writeShort(signed(offset), val, locationIdentity); 826 } 827 828 @Override 829 @Operation(opcode = Opcode.WRITE_POINTER) 830 public void writeInt(int offset, int val, LocationIdentity locationIdentity) { 831 writeInt(signed(offset), val, locationIdentity); 832 } 833 834 @Override 835 @Operation(opcode = Opcode.WRITE_POINTER) 836 public void writeLong(int offset, long val, LocationIdentity locationIdentity) { 837 writeLong(signed(offset), val, locationIdentity); 838 } 839 840 @Override 841 @Operation(opcode = Opcode.WRITE_POINTER) 842 public void writeFloat(int offset, float val, LocationIdentity locationIdentity) { 843 writeFloat(signed(offset), val, locationIdentity); 844 } 845 846 @Override 847 @Operation(opcode = Opcode.WRITE_POINTER) 848 public void writeDouble(int offset, double val, LocationIdentity locationIdentity) { 849 writeDouble(signed(offset), val, locationIdentity); 850 } 851 852 @Override 853 @Operation(opcode = Opcode.WRITE_POINTER) 854 public void writeWord(int offset, WordBase val, LocationIdentity locationIdentity) { 855 writeWord(signed(offset), val, locationIdentity); 856 } 857 858 @Override 859 @Operation(opcode = Opcode.INITIALIZE) 860 public void initializeLong(int offset, long val, LocationIdentity locationIdentity) { 861 initializeLong(signed(offset), val, locationIdentity); 862 } 863 864 @Override 865 @Operation(opcode = Opcode.WRITE_POINTER) 866 public void writeObject(int offset, Object val, LocationIdentity locationIdentity) { 867 writeObject(signed(offset), val, locationIdentity); 868 } 869 870 @Override 871 @Operation(opcode = Opcode.READ_POINTER) 872 public byte readByte(WordBase offset) { 873 return unsafe.getByte(add((Word) offset).unbox()); 874 } 875 876 @Override 877 @Operation(opcode = Opcode.READ_POINTER) 878 public char readChar(WordBase offset) { 879 return unsafe.getChar(add((Word) offset).unbox()); 880 } 881 882 @Override 883 @Operation(opcode = Opcode.READ_POINTER) 884 public short readShort(WordBase offset) { 885 return unsafe.getShort(add((Word) offset).unbox()); 886 } 887 888 @Override 889 @Operation(opcode = Opcode.READ_POINTER) 890 public int readInt(WordBase offset) { 891 return unsafe.getInt(add((Word) offset).unbox()); 892 } 893 894 @Override 895 @Operation(opcode = Opcode.READ_POINTER) 896 public long readLong(WordBase offset) { 897 return unsafe.getLong(add((Word) offset).unbox()); 898 } 899 900 @Override 901 @Operation(opcode = Opcode.READ_POINTER) 902 public float readFloat(WordBase offset) { 903 return unsafe.getFloat(add((Word) offset).unbox()); 904 } 905 906 @Override 907 @Operation(opcode = Opcode.READ_POINTER) 908 public double readDouble(WordBase offset) { 909 return unsafe.getDouble(add((Word) offset).unbox()); 910 } 911 912 @Override 913 @Operation(opcode = Opcode.READ_POINTER) 914 public Word readWord(WordBase offset) { 915 return box(unsafe.getAddress(add((Word) offset).unbox())); 916 } 917 918 @Override 919 @Operation(opcode = Opcode.READ_POINTER) 920 public native Object readObject(WordBase offset); 921 922 @Operation(opcode = Opcode.READ_HEAP) 923 public native Object readObject(WordBase offset, BarrierType barrierType); 924 925 @Override 926 @Operation(opcode = Opcode.READ_POINTER) 927 public byte readByte(int offset) { 928 return readByte(signed(offset)); 929 } 930 931 @Override 932 @Operation(opcode = Opcode.READ_POINTER) 933 public char readChar(int offset) { 934 return readChar(signed(offset)); 935 } 936 937 @Override 938 @Operation(opcode = Opcode.READ_POINTER) 939 public short readShort(int offset) { 940 return readShort(signed(offset)); 941 } 942 943 @Override 944 @Operation(opcode = Opcode.READ_POINTER) 945 public int readInt(int offset) { 946 return readInt(signed(offset)); 947 } 948 949 @Override 950 @Operation(opcode = Opcode.READ_POINTER) 951 public long readLong(int offset) { 952 return readLong(signed(offset)); 953 } 954 955 @Override 956 @Operation(opcode = Opcode.READ_POINTER) 957 public float readFloat(int offset) { 958 return readFloat(signed(offset)); 959 } 960 961 @Override 962 @Operation(opcode = Opcode.READ_POINTER) 963 public double readDouble(int offset) { 964 return readDouble(signed(offset)); 965 } 966 967 @Override 968 @Operation(opcode = Opcode.READ_POINTER) 969 public Word readWord(int offset) { 970 return readWord(signed(offset)); 971 } 972 973 @Override 974 @Operation(opcode = Opcode.READ_POINTER) 975 public Object readObject(int offset) { 976 return readObject(signed(offset)); 977 } 978 979 @Operation(opcode = Opcode.READ_HEAP) 980 public Object readObject(int offset, BarrierType barrierType) { 981 return readObject(signed(offset), barrierType); 982 } 983 984 @Override 985 @Operation(opcode = Opcode.WRITE_POINTER) 986 public void writeByte(WordBase offset, byte val) { 987 unsafe.putByte(add((Word) offset).unbox(), val); 988 } 989 990 @Override 991 @Operation(opcode = Opcode.WRITE_POINTER) 992 public void writeChar(WordBase offset, char val) { 993 unsafe.putChar(add((Word) offset).unbox(), val); 994 } 995 996 @Override 997 @Operation(opcode = Opcode.WRITE_POINTER) 998 public void writeShort(WordBase offset, short val) { 999 unsafe.putShort(add((Word) offset).unbox(), val); 1000 } 1001 1002 @Override 1003 @Operation(opcode = Opcode.WRITE_POINTER) 1004 public void writeInt(WordBase offset, int val) { 1005 unsafe.putInt(add((Word) offset).unbox(), val); 1006 } 1007 1008 @Override 1009 @Operation(opcode = Opcode.WRITE_POINTER) 1010 public void writeLong(WordBase offset, long val) { 1011 unsafe.putLong(add((Word) offset).unbox(), val); 1012 } 1013 1014 @Override 1015 @Operation(opcode = Opcode.WRITE_POINTER) 1016 public void writeFloat(WordBase offset, float val) { 1017 unsafe.putFloat(add((Word) offset).unbox(), val); 1018 } 1019 1020 @Override 1021 @Operation(opcode = Opcode.WRITE_POINTER) 1022 public void writeDouble(WordBase offset, double val) { 1023 unsafe.putDouble(add((Word) offset).unbox(), val); 1024 } 1025 1026 @Override 1027 @Operation(opcode = Opcode.WRITE_POINTER) 1028 public void writeWord(WordBase offset, WordBase val) { 1029 unsafe.putAddress(add((Word) offset).unbox(), ((Word) val).unbox()); 1030 } 1031 1032 @Override 1033 @Operation(opcode = Opcode.WRITE_POINTER) 1034 public native void writeObject(WordBase offset, Object val); 1035 1036 @Override 1037 @Operation(opcode = Opcode.WRITE_POINTER) 1038 public void writeByte(int offset, byte val) { 1039 writeByte(signed(offset), val); 1040 } 1041 1042 @Override 1043 @Operation(opcode = Opcode.WRITE_POINTER) 1044 public void writeChar(int offset, char val) { 1045 writeChar(signed(offset), val); 1046 } 1047 1048 @Override 1049 @Operation(opcode = Opcode.WRITE_POINTER) 1050 public void writeShort(int offset, short val) { 1051 writeShort(signed(offset), val); 1052 } 1053 1054 @Override 1055 @Operation(opcode = Opcode.WRITE_POINTER) 1056 public void writeInt(int offset, int val) { 1057 writeInt(signed(offset), val); 1058 } 1059 1060 @Override 1061 @Operation(opcode = Opcode.WRITE_POINTER) 1062 public void writeLong(int offset, long val) { 1063 writeLong(signed(offset), val); 1064 } 1065 1066 @Override 1067 @Operation(opcode = Opcode.WRITE_POINTER) 1068 public void writeFloat(int offset, float val) { 1069 writeFloat(signed(offset), val); 1070 } 1071 1072 @Override 1073 @Operation(opcode = Opcode.WRITE_POINTER) 1074 public void writeDouble(int offset, double val) { 1075 writeDouble(signed(offset), val); 1076 } 1077 1078 @Override 1079 @Operation(opcode = Opcode.WRITE_POINTER) 1080 public void writeWord(int offset, WordBase val) { 1081 writeWord(signed(offset), val); 1082 } 1083 1084 @Override 1085 @Operation(opcode = Opcode.WRITE_POINTER) 1086 public void writeObject(int offset, Object val) { 1087 writeObject(signed(offset), val); 1088 } 1089 1090 @Override 1091 public final boolean equals(Object obj) { 1092 throw JVMCIError.shouldNotReachHere("equals must not be called on words"); 1093 } 1094 1095 @Override 1096 public final int hashCode() { 1097 throw JVMCIError.shouldNotReachHere("hashCode must not be called on words"); 1098 } 1099 1100 @Override 1101 public String toString() { 1102 throw JVMCIError.shouldNotReachHere("toString must not be called on words"); 1103 } 1104} 1105 1106final class HostedWord extends Word { 1107 1108 private static final int SMALL_FROM = -1; 1109 private static final int SMALL_TO = 100; 1110 1111 private static final HostedWord[] smallCache = new HostedWord[SMALL_TO - SMALL_FROM + 1]; 1112 1113 static { 1114 for (int i = SMALL_FROM; i <= SMALL_TO; i++) { 1115 smallCache[i - SMALL_FROM] = new HostedWord(i); 1116 } 1117 } 1118 1119 private final long rawValue; 1120 1121 private HostedWord(long rawValue) { 1122 this.rawValue = rawValue; 1123 } 1124 1125 protected static Word boxLong(long val) { 1126 if (val >= SMALL_FROM && val <= SMALL_TO) { 1127 return smallCache[(int) val - SMALL_FROM]; 1128 } 1129 return new HostedWord(val); 1130 } 1131 1132 @Override 1133 protected long unbox() { 1134 return rawValue; 1135 } 1136 1137 @Override 1138 public String toString() { 1139 return "Word<" + rawValue + ">"; 1140 } 1141}