Search in sources :

Example 16 with AppInfoError

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

the class InvokeDot method runDot.

public void runDot(File dotFile, File imageFile) throws IOException {
    byte[] md5;
    try {
        md5 = calculateMD5(dotFile);
    } catch (NoSuchAlgorithmException e) {
        throw new AppInfoError("Unexpected exception: MD5 Algorithm not available", e);
    }
    if (cacheDir != null) {
        File cachedFile = getCacheFile(byteArrayToString(md5) + ".png");
        if (!cachedFile.exists()) {
            runDot(dotFile, cachedFile, format);
        }
        copyFile(cachedFile, imageFile);
    } else {
        runDot(dotFile, imageFile, format);
    }
}
Also used : NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) File(java.io.File) AppInfoError(com.jopdesign.common.misc.AppInfoError)

Example 17 with AppInfoError

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

the class PhaseExecutor method dumpCallgraph.

/////////////////////////////////////////////////////////////////////////////////////
// Dump Callgraph
/////////////////////////////////////////////////////////////////////////////////////
public void dumpCallgraph(String graphName) {
    if (getDebugConfig().getOption(DUMP_CALLGRAPH) == CallGraph.DUMPTYPE.off && getDebugConfig().getOption(DUMP_JVM_CALLGRAPH) == CallGraph.DUMPTYPE.off) {
        return;
    }
    try {
        // Dumping the full graph is a bit much, we split it into several graphs
        Set<ExecutionContext> appRoots = new LinkedHashSet<ExecutionContext>();
        Set<ExecutionContext> jvmRoots = new LinkedHashSet<ExecutionContext>();
        Set<ExecutionContext> clinitRoots = new LinkedHashSet<ExecutionContext>();
        Set<String> jvmClasses = new LinkedHashSet<String>();
        if (appInfo.getProcessorModel() != null) {
            jvmClasses.addAll(appInfo.getProcessorModel().getJVMClasses());
            jvmClasses.addAll(appInfo.getProcessorModel().getNativeClasses());
        }
        CallGraph graph = appInfo.getCallGraph();
        for (ExecutionContext ctx : graph.getRootNodes()) {
            if (ctx.getMethodInfo().getMethodSignature().equals(ClinitOrder.clinitSig)) {
                clinitRoots.add(ctx);
            } else if (jvmClasses.contains(ctx.getMethodInfo().getClassName())) {
                jvmRoots.add(ctx);
            } else if (appInfo.isJVMThread(ctx.getMethodInfo().getClassInfo())) {
                // This is to add Runnables like Scheduler and RtThread to the JVM classes.
                jvmRoots.add(ctx);
            } else {
                appRoots.add(ctx);
            }
        }
        OptionGroup debug = getDebugConfig();
        // TODO to keep the CG size down, we could add options to exclude methods (like '<init>') or packages
        // from dumping and skip dumping methods reachable only over excluded methods
        graph.dumpCallgraph(getConfig(), graphName, "app", appRoots, debug.getOption(DUMP_CALLGRAPH), false);
        graph.dumpCallgraph(getConfig(), graphName, "clinit", clinitRoots, debug.getOption(DUMP_CALLGRAPH), false);
        graph.dumpCallgraph(getConfig(), graphName, "jvm", jvmRoots, debug.getOption(DUMP_JVM_CALLGRAPH), !debug.getOption(DUMP_NOIM_CALLS));
    } catch (IOException e) {
        throw new AppInfoError("Unable to export to .dot file", e);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) ExecutionContext(com.jopdesign.common.code.ExecutionContext) OptionGroup(com.jopdesign.common.config.OptionGroup) CallGraph(com.jopdesign.common.code.CallGraph) IOException(java.io.IOException) AppInfoError(com.jopdesign.common.misc.AppInfoError)

Example 18 with AppInfoError

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

the class MethodCacheAnalysis method getAllFitChangeCosts.

private long getAllFitChangeCosts(ExecFrequencyProvider ecp, CodeModification modification, int deltaBlocks) {
    if (analysisType == AnalysisType.ALWAYS_HIT || analysisType == AnalysisType.ALWAYS_MISS) {
        return 0;
    }
    int deltaBytes = modification.getDeltaLocalCodesize();
    MethodInfo method = modification.getMethod();
    // for ALWAYS_MISS_HIT oder MOST_ONCE we need to find out what has changed for all-fit
    Set<MethodInfo> changes = findClassificationChanges(method, deltaBlocks, modification.getRemovedInvokees(), false);
    AppInfo appInfo = AppInfo.getSingleton();
    // In all nodes where we have changes, we need to sum up the new costs
    long deltaCosts = 0;
    for (MethodInfo node : changes) {
        // but all invokes in the method are now no longer always-hit/-miss
        for (InvokeSite invokeSite : node.getCode().getInvokeSites()) {
            // Note: this is very similar to getInvokeReturnCacheCosts(invokeSite), but we cannot use
            //       this here, because that method uses allFit and does not honor our 'virtual' codesize change
            int size = 0;
            for (MethodInfo impl : appInfo.findImplementations(invokeSite)) {
                size = Math.max(size, getMethodSize(impl));
            }
            size = MiscUtils.bytesToWords(size);
            int sizeInvoker = getMethodSize(invokeSite.getInvoker());
            sizeInvoker = MiscUtils.bytesToWords(sizeInvoker);
            long invokeCosts = cache.getMissPenaltyOnInvoke(size, invokeSite.getInvokeInstruction());
            long returnCosts = cache.getMissPenaltyOnReturn(sizeInvoker, invokeSite.getInvokeeRef().getDescriptor().getType());
            long count = ecp.getExecCount(invokeSite);
            if (analysisType == AnalysisType.ALL_FIT_REGIONS) {
                // for this analysis we already have one miss in the original cost estimation
                count--;
            }
            deltaCosts += count * (invokeCosts + returnCosts);
        }
    }
    // if the code increased, the classification changed from always-hit to always-miss ..
    long costs = deltaBytes > 0 ? deltaCosts : -deltaCosts;
    if (analysisType == AnalysisType.ALL_FIT_REGIONS) {
        // find out how many additional persistent cache misses we have
        // find out border of new all-fit region
        Map<MethodInfo, Integer> deltaExec = new LinkedHashMap<MethodInfo, Integer>();
        int deltaCount = 0;
        Set<ExecutionContext> border = new LinkedHashSet<ExecutionContext>();
        if (deltaBlocks < 0) {
            throw new AppInfoError("Not implemented");
        } else {
            for (MethodInfo miss : changes) {
                for (ExecutionContext context : callGraph.getNodes(miss)) {
                    for (ExecutionContext invokee : callGraph.getChildren(context)) {
                        // not all-fit if in changeset
                        if (changes.contains(invokee.getMethodInfo()))
                            continue;
                        // we ignore native stuff
                        if (invokee.getMethodInfo().isNative())
                            continue;
                        // invokee is all-fit
                        if (border.add(invokee)) {
                            deltaCount += ecp.getExecCount(invokee);
                        }
                    }
                }
            }
            // remove old miss count
            deltaCount -= getPersistentMisses(ecp, border);
        }
        // TODO this is not quite correct: instead of joining the reachable sets and multiplying
        //  with the delta count for the whole region, we should:
        //  - for every node in the reachable sets of the new border, sum up exec-counts of border nodes
        //    which contain that node in the reachable set
        //  - for every node in the reachable sets of the old border, subtract the exec counts of those border nodes
        //  - sum up invoke miss costs times calculates delta counts per node
        // find out cache miss costs of new all-fit region
        int regionCosts = 0;
        Set<MethodInfo> visited = new LinkedHashSet<MethodInfo>();
        for (ExecutionContext context : border) {
            for (MethodInfo reachable : reachableMethods.get(context)) {
                if (visited.add(reachable)) {
                    regionCosts += cache.getMissPenalty(reachable.getCode().getNumberOfWords(), cache.isLRU());
                }
            }
        }
        costs += deltaCount * regionCosts;
    }
    return costs;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) AppInfoError(com.jopdesign.common.misc.AppInfoError) AppInfo(com.jopdesign.common.AppInfo) LinkedHashMap(java.util.LinkedHashMap) ExecutionContext(com.jopdesign.common.code.ExecutionContext) MethodInfo(com.jopdesign.common.MethodInfo) InvokeSite(com.jopdesign.common.code.InvokeSite)

Example 19 with AppInfoError

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

the class LoopBounds method handleNative.

@SuppressWarnings({ "LiteralAsArgToStringEquals" })
private Map<CallString, Map<Location, ValueMapping>> handleNative(MethodInfo method, Context context, Map<CallString, Map<Location, ValueMapping>> input, Map<CallString, Map<Location, ValueMapping>> result) {
    String methodId = method.getMemberID().toString();
    Map<Location, ValueMapping> in = input.get(context.callString);
    Map<Location, ValueMapping> out = new LinkedHashMap<Location, ValueMapping>();
    if (methodId.equals("com.jopdesign.sys.Native#rd(I)I") || methodId.equals("com.jopdesign.sys.Native#rdMem(I)I") || methodId.equals("com.jopdesign.sys.Native#rdIntMem(I)I") || methodId.equals("com.jopdesign.sys.Native#getStatic(I)I")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr - 1) {
                out.put(l, in.get(l));
            }
        }
        out.put(new Location(context.stackPtr - 1), new ValueMapping());
    } else if (methodId.equals("com.jopdesign.sys.Native#wr(II)V") || methodId.equals("com.jopdesign.sys.Native#wrMem(II)V") || methodId.equals("com.jopdesign.sys.Native#wrIntMem(II)V") || methodId.equals("com.jopdesign.sys.Native#putStatic(II)V") || methodId.equals("com.jopdesign.sys.Native#toLong(D)J") || methodId.equals("com.jopdesign.sys.Native#toDouble(J)D")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr - 2) {
                out.put(l, in.get(l));
            }
        }
    } else if (methodId.equals("com.jopdesign.sys.Native#toInt(Ljava/lang/Object;)I") || methodId.equals("com.jopdesign.sys.Native#toInt(F)I")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr - 1) {
                out.put(l, in.get(l));
            }
        }
        out.put(new Location(context.stackPtr - 1), new ValueMapping());
    } else if (methodId.equals("com.jopdesign.sys.Native#toObject(I)Ljava/lang/Object;") || methodId.equals("com.jopdesign.sys.Native#toIntArray(I)[I") || methodId.equals("com.jopdesign.sys.Native#toFloat(I)F")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr - 1) {
                out.put(l, in.get(l));
            }
        }
    } else if (methodId.equals("com.jopdesign.sys.Native#getSP()I")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr) {
                out.put(l, in.get(l));
            }
        }
        out.put(new Location(context.stackPtr), new ValueMapping());
    } else if (methodId.equals("com.jopdesign.sys.Native#toInt(Ljava/lang/Object;)I")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr - 1) {
                out.put(l, in.get(l));
            }
        }
        out.put(new Location(context.stackPtr - 1), new ValueMapping());
    } else if (methodId.equals("com.jopdesign.sys.Native#condMove(IIZ)I") || methodId.equals("com.jopdesign.sys.Native#condMoveRef(Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;") || methodId.equals("com.jopdesign.sys.Native#memCopy(III)V")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr - 3) {
                out.put(l, in.get(l));
            }
        }
    } else if (methodId.equals("com.jopdesign.sys.Native#invalidate()V")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr) {
                out.put(l, in.get(l));
            }
        }
    } else if (methodId.equals("com.jopdesign.sys.Native#arrayLength(I)I") || methodId.equals("com.jopdesign.sys.Native#invoke(I)V")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr - 1) {
                out.put(l, in.get(l));
            }
        }
    } else if (methodId.equals("com.jopdesign.sys.Native#invoke(II)V")) {
        for (Location l : in.keySet()) {
            if (l.stackLoc < context.stackPtr - 2) {
                out.put(l, in.get(l));
            }
        }
    } else {
        AppInfoError ex = new AppInfoError("Unknown native method: " + methodId);
        logger.error(ex);
        throw ex;
    }
    result.put(context.callString, out);
    return result;
}
Also used : CallString(com.jopdesign.common.code.CallString) AppInfoError(com.jopdesign.common.misc.AppInfoError) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

AppInfoError (com.jopdesign.common.misc.AppInfoError)19 MethodInfo (com.jopdesign.common.MethodInfo)6 LinkedHashSet (java.util.LinkedHashSet)6 CallString (com.jopdesign.common.code.CallString)5 IOException (java.io.IOException)5 ExecutionContext (com.jopdesign.common.code.ExecutionContext)3 File (java.io.File)3 FileNotFoundException (java.io.FileNotFoundException)3 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)3 ClassInfo (com.jopdesign.common.ClassInfo)2 CFGEdge (com.jopdesign.common.code.ControlFlowGraph.CFGEdge)2 CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)2 InvokeSite (com.jopdesign.common.code.InvokeSite)2 LoopBound (com.jopdesign.common.code.LoopBound)2 FieldRef (com.jopdesign.common.type.FieldRef)2 MethodRef (com.jopdesign.common.type.MethodRef)2 DFATool (com.jopdesign.dfa.DFATool)2 Context (com.jopdesign.dfa.framework.Context)2 ContextMap (com.jopdesign.dfa.framework.ContextMap)2 BufferedReader (java.io.BufferedReader)2