Search in sources :

Example 26 with MethodInfo

use of com.jopdesign.common.MethodInfo in project jop by jop-devel.

the class SimpleInliner method performSimpleInline.

/**
     * Try to inline a simple getter, wrapper or stub method.
     * <p>
     * If the inlined code is again an invoke, the InvokeSite does not change because
     * the InstructionHandle of the invoker's invoke is kept.</p>
     *
     * @param invokeSite the invoke to replace.
     * @param invokee the method to inline.
     * @param inlineData the parameters of the invokee and the code to inline.
     * @return true if inlining has been performed.
     */
private InvokeSite performSimpleInline(InvokeSite invokeSite, MethodInfo invokee, InlineData inlineData) {
    MethodInfo invoker = invokeSite.getInvoker();
    MethodCode invokerCode = invoker.getCode();
    if (logger.isDebugEnabled()) {
        logger.debug("Inlining at " + invokeSite + " using " + invokee);
    }
    // Prepare code for the actual inlining
    helper.prepareInlining(invoker, invokee);
    InstructionHandle invoke = invokeSite.getInstructionHandle();
    // Perform inlining: update the prologue
    if (inlineData.getOldPrologueLength() > 0) {
        InstructionHandle start = invoke;
        for (int i = 0; i < inlineData.getOldPrologueLength(); i++) {
            start = start.getPrev();
        }
        // invokeSite is not a target in this case, no need to worry about targets here
        invokerCode.replace(start, inlineData.getOldPrologueLength(), inlineData.getPrologue(), false);
    } else if (inlineData.getPrologue().getLength() > 0) {
        // old-prologue is empty, invokeSite may be a target.. Need to update the targets to the new prologue
        if (invoke.hasTargeters()) {
            invokerCode.retarget(invoke, inlineData.getPrologue().getStart());
        }
        InstructionList il = invokerCode.getInstructionList();
        il.insert(invoke, inlineData.getPrologue());
    }
    // Replace the invoke
    MethodCode invokeeCode = invokee.getCode();
    InstructionList il = invokeeCode.getInstructionList();
    InstructionHandle start = invokeeCode.getInstructionHandle(inlineData.getInlineStart());
    int cnt = il.getLength() - inlineData.getInlineStart();
    if (il.getEnd().getInstruction() instanceof ReturnInstruction) {
        // do not inline the return
        cnt--;
    }
    InstructionHandle end = invokerCode.replace(invoke, 1, invokee, start, cnt, true);
    // the invokee
    if (cnt > 0) {
        InstructionHandle ih = end;
        for (int i = 0; i < cnt; i++) {
            ih = ih.getPrev();
        }
        invokerCode.setLineNumber(ih, invokeeCode.getSourceClassInfo(start), invokeeCode.getLineNumber(start));
    }
    // insert epilogue
    invokerCode.getInstructionList().insert(end, inlineData.getEpilogue());
    // If we inlined another invokesite, find the new invokesite and return it
    if (inlineData.getInvokeSite() != null) {
        end = end.getPrev();
        // search backwards from last inlined instruction
        while (end != null) {
            if (invokerCode.isInvokeSite(end)) {
                return invokerCode.getInvokeSite(end);
            }
            end = end.getPrev();
        }
    }
    return null;
}
Also used : ReturnInstruction(org.apache.bcel.generic.ReturnInstruction) InstructionList(org.apache.bcel.generic.InstructionList) MethodInfo(com.jopdesign.common.MethodInfo) MethodCode(com.jopdesign.common.MethodCode) InstructionHandle(org.apache.bcel.generic.InstructionHandle)

Example 27 with MethodInfo

use of com.jopdesign.common.MethodInfo in project jop by jop-devel.

the class SimpleInliner method optimizeMethod.

@Override
public void optimizeMethod(MethodInfo method) {
    InlineData inlineData = new InlineData();
    List<InvokeSite> invokes = new ArrayList<InvokeSite>(method.getCode().getInvokeSites());
    // we iterate over the invoke sites in a sorted order for the single reason that the DFA cache hack works
    // (else the order of the entries in the constantpool can differ)
    Collections.sort(invokes, new Comparator<InvokeSite>() {

        @Override
        public int compare(InvokeSite o1, InvokeSite o2) {
            return o1.getInstructionHandle().getPosition() - o2.getInstructionHandle().getPosition();
        }
    });
    for (InvokeSite invoke : invokes) {
        // The callstring contains 'original' invokesites from the unmodified callgraph,
        // 'invoke' refers to the new invokesite in the modified code
        CallString cs = new CallString(invoke);
        while (invoke != null) {
            countInvokeSites++;
            MethodInfo invokee = helper.devirtualize(cs);
            if (invokee == null)
                break;
            countDevirtualized++;
            // Preliminary checks
            if (checkInvoke(invoke, cs, invokee, inlineData)) {
                invoke = performSimpleInline(invoke, invokee, inlineData);
                inlineCounter++;
                if (inlineData.getInvokeSite() != null) {
                    cs.push(inlineData.getInvokeSite());
                } else {
                    break;
                }
            } else {
                break;
            }
        }
    }
// update callgraph (?) If we update the callgraph, the callstrings become invalid!
// -> update callgraph only after we finished inlining of a toplevel invokesite;
//    collect all invokesites to collapse into toplevel invokesite;
//    replace old invokesite with invokesites from inlined code, add edges to not inlined methods
// We could collect all nodes to merge and call callgraph.merge(), but this is not yet implemented.
// Instead we simply rebuild the whole callgraph and all results which use callstrings.
}
Also used : ArrayList(java.util.ArrayList) MethodInfo(com.jopdesign.common.MethodInfo) InvokeSite(com.jopdesign.common.code.InvokeSite) CallString(com.jopdesign.common.code.CallString)

