1 /* 2 * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP 26 #define SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP 27 28 #include "memory/allStatic.hpp" 29 #include "runtime/flags/jvmFlag.hpp" 30 #include "utilities/vmEnums.hpp" 31 32 class FlagAccessImpl; 33 class JVMFlagLimit; 34 class outputStream; 35 36 // Use this macro in combination with JVMFlag::{read, write} and JVMFlagAccess::{get, set} 37 // to safely access the underlying variable of a JVMFlag: 38 // 39 // JVMFlag* flag = JVMFlag::flag_from_enum(FLAG_MEMBER_ENUM(ObjectAlignmentInBytes)); 40 // 41 // /* If you use a wrong type, a run-time assertion will happen */ 42 // intx v = flag->read<JVM_FLAG_TYPE(intx)>(); 43 // 44 // /* If you use a wrong type, or a NULL flag, an error code is returned */ 45 // JVMFlag::Error err = JVMFlagAccess::get<JVM_FLAG_TYPE(intx)>(flag, &v); 46 47 #define JVM_FLAG_TYPE(t) \ 48 t, JVMFlag::TYPE_ ## t 49 50 // This class provides a unified interface for getting/setting the JVM flags, with support 51 // for (1) type correctness checks, (2) range checks, (3) constraint checks. Two main types 52 // of setters are provided. See notes below on which one to use. 53 class JVMFlagAccess : AllStatic { 54 inline static const FlagAccessImpl* access_impl(const JVMFlag* flag); 55 static JVMFlag::Error set_impl(JVMFlagsEnum flag_enum, int type_enum, void* value, JVMFlagOrigin origin); 56 static JVMFlag::Error set_impl(JVMFlag* flag, int type_enum, void* value, JVMFlagOrigin origin); 57 static JVMFlag::Error ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlagOrigin origin); 58 59 public: 60 static JVMFlag::Error check_range(const JVMFlag* flag, bool verbose); 61 static JVMFlag::Error check_constraint(const JVMFlag* flag, void * func, bool verbose); 62 static void print_range(outputStream* st, const JVMFlag* flag, const JVMFlagLimit* range); 63 static void print_range(outputStream* st, const JVMFlag* flag); 64 65 template <typename T, int type_enum> get(const JVMFlag * flag,T * value)66 static JVMFlag::Error get(const JVMFlag* flag, T* value) { 67 if (flag == NULL) { 68 return JVMFlag::INVALID_FLAG; 69 } 70 if (type_enum == JVMFlag::TYPE_ccstr) { 71 if (!flag->is_ccstr()) { // ccstr or ccstrlist 72 return JVMFlag::WRONG_FORMAT; 73 } 74 } else { 75 if (flag->type() != type_enum) { 76 return JVMFlag::WRONG_FORMAT; 77 } 78 } 79 *value = flag->read<T, type_enum>(); 80 return JVMFlag::SUCCESS; 81 } 82 83 // This is a *flag specific* setter. It should be used only via by the 84 // FLAG_SET_{DEFAULT, CMDLINE, ERGO, MGMT} macros. 85 // It's used to set a specific flag whose type is statically known. A mismatched 86 // type_enum will result in an assert. 87 template <typename T, int type_enum> set(JVMFlagsEnum flag_enum,T value,JVMFlagOrigin origin)88 static JVMFlag::Error set(JVMFlagsEnum flag_enum, T value, JVMFlagOrigin origin) { 89 return set_impl(flag_enum, type_enum, &value, origin); 90 } 91 92 // This setter, and the xxxAtPut functions below, are *generic* setters. They should be used 93 // by code that can set a number of different flags, often according to external input that 94 // may contain errors. 95 // Examples callers are arguments.cpp, writeableFlags.cpp, and WB_SetXxxVMFlag functions. 96 // A mismatched type_enum would result in a JVMFlag::WRONG_FORMAT code. 97 template <typename T, int type_enum> set(JVMFlag * flag,T * value,JVMFlagOrigin origin)98 static JVMFlag::Error set(JVMFlag* flag, T* value, JVMFlagOrigin origin) { 99 return set_impl(flag, type_enum, (void*)value, origin); 100 } 101 boolAtPut(JVMFlag * f,bool * v,JVMFlagOrigin origin)102 static JVMFlag::Error boolAtPut (JVMFlag* f, bool* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(bool)> (f, v, origin); } intAtPut(JVMFlag * f,int * v,JVMFlagOrigin origin)103 static JVMFlag::Error intAtPut (JVMFlag* f, int* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(int)> (f, v, origin); } uintAtPut(JVMFlag * f,uint * v,JVMFlagOrigin origin)104 static JVMFlag::Error uintAtPut (JVMFlag* f, uint* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uint)> (f, v, origin); } intxAtPut(JVMFlag * f,intx * v,JVMFlagOrigin origin)105 static JVMFlag::Error intxAtPut (JVMFlag* f, intx* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(intx)> (f, v, origin); } uintxAtPut(JVMFlag * f,uintx * v,JVMFlagOrigin origin)106 static JVMFlag::Error uintxAtPut (JVMFlag* f, uintx* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uintx)> (f, v, origin); } uint64_tAtPut(JVMFlag * f,uint64_t * v,JVMFlagOrigin origin)107 static JVMFlag::Error uint64_tAtPut(JVMFlag* f, uint64_t* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(uint64_t)>(f, v, origin); } size_tAtPut(JVMFlag * f,size_t * v,JVMFlagOrigin origin)108 static JVMFlag::Error size_tAtPut (JVMFlag* f, size_t* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(size_t)> (f, v, origin); } doubleAtPut(JVMFlag * f,double * v,JVMFlagOrigin origin)109 static JVMFlag::Error doubleAtPut (JVMFlag* f, double* v, JVMFlagOrigin origin) { return set<JVM_FLAG_TYPE(double)> (f, v, origin); } 110 111 // Special handling needed for ccstr 112 // Contract: JVMFlag will make private copy of the incoming value. 113 // Outgoing value is always malloc-ed, and caller MUST call free. 114 static JVMFlag::Error ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin); 115 116 // Handy aliases ccstrAt(const JVMFlag * flag,ccstr * value)117 static JVMFlag::Error ccstrAt(const JVMFlag* flag, ccstr* value) { 118 return get<ccstr, JVMFlag::TYPE_ccstr>(flag, value); 119 } 120 }; 121 122 #endif // SHARE_RUNTIME_FLAGS_JVMFLAGACCESS_HPP 123