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