Commit 9d9aee0d authored by Aibek Sarimbekov's avatar Aibek Sarimbekov

Added recasted hprof

parent 32990332
<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}"/>
<pathelement location="../../build/dislagent-unspec.jar"/>
</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
# PROBLEM WITH FOP (CODE TOO BIG)
# 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.*
# END JDK
# /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/hprof/DiSLClass.class"
TARGET_CLASS="ch.usi.dag.disl.example.hprof.TargetClass"
if [ "$1" = "pkg" ]
then
# start server and take pid
ant package -Dtest.name=hprof
./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 -Xmx4g -XX:MaxPermSize=128m -noverify -agentpath:${C_AGENT} \
-javaagent:../../build/dislagent-unspec.jar \
-Xbootclasspath/a:../../build/dislagent-unspec.jar:../../build/dislinstr.jar \
-cp bin/ \
-jar /Users/aibeksarimbekov/Software/dacapo-9.12-bach.jar -n 5 -s small avrora
#$*
#!/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 $* \
-Ddislserver.instrumented="instrumented" \
-Ddislserver.uninstrumented="uninstrumented" \
-Ddisl.exclusionList="conf/exclusion.lst" \
-Ddislserver.continuous=true \
-jar ../../build/dislserver-unspec.jar \
&
echo $! > ${SERVER_FILE}
package ch.usi.dag.disl.example.hprof;
import java.util.Stack;
import ch.usi.dag.disl.annotation.AfterReturning;
import ch.usi.dag.disl.annotation.ThreadLocal;
import ch.usi.dag.disl.dynamiccontext.DynamicContext;
import ch.usi.dag.disl.example.hprof.runtime.HPROFAnalysis;
import ch.usi.dag.disl.marker.BytecodeMarker;
import ch.usi.dag.disl.marker.NewObjMarker;
import ch.usi.dag.disl.staticcontext.uid.UniqueMethodId;
public class DiSLClass {
@ThreadLocal
public static Stack<Object> objStack;
@AfterReturning(marker = BytecodeMarker.class, args = "newarray, anewarray, multianewarray")
public static void eee(DynamicContext dc, MyMethodStaticContext sc, UniqueMethodId id) {
Object allocatedObj = dc.getStackValue(0, Object.class);
// int offset = sc.getOffset();
// int methodID = id.get();
// int clID = System.identityHashCode(allocatedObj.getClass().getClassLoader());
HPROFAnalysis.instanceOf().onObjectInitialization(
allocatedObj, //the allocated object
sc.getExtendedID(),
System.identityHashCode(allocatedObj.getClass().getClassLoader())
);
}
@AfterReturning(marker = BytecodeMarker.class, args="new")
public static void fff(DynamicContext dc) {
if(objStack == null) objStack = new Stack<Object>();
objStack.push(dc.getStackValue(0, Object.class));
}
/** ALLOCATION SITE **/
@AfterReturning(marker = NewObjMarker.class, order = 10)
public static void afterReturningNew(MyMethodStaticContext sc, DynamicContext dc, UniqueMethodId id) {
// System.err.println("allocation snippet in " + sc.thisMethodFullName());
// if(objStack != null) {
if(!objStack.empty()) {
Object allocatedObj = objStack.pop();
// int offset = sc.getOffset();
// int methodID = id.get();
// int clID = System.identityHashCode(allocatedObj.getClass().getClassLoader());
HPROFAnalysis.instanceOf().onObjectInitialization(
allocatedObj, //the allocated object
sc.getExtendedID(),
System.identityHashCode(allocatedObj.getClass().getClassLoader())
);
} else {
System.out.println("EMPTY STACK\t" + Thread.currentThread().getName() +"\t" + sc.thisMethodFullName());
}
// }
}
}
Manifest-Version: 1.0
DiSL-Classes: ch.usi.dag.disl.example.hprof.DiSLClass
\ No newline at end of file
package ch.usi.dag.disl.example.hprof;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
public class MyMethodStaticContext extends MethodStaticContext {
public int getOffset() {
int idx = 0;
for(AbstractInsnNode instr = staticContextData.getRegionStart(); instr != null; instr = instr.getPrevious()) {
idx++;
}
return idx;
}
public String getExtendedID() {
return thisMethodFullName() + "_" + getOffset() + "_";
}
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()");
}
}
public String getInstructionTarget(){
AbstractInsnNode instr = staticContextData.getRegionStart();
if (instr.getOpcode() == Opcodes.INVOKESPECIAL) {
return ((MethodInsnNode) instr).owner + ":" + ((MethodInsnNode) instr).name;
} else {
throw new RuntimeException("[MyMethodStaticContext.getFieldId] Error! Improper use of getFieldId()");
}
}
}
package ch.usi.dag.disl.example.hprof;
public class TargetClass {
public static void main(String[]args) {
System.err.println("Hello!!");
for(int i=0; i<10000;i++) {
new Object();
}
}
}
package ch.usi.dag.disl.example.hprof.runtime;
public class Counter {
private int totalNumberOfObjects;
private int currentNumberOfObjects;
private final String objectType;
private long totalSize;
private long currentSize;
public Counter(String objType) {
this.objectType = objType;
}
public int getTotalNumberOfObjects() {
return totalNumberOfObjects;
}
public long getTotalSize(){
return totalSize;
}
public long getCurrentSize(){
return currentSize;
}
public int getCurrentNumberOfObjects() {
return currentNumberOfObjects;
}
public synchronized void incrementCounter(long size) {
totalNumberOfObjects++;
currentNumberOfObjects++;
this.totalSize += size;
this.currentSize += size;
}
public synchronized void decrementCounters(long size) {
currentNumberOfObjects--;
this.currentSize -= size;
}
public String getObjectType(){
return objectType;
}
public String toString() {
return getObjectType() + "\t" + "...";
}
}
package ch.usi.dag.disl.example.hprof.runtime;
import java.lang.instrument.Instrumentation;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
import ch.usi.dag.disl.dynamicbypass.DynamicBypass;
import ch.usi.dag.dislagent.DiSLAgent;
public class HPROFAnalysis {
private class ReaperThread extends Thread {
public ReaperThread() {
setDaemon(true);
}
public void run() {
DynamicBypass.activate();
//TODO: maybe this should be an int --> call gc multiple times in a row if not refs are available
boolean blocking = false;
while(true) {
try {
Object obj;
// if(!blocking) {
// obj = refqueue.poll();
// } else {
obj = refqueue.remove();
// }
// if(obj != null) {
// blocking = false;
MyWeakReference mwr = weakReferenceMap.remove(obj);
if(mwr != null) {
String fullAllocSiteID = mwr.getFullAllocSiteID();
counterMap.get(fullAllocSiteID).decrementCounters(mwr.getSize());
} else {
//TODO: write something more meaningful
System.err.println("WEIRD! THE WEAKREFERENCE WAS NOT IN THE MAP!");
}
// } else {
// blocking = true;
// callGC(0);
// }
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
//HashMap that contains object IDs as a key and an object of type MyWeakReference as the value
private final ConcurrentHashMap<Reference<? extends Object>, MyWeakReference> weakReferenceMap;
//HashMap that contains object IDs as a key and a wrapper object of type Counter as the value
protected static final ConcurrentHashMap<String, Counter> counterMap;
private static final ReferenceQueue<Object> refqueue;
private final Thread reaper;
private static final HPROFAnalysis instanceOfHPROF;
private static final Instrumentation instr;
static {
instanceOfHPROF = new HPROFAnalysis();
refqueue = new ReferenceQueue<Object>();
counterMap = new ConcurrentHashMap<String, Counter>();
instr = DiSLAgent.getInstrumentation();
}
private HPROFAnalysis() {
weakReferenceMap = new ConcurrentHashMap<Reference<? extends Object>, MyWeakReference>();
reaper = new ReaperThread();
reaper.start();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
DynamicBypass.activate();
//
System.err.println("In shutdown hook!");
//
try {
//
Iterator<Entry<String, Counter>> iterator = counterMap.entrySet().iterator();
int idx = 0;
while (iterator.hasNext()) {
idx++;
Entry<String, Counter> entry = iterator.next();
String key = entry.getKey();
Counter myCounter = entry.getValue();
//TODO: myCounter.toString();
int totalNumber = myCounter.getTotalNumberOfObjects();
long totalSize = myCounter.getTotalSize();
long currentSize = myCounter.getCurrentSize();
int currentNumber = myCounter.getCurrentNumberOfObjects();
String typeOfObject = myCounter.getObjectType();
System.err.println(idx + " TOTAL SIZE " + totalSize + " TOTAL # " + totalNumber + " CURRENT SIZE " + currentSize + " CURRENT # "+ currentNumber + " TYPE OF THE OBJECT " + typeOfObject + " ALLOCATION SITE: " + key );
}
} catch (Throwable e) {
e.printStackTrace();
}
}
});
}
public static HPROFAnalysis instanceOf() {
return instanceOfHPROF;
}
public void onObjectInitialization(Object allocatedObj, String allocSiteID, int clID) {
try {
long size = instr.getObjectSize(allocatedObj);
String fullAllocSiteID = allocSiteID + clID;
MyWeakReference myReference;
Counter myCounter;
//TODO: do this at instrumentation time? (may require a @SyntheticLocal stack...)
String objType = allocatedObj.getClass().getName();
myReference = new MyWeakReference(allocatedObj, fullAllocSiteID, size, refqueue);
weakReferenceMap.put(myReference, myReference);
if ((myCounter = counterMap.get(fullAllocSiteID)) == null) {
myCounter = new Counter(objType);
Counter tmpCounter;
if((tmpCounter = counterMap.putIfAbsent(fullAllocSiteID, myCounter)) != null) {
myCounter = tmpCounter;
}
}
myCounter.incrementCounter(size);
} catch (Throwable t) {
t.printStackTrace();
}
}
private static void callGC(long sleepTime) {
System.runFinalization();
System.gc();
if(sleepTime > 0) {
try { Thread.sleep(sleepTime); } catch(InterruptedException e) { e.printStackTrace(); }
}
}
}
package ch.usi.dag.disl.example.hprof.runtime;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
public class MyWeakReference extends PhantomReference<Object>{
private final String fullAllocSiteID;
private final long size;
public MyWeakReference(Object obj, String fullAllocSiteID, long size, ReferenceQueue<Object> refqueue) {
super(obj,refqueue);
this.fullAllocSiteID = fullAllocSiteID;
this.size = size;
}
public String getFullAllocSiteID(){
return fullAllocSiteID;
}
public long getSize() {
return size;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment