Search in sources :

Example 11 with RopMethod

use of com.android.dx.rop.code.RopMethod in project buck by facebook.

the class BlockDumper method ropDump.

/**
     * Does a registerizing dump.
     *
     * @param meth {@code non-null;} method data to dump
     */
private void ropDump(ConcreteMethod meth) {
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    BytecodeArray code = meth.getCode();
    ByteArray bytes = code.getBytes();
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    StringBuffer sb = new StringBuffer(2000);
    if (optimize) {
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        int paramWidth = computeParamWidth(meth, isStatic);
        rmeth = Optimizer.optimize(rmeth, paramWidth, isStatic, true, advice);
    }
    BasicBlockList blocks = rmeth.getBlocks();
    int[] order = blocks.getLabelsInOrder();
    sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n");
    for (int label : order) {
        BasicBlock bb = blocks.get(blocks.indexOfLabel(label));
        sb.append("block ");
        sb.append(Hex.u2(label));
        sb.append("\n");
        IntList preds = rmeth.labelToPredecessors(label);
        int psz = preds.size();
        for (int i = 0; i < psz; i++) {
            sb.append("  pred ");
            sb.append(Hex.u2(preds.get(i)));
            sb.append("\n");
        }
        InsnList il = bb.getInsns();
        int ilsz = il.size();
        for (int i = 0; i < ilsz; i++) {
            Insn one = il.get(i);
            sb.append("  ");
            sb.append(il.get(i).toHuman());
            sb.append("\n");
        }
        IntList successors = bb.getSuccessors();
        int ssz = successors.size();
        if (ssz == 0) {
            sb.append("  returns\n");
        } else {
            int primary = bb.getPrimarySuccessor();
            for (int i = 0; i < ssz; i++) {
                int succ = successors.get(i);
                sb.append("  next ");
                sb.append(Hex.u2(succ));
                if ((ssz != 1) && (succ == primary)) {
                    sb.append(" *");
                }
                sb.append("\n");
            }
        }
    }
    suppressDump = false;
    setAt(bytes, 0);
    parsed(bytes, 0, bytes.size(), sb.toString());
    suppressDump = true;
}
Also used : BytecodeArray(com.android.dx.cf.code.BytecodeArray) Insn(com.android.dx.rop.code.Insn) RopMethod(com.android.dx.rop.code.RopMethod) BasicBlock(com.android.dx.rop.code.BasicBlock) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) InsnList(com.android.dx.rop.code.InsnList) IntList(com.android.dx.util.IntList) ByteArray(com.android.dx.util.ByteArray) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 12 with RopMethod

use of com.android.dx.rop.code.RopMethod in project buck by facebook.

the class SsaDumper method endParsingMember.

