28 Oct 2011

feedPlanet Ruby

O'Reilly Ruby: MacRuby: The Definitive Guide

Ruby and Cocoa on OS X, the iPhone, and the Device That Shall Not Be Named

28 Oct 2011 8:00pm GMT

14 Oct 2011

feedPlanet Ruby

Charles Oliver Nutter: Why Clojure Doesn't Need Invokedynamic (Unless You Want It to be More Awesome)

This was originally posted as a comment on @fogus's blog post "Why Clojure doesn't need invokedynamic, but it might be nice". I figured it's worth a top-level post here.

Ok, there's some good points here and a few misguided/misinformed positions. I'll try to cover everything.

First, I need to point out a key detail of invokedynamic that may have escaped notice: any case where you must bounce through a generic piece of code to do dispatch -- regardless of how fast that bounce may be -- prevents a whole slew of optimizations from happening. This might affect Java dispatch, if there's any argument-twiddling logic shared between call sites. It would definitely affect multimethods, which are using a hand-implemented PIC. Any case where there's intervening code between the call site and the target would benefit from invokedynamic, since invokedynamic could be used to plumb that logic and let it inline straight through. This is, indeed, the primary benefit of using invokedynamic: arbitrarily complex dispatch logic folds away allowing the dispatch to optimize as if it were direct.

Your point about inference in Java dispatch is a fair one...if Clojure is able to infer all cases, then there's no need to use invokedynamic at all. But unless Clojure is able to infer all cases, then you've got this little performance time bomb just waiting to happen. Tweak some code path and obscure the inference, and kablam, you're back on a slow reflective impl. Invokedynamic would provide a measure of consistency; the only unforeseen perf impact would be when the dispatch turns out to *actually* be polymorphic, in which case even a direct call wouldn't do much better.

For multimethods, the benefit should be clear: the MM selection logic would be mostly implemented using method handles and "leaf" logic, allowing hotspot to inline it everywhere it is used. That means for small-morphic MM call sites, all targets could potentially inline too. That's impossible without invokedynamic unless you generate every MM path immediately around the eventual call.

Now, on to defs and Var lookup. Depending on the cost of Var lookup, using a SwitchPoint-based invalidation plus invokedynamic could be a big win. In Java 7u2, SwitchPoint-based invalidation is essentially free until invalidated, and as you point out that's a rare case. There would essentially be *no* cost in indirecting through a var until that var changes...and then it would settle back into no cost until it changes again. Frequently-changing vars could gracefully degrade to a PIC.

It's also dangerous to understate the impact code size has on JVM optimization. The usual recommendation on the JVM is to move code into many small methods, possibly using call-through logic as in multimethods to reuse the same logic in many places. As I've mentioned, that defeats many optimizations, so the next approach is often to hand-inline logic everywhere it's used, to let the JVM have a more optimizable view of the system. But now we're stepping on our own feet...by adding more bytecode, we're almost certainly impacting the JVM's optimization and inlining budgets.

OpenJDK (and probably the other VMs too) has various limits on how far it will go to optimize code. A large number of these limits are based on the bytecoded size of the target methods. Methods that get too big won't inline, and sometimes won't compile. Methods that inline a lot of code might not get inlined into other methods. Methods that inline one path and eat up too much budget might push out more important calls later on. The only way around this is to reduce bytecode size, which is where invokedynamic comes in.

As of OpenJDK 7u2, MethodHandle logic is not included when calculating inlining budgets. In other words, if you push all the Java dispatch logic or multimethod dispatch logic or var lookup into mostly MethodHandles, you're getting that logic *for free*. That has had a tremendous impact on JRuby performance; I had previous versions of our compiler that did indeed infer static target methods from the interpreter, but they were often *slower* than call site caching solely because the code was considerably larger. With invokedynamic, a call is a call is a call, and the intervening plumbing is not counted against you.

Now, what about negative impacts to Clojure itself...

