< prev index next >

src/java.base/share/classes/java/lang/StackStreamFactory.java

Print this page

        

*** 30,39 **** --- 30,41 ---- import java.lang.StackWalker.StackFrame; import java.lang.annotation.Native; import java.lang.reflect.Method; import java.lang.reflect.Constructor; + import java.security.AccessController; + import java.security.PrivilegedAction; import java.util.HashSet; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Set; import java.util.Spliterator;
*** 81,91 **** * Performance work and extensive testing is needed to replace the * VM built-in backtrace filled in Throwable with the StackWalker. */ final static boolean isDebug = "true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug")); ! static <T> StackFrameTraverser<T> makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function) { if (walker.hasLocalsOperandsOption()) return new LiveStackInfoTraverser<>(walker, function); --- 83,93 ---- * Performance work and extensive testing is needed to replace the * VM built-in backtrace filled in Throwable with the StackWalker. */ final static boolean isDebug = "true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug")); ! static <T> StackFrameTraverser<T> makeStackTraverser(StackWalker walker, Function<? super Stream<StackFrame>, ? extends T> function) { if (walker.hasLocalsOperandsOption()) return new LiveStackInfoTraverser<>(walker, function);
*** 124,133 **** --- 126,137 ---- protected final int maxDepth; protected final long mode; protected int depth; // traversed stack depth protected FrameBuffer<? extends T> frameBuffer; protected long anchor; + protected final ContinuationScope contScope; + protected Continuation continuation; // buffers to fill in stack frame information protected AbstractStackWalker(StackWalker walker, int mode) { this(walker, mode, Integer.MAX_VALUE); }
*** 135,144 **** --- 139,150 ---- this.thread = Thread.currentThread(); this.mode = toStackWalkMode(walker, mode); this.walker = walker; this.maxDepth = maxDepth; this.depth = 0; + this.contScope = walker.getContScope(); + this.continuation = walker.getContinuation(); } private int toStackWalkMode(StackWalker walker, int mode) { int newMode = mode; if (walker.hasOption(Option.SHOW_HIDDEN_FRAMES) &&
*** 234,243 **** --- 240,255 ---- * Walks stack frames until {@link #consumeFrames} is done consuming * the frames it is interested in. */ final R walk() { checkState(NEW); + return continuation != null + ? Continuation.wrapWalk(continuation, contScope, this::walkHelper) + : walkHelper(); + } + + private final R walkHelper() { try { // VM will need to stablize the stack before walking. It will invoke // the AbstractStackWalker::doStackWalk method once it fetches the first batch. // the callback will be invoked within the scope of the callStackWalk frame. return beginStackWalk();
*** 298,307 **** --- 310,321 ---- System.err.format("doStackWalk: skip %d start %d end %d%n", skipFrames, bufStartIndex, bufEndIndex); } this.anchor = anchor; // set anchor for this bulk stack frame traversal + + int numFrames = bufEndIndex - bufStartIndex; frameBuffer.setBatch(depth, bufStartIndex, bufEndIndex); // traverse all frames and perform the action on the stack frames, if specified return consumeFrames(); }
*** 309,327 **** /* * Get next batch of stack frames. */ private int getNextBatch() { int nextBatchSize = Math.min(maxDepth - depth, getNextBatchSize()); ! if (!frameBuffer.isActive() || nextBatchSize <= 0) { if (isDebug) { System.out.format(" more stack walk done%n"); } frameBuffer.freeze(); // stack walk done return 0; } ! return fetchStackFrames(nextBatchSize); } /* * This method traverses the next stack frame and returns the Class * invoking that stack frame. --- 323,359 ---- /* * Get next batch of stack frames. */ private int getNextBatch() { int nextBatchSize = Math.min(maxDepth - depth, getNextBatchSize()); ! ! if (!frameBuffer.isActive() || nextBatchSize <= 0 || (frameBuffer.isAtBottom() && !hasMoreContinuations())) { if (isDebug) { System.out.format(" more stack walk done%n"); } frameBuffer.freeze(); // stack walk done return 0; } ! if (frameBuffer.isAtBottom() && hasMoreContinuations()) { ! setContinuation(continuation.getParent()); ! } ! ! int numFrames = fetchStackFrames(nextBatchSize); ! if (numFrames == 0 && !hasMoreContinuations()) { ! frameBuffer.freeze(); // done stack walking ! } ! return numFrames; ! } ! ! private boolean hasMoreContinuations() { ! return continuation != null && continuation.getScope() != contScope && continuation.getParent() != null; ! } ! ! private void setContinuation(Continuation cont) { ! this.continuation = cont; ! setContinuation(anchor, frameBuffer.frames(), cont); } /* * This method traverses the next stack frame and returns the Class * invoking that stack frame.
*** 365,375 **** */ private R beginStackWalk() { // initialize buffers for VM to fill the stack frame info initFrameBuffer(); ! return callStackWalk(mode, 0, frameBuffer.curBatchFrameCount(), frameBuffer.startIndex(), frameBuffer.frames()); } --- 397,408 ---- */ private R beginStackWalk() { // initialize buffers for VM to fill the stack frame info initFrameBuffer(); ! return callStackWalk(mode, 0, ! contScope, continuation, frameBuffer.curBatchFrameCount(), frameBuffer.startIndex(), frameBuffer.frames()); }
*** 388,401 **** frameBuffer.frames()); if (isDebug) { System.out.format(" more stack walk requesting %d got %d to %d frames%n", batchSize, frameBuffer.startIndex(), endIndex); } int numFrames = endIndex - startIndex; ! if (numFrames == 0) { ! frameBuffer.freeze(); // done stack walking ! } else { frameBuffer.setBatch(depth, startIndex, endIndex); } return numFrames; } --- 421,434 ---- frameBuffer.frames()); if (isDebug) { System.out.format(" more stack walk requesting %d got %d to %d frames%n", batchSize, frameBuffer.startIndex(), endIndex); } + int numFrames = endIndex - startIndex; ! ! if (numFrames > 0) { frameBuffer.setBatch(depth, startIndex, endIndex); } return numFrames; }
*** 403,419 **** * Begins stack walking. This method anchors this frame and invokes * AbstractStackWalker::doStackWalk after fetching the first batch of stack frames. * * @param mode mode of stack walking * @param skipframes number of frames to be skipped before filling the frame buffer. * @param batchSize the batch size, max. number of elements to be filled in the frame buffers. * @param startIndex start index of the frame buffers to be filled. * @param frames Either a Class<?> array, if mode is {@link #FILL_CLASS_REFS_ONLY} * or a {@link StackFrameInfo} (or derivative) array otherwise. * @return Result of AbstractStackWalker::doStackWalk */ ! private native R callStackWalk(long mode, int skipframes, int batchSize, int startIndex, T[] frames); /** * Fetch the next batch of stack frames. --- 436,455 ---- * Begins stack walking. This method anchors this frame and invokes * AbstractStackWalker::doStackWalk after fetching the first batch of stack frames. * * @param mode mode of stack walking * @param skipframes number of frames to be skipped before filling the frame buffer. + * @param contScope the continuation scope to walk. + * @param continuation the continuation to walk, or {@code null} if walking a thread. * @param batchSize the batch size, max. number of elements to be filled in the frame buffers. * @param startIndex start index of the frame buffers to be filled. * @param frames Either a Class<?> array, if mode is {@link #FILL_CLASS_REFS_ONLY} * or a {@link StackFrameInfo} (or derivative) array otherwise. * @return Result of AbstractStackWalker::doStackWalk */ ! private native R callStackWalk(long mode, int skipframes, ! ContinuationScope contScope, Continuation continuation, int batchSize, int startIndex, T[] frames); /** * Fetch the next batch of stack frames.
*** 428,437 **** --- 464,475 ---- * @return the end index to the frame buffers */ private native int fetchStackFrames(long mode, long anchor, int batchSize, int startIndex, T[] frames); + + private native void setContinuation(long anchor, T[] frames, Continuation cont); } /* * This StackFrameTraverser supports {@link Stream} traversal. *
*** 879,889 **** /* * Tests if this frame buffer is active. It is inactive when * it is done for traversal. All stack frames have been traversed. */ final boolean isActive() { ! return origin > 0 && (fence == 0 || origin < fence || fence == currentBatchSize); } /** * Gets the class at the current frame and move to the next frame. */ --- 917,935 ---- /* * Tests if this frame buffer is active. It is inactive when * it is done for traversal. All stack frames have been traversed. */ final boolean isActive() { ! return origin > 0; // && (fence == 0 || origin < fence || fence == currentBatchSize); ! } ! ! /* ! * Tests if this frame buffer is at the end of the stack ! * and all frames have been traversed. ! */ ! final boolean isAtBottom() { ! return origin > 0 && origin >= fence && fence < currentBatchSize; } /** * Gets the class at the current frame and move to the next frame. */
< prev index next >