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