Search in sources :

Example 1 with Nop

use of org.jikesrvm.osr.bytecodes.Nop in project JikesRVM by JikesRVM.

the class ExecutionState method paddingBytecode.

/**
 * Adds padding (NOP) at the beginning of pseudo bytecode
 * to make the new bytecode size dividable by 4, then no branch
 * target adjustment is needed in the original code.
 * @param head the first pseudo bytecode (must be NOP)
 * @return the new bytecode size
 */
private static int paddingBytecode(PseudoBytecode head) {
    /* skip the first Nop. */
    PseudoBytecode bcode = head.next;
    /* count the total size of prologue code. */
    int bsize = 0;
    while (bcode != null) {
        bsize += bcode.getSize();
        bcode = bcode.next;
    }
    /* insert Nop at the beginning to make the code size of x4. */
    int padding = 3 - (bsize + 3) & 0x03;
    for (int i = 0; i < padding; i++) {
        bcode = new Nop();
        bcode.next = head.next;
        head.next = bcode;
    }
    bsize += padding;
    return bsize;
}
Also used : PseudoBytecode(org.jikesrvm.osr.bytecodes.PseudoBytecode) Nop(org.jikesrvm.osr.bytecodes.Nop)

Example 2 with Nop

use of org.jikesrvm.osr.bytecodes.Nop in project JikesRVM by JikesRVM.

the class ExecutionState method generatePrologue.

/**
 * Goes through variable elements and produces specialized
 * prologue using pseudo-bytecode.
 *
 * @return the specialized prologue
 */
public byte[] generatePrologue() {
    int size = varElms.size();
    this.objs = new Object[size];
    this.objnum = 0;
    this.rid = ObjectHolder.handinRefs(this.objs);
    PseudoBytecode head = new Nop();
    PseudoBytecode tail = head;
    int elmcount = 0;
    // restore "this"
    if (!this.meth.isStatic()) {
        VariableElement var = varElms.get(elmcount);
        tail = processElement(var, tail, elmcount);
        elmcount++;
        if (VM.VerifyAssertions) {
            VM._assert(var.isLocal() && (var.getNumber() == 0));
        }
    }
    // restore other parameters,
    int paranum = this.meth.getParameterTypes().length;
    for (int i = 0; i < paranum; i++) {
        VariableElement var = varElms.get(elmcount);
        tail = processElement(var, tail, elmcount);
        elmcount++;
        if (VM.VerifyAssertions) {
            VM._assert(var.isLocal());
        // the number may not match because of long and double type
        }
    }
    // ok, ready to indicate param initialized, thread switch
    // and stack overflow check happens here
    tail.next = new ParamInitEnd();
    tail = tail.next;
    // were sorted
    for (; elmcount < size; elmcount++) {
        VariableElement var = varElms.get(elmcount);
        tail = processElement(var, tail, elmcount);
    }
    if (this.objnum != 0) {
        tail.next = new LoadIntConst(this.rid);
        tail = tail.next;
        tail.next = new InvokeStatic(CLEANREFS);
        tail = tail.next;
    } else {
        ObjectHolder.cleanRefs(this.rid);
    }
    // default situation
    int branchTarget = this.bcIndex;
    /* when this method must start with a call of callee,
     * we are using invokeCompiledMethod,
     */
    if (callee_cmid != -1) {
        // remember the callee's cmid, and the index of original index
        tail.next = new InvokeCompiledMethod(callee_cmid, this.bcIndex);
        tail = tail.next;
        // if this method needs a call, than we must jump to
        // the instruction after the call.
        BytecodeStream bcodes = this.meth.getBytecodes();
        bcodes.reset(this.bcIndex);
        int code = bcodes.nextInstruction();
        if (JBC_isJava6Call(code)) {
            branchTarget = this.bcIndex + JBC_length(code);
        } else {
            if (VM.VerifyAssertions) {
                String msg = "ExecutionState: unknown bytecode " + code + " at " + this.bcIndex + "@" + this.meth;
                VM._assert(VM.NOT_REACHED, msg);
            }
        }
    }
    // add goto statement, be careful, after goto
    // there may be several pop instructions
    int pops = computeStackHeight(head);
    // preserve space
    branchTarget += pops;
    {
        Goto togo = new Goto(branchTarget);
        int osize = togo.getSize();
        togo.patch(branchTarget + osize);
        int nsize = togo.getSize();
        if (nsize != osize) {
            togo.patch(branchTarget + nsize);
        }
        tail.next = togo;
        tail = tail.next;
    }
    // compute stack heights and padding pops
    tail = adjustStackHeight(tail, pops);
    int bsize = paddingBytecode(head);
    byte[] prologue = generateBinaries(head, bsize);
    // clean fields
    this.objs = null;
    this.objnum = 0;
    return prologue;
}
Also used : PseudoBytecode(org.jikesrvm.osr.bytecodes.PseudoBytecode) Goto(org.jikesrvm.osr.bytecodes.Goto) LoadIntConst(org.jikesrvm.osr.bytecodes.LoadIntConst) BytecodeStream(org.jikesrvm.classloader.BytecodeStream) ParamInitEnd(org.jikesrvm.osr.bytecodes.ParamInitEnd) InvokeCompiledMethod(org.jikesrvm.osr.bytecodes.InvokeCompiledMethod) Nop(org.jikesrvm.osr.bytecodes.Nop) InvokeStatic(org.jikesrvm.osr.bytecodes.InvokeStatic)

Aggregations

Nop (org.jikesrvm.osr.bytecodes.Nop)2 PseudoBytecode (org.jikesrvm.osr.bytecodes.PseudoBytecode)2 BytecodeStream (org.jikesrvm.classloader.BytecodeStream)1 Goto (org.jikesrvm.osr.bytecodes.Goto)1 InvokeCompiledMethod (org.jikesrvm.osr.bytecodes.InvokeCompiledMethod)1 InvokeStatic (org.jikesrvm.osr.bytecodes.InvokeStatic)1 LoadIntConst (org.jikesrvm.osr.bytecodes.LoadIntConst)1 ParamInitEnd (org.jikesrvm.osr.bytecodes.ParamInitEnd)1