Created
October 20, 2017 13:15
-
-
Save raphw/96e7c81d7c719cf7991b361bb7266c70 to your computer and use it in GitHub Desktop.
Approaches to stack extraction.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.openjdk.jmh.annotations.Benchmark; | |
public class StackWalkerExtraction { | |
private static Object call(int depth, Callable<?> result) throws Exception { | |
if (depth == 0) { | |
return result.call(); | |
} else { | |
return call(depth - 1, result); | |
} | |
} | |
@Benchmark | |
public Object snapshot() throws Exception { | |
return call(100, () -> StackWalker.getInstance().walk(new InstanaWalker(35, 0))); | |
} | |
@Benchmark | |
public Object complete() throws Exception { | |
return call(100, () -> StackWalker.getInstance().walk(new InstanaWalker(35, 0))); | |
} | |
private class RawWalker implements Function<Stream<StackWalker.StackFrame>, StackWalker.StackFrame[]> { | |
private final int stackDepth, startFrame; | |
RawWalker(int stackDepth, int startFrame) { | |
this.stackDepth = stackDepth; | |
this.startFrame = startFrame; | |
} | |
@Override | |
public StackWalker.StackFrame[] apply(Stream<StackWalker.StackFrame> stackFrameStream) { | |
StackWalker.StackFrame[] elements = new StackWalker.StackFrame[stackDepth]; | |
Iterator<StackWalker.StackFrame> it = stackFrameStream.skip(startFrame).limit(stackDepth).iterator(); | |
int index = 0; | |
while (it.hasNext()) { | |
elements[index++] = it.next(); | |
} | |
return elements; | |
} | |
} | |
private class TransformingWalker implements Function<Stream<StackWalker.StackFrame>, StackWalker.StackFrame[]> { | |
private final int stackDepth, startFrame; | |
TransformingWalker(int stackDepth, int startFrame) { | |
this.stackDepth = stackDepth; | |
this.startFrame = startFrame; | |
} | |
@Override | |
public StackFrameElement[] apply(Stream<StackWalker.StackFrame> stackFrameStream) { | |
StackFrameElement[] elements = new StackWalker.StackFrame[stackDepth]; | |
Iterator<StackWalker.StackFrame> it = stackFrameStream.skip(startFrame).limit(stackDepth).iterator(); | |
int index = 0; | |
while (it.hasNext()) { | |
elements[index++] = it.next().toStackFrameElement(); | |
} | |
return elements; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.openjdk.jmh.annotations.Benchmark; | |
public class ThrowableExtraction { | |
private static Throwable call(int depth) { | |
if (depth == 0) { | |
return new Throwable(); | |
} else { | |
return call(depth - 1); | |
} | |
} | |
@Benchmark | |
public Throwable snapshot() { | |
return call(100); | |
} | |
@Benchmark | |
public Object complete() { | |
int stackDepth = 35, startFrame = 1; | |
Throwable throwable = call(100); | |
StackTraceElement[] source = throwable.getStackTrace(); | |
StackTraceElement[] copy = new StackTraceElement[Math.min(stackDepth, source.length - startFrame)]; | |
int sourceIndex = startFrame; | |
int copyIndex = 0; | |
while (sourceIndex < source.length && copyIndex < copy.length) { | |
copy[copyIndex++] = source[sourceIndex++]; | |
} | |
return copy; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.openjdk.jmh.annotations.Benchmark; | |
public class ThrowableSecretExtraction { | |
static final JavaLangAccess JAVA_LANG_ACCESS = SharedSecrets.getJavaLangAccess(); | |
private static Throwable call(int depth) { | |
if (depth == 0) { | |
return new Throwable(); | |
} else { | |
return call(depth - 1); | |
} | |
} | |
@Benchmark | |
public Throwable snapshot() { | |
return call(100); | |
} | |
@Benchmark | |
public Object complete() { | |
int stackDepth = 35, startFrame = 1; | |
Throwable throwable = call(100); | |
int length = JAVA_LANG_ACCESS.getStackTraceDepth(throwable); | |
StackTraceElement[] copy = new StackTraceElement[Math.min(stackDepth, source.length - startFrame)]; | |
int sourceIndex = startFrame; | |
int copyIndex = 0; | |
while (sourceIndex < length && copyIndex < copy.length) { | |
copy[copyIndex++] = JAVA_LANG_ACCESS.getStackTraceElement(throwable, sorceIndex++); | |
} | |
return copy; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment