1 /* 2 * Copyright (c) 1997, 2013, 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 "memory/allocation.inline.hpp" 27 #include "oops/oop.inline.hpp" 28 #include "runtime/arguments.hpp" 29 #include "runtime/globals.hpp" 30 #include "runtime/globals_extension.hpp" 31 #include "utilities/ostream.hpp" 32 #include "utilities/macros.hpp" 33 #include "utilities/top.hpp" 34 #if INCLUDE_ALL_GCS 35 #include "gc_implementation/g1/g1_globals.hpp" 36 #endif // INCLUDE_ALL_GCS 37 #ifdef COMPILER1 38 #include "c1/c1_globals.hpp" 39 #endif 40 #ifdef COMPILER2 41 #include "opto/c2_globals.hpp" 42 #endif 43 #ifdef SHARK 44 #include "shark/shark_globals.hpp" 45 #endif 46 47 RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \ 48 MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \ 49 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \ 50 MATERIALIZE_NOTPRODUCT_FLAG, \ 51 MATERIALIZE_MANAGEABLE_FLAG, MATERIALIZE_PRODUCT_RW_FLAG, \ 52 MATERIALIZE_LP64_PRODUCT_FLAG) 53 54 RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \ 55 MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \ 56 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG) 57 58 ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, \ 59 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \ 60 MATERIALIZE_NOTPRODUCT_FLAG) 61 62 MATERIALIZE_FLAGS_EXT 63 64 65 bool Flag::is_unlocker() const { 66 return strcmp(name, "UnlockDiagnosticVMOptions") == 0 || 67 strcmp(name, "UnlockExperimentalVMOptions") == 0 || 68 is_unlocker_ext(); 69 } 70 71 bool Flag::is_unlocked() const { 72 if (strcmp(kind, "{diagnostic}") == 0 || 73 strcmp(kind, "{C2 diagnostic}") == 0 || 74 strcmp(kind, "{ARCH diagnostic}") == 0 || 75 strcmp(kind, "{Shark diagnostic}") == 0) { 76 return UnlockDiagnosticVMOptions; 77 } else if (strcmp(kind, "{experimental}") == 0 || 78 strcmp(kind, "{C2 experimental}") == 0 || 79 strcmp(kind, "{ARCH experimental}") == 0 || 80 strcmp(kind, "{Shark experimental}") == 0) { 81 return UnlockExperimentalVMOptions; 82 } else { 83 return is_unlocked_ext(); 84 } 85 } 86 87 // Get custom message for this locked flag, or return NULL if 88 // none is available. 89 void Flag::get_locked_message(char* buf, int buflen) const { 90 get_locked_message_ext(buf, buflen); 91 } 92 93 bool Flag::is_writeable() const { 94 return strcmp(kind, "{manageable}") == 0 || 95 strcmp(kind, "{product rw}") == 0 || 96 is_writeable_ext(); 97 } 98 99 // All flags except "manageable" are assumed to be internal flags. 100 // Long term, we need to define a mechanism to specify which flags 101 // are external/stable and change this function accordingly. 102 bool Flag::is_external() const { 103 return strcmp(kind, "{manageable}") == 0 || is_external_ext(); 104 } 105 106 107 // Length of format string (e.g. "%.1234s") for printing ccstr below 108 #define FORMAT_BUFFER_LEN 16 109 110 void Flag::print_on(outputStream* st, bool withComments) { 111 st->print("%9s %-40s %c= ", type, name, (origin != DEFAULT ? ':' : ' ')); 112 if (is_bool()) st->print("%-16s", get_bool() ? "true" : "false"); 113 if (is_intx()) st->print("%-16ld", get_intx()); 114 if (is_uintx()) st->print("%-16lu", get_uintx()); 115 if (is_uint64_t()) st->print("%-16lu", get_uint64_t()); 116 if (is_double()) st->print("%-16f", get_double()); 117 118 if (is_ccstr()) { 119 const char* cp = get_ccstr(); 120 if (cp != NULL) { 121 const char* eol; 122 while ((eol = strchr(cp, '\n')) != NULL) { 123 char format_buffer[FORMAT_BUFFER_LEN]; 124 size_t llen = pointer_delta(eol, cp, sizeof(char)); 125 jio_snprintf(format_buffer, FORMAT_BUFFER_LEN, 126 "%%." SIZE_FORMAT "s", llen); 127 st->print(format_buffer, cp); 128 st->cr(); 129 cp = eol+1; 130 st->print("%5s %-35s += ", "", name); 131 } 132 st->print("%-16s", cp); 133 } 134 else st->print("%-16s", ""); 135 } 136 st->print("%-20s", kind); 137 if (withComments) { 138 #ifndef PRODUCT 139 st->print("%s", doc ); 140 #endif 141 } 142 st->cr(); 143 } 144 145 void Flag::print_as_flag(outputStream* st) { 146 if (is_bool()) { 147 st->print("-XX:%s%s", get_bool() ? "+" : "-", name); 148 } else if (is_intx()) { 149 st->print("-XX:%s=" INTX_FORMAT, name, get_intx()); 150 } else if (is_uintx()) { 151 st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx()); 152 } else if (is_uint64_t()) { 153 st->print("-XX:%s=" UINT64_FORMAT, name, get_uint64_t()); 154 } else if (is_double()) { 155 st->print("-XX:%s=%f", name, get_double()); 156 } else if (is_ccstr()) { 157 st->print("-XX:%s=", name); 158 const char* cp = get_ccstr(); 159 if (cp != NULL) { 160 // Need to turn embedded '\n's back into separate arguments 161 // Not so efficient to print one character at a time, 162 // but the choice is to do the transformation to a buffer 163 // and print that. And this need not be efficient. 164 for (; *cp != '\0'; cp += 1) { 165 switch (*cp) { 166 default: 167 st->print("%c", *cp); 168 break; 169 case '\n': 170 st->print(" -XX:%s=", name); 171 break; 172 } 173 } 174 } 175 } else { 176 ShouldNotReachHere(); 177 } 178 } 179 180 // 4991491 do not "optimize out" the was_set false values: omitting them 181 // tickles a Microsoft compiler bug causing flagTable to be malformed 182 183 #define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product}", DEFAULT }, 184 #define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{pd product}", DEFAULT }, 185 #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{diagnostic}", DEFAULT }, 186 #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{experimental}", DEFAULT }, 187 #define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{manageable}", DEFAULT }, 188 #define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{product rw}", DEFAULT }, 189 190 #ifdef PRODUCT 191 #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 192 #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ 193 #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) 194 #else 195 #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "", DEFAULT }, 196 #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{pd}", DEFAULT }, 197 #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{notproduct}", DEFAULT }, 198 #endif 199 200 #ifdef _LP64 201 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{lp64_product}", DEFAULT }, 202 #else 203 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 204 #endif // _LP64 205 206 #define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 product}", DEFAULT }, 207 #define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 pd product}", DEFAULT }, 208 #define C1_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C1 diagnostic}", DEFAULT }, 209 #ifdef PRODUCT 210 #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 211 #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ 212 #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) 213 #else 214 #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1}", DEFAULT }, 215 #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{C1 pd}", DEFAULT }, 216 #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1 notproduct}", DEFAULT }, 217 #endif 218 219 #define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 product}", DEFAULT }, 220 #define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 pd product}", DEFAULT }, 221 #define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 diagnostic}", DEFAULT }, 222 #define C2_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 experimental}", DEFAULT }, 223 #ifdef PRODUCT 224 #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 225 #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ 226 #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) 227 #else 228 #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2}", DEFAULT }, 229 #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{C2 pd}", DEFAULT }, 230 #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2 notproduct}", DEFAULT }, 231 #endif 232 233 #define ARCH_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH product}", DEFAULT }, 234 #define ARCH_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH diagnostic}", DEFAULT }, 235 #define ARCH_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH experimental}", DEFAULT }, 236 #ifdef PRODUCT 237 #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 238 #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) 239 #else 240 #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH}", DEFAULT }, 241 #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH notproduct}", DEFAULT }, 242 #endif 243 244 #define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark product}", DEFAULT }, 245 #define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark pd product}", DEFAULT }, 246 #define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark diagnostic}", DEFAULT }, 247 #ifdef PRODUCT 248 #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 249 #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ 250 #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) 251 #else 252 #define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark}", DEFAULT }, 253 #define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, doc, "{Shark pd}", DEFAULT }, 254 #define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{Shark notproduct}", DEFAULT }, 255 #endif 256 257 static Flag flagTable[] = { 258 RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT) 259 RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT) 260 #if INCLUDE_ALL_GCS 261 G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT) 262 #endif // INCLUDE_ALL_GCS 263 #ifdef COMPILER1 264 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_DIAGNOSTIC_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT) 265 #endif 266 #ifdef COMPILER2 267 C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT) 268 #endif 269 #ifdef SHARK 270 SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, SHARK_PD_DEVELOP_FLAG_STRUCT, SHARK_PRODUCT_FLAG_STRUCT, SHARK_PD_PRODUCT_FLAG_STRUCT, SHARK_DIAGNOSTIC_FLAG_STRUCT, SHARK_NOTPRODUCT_FLAG_STRUCT) 271 #endif 272 ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, ARCH_PRODUCT_FLAG_STRUCT, ARCH_DIAGNOSTIC_FLAG_STRUCT, ARCH_EXPERIMENTAL_FLAG_STRUCT, ARCH_NOTPRODUCT_FLAG_STRUCT) 273 FLAGTABLE_EXT 274 {0, NULL, NULL} 275 }; 276 277 Flag* Flag::flags = flagTable; 278 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag)); 279 280 inline bool str_equal(const char* s, const char* q, size_t len) { 281 // s is null terminated, q is not! 282 if (strlen(s) != (unsigned int) len) return false; 283 return strncmp(s, q, len) == 0; 284 } 285 286 // Search the flag table for a named flag 287 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked) { 288 for (Flag* current = &flagTable[0]; current->name != NULL; current++) { 289 if (str_equal(current->name, name, length)) { 290 // Found a matching entry. Report locked flags only if allowed. 291 if (!(current->is_unlocked() || current->is_unlocker())) { 292 if (!allow_locked) { 293 // disable use of locked flags, e.g. diagnostic, experimental, 294 // commercial... until they are explicitly unlocked 295 return NULL; 296 } 297 } 298 return current; 299 } 300 } 301 // Flag name is not in the flag table 302 return NULL; 303 } 304 305 // Compute string similarity based on Dice's coefficient 306 static float str_similar(const char* str1, const char* str2, size_t len2) { 307 int len1 = (int) strlen(str1); 308 int total = len1 + (int) len2; 309 310 int hit = 0; 311 312 for (int i = 0; i < len1 -1; ++i) { 313 for (int j = 0; j < (int) len2 -1; ++j) { 314 if ((str1[i] == str2[j]) && (str1[i+1] == str2[j+1])) { 315 ++hit; 316 break; 317 } 318 } 319 } 320 321 return 2.0f * (float) hit / (float) total; 322 } 323 324 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) { 325 float VMOptionsFuzzyMatchSimilarity = 0.7f; 326 Flag* match = NULL; 327 float score; 328 float max_score = -1; 329 330 for (Flag* current = &flagTable[0]; current->name != NULL; current++) { 331 score = str_similar(current->name, name, length); 332 if (score > max_score) { 333 max_score = score; 334 match = current; 335 } 336 } 337 338 if (!(match->is_unlocked() || match->is_unlocker())) { 339 if (!allow_locked) { 340 return NULL; 341 } 342 } 343 344 if (max_score < VMOptionsFuzzyMatchSimilarity) { 345 return NULL; 346 } 347 348 return match; 349 } 350 351 // Returns the address of the index'th element 352 static Flag* address_of_flag(CommandLineFlagWithType flag) { 353 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 354 return &Flag::flags[flag]; 355 } 356 357 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) { 358 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 359 Flag* f = &Flag::flags[flag]; 360 return (f->origin == DEFAULT); 361 } 362 363 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) { 364 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 365 Flag* f = &Flag::flags[flag]; 366 return (f->origin == ERGONOMIC); 367 } 368 369 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) { 370 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 371 Flag* f = &Flag::flags[flag]; 372 return (f->origin == COMMAND_LINE); 373 } 374 375 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) { 376 Flag* result = Flag::find_flag((char*)name, strlen(name)); 377 if (result == NULL) return false; 378 *value = (result->origin == COMMAND_LINE); 379 return true; 380 } 381 382 bool CommandLineFlags::boolAt(char* name, size_t len, bool* value) { 383 Flag* result = Flag::find_flag(name, len); 384 if (result == NULL) return false; 385 if (!result->is_bool()) return false; 386 *value = result->get_bool(); 387 return true; 388 } 389 390 bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin) { 391 Flag* result = Flag::find_flag(name, len); 392 if (result == NULL) return false; 393 if (!result->is_bool()) return false; 394 bool old_value = result->get_bool(); 395 result->set_bool(*value); 396 *value = old_value; 397 result->origin = origin; 398 return true; 399 } 400 401 void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin) { 402 Flag* faddr = address_of_flag(flag); 403 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type"); 404 faddr->set_bool(value); 405 faddr->origin = origin; 406 } 407 408 bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) { 409 Flag* result = Flag::find_flag(name, len); 410 if (result == NULL) return false; 411 if (!result->is_intx()) return false; 412 *value = result->get_intx(); 413 return true; 414 } 415 416 bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin) { 417 Flag* result = Flag::find_flag(name, len); 418 if (result == NULL) return false; 419 if (!result->is_intx()) return false; 420 intx old_value = result->get_intx(); 421 result->set_intx(*value); 422 *value = old_value; 423 result->origin = origin; 424 return true; 425 } 426 427 void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin) { 428 Flag* faddr = address_of_flag(flag); 429 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type"); 430 faddr->set_intx(value); 431 faddr->origin = origin; 432 } 433 434 bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) { 435 Flag* result = Flag::find_flag(name, len); 436 if (result == NULL) return false; 437 if (!result->is_uintx()) return false; 438 *value = result->get_uintx(); 439 return true; 440 } 441 442 bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin) { 443 Flag* result = Flag::find_flag(name, len); 444 if (result == NULL) return false; 445 if (!result->is_uintx()) return false; 446 uintx old_value = result->get_uintx(); 447 result->set_uintx(*value); 448 *value = old_value; 449 result->origin = origin; 450 return true; 451 } 452 453 void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin) { 454 Flag* faddr = address_of_flag(flag); 455 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type"); 456 faddr->set_uintx(value); 457 faddr->origin = origin; 458 } 459 460 bool CommandLineFlags::uint64_tAt(char* name, size_t len, uint64_t* value) { 461 Flag* result = Flag::find_flag(name, len); 462 if (result == NULL) return false; 463 if (!result->is_uint64_t()) return false; 464 *value = result->get_uint64_t(); 465 return true; 466 } 467 468 bool CommandLineFlags::uint64_tAtPut(char* name, size_t len, uint64_t* value, FlagValueOrigin origin) { 469 Flag* result = Flag::find_flag(name, len); 470 if (result == NULL) return false; 471 if (!result->is_uint64_t()) return false; 472 uint64_t old_value = result->get_uint64_t(); 473 result->set_uint64_t(*value); 474 *value = old_value; 475 result->origin = origin; 476 return true; 477 } 478 479 void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, FlagValueOrigin origin) { 480 Flag* faddr = address_of_flag(flag); 481 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type"); 482 faddr->set_uint64_t(value); 483 faddr->origin = origin; 484 } 485 486 bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) { 487 Flag* result = Flag::find_flag(name, len); 488 if (result == NULL) return false; 489 if (!result->is_double()) return false; 490 *value = result->get_double(); 491 return true; 492 } 493 494 bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin) { 495 Flag* result = Flag::find_flag(name, len); 496 if (result == NULL) return false; 497 if (!result->is_double()) return false; 498 double old_value = result->get_double(); 499 result->set_double(*value); 500 *value = old_value; 501 result->origin = origin; 502 return true; 503 } 504 505 void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin) { 506 Flag* faddr = address_of_flag(flag); 507 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); 508 faddr->set_double(value); 509 faddr->origin = origin; 510 } 511 512 bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) { 513 Flag* result = Flag::find_flag(name, len); 514 if (result == NULL) return false; 515 if (!result->is_ccstr()) return false; 516 *value = result->get_ccstr(); 517 return true; 518 } 519 520 // Contract: Flag will make private copy of the incoming value. 521 // Outgoing value is always malloc-ed, and caller MUST call free. 522 bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin) { 523 Flag* result = Flag::find_flag(name, len); 524 if (result == NULL) return false; 525 if (!result->is_ccstr()) return false; 526 ccstr old_value = result->get_ccstr(); 527 char* new_value = NULL; 528 if (*value != NULL) { 529 new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1, mtInternal); 530 strcpy(new_value, *value); 531 } 532 result->set_ccstr(new_value); 533 if (result->origin == DEFAULT && old_value != NULL) { 534 // Prior value is NOT heap allocated, but was a literal constant. 535 char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal); 536 strcpy(old_value_to_free, old_value); 537 old_value = old_value_to_free; 538 } 539 *value = old_value; 540 result->origin = origin; 541 return true; 542 } 543 544 // Contract: Flag will make private copy of the incoming value. 545 void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin) { 546 Flag* faddr = address_of_flag(flag); 547 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type"); 548 ccstr old_value = faddr->get_ccstr(); 549 char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal); 550 strcpy(new_value, value); 551 faddr->set_ccstr(new_value); 552 if (faddr->origin != DEFAULT && old_value != NULL) { 553 // Prior value is heap allocated so free it. 554 FREE_C_HEAP_ARRAY(char, old_value, mtInternal); 555 } 556 faddr->origin = origin; 557 } 558 559 extern "C" { 560 static int compare_flags(const void* void_a, const void* void_b) { 561 return strcmp((*((Flag**) void_a))->name, (*((Flag**) void_b))->name); 562 } 563 } 564 565 void CommandLineFlags::printSetFlags(outputStream* out) { 566 // Print which flags were set on the command line 567 // note: this method is called before the thread structure is in place 568 // which means resource allocation cannot be used. 569 570 // Compute size 571 int length= 0; 572 while (flagTable[length].name != NULL) length++; 573 574 // Sort 575 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal); 576 for (int index = 0; index < length; index++) { 577 array[index] = &flagTable[index]; 578 } 579 qsort(array, length, sizeof(Flag*), compare_flags); 580 581 // Print 582 for (int i = 0; i < length; i++) { 583 if (array[i]->origin /* naked field! */) { 584 array[i]->print_as_flag(out); 585 out->print(" "); 586 } 587 } 588 out->cr(); 589 FREE_C_HEAP_ARRAY(Flag*, array, mtInternal); 590 } 591 592 #ifndef PRODUCT 593 594 595 void CommandLineFlags::verify() { 596 assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict"); 597 } 598 599 #endif // PRODUCT 600 601 void CommandLineFlags::printFlags(outputStream* out, bool withComments) { 602 // Print the flags sorted by name 603 // note: this method is called before the thread structure is in place 604 // which means resource allocation cannot be used. 605 606 // Compute size 607 int length= 0; 608 while (flagTable[length].name != NULL) length++; 609 610 // Sort 611 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal); 612 for (int index = 0; index < length; index++) { 613 array[index] = &flagTable[index]; 614 } 615 qsort(array, length, sizeof(Flag*), compare_flags); 616 617 // Print 618 out->print_cr("[Global flags]"); 619 for (int i = 0; i < length; i++) { 620 if (array[i]->is_unlocked()) { 621 array[i]->print_on(out, withComments); 622 } 623 } 624 FREE_C_HEAP_ARRAY(Flag*, array, mtInternal); 625 }