use of org.jikesrvm.compilers.opt.ir.operand.OsrTypeInfoOperand in project JikesRVM by JikesRVM.
the class OsrPointConstructor method isBarrierClean.
/**
* Determines if the barrier is clean by checking the number of valid operands.
* @param barrier the instruction to verifiy
* @return {@code true} if and only if the barrier is clean
*/
private boolean isBarrierClean(Instruction barrier) {
OsrTypeInfoOperand typeInfo = OsrBarrier.getTypeInfo(barrier);
int totalOperands = countNonVoidTypes(typeInfo.localTypeCodes);
totalOperands += countNonVoidTypes(typeInfo.stackTypeCodes);
return (totalOperands == OsrBarrier.getNumberOfElements(barrier));
}
use of org.jikesrvm.compilers.opt.ir.operand.OsrTypeInfoOperand in project JikesRVM by JikesRVM.
the class BC2IR method _createOsrBarrier.
/* create an OSR Barrier instruction at the current position.
*/
private Instruction _createOsrBarrier() {
ArrayList<Operand> livevars = new ArrayList<Operand>();
/* for local variables, we have to use helper to make a register. */
/* ltypes and stypes should be the full length
* WARNING: what's the order of DUMMY and LONG?
*/
int localnum = _localState.length;
byte[] ltypes = new byte[localnum];
int num_llocals = 0;
for (int i = 0, n = _localState.length; i < n; i++) {
Operand op = _localState[i];
if ((op != null) && (op != DUMMY)) {
livevars.add(_loadLocalForOSR(op));
num_llocals++;
if (op instanceof ReturnAddressOperand) {
ltypes[i] = ReturnAddressTypeCode;
} else {
TypeReference typ = op.getType();
if (typ.isWordLikeType() || (typ == TypeReference.NULL_TYPE)) {
ltypes[i] = WordTypeCode;
} else {
ltypes[i] = typ.getName().parseForTypeCode();
}
}
} else {
ltypes[i] = VoidTypeCode;
}
}
int stacknum = stack.getSize();
byte[] stypes = new byte[stacknum];
/* the variable on stack can be used directly ? */
int num_lstacks = 0;
for (int i = 0, n = stack.getSize(); i < n; i++) {
Operand op = stack.getFromBottom(i);
if ((op != null) && (op != DUMMY)) {
if (op.isRegister()) {
livevars.add(op.asRegister().copyU2U());
} else {
livevars.add(op.copy());
}
num_lstacks++;
if (op instanceof ReturnAddressOperand) {
stypes[i] = ReturnAddressTypeCode;
} else {
TypeReference typ = op.getType();
if (typ.isWordLikeType() || (typ == TypeReference.NULL_TYPE)) {
stypes[i] = WordTypeCode;
} else {
/* for stack operand, reverse the order for long and double */
byte tcode = typ.getName().parseForTypeCode();
if ((tcode == LongTypeCode) || (tcode == DoubleTypeCode)) {
stypes[i - 1] = tcode;
stypes[i] = VoidTypeCode;
} else {
stypes[i] = tcode;
}
}
}
} else {
stypes[i] = VoidTypeCode;
}
}
Instruction barrier = // temporarily
OsrBarrier.create(// temporarily
OSR_BARRIER, // temporarily
null, num_llocals + num_lstacks);
for (int i = 0, n = livevars.size(); i < n; i++) {
Operand op = livevars.get(i);
if (op instanceof ReturnAddressOperand) {
int tgtpc = ((ReturnAddressOperand) op).retIndex - gc.getMethod().getOsrPrologueLength();
op = new IntConstantOperand(tgtpc);
} else if (op instanceof LongConstantOperand) {
op = _prepareLongConstant(op);
} else if (op instanceof DoubleConstantOperand) {
op = _prepareDoubleConstant(op);
}
if (VM.VerifyAssertions)
opt_assert(op != null);
OsrBarrier.setElement(barrier, i, op);
}
// patch type info operand
OsrTypeInfoOperand typeinfo = new OsrTypeInfoOperand(ltypes, stypes);
OsrBarrier.setTypeInfo(barrier, typeinfo);
setSourcePosition(barrier);
return barrier;
}
use of org.jikesrvm.compilers.opt.ir.operand.OsrTypeInfoOperand in project JikesRVM by JikesRVM.
the class OsrPointConstructor method renovateOsrPoints.
/**
* For each OsrPoint instruction, traces its OsrBarriers created by
* inlining. rebuild OsrPoint instruction to hold all necessary
* information to recover from inlined activation.
* @param ir the IR
*/
private void renovateOsrPoints(IR ir) {
for (int osrIdx = 0, osrSize = osrPoints.size(); osrIdx < osrSize; osrIdx++) {
Instruction osr = osrPoints.get(osrIdx);
LinkedList<Instruction> barriers = new LinkedList<Instruction>();
// Step 1: collect barriers put before inlined method
// in the order of from inner to outer
{
GenerationContext gc = ir.getGc();
Instruction bar = gc.getOSRBarrierFromInst(osr);
if (osr.position() == null)
osr.setPosition(bar.position());
adjustBCIndex(osr);
while (bar != null) {
barriers.add(bar);
// verify each barrier is clean
if (VM.VerifyAssertions) {
if (!isBarrierClean(bar)) {
VM.sysWriteln("Barrier " + bar + " is not clean!");
}
VM._assert(isBarrierClean(bar));
}
Instruction callsite = bar.position().getCallSite();
if (callsite != null) {
bar = gc.getOSRBarrierFromInst(callsite);
if (bar == null) {
VM.sysWrite("call site :" + callsite);
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
}
adjustBCIndex(bar);
} else {
bar = null;
}
}
}
int inlineDepth = barriers.size();
if (VM.VerifyAssertions) {
if (inlineDepth == 0) {
VM.sysWriteln("Inlining depth for " + osr + " is 0!");
}
VM._assert(inlineDepth != 0);
}
// Step 2: make a new InlinedOsrTypeOperand from barriers
int[] methodids = new int[inlineDepth];
int[] bcindexes = new int[inlineDepth];
byte[][] localTypeCodes = new byte[inlineDepth][];
byte[][] stackTypeCodes = new byte[inlineDepth][];
int totalOperands = 0;
// first iteration, count the size of total locals and stack sizes
for (int barIdx = 0, barSize = barriers.size(); barIdx < barSize; barIdx++) {
Instruction bar = barriers.get(barIdx);
methodids[barIdx] = bar.position().method.getId();
bcindexes[barIdx] = bar.getBytecodeIndex();
OsrTypeInfoOperand typeInfo = OsrBarrier.getTypeInfo(bar);
localTypeCodes[barIdx] = typeInfo.localTypeCodes;
stackTypeCodes[barIdx] = typeInfo.stackTypeCodes;
// count the number of operand, but ignore VoidTypeCode
totalOperands += OsrBarrier.getNumberOfElements(bar);
/*
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("OsrBarrier : "+bar.bcIndex
+"@"+bar.position.method
+" "+typeInfo);
}
*/
}
// new make InlinedOsrTypeInfoOperand
InlinedOsrTypeInfoOperand typeInfo = new InlinedOsrTypeInfoOperand(methodids, bcindexes, localTypeCodes, stackTypeCodes);
OsrPoint.mutate(osr, osr.operator(), typeInfo, totalOperands);
// Step 3: second iteration, copy operands
int opIndex = 0;
for (int barIdx = 0, barSize = barriers.size(); barIdx < barSize; barIdx++) {
Instruction bar = barriers.get(barIdx);
for (int elmIdx = 0, elmSize = OsrBarrier.getNumberOfElements(bar); elmIdx < elmSize; elmIdx++) {
Operand op = OsrBarrier.getElement(bar, elmIdx);
if (VM.VerifyAssertions) {
if (op == null) {
VM.sysWriteln(elmIdx + "th Operand of " + bar + " is null!");
}
VM._assert(op != null);
}
if (op.isRegister()) {
op = op.asRegister().copyU2U();
} else {
op = op.copy();
}
OsrPoint.setElement(osr, opIndex, op);
opIndex++;
}
}
// the last OsrBarrier should in the current method
if (VM.VerifyAssertions) {
Instruction lastBar = barriers.getLast();
if (ir.method != lastBar.position().method) {
VM.sysWriteln("The last barrier is not in the same method as osr:");
VM.sysWriteln(lastBar + "@" + lastBar.position().method);
VM.sysWriteln("current method @" + ir.method);
}
VM._assert(ir.method == lastBar.position().method);
if (opIndex != totalOperands) {
VM.sysWriteln("opIndex and totalOperands do not match:");
VM.sysWriteln("opIndex = " + opIndex);
VM.sysWriteln("totalOperands = " + totalOperands);
}
VM._assert(opIndex == totalOperands);
}
// end of assertion
}
// end of for loop
}
Aggregations