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