001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm.runtime; 014 015 import org.jikesrvm.ArchitectureSpecific.CodeArray; 016 import org.jikesrvm.ArchitectureSpecific.Registers; 017 import org.jikesrvm.VM; 018 import org.jikesrvm.classloader.RVMType; 019 import org.jikesrvm.objectmodel.TIB; 020 import org.jikesrvm.scheduler.RVMThread; 021 import org.vmmagic.Intrinsic; 022 import org.vmmagic.pragma.Entrypoint; 023 import org.vmmagic.pragma.Uninterruptible; 024 import org.vmmagic.unboxed.Address; 025 import org.vmmagic.unboxed.Extent; 026 import org.vmmagic.unboxed.Offset; 027 import org.vmmagic.unboxed.Word; 028 import org.vmmagic.unboxed.WordArray; 029 030 /** 031 * Magic methods for accessing raw machine memory, registers, and 032 * operating system calls. 033 * 034 * <p> These are "inline assembler functions" that cannot be implemented in 035 * Java code. Their names are recognized by RVM's compilers 036 * and cause inline machine code to be generated instead of 037 * actual method calls. 038 */ 039 @SuppressWarnings({"UnusedDeclaration"}) 040 @Intrinsic 041 public final class Magic { 042 043 //---------------------------------------// 044 // Register and Psuedo-Register Access. // 045 //---------------------------------------// 046 047 /** Get contents of "stack frame pointer" register. */ 048 public static Address getFramePointer() { 049 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 050 return null; 051 } 052 053 /** Get contents of "JTOC" register. */ 054 public static Address getTocPointer() { 055 if (VM.runningVM && VM.VerifyAssertions) { 056 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 057 } 058 return BootRecord.the_boot_record.tocRegister; 059 } 060 061 /** Get contents of "JTOC" register */ 062 public static Address getJTOC() { 063 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 064 return null; 065 } 066 067 /** Get contents of "thread" register. */ 068 public static RVMThread getThreadRegister() { 069 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 070 return null; 071 } 072 073 /** Set contents of "thread" register. */ 074 public static void setThreadRegister(RVMThread p) { 075 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 076 } 077 078 /** Get contents of ESI, as a RVMThread. NOTE: IA-specific */ 079 public static RVMThread getESIAsThread() { 080 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 081 return null; 082 } 083 084 /** Set contents of ESI to hold a reference to a thread object. NOTE: IA-specific */ 085 public static void setESIAsThread(RVMThread p) { 086 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 087 } 088 089 /** 090 * Read contents of hardware time base registers. 091 * <p> 092 * Note: we think that 1 "tick" == 4 "machine cycles", but this seems to be 093 * undocumented and may vary across processor implementations. 094 * @return number of ticks (epoch undefined) 095 */ 096 public static long getTimeBase() { 097 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 098 return -1; 099 } 100 101 //---------------------------------------// 102 // Stackframe Manipulation // 103 //---------------------------------------// 104 105 /** 106 * Get fp for parent frame 107 * @param fp frame pointer for child frame 108 */ 109 public static Address getCallerFramePointer(Address fp) { 110 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 111 return null; 112 } 113 114 /** 115 * Set fp for parent frame 116 * @param fp frame pointer for child frame 117 * @param newCallerFP new value for caller frame pointer 118 */ 119 public static void setCallerFramePointer(Address fp, Address newCallerFP) { 120 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 121 } 122 123 /** 124 * Get Compiled Method ID for a frame 125 * @param fp its frame pointer). 126 */ 127 public static int getCompiledMethodID(Address fp) { 128 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 129 return -1; 130 } 131 132 /** 133 * Set the Compiled Method ID for a frame. 134 * @param fp its frame pointer 135 * @param newCMID a new cmid for the frame 136 */ 137 public static void setCompiledMethodID(Address fp, int newCMID) { 138 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 139 } 140 141 /** 142 * Get next instruction address for a frame 143 * @param fp its frame pointer. 144 */ 145 public static Address getNextInstructionAddress(Address fp) { 146 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 147 return null; 148 } 149 150 /** 151 * Get location containing return address for a frame 152 * @param fp its frame pointer 153 */ 154 public static Address getReturnAddressLocation(Address fp) { 155 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 156 return null; 157 } 158 159 /** 160 * Get return address for a frame in a case where the frame is 161 * known not to be a trampoline frame. 162 * 163 * @param fp its frame pointer 164 */ 165 @Uninterruptible 166 public static Address getReturnAddressUnchecked(Address fp) { 167 Address ip = getReturnAddressLocation(fp).loadAddress(); 168 if (VM.VerifyAssertions) VM._assert(!RVMThread.isTrampolineIP(ip)); 169 return ip; 170 } 171 172 /** 173 * Get return address for a frame in the current thread 174 * 175 * @param fp its frame pointer 176 */ 177 @Uninterruptible 178 public static Address getReturnAddress(Address fp) { 179 return getReturnAddress(fp, RVMThread.getCurrentThread()); 180 } 181 182 /** 183 * Get return address for a frame in a specific thread 184 * 185 * @param fp its frame pointer 186 * @param thread the thread whose stack is being examined 187 */ 188 @Uninterruptible 189 public static Address getReturnAddress(Address fp, RVMThread thread) { 190 Address ip = getReturnAddressLocation(fp).loadAddress(); 191 if (RVMThread.isTrampolineIP(ip)) 192 return thread.getTrampolineHijackedReturnAddress(); 193 else 194 return ip; 195 } 196 197 /** 198 * Get return address for a frame 199 * @param fp its frame pointer 200 */ 201 @Uninterruptible 202 public static void setReturnAddress(Address fp, Address v) { 203 getReturnAddressLocation(fp).store(v); 204 } 205 206 //---------------------------------------// 207 // Memory Access. // 208 //---------------------------------------// 209 210 /** 211 * Get unsigned byte at arbitrary (byte) offset from object. The 212 * most significant 24bits of the result will be 0. 213 */ 214 public static byte getUnsignedByteAtOffset(Object object, Offset offset) { 215 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 216 return -1; 217 } 218 219 /** 220 * Get byte at arbitrary (byte) offset from object. The most 221 * significant 24bits of the result will be the same as the most 222 * significant bit in the byte. 223 */ 224 public static byte getByteAtOffset(Object object, Offset offset) { 225 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 226 return -1; 227 } 228 229 /** 230 * Get char at arbitrary (byte) offset from object. The most 231 * significant 16bits will be 0. 232 */ 233 public static char getCharAtOffset(Object object, Offset offset) { 234 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 235 return (char) -1; 236 } 237 238 /** 239 * Get short at arbitrary (byte) offset from object. The most 240 * significant 16bits will be the same as the most significant bit 241 * in the short. 242 */ 243 public static short getShortAtOffset(Object object, Offset offset) { 244 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 245 return (short) -1; 246 } 247 248 /** 249 * Get int at arbitrary (byte) offset from object. 250 * Use getIntAtOffset(obj, ofs) instead of getMemoryInt(objectAsAddress(obj)+ofs) 251 */ 252 public static int getIntAtOffset(Object object, Offset offset) { 253 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 254 return -1; 255 } 256 257 /** 258 * Get long at arbitrary (byte) offset from object. 259 * Use getlongAtOffset(obj, ofs) instead of two getIntAtOffset 260 */ 261 public static long getLongAtOffset(Object object, Offset offset) { 262 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 263 return -1; 264 } 265 266 /** 267 * Get float at arbitrary (byte) offset from object. 268 */ 269 public static float getFloatAtOffset(Object object, Offset offset) { 270 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 271 return -1; 272 } 273 274 /** 275 * Get double at arbitrary (byte) offset from object. 276 * Use getDoubleAtOffset(obj, ofs) instead of two getIntAtOffset 277 */ 278 public static double getDoubleAtOffset(Object object, Offset offset) { 279 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 280 return -1; 281 } 282 283 /** 284 * Get Object at arbitrary (byte) offset from object. 285 * Use getObjectAtOffset(obj, ofs) instead of 286 * addressAsObject(getMemoryAddress(objectAsAddress(obj)+ofs)) 287 */ 288 public static Object getObjectAtOffset(Object object, Offset offset) { 289 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 290 return null; 291 } 292 293 /** 294 * Get Object at arbitrary (byte) offset from object. 295 * Use getObjectAtOffset(obj, ofs) instead of 296 * addressAsObject(getMemoryAddress(objectAsAddress(obj)+ofs)) 297 */ 298 public static Object getObjectAtOffset(Object object, Offset offset, int locationMetadata) { 299 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 300 return null; 301 } 302 303 /** 304 * Get Word at arbitrary (byte) offset from object. 305 * Use getWordAtOffset(obj, ofs) instead of getMemoryWord(objectAsAddress(obj)+ofs) 306 */ 307 public static Word getWordAtOffset(Object object, Offset offset) { 308 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 309 return Word.max(); 310 } 311 312 /** 313 * Get Word at arbitrary (byte) offset from object. 314 */ 315 public static Word getWordAtOffset(Object object, Offset offset, int locationMetadata) { 316 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 317 return null; 318 } 319 320 /** 321 * Get Address at arbitrary (byte) offset from object. 322 * Use getAddressAtOffset(obj, ofs) instead of getMemoryWord(objectAsAddress(obj)+ofs) 323 */ 324 public static Address getAddressAtOffset(Object object, Offset offset) { 325 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 326 return null; 327 } 328 329 /** 330 * Get Address at arbitrary (byte) offset from object. 331 */ 332 public static Address getAddressAtOffset(Object object, Offset offset, int locationMetadata) { 333 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 334 return null; 335 } 336 337 /** 338 * Get Extent at arbitrary (byte) offset from object. 339 * Use getExtentAtOffset(obj, ofs) instead of getMemoryWord(objectAsAddress(obj)+ofs) 340 */ 341 public static Extent getExtentAtOffset(Object object, Offset offset) { 342 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 343 return null; 344 } 345 346 /** 347 * Get Extent at arbitrary (byte) offset from object. 348 */ 349 public static Extent getExtentAtOffset(Object object, Offset offset, int locationMetadata) { 350 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 351 return null; 352 } 353 354 /** 355 * Get Offset at arbitrary (byte) offset from object. 356 * Use getOffsetAtOffset(obj, ofs) instead of getMemoryWord(objectAsAddress(obj)+ofs) 357 */ 358 public static Offset getOffsetAtOffset(Object object, Offset offset) { 359 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 360 return null; 361 } 362 363 /** 364 * Get Offset at arbitrary (byte) offset from object. 365 */ 366 public static Offset getOffsetAtOffset(Object object, Offset offset, int locationMetadata) { 367 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 368 return null; 369 } 370 371 /** 372 * Get TIB at arbitrary (byte) offset from object. 373 * Use getTIBAtOffset(obj, ofs) instead of 374 * (TIB])addressAsObject(getMemoryAddr(objectAsAddress(obj)+ofs)) 375 */ 376 public static TIB getTIBAtOffset(Object object, Offset offset) { 377 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 378 return null; 379 } 380 381 /** 382 * Set boolean at arbitrary (byte) offset from object. 383 */ 384 public static void setBooleanAtOffset(Object object, Offset offset, boolean newvalue) { 385 if (VM.VerifyAssertions) 386 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 387 } 388 389 /** 390 * Set boolean at arbitrary (byte) offset from object. 391 */ 392 public static void setBooleanAtOffset(Object object, Offset offset, boolean newvalue, int locationMetadata) { 393 if (VM.VerifyAssertions) 394 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 395 } 396 397 /** 398 * Set byte at arbitrary (byte) offset from object. 399 */ 400 public static void setByteAtOffset(Object object, Offset offset, byte newvalue) { 401 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 402 } 403 404 /** 405 * Set byte at arbitrary (byte) offset from object. 406 */ 407 public static void setByteAtOffset(Object object, Offset offset, byte newvalue, int locationMetadata) { 408 if (VM.VerifyAssertions) 409 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 410 } 411 412 /** 413 * Set char at arbitrary (byte) offset from object. 414 */ 415 public static void setCharAtOffset(Object object, Offset offset, char newvalue) { 416 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 417 } 418 419 /** 420 * Set char at arbitrary (byte) offset from object. 421 */ 422 public static void setCharAtOffset(Object object, Offset offset, char newvalue, int locationMetadata) { 423 if (VM.VerifyAssertions) 424 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 425 } 426 427 /** 428 * Set short at arbitrary (byte) offset from object. 429 */ 430 public static void setShortAtOffset(Object object, Offset offset, short newvalue) { 431 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 432 } 433 434 /** 435 * Set short at arbitrary (byte) offset from object. 436 */ 437 public static void setShortAtOffset(Object object, Offset offset, short newvalue, int locationMetadata) { 438 if (VM.VerifyAssertions) 439 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 440 } 441 442 /** 443 * Set int at arbitrary (byte) offset from object. 444 * Use setIntAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 445 */ 446 public static void setIntAtOffset(Object object, Offset offset, int newvalue) { 447 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 448 } 449 450 /** 451 * Set int at arbitrary (byte) offset from object. 452 */ 453 public static void setIntAtOffset(Object object, Offset offset, int newvalue, int locationMetadata) { 454 if (VM.VerifyAssertions) 455 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 456 } 457 458 /** 459 * Set long at arbitrary (byte) offset from object. 460 * Use setlongAtOffset(obj, ofs) instead of two setIntAtOffset 461 */ 462 public static void setLongAtOffset(Object object, Offset offset, long newvalue) { 463 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 464 } 465 466 /** 467 * Set long at arbitrary (byte) offset from object. Use setlongAtOffset(obj, 468 * ofs) instead of two setIntAtOffset 469 */ 470 public static void setLongAtOffset(Object object, Offset offset, long newvalue, int locationMetadata) { 471 if (VM.VerifyAssertions) 472 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 473 } 474 475 /** 476 * Set float at arbitrary (byte) offset from object. 477 */ 478 public static void setFloatAtOffset(Object object, Offset offset, float newvalue) { 479 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 480 } 481 482 /** 483 * Set float at arbitrary (byte) offset from object. 484 */ 485 public static void setFloatAtOffset(Object object, Offset offset, float newvalue, int locationMetadata) { 486 if (VM.VerifyAssertions) 487 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 488 } 489 490 /** 491 * Set double at arbitrary (byte) offset from object. 492 * Use setDoubleAtOffset(obj, ofs) instead of two setIntAtOffset 493 */ 494 public static void setDoubleAtOffset(Object object, Offset offset, double newvalue) { 495 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 496 } 497 498 /** 499 * Set double at arbitrary (byte) offset from object. Use 500 * setDoubleAtOffset(obj, ofs) instead of two setIntAtOffset 501 */ 502 public static void setDoubleAtOffset(Object object, Offset offset, double newvalue, int locationMetadata) { 503 if (VM.VerifyAssertions) 504 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 505 } 506 507 /** 508 * Set Word at arbitrary (byte) offset from object. 509 * Use setWordAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 510 */ 511 public static void setWordAtOffset(Object object, Offset offset, Word newvalue) { 512 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 513 } 514 515 /** 516 * Set Word at arbitrary (byte) offset from object. 517 * Use setWordAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 518 */ 519 public static void setWordAtOffset(Object object, Offset offset, Word newvalue, int locationMetadata) { 520 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 521 } 522 523 /** 524 * Set Address at arbitrary (byte) offset from object. 525 * Use setAddressAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 526 */ 527 public static void setAddressAtOffset(Object object, Offset offset, Address newvalue) { 528 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 529 } 530 531 /** 532 * Set Address at arbitrary (byte) offset from object. 533 * Use setAddressAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 534 */ 535 public static void setAddressAtOffset(Object object, Offset offset, Address newvalue, int locationMetadata) { 536 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 537 } 538 539 /** 540 * Set Extent at arbitrary (byte) offset from object. 541 * Use setExtentAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 542 */ 543 public static void setExtentAtOffset(Object object, Offset offset, Extent newvalue) { 544 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 545 } 546 547 /** 548 * Set Extent at arbitrary (byte) offset from object. 549 * Use setExtenttOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 550 */ 551 public static void setExtentAtOffset(Object object, Offset offset, Extent newvalue, int locationMetadata) { 552 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 553 } 554 555 /** 556 * Set Offset at arbitrary (byte) offset from object. 557 * Use setOffsetAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 558 */ 559 public static void setOffsetAtOffset(Object object, Offset offset, Offset newvalue) { 560 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 561 } 562 563 /** 564 * Set Offset at arbitrary (byte) offset from object. 565 * Use setOffsetAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new) 566 */ 567 public static void setOffsetAtOffset(Object object, Offset offset, Offset newvalue, int locationMetadata) { 568 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 569 } 570 571 /** 572 * Set Object at arbitrary (byte) offset from object. 573 * Use setObjectAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, objectAsAddress(new)) 574 */ 575 public static void setObjectAtOffset(Object object, Offset offset, Object newvalue) { 576 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 577 } 578 579 /** 580 * Set Object at arbitrary (byte) offset from object. 581 */ 582 public static void setObjectAtOffset(Object object, Offset offset, Object newvalue, int locationMetadata) { 583 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 584 } 585 586 587 //---------------------------------------// 588 // Atomic Memory Access Primitives. // 589 //---------------------------------------// 590 591 /** 592 * Get contents of (object + offset) and begin conditional critical section. 593 */ 594 public static int prepareInt(Object object, Offset offset) { 595 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 596 return -1; 597 } 598 599 /** 600 * Get contents of (object + offset) and begin conditional critical section. 601 */ 602 public static Object prepareObject(Object object, Offset offset) { 603 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 604 return null; 605 } 606 607 /** 608 * Get contents of (object + offset) and begin conditional critical section. 609 */ 610 public static Address prepareAddress(Object object, Offset offset) { 611 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 612 return Address.max(); 613 } 614 615 /** 616 * Get contents of (object + offset) and begin conditional critical section. 617 */ 618 public static Word prepareWord(Object object, Offset offset) { 619 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 620 return Word.max(); 621 } 622 623 /** 624 * Get contents of (object + offset) and begin conditional critical section. 625 */ 626 @Uninterruptible 627 public static long prepareLong(Object object, Offset offset) { 628 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 629 return -1; 630 } 631 632 /** 633 * Sets the memory at (object + offset) to newValue if its contents are oldValue. 634 * Must be paired with a preceding prepare (which returned the oldValue) 635 * Returns true if successful. 636 * Ends conditional critical section. 637 */ 638 public static boolean attemptInt(Object object, Offset offset, int oldValue, int newValue) { 639 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 640 return false; 641 } 642 643 /** 644 * Sets the memory at (object + offset) to newValue if its contents are oldValue. 645 * Must be paired with a preceding prepare (which returned the oldValue) 646 * Returns true if successful. 647 * Ends conditional critical section. 648 */ 649 public static boolean attemptObject(Object object, Offset offset, Object oldValue, Object newValue) { 650 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 651 return false; 652 } 653 654 /** 655 * Sets the memory at (object + offset) to newValue if its contents are oldValue. 656 * Must be paired with a preceding prepare (which returned the oldValue) 657 * Returns true if successful. 658 * Ends conditional critical section. 659 */ 660 public static boolean attemptAddress(Object object, Offset offset, Address oldValue, Address newValue) { 661 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 662 return false; 663 } 664 665 /** 666 * Sets the memory at (object + offset) to newValue if its contents are oldValue. 667 * Must be paired with a preceding prepare (which returned the oldValue) 668 * Returns true if successful. 669 * Ends conditional critical section. 670 */ 671 public static boolean attemptWord(Object object, Offset offset, Word oldValue, Word newValue) { 672 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 673 return false; 674 } 675 676 /** 677 * Sets the memory at (object + offset) to newValue if its contents are oldValue. 678 * Must be paired with a preceding prepare (which returned the oldValue) 679 * Returns true if successful. 680 * Ends conditional critical section. 681 */ 682 public static boolean attemptLong(Object object, Offset offset, long oldValue, 683 long newValue) { 684 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 685 return false; 686 } 687 688 //---------------------------------------// 689 // Type Conversion. // 690 //---------------------------------------// 691 692 @Entrypoint 693 private static ObjectAddressRemapper objectAddressRemapper; 694 695 /** 696 * Specify how to handle "objectAsAddress" and "addressAsObject" casts. 697 * Used by debugger and boot image writer. 698 */ 699 public static void setObjectAddressRemapper(ObjectAddressRemapper x) { 700 objectAddressRemapper = x; 701 } 702 703 /** 704 * Cast bits. 705 * Note: the returned integer is only valid until next garbage collection 706 * cycle (thereafter the referenced object might have moved and 707 * its address changed) 708 * @param object object reference 709 * @return object reference as bits 710 */ 711 public static <T> Address objectAsAddress(T object) { 712 if (VM.runningVM && VM.VerifyAssertions) { 713 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 714 } 715 716 if (objectAddressRemapper == null) { 717 return Address.zero(); // tool isn't interested in remapping 718 } 719 720 return objectAddressRemapper.objectAsAddress(object); 721 } 722 723 /** 724 * Certain objects aren't replicated in the boot image to save space. 725 * @param object to intern 726 * @return interned object 727 */ 728 public static <T> T bootImageIntern(T object) { 729 if (VM.runningVM && VM.VerifyAssertions) { 730 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 731 } 732 733 if (objectAddressRemapper == null) { 734 return object; // tool isn't interested in remapping 735 } 736 737 return objectAddressRemapper.intern(object); 738 } 739 740 /** 741 * Certain objects aren't replicated in the boot image to save space. 742 * @param object to intern 743 * @return interned object 744 */ 745 public static int bootImageIdentityHashCode(Object object) { 746 if (VM.runningVM && VM.VerifyAssertions) { 747 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 748 } 749 750 if (objectAddressRemapper == null) { 751 // shouldn't create identity hash codes when we cannot record the effect, ignore if we're running a tool 752 if (VM.VerifyAssertions) VM._assert(VM.runningTool || VM.writingImage); 753 return System.identityHashCode(object); 754 } 755 756 return objectAddressRemapper.identityHashCode(object); 757 } 758 759 /** 760 * Cast bits. 761 * @param address object reference as bits 762 * @return object reference 763 */ 764 public static Object addressAsObject(Address address) { 765 if (VM.runningVM && VM.VerifyAssertions) { 766 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 767 } 768 769 if (objectAddressRemapper == null) { 770 return null; // tool isn't interested in remapping 771 } 772 773 return objectAddressRemapper.addressAsObject(address); 774 } 775 776 /** 777 * Cast bits of code array into an object 778 * Note: for use by Statics when assigning slots to static method pointers 779 * @param code the code array to convert 780 * @return object reference 781 */ 782 public static Object codeArrayAsObject(CodeArray code) { 783 if (VM.runningVM && VM.VerifyAssertions) { 784 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 785 } 786 787 return code; 788 } 789 790 /** 791 * Cast bits of tib into an object 792 * Note: for use by Statics when assigning slots 793 * @param tib the tib to convert 794 * @return object reference 795 */ 796 public static Object tibAsObject(TIB tib) { 797 if (VM.runningVM && VM.VerifyAssertions) { 798 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 799 } 800 801 return tib; 802 } 803 804 /** 805 * Cast bits. 806 * @param address object array reference as bits 807 * @return object array reference 808 */ 809 public static TIB addressAsTIB(Address address) { 810 if (VM.runningVM && VM.VerifyAssertions) { 811 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 812 } 813 return null; 814 } 815 816 /** 817 * Cast object. 818 * @param object object reference 819 * @return object reference as type (no checking on cast) 820 */ 821 public static RVMType objectAsType(Object object) { 822 if (VM.runningVM && VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 823 824 return (RVMType)object; 825 } 826 827 /** 828 * Cast object. 829 * Note: for use by GC to avoid checkcast during GC 830 * @param object object reference 831 * @return object reference as thread (no checking on cast) 832 */ 833 public static RVMThread objectAsThread(Object object) { 834 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 835 return null; 836 } 837 /** 838 * Cast bits. 839 * @param number A floating point number 840 * @return <code>number</code> as bits 841 */ 842 public static int floatAsIntBits(float number) { 843 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 844 return -1; 845 } 846 847 /** 848 * Cast bits. 849 * @param number as bits 850 * @return <code>number</code> as a <code>float</code> 851 */ 852 public static float intBitsAsFloat(int number) { 853 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 854 return -1; 855 } 856 857 /** 858 * Cast bits. 859 * @param number as double 860 * @return number as bits 861 */ 862 public static long doubleAsLongBits(double number) { 863 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 864 return -1; 865 } 866 867 /** 868 * Cast bits. 869 * @param number as bits 870 * @return number as double 871 */ 872 public static double longBitsAsDouble(long number) { 873 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 874 return -1; 875 } 876 877 /** 878 * Recast. 879 * Note: for use by GC to avoid checkcast during GC 880 * @param byte_array an address 881 * Returned: byte array (byte[]) object reference 882 */ 883 public static byte[] addressAsByteArray(Address byte_array) { 884 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 885 return null; 886 } 887 888 /** 889 * Cast object. 890 * Note: for use in dynamic type checking (avoid dynamic type checking in impl. of dynamic type checking) 891 * @param object 892 * @return short array (short[]) object reference 893 */ 894 public static short[] objectAsShortArray(Object object) { 895 if (VM.runningVM && VM.VerifyAssertions) { 896 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 897 } 898 return (short[]) object; 899 } 900 901 /** 902 * Cast object. 903 * Note: for use in dynamic type checking (avoid dynamic type checking in impl. of dynamic type checking) 904 * @param object 905 * @return int array (int[]) object reference 906 */ 907 public static int[] objectAsIntArray(Object object) { 908 if (VM.runningVM && VM.VerifyAssertions) { 909 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 910 } 911 return (int[]) object; 912 } 913 914 //---------------------------------------// 915 // Object Header Access. // 916 //---------------------------------------// 917 918 /** 919 * Get an object's type. 920 * @param object object reference 921 * @return object type 922 */ 923 public static RVMType getObjectType(Object object) { 924 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 925 return null; 926 } 927 928 /** 929 * Get an array's length. 930 * @param object object reference 931 * @return array length (number of elements) 932 */ 933 public static int getArrayLength(Object object) { 934 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 935 return -1; 936 } 937 938 //---------------------------------------// 939 // Method Invocation And Stack Trickery. // 940 //---------------------------------------// 941 942 /** 943 * Saves current thread state. Stores the values in the hardware registers 944 * into a Registers object. 945 * <p> 946 * We used to use this to implement thread switching, but we have a 947 * threadSwitch magic now that does both of these in a single step as that 948 * is less error-prone. saveThreadState is now only used in the 949 * implementation of athrow (RuntimeEntrypoints.athrow). 950 * <p> 951 * The following registers are saved: 952 * <ul> 953 * <li>nonvolatile fpr registers 954 * <li>nonvolatile gpr registers 955 * <li>FRAME_POINTER register 956 * <li>THREAD_ID "register" 957 * </ul> 958 * @param registers place to save register values 959 */ 960 // PNT: make a version of this that implicitly uses contextRegisters. 961 public static void saveThreadState(Registers registers) { 962 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 963 } 964 /** 965 * Switch threads. 966 * The following registers are saved/restored 967 * <ul> 968 * <li>nonvolatile fpr registers 969 * <li>nonvolatile gpr registers 970 * <li>FRAME_POINTER register 971 * <li>THREAD_ID "register" 972 * </ul> * 973 * @param currentThread thread that is currently running 974 * @param restoreRegs registers from which we should restore 975 * the saved hardware state of another thread. 976 */ 977 public static void threadSwitch(RVMThread currentThread, Registers restoreRegs) { 978 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 979 } 980 981 /** 982 * Resume execution with specified thread exception state. 983 * <p> 984 * Restores virtually all registers (details vary by architecture). 985 * But, the following are _NOT_ restored 986 * <ul> 987 * <li>JTOC_POINTER 988 * <li>THREAD_REGISTER 989 * </ul> 990 * does not return (execution resumes at new IP) 991 * @param registers register values to be used 992 */ 993 public static void restoreHardwareExceptionState(Registers registers) { 994 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 995 } 996 997 /** 998 * Return to caller of current method, resuming execution on a new stack 999 * that's a copy of the original. 1000 * @param fp value to place into FRAME_POINTER register 1001 */ 1002 public static void returnToNewStack(Address fp) { 1003 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1004 } 1005 1006 /** 1007 * Transfer execution to target of a dynamic bridge method. 1008 * <p> 1009 * The following registers are restored: non-volatiles, volatiles 1010 * <p> 1011 * Note: this method must only be called from a DynamicBridge method because it 1012 * never returns (target method returns to caller of dynamic bridge method) 1013 * @param instructions target method 1014 */ 1015 public static void dynamicBridgeTo(CodeArray instructions) { 1016 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1017 } 1018 1019 /** Call <clinit> method with no argument list. */ 1020 public static void invokeClassInitializer(CodeArray clinit) throws Exception { 1021 // Since the real method passes exceptions up. Constructor might throw an arbitrary exception. 1022 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1023 throw new Exception("UNREACHED"); 1024 } 1025 1026 /** Call arbitrary method with argument list. */ 1027 public static void invokeMethodReturningVoid(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) { 1028 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1029 } 1030 1031 /** Call arbitrary method with argument list. */ 1032 public static int invokeMethodReturningInt(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) { 1033 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1034 return -1; 1035 } 1036 1037 /** Call arbitrary method with argument list. */ 1038 public static long invokeMethodReturningLong(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) { 1039 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1040 return -1; 1041 } 1042 1043 /** Call arbitrary method with argument list. */ 1044 public static float invokeMethodReturningFloat(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) { 1045 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1046 return -1; 1047 } 1048 1049 /** Call arbitrary method with argument list. */ 1050 public static double invokeMethodReturningDouble(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) { 1051 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1052 return -1; 1053 } 1054 1055 /** Call arbitrary method with argument list. */ 1056 public static Object invokeMethodReturningObject(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) { 1057 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1058 return null; 1059 } 1060 1061 //---------------------------------------// 1062 // Memory Fences. // 1063 //---------------------------------------// 1064 1065 /** 1066 * Disallow any reads to float above this point. 1067 */ 1068 public static void readCeiling() { 1069 if (VM.runningVM && VM.VerifyAssertions) { 1070 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1071 } 1072 } 1073 1074 /** 1075 * Disallow any writes to sink below this point. 1076 */ 1077 public static void writeFloor() { 1078 if (VM.runningVM && VM.VerifyAssertions) { 1079 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1080 } 1081 } 1082 1083 //---------------------------------------// 1084 // Cache Management. // 1085 //---------------------------------------// 1086 1087 /**** NOTE: all per-address operations now live in vmmagic.Address *****/ 1088 1089 /** 1090 * A strong memory fence, used to enforce StoreLoad in the JMM. 1091 */ 1092 public static void fence() { 1093 if (VM.runningVM && VM.VerifyAssertions) { 1094 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1095 } 1096 } 1097 1098 /** 1099 * Wait for preceeding cache flush/invalidate instructions to 1100 * complete on all processors. 1101 */ 1102 public static void sync() { 1103 if (VM.runningVM && VM.VerifyAssertions) { 1104 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1105 } 1106 } 1107 1108 /** 1109 * Wait for all preceeding instructions to complete and discard any 1110 * prefetched instructions on this processor. 1111 */ 1112 public static void isync() { 1113 if (VM.runningVM && VM.VerifyAssertions) { 1114 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1115 } 1116 } 1117 1118 /**************************************************************** 1119 * 1120 * Misc 1121 * 1122 */ 1123 1124 /** 1125 * On IA32, emit a PAUSE instruction, to optimize spin-wait loops. 1126 */ 1127 public static void pause() { 1128 if (VM.runningVM && VM.VerifyAssertions) { 1129 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1130 } 1131 } 1132 1133 /** 1134 * A hardware SQRT instruction 1135 */ 1136 public static float sqrt(float value) { 1137 if (VM.runningVM && VM.VerifyAssertions) { 1138 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1139 } 1140 return -1.0f; // which should upset them even if assertions aren't enabled ... 1141 } 1142 1143 /** 1144 * A hardware SQRT instruction 1145 */ 1146 public static double sqrt(double value) { 1147 if (VM.runningVM && VM.VerifyAssertions) { 1148 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1149 } 1150 return -1.0d; // which should upset them even if assertions aren't enabled ... 1151 } 1152 1153 /** 1154 * How deeply inlined is this method (0 means no inlining). 1155 */ 1156 public static int getInlineDepth() { 1157 if (VM.runningVM && VM.VerifyAssertions) { 1158 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1159 } 1160 return 0; 1161 } 1162 1163 /** 1164 * Is the specified parameter constant (due to either inlining or specialization). 1165 * Count starts at zero and includes the 'this' parameter for instance methods. 1166 */ 1167 public static boolean isConstantParameter(int index) { 1168 if (VM.runningVM && VM.VerifyAssertions) { 1169 VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler 1170 } 1171 return false; 1172 } 1173 }