use of com.jopdesign.dfa.framework.Context in project jop by jop-devel.
the class LoopBounds method doInvoke.
private void doInvoke(String methodName, InstructionHandle stmt, Context context, Map<CallString, Map<Location, ValueMapping>> input, Interpreter<CallString, Map<Location, ValueMapping>> interpreter, Map<InstructionHandle, ContextMap<CallString, Map<Location, ValueMapping>>> state, Map<CallString, Map<Location, ValueMapping>> result) {
DFATool p = interpreter.getDFATool();
MethodInfo method = p.getMethod(methodName);
if (method.isNative()) {
handleNative(method, context, input, result);
} else {
// set up new context
int varPtr = context.stackPtr - MethodHelper.getArgSize(method);
Context c = new Context(context);
c.stackPtr = method.getCode().getMaxLocals();
if (method.isSynchronized()) {
c.syncLevel = context.syncLevel + 1;
}
c.setMethodInfo(method);
c.callString = c.callString.push(method, stmt, callStringLength);
// carry only minimal information with call
Map<Location, ValueMapping> in = input.get(context.callString);
Map<Location, ValueMapping> out = new LinkedHashMap<Location, ValueMapping>();
for (Location l : in.keySet()) {
if (l.stackLoc < 0) {
out.put(l, in.get(l));
}
if (l.stackLoc >= varPtr) {
out.put(new Location(l.stackLoc - varPtr), new ValueMapping(in.get(l), false));
}
}
ContextMap<CallString, Map<Location, ValueMapping>> tmpresult = new ContextMap<CallString, Map<Location, ValueMapping>>(c, new LinkedHashMap<CallString, Map<Location, ValueMapping>>());
tmpresult.put(c.callString, out);
InstructionHandle entry = p.getEntryHandle(method);
state.put(entry, join(state.get(entry), tmpresult));
// interpret method
Map<InstructionHandle, ContextMap<CallString, Map<Location, ValueMapping>>> r = interpreter.interpret(c, entry, state, false);
//System.out.println(">>>>>>>>");
// pull out relevant information from call
InstructionHandle exit = p.getExitHandle(method);
if (r.get(exit) != null) {
Map<Location, ValueMapping> returned = r.get(exit).get(c.callString);
if (returned != null) {
for (Location l : returned.keySet()) {
if (l.stackLoc < 0) {
ValueMapping m = new ValueMapping(returned.get(l), true);
m.join(result.get(context.callString).get(l));
result.get(context.callString).put(l, m);
}
if (l.stackLoc >= 0) {
ValueMapping m = new ValueMapping(returned.get(l), false);
Location loc = new Location(l.stackLoc + varPtr);
m.join(result.get(context.callString).get(loc));
result.get(context.callString).put(loc, m);
}
}
}
}
// add relevant information to result
for (Location l : in.keySet()) {
if (l.stackLoc >= 0 && l.stackLoc < context.stackPtr - MethodHelper.getArgSize(method)) {
result.get(context.callString).put(l, new ValueMapping(in.get(l), true));
}
}
}
}
use of com.jopdesign.dfa.framework.Context in project jop by jop-devel.
the class DFATool method runLocalAnalysis.
public <K, V> Map runLocalAnalysis(Analysis<K, V> localAnalysis, ExecutionContext scope) {
Interpreter<K, V> interpreter = new Interpreter<K, V>(localAnalysis, this);
if (scope == null)
throw new AssertionError("No such method: " + scope);
Context context = new Context();
MethodCode entryCode = scope.getMethodInfo().getCode();
context.stackPtr = entryCode.getMaxLocals();
context.setMethodInfo(scope.getMethodInfo());
context.setCallString(scope.getCallString());
localAnalysis.initialize(scope.getMethodInfo(), context);
/* Here used to be a extremely-hard-to-trackdown bug!
* Without the boolean parameters, getInstructionList() will dispose
* the CFG, a very bad idea during WCET analysis which relies on
* pointer equality for CFG edges :(
*/
InstructionHandle entry = entryCode.getInstructionList(false, false).getStart();
interpreter.interpret(context, entry, new LinkedHashMap<InstructionHandle, ContextMap<K, V>>(), true);
return localAnalysis.getResult();
}
use of com.jopdesign.dfa.framework.Context in project jop by jop-devel.
the class DFATool method runAnalysis.
@SuppressWarnings("unchecked")
public Map runAnalysis(Analysis analysis) {
/* use cached results if possible */
Map results;
if ((results = getCachedResults(analysis)) != null) {
logger.warn("Analysis " + analysis.getId() + ": Using cached DFA analysis results");
return results;
}
Interpreter interpreter = new Interpreter(analysis, this);
MethodInfo main = appInfo.getMainMethod();
MethodInfo prologue = main.getClassInfo().getMethodInfo(prologueName + prologueSig);
Context context = new Context();
context.stackPtr = 0;
context.syncLevel = 0;
context.setMethodInfo(prologue);
analysis.initialize(main, context);
InstructionHandle entry = prologue.getCode().getInstructionList().getStart();
interpreter.interpret(context, entry, new LinkedHashMap(), true);
/* cache results if requested */
writeCachedResults(analysis);
return analysis.getResult();
}
use of com.jopdesign.dfa.framework.Context in project jop by jop-devel.
the class CallStringReceiverTypes method doInvokeVirtual.
private void doInvokeVirtual(String receiver, MethodInfo method, InstructionHandle stmt, Context context, ContextMap<CallString, Set<TypeMapping>> input, Interpreter<CallString, Set<TypeMapping>> interpreter, Map<InstructionHandle, ContextMap<CallString, Set<TypeMapping>>> state, ContextMap<CallString, Set<TypeMapping>> result) {
String methodImplName = method.getClassName() + "." + method.getMethodSignature();
recordReceiver(stmt, context, methodImplName);
// LineNumberTable lines = p.getMethods().get(context.method).getLineNumberTable(context.constPool);
// int sourceLine = lines.getSourceLine(stmt.getPosition());
// String invokeId = context.method+"\t"+":"+sourceLine+"."+stmt.getPosition();
// set up new context
int varPtr = context.stackPtr - MethodHelper.getArgSize(method);
Context c = new Context(context);
c.stackPtr = method.getCode().getMaxLocals();
if (method.isSynchronized()) {
c.syncLevel = context.syncLevel + 1;
}
c.setMethodInfo(method);
c.callString = c.callString.push(context.getMethodInfo(), stmt, callStringLength);
boolean threaded = false;
DFATool p = interpreter.getDFATool();
if (p.getAppInfo().getClassInfo(receiver).isSubclassOf(p.getAppInfo().getClassInfo("joprt.RtThread")) && "run()V".equals(method.getMethodSignature())) {
c.createThread();
threaded = true;
}
// carry only minimal information with call
Set<TypeMapping> in = input.get(context.callString);
Set<TypeMapping> out = new LinkedHashSet<TypeMapping>();
ContextMap<CallString, Set<TypeMapping>> tmpresult = new ContextMap<CallString, Set<TypeMapping>>(c, new LinkedHashMap<CallString, Set<TypeMapping>>());
tmpresult.put(c.callString, out);
for (TypeMapping m : in) {
if (m.stackLoc < 0) {
out.add(m);
}
if (m.stackLoc > varPtr) {
out.add(new TypeMapping(m.stackLoc - varPtr, m.type));
}
if (m.stackLoc == varPtr) {
// add "this"
ClassInfo staticClass = p.getAppInfo().getClassInfo(receiver);
ClassInfo dynamicClass = null;
try {
dynamicClass = p.getAppInfo().getClassInfo(m.type.split("@")[0]);
} catch (MissingClassError ex) {
logger.error("doInvokeVirtual - trying to improve type of " + staticClass + ": " + ex);
// TODO: maybe we should throw an exception/error instead?
}
if (dynamicClass != null && dynamicClass.isSubclassOf(staticClass)) {
out.add(new TypeMapping(0, m.type));
}
}
}
InstructionHandle entry = p.getEntryHandle(method);
state.put(entry, join(state.get(entry), tmpresult));
// interpret method
Map<InstructionHandle, ContextMap<CallString, Set<TypeMapping>>> r = interpreter.interpret(c, entry, state, false);
// pull out relevant information from call
InstructionHandle exit = p.getExitHandle(method);
if (r.get(exit) != null) {
Set<TypeMapping> returned = r.get(exit).get(c.callString);
if (returned != null) {
filterReturnSet(returned, result.get(context.callString), varPtr);
}
}
// update all threads
if (threaded) {
threads.put(methodImplName, new ContextMap<CallString, Set<TypeMapping>>(c, result));
updateThreads(result, interpreter, state);
}
}
use of com.jopdesign.dfa.framework.Context in project jop by jop-devel.
the class CallStringReceiverTypes method join.
public ContextMap<CallString, Set<TypeMapping>> join(ContextMap<CallString, Set<TypeMapping>> s1, ContextMap<CallString, Set<TypeMapping>> s2) {
if (s1 == null) {
return new ContextMap<CallString, Set<TypeMapping>>(s2);
}
if (s2 == null) {
return new ContextMap<CallString, Set<TypeMapping>>(s1);
}
ContextMap<CallString, Set<TypeMapping>> result = new ContextMap<CallString, Set<TypeMapping>>(new Context(s2.getContext()), new LinkedHashMap<CallString, Set<TypeMapping>>());
result.putAll(s1);
result.putAll(s2);
Set<TypeMapping> a = s1.get(s2.getContext().callString);
Set<TypeMapping> b = s2.get(s2.getContext().callString);
Set<TypeMapping> merged = new LinkedHashSet<TypeMapping>();
if (a != null) {
merged.addAll(a);
}
if (b == null) {
logger.error("RT join: failed to find DF information for " + s2.getContext().callString.toStringVerbose(false));
}
merged.addAll(b);
result.put(s2.getContext().callString, merged);
if (result.getContext().stackPtr < 0) {
result.getContext().stackPtr = s2.getContext().stackPtr;
}
if (result.getContext().syncLevel < 0) {
result.getContext().syncLevel = s2.getContext().syncLevel;
}
result.getContext().threaded = Context.isThreaded();
return result;
}
Aggregations