Search in sources :

Example 1 with ConcreteMethod

use of com.android.dx.cf.code.ConcreteMethod in project buck by facebook.

the class CfTranslator method processMethods.

/**
     * Processes the methods of the given class.
     *
     * @param context
     * @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);
                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 2 with ConcreteMethod

use of com.android.dx.cf.code.ConcreteMethod in project buck by facebook.

the class DotDumper method endParsingMember.

public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) {
    if (!(member instanceof Method)) {
        return;
    }
    if (!shouldDumpMethod(name)) {
        return;
    }
    ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true);
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    if (optimize) {
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        rmeth = Optimizer.optimize(rmeth, BaseDumper.computeParamWidth(meth, isStatic), isStatic, true, advice);
    }
    System.out.println("digraph " + name + "{");
    System.out.println("\tfirst -> n" + Hex.u2(rmeth.getFirstLabel()) + ";");
    BasicBlockList blocks = rmeth.getBlocks();
    int sz = blocks.size();
    for (int i = 0; i < sz; i++) {
        BasicBlock bb = blocks.get(i);
        int label = bb.getLabel();
        IntList successors = bb.getSuccessors();
        if (successors.size() == 0) {
            System.out.println("\tn" + Hex.u2(label) + " -> returns;");
        } else if (successors.size() == 1) {
            System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(successors.get(0)) + ";");
        } else {
            System.out.print("\tn" + Hex.u2(label) + " -> {");
            for (int j = 0; j < successors.size(); j++) {
                int successor = successors.get(j);
                if (successor != bb.getPrimarySuccessor()) {
                    System.out.print(" n" + Hex.u2(successor) + " ");
                }
            }
            System.out.println("};");
            System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(bb.getPrimarySuccessor()) + " [label=\"primary\"];");
        }
    }
    System.out.println("}");
}
Also used : RopMethod(com.android.dx.rop.code.RopMethod) ConcreteMethod(com.android.dx.cf.code.ConcreteMethod) BasicBlock(com.android.dx.rop.code.BasicBlock) 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) Method(com.android.dx.cf.iface.Method) BasicBlockList(com.android.dx.rop.code.BasicBlockList) IntList(com.android.dx.util.IntList)

Example 3 with ConcreteMethod

use of com.android.dx.cf.code.ConcreteMethod 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 4 with ConcreteMethod

use of com.android.dx.cf.code.ConcreteMethod 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)

Aggregations

ConcreteMethod (com.android.dx.cf.code.ConcreteMethod)4 Method (com.android.dx.cf.iface.Method)4 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)4 RopMethod (com.android.dx.rop.code.RopMethod)4 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)4 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 IntList (com.android.dx.util.IntList)2 BasicBlock (com.android.dx.rop.code.BasicBlock)1 BasicBlockList (com.android.dx.rop.code.BasicBlockList)1 Optimizer (com.android.dx.ssa.Optimizer)1 SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)1