diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp index e7ef97031914b..868ae8bfa41f4 100644 --- a/src/hotspot/share/compiler/compilerOracle.cpp +++ b/src/hotspot/share/compiler/compilerOracle.cpp @@ -317,8 +317,10 @@ TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& me } template -static void register_command(TypedMethodOptionMatcher* matcher, +static bool register_command(TypedMethodOptionMatcher* matcher, CompileCommandEnum option, + char* errorbuf, + const int buf_size, T value) { assert(matcher != option_list, "No circular lists please"); if (option == CompileCommandEnum::Log && !LogCompilation) { @@ -331,7 +333,17 @@ static void register_command(TypedMethodOptionMatcher* matcher, warning("Blackhole compile option is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions"); // Delete matcher as we don't keep it delete matcher; - return; + return true; + } + + if (!UnlockDiagnosticVMOptions) { + const char* name = option2name(option); + JVMFlag* flag = JVMFlag::find_declared_flag(name); + if (flag != nullptr && flag->is_diagnostic()) { + jio_snprintf(errorbuf, buf_size, "VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.", name); + delete matcher; + return false; + } } matcher->init(option, option_list); @@ -346,7 +358,7 @@ static void register_command(TypedMethodOptionMatcher* matcher, matcher->print(); } - return; + return true; } template @@ -714,7 +726,7 @@ static bool parseMemStat(const char* line, uintx& value, int& bytes_read, char* return false; } -static void scan_value(enum OptionType type, char* line, int& total_bytes_read, +static bool scan_value(enum OptionType type, char* line, int& total_bytes_read, TypedMethodOptionMatcher* matcher, CompileCommandEnum option, char* errorbuf, const int buf_size) { int bytes_read = 0; const char* ccname = option2name(option); @@ -733,11 +745,10 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read, } if (success) { total_bytes_read += bytes_read; - line += bytes_read; - register_command(matcher, option, value); - return; + return register_command(matcher, option, errorbuf, buf_size, value); } else { jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); + return false; } } else if (type == OptionType::Uintx) { uintx value; @@ -751,21 +762,20 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read, } if (success) { total_bytes_read += bytes_read; - line += bytes_read; - register_command(matcher, option, value); + return register_command(matcher, option, errorbuf, buf_size, value); } else { jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); + return false; } } else if (type == OptionType::Ccstr) { ResourceMark rm; char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1); if (sscanf(line, "%255[_a-zA-Z0-9]%n", value, &bytes_read) == 1) { total_bytes_read += bytes_read; - line += bytes_read; - register_command(matcher, option, (ccstr) value); - return; + return register_command(matcher, option, errorbuf, buf_size, (ccstr) value); } else { jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); + return false; } } else if (type == OptionType::Ccstrlist) { // Accumulates several strings into one. The internal type is ccstr. @@ -790,6 +800,7 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read, if (!validator.is_valid()) { jio_snprintf(errorbuf, buf_size, "Unrecognized intrinsic detected in %s: %s", option2name(option), validator.what()); + return false; } } #if !defined(PRODUCT) && defined(COMPILER2) @@ -798,18 +809,21 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read, if (!validator.is_valid()) { jio_snprintf(errorbuf, buf_size, "Unrecognized tag name in %s: %s", option2name(option), validator.what()); + return false; } } else if (option == CompileCommandEnum::TraceMergeStores) { TraceMergeStores::TagValidator validator(value, true); if (!validator.is_valid()) { jio_snprintf(errorbuf, buf_size, "Unrecognized tag name in %s: %s", option2name(option), validator.what()); + return false; } } else if (option == CompileCommandEnum::PrintIdealPhase) { PhaseNameValidator validator(value); if (!validator.is_valid()) { jio_snprintf(errorbuf, buf_size, "Unrecognized phase name in %s: %s", option2name(option), validator.what()); + return false; } } else if (option == CompileCommandEnum::TestOptionList) { // all values are ok @@ -819,35 +833,32 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read, assert(false, "Ccstrlist type option missing validator"); } - register_command(matcher, option, (ccstr) value); - return; + return register_command(matcher, option, errorbuf, buf_size, (ccstr) value); } else { jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str); + return false; } } else if (type == OptionType::Bool) { char value[256]; if (*line == '\0') { // Short version of a CompileCommand sets a boolean Option to true // -XXCompileCommand=