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;
}
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);
}
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;
}
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);
}
}
}
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;
}
Aggregations