JDK-8145357 : command line flag constraints runs constraint functions too early
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9
  • Priority: P2
  • Status: Resolved
  • Resolution: Not an Issue
  • Submitted: 2015-12-14
  • Updated: 2016-01-12
  • Resolved: 2015-12-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Resolved
Related Reports
Relates :  
Relates :  
Description
JVMCI uses a constraint function to make sure you can't turn on certain flags without another being turned on:

Flag::Error EnableJVMCIMustBeEnabledConstraintFunc(bool value, bool verbose) {
  if (!EnableJVMCI) {
    if (verbose == true) {
      jio_fprintf(defaultStream::error_stream(), "EnableJVMCI must be enabled\n");
    }
    return Flag::VIOLATES_CONSTRAINT;
  } else {
    return Flag::SUCCESS;
  }
}

But it doesn't work as expected:

cthaling@macbook:~/ws/jdk9/hs-comp$ ./build/macosx-x86_64-normal-server-release/jdk/bin/java -XX:+UnlockExperimentalVMOptions -XX:-EnableJVMCI -XX:+UseJVMCICompiler
EnableJVMCI must be enabled
Improperly specified VM option 'UseJVMCICompiler'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

cthaling@macbook:~/ws/jdk9/hs-comp$ ./build/macosx-x86_64-normal-server-release/jdk/bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler -XX:-EnableJVMCI
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000110218778, pid=92084, tid=5891
#
# JRE version: Java(TM) SE Runtime Environment (9.0) (build 9-internal+0-2015-12-08-103439.cthaling.hs-comp)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (9-internal+0-2015-12-08-103439.cthaling.hs-comp, mixed mode, tiered, jvmci compiler, compressed oops, g1 gc, bsd-amd64)
# Problematic frame:
# V  [libjvm.dylib+0x218778]
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/cthaling/ws/jdk9/hs-comp/hs_err_pid92084.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
Abort trap: 6

Comments
I tried :-)
23-12-2015

For those flags with values that are only valid within some range, then yes you should use the JEP-245 mechanism. It was never designed, however, and is not guaranteed to work in cases where one flag depends on a value of another flag (though it can work in some carefully tested instances), and definitely not designed as a "gate" to protect code requiring certain flag's value at a random point in initialization sequence.
23-12-2015

The range/constraint check comes right after Arguments::apply_ergo() where the flags are parsed, so it comes at the proper time. GC added 2nd check right after Metaspace::global_initialize() since many of their flags values get initialized there, but that is more of a workaround.
23-12-2015

During the review of JEP 243 someone suggested to use the constraints machinery so we did. Isn't there a point in time when all command line flags have settled? You could run the constraints after that point.
22-12-2015

This is a very cool way you are trying to use the range/constraint checks mechanism, however, I believe that you are overestimating the mechanism capabilities. It was designed only to check a single flag range, and its constraint in case the range is not sufficient (like the value has to be a power of 2). The mechanism was never designed as a gate, especially in case where one flag is dependent on another flag. There are simple existing such cases, but you are on your own in such cases and it's not guaranteed to work as evidenced by your case. Here is the call graph in this case: JNI_CreateJavaVM_inner() { __. __Threads::create_vm() ____.. ____Arguments::apply_ergo() ____CommandLineFlagRangeList::check_ranges() ____CommandLineFlagConstraintList::check_constraints(CommandLineFlagConstraint::AfterErgo) ____.. ____init_globals() ______... ______universe_init() ________.... ________Metaspace::global_initialize(); ________CommandLineFlagConstraintList::check_constraints(CommandLineFlagConstraint::AfterMemoryInit) ________.... ______... ____.. ____CompileBroker::compilation_init() ____.. __. __JVMCICompiler::instance(); __. } so yes, it certainly does look like the constraints functions are run too early here, but again the mechanism was not designed for such use. At first there was only one point in the code where we checked constraints, ie. "AfterErgo". That wasn't sufficient for the GC team, so they added another point in time later where they check constraints, i.e.: "AfterMemoryInit". In case of GC, however, they had an entire bunch of flags that required the late check. In theory, you could add (yourself) a new later check for constraint to suit the JVMCI init code, but frankly I would be against it. JEP-245 is only about range (and constraint) checks of single values, not a logical gate that protects custom code - however cool that in fact would be. I think this should be closed as "will not fix / works as expected" and you will need a custom check to protect your JVMCI init code. Is that OK?
22-12-2015

It's on my radar.
21-12-2015

You realize that this crashes the VM, right?
21-12-2015