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