#0 is a red herring. JRuby supports Java 5, 6, and 7 with only a few hundred lines of changes in the compiler. Basically, the compiler has abstract interfaces for doing things like constant lookup, literal loading, and dispatch that we simply reimplement to use invokedynamic (extending the old non-indy logic for non-indified paths). In order to compile our uses of invokedynamic, we use Rémi Forax's JSR-292 backport, which includes a "mock" jar with all the invokedynamic APIs stubbed out. In our release, we just leave that library out, reflectively load the invokedynamic-based compiler impls, and we're off to the races.

#1 would be fair if the Oracle Java 7u2 early-access drops did not already include the optimizations that gave JRuby those awesome numbers. The biggest of those optimizations was making SwitchPoint free, but also important are the inlining discounting and MutableCallSite improvements. The perf you see for JRuby there can apply to any indirected behavior in Clojure, with the same perf benefits as of 7u2.

For #2, to address the apparent vagueness in my blog post...the big perf gain was largely from using SwitchPoint to invalidate constants rather than pinging a global serial number. Again, indirection folds away if you can shove it into MethodHandles. And it's pretty easy to do it.

#3 is just plain FUD. Oracle has committed to making invokedynamic work well for Java too. The current thinking is that "lambda", the support for closures in Java 7, will use invokedynamic under the covers to implement "function-like" constructs. Oracle has also committed to Nashorn, a fully invokedynamic-based JavaScript implementation, which has many of the same challenges as languages like Ruby or Python. I talked with Adam Messinger at Oracle, who explained to me that Oracle chose JavaScript in part because it's so far away from Java...as I put it (and he agreed) it's going to "keep Oracle honest" about optimizing for non-Java languages. Invokedynamic is driving the future of the JVM, and Oracle knows it all too well.

As for #4...well, all good things take a little effort :) I think the effort required is far lower than you suspect, though.

14 Oct 2011 2:40pm GMT

07 Oct 2011

feedPlanet Ruby

Ruby on Rails: Rails 3.1.1 has been released!

Hi everyone,

Rails 3.1.1 has been released. This release requires at least sass-rails 3.1.4

CHANGES

ActionMailer

ActionPack

ActiveModel

ActiveRecord

ActiveResource

ActiveSupport

Railties

SHA-1

You can find an exhaustive list of changes on github. Along with the closed issues marked for v3.1.1.

Thanks to everyone!

07 Oct 2011 5:26pm GMT

06 Oct 2011

feedPlanet Ruby

Ruby on Rails: [ANN] Rails 3.1.1.rc3

Hi everyone,

Rails 3.1.1.rc3 has been released. Please give it a try, it's our chance to fix regressions you might find and make a beautiful 3.1.1 stable release. If there are no regressions I will be releasing 3.1.1 final next October 7th. If you find any regression please contact me ASAP by email, twitter or github.

CHANGES

ActionMailer

ActionPack

ActiveModel

ActiveRecord

ActiveResource

ActiveSupport

Railties

You can find an exhaustive list of changes on github. Along with the closed issues marked for v3.1.1. You can also take a look to what's new between v3.1.1.rc2 and v3.1.1.rc3

You can also see issues we haven't closed yet.

Thanks to everyone!

06 Oct 2011 2:34am GMT

29 Sep 2011

feedPlanet Ruby

Ruby on Rails: [ANN] Rails 3.1.1.rc2

Hi everyone,

Rails 3.1.1.rc2 has been released. Please give it a try, it's our chance to fix regressions you might find and make a beautiful 3.1.1 stable release. If there are no regressions I will be releasing 3.1.1 final next October 3rd. If you find any regression please contact me ASAP by email, twitter or github.

CHANGES

ActionMailer

ActionPack

ActiveModel

ActiveRecord

ActiveResource

ActiveSupport

Railties

You can find an exhaustive list of changes on github. Along with the closed issues marked for v3.1.1. You can also take a look to what's new between v3.1.1.rc1 and v3.1.1.rc2

You can also see issues we haven't closed yet.

Thanks to everyone!

29 Sep 2011 10:20pm GMT

15 Sep 2011

feedPlanet Ruby

Ruby on Rails: [ANN] Rails 3.1.1.rc1

Hi everyone,

Rails 3.1.1.rc1 has been released. Please give it a try, it's our chance to fix regressions you might find and make a beautiful 3.1.1 stable release. If there are no regressions I will be releasing 3.1.1 final next September 16th during GoGaRuCo.

