• 0.32.0

hone:optimize

Full name:

org.eolang:hone-maven-plugin:0.32.0:optimize

Description:

Converts Bytecode to Bytecode in order to make it faster.

This goal takes every .class file from the target/classes/ directory, converts it to .xmir format (which is XML representation of EO), then converts .xmir to .phi (which is 𝜑-calculus), then optimizes it via phino, and then back to .xmir and to .class. As a result, you obtain optimized Bytecode in the target/classes/ directory, which supposedly works faster than before.

The entire optimization pipeline happens inside Docker container, which is run from the image specified in the image parameter. The image may either be pulled or built locally. We recommend pulling it from the Docker Hub with the help of the pull goal. Also, we recommend deleting the image after optimization is done, with the help of the rmi goal.

Attributes:

  • The goal is not marked as thread-safe and thus does not support parallel builds.
  • Since version: 0.1.0.
  • Binds by default to the lifecycle phase: process-classes.

Optional Parameters

Name Type Since Description
<alwaysWithDocker> boolean 0.17.0 Run without Docker even if phino is available.

If this is set to true, Docker is used even if phino is available. It is recommended to keep this parameter to false, thus making the build faster if it's possible.


Default: false
User Property: hone.always-with-docker
<cache> File 0.1.0 EO cache directory.
Default: ${user.home}/.eo
User Property: hone.cache
<classes> String 0.8.0 Location of .class files to optimize inside the target directory.
Default: classes
User Property: hone.classes
<debug> boolean 0.11.0 Print all commands of all Bash scripts.

If this is set to true, all our internal bash scripts will start with set -x. This will lead to very verbose output but may help debug internal issues.


Default: false
User Property: hone.debug
<eoVersion> String 0.1.0 EO version to use.
User Property: hone.eo-version
<excludes> String[] 0.1.0 Exclude patterns for .class files.

An array of patterns to exclude specific .class files from optimization. If not specified, no .class files will be excluded.

Start them with "/target/classes".


User Property: hone.excludes
<extra> List<String> 0.1.0 List of extra rules to use for optimization, provided as YAML files.
User Property: hone.extra
<extraExtensions> String 0.5.0 The list of all file extensions for the extra rules.
Default: yml,yaml,phr
User Property: hone.extra-extensions
<grepIn> String 0.10.0 Grep XMIR files to rewrite.

Using this regular expression, you can filter in (include) XMIR files that need to be rewritten. It's advised to use this regex to save time. This is a good example to filter in only the files that contain filter() and map() methods:

>(66-69-6C-74-65-72|6D-61-70)<

Here, 66-69-6C-74-65-72 stands for the "filter" and 6D-61-70 for the "map", in hexadecimal format.

To rewrite all files, use the .* pattern


User Property: hone.grep-in
<image> String 0.1.0 Docker image to use.
Default: yegor256/hone:0.32.0
User Property: hone.image
<includes> String[] 0.1.0 Include patterns for .class files.

An array of patterns to include specific .class files for optimization. If not specified, all .class files will be included.

Start them with "/target/classes".


User Property: hone.includes
<jeoVersion> String 0.1.0 JEO version to use.
User Property: hone.jeo-version
<killgrace> int 0.38.0 How many seconds to wait after the TERM signal before force-killing a timed-out phino process tree.

