blob: f8e5847428408b3d3f363a826e1dffd190675d25 [file] [log] [blame]
/*
* Copyright (c) 2020, 2023, 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_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP
#define SHARE_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP
#include "runtime/flags/jvmFlag.hpp"
class outputStream;
template <typename T> class JVMTypedFlagLimit;
enum class JVMFlagConstraintPhase : int {
// Will be validated during argument processing (Arguments::parse_argument).
AtParse = 0,
// Will be validated inside Threads::create_vm(), right after Arguments::apply_ergo().
AfterErgo = 1,
// Will be validated inside universe_init(), right after Metaspace::global_initialize().
AfterMemoryInit = 2
};
typedef JVMFlag::Error (*JVMFlagConstraintFunc_bool)(bool value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_int)(int value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_intx)(intx value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint)(uint value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uintx)(uintx value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_uint64_t)(uint64_t value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_size_t)(size_t value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_double)(double value, bool verbose);
typedef JVMFlag::Error (*JVMFlagConstraintFunc_ccstr)(ccstr value, bool verbose);
template <typename T> class JVMTypedFlagLimit;
// A JVMFlagLimit is created for each JVMFlag that has a range() and/or constraint() in its declaration in
// the globals_xxx.hpp file.
//
// To query the range information of a JVMFlag:
// JVMFlagLimit::get_range(JVMFlag*)
// JVMFlagLimit::get_range_at(int flag_enum)
// If the given flag doesn't have a range, null is returned.
//
// To query the constraint information of a JVMFlag:
// JVMFlagLimit::get_constraint(JVMFlag*)
// JVMFlagLimit::get_constraint_at(int flag_enum)
// If the given flag doesn't have a constraint, null is returned.
class JVMFlagLimit {
short _constraint_func;
char _phase;
char _kind;
#ifdef ASSERT
int _type_enum;
#endif
static const JVMFlagLimit* const* flagLimits;
static JVMFlagsEnum _last_checked;
static JVMFlagConstraintPhase _validating_phase;
protected:
static constexpr int HAS_RANGE = 1;
static constexpr int HAS_CONSTRAINT = 2;
private:
static const JVMFlagLimit* get_kind_at(JVMFlagsEnum flag_enum, int required_kind) {
const JVMFlagLimit* limit = at(flag_enum);
if (limit != nullptr && (limit->_kind & required_kind) != 0) {
_last_checked = flag_enum;
return limit;
} else {
return nullptr;
}
}
static const JVMFlagLimit* at(JVMFlagsEnum flag_enum) {
JVMFlag::assert_valid_flag_enum(flag_enum);
return flagLimits[static_cast<int>(flag_enum)];
}
public:
void* constraint_func() const;
char phase() const { return _phase; }
char kind() const { return _kind; }
constexpr JVMFlagLimit(int type_enum, short func, short phase, short kind)
: _constraint_func(func), _phase(phase), _kind(kind) DEBUG_ONLY(COMMA _type_enum(type_enum)) {}
static const JVMFlagLimit* get_range(const JVMFlag* flag) {
return get_range_at(flag->flag_enum());
}
static const JVMFlagLimit* get_range_at(JVMFlagsEnum flag_enum) {
return get_kind_at(flag_enum, HAS_RANGE);
}
static const JVMFlagLimit* get_constraint(const JVMFlag* flag) {
return get_constraint_at(flag->flag_enum());
}
static const JVMFlagLimit* get_constraint_at(JVMFlagsEnum flag_enum) {
return get_kind_at(flag_enum, HAS_CONSTRAINT);
}
static const JVMFlag* last_checked_flag();
// Is the current value of each JVM flag within the allowed range (if specified)
static bool check_all_ranges();
void print_range(outputStream* st, const JVMFlag* flag) const;
// Does the current value of each JVM flag satisfy the specified constraint
static bool check_all_constraints(JVMFlagConstraintPhase phase);
// If range/constraint checks fail, print verbose error messages only if we are parsing
// arguments from the command-line. Silently ignore any invalid values that are
// set programmatically via FLAG_SET_ERGO, etc.
static bool verbose_checks_needed() {
return _validating_phase == JVMFlagConstraintPhase::AtParse;
}
static JVMFlagConstraintPhase validating_phase() { return _validating_phase; }
template <typename T>
const JVMTypedFlagLimit<T>* cast() const;
};
enum ConstraintMarker {
next_two_args_are_constraint,
};
template <typename T>
class JVMTypedFlagLimit : public JVMFlagLimit {
const T _min;
const T _max;
public:
// dummy - no range or constraint. This object will not be emitted into the .o file
// because we declare it as "const" but has no reference to it.
constexpr JVMTypedFlagLimit(int type_enum) :
JVMFlagLimit(0, 0, 0, 0), _min(0), _max(0) {}
// range only
constexpr JVMTypedFlagLimit(int type_enum, T min, T max) :
JVMFlagLimit(type_enum, 0, 0, HAS_RANGE), _min(min), _max(max) {}
// constraint only
constexpr JVMTypedFlagLimit(int type_enum, ConstraintMarker dummy2, short func, int phase) :
JVMFlagLimit(type_enum, func, phase, HAS_CONSTRAINT), _min(0), _max(0) {}
// range and constraint
constexpr JVMTypedFlagLimit(int type_enum, T min, T max, ConstraintMarker dummy2, short func, int phase) :
JVMFlagLimit(type_enum, func, phase, HAS_RANGE | HAS_CONSTRAINT), _min(min), _max(max) {}
// constraint and range
constexpr JVMTypedFlagLimit(int type_enum, ConstraintMarker dummy2, short func, int phase, T min, T max) :
JVMFlagLimit(type_enum, func, phase, HAS_RANGE | HAS_CONSTRAINT), _min(min), _max(max) {}
T min() const { return _min; }
T max() const { return _max; }
};
template <typename T>
const JVMTypedFlagLimit<T>* JVMFlagLimit::cast() const {
DEBUG_ONLY(JVMFlag::assert_compatible_type<T>(_type_enum));
return static_cast<const JVMTypedFlagLimit<T>*>(this);
}
#endif // SHARE_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP