Re: [jvm-l] Improving the performance of stacktrace generation

2013-04-11 Thread John Rose
On Apr 11, 2013, at 10:12 AM, Charles Oliver Nutter  wrote:

> Unfortunately there's no API to get just a partial stack trace, via
> JVMTI or otherwise. The relevant code in Hotspot itself is rather
> simple; I started prototyping a JNI call that would allow getting a
> partial trace. Perhaps something like:
> 
> thread.getStackTrace(depth)

You may have looked at the internal API used by LogRecord.inferCaller.

Reference:  
http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/tip/src/share/classes/java/util/logging/LogRecord.java

When a Throwable calls fillInStackTrace, the entire stack is walked (eagerly!) 
and an initial internal chunked array is filled with metadata.

Later on, native methods getStackTraceDepth() and getStackTraceElement(int) 
unpack that stuff into StackTraceElement fields.

It would be reasonable to add entry points which would instantiate only 
requested segments of the data (e.g., 0..9, 0..99) created by fillInStackTrace, 
like your method above, except on Throwable.  Then the getStackTraceElement 
stuff could be used to fetch the data that is there.  (If you asked for 
elements that hadn't been filled in yet, you could be hit with an index 
exception.)

— John

> ...and something equivalent for JVMTI.
> 
> John agreed that this would be a worthwhile feature for a JEP, and I'd
> certainly like to see it trickle into a standard API too.

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: [jvm-l] Improving the performance of stacktrace generation

2013-04-11 Thread Charles Oliver Nutter
I talked a bit with John Rose about this, and he agreed with me that a
good partial measure might be to add APIs for getting a *partial*
stack.

Currently, Hotspot will limit how deep a stack trace it generates.
This can have a very large impact on the performance of generating
traces.

The magic flag is -XX:MaxJavaStackTraceDepth=, and the default on
my system is 1024. Here's a set of benchmarks of various trace depths
from 1000 down to 2. Once you get down to 100 frames, performance of
generating a stack trace starts to improve considerably.

https://gist.github.com/headius/5365217

Unfortunately there's no API to get just a partial stack trace, via
JVMTI or otherwise. The relevant code in Hotspot itself is rather
simple; I started prototyping a JNI call that would allow getting a
partial trace. Perhaps something like:

thread.getStackTrace(depth)

...and something equivalent for JVMTI.

John agreed that this would be a worthwhile feature for a JEP, and I'd
certainly like to see it trickle into a standard API too.

- Charlie

