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.ia32; 014 015import static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS; 016import static org.jikesrvm.ia32.RegisterConstants.ESP; 017import static org.jikesrvm.ia32.StackframeLayoutConstants.INVISIBLE_METHOD_ID; 018import static org.jikesrvm.ia32.StackframeLayoutConstants.STACKFRAME_BODY_OFFSET; 019import static org.jikesrvm.ia32.StackframeLayoutConstants.STACKFRAME_HEADER_SIZE; 020import static org.jikesrvm.ia32.StackframeLayoutConstants.STACKFRAME_SENTINEL_FP; 021 022import org.jikesrvm.VM; 023import org.jikesrvm.architecture.AbstractRegisters; 024import org.jikesrvm.runtime.Magic; 025import org.jikesrvm.scheduler.RVMThread; 026import org.vmmagic.pragma.Entrypoint; 027import org.vmmagic.pragma.NonMoving; 028import org.vmmagic.pragma.Uninterruptible; 029import org.vmmagic.unboxed.Address; 030import org.vmmagic.unboxed.Offset; 031import org.vmmagic.unboxed.Word; 032 033/** 034 * The machine state comprising a thread's execution context, used both for 035 * thread context switching and for software/hardware exception 036 * reporting/delivery. 037 */ 038@Uninterruptible 039@NonMoving 040public final class Registers extends AbstractRegisters { 041 /** Frame pointer */ 042 @Entrypoint 043 public Address fp; 044 045 @Override 046 public void clear() { 047 fp = Address.zero(); 048 super.clear(); 049 } 050 051 /** 052 * @return framepointer for the deepest stackframe 053 */ 054 @Override 055 public Address getInnermostFramePointer() { 056 return fp; 057 } 058 059 /** 060 * @return next instruction address for the deepest stackframe 061 */ 062 @Override 063 public Address getInnermostInstructionAddress() { 064 return ip; 065 } 066 067 /** 068 * Updates the machine state as if the stackframe were unwound. 069 */ 070 @Override 071 public void unwindStackFrame() { 072 ip = Magic.getReturnAddress(fp, RVMThread.getCurrentThread()); 073 fp = Magic.getCallerFramePointer(fp); 074 } 075 076 /** 077 * Sets ip & fp. used to control the stack frame at which a scan of 078 * the stack during GC will start, for ex., the top java frame for 079 * a thread that is blocked in native code during GC. 080 * 081 * @param newip the new instruction pointer 082 * @param newfp the new frame pointer 083 */ 084 @Override 085 public void setInnermost(Address newip, Address newfp) { 086 ip = newip; 087 fp = newfp; 088 } 089 090 /** 091 * set ip and fp values to those of the caller. used just prior to entering 092 * sigwait to set fp & ip so that GC will scan the threads stack 093 * starting at the frame of the method that called sigwait. 094 */ 095 public void setInnermost() { 096 Address current_fp = Magic.getFramePointer(); 097 ip = Magic.getReturnAddress(current_fp); 098 fp = Magic.getCallerFramePointer(current_fp); 099 } 100 101 /** 102 * The following method initializes a thread stack as if 103 * "startoff" method had been called by an empty baseline-compiled 104 * "sentinel" frame with one local variable 105 * 106 * @param ip The instruction pointer for the "startoff" method 107 * @param sp The base of the stack 108 */ 109 @Override 110 @Uninterruptible 111 public void initializeStack(Address ip, Address sp) { 112 Address fp; 113 sp = sp.minus(STACKFRAME_HEADER_SIZE); // last word of header 114 fp = sp.minus(BYTES_IN_ADDRESS).minus(STACKFRAME_BODY_OFFSET); 115 Magic.setCallerFramePointer(fp, STACKFRAME_SENTINEL_FP); 116 Magic.setCompiledMethodID(fp, INVISIBLE_METHOD_ID); 117 118 sp = sp.minus(BYTES_IN_ADDRESS); // allow for one local 119 getGPRs().set(ESP.value(), sp.toWord()); 120 this.fp = fp; 121 this.ip = ip; 122 } 123 124 /** 125 * A thread's stack has been moved or resized. 126 * Adjust the ESP register to reflect new position. 127 * 128 * @param delta The displacement to be applied 129 * @param traceAdjustments Log all adjustments to stderr if true 130 */ 131 @Uninterruptible 132 @Override 133 public void adjustESP(Offset delta, boolean traceAdjustments) { 134 Word old = getGPRs().get(ESP.value()); 135 getGPRs().set(ESP.value(), old.plus(delta)); 136 if (traceAdjustments) { 137 VM.sysWrite(" esp ="); 138 VM.sysWrite(getGPRs().get(ESP.value())); 139 } 140 } 141 142 @Override 143 public void dump() { 144 super.dump(); 145 VM.sysWriteln("fp = ",fp); 146 } 147} 148