8383743: Use RAII pattern to find matching compiler directive

Reviewed-by: kvn, adinn, aseoane
This commit is contained in:
Ashutosh Mehra 2026-05-05 18:16:10 +00:00
parent 08eb5df37d
commit 601c1fec8b
8 changed files with 82 additions and 77 deletions

View File

@ -1382,10 +1382,9 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
}
#endif
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp);
CompilerDirectiveMatcher matcher(method, comp);
// 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);
nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_count, compile_reason, matcher.directive_set(), THREAD);
return nm;
}
@ -2415,7 +2414,6 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
ResourceMark rm;
task->print_post(tty);
}
DirectivesStack::release(directive);
Log(compilation, codecache) log;
if (log.is_debug()) {

View File

@ -44,43 +44,36 @@ CompileTask::CompileTask(int compile_id,
int comp_level,
int hot_count,
CompileReason compile_reason,
bool is_blocking) {
Thread* thread = Thread::current();
_compile_id = compile_id;
_method = method();
_method_holder = JNIHandles::make_weak_global(Handle(thread, method->method_holder()->klass_holder()));
_osr_bci = osr_bci;
_is_blocking = is_blocking;
_comp_level = comp_level;
_num_inlined_bytecodes = 0;
_is_complete = false;
_is_success = false;
_hot_count = hot_count;
_time_created = os::elapsed_counter();
_time_queued = 0;
_time_started = 0;
_time_finished = 0;
_compile_reason = compile_reason;
_nm_content_size = 0;
_nm_insts_size = 0;
_nm_total_size = 0;
_failure_reason = nullptr;
_failure_reason_on_C_heap = false;
_training_data = nullptr;
AbstractCompiler* comp = CompileBroker::compiler(comp_level);
_compiler = comp;
_directive = DirectivesStack::getMatchingDirective(method, comp);
JVMCI_ONLY(_has_waiter = comp->is_jvmci();)
JVMCI_ONLY(_blocking_jvmci_compile_state = nullptr;)
_arena_bytes = 0;
_next = nullptr;
_prev = nullptr;
bool is_blocking) :
_compile_id(compile_id),
_method(method()),
_method_holder(JNIHandles::make_weak_global(Handle(Thread::current(), method->method_holder()->klass_holder()))),
_osr_bci(osr_bci),
_is_complete(false),
_is_success(false),
_is_blocking(is_blocking),
_nm_content_size(0),
_nm_total_size(0),
_nm_insts_size(0),
_comp_level(comp_level),
_compiler(CompileBroker::compiler(comp_level)),
_comp_directive_matcher(method, _compiler),
JVMCI_ONLY(_has_waiter(_compiler->is_jvmci()) COMMA)
JVMCI_ONLY(_blocking_jvmci_compile_state(nullptr) COMMA)
_num_inlined_bytecodes(0),
_next(nullptr),
_prev(nullptr),
_time_created(os::elapsed_counter()),
_time_queued(0),
_time_started(0),
_time_finished(0),
_hot_count(hot_count),
_compile_reason(compile_reason),
_failure_reason(nullptr),
_failure_reason_on_C_heap(false),
_training_data(nullptr),
_arena_bytes(0)
{
AtomicAccess::add(&_active_tasks, 1, memory_order_relaxed);
}

View File

@ -28,12 +28,12 @@
#include "ci/ciMethod.hpp"
#include "code/nmethod.hpp"
#include "compiler/compileLog.hpp"
#include "compiler/compilerDirectives.hpp"
#include "memory/allocation.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/xmlstream.hpp"
class CompileTrainingData;
class DirectiveSet;
JVMCI_ONLY(class JVMCICompileState;)
@ -93,14 +93,14 @@ class CompileTask : public CHeapObj<mtCompiler> {
CodeSection::csize_t _nm_content_size;
CodeSection::csize_t _nm_total_size;
CodeSection::csize_t _nm_insts_size;
DirectiveSet* _directive;
int _comp_level;
AbstractCompiler* _compiler;
CompilerDirectiveMatcher _comp_directive_matcher;
#if INCLUDE_JVMCI
bool _has_waiter;
// Compilation state for a blocking JVMCI compilation
JVMCICompileState* _blocking_jvmci_compile_state;
#endif
int _comp_level;
int _num_inlined_bytecodes;
CompileTask* _next;
CompileTask* _prev;
@ -130,7 +130,7 @@ class CompileTask : public CHeapObj<mtCompiler> {
bool is_complete() const { return _is_complete; }
bool is_blocking() const { return _is_blocking; }
bool is_success() const { return _is_success; }
DirectiveSet* directive() const { return _directive; }
DirectiveSet* directive() const { return _comp_directive_matcher.directive_set(); }
CompileReason compile_reason() const { return _compile_reason; }
CodeSection::csize_t nm_content_size() { return _nm_content_size; }
void set_nm_content_size(CodeSection::csize_t size) { _nm_content_size = size; }

View File

@ -106,23 +106,26 @@ class CompilerDirectives;
class DirectiveSet;
class DirectivesStack : AllStatic {
// To allow access to private methods
friend class CompilerDirectiveMatcher;
friend class DirectiveSetPtr;
private:
static CompilerDirectives* _top;
static CompilerDirectives* _bottom;
static int _depth;
static void pop_inner(); // no lock version of pop
public:
static void init();
static DirectiveSet* getMatchingDirective(const methodHandle& mh, AbstractCompiler* comp);
static DirectiveSet* getDefaultDirective(AbstractCompiler* comp);
static void release(DirectiveSet* set);
static void release(CompilerDirectives* dir);
public:
static void init();
static void push(CompilerDirectives* directive);
static void pop(int count);
static bool check_capacity(int request_size, outputStream* st);
static void clear();
static void print(outputStream* st);
static void release(DirectiveSet* set);
static void release(CompilerDirectives* dir);
};
class DirectiveSet : public CHeapObj<mtCompiler> {
@ -327,4 +330,26 @@ public:
DirectiveSet* _c2_store;
};
// Helper class to get a matching CompilerDirective using RAII pattern.
// CompileDirective ref count is decremented in the destructor.
class CompilerDirectiveMatcher {
private:
DirectiveSet* _match;
public:
// Use this constructor to get default directive
CompilerDirectiveMatcher(AbstractCompiler* comp) {
_match = DirectivesStack::getDefaultDirective(comp);
}
CompilerDirectiveMatcher(const methodHandle& mh, AbstractCompiler* comp) {
_match = DirectivesStack::getMatchingDirective(mh, comp);
}
~CompilerDirectiveMatcher() {
DirectivesStack::release(_match);
}
DirectiveSet* directive_set() const { return _match; }
};
#endif // SHARE_COMPILER_COMPILERDIRECTIVES_HPP

View File

@ -818,9 +818,8 @@ JVMCI::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler,
cb = nm;
if (compile_state == nullptr) {
// This compile didn't come through the CompileBroker so perform the printing here
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler);
nm->maybe_print_nmethod(directive);
DirectivesStack::release(directive);
CompilerDirectiveMatcher matcher(method, compiler);
nm->maybe_print_nmethod(matcher.directive_set());
// Since this compilation didn't pass through the broker it wasn't logged yet.
if (PrintCompilation) {

View File

@ -256,11 +256,10 @@ address OptoRuntime::generate_stub(ciEnv* env,
bool return_pc) {
// Matching the default directive, we currently have no method to match.
DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_full_optimization));
CompilationMemoryStatisticMark cmsm(directive);
CompilerDirectiveMatcher default_directive(CompileBroker::compiler(CompLevel_full_optimization));
CompilationMemoryStatisticMark cmsm(default_directive.directive_set());
ResourceMark rm;
Compile C(env, gen, C_function, name, stub_id, is_fancy_jump, pass_tls, return_pc, directive);
DirectivesStack::release(directive);
Compile C(env, gen, C_function, name, stub_id, is_fancy_jump, pass_tls, return_pc, default_directive.directive_set());
return C.stub_entry_point();
}

View File

@ -876,10 +876,8 @@ static bool is_excluded_for_compiler(AbstractCompiler* comp, methodHandle& mh) {
if (comp == nullptr) {
return true;
}
DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp);
bool exclude = directive->ExcludeOption;
DirectivesStack::release(directive);
return exclude;
CompilerDirectiveMatcher matcher(mh, comp);
return matcher.directive_set()->ExcludeOption;
}
static bool can_be_compiled_at_level(methodHandle& mh, jboolean is_osr, int level) {
@ -950,19 +948,17 @@ WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject metho
CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(method_id));
DirectiveSet* directive;
if (compilation_context != nullptr) {
compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context);
CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
methodHandle cch(THREAD, Method::checked_resolve_jmethod_id(compilation_context_id));
directive = DirectivesStack::getMatchingDirective(cch, comp);
CompilerDirectiveMatcher matcher(cch, comp);
return comp->is_intrinsic_available(mh, matcher.directive_set());
} else {
// Calling with null matches default directive
directive = DirectivesStack::getDefaultDirective(comp);
CompilerDirectiveMatcher default_directive(comp);
return comp->is_intrinsic_available(mh, default_directive.directive_set());
}
bool result = comp->is_intrinsic_available(mh, directive);
DirectivesStack::release(directive);
return result;
WB_END
WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
@ -1136,9 +1132,8 @@ bool WhiteBox::compile_method(Method* method, int comp_level, int bci, JavaThrea
// Check if compilation is blocking
methodHandle mh(THREAD, method);
DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp);
bool is_blocking = !directive->BackgroundCompilationOption;
DirectivesStack::release(directive);
CompilerDirectiveMatcher matcher(mh, comp);
bool is_blocking = !matcher.directive_set()->BackgroundCompilationOption;
// Compile method and check result
nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh->invocation_count(), CompileTask::Reason_Whitebox, CHECK_false);
@ -1189,11 +1184,8 @@ WB_ENTRY(jboolean, WB_ShouldPrintAssembly(JNIEnv* env, jobject o, jobject method
CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, CompileBroker::compiler(comp_level));
bool result = directive->PrintAssemblyOption;
DirectivesStack::release(directive);
return result;
CompilerDirectiveMatcher matcher(mh, CompileBroker::compiler(comp_level));
return matcher.directive_set()->PrintAssemblyOption;
WB_END
WB_ENTRY(jint, WB_MatchesInline(JNIEnv* env, jobject o, jobject method, jstring pattern))

View File

@ -3194,11 +3194,10 @@ void AdapterHandlerLibrary::create_native_wrapper(const methodHandle& method) {
}
}
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, CompileBroker::compiler(CompLevel_simple));
if (directive->PrintAssemblyOption) {
CompilerDirectiveMatcher matcher(method, CompileBroker::compiler(CompLevel_simple));
if (matcher.directive_set()->PrintAssemblyOption) {
nm->print_code();
}
DirectivesStack::release(directive);
}
}
} // Unlock AdapterHandlerLibrary_lock