Path: blob/master/src/hotspot/share/runtime/flags/jvmFlagLimit.cpp
40957 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "memory/allocation.inline.hpp"26#include "gc/shared/jvmFlagConstraintsGC.hpp"27#include "runtime/flags/jvmFlag.hpp"28#include "runtime/flags/jvmFlagAccess.hpp"29#include "runtime/flags/jvmFlagLimit.hpp"30#include "runtime/flags/jvmFlagConstraintsCompiler.hpp"31#include "runtime/flags/jvmFlagConstraintsRuntime.hpp"32#include "runtime/globals_extension.hpp"33#include "gc/shared/referenceProcessor.hpp"34#include "oops/markWord.hpp"35#include "runtime/task.hpp"3637//----------------------------------------------------------------------38// Build flagLimitTable[]3940#define CONSTRAINT_ENUM(func) constraint_enum_ ## func41#define CONSTRAINT_ENUM_(type, func) CONSTRAINT_ENUM(func),42#define CONSTRAINT_FUNC(type, func) (void*)&func,4344enum JVMFlagConstraintsEnum : int {45ALL_CONSTRAINTS(CONSTRAINT_ENUM_)46NUM_JVMFlagConstraintsEnum47};4849static void* const flagConstraintTable[NUM_JVMFlagConstraintsEnum] = {50ALL_CONSTRAINTS(CONSTRAINT_FUNC)51};5253void* JVMFlagLimit::constraint_func() const {54int i = _constraint_func;55assert(0 <= i && i < NUM_JVMFlagConstraintsEnum, "sanity");56return flagConstraintTable[i];57}5859struct DummyLimit {60char dummy;61constexpr DummyLimit(...) : dummy() {}62};6364template <typename T>65class LimitGetter {66public:67// These functions return NULL for develop flags in a PRODUCT build68static constexpr const JVMFlagLimit* no_limit(...) {69return NULL;70}7172// This is for flags that have neither range no constraint. We don't need the JVMFlagLimit struct.73static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy) {74return NULL;75}7677static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy, T min, T max) {78return p;79}80static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy, ConstraintMarker dummy2, short func, int phase) {81return p;82}83static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy, T min, T max, ConstraintMarker dummy2, short func, int phase) {84return p;85}86static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy, ConstraintMarker dummy2, short func, int phase, T min, T max) {87return p;88}89};9091// macro body starts here -------------------+92// |93// v94#define FLAG_LIMIT_DEFINE( type, name, ...) ); constexpr JVMTypedFlagLimit<type> limit_##name(JVMFlag::TYPE_##type95#define FLAG_LIMIT_DEFINE_DUMMY(type, name, ...) ); constexpr DummyLimit nolimit_##name(096#define FLAG_LIMIT_PTR( type, name, ...) ), LimitGetter<type>::get_limit(&limit_##name, 097#define FLAG_LIMIT_PTR_NONE( type, name, ...) ), LimitGetter<type>::no_limit(098#define APPLY_FLAG_RANGE(...) , __VA_ARGS__99#define APPLY_FLAG_CONSTRAINT(func, phase) , next_two_args_are_constraint, (short)CONSTRAINT_ENUM(func), int(JVMFlagConstraintPhase::phase)100101constexpr JVMTypedFlagLimit<int> limit_dummy102(103#ifdef PRODUCT104ALL_FLAGS(FLAG_LIMIT_DEFINE_DUMMY,105FLAG_LIMIT_DEFINE_DUMMY,106FLAG_LIMIT_DEFINE,107FLAG_LIMIT_DEFINE,108FLAG_LIMIT_DEFINE_DUMMY,109APPLY_FLAG_RANGE,110APPLY_FLAG_CONSTRAINT)111#else112ALL_FLAGS(FLAG_LIMIT_DEFINE,113FLAG_LIMIT_DEFINE,114FLAG_LIMIT_DEFINE,115FLAG_LIMIT_DEFINE,116FLAG_LIMIT_DEFINE,117APPLY_FLAG_RANGE,118APPLY_FLAG_CONSTRAINT)119#endif120);121122static constexpr const JVMFlagLimit* const flagLimitTable[1 + NUM_JVMFlagsEnum] = {123// Because FLAG_LIMIT_PTR must start with an "),", we have to place a dummy element here.124LimitGetter<int>::get_limit(NULL, 0125126#ifdef PRODUCT127ALL_FLAGS(FLAG_LIMIT_PTR_NONE,128FLAG_LIMIT_PTR_NONE,129FLAG_LIMIT_PTR,130FLAG_LIMIT_PTR,131FLAG_LIMIT_PTR_NONE,132APPLY_FLAG_RANGE,133APPLY_FLAG_CONSTRAINT)134#else135ALL_FLAGS(FLAG_LIMIT_PTR,136FLAG_LIMIT_PTR,137FLAG_LIMIT_PTR,138FLAG_LIMIT_PTR,139FLAG_LIMIT_PTR,140APPLY_FLAG_RANGE,141APPLY_FLAG_CONSTRAINT)142#endif143)144};145146JVMFlagsEnum JVMFlagLimit::_last_checked = INVALID_JVMFlagsEnum;147JVMFlagConstraintPhase JVMFlagLimit::_validating_phase = JVMFlagConstraintPhase::AtParse;148149const JVMFlagLimit* const* JVMFlagLimit::flagLimits = &flagLimitTable[1]; // excludes dummy150151const JVMFlag* JVMFlagLimit::last_checked_flag() {152if (_last_checked != INVALID_JVMFlagsEnum) {153return JVMFlag::flag_from_enum(_last_checked);154} else {155return NULL;156}157}158159bool JVMFlagLimit::check_all_ranges() {160bool status = true;161for (int i = 0; i < NUM_JVMFlagsEnum; i++) {162JVMFlagsEnum flag_enum = static_cast<JVMFlagsEnum>(i);163if (get_range_at(flag_enum) != NULL &&164JVMFlagAccess::check_range(JVMFlag::flag_from_enum(flag_enum), true) != JVMFlag::SUCCESS) {165status = false;166}167}168return status;169}170171// Check constraints for specific constraint phase.172bool JVMFlagLimit::check_all_constraints(JVMFlagConstraintPhase phase) {173guarantee(phase > _validating_phase, "Constraint check is out of order.");174_validating_phase = phase;175176bool status = true;177for (int i = 0; i < NUM_JVMFlagsEnum; i++) {178JVMFlagsEnum flag_enum = static_cast<JVMFlagsEnum>(i);179const JVMFlagLimit* constraint = get_constraint_at(flag_enum);180if (constraint != NULL && constraint->phase() == static_cast<int>(phase) &&181JVMFlagAccess::check_constraint(JVMFlag::flag_from_enum(flag_enum),182constraint->constraint_func(), true) != JVMFlag::SUCCESS) {183status = false;184}185}186return status;187}188189void JVMFlagLimit::print_range(outputStream* st, const JVMFlag* flag) const {190JVMFlagAccess::print_range(st, flag, this);191}192193194