On Sun, Dec 5, 2010 at 9:58 AM, Subbu Sastry <[email protected]> wrote: > So, while it is true that the runtime of a dynamic language has to > transform the dynamic language to a typed bytecode, I think it also > means that the rntime has to implement any optimizations (inlining, > type guards, unboxing, EA, etc.) in the dynamic language VM which the > JVM cannot see through.
Yes, I agree. I see the goal of "high performance" for JRuby following a few paths (which are not mutually exclusive, and feed into one another: * Basic static optimization (done in a limited way already, e.g. eliminating heap scopes when not needed, omitting frames when not likely to be needed, etc). * Lift dynamic calls to guard + static call based on runtime information, to permit JVM optimizations to apply better to Ruby. * Perform JVM-like optimizations at the bytecode level where the JVM does not do a good enough job or where Ruby-specific behaviors are difficult to "explain" to the JVM. I mention the first path is already underway, in the current (fairly naïve) static compiler we have today. Method bodies are inspected for closures, "magic" method names like 'eval', and so on...and based on that we can reduce the per-call overhead for those methods. More can be done with this, but dynamic optimization is where the good stuff comes into place. "Dynopt", currently experimental on JRuby master, starts to take the next step, looking at call sites being jitted and emitting both a slow fully-dynamic path and a fast guard-plus-static-call path. This has, in small experiments, improved performance many times over...considerably faster than most other JVM dynlangs that do not have opportunities to use runtime information for optimization. But the down side is that bytecode size starts to increase very rapidly since each dyncall is now significantly more logic. This is where the third phase starts to come in, which we have to a limited extent in our IR logic (thanks to Subbu) and which Rémi has been doing with phpreboot. Here, rather than try to accommodate all possible paths through a piece of code in the same blob of bytecode, we can start specializing paths, introducing traced optimizations, propagating values and types...ultimately distilling down to smaller, less-complex bytecode as quickly as possible rather than overloading the JVM JIT with gigantic "all-in-one" method bodies. Bringing this back to the discussion on numeric operations against Integer... Without more help from the JVM, the best future for optimizing boxed math to primitive math almost certainly lies in dynamic optimization. Only when you know at runtime that calls are being performed against boxed numerics can you start to consistently lift those operations to primitive math. You can, as in Groovy or Erjang, provide specialized call paths to attempt to propagate primitives as far as possible, but eventually things fall back into Object and you're boxed again. With dynamic optimizations, especially bytecode-level optimization like inlining, tracing, etc, you can propagate them as far as you like (and Rémi has shown how far you can take this...and how powerful a tool invokedynamic can be for making that easier). - Charlie -- You received this message because you are subscribed to the Google Groups "JVM Languages" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en.
