use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class OptGenericGCMapIterator method setupIterator.
/**
* Initialize the iterator for another stack frame scan
* @param cm The compiled method we are interested in
* @param instructionOffset The place in the method where we currently are
* @param framePtr The current frame pointer
*/
@Override
public final void setupIterator(CompiledMethod cm, Offset instructionOffset, Address framePtr) {
if (DEBUG) {
VM.sysWriteln();
VM.sysWrite("\t ==========================");
VM.sysWriteln();
VM.sysWrite("Reference map request made");
VM.sysWrite(" for machine code offset: ");
VM.sysWrite(instructionOffset);
VM.sysWriteln();
VM.sysWrite("\tframePtr: ");
VM.sysWrite(framePtr);
VM.sysWriteln();
}
reset();
// retrieve and save the corresponding OptMachineCodeMap for
// this method and instructionOffset
compiledMethod = (OptCompiledMethod) cm;
map = compiledMethod.getMCMap();
mapIndex = map.findGCMapIndex(instructionOffset);
if (mapIndex == OptGCMap.ERROR) {
if (instructionOffset.sLT(Offset.zero())) {
VM.sysWriteln("OptGenericGCMapIterator.setupIterator called with negative instructionOffset", instructionOffset);
} else {
Offset possibleLen = Offset.fromIntZeroExtend(cm.numberOfInstructions() << ArchConstants.getLogInstructionWidth());
if (possibleLen.sLT(instructionOffset)) {
VM.sysWriteln("OptGenericGCMapIterator.setupIterator called with too big of an instructionOffset");
VM.sysWriteln("offset is", instructionOffset);
VM.sysWriteln(" bytes of machine code for method ", possibleLen);
} else {
VM.sysWriteln("OptGenericGCMapIterator.setupIterator called with apparently valid offset, but no GC map found!");
VM.sysWrite("Method: ");
VM.sysWrite(compiledMethod.getMethod());
VM.sysWrite(", Machine Code (MC) Offset: ");
VM.sysWriteln(instructionOffset);
VM.sysFail("OptGenericMapIterator: findGCMapIndex failed\n");
}
}
VM.sysWrite("Supposed method: ");
VM.sysWrite(compiledMethod.getMethod());
VM.sysWriteln();
VM.sysWriteln("Base of its code array", Magic.objectAsAddress(cm.getEntryCodeArray()));
Address ra = cm.getInstructionAddress(instructionOffset);
VM.sysWriteln("Calculated actual return address is ", ra);
CompiledMethod realCM = CompiledMethods.findMethodForInstruction(ra);
if (realCM == null) {
VM.sysWriteln("Unable to find compiled method corresponding to this return address");
} else {
VM.sysWrite("Found compiled method ");
VM.sysWrite(realCM.getMethod());
VM.sysWriteln(" whose code contains this return address");
}
VM.sysFail("OptGenericMapIterator: setupIterator failed\n");
}
// save the frame pointer
this.framePtr = framePtr;
if (DEBUG) {
VM.sysWrite("\tMethod: ");
VM.sysWrite(compiledMethod.getMethod());
VM.sysWriteln();
if (mapIndex == OptGCMap.NO_MAP_ENTRY) {
VM.sysWriteln("... empty map found");
} else {
VM.sysWriteln("... found a map");
}
if (lookForMissedReferencesInSpills) {
VM.sysWrite("FramePtr: ");
VM.sysWrite(framePtr);
VM.sysWrite("\tFirst Spill: ");
VM.sysWrite(getFirstSpillLoc());
VM.sysWrite("\tLast Spill: ");
VM.sysWrite(getLastSpillLoc());
VM.sysWriteln();
}
}
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class OptSaveVolatile method resolve.
/**
* Wrapper to save/restore volatile registers when a class needs to be
* dynamically loaded/resolved/etc.
*/
@Entrypoint
@Interruptible
public static void resolve() throws NoClassDefFoundError {
VM.disableGC();
// (1) Get the compiled method & compilerInfo for the (opt)
// compiled method that called resolve
Address fp = Magic.getCallerFramePointer(Magic.getFramePointer());
int cmid = Magic.getCompiledMethodID(fp);
OptCompiledMethod cm = (OptCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
// (2) Get the return address
Address ip = Magic.getReturnAddressUnchecked(Magic.getFramePointer());
Offset offset = cm.getInstructionOffset(ip);
VM.enableGC();
// (3) Call the routine in OptLinker that does all the real work.
OptLinker.resolveDynamicLink(cm, offset);
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class OutOfLineMachineCode method generateSaveThreadStateInstructions.
/**
* Machine code to implement "Magic.saveThreadState()".
* <pre>
* Registers taken at runtime:
* T0 == address of Registers object
*
* Registers returned at runtime:
* none
*
* Side effects at runtime:
* S0, T1 destroyed
* Thread state stored into Registers object
* </pre>
*
* @return instructions for saving the thread state
*/
private static CodeArray generateSaveThreadStateInstructions() {
if (VM.VerifyAssertions) {
// assuming no NV FPRs (otherwise would have to save them here)
VM._assert(NUM_NONVOLATILE_FPRS == 0);
}
Assembler asm = new Assembler(0);
Offset ipOffset = ArchEntrypoints.registersIPField.getOffset();
Offset fpOffset = ArchEntrypoints.registersFPField.getOffset();
Offset gprsOffset = ArchEntrypoints.registersGPRsField.getOffset();
if (VM.BuildFor32Addr) {
asm.emitMOV_Reg_RegDisp(S0, TR, ArchEntrypoints.framePointerField.getOffset());
// registers.fp := pr.framePointer
asm.emitMOV_RegDisp_Reg(T0, fpOffset, S0);
} else {
asm.emitMOV_Reg_RegDisp_Quad(S0, TR, ArchEntrypoints.framePointerField.getOffset());
// registers.fp := pr.framePointer
asm.emitMOV_RegDisp_Reg_Quad(T0, fpOffset, S0);
}
// T1 := return address (target of final jmp)
asm.emitPOP_Reg(T1);
if (VM.BuildFor32Addr) {
// registers.ip := return address
asm.emitMOV_RegDisp_Reg(T0, ipOffset, T1);
} else {
// registers.ip := return address
asm.emitMOV_RegDisp_Reg_Quad(T0, ipOffset, T1);
}
// throw away space for registers parameter (in T0)
asm.emitPOP_Reg(S0);
if (VM.BuildFor32Addr) {
// S0 := registers.gprs[]
asm.emitMOV_Reg_RegDisp(S0, T0, gprsOffset);
// registers.gprs[#SP] := SP
asm.emitMOV_RegDisp_Reg(S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE), SP);
for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
asm.emitMOV_RegDisp_Reg(S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE), // registers.gprs[i] := i'th register
NONVOLATILE_GPRS[i]);
}
} else {
// S0 := registers.gprs[]
asm.emitMOV_Reg_RegDisp_Quad(S0, T0, gprsOffset);
// registers.gprs[#SP] := SP
asm.emitMOV_RegDisp_Reg_Quad(S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE), SP);
for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
asm.emitMOV_RegDisp_Reg_Quad(S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE), // registers.gprs[i] := i'th register
NONVOLATILE_GPRS[i]);
}
}
// return to return address
asm.emitJMP_Reg(T1);
return asm.getMachineCodes();
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class OutOfLineMachineCode method generateThreadSwitchInstructions.
/**
* Machine code to implement "Magic.threadSwitch()".
* <pre>
* NOTE: Currently not functional for PNT: left as a guide for possible reimplementation.
*
* Parameters taken at runtime:
* T0 == address of Thread object for the current thread
* T1 == address of Registers object for the new thread
*
* Registers returned at runtime:
* none
*
* Side effects at runtime:
* sets current Thread's beingDispatched field to false
* saves current Thread's nonvolatile hardware state in its Registers object
* restores new thread's Registers nonvolatile hardware state.
* execution resumes at address specificed by restored thread's Registers ip field
* </pre>
*
* @return instructions for doing a thread switch
*/
private static CodeArray generateThreadSwitchInstructions() {
if (VM.VerifyAssertions) {
// assuming no NV FPRs (otherwise would have to save them here)
VM._assert(NUM_NONVOLATILE_FPRS == 0);
}
Assembler asm = new Assembler(0);
Offset ipOffset = ArchEntrypoints.registersIPField.getOffset();
Offset fpOffset = ArchEntrypoints.registersFPField.getOffset();
Offset gprsOffset = ArchEntrypoints.registersGPRsField.getOffset();
Offset regsOffset = Entrypoints.threadContextRegistersField.getOffset();
// (1) Save hardware state of thread we are switching off of.
if (VM.BuildFor32Addr) {
// S0 = T0.contextRegisters
asm.emitMOV_Reg_RegDisp(S0, T0, regsOffset);
} else {
// S0 = T0.contextRegisters
asm.emitMOV_Reg_RegDisp_Quad(S0, T0, regsOffset);
}
// T0.contextRegisters.ip = returnAddress
asm.emitPOP_RegDisp(S0, ipOffset);
// push TR.framePointer
asm.emitPUSH_RegDisp(TR, ArchEntrypoints.framePointerField.getOffset());
// T0.contextRegisters.fp = pushed framepointer
asm.emitPOP_RegDisp(S0, fpOffset);
if (VM.BuildFor32Addr) {
// discard 2 words of parameters (T0, T1)
asm.emitADD_Reg_Imm(SP, 2 * WORDSIZE);
// S0 = T0.contextRegisters.gprs;
asm.emitMOV_Reg_RegDisp(S0, S0, gprsOffset);
// T0.contextRegisters.gprs[#SP] := SP
asm.emitMOV_RegDisp_Reg(S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE), SP);
for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
// T0.contextRegisters.gprs[i] := i'th register
asm.emitMOV_RegDisp_Reg(S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE), NONVOLATILE_GPRS[i]);
}
} else {
// discard 2 words of parameters (T0, T1)
asm.emitADD_Reg_Imm_Quad(SP, 2 * WORDSIZE);
// S0 = T0.contextRegisters.gprs;
asm.emitMOV_Reg_RegDisp_Quad(S0, S0, gprsOffset);
// T0.contextRegisters.gprs[#SP] := SP
asm.emitMOV_RegDisp_Reg_Quad(S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE), SP);
for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
// T0.contextRegisters.gprs[i] := i'th register
asm.emitMOV_RegDisp_Reg_Quad(S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE), NONVOLATILE_GPRS[i]);
}
}
// (3) Restore hardware state of thread we are switching to.
if (VM.BuildFor32Addr) {
// S0 := restoreRegs.fp
asm.emitMOV_Reg_RegDisp(S0, T1, fpOffset);
} else {
// S0 := restoreRegs.fp
asm.emitMOV_Reg_RegDisp_Quad(S0, T1, fpOffset);
}
// TR.framePointer = restoreRegs.fp
if (VM.BuildFor32Addr) {
asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, ArchEntrypoints.framePointerField.getOffset(), S0);
// S0 := restoreRegs.gprs[]
asm.emitMOV_Reg_RegDisp(S0, T1, gprsOffset);
// SP := restoreRegs.gprs[#SP]
asm.emitMOV_Reg_RegDisp(SP, S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE));
for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
// i'th register := restoreRegs.gprs[i]
asm.emitMOV_Reg_RegDisp(NONVOLATILE_GPRS[i], S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE));
}
} else {
asm.emitMOV_RegDisp_Reg_Quad(THREAD_REGISTER, ArchEntrypoints.framePointerField.getOffset(), S0);
// S0 := restoreRegs.gprs[]
asm.emitMOV_Reg_RegDisp_Quad(S0, T1, gprsOffset);
// SP := restoreRegs.gprs[#SP]
asm.emitMOV_Reg_RegDisp_Quad(SP, S0, Offset.fromIntZeroExtend(SP.value() << LG_WORDSIZE));
for (int i = 0; i < NUM_NONVOLATILE_GPRS; i++) {
// i'th register := restoreRegs.gprs[i]
asm.emitMOV_Reg_RegDisp_Quad(NONVOLATILE_GPRS[i], S0, Offset.fromIntZeroExtend(NONVOLATILE_GPRS[i].value() << LG_WORDSIZE));
}
}
// return to (save) return address
asm.emitJMP_RegDisp(T1, ipOffset);
return asm.getMachineCodes();
}
use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.
the class OptExceptionDeliverer method deliverException.
/**
* Pass control to a catch block.
*/
@Override
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public void deliverException(CompiledMethod cm, Address catchBlockInstructionAddress, Throwable exceptionObject, AbstractRegisters registers) {
// store exception object for later retrieval by catch block
OptCompiledMethod compiledMethod = (OptCompiledMethod) cm;
Offset offset = Offset.fromIntSignExtend(compiledMethod.getUnsignedExceptionOffset());
if (!offset.isZero()) {
// only put the exception object in the stackframe if the catch block is expecting it.
// (if the method hasn't allocated a stack slot for caught exceptions, then we can safely
// drop the exceptionObject on the floor).
Address fp = registers.getInnermostFramePointer();
Magic.setObjectAtOffset(Magic.addressAsObject(fp), offset, exceptionObject);
}
// set address at which to resume executing frame
registers.setIP(catchBlockInstructionAddress);
// disabled right before Runtime.deliverException was called
VM.enableGC();
if (VM.VerifyAssertions)
VM._assert(registers.getInUse());
registers.setInUse(false);
// "branches" to catchBlockInstructionAddress
Magic.restoreHardwareExceptionState(registers);
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
}
Aggregations