1 /* 2 * Copyright (c) 2015, 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 #include "precompiled.hpp" 26 #include "jvm.h" 27 #include "classfile/stringTable.hpp" 28 #include "classfile/symbolTable.hpp" 29 #include "gc/shared/referenceProcessor.hpp" 30 #include "oops/markWord.hpp" 31 #include "runtime/arguments.hpp" 32 #include "runtime/flags/jvmFlag.hpp" 33 #include "runtime/flags/jvmFlagConstraintList.hpp" 34 #include "runtime/flags/jvmFlagRangeList.hpp" 35 #include "runtime/globals.hpp" 36 #include "runtime/globals_extension.hpp" 37 #include "runtime/os.hpp" 38 #include "runtime/task.hpp" 39 #include "utilities/macros.hpp" 40 41 class JVMFlagRange_int : public JVMFlagRange { 42 int _min; 43 int _max; 44 45 public: 46 JVMFlagRange_int(const JVMFlag* flag, int min, int max) 47 : JVMFlagRange(flag), _min(min), _max(max) {} 48 49 JVMFlag::Error check(bool verbose = true) { 50 return check_int(_flag->get_int(), verbose); 51 } 52 53 JVMFlag::Error check_int(int value, bool verbose = true) { 54 if ((value < _min) || (value > _max)) { 55 JVMFlag::printError(verbose, 56 "int %s=%d is outside the allowed range " 57 "[ %d ... %d ]\n", 58 name(), value, _min, _max); 59 return JVMFlag::OUT_OF_BOUNDS; 60 } else { 61 return JVMFlag::SUCCESS; 62 } 63 } 64 65 void print(outputStream* st) { 66 st->print("[ %-25d ... %25d ]", _min, _max); 67 } 68 }; 69 70 class JVMFlagRange_intx : public JVMFlagRange { 71 intx _min; 72 intx _max; 73 74 public: 75 JVMFlagRange_intx(const JVMFlag* flag, intx min, intx max) 76 : JVMFlagRange(flag), _min(min), _max(max) {} 77 78 JVMFlag::Error check(bool verbose = true) { 79 return check_intx(_flag->get_intx(), verbose); 80 } 81 82 JVMFlag::Error check_intx(intx value, bool verbose = true) { 83 if ((value < _min) || (value > _max)) { 84 JVMFlag::printError(verbose, 85 "intx %s=" INTX_FORMAT " is outside the allowed range " 86 "[ " INTX_FORMAT " ... " INTX_FORMAT " ]\n", 87 name(), value, _min, _max); 88 return JVMFlag::OUT_OF_BOUNDS; 89 } else { 90 return JVMFlag::SUCCESS; 91 } 92 } 93 94 void print(outputStream* st) { 95 st->print("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", _min, _max); 96 } 97 }; 98 99 class JVMFlagRange_uint : public JVMFlagRange { 100 uint _min; 101 uint _max; 102 103 public: 104 JVMFlagRange_uint(const JVMFlag* flag, uint min, uint max) 105 : JVMFlagRange(flag), _min(min), _max(max) {} 106 107 JVMFlag::Error check(bool verbose = true) { 108 return check_uint(_flag->get_uint(), verbose); 109 } 110 111 JVMFlag::Error check_uint(uint value, bool verbose = true) { 112 if ((value < _min) || (value > _max)) { 113 JVMFlag::printError(verbose, 114 "uint %s=%u is outside the allowed range " 115 "[ %u ... %u ]\n", 116 name(), value, _min, _max); 117 return JVMFlag::OUT_OF_BOUNDS; 118 } else { 119 return JVMFlag::SUCCESS; 120 } 121 } 122 123 void print(outputStream* st) { 124 st->print("[ %-25u ... %25u ]", _min, _max); 125 } 126 }; 127 128 class JVMFlagRange_uintx : public JVMFlagRange { 129 uintx _min; 130 uintx _max; 131 132 public: 133 JVMFlagRange_uintx(const JVMFlag* flag, uintx min, uintx max) 134 : JVMFlagRange(flag), _min(min), _max(max) {} 135 136 JVMFlag::Error check(bool verbose = true) { 137 return check_uintx(_flag->get_uintx(), verbose); 138 } 139 140 JVMFlag::Error check_uintx(uintx value, bool verbose = true) { 141 if ((value < _min) || (value > _max)) { 142 JVMFlag::printError(verbose, 143 "uintx %s=" UINTX_FORMAT " is outside the allowed range " 144 "[ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n", 145 name(), value, _min, _max); 146 return JVMFlag::OUT_OF_BOUNDS; 147 } else { 148 return JVMFlag::SUCCESS; 149 } 150 } 151 152 void print(outputStream* st) { 153 st->print("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", _min, _max); 154 } 155 }; 156 157 class JVMFlagRange_uint64_t : public JVMFlagRange { 158 uint64_t _min; 159 uint64_t _max; 160 161 public: 162 JVMFlagRange_uint64_t(const JVMFlag* flag, uint64_t min, uint64_t max) 163 : JVMFlagRange(flag), _min(min), _max(max) {} 164 165 JVMFlag::Error check(bool verbose = true) { 166 return check_uint64_t(_flag->get_uintx(), verbose); 167 } 168 169 JVMFlag::Error check_uint64_t(uint64_t value, bool verbose = true) { 170 if ((value < _min) || (value > _max)) { 171 JVMFlag::printError(verbose, 172 "uint64_t %s=" UINT64_FORMAT " is outside the allowed range " 173 "[ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n", 174 name(), value, _min, _max); 175 return JVMFlag::OUT_OF_BOUNDS; 176 } else { 177 return JVMFlag::SUCCESS; 178 } 179 } 180 181 void print(outputStream* st) { 182 st->print("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", _min, _max); 183 } 184 }; 185 186 class JVMFlagRange_size_t : public JVMFlagRange { 187 size_t _min; 188 size_t _max; 189 190 public: 191 JVMFlagRange_size_t(const JVMFlag* flag, size_t min, size_t max) 192 : JVMFlagRange(flag), _min(min), _max(max) {} 193 194 JVMFlag::Error check(bool verbose = true) { 195 return check_size_t(_flag->get_size_t(), verbose); 196 } 197 198 JVMFlag::Error check_size_t(size_t value, bool verbose = true) { 199 if ((value < _min) || (value > _max)) { 200 JVMFlag::printError(verbose, 201 "size_t %s=" SIZE_FORMAT " is outside the allowed range " 202 "[ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n", 203 name(), value, _min, _max); 204 return JVMFlag::OUT_OF_BOUNDS; 205 } else { 206 return JVMFlag::SUCCESS; 207 } 208 } 209 210 void print(outputStream* st) { 211 st->print("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", _min, _max); 212 } 213 }; 214 215 class JVMFlagRange_double : public JVMFlagRange { 216 double _min; 217 double _max; 218 219 public: 220 JVMFlagRange_double(const JVMFlag* flag, double min, double max) 221 : JVMFlagRange(flag), _min(min), _max(max) {} 222 223 JVMFlag::Error check(bool verbose = true) { 224 return check_double(_flag->get_double(), verbose); 225 } 226 227 JVMFlag::Error check_double(double value, bool verbose = true) { 228 if ((value < _min) || (value > _max)) { 229 JVMFlag::printError(verbose, 230 "double %s=%f is outside the allowed range " 231 "[ %f ... %f ]\n", 232 name(), value, _min, _max); 233 return JVMFlag::OUT_OF_BOUNDS; 234 } else { 235 return JVMFlag::SUCCESS; 236 } 237 } 238 239 void print(outputStream* st) { 240 st->print("[ %-25.3f ... %25.3f ]", _min, _max); 241 } 242 }; 243 244 // No constraint emitting 245 void emit_range_no(...) { /* NOP */ } 246 247 // No constraint emitting if function argument is NOT provided 248 void emit_range_bool(const JVMFlag* /*flag*/) { /* NOP */ } 249 void emit_range_ccstr(const JVMFlag* /*flag*/) { /* NOP */ } 250 void emit_range_ccstrlist(const JVMFlag* /*flag*/) { /* NOP */ } 251 void emit_range_int(const JVMFlag* /*flag*/) { /* NOP */ } 252 void emit_range_intx(const JVMFlag* /*flag*/) { /* NOP */ } 253 void emit_range_uint(const JVMFlag* /*flag*/) { /* NOP */ } 254 void emit_range_uintx(const JVMFlag* /*flag*/) { /* NOP */ } 255 void emit_range_uint64_t(const JVMFlag* /*flag*/) { /* NOP */ } 256 void emit_range_size_t(const JVMFlag* /*flag*/) { /* NOP */ } 257 void emit_range_double(const JVMFlag* /*flag*/) { /* NOP */ } 258 259 // JVMFlagRange emitting code functions if range arguments are provided 260 void emit_range_int(const JVMFlag* flag, int min, int max) { 261 JVMFlagRangeList::add(new JVMFlagRange_int(flag, min, max)); 262 } 263 void emit_range_intx(const JVMFlag* flag, intx min, intx max) { 264 JVMFlagRangeList::add(new JVMFlagRange_intx(flag, min, max)); 265 } 266 void emit_range_uint(const JVMFlag* flag, uint min, uint max) { 267 JVMFlagRangeList::add(new JVMFlagRange_uint(flag, min, max)); 268 } 269 void emit_range_uintx(const JVMFlag* flag, uintx min, uintx max) { 270 JVMFlagRangeList::add(new JVMFlagRange_uintx(flag, min, max)); 271 } 272 void emit_range_uint64_t(const JVMFlag* flag, uint64_t min, uint64_t max) { 273 JVMFlagRangeList::add(new JVMFlagRange_uint64_t(flag, min, max)); 274 } 275 void emit_range_size_t(const JVMFlag* flag, size_t min, size_t max) { 276 JVMFlagRangeList::add(new JVMFlagRange_size_t(flag, min, max)); 277 } 278 void emit_range_double(const JVMFlag* flag, double min, double max) { 279 JVMFlagRangeList::add(new JVMFlagRange_double(flag, min, max)); 280 } 281 282 // Generate code to call emit_range_xxx function 283 #define EMIT_RANGE_START (void)(0 284 #define EMIT_RANGE(type, name) ); emit_range_##type(JVMFlagEx::flag_from_enum(FLAG_MEMBER_ENUM(name)) 285 #define EMIT_RANGE_NO ); emit_range_no(0 286 #define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc) EMIT_RANGE(type, name) 287 #define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc) EMIT_RANGE(type, name) 288 #define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) EMIT_RANGE(type, name) 289 #define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc) EMIT_RANGE(type, name) 290 #define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc) EMIT_RANGE(type, name) 291 #define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc) EMIT_RANGE(type, name) 292 #define EMIT_RANGE_PD_DIAGNOSTIC_FLAG(type, name, doc) EMIT_RANGE(type, name) 293 #ifndef PRODUCT 294 #define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc) EMIT_RANGE(type, name) 295 #define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc) EMIT_RANGE(type, name) 296 #define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc) EMIT_RANGE(type, name) 297 #else 298 #define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc) EMIT_RANGE_NO 299 #define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc) EMIT_RANGE_NO 300 #define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc) EMIT_RANGE_NO 301 #endif 302 #ifdef _LP64 303 #define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_RANGE(type, name) 304 #else 305 #define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_RANGE_NO 306 #endif 307 #define EMIT_RANGE_END ); 308 309 // Generate func argument to pass into emit_range_xxx functions 310 #define EMIT_RANGE_CHECK(a, b) , a, b 311 312 #define INITIAL_RANGES_SIZE 379 313 GrowableArray<JVMFlagRange*>* JVMFlagRangeList::_ranges = NULL; 314 315 // Check the ranges of all flags that have them 316 void JVMFlagRangeList::init(void) { 317 318 _ranges = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagRange*>(INITIAL_RANGES_SIZE, true); 319 320 EMIT_RANGE_START 321 322 ALL_FLAGS(EMIT_RANGE_DEVELOPER_FLAG, 323 EMIT_RANGE_PD_DEVELOPER_FLAG, 324 EMIT_RANGE_PRODUCT_FLAG, 325 EMIT_RANGE_PD_PRODUCT_FLAG, 326 EMIT_RANGE_DIAGNOSTIC_FLAG, 327 EMIT_RANGE_PD_DIAGNOSTIC_FLAG, 328 EMIT_RANGE_EXPERIMENTAL_FLAG, 329 EMIT_RANGE_NOTPRODUCT_FLAG, 330 EMIT_RANGE_MANAGEABLE_FLAG, 331 EMIT_RANGE_PRODUCT_RW_FLAG, 332 EMIT_RANGE_LP64_PRODUCT_FLAG, 333 EMIT_RANGE_CHECK, 334 IGNORE_CONSTRAINT) 335 336 EMIT_RANGE_END 337 } 338 339 JVMFlagRange* JVMFlagRangeList::find(const JVMFlag* flag) { 340 JVMFlagRange* found = NULL; 341 for (int i=0; i<length(); i++) { 342 JVMFlagRange* range = at(i); 343 if (range->flag() == flag) { 344 found = range; 345 break; 346 } 347 } 348 return found; 349 } 350 351 void JVMFlagRangeList::print(outputStream* st, const JVMFlag* flag, RangeStrFunc default_range_str_func) { 352 JVMFlagRange* range = JVMFlagRangeList::find(flag); 353 if (range != NULL) { 354 range->print(st); 355 } else { 356 JVMFlagConstraint* constraint = JVMFlagConstraintList::find(flag); 357 if (constraint != NULL) { 358 assert(default_range_str_func!=NULL, "default_range_str_func must be provided"); 359 st->print("%s", default_range_str_func()); 360 } else { 361 st->print("[ ... ]"); 362 } 363 } 364 } 365 366 bool JVMFlagRangeList::check_ranges() { 367 bool status = true; 368 for (int i=0; i<length(); i++) { 369 JVMFlagRange* range = at(i); 370 if (range->check(true) != JVMFlag::SUCCESS) status = false; 371 } 372 return status; 373 }