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

2023-08-25 Thread Mandy Chung
> 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> 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.
> 
>  Javadoc & specdiff
> 
> https://cr.openjdk.org/~mchung/api/java.base/java/lang/StackWalker.html
> https://cr.openjdk.org/~mchung/jdk22/specdiff/overview-summary.html
> 
>  Alternatives Considered
> One alternative is to provide a new API:
> ` T walkClass(Function, ? 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 alte...

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

 - fixup javadoc
 - Review feedback: move JLIA to ClassFrameInfo

-

Changes:
  - all: https://git.openjdk.org/jdk/pull/15370/files
  - new: https://git.openjdk.org/jdk/pull/15370/files/a3a44575..4c5c5d79

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

  Stats: 19 lines in 4 files changed: 3 ins; 10 del; 6 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


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

2023-08-26 Thread Rémi Forax
On Fri, 25 Aug 2023 22:22:43 GMT, Mandy Chung  wrote:

>> 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> 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.
>> 
>>  Javadoc & specdiff
>> 
>> https://cr.openjdk.org/~mchung/api/java.base/java/lang/StackWalker.html
>> https://cr.openjdk.org/~mchung/jdk22/specdiff/overview-summary.html
>> 
>>  Alternatives Considered
>> One alternative is to provide a new API:
>> ` T walkClass(Function, ? 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 hav...
>
> Mandy Chung has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - fixup javadoc
>  - Review feedback: move JLIA to ClassFrameInfo

src/java.base/share/classes/java/lang/ClassFrameInfo.java line 34:

> 32: static final JavaLangInvokeAccess JLIA = 
> SharedSecrets.getJavaLangInvokeAccess();
> 33: 
> 34: protected Object classOrMemberName;// Class or ResolvedMemberName 
> initialized by VM

I believe that the package-private access is enough here.

-

PR Review Comment: https://git.openjdk.org/jdk/pull/15370#discussion_r1306387977


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

2023-08-26 Thread Rémi Forax
On Fri, 25 Aug 2023 22:22:43 GMT, Mandy Chung  wrote:

>> 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> 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.
>> 
>>  Javadoc & specdiff
>> 
>> https://cr.openjdk.org/~mchung/api/java.base/java/lang/StackWalker.html
>> https://cr.openjdk.org/~mchung/jdk22/specdiff/overview-summary.html
>> 
>>  Alternatives Considered
>> One alternative is to provide a new API:
>> ` T walkClass(Function, ? 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 hav...
>
> Mandy Chung has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - fixup javadoc
>  - Review feedback: move JLIA to ClassFrameInfo

src/java.base/share/classes/java/lang/StackFrameInfo.java line 82:

> 80: 
> 81: {
> 82: // Get a snapshot of type which doesn't get changed by racing 
> threads.

Also the constructed MethodType is non mutable

src/java.base/share/classes/java/lang/StackFrameInfo.java line 94:

> 92: type = JLIA.getMethodType(sig, 
> declaringClass().getClassLoader());
> 93: }
> 94: assert type instanceof MethodType : "bad method type " + type;

Not sure this assert is useful given the next instruction is a cast to 
MethodType

-

PR Review Comment: https://git.openjdk.org/jdk/pull/15370#discussion_r1306389071
PR Review Comment: https://git.openjdk.org/jdk/pull/15370#discussion_r1306389160


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

2023-08-26 Thread Rémi Forax
On Fri, 25 Aug 2023 22:22:43 GMT, Mandy Chung  wrote:

>> 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> 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.
>> 
>>  Javadoc & specdiff
>> 
>> https://cr.openjdk.org/~mchung/api/java.base/java/lang/StackWalker.html
>> https://cr.openjdk.org/~mchung/jdk22/specdiff/overview-summary.html
>> 
>>  Alternatives Considered
>> One alternative is to provide a new API:
>> ` T walkClass(Function, ? 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 hav...
>
> Mandy Chung has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - fixup javadoc
>  - Review feedback: move JLIA to ClassFrameInfo

src/java.base/share/classes/java/lang/StackWalker.java line 81:

> 79:  * Optional> callerClass = walker.walk(s ->
> 80:  * s.map(StackFrame::getDeclaringClass)
> 81:  *  .filter(interestingClasses::contains)

Usually it's more `.filter(Predicate.not(implClasses::contains))`

src/java.base/share/classes/java/lang/StackWalker.java line 88:

> 86:  * {@snippet lang="java" :
> 87:  * List stack = StackWalker.getInstance().walk(s ->
> 88:  * s.limit(10).collect(Collectors.toList()));

`s.limit(10).toList()`

src/java.base/share/classes/java/lang/StackWalker.java line 505:

> 503:  */
> 504: public static StackWalker getInstance(Kind kind, Option... options) {
> 505: return getInstance(Objects.requireNonNull(kind), 
> Set.of(Objects.requireNonNull(options)));

Set.of() already does a NPE check

src/java.base/share/classes/java/lang/StackWalker.java line 649:

> 647:  * s.dropWhile(f -> f.getClassName().startsWith("com.foo."))
> 648:  *  .limit(10)
> 649:  *  .collect(Collectors.toList()));

`.toList())`

-

PR Review Comment: https://git.openjdk.org/jdk/pull/15370#discussion_r1306390180
PR Review Comment: https://git.openjdk.org/jdk/pull/15370#discussion_r1306390266
PR Review Comment: https://git.openjdk.org/jdk/pull/15370#discussion_r1306390553
PR Review Comment: https://git.openjdk.org/jdk/pull/15370#discussion_r1306390713


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

2023-08-28 Thread Volker Simonis
On Fri, 25 Aug 2023 22:22:43 GMT, Mandy Chung  wrote:

>> 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> 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.
>> 
>>  Javadoc & specdiff
>> 
>> https://cr.openjdk.org/~mchung/api/java.base/java/lang/StackWalker.html
>> https://cr.openjdk.org/~mchung/jdk22/specdiff/overview-summary.html
>> 
>>  Alternatives Considered
>> One alternative is to provide a new API:
>> ` T walkClass(Function, ? 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 hav...
>
> Mandy Chung has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - fixup javadoc
>  - Review feedback: move JLIA to ClassFrameInfo

Hi Mandy,

thanks for doing this experiment. I've looked at your proposal, but I can't see 
how it can help to fix 
[JDK-8311500](https://bugs.openjdk.org/browse/JDK-8311500). Your change 
proposes to add a bunch of new Java SE specific changes which can't be 
downported to any previous JDK version but 
[JDK-8311500](https://bugs.openjdk.org/browse/JDK-8311500) affects JDK 11, 17 
and 21. I'd therefore still appreciate if we could fix 
[JDK-8311500](https://bugs.openjdk.org/browse/JDK-8311500) first before we 
start to redesign the public StackWalker API.

In case you do redesign the `StackWalker` API, I fully agree with @bchristi-git 
that the current version is overkill. As your 
[specdiff](https://cr.openjdk.org/~mchung/jdk22/specdiff/overview-summary.html) 
shows, it introduces 34 API changes (9 additions and 18 changes) with no clear 
benefit. I second @bchristi-git that an addtional `StackWalker.Option` would be 
simpler and much cleaner (I'd vote for `SKIP_METHOD_INFO`) if we decide to 
change the API at all..

Another point that should be taken into account when we start to redesign the 
StackWalker API is its interaction with the `-XX:+ShowHiddenFrames` command 
line parameter. This is currently not specified and can lead to surprising 
results (see e.g. [this remark about failing JTreg tests with 
`-XX:+ShowHiddenFrames`](https://github.com/openjdk/jdk/pull/14773#issuecomment-1631065562)).

I'm also not convinced that doing frame filtering in Java is the right thing to 
do. If we have to call into the JVM anyway, I think it would be more natural to 
let the JVM do as much of the work as possible. To me it seems as if your 
change is mostly about improving the performance of stack walks and I think 
this could be achieved to an even greater extent without the need to change the 
public API, simply by improving the implementation. Such improvements could 
than also be downported to JDK 17 & 21 which isn't possible with your approach.

If it turns out that API changes are required in order to achieve superior 
performance, we should try to keep them to a minimum and weight them against 
the performance benefits. E.g. we could 

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

2023-08-28 Thread Daniel Fuchs
On Fri, 25 Aug 2023 22:22:43 GMT, Mandy Chung  wrote:

>> 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> 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.
>> 
>>  Javadoc & specdiff
>> 
>> https://cr.openjdk.org/~mchung/api/java.base/java/lang/StackWalker.html
>> https://cr.openjdk.org/~mchung/jdk22/specdiff/overview-summary.html
>> 
>>  Alternatives Considered
>> One alternative is to provide a new API:
>> ` T walkClass(Function, ? 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 hav...
>
> Mandy Chung has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - fixup javadoc
>  - Review feedback: move JLIA to ClassFrameInfo

As far as I understand the point of this change is to provide a new API that 
will allow a caller to request class information only, thus improving 
performance when only class information is required. Whether we use a new enum 
or a new option constant, we will need changes to the API documentation. If we 
use a new option constant we won't need any new static factory methods though.
Whether filtering is performed in java or in native is orthogonal to that. The 
trend these days is to do as much as possible in java, and the patch goes in 
that direction. There is a small price to pay if the frame to be filtered is a 
continuation, as this will cause the member name to be resolved. Is that 
significant enough to push back towards doing the filtering in native: I don't 
know. It may be worth investigating.

-

PR Comment: https://git.openjdk.org/jdk/pull/15370#issuecomment-1695899325


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

2023-08-28 Thread Mandy Chung
On Mon, 28 Aug 2023 14:47:20 GMT, Volker Simonis  wrote:

> thanks for doing this experiment. I've looked at your proposal, but I can't 
> see how it can help to fix 
> [JDK-8311500](https://bugs.openjdk.org/browse/JDK-8311500).

I think you may be confused.   This PR can be viewed as follows:

1. introduce a new API to allow walking the stack with no method information 
and the implementation will use `ClassFrameInfo` buffer
2. reduce the memory footprint of `StackFrameInfo` buffer
3. change `getCallerClass` to use the `ClassFrameInfo` buffer
4. fix JDK-8311500 by checking if a method is caller-sensitive in Java.   Note 
that the filtering of reflection frames has been done in Java.

#2-4 can be backport to older releases.   #2 improve the StackWalker 
performance.Backporting the PR should be straight-forward by excluding the 
API and javadoc change.

-

PR Comment: https://git.openjdk.org/jdk/pull/15370#issuecomment-1696134958


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

2023-08-28 Thread Mandy Chung
On Fri, 25 Aug 2023 22:22:43 GMT, Mandy Chung  wrote:

>> 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> 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.
>> 
>>  Javadoc & specdiff
>> 
>> https://cr.openjdk.org/~mchung/api/java.base/java/lang/StackWalker.html
>> https://cr.openjdk.org/~mchung/jdk22/specdiff/overview-summary.html
>> 
>>  Alternatives Considered
>> One alternative is to provide a new API:
>> ` T walkClass(Function, ? 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 hav...
>
> Mandy Chung has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - fixup javadoc
>  - Review feedback: move JLIA to ClassFrameInfo

Thank you all for the feedback on the API.   I discussed with @AlanBateman and 
@RogerRiggs offline.  Alan suggests an option to drop that would work well 
(`Lookup::dropLookupMode` is a precedent).  I like the suggested name 
`DROP_METHOD_INFO`.

| Option | getDeclaringClass | class name | method info |
| --- | -- | --- |  |
| | N | Y | Y |
| `RETAIN_CLASS_REFERENCE` | Y | Y | Y |
| `DROP_METHOD_INFO` | N | Y | N |
| `RETAIN_CLASS_REFERENCE, DROP_METHOD_INFO` | Y | Y | N |

-

PR Comment: https://git.openjdk.org/jdk/pull/15370#issuecomment-1696152180