translateAndGetResult @ RopTranslator.java 源码分析------流水记录(二)

outputInstructions@RopTranslator.java

    private void outputInstructions() {
        BasicBlockList blocks = method.getBlocks();
        int[] order = this.order;
        int len = order.length;

        // Process the blocks in output order.
        for (int i = 0; i < len; i++) {
            int nextI = i + 1;
            int nextLabel = (nextI == order.length) ? -1 : order[nextI];//nextLabel为order[nextI]或-1(end了)
            outputBlock(blocks.labelToBlock(order[i]), nextLabel);
        }
    }

根据order的顺序处理blocks

其中outputBlock@RopTranslator.java

    private void outputBlock(BasicBlock block, int nextLabel) {
        // Append the code address for this block.
        CodeAddress startAddress = addresses.getStart(block);//getStart@BlockAddresses.java return starts[x]; 
        //starts 从RopTranslator构造跟踪下去
        output.add(startAddress);

        // Append the local variable state for the block.
        if (locals != null) {
            RegisterSpecSet starts = locals.getStarts(block);
            output.add(new LocalSnapshot(startAddress.getPosition(),
                                         starts));
        }

        /*
         * Choose and append an output instruction for each original
         * instruction.
         */
        translationVisitor.setBlock(block, addresses.getLast(block));//getLast 与上面的getStart相似
        block.getInsns().forEach(translationVisitor);

        // Insert the block end code address.
        output.add(addresses.getEnd(block));

        // Set up for end-of-block activities.

        int succ = block.getPrimarySuccessor();
        Insn lastInsn = block.getLastInsn();

        /*
         * Check for (and possibly correct for) a non-optimal choice of
         * which block will get output next.
         */

        if ((succ >= 0) && (succ != nextLabel)) {
            /*
             * The block has a "primary successor" and that primary
             * successor isn't the next block to be output.
             */
            Rop lastRop = lastInsn.getOpcode();
            if ((lastRop.getBranchingness() == Rop.BRANCH_IF) &&
                    (block.getSecondarySuccessor() == nextLabel)) {
                /*
                 * The block ends with an "if" of some sort, and its
                 * secondary successor (the "then") is in fact the
                 * next block to output. So, reverse the sense of
                 * the test, so that we can just emit the next block
                 * without an interstitial goto.
                 */
                output.reverseBranch(1, addresses.getStart(succ));
            } else {
                /*
                 * Our only recourse is to add a goto here to get the
                 * flow to be correct.
                 */
                TargetInsn insn =
                    new TargetInsn(Dops.GOTO, lastInsn.getPosition(),
                            RegisterSpecList.EMPTY,
                            addresses.getStart(succ));
                output.add(insn);
            }
        }
    }


其中,

        translationVisitor.setBlock(block, addresses.getLast(block));//getLast 与上面的getStart相似
        block.getInsns().forEach(translationVisitor);


forEach@IntList.java

    public void forEach(Insn.Visitor visitor) {
        int sz = size();

        for (int i = 0; i < sz; i++) {
            get(i).accept(visitor);
        }
    }

get(i)得到的应该是Insn的子类,可能是 PlainInsn / PlainCstInsn / ThrowingCstInsn / SwitchCstInsn / FillArrayDataInsn / ThrowingInsn

每个子类中overwrite了accept方法 ,基本的形式都是这种:

        visitor.visitPlainInsn(this);    // visitor.visitXxxxxInsn(this);

而传进来的visitor的类型为 TranslationVisitor ,各个子类会调用 TranslationVisitor中相应的visitXxxxx 方法


