use of org.jikesrvm.osr.VariableElement in project JikesRVM by JikesRVM.
the class BaselineExecutionStateExtractor method getVariableValue.
/* go over local/stack array, and build VariableElement. */
private static void getVariableValue(byte[] stack, Offset offset, byte[] types, ArchBaselineCompiledMethod compiledMethod, boolean kind, ExecutionState state) {
int size = types.length;
Offset vOffset = offset;
for (int i = 0; i < size; i++) {
if (VM.TraceOnStackReplacement) {
Word content = Magic.getWordAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
VM.sysWrite("0x", vOffset.minus(BYTES_IN_ADDRESS), " 0x");
VM.sysWriteln(content);
if ((types[i] == LongTypeCode) || (types[i] == DoubleTypeCode)) {
content = Magic.getWordAtOffset(stack, vOffset.minus(2 * BYTES_IN_ADDRESS));
VM.sysWrite("0x", vOffset.minus(2 * BYTES_IN_ADDRESS), " 0x");
VM.sysWriteln(content);
}
}
switch(types[i]) {
case VoidTypeCode:
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
break;
case BooleanTypeCode:
case ByteTypeCode:
case ShortTypeCode:
case CharTypeCode:
case IntTypeCode:
case FloatTypeCode:
{
int value = Magic.getIntAtOffset(stack, vOffset.minus(BYTES_IN_STACKSLOT));
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
byte tcode = (types[i] == FloatTypeCode) ? FLOAT : INT;
state.add(new VariableElement(kind, i, tcode, value));
break;
}
case LongTypeCode:
case DoubleTypeCode:
{
// KV: this code would be nicer if VoidTypeCode would always follow a 64-bit value. Rigth now for LOCAL it follows, for STACK it proceeds
Offset memoff = (kind == LOCAL) ? vOffset.minus(2 * BYTES_IN_STACKSLOT) : vOffset.minus(BYTES_IN_STACKSLOT);
long value = Magic.getLongAtOffset(stack, memoff);
byte tcode = (types[i] == LongTypeCode) ? LONG : DOUBLE;
state.add(new VariableElement(kind, i, tcode, value));
if (kind == LOCAL) {
// KV:VoidTypeCode is next
vOffset = vOffset.minus(2 * BYTES_IN_STACKSLOT);
i++;
} else {
// KV:VoidTypeCode was already in front
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
}
break;
}
case ReturnAddressTypeCode:
{
VM.disableGC();
Address rowIP = Magic.objectAsAddress(stack).loadAddress(vOffset);
Offset ipOffset = compiledMethod.getInstructionOffset(rowIP);
VM.enableGC();
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
if (VM.TraceOnStackReplacement) {
Offset ipIndex = ipOffset.toWord().rsha(LG_INSTRUCTION_WIDTH).toOffset();
VM.sysWrite("baseline ret_addr ip ", ipIndex, " --> ");
}
int bcIndex = compiledMethod.findBytecodeIndexForInstruction(ipOffset.plus(INSTRUCTION_WIDTH));
if (VM.TraceOnStackReplacement) {
VM.sysWriteln(" bc " + bcIndex);
}
state.add(new VariableElement(kind, i, RET_ADDR, bcIndex));
break;
}
case ClassTypeCode:
case ArrayTypeCode:
{
VM.disableGC();
Object ref = Magic.getObjectAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
VM.enableGC();
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
state.add(new VariableElement(kind, i, REF, ref));
break;
}
case WordTypeCode:
{
Word value = Magic.getWordAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
state.add(new VariableElement(kind, i, WORD, value));
break;
}
default:
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
break;
}
// switch
}
// for loop
}
use of org.jikesrvm.osr.VariableElement in project JikesRVM by JikesRVM.
the class OptExecutionStateExtractor method getExecStateSequence.
private ExecutionState getExecStateSequence(RVMThread thread, byte[] stack, Offset ipOffset, Offset fpOffset, int cmid, Offset tsFPOffset, TempRegisters registers, EncodedOSRMap osrmap) {
// go through the stack frame and extract values
// In the variable value list, we keep the order as follows:
// L0, L1, ..., S0, S1, ....
/* go over osr map element, build list of VariableElement.
* assuming iterator has ordered element as
* L0, L1, ..., S0, S1, ...
*
* ThreadSwitch
* threadSwitchFromOsr
* FOO <-- fpOffset
*
* Also, all registers saved by threadSwitchFromDeopt method
* is restored in "registers", address for object is converted
* back to object references.
*
* This method should be called in non-GC critical section since
* it allocates many objects.
*/
// for 64-bit type values which have two int parts.
// this holds the high part.
int lvalue_one = 0;
int lvtype_one = 0;
// now recover execution states
OSRMapIterator iterator = osrmap.getOsrMapIteratorForMCOffset(ipOffset);
if (VM.VerifyAssertions)
VM._assert(iterator != null);
ExecutionState state = new ExecutionState(thread, fpOffset, cmid, iterator.getBcIndex(), tsFPOffset);
MethodReference mref = MemberReference.getMethodRef(iterator.getMethodId());
state.setMethod((NormalMethod) mref.peekResolvedMethod());
// this is not caller, but the callee, reverse it when outside
// of this function.
state.callerState = null;
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("osr map table of " + state.meth.toString());
}
while (iterator.hasMore()) {
if (iterator.getMethodId() != state.meth.getId()) {
ExecutionState newstate = new ExecutionState(thread, fpOffset, cmid, iterator.getBcIndex(), tsFPOffset);
mref = MemberReference.getMethodRef(iterator.getMethodId());
newstate.setMethod((NormalMethod) mref.peekResolvedMethod());
// this is not caller, but the callee, reverse it when outside
// of this function.
newstate.callerState = state;
state = newstate;
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("osr map table of " + state.meth.toString());
}
}
// create a VariableElement for it.
boolean kind = iterator.getKind();
char num = iterator.getNumber();
byte tcode = iterator.getTypeCode();
byte vtype = iterator.getValueType();
int value = iterator.getValue();
iterator.moveToNext();
if (VM.TraceOnStackReplacement) {
VM.sysWrite((kind == LOCAL) ? "L" : "S");
VM.sysWrite((int) num);
VM.sysWrite(" , ");
if (vtype == ICONST) {
VM.sysWrite("ICONST ");
VM.sysWrite(value);
} else if (vtype == PHYREG) {
VM.sysWrite("PHYREG ");
VM.sysWrite(GPR.lookup(value).toString());
} else if (vtype == SPILL) {
VM.sysWrite("SPILL ");
VM.sysWrite(value);
}
VM.sysWriteln();
}
switch(tcode) {
case INT:
{
int ibits = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
state.add(new VariableElement(kind, num, tcode, ibits));
break;
}
case FLOAT:
{
float fv = (float) getDoubleFrom(vtype, value, stack, fpOffset, registers);
int ibits = Magic.floatAsIntBits(fv);
state.add(new VariableElement(kind, num, tcode, ibits));
break;
}
case HIGH_64BIT:
{
lvalue_one = value;
lvtype_one = vtype;
break;
}
case LONG:
{
long lbits = getLongBitsFrom(lvtype_one, lvalue_one, vtype, value, stack, fpOffset, registers);
lvalue_one = 0;
lvtype_one = 0;
state.add(new VariableElement(kind, num, LONG, lbits));
break;
}
case DOUBLE:
{
double dv = getDoubleFrom(vtype, value, stack, fpOffset, registers);
long lbits = Magic.doubleAsLongBits(dv);
state.add(new VariableElement(kind, num, tcode, lbits));
break;
}
// To be VERIFIED.
case RET_ADDR:
{
int bcIndex = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
state.add(new VariableElement(kind, num, tcode, bcIndex));
break;
}
case WORD:
{
// KV:TODO
if (VM.BuildFor64Addr) {
if (VM.VerifyAssertions) {
VM._assert(VM.NOT_REACHED);
} else {
VM.sysFail("Case not yet implemented for 64-bit addresssing.");
}
}
int word = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
state.add(new VariableElement(kind, num, tcode, word));
break;
}
case REF:
{
Object ref = getObjectFrom(vtype, value, stack, fpOffset, registers);
state.add(new VariableElement(kind, num, tcode, ref));
break;
}
default:
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
break;
}
// switch
}
return state;
}
use of org.jikesrvm.osr.VariableElement in project JikesRVM by JikesRVM.
the class BaselineExecutionStateExtractor method getVariableValue.
/* go over local/stack array, and build VariableElement. */
private static void getVariableValue(byte[] stack, Offset offset, byte[] types, ArchBaselineCompiledMethod compiledMethod, boolean kind, ExecutionState state) {
int size = types.length;
Offset vOffset = offset;
for (int i = 0; i < size; i++) {
switch(types[i]) {
case VoidTypeCode:
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
break;
case BooleanTypeCode:
case ByteTypeCode:
case ShortTypeCode:
case CharTypeCode:
case IntTypeCode:
case FloatTypeCode:
{
int value = Magic.getIntAtOffset(stack, vOffset.minus(BYTES_IN_INT));
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
byte tcode = (types[i] == FloatTypeCode) ? FLOAT : INT;
state.add(new VariableElement(kind, i, tcode, value));
break;
}
case LongTypeCode:
case DoubleTypeCode:
{
// KV: this code would be nicer if VoidTypeCode would always follow a 64-bit value. Rigth now for LOCAL it follows, for STACK it proceeds
Offset memoff = (kind == LOCAL) ? vOffset.minus(BYTES_IN_DOUBLE) : VM.BuildFor64Addr ? vOffset : vOffset.minus(BYTES_IN_STACKSLOT);
long value = Magic.getLongAtOffset(stack, memoff);
byte tcode = (types[i] == LongTypeCode) ? LONG : DOUBLE;
state.add(new VariableElement(kind, i, tcode, value));
if (kind == LOCAL) {
// KV:VoidTypeCode is next
vOffset = vOffset.minus(2 * BYTES_IN_STACKSLOT);
// KV:skip VoidTypeCode
i++;
} else {
// KV:VoidTypeCode was already in front
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
}
break;
}
case ReturnAddressTypeCode:
{
VM.disableGC();
Address rowIP = Magic.objectAsAddress(stack).loadAddress(vOffset.minus(BYTES_IN_ADDRESS));
Offset ipOffset = compiledMethod.getInstructionOffset(rowIP);
VM.enableGC();
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
if (VM.TraceOnStackReplacement) {
Offset ipIndex = ipOffset.toWord().rsha(LG_INSTRUCTION_WIDTH).toOffset();
VM.sysWrite("baseline ret_addr ip ", ipIndex, " --> ");
}
int bcIndex = compiledMethod.findBytecodeIndexForInstruction(ipOffset.plus(INSTRUCTION_WIDTH));
if (VM.TraceOnStackReplacement) {
VM.sysWriteln(" bc " + bcIndex);
}
state.add(new VariableElement(kind, i, RET_ADDR, bcIndex));
break;
}
case ClassTypeCode:
case ArrayTypeCode:
{
VM.disableGC();
Object ref = Magic.getObjectAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
VM.enableGC();
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
state.add(new VariableElement(kind, i, REF, ref));
break;
}
case WordTypeCode:
{
Word value = Magic.getWordAtOffset(stack, vOffset.minus(BYTES_IN_ADDRESS));
vOffset = vOffset.minus(BYTES_IN_STACKSLOT);
state.add(new VariableElement(kind, i, WORD, value));
break;
}
default:
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
break;
}
// switch
}
// for loop
}
use of org.jikesrvm.osr.VariableElement in project JikesRVM by JikesRVM.
the class OptExecutionStateExtractor method getExecStateSequence.
private ExecutionState getExecStateSequence(RVMThread thread, byte[] stack, Offset ipOffset, Offset fpOffset, int cmid, Offset tsFPOffset, TempRegisters registers, EncodedOSRMap osrmap) {
// go through the stack frame and extract values
// In the variable value list, we keep the order as follows:
// L0, L1, ..., S0, S1, ....
/* go over osr map element, build list of VariableElement.
* assuming iterator has ordered element as
* L0, L1, ..., S0, S1, ...
*
* RVMThread.ThreadSwitch
* OptSaveVolatile.threadSwitchFromDeopt
* FOO <-- fpOffset
*
* Also, all registers saved by threadSwitchFromDeopt method
* is restored in "registers", address for object is converted
* back to object references.
*
* This method should be called in non-GC critical section since
* it allocates many objects.
*/
// for 64-bit type values which have two int parts.
// this holds the high part.
int lpart_one = 0;
// now recover execution states
OSRMapIterator iterator = osrmap.getOsrMapIteratorForMCOffset(ipOffset);
if (VM.VerifyAssertions)
VM._assert(iterator != null);
ExecutionState state = new ExecutionState(thread, fpOffset, cmid, iterator.getBcIndex(), tsFPOffset);
MethodReference mref = MemberReference.getMethodRef(iterator.getMethodId());
state.setMethod((NormalMethod) mref.peekResolvedMethod());
state.callerState = null;
while (iterator.hasMore()) {
if (iterator.getMethodId() != state.meth.getId()) {
ExecutionState newstate = new ExecutionState(thread, fpOffset, cmid, iterator.getBcIndex(), tsFPOffset);
mref = MemberReference.getMethodRef(iterator.getMethodId());
newstate.setMethod((NormalMethod) mref.peekResolvedMethod());
// this is not caller, but the callee, reverse it when outside
// of this function.
newstate.callerState = state;
state = newstate;
}
// create a VariableElement for it.
boolean kind = iterator.getKind();
int num = iterator.getNumber();
byte tcode = iterator.getTypeCode();
byte vtype = iterator.getValueType();
int value = iterator.getValue();
iterator.moveToNext();
switch(tcode) {
case INT:
{
int ibits = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
state.add(new VariableElement(kind, num, tcode, ibits));
break;
}
case FLOAT:
{
float fv = (float) getDoubleFrom(vtype, value, stack, fpOffset, registers);
int ibits = Magic.floatAsIntBits(fv);
state.add(new VariableElement(kind, num, tcode, ibits));
break;
}
case HIGH_64BIT:
{
lpart_one = value;
break;
}
case LONG:
{
long lbits = getLongBitsFrom(vtype, lpart_one, value, stack, fpOffset, registers);
lpart_one = 0;
state.add(new // not use LONG2,
VariableElement(// not use LONG2,
kind, // not use LONG2,
num, // not use LONG2,
LONG, lbits));
break;
}
case DOUBLE:
{
double dv = getDoubleFrom(vtype, value, stack, fpOffset, registers);
long lbits = Magic.doubleAsLongBits(dv);
state.add(new VariableElement(kind, num, tcode, lbits));
break;
}
// To be VERIFIED.
case RET_ADDR:
{
int bcIndex = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
state.add(new VariableElement(kind, num, tcode, bcIndex));
break;
}
case REF:
{
Object ref = getObjectFrom(vtype, value, stack, fpOffset, registers);
state.add(new VariableElement(kind, num, tcode, ref));
break;
}
case WORD:
{
if (VM.BuildFor32Addr) {
int word = getIntBitsFrom(vtype, value, stack, fpOffset, registers);
state.add(new VariableElement(kind, num, tcode, word));
} else {
long word = getLongBitsFrom(vtype, lpart_one, value, stack, fpOffset, registers);
lpart_one = 0;
state.add(new VariableElement(kind, num, tcode, word));
}
break;
}
default:
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
break;
}
// switch
}
return state;
}
Aggregations