Compiler Control (https://openjdk.org/jeps/165) provides method-context 
dependent control of the JVM compilers (C1 and C2). The active directive stack 
is built from the directive files passed with the `-XX:CompilerDirectivesFile` 
diagnostic command-line option and the Compiler.add_directives diagnostic 
command. It is also possible to clear all directives or remove the top from the 
stack.

A matching directive will be applied at method compilation time when such 
compilation is started. If directives are added or changed, but compilation 
does not start, then the state of compiled methods doesn't correspond to the 
rules. This is not an error, and it happens in long running applications when 
directives are added or removed after compilation of methods that could be 
matched. For example, the user decides that C2 compilation needs to be disabled 
for some method due to a compiler bug, issues such a directive but this does 
not affect the application behavior. In such case, the target application needs 
to be restarted, and such an operation can have high costs and risks. Another 
goal is testing/debugging compilers.

It would be convenient to optionally reconcile at least existing matching 
nmethods to the current stack of compiler directives. Methods in general are 
often inlined, and this information is hard to track down.

Natural way to eliminate the discrepancy between the result of compilation and 
the broken rule is to discard the compilation result, i.e. deoptimization. 
Obviously there is a performance penalty, so it should be applied with care. 
Hot code will most likely be recompiled soon, as nothing happens to its hotness.

A new flag '`-d`' has beed introduced for some directives related to compile 
commands: `Compiler.add_directives`, `Compiler.remove_directives`, 
`Compiler.clear_directives`. The default behavior has not changed (no flag). If 
the new flag is present, the command scans already compiled methods and marks 
for deoptimization those methods that have any active non-default matching 
compiler directives. There is currently no distinction which directives are 
found. In particular, this means that if there are rules for inlining into some 
method, it will be deoptimized. On the other hand, if there are rules for a 
method and it was inlined, top-level methods won't be deoptimized, but this can 
be achieved by having rules for them.

In addition, a new diagnistic command `Compiler.replace_directives`, has been 
added for convenience. It's like a combination of `Compiler.clear_directives` 
and `Compiler.add_directives`. It supports the same new optional '-d' flag that 
marks both cleared and added methods for deoptimization.

The behavior of the '-d' flag is implemented in the new 
`CodeCache::mark_for_deoptimization_directives_matches` and 
`DirectivesStack::hasMatchingDirectives` methods.

`CompilerDirectivesDCMDTest` now checks add, remove and replace commands in two 
modes (default and '-d') and checks that '-d' flag causes deoptimization.

An alternative approach to the '-d' flag could be to have a special diagnostic 
command for deoptimization. It will get a list of method patterns and reuse the 
matcher, however this is not so trivial. Overall usage and effects will be 
similar but this is one more file format. The user will also need to monitor or 
query active directives in advance, e.g. to deoptimize all mentioned methods 
after clearing all directives.

An alternative approach for selection of deoptimized methods could be to track 
down all inlining dependencies. This may be similar to searching references to 
old methods, but it requires scanning all code blobs, which looks too expensive.

An alternative naming for the flag is welcome. The obvious '-f' ('force') 
unfortunately has a conflict. Other verbs can be 'update', 'refresh' or 
'apply'. Deoptimization is just what's done to reconcile the state. It could be 
something else, like first compiling with a different compiler and then 
switching to that version. Although in the latter case, triggered compilation 
would be an essential detail.

-------------

Commit messages:
 - Merge branch 'openjdk:master' into compiler-directives-force-update
 - Formatting
 - Formatting
 - Merge branch 'openjdk:master' into compiler-directives-force-update
 - Merge branch 'openjdk:master' into compiler-directives-force-update
 - Correct arguments info for new commands
 - Update through de-optimization

Changes: https://git.openjdk.org/jdk/pull/14111/files
 Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=14111&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8309271
  Stats: 214 lines in 9 files changed: 194 ins; 0 del; 20 mod
  Patch: https://git.openjdk.org/jdk/pull/14111.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/14111/head:pull/14111

PR: https://git.openjdk.org/jdk/pull/14111

Reply via email to