/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * 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/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.ia32; import org.jikesrvm.runtime.ArchEntrypoints; import org.jikesrvm.runtime.Magic; import org.jikesrvm.scheduler.RVMThread; import org.jikesrvm.VM; import org.jikesrvm.mm.mminterface.MemoryManager; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.pragma.Untraced; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Word; import org.vmmagic.unboxed.Offset; import org.vmmagic.unboxed.WordArray; /** * The machine state comprising a thread's execution context, used both for * thread context switching and for software/hardware exception * reporting/delivery. */ @Uninterruptible @NonMoving public abstract class Registers implements RegisterConstants { /** General purpose registers */ @Untraced public final WordArray gprs; /** Floating point registers */ @Untraced public final double[] fprs; public final WordArray gprsShadow; public final double[] fprsShadow; /** Instruction address register */ public Address ip; /** Frame pointer */ public Address fp; /** * Do exception registers currently contain live values? Set by C hardware * exception handler and RuntimeEntrypoints.athrow and reset by each * implementation of ExceptionDeliverer.deliverException */ public boolean inuse; public Registers() { gprs = gprsShadow = MemoryManager.newNonMovingWordArray(NUM_GPRS); fprs = fprsShadow = MemoryManager.newNonMovingDoubleArray(NUM_FPRS); } public final void copyFrom(Registers other) { for (int i=0;i<NUM_GPRS;++i) { gprs.set(i,other.gprs.get(i)); } for (int i=0;i<NUM_FPRS;++i) { fprs[i]=other.fprs[i]; } ip=other.ip; fp=other.fp; } public final void clear() { for (int i=0;i<NUM_GPRS;++i) { gprs.set(i,Word.zero()); } for (int i=0;i<NUM_FPRS;++i) { fprs[i]=0.; } ip=Address.zero(); fp=Address.zero(); } public final void assertSame(Registers other) { boolean fail=false; for (int i=0;i<NUM_GPRS;++i) { if (gprs.get(i).NE(other.gprs.get(i))) { VM.sysWriteln("Registers not equal: GPR #",i); fail=true; } } for (int i=0;i<NUM_FPRS;++i) { if (fprs[i]!=other.fprs[i]) { VM.sysWriteln("Registers not equal: FPR #",i); fail=true; } } if (ip.NE(other.ip)) { VM.sysWriteln("Registers not equal: IP"); fail=true; } if (fp.NE(other.fp)) { VM.sysWriteln("Registers not equal: FP"); fail=true; } if (fail) { RVMThread.dumpStack(); VM.sysFail("Registers.assertSame() failed"); } } /** * Return framepointer for the deepest stackframe */ public final Address getInnermostFramePointer() { return fp; } /** * Return next instruction address for the deepest stackframe */ public final Address getInnermostInstructionAddress() { return ip; } /** * update the machine state as if the stackframe were unwound. */ public final void unwindStackFrame() { ip = Magic.getReturnAddress(fp); fp = Magic.getCallerFramePointer(fp); } /** * 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(Address newip, Address newfp) { ip = newip; fp = newfp; } /** * 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() { Address current_fp = Magic.getFramePointer(); ip = Magic.getReturnAddress(current_fp); fp = Magic.getCallerFramePointer(current_fp); } public final Address getIPLocation() { Offset ipOffset = ArchEntrypoints.registersIPField.getOffset(); return Magic.objectAsAddress(this).plus(ipOffset); } public final void dump() { for (int i=0;i<NUM_GPRS;++i) { VM.sysWriteln("gprs[",i,"] = ",gprs.get(i)); } for (int i=0;i<NUM_FPRS;++i) { VM.sysWriteln("fprs[",i,"] = ",fprs[i]); } VM.sysWriteln("ip = ",ip); VM.sysWriteln("fp = ",fp); } }