/** {@inheritDoc} */
@Override
public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) {
    if (!(member instanceof Method)) {
        return;
    }
    if (!shouldDumpMethod(name)) {
        return;
    }
    if ((member.getAccessFlags() & (AccessFlags.ACC_ABSTRACT | AccessFlags.ACC_NATIVE)) != 0) {
        return;
    }
    ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true);
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    SsaMethod ssaMeth = null;
    boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
    int paramWidth = computeParamWidth(meth, isStatic);
    if (args.ssaStep == null) {
        ssaMeth = Optimizer.debugNoRegisterAllocation(rmeth, paramWidth, isStatic, true, advice, EnumSet.allOf(Optimizer.OptionalStep.class));
    } else if ("edge-split".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugEdgeSplit(rmeth, paramWidth, isStatic, true, advice);
    } else if ("phi-placement".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugPhiPlacement(rmeth, paramWidth, isStatic, true, advice);
    } else if ("renaming".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugRenaming(rmeth, paramWidth, isStatic, true, advice);
    } else if ("dead-code".equals(args.ssaStep)) {
        ssaMeth = Optimizer.debugDeadCodeRemover(rmeth, paramWidth, isStatic, true, advice);
    }
    StringBuffer sb = new StringBuffer(2000);
    sb.append("first ");
    sb.append(Hex.u2(ssaMeth.blockIndexToRopLabel(ssaMeth.getEntryBlockIndex())));
    sb.append('\n');
    ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
    ArrayList<SsaBasicBlock> sortedBlocks = (ArrayList<SsaBasicBlock>) blocks.clone();
    Collections.sort(sortedBlocks, SsaBasicBlock.LABEL_COMPARATOR);
    for (SsaBasicBlock block : sortedBlocks) {
        sb.append("block ").append(Hex.u2(block.getRopLabel())).append('\n');
        BitSet preds = block.getPredecessors();
        for (int i = preds.nextSetBit(0); i >= 0; i = preds.nextSetBit(i + 1)) {
            sb.append("  pred ");
            sb.append(Hex.u2(ssaMeth.blockIndexToRopLabel(i)));
            sb.append('\n');
        }
        sb.append("  live in:" + block.getLiveInRegs());
        sb.append("\n");
        for (SsaInsn insn : block.getInsns()) {
            sb.append("  ");
            sb.append(insn.toHuman());
            sb.append('\n');
        }
        if (block.getSuccessors().cardinality() == 0) {
            sb.append("  returns\n");
        } else {
            int primary = block.getPrimarySuccessorRopLabel();
            IntList succLabelList = block.getRopLabelSuccessorList();
            int szSuccLabels = succLabelList.size();
            for (int i = 0; i < szSuccLabels; i++) {
                sb.append("  next ");
                sb.append(Hex.u2(succLabelList.get(i)));
                if (szSuccLabels != 1 && primary == succLabelList.get(i)) {
                    sb.append(" *");
                }
                sb.append('\n');
            }
        }
        sb.append("  live out:" + block.getLiveOutRegs());
        sb.append("\n");
    }
    suppressDump = false;
    setAt(bytes, 0);
    parsed(bytes, 0, bytes.size(), sb.toString());
    suppressDump = true;
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod) Optimizer(com.android.dx.ssa.Optimizer) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) SsaMethod(com.android.dx.ssa.SsaMethod) Method(com.android.dx.cf.iface.Method) IntList(com.android.dx.util.IntList) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) SsaMethod(com.android.dx.ssa.SsaMethod) SsaInsn(com.android.dx.ssa.SsaInsn)

Example 13 with RopMethod

use of com.android.dx.rop.code.RopMethod in project J2ME-Loader by nikita36078.

the class CfTranslator method processMethods.

/**
 * Processes the methods of the given class.
 *
 * @param context {@code non-null;} the state global to this invocation.
 * @param cf {@code non-null;} class being translated
 * @param cfOptions {@code non-null;} options for class translation
 * @param dexOptions {@code non-null;} options for dex output
 * @param out {@code non-null;} output class
 * @param dexFile {@code non-null;} dex output
 */
