Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
c991c6a
8313713: Allow CompileCommand flag to specify compilation level: Init…
kirill-shirokov Feb 21, 2026
61afcbc
Update copyright year
kirill-shirokov Feb 21, 2026
be85ef5
Use actual compile level when matching compile directives
kirill-shirokov Feb 26, 2026
ca608b4
Remove DirectiveSet::_comp_level. Add comp_level to DirectiveSet::sho…
kirill-shirokov Feb 26, 2026
8e00dc4
Remove extra line added due to an error in CLion
kirill-shirokov Feb 26, 2026
4ab7a5e
Fix flag checking and CompileOnly-checking code in CompilerOracle.cpp…
kirill-shirokov Feb 26, 2026
12843b5
Allow optional arguments for break, compileonly, exclude, print Compi…
kirill-shirokov Feb 26, 2026
73efcb6
Fix crash in printing methods. Fix default CompileCommand CompLevel b…
kirill-shirokov Mar 6, 2026
fd4c0e4
Include full CompileLevelParsingTest. Fix constructor arguments bug i…
kirill-shirokov Mar 7, 2026
a4ba2cf
Disallow downgrading method in queue to compilation level 2 if this l…
kirill-shirokov Mar 10, 2026
a693c2b
Add CompileLevelWBTest.java for verifying actual compilations with co…
kirill-shirokov Mar 10, 2026
684eae9
Add @requires to CompileLevelWBTest
kirill-shirokov Mar 10, 2026
62b0281
Minor fixes + formatting + extra comments
kirill-shirokov Mar 12, 2026
8d0ca08
Fix copyright year in ClearDirectivesFileStackTest.java
kirill-shirokov Mar 12, 2026
571a537
Add a new test that verifies compilation levels from VM diagnostic ou…
kirill-shirokov Mar 12, 2026
a5eb93c
Update compiler/compilercontrol/commands/CompileLevelPrintTest.java t…
kirill-shirokov Mar 14, 2026
60c4db2
Compile level mask argument parsing fixed. TODOs removed. Negative ca…
kirill-shirokov Mar 17, 2026
1e45337
Fix copyright year
kirill-shirokov Mar 21, 2026
cbd3067
:retab
kirill-shirokov Mar 21, 2026
79407ad
Changes requested in the review comments
kirill-shirokov Mar 22, 2026
0828046
Cosmetic fix in src/hotspot/share/compiler/compilationPolicy.cpp
kirill-shirokov Mar 23, 2026
312002f
Fixed tests to correctly verify -Xcomp and -XX:-TieredCompilation
kirill-shirokov Mar 25, 2026
a810d29
Replace level separator with shell-neutral character in test/hotspot/…
kirill-shirokov Mar 25, 2026
b155b2f
Replace test class name with a macro in the tests, fix @run directives
kirill-shirokov Mar 25, 2026
13de6c4
Fix jtreg vm.opt.TieredCompilation flag checks in CompileLevelWBTest
kirill-shirokov Mar 25, 2026
a4e6438
Fix intermittent failures due to mixed output in CompileLevelPrintTes…
kirill-shirokov Mar 27, 2026
83cde8d
Add a section about compile level bitmasks to -XX:CompileCommand=help
kirill-shirokov Mar 27, 2026
c5c5d2c
Wording in compilerOracle.cpp usage() fixed
kirill-shirokov Mar 27, 2026
dd358fe
Add CompileCommand compilation level description to java.md
kirill-shirokov Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/hotspot/share/c1/c1_GraphBuilder.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -3558,7 +3558,7 @@ const char* GraphBuilder::check_can_parse(ciMethod* callee) const {

// negative filter: should callee NOT be inlined? returns null, ok to inline, or rejection msg
const char* GraphBuilder::should_not_inline(ciMethod* callee) const {
if ( compilation()->directive()->should_not_inline(callee)) return "disallowed by CompileCommand";
if ( compilation()->directive()->should_not_inline(callee, compilation()->env()->comp_level())) return "disallowed by CompileCommand";
if ( callee->dont_inline()) return "don't inline by annotation";
return nullptr;
}
Expand Down
35 changes: 21 additions & 14 deletions src/hotspot/share/compiler/compilationPolicy.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -814,23 +814,30 @@ CompileTask* CompilationPolicy::select_task(CompileQueue* compile_queue, JavaThr
max_method = max_task->method();
}

methodHandle max_method_h(THREAD, max_method);
if (max_task != nullptr && max_method != nullptr) {
methodHandle max_method_h(THREAD, max_method);
DirectiveSet* limited_profile_directive = DirectivesStack::getMatchingDirective(max_method_h, CompLevel_limited_profile);
bool excludeLimitedProfile = limited_profile_directive->ExcludeOption;

if (max_task != nullptr && max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile &&
max_method != nullptr && is_method_profiled(max_method_h) && !Arguments::is_compiler_only()) {
max_task->set_comp_level(CompLevel_limited_profile);
if (max_task->comp_level() == CompLevel_full_profile && TieredStopAtLevel > CompLevel_full_profile &&
!excludeLimitedProfile && is_method_profiled(max_method_h) && !Arguments::is_compiler_only()) {
max_task->set_comp_level(CompLevel_limited_profile);
max_task->set_directive(limited_profile_directive);

if (CompileBroker::compilation_is_complete(max_method_h, max_task->osr_bci(), CompLevel_limited_profile)) {
if (PrintTieredEvents) {
print_event(REMOVE_FROM_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
if (CompileBroker::compilation_is_complete(max_method_h, max_task->osr_bci(), CompLevel_limited_profile)) {
if (PrintTieredEvents) {
print_event(REMOVE_FROM_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
}
compile_queue->remove_and_mark_stale(max_task);
max_method->clear_queued_for_compilation();
return nullptr;
}
compile_queue->remove_and_mark_stale(max_task);
max_method->clear_queued_for_compilation();
return nullptr;
}

if (PrintTieredEvents) {
print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
if (PrintTieredEvents) {
print_event(UPDATE_IN_QUEUE, max_method, max_method, max_task->osr_bci(), (CompLevel)max_task->comp_level());
}
} else {
DirectivesStack::release(limited_profile_directive);
}
}
return max_task;
Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/share/compiler/compileBroker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1380,7 +1380,7 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
}
#endif

DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp);
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp_level);
// CompileBroker::compile_method can trap and can have pending async exception.
nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_count, compile_reason, directive, THREAD);
DirectivesStack::release(directive);
Expand Down Expand Up @@ -2402,7 +2402,8 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
}
}

