整理综合之一 ----从Bytecode到BasicBlock

来源:互联网 发布:C语言 函数库 下载 编辑:程序博客网 时间:2024/06/06 05:38


一、

第一次visitor.visitXXXX等 ,从Bytecode开始,转换为 。。。

调用过程 。。。。。

1.visitNoArgs@BasicBlocker

主要对应的Bytecode如下:

    public void visitNoArgs(int opcode, int offset, int length, Type type) {        switch (opcode) {            case ByteOps.IRETURN:            case ByteOps.RETURN: {                visitCommon(offset, length, false);                targetLists[offset] = IntList.EMPTY;                break;            }            case ByteOps.ATHROW: {                visitCommon(offset, length, false);                visitThrowing(offset, length, false);                break;            }            case ByteOps.IALOAD:            case ByteOps.LALOAD:            case ByteOps.FALOAD:            case ByteOps.DALOAD:            case ByteOps.AALOAD:            case ByteOps.BALOAD:            case ByteOps.CALOAD:            case ByteOps.SALOAD:            case ByteOps.IASTORE:            case ByteOps.LASTORE:            case ByteOps.FASTORE:            case ByteOps.DASTORE:            case ByteOps.AASTORE:            case ByteOps.BASTORE:            case ByteOps.CASTORE:            case ByteOps.SASTORE:            case ByteOps.ARRAYLENGTH:            case ByteOps.MONITORENTER:            case ByteOps.MONITOREXIT: {                /*                 * These instructions can all throw, so they have to end                 * the block they appear in (since throws are branches).                 */                visitCommon(offset, length, true);                visitThrowing(offset, length, true);                break;            }            case ByteOps.IDIV:            case ByteOps.IREM: {                /*                 * The int and long versions of division and remainder may                 * throw, but not the other types.                 */                visitCommon(offset, length, true);                if ((type == Type.INT) || (type == Type.LONG)) {                    visitThrowing(offset, length, true);                }                break;            }            default: {                visitCommon(offset, length, true);                break;            }        }    }

<情况一>:

IRETURN / RETURN

(1)其中visitCommon(offset,length,nextIsLive)


       Bits.set(liveSet, offset);


         true---->addWorkIfNecessary(offset + length, false);

                        //在addWorkIfNecessary(offset,blockStart)中,

                        //如果 liveSet在offset出没有置位,则置位workSet的offset处,否则不做

                        //如果blockStart为真,则置位 blockSet相应的offset处,否则不做

         flase----> Bits.set(blockSet, offset + length);

(2)更新targetLists[offset]

<情况二>:

ATHROW

(1)

                visitCommon(offset, length, false);

(2)

                visitThrowing(offset, length, false);

如果为真 --->addWorkIfNecessary(next,true) //置位blockSet

赋值catchLists[offset] 以及 targetLists[offset]

    private void visitThrowing(int offset, int length, boolean nextIsLive) {        int next = offset + length;        if (nextIsLive) {            addWorkIfNecessary(next, true);        }        ByteCatchList catches = method.getCatches().listFor(offset);        catchLists[offset] = catches;        targetLists[offset] = catches.toTargetList(nextIsLive ? next : -1);    }
a.