private static void processMethods(DxContext context, DirectClassFile cf, CfOptions cfOptions, DexOptions dexOptions, ClassDefItem out, DexFile dexFile) {
    CstType thisClass = cf.getThisClass();
    MethodList methods = cf.getMethods();
    int sz = methods.size();
    for (int i = 0; i < sz; i++) {
        Method one = methods.get(i);
        try {
            CstMethodRef meth = new CstMethodRef(thisClass, one.getNat());
            int accessFlags = one.getAccessFlags();
            boolean isStatic = AccessFlags.isStatic(accessFlags);
            boolean isPrivate = AccessFlags.isPrivate(accessFlags);
            boolean isNative = AccessFlags.isNative(accessFlags);
            boolean isAbstract = AccessFlags.isAbstract(accessFlags);
            boolean isConstructor = meth.isInstanceInit() || meth.isClassInit();
            DalvCode code;
            if (isNative || isAbstract) {
                // There's no code for native or abstract methods.
                code = null;
            } else {
                ConcreteMethod concrete = new ConcreteMethod(one, cf, (cfOptions.positionInfo != PositionList.NONE), cfOptions.localInfo);
                TranslationAdvice advice;
                advice = DexTranslationAdvice.THE_ONE;
                RopMethod rmeth = Ropper.convert(concrete, advice, methods, dexOptions);
                RopMethod nonOptRmeth = null;
                int paramSize;
                paramSize = meth.getParameterWordCount(isStatic);
                String canonicalName = thisClass.getClassType().getDescriptor() + "." + one.getName().getString();
                if (cfOptions.optimize && context.optimizerOptions.shouldOptimize(canonicalName)) {
                    if (DEBUG) {
                        System.err.println("Optimizing " + canonicalName);
                    }
                    nonOptRmeth = rmeth;
                    rmeth = Optimizer.optimize(rmeth, paramSize, isStatic, cfOptions.localInfo, advice);
                    if (DEBUG) {
                        context.optimizerOptions.compareOptimizerStep(nonOptRmeth, paramSize, isStatic, cfOptions, advice, rmeth);
                    }
                    if (cfOptions.statistics) {
                        context.codeStatistics.updateRopStatistics(nonOptRmeth, rmeth);
                    }
                }
                LocalVariableInfo locals = null;
                if (cfOptions.localInfo) {
                    locals = LocalVariableExtractor.extract(rmeth);
                }
                code = RopTranslator.translate(rmeth, cfOptions.positionInfo, locals, paramSize, dexOptions);
                if (cfOptions.statistics && nonOptRmeth != null) {
                    updateDexStatistics(context, cfOptions, dexOptions, rmeth, nonOptRmeth, locals, paramSize, concrete.getCode().size());
                }
            }
            // Preserve the synchronized flag as its "declared" variant...
            if (AccessFlags.isSynchronized(accessFlags)) {
                accessFlags |= AccessFlags.ACC_DECLARED_SYNCHRONIZED;
                /*
                     * ...but only native methods are actually allowed to be
                     * synchronized.
                     */
                if (!isNative) {
                    accessFlags &= ~AccessFlags.ACC_SYNCHRONIZED;
                }
            }
            if (isConstructor) {
                accessFlags |= AccessFlags.ACC_CONSTRUCTOR;
            }
            TypeList exceptions = AttributeTranslator.getExceptions(one);
            EncodedMethod mi = new EncodedMethod(meth, accessFlags, code, exceptions);
            if (meth.isInstanceInit() || meth.isClassInit() || isStatic || isPrivate) {
                out.addDirectMethod(mi);
            } else {
                out.addVirtualMethod(mi);
            }
            Annotations annotations = AttributeTranslator.getMethodAnnotations(one);
            if (annotations.size() != 0) {
                out.addMethodAnnotations(meth, annotations, dexFile);
            }
            AnnotationsList list = AttributeTranslator.getParameterAnnotations(one);
            if (list.size() != 0) {
                out.addParameterAnnotations(meth, list, dexFile);
            }
            dexFile.getMethodIds().intern(meth);
        } catch (RuntimeException ex) {
            String msg = "...while processing " + one.getName().toHuman() + " " + one.getDescriptor().toHuman();
            throw ExceptionWithContext.withContext(ex, msg);
        }
    }
}
Also used : DalvCode(com.android.dx.dex.code.DalvCode) RopMethod(com.android.dx.rop.code.RopMethod) AnnotationsList(com.android.dx.rop.annotation.AnnotationsList) MethodList(com.android.dx.cf.iface.MethodList) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) EncodedMethod(com.android.dx.dex.file.EncodedMethod) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) RopMethod(com.android.dx.rop.code.RopMethod) Method(com.android.dx.cf.iface.Method) CstString(com.android.dx.rop.cst.CstString) CstMethodRef(com.android.dx.rop.cst.CstMethodRef) LocalVariableInfo(com.android.dx.rop.code.LocalVariableInfo) Annotations(com.android.dx.rop.annotation.Annotations) EncodedMethod(com.android.dx.dex.file.EncodedMethod) CstType(com.android.dx.rop.cst.CstType) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) TypeList(com.android.dx.rop.type.TypeList)

