Commit 116746b0 authored by Danilo Ansaloni's avatar Danilo Ansaloni

Removed the example directory.

parent 9b4ceca9
<project name="disl-test" default="compile" basedir=".">
<property file="../../disl.version"/>
<property file="../../build.properties"/>
<property file="build.properties"/>
<property name="disl.jar.path" value="../../build/dislserver-${disl.version}.jar"/>
<path id="buildpath">
<pathelement location="${disl.jar.path}"/>
<pathelement location="../../${asm.path}"/>
</path>
<target name="check-disl-jar">
<available file="${disl.jar.path}" property="disl.jar.present"/>
</target>
<target name="report-missing-jar" depends="check-disl-jar" unless="disl.jar.present">
<fail message="DiSL jar not found at ${disl.jar.path}. Build DiSL first!" />
</target>
<target name="compile" depends="report-missing-jar">
<mkdir dir="bin"/>
<javac srcdir="src" destdir="bin" debug="true" includeAntRuntime="false">
<classpath refid="buildpath"/>
</javac>
</target>
<target name="check-test-property">
<condition property="test.set">
<isset property="test.name"/>
</condition>
</target>
<target name="report-missing-property" depends="check-test-property" unless="test.set">
<fail message="Property test.name is not set. Set it using -Dtest.name=value" />
</target>
<property name="test.path" value="ch/usi/dag/disl/example/${test.name}"/>
<target name="package" depends="report-missing-property,compile" description="create instrumentation package for specified test">
<mkdir dir="build"/>
<jar jarfile="../../build/${instr.jar.name}"
basedir="./bin"
includes="${test.path}/**"
excludes="${test.path}/TargetClass*.class ${test.path}/MANIFEST.MF"
manifest="./src/${test.path}/MANIFEST.MF">
</jar>
</target>
<target name="clean">
<delete dir="bin"/>
<delete dir="build"/>
</target>
</project>
# THESE ARE THE BASIC SETTINGS
#sun.instrument.*
# THESE ARE THE RUNTIME CLASSES THAT MUST NOT BE WOVEN
#ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.runtime.*
# PROBLEM WITH FOP (CODE TOO BIG)
#org/apache/fop/fonts/CodePointMapping
# BEGIN JDK WEAVING
# COMMENT THE FOLLOWING FOR FULL COVERAGE
#org.jcp.*
#org.omg.*
#org.xml.*
#org.ietf.*
#java.lang.Object.*
#javax.*.*
#com.sun.*
#com.apple.*
#sun.*.*
#sunx.*
#org.apache.batik.xml.XMLCharacters.<clinit>
# END JDK
# This is a sample configuration with relative paths
# you can use full path using file:/// format
../../lib/asm-debug-all-4.0.jar
../../test/lib/remote-jborat.jar
../../lib/jborat.jar
# This is a sample configuration with relative paths
# you can use full path using file:/// format
../../lib/asm-debug-all-4.0.jar
../../build/disl-unspec.jar
../../build/dislinstr.jar
# /bin/sh
EXPECTED_ARGS=1
if [ $# -gt $EXPECTED_ARGS ]
then
echo "Usage: `basename $0` [pkg]"
exit
fi
SERVER_FILE=.server.pid
export SERVER_FILE
if [ -e ${SERVER_FILE} ]
then
kill -KILL `cat ${SERVER_FILE}`
rm .server.pid
fi
DISL_CLASS="./bin/ch/usi/dag/disl/example/fieldsImmutabilityAnalysis/DiSLClass.class"
TARGET_CLASS="ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.TargetClass"
if [ "$1" = "pkg" ]
then
# start server and take pid
ant package -Dtest.name=fieldsImmutabilityAnalysis
./runServer.sh
else
# start server and take pid
./runServer.sh -Ddisl.classes=${DISL_CLASS}
fi
# wait for server startup
sleep 5
# run client
./runClient.sh ${TARGET_CLASS}
# kill server
kill -KILL `cat ${SERVER_FILE}`
rm .server.pid
#!/bin/bash
OS=`uname`
if [ "${OS}" = "Darwin" ]; then
C_AGENT="../../src-agent-c/libdislagent.jnilib"
else
C_AGENT="../../src-agent-c/libdislagent.so"
fi
# 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
# 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 \
java $* \
-Ddisl.exclusionList="conf/exclusion.lst" \
-Ddislserver.continuous=true \
-jar ../../build/dislserver-unspec.jar \
&
echo $! > ${SERVER_FILE}
package ch.usi.dag.disl.example.fieldsImmutabilityAnalysis;
import java.util.ArrayDeque;
import java.util.Deque;
import ch.usi.dag.disl.annotation.After;
import ch.usi.dag.disl.annotation.AfterReturning;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.annotation.ThreadLocal;
import ch.usi.dag.disl.dynamiccontext.DynamicContext;
import ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.runtime.ImmutabilityAnalysis;
import ch.usi.dag.disl.marker.BodyMarker;
import ch.usi.dag.disl.marker.BytecodeMarker;
public class DiSLClass {
@ThreadLocal
private static Deque<Object> objectsUnderConstruction;
/** STACK MAINTENANCE **/
@Before(marker = BodyMarker.class, guard = OnlyInit.class)
public static void beforeConstructor(DynamicContext dc) {
try {
if (objectsUnderConstruction == null)
objectsUnderConstruction = new ArrayDeque<Object>();
objectsUnderConstruction.push(dc.getThis());
}
catch (Throwable t) {
t.printStackTrace();
}
}
@After(marker = BodyMarker.class, guard = OnlyInit.class)
public static void afterConstructor() {
ImmutabilityAnalysis.instanceOf().popStackIfNonNull(objectsUnderConstruction);
}
/** ALLOCATION SITE **/
@AfterReturning(marker = BytecodeMarker.class, args = "new")
public static void afterReturningInit(MyMethodStaticContext sc, DynamicContext dc) {
ImmutabilityAnalysis.instanceOf().onObjectInitialization(
dc.getStackValue(0, Object.class), //the allocated object
sc.getAllocationSite() //the allocation site
);
}
/** FIELD ACCESSES **/
@Before(marker = BytecodeMarker.class, args = "putfield")
public static void beforeFieldWrite(MyMethodStaticContext sc, DynamicContext dc) {
ImmutabilityAnalysis.instanceOf().onFieldWrite(
dc.getStackValue(1, Object.class), //the accessed object
sc.getFieldId(), //the field identifier
objectsUnderConstruction //the stack of constructors
);
}
@Before(marker = BytecodeMarker.class, args = "getfield")
public static void afterFieldWrite(MyMethodStaticContext sc, DynamicContext dc) {
ImmutabilityAnalysis.instanceOf().onFieldRead(
dc.getStackValue(0, Object.class), //the accessed object
sc.getFieldId(), //the field identifier
objectsUnderConstruction //the stack of constructors
);
}
}
Manifest-Version: 1.0
DiSL-Classes: ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.DiSLClass
\ No newline at end of file
package ch.usi.dag.disl.example.fieldsImmutabilityAnalysis;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
public class MyMethodStaticContext extends MethodStaticContext {
public String getAllocationSite() {
int idx = 0;
for(AbstractInsnNode instr = staticContextData.getRegionStart(); instr != null; instr = instr.getPrevious()) {
idx++;
}
return thisMethodFullName() + thisMethodDescriptor() + "[" + String.valueOf(idx) + "]";
}
public String getFieldId() {
AbstractInsnNode instr = staticContextData.getRegionStart();
if (instr.getOpcode() == Opcodes.PUTFIELD || instr.getOpcode() == Opcodes.GETFIELD) {
return ((FieldInsnNode) instr).owner + ":" + ((FieldInsnNode) instr).name + ":" + ((FieldInsnNode) instr).desc.replace('.', '/');
} else {
throw new RuntimeException("[MyMethodStaticContext.getFieldId] Error! Improper use of getFieldId()");
}
}
}
package ch.usi.dag.disl.example.fieldsImmutabilityAnalysis;
import ch.usi.dag.disl.annotation.GuardMethod;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
public class OnlyInit {
@GuardMethod
public static boolean isApplicable(MethodStaticContext msc) {
return msc.thisMethodName().equals("<init>");
}
}
package ch.usi.dag.disl.example.fieldsImmutabilityAnalysis;
import java.util.ArrayList;
import java.util.List;
public class TargetClass {
private int immutable;
private int mutable;
private int neverAccessed1;
private int neverAccessed2;
public TargetClass() {
immutable = 3;
}
// private static List<Integer> list;
//
// static{
// list = new ArrayList<Integer>();
//
// }
//
// private class Inner extends TargetClass {
// private int inner_mutable_1;
// private int iner_immutable_1;
//
// public Inner(){
// this.iner_immutable_1=2;
// }
//
// public void setTargetClassMutableValue(int value){
// super.mutable_1=3;
// }
// }
//
// private int immutable_1;
// private int immutable_2;
// private int mutable_1;
//
// private void useAnonymousClass(){
// Anomymous ac = new Anomymous(){
// int anonymous_immutable =4;
// void setMutableValue(int value){
// this.anonymous_immutable = value;
// }
// };
// }
//
//
//
// public TargetClass(){
// immutable_1=3;
// init(75);
// }
//
// private void init(int value) {
// immutable_2=value;
// }
//
// public static void main(String[] args){
// TargetClass tc = new TargetClass();
// tc.mutable_1 = 21;
// TargetClass.Inner ic = tc.new Inner();
// ic.setTargetClassMutableValue(3);
// tc.useAnonymousClass();
// System.out.println("TargetClass successfully executed!");
// }
// public interface Anomymous {
//
// }
//
public static void main(String[]args) {
TargetClass tc = new TargetClass();
System.err.println(tc.immutable);
tc.mutable = 6;
System.err.println(tc.mutable);
}
}
\ No newline at end of file
package ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.runtime;
public class FieldState {
private final String fieldId;
private State currentState = State.VIRGIN;
private long numReads, numWrites;
private boolean defaultInit = false;
private enum State { VIRGIN, IMMUTABLE, MUTABLE };
public FieldState(String fieldId) {
this.fieldId = fieldId;
}
public synchronized String getFieldId() { return fieldId; }
public synchronized State getState() { return currentState; }
public synchronized long getNumReads() { return numReads; }
public synchronized long getNumWrites() { return numWrites; }
public synchronized boolean isDefaultInit() { return defaultInit; }
public synchronized void onRead() {
numReads++;
switch (currentState) {
case VIRGIN:
defaultInit = true;
currentState = State.IMMUTABLE;
break;
}
}
public synchronized void onWrite(boolean isInDynamicExtendOfConstructor) {
numWrites++;
switch(currentState) {
case VIRGIN:
case IMMUTABLE:
currentState = isInDynamicExtendOfConstructor ? State.IMMUTABLE : State.MUTABLE;
break;
}
}
}
package ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.runtime;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.zip.GZIPOutputStream;
import ch.usi.dag.disl.dynamicbypass.*;
public class ImmutabilityAnalysis {
private final MyWeakKeyIdentityHashMap<Object, FieldState[]> fieldStateMap;
private final HashSet<String> reflectionErrors;
static {
instanceOfIA = new ImmutabilityAnalysis();
}
private static final ImmutabilityAnalysis instanceOfIA;
private ImmutabilityAnalysis() {
PrintStream ps = null;
try {
String dumpFile = System.getProperty("dump", "dump.tsv.gz");
ps = new PrintStream(new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(dumpFile))));
} catch (Throwable t) {
t.printStackTrace();
System.exit(-1);
}
final TabSeparatedValuesDumper dumper = new TabSeparatedValuesDumper(ps);
fieldStateMap = new MyWeakKeyIdentityHashMap<Object, FieldState[]>(dumper);
reflectionErrors = new HashSet<String>();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
DynamicBypass.activate();
System.err.println("In shutdown hook!");
try {
synchronized (fieldStateMap) {
fieldStateMap.dump();
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
dumper.close();
}
}
});
}
public static ImmutabilityAnalysis instanceOf() {
return instanceOfIA;
}
public void onObjectInitialization(Object allocatedObj, String allocSite) {
try {
String objectID = getObjectID(allocatedObj, allocSite);
getOrCreateFieldsArray(allocatedObj, objectID);
} catch (Throwable t) {
t.printStackTrace();
}
}
public void onFieldWrite(Object accessedObj, String fieldId, Deque<Object> stack) {
try {
FieldState fs = getOrCreateFieldState(accessedObj, fieldId);
if(fs != null) {
fs.onWrite(isUnderConstruction(accessedObj, stack));
}
} catch (Throwable t) {
t.printStackTrace();
}
}
public void onFieldRead(Object accessedObj, String fieldId, Deque<Object> stackTL) {
try {
FieldState fs = getOrCreateFieldState(accessedObj, fieldId);
if(fs != null) {
fs.onRead();
}
} catch(Throwable t) {
t.printStackTrace();
}
}
private FieldState getOrCreateFieldState(Object accessedObj, String fieldId) {
FieldState[] fieldsArray = getFieldsArray(accessedObj);
if(fieldsArray == null) {
String objectID = getObjectID(accessedObj, null);
fieldsArray = getOrCreateFieldsArray(accessedObj, objectID);
}
Short s = Offsets.getFieldOffset(fieldId);
try {
return fieldsArray[s];
}
catch(NullPointerException e) {
synchronized (reflectionErrors) {
if(!reflectionErrors.contains(fieldId)) {
reflectionErrors.add(fieldId);
System.err.println("[ImmutabilityAnalysis.getOrCreateFieldState] Warning: unregistered access to: "
+ fieldId
+ "; skipping event");
}
}
return null;
}
}
private FieldState[] getFieldsArray(Object ownerObj) {
synchronized (fieldStateMap) {
return fieldStateMap.get(ownerObj);
}
}
private FieldState[] getOrCreateFieldsArray(Object ownerObj, String objectID) {
Offsets.registerIfNeeded(ownerObj.getClass());
FieldState[] fieldsArray;
synchronized (fieldStateMap) {
if ((fieldsArray = fieldStateMap.get(ownerObj)) == null) {
String[] fieldIDs = Offsets.getFieldIDs(ownerObj.getClass());
fieldsArray = new FieldState[fieldIDs.length];
for(int i = 0; i < fieldIDs.length; i++) {
fieldsArray[i] = new FieldState(fieldIDs[i]);
}
fieldStateMap.put(ownerObj, fieldsArray, objectID);
}
}
return fieldsArray;
}
public boolean isUnderConstruction(Object object, Deque<Object> objectsUnderConstruction) {
if (objectsUnderConstruction != null) {
for (Iterator<Object> iter = objectsUnderConstruction.iterator(); iter.hasNext();) {
if (iter.next() == object) {
return true;
}
}
}
return false;
}
private String getObjectID(Object accessedObj, String allocSite) {
return accessedObj.getClass().getName() + ":" + allocSite;
}
public void popStackIfNonNull(Deque<Object> stackTL) {
try {
stackTL.pop();
} catch(NullPointerException e) {
System.err.println("The stack is null " + Thread.currentThread().getName());
}
}
}
package ch.usi.dag.disl.example.fieldsImmutabilityAnalysis.runtime;
/**
* Identity-based hashmap that internally uses {@code MyWeakReference} to
* store {@code keys}.
* Key values can be made finalizable, finalized, and then reclaimed.
*
* If the size of the map (the number of key-value mappings) sufficiently
* exceeds the expected maximum size, the number of buckets is increased.
* Upon resizing, cleared references to keys are removed from the map.
* It is possible to register a dumper to be executed upon removal.
* The same dumper can be used to dump all entries in the map.
*
* The implementation is NOT thread-safe.
*/
public final class MyWeakKeyIdentityHashMap<K,V> {
private static final int DEFAULT_INITIAL_CAPACITY = 4096;
private static final int INCREMENT_FACTOR = 2;
private transient Object[] table;
private int size = 0;
private transient int threshold;
private int currentSize;