CHANGES

ActionMailer

ActionPack

ActiveModel

ActiveRecord

ActiveResource

ActiveSupport

Railties

You can find an exhaustive list of changes on github. Along with the closed issues marked for v3.1.1.

You can also see issues we haven't closed yet.

Thanks to everyone!

15 Sep 2011 12:55am GMT

31 Aug 2011

feedPlanet Ruby

Ruby on Rails: Rails 3.1.0 has been released!

Hi everybody!

It's been 3 Months since RailsConf, so I think it's time we released Rails 3.1.0. So, here it is! I've released Rails 3.1.0!

CHANGES

For a much more attractive and easy to read list of changes, please check out the awesome Rails 3.1.0 Release Notes on the Rails Guides site. For a less attractive list of changes, please continue to read!

Here are some highlights of the major changes in Rails 3.1.0:

ActionPack

ActiveModel

ActiveRecord

ActiveResource

ActiveSupport

Railties

For more info

For a more detailed list of changes, please see each of the CHANGELOG files checked in to the Rails repository on github.

For an even more detailed list of changes, please see the commit list between Rails 3.0.10 and 3.1.0.

The End

I am personally very proud of this release. I want to say thank you to the people testing our release candidates, the people submitting patches and sending in bug reports. I think that Rails 3.1.0 is the best release of Rails to date, and we could not have done it without you.

Please continue to create amazing things with this framework!

SHA-1

<3 <3 <3

31 Aug 2011 9:20pm GMT

29 Aug 2011

feedPlanet Ruby

Ruby on Rails: The Ruby on Rails API Switches to SDoc

The Ruby on Rails API is switching to SDoc starting with 3.1.

SDoc is a RDoc format created by Володя Колесников (@voloko) that has been powering railsapi.com for a long time.

Among other things, SDoc provides a search box with fuzzy match completion, tree browsing, keyboard navigation, and a really nice template.

You can already see the upgrade in the edge API.

We'd like to thank very much Володя for his work updating SDoc for the official API. Thanks man!

29 Aug 2011 2:32pm GMT

Ruby on Rails: [ANN] Rails 3.1.0.rc8

Hi everyone,

