This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/groovy-website.git
The following commit(s) were added to refs/heads/asf-site by this push:
new a4e0da0 clarify doco
a4e0da0 is described below
commit a4e0da063f6bc6fef4c3ef8e24d0b55b92206f61
Author: Paul King <[email protected]>
AuthorDate: Mon Apr 13 07:02:23 2026 +1000
clarify doco
Thanks to @dilyanpalauzov for raising the documentation inconsistency
---
site/src/site/pages/indy.groovy | 108 ++++++++++++++---------------
site/src/site/releasenotes/groovy-4.0.adoc | 11 +--
2 files changed, 57 insertions(+), 62 deletions(-)
diff --git a/site/src/site/pages/indy.groovy b/site/src/site/pages/indy.groovy
index f1ebbec..386e29e 100644
--- a/site/src/site/pages/indy.groovy
+++ b/site/src/site/pages/indy.groovy
@@ -42,89 +42,83 @@ layout 'layouts/main.groovy', true,
h2 'Introduction'
p '''
Since Groovy 2.0, support was added for
the JVM invokedynamic instruction.
- This instruction is supported since Java 7
and is a new bytecode instruction in the JVM
+ This instruction is supported since Java 7
and is a bytecode instruction in the JVM
that allows easier implementation of
dynamic languages.
- This instruction is used internally, by
the JVM, for the lambda support in Java 8.
+ This instruction is also used internally,
by the JVM, for lambda support in Java 8+.
'''
p '''
- This means that unlike APIs, AST
transformations or syntactic sugar,
- this feature is not visible to the
developer or the end user.
+ This feature is not visible to the
developer or the end user.
It is a compilation and runtime feature
only.
- This means that given two programs written
in Groovy,
- you have the choice to compile it with or
without invokedynamic support.
- Whatever you choose, it comes with pros
and cons.
+ It affects how Groovy compiles dynamic
method calls, property access, and other
+ dynamic operations into bytecode.
+ '''
+
+ h2 'Groovy 4.0+ (current)'
+ p '''
+ From Groovy 4.0 onwards, invokedynamic
bytecode generation is <b>enabled by default</b>.
+ There is a single set of jars, compiled
with invokedynamic enabled.
+ The separate "-indy" jars and Maven
classifiers from earlier versions are no longer needed.
+ '''
+ p '''
+ It is still possible to disable
invokedynamic for user-compiled code, which causes the
+ compiler to fall back to classic call-site
caching bytecode. This can be useful in cases
+ where call-site caching is faster for
specific workloads. To disable:
'''
ul {
li {
- yield 'classes compiled with
invokedynamic can only be used on JDK 1.7+'
- ul {
- li 'without invokedynamic, Groovy
classes are still compatible with JDK 1.6+'
- }
+ yield 'System property: '
+ code 'groovy.target.indy=false'
+ }
+ li {
+ yield 'Compiler configuration: set the
'
+ code 'indy'
+ yield ' optimization option to '
+ code 'false'
}
- li 'it is possible to mix classes compiled
with and without invokedynamic in the same project, as long as you run JDK 1.7+'
- li 'depending on the JVM (even different
minor versions of the JVM), you can target close to Java performance for
dynamic Groovy with invokedynamic support activated'
}
-
- h2 'JDK version'
p '''
- All JDK 7 versions ranging from 7u21 to
7u55 are buggy with regards to invokedynamic.
- If you plan to use invokedynamic support,
make sure you either use 7u60 or JDK 8.
+ Note that disabling invokedynamic only
affects the bytecode generated for your code.
+ The Groovy runtime jars themselves are
compiled with invokedynamic enabled.
'''
+ p '''
+ There are also internal thresholds that
can be tuned for performance
+ (search the codebase for
<code>groovy.indy.optimize.threshold</code>
+ and
<code>groovy.indy.fallback.threshold</code>).
+ '''
+
+ h2 'Groovy 2.0 to 3.x'
+
+ div(class: 'alert alert-info', role: 'alert') {
+ yield 'This section applies only to Groovy
versions before 4.0.'
+ }
- h2 'The distributions'
h3 'Two JARs'
- p 'The Groovy distribution comes with two
jars:'
+ p 'The Groovy distribution came with two jars:'
ul {
li {
code 'groovy-x.y.z.jar'
- yield ': compatible with JDK 1.6+,
contains Groovy sources compiled with call site caching'
+ yield ': compiled with classic
call-site caching'
}
li {
code 'groovy-x-y-z-indy.jar'
- yield ': compatible with JDK 1.7+,
contains Groovy sources compiled with invokedynamic'
+ yield ': compiled with invokedynamic'
}
}
p '''
- As Groovy core and the Groovy modules are
sometimes written in Groovy, we currently have no choice but to distribute two
distinct versions of Groovy.
- This means that if you pick the "normal"
jar, the Groovy classes of Groovy itself are compiled with call site caching,
- while if you use the "indy" jar, the
Groovy classes of Groovy itself are compiled using invokedynamic.
- '''
- p '''Both jars contain a fully working Groovy
implementation that is capable of compiling user supplied Groovy sources using
either
- invokedynamic or call site caching. The
sets of jars are mutually exclusive (don't put both on classpath) and the key
difference between
- them has to do with how the Groovy source
files that make up Groovy itself are compiled.
- '''
- p '''
- When accessing a Groovy jar from a Maven
repository, you can select the indy version using the 'indy' classifier.
+ Both jars contained a fully working Groovy
implementation capable of compiling user
+ code using either invokedynamic or
call-site caching. The sets of jars were mutually
+ exclusive (don't put both on classpath)
and the key difference was how the Groovy
+ source files that make up Groovy itself
were compiled.
'''
-
- h3 'Command-line and indy'
- p '''
- If you download the distribution and use
the command line,
- it's always the "normal" version of Groovy
which is picked up in classpath.
- This means that whatever command you use
(groovy, groovyc, groovysh or groovyConsole), invokedynamic support is not
available out of the box.
- To use a Groovy distribution that was
compiled with invokedynamic for its Groovy sources you have to switch the jars
manually.
- The distribution makes use of the jars in
the lib directory, while the indy jars are available in the indy directory.
- You have three things to do:
- '''
- ul {
- li 'remove or rename the groovy-*.jar
files in the lib directory'
- li 'replace them with the indy version
from the indy directory'
- li 'remove the -indy classifier from jar
names'
- }
- p "Here's a bash script that would do it all
at once:"
- pre { code '$ for f in `ls lib/groovy*.jar |
cut -d/ -f2`;do k=`basename $f .jar`; mv lib/$k.jar lib/$k.jar.old; cp
indy/$k-indy.jar lib/$k.jar ; done' }
-
- h3 'Running groovy script from command line'
p '''
- The usual way to run a script from the
command line is by "groovy foo.groovy", where foo.groovy is the Groovy program
in source form.
- To use indy for this you have to use the
indy compilation flag, "groovy --indy foo.groovy".
+ When accessing a Groovy jar from a Maven
repository, you could select the indy version using the 'indy' classifier.
'''
h3 'The compilation flag'
p '''
- Independently of the jar version that you
use, invokedynamic support requires a specific compilation flag (indy).
- If you want to compile your classes with
invokedynamic support, this flag must be set at compile time.
- The following tables show you what happens
with user compiled classes and Groovy core classes depending on the jar you use
and the compilation flag:
+ Independently of the jar version used,
invokedynamic support required a specific
+ compilation flag (indy). If you wanted to
compile your classes with invokedynamic
+ support, this flag had to be set at
compile time.
'''
p 'For user compiled classes:'
table(class: 'table') {
@@ -164,8 +158,8 @@ layout 'layouts/main.groovy', true,
}
}
p '''
- So even if you use the indy jar, if you
don't use the invokedynamic flag at compile time,
- then the compiled classes will use the
"old" format, meaning they will use the JDK1.6+ classes without invokedynamic.
+ So even if you used the indy jar, if you
didn't use the invokedynamic flag at compile time,
+ then the compiled classes would use the
"old" format with call-site caching.
'''
}
hr(class: 'divider')
diff --git a/site/src/site/releasenotes/groovy-4.0.adoc
b/site/src/site/releasenotes/groovy-4.0.adoc
index 05f1e26..234c40b 100644
--- a/site/src/site/releasenotes/groovy-4.0.adoc
+++ b/site/src/site/releasenotes/groovy-4.0.adoc
@@ -1104,19 +1104,20 @@ if you wanted. In Groovy 4, the old Antlr2 based parser
is removed.
Please use older versions of Groovy if you require the old parser.
[[Groovy4.0-indy-only]]
-=== Classic bytecode generation removal
+=== Invokedynamic bytecode enabled by default
For many versions, Groovy could generate classic _call-site based_ bytecode
or bytecode targeting the JDK7+ invoke dynamic ("indy") bytecode instructions.
You could switch between them with a compiler switch and we had two sets of
jars ("normal" and "-indy") built with and without the switch enabled.
-In Groovy 4.0, only bytecode using the latter approach can be generated.
-There is now one set of jars and they happen to be indy flavored.
+In Groovy 4.0, invokedynamic bytecode generation is enabled by default.
+There is now one set of jars and they are compiled with indy enabled.
+It is still possible to disable invokedynamic for user code by setting the
+system property `groovy.target.indy` to `false` or by setting the
+`indy` compiler optimization option to `false`.
Currently, the Groovy runtime still contains any necessary support for
classes compiled using older versions of Groovy.
-Please use Groovy versions up to 3.x if you need to generate the older
-style bytecode.
This work was originally planned for Groovy 3.0, but there were numerous places
where "indy" code was noticeably slower than "classic" bytecode.