use of org.jikesrvm.compilers.baseline.ia32.ArchBaselineCompiledMethod in project JikesRVM by JikesRVM.
the class BaselineExecutionStateExtractor method extractState.
/**
* Implements ExecutionStateExtractor.extractState.
*
* @param thread : the suspended thread, the registers and stack frames are used.
* @param osrFPoff : the osr method's stack frame offset
* @param methFPoff : the real method's stack frame offset
* @param cmid : the top application method ( system calls are unwounded ).
*
* return a ExecutionStateExtractor object.
*/
@Override
public ExecutionState extractState(RVMThread thread, Offset osrFPoff, Offset methFPoff, int cmid) {
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("BASE execStateExtractor starting ...");
}
byte[] stack = thread.getStack();
if (VM.VerifyAssertions) {
int fooCmid = Magic.getIntAtOffset(stack, methFPoff.plus(STACKFRAME_METHOD_ID_OFFSET));
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("fooCmid = " + fooCmid);
VM.sysWriteln(" cmid = " + cmid);
}
VM._assert(fooCmid == cmid);
}
ArchBaselineCompiledMethod fooCM = (ArchBaselineCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
NormalMethod fooM = (NormalMethod) fooCM.getMethod();
VM.disableGC();
Address rowIP = Magic.objectAsAddress(stack).loadAddress(osrFPoff.plus(STACKFRAME_RETURN_ADDRESS_OFFSET));
Offset ipOffset = fooCM.getInstructionOffset(rowIP);
VM.enableGC();
// CAUTION: IP Offset should point to next instruction
int bcIndex = fooCM.findBytecodeIndexForInstruction(ipOffset.plus(INSTRUCTION_WIDTH));
// assertions
if (VM.VerifyAssertions) {
if (bcIndex == -1) {
VM.sysWriteln("osrFPoff = ", osrFPoff);
VM.sysWriteln("instr_beg = ", Magic.objectAsAddress(fooCM.getEntryCodeArray()));
for (int i = (osrFPoff.toInt()) - 10; i < (osrFPoff.toInt()) + 10; i++) {
VM.sysWriteln(" stack[" + i + "] = " + stack[i]);
}
Offset ipIndex = ipOffset.toWord().rsha(LG_INSTRUCTION_WIDTH).toOffset();
VM.sysWriteln("ipIndex : ", ipIndex);
VM.sysWriteln("bcIndex : " + bcIndex);
}
VM._assert(bcIndex != -1);
}
// create execution state object
ExecutionState state = new ExecutionState(thread, methFPoff, cmid, bcIndex, osrFPoff);
/* extract values for local and stack, but first of all
* we need to get type information for current PC.
*/
BytecodeTraverser typer = new BytecodeTraverser();
typer.computeLocalStackTypes(fooM, bcIndex);
byte[] localTypes = typer.getLocalTypes();
byte[] stackTypes = typer.getStackTypes();
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("BC Index : " + bcIndex);
VM.sysWrite("Local Types :");
for (byte localType : localTypes) {
VM.sysWrite(" " + (char) localType);
}
VM.sysWriteln();
VM.sysWrite("Stack Types :");
for (byte stackType : stackTypes) {
VM.sysWrite(" " + (char) stackType);
}
VM.sysWriteln();
}
// type. We should remove non-reference type
for (int i = 0, n = localTypes.length; i < n; i++) {
// then set the localType to uninitialized, see VM spec, bytecode verifier
if (localTypes[i] == ClassTypeCode) {
if (!fooCM.referenceMaps.isLocalRefType(fooM, ipOffset.plus(1 << LG_INSTRUCTION_WIDTH), i)) {
localTypes[i] = VoidTypeCode;
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("GC maps disagrees with type matcher at " + i + "th local");
VM.sysWriteln();
}
}
}
}
// go through the stack frame and extract values
// In the variable value list, we keep the order as follows:
// L0, L1, ..., S0, S1, ....
// adjust local offset and stack offset
// NOTE: do not call BaselineCompilerImpl.getFirstLocalOffset(method)
Offset startLocalOffset = methFPoff.plus(BaselineCompilerImpl.locationToOffset(fooCM.getGeneralLocalLocation(0)));
Offset stackOffset = methFPoff.plus(fooCM.getEmptyStackOffset());
// for locals
getVariableValue(stack, startLocalOffset, localTypes, fooCM, LOCAL, state);
// for stacks
getVariableValue(stack, stackOffset, stackTypes, fooCM, STACK, state);
if (VM.TraceOnStackReplacement) {
state.printState();
}
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("BASE executionStateExtractor done ");
}
return state;
}
Aggregations