Commit 051498a6 authored by Lukáš Marek's avatar Lukáš Marek

Merged trunk to remoteval branch revisions 460:476

parent edf4cb2c
user.runtime.jar.name=fia-runtime.jar
......@@ -3,14 +3,11 @@
<property file="../../disl.version"/>
<property file="../../build.properties"/>
<property file="build.properties"/>
<property name="disl.jar.path" value="../../build/disl-${disl.version}.jar"/>
<property name="disl.jar.path" value="../../build/dislserver-${disl.version}.jar"/>
<path id="buildpath">
<pathelement location="${disl.jar.path}"/>
<pathelement location="../../${asm.path}"/>
<pathelement location="../../${jborat.path}"/>
<pathelement location="../../${jborat-runtime.path}"/>
<pathelement location="lib/stp.jar"/>
</path>
<target name="check-disl-jar">
......@@ -25,19 +22,9 @@
<mkdir dir="bin"/>
<javac srcdir="src" destdir="bin" debug="true" includeAntRuntime="false">
<classpath refid="buildpath"/>
<compilerarg value="-Xbootclasspath/p:lib/Thread_test.jar"/>
</javac>
</target>
<target name="agent" description="create simple agent jar file" >
<mkdir dir="build"/>
<jar jarfile="build/agent-light.jar">
<manifest>
<attribute name="Premain-Class" value="ch.usi.dag.disl.test.agent.Agent"/>
</manifest>
</jar>
</target>
<target name="check-test-property">
<condition property="test.set">
<isset property="test.name"/>
......@@ -52,14 +39,10 @@
<target name="package" depends="report-missing-property,compile" description="create instrumentation package for specified test">
<mkdir dir="build"/>
<jar jarfile="./build/${user.runtime.jar.name}"
basedir="./bin"
includes="${test.path}/runtime/**">
</jar>
<jar jarfile="../../build/${instr.jar.name}"
basedir="./bin"
includes="${test.path}/*"
excludes="${test.path}/runtime ${test.path}/TargetClass*.class ${test.path}/MANIFEST.MF"
includes="${test.path}/**"
excludes="${test.path}/TargetClass*.class ${test.path}/MANIFEST.MF"
manifest="./src/${test.path}/MANIFEST.MF">
</jar>
</target>
......
# THESE ARE THE BASIC SETTINGS
ch.usi.dag.jborat.*
sun.instrument.*
#sun.instrument.*
# THESE ARE THE RUNTIME CLASSES THAT MUST NOT BE WOVEN
ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.runtime.*
#ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.runtime.*
# PROBLEM WITH FOP (CODE TOO BIG)
org/apache/fop/fonts/CodePointMapping
#org/apache/fop/fonts/CodePointMapping
# BEGIN JDK WEAVING
# COMMENT THE FOLLOWING FOR FULL COVERAGE
#org.jcp.*
#org.omg.*
#org.xml.*
#org.ietf.*
#java.*
#javax.*
#java.lang.Object.*
#javax.*.*
#com.sun.*
#com.apple.*
#sun.*
#sun.*.*
#sunx.*
#org.apache.batik.xml.XMLCharacters.<clinit>
# END JDK
#!/bin/bash
OS=`uname`
ARCH_RAW=`uname -m`
ARCH="unspec"
if [ "${ARCH_RAW}" = "i686" -o "${ARCH_RAW}" = "x86_32" -o "${ARCH_RAW}" = "i386" ]; then
ARCH="x32"
elif [ "${ARCH_RAW}" = "x86_64" ]; then
ARCH="x64"
else
echo "Unknow architecture...."
exit -1
fi
if [ "${OS}" = "Darwin" ]; then
JBORAT_AGENT="macosx/${ARCH}/"libjboratagent.jnilib
elif [ "${OS}" = "Linux" ]; then
JBORAT_AGENT="linux/${ARCH}/"libjboratagent.so
C_AGENT="../../src-agent-c/libdislagent.jnilib"
else
echo "Unknow platform..."
exit -1
C_AGENT="../../src-agent-c/libdislagent.so"
fi
# shared memory is the default communication
# to enable socket, add ",ipc.socket" to the options
JBORAT_AGENT_OPTS="1234,localhost,ipc.socket"
java -noverify \
-XX:MaxPermSize=128m \
-Xmx2G \
-javaagent:../../test/lib/agent.jar \
-Xbootclasspath/p:../../test/lib/remote-runtime.jar:../../lib/jborat-runtime.jar:build/fia-runtime.jar \
-agentpath:../../test/lib/${JBORAT_AGENT}=${JBORAT_AGENT_OPTS} \
-cp ./bin \
$*
# -jar /home/sarimbea/workspace/lib/dacapo-9.12-bach.jar luindex lusearch pmd h2 tradebeans tradesoap sunflow tomcat
# ipc.socket is the default communication
# to enable shared memory, remove ",ipc.socket" from the options
java -Xmx2g -XX:MaxPermSize=128m -noverify -agentpath:${C_AGENT} \
-javaagent:../../build/dislagent-unspec.jar \
-Xbootclasspath/a:../../build/dislagent-unspec.jar:../../build/dislinstr.jar \
-cp bin/ \
$*
#!/bin/sh
OS=`uname`
ARCH_RAW=`uname -m`
ARCH="unspec"
# available options
# -Ddebug=true \
# -Ddisl.classes="list of disl classes (: - separator)"
# -Ddisl.noexcepthandler=true \
# -Ddisl.exclusionList="path" \
# -Ddislserver.instrumented="path" \
# -Ddislserver.uninstrumented="path" \
# -Ddislserver.port="portNum" \
# -Ddislserver.timestat=true \
# -Ddislserver.continuous=true \
if [ "${ARCH_RAW}" = "i686" -o "${ARCH_RAW}" = "x86_32" -o "${ARCH_RAW}" = "i386" ]; then
ARCH="x32"
elif [ "${ARCH_RAW}" = "x86_64" ]; then
ARCH="x64"
else
echo "Unknow architecture.."
exit -1
fi
if [ "${OS}" = "Darwin" ]; then
JBORAT_AGENT_PATH="macosx/${ARCH}"
elif [ "${OS}" = "Linux" ]; then
JBORAT_AGENT_PATH="linux/${ARCH}"
else
echo "Unknow platform..."
exit -1
fi
CLASSPATH=../../lib/jborat-agent.jar:../../lib/jborat-runtime.jar:../../lib/jborat-interface.jar:../../test/lib/remote-server.jar
java \
-Dch.usi.dag.jborat.uninstrumented="uninstrumented" \
-Dch.usi.dag.jborat.instrumented="instrumented" \
-Djborat.debug \
-Ddisl.dynbypass=true \
-Ddisl.debug=false \
-Djborat.ipc.socket=true \
-Djava.library.path=./lib/${JBORAT_AGENT_PATH} \
-Dch.usi.dag.jborat.instrumentation="ch.usi.dag.disl.DiSL" \
-Dch.usi.dag.jborat.codemergerList="../../test/conf/codemerger.lst" \
-Dch.usi.dag.jborat.liblist="conf/lib.lst" \
-Dch.usi.dag.jborat.udiliblist="conf/udilib.lst" \
-Dch.usi.dag.jborat.exclusionList="conf/exclusion.lst" \
$* \
-cp ${CLASSPATH} \
ch.usi.dag.jborat.remote.server.Server \
&
java $* \
-Ddisl.exclusionList="conf/exclusion.lst" \
-Ddislserver.continuous=true \
-jar ../../build/dislserver-unspec.jar \
&
echo $! > ${SERVER_FILE}
......@@ -8,7 +8,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.zip.GZIPOutputStream;
import ch.usi.dag.jborat.runtime.DynamicBypass;
import ch.usi.dag.disl.dynamicbypass.*;
public class ImmutabilityAnalysis {
......@@ -38,7 +38,7 @@ public class ImmutabilityAnalysis {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
DynamicBypass.set(true);
DynamicBypass.activate();
System.err.println("In shutdown hook!");
try {
synchronized (fieldStateMap) {
......
......@@ -31,6 +31,11 @@ CFLAGS += $(COMMON_FLAGS)
CFLAGS += -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux
# add debugging output
ifeq ($(DEBUG), TRUE)
CFLAGS += -DDEBUG
endif
all: $(LIBRARY)
# Build native library
......@@ -40,3 +45,6 @@ $(LIBRARY): $(OBJECTS)
# Cleanup the built bits
clean:
rm -f $(LIBRARY) $(OBJECTS)
debug:
$(MAKE) DEBUG=TRUE
This diff is collapsed.
......@@ -67,9 +67,11 @@ public class DiSL {
Boolean.getBoolean(PROP_SPLIT_LONG_METHODS);
private final boolean useDynamicBypass;
private final Transformer transformer;
private final boolean transPropagateUninstr;
private final Set<Scope> exclusionSet;
private final List<Snippet> snippets;
......@@ -84,6 +86,15 @@ public class DiSL {
// *** resolve transformer ***
transformer = resolveTransformer();
// transfomer output propagation
if(transformer == null) {
transPropagateUninstr = false;
}
else {
transPropagateUninstr =
transformer.propagateUninstrumentedClasses();
}
// *** prepare exclusion set ***
exclusionSet = ExclusionSet.prepare();
......@@ -482,6 +493,13 @@ public class DiSL {
InstrumentedClass instrClass = instrument(classNode);
if(instrClass == null) {
// propagate uninstrumented classes
// useful, when transformer is doing some job on all classes
if(transPropagateUninstr) {
return classAsBytes;
}
return null;
}
......
......@@ -28,6 +28,7 @@ public class ManifestHelper {
this.resource = resource;
this.manifest = manifest;
this.dislClasses = dislClasses;
this.dislTransformer = dislTransformer;
}
public URL getResource() {
......
......@@ -63,7 +63,6 @@ public abstract class ExclusionSet {
exclSet.add(new ScopeImpl(
"sun.instrument" + EXCLUDE_CLASSES));
// TODO jb - rally has to be excluded ?
// finalize method in java.lang.Object can cause problems
exclSet.add(new ScopeImpl("java.lang.Object.finalize"));
......
......@@ -15,10 +15,9 @@ public class ScopeImpl implements Scope {
private final String PARAM_END = ")";
private final String PARAM_DELIM = ",";
private final String METHOD_DELIM = ".";
private final String PACKAGE_DELIM = ".";
private final String PARAM_MATCH_REST = "..";
private final String DEFAULT_PKG = "[default]";
private String packageWildCard;
private String classWildCard;
private String methodWildCard;
private String returnWildCard;
......@@ -124,7 +123,7 @@ public class ScopeImpl implements Scope {
+ "\" should have defined method at least as \"*\"");
}
// -- full class name + package --
// -- full class name --
if(restOfExpr != null) {
// remove whitespace
......@@ -132,7 +131,6 @@ public class ScopeImpl implements Scope {
if(! restOfExpr.isEmpty()) {
// extract class name
int classDelim = lastWhitespace(restOfExpr);
if(classDelim != -1) {
// + 1 - don't include whitespace
......@@ -144,13 +142,11 @@ public class ScopeImpl implements Scope {
restOfExpr = null;
}
// extract package name
int packageEnd = classWildCard.lastIndexOf(PACKAGE_DELIM);
if(packageEnd != -1) {
packageWildCard = classWildCard.substring(0, packageEnd);
// do not include PACKAGE_DELIM
classWildCard = classWildCard.substring(packageEnd + 1);
// if there is no package specified - allow any
if(classWildCard.indexOf(Constants.PACKAGE_STD_DELIM) == -1
&& ! classWildCard.startsWith(WildCard.WILDCARD_STR)) {
classWildCard = WildCard.WILDCARD_STR +
Constants.PACKAGE_STD_DELIM + classWildCard;
}
}
}
......@@ -175,28 +171,23 @@ public class ScopeImpl implements Scope {
}
}
@Override
public boolean matches(String className, String methodName, String methodDesc) {
// -- match class (package) --
public boolean matches(String className, String methodName,
String methodDesc) {
// -- match class (with package) --
// replace delimiters for matching
className = className.replace(
Constants.PACKAGE_INTERN_DELIM, Constants.PACKAGE_STD_DELIM);
String packageName = new String();
// extract package name from class name if any
int packageEnd = className.lastIndexOf(PACKAGE_DELIM);
if(packageEnd != -1) {
packageName = className.substring(0, packageEnd);
// do not include PACKAGE_DELIM
className = className.substring(packageEnd + 1);
}
if(packageWildCard != null
&& ! WildCard.match(packageName, packageWildCard)) {
return false;
// if className has default package (nothing), add our default package
// reasons:
// 1) we can restrict scope on default package by putting our default
// package into scope
// 2) default package would not be matched if no package was specified
// in the scope (because of substitution made)
if(className.indexOf(Constants.PACKAGE_STD_DELIM) == -1) {
className = DEFAULT_PKG + Constants.PACKAGE_STD_DELIM + className;
}
if(classWildCard != null
......
......@@ -5,13 +5,14 @@ import java.util.List;
import org.objectweb.asm.tree.AbstractInsnNode;
import ch.usi.dag.disl.util.cfg.CtrlFlowGraph;
import ch.usi.dag.disl.util.cfg.LoopAnalyzer;
public class BasicBlockStaticContext extends AbstractStaticContext {
public int getTotBBs() {
CtrlFlowGraph cfg = new CtrlFlowGraph(
staticContextData.getMethodNode());
return cfg.getNodes().size();
CtrlFlowGraph cfg = new CtrlFlowGraph(
staticContextData.getMethodNode());
return cfg.getNodes().size();
}
public int getBBSize() {
......@@ -24,11 +25,11 @@ public class BasicBlockStaticContext extends AbstractStaticContext {
ends = staticContextData.getRegionEnds();
while (!ends.contains(start)) {
if (start.getOpcode() != 1) {
count++;
}
start = start.getNext();
}
......@@ -41,12 +42,10 @@ public class BasicBlockStaticContext extends AbstractStaticContext {
staticContextData.getMethodNode());
return cfg.getIndex(staticContextData.getRegionStart());
}
public boolean isFirstOfLoop() {
CtrlFlowGraph cfg = CtrlFlowGraph.buildAll(staticContextData
.getMethodNode());
return cfg.getBB(staticContextData.getRegionStart())
.isLoop();
return LoopAnalyzer.isEntryOfLoop(staticContextData.getMethodNode(),
staticContextData.getRegionStart());
}
}
......@@ -3,4 +3,6 @@ package ch.usi.dag.disl.transformer;
public interface Transformer {
byte[] transform(byte[] classfileBuffer) throws Exception;
boolean propagateUninstrumentedClasses();
}
......@@ -12,7 +12,6 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.commons.AdviceAdapter;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.IntInsnNode;
......@@ -24,25 +23,11 @@ import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.VarInsnNode;
import ch.usi.dag.disl.exception.DiSLFatalException;
public abstract class AsmHelper {
public static boolean before(AbstractInsnNode first, AbstractInsnNode second) {
while (first != null) {
first = first.getNext();
if (first == second) {
return true;
}
}
return false;
}
public static boolean offsetBefore(InsnList ilst, int from, int to) {
if (from >= to) {
......@@ -254,48 +239,6 @@ public abstract class AsmHelper {
}
public static int calcMaxLocal(InsnList ilst) {
int max = 0;
for (AbstractInsnNode instr : ilst.toArray()) {
if (instr instanceof VarInsnNode) {
VarInsnNode varInstr = (VarInsnNode) instr;
switch (varInstr.getOpcode()) {
case Opcodes.LLOAD:
case Opcodes.DLOAD:
case Opcodes.LSTORE:
case Opcodes.DSTORE:
if ((varInstr.var + 2) > max) {
max = varInstr.var + 2;
}
break;
default:
if ((varInstr.var + 1) > max) {
max = varInstr.var + 1;
}
break;
}
} else if (instr instanceof IincInsnNode) {
IincInsnNode iinc = (IincInsnNode) instr;
if ((iinc.var + 1) > max) {
max = iinc.var + 1;
}
}
}
return max;
}
public static void replaceRetWithGoto(InsnList ilst) {
// collect all returns to the list
......
......@@ -14,17 +14,12 @@ public class BasicBlock {
private Set<BasicBlock> predecessors;
private Set<BasicBlock> successors;
// joins refer to the join point of a new cfg to an existing cfg in the
// joins refer to the join point of a new cfg to an existing cfg in the
// same method. NOTE that an exception handler is regarded as a new cfg
// but not included in the normal execution cfg
private Set<BasicBlock> joins;
private Set<BasicBlock> dominators;
// whether this basic block starts a loop or not
private boolean loop;
public BasicBlock(int index, AbstractInsnNode entrance,
AbstractInsnNode exit) {
this.index = index;
......@@ -34,10 +29,6 @@ public class BasicBlock {
successors = new HashSet<BasicBlock>();
predecessors = new HashSet<BasicBlock>();
joins = new HashSet<BasicBlock>();
dominators = new HashSet<BasicBlock>();
loop = false;
}
public int getIndex() {
......@@ -68,16 +59,4 @@ public class BasicBlock {
return joins;
}
public Set<BasicBlock> getDominators() {
return dominators;
}
public void setLoop(boolean loop) {
this.loop = loop;
}
public boolean isLoop() {
return loop;
}
}
......@@ -7,8 +7,6 @@ import java.util.Set;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
......@@ -16,15 +14,14 @@ import org.objectweb.asm.tree.LookupSwitchInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.VarInsnNode;
import ch.usi.dag.disl.util.AsmHelper;
import ch.usi.dag.disl.util.BasicBlockCalc;
public class CtrlFlowGraph {
public final static int NOT_FOUND = -1;
public final static int NEW = -2;
private final static int NOT_FOUND = -1;
private final static int NEW = -2;
// basic blocks of a method
private List<BasicBlock> nodes;
......@@ -252,175 +249,8 @@ public class CtrlFlowGraph {
return ends;
}
// test if the current instruction rewrites a field
// add to 'source' if it does rewrite
private boolean testStore(Set<AbstractInsnNode> source,
AbstractInsnNode instr, String owner, String name) {
if (instr.getOpcode() == Opcodes.PUTFIELD
|| instr.getOpcode() == Opcodes.PUTSTATIC) {
FieldInsnNode fin = (FieldInsnNode) instr;
if (owner.equals(fin.owner) && name.equals(fin.name)) {
source.add(instr);
return true;
}
}
return false;
}
// test if the current instruction rewrites a local slot
// add to 'source' if it does rewrite, or if it is an 'iinc' instruction,
// which updates the local slot, but still relies on the value of last store
private boolean testStore(Set<AbstractInsnNode> source,
AbstractInsnNode instr, int var) {
switch (instr.getOpcode()) {
case Opcodes.ISTORE:
case Opcodes.LSTORE:
case Opcodes.FSTORE:
case Opcodes.DSTORE:
case Opcodes.ASTORE:
if (((VarInsnNode) instr).var == var) {
source.add(instr);
return true;
}
case Opcodes.IINC:
if (((IincInsnNode) instr).var == var) {
source.add(instr);
return false;
}
default:
return false;
}
}
// test if the current instruction rewrites a field or a local slot
private boolean testStore(Set<AbstractInsnNode> source,
AbstractInsnNode instr, AbstractInsnNode criterion) {
if (criterion instanceof FieldInsnNode) {
FieldInsnNode fin = (FieldInsnNode) criterion;
return testStore(source, instr, fin.owner, fin.name);
} else if (criterion instanceof VarInsnNode) {
return testStore(source, instr, ((VarInsnNode) criterion).var);
} else {
return false;
}
}
// Get last store instructions before 'instr'
// 'criterion' is either a field instruction that indicates the field node,
// or a load/store instruction that indicates the local slot number.
public Set<AbstractInsnNode> lastStore(AbstractInsnNode instr,
AbstractInsnNode criterion) {
Set<AbstractInsnNode> source = new HashSet<AbstractInsnNode>();
Set<BasicBlock> unvisited = new HashSet<BasicBlock>();
Set<BasicBlock> visited = new HashSet<BasicBlock>();
BasicBlock current = getBB(instr);
// marked the basic block that contains 'instr' as visited when
// it is going to be fully visited in the loop
if (instr.equals(current.getExit())) {
visited.add(current);
}
while (true) {
// whether last store is found
boolean fLastStore = false;