globals.cpp revision 196:d1605aabd0a1
1/* 2 * Copyright 1997-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25# include "incls/_precompiled.incl" 26# include "incls/_globals.cpp.incl" 27 28 29RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \ 30 MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \ 31 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG, \ 32 MATERIALIZE_MANAGEABLE_FLAG, MATERIALIZE_PRODUCT_RW_FLAG, \ 33 MATERIALIZE_LP64_PRODUCT_FLAG) 34 35RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \ 36 MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \ 37 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG) 38 39bool Flag::is_unlocker() const { 40 return strcmp(name, "UnlockDiagnosticVMOptions") == 0; 41} 42 43bool Flag::is_unlocked() const { 44 if (strcmp(kind, "{diagnostic}") == 0) { 45 return UnlockDiagnosticVMOptions; 46 } else { 47 return true; 48 } 49} 50 51bool Flag::is_writeable() const { 52 return (strcmp(kind, "{manageable}") == 0 || strcmp(kind, "{product rw}") == 0); 53} 54 55// All flags except "manageable" are assumed internal flags. 56// Long term, we need to define a mechanism to specify which flags 57// are external/stable and change this function accordingly. 58bool Flag::is_external() const { 59 return (strcmp(kind, "{manageable}") == 0); 60} 61 62// Length of format string (e.g. "%.1234s") for printing ccstr below 63#define FORMAT_BUFFER_LEN 16 64 65void Flag::print_on(outputStream* st) { 66 st->print("%5s %-35s %c= ", type, name, (origin != DEFAULT ? ':' : ' ')); 67 if (is_bool()) st->print("%-16s", get_bool() ? "true" : "false"); 68 if (is_intx()) st->print("%-16ld", get_intx()); 69 if (is_uintx()) st->print("%-16lu", get_uintx()); 70 if (is_ccstr()) { 71 const char* cp = get_ccstr(); 72 if (cp != NULL) { 73 const char* eol; 74 while ((eol = strchr(cp, '\n')) != NULL) { 75 char format_buffer[FORMAT_BUFFER_LEN]; 76 size_t llen = pointer_delta(eol, cp, sizeof(char)); 77 jio_snprintf(format_buffer, FORMAT_BUFFER_LEN, 78 "%%." SIZE_FORMAT "s", llen); 79 st->print(format_buffer, cp); 80 st->cr(); 81 cp = eol+1; 82 st->print("%5s %-35s += ", "", name); 83 } 84 st->print("%-16s", cp); 85 } 86 } 87 st->print(" %s", kind); 88 st->cr(); 89} 90 91void Flag::print_as_flag(outputStream* st) { 92 if (is_bool()) { 93 st->print("-XX:%s%s", get_bool() ? "+" : "-", name); 94 } else if (is_intx()) { 95 st->print("-XX:%s=" INTX_FORMAT, name, get_intx()); 96 } else if (is_uintx()) { 97 st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx()); 98 } else if (is_ccstr()) { 99 st->print("-XX:%s=", name); 100 const char* cp = get_ccstr(); 101 if (cp != NULL) { 102 // Need to turn embedded '\n's back into separate arguments 103 // Not so efficient to print one character at a time, 104 // but the choice is to do the transformation to a buffer 105 // and print that. And this need not be efficient. 106 for (; *cp != '\0'; cp += 1) { 107 switch (*cp) { 108 default: 109 st->print("%c", *cp); 110 break; 111 case '\n': 112 st->print(" -XX:%s=", name); 113 break; 114 } 115 } 116 } 117 } else { 118 ShouldNotReachHere(); 119 } 120} 121 122// 4991491 do not "optimize out" the was_set false values: omitting them 123// tickles a Microsoft compiler bug causing flagTable to be malformed 124 125#define RUNTIME_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{product}", DEFAULT }, 126#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{pd product}", DEFAULT }, 127#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{diagnostic}", DEFAULT }, 128#define RUNTIME_MANAGEABLE_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{manageable}", DEFAULT }, 129#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{product rw}", DEFAULT }, 130 131#ifdef PRODUCT 132 #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 133 #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ 134 #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) 135#else 136 #define RUNTIME_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "", DEFAULT }, 137 #define RUNTIME_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{pd}", DEFAULT }, 138 #define RUNTIME_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{notproduct}", DEFAULT }, 139#endif 140 141#ifdef _LP64 142 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{lp64_product}", DEFAULT }, 143#else 144 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 145#endif // _LP64 146 147#define C1_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1 product}", DEFAULT }, 148#define C1_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{C1 pd product}", DEFAULT }, 149#ifdef PRODUCT 150 #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 151 #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ 152 #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) 153#else 154 #define C1_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1}", DEFAULT }, 155 #define C1_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{C1 pd}", DEFAULT }, 156 #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C1 notproduct}", DEFAULT }, 157#endif 158 159 160#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 product}", DEFAULT }, 161#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{C2 pd product}", DEFAULT }, 162#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 diagnostic}", DEFAULT }, 163#ifdef PRODUCT 164 #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ 165 #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */ 166 #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) 167#else 168 #define C2_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2}", DEFAULT }, 169 #define C2_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{C2 pd}", DEFAULT }, 170 #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 notproduct}", DEFAULT }, 171#endif 172 173 174static Flag flagTable[] = { 175 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_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT) 176 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) 177#ifdef COMPILER1 178 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT) 179#endif 180#ifdef COMPILER2 181 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_NOTPRODUCT_FLAG_STRUCT) 182#endif 183 {0, NULL, NULL} 184}; 185 186Flag* Flag::flags = flagTable; 187size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag)); 188 189inline bool str_equal(const char* s, char* q, size_t len) { 190 // s is null terminated, q is not! 191 if (strlen(s) != (unsigned int) len) return false; 192 return strncmp(s, q, len) == 0; 193} 194 195Flag* Flag::find_flag(char* name, size_t length) { 196 for (Flag* current = &flagTable[0]; current->name; current++) { 197 if (str_equal(current->name, name, length)) { 198 if (!(current->is_unlocked() || current->is_unlocker())) { 199 // disable use of diagnostic flags until they are unlocked 200 return NULL; 201 } 202 return current; 203 } 204 } 205 return NULL; 206} 207 208// Returns the address of the index'th element 209static Flag* address_of_flag(CommandLineFlagWithType flag) { 210 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 211 return &Flag::flags[flag]; 212} 213 214bool CommandLineFlagsEx::is_default(CommandLineFlag flag) { 215 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 216 Flag* f = &Flag::flags[flag]; 217 return (f->origin == DEFAULT); 218} 219 220bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) { 221 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 222 Flag* f = &Flag::flags[flag]; 223 return (f->origin == ERGONOMIC); 224} 225 226bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) { 227 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); 228 Flag* f = &Flag::flags[flag]; 229 return (f->origin == COMMAND_LINE); 230} 231 232bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) { 233 Flag* result = Flag::find_flag((char*)name, strlen(name)); 234 if (result == NULL) return false; 235 *value = (result->origin == COMMAND_LINE); 236 return true; 237} 238 239bool CommandLineFlags::boolAt(char* name, size_t len, bool* value) { 240 Flag* result = Flag::find_flag(name, len); 241 if (result == NULL) return false; 242 if (!result->is_bool()) return false; 243 *value = result->get_bool(); 244 return true; 245} 246 247bool CommandLineFlags::boolAtPut(char* name, size_t len, bool* value, FlagValueOrigin origin) { 248 Flag* result = Flag::find_flag(name, len); 249 if (result == NULL) return false; 250 if (!result->is_bool()) return false; 251 bool old_value = result->get_bool(); 252 result->set_bool(*value); 253 *value = old_value; 254 result->origin = origin; 255 return true; 256} 257 258void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, FlagValueOrigin origin) { 259 Flag* faddr = address_of_flag(flag); 260 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type"); 261 faddr->set_bool(value); 262 faddr->origin = origin; 263} 264 265bool CommandLineFlags::intxAt(char* name, size_t len, intx* value) { 266 Flag* result = Flag::find_flag(name, len); 267 if (result == NULL) return false; 268 if (!result->is_intx()) return false; 269 *value = result->get_intx(); 270 return true; 271} 272 273bool CommandLineFlags::intxAtPut(char* name, size_t len, intx* value, FlagValueOrigin origin) { 274 Flag* result = Flag::find_flag(name, len); 275 if (result == NULL) return false; 276 if (!result->is_intx()) return false; 277 intx old_value = result->get_intx(); 278 result->set_intx(*value); 279 *value = old_value; 280 result->origin = origin; 281 return true; 282} 283 284void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, FlagValueOrigin origin) { 285 Flag* faddr = address_of_flag(flag); 286 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type"); 287 faddr->set_intx(value); 288 faddr->origin = origin; 289} 290 291bool CommandLineFlags::uintxAt(char* name, size_t len, uintx* value) { 292 Flag* result = Flag::find_flag(name, len); 293 if (result == NULL) return false; 294 if (!result->is_uintx()) return false; 295 *value = result->get_uintx(); 296 return true; 297} 298 299bool CommandLineFlags::uintxAtPut(char* name, size_t len, uintx* value, FlagValueOrigin origin) { 300 Flag* result = Flag::find_flag(name, len); 301 if (result == NULL) return false; 302 if (!result->is_uintx()) return false; 303 uintx old_value = result->get_uintx(); 304 result->set_uintx(*value); 305 *value = old_value; 306 result->origin = origin; 307 return true; 308} 309 310void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, FlagValueOrigin origin) { 311 Flag* faddr = address_of_flag(flag); 312 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type"); 313 faddr->set_uintx(value); 314 faddr->origin = origin; 315} 316 317bool CommandLineFlags::doubleAt(char* name, size_t len, double* value) { 318 Flag* result = Flag::find_flag(name, len); 319 if (result == NULL) return false; 320 if (!result->is_double()) return false; 321 *value = result->get_double(); 322 return true; 323} 324 325bool CommandLineFlags::doubleAtPut(char* name, size_t len, double* value, FlagValueOrigin origin) { 326 Flag* result = Flag::find_flag(name, len); 327 if (result == NULL) return false; 328 if (!result->is_double()) return false; 329 double old_value = result->get_double(); 330 result->set_double(*value); 331 *value = old_value; 332 result->origin = origin; 333 return true; 334} 335 336void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, FlagValueOrigin origin) { 337 Flag* faddr = address_of_flag(flag); 338 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); 339 faddr->set_double(value); 340 faddr->origin = origin; 341} 342 343bool CommandLineFlags::ccstrAt(char* name, size_t len, ccstr* value) { 344 Flag* result = Flag::find_flag(name, len); 345 if (result == NULL) return false; 346 if (!result->is_ccstr()) return false; 347 *value = result->get_ccstr(); 348 return true; 349} 350 351// Contract: Flag will make private copy of the incoming value. 352// Outgoing value is always malloc-ed, and caller MUST call free. 353bool CommandLineFlags::ccstrAtPut(char* name, size_t len, ccstr* value, FlagValueOrigin origin) { 354 Flag* result = Flag::find_flag(name, len); 355 if (result == NULL) return false; 356 if (!result->is_ccstr()) return false; 357 ccstr old_value = result->get_ccstr(); 358 char* new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1); 359 strcpy(new_value, *value); 360 result->set_ccstr(new_value); 361 if (result->origin == DEFAULT && old_value != NULL) { 362 // Prior value is NOT heap allocated, but was a literal constant. 363 char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1); 364 strcpy(old_value_to_free, old_value); 365 old_value = old_value_to_free; 366 } 367 *value = old_value; 368 result->origin = origin; 369 return true; 370} 371 372// Contract: Flag will make private copy of the incoming value. 373void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, FlagValueOrigin origin) { 374 Flag* faddr = address_of_flag(flag); 375 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type"); 376 ccstr old_value = faddr->get_ccstr(); 377 char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1); 378 strcpy(new_value, value); 379 faddr->set_ccstr(new_value); 380 if (faddr->origin != DEFAULT && old_value != NULL) { 381 // Prior value is heap allocated so free it. 382 FREE_C_HEAP_ARRAY(char, old_value); 383 } 384 faddr->origin = origin; 385} 386 387extern "C" { 388 static int compare_flags(const void* void_a, const void* void_b) { 389 return strcmp((*((Flag**) void_a))->name, (*((Flag**) void_b))->name); 390 } 391} 392 393void CommandLineFlags::printSetFlags() { 394 // Print which flags were set on the command line 395 // note: this method is called before the thread structure is in place 396 // which means resource allocation cannot be used. 397 398 // Compute size 399 int length= 0; 400 while (flagTable[length].name != NULL) length++; 401 402 // Sort 403 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length); 404 for (int index = 0; index < length; index++) { 405 array[index] = &flagTable[index]; 406 } 407 qsort(array, length, sizeof(Flag*), compare_flags); 408 409 // Print 410 for (int i = 0; i < length; i++) { 411 if (array[i]->origin /* naked field! */) { 412 array[i]->print_as_flag(tty); 413 tty->print(" "); 414 } 415 } 416 tty->cr(); 417 FREE_C_HEAP_ARRAY(Flag*, array); 418} 419 420#ifndef PRODUCT 421 422 423void CommandLineFlags::verify() { 424 assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict"); 425} 426 427void CommandLineFlags::printFlags() { 428 // Print the flags sorted by name 429 // note: this method is called before the thread structure is in place 430 // which means resource allocation cannot be used. 431 432 // Compute size 433 int length= 0; 434 while (flagTable[length].name != NULL) length++; 435 436 // Sort 437 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length); 438 for (int index = 0; index < length; index++) { 439 array[index] = &flagTable[index]; 440 } 441 qsort(array, length, sizeof(Flag*), compare_flags); 442 443 // Print 444 tty->print_cr("[Global flags]"); 445 for (int i = 0; i < length; i++) { 446 if (array[i]->is_unlocked()) { 447 array[i]->print_on(tty); 448 } 449 } 450 FREE_C_HEAP_ARRAY(Flag*, array); 451} 452 453#endif 454