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