其中, listFor@ByteCatchList.java

    public ByteCatchList listFor(int pc) {        int sz = size();        Item[] resultArr = new Item[sz];        int resultSz = 0;        for (int i = 0; i < sz; i++) {            Item one = get(i);            if (one.covers(pc) && typeNotFound(one, resultArr, resultSz)) {            //covers看看给的pc是不是在这个catch的管辖范围之内;            //typeNotFound,如果发现在resultArr中没有catch这种对象时才返回true;只有两个情况都发生,才。。。                resultArr[resultSz] = one; //可能不只一个catch管这个pc?                resultSz++;            }        }        if (resultSz == 0) {            return EMPTY;        }        ByteCatchList result = new ByteCatchList(resultSz);        for (int i = 0; i < resultSz; i++) {            result.set(i, resultArr[i]); //倒腾一下        }        result.setImmutable();        return result;    }

b.

toTargetList@ByteCatchList.java

        catchLists[offset] = catches;

        targetLists[offset] = catches.toTargetList(nextIsLive ? next : -1);

    public IntList toTargetList(int noException) {        if (noException < -1) {            throw new IllegalArgumentException("noException < -1");        }        boolean hasDefault = (noException >= 0);        int sz = size();//catches中有多少catch        if (sz == 0) {//没有catch的情况?            if (hasDefault) { //把next给targetList                /*                 * The list is empty, but there is a no-exception                 * address; so, the result is just that address.                 */                return IntList.makeImmutable(noException);            }            /*             * The list is empty and there isn't even a no-exception             * address.             */            return IntList.EMPTY;//没有catch也没有next了?        }//以下是存在catch的情况        IntList result = new IntList(sz + (hasDefault ? 1 : 0));        for (int i = 0; i < sz; i++) {            result.add(get(i).getHandlerPc());//将catches中的catch的handlerPc加入result        }        if (hasDefault) {            result.add(noException);//(缺省,如果没有异常发生,则执行下一条?)将next加入result        }        result.setImmutable();//mutable=false;神马作用?        return result;    }

<情况三>

IALOAD / LALOAD / FALOAD / DALOAD / AALOAD / BALOAD / CALOAD / SALOAD / IASTORE / LASTORE / FASTORE / DASTORE / AASTORE /BASTORE /CASTORE  / SASTORE / ARRAYLENGTH / MONITORENTER / MONITOREXIT

                visitCommon(offset, length, true);
                visitThrowing(offset, length, true);
                break;

<情况四>

IDIV / IREM

                visitCommon(offset, length, true);
                if ((type == Type.INT) || (type == Type.LONG)) {
                    visitThrowing(offset, length, true);
                }
                break;

<情况五>

default:

NOP

POP / POP2 / DUP / DUP_X1 / DUP_X2 / DUP2 / DUP2_X1 / DUP2_X2 / SWAP

IADD / ISUB / IMUL / IDIV(情况四) / IREM(情况四)/ INEG / ISHL / ISHR / IUSHR / IAND / IOR / IXOR

LADD / LSUB / LMUL / LDIV / LREM / LNEG / LSHL / LSHR / LUSHR / LAND / LOR / LXOR

FADD / FSUB / FMUL / FDIV / FREM / FNEG

DADD / DSUB / DMUL / DDIV / DREM / DNEG

I2L / F2L / D2L

I2F / L2F / D2F

I2D / L2D / F2D

L2I  / F2I / D2I / I2B / I2C / I2S / LCMP / FCMP / FCMPG / DCMPL / DCMPG /ARRAYLENGTH(情况三)

LRETURN

FRETURN

DRETURN

ARETURN

RETURN (情况一)/ ATHROW(情况二) / MONITORENTER (情况三)/ MONITOREXIT(情况三)

                visitCommon(offset, length, true);
                break;

2.

visitConstant@BasicBlocker.java

ACONST_NULL   ICONST_M1  ICONST_0  ICONST_1  ICONST_2  ICONST_3  ICONST_4  ICONST_5   LCONST_0  LCONST_1  FCONST_0  FCONST_1  FCONST_2

  DCONST_0  DCONST_1  BIPUSH  SIPUSH  LDC  LDCW  LDC2_W

GETSTATIC / PUTSTATIC / GETFIELD / PUTFIELD / INVOKEVIRTUAL / INVOKESPECIAL / INVOKESTATIC / NEW / ANEWARRAY / CHECKCAST / INSTANCEOF

INVOKEINTERFACE

MULTIANEWARRAY

    public void visitConstant(int opcode, int offset, int length,            Constant cst, int value) {        visitCommon(offset, length, true);        if ((cst instanceof CstMemberRef) || (cst instanceof CstType) ||            (cst instanceof CstString)) {//从常量池中取出的,有可能,不确定神马指令            /*             * Instructions with these sorts of constants have the             * possibility of throwing, so this instruction needs to             * end its block (since it can throw, and possible-throws             * are branch points).             */            visitThrowing(offset, length, true);        }    }
3.

visitLocal@BasicBlocker.java

ILOAD  LLOAD  FLOAD  DLOAD  ALOAD  ILOAD_0/1/2/3  LLOAD_0/1/2/3  FLOAD_0/1/2/3  DLOAD_0/1/2/3  ALOAD_0/1/2/3  ISTORE  LSTORE  FSTORE  DSTORE  DSTORE  ASTORE  ISTORE_0/1/2/3  LSTORE_0/1/2/3  FSTORE_0/1/2/3  DSTORE_0/1/2/3  ASTORE_0/1/2/3   IINC  RET

    public void visitLocal(int opcode, int offset, int length,            int idx, Type type, int value) {        if (opcode == ByteOps.RET) {            visitCommon(offset, length, false);//设置liveSet;设置blockSet            targetLists[offset] = IntList.EMPTY;// targetList[offset]空        } else {            visitCommon(offset, length, true);//设置liveSet        }    }

4.

visitBranch@BasicBlocker.java

IFEQ(NE/LT/GE/GT/LE)  /  IF_ICMPEQ(NE/LT/GE/GT/LE/EQ/NE)  /  GOTO  /  JSR  /  IFNULL  /  IFNONNULL

GOTO_W  /  JSR_W

    public void visitBranch(int opcode, int offset, int length,            int target) {        switch (opcode) {            case ByteOps.GOTO: {                visitCommon(offset, length, false);                targetLists[offset] = IntList.makeImmutable(target);//下面代码                break;            }            case ByteOps.JSR: {                /*                 * Each jsr is quarantined into a separate block (containing                 * only the jsr instruction) but is otherwise treated                 * as a conditional branch. (That is to say, both its                 * target and next instruction begin new blocks.)                 */                addWorkIfNecessary(offset, true);//ifNecessary,设置workSet ;设置blockSet;                // Fall through to next case...            }            default: {                int next = offset + length;                visitCommon(offset, length, true);                addWorkIfNecessary(next, true);//ifNecessary,设置workSet ; 设置blockSet                targetLists[offset] = IntList.makeImmutable(next, target);//下面代码                break;            }        }        addWorkIfNecessary(target, true);//target为传进来的参数    }

makeImmutable@IntList.java

public static IntList makeImmutable(int value) {//一个参数        IntList result = new IntList(1);        result.add(value);        result.setImmutable();        return result;    }   public static IntList makeImmutable(int value0, int value1) {//两个参数        IntList result = new IntList(2);        result.add(value0);        result.add(value1);        result.setImmutable();        return result;    }


5.

parseTableswitch@BytecodeArray.java

TABLESWITCH

6.

parseLookupswitch

LOOKUPSWITCH

7.

parseNewarray

NEWARRAY

8.

parseWide

WIDE

9.

visitInvalid

其他指令



原创粉丝点击