DirectivesStack::release(directive);
// We don't need directive further, release it
task->set_directive(nullptr);

methodHandle method(thread, task->method());

Expand Down
13 changes: 10 additions & 3 deletions src/hotspot/share/compiler/compileTask.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -64,8 +64,7 @@ CompileTask::CompileTask(int compile_id,
_time_started = 0;
_compile_reason = compile_reason;
_nm_content_size = 0;
AbstractCompiler* comp = compiler();
_directive = DirectivesStack::getMatchingDirective(method, comp);
_directive = DirectivesStack::getMatchingDirective(method, comp_level);
_nm_insts_size = 0;
_nm_total_size = 0;
_failure_reason = nullptr;
Expand Down Expand Up @@ -95,6 +94,14 @@ CompileTask::~CompileTask() {
MonitorLocker wait_ml(CompileTaskWait_lock);
wait_ml.notify_all();
}
set_directive(nullptr);
}

void CompileTask::set_directive(DirectiveSet* new_directive) {
if (_directive != nullptr) {
DirectivesStack::release(_directive);
}
_directive = new_directive;
}

void CompileTask::wait_for_no_active_tasks() {
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/compiler/compileTask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class CompileTask : public CHeapObj<mtCompiler> {
bool is_blocking() const { return _is_blocking; }
bool is_success() const { return _is_success; }
DirectiveSet* directive() const { return _directive; }
// We own _directive instance and release it in the destructor. Use set_directive(nullptr) to release it prematurely.
void set_directive(DirectiveSet* directive);
CodeSection::csize_t nm_content_size() { return _nm_content_size; }
void set_nm_content_size(CodeSection::csize_t size) { _nm_content_size = size; }
CodeSection::csize_t nm_insts_size() { return _nm_insts_size; }
Expand Down
22 changes: 12 additions & 10 deletions src/hotspot/share/compiler/compilerDirectives.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -25,6 +25,7 @@
#include "ci/ciMethod.hpp"
#include "ci/ciUtilities.inline.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compilerDefinitions.inline.hpp"
#include "compiler/compilerDirectives.hpp"
#include "compiler/compilerOracle.hpp"
Expand Down Expand Up @@ -378,7 +379,7 @@ class DirectiveSetPtr {
// - if some option is changed we need to copy directiveset since it no longer can be shared
// - Need to free copy after use
// - Requires a modified bit so we don't overwrite options that is set by directives
DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle& method) {
DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle& method, int comp_level) {
// Early bail out - checking all options is expensive - we rely on them not being used
// Only set a flag if it has not been modified and value changes.
// Only copy set if a flag needs to be set
Expand All @@ -397,7 +398,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle

// All CompileCommands are not equal so this gets a bit verbose
// When CompileCommands have been refactored less clutter will remain.
if (CompilerOracle::should_break_at(method)) {
if (CompilerOracle::should_break_at(method, static_cast<CompLevel>(comp_level))) {
// If the directives didn't have 'BreakAtCompile' or 'BreakAtExecute',
// the sub-command 'Break' of the 'CompileCommand' would become effective.
if (!_modified[BreakAtCompileIndex]) {
Expand All @@ -414,13 +415,13 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
}
}

if (CompilerOracle::should_print(method)) {
if (CompilerOracle::should_print(method, static_cast<CompLevel>(comp_level))) {
if (!_modified[PrintAssemblyIndex]) {
set.cloned()->PrintAssemblyOption = true;
}
}
// Exclude as in should not compile == Enabled
if (CompilerOracle::should_exclude(method)) {
if (CompilerOracle::should_exclude(method, static_cast<CompLevel>(comp_level))) {
if (!_modified[ExcludeIndex]) {
set.cloned()->ExcludeOption = true;
}
Expand Down Expand Up @@ -547,7 +548,7 @@ bool DirectiveSet::should_inline(ciMethod* inlinee) {
return false;
}

bool DirectiveSet::should_not_inline(ciMethod* inlinee) {
bool DirectiveSet::should_not_inline(ciMethod* inlinee, int comp_level) {
inlinee->check_is_loaded();
VM_ENTRY_MARK;
methodHandle mh(THREAD, inlinee->get_Method());
Expand All @@ -556,7 +557,7 @@ bool DirectiveSet::should_not_inline(ciMethod* inlinee) {
return matches_inline(mh, InlineMatcher::dont_inline);
}
if (!CompilerDirectivesIgnoreCompileCommandsOption) {
return CompilerOracle::should_not_inline(mh);
return CompilerOracle::should_not_inline(mh, static_cast<CompLevel>(comp_level));
}
return false;
}
Expand Down Expand Up @@ -755,7 +756,7 @@ void DirectivesStack::release(DirectiveSet* set) {
assert(set != nullptr, "Never nullptr");
MutexLocker locker(DirectivesStack_lock, Mutex::_no_safepoint_check_flag);
if (set->is_exclusive_copy()) {
// Old CompilecCmmands forced us to create an exclusive copy
// Old CompileCommands forced us to create an exclusive copy
delete set;
} else {
assert(set->directive() != nullptr, "Never nullptr");
Expand All @@ -772,8 +773,9 @@ void DirectivesStack::release(CompilerDirectives* dir) {
}
}

DirectiveSet* DirectivesStack::getMatchingDirective(const methodHandle& method, AbstractCompiler *comp) {
DirectiveSet* DirectivesStack::getMatchingDirective(const methodHandle& method, int comp_level) {
assert(_depth > 0, "Must never be empty");
AbstractCompiler* comp = CompileBroker::compiler(comp_level);

DirectiveSet* match = nullptr;
{
Expand All @@ -798,5 +800,5 @@ DirectiveSet* DirectivesStack::getMatchingDirective(const methodHandle& method,
guarantee(match != nullptr, "There should always be a default directive that matches");

// Check for legacy compile commands update, without DirectivesStack_lock
return match->compilecommand_compatibility_init(method);
return match->compilecommand_compatibility_init(method, comp_level);
}
8 changes: 4 additions & 4 deletions src/hotspot/share/compiler/compilerDirectives.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -113,7 +113,7 @@ class DirectivesStack : AllStatic {
static void pop_inner(); // no lock version of pop
public:
static void init();
static DirectiveSet* getMatchingDirective(const methodHandle& mh, AbstractCompiler* comp);
static DirectiveSet* getMatchingDirective(const methodHandle& mh, int comp_level);
static DirectiveSet* getDefaultDirective(AbstractCompiler* comp);
static void push(CompilerDirectives* directive);
static void pop(int count);
Expand Down Expand Up @@ -141,10 +141,10 @@ class DirectiveSet : public CHeapObj<mtCompiler> {
bool parse_and_add_inline(char* str, const char*& error_msg);
void append_inline(InlineMatcher* m);
bool should_inline(ciMethod* inlinee);
bool should_not_inline(ciMethod* inlinee);
bool should_not_inline(ciMethod* inlinee, int comp_level);
bool should_delay_inline(ciMethod* inlinee);
void print_inline(outputStream* st);
DirectiveSet* compilecommand_compatibility_init(const methodHandle& method);
DirectiveSet* compilecommand_compatibility_init(const methodHandle& method, int comp_level);
bool is_exclusive_copy() { return _directive == nullptr; }
bool matches_inline(const methodHandle& method, int inline_action);
static DirectiveSet* clone(DirectiveSet const* src);
Expand Down
Loading