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 */
013package org.jikesrvm.runtime;
014
015import org.jikesrvm.compilers.common.CodeArray;
016import org.jikesrvm.architecture.AbstractRegisters;
017import org.jikesrvm.VM;
018import org.jikesrvm.classloader.RVMType;
019import org.jikesrvm.objectmodel.TIB;
020import org.jikesrvm.scheduler.RVMThread;
021import org.vmmagic.Intrinsic;
022import org.vmmagic.pragma.Entrypoint;
023import org.vmmagic.pragma.Uninterruptible;
024import org.vmmagic.unboxed.Address;
025import org.vmmagic.unboxed.Extent;
026import org.vmmagic.unboxed.Offset;
027import org.vmmagic.unboxed.Word;
028import 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
041public final class Magic {
042
043  //---------------------------------------//
044  // Register and Psuedo-Register Access.  //
045  //---------------------------------------//
046
047  /** @return 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  /** @return contents of "JTOC" register. */
054  public static Address getTocPointer() {
055    if (VM.VerifyAssertions && VM.runningVM) {
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  /** @return 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  /** @return 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  /**
074   * Sets contents of "thread" register.
075   * @param p new contents of the thread register
076   */
077  public static void setThreadRegister(RVMThread p) {
078    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
079  }
080
081  /** @return contents of ESI, as a RVMThread. NOTE: IA-specific */
082  public static RVMThread getESIAsThread() {
083    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
084    return null;
085  }
086
087  /**
088   * Sets contents of ESI to hold a reference to a thread object. NOTE: IA-specific.
089   * @param p the thread
090   */
091  public static void setESIAsThread(RVMThread p) {
092    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
093  }
094
095  /**
096   * Reads contents of hardware time base registers.
097   * <p>
098   * Note:     we think that 1 "tick" == 4 "machine cycles", but this seems to be
099   *           undocumented and may vary across processor implementations.
100   * @return number of ticks (epoch undefined)
101   */
102  public static long getTimeBase() {
103    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
104    return -1;
105  }
106
107  //---------------------------------------//
108  //       Stackframe Manipulation         //
109  //---------------------------------------//
110
111  /**
112   * Get fp for parent frame
113   * @param fp frame pointer for child frame
114   * @return the frame pointer of the parent frame
115   */
116  public static Address getCallerFramePointer(Address fp) {
117    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
118    return null;
119  }
120
121  /**
122   * Set fp for parent frame
123   * @param fp frame pointer for child frame
124   * @param newCallerFP new value for caller frame pointer
125   */
126  public static void setCallerFramePointer(Address fp, Address newCallerFP) {
127    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
128  }
129
130  /**
131   * @param fp its frame pointer
132   * @return the compiled Method ID for the frame
133   */
134  public static int getCompiledMethodID(Address fp) {
135    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
136    return -1;
137  }
138
139  /**
140   * Sets the Compiled Method ID for a frame.
141   * @param fp its frame pointer
142   * @param newCMID a new cmid for the frame
143   */
144  public static void setCompiledMethodID(Address fp, int newCMID) {
145    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
146  }
147
148  /**
149   * @param fp its frame pointer.
150   * @return next instruction address for a frame
151   */
152  public static Address getNextInstructionAddress(Address fp) {
153    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
154    return null;
155  }
156
157  /**
158   * @param fp its frame pointer
159   * @return location containing return address for a frame
160   */
161  public static Address getReturnAddressLocation(Address fp) {
162    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
163    return null;
164  }
165
166  /**
167   * Get return address for a frame in a case where the frame is
168   * known not to be a trampoline frame.
169   *
170   * @param fp its frame pointer
171   * @return the return address
172   */
173  @Uninterruptible
174  public static Address getReturnAddressUnchecked(Address fp) {
175    Address ip = getReturnAddressLocation(fp).loadAddress();
176    if (VM.VerifyAssertions) VM._assert(!RVMThread.isTrampolineIP(ip));
177    return ip;
178  }
179
180  /**
181   * Get return address for a frame in the current thread
182   *
183   * @param fp its frame pointer
184   * @return the return address
185   */
186  @Uninterruptible
187  public static Address getReturnAddress(Address fp) {
188    return getReturnAddress(fp, RVMThread.getCurrentThread());
189  }
190
191  /**
192   * Get return address for a frame in a specific thread
193   *
194   * @param fp its frame pointer
195   * @param thread the thread whose stack is being examined
196   * @return the return address
197   */
198  @Uninterruptible
199  public static Address getReturnAddress(Address fp, RVMThread thread) {
200    Address ip = getReturnAddressLocation(fp).loadAddress();
201    if (RVMThread.isTrampolineIP(ip))
202      return thread.getTrampolineHijackedReturnAddress();
203    else
204      return ip;
205  }
206
207  /**
208   * Sets return address for a frame.
209   * @param fp its frame pointer
210   * @param v the new return address
211   */
212  @Uninterruptible
213  public static void setReturnAddress(Address fp, Address v) {
214    getReturnAddressLocation(fp).store(v);
215  }
216
217  //---------------------------------------//
218  //           Memory Access.              //
219  //---------------------------------------//
220
221  /**
222   * Get unsigned byte at arbitrary (byte) offset from object. The
223   * most significant 24bits of the result will be 0.
224   *
225   * @param object the object serving as start address
226   * @param offset the offset from the object
227   * @return the byte at the location
228   */
229  public static byte getUnsignedByteAtOffset(Object object, Offset offset) {
230    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
231    return -1;
232  }
233
234  /**
235   * Get byte at arbitrary (byte) offset from object. The most
236   * significant 24bits of the result will be the same as the most
237   * significant bit in the byte.
238   *
239   * @param object the object serving as start address
240   * @param offset the offset from the object
241   * @return the byte at the location
242   */
243  public static byte getByteAtOffset(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 -1;
246  }
247
248  /**
249   * Get char at arbitrary (byte) offset from object. The most
250   * significant 16bits will be 0.
251   *
252   * @param object the object serving as start address
253   * @param offset the offset from the object
254   * @return the char at the location
255   */
256  public static char getCharAtOffset(Object object, Offset offset) {
257    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
258    return (char) -1;
259  }
260
261  /**
262   * Get short at arbitrary (byte) offset from object. The most
263   * significant 16bits will be the same as the most significant bit
264   * in the short.
265   *
266   * @param object the object serving as start address
267   * @param offset the offset from the object
268   * @return the short at the location
269   */
270  public static short getShortAtOffset(Object object, Offset offset) {
271    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
272    return (short) -1;
273  }
274
275  /**
276   * Get int at arbitrary (byte) offset from object.
277   * Use getIntAtOffset(obj, ofs) instead of getMemoryInt(objectAsAddress(obj)+ofs)
278   *
279   * @param object the object serving as start address
280   * @param offset the offset from the object
281   * @return the int at the location
282   */
283  public static int getIntAtOffset(Object object, Offset offset) {
284    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
285    return -1;
286  }
287
288  /**
289   * Get long at arbitrary (byte) offset from object.
290   * Use getlongAtOffset(obj, ofs) instead of two getIntAtOffset
291
292   * @param object the object serving as start address
293   * @param offset the offset from the object
294   * @return the long at the location
295   */
296  public static long getLongAtOffset(Object object, Offset offset) {
297    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
298    return -1;
299  }
300
301  /**
302   * Get float at arbitrary (byte) offset from object.
303   *
304   * @param object the object serving as start address
305   * @param offset the offset from the object
306   * @return the float at the location
307   */
308  public static float getFloatAtOffset(Object object, Offset offset) {
309    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
310    return -1;
311  }
312
313  /**
314   * Get double at arbitrary (byte) offset from object.
315   * Use getDoubleAtOffset(obj, ofs) instead of two getIntAtOffset
316   *
317   * @param object the object serving as start address
318   * @param offset the offset from the object
319   * @return the double at the location
320   */
321  public static double getDoubleAtOffset(Object object, Offset offset) {
322    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
323    return -1;
324  }
325
326  /**
327   * Get Object at arbitrary (byte) offset from object.
328   * Use getObjectAtOffset(obj, ofs) instead of
329   * addressAsObject(getMemoryAddress(objectAsAddress(obj)+ofs))
330   *
331   * @param object the object serving as start address
332   * @param offset the offset from the object
333   * @return the object at the location
334   */
335  public static Object getObjectAtOffset(Object object, Offset offset) {
336    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
337    return null;
338  }
339
340  /**
341   * Get Object at arbitrary (byte) offset from object.
342   * Use getObjectAtOffset(obj, ofs) instead of
343   * addressAsObject(getMemoryAddress(objectAsAddress(obj)+ofs))
344   *
345   * @param object the object serving as start address
346   * @param offset the offset from the object
347   * @param locationMetadata metadata about the location for the compilers
348   * @return the object at the computed address
349   */
350  public static Object getObjectAtOffset(Object object, Offset offset, int locationMetadata) {
351    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
352    return null;
353  }
354
355  /**
356   * Get Word at arbitrary (byte) offset from object.
357   * Use getWordAtOffset(obj, ofs) instead of getMemoryWord(objectAsAddress(obj)+ofs)
358   *
359   * @param object the object serving as start address
360   * @param offset the offset from the object
361   * @return the word at the computed address
362   */
363  public static Word getWordAtOffset(Object object, Offset offset) {
364    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
365    return Word.max();
366  }
367
368  /**
369   * Get Word at arbitrary (byte) offset from object.
370   *
371   * @param object the object serving as start address
372   * @param offset the offset from the object
373   * @param locationMetadata metadata about the location for the compilers
374   * @return the Word at the computed address
375   */
376  public static Word getWordAtOffset(Object object, Offset offset, int locationMetadata) {
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   * Get Address at arbitrary (byte) offset from object.
383   * Use getAddressAtOffset(obj, ofs) instead of getMemoryWord(objectAsAddress(obj)+ofs)
384   *
385   * @param object the object serving as start address
386   * @param offset the offset from the object
387   * @return the Address at the computed address
388   */
389  public static Address getAddressAtOffset(Object object, Offset offset) {
390    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
391    return null;
392  }
393
394  /**
395   * Get Address at arbitrary (byte) offset from object.
396   *
397   * @param object the object serving as start address
398   * @param offset the offset from the object
399   * @param locationMetadata metadata about the location for the compilers
400   * @return the Address at the computed address
401   */
402  public static Address getAddressAtOffset(Object object, Offset offset, int locationMetadata) {
403    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
404    return null;
405  }
406
407  /**
408   * Get Extent at arbitrary (byte) offset from object.
409   * Use getExtentAtOffset(obj, ofs) instead of getMemoryWord(objectAsAddress(obj)+ofs)
410   *
411   * @param object the object serving as start address
412   * @param offset the offset from the object
413   * @return the Extent at the computed address
414   */
415  public static Extent getExtentAtOffset(Object object, Offset offset) {
416    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
417    return null;
418  }
419
420  /**
421   * Get Extent at arbitrary (byte) offset from object.
422   *
423   * @param object the object serving as start address
424   * @param offset the offset from the object
425   * @param locationMetadata metadata about the location for the compilers
426   * @return the Extent at the computed address
427   */
428  public static Extent getExtentAtOffset(Object object, Offset offset, int locationMetadata) {
429    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
430    return null;
431  }
432
433  /**
434   * Get Offset at arbitrary (byte) offset from object.
435   * Use getOffsetAtOffset(obj, ofs) instead of getMemoryWord(objectAsAddress(obj)+ofs)
436   *
437   * @param object the object serving as start address
438   * @param offset the offset from the object
439   * @return the Offset at the computed address
440   */
441  public static Offset getOffsetAtOffset(Object object, Offset offset) {
442    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
443    return null;
444  }
445
446  /**
447   * Get Offset at arbitrary (byte) offset from object.
448   *
449   * @param object the object serving as start address
450   * @param offset the offset from the object
451   * @param locationMetadata metadata about the location for the compilers
452   * @return the Offset at the computed address
453   */
454  public static Offset getOffsetAtOffset(Object object, Offset offset, int locationMetadata) {
455    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
456    return null;
457  }
458
459  /**
460   * Get TIB at arbitrary (byte) offset from object.
461   * Use getTIBAtOffset(obj, ofs) instead of
462   * (TIB])addressAsObject(getMemoryAddr(objectAsAddress(obj)+ofs))
463   *
464   * @param object the object serving as start address
465   * @param offset the offset from the object
466   * @return the TIB at the computed address
467   */
468  public static TIB getTIBAtOffset(Object object, Offset offset) {
469    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
470    return null;
471  }
472
473  /**
474   * Set boolean at arbitrary (byte) offset from object.
475   *
476   * @param object the object serving as start address
477   * @param offset the offset from the object
478   * @param newvalue the value to write to the computed address
479   */
480  public static void setBooleanAtOffset(Object object, Offset offset, boolean newvalue) {
481    if (VM.VerifyAssertions)
482      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
483  }
484
485  /**
486   * Set boolean at arbitrary (byte) offset from object.
487   *
488   * @param object the object serving as start address
489   * @param offset the offset from the object
490   * @param newvalue the value to write to the computed address
491   * @param locationMetadata metadata about the location for the compilers
492   */
493  public static void setBooleanAtOffset(Object object, Offset offset, boolean newvalue, int locationMetadata) {
494    if (VM.VerifyAssertions)
495      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
496  }
497
498  /**
499   * Set byte at arbitrary (byte) offset from object.
500   *
501   * @param object the object serving as start address
502   * @param offset the offset from the object
503   * @param newvalue the value to write to the computed address
504   */
505  public static void setByteAtOffset(Object object, Offset offset, byte newvalue) {
506    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
507  }
508
509  /**
510   * Set byte at arbitrary (byte) offset from object.
511   *
512   * @param object the object serving as start address
513   * @param offset the offset from the object
514   * @param newvalue the value to write to the computed address
515   * @param locationMetadata metadata about the location for the compilers
516   */
517  public static void setByteAtOffset(Object object, Offset offset, byte newvalue, int locationMetadata) {
518    if (VM.VerifyAssertions)
519      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
520  }
521
522  /**
523   * Set char at arbitrary (byte) offset from object.
524   *
525   * @param object the object serving as start address
526   * @param offset the offset from the object
527   * @param newvalue the value to write to the computed address
528   */
529  public static void setCharAtOffset(Object object, Offset offset, char newvalue) {
530    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
531  }
532
533  /**
534   * Set char at arbitrary (byte) offset from object.
535   *
536   * @param object the object serving as start address
537   * @param offset the offset from the object
538   * @param newvalue the value to write to the computed address
539   * @param locationMetadata metadata about the location for the compilers
540   */
541  public static void setCharAtOffset(Object object, Offset offset, char newvalue, int locationMetadata) {
542    if (VM.VerifyAssertions)
543      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
544  }
545
546  /**
547   * Set short at arbitrary (byte) offset from object.
548   *
549   * @param object the object serving as start address
550   * @param offset the offset from the object
551   * @param newvalue the value to write to the computed address
552   */
553  public static void setShortAtOffset(Object object, Offset offset, short newvalue) {
554    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
555  }
556
557  /**
558   * Set short at arbitrary (byte) offset from object.
559   *
560   * @param object the object serving as start address
561   * @param offset the offset from the object
562   * @param newvalue the value to write to the computed address
563   * @param locationMetadata metadata about the location for the compilers
564   */
565  public static void setShortAtOffset(Object object, Offset offset, short newvalue, int locationMetadata) {
566    if (VM.VerifyAssertions)
567      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
568  }
569
570  /**
571   * Set int at arbitrary (byte) offset from object.
572   * Use setIntAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
573   *
574   * @param object the object serving as start address
575   * @param offset the offset from the object
576   * @param newvalue the value to write to the computed address
577   */
578  public static void setIntAtOffset(Object object, Offset offset, int newvalue) {
579    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
580  }
581
582  /**
583   * Set int at arbitrary (byte) offset from object.
584   *
585   * @param object the object serving as start address
586   * @param offset the offset from the object
587   * @param newvalue the value to write to the computed address
588   * @param locationMetadata metadata about the location for the compilers
589   */
590  public static void setIntAtOffset(Object object, Offset offset, int newvalue, int locationMetadata) {
591    if (VM.VerifyAssertions)
592      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
593  }
594
595  /**
596   * Set long at arbitrary (byte) offset from object.
597   * Use setlongAtOffset(obj, ofs) instead of two setIntAtOffset
598   *
599   * @param object the object serving as start address
600   * @param offset the offset from the object
601   * @param newvalue the value to write to the computed address
602   */
603  public static void setLongAtOffset(Object object, Offset offset, long newvalue) {
604    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
605  }
606
607  /**
608   * Set long at arbitrary (byte) offset from object. Use setlongAtOffset(obj,
609   * ofs) instead of two setIntAtOffset
610   *
611   * @param object the object serving as start address
612   * @param offset the offset from the object
613   * @param newvalue the value to write to the computed address
614   * @param locationMetadata metadata about the location for the compilers
615   */
616  public static void setLongAtOffset(Object object, Offset offset, long newvalue, int locationMetadata) {
617    if (VM.VerifyAssertions)
618      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
619  }
620
621  /**
622   * Set float at arbitrary (byte) offset from object.
623   *
624   * @param object the object serving as start address
625   * @param offset the offset from the object
626   * @param newvalue the value to write to the computed address
627   */
628  public static void setFloatAtOffset(Object object, Offset offset, float newvalue) {
629    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
630  }
631
632  /**
633   * Set float at arbitrary (byte) offset from object.
634   *
635   * @param object the object serving as start address
636   * @param offset the offset from the object
637   * @param newvalue the value to write to the computed address
638   * @param locationMetadata metadata about the location for the compilers
639   */
640  public static void setFloatAtOffset(Object object, Offset offset, float newvalue, int locationMetadata) {
641    if (VM.VerifyAssertions)
642      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
643  }
644
645  /**
646   * Set double at arbitrary (byte) offset from object.
647   * Use setDoubleAtOffset(obj, ofs) instead of two setIntAtOffset
648   *
649   * @param object the object serving as start address
650   * @param offset the offset from the object
651   * @param newvalue the value to write to the computed address
652   */
653  public static void setDoubleAtOffset(Object object, Offset offset, double newvalue) {
654    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
655  }
656
657  /**
658   * Set double at arbitrary (byte) offset from object. Use
659   * setDoubleAtOffset(obj, ofs) instead of two setIntAtOffset
660   *
661   * @param object the object serving as start address
662   * @param offset the offset from the object
663   * @param newvalue the value to write to the computed address
664   * @param locationMetadata metadata about the location for the compilers
665   */
666  public static void setDoubleAtOffset(Object object, Offset offset, double newvalue, int locationMetadata) {
667    if (VM.VerifyAssertions)
668      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
669  }
670
671  /**
672   * Set Word at arbitrary (byte) offset from object.
673   * Use setWordAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
674   *
675   * @param object the object serving as start address
676   * @param offset the offset from the object
677   * @param newvalue the value to write to the computed address
678   */
679  public static void setWordAtOffset(Object object, Offset offset, Word newvalue) {
680    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
681  }
682
683  /**
684   * Set Word at arbitrary (byte) offset from object.
685   * Use setWordAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
686   *
687   * @param object the object serving as start address
688   * @param offset the offset from the object
689   * @param newvalue the value to write to the computed address
690   * @param locationMetadata metadata about the location for the compilers
691   */
692  public static void setWordAtOffset(Object object, Offset offset, Word newvalue, int locationMetadata) {
693    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
694  }
695
696  /**
697   * Set Address at arbitrary (byte) offset from object.
698   * Use setAddressAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
699   *
700   * @param object the object serving as start address
701   * @param offset the offset from the object
702   * @param newvalue the value to write to the computed address
703   */
704  public static void setAddressAtOffset(Object object, Offset offset, Address newvalue) {
705    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
706  }
707
708  /**
709   * Set Address at arbitrary (byte) offset from object.
710   * Use setAddressAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
711   *
712   * @param object the object serving as start address
713   * @param offset the offset from the object
714   * @param newvalue the value to write to the computed address
715   * @param locationMetadata metadata about the location for the compilers
716   */
717  public static void setAddressAtOffset(Object object, Offset offset, Address newvalue, int locationMetadata) {
718    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
719  }
720
721  /**
722   * Set Extent at arbitrary (byte) offset from object.
723   * Use setExtentAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
724   *
725   * @param object the object serving as start address
726   * @param offset the offset from the object
727   * @param newvalue the value to write to the computed address
728   */
729  public static void setExtentAtOffset(Object object, Offset offset, Extent newvalue) {
730    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
731  }
732
733  /**
734   * Set Extent at arbitrary (byte) offset from object.
735   * Use setExtenttOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
736   *
737   * @param object the object serving as start address
738   * @param offset the offset from the object
739   * @param newvalue the value to write to the computed address
740   * @param locationMetadata metadata about the location for the compilers
741   */
742  public static void setExtentAtOffset(Object object, Offset offset, Extent newvalue, int locationMetadata) {
743    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
744  }
745
746  /**
747   * Set Offset at arbitrary (byte) offset from object.
748   * Use setOffsetAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
749   *
750   * @param object the object serving as start address
751   * @param offset the offset from the object
752   * @param newvalue the value to write to the computed address
753   */
754  public static void setOffsetAtOffset(Object object, Offset offset, Offset newvalue) {
755    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
756  }
757
758  /**
759   * Set Offset at arbitrary (byte) offset from object.
760   * Use setOffsetAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, new)
761   *
762   * @param object the object serving as start address
763   * @param offset the offset from the object
764   * @param newvalue the value to write to the computed address
765   * @param locationMetadata metadata about the location for the compilers
766   */
767  public static void setOffsetAtOffset(Object object, Offset offset, Offset newvalue, int locationMetadata) {
768    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
769  }
770
771  /**
772   * Set Object at arbitrary (byte) offset from object.
773   * Use setObjectAtOffset(obj, ofs, new) instead of setMemoryWord(objectAsAddress(obj)+ofs, objectAsAddress(new))
774   *
775   * @param object the object serving as start address
776   * @param offset the offset from the object
777   * @param newvalue the value to write to the computed address
778   */
779  public static void setObjectAtOffset(Object object, Offset offset, Object newvalue) {
780    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
781  }
782
783  /**
784   * Set Object at arbitrary (byte) offset from object
785   *
786   * @param object the object serving as start address
787   * @param offset the offset from the object
788   * @param newvalue the value to write to the computed address
789   * @param locationMetadata metadata about the location for the compilers
790   */
791  public static void setObjectAtOffset(Object object, Offset offset, Object newvalue, int locationMetadata) {
792    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
793  }
794
795
796  //---------------------------------------//
797  //    Atomic Memory Access Primitives.   //
798  //---------------------------------------//
799
800  /**
801   * Gets contents of (object + offset) and begin conditional critical section.
802   *
803   * @param object the object serving as start address
804   * @param offset the offset from the object
805   * @return the int that was read out from the computed address
806   */
807  public static int prepareInt(Object object, Offset offset) {
808    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
809    return -1;
810  }
811
812  /**
813   * Get contents of (object + offset) and begin conditional critical section.
814   *
815   * @param object the object serving as start address
816   * @param offset the offset from the object
817   * @return the object that was read out from the computed address
818   */
819  public static Object prepareObject(Object object, Offset offset) {
820    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
821    return null;
822  }
823
824  /**
825   * Get contents of (object + offset) and begin conditional critical section.
826   *
827   * @param object the object serving as start address
828   * @param offset the offset from the object
829   * @return the Address that was read out from the computed address
830   */
831  public static Address prepareAddress(Object object, Offset offset) {
832    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
833    return Address.max();
834  }
835
836  /**
837   * Get contents of (object + offset) and begin conditional critical section.
838   *
839   * @param object the object serving as start address
840   * @param offset the offset from the object
841   * @return the Word that was read out from the computed address
842   */
843  public static Word prepareWord(Object object, Offset offset) {
844    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
845    return Word.max();
846  }
847
848  /**
849   * Get contents of (object + offset) and begin conditional critical section.
850   *
851   * @param object the object serving as start address
852   * @param offset the offset from the object
853   * @return the long that was read out from the computed address
854   */
855  @Uninterruptible
856  public static long prepareLong(Object object, Offset offset) {
857    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
858    return -1;
859  }
860
861  /**
862   * Sets the memory at (object + offset) to newValue if its contents are oldValue.
863   * Must be paired with a preceding prepare (which returned the oldValue).
864   * Ends conditional critical section.
865   *
866   * @param object the object serving as start address
867   * @param offset the offset from the object
868   * @param oldValue the value that is expected to be at the computed address
869   * @param newValue the value that is supposed to be written to the computed
870   *  address
871   * @return {@code true} if successful, {@code false} if not
872   */
873  public static boolean attemptInt(Object object, Offset offset, int oldValue, int newValue) {
874    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
875    return false;
876  }
877
878  /**
879   * Sets the memory at (object + offset) to newValue if its contents are oldValue.
880   * Must be paired with a preceding prepare (which returned the oldValue)
881   * Ends conditional critical section.
882   *
883   * @param object the object serving as start address
884   * @param offset the offset from the object
885   * @param oldValue the value that is expected to be at the computed address
886   * @param newValue the value that is supposed to be written to the computed
887   *  address
888   * @return {@code true} if successful, {@code false} if not
889   */
890  public static boolean attemptObject(Object object, Offset offset, Object oldValue, Object newValue) {
891    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
892    return false;
893  }
894
895  /**
896   * Sets the memory at (object + offset) to newValue if its contents are oldValue.
897   * Must be paired with a preceding prepare (which returned the oldValue)
898   * Ends conditional critical section.
899   *
900   * @param object the object serving as start address
901   * @param offset the offset from the object
902   * @param oldValue the value that is expected to be at the computed address
903   * @param newValue the value that is supposed to be written to the computed
904   *  address
905   * @return {@code true} if successful, {@code false} if not
906   */
907  public static boolean attemptAddress(Object object, Offset offset, Address oldValue, Address newValue) {
908    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
909    return false;
910  }
911
912  /**
913   * Sets the memory at (object + offset) to newValue if its contents are oldValue.
914   * Must be paired with a preceding prepare (which returned the oldValue)
915   * Ends conditional critical section.
916   *
917   * @param object the object serving as start address
918   * @param offset the offset from the object
919   * @param oldValue the value that is expected to be at the computed address
920   * @param newValue the value that is supposed to be written to the computed
921   *  address
922   * @return {@code true} if successful, {@code false} if not
923   */
924  public static boolean attemptWord(Object object, Offset offset, Word oldValue, Word newValue) {
925    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
926    return false;
927  }
928
929  /**
930   * Sets the memory at (object + offset) to newValue if its contents are oldValue.
931   * Must be paired with a preceding prepare (which returned the oldValue)
932   * Ends conditional critical section.
933   *
934   * @param object the object serving as start address
935   * @param offset the offset from the object
936   * @param oldValue the value that is expected to be at the computed address
937   * @param newValue the value that is supposed to be written to the computed
938   *  address
939   * @return {@code true} if successful, {@code false} if not
940   */
941  public static boolean attemptLong(Object object, Offset offset, long oldValue,
942      long newValue) {
943    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
944    return false;
945  }
946
947  //---------------------------------------//
948  //             Type Conversion.          //
949  //---------------------------------------//
950
951  @Entrypoint
952  private static ObjectAddressRemapper objectAddressRemapper;
953
954  /**
955   * Specify how to handle "objectAsAddress" and "addressAsObject" casts.
956   * Used by debugger and boot image writer.
957   *
958   * @param x the remapper ot use
959   */
960  public static void setObjectAddressRemapper(ObjectAddressRemapper x) {
961    objectAddressRemapper = x;
962  }
963
964  /**
965   * Cast bits.
966   * Note: the returned integer is only valid until next garbage collection
967   *   cycle (thereafter the referenced object might have moved and
968   *   its address changed)
969   * @param <T> the object's type
970   * @param object object reference
971   * @return object reference as bits
972   */
973  public static <T> Address objectAsAddress(T object) {
974    if (VM.VerifyAssertions && VM.runningVM) {
975      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
976    }
977
978    if (objectAddressRemapper == null) {
979      return Address.zero();                 // tool isn't interested in remapping
980    }
981
982    return objectAddressRemapper.objectAsAddress(object);
983  }
984
985  /**
986   * Certain objects aren't replicated in the boot image to save space.
987   * @param <T> the object's type
988   * @param object to intern
989   * @return interned object
990   */
991  public static <T> T bootImageIntern(T object) {
992    if (VM.VerifyAssertions && VM.runningVM) {
993      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
994    }
995
996    if (objectAddressRemapper == null) {
997      return object;                 // tool isn't interested in remapping
998    }
999
1000    return objectAddressRemapper.intern(object);
1001  }
1002
1003  /**
1004   * Certain objects aren't replicated in the boot image to save space.
1005   * @param object to intern
1006   * @return interned object
1007   */
1008  public static int bootImageIdentityHashCode(Object object) {
1009    if (VM.VerifyAssertions && VM.runningVM) {
1010      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
1011    }
1012
1013    if (objectAddressRemapper == null) {
1014      // shouldn't create identity hash codes when we cannot record the effect, ignore if we're running a tool
1015      if (VM.VerifyAssertions) VM._assert(VM.runningTool || VM.writingImage);
1016      return System.identityHashCode(object);
1017    }
1018
1019    return objectAddressRemapper.identityHashCode(object);
1020  }
1021
1022  /**
1023   * Cast bits.
1024   * @param address object reference as bits
1025   * @return object reference
1026   */
1027  public static Object addressAsObject(Address address) {
1028    if (VM.VerifyAssertions && VM.runningVM) {
1029      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1030    }
1031
1032    if (objectAddressRemapper == null) {
1033      return null;               // tool isn't interested in remapping
1034    }
1035
1036    return objectAddressRemapper.addressAsObject(address);
1037  }
1038
1039  /**
1040   * Cast bits of code array into an object
1041   * Note: for use by Statics when assigning slots to static method pointers
1042   * @param code the code array to convert
1043   * @return object reference
1044   */
1045  public static Object codeArrayAsObject(CodeArray code) {
1046    if (VM.VerifyAssertions && VM.runningVM) {
1047      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
1048    }
1049
1050    return code;
1051  }
1052
1053  /**
1054   * Cast bits of tib into an object
1055   * Note: for use by Statics when assigning slots
1056   * @param tib the tib to convert
1057   * @return object reference
1058   */
1059  public static Object tibAsObject(TIB tib) {
1060    if (VM.VerifyAssertions && VM.runningVM) {
1061      VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
1062    }
1063
1064    return tib;
1065  }
1066
1067  /**
1068   * Cast bits.
1069   * @param address object array reference as bits
1070   * @return object array reference
1071   */
1072  public static TIB addressAsTIB(Address address) {
1073    if (VM.VerifyAssertions && VM.runningVM) {
1074      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1075    }
1076    return null;
1077  }
1078
1079  /**
1080   * Cast object.
1081   * @param object object reference
1082   * @return object reference as type (no checking on cast)
1083   */
1084  public static RVMType objectAsType(Object object) {
1085    if (VM.VerifyAssertions && VM.runningVM) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1086
1087    return (RVMType)object;
1088  }
1089
1090  /**
1091   * Cast object.
1092   * Note:     for use by GC to avoid checkcast during GC
1093   * @param object object reference
1094   * @return object reference as thread (no checking on cast)
1095   */
1096  public static RVMThread objectAsThread(Object object) {
1097    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1098    return null;
1099  }
1100  /**
1101   * Cast bits.
1102   * @param number A floating point number
1103   * @return   <code>number</code> as bits
1104   */
1105  public static int floatAsIntBits(float number) {
1106    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1107    return -1;
1108  }
1109
1110  /**
1111   * Cast bits.
1112   * @param number as bits
1113   * @return <code>number</code> as a <code>float</code>
1114   */
1115  public static float intBitsAsFloat(int number) {
1116    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1117    return -1;
1118  }
1119
1120  /**
1121   * Cast bits.
1122   * @param number as double
1123   * @return number as bits
1124   */
1125  public static long doubleAsLongBits(double number) {
1126    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1127    return -1;
1128  }
1129
1130  /**
1131   * Cast bits.
1132   * @param number as bits
1133   * @return number as double
1134   */
1135  public static double longBitsAsDouble(long number) {
1136    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1137    return -1;
1138  }
1139
1140  /**
1141   * Recast.
1142   * Note:     for use by GC to avoid checkcast during GC
1143   * @param byte_array an address
1144   * @return byte array (byte[])  object reference
1145   */
1146  public static byte[] addressAsByteArray(Address byte_array) {
1147    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1148    return null;
1149  }
1150
1151  /**
1152   * Cast object.
1153   * Note:     for use in dynamic type checking (avoid dynamic type checking in impl. of dynamic type checking)
1154   * @param object an object that must be a short array
1155   * @return short array (short[])  object reference
1156   */
1157  public static short[] objectAsShortArray(Object object) {
1158    if (VM.VerifyAssertions && VM.runningVM) {
1159      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1160    }
1161    return (short[]) object;
1162  }
1163
1164  /**
1165   * Cast object.
1166   * Note:     for use in dynamic type checking (avoid dynamic type checking in impl. of dynamic type checking)
1167   * @param object an object that must be an int array
1168   * @return int array (int[])  object reference
1169   */
1170  public static int[] objectAsIntArray(Object object) {
1171    if (VM.VerifyAssertions && VM.runningVM) {
1172      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1173    }
1174    return (int[]) object;
1175  }
1176
1177  //---------------------------------------//
1178  //          Object Header Access.        //
1179  //---------------------------------------//
1180
1181  /**
1182   * Get an object's type.
1183   * @param object object reference
1184   * @return object type
1185   */
1186  public static RVMType getObjectType(Object object) {
1187    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
1188    return null;
1189  }
1190
1191  /**
1192   * Get an array's length.
1193   * @param object object reference
1194   * @return array length (number of elements)
1195   */
1196  public static int getArrayLength(Object object) {
1197    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); // call site should have been hijacked by magic in compiler
1198    return -1;
1199  }
1200
1201  //---------------------------------------//
1202  // Method Invocation And Stack Trickery. //
1203  //---------------------------------------//
1204
1205  /**
1206   * Saves current thread state.  Stores the values in the hardware registers
1207   * into a Registers object.
1208   * <p>
1209   * We used to use this to implement thread switching, but we have a
1210   * threadSwitch magic now that does both of these in a single step as that
1211   * is less error-prone.  saveThreadState is now only used in the
1212   * implementation of athrow (RuntimeEntrypoints.athrow).
1213   * <p>
1214   * The following registers are saved:
1215   * <ul>
1216   *  <li>nonvolatile fpr registers
1217   *  <li>nonvolatile gpr registers
1218   *  <li>FRAME_POINTER register
1219   *  <li>THREAD_ID     "register"
1220   * </ul>
1221   * @param registers place to save register values
1222   */
1223  // PNT: make a version of this that implicitly uses contextRegisters.
1224  public static void saveThreadState(AbstractRegisters registers) {
1225    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1226  }
1227  /**
1228   * Switch threads.
1229   * The following registers are saved/restored
1230   * <ul>
1231   *  <li>nonvolatile fpr registers
1232   *  <li>nonvolatile gpr registers
1233   *  <li>FRAME_POINTER register
1234   *  <li>THREAD_ID     "register"
1235   * </ul>   *
1236   * @param currentThread thread that is currently running
1237   * @param restoreRegs   registers from which we should restore
1238   *                      the saved hardware state of another thread.
1239   */
1240  public static void threadSwitch(RVMThread currentThread, AbstractRegisters restoreRegs) {
1241    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1242  }
1243
1244  /**
1245   * Resume execution with specified thread exception state.
1246   * <p>
1247   * Restores virtually all registers (details vary by architecture).
1248   * But, the following are _NOT_ restored
1249   * <ul>
1250   *  <li>JTOC_POINTER
1251   *  <li>THREAD_REGISTER
1252   * </ul>
1253   * does not return (execution resumes at new IP)
1254   * @param registers register values to be used
1255   */
1256  public static void restoreHardwareExceptionState(AbstractRegisters registers) {
1257    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1258  }
1259
1260  /**
1261   * Return to caller of current method, resuming execution on a new stack
1262   * that's a copy of the original.
1263   * @param fp value to place into FRAME_POINTER register
1264   */
1265  public static void returnToNewStack(Address fp) {
1266    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1267  }
1268
1269  /**
1270   * Transfer execution to target of a dynamic bridge method.
1271   * <p>
1272   * The following registers are restored:  non-volatiles, volatiles
1273   * <p>
1274   * Note: this method must only be called from a DynamicBridge method because it
1275   * never returns (target method returns to caller of dynamic bridge method)
1276   * @param instructions target method
1277   */
1278  public static void dynamicBridgeTo(CodeArray instructions) {
1279    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1280  }
1281
1282  /**
1283   * Call &lt;clinit&gt; method with no argument list
1284   * @param clinit the code of the class initializer
1285   * @throws Exception all expections from invocation of the class initializer
1286   *  are passed along
1287   */
1288  public static void invokeClassInitializer(CodeArray clinit) throws Exception {
1289    // Since the real method passes exceptions up. Constructor might throw an arbitrary exception.
1290    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1291    throw new Exception("UNREACHED");
1292  }
1293
1294  /**
1295   * @param code the method's code
1296   * @param gprs parameters passed in the general purpose registers
1297   * @param fprs parameters passed in the floating point registers
1298   * @param fprmeta meta-data (e.g. flags) about the floating point registers
1299   * @param spills parameters passed on the stack
1300   */
1301  public static void invokeMethodReturningVoid(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) {
1302    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1303  }
1304
1305  /**
1306   * @param code the method's code
1307   * @param gprs parameters passed in the general purpose registers
1308   * @param fprs parameters passed in the floating point registers
1309   * @param fprmeta meta-data (e.g. flags) about the floating point registers
1310   * @param spills parameters passed on the stack
1311   * @return the return value of the called method
1312   */
1313  public static int invokeMethodReturningInt(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) {
1314    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1315    return -1;
1316  }
1317
1318  /**
1319   * @param code the method's code
1320   * @param gprs parameters passed in the general purpose registers
1321   * @param fprs parameters passed in the floating point registers
1322   * @param fprmeta meta-data (e.g. flags) about the floating point registers
1323   * @param spills parameters passed on the stack
1324   * @return the return value of the called method
1325   */
1326  public static long invokeMethodReturningLong(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) {
1327    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1328    return -1;
1329  }
1330
1331  /**
1332   * @param code the method's code
1333   * @param gprs parameters passed in the general purpose registers
1334   * @param fprs parameters passed in the floating point registers
1335   * @param fprmeta meta-data (e.g. flags) about the floating point registers
1336   * @param spills parameters passed on the stack
1337   * @return the return value of the called method
1338   */
1339  public static float invokeMethodReturningFloat(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) {
1340    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1341    return -1;
1342  }
1343
1344  /**
1345   * @param code the method's code
1346   * @param gprs parameters passed in the general purpose registers
1347   * @param fprs parameters passed in the floating point registers
1348   * @param fprmeta meta-data (e.g. flags) about the floating point registers
1349   * @param spills parameters passed on the stack
1350   * @return the return value of the called method
1351   */
1352  public static double invokeMethodReturningDouble(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) {
1353    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1354    return -1;
1355  }
1356
1357  /**
1358   * @param code the method's code
1359   * @param gprs parameters passed in the general purpose registers
1360   * @param fprs parameters passed in the floating point registers
1361   * @param fprmeta meta-data (e.g. flags) about the floating point registers
1362   * @param spills parameters passed on the stack
1363   * @return the return value of the called method
1364   */
1365  public static Object invokeMethodReturningObject(CodeArray code, WordArray gprs, double[] fprs, byte[] fprmeta, WordArray spills) {
1366    if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1367    return null;
1368  }
1369
1370  //---------------------------------------//
1371  //            Memory Fences.             //
1372  //---------------------------------------//
1373
1374  /**
1375   * Emits a strong memory fence, used to enforce StoreLoad in the JMM. A StoreLoad
1376   * barrier ensures that the data that was stored by the instruction before the
1377   * barrier is visible to all load instructions after the barrier.
1378   * <p>
1379   * Note: A StoreLoad barrier includes all other barriers on all platforms
1380   * that we currently support (IA32 and PPC).
1381   */
1382  public static void fence() {
1383    if (VM.VerifyAssertions && VM.runningVM) {
1384      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1385    }
1386  }
1387
1388  /**
1389   * Emits an instruction that provides both a LoadLoad and a LoadStore barrier.
1390   * A LoadLoad barrier ensures that the data accessed by all load instructions
1391   * before the barrier is loaded before any data from load instructions after
1392   * the barrier.
1393   * A LoadStore barrier ensures that the data accessed by all load instructions
1394   * before the barrier is loaded before any data store instructions after the barrier
1395   * are completed.
1396   * <p>
1397   * We don't provide separate methods for LoadStore and LoadLoad barriers because
1398   * the appropriate instructions for IA32 and PPC provide both barriers.
1399   */
1400  public static void combinedLoadBarrier() {
1401    if (VM.VerifyAssertions && VM.runningVM) {
1402      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1403    }
1404  }
1405
1406  /**
1407   * Emits a StoreStore barrier. A StoreStore barrier ensures that the data
1408   * that was stored by the instruction before the barrier is visible to all
1409   * subsequent store instructions.
1410   */
1411  public static void storeStoreBarrier() {
1412    if (VM.VerifyAssertions && VM.runningVM) {
1413      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1414    }
1415  }
1416
1417  //---------------------------------------//
1418  //            Cache Management.          //
1419  //---------------------------------------//
1420
1421  /**** NOTE: all per-address operations now live in vmmagic.Address *****/
1422
1423  /**
1424   * Wait for preceeding cache flush/invalidate instructions to
1425   * complete on all processors.
1426   */
1427  public static void sync() {
1428    if (VM.VerifyAssertions && VM.runningVM) {
1429      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1430    }
1431  }
1432
1433  /**
1434   * Wait for all preceeding instructions to complete and discard any
1435   * prefetched instructions on this processor.
1436   */
1437  public static void isync() {
1438    if (VM.VerifyAssertions && VM.runningVM) {
1439      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1440    }
1441  }
1442
1443  //---------------------------------------//
1444  //           Misc.                       //
1445  //---------------------------------------//
1446
1447  /**
1448   * On IA32, emit a PAUSE instruction, to optimize spin-wait loops.
1449   */
1450  public static void pause() {
1451    if (VM.VerifyAssertions && VM.runningVM) {
1452      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1453    }
1454  }
1455
1456  /**
1457   * A hardware SQRT instruction.
1458   * <p>
1459   * Note: this method may only be if the current configuration supports
1460   * hardware floating point, i.e. if
1461   * {@link org.jikesrvm.Configuration#BuildForHwFsqrt} is true.
1462   *
1463   * @param value the value whose square root will be computed
1464   * @return the SQRT of the given value
1465   */
1466  public static float sqrt(float value) {
1467    if (VM.VerifyAssertions && VM.runningVM) {
1468      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1469    }
1470    return -1.0f; // which should upset them even if assertions aren't enabled ...
1471  }
1472
1473  /**
1474   * A hardware SQRT instruction.
1475   * <p>
1476   * Note: this method may only be if the current configuration supports
1477   * hardware floating point, i.e. if
1478   * {@link org.jikesrvm.Configuration#BuildForHwFsqrt} is true.
1479   *
1480   * @param value the value whose square root will be computed
1481   * @return the SQRT of the given value
1482   */
1483  public static double sqrt(double value) {
1484    if (VM.VerifyAssertions && VM.runningVM) {
1485      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1486    }
1487    return -1.0d; // which should upset them even if assertions aren't enabled ...
1488  }
1489
1490  //---------------------------------------//
1491  //    Methods which are evaluated at     //
1492  //    compile-time when instructions     //
1493  //    for magic methods are generated.   //
1494  //---------------------------------------//
1495
1496  /**
1497   * How deeply inlined is this method (0 means no inlining).
1498   * @return depth of inlining
1499   */
1500  public static int getInlineDepth() {
1501    if (VM.VerifyAssertions && VM.runningVM) {
1502      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1503    }
1504    return 0;
1505  }
1506
1507  /**
1508   * Is the specified parameter constant (due to either inlining or specialization).
1509   * Count starts at zero and includes the 'this' parameter for instance methods.
1510   *
1511   * @param index the index for the parameter as described above
1512   * @return whether the specified parameter is constant
1513   */
1514  public static boolean isConstantParameter(int index) {
1515    if (VM.VerifyAssertions && VM.runningVM) {
1516      VM._assert(VM.NOT_REACHED);  // call site should have been hijacked by magic in compiler
1517    }
1518    return false;
1519  }
1520}