Example 28 with MethodInfo

use of com.jopdesign.common.MethodInfo in project jop by jop-devel.

the class DFACallgraphBuilder method getInvokedMethods.

@Override
protected Set<MethodInfo> getInvokedMethods(ExecutionContext context, InvokeSite invokeSite) {
    // to avoid problems we only use the DFA for virtual calls, all other can be uniquely resolved anyway.
    if (!invokeSite.isVirtual()) {
        return Collections.singleton(invokeSite.getInvokeeRef().getMethodInfo());
    }
    Set<String> receivers = dfaTool.getReceivers(invokeSite.getInstructionHandle(), context.getCallString());
    if (receivers == null) {
        // This can happen e.g. because we have all Runnable.run() methods as roots, regardless if they are used
        logger.debug("No receivers for " + invokeSite.getInvokeeRef() + " at " + invokeSite + " in call context " + context.getCallString().toStringVerbose(false));
        return appInfo.findImplementations(invokeSite, context.getCallString());
    }
    if (receivers.size() == 0) {
        // This can happen if a method is analyzed for some contexts but not for this context
        logger.debug("No receivers for " + invokeSite.getInvokeeRef() + " at " + invokeSite + " in call context " + context.getCallString().toStringVerbose(false));
        return appInfo.findImplementations(invokeSite, context.getCallString());
    }
    Set<MethodInfo> methods = new LinkedHashSet<MethodInfo>(receivers.size());
    for (String rcv : receivers) {
        MemberID mId = MemberID.parse(rcv);
        methods.add(appInfo.getMethodRef(mId).getMethodInfo());
    }
    return methods;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) MemberID(com.jopdesign.common.type.MemberID) MethodInfo(com.jopdesign.common.MethodInfo)

Example 29 with MethodInfo

use of com.jopdesign.common.MethodInfo in project jop by jop-devel.

the class PhaseExecutor method removeDebugAttributes.

public void removeDebugAttributes() {
    logger.info("Starting removal of debug attributes");
    MethodVisitor visitor = new MethodVisitor() {

        @Override
        public void visitMethod(MethodInfo method) {
            method.getCode().removeDebugAttributes();
        }
    };
    appInfo.iterate(new MethodTraverser(visitor, true));
    logger.info("Finished removal of debug attributes");
}
Also used : MethodTraverser(com.jopdesign.common.graphutils.MethodTraverser) MethodInfo(com.jopdesign.common.MethodInfo) MethodVisitor(com.jopdesign.common.graphutils.MethodTraverser.MethodVisitor)

Example 30 with MethodInfo

use of com.jopdesign.common.MethodInfo in project jop by jop-devel.

the class ExecFrequencyAnalysis method getExecFrequency.

public long getExecFrequency(ExecutionContext context, InstructionHandle ih) {
    MethodInfo method = context.getMethodInfo();
    // By loading the CFG, loopbounds are attached to the blocks if the WCA tool is loaded
    ControlFlowGraph cfg = method.getCode().getControlFlowGraph(false);
    LoopColoring<CFGNode, CFGEdge> lc = cfg.getLoopColoring();
    BasicBlockNode node = cfg.getHandleNode(ih, true);
    if (node == null) {
        // THIS IS UNSAFE! but what can you do ...
        return 1;
    }
    long ef = 1;
    for (CFGNode hol : lc.getLoopColor(node)) {
        LoopBound lb = hol.getLoopBound();
        if (lb != null) {
            if (lb.isDefaultBound() && !analyses.isWCAMethod(method)) {
                ef *= DEFAULT_ACET_LOOP_BOUND;
            } else {
                ef *= lb.getUpperBound(context);
            }
        } else {
            ef *= DEFAULT_ACET_LOOP_BOUND;
        }
    }
    return ef;
}
Also used : CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) BasicBlockNode(com.jopdesign.common.code.ControlFlowGraph.BasicBlockNode) LoopBound(com.jopdesign.common.code.LoopBound) ControlFlowGraph(com.jopdesign.common.code.ControlFlowGraph) MethodInfo(com.jopdesign.common.MethodInfo) CFGEdge(com.jopdesign.common.code.ControlFlowGraph.CFGEdge)

Aggregations

MethodInfo (com.jopdesign.common.MethodInfo)108 LinkedHashSet (java.util.LinkedHashSet)21 InstructionHandle (org.apache.bcel.generic.InstructionHandle)20 ClassInfo (com.jopdesign.common.ClassInfo)19 ExecutionContext (com.jopdesign.common.code.ExecutionContext)16 CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)13 ArrayList (java.util.ArrayList)13 CallString (com.jopdesign.common.code.CallString)12 ControlFlowGraph (com.jopdesign.common.code.ControlFlowGraph)12 HashMap (java.util.HashMap)10 Set (java.util.Set)10 LinkedHashMap (java.util.LinkedHashMap)9 Instruction (org.apache.bcel.generic.Instruction)9 FieldInfo (com.jopdesign.common.FieldInfo)8 MethodCode (com.jopdesign.common.MethodCode)8 AppInfo (com.jopdesign.common.AppInfo)7 ContextEdge (com.jopdesign.common.code.CallGraph.ContextEdge)7 InvokeSite (com.jopdesign.common.code.InvokeSite)7 MemberID (com.jopdesign.common.type.MemberID)7 Context (com.jopdesign.dfa.framework.Context)7