Search in sources :

Example 6 with InvokeSite

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

the class ConstantPoolReferenceFinder method findReferencedMembers.

/**
     * Find all referenced members in a class.
     * @param classInfo the class to search.
     * @param checkMembers if false, do not check fields and methods. Else check everything.
     * @return a set of class names and class member signatures found in the class.
     */
public static Set<String> findReferencedMembers(ClassInfo classInfo, boolean checkMembers) {
    // Else we need to go into details..
    Set<String> members = new HashSet<String>();
    ClassMemberVisitor visitor = new ClassMemberVisitor(members);
    JavaClass javaClass = classInfo.compile();
    Set<Integer> ids = findPoolReferences(classInfo, javaClass);
    List<InvokeSite> invokes = new ArrayList<InvokeSite>();
    if (checkMembers) {
        for (Field field : javaClass.getFields()) {
            FieldInfo fieldInfo = classInfo.getFieldInfo(field.getName());
            // add members found in the field
            visitor.visitField(fieldInfo);
            // there are no invokesites in a field, only add found ids
            ids.addAll(findPoolReferences(fieldInfo, field));
        }
        for (Method method : javaClass.getMethods()) {
            MethodInfo methodInfo = classInfo.getMethodInfo(method.getName() + method.getSignature());
            // add members found in the method
            visitor.visitMethod(methodInfo);
            // add all ids for checking, add all invoke sites
            ids.addAll(findPoolReferences(methodInfo, method));
        }
    }
    // fill the members list with all found constantpool references
    visitor.visitClass(classInfo);
    visitPoolReferences(classInfo, visitor, ids);
    return members;
}
Also used : ArrayList(java.util.ArrayList) ConstantString(org.apache.bcel.classfile.ConstantString) Method(org.apache.bcel.classfile.Method) EnclosingMethod(com.jopdesign.common.bcel.EnclosingMethod) ConstantInteger(org.apache.bcel.classfile.ConstantInteger) Field(org.apache.bcel.classfile.Field) JavaClass(org.apache.bcel.classfile.JavaClass) MethodInfo(com.jopdesign.common.MethodInfo) ConstantMethodInfo(com.jopdesign.common.type.ConstantMethodInfo) InvokeSite(com.jopdesign.common.code.InvokeSite) ConstantFieldInfo(com.jopdesign.common.type.ConstantFieldInfo) FieldInfo(com.jopdesign.common.FieldInfo) HashSet(java.util.HashSet)

Example 7 with InvokeSite

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

the class AppInfo method findImplementations.

/**
     * Find all methods which might get invoked for a given invokesite.
     * This uses the callgraph returned by {@link #getCallGraph()} to lookup possible implementations.
     * Use callgraph thinning to make the result of this method more precise.
     * If the callgraph has not yet been built by {@link #buildCallGraph(boolean)}, this uses
     * {@link #findImplementations(MethodRef)} to resolve virtual invocations.
     *
     * @param cs the callstring to the the invocation, including the given invokesite. Must not be empty.
     * @return a list of possible implementations for the invocation including native methods, or an empty set if resolution fails or is not safe.
     */
public Set<MethodInfo> findImplementations(CallString cs) {
    if (cs.length() == 0) {
        throw new AssertionError("findImplementations() called with empty callstring!");
    }
    InvokeSite invokeSite = cs.top();
    // callgraph is at least one, else we will get incorrect results
    if (!invokeSite.isVirtual()) {
        Set<MethodInfo> methods = new LinkedHashSet<MethodInfo>();
        MethodInfo method = invokeSite.getInvokeeRef().getMethodInfo();
        if (method == null) {
            return methods;
        }
        if (method.isAbstract()) {
            throw new JavaClassFormatError("Invokespecial calls abstract method " + invokeSite.getInvokeeRef());
        }
        methods.add(method);
        return methods;
    }
    if (callGraph == null) {
        // we do not have a callgraph, so just use typegraph info
        return findImplementations(invokeSite.getInvokeeRef());
    }
    if (!callGraph.containsMethod(invokeSite.getInvoker())) {
        if (logger.isTraceEnabled()) {
            logger.trace("Could not find method " + invokeSite.getInvoker() + " in the callgraph, falling back to typegraph");
        }
        return findImplementations(invokeSite.getInvokeeRef());
    }
    return callGraph.findImplementations(cs);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) JavaClassFormatError(com.jopdesign.common.misc.JavaClassFormatError) InvokeSite(com.jopdesign.common.code.InvokeSite)

Example 8 with InvokeSite

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

the class MethodCode method getInvokeSite.

/**
     * Get the InvokeSite for an instruction handle from the code of this method.
     * This does not check if the given instruction is an invoke instruction.
     *
     * @param ih an instruction handle from this code
     * @return the InvokeSite associated with this instruction or a new one.
     */
public InvokeSite getInvokeSite(InstructionHandle ih) {
    InvokeSite is = (InvokeSite) ih.getAttribute(KEY_INVOKESITE);
    if (is == null) {
        is = new InvokeSite(ih, this.getMethodInfo());
        ih.addAttribute(KEY_INVOKESITE, is);
    }
    return is;
}
Also used : InvokeSite(com.jopdesign.common.code.InvokeSite)

Example 9 with InvokeSite

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

the class ExecFrequencyAnalysis method updateChilds.

private void updateChilds(ExecutionContext context) {
    long ecCount = nodeCount.get(context);
    for (Map.Entry<InvokeSite, Set<ExecutionContext>> entry : callGraph.getChildsPerInvokeSite(context).entrySet()) {
        InvokeSite invokeSite = entry.getKey();
        long count = ecCount * getExecFrequency(context, invokeSite.getInstructionHandle());
        for (ExecutionContext child : entry.getValue()) {
            addExecCount(child, count);
        }
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) ExecutionContext(com.jopdesign.common.code.ExecutionContext) InvokeSite(com.jopdesign.common.code.InvokeSite) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 10 with InvokeSite

use of com.jopdesign.common.code.InvokeSite 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)

Aggregations

InvokeSite (com.jopdesign.common.code.InvokeSite)13 MethodInfo (com.jopdesign.common.MethodInfo)7 InstructionHandle (org.apache.bcel.generic.InstructionHandle)6 FieldInstruction (org.apache.bcel.generic.FieldInstruction)4 Instruction (org.apache.bcel.generic.Instruction)4 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)4 FieldInfo (com.jopdesign.common.FieldInfo)3 MethodCode (com.jopdesign.common.MethodCode)3 CallString (com.jopdesign.common.code.CallString)3 LinkedHashSet (java.util.LinkedHashSet)3 ConstantPushInstruction (org.apache.bcel.generic.ConstantPushInstruction)3 InstructionList (org.apache.bcel.generic.InstructionList)3 LocalVariableInstruction (org.apache.bcel.generic.LocalVariableInstruction)3 ExecutionContext (com.jopdesign.common.code.ExecutionContext)2 AppInfoError (com.jopdesign.common.misc.AppInfoError)2 FieldRef (com.jopdesign.common.type.FieldRef)2 MethodRef (com.jopdesign.common.type.MethodRef)2 ValueInfo (com.jopdesign.common.type.ValueInfo)2 ValueMapAnalysis (com.jopdesign.jcopter.analysis.ValueMapAnalysis)2 ArrayList (java.util.ArrayList)2