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 */ 013package org.jikesrvm.architecture; 014 015import org.jikesrvm.VM; 016import org.jikesrvm.mm.mminterface.MemoryManager; 017import org.jikesrvm.runtime.ArchEntrypoints; 018import org.jikesrvm.runtime.Magic; 019import org.vmmagic.pragma.Untraced; 020import org.vmmagic.unboxed.Address; 021import org.vmmagic.unboxed.Offset; 022import org.vmmagic.unboxed.Word; 023import org.vmmagic.unboxed.WordArray; 024import org.vmmagic.pragma.Entrypoint; 025import org.vmmagic.pragma.NonMoving; 026import org.vmmagic.pragma.Uninterruptible; 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 035public abstract class AbstractRegisters { 036 037 /** General purpose registers */ 038 @Untraced 039 @Entrypoint 040 private final WordArray gprs; 041 private final WordArray gprsShadow; 042 /** Floating point registers */ 043 @Untraced 044 @Entrypoint 045 private final double[] fprs; 046 private final double[] fprsShadow; 047 /** Instruction address register */ 048 @Entrypoint 049 protected Address ip; 050 051 /** 052 * Do exception registers currently contain live values? Set by C hardware 053 * exception handler and RuntimeEntrypoints.athrow and reset by each 054 * implementation of ExceptionDeliverer.deliverException 055 */ 056 @Entrypoint 057 private boolean inuse; 058 059 protected AbstractRegisters() { 060 gprs = gprsShadow = MemoryManager.newNonMovingWordArray(ArchConstants.getNumberOfGPRs()); 061 fprs = fprsShadow = MemoryManager.newNonMovingDoubleArray(ArchConstants.getNumberOfFPRs()); 062 } 063 064 public final boolean getInUse() { 065 return inuse; 066 } 067 068 public final void setInUse(boolean b) { 069 inuse = b; 070 } 071 072 public final WordArray getGPRs() { 073 return gprs; 074 } 075 076 public final double[] getFPRs() { 077 return fprs; 078 } 079 080 /** @return Instruction address register */ 081 082 public final Address getIP() { 083 return ip; 084 } 085 086 /** 087 * Sets instruction address register. 088 * @param ip the new value for the instruction address register 089 */ 090 public final void setIP(Address ip) { 091 this.ip = ip; 092 } 093 094 /** @return memory location of IP register in this data structure */ 095 public final Address getIPLocation() { 096 Offset ipOffset = ArchEntrypoints.registersIPField.getOffset(); 097 return Magic.objectAsAddress(this).plus(ipOffset); 098 } 099 100 /** Zeroes all registers */ 101 public void clear() { 102 for (int i = 0; i < gprs.length(); ++i) { 103 gprs.set(i, Word.zero()); 104 } 105 for (int i = 0; i < fprs.length; ++i) { 106 fprs[i] = 0.; 107 } 108 ip = Address.zero(); 109 } 110 111 protected void dump() { 112 for (int i = 0; i < gprs.length(); ++i) { 113 VM.sysWriteln("gprs[", i, "] = ", gprs.get(i)); 114 } 115 for (int i = 0; i < fprs.length; ++i) { 116 VM.sysWriteln("fprs[", i, "] = ", fprs[i]); 117 } 118 VM.sysWriteln("ip = ", ip); 119 } 120 121 /** 122 * The following method initializes a thread stack as if 123 * "startoff" method had been called by an empty baseline-compiled 124 * "sentinel" frame with one local variable 125 * 126 * @param ip The instruction pointer for the "startoff" method 127 * @param sp The base of the stack 128 */ 129 public abstract void initializeStack(Address ip, Address sp); 130 131 /** 132 * A thread's stack has been moved or resized. 133 * Adjust the ESP register to reflect new position. 134 * 135 * @param delta The displacement to be applied 136 * @param traceAdjustments Log all adjustments to stderr if true 137 */ 138 public abstract void adjustESP(Offset delta, boolean traceAdjustments); 139 140 /** 141 * Set ip & fp. used to control the stack frame at which a scan of 142 * the stack during GC will start, for ex., the top java frame for 143 * a thread that is blocked in native code during GC. 144 * 145 * @param returnAddress the new return address (i.e. ip) 146 * @param callerFramePointer the new frame pointer (i.e. fp) 147 */ 148 public abstract void setInnermost(Address returnAddress, Address callerFramePointer); 149 150 public abstract Address getInnermostFramePointer(); 151 152 public abstract void unwindStackFrame(); 153 154 public abstract Address getInnermostInstructionAddress(); 155 156}