Skip to content

8313713: Allow CompileCommand flag to specify compilation level#30352

Open
kirill-shirokov wants to merge 20 commits intoopenjdk:masterfrom
kirill-shirokov:8313713-add-comp-level-to-compilecommand-2
Open

8313713: Allow CompileCommand flag to specify compilation level#30352
kirill-shirokov wants to merge 20 commits intoopenjdk:masterfrom
kirill-shirokov:8313713-add-comp-level-to-compilecommand-2

Conversation

@kirill-shirokov
Copy link
Member

@kirill-shirokov kirill-shirokov commented Mar 21, 2026

Implemented intx arguments in -XX:CompileCommand={break,compileonly,exclude,print} commands that allow to select specific compilation levels.

E.g. -XX:CompileCommand=compileonly,java/lang/Object::wait,9 would allow to compile the wait() method only on CompLevel 1 and 4 (1 << (4 - 1) | 1 << (1 - 1) == 9).

CompLevel -XX:CompileCommand bitmask
0 (interpreter) not applicable
1 (C1) 1
2 (C1 + counters) 2
3 (C1 + counters + mdo) 4
4 (C2/JVMCI) 8
All C1 levels 7
All levels 15

For compatibility with the old format, specifying the commands without intx argument is also supported. In this case all levels will be covered (using a default value of 15). Specifying boolean values is not supported anymore.

New tests are provided and I ran them manually. The tests are not included into any tiers yet.

Some implementation choices I made (and I open to discussing/modifying them):

  • intx for the value, not uintx as most flags use intx
  • I tried to avoid any changes to compilation level state machine. The only modification I did is to avoid downgrading level from 3 to 2 if level 2 is excluded in CompilationPolicy::select_task(), see line 817+
  • I refactored direct freeing CompileTask::_directive pointer in CompileBroker::compile_method(), line 2405 via a new CompileTask method (this approach conforms to OO encapsulation principles more)
  • JVMCI CodeInstaller::install() method processes compilation level like this:
    DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler == nullptr || compiler->is_c1() ? CompLevel_simple : CompLevel_full_optimization);
    Please let me know if this needs changing.
  • Same for C2V_VMENTRY_0(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, ARGUMENT_PAIR(method))):
    return !Inline || CompilerOracle::should_not_inline(method, CompLevel_full_optimization) || method->dont_inline();
    (level 4 is assumed, please let me know if this has to be changed)

Verified by running tier1 tests on linux + macosx aarch64.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8313713: Allow CompileCommand flag to specify compilation level (Enhancement - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/30352/head:pull/30352
$ git checkout pull/30352

Update a local copy of the PR:
$ git checkout pull/30352
$ git pull https://git.openjdk.org/jdk.git pull/30352/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 30352

View PR using the GUI difftool:
$ git pr show -t 30352

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/30352.diff

Using Webrev

Link to Webrev Comment

…uld_not_inline(). Replace compiler arument with comp_level in DirectivesStack::getMatchingDirective()
…. Fix level checking in WB_IsMethodCompilable()
…n ClearDirectivesFileStackTest. Sort includes. Update copyright year.
…evel is excluded for the method. Fix WB_IsMethodCompilable for levels 1-3
…mpileonly and exclude CompileCommands with a level argument
…se added to CompileLevelParseTest.java. CompileTask::release_direcive() added for ownership clarity. Null pointer crash fixed in CompilationPolicy::select_task()
@bridgekeeper
Copy link

bridgekeeper bot commented Mar 21, 2026

👋 Welcome back kshiroko! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Mar 21, 2026

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk bot added the hotspot hotspot-dev@openjdk.org label Mar 21, 2026
@openjdk
Copy link

openjdk bot commented Mar 21, 2026

@kirill-shirokov The following label will be automatically applied to this pull request:

  • hotspot

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the rfr Pull request is ready for review label Mar 21, 2026
@mlbridge
Copy link

mlbridge bot commented Mar 21, 2026

Webrevs

Copy link
Contributor

@vnkozlov vnkozlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work, thank you. I have few comments.

if (compile_state == nullptr) {
// This compile didn't come through the CompileBroker so perform the printing here
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler == nullptr || compiler->is_c1() ? CompLevel_simple : CompLevel_full_optimization);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point compiler should be JVMCI compiler and not NULL. It used in nmethod::new_nmethod() during registration. So, just use CompLevel_full_optimization here.

option(Quiet, "quiet", Unknown) \
option(Log, "log", Bool) \
option(Print, "print", Bool) \
option(Print, "print", Intx) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For an other RFE. intx is 64 bits in 64-bits VM we have now. We should introduce normal int for small values like you added in these changes.

Comment on lines +817 to +819
if (max_task != nullptr && max_method != nullptr) {
methodHandle max_method_h(THREAD, max_method);
DirectiveSet * directive = DirectivesStack::getMatchingDirective(max_method_h, CompLevel_limited_profile);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to use and update task->directive() here? Because max_task->set_comp_level(CompLevel_limited_profile) will not match it - it was created for CompLevel_full_profile.

// All C1 levels | 7
// All levels | 15
inline int comp_level_bitmask(int comp_level) {
assert(comp_level > 0 && comp_level < CompLevel_count, "CompLevel out of bounds");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use CompLevel_none instead of 0.

}
// clear the stack
builder.add(new JcmdCommand(Command.NONEXISTENT, null, null,
builder.add(new JcmdCommand(Command.NONEXISTENT, true, null, null,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don you know how we were able to run it before? The JcmdCommand was changed 3 years ago.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just came across this package and this file did not compile, so I fixed it.
Technically it does not belong to this PR. I can file a separate bug and fix it there, if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hotspot hotspot-dev@openjdk.org rfr Pull request is ready for review

Development

Successfully merging this pull request may close these issues.

2 participants