Browse Source

don't hold hard references to state in this context. Assume single threaded unless told otherwise. Provide reset to ditch memory we are holding.

tags/POST_MEMORY_CHANGES
acolyer 18 years ago
parent
commit
594f80c4b8

+ 37
- 11
bridge/src/org/aspectj/bridge/context/CompilationAndWeavingContext.java View File

* ******************************************************************/ * ******************************************************************/
package org.aspectj.bridge.context; package org.aspectj.bridge.context;


import java.lang.ref.WeakReference;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
// context stacks, one per thread // context stacks, one per thread
private static Map contextMap = new HashMap(); private static Map contextMap = new HashMap();
// single thread mode stack
private static Stack contextStack = new Stack();
// formatters, by phase id // formatters, by phase id
private static Map formatterMap = new HashMap(); private static Map formatterMap = new HashMap();
private static ContextFormatter defaultFormatter = new DefaultFormatter(); private static ContextFormatter defaultFormatter = new DefaultFormatter();
private static boolean multiThreaded = false;
/** /**
* this is a static service * this is a static service
// for testing... // for testing...
public static void reset() { public static void reset() {
contextMap = new HashMap(); contextMap = new HashMap();
contextStack = new Stack();
formatterMap = new HashMap(); formatterMap = new HashMap();
nextTokenId = 1; nextTokenId = 1;
} }
public static void setMultiThreaded(boolean mt) { multiThreaded = mt; }
public static void registerFormatter(int phaseId, ContextFormatter aFormatter) { public static void registerFormatter(int phaseId, ContextFormatter aFormatter) {
formatterMap.put(new Integer(phaseId),aFormatter); formatterMap.put(new Integer(phaseId),aFormatter);
} }
Stack explanationStack = new Stack(); Stack explanationStack = new Stack();
for (Iterator iter = contextStack.iterator(); iter.hasNext();) { for (Iterator iter = contextStack.iterator(); iter.hasNext();) {
ContextStackEntry entry = (ContextStackEntry) iter.next(); ContextStackEntry entry = (ContextStackEntry) iter.next();
explanationStack.push(getFormatter(entry).formatEntry(entry.phaseId,entry.data));
Object data = entry.getData();
if (data != null) {
explanationStack.push(getFormatter(entry).formatEntry(entry.phaseId,data));
}
} }
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
while (!explanationStack.isEmpty()) { while (!explanationStack.isEmpty()) {
public static ContextToken enteringPhase(int phaseId, Object data) { public static ContextToken enteringPhase(int phaseId, Object data) {
Stack contextStack = getContextStack(); Stack contextStack = getContextStack();
ContextTokenImpl nextToken = nextToken(); ContextTokenImpl nextToken = nextToken();
contextStack.push(new ContextStackEntry(nextToken,phaseId,data));
contextStack.push(new ContextStackEntry(nextToken,phaseId,new WeakReference(data)));
return nextToken; return nextToken;
} }
} }
private static Stack getContextStack() { private static Stack getContextStack() {
if (contextMap.containsKey(Thread.currentThread())) {
return (Stack) contextMap.get(Thread.currentThread());
} else {
Stack contextStack = new Stack();
contextMap.put(Thread.currentThread(),contextStack);
if (!multiThreaded) {
return contextStack; return contextStack;
} }
else {
if (contextMap.containsKey(Thread.currentThread())) {
return (Stack) contextMap.get(Thread.currentThread());
} else {
Stack contextStack = new Stack();
contextMap.put(Thread.currentThread(),contextStack);
return contextStack;
}
}
} }
private static ContextTokenImpl nextToken() { private static ContextTokenImpl nextToken() {
private static class ContextStackEntry { private static class ContextStackEntry {
public ContextTokenImpl contextToken; public ContextTokenImpl contextToken;
public int phaseId; public int phaseId;
public Object data;
public ContextStackEntry(ContextTokenImpl ct, int phase, Object data) {
private WeakReference dataRef;
public ContextStackEntry(ContextTokenImpl ct, int phase, WeakReference data) {
this.contextToken = ct; this.contextToken = ct;
this.phaseId = phase; this.phaseId = phase;
this.data = data;
this.dataRef = data;
}
public Object getData() {
return dataRef.get();
} }
public String toString() { public String toString() {
return CompilationAndWeavingContext.getFormatter(this).formatEntry(phaseId, data);
Object data = getData();
if (data == null) {
return "referenced context entry has gone out of scope";
} else {
return CompilationAndWeavingContext.getFormatter(this).formatEntry(phaseId, data);
}
} }
} }

Loading…
Cancel
Save