/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.ia32; import org.jikesrvm.compilers.common.assembler.ia32.Assembler; import org.jikesrvm.runtime.Magic; import org.jikesrvm.scheduler.RVMThread; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.Offset; import org.jikesrvm.ia32.RegisterConstants.GPR; /** * This class provides a layer of abstraction that the rest of the VM must * use in order to access the current <code>RVMThread</code> object. * * @see RVMThread */ public abstract class ThreadLocalState { protected static final GPR THREAD_REGISTER = RegisterConstants.ESI; /** * The C bootstrap program has placed a pointer to the initial * RVMThread in ESI. */ @Uninterruptible public static void boot() { // do nothing - everything is already set up. } /** * Return the current RVMThread object */ @Uninterruptible public static RVMThread getCurrentThread() { return Magic.getESIAsThread(); } /** * Set the current RVMThread object */ @Uninterruptible public static void setCurrentThread(RVMThread p) { Magic.setESIAsThread(p); } /** * Emit an instruction sequence to move the value of a register into a field * in the current thread offset * * @param asm assembler object * @param offset of field in the <code>RVMThread</code> object * @param reg number of the register supplying the new value */ public static void emitMoveRegToField(Assembler asm, Offset offset, GPR reg) { asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, offset, reg); } /** * Emit an instruction sequence to move an immediate value into a field * in the current thread offset * * @param asm assembler object * @param offset of field in the <code>RVMThread</code> object * @param imm immediate value */ public static void emitMoveImmToField(Assembler asm, Offset offset, int imm) { asm.emitMOV_RegDisp_Imm(THREAD_REGISTER, offset, imm); } /** * Emit an instruction sequence to move the value of a field in the * current thread offset to a register * * @param asm assembler object * @param dest number of destination register * @param offset of field in the <code>RVMThread</code> object */ public static void emitMoveFieldToReg(Assembler asm, GPR dest, Offset offset) { asm.emitMOV_Reg_RegDisp(dest, THREAD_REGISTER, offset); } /** * Emit an instruction sequence to compare the value of a field in the * current thread offset with an immediate value * * @param asm assembler object * @param offset of field in the <code>RVMThread</code> object * @param imm immediate value to compare with */ public static void emitCompareFieldWithImm(Assembler asm, Offset offset, int imm) { asm.emitCMP_RegDisp_Imm(THREAD_REGISTER, offset, imm); } /** * Emit an instruction sequence to to an atomic compare and exchange on a field in the * current thread offset with an immediate value. Assumes EAX (T0) contains old value. * * @param asm assembler object * @param offset of field in the <code>RVMThread</code> object * @param srcReg register containing value to exchange */ public static void emitCompareAndExchangeField(Assembler asm, Offset offset, GPR srcReg) { asm.emitLockNextInstruction(); asm.emitCMPXCHG_RegDisp_Reg(THREAD_REGISTER, offset, srcReg); } /** * Emit an instruction sequence to decrement the value of a field in the * current thread offset * * @param asm assembler object * @param offset of field in the <code>RVMThread</code> object */ public static void emitDecrementField(Assembler asm, Offset offset) { asm.emitDEC_RegDisp(THREAD_REGISTER, offset); } /** * Emit an instruction sequence to PUSH the value of a field in the * current thread offset * * @param asm assembler object * @param offset of field in the <code>RVMThread</code> object */ public static void emitPushField(Assembler asm, Offset offset) { asm.emitPUSH_RegDisp(THREAD_REGISTER, offset); } /** * Emit an instruction sequence to POP a value into a field in the * current thread offset * * @param asm assembler object * @param offset of field in the <code>RVMThread</code> object */ public static void emitPopField(Assembler asm, Offset offset) { asm.emitPOP_RegDisp(THREAD_REGISTER, offset); } /** * Emit an instruction sequence to PUSH a pointer to the current RVMThread * object on the stack. * * @param asm assembler object */ public static void emitPushThread(Assembler asm) { asm.emitPUSH_Reg(THREAD_REGISTER); } /** * Emit an instruction sequence to POP a value on the stack, and set the * current thread reference to be this value. * * @param asm assembler object */ public static void emitPopThread(Assembler asm) { asm.emitPOP_Reg(THREAD_REGISTER); } /** * Emit an instruction sequence to store a pointer to the current RVMThread * object at a location defined by [base]+offset * * @param asm assembler object * @param base number of base register * @param offset offset */ public static void emitStoreThread(Assembler asm, GPR base, Offset offset) { asm.emitMOV_RegDisp_Reg(base, offset, THREAD_REGISTER); } /** * Emit an instruction sequence to load current RVMThread * object from a location defined by [base]+offset * * @param asm assembler object * @param base number of base register * @param offset offset */ public static void emitLoadThread(Assembler asm, GPR base, Offset offset) { asm.emitMOV_Reg_RegDisp(THREAD_REGISTER, base, offset); } }