On Thu, Apr 11, 2013 at 3:37 AM,   wrote:
> Hi Bob,
>
> I wrote an article last year on the cost and impact of JVMTI stack collection.
>
> http://www.jinspired.com/site/is-jvm-call-stack-sampling-suitable-for-monitoring-low-latency-trading-apps
>
> I would prefer to see the JVM come up with a standard API and mechanism to 
> allow the stack to be augmented with additional frames that not only include 
> Java code but more contextual information related to executing activity 
> (code, block, flow,) this would include other JVM languages.
>
> We provide this sort of thing already today for Java, JRuby/Ruby and 
> Jython/Python, even SQL, in our metering engine but would welcome an ability 
> to replicate this data to the VM itself so standard tools need not be 
> changed. What is cool about this is that we can simulate a stack in a remote 
> JVM that spans multiple real application runtimes.
>
> http://www.jinspired.com/site/jxinsight-opencore-6-4-ea-12-released
>
> Kind regards,
>
> William
>
>>-Original Message-
>>From: Bob Foster [mailto:bobfos...@gmail.com]
>>Sent: Sunday, July 8, 2012 01:32 AM
>>To: jvm-langua...@googlegroups.com
>>Cc: 'Da Vinci Machine Project'
>>Subject: Re: [jvm-l] Improving the performance of stacktrace generation
>>
>>> Any thoughts on this? Does anyone else have need for
>>lighter-weight name/file/line inspection of the call stack?
>>
>>Well, yes. Profilers do.
>>
>>Recall Cliff Click bragging a couple of years ago at the JVM Language
>>Summit about how fast stack trace generation is in Azul Systems' OSs...and
>>knocking Hotspot for being so slow. It turns out that stack trace
>>generation is a very significant overhead in profiling Hotspot using JVMTI.
>>Even CPU sampling on 20 ms. intervals can add 3% or more to execution time,
>>almost entirely due to the delay in reaching a safe point (which also
>>guarantees the profile will be incorrect) and generating a stack trace for
>>each thread.
>>
>>But 3% is peanuts compared to the cost of memory profiling, which can
>>require a stack trace on every new instance creation. In a profiler I wrote
>>using JVMTI, I discovered that it was faster to call into JNI code on every
>>method entry and exit (and exception catch), keeping a stack trace
>>dynamically than to call into JNI only when memory was allocated and
>>request a stack trace each time. The "fast" technique is about 3-10 times
>>slower than running without profiling. The Netbeans profiler doesn't use
>>this optimization, and its memory profiler when capturing every allocation,
>>as I did, is 2-3 ORDERS OF MAGNITUDE slower than normal (non-server)
>>execution.
>>
>>Faster stack traces would benefit the entire Hotspot profiling community.
>>
>>Bob
>>
>>On Sat, Jul 7, 2012 at 3:03 PM, Charles Oliver Nutter
>>wrote:
>>
>>> Today I have a new conundrum for you all: I need stack trace
>>> generation on Hotspot to be considerably faster than it is now.
>>>
>>> In order to simulate many Ruby features, JRuby (over)uses Java stack
>>> traces. We recently (JRuby 1.6, about a year ago) moved to using the
>>> Java stack trace as the source of our Ruby backtrace information,
>>> mining out compiled frames and using interpreter markers to peel off
>>> interpreter frames. The result is that a Ruby trace with mixed
>>> compiled and interpreted code like this
>>> (https://gist.github.com/3068210) turns into this
>>> (https://gist.github.com/3068213). I consider this a great deal better
>>> than the plain J

Re: [jvm-l] Improving the performance of stacktrace generation

2013-04-11 Thread william . louth
Hi Bob,

I wrote an article last year on the cost and impact of JVMTI stack collection.

http://www.jinspired.com/site/is-jvm-call-stack-sampling-suitable-for-monitoring-low-latency-trading-apps

I would prefer to see the JVM come up with a standard API and mechanism to 
allow the stack to be augmented with additional frames that not only include 
Java code but more contextual information related to executing activity (code, 
block, flow,) this would include other JVM languages.

We provide this sort of thing already today for Java, JRuby/Ruby and 
Jython/Python, even SQL, in our metering engine but would welcome an ability to 
replicate this data to the VM itself so standard tools need not be changed. 
What is cool about this is that we can simulate a stack in a remote JVM that 
spans multiple real application runtimes.

http://www.jinspired.com/site/jxinsight-opencore-6-4-ea-12-released

Kind regards,

William

>-Original Message-
>From: Bob Foster [mailto:bobfos...@gmail.com]
>Sent: Sunday, July 8, 2012 01:32 AM
>To: jvm-langua...@googlegroups.com
>Cc: 'Da Vinci Machine Project'
>Subject: Re: [jvm-l] Improving the performance of stacktrace generation
>
>> Any thoughts on this? Does anyone else have need for
>lighter-weight name/file/line inspection of the call stack?
>
>Well, yes. Profilers do.
>
>Recall Cliff Click bragging a couple of years ago at the JVM Language
>Summit about how fast stack trace generation is in Azul Systems' OSs...and
>knocking Hotspot for being so slow. It turns out that stack trace
>generation is a very significant overhead in profiling Hotspot using JVMTI.
>Even CPU sampling on 20 ms. intervals can add 3% or more to execution time,
>almost entirely due to the delay in reaching a safe point (which also
>guarantees the profile will be incorrect) and generating a stack trace for
>each thread.
>
>But 3% is peanuts compared to the cost of memory profiling, which can
>require a stack trace on every new instance creation. In a profiler I wrote
>using JVMTI, I discovered that it was faster to call into JNI code on every
>method entry and exit (and exception catch), keeping a stack trace
>dynamically than to call into JNI only when memory was allocated and
>request a stack trace each time. The "fast" technique is about 3-10 times
>slower than running without profiling. The Netbeans profiler doesn't use
>this optimization, and its memory profiler when capturing every allocation,
>as I did, is 2-3 ORDERS OF MAGNITUDE slower than normal (non-server)
>execution.
>
>Faster stack traces would benefit the entire Hotspot profiling community.
>
>Bob
>
>On Sat, Jul 7, 2012 at 3:03 PM, Charles Oliver Nutter
>wrote:
>
>> Today I have a new conundrum for you all: I need stack trace
>> generation on Hotspot to be considerably faster than it is now.
>>
>> In order to simulate many Ruby features, JRuby (over)uses Java stack
>> traces. We recently (JRuby 1.6, about a year ago) moved to using the
>> Java stack trace as the source of our Ruby backtrace information,
>> mining out compiled frames and using interpreter markers to peel off
>> interpreter frames. The result is that a Ruby trace with mixed
>> compiled and interpreted code like this
>> (https://gist.github.com/3068210) turns into this
>> (https://gist.github.com/3068213). I consider this a great deal better
>> than the plain Java trace, and I know other language implementers have
>> lamented the verbosity of stack traces coming out of their languages.
>>
>> The unfortunate thing is that stack trace generation is very expensive
>> in the JVM, and in order to generate normal exceptions and emulate
>> other features we sometimes generate a lot of them. I think there's
>> value in exploring how we can make stack trace generation cheaper at
>> the JVM level.
>>
>> Here's a few cases in Ruby where we need to use Java stack traces to
>> provide the same features:
>>
>> * Exceptions as non-exceptional or moderately-exceptional method results
>>
>> In this case I'm specifically thinking about Ruby's tendency to
>> propagate errno values as exceptions; EAGAIN/EWOULDBLOCK for example
>> are thrown from nonblocking IO methods when there's no data available.
>>
>> You will probably say "that's a horrible use for exceptions" and I
>> agree. But there are a couple reasons why it's nicer too:
>> - using return value sigils requires you to propagate them back out
>> through many levels of calls
>> - exception-handling is cleaner in code than having all your errno
>> handling logic spliced into regular program flow
>>
>> In any case, 

Re: Improving the performance of stacktrace generation

2013-04-10 Thread Jason Zaugg
On Sunday, July 8, 2012 12:03:34 AM UTC+2, Charles Oliver Nutter wrote:
>
> * Exceptions as non-exceptional or moderately-exceptional method results 
>
> In this case I'm specifically thinking about Ruby's tendency to 
> propagate errno values as exceptions; EAGAIN/EWOULDBLOCK for example 
> are thrown from nonblocking IO methods when there's no data available. 
>
> You will probably say "that's a horrible use for exceptions" and I 
> agree. But there are a couple reasons why it's nicer too: 
> - using return value sigils requires you to propagate them back out 
> through many levels of calls 
> - exception-handling is cleaner in code than having all your errno 
> handling logic spliced into regular program flow 
>
> In any case, the cost of generating a stack trace for potentially 
> every non-blocking IO call is obviously too high. In JRuby, we default 
> to having EAGAIN/EWOULDBLOCK exceptions not generate a stack trace, 
> and you must pass a flag for them to do so. The justification is that 
> these exceptions are almost always used to branch back to the top of a 
> nonblocking IO loop, so the backtrace is useless. 
>

That's also the approach used in Scala for non local returns from closures 
and breaks [1] [2].

-jason

[1] 
https://github.com/scala/scala/blob/master/src/library/scala/util/control/NoStackTrace.scala
[2] 
https://github.com/scala/scala/blob/master/src/library/scala/util/control/ControlThrowable.scala
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: [jvm-l] Improving the performance of stacktrace generation

2013-04-10 Thread Bob Foster
> Any thoughts on this? Does anyone else have need for
lighter-weight name/file/line inspection of the call stack?

Well, yes. Profilers do.

Recall Cliff Click bragging a couple of years ago at the JVM Language
Summit about how fast stack trace generation is in Azul Systems' OSs...and
knocking Hotspot for being so slow. It turns out that stack trace
generation is a very significant overhead in profiling Hotspot using JVMTI.
Even CPU sampling on 20 ms. intervals can add 3% or more to execution time,
almost entirely due to the delay in reaching a safe point (which also
guarantees the profile will be incorrect) and generating a stack trace for
each thread.

But 3% is peanuts compared to the cost of memory profiling, which can
require a stack trace on every new instance creation. In a profiler I wrote
using JVMTI, I discovered that it was faster to call into JNI code on every
method entry and exit (and exception catch), keeping a stack trace
dynamically than to call into JNI only when memory was allocated and
request a stack trace each time. The "fast" technique is about 3-10 times
slower than running without profiling. The Netbeans profiler doesn't use
this optimization, and its memory profiler when capturing every allocation,
as I did, is 2-3 ORDERS OF MAGNITUDE slower than normal (non-server)
execution.

Faster stack traces would benefit the entire Hotspot profiling community.

Bob

On Sat, Jul 7, 2012 at 3:03 PM, Charles Oliver Nutter
wrote:

> Today I have a new conundrum for you all: I need stack trace
> generation on Hotspot to be considerably faster than it is now.
>
> In order to simulate many Ruby features, JRuby (over)uses Java stack
> traces. We recently (JRuby 1.6, about a year ago) moved to using the
> Java stack trace as the source of our Ruby backtrace information,
> mining out compiled frames and using interpreter markers to peel off
> interpreter frames. The result is that a Ruby trace with mixed
> compiled and interpreted code like this
> (https://gist.github.com/3068210) turns into this
> (https://gist.github.com/3068213). I consider this a great deal better
> than the plain Java trace, and I know other language implementers have
> lamented the verbosity of stack traces coming out of their languages.
>
> The unfortunate thing is that stack trace generation is very expensive
> in the JVM, and in order to generate normal exceptions and emulate
> other features we sometimes generate a lot of them. I think there's
> value in exploring how we can make stack trace generation cheaper at
> the JVM level.
>
> Here's a few cases in Ruby where we need to use Java stack traces to
> provide the same features:
>
> * Exceptions as non-exceptional or moderately-exceptional method results
>
> In this case I'm specifically thinking about Ruby's tendency to
> propagate errno values as exceptions; EAGAIN/EWOULDBLOCK for example
> are thrown from nonblocking IO methods when there's no data available.
>
> You will probably say "that's a horrible use for exceptions" and I
> agree. But there are a couple reasons why it's nicer too:
> - using return value sigils requires you to propagate them back out
> through many levels of calls
> - exception-handling is cleaner in code than having all your errno
> handling logic spliced into regular program flow
>
> In any case, the cost of generating a stack trace for potentially
> every non-blocking IO call is obviously too high. In JRuby, we default
> to having EAGAIN/EWOULDBLOCK exceptions not generate a stack trace,
> and you must pass a flag for them to do so. The justification is that
> these exceptions are almost always used to branch back to the top of a
> nonblocking IO loop, so the backtrace is useless.
>
> * Getting the current or previous method's name/file/line
>
> Ruby supports a number of features that allow you to get basic
> information about the method currently being executed or the method
> that called it. The most general of these features is the "caller"
> method, which provides an array of all method name + file + line that
> would appear in a stack trace at this point. This feature is often
> abused to get only the current or previous frame, and so in Ruby 1.9
> they added __method__ to get the currently-executing method's
> name+file+line.
>
> In both cases, we must generate a full Java trace for these methods
> because the name of a method body is not necessarily statically known.
> We often want only the current frame or the current and previous
> frames, but we pay the cost of generating an entire Java stack trace
> to get them.
>
> * Warnings that actually report the line of code that triggered them
>
> In Ruby, it is possible to generate non-fatal warnings to stderr. In
> many cases, these warnings automatically include the file and line at
> which the triggering code lives. Because the warning logic is
> downstream from the Ruby code, we again must use a full Java stack
> trace to find the most recent (on stack) Ruby frame. This causes
> warning

Re: Improving the performance of stacktrace generation

2012-07-07 Thread Mark Roos
>From Charile

Any thoughts on this? Does anyone else have need for lighter-weight
name/file/line inspection of the call stack?

Yeah I need it for my debugger and error displays.  But I need it for 
suspended threads
( my debugging steps ) as well as for exceptions.  And for exceptions it 
would be nice
to access the stack vars as well.

Currently I have a debug agent I use to help with this but it would be 
nice if I didn't.

I'll probably look at Lukas' coroutines for this eventually.

regards
mark___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Improving the performance of stacktrace generation

2012-07-07 Thread Rémi Forax
On 07/08/2012 12:50 AM, Charles Oliver Nutter wrote:
> On Saturday, July 7, 2012, Rémi Forax wrote:
>
> You can use Throwable.getStackTraceElement()
> which is package visible and OpenJDK specific but at least
> it will be faster for all VMs that uses OpenJDK.
>
> I'll certainly explore that to see if it improves the situation. If 
> it's faster, it might be a way out in some circumstances.
>
> It seems like an official public API is needed here...
>
> Please never optimize warnings, they are here to bug users
>
> until they fix the thing. So they should be slow :)
>
>
> Yes, except when *everyone else* has faster warnings than you. Then 
> you're just giving people another reason to not use your stuff.
>
> Granted, JRuby is now becoming far and away the fastest Ruby 
> implementation for exactly the reasons that stack traces are slow, but 
> often making 90% of the code 5x faster but 10% of the code 100x slower 
> means people give up on you without bothering.
>
> Remember, I agree with you...but I also feel like this attitude has 
> allowed stack trace generation to avoid optimization effort for a long 
> time, and there *are* useful things you can do with an introspectable 
> call stack.

Throwable.getStackTraceElement() let you walk the stack trace without 
generating the whole stack trace,
in my opinion it's enough.

BTW, I also think you are responsible too for the cost of generating 
stacktraces because the cost depends on the size of the stacktrace
and an AST interpreter is a big consumer of stack frames. I am guilty 
too, PHP.reboot has the same issue and
I try to mitigate that by avoiding to have an helper methods in the 
stacktrace of calls (not that easy without tailcall).

>
> - Charlie

Rémi

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Improving the performance of stacktrace generation

2012-07-07 Thread Charles Oliver Nutter
On Saturday, July 7, 2012, Rémi Forax wrote:

> You can use Throwable.**getStackTraceElement()
> which is package visible and OpenJDK specific but at least
> it will be faster for all VMs that uses OpenJDK.
>

I'll certainly explore that to see if it improves the situation. If it's
faster, it might be a way out in some circumstances.

It seems like an official public API is needed here...

Please never optimize warnings, they are here to bug users
>
> until they fix the thing. So they should be slow :)
>

Yes, except when *everyone else* has faster warnings than you. Then you're
just giving people another reason to not use your stuff.

Granted, JRuby is now becoming far and away the fastest Ruby implementation
for exactly the reasons that stack traces are slow, but often making 90% of
the code 5x faster but 10% of the code 100x slower means people give up on
you without bothering.

Remember, I agree with you...but I also feel like this attitude has allowed
stack trace generation to avoid optimization effort for a long time, and
there *are* useful things you can do with an introspectable call stack.

- Charlie
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Improving the performance of stacktrace generation

2012-07-07 Thread Rémi Forax
On 07/08/2012 12:03 AM, Charles Oliver Nutter wrote:
> Today I have a new conundrum for you all: I need stack trace
> generation on Hotspot to be considerably faster than it is now.
>
> In order to simulate many Ruby features, JRuby (over)uses Java stack
> traces. We recently (JRuby 1.6, about a year ago) moved to using the
> Java stack trace as the source of our Ruby backtrace information,
> mining out compiled frames and using interpreter markers to peel off
> interpreter frames. The result is that a Ruby trace with mixed
> compiled and interpreted code like this
> (https://gist.github.com/3068210) turns into this
> (https://gist.github.com/3068213). I consider this a great deal better
> than the plain Java trace, and I know other language implementers have
> lamented the verbosity of stack traces coming out of their languages.
>
> The unfortunate thing is that stack trace generation is very expensive
> in the JVM, and in order to generate normal exceptions and emulate
> other features we sometimes generate a lot of them. I think there's
> value in exploring how we can make stack trace generation cheaper at
> the JVM level.
>
> Here's a few cases in Ruby where we need to use Java stack traces to
> provide the same features:
>
> * Exceptions as non-exceptional or moderately-exceptional method results
>
> In this case I'm specifically thinking about Ruby's tendency to
> propagate errno values as exceptions; EAGAIN/EWOULDBLOCK for example
> are thrown from nonblocking IO methods when there's no data available.
>
> You will probably say "that's a horrible use for exceptions" and I
> agree. But there are a couple reasons why it's nicer too:
> - using return value sigils requires you to propagate them back out
> through many levels of calls
> - exception-handling is cleaner in code than having all your errno
> handling logic spliced into regular program flow
>
> In any case, the cost of generating a stack trace for potentially
> every non-blocking IO call is obviously too high. In JRuby, we default
> to having EAGAIN/EWOULDBLOCK exceptions not generate a stack trace,
> and you must pass a flag for them to do so. The justification is that
> these exceptions are almost always used to branch back to the top of a
> nonblocking IO loop, so the backtrace is useless.

I don't see how to do more.

>
> * Getting the current or previous method's name/file/line
>
> Ruby supports a number of features that allow you to get basic
> information about the method currently being executed or the method
> that called it. The most general of these features is the "caller"
> method, which provides an array of all method name + file + line that
> would appear in a stack trace at this point. This feature is often
> abused to get only the current or previous frame, and so in Ruby 1.9
> they added __method__ to get the currently-executing method's
> name+file+line.
>
> In both cases, we must generate a full Java trace for these methods
> because the name of a method body is not necessarily statically known.
> We often want only the current frame or the current and previous
> frames, but we pay the cost of generating an entire Java stack trace
> to get them.

You can use Throwable.getStackTraceElement()
which is package visible and OpenJDK specific but at least
it will be faster for all VMs that uses OpenJDK.

>
> * Warnings that actually report the line of code that triggered them
>
> In Ruby, it is possible to generate non-fatal warnings to stderr. In
> many cases, these warnings automatically include the file and line at
> which the triggering code lives. Because the warning logic is
> downstream from the Ruby code, we again must use a full Java stack
> trace to find the most recent (on stack) Ruby frame. This causes
> warnings to be as expensive as regular exceptions.

Please never optimize warnings, they are here to bug users
until they fix the thing. So they should be slow :)

>
> Because the use of frame introspection (in this case through stack
> traces) has largely been ignored on current JVMs, I suspect there's a
> lot of improvement possible. At a minimum, the ability to only grab
> the top N frames from the stack trace could be a great improvement
> (Hotspot even has flags to restrict how large a trace it will
> generate, presumably to avoid the cost of accounting for deep stacks
> and generating traces from them).
>
> Any thoughts on this? Does anyone else have need for lighter-weight
> name/file/line inspection of the call stack?
>
> - Charlie

Rémi

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Improving the performance of stacktrace generation

2012-07-07 Thread Charles Oliver Nutter
Today I have a new conundrum for you all: I need stack trace
generation on Hotspot to be considerably faster than it is now.

In order to simulate many Ruby features, JRuby (over)uses Java stack
traces. We recently (JRuby 1.6, about a year ago) moved to using the
Java stack trace as the source of our Ruby backtrace information,
mining out compiled frames and using interpreter markers to peel off
interpreter frames. The result is that a Ruby trace with mixed
compiled and interpreted code like this
(https://gist.github.com/3068210) turns into this
(https://gist.github.com/3068213). I consider this a great deal better
than the plain Java trace, and I know other language implementers have
lamented the verbosity of stack traces coming out of their languages.

The unfortunate thing is that stack trace generation is very expensive
in the JVM, and in order to generate normal exceptions and emulate
other features we sometimes generate a lot of them. I think there's
value in exploring how we can make stack trace generation cheaper at
the JVM level.

Here's a few cases in Ruby where we need to use Java stack traces to
provide the same features:

* Exceptions as non-exceptional or moderately-exceptional method results

In this case I'm specifically thinking about Ruby's tendency to
propagate errno values as exceptions; EAGAIN/EWOULDBLOCK for example
are thrown from nonblocking IO methods when there's no data available.

You will probably say "that's a horrible use for exceptions" and I
agree. But there are a couple reasons why it's nicer too:
- using return value sigils requires you to propagate them back out
through many levels of calls
- exception-handling is cleaner in code than having all your errno
handling logic spliced into regular program flow

In any case, the cost of generating a stack trace for potentially
every non-blocking IO call is obviously too high. In JRuby, we default
to having EAGAIN/EWOULDBLOCK exceptions not generate a stack trace,
and you must pass a flag for them to do so. The justification is that
these exceptions are almost always used to branch back to the top of a
nonblocking IO loop, so the backtrace is useless.

* Getting the current or previous method's name/file/line

Ruby supports a number of features that allow you to get basic
information about the method currently being executed or the method
that called it. The most general of these features is the "caller"
method, which provides an array of all method name + file + line that
would appear in a stack trace at this point. This feature is often
abused to get only the current or previous frame, and so in Ruby 1.9
they added __method__ to get the currently-executing method's
name+file+line.

In both cases, we must generate a full Java trace for these methods
because the name of a method body is not necessarily statically known.
We often want only the current frame or the current and previous
frames, but we pay the cost of generating an entire Java stack trace
to get them.

* Warnings that actually report the line of code that triggered them

In Ruby, it is possible to generate non-fatal warnings to stderr. In
many cases, these warnings automatically include the file and line at
which the triggering code lives. Because the warning logic is
downstream from the Ruby code, we again must use a full Java stack
trace to find the most recent (on stack) Ruby frame. This causes
warnings to be as expensive as regular exceptions.

Because the use of frame introspection (in this case through stack
traces) has largely been ignored on current JVMs, I suspect there's a
lot of improvement possible. At a minimum, the ability to only grab
the top N frames from the stack trace could be a great improvement
(Hotspot even has flags to restrict how large a trace it will
generate, presumably to avoid the cost of accounting for deep stacks
and generating traces from them).

Any thoughts on this? Does anyone else have need for lighter-weight
name/file/line inspection of the call stack?

- Charlie
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev