On Sep 20, 2013, at 2:09 AM, Mandy Chung wrote:
> On 9/18/2013 9:22 AM, Nick Williams wrote:
>> Okay. Again, sorry for my absence. This wraps up my feedback for now. I now
>> await responses from Mandy.
>>
>> On Sep 17, 2013, at 3:53 PM, Mandy Chung wrote:
>>
>>> You asked at a good time. I discussed this with John Rose last couple days
>>> on this topic. He has been thinking about how to do fillInStackTrace
>>> performantly and walk the stack with laziness and frame filtering. The
>>> current implementation fills the entire stack trace while Groovy and Log4j
>>> use case filters the frames of some specific classes until it reaches the
>>> first one not being filtered.
>>>
>>> He suggests to consider an API taking a callback shape (e.g. Function,
>>> Consumer, etc) that Remi Forax suggested at one time that allows the JVM to
>>> do something. I will work with John to work out the details and determine
>>> the interface between VM and library and hash out issues.
>>>
>>> I like the callback shape idea and hope to work out a proposal soon.
>
> This will give you an idea the API we are thinking about:
> http://cr.openjdk.java.net/~mchung/jdk8/webrevs/walkstack-webrev/
Just to be clear, this means the patch I worked on for a month has been
completely junked. Correct? Awesome.
> More work to do as we are working on the VM interface and implementation.
> We'll post an update when it's ready.
>
> Stack is a "stream" that allows you to walk partial stack (e.g. find caller)
> or full stack trace (e.g. throwable). The filtering and mapping operations
> are lazy to avoid having the VM eagerly copying the entire stack trace data
> even for the short reach case (like Groovy and Log4j).
>
> The API takes a predicate, consumer or function so that the caller will only
> need to carry the data it needs. There is no method to return the stream of
> stack frames; otherwise, the returned stack frame stream would be a snapshot
> and require to do fillInStackTrace and get the entire stack trace. The API
> can also take a depth limit to control the number of elements and can use it
> as optimization (currently the VM has a predefined max number of stack frames
> returned in a stack trace).
This is all well and good, but some of us just need a simple array. This seems
like over-engineering. I just want an array of StackFrameInfos/StackTraceFrames.
> I have modified java.util.logging.LogRecord to infer the caller using the new
> API (much simpler):
>
> StackTraceElement frame =
> Thread.firstCaller(e -> {return !isLoggerImplFrame(e.getClassName());
> },
> StackFrameInfo::stackTraceElement);
>
> Replacement for getCallerClass()
> Class<?> c = Thread.getCaller(StackFrameInfo::getDeclaringClass);
>
> Replacement for traversing the stack with getCallerClass(int depth)
> Thread.walkStack(e -> doSomething(e));
This looks beautiful for Java 8, sure. Now try doing these same things in a
library compiled for Java 6 but made to be compatible with Java 8 and so all of
this has to happen via reflection. Suddenly it's nightmarish.
Finally, none of the points I made and questions I raised a couple of days ago
have been addressed (see five emails on September 18). Particularly, the
security checks bother me and we _still_ have no explanation as to why they're
necessary.
Nick