RFR: 8268829: Provide an optimized way to walk the stack with Class object only [v4]

Mandy Chung mchung at openjdk.org
Wed Aug 23 20:27:38 UTC 2023


> 8268829: Provide an optimized way to walk the stack with Class object only
> 
> `StackWalker::walk` creates one `StackFrame` per frame and the current implementation
> allocates one `StackFrameInfo` and one `MemberName` objects per frame. Some frameworks
> like logging may only interest in the Class object but not the method name nor the BCI,
> for example, filters out its implementation classes to find the caller class.  It's
> similar to `StackWalker::getCallerClass` but allows a predicate to filter out the element.
> 
> This PR proposes to add `StackWalker.Kind` enum to specify the information that a stack walker
> collects.  If no method information is needed, a `StackWalker` of `CLASS_INFO` can be used
> instead and such stack walker will save the overhead (1) to extract the method information
> and (2) the memory used for the stack walking.   In addition, this can also fix
> 
> - [8311500](https://bugs.openjdk.org/browse/JDK-8311500): StackWalker.getCallerClass() throws UOE if invoked reflectively
> 
> New factory methods to take a parameter to specify the kind of stack walker to be created are defined.
> This provides a simple way for existing code, for example logging frameworks, to take advantage of
> this enhancement with the least change as it can keep the existing function for traversing
> `StackFrame`s.
> 
> For example: to find the first caller filtering a known list of implementation class,
> existing code can call `StackWalker::getInstance(CLASS_INFO, ...)` to create a stack walker instance:
> 
> 
>      StackWalker walker = StackWalker.getInstance(Kind.CLASS_INFO, Option.RETAIN_CLASS_REFERENCE);
>      Optional<Class<?>> callerClass = walker.walk(s ->
>              s.map(StackFrame::getDeclaringClass)
>               .filter(interestingClasses::contains)
>               .findFirst());
> 
> 
> If method information is accessed on the `StackFrame`s produced by this stack walker such as
> `StackFrame::getMethodName`, then `UnsupportedOperationException` will be thrown.
> 
> #### Alternatives Considered
> One alternative is to provide a new API:
> `<T> T walkClass(Function<? super Stream<Class<?>, ? extends T> function)`
> 
> In this case, the caller would need to pass a function that takes a stream
> of `Class` object instead of `StackFrame`.  Existing code would have to
> modify calls to the `walk` method to `walkClass` and the function body.
> 
> Another alternative is to add a new `NO_METHOD_INFO` option.  Similar to the proposed API,
> it only needs a small change in calling `getInstance` method to request class only info...

Mandy Chung has updated the pull request incrementally with three additional commits since the last revision:

 - fix whitespace
 - move retainClassRef to ClassFrameInfo as a bit set in the flags field
 - fixup the factory methods

-------------

Changes:
  - all: https://git.openjdk.org/jdk/pull/15370/files
  - new: https://git.openjdk.org/jdk/pull/15370/files/434d90cb..30984253

Webrevs:
 - full: https://webrevs.openjdk.org/?repo=jdk&pr=15370&range=03
 - incr: https://webrevs.openjdk.org/?repo=jdk&pr=15370&range=02-03

  Stats: 109 lines in 10 files changed: 44 ins; 28 del; 37 mod
  Patch: https://git.openjdk.org/jdk/pull/15370.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/15370/head:pull/15370

PR: https://git.openjdk.org/jdk/pull/15370


More information about the core-libs-dev mailing list