/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Common Public License (CPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/cpl1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.ppc; import org.jikesrvm.runtime.VM_ArchEntrypoints; import org.jikesrvm.runtime.VM_Magic; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.LocalAddress; import org.vmmagic.unboxed.Offset; import org.vmmagic.unboxed.WordArray; /** * The machine state comprising a thread's execution context. */ @Uninterruptible public abstract class VM_Registers extends org.jikesrvm.VM_Registers implements VM_ArchConstants { // The following are used by exception delivery. // They are set by either VM_Runtime.athrow or the C hardware exception // handler and restored by "VM_Magic.restoreHardwareExceptionState". // They are not used for context switching. // public Address lr; // link register static LocalAddress invalidIP = LocalAddress.max(); public VM_Registers() { gprs = WordArray.create(NUM_GPRS); fprs = new double[NUM_FPRS]; ip = invalidIP; } // Return framepointer for the deepest stackframe // public final LocalAddress getInnermostFramePointer() { return gprs.get(FRAME_POINTER).toLocalAddress(); } // Return next instruction address for the deepest stackframe // public final LocalAddress getInnermostInstructionAddress() { if (ip.NE(invalidIP)) return ip; // ip set by hardware exception handler or VM_Magic.threadSwitch return VM_Magic.getNextInstructionAddress(getInnermostFramePointer()); // ip set to -1 because we're unwinding } // update the machine state to unwind the deepest stackframe. // public final void unwindStackFrame() { ip = invalidIP; // if there was a valid value in ip, it ain't valid anymore gprs.set(FRAME_POINTER, VM_Magic.getCallerFramePointer(getInnermostFramePointer()).toWord()); } // set ip & fp. used to control the stack frame at which a scan of // the stack during GC will start, for ex., the top java frame for // a thread that is blocked in native code during GC. // public final void setInnermost(LocalAddress newip, LocalAddress newfp) { ip = newip; gprs.set(FRAME_POINTER, newfp.toWord()); } // set ip and fp values to those of the caller. used just prior to entering // sigwait to set fp & ip so that GC will scan the threads stack // starting at the frame of the method that called sigwait. // public final void setInnermost() { LocalAddress fp = VM_Magic.getFramePointer(); ip = VM_Magic.getReturnAddress(fp); gprs.set(FRAME_POINTER, VM_Magic.getCallerFramePointer(fp).toWord()); } public final LocalAddress getIPLocation() { Offset ipOffset = VM_ArchEntrypoints.registersIPField.getOffset(); return VM_Magic.objectAsLocalAddress(this).plus(ipOffset); } }