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.ia32; 014 015 import org.jikesrvm.runtime.ArchEntrypoints; 016 import org.jikesrvm.runtime.Magic; 017 import org.jikesrvm.scheduler.RVMThread; 018 import org.jikesrvm.VM; 019 import org.jikesrvm.mm.mminterface.MemoryManager; 020 import org.vmmagic.pragma.NonMoving; 021 import org.vmmagic.pragma.Uninterruptible; 022 import org.vmmagic.pragma.Untraced; 023 import org.vmmagic.unboxed.Address; 024 import org.vmmagic.unboxed.Word; 025 import org.vmmagic.unboxed.Offset; 026 import org.vmmagic.unboxed.WordArray; 027 028 /** 029 * The machine state comprising a thread's execution context, used both for 030 * thread context switching and for software/hardware exception 031 * reporting/delivery. 032 */ 033 @Uninterruptible 034 @NonMoving 035 public abstract class Registers implements RegisterConstants { 036 037 /** General purpose registers */ 038 @Untraced 039 public final WordArray gprs; 040 /** Floating point registers */ 041 @Untraced 042 public final double[] fprs; 043 public final WordArray gprsShadow; 044 public final double[] fprsShadow; 045 /** Instruction address register */ 046 public Address ip; 047 /** Frame pointer */ 048 public Address fp; 049 050 /** 051 * Do exception registers currently contain live values? Set by C hardware 052 * exception handler and RuntimeEntrypoints.athrow and reset by each 053 * implementation of ExceptionDeliverer.deliverException 054 */ 055 public boolean inuse; 056 057 public Registers() { 058 gprs = gprsShadow = MemoryManager.newNonMovingWordArray(NUM_GPRS); 059 fprs = fprsShadow = MemoryManager.newNonMovingDoubleArray(NUM_FPRS); 060 } 061 public final void copyFrom(Registers other) { 062 for (int i=0;i<NUM_GPRS;++i) { 063 gprs.set(i,other.gprs.get(i)); 064 } 065 for (int i=0;i<NUM_FPRS;++i) { 066 fprs[i]=other.fprs[i]; 067 } 068 ip=other.ip; 069 fp=other.fp; 070 } 071 public final void clear() { 072 for (int i=0;i<NUM_GPRS;++i) { 073 gprs.set(i,Word.zero()); 074 } 075 for (int i=0;i<NUM_FPRS;++i) { 076 fprs[i]=0.; 077 } 078 ip=Address.zero(); 079 fp=Address.zero(); 080 } 081 public final void assertSame(Registers other) { 082 boolean fail=false; 083 for (int i=0;i<NUM_GPRS;++i) { 084 if (gprs.get(i).NE(other.gprs.get(i))) { 085 VM.sysWriteln("Registers not equal: GPR #",i); 086 fail=true; 087 } 088 } 089 for (int i=0;i<NUM_FPRS;++i) { 090 if (fprs[i]!=other.fprs[i]) { 091 VM.sysWriteln("Registers not equal: FPR #",i); 092 fail=true; 093 } 094 } 095 if (ip.NE(other.ip)) { 096 VM.sysWriteln("Registers not equal: IP"); 097 fail=true; 098 } 099 if (fp.NE(other.fp)) { 100 VM.sysWriteln("Registers not equal: FP"); 101 fail=true; 102 } 103 if (fail) { 104 RVMThread.dumpStack(); 105 VM.sysFail("Registers.assertSame() failed"); 106 } 107 } 108 109 /** 110 * Return framepointer for the deepest stackframe 111 */ 112 public final Address getInnermostFramePointer() { 113 return fp; 114 } 115 116 /** 117 * Return next instruction address for the deepest stackframe 118 */ 119 public final Address getInnermostInstructionAddress() { 120 return ip; 121 } 122 123 /** 124 * update the machine state as if the stackframe were unwound. 125 */ 126 public final void unwindStackFrame() { 127 ip = Magic.getReturnAddress(fp, RVMThread.getCurrentThread()); 128 fp = Magic.getCallerFramePointer(fp); 129 } 130 131 /** 132 * set ip & fp. used to control the stack frame at which a scan of 133 * the stack during GC will start, for ex., the top java frame for 134 * a thread that is blocked in native code during GC. 135 */ 136 public final void setInnermost(Address newip, Address newfp) { 137 ip = newip; 138 fp = newfp; 139 } 140 141 /** 142 * set ip and fp values to those of the caller. used just prior to entering 143 * sigwait to set fp & ip so that GC will scan the threads stack 144 * starting at the frame of the method that called sigwait. 145 */ 146 public final void setInnermost() { 147 Address current_fp = Magic.getFramePointer(); 148 ip = Magic.getReturnAddress(current_fp); 149 fp = Magic.getCallerFramePointer(current_fp); 150 } 151 152 public final Address getIPLocation() { 153 Offset ipOffset = ArchEntrypoints.registersIPField.getOffset(); 154 return Magic.objectAsAddress(this).plus(ipOffset); 155 } 156 public final void dump() { 157 for (int i=0;i<NUM_GPRS;++i) { 158 VM.sysWriteln("gprs[",i,"] = ",gprs.get(i)); 159 } 160 for (int i=0;i<NUM_FPRS;++i) { 161 VM.sysWriteln("fprs[",i,"] = ",fprs[i]); 162 } 163 VM.sysWriteln("ip = ",ip); 164 VM.sysWriteln("fp = ",fp); 165 } 166 } 167