Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ public Context swap(Context context) {

static final class ScopeStackThreadLocal extends ThreadLocal<ScopeStack> {

private final ScopeStack[] fastStacks = new ScopeStack[2048]; // This should be tuned
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something to consider from https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#getId--:

When a thread is terminated, this thread ID may be reused

What if an instrumentation left one or more unclosed scopes on a scope stack and the owning thread died and its id was reused? Or what if a thread dies during traced work before the scope stack could be cleaned up?


private final ProfilingContextIntegration profilingContextIntegration;

ScopeStackThreadLocal(ProfilingContextIntegration profilingContextIntegration) {
Expand All @@ -401,6 +403,41 @@ static final class ScopeStackThreadLocal extends ThreadLocal<ScopeStack> {
protected ScopeStack initialValue() {
return new ScopeStack(profilingContextIntegration);
}

@Override
public ScopeStack get() {
final long id = Thread.currentThread().getId();
if (id >= 0 && id < this.fastStacks.length) {
ScopeStack ret = fastStacks[(int) id];
if (ret == null) {
ret = initialValue();
fastStacks[(int) id] = ret;
}
return ret;
} else {
return super.get();
}
}

@Override
public void set(ScopeStack value) {
final long id = Thread.currentThread().getId();
if (id >= 0 && id < this.fastStacks.length) {
fastStacks[(int) id] = value;
} else {
super.set(value);
}
}

@Override
public void remove() {
final long id = Thread.currentThread().getId();
if (id >= 0 && id < this.fastStacks.length) {
fastStacks[(int) id] = null;
} else {
super.remove();
}
}
}

private void scheduleRootIterationScopeCleanup(ScopeStack scopeStack, ContinuableScope scope) {
Expand Down