8145333: -XX:+EnableJVMCI -XX:+UseJVMCICompiler -XX:-EnableJVMCI makes JVM crash

JVMCI Flags are checked for consistency after parse.

Reviewed-by: twisti
This commit is contained in:
Jamsheed Mohammed C M 2016-02-22 23:37:29 -08:00
parent 310eb4ad4d
commit 36e011b2f0
7 changed files with 210 additions and 119 deletions

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2015, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "jvmci/commandLineFlagConstraintsJVMCI.hpp"
#include "runtime/arguments.hpp"
#include "runtime/globals.hpp"
#include "utilities/defaultStream.hpp"
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;
}
}
Flag::Error EnableJVMCIMustBeEnabledConstraintFunc(intx 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;
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2015, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_JVMCI_COMMANDLINEFLAGCONSTRAINTSJVMCI_HPP
#define SHARE_VM_JVMCI_COMMANDLINEFLAGCONSTRAINTSJVMCI_HPP
#include "runtime/globals.hpp"
#include "utilities/globalDefinitions.hpp"
/*
* Here we have JVMCI arguments constraints functions, which are called automatically
* whenever flag's value changes. If the constraint fails the function should return
* an appropriate error value.
*/
Flag::Error EnableJVMCIMustBeEnabledConstraintFunc(bool value, bool verbose);
Flag::Error EnableJVMCIMustBeEnabledConstraintFunc(intx value, bool verbose);
#endif /* SHARE_VM_JVMCI_COMMANDLINEFLAGCONSTRAINTSJVMCI_HPP */

View File

@ -24,6 +24,8 @@
#include "precompiled.hpp"
#include "jvmci/jvmci_globals.hpp"
#include "utilities/defaultStream.hpp"
#include "runtime/globals_extension.hpp"
JVMCI_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
MATERIALIZE_PD_DEVELOPER_FLAG, \
@ -34,3 +36,185 @@ JVMCI_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
MATERIALIZE_NOTPRODUCT_FLAG,
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
#define JVMCI_IGNORE_FLAG_FOUR_PARAM(type, name, value, doc)
#define JVMCI_IGNORE_FLAG_THREE_PARAM(type, name, doc)
// Return true if jvmci flags are consistent.
bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
if (EnableJVMCI) {
return true;
}
// "FLAG_IS_DEFAULT" fail count.
int fail_count = 0;
// Number of "FLAG_IS_DEFAULT" fails that should be skipped before code
// detect real consistency failure.
int skip_fail_count;
// EnableJVMCI flag is false here.
// If any other flag is changed, consistency check should fail.
// JVMCI_FLAGS macros added below can handle all JVMCI flags automatically.
// But it contains check for EnableJVMCI flag too, which is required to be
// skipped. This can't be handled easily!
// So the code looks for at-least two flag changes to detect consistency
// failure when EnableJVMCI flag is changed.
// Otherwise one flag change is sufficient to detect consistency failure.
// Set skip_fail_count to 0 if EnableJVMCI flag is default.
// Set skip_fail_count to 1 if EnableJVMCI flag is changed.
// This value will be used to skip fails in macro expanded code later.
if (!FLAG_IS_DEFAULT(EnableJVMCI)) {
skip_fail_count = 1;
} else {
skip_fail_count = 0;
}
#define EMIT_FLAG_VALUE_CHANGED_CHECK_CODE(FLAG) \
if (!FLAG_IS_DEFAULT(FLAG)) { \
fail_count++; \
if (fail_count > skip_fail_count) { \
return false; \
} \
}
#define JVMCI_DIAGNOSTIC_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, value, doc) EMIT_FLAG_VALUE_CHANGED_CHECK_CODE(name)
#define JVMCI_EXPERIMENTAL_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, value, doc) EMIT_FLAG_VALUE_CHANGED_CHECK_CODE(name)
// Check consistency of diagnostic flags if UnlockDiagnosticVMOptions is true
// or not default. UnlockDiagnosticVMOptions is default true in debug builds.
if (UnlockDiagnosticVMOptions || !FLAG_IS_DEFAULT(UnlockDiagnosticVMOptions)) {
JVMCI_FLAGS(JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_THREE_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_THREE_PARAM, \
JVMCI_DIAGNOSTIC_FLAG_VALUE_CHANGED_CHECK_CODE, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
}
// Check consistency of experimental flags if UnlockExperimentalVMOptions is
// true or not default.
if (UnlockExperimentalVMOptions || !FLAG_IS_DEFAULT(UnlockExperimentalVMOptions)) {
JVMCI_FLAGS(JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_THREE_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_THREE_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_EXPERIMENTAL_FLAG_VALUE_CHANGED_CHECK_CODE, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
}
#ifndef PRODUCT
#define JVMCI_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, value, doc) EMIT_FLAG_VALUE_CHANGED_CHECK_CODE(name)
#define JVMCI_PD_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, doc) EMIT_FLAG_VALUE_CHANGED_CHECK_CODE(name)
#define JVMCI_NOTPRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, value, doc) EMIT_FLAG_VALUE_CHANGED_CHECK_CODE(name)
#else
#define JVMCI_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, value, doc)
#define JVMCI_PD_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, doc)
#define JVMCI_NOTPRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, value, doc)
#endif
#define JVMCI_PD_PRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, doc) EMIT_FLAG_VALUE_CHANGED_CHECK_CODE(name)
#define JVMCI_PRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE(type, name, value, doc) EMIT_FLAG_VALUE_CHANGED_CHECK_CODE(name)
JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE, \
JVMCI_PD_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE, \
JVMCI_PRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE, \
JVMCI_PD_PRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_NOTPRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE, \
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
#undef EMIT_FLAG_VALUE_CHANGED_CHECK_CODE
#undef JVMCI_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE
#undef JVMCI_PD_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE
#undef JVMCI_NOTPRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE
#undef JVMCI_DIAGNOSTIC_FLAG_VALUE_CHANGED_CHECK_CODE
#undef JVMCI_PD_PRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE
#undef JVMCI_PRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE
#undef JVMCI_EXPERIMENTAL_FLAG_VALUE_CHANGED_CHECK_CODE
return true;
}
// Print jvmci arguments inconsistency error message.
void JVMCIGlobals::print_jvmci_args_inconsistency_error_message() {
const char* error_msg = "Improperly specified VM option '%s'\n";
jio_fprintf(defaultStream::error_stream(), "EnableJVMCI must be enabled\n");
#define EMIT_CHECK_PRINT_ERR_MSG_CODE(FLAG) \
if (!FLAG_IS_DEFAULT(FLAG)) { \
if (strcmp(#FLAG, "EnableJVMCI")) { \
jio_fprintf(defaultStream::error_stream(), error_msg, #FLAG); \
} \
}
#define JVMCI_DIAGNOSTIC_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, value, doc) EMIT_CHECK_PRINT_ERR_MSG_CODE(name)
#define JVMCI_EXPERIMENTAL_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, value, doc) EMIT_CHECK_PRINT_ERR_MSG_CODE(name)
if (UnlockDiagnosticVMOptions || !FLAG_IS_DEFAULT(UnlockDiagnosticVMOptions)) {
JVMCI_FLAGS(JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_THREE_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_THREE_PARAM, \
JVMCI_DIAGNOSTIC_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
}
if (UnlockExperimentalVMOptions || !FLAG_IS_DEFAULT(UnlockExperimentalVMOptions)) {
JVMCI_FLAGS(JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_THREE_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_THREE_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_EXPERIMENTAL_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
}
#ifndef PRODUCT
#define JVMCI_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, value, doc) EMIT_CHECK_PRINT_ERR_MSG_CODE(name)
#define JVMCI_PD_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, doc) EMIT_CHECK_PRINT_ERR_MSG_CODE(name)
#define JVMCI_NOTPRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, value, doc) EMIT_CHECK_PRINT_ERR_MSG_CODE(name)
#else
#define JVMCI_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, value, doc)
#define JVMCI_PD_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, doc)
#define JVMCI_NOTPRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, value, doc)
#endif
#define JVMCI_PD_PRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, doc) EMIT_CHECK_PRINT_ERR_MSG_CODE(name)
#define JVMCI_PRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE(type, name, value, doc) EMIT_CHECK_PRINT_ERR_MSG_CODE(name)
JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
JVMCI_PD_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
JVMCI_PRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
JVMCI_PD_PRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_IGNORE_FLAG_FOUR_PARAM, \
JVMCI_NOTPRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
#undef EMIT_CHECK_PRINT_ERR_MSG_CODE
#undef JVMCI_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE
#undef JVMCI_PD_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE
#undef JVMCI_NOTPRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE
#undef JVMCI_PD_PRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE
#undef JVMCI_PRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE
#undef JVMCI_DIAGNOSTIC_FLAG_CHECK_PRINT_ERR_MSG_CODE
#undef JVMCI_EXPERIMENTAL_FLAG_CHECK_PRINT_ERR_MSG_CODE
}
#undef JVMCI_IGNORE_FLAG_FOUR_PARAM
#undef JVMCI_IGNORE_FLAG_THREE_PARAM

View File

@ -39,29 +39,23 @@
\
experimental(bool, UseJVMCICompiler, false, \
"Use JVMCI as the default compiler") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
experimental(bool, BootstrapJVMCI, false, \
"Bootstrap JVMCI before running Java main method") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
experimental(bool, PrintBootstrap, true, \
"Print JVMCI bootstrap progress and summary") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
experimental(intx, JVMCIThreads, 1, \
"Force number of JVMCI compiler threads to use") \
range(1, max_jint) \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
experimental(intx, JVMCIHostThreads, 1, \
"Force number of compiler threads for JVMCI host compiler") \
range(1, max_jint) \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
experimental(bool, CodeInstallSafepointChecks, true, \
"Perform explicit safepoint checks while installing code") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
NOT_COMPILER2(product(intx, MaxVectorSize, 64, \
"Max vector size in bytes, " \
@ -74,28 +68,22 @@
"Trace level for JVMCI: " \
"1 means emit a message for each CompilerToVM call," \
"levels greater than 1 provide progressively greater detail") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
experimental(intx, JVMCICounterSize, 0, \
"Reserved size for benchmark counters") \
range(0, max_jint) \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
experimental(bool, JVMCICountersExcludeCompiler, true, \
"Exclude JVMCI compiler threads from benchmark counters") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
develop(bool, JVMCIUseFastLocking, true, \
"Use fast inlined locking code") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
experimental(intx, JVMCINMethodSizeLimit, (80*K)*wordSize, \
"Maximum size of a compiled method.") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
\
develop(bool, TraceUncollectedSpeculations, false, \
"Print message when a failed speculation was not collected") \
constraint(EnableJVMCIMustBeEnabledConstraintFunc,AtParse) \
"Print message when a failed speculation was not collected")
// Read default values for JVMCI globals
@ -110,4 +98,11 @@ JVMCI_FLAGS(DECLARE_DEVELOPER_FLAG, \
IGNORE_RANGE, \
IGNORE_CONSTRAINT)
class JVMCIGlobals {
public:
// Return true if jvmci flags are consistent.
static bool check_jvmci_flags_are_consistent();
// Print jvmci arguments inconsistency error message.
static void print_jvmci_args_inconsistency_error_message();
};
#endif // SHARE_VM_JVMCI_JVMCIGLOBALS_HPP

View File

@ -2314,6 +2314,17 @@ bool Arguments::sun_java_launcher_is_altjvm() {
//===========================================================================================================
// Parsing of main arguments
#if INCLUDE_JVMCI
// Check consistency of jvmci vm argument settings.
bool Arguments::check_jvmci_args_consistency() {
if (!EnableJVMCI && !JVMCIGlobals::check_jvmci_flags_are_consistent()) {
JVMCIGlobals::print_jvmci_args_inconsistency_error_message();
return false;
}
return true;
}
#endif //INCLUDE_JVMCI
// Check consistency of GC selection
bool Arguments::check_gc_consistency() {
// Ensure that the user has not selected conflicting sets
@ -2410,6 +2421,9 @@ bool Arguments::check_vm_args_consistency() {
#endif
}
#if INCLUDE_JVMCI
status = status && check_jvmci_args_consistency();
if (EnableJVMCI) {
if (!ScavengeRootsInCode) {
warning("forcing ScavengeRootsInCode non-zero because JVMCI is enabled");

View File

@ -505,7 +505,10 @@ class Arguments : AllStatic {
static void set_gc_specific_flags();
static inline bool gc_selected(); // whether a gc has been selected
static void select_gc_ergonomically();
#if INCLUDE_JVMCI
// Check consistency of jvmci vm argument settings.
static bool check_jvmci_args_consistency();
#endif
// Check for consistency in the selection of the garbage collector.
static bool check_gc_consistency(); // Check user-selected gc
// Check consistency or otherwise of VM argument settings

View File

@ -33,9 +33,6 @@
#include "runtime/commandLineFlagConstraintsRuntime.hpp"
#include "runtime/os.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_JVMCI
#include "jvmci/commandLineFlagConstraintsJVMCI.hpp"
#endif
class CommandLineFlagConstraint_bool : public CommandLineFlagConstraint {
CommandLineFlagConstraintFunc_bool _constraint;
@ -254,17 +251,6 @@ void CommandLineFlagConstraintList::init(void) {
IGNORE_RANGE,
EMIT_CONSTRAINT_CHECK));
#if INCLUDE_JVMCI
emit_constraint_no(NULL JVMCI_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
EMIT_CONSTRAINT_PRODUCT_FLAG,
EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
IGNORE_RANGE,
EMIT_CONSTRAINT_CHECK));
#endif // INCLUDE_JVMCI
#ifdef COMPILER1
emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,