The watchdog of rewrite.sh sends TERM to the whole process group once the hone.timeout deadline passes, then gives the tree this grace window to clean up, and finally force-kills whatever survived, so no orphan phino is left burning CPU (see #863).


Default: 10
User Property: hone.kill-grace
<maxCycles> int 0.4.0 How many rewriting cycles across all rules to tolerate at maximum?

This number doesn't need to be changed. However, it may be used for debugging. The larger the number, the longer optimization might take. We pass this number to phino as the --max-cycles argument.


Default: 1
User Property: hone.max-cycles
<maxDepth> int 0.4.0 How many rewriting cycles per rule to tolerate at maximum?

This number doesn't need to be changed. However, it may be used for debugging. The larger the number, the longer optimization might take. We pass this number to phino as the --max-depth argument.


Default: 500
User Property: hone.max-depth
<phinoVersion> String 0.21.0 Phino version to use.
User Property: hone.phino-version
<rules> String 0.1.0 List of built-in rules to use for optimization.

For example, "simple,b*,!abc" would include the simple rule, all rules that start with the b character, and exclude the abc rule.

In order to disable them all, simply set this parameter to none.

If you enable them all with "*", your code most definitely will be corrupted, because some rules are for testing purposes only.


Default: none
User Property: hone.rules
<skip> boolean 0.1.0 Skip the execution, if set to TRUE.
Default: false
User Property: hone.skip
<skipIfNoClasses> boolean 0.16.0 Skip if no .class files found.
Default: true
User Property: hone.skip-if-no-classes
<skipIfNotSuitable> boolean 0.74.0 Skip quietly if nothing is suitable for rewrite.

Some .class files may all get excluded from the pipeline (for example, the streams/ rules require Java 16 bytecode and exclude every class below it), leaving nothing for the rewrite to work on. If this is set to true, that situation is only logged and the build proceeds; if false, the build fails.


Default: true
User Property: hone.skip-if-not-suitable
<skipOnWindows> boolean 0.23.0 Skip the execution, if it's Windows.
Default: false
User Property: hone.skipOnWindows
<skipPhino> boolean 0.15.0 Skip phino entirely.

If this is set to true, phino is not executed and no rewriting happens.


Default: false
User Property: hone.skip-phino
<skipVerification> boolean 0.31.0 Skip the verification of the assembled bytecode.

After the rewriting, jeo assembles .class files back from XMIR and verifies that each of them conforms to the JVM specification and can be loaded. If this is set to true, that check is not performed: the build is faster, but a broken class reaches the runtime of the user and fails there with a VerifyError.

Turn it on when the verifier stops on a type it can not resolve: jeo knows only the classes it assembles, so a method that touches a type from a dependency fails with ClassNotFoundException instead of a verdict on the bytecode (see jeo#1763).


Default: false
User Property: hone.skip-verification
<skipWithoutDocker> boolean 0.22.0 Skip the execution, if there is no way to run: no Docker and no local phino.
Default: false
User Property: hone.skipWithoutDocker
<smallSteps> boolean 0.3.0 Small steps or big steps?

Small steps mode will apply one rule at a time, producing separate .phi files. This may be useful for debugging the rules. To the contrary, big steps mode will apply all rules at once, which is faster but less transparent for debugging.


Default: false
User Property: hone.small-steps
<sudo> boolean 0.1.0 Whether to use "sudo" when executing Docker commands.
Default: false
User Property: hone.sudo
<target> File 0.1.0 The "target/" directory of Maven project.
Default: ${project.build.directory}
User Property: hone.target
<threads> int 0.11.0 How many threads to use for rewriting?

By default, it is set to zero, which means the number of threads will be set to the number of CPUs on the machine. This is normally the most efficient choice for large projects. Set it to 1 to disable parallelism, or to any positive value to cap the number of worker threads.


Default: 0
User Property: hone.threads
<timeout> int 0.11.0 How many seconds to spend on each .phi file at most?

If rewriting for a file takes longer than the timeout, the file remains untouched. The timeout doesn't lead to runtime failure but only to the file processing being skipped.


Default: 999
User Property: hone.timeout

Parameter Details

<alwaysWithDocker>

Run without Docker even if phino is available.

If this is set to true, Docker is used even if phino is available. It is recommended to keep this parameter to false, thus making the build faster if it's possible.

  • Type: boolean
  • Since: 0.17.0
  • Required: No
  • User Property: hone.always-with-docker
  • Default: false

<cache>

EO cache directory.
  • Type: java.io.File
  • Since: 0.1.0
  • Required: No
  • User Property: hone.cache
  • Default: ${user.home}/.eo

<classes>

Location of .class files to optimize inside the target directory.
  • Type: java.lang.String
  • Since: 0.8.0
  • Required: No
  • User Property: hone.classes
  • Default: classes

<debug>

Print all commands of all Bash scripts.

If this is set to true, all our internal bash scripts will start with set -x. This will lead to very verbose output but may help debug internal issues.

  • Type: boolean
  • Since: 0.11.0
  • Required: No
  • User Property: hone.debug
  • Default: false

<eoVersion>

EO version to use.
  • Type: java.lang.String
  • Since: 0.1.0
  • Required: No
  • User Property: hone.eo-version

<excludes>

Exclude patterns for .class files.

An array of patterns to exclude specific .class files from optimization. If not specified, no .class files will be excluded.

Start them with "/target/classes".

  • Type: java.lang.String[]
  • Since: 0.1.0
  • Required: No
  • User Property: hone.excludes

<extra>

List of extra rules to use for optimization, provided as YAML files.
  • Type: java.util.List<java.lang.String>
  • Since: 0.1.0
  • Required: No
  • User Property: hone.extra

<extraExtensions>

The list of all file extensions for the extra rules.
  • Type: java.lang.String
  • Since: 0.5.0
  • Required: No
  • User Property: hone.extra-extensions
  • Default: yml,yaml,phr

<grepIn>

Grep XMIR files to rewrite.

Using this regular expression, you can filter in (include) XMIR files that need to be rewritten. It's advised to use this regex to save time. This is a good example to filter in only the files that contain filter() and map() methods:

>(66-69-6C-74-65-72|6D-61-70)<

Here, 66-69-6C-74-65-72 stands for the "filter" and 6D-61-70 for the "map", in hexadecimal format.

To rewrite all files, use the .* pattern

  • Type: java.lang.String
  • Since: 0.10.0
  • Required: No
  • User Property: hone.grep-in

<image>

Docker image to use.
  • Type: java.lang.String
  • Since: 0.1.0
  • Required: No
  • User Property: hone.image
  • Default: yegor256/hone:0.32.0

<includes>

Include patterns for .class files.

An array of patterns to include specific .class files for optimization. If not specified, all .class files will be included.

Start them with "/target/classes".

  • Type: java.lang.String[]
  • Since: 0.1.0
  • Required: No
  • User Property: hone.includes

<jeoVersion>

JEO version to use.
  • Type: java.lang.String
  • Since: 0.1.0
  • Required: No
  • User Property: hone.jeo-version

<killgrace>

How many seconds to wait after the TERM signal before force-killing a timed-out phino process tree.

The watchdog of rewrite.sh sends TERM to the whole process group once the hone.timeout deadline passes, then gives the tree this grace window to clean up, and finally force-kills whatever survived, so no orphan phino is left burning CPU (see #863).

  • Type: int
  • Since: 0.38.0
  • Required: No
  • User Property: hone.kill-grace
  • Default: 10

<maxCycles>

How many rewriting cycles across all rules to tolerate at maximum?

This number doesn't need to be changed. However, it may be used for debugging. The larger the number, the longer optimization might take. We pass this number to phino as the --max-cycles argument.

  • Type: int
  • Since: 0.4.0
  • Required: No
  • User Property: hone.max-cycles
  • Default: 1

<maxDepth>

How many rewriting cycles per rule to tolerate at maximum?

This number doesn't need to be changed. However, it may be used for debugging. The larger the number, the longer optimization might take. We pass this number to phino as the --max-depth argument.

  • Type: int
  • Since: 0.4.0
  • Required: No
  • User Property: hone.max-depth
  • Default: 500

<phinoVersion>

Phino version to use.
  • Type: java.lang.String
  • Since: 0.21.0
  • Required: No
  • User Property: hone.phino-version

<rules>

List of built-in rules to use for optimization.

For example, "simple,b*,!abc" would include the simple rule, all rules that start with the b character, and exclude the abc rule.

In order to disable them all, simply set this parameter to none.

If you enable them all with "*", your code most definitely will be corrupted, because some rules are for testing purposes only.

  • Type: java.lang.String
  • Since: 0.1.0
  • Required: No
  • User Property: hone.rules
  • Default: none

<skip>

Skip the execution, if set to TRUE.
  • Type: boolean
  • Since: 0.1.0
  • Required: No
  • User Property: hone.skip
  • Default: false

<skipIfNoClasses>

Skip if no .class files found.
  • Type: boolean
  • Since: 0.16.0
  • Required: No
  • User Property: hone.skip-if-no-classes
  • Default: true

<skipIfNotSuitable>

Skip quietly if nothing is suitable for rewrite.

Some .class files may all get excluded from the pipeline (for example, the streams/ rules require Java 16 bytecode and exclude every class below it), leaving nothing for the rewrite to work on. If this is set to true, that situation is only logged and the build proceeds; if false, the build fails.

  • Type: boolean
  • Since: 0.74.0
  • Required: No
  • User Property: hone.skip-if-not-suitable
  • Default: true

<skipOnWindows>

Skip the execution, if it's Windows.
  • Type: boolean
  • Since: 0.23.0
  • Required: No
  • User Property: hone.skipOnWindows
  • Default: false

<skipPhino>

Skip phino entirely.

If this is set to true, phino is not executed and no rewriting happens.

  • Type: boolean
  • Since: 0.15.0
  • Required: No
  • User Property: hone.skip-phino
  • Default: false

<skipVerification>

Skip the verification of the assembled bytecode.

After the rewriting, jeo assembles .class files back from XMIR and verifies that each of them conforms to the JVM specification and can be loaded. If this is set to true, that check is not performed: the build is faster, but a broken class reaches the runtime of the user and fails there with a VerifyError.

Turn it on when the verifier stops on a type it can not resolve: jeo knows only the classes it assembles, so a method that touches a type from a dependency fails with ClassNotFoundException instead of a verdict on the bytecode (see jeo#1763).

  • Type: boolean
  • Since: 0.31.0
  • Required: No
  • User Property: hone.skip-verification
  • Default: false

<skipWithoutDocker>

Skip the execution, if there is no way to run: no Docker and no local phino.
  • Type: boolean
  • Since: 0.22.0
  • Required: No
  • User Property: hone.skipWithoutDocker
  • Default: false

<smallSteps>

Small steps or big steps?

Small steps mode will apply one rule at a time, producing separate .phi files. This may be useful for debugging the rules. To the contrary, big steps mode will apply all rules at once, which is faster but less transparent for debugging.

  • Type: boolean
  • Since: 0.3.0
  • Required: No
  • User Property: hone.small-steps
  • Default: false

<sudo>

Whether to use "sudo" when executing Docker commands.
  • Type: boolean
  • Since: 0.1.0
  • Required: No
  • User Property: hone.sudo
  • Default: false

<target>

The "target/" directory of Maven project.
  • Type: java.io.File
  • Since: 0.1.0
  • Required: No
  • User Property: hone.target
  • Default: ${project.build.directory}

<threads>

How many threads to use for rewriting?

By default, it is set to zero, which means the number of threads will be set to the number of CPUs on the machine. This is normally the most efficient choice for large projects. Set it to 1 to disable parallelism, or to any positive value to cap the number of worker threads.

  • Type: int
  • Since: 0.11.0
  • Required: No
  • User Property: hone.threads
  • Default: 0

<timeout>

How many seconds to spend on each .phi file at most?

If rewriting for a file takes longer than the timeout, the file remains untouched. The timeout doesn't lead to runtime failure but only to the file processing being skipped.

  • Type: int
  • Since: 0.11.0
  • Required: No
  • User Property: hone.timeout
  • Default: 999