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.compilers.common.assembler.ia32.Assembler;
016 import org.jikesrvm.runtime.Magic;
017 import org.jikesrvm.scheduler.RVMThread;
018 import org.vmmagic.pragma.Uninterruptible;
019 import org.vmmagic.unboxed.Offset;
020 import org.jikesrvm.ia32.RegisterConstants.GPR;
021
022 /**
023 * This class provides a layer of abstraction that the rest of the VM must
024 * use in order to access the current <code>RVMThread</code> object.
025 *
026 * @see RVMThread
027 */
028 public abstract class ThreadLocalState {
029
030 protected static final GPR THREAD_REGISTER = RegisterConstants.ESI;
031
032 /**
033 * The C bootstrap program has placed a pointer to the initial
034 * RVMThread in ESI.
035 */
036 @Uninterruptible
037 public
038 static void boot() {
039 // do nothing - everything is already set up.
040 }
041
042 /**
043 * Return the current RVMThread object
044 */
045 @Uninterruptible
046 public static RVMThread getCurrentThread() {
047 return Magic.getESIAsThread();
048 }
049
050 /**
051 * Set the current RVMThread object
052 */
053 @Uninterruptible
054 public static void setCurrentThread(RVMThread p) {
055 Magic.setESIAsThread(p);
056 }
057
058 /**
059 * Emit an instruction sequence to move the value of a register into a field
060 * in the current thread offset
061 *
062 * @param asm assembler object
063 * @param offset of field in the <code>RVMThread</code> object
064 * @param reg number of the register supplying the new value
065 */
066 public static void emitMoveRegToField(Assembler asm, Offset offset, GPR reg) {
067 asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, offset, reg);
068 }
069
070 /**
071 * Emit an instruction sequence to move an immediate value into a field
072 * in the current thread offset
073 *
074 * @param asm assembler object
075 * @param offset of field in the <code>RVMThread</code> object
076 * @param imm immediate value
077 */
078 public static void emitMoveImmToField(Assembler asm, Offset offset, int imm) {
079 asm.emitMOV_RegDisp_Imm(THREAD_REGISTER, offset, imm);
080 }
081
082 /**
083 * Emit an instruction sequence to move the value of a field in the
084 * current thread offset to a register
085 *
086 * @param asm assembler object
087 * @param dest number of destination register
088 * @param offset of field in the <code>RVMThread</code> object
089 */
090 public static void emitMoveFieldToReg(Assembler asm, GPR dest, Offset offset) {
091 asm.emitMOV_Reg_RegDisp(dest, THREAD_REGISTER, offset);
092 }
093
094 /**
095 * Emit an instruction sequence to compare the value of a field in the
096 * current thread offset with an immediate value
097 *
098 * @param asm assembler object
099 * @param offset of field in the <code>RVMThread</code> object
100 * @param imm immediate value to compare with
101 */
102 public static void emitCompareFieldWithImm(Assembler asm, Offset offset, int imm) {
103 asm.emitCMP_RegDisp_Imm(THREAD_REGISTER, offset, imm);
104 }
105
106 /**
107 * Emit an instruction sequence to to an atomic compare and exchange on a field in the
108 * current thread offset with an immediate value. Assumes EAX (T0) contains old value.
109 *
110 * @param asm assembler object
111 * @param offset of field in the <code>RVMThread</code> object
112 * @param srcReg register containing value to exchange
113 */
114 public static void emitCompareAndExchangeField(Assembler asm, Offset offset, GPR srcReg) {
115 asm.emitLockNextInstruction();
116 asm.emitCMPXCHG_RegDisp_Reg(THREAD_REGISTER, offset, srcReg);
117 }
118
119 /**
120 * Emit an instruction sequence to decrement the value of a field in the
121 * current thread offset
122 *
123 * @param asm assembler object
124 * @param offset of field in the <code>RVMThread</code> object
125 */
126 public static void emitDecrementField(Assembler asm, Offset offset) {
127 asm.emitDEC_RegDisp(THREAD_REGISTER, offset);
128 }
129
130 /**
131 * Emit an instruction sequence to PUSH the value of a field in the
132 * current thread offset
133 *
134 * @param asm assembler object
135 * @param offset of field in the <code>RVMThread</code> object
136 */
137 public static void emitPushField(Assembler asm, Offset offset) {
138 asm.emitPUSH_RegDisp(THREAD_REGISTER, offset);
139 }
140
141 /**
142 * Emit an instruction sequence to POP a value into a field in the
143 * current thread offset
144 *
145 * @param asm assembler object
146 * @param offset of field in the <code>RVMThread</code> object
147 */
148 public static void emitPopField(Assembler asm, Offset offset) {
149 asm.emitPOP_RegDisp(THREAD_REGISTER, offset);
150 }
151
152 /**
153 * Emit an instruction sequence to PUSH a pointer to the current RVMThread
154 * object on the stack.
155 *
156 * @param asm assembler object
157 */
158 public static void emitPushThread(Assembler asm) {
159 asm.emitPUSH_Reg(THREAD_REGISTER);
160 }
161
162 /**
163 * Emit an instruction sequence to POP a value on the stack, and set the
164 * current thread reference to be this value.
165 *
166 * @param asm assembler object
167 */
168 public static void emitPopThread(Assembler asm) {
169 asm.emitPOP_Reg(THREAD_REGISTER);
170 }
171
172 /**
173 * Emit an instruction sequence to store a pointer to the current RVMThread
174 * object at a location defined by [base]+offset
175 *
176 * @param asm assembler object
177 * @param base number of base register
178 * @param offset offset
179 */
180 public static void emitStoreThread(Assembler asm, GPR base, Offset offset) {
181 asm.emitMOV_RegDisp_Reg(base, offset, THREAD_REGISTER);
182 }
183
184 /**
185 * Emit an instruction sequence to load current RVMThread
186 * object from a location defined by [base]+offset
187 *
188 * @param asm assembler object
189 * @param base number of base register
190 * @param offset offset
191 */
192 public static void emitLoadThread(Assembler asm, GPR base, Offset offset) {
193 asm.emitMOV_Reg_RegDisp(THREAD_REGISTER, base, offset);
194 }
195 }
196