Example 14 with RopMethod

use of com.android.dx.rop.code.RopMethod in project J2ME-Loader by nikita36078.

the class OptimizerOptions method compareOptimizerStep.

/**
 * Compares the output of the optimizer run normally with a run skipping
 * some optional steps. Results are printed to stderr.
 *
 * @param nonOptRmeth {@code non-null;} origional rop method
 * @param paramSize {@code >= 0;} parameter size of method
 * @param isStatic true if this method has no 'this' pointer argument.
 * @param args {@code non-null;} translator arguments
 * @param advice {@code non-null;} translation advice
 * @param rmeth {@code non-null;} method with all optimization steps run.
 */
public void compareOptimizerStep(RopMethod nonOptRmeth, int paramSize, boolean isStatic, CfOptions args, TranslationAdvice advice, RopMethod rmeth) {
    EnumSet<Optimizer.OptionalStep> steps;
    steps = EnumSet.allOf(Optimizer.OptionalStep.class);
    // This is the step to skip.
    steps.remove(Optimizer.OptionalStep.CONST_COLLECTOR);
    RopMethod skipRopMethod = Optimizer.optimize(nonOptRmeth, paramSize, isStatic, args.localInfo, advice, steps);
    int normalInsns = rmeth.getBlocks().getEffectiveInstructionCount();
    int skipInsns = skipRopMethod.getBlocks().getEffectiveInstructionCount();
    System.err.printf("optimize step regs:(%d/%d/%.2f%%)" + " insns:(%d/%d/%.2f%%)\n", rmeth.getBlocks().getRegCount(), skipRopMethod.getBlocks().getRegCount(), 100.0 * ((skipRopMethod.getBlocks().getRegCount() - rmeth.getBlocks().getRegCount()) / (float) skipRopMethod.getBlocks().getRegCount()), normalInsns, skipInsns, 100.0 * ((skipInsns - normalInsns) / (float) skipInsns));
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod)

Example 15 with RopMethod

use of com.android.dx.rop.code.RopMethod in project J2ME-Loader by nikita36078.

the class Ropper method getRopMethod.

/**
 * Extracts the resulting {@link RopMethod} from the instance.
 *
 * @return {@code non-null;} the method object
 */
private RopMethod getRopMethod() {
    // Construct the final list of blocks.
    int sz = result.size();
    BasicBlockList bbl = new BasicBlockList(sz);
    for (int i = 0; i < sz; i++) {
        bbl.set(i, result.get(i));
    }
    bbl.setImmutable();
    /*
         * Note: The parameter assignment block is always the first
         * that should be executed, hence the second argument to the
         * constructor.
         */
    return new RopMethod(bbl, getSpecialLabel(PARAM_ASSIGNMENT));
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Aggregations

RopMethod (com.android.dx.rop.code.RopMethod)17 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)5 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)5 IntList (com.android.dx.util.IntList)5 ConcreteMethod (com.android.dx.cf.code.ConcreteMethod)4 Method (com.android.dx.cf.iface.Method)4 BasicBlock (com.android.dx.rop.code.BasicBlock)4 BasicBlockList (com.android.dx.rop.code.BasicBlockList)4 BitSet (java.util.BitSet)3 MethodList (com.android.dx.cf.iface.MethodList)2 DalvCode (com.android.dx.dex.code.DalvCode)2 EncodedMethod (com.android.dx.dex.file.EncodedMethod)2 Annotations (com.android.dx.rop.annotation.Annotations)2 AnnotationsList (com.android.dx.rop.annotation.AnnotationsList)2 LocalVariableInfo (com.android.dx.rop.code.LocalVariableInfo)2 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)2 CstString (com.android.dx.rop.cst.CstString)2 CstType (com.android.dx.rop.cst.CstType)2 TypeList (com.android.dx.rop.type.TypeList)2 BasicRegisterMapper (com.android.dx.ssa.BasicRegisterMapper)2