54 * to avoid overhead of Stream/Lambda
55 * 1. Support traversing Stream<StackFrame>
56 * 2. StackWalker::getCallerClass
57 * 3. AccessControlContext getting ProtectionDomain
58 */
59 final class StackStreamFactory {
60 private StackStreamFactory() {}
61
62 // Stack walk implementation classes to be excluded during stack walking
63 // lazily add subclasses when they are loaded.
64 private final static Set<Class<?>> stackWalkImplClasses = init();
65
66 private static final int SMALL_BATCH = 8;
67 private static final int BATCH_SIZE = 32;
68 private static final int LARGE_BATCH_SIZE = 256;
69 private static final int MIN_BATCH_SIZE = SMALL_BATCH;
70
71 // These flags must match the values maintained in the VM
72 @Native private static final int DEFAULT_MODE = 0x0;
73 @Native private static final int FILL_CLASS_REFS_ONLY = 0x2;
74 @Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM
75 @Native private static final int FILL_LIVE_STACK_FRAMES = 0x100;
76 /*
77 * For Throwable to use StackWalker, set useNewThrowable to true.
78 * Performance work and extensive testing is needed to replace the
79 * VM built-in backtrace filled in Throwable with the StackWalker.
80 */
81 final static boolean isDebug =
82 "true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug"));
83
84 static <T> StackFrameTraverser<T>
85 makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function)
86 {
87 if (walker.hasLocalsOperandsOption())
88 return new LiveStackInfoTraverser<>(walker, function);
89 else
90 return new StackFrameTraverser<>(walker, function);
91 }
92
93 /**
597 }
598 if (isDebug) {
599 System.err.println("tryAdvance: " + index + " NO element");
600 }
601 return false;
602 }
603 }
604
605 /*
606 * CallerClassFinder is specialized to return Class<?> for each stack frame.
607 * StackFrame is not requested.
608 */
609 static final class CallerClassFinder extends AbstractStackWalker<Integer, Class<?>> {
610 static {
611 stackWalkImplClasses.add(CallerClassFinder.class);
612 }
613
614 private Class<?> caller;
615
616 CallerClassFinder(StackWalker walker) {
617 super(walker, FILL_CLASS_REFS_ONLY);
618 assert (mode & FILL_CLASS_REFS_ONLY) == FILL_CLASS_REFS_ONLY
619 : "mode should contain FILL_CLASS_REFS_ONLY";
620 }
621
622 final class ClassBuffer extends FrameBuffer<Class<?>> {
623 Class<?>[] classes; // caller class for fast path
624 ClassBuffer(int batchSize) {
625 super(batchSize);
626 classes = new Class<?>[batchSize];
627 }
628
629 @Override
630 Class<?>[] frames() { return classes;}
631
632 @Override
633 final Class<?> at(int index) { return classes[index];}
634
635
636 // ------ subclass may override the following methods -------
637 /**
638 * Resizes the buffers for VM to fill in the next batch of stack frames.
639 * The next batch will start at the given startIndex with the maximum number
|
54 * to avoid overhead of Stream/Lambda
55 * 1. Support traversing Stream<StackFrame>
56 * 2. StackWalker::getCallerClass
57 * 3. AccessControlContext getting ProtectionDomain
58 */
59 final class StackStreamFactory {
60 private StackStreamFactory() {}
61
62 // Stack walk implementation classes to be excluded during stack walking
63 // lazily add subclasses when they are loaded.
64 private final static Set<Class<?>> stackWalkImplClasses = init();
65
66 private static final int SMALL_BATCH = 8;
67 private static final int BATCH_SIZE = 32;
68 private static final int LARGE_BATCH_SIZE = 256;
69 private static final int MIN_BATCH_SIZE = SMALL_BATCH;
70
71 // These flags must match the values maintained in the VM
72 @Native private static final int DEFAULT_MODE = 0x0;
73 @Native private static final int FILL_CLASS_REFS_ONLY = 0x2;
74 @Native private static final int GET_CALLER_CLASS = 0x4;
75 @Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM
76 @Native private static final int FILL_LIVE_STACK_FRAMES = 0x100;
77 /*
78 * For Throwable to use StackWalker, set useNewThrowable to true.
79 * Performance work and extensive testing is needed to replace the
80 * VM built-in backtrace filled in Throwable with the StackWalker.
81 */
82 final static boolean isDebug =
83 "true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug"));
84
85 static <T> StackFrameTraverser<T>
86 makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function)
87 {
88 if (walker.hasLocalsOperandsOption())
89 return new LiveStackInfoTraverser<>(walker, function);
90 else
91 return new StackFrameTraverser<>(walker, function);
92 }
93
94 /**
598 }
599 if (isDebug) {
600 System.err.println("tryAdvance: " + index + " NO element");
601 }
602 return false;
603 }
604 }
605
606 /*
607 * CallerClassFinder is specialized to return Class<?> for each stack frame.
608 * StackFrame is not requested.
609 */
610 static final class CallerClassFinder extends AbstractStackWalker<Integer, Class<?>> {
611 static {
612 stackWalkImplClasses.add(CallerClassFinder.class);
613 }
614
615 private Class<?> caller;
616
617 CallerClassFinder(StackWalker walker) {
618 super(walker, FILL_CLASS_REFS_ONLY|GET_CALLER_CLASS);
619 }
620
621 final class ClassBuffer extends FrameBuffer<Class<?>> {
622 Class<?>[] classes; // caller class for fast path
623 ClassBuffer(int batchSize) {
624 super(batchSize);
625 classes = new Class<?>[batchSize];
626 }
627
628 @Override
629 Class<?>[] frames() { return classes;}
630
631 @Override
632 final Class<?> at(int index) { return classes[index];}
633
634
635 // ------ subclass may override the following methods -------
636 /**
637 * Resizes the buffers for VM to fill in the next batch of stack frames.
638 * The next batch will start at the given startIndex with the maximum number
|