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 }