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 &lt;clinit&gt; 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    }