Proposed API for JEP 259: Stack-Walking API

Mandy Chung mandy.chung at oracle.com
Thu Nov 5 01:15:58 UTC 2015


Sorry for the delay getting back to this.  

> On Nov 2, 2015, at 4:46 AM, David M. Lloyd <david.lloyd at redhat.com> wrote:
> 
> I think there are two problems with the current approach:
> 
> 1. The function for getting the next batch size is not coupled to the function actually doing the work.  I think it is just as likely (if not more so) that any information about the optimum number of frames to be gathered per batch can only be sensibly determined as a result of the current work being done.  In this case, you'd have to do something odd like use a captured shared AtomicInteger or similar to pass information back and forth, which is not good.

I agree that the next batch size is not coupled to the function consuming the stack frames.

> 
> 2. The fact that frames are acquired in batches is an implementation detail.  I do not believe it's a reasonable expectation of a user to know the optimum batch size; the API should not be exposing implementation details like this.  On the other hand, the user might be reasonably expected to be able to inform the stack walker as to how many more frames are expected to be needed.  The stack walker could easily use this information, even if it fetches in batches, by keeping a "remainingNeeded" counter of number of remaining frames expected to be used, which is decremented each time the stream returns an item, and read when a new batch is needed: it could (for example) use Math.min(10, remainingNeeded).

For short-circuiting, I also think it’s reasonable to expect the user know how many remaining frames it expects to traverse and it may not need to increase the batch size i.e. it might not need to update the remainingNeeded over time.  The user to supply the estimate number of frames needed may be adequate for it (like what you suggest previously having the walk method to take an initial batch size for the simple case).

Walking the entire stack (or almost all stack frames) is the use case that this hint may help in performance   since the stack depth is unknown and it’s a tradeoff between memory and runtime.   Throwable::init and AccessControlContext are the use cases that need to be performant.  It’s better to wait for more experience of using the StackWalker and see if any other use cases need adaptive sizing .  I propose to drop this walk(Function, IntUnaryFunction) for now and decide to add such ability later.

For taking the estimated number of consumed frames, one option is to have a walk(int initialFramesNeeded, Function function) method.  The other option is to have the
   StackWalker(int minDepth, int maxDepth, Set<Option> options)

It’s cheap to have one StackWalker for each kind of stack walking.  Having the constructor to take an additional minDepth (or estimate minimum number of frames to be traversed) seems a better option.

Any thought? 

Mandy


More information about the core-libs-dev mailing list