It was already possible to run dynamic languages on top of the JVM, but the goal is to ease new dynamic language implementations and increase their performance. This project was the reference implementation of JSR 292 (Supporting Dynamically Typed Languages on the Java Platform).[1]
JSR 292 (Supporting Dynamically Typed Languages on the Java Platform)[1] proposes to:
add a new invokedynamic instruction at the JVM level, to allow method invocation relying on dynamic type checking,[3][4][5]
to be able to change classes and methods at runtime dynamically in a production environment.
Following the success of the JRubyJava implementation, the Da Vinci project was started at the end of January 2008.[6] The capabilities experimented by Da Vinci were planned to be added to Java 7. It aims to prototype this JSR, but also other lower-priority extensions.[7] The first working prototype, developed as a patch on OpenJDK, was announced and made available on end of August 2008.[8][9][10]
Since then, the JRuby team has successfully wired dynamic invocation in their codebase. Dynamic invocation shipped with the 1.1.5 release, and will be disabled on JVMs without invokedynamic capabilities.[11]
Since then, the project has been integrated in the JDK 7 codebase[12] and then integrated in the Java 7 release.
Architecture
Dynamic invocation is built on the fact that, even if Java is a strongly static language at the language level, the type information is much less prevalent at the bytecode level.
However, dynamic languages implementations need to be able to use just-in-time compilation (rather than reflection) to achieve good performance, and so to compile scripts to bytecode at runtime.[citation needed] To be allowed to be run by the Java Virtual Machine, these bytecodes must be verified prior to the execution, and the verifier check that the types are static throughout the code. It leads to these implementations having to create many different bytecodes for the different contexts of a method call, each time the signature of the arguments change.
This not only uses a lot of memory, but also fills a memory area called Metaspace (Permanent Generation prior to Java 8), a part of the heap used by the JVM to store information about classes. Memory used in this area is almost never garbage collected because it stores immutable data in the context of Java programs; and because of that, dynamic languages implementations can only compile a small part of the scripts.[13]
JSR 292 proposes to:
provide a mechanism whereby an existing class can be loaded and modified, producing a new class with those modifications but sharing the rest of its structure and data, thus not filling the Permanent Generation space,
provide the new invokedynamic bytecode which allows the JVM to optimize calls of this kind.[3]
^Nutter, Charles (2008-09-11). "A First Taste of InvokeDynamic". Retrieved 2008-09-13. I managed to successfully wire InvokeDynamic directly into JRuby's dispatch process! Such excitement! The code is already in JRuby's trunk, and will ship with JRuby 1.1.5 (though it obviously will be disabled on JVMs without InvokeDynamic).
^Rose, John (2009-04-22). "progress: indy.patch -> JDK7". Retrieved 2009-04-30. The majority of indy.patch has entered the JDK7 VM at my workgroup's integration repo, today at about 4:00AM PDT:
^Nutter, Charles (2008-09-11). "A First Taste of InvokeDynamic". Retrieved 2008-02-06. The dirty secret of several JVM implementations, Hotspot included, is that there's a separate heap (or a separate generation of the heap) used for special types of data like class definitions, class metadata, and sometimes bytecode or JITted native code. And it couldn't have a scarier name: The Permanent Generation. Except in rare cases, objects loaded into the PermGen are never garbage collected (because they're supposed to be permanent, get it?) and if not used very, very carefully, it will fill up(...)