Commit 51dac9e0 authored by Lukáš Marek's avatar Lukáš Marek

trunk cleanup

this commit is start of bigger trunk cleanup wich should result in live trunk
1) trunk is reverted back to revison 575
2) trunk is branched from 577 to crate branch with SyntheticStatic stuff (not stable enough)
3) remoteval is applied to trunk
parent 2dd07726
......@@ -4,10 +4,5 @@ The DiSL framework will load the jar, parse the instrumentation specification, a
The examples of simple instrumentation are in src-test directory.
The test can be invoked using runTest.sh script in the root directory.
For user defined instrumentation, it is recommended to mimic the start and build script as they are provided for the tests.
For user defined instrumentation, it is recommended to mimic the start and build script as they are provided for test.
We are working on better setup scripts to ease the setup effort for developer.
The supported platform is Linux with installed Java and GCC.
To compile DiSL please run the "ant" command in the root directory and "make" in the src-agent-c directory.
If the make is complaining about missing java headers, modify the Makefile.local.tmpl accordingly.
......@@ -18,7 +18,7 @@ then
rm .server.pid
fi
# represents the observed program
DISL_CLASS="./bin/ch/usi/dag/disl/test/$1/DiSLClass.class"
TARGET_CLASS="ch.usi.dag.disl.test.$1.TargetClass"
# start server and take pid
......
package ch.usi.dag.disl.test.staticfield;
import ch.usi.dag.disl.annotation.AfterReturning;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.annotation.SyntheticStaticField;
import ch.usi.dag.disl.annotation.SyntheticStaticField.Scope;
import ch.usi.dag.disl.marker.BodyMarker;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
public class DiSLClass {
@SyntheticStaticField(scope = Scope.PERCLASS)
public static String s;
@SyntheticStaticField(scope = Scope.PERMETHOD)
public static String mid;
@Before(marker = BodyMarker.class, scope = "TargetClass.*", order = 2)
public static void precondition(MethodStaticContext msc) {
mid = msc.thisMethodFullName();
System.out.println("Entering " + mid + " while s is " + s);
}
@AfterReturning(marker = BodyMarker.class, scope = "TargetClass.*", order = 2)
public static void postcondition() {
System.out.println("Exiting " + mid + " while s is " + s);
}
@Before(marker = BodyMarker.class, scope = "TargetClass.print", order = 1)
public static void precondition2() {
s = "Set in TargetClass.print";
}
}
Manifest-Version: 1.0
DiSL-Classes: ch.usi.dag.disl.test.staticfield.DiSLClass
\ No newline at end of file
package ch.usi.dag.disl.test.staticfield;
public class TargetClass {
public void print() {
System.out.println("This is the body of TargetClass.print");
}
public static void main(String[] args) {
TargetClass t = new TargetClass();
t.print();
}
}
......@@ -36,7 +36,6 @@ import ch.usi.dag.disl.exception.TransformerException;
import ch.usi.dag.disl.exclusion.ExclusionSet;
import ch.usi.dag.disl.guard.GuardHelper;
import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.localvar.SyntheticStaticFieldVar;
import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.processor.Proc;
import ch.usi.dag.disl.processor.generator.PIResolver;
......@@ -83,8 +82,6 @@ public class DiSL {
private final List<Snippet> snippets;
private final List<SyntheticStaticFieldVar> syntheticStaticFields;
/**
* DiSL initialization
* @param useDynamicBypass enable or disable dynamic bypass instrumentation
......@@ -147,10 +144,6 @@ public class DiSL {
// - it serves as initialization flag
snippets = parsedSnippets;
// get parsed synthetic static fields
syntheticStaticFields = new LinkedList<SyntheticStaticFieldVar>(parser
.getAllLocalVars().getSyntheticStaticFields().values());
// TODO put checker here
// like After should catch normal and abnormal execution
// but if you are using After (AfterThrowing) with BasicBlockMarker
......@@ -234,7 +227,6 @@ public class DiSL {
System.out.println("Instrumenting method: " + className
+ Constants.CLASS_DELIM + methodName + "(" + methodDesc
+ ")");
}
// evaluate exclusions
for (Scope exclScope : exclusionSet) {
......@@ -323,8 +315,9 @@ public class DiSL {
// *** viewing ***
Weaver.instrument(classNode, methodNode, snippetMarkings,
new LinkedList<SyntheticLocalVar>(usedSLVs),
syntheticStaticFields, staticInfo, piResolver);
new LinkedList<SyntheticLocalVar>(usedSLVs), staticInfo,
piResolver);
}
return true;
}
......
package ch.usi.dag.disl.annotation;
public @interface SyntheticStaticField {
public enum Scope {
PERCLASS, PERMETHOD
}
Scope scope() default (Scope.PERMETHOD);
}
......@@ -18,11 +18,9 @@ import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.SourceValue;
import ch.usi.dag.disl.annotation.SyntheticStaticField;
import ch.usi.dag.disl.annotation.SyntheticLocal;
import ch.usi.dag.disl.exception.ParserException;
import ch.usi.dag.disl.localvar.LocalVars;
import ch.usi.dag.disl.localvar.SyntheticStaticFieldVar;
import ch.usi.dag.disl.localvar.SyntheticLocalVar;
import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.AsmHelper;
......@@ -120,15 +118,6 @@ abstract class AbstractParser {
continue;
}
// static local
if (annotationType.equals(Type.getType(SyntheticStaticField.class))) {
SyntheticStaticFieldVar slv = parseSyntheticStaticField(
className, field, annotation);
result.getSyntheticStaticFields().put(slv.getID(), slv);
continue;
}
throw new ParserException("Field " + className + "."
+ field.name + " has unsupported DiSL annotation");
}
......@@ -382,40 +371,4 @@ abstract class AbstractParser {
}
}
}
private SyntheticStaticFieldVar parseSyntheticStaticField(String className,
FieldNode field, AnnotationNode annotation) throws ParserException {
// check if field is static
if ((field.access & Opcodes.ACC_STATIC) == 0) {
throw new ParserException("Field " + field.name + className + "."
+ " declared as SyntheticLocalField but is not static");
}
// parse annotation data
STLAnnotaionData slad = new STLAnnotaionData();
ParserHelper.parseAnnotation(slad, annotation);
SyntheticStaticField.Scope ssfScope = SyntheticStaticField.Scope.PERMETHOD;
if (slad.scope != null) {
// enum is converted to array
// - first value is class name
// - second value is value name
ssfScope = SyntheticStaticField.Scope.valueOf(slad.scope[1]);
}
// field type
Type fieldType = Type.getType(field.desc);
return new SyntheticStaticFieldVar(className, field.name, fieldType,
ssfScope, field.access);
}
private static class STLAnnotaionData {
public String[] scope = null;
}
}
......@@ -12,9 +12,6 @@ import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.ClonedCode;
/**
* Stores various information about a piece of java bytecode.
*/
public class Code {
private InsnList instructions;
......@@ -28,9 +25,6 @@ public class Code {
// it further - can cause stack inconsistency that has to be handled
private boolean containsHandledException;
/**
* Constructs the Code structure.
*/
public Code(InsnList instructions, List<TryCatchBlockNode> tryCatchBlocks,
Set<SyntheticLocalVar> referencedSLVs,
Set<ThreadLocalVar> referencedTLVs,
......@@ -49,58 +43,34 @@ public class Code {
this.containsHandledException = containsHandledException;
}
/**
* Returns an ASM instruction list.
*/
public InsnList getInstructions() {
return instructions;
}
/**
* Returns list of exceptions (as represented in ASM).
*/
public List<TryCatchBlockNode> getTryCatchBlocks() {
return tryCatchBlocks;
}
/**
* Returns list of all synthetic local variables referenced in the code.
*/
public Set<SyntheticLocalVar> getReferencedSLVs() {
return referencedSLVs;
}
/**
* Returns list of all thread local variables referenced in the code.
*/
public Set<ThreadLocalVar> getReferencedTLVs() {
return referencedTLVs;
}
/**
* Returns list of all static contexts referenced in the code.
*/
public Set<StaticContextMethod> getStaticContexts() {
return staticContexts;
}
/**
* Returns true if the code is using dynamic context. False otherwise.
*/
public boolean usesDynamicContext() {
return usesDynamicContext;
}
/**
* Returns true if the code is using class context. False otherwise.
*/
public boolean usesClassContext() {
return usesClassContext;
}
/**
* Returns true if the code contains catch block (handles exception).
*/
public boolean containsHandledException() {
return containsHandledException;
}
......
......@@ -9,8 +9,6 @@ public class LocalVars {
new HashMap<String, SyntheticLocalVar>();
private Map<String, ThreadLocalVar> threadLocals =
new HashMap<String, ThreadLocalVar>();
private Map<String, SyntheticStaticFieldVar> syntheticStaticFields =
new HashMap<String, SyntheticStaticFieldVar>();
public Map<String, SyntheticLocalVar> getSyntheticLocals() {
return syntheticLocals;
......@@ -20,14 +18,9 @@ public class LocalVars {
return threadLocals;
}
public Map<String, SyntheticStaticFieldVar> getSyntheticStaticFields() {
return syntheticStaticFields;
}
public void putAll(LocalVars localVars) {
syntheticLocals.putAll(localVars.getSyntheticLocals());
threadLocals.putAll(localVars.getThreadLocals());
syntheticStaticFields.putAll(localVars.getSyntheticStaticFields());
}
}
package ch.usi.dag.disl.localvar;
import org.objectweb.asm.Type;
import ch.usi.dag.disl.annotation.SyntheticStaticField.Scope;
public class SyntheticStaticFieldVar extends AbstractLocalVar {
private int access;
private Scope scope;
public SyntheticStaticFieldVar(String className, String fieldName, Type type,
Scope scope, int access) {
super(className, fieldName, type);
this.scope = scope;
this.access = access;
}
public String getTypeAsDesc() {
return getType().getDescriptor();
}
public int getAccess() {
return access;
}
public Scope getScope() {
return scope;
}
}
......@@ -20,7 +20,7 @@ public class BasicBlockMarker extends AbstractDWRMarker {
List<AbstractInsnNode> seperators = BasicBlockCalc.getAll(
methodNode.instructions, methodNode.tryCatchBlocks, isPrecise);
AbstractInsnNode last = AsmHelper.skipVirtualInsns(
AbstractInsnNode last = AsmHelper.skipVirualInsns(
methodNode.instructions.getLast(), false);
seperators.add(last);
......@@ -34,7 +34,7 @@ public class BasicBlockMarker extends AbstractDWRMarker {
end = end.getPrevious();
}
regions.add(new MarkedRegion(start, AsmHelper.skipVirtualInsns(end,
regions.add(new MarkedRegion(start, AsmHelper.skipVirualInsns(end,
false)));
}
......
......@@ -24,7 +24,7 @@ public class ExceptionHandlerMarker extends AbstractDWRMarker {
for (TryCatchBlockNode tcb : method.tryCatchBlocks) {
List<AbstractInsnNode> exits = cfg.visit(tcb.handler);
regions.add(new MarkedRegion(AsmHelper.skipVirtualInsns(tcb.handler,
regions.add(new MarkedRegion(AsmHelper.skipVirualInsns(tcb.handler,
true), exits));
}
......
......@@ -18,8 +18,8 @@ public class TryClauseMarker extends AbstractDWRMarker {
for (TryCatchBlockNode tcb : method.tryCatchBlocks) {
AbstractInsnNode start = AsmHelper.skipVirtualInsns(tcb.start, true);
AbstractInsnNode end = AsmHelper.skipVirtualInsns(tcb.end, false);
AbstractInsnNode start = AsmHelper.skipVirualInsns(tcb.start, true);
AbstractInsnNode end = AsmHelper.skipVirualInsns(tcb.end, false);
regions.add(new MarkedRegion(start, end));
}
......
......@@ -6,15 +6,7 @@ import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
/**
* Holds information about a region where a snippet will be woven. The shadow
* contains two type of regions. Logical region which is available directly in
* the shadow is designed mainly for static analysis and represents a region
* which is logically captured. Weaving region is designed as a guidance for the
* weaver, where exactly should be the code woven. Note that normally are the
* regions same but can differ in cases where specific instrumentation is
* needed.
*/
public class Shadow {
protected ClassNode classNode;
......@@ -26,10 +18,6 @@ public class Shadow {
private WeavingRegion weavingRegion;
/**
* Holds exact information where the code will be woven. This structure is
* a guiding source for the weaver.
*/
public static class WeavingRegion {
// NOTE: "ends" can be null. This means, that we have the special case
......@@ -115,44 +103,26 @@ public class Shadow {
this.weavingRegion = sa.weavingRegion;
}
/**
* Returns class node of the class where the shadow is defined.
*/
public ClassNode getClassNode() {
return classNode;
}
/**
* Returns method node of the method where the shadow is defined.
*/
public MethodNode getMethodNode() {
return methodNode;
}
/**
* Returns snippet that will be woven.
*/
public Snippet getSnippet() {
return snippet;
}
/**
* Returns region start (this region is designed for static analysis)
*/
public AbstractInsnNode getRegionStart() {
return regionStart;
}
/**
* Returns region ends (this region is designed for static analysis)
*/
public List<AbstractInsnNode> getRegionEnds() {
return regionEnds;
}
/**
* Returns weaving region (this region is designed for weaver)
*/
public WeavingRegion getWeavingRegion() {
return weavingRegion;
}
......
......@@ -13,9 +13,6 @@ import ch.usi.dag.disl.marker.Marker;
import ch.usi.dag.disl.processor.Proc;
import ch.usi.dag.disl.scope.Scope;
/**
* Holds all the information about a snippet.
*/
public class Snippet implements Comparable<Snippet> {
private String originClassName;
......@@ -29,9 +26,6 @@ public class Snippet implements Comparable<Snippet> {
private SnippetUnprocessedCode unprocessedCode;
private SnippetCode code;
/**
* Creates snippet structure.
*/
public Snippet(String originClassName, String originMethodName,
Class<?> annotationClass, Marker marker, Scope scope, Method guard,
int order, SnippetUnprocessedCode unprocessedCode) {
......@@ -46,72 +40,42 @@ public class Snippet implements Comparable<Snippet> {
this.unprocessedCode = unprocessedCode;
}
/**
* Get the class name where the snippet is defined.
*/
public String getOriginClassName() {
return originClassName;
}
/**
* Get the method name where the snippet is defined.
*/
public String getOriginMethodName() {
return originMethodName;
}
/**
* Get the snippet annotation class.
*/
public Class<?> getAnnotationClass() {
return annotationClass;
}
/**
* Get the snippet marker.
*/
public Marker getMarker() {
return marker;
}
/**
* Get the snippet scope.
*/
public Scope getScope() {
return scope;
}
/**
* Get the snippet guard.
*/
public Method getGuard() {
return guard;
}
/**
* Get the snippet order.
*/
public int getOrder() {
return order;
}
/**
* Get the snippet code.
*/
public SnippetCode getCode() {
return code;
}
/**
* Compares snippets according to order.
*/
public int compareTo(Snippet o) {
return o.getOrder() - order;
}
/**
* Initializes snippet -- prepares the snippet code.
*/
public void init(LocalVars allLVs, Map<Type, Proc> processors,
boolean exceptHandler, boolean useDynamicBypass)
throws StaticContextGenException, ReflectionException,
......
......@@ -16,9 +16,6 @@ import ch.usi.dag.disl.localvar.ThreadLocalVar;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.AsmHelper.ClonedCode;
/**
* Stores the information about snippet code.
*/
public class SnippetCode extends Code {
private boolean usesProcessorContext;
......@@ -45,9 +42,6 @@ public class SnippetCode extends Code {
this.usesProcessorContext = usesProcessorContext;
}
/**
* Returns list of all argument processors referenced in the code.
*/
public Map<Integer, ProcInvocation> getInvokedProcessors() {
return invokedProcessors;
}
......
......@@ -32,9 +32,6 @@ import ch.usi.dag.disl.processorcontext.ArgumentProcessorContext;
import ch.usi.dag.disl.processorcontext.ArgumentProcessorMode;
import ch.usi.dag.disl.util.AsmHelper;
/**
* Contains unprocessed code of the Snippet.
*/
public class SnippetUnprocessedCode extends UnprocessedCode {
private String className;
......@@ -42,9 +39,6 @@ public class SnippetUnprocessedCode extends UnprocessedCode {
private boolean dynamicBypass;
private boolean usesProcessorContext;
/**
* Creates unprocessed code structure.
*/
public SnippetUnprocessedCode(String className, String methodName,
InsnList instructions, List<TryCatchBlockNode> tryCatchBlocks,
Set<String> declaredStaticContexts, boolean usesDynamicContext,
......@@ -59,9 +53,6 @@ public class SnippetUnprocessedCode extends UnprocessedCode {
this.usesProcessorContext = usesProcessorContext;
}
/**
* Processes the stored data and creates snippet code structure.
*/
public SnippetCode process(LocalVars allLVs, Map<Type, Proc> processors,
Marker marker, boolean exceptHandler, boolean useDynamicBypass)
throws StaticContextGenException, ReflectionException,
......
......@@ -2,10 +2,6 @@ package ch.usi.dag.disl.staticcontext;
import ch.usi.dag.disl.snippet.Shadow;
/**
* Provides simple implementation of StaticContext that holds the static context
* data in a protected field.
*/
public abstract class AbstractStaticContext implements StaticContext {
protected Shadow staticContextData;
......
......@@ -2,18 +2,13 @@ package ch.usi.dag.disl.staticcontext;
import ch.usi.dag.disl.snippet.Shadow;
/**
* Every static context class has to implement this interface.
*
* All static context methods should follow convention:
* a) static context methods does not have parameters
* b) return value can be only basic type or String
*/
public interface StaticContext {
/**
* Receives static context data. Call to this method precedes a static
* context method invocation.
*/
// It is mandatory to implement this interface
// NOTE: all static context methods should follow convention:
// a) static context methods does not have parameters
// b) return value can be only basic type or String
public void staticContextData(Shadow sa);
}
package ch.usi.dag.disl.transformer;
/**
* Allows to transform a class before it is passed to DiSL. The transformer
* class has to be specified in the instrumentation manifest.
*/
public interface Transformer {
/**
* The transformation interface. The class to be transformed is passed as
* an argument and the transformed class is returned.
*
* @param classfileBuffer class to be transformed
* @return transformed class
*/
byte[] transform(byte[] classfileBuffer) throws Exception;
/**
* If this method returns true, not instrumented classes are still
* set as changed and returned by DiSL as modified. Otherwise, the DiSL will
* report class as unmodified.
*
* @return propagation flag
*/
boolean propagateUninstrumentedClasses();
}
......@@ -148,7 +148,7 @@ public abstract class AsmHelper {
}
}
public static AbstractInsnNode loadDefault(Type type) {
public static AbstractInsnNode loadNull(Type type) {
switch (type.getSort()) {
case Type.BOOLEAN:
......@@ -368,7 +368,7 @@ public abstract class AsmHelper {
return dst;
}
public static AbstractInsnNode skipVirtualInsns(AbstractInsnNode instr,
public static AbstractInsnNode skipVirualInsns(AbstractInsnNode instr,
boolean isForward) {
while (instr != null && isVirtualInstr(instr)) {
......
......@@ -54,7 +54,7 @@ public class BasicBlockCalc {
@Override
public boolean add(AbstractInsnNode e) {
return super.add(AsmHelper.skipVirtualInsns(e, true));
return super.add(AsmHelper.skipVirualInsns(e, true));
}
};
......
......@@ -60,7 +60,7 @@ public class CtrlFlowGraph {
end = end.getPrevious();
}
end = AsmHelper.skipVirtualInsns(end, false);
end = AsmHelper.skipVirualInsns(end, false);
nodes.add(new BasicBlock(i, start, end));
}
}
......@@ -91,7 +91,7 @@ public class CtrlFlowGraph {
// If not found, return null.
public BasicBlock getBB(AbstractInsnNode instr) {
instr = AsmHelper.skipVirtualInsns(instr, true);
instr = AsmHelper.skipVirualInsns(instr, true);
while (instr != null) {
......
......@@ -27,13 +27,13 @@ public class AdvancedSorter extends TryCatchBlockSorter {
for (int i = 0; i < tcbs.length; i++) {
int istart = instructions.indexOf(AsmHelper.skipVirtualInsns(
int istart = instructions.indexOf(AsmHelper.skipVirualInsns(
tcbs[i].start, true));
int iend = instructions.indexOf(tcbs[i].end);
for (int j = i; j < tcbs.length; j++) {
int jstart = instructions.indexOf(AsmHelper.skipVirtualInsns(
int jstart = instructions.indexOf(AsmHelper.skipVirualInsns(
tcbs[j].start, true));
int jend = instructions.indexOf(tcbs[j].end);
......@@ -61,7 +61,7 @@ public class AdvancedSorter extends TryCatchBlockSorter {
}
private int blockLength(TryCatchBlockNode block) {
int startidx = instructions.indexOf(AsmHelper.skipVirtualInsns(
int startidx = instructions.indexOf(AsmHelper.skipVirualInsns(
block.start, true));
int endidx = instructions.indexOf(block.end);