Rails 3.1.0.rc8 has been released (we've an issue with rc7). This is the final release candidate. Please give it a try, it's our last chance to fix regressions and severe issues. We will be releasing final 3.1.0 next August 30th.

CHANGES

Check the CHANGELOG file of each framework to see what we've changed.

You can find an exhaustive list of changes on github. Along with the closed issues marked for v3.1.0.

You can also see issues we haven't closed.

A comprehensive CHANGELOG will be announced when 3.1.0 final is released.

Thanks!

29 Aug 2011 1:39pm GMT

17 Aug 2011

feedPlanet Ruby

Ruby on Rails: [ANN] Rails 2.3.14

Hi everyone,

Rails 2.3.14 has been released. This release contains critical security fixes.

CHANGES

You can find an exhaustive list of changes on github. Here are some notable excerpts:

4 Security Fixes

Please follow the links to see specific information about each vulnerability, along with individual patches for fixing them.

Also remember to subscribe to the Ruby on Rails Security mailing list.

2 Bug Fixes

THE END

Thanks! <3

17 Aug 2011 12:02am GMT

16 Aug 2011

feedPlanet Ruby

Ruby on Rails: [ANN] Rails 3.1.0.rc6

Hi everyone,

Rails 3.1.0.rc6 has been released. This release contains critical security fixes.

CHANGES

You can find an exhaustive list of changes on github. Along with the closed issues marked for v3.1.0.

You can also see issues we haven't closed.

A comprehensive CHANGELOG will be announced when 3.1.0 final is released. Barring any show stopping bugs, Rails 3.1.0 will be released on August 30th.

4 Security Fixes

Please follow the links to see specific information about each vulnerability, along with individual patches for fixing them.

Please note that these security fixes do not have CVE identifiers. We requested identifiers on August 5th, and have yet to received a response. When we get identifiers, we'll update the notices with those values.

Also remember to subscribe to the Ruby on Rails Security mailing list.

Why was this release delayed?

You may have noticed this release was originally slated to be released on August 8th. We decided to delay the release in order to obtain CVE identifiers. Unfortunately, identifiers still have not been issued. We felt that getting the security fixes to our users was more important than obtaining CVE values.

That is why our release is late, and contains no CVE identifiers.

THE END

Thanks! <3

16 Aug 2011 11:38pm GMT

Ruby on Rails: [ANN] Rails 3.0.10

Hi everyone,

Rails 3.0.10 has been released. This release contains critical security fixes.

CHANGES

You can find an exhaustive list of changes on github. Here are some notable excerpts:

4 Security Fixes

Please follow the links to see specific information about each vulnerability, along with individual patches for fixing them.

Please note that these security fixes do not have CVE identifiers. We requested identifiers on August 5th, and have yet to received a response. When we get identifiers, we'll update the notices with those values.

Also remember to subscribe to the Ruby on Rails Security mailing list.

ActionPack:

ActiveRecord:

Why was this release delayed?

You may have noticed this release was originally slated to be released on August 8th. We decided to delay the release in order to obtain CVE identifiers. Unfortunately, identifiers still have not been issued. We felt that getting the security fixes to our users was more important than obtaining CVE values.

That is why our release is late, and contains no CVE identifiers.

THE END

Thanks! <3

16 Aug 2011 11:37pm GMT

10 Aug 2011

feedPlanet Ruby

Charles Oliver Nutter: Invokedynamic in JRuby: Constant Lookup

This is the first of a set (not a series...there's no particular order) of articles I'll write on how JRuby is using invokedynamic. Hopefully they will show Rubyists how drastically invokedynamic is going to improve JRuby, and show other JVM language folks how to use invokedynamic effectively.

Hello friends!

I figured it's about time for me to start writing a bit on how JRuby is actually using invokedynamic.

As of today, JRuby utilizes invokedynamic far more than any other mainstream JVM language. We have worked very closely with the JSR leads and the OpenJDK developers to make sure invokedynamic runs well. And we have been advocating invokedynamic as a game-changer for the JVM and for JVM languages.

Let's explore one area where JRuby is using invokedynamic: Ruby's "constant" lookup.

Non-constant "Constants"

A constant in Ruby is defined on a class or module, and is subject to Ruby's typical namespacing logic. Constants start with a capital letter.

I often put "constants" in parentheses because constant values can be reassigned. This will usually produce a warning...but not an error. This means we can't simply look up constant values once and never look them up again (without special tricks I'll get into later).

Constant lookup is a also bit more complicated than method lookup. When retrieving a constant, Ruby first scans lexically-enclosing scopes' classes and modules for the constant. If the constant can't be found, the next search walks the current class's inheritance hierarchy. If we still can't find the constant, const_missing is called on the current class.

In order to make constant lookup fast, we want to do some sort of caching. In classic JRuby, Ruby 1.9 (YARV), Rubinius, and probably most other modern Ruby implementations, this is done with a global serial number. Whenever a constant is updated or a module is included (changing the inheritance hierarchy) all cached constants everywhere are forced to lookup again.

I have played with mechanisms for reducing the global impact of constant invalidation, but because constants can be looked up lexically it's simply too complicated to localize (since we need invalidate classes down-hierarchy from the change and we also need to update all lexical scopes that might see the change).

Constant Invalidation in JRuby 1.6

The logic in JRuby 1.6 goes something like this:

This turns out to work fairly well. The same mechanism in Ruby 1.9 produced drastically faster constant lookups, and JRuby's performance is even better than 1.9.

But there's a problem here. Because there's this constant pinging of the global constant serial number, every constant access can potentially produce a new value. So we're paying the cost to check that serial number as well as interfering with optimizations that want to see constant values actually be constant.

Can we do better?

Quick Invokedynamic Primer

The main atom of invokedynamic is the MethodHandle. Method handles are essentially function pointers, which can point at Java methods or fields, constructors, constant values, or other method handles. Invokedynamic also provides the MethodHandles utility class, which lets us juggle method handles in various ways:
  • adapting method signatures by casting, adding, moving, or dropping arguments
  • combining three handles ("test", "target", and "fallback") to form new a "guard with test" if-statement-like handle
  • wrap handles with exception handling or argument/return pre/post-processing
You can think of method handles and the chains of adapter handles that stitch them together as a special sort of functional language the JVM knows how to optimize. Given a chain of handles, you should usually get a piece of code that optimizes as well as (or better, in some cases) writing the same logic by hand in Java.

The invokedynamic bytecode simply provides a place to plug a method handle chain into code. When the JVM encounters an invokedynamic bytecode, it calls a "bootstrap method" associated with that bytecode for further instructions.

The bootstrap method returns a CallSite object, provided in java.lang.invoke. There are constant call sites for constant values, mutable call sites for when the target handle chain may have to change, and volatile call sites for when those changes must immediately be reflected across threads.

Once a CallSite has been installed for a given invokedynamic, subsequent hits skip the bootstrapping process, and we're off to the races.

SwitchPoint

I mentioned that the MethodHandles class provides a "guardWithTest" method for combining a test, a target (the "then" branch), and a fallback (the "else" branch). SwitchPoint, also in java.lang.invoke, acts like an on/off guardWithTest that once turned off can never be turned on again. You provide a target and fallback, and until the "switch" is thrown the target will be invoked. After the switch is thrown the fallback will be called.

What's the difference between this and a guardWithTest where the test just pings some global value? The difference is that SwitchPoint doesn't need to check anything.

Optimization and Deoptimization in the JVM

When the JVM decides to optimize a piece of code, it does so in an optimistic way. In very broad terms, this means it assumes its information up to this point is perfect: no new methods or classes will be introduced, profiling information is accurate, etc. Based on this "perfect" view of the world, it aggressively optimizes code.

Of course, the world isn't perfect. The JVM has to give up profiling and monitoring at some point, so it always has an imperfect view of the system. In order to avoid its aggressive optimizations triggering a fatal error later on, JVMs like OpenJDK (Hotspot) do something called deoptimization.

Deoptimization is the process by which running, optimized code can adapt on-the-fly to a changing system. In OpenJDK, there's several ways this is accomplished:
  • Branches out of compiled code back into the interpreter, when compiled code is determined to be invalid.
  • Guards around inlined virtual method accesses, to ensure we're still calling against the same class.
  • On-stack replacement, for fixing up a running method already on the native call stack
  • ...
Because of this ability to deoptimize, it's possible to support zero-cost guards at the JVM level. Returning to SwitchPoint, we can see how this new form of "guardWithTest" can be basically free: we're explicitly telling the JVM this switch is a rare occurrence it can optimize aggressively.

SwitchPoint for Constant Lookup

JRuby on invokedynamic uses SwitchPoint for constant lookup, as you'd expect. Instead of actively pinging that global constant serial number, we instead use a global SwitchPoint object to guard all cached constant accesses. When it comes time to invalidate the system's constants, we just flip the SwitchPoint off and create a new one. All SwitchPoint-guarded constant accesses in the system must then recache and use the new SwitchPoint.

In a well-behaved system, we should reach a steady state where no new constants are being defined and no new modules are being introduced. Because we're using SwitchPoint, the stable state means all constant accesses are treated as truly constant by the JVM, allowing optimizations that were impossible before. And of course this also means that we've achieved constant lookup performance very near a theoretical maximum.

Numbers

First, a caveat: SwitchPoint is implemented in a fairly naïve way in the released OpenJDK 7, using a volatile field as the switch value. As a result, SwitchPoint guardWithTest is very slow currently, and JRuby's SwitchPoint-based constant logic must be enabled. I show numbers below based on leading-edge Hotspot compiler patches that will go into the first update release (numbers provided by one of the Hotspot devs, Christian Thalinger...thanks Christian!)

The benchmark we're running is a modified version of bench_const_lookup in JRuby's benchmark suite. The modification here runs more iterations (10M instead of 1M) with more constant lookups (50 instead of 10) to get a better idea of optimized performance.

Here's JRuby running our constant-lookup benchmark without SwitchPoint-based constants on Java 7:


As I said before, this is pretty good. JRuby's existing constant lookup performance is roughly 2x faster than Ruby 1.9.2.

Next, we'll try JRuby with SwitchPoint constants on Java 7 (released version, so we expect this to be slow):




The perf hit of purely volatile SwitchPoint is apparent.

And finally, JRuby with SwitchPoint constants on a dev build of Hotspot, which uses deoptimization rather than a volatile field:




This is basically the performance of the 10M iteration loop alone. In fact, if you look at the resulting optimized assembly, the constant accesses have been eliminated entirely since they're optimistically inlined and never used. Of course this would normally not happen in real code, but it shows how much better the JVM can optimized Ruby's behavior using invokedynamic.

10 Aug 2011 12:59pm GMT

05 Aug 2011

feedPlanet Ruby

Ruby on Rails: [ANN] Rails 3.0.10.rc1 has been released!

Hi everyone,

Rails 3.0.10.rc1 has been released. As usual, please try out this release candidate and report any issues to the ruby on rails core mailing list. If no issues are found, we'll release 3.0.10 on August 8th (around 5pm PDT).

If you do find issues, please send them to the rails core mailing list. If the release candidate is found to not be backwards compatible with the previous release, we'll do another release candidate and postpone the final release date.

Remember that this is your chance to veto / postpone the rails release. Please take this opportunity to test!

CHANGES

You can find an exhaustive list of changes on github. Here are some notable excerpts:

From ActionPack:

From ActiveRecord:

THE END

Thanks!

-Aaron <3

05 Aug 2011 12:31am GMT

02 Aug 2011

feedPlanet Ruby

Charles Oliver Nutter: JRuby and Java 7: What to Expect

Java 7 has landed, with a modest set of new features and a few major improvements as well. What can you expect from JRuby running on Java 7?

What's In Java 7


The biggest changes in Java 7 are not related to the Java language at all. Sure, there's the "project coin" enhancements to the Java language, which add some exception-handling shortcuts, new literals for numbers, arrays, hashes, the oft-requested "strings in switch" support, and a few other things. But they're modest incremental changes; the real revolution is at the JVM and JDK level.

Invokedynamic


The most important change in Java 7 is the incorporation of a new bytecode -- invokedynamic -- and an API for building chains of "method handles" to back that bytecode up.

You can look at invokedynamic as a way for JVM users to communicate directly with the optimizing backend of the JVM. Method handles act as both function pointers and as function combinators, allowing a built-in way to construct a call protocol flow from a caller to a callee. You can move arguments around, insert new arguments, process existing arguments and return values, catch exceptions, and perform fast guarded branches between two (or more) paths. The invokedynamic bytecode itself provides a bytecode-level hook to which you attach your method handle chain, with the assumption that the JVM can optimize that chain directly into the invokedynamic caller.

The tl;dr is that invokedynamic makes it possible for the JVM to see through complicated method call logic, such as that found in dynamic languages, and optimize that logic like it would for regular "static" calls.

JRuby's master branch already takes heavy advantage of invokedynamic, by routing most Ruby calls through invokedynamic operations. For simple paths and those that have been optimized by the Hotspot guys (Hotspot is the VM at the core of OpenJDK), invokedynamic often provides performance improvements of 150-200%, with work ongoing to make it even faster. Other paths may not be as well-optimized by the "dot zero" version of OpenJDK 7, so there's opportunity to improve them.

Because JRuby is already well along the road to utilizing invokedynamic, you can try it out today.

  1. Build your own JRuby from master or grab a snapshot from our CI server.
  2. Grab a build of OpenJDK 7 from Oracle (or a build of OpenJDK 7 for OS X).
  3. Point JAVA_HOME at the new JDK and try out JRuby!
We're looking for small benchmarks that show the performance of invokedynamic (good or bad), so please contact me, the JRuby team, or the JRuby users mailing list with your reports from the field. Also, feel free to open performance bugs on the JRuby bug tracker if invokedynamic performs worse than non-invokedynamic. Pass -Xcompile.invokedynamic=false to JRuby to revert to the old non-invokedynamic logic.

NIO.2

NIO is Java's "New IO" APIs, a set of wrappers around low-level file-descriptor logic and memory buffers. NIO has been around since Java 1.4, but the recent update -- dubbed NIO.2 -- brings a sorely-needed update to the functionality provided:
  • Filesystem operations (like symlinks, permissions, etc) are now almost all available through NIO.2's filesystem APIs. This also includes standard, cross-platform support for filesystem events, such as watching a directory for changes (using efficient OS-level operations, rather than polling).
  • File and directory walking now comes with considerably less overhead and more options for filtering directory lists before handing filenames off to user code. There's also support for opening a directory directly and walking its contents as you would a file.
  • Most IO channel types now have asynchronous versions. Asynchronous in this case means "punt my IO operation to a built-in thread pool", with subsequent code checking on the status of those operations and getting results from a "future" handle.
For JRuby, the new IO APIs will mean we can support more filesystem operations across platforms without resorting to native code. It will also provide JRuby users a means of handling filesystem events and asynchronous IO operations without using a platform-specific library. We have not yet started adding NIO.2 support to JRuby's core classes, but that will come soon.

General Improvements

There's lots of smaller, less flashy changes in OpenJDK that also appear to help JRuby.

Even without invokedynamic, the latest OpenJDK 7 builds usually perform better than OpenJDK 6. Some benchmarks have proven to be as much as 2x faster, just by upgrading the JVM! General perf improvements will be more modest, but in almost every case we've tested OpenJDK 7 definitely performs better.

The release of OpenJDK 7 also brings improvements to the "tiered" compilation mode. Tiered compilation aims to merge the benefits of the "client" mode (fast startup) with those of the "server" mode (maximum peak performance). You can turn on tiered compilation using -XX:+TieredCompilation (in JAVA_OPTS or at the "java" command line, or prefixed with -J when passed to JRuby). We're looking for user reports about how well "tiered" mode works, too.

This general improvement means that even JRuby 1.6.x users can take advantage of OpenJDK 7 today, with the promise of even bigger improvements in JRuby 1.7 (our target release for pervasive invokedynamic support).

Consistency

As with previous Java releases, a great deal of care has been taken to ensure existing applications work properly. That applies as well to Java 7. We have been testing against Java 7 for over a year, on and off, and recently started running tests "green" with even heavy invokedynamic use.

We have made no major Java 7-specific fixes in JRuby...it should generally "just work".

Let Us Know!

As always, we really want to hear from you bleeding-edge users that are playing around with JRuby on Java 7. Please don't be shy...let us know how it works for you!

Update: The Hotspot guys have been helping me find invokedynamic bottlenecks in a few JRuby microbenchmarks, and discovered that a flaw in invokedynamic was causing too much code to inline, forcing out more important optimizations. The details belong in another post, but they offered me a long Hotspot flag to accomplish basically what their fix does: -XX:CompileCommand=dontinline,org.jruby.runtime.invokedynamic.InvokeDynamicSupport::invocationFallback ... With this flag, performance on e.g. "tak" easily beats stock JRuby (see the third benchmark run here: https://gist.github.com/1121880).

I would recommend trying this flag if you are finding invokedynamic slowdowns in JRuby.

02 Aug 2011 10:03pm GMT

27 Jul 2011

feedPlanet Ruby

Ruby on Rails: Rails now tested on Travis CI

Setting up continuous integration for Rails has been a complicated undertaking in the past.

Rails needs to be tested against different Ruby versions and various modes (such as running test cases in isolation/non-isolation, running ActiveRecord with identitymap enabled/disabled). This made the test suite run for an isanely long time (up to 2 hours on 1.9.2 alone) and required regular maintenance by the Rails core team.

Over the past weeks the folks at Travis CI have been working hard to provide a better experience to Rails continous integration and today we can happily announce that Rails is now testing on Travis CI!

Travis CI is doing a great job in providing multi-ruby testing capabilities and it is dead-simple to use. There's some great potential to this project and it might change the way we see open-source development and testing quite a bit.

So, if you are publishing any kind of open-source code, library or web application, we recommend you have a look at it. And if you have a spare hour once in a while then consider potentially jumping on board to help improve the code base.

Travis CI is using a separate physical worker server (and a quite beefy one!) for running workers dedicated to Rails builds. This server has kindly been sponsored by the great folks over at Enterprise Rails.

[Guest post by Josh Kalderimis & Sven Fuchs]

27 Jul 2011 10:52am GMT