JDK-8308287 : Unify syntax of CompileOnly and CompileCommand
  • Type: CSR
  • Component: hotspot
  • Sub-Component: compiler
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 22
  • Submitted: 2023-05-17
  • Updated: 2023-06-01
  • Resolved: 2023-06-01
Related Reports
CSR :  
Relates :  
Sub Tasks
JDK-8309185 :  
Description
# Summary
At the moment, CompileCommand and CompileOnly use different syntax for matching methods. In general, it is not possible to just take a pattern used with CompileOnly and plug it into a CompileCommand command. 

The syntax of CompileCommand is more explicit and allows wildcards (*) usage. Whereas the syntax used by CompileOnly is more implicit and also not very intuitive. We want to keep CompileOnly because it is convenient: it’s shorter to write and allows to give lists of patterns, whereas CompileCommand only takes one pattern per command.

With this CSR we propose CompileOnly to become an alias for CompileCommand=compileonly. 
If a list of pattern is passed to CompileOnly it should map to a list of CompileCommand=compileonly commands. 
`-XX:CompileOnly=pattern1,pattern2` would be an **alias** for:
`-XX:CompileCommand=compileonly,pattern1`
`-XX:CompileCommand=compileonly,pattern2`

# Problem
The syntax used by CompileOnly is not very well defined and also not very intuitive.  Since `CompileOnly` just ignores invalid syntax, the user could miss that a CompileOnly command was wrong. CompileOnly also does not allow wildcards (*) usage - it sometimes uses an implicit wildcard as shown below: 

The old CompileOnly format supports:

- matching a **method name** with **class name** and **package name**:
 - `-XX:CompileOnly=package/path/Class.method`
 - `-XX:CompileOnly=package/path/Class::method`
 - `-XX:CompileOnly=package.path.Class::method`
 - BUT NOT: `-XX:CompileOnly=package.path.Class.method`

-  just matching a **single method name**:
 - `-XX:CompileOnly=.hashCode`
 - `-XX:CompileOnly=::hashCode`
 - BUT NOT: `-XX:CompileOnly=hashCode`
- Matching **all method names** with **class name** and **package name**
 - ` -XX:CompileOnly=java/lang/String`
 - BUT NOT: ` -XX:CompileOnly=java/lang/String.`
 - BUT NOT: ` -XX:CompileOnly=java.lang.String`
 - BUT NOT: ` -XX:CompileOnly=java.lang.String::` (This is actually a bug) 
 - BUT NOT: ` -XX:CompileOnly=String`
 - BUT NOT: ` -XX:CompileOnly=String.`
 - BUT NOT: ` -XX:CompileOnly=String::`

- Matching  **all method names** with **class name** and **NO package name**
 - ` -XX:CompileOnly=String`
 - BUT NOT: ` -XX:CompileOnly=String.`
 - BUT NOT: ` -XX:CompileOnly=String::`

- When `CompileOnly` ends with `::` the `CompileOnly` is just ignored
e.g. `-XX:CompileOnly=String::` compiles as many methods as when omitting the `-XX:CompileOnly=` command


# Solution
Make  `CompileOnly` an alias for `CompileCommand=compileonly` with the possibility to take lists as input. This allows to use the CompileCommand syntax for CompileOnly.


# Specification
New syntax for `CompileOnly`:

`-XX:CompileOnly=pattern1,pattern2` is an **alias** for: `-XX:CompileCommand=compileonly,pattern1 -XX:CompileCommand=compileonly,pattern2`

## CompileCommand=compileonly format
`CompileCommand` allows two different forms for paths: 

- `package/path/Class.method`
- `package.path.Class::method`

In contrary to `CompileOnly `, `CompileCommand` supports wildcard matching using `*` which can appear at the beginning and/or end of a `package.path.Class` and `method` name. 

Valid forms: 

- `-XX:CompileCommand=compileonly,*.lang.*::*shCo*`
- `-XX:CompileCommand=compileonly,*/lang/*.*shCo*` 
- `-XX:CompileCommand=compileonly,java.lang.String::*`
- `-XX:CompileCommand=compileonly,*::hashCode`
- `-XX:CompileCommand=compileonly,*ng.String::hashC*`
- `-XX:CompileCommand=compileonly,*String::hash*`

Invalid forms (`Error:  Embedded * not allowed`):

- `-XX:CompileCommand=compileonly,java.*.String::has*Code`

## Handling invalid syntax
Before, `CompileOnly` just ignored invalid syntax. `CompileCommand` at least prints an error message for invalid patterns:
```
CompileOnly: An error occurred during parsing
Error: Could not parse method pattern
Line: 'pattern'
```
Since `CompileOnly` now maps to `CompileCommand` is also prints the error message for invalid inputs. 

## Update the "java" tool specification
Remove the explanation of the allowed pattern syntax. Refer to `CompileCommand`. New text:

`-XX:CompileOnly=pattern1,[...],patternN` is an alias for: `-XX:CompileCommand=compileonly,pattern1 [...] -XX:CompileCommand=compileonly,patternN`
Comments
Moving to Approved for JDK 22.
01-06-2023

I filed https://bugs.openjdk.org/browse/JDK-8308662 New text for `-XX:CompileOnly` ``` -XX:CompileOnly=pattern1,[...],patternN is an alias for: -XX:CompileCommand=compileonly,pattern1 [...] -XX:CompileCommand=compileonly,patternN ```
23-05-2023

Thanks [~tholenstein]; please include a representation of the change to the tool specification when the CSR is Finalized.
22-05-2023

[~darcy] The CompileOnly flag is documented in the JDK Tool Specifications https://docs.oracle.com/en/java/javase/20/docs/specs/man/java.html . We will need to update this documentation after the change. Because CompileOnly will be an alias for CompileCommand=compileonly afterwards, we can simply refer to the documentation of CompileCommand.
22-05-2023

Moving to Provisional, not Approved. Where is this sort of information about the valid syntax for options documented for end users?
18-05-2023

Reviewed.
17-05-2023