@RopTranslator.java

    private class TranslationVisitor implements Insn.Visitor {。。。。当中 

其中构造为:

        public TranslationVisitor(OutputCollector output) {
            this.output = output;
        }

1.

visitPlainInsn

梳理以下几个主要数据:

Rop构造:

        this.opcode = opcode;//RegOps中 57个
        this.result = result;
        this.sources = sources;
        this.exceptions = exceptions;
        this.branchingness = branchingness;//?????
        this.isCallLike = isCallLike;
        this.nickname = nickname;

Insn构造:这个都是子类构造调用父类构造Insn构造

        this.opcode = opcode; //Rop类型
        this.position = position;
        this.result = result;
        this.sources = sources;

1-1.

            SourcePosition pos = insn.getPosition();
            Dop opcode = RopToDop.dopFor(insn);
            DalvInsn di;

(1)getPosition  其中几个函数里有比较多的PlainInsn构造: @RopperMachine.java @Ropper.java 

(2)doFor@RopToDop.java

    public static Dop dopFor(Insn insn) {
        Rop rop = insn.getOpcode();

        /*
         * First, just try looking up the rop in the MAP of easy
         * cases.
         */
        Dop result = MAP.get(rop);
        if (result != null) {
            return result;
        }
        switch (rop.getOpcode()) {
            case RegOps.MOVE_EXCEPTION:   return Dops.MOVE_EXCEPTION;
            case RegOps.INVOKE_STATIC:    return Dops.INVOKE_STATIC;
            case RegOps.INVOKE_VIRTUAL:   return Dops.INVOKE_VIRTUAL;
            case RegOps.INVOKE_SUPER:     return Dops.INVOKE_SUPER;
            case RegOps.INVOKE_DIRECT:    return Dops.INVOKE_DIRECT;
            case RegOps.INVOKE_INTERFACE: return Dops.INVOKE_INTERFACE;
            case RegOps.NEW_ARRAY:        return Dops.NEW_ARRAY;
            case RegOps.FILLED_NEW_ARRAY: return Dops.FILLED_NEW_ARRAY;
            case RegOps.FILL_ARRAY_DATA:  return Dops.FILL_ARRAY_DATA;
            case RegOps.MOVE_RESULT: {
                RegisterSpec resultReg = insn.getResult();

                if (resultReg == null) {
                    return Dops.NOP;
                } else {
                    switch (resultReg.getBasicType()) {
                        case Type.BT_INT:
                        case Type.BT_FLOAT:
                        case Type.BT_BOOLEAN:
                        case Type.BT_BYTE:
                        case Type.BT_CHAR:
                        case Type.BT_SHORT:
                            return Dops.MOVE_RESULT;
                        case Type.BT_LONG:
                        case Type.BT_DOUBLE:
                            return Dops.MOVE_RESULT_WIDE;
                        case Type.BT_OBJECT:
                            return Dops.MOVE_RESULT_OBJECT;
                        default: {
                            throw new RuntimeException("Unexpected basic type");
                        }
                    }
                }
            }

            case RegOps.GET_FIELD: {
                CstFieldRef ref =
                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
                int basicType = ref.getBasicType();
                switch (basicType) {
                    case Type.BT_BOOLEAN: return Dops.IGET_BOOLEAN;
                    case Type.BT_BYTE:    return Dops.IGET_BYTE;
                    case Type.BT_CHAR:    return Dops.IGET_CHAR;
                    case Type.BT_SHORT:   return Dops.IGET_SHORT;
                    case Type.BT_INT:     return Dops.IGET;
                }
                break;
            }
            case RegOps.PUT_FIELD: {
                CstFieldRef ref =
                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
                int basicType = ref.getBasicType();
                switch (basicType) {
                    case Type.BT_BOOLEAN: return Dops.IPUT_BOOLEAN;
                    case Type.BT_BYTE:    return Dops.IPUT_BYTE;
                    case Type.BT_CHAR:    return Dops.IPUT_CHAR;
                    case Type.BT_SHORT:   return Dops.IPUT_SHORT;
                    case Type.BT_INT:     return Dops.IPUT;
                }
                break;
            }
            case RegOps.GET_STATIC: {
                CstFieldRef ref =
                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
                int basicType = ref.getBasicType();
                switch (basicType) {
                    case Type.BT_BOOLEAN: return Dops.SGET_BOOLEAN;
                    case Type.BT_BYTE:    return Dops.SGET_BYTE;
                    case Type.BT_CHAR:    return Dops.SGET_CHAR;
                    case Type.BT_SHORT:   return Dops.SGET_SHORT;
                    case Type.BT_INT:     return Dops.SGET;
                }
                break;
            }
            case RegOps.PUT_STATIC: {
                CstFieldRef ref =
                    (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
                int basicType = ref.getBasicType();
                switch (basicType) {
                    case Type.BT_BOOLEAN: return Dops.SPUT_BOOLEAN;
                    case Type.BT_BYTE:    return Dops.SPUT_BYTE;
                    case Type.BT_CHAR:    return Dops.SPUT_CHAR;
                    case Type.BT_SHORT:   return Dops.SPUT_SHORT;
                    case Type.BT_INT:     return Dops.SPUT;
                }
                break;
            }
            case RegOps.CONST: {
                Constant cst = ((ThrowingCstInsn) insn).getConstant();
                if (cst instanceof CstType) {
                    return Dops.CONST_CLASS;
                } else if (cst instanceof CstString) {
                    return Dops.CONST_STRING;
                }
                break;
            }
        }

        throw new RuntimeException("unknown rop: " + rop);
    }
}

MAP.get中会看到其他平常的指令。

1-2

                    di = new SimpleInsn(opcode, pos, getRegs(insn));

可能会有几种构造:

visitPlainInsn中有两个构造 SimpleInsn和TargetInsn

会在一个switch中选择。

1-3

            addOutput(di); //output.add(insn);

2.

visitPlainCstInsn

2-1

RegSpecList相关的东东

2-2

SimpleInsn构造及CstInsn

3.

visitSwitchInsn


3-1

successors 相关的

3-2

switchTargets  codeAddress[ ] 相关的

3-3

SwitchData构造

TargetInsn构造

3-4

 addOutputSuffix

4.

visitThrowingCstInsn

4-1

SimpleInsn

CstInsn

5.

visitThrowingInsn

SimpleInsn

6.

visitFillArrayDataInsn

ArrayData构造

TargetInsn


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

上面总共提到 SimpleInsn TargetInsn CstInsn 三个指令构造函数 SwitchData ArrayData 两个数据构造函数

SimpleInsn

        super(opcode, position, registers); //FixedSizeInsn

TargetInsn

        比SimpleInsn多了个         this.target = target;

CstInsn

        比SimpleInsn多了 

        this.constant = constant;
        this.index = -1;
        this.classIndex = -1;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值