< prev index next >

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

Print this page
@@ -31,10 +31,12 @@
  import java.util.Objects;
  import java.util.Set;
  import java.util.function.Consumer;
  import java.util.function.Function;
  import java.util.stream.Stream;
+ import jdk.internal.vm.Continuation;
+ import jdk.internal.vm.ContinuationScope;
  
  /**
   * A stack walker.
   *
   * <p> The {@link StackWalker#walk walk} method opens a sequential stream

@@ -222,10 +224,22 @@
           * @return {@code true} if the method containing the execution point
           *         represented by this stack frame is a native method.
           */
          public boolean isNativeMethod();
  
+         /**
+          * Returns the name of the {@link ContinuationScope} of the continuation 
+          * (if any) in which this frame exists.
+          * 
+          * @return the name of the {@link ContinuationScope} of the continuation 
+          *         in which this frame exists or {@code null} if this frame is 
+          *         not in a continuation.
+          */
+         public default String getContinuationScopeName() {
+             return null;
+         }
+ 
          /**
           * Gets a {@code StackTraceElement} for this stack frame.
           *
           * @return {@code StackTraceElement} for this stack frame.
           */

@@ -276,11 +290,11 @@
           * <p>A Java Virtual Machine implementation may hide implementation
           * specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES
           * reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES}
           * option will show all hidden frames (including reflection frames).
           */
-         SHOW_HIDDEN_FRAMES;
+         SHOW_HIDDEN_FRAMES,
      }
  
      enum ExtendedOption {
          /**
           * Obtain monitors, locals and operands.

@@ -291,10 +305,12 @@
      static final EnumSet<Option> DEFAULT_EMPTY_OPTION = EnumSet.noneOf(Option.class);
  
      private static final StackWalker DEFAULT_WALKER =
          new StackWalker(DEFAULT_EMPTY_OPTION);
  
+     private final Continuation continuation;
+     private final ContinuationScope contScope;
      private final Set<Option> options;
      private final ExtendedOption extendedOption;
      private final int estimateDepth;
      final boolean retainClassRef; // cached for performance
  

@@ -313,10 +329,28 @@
      public static StackWalker getInstance() {
          // no permission check needed
          return DEFAULT_WALKER;
      }
  
+     /**
+      * Returns a {@code StackWalker} instance.
+      *
+      * <p> This {@code StackWalker} is configured to skip all
+      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
+      * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
+      * 
+      * @param contScope the continuation scope up to which (inclusive) to walk the stack
+      * 
+      * @return a {@code StackWalker} configured to skip all
+      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
+      * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
+      *
+      */
+     static StackWalker getInstance(ContinuationScope contScope) {
+         return getInstance(EnumSet.noneOf(Option.class), contScope);
+     }
+ 
      /**
       * Returns a {@code StackWalker} instance with the given option specifying
       * the stack frame information it can access.
       *
       * <p>

@@ -334,10 +368,32 @@
       */
      public static StackWalker getInstance(Option option) {
          return getInstance(EnumSet.of(Objects.requireNonNull(option)));
      }
  
+    /**
+      * Returns a {@code StackWalker} instance with the given option specifying
+      * the stack frame information it can access.
+      *
+      * <p>
+      * If a security manager is present and the given {@code option} is
+      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
+      * it calls its {@link SecurityManager#checkPermission checkPermission}
+      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
+      *
+      * @param option {@link Option stack walking option}
+      * @param contScope the continuation scope up to which (inclusive) to walk the stack
+      *
+      * @return a {@code StackWalker} configured with the given option
+      *
+      * @throws SecurityException if a security manager exists and its
+      *         {@code checkPermission} method denies access.
+      */
+     static StackWalker getInstance(Option option, ContinuationScope contScope) {
+         return getInstance(EnumSet.of(Objects.requireNonNull(option)), contScope);
+     }
+ 
      /**
       * Returns a {@code StackWalker} instance with the given {@code options} specifying
       * the stack frame information it can access.  If the given {@code options}
       * is empty, this {@code StackWalker} is configured to skip all
       * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no

@@ -355,17 +411,42 @@
       *
       * @throws SecurityException if a security manager exists and its
       *         {@code checkPermission} method denies access.
       */
      public static StackWalker getInstance(Set<Option> options) {
-         if (options.isEmpty()) {
+         return getInstance(options, null);
+     }
+ 
+     /**
+      * Returns a {@code StackWalker} instance with the given {@code options} specifying
+      * the stack frame information it can access.  If the given {@code options}
+      * is empty, this {@code StackWalker} is configured to skip all
+      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
+      * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
+      *
+      * <p>
+      * If a security manager is present and the given {@code options} contains
+      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
+      * it calls its {@link SecurityManager#checkPermission checkPermission}
+      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
+      *
+      * @param options {@link Option stack walking option}
+      * @param contScope the continuation scope up to which (inclusive) to walk the stack
+      *
+      * @return a {@code StackWalker} configured with the given options
+      *
+      * @throws SecurityException if a security manager exists and its
+      *         {@code checkPermission} method denies access.
+      */
+     static StackWalker getInstance(Set<Option> options, ContinuationScope contScope) {
+         if (options.isEmpty() && contScope == null) {
              return DEFAULT_WALKER;
          }
  
          EnumSet<Option> optionSet = toEnumSet(options);
          checkPermission(optionSet);
-         return new StackWalker(optionSet);
+         return new StackWalker(optionSet, contScope);
      }
  
      /**
       * Returns a {@code StackWalker} instance with the given {@code options} specifying
       * the stack frame information it can access. If the given {@code options}

@@ -402,20 +483,41 @@
          return new StackWalker(optionSet, estimateDepth);
      }
  
      // ----- private constructors ------
      private StackWalker(EnumSet<Option> options) {
-         this(options, 0, null);
+         this(options, 0, null, null, null);
+     }
+     private StackWalker(EnumSet<Option> options, ContinuationScope contScope) {
+         this(options, 0, null, contScope, null);
+     }
+     private StackWalker(EnumSet<Option> options, ContinuationScope contScope, Continuation continuation) {
+         this(options, 0, null, contScope, continuation);
      }
      private StackWalker(EnumSet<Option> options, int estimateDepth) {
-         this(options, estimateDepth, null);
+         this(options, estimateDepth, null, null, null);
      }
-     private StackWalker(EnumSet<Option> options, int estimateDepth, ExtendedOption extendedOption) {
+     private StackWalker(EnumSet<Option> options, int estimateDepth, ContinuationScope contScope) {
+         this(options, estimateDepth, null, contScope, null);
+     }
+     private StackWalker(EnumSet<Option> options,
+                         int estimateDepth,
+                         ContinuationScope contScope,
+                         Continuation continuation) {
+         this(options, estimateDepth, null, contScope, continuation);
+     }
+     private StackWalker(EnumSet<Option> options,
+                         int estimateDepth,
+                         ExtendedOption extendedOption,
+                         ContinuationScope contScope,
+                         Continuation continuation) {
          this.options = options;
          this.estimateDepth = estimateDepth;
          this.extendedOption = extendedOption;
          this.retainClassRef = hasOption(Option.RETAIN_CLASS_REFERENCE);
+         this.contScope = contScope;
+         this.continuation = continuation;
      }
  
      private static void checkPermission(Set<Option> options) {
          Objects.requireNonNull(options);
          @SuppressWarnings("removal")

@@ -595,20 +697,33 @@
      public Class<?> getCallerClass() {
          if (!retainClassRef) {
              throw new UnsupportedOperationException("This stack walker " +
                      "does not have RETAIN_CLASS_REFERENCE access");
          }
+         if (continuation != null) {
+             throw new UnsupportedOperationException("This stack walker walks a continuation");
+         }
  
          return StackStreamFactory.makeCallerFinder(this).findCaller();
      }
  
      // ---- package access ----
  
      static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption) {
+         return newInstance(options, extendedOption, null);
+     }
+ 
+     static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption, ContinuationScope contScope) {
+         EnumSet<Option> optionSet = toEnumSet(options);
+         checkPermission(optionSet);
+         return new StackWalker(optionSet, 0, extendedOption, contScope, null);
+     }
+ 
+     static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption, ContinuationScope contScope, Continuation continuation) {
          EnumSet<Option> optionSet = toEnumSet(options);
          checkPermission(optionSet);
-         return new StackWalker(optionSet, 0, extendedOption);
+         return new StackWalker(optionSet, 0, extendedOption, contScope, continuation);
      }
  
      int estimateDepth() {
          return estimateDepth;
      }

@@ -618,6 +733,14 @@
      }
  
      boolean hasLocalsOperandsOption() {
          return extendedOption == ExtendedOption.LOCALS_AND_OPERANDS;
      }
+ 
+     ContinuationScope getContScope() {
+         return contScope;
+     }
+ 
+     Continuation getContinuation() {
+         return continuation;
+     }
  }
< prev index next >