On Wed, 5 Jul 2023 11:45:59 GMT, Volker Simonis <simo...@openjdk.org> wrote:

> As the included jtreg test demonstrates, `StackWalker.getCallerClass()` can 
> throw an `UnsupportedOperationException` if called reflectively. Currently 
> this only happens if we invoke `StackWalker.getCallerClass()` recursively 
> reflectively, but this issue will become more prominent once we fix 
> [JDK-8285447](https://bugs.openjdk.org/browse/JDK-8285447). The gory details 
> follow below:
> 
> The protocol between the Java API and the JVM for 
> `StackWalker.getCallerClass()/walk()` is as follows:
> - On the Java side, `StackWalker` calls into `StackStreamFactory` for the 
> real work.
> - For `StackWalker.getCallerClass()` `StackStreamFactory` basically creates a 
> `Class[]` which will be passed down and filled in the JVM. For 
> `StackWalker.walk()` it will normally be a `StackFrameInfo[]` (or a 
> `LiveStackFrameInfo[]` if the internal `ExtendedOption.LOCALS_AND_OPERANDS` 
> option was used).
> - The default size of this arrays is currently 
> `StackStreamFactory.SMALL_BATCH` which is 8 (but see 
> [JDK-8285447](https://bugs.openjdk.org/browse/JDK-8285447)).
> - `StackStreamFactory` than calls `AbstractStackWalker.callStackWalk()` which 
> is a natively implemented in the VM by `JVM_CallStackWalk()`.
> -  `JVM_CallStackWalk()` calls `StackWalk::walk()` which calls 
> `StackWalk::fetchFirstBatch()` which calls `StackWalk::fill_in_frames()` 
> which walks the stack and fills in the available class/stackframe slots in 
> the passed in array until the array is full or there are no more stack frames,
> - Once  `StackWalk::fill_in_frames()` returns, `StackWalk::fetchFirstBatch()` 
> calls back to Java by invoking `AbstractStackWalker::doStackWalk()` to 
> consume the result.
> - `AbstractStackWalker::doStackWalk()` calls `consumeFrames()` (which is 
> overridden depending on whether we initially called `getCallerClass()` or 
> `walk()`) which consumes the frames until it either finishes (e.g. finds the 
> caller class) or until there are no more frames.
> - In the latter case `consumeFrames()` will call into the the VM again by 
> calling `AbstractStackWalker.fetchStackFrames()` to fetch additional frames 
> from the stack.
> - `AbstractStackWalker.fetchStackFrames()` is implemented by 
> `JVM_MoreStackWalk()` which calls `StackWalk::fetchNextBatch()` which calls 
> `StackWalk::fill_in_frames()` (the same method that already fetched the 
> initial batch of frames).
> 
> Following is a stacktrace of what I've explained so far:
> 
> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
> code)
> V  [libjvm.so+0x143a96a]  StackWalk::fill_in_frames...

This pull request has been closed without being integrated.

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

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

Reply via email to