Skip to content

Commit 0c54ffd

Browse files
committed
Stacktrace manager optimization
Store `StacktTraceManager` directly in `GlobalEnv` to prevent a synchronized hashmap lookup on every `eval()` and `seval()` call. Move `StackTraceManager` getter in `CClosure` to post-environment-clone to ensure that it does not overwrite the `StackTraceManager` of the original thread when called from a new thread(by for example `x_new_thread()`).
1 parent 97c0882 commit 0c54ffd

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

src/main/java/com/laytonsmith/core/constructs/CClosure.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,13 +207,18 @@ protected void execute(Mixed... values) throws ConfigRuntimeException, ProgramFl
207207
if(node == null) {
208208
return;
209209
}
210-
StackTraceManager stManager = env.getEnv(GlobalEnv.class).GetStackTraceManager();
211-
stManager.addStackTraceElement(new ConfigRuntimeException.StackTraceElement("<<closure>>", getTarget()));
210+
Environment environment;
212211
try {
213-
Environment environment;
214212
synchronized(this) {
215213
environment = env.clone();
216214
}
215+
} catch (CloneNotSupportedException ex) {
216+
Logger.getLogger(CClosure.class.getName()).log(Level.SEVERE, null, ex);
217+
return;
218+
}
219+
StackTraceManager stManager = environment.getEnv(GlobalEnv.class).GetStackTraceManager();
220+
stManager.addStackTraceElement(new ConfigRuntimeException.StackTraceElement("<<closure>>", getTarget()));
221+
try {
217222
CArray arguments = new CArray(node.getData().getTarget());
218223
CArray vararg = null;
219224
CClassType varargType = null;

src/main/java/com/laytonsmith/core/environments/GlobalEnv.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import java.util.HashMap;
2828
import java.util.List;
2929
import java.util.Map;
30-
import java.util.WeakHashMap;
3130
import java.util.concurrent.ConcurrentHashMap;
3231

3332
/**
@@ -54,7 +53,8 @@ public class GlobalEnv implements Environment.EnvironmentImpl, Cloneable {
5453
private BoundEvent.ActiveEvent event = null;
5554
private boolean interrupt = false;
5655
private final List<Iterator> arrayAccessList = Collections.synchronizedList(new ArrayList<>());
57-
private final WeakHashMap<Thread, StackTraceManager> stackTraceManagers = new WeakHashMap<>();
56+
private Thread stackTraceManagerThread = null;
57+
private StackTraceManager stackTraceManager = null;
5858
private final MutableObject<Map<String, Mixed>> runtimeSettings
5959
= new MutableObject<>(new ConcurrentHashMap<>());
6060
private FileOptions fileOptions;
@@ -155,6 +155,8 @@ public EnvironmentImpl clone() throws CloneNotSupportedException {
155155
} else if(!cloneVars) {
156156
clone.iVariableList = new IVariableList(clone.iVariableList);
157157
}
158+
clone.stackTraceManager = this.stackTraceManager;
159+
clone.stackTraceManagerThread = this.stackTraceManagerThread;
158160
return clone;
159161
}
160162

@@ -344,14 +346,11 @@ public List<Iterator> GetArrayAccessIteratorsFor(ArrayAccess array) {
344346
*/
345347
public StackTraceManager GetStackTraceManager() {
346348
Thread currentThread = Thread.currentThread();
347-
synchronized(stackTraceManagers) {
348-
StackTraceManager manager = stackTraceManagers.get(currentThread);
349-
if(manager == null) {
350-
manager = new StackTraceManager();
351-
stackTraceManagers.put(currentThread, manager);
352-
}
353-
return manager;
349+
if(this.stackTraceManager == null || currentThread != this.stackTraceManagerThread) {
350+
this.stackTraceManager = new StackTraceManager();
351+
this.stackTraceManagerThread = currentThread;
354352
}
353+
return this.stackTraceManager;
355354
}
356355

357356
/**

0 commit comments

Comments
 (0)