Integrated: 8333722: Fix CompilerDirectives for non-compiler JVM variants

Volker Simonis simonis at openjdk.org
Mon Jun 10 09:40:16 UTC 2024


On Thu, 6 Jun 2024 13:36:25 GMT, Volker Simonis <simonis at openjdk.org> wrote:

> `DirectivesStack::getMatchingDirective()` relies on the fact that the default directives set is always enabled. And that's indeed the case for normal builds with C1 and C2 compilers (see `DirectivesStack::init()` in `compilerDirectives.cpp`):
> 
> 
> // Create a new dirstack and push a default directive
> void DirectivesStack::init() {
>   CompilerDirectives* _default_directives = new CompilerDirectives();
>   char str[] = "*.*";
>   const char* error_msg = nullptr;
>   _default_directives->add_match(str, error_msg);
> #if defined(COMPILER1) || INCLUDE_JVMCI
>   _default_directives->_c1_store->EnableOption = true;
> #endif
> #ifdef COMPILER2
>   if (CompilerConfig::is_c2_enabled()) {
>     _default_directives->_c2_store->EnableOption = true;
>   }
> #endif
>   assert(error_msg == nullptr, "Must succeed.");
>   push(_default_directives);
> }
> 
> 
> However, if we're building a JVM configuration without compilers (e.g. `--with-jvm-variants=core`), this is not the case and `DirectivesStack::getMatchingDirective()` will return the base directive set without incrementing the reference count of its directive:
> 
> 
>     CompilerDirectives* dir = _top;
>     assert(dir != nullptr, "Must be initialized");
> 
>     while (dir != nullptr) {
>       if (dir->is_default_directive() || dir->match(method)) {
>         match = dir->get_for(comp);
>         assert(match != nullptr, "Consistency");
>         if (match->EnableOption) {
>           // The directiveSet for this compile is also enabled -> success
>           dir->inc_refcount();
>           break;
>         }
>       }
>       dir = dir->next();
>     }
>   }
>   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);
> 
> 
> If this directive set will be released, it will delete the corresponding base directive and subsequent usages of the base directive will lead to a segmentation fault.
> 
> After [JDK-8329421: Native methods can not be selectively printed](https://bugs.openjdk.org/browse/JDK-8329421) which replaced the call to
> 
> DirectiveSet* directive = DirectivesStack::getDefaultDirective(CompileBroker::compiler(CompLevel_simple));
> 
> by
> 
> DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, CompileBroker::compiler(CompLevel_simple));
> 
> in `sharedRuntime.cpp` this issue is now triggered at JVM startup for non-compiler configurations when native wrappers are generated (see https://github.com/openjdk/jdk/pull/18567#...

This pull request has now been integrated.

Changeset: 5f9d3e3a
Author:    Volker Simonis <simonis at openjdk.org>
URL:       https://git.openjdk.org/jdk/commit/5f9d3e3af8342592242cb304b2c219508d56ed3a
Stats:     1 line in 1 file changed: 0 ins; 0 del; 1 mod

8333722: Fix CompilerDirectives for non-compiler JVM variants

Reviewed-by: kvn

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

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


More information about the hotspot-compiler-dev mailing list