Path: blob/master/src/hotspot/share/runtime/flags/jvmFlagAccess.hpp
40957 views
/*1* Copyright (c) 2020, 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#ifndef SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP25#define SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP2627#include "memory/allStatic.hpp"28#include "runtime/flags/jvmFlag.hpp"29#include "utilities/vmEnums.hpp"3031class FlagAccessImpl;32class JVMFlagLimit;33class outputStream;3435// Use this macro in combination with JVMFlag::{read, write} and JVMFlagAccess::{get, set}36// to safely access the underlying variable of a JVMFlag:37//38// JVMFlag* flag = JVMFlag::flag_from_enum(FLAG_MEMBER_ENUM(ObjectAlignmentInBytes));39//40// /* If you use a wrong type, a run-time assertion will happen */41// intx v = flag->read<intx>();42//43// /* If you use a wrong type, or a NULL flag, an error code is returned */44// JVMFlag::Error err = JVMFlagAccess::get<JVM_FLAG_TYPE(intx)>(flag, &v, origin);4546#define JVM_FLAG_TYPE(t) \47t, JVMFlag::TYPE_ ## t4849// This class provides a unified interface for getting/setting the JVM flags, with support50// for (1) type correctness checks, (2) range checks, (3) constraint checks. Two main types51// of setters are provided. See notes below on which one to use.52class JVMFlagAccess : AllStatic {53inline static const FlagAccessImpl* access_impl(const JVMFlag* flag);54static JVMFlag::Error set_impl(JVMFlag* flag, void* value, JVMFlagOrigin origin);55static JVMFlag::Error set_or_assert(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlagOrigin origin);5657static bool is_correct_type(const JVMFlag* flag, int type_enum) {58if (type_enum == JVMFlag::TYPE_ccstr) {59if (!flag->is_ccstr()) { // ccstr or ccstrlist60return false;61}62} else {63if (flag->type() != type_enum) {64return false;65}66}67return true;68}6970public:71static JVMFlag::Error check_range(const JVMFlag* flag, bool verbose);72static JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose);73static void print_range(outputStream* st, const JVMFlag* flag, const JVMFlagLimit* range);74static void print_range(outputStream* st, const JVMFlag* flag);7576template <typename T, int type_enum>77static JVMFlag::Error get(const JVMFlag* flag, T* value) {78// The caller must not not mix incompatible types such as79// set<double, JVMFlag::TYPE_int>(flag, double_ptr);80assert(JVMFlag::is_compatible_type<T>(type_enum), "must be");8182if (flag == NULL) {83return JVMFlag::INVALID_FLAG;84}85if (!is_correct_type(flag, type_enum)) {86return JVMFlag::WRONG_FORMAT;87}8889*value = flag->read<T>();90return JVMFlag::SUCCESS;91}9293// This is a *flag specific* setter. It should be used only via by the94// FLAG_SET_{DEFAULT, CMDLINE, ERGO, MGMT} macros.95// It's used to set a specific flag whose type is statically known. A mismatched96// type_enum will result in an assert.97template <typename T, int type_enum>98static JVMFlag::Error set(JVMFlagsEnum flag_enum, T value, JVMFlagOrigin origin) {99return set_or_assert(flag_enum, type_enum, &value, origin);100}101102// This is a *generic* setter. It should be used by code that can set a number of different103// flags, often according to external input that may contain errors.104// Examples callers are arguments.cpp, writeableFlags.cpp, and WB_SetXxxVMFlag functions.105// A mismatched type_enum would result in a JVMFlag::WRONG_FORMAT code.106template <typename T, int type_enum>107static JVMFlag::Error set(JVMFlag* flag, T* value, JVMFlagOrigin origin) {108// The caller must not not mix incompatible types such as109// set<double, JVMFlag::TYPE_int>(flag, double_ptr);110assert(JVMFlag::is_compatible_type<T>(type_enum), "must be");111112if (flag == NULL) {113return JVMFlag::INVALID_FLAG;114}115if (!is_correct_type(flag, type_enum)) {116return JVMFlag::WRONG_FORMAT;117}118119return set_impl(flag, (void*)value, origin);120}121122// Special handling needed for ccstr123// Contract: JVMFlag will make private copy of the incoming value.124// Outgoing value is always malloc-ed, and caller MUST call free.125static JVMFlag::Error set_ccstr(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin);126127// Handy aliases128static JVMFlag::Error get_ccstr(const JVMFlag* flag, ccstr* value) {129return get<JVM_FLAG_TYPE(ccstr)>(flag, value);130}131132static JVMFlag::Error set_bool (JVMFlag* f, bool* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(bool)> (f, v, origin); }133static JVMFlag::Error set_int (JVMFlag* f, int* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(int)> (f, v, origin); }134static JVMFlag::Error set_uint (JVMFlag* f, uint* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uint)> (f, v, origin); }135static JVMFlag::Error set_intx (JVMFlag* f, intx* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(intx)> (f, v, origin); }136static JVMFlag::Error set_uintx (JVMFlag* f, uintx* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uintx)> (f, v, origin); }137static JVMFlag::Error set_uint64_t(JVMFlag* f, uint64_t* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uint64_t)>(f, v, origin); }138static JVMFlag::Error set_size_t (JVMFlag* f, size_t* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(size_t)> (f, v, origin); }139static JVMFlag::Error set_double (JVMFlag* f, double* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(double)> (f, v, origin); }140};141142#endif // SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP143144145