1 /* 2 * Copyright (c) 2015, 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 #include "precompiled.hpp" 26 #include "classfile/stringTable.hpp" 27 #include "classfile/symbolTable.hpp" 28 #include "gc/shared/referenceProcessor.hpp" 29 #include "runtime/arguments.hpp" 30 #include "runtime/commandLineFlagConstraintList.hpp" 31 #include "runtime/commandLineFlagConstraintsCompiler.hpp" 32 #include "runtime/commandLineFlagConstraintsGC.hpp" 33 #include "runtime/commandLineFlagConstraintsRuntime.hpp" 34 #include "runtime/os.hpp" 35 #include "utilities/macros.hpp" 36 37 class CommandLineFlagConstraint_bool : public CommandLineFlagConstraint { 38 CommandLineFlagConstraintFunc_bool _constraint; 39 40 public: 41 // the "name" argument must be a string literal 42 CommandLineFlagConstraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func) : CommandLineFlagConstraint(name) { 43 _constraint=func; 44 } 45 46 Flag::Error apply_bool(bool* value, bool verbose) { 47 return _constraint(verbose, value); 48 } 49 }; 50 51 class CommandLineFlagConstraint_int : public CommandLineFlagConstraint { 52 CommandLineFlagConstraintFunc_int _constraint; 53 54 public: 55 // the "name" argument must be a string literal 56 CommandLineFlagConstraint_int(const char* name, CommandLineFlagConstraintFunc_int func) : CommandLineFlagConstraint(name) { 57 _constraint=func; 58 } 59 60 Flag::Error apply_int(int* value, bool verbose) { 61 return _constraint(verbose, value); 62 } 63 }; 64 65 class CommandLineFlagConstraint_intx : public CommandLineFlagConstraint { 66 CommandLineFlagConstraintFunc_intx _constraint; 67 68 public: 69 // the "name" argument must be a string literal 70 CommandLineFlagConstraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func) : CommandLineFlagConstraint(name) { 71 _constraint=func; 72 } 73 74 Flag::Error apply_intx(intx* value, bool verbose) { 75 return _constraint(verbose, value); 76 } 77 }; 78 79 class CommandLineFlagConstraint_uint : public CommandLineFlagConstraint { 80 CommandLineFlagConstraintFunc_uint _constraint; 81 82 public: 83 // the "name" argument must be a string literal 84 CommandLineFlagConstraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func) : CommandLineFlagConstraint(name) { 85 _constraint=func; 86 } 87 88 Flag::Error apply_uint(uint* value, bool verbose) { 89 return _constraint(verbose, value); 90 } 91 }; 92 93 class CommandLineFlagConstraint_uintx : public CommandLineFlagConstraint { 94 CommandLineFlagConstraintFunc_uintx _constraint; 95 96 public: 97 // the "name" argument must be a string literal 98 CommandLineFlagConstraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func) : CommandLineFlagConstraint(name) { 99 _constraint=func; 100 } 101 102 Flag::Error apply_uintx(uintx* value, bool verbose) { 103 return _constraint(verbose, value); 104 } 105 }; 106 107 class CommandLineFlagConstraint_uint64_t : public CommandLineFlagConstraint { 108 CommandLineFlagConstraintFunc_uint64_t _constraint; 109 110 public: 111 // the "name" argument must be a string literal 112 CommandLineFlagConstraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func) : CommandLineFlagConstraint(name) { 113 _constraint=func; 114 } 115 116 Flag::Error apply_uint64_t(uint64_t* value, bool verbose) { 117 return _constraint(verbose, value); 118 } 119 }; 120 121 class CommandLineFlagConstraint_size_t : public CommandLineFlagConstraint { 122 CommandLineFlagConstraintFunc_size_t _constraint; 123 124 public: 125 // the "name" argument must be a string literal 126 CommandLineFlagConstraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func) : CommandLineFlagConstraint(name) { 127 _constraint=func; 128 } 129 130 Flag::Error apply_size_t(size_t* value, bool verbose) { 131 return _constraint(verbose, value); 132 } 133 }; 134 135 class CommandLineFlagConstraint_double : public CommandLineFlagConstraint { 136 CommandLineFlagConstraintFunc_double _constraint; 137 138 public: 139 // the "name" argument must be a string literal 140 CommandLineFlagConstraint_double(const char* name, CommandLineFlagConstraintFunc_double func) : CommandLineFlagConstraint(name) { 141 _constraint=func; 142 } 143 144 Flag::Error apply_double(double* value, bool verbose) { 145 return _constraint(verbose, value); 146 } 147 }; 148 149 // No constraint emitting 150 void emit_constraint_no(...) { /* NOP */ } 151 152 // No constraint emitting if function argument is NOT provided 153 void emit_constraint_bool(const char* /*name*/) { /* NOP */ } 154 void emit_constraint_ccstr(const char* /*name*/) { /* NOP */ } 155 void emit_constraint_ccstrlist(const char* /*name*/) { /* NOP */ } 156 void emit_constraint_int(const char* /*name*/) { /* NOP */ } 157 void emit_constraint_intx(const char* /*name*/) { /* NOP */ } 158 void emit_constraint_uint(const char* /*name*/) { /* NOP */ } 159 void emit_constraint_uintx(const char* /*name*/) { /* NOP */ } 160 void emit_constraint_uint64_t(const char* /*name*/) { /* NOP */ } 161 void emit_constraint_size_t(const char* /*name*/) { /* NOP */ } 162 void emit_constraint_double(const char* /*name*/) { /* NOP */ } 163 164 // CommandLineFlagConstraint emitting code functions if function argument is provided 165 void emit_constraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func) { 166 CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_bool(name, func)); 167 } 168 void emit_constraint_int(const char* name, CommandLineFlagConstraintFunc_int func) { 169 CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_int(name, func)); 170 } 171 void emit_constraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func) { 172 CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_intx(name, func)); 173 } 174 void emit_constraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func) { 175 CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint(name, func)); 176 } 177 void emit_constraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func) { 178 CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uintx(name, func)); 179 } 180 void emit_constraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func) { 181 CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint64_t(name, func)); 182 } 183 void emit_constraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func) { 184 CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_size_t(name, func)); 185 } 186 void emit_constraint_double(const char* name, CommandLineFlagConstraintFunc_double func) { 187 CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_double(name, func)); 188 } 189 190 // Generate code to call emit_constraint_xxx function 191 #define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 192 #define EMIT_CONSTRAINT_COMMERCIAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 193 #define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 194 #define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 195 #define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 196 #define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 197 #define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc) ); emit_constraint_##type(#name 198 #define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 199 #define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc) ); emit_constraint_##type(#name 200 #define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 201 #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name 202 203 // Generate func argument to pass into emit_constraint_xxx functions 204 #define EMIT_CONSTRAINT_CHECK(func) , func 205 206 // the "name" argument must be a string literal 207 #define INITIAL_CONTRAINTS_SIZE 16 208 GrowableArray<CommandLineFlagConstraint*>* CommandLineFlagConstraintList::_constraints = NULL; 209 210 // Check the ranges of all flags that have them or print them out and exit if requested 211 void CommandLineFlagConstraintList::init(void) { 212 213 _constraints = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONTRAINTS_SIZE, true); 214 215 emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 216 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 217 EMIT_CONSTRAINT_PRODUCT_FLAG, 218 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 219 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 220 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 221 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 222 EMIT_CONSTRAINT_MANAGEABLE_FLAG, 223 EMIT_CONSTRAINT_PRODUCT_RW_FLAG, 224 EMIT_CONSTRAINT_LP64_PRODUCT_FLAG, 225 IGNORE_RANGE, 226 EMIT_CONSTRAINT_CHECK)); 227 228 EMIT_CONSTRAINTS_FOR_GLOBALS_EXT 229 230 emit_constraint_no(NULL ARCH_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 231 EMIT_CONSTRAINT_PRODUCT_FLAG, 232 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 233 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 234 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 235 IGNORE_RANGE, 236 EMIT_CONSTRAINT_CHECK)); 237 238 #ifdef COMPILER1 239 emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 240 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 241 EMIT_CONSTRAINT_PRODUCT_FLAG, 242 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 243 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 244 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 245 IGNORE_RANGE, 246 EMIT_CONSTRAINT_CHECK)); 247 #endif // COMPILER1 248 249 #ifdef COMPILER2 250 emit_constraint_no(NULL C2_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 251 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 252 EMIT_CONSTRAINT_PRODUCT_FLAG, 253 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 254 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 255 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 256 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 257 IGNORE_RANGE, 258 EMIT_CONSTRAINT_CHECK)); 259 #endif // COMPILER2 260 261 #ifndef INCLUDE_ALL_GCS 262 emit_constraint_no(NULL G1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG, 263 EMIT_CONSTRAINT_PD_DEVELOPER_FLAG, 264 EMIT_CONSTRAINT_PRODUCT_FLAG, 265 EMIT_CONSTRAINT_PD_PRODUCT_FLAG, 266 EMIT_CONSTRAINT_DIAGNOSTIC_FLAG, 267 EMIT_CONSTRAINT_EXPERIMENTAL_FLAG, 268 EMIT_CONSTRAINT_NOTPRODUCT_FLAG, 269 EMIT_CONSTRAINT_MANAGEABLE_FLAG, 270 EMIT_CONSTRAINT_PRODUCT_RW_FLAG, 271 IGNORE_RANGE, 272 EMIT_CONSTRAINT_CHECK)); 273 #endif // INCLUDE_ALL_GCS 274 } 275 276 CommandLineFlagConstraint* CommandLineFlagConstraintList::find(const char* name) { 277 CommandLineFlagConstraint* found = NULL; 278 for (int i=0; i<length(); i++) { 279 CommandLineFlagConstraint* constraint = at(i); 280 if (strcmp(constraint->name(), name) == 0) { 281 found = constraint; 282 break; 283 } 284 } 285 return found; 286 }