< 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 ***
           * <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;
      }
  
      enum ExtendedOption {
          /**
           * Obtain monitors, locals and operands.
--- 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,
      }
  
      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 ***
       *
       * @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 DEFAULT_WALKER;
          }
  
          EnumSet<Option> optionSet = toEnumSet(options);
          checkPermission(optionSet);
!         return new StackWalker(optionSet);
      }
  
      /**
       * Returns a {@code StackWalker} instance with the given {@code options} specifying
       * the stack frame information it can access. If the given {@code options}
--- 411,42 ---
       *
       * @throws SecurityException if a security manager exists and its
       *         {@code checkPermission} method denies access.
       */
      public static StackWalker getInstance(Set<Option> options) {
!         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, 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 ***
          return new StackWalker(optionSet, estimateDepth);
      }
  
      // ----- private constructors ------
      private StackWalker(EnumSet<Option> options) {
!         this(options, 0, null);
      }
      private StackWalker(EnumSet<Option> options, int estimateDepth) {
!         this(options, estimateDepth, null);
      }
!     private StackWalker(EnumSet<Option> options, int estimateDepth, ExtendedOption extendedOption) {
          this.options = options;
          this.estimateDepth = estimateDepth;
          this.extendedOption = extendedOption;
          this.retainClassRef = hasOption(Option.RETAIN_CLASS_REFERENCE);
      }
  
      private static void checkPermission(Set<Option> options) {
          Objects.requireNonNull(options);
          @SuppressWarnings("removal")
--- 483,41 ---
          return new StackWalker(optionSet, estimateDepth);
      }
  
      // ----- private constructors ------
      private StackWalker(EnumSet<Option> options) {
!         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, null, null);
      }
!     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 ***
      public Class<?> getCallerClass() {
          if (!retainClassRef) {
              throw new UnsupportedOperationException("This stack walker " +
                      "does not have RETAIN_CLASS_REFERENCE access");
          }
  
          return StackStreamFactory.makeCallerFinder(this).findCaller();
      }
  
      // ---- package access ----
  
      static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption) {
          EnumSet<Option> optionSet = toEnumSet(options);
          checkPermission(optionSet);
!         return new StackWalker(optionSet, 0, extendedOption);
      }
  
      int estimateDepth() {
          return estimateDepth;
      }
--- 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, 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 >