Commit 9d59b1ce authored by Danilo Ansaloni's avatar Danilo Ansaloni

Cleanup to example/hprof.

parent 3d2bf182
......@@ -32,7 +32,7 @@ public class DiSLClass {
}
/** ALLOCATION SITE **/
@AfterReturning(marker = NewObjMarker.class, order = 10)
@AfterReturning(marker = NewObjMarker.class, order = 10)
public static void afterReturningNew(MyMethodStaticContext sc, DynamicContext dc, UniqueMethodId id) {
if(!objStack.empty()) {
......
......@@ -2,61 +2,59 @@ package ch.usi.dag.disl.example.hprof.runtime;
public class Counter {
private final String objectType;
private int totalNumberOfObjects;
private int currentNumberOfObjects;
private long totalSize;
private long currentSize;
//maybe not the best solution
private String allocationSite;
private int totalNumberOfObjects;
private int currentNumberOfObjects;
private final String objectType;
private long totalSize;
private long currentSize;
//maybe not the best solution
private String allocationSite;
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 setAllocationSite(String allocationSite) {
this.allocationSite = allocationSite;
}
public String getAllocationSite() {
return allocationSite;
}
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 getCurrentSize() + "\t" + getCurrentNumberOfObjects() + "\t" + getTotalSize() + "\t" + getTotalNumberOfObjects() + "\t" + getObjectType() + "\t" + getAllocationSite();
}
public Counter(String objType) {
this.objectType = objType;
}
public String getObjectType(){
return objectType;
}
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 void setAllocationSite(String allocationSite) {
this.allocationSite = allocationSite;
}
public synchronized int getTotalNumberOfObjects() {
return totalNumberOfObjects;
}
public synchronized int getCurrentNumberOfObjects() {
return currentNumberOfObjects;
}
public synchronized long getTotalSize(){
return totalSize;
}
public synchronized long getCurrentSize(){
return currentSize;
}
public String getAllocationSite() {
return allocationSite;
}
public String toString() {
return getCurrentSize() + "\t" + getCurrentNumberOfObjects() + "\t" + getTotalSize() + "\t" + getTotalNumberOfObjects() + "\t" + getObjectType() + "\t" + getAllocationSite();
}
}
......@@ -2,21 +2,10 @@ package ch.usi.dag.disl.example.hprof.runtime;
import java.util.Comparator;
public class CounterComparator implements Comparator<Counter> {
public class CounterComparator implements Comparator<Object> {
@Override
public int compare(Object arg0, Object arg1) {
long arg0Size = ((Counter) arg0).getTotalSize();
long arg1Size = ((Counter) arg1).getTotalSize();
if(arg0Size > arg1Size)
return -1;
else if (arg0Size < arg1Size)
return 1;
else
return 0;
}
@Override
public int compare(Counter arg0, Counter arg1) {
return (arg0.getTotalSize() > arg1.getTotalSize()) ? 1 : -1;
}
}
......@@ -2,13 +2,15 @@ package ch.usi.dag.disl.example.hprof.runtime;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.lang.instrument.Instrumentation;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import ch.usi.dag.disl.dynamicbypass.DynamicBypass;
......@@ -16,146 +18,117 @@ 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 {
ArrayList<Counter> list = new ArrayList<Counter>();
Iterator<Entry<String, Counter>> iterator = counterMap.entrySet().iterator();
int idx = 0;
while (iterator.hasNext()) {
Entry<String, Counter> entry = iterator.next();
String key = entry.getKey();
Counter myCounter = entry.getValue();
myCounter.setAllocationSite(key);
list.add(myCounter);
}
Object[] counters = list.toArray();
Arrays.sort(counters, new CounterComparator());
for (Object counter:counters) {
idx++;
System.err.println(idx + "\t" + ((Counter)counter).toString());
}
} 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(); }
}
}
//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 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>();
new ReaperThread().start();
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
DynamicBypass.activate();
System.err.println("In shutdown hook!");
try {
PrintWriter pw = new PrintWriter(new BufferedOutputStream(new FileOutputStream("dump.log")));
TreeSet<Counter> set = new TreeSet<Counter>(new CounterComparator());
for (Iterator<Entry<String, Counter>> iter = counterMap.entrySet().iterator(); iter.hasNext();) {
Entry<String, Counter> entry = iter.next();
String key = entry.getKey();
Counter myCounter = entry.getValue();
myCounter.setAllocationSite(key);
set.add(myCounter);
}
int idx = 0;
for(Counter counter : set.descendingSet()) {
pw.println(idx++ + "\t" + counter.toString());
}
pw.flush();
pw.close();
} 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 class ReaperThread extends Thread {
public ReaperThread() {
setDaemon(true);
}
public void run() {
DynamicBypass.activate();
while(true) {
try {
Object obj = refqueue.remove();
MyWeakReference mwr = weakReferenceMap.remove(obj);
if(mwr != null) {
String fullAllocSiteID = mwr.getFullAllocSiteID();
counterMap.get(fullAllocSiteID).decrementCounters(mwr.getSize());
} else {
System.err.println("[HPROFAnalysis.ReaperThread] Error: the weak reference map does not have an entry for: " + obj.toString());
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
......@@ -6,7 +6,7 @@ import ch.usi.dag.disl.dynamicbypass.Bootstrap;
public class DiSLAgent {
private static Instrumentation myInstrumentation;
private static volatile Instrumentation myInstrumentation;
public static void premain(String agentArguments,
Instrumentation instrumentation) {
......
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