83 IGNORE_RANGE, \ |
83 IGNORE_RANGE, \ |
84 IGNORE_CONSTRAINT, \ |
84 IGNORE_CONSTRAINT, \ |
85 IGNORE_WRITEABLE) |
85 IGNORE_WRITEABLE) |
86 |
86 |
87 MATERIALIZE_FLAGS_EXT |
87 MATERIALIZE_FLAGS_EXT |
88 |
|
89 #define DEFAULT_RANGE_STR_CHUNK_SIZE 64 |
|
90 static char* create_range_str(const char *fmt, ...) { |
|
91 static size_t string_length = DEFAULT_RANGE_STR_CHUNK_SIZE; |
|
92 static char* range_string = NEW_C_HEAP_ARRAY(char, string_length, mtLogging); |
|
93 |
|
94 int size_needed = 0; |
|
95 do { |
|
96 va_list args; |
|
97 va_start(args, fmt); |
|
98 size_needed = jio_vsnprintf(range_string, string_length, fmt, args); |
|
99 va_end(args); |
|
100 |
|
101 if (size_needed < 0) { |
|
102 string_length += DEFAULT_RANGE_STR_CHUNK_SIZE; |
|
103 range_string = REALLOC_C_HEAP_ARRAY(char, range_string, string_length, mtLogging); |
|
104 guarantee(range_string != NULL, "create_range_str string should not be NULL"); |
|
105 } |
|
106 } while (size_needed < 0); |
|
107 |
|
108 return range_string; |
|
109 } |
|
110 |
|
111 const char* Flag::get_int_default_range_str() { |
|
112 return create_range_str("[ " INT32_FORMAT_W(-25) " ... " INT32_FORMAT_W(25) " ]", INT_MIN, INT_MAX); |
|
113 } |
|
114 |
|
115 const char* Flag::get_uint_default_range_str() { |
|
116 return create_range_str("[ " UINT32_FORMAT_W(-25) " ... " UINT32_FORMAT_W(25) " ]", 0, UINT_MAX); |
|
117 } |
|
118 |
|
119 const char* Flag::get_intx_default_range_str() { |
|
120 return create_range_str("[ " INTX_FORMAT_W(-25) " ... " INTX_FORMAT_W(25) " ]", min_intx, max_intx); |
|
121 } |
|
122 |
|
123 const char* Flag::get_uintx_default_range_str() { |
|
124 return create_range_str("[ " UINTX_FORMAT_W(-25) " ... " UINTX_FORMAT_W(25) " ]", 0, max_uintx); |
|
125 } |
|
126 |
|
127 const char* Flag::get_uint64_t_default_range_str() { |
|
128 return create_range_str("[ " UINT64_FORMAT_W(-25) " ... " UINT64_FORMAT_W(25) " ]", 0, uint64_t(max_juint)); |
|
129 } |
|
130 |
|
131 const char* Flag::get_size_t_default_range_str() { |
|
132 return create_range_str("[ " SIZE_FORMAT_W(-25) " ... " SIZE_FORMAT_W(25) " ]", 0, SIZE_MAX); |
|
133 } |
|
134 |
|
135 const char* Flag::get_double_default_range_str() { |
|
136 return create_range_str("[ %-25.3f ... %25.3f ]", DBL_MIN, DBL_MAX); |
|
137 } |
|
138 |
|
139 static bool is_product_build() { |
|
140 #ifdef PRODUCT |
|
141 return true; |
|
142 #else |
|
143 return false; |
|
144 #endif |
|
145 } |
|
146 |
|
147 Flag::Error Flag::check_writable(bool changed) { |
|
148 if (is_constant_in_binary()) { |
|
149 fatal("flag is constant: %s", _name); |
|
150 } |
|
151 |
|
152 Flag::Error error = Flag::SUCCESS; |
|
153 if (changed) { |
|
154 CommandLineFlagWriteable* writeable = CommandLineFlagWriteableList::find(_name); |
|
155 if (writeable) { |
|
156 if (writeable->is_writeable() == false) { |
|
157 switch (writeable->type()) |
|
158 { |
|
159 case CommandLineFlagWriteable::Once: |
|
160 error = Flag::SET_ONLY_ONCE; |
|
161 jio_fprintf(defaultStream::error_stream(), "Error: %s may not be set more than once\n", _name); |
|
162 break; |
|
163 case CommandLineFlagWriteable::CommandLineOnly: |
|
164 error = Flag::COMMAND_LINE_ONLY; |
|
165 jio_fprintf(defaultStream::error_stream(), "Error: %s may be modified only from commad line\n", _name); |
|
166 break; |
|
167 default: |
|
168 ShouldNotReachHere(); |
|
169 break; |
|
170 } |
|
171 } |
|
172 writeable->mark_once(); |
|
173 } |
|
174 } |
|
175 return error; |
|
176 } |
|
177 |
|
178 bool Flag::is_bool() const { |
|
179 return strcmp(_type, "bool") == 0; |
|
180 } |
|
181 |
|
182 bool Flag::get_bool() const { |
|
183 return *((bool*) _addr); |
|
184 } |
|
185 |
|
186 Flag::Error Flag::set_bool(bool value) { |
|
187 Flag::Error error = check_writable(value!=get_bool()); |
|
188 if (error == Flag::SUCCESS) { |
|
189 *((bool*) _addr) = value; |
|
190 } |
|
191 return error; |
|
192 } |
|
193 |
|
194 bool Flag::is_int() const { |
|
195 return strcmp(_type, "int") == 0; |
|
196 } |
|
197 |
|
198 int Flag::get_int() const { |
|
199 return *((int*) _addr); |
|
200 } |
|
201 |
|
202 Flag::Error Flag::set_int(int value) { |
|
203 Flag::Error error = check_writable(value!=get_int()); |
|
204 if (error == Flag::SUCCESS) { |
|
205 *((int*) _addr) = value; |
|
206 } |
|
207 return error; |
|
208 } |
|
209 |
|
210 bool Flag::is_uint() const { |
|
211 return strcmp(_type, "uint") == 0; |
|
212 } |
|
213 |
|
214 uint Flag::get_uint() const { |
|
215 return *((uint*) _addr); |
|
216 } |
|
217 |
|
218 Flag::Error Flag::set_uint(uint value) { |
|
219 Flag::Error error = check_writable(value!=get_uint()); |
|
220 if (error == Flag::SUCCESS) { |
|
221 *((uint*) _addr) = value; |
|
222 } |
|
223 return error; |
|
224 } |
|
225 |
|
226 bool Flag::is_intx() const { |
|
227 return strcmp(_type, "intx") == 0; |
|
228 } |
|
229 |
|
230 intx Flag::get_intx() const { |
|
231 return *((intx*) _addr); |
|
232 } |
|
233 |
|
234 Flag::Error Flag::set_intx(intx value) { |
|
235 Flag::Error error = check_writable(value!=get_intx()); |
|
236 if (error == Flag::SUCCESS) { |
|
237 *((intx*) _addr) = value; |
|
238 } |
|
239 return error; |
|
240 } |
|
241 |
|
242 bool Flag::is_uintx() const { |
|
243 return strcmp(_type, "uintx") == 0; |
|
244 } |
|
245 |
|
246 uintx Flag::get_uintx() const { |
|
247 return *((uintx*) _addr); |
|
248 } |
|
249 |
|
250 Flag::Error Flag::set_uintx(uintx value) { |
|
251 Flag::Error error = check_writable(value!=get_uintx()); |
|
252 if (error == Flag::SUCCESS) { |
|
253 *((uintx*) _addr) = value; |
|
254 } |
|
255 return error; |
|
256 } |
|
257 |
|
258 bool Flag::is_uint64_t() const { |
|
259 return strcmp(_type, "uint64_t") == 0; |
|
260 } |
|
261 |
|
262 uint64_t Flag::get_uint64_t() const { |
|
263 return *((uint64_t*) _addr); |
|
264 } |
|
265 |
|
266 Flag::Error Flag::set_uint64_t(uint64_t value) { |
|
267 Flag::Error error = check_writable(value!=get_uint64_t()); |
|
268 if (error == Flag::SUCCESS) { |
|
269 *((uint64_t*) _addr) = value; |
|
270 } |
|
271 return error; |
|
272 } |
|
273 |
|
274 bool Flag::is_size_t() const { |
|
275 return strcmp(_type, "size_t") == 0; |
|
276 } |
|
277 |
|
278 size_t Flag::get_size_t() const { |
|
279 return *((size_t*) _addr); |
|
280 } |
|
281 |
|
282 Flag::Error Flag::set_size_t(size_t value) { |
|
283 Flag::Error error = check_writable(value!=get_size_t()); |
|
284 if (error == Flag::SUCCESS) { |
|
285 *((size_t*) _addr) = value; |
|
286 } |
|
287 return error; |
|
288 } |
|
289 |
|
290 bool Flag::is_double() const { |
|
291 return strcmp(_type, "double") == 0; |
|
292 } |
|
293 |
|
294 double Flag::get_double() const { |
|
295 return *((double*) _addr); |
|
296 } |
|
297 |
|
298 Flag::Error Flag::set_double(double value) { |
|
299 Flag::Error error = check_writable(value!=get_double()); |
|
300 if (error == Flag::SUCCESS) { |
|
301 *((double*) _addr) = value; |
|
302 } |
|
303 return error; |
|
304 } |
|
305 |
|
306 bool Flag::is_ccstr() const { |
|
307 return strcmp(_type, "ccstr") == 0 || strcmp(_type, "ccstrlist") == 0; |
|
308 } |
|
309 |
|
310 bool Flag::ccstr_accumulates() const { |
|
311 return strcmp(_type, "ccstrlist") == 0; |
|
312 } |
|
313 |
|
314 ccstr Flag::get_ccstr() const { |
|
315 return *((ccstr*) _addr); |
|
316 } |
|
317 |
|
318 Flag::Error Flag::set_ccstr(ccstr value) { |
|
319 Flag::Error error = check_writable(value!=get_ccstr()); |
|
320 if (error == Flag::SUCCESS) { |
|
321 *((ccstr*) _addr) = value; |
|
322 } |
|
323 return error; |
|
324 } |
|
325 |
|
326 |
|
327 Flag::Flags Flag::get_origin() { |
|
328 return Flags(_flags & VALUE_ORIGIN_MASK); |
|
329 } |
|
330 |
|
331 void Flag::set_origin(Flags origin) { |
|
332 assert((origin & VALUE_ORIGIN_MASK) == origin, "sanity"); |
|
333 Flags new_origin = Flags((origin == COMMAND_LINE) ? Flags(origin | ORIG_COMMAND_LINE) : origin); |
|
334 _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | new_origin); |
|
335 } |
|
336 |
|
337 bool Flag::is_default() { |
|
338 return (get_origin() == DEFAULT); |
|
339 } |
|
340 |
|
341 bool Flag::is_ergonomic() { |
|
342 return (get_origin() == ERGONOMIC); |
|
343 } |
|
344 |
|
345 bool Flag::is_command_line() { |
|
346 return (_flags & ORIG_COMMAND_LINE) != 0; |
|
347 } |
|
348 |
|
349 void Flag::set_command_line() { |
|
350 _flags = Flags(_flags | ORIG_COMMAND_LINE); |
|
351 } |
|
352 |
|
353 bool Flag::is_product() const { |
|
354 return (_flags & KIND_PRODUCT) != 0; |
|
355 } |
|
356 |
|
357 bool Flag::is_manageable() const { |
|
358 return (_flags & KIND_MANAGEABLE) != 0; |
|
359 } |
|
360 |
|
361 bool Flag::is_diagnostic() const { |
|
362 return (_flags & KIND_DIAGNOSTIC) != 0; |
|
363 } |
|
364 |
|
365 bool Flag::is_experimental() const { |
|
366 return (_flags & KIND_EXPERIMENTAL) != 0; |
|
367 } |
|
368 |
|
369 bool Flag::is_notproduct() const { |
|
370 return (_flags & KIND_NOT_PRODUCT) != 0; |
|
371 } |
|
372 |
|
373 bool Flag::is_develop() const { |
|
374 return (_flags & KIND_DEVELOP) != 0; |
|
375 } |
|
376 |
|
377 bool Flag::is_read_write() const { |
|
378 return (_flags & KIND_READ_WRITE) != 0; |
|
379 } |
|
380 |
|
381 bool Flag::is_commercial() const { |
|
382 return (_flags & KIND_COMMERCIAL) != 0; |
|
383 } |
|
384 |
|
385 /** |
|
386 * Returns if this flag is a constant in the binary. Right now this is |
|
387 * true for notproduct and develop flags in product builds. |
|
388 */ |
|
389 bool Flag::is_constant_in_binary() const { |
|
390 #ifdef PRODUCT |
|
391 return is_notproduct() || is_develop(); |
|
392 #else |
|
393 return false; |
|
394 #endif |
|
395 } |
|
396 |
|
397 bool Flag::is_unlocker() const { |
|
398 return strcmp(_name, "UnlockDiagnosticVMOptions") == 0 || |
|
399 strcmp(_name, "UnlockExperimentalVMOptions") == 0 || |
|
400 is_unlocker_ext(); |
|
401 } |
|
402 |
|
403 bool Flag::is_unlocked() const { |
|
404 if (is_diagnostic()) { |
|
405 return UnlockDiagnosticVMOptions; |
|
406 } |
|
407 if (is_experimental()) { |
|
408 return UnlockExperimentalVMOptions; |
|
409 } |
|
410 return is_unlocked_ext(); |
|
411 } |
|
412 |
|
413 void Flag::clear_diagnostic() { |
|
414 assert(is_diagnostic(), "sanity"); |
|
415 _flags = Flags(_flags & ~KIND_DIAGNOSTIC); |
|
416 assert(!is_diagnostic(), "sanity"); |
|
417 } |
|
418 |
|
419 // Get custom message for this locked flag, or NULL if |
|
420 // none is available. Returns message type produced. |
|
421 Flag::MsgType Flag::get_locked_message(char* buf, int buflen) const { |
|
422 buf[0] = '\0'; |
|
423 if (is_diagnostic() && !is_unlocked()) { |
|
424 jio_snprintf(buf, buflen, |
|
425 "Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n" |
|
426 "Error: The unlock option must precede '%s'.\n", |
|
427 _name, _name); |
|
428 return Flag::DIAGNOSTIC_FLAG_BUT_LOCKED; |
|
429 } |
|
430 if (is_experimental() && !is_unlocked()) { |
|
431 jio_snprintf(buf, buflen, |
|
432 "Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n" |
|
433 "Error: The unlock option must precede '%s'.\n", |
|
434 _name, _name); |
|
435 return Flag::EXPERIMENTAL_FLAG_BUT_LOCKED; |
|
436 } |
|
437 if (is_develop() && is_product_build()) { |
|
438 jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n", |
|
439 _name); |
|
440 return Flag::DEVELOPER_FLAG_BUT_PRODUCT_BUILD; |
|
441 } |
|
442 if (is_notproduct() && is_product_build()) { |
|
443 jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n", |
|
444 _name); |
|
445 return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD; |
|
446 } |
|
447 return get_locked_message_ext(buf, buflen); |
|
448 } |
|
449 |
|
450 bool Flag::is_writeable() const { |
|
451 return is_manageable() || (is_product() && is_read_write()) || is_writeable_ext(); |
|
452 } |
|
453 |
|
454 // All flags except "manageable" are assumed to be internal flags. |
|
455 // Long term, we need to define a mechanism to specify which flags |
|
456 // are external/stable and change this function accordingly. |
|
457 bool Flag::is_external() const { |
|
458 return is_manageable() || is_external_ext(); |
|
459 } |
|
460 |
|
461 // Helper function for Flag::print_on(). |
|
462 // Fills current line up to requested position. |
|
463 // Should the current position already be past the requested position, |
|
464 // one separator blank is enforced. |
|
465 void fill_to_pos(outputStream* st, unsigned int req_pos) { |
|
466 if ((unsigned int)st->position() < req_pos) { |
|
467 st->fill_to(req_pos); // need to fill with blanks to reach req_pos |
|
468 } else { |
|
469 st->print(" "); // enforce blank separation. Previous field too long. |
|
470 } |
|
471 } |
|
472 |
|
473 void Flag::print_on(outputStream* st, bool withComments, bool printRanges) { |
|
474 // Don't print notproduct and develop flags in a product build. |
|
475 if (is_constant_in_binary()) { |
|
476 return; |
|
477 } |
|
478 |
|
479 if (!printRanges) { |
|
480 // The command line options -XX:+PrintFlags* cause this function to be called |
|
481 // for each existing flag to print information pertinent to this flag. The data |
|
482 // is displayed in columnar form, with the following layout: |
|
483 // col1 - data type, right-justified |
|
484 // col2 - name, left-justified |
|
485 // col3 - ' =' double-char, leading space to align with possible '+=' |
|
486 // col4 - value left-justified |
|
487 // col5 - kind right-justified |
|
488 // col6 - origin left-justified |
|
489 // col7 - comments left-justified |
|
490 // |
|
491 // The column widths are fixed. They are defined such that, for most cases, |
|
492 // an eye-pleasing tabular output is created. |
|
493 // |
|
494 // Sample output: |
|
495 // bool CMSScavengeBeforeRemark = false {product} {default} |
|
496 // uintx CMSScheduleRemarkEdenPenetration = 50 {product} {default} |
|
497 // size_t CMSScheduleRemarkEdenSizeThreshold = 2097152 {product} {default} |
|
498 // uintx CMSScheduleRemarkSamplingRatio = 5 {product} {default} |
|
499 // double CMSSmallCoalSurplusPercent = 1.050000 {product} {default} |
|
500 // ccstr CompileCommandFile = MyFile.cmd {product} {command line} |
|
501 // ccstrlist CompileOnly = Method1 |
|
502 // CompileOnly += Method2 {product} {command line} |
|
503 // | | | | | | | |
|
504 // | | | | | | +-- col7 |
|
505 // | | | | | +-- col6 |
|
506 // | | | | +-- col5 |
|
507 // | | | +-- col4 |
|
508 // | | +-- col3 |
|
509 // | +-- col2 |
|
510 // +-- col1 |
|
511 |
|
512 const unsigned int col_spacing = 1; |
|
513 const unsigned int col1_pos = 0; |
|
514 const unsigned int col1_width = 9; |
|
515 const unsigned int col2_pos = col1_pos + col1_width + col_spacing; |
|
516 const unsigned int col2_width = 39; |
|
517 const unsigned int col3_pos = col2_pos + col2_width + col_spacing; |
|
518 const unsigned int col3_width = 2; |
|
519 const unsigned int col4_pos = col3_pos + col3_width + col_spacing; |
|
520 const unsigned int col4_width = 30; |
|
521 const unsigned int col5_pos = col4_pos + col4_width + col_spacing; |
|
522 const unsigned int col5_width = 20; |
|
523 const unsigned int col6_pos = col5_pos + col5_width + col_spacing; |
|
524 const unsigned int col6_width = 15; |
|
525 const unsigned int col7_pos = col6_pos + col6_width + col_spacing; |
|
526 const unsigned int col7_width = 1; |
|
527 |
|
528 st->fill_to(col1_pos); |
|
529 st->print("%*s", col1_width, _type); // right-justified, therefore width is required. |
|
530 |
|
531 fill_to_pos(st, col2_pos); |
|
532 st->print("%s", _name); |
|
533 |
|
534 fill_to_pos(st, col3_pos); |
|
535 st->print(" ="); // use " =" for proper alignment with multiline ccstr output. |
|
536 |
|
537 fill_to_pos(st, col4_pos); |
|
538 if (is_bool()) { |
|
539 st->print("%s", get_bool() ? "true" : "false"); |
|
540 } else if (is_int()) { |
|
541 st->print("%d", get_int()); |
|
542 } else if (is_uint()) { |
|
543 st->print("%u", get_uint()); |
|
544 } else if (is_intx()) { |
|
545 st->print(INTX_FORMAT, get_intx()); |
|
546 } else if (is_uintx()) { |
|
547 st->print(UINTX_FORMAT, get_uintx()); |
|
548 } else if (is_uint64_t()) { |
|
549 st->print(UINT64_FORMAT, get_uint64_t()); |
|
550 } else if (is_size_t()) { |
|
551 st->print(SIZE_FORMAT, get_size_t()); |
|
552 } else if (is_double()) { |
|
553 st->print("%f", get_double()); |
|
554 } else if (is_ccstr()) { |
|
555 // Honor <newline> characters in ccstr: print multiple lines. |
|
556 const char* cp = get_ccstr(); |
|
557 if (cp != NULL) { |
|
558 const char* eol; |
|
559 while ((eol = strchr(cp, '\n')) != NULL) { |
|
560 size_t llen = pointer_delta(eol, cp, sizeof(char)); |
|
561 st->print("%.*s", (int)llen, cp); |
|
562 st->cr(); |
|
563 cp = eol+1; |
|
564 fill_to_pos(st, col2_pos); |
|
565 st->print("%s", _name); |
|
566 fill_to_pos(st, col3_pos); |
|
567 st->print("+="); |
|
568 fill_to_pos(st, col4_pos); |
|
569 } |
|
570 st->print("%s", cp); |
|
571 } |
|
572 } else { |
|
573 st->print("unhandled type %s", _type); |
|
574 st->cr(); |
|
575 return; |
|
576 } |
|
577 |
|
578 fill_to_pos(st, col5_pos); |
|
579 print_kind(st, col5_width); |
|
580 |
|
581 fill_to_pos(st, col6_pos); |
|
582 print_origin(st, col6_width); |
|
583 |
|
584 #ifndef PRODUCT |
|
585 if (withComments) { |
|
586 fill_to_pos(st, col7_pos); |
|
587 st->print("%s", _doc); |
|
588 } |
|
589 #endif |
|
590 st->cr(); |
|
591 } else if (!is_bool() && !is_ccstr()) { |
|
592 // The command line options -XX:+PrintFlags* cause this function to be called |
|
593 // for each existing flag to print information pertinent to this flag. The data |
|
594 // is displayed in columnar form, with the following layout: |
|
595 // col1 - data type, right-justified |
|
596 // col2 - name, left-justified |
|
597 // col4 - range [ min ... max] |
|
598 // col5 - kind right-justified |
|
599 // col6 - origin left-justified |
|
600 // col7 - comments left-justified |
|
601 // |
|
602 // The column widths are fixed. They are defined such that, for most cases, |
|
603 // an eye-pleasing tabular output is created. |
|
604 // |
|
605 // Sample output: |
|
606 // intx MinPassesBeforeFlush [ 0 ... 9223372036854775807 ] {diagnostic} {default} |
|
607 // uintx MinRAMFraction [ 1 ... 18446744073709551615 ] {product} {default} |
|
608 // double MinRAMPercentage [ 0.000 ... 100.000 ] {product} {default} |
|
609 // uintx MinSurvivorRatio [ 3 ... 18446744073709551615 ] {product} {default} |
|
610 // size_t MinTLABSize [ 1 ... 9223372036854775807 ] {product} {default} |
|
611 // intx MonitorBound [ 0 ... 2147483647 ] {product} {default} |
|
612 // | | | | | | |
|
613 // | | | | | +-- col7 |
|
614 // | | | | +-- col6 |
|
615 // | | | +-- col5 |
|
616 // | | +-- col4 |
|
617 // | +-- col2 |
|
618 // +-- col1 |
|
619 |
|
620 const unsigned int col_spacing = 1; |
|
621 const unsigned int col1_pos = 0; |
|
622 const unsigned int col1_width = 9; |
|
623 const unsigned int col2_pos = col1_pos + col1_width + col_spacing; |
|
624 const unsigned int col2_width = 49; |
|
625 const unsigned int col3_pos = col2_pos + col2_width + col_spacing; |
|
626 const unsigned int col3_width = 0; |
|
627 const unsigned int col4_pos = col3_pos + col3_width + col_spacing; |
|
628 const unsigned int col4_width = 60; |
|
629 const unsigned int col5_pos = col4_pos + col4_width + col_spacing; |
|
630 const unsigned int col5_width = 35; |
|
631 const unsigned int col6_pos = col5_pos + col5_width + col_spacing; |
|
632 const unsigned int col6_width = 15; |
|
633 const unsigned int col7_pos = col6_pos + col6_width + col_spacing; |
|
634 const unsigned int col7_width = 1; |
|
635 |
|
636 st->fill_to(col1_pos); |
|
637 st->print("%*s", col1_width, _type); // right-justified, therefore width is required. |
|
638 |
|
639 fill_to_pos(st, col2_pos); |
|
640 st->print("%s", _name); |
|
641 |
|
642 fill_to_pos(st, col4_pos); |
|
643 RangeStrFunc func = NULL; |
|
644 if (is_int()) { |
|
645 func = Flag::get_int_default_range_str; |
|
646 } else if (is_uint()) { |
|
647 func = Flag::get_uint_default_range_str; |
|
648 } else if (is_intx()) { |
|
649 func = Flag::get_intx_default_range_str; |
|
650 } else if (is_uintx()) { |
|
651 func = Flag::get_uintx_default_range_str; |
|
652 } else if (is_uint64_t()) { |
|
653 func = Flag::get_uint64_t_default_range_str; |
|
654 } else if (is_size_t()) { |
|
655 func = Flag::get_size_t_default_range_str; |
|
656 } else if (is_double()) { |
|
657 func = Flag::get_double_default_range_str; |
|
658 } else { |
|
659 st->print("unhandled type %s", _type); |
|
660 st->cr(); |
|
661 return; |
|
662 } |
|
663 CommandLineFlagRangeList::print(st, _name, func); |
|
664 |
|
665 fill_to_pos(st, col5_pos); |
|
666 print_kind(st, col5_width); |
|
667 |
|
668 fill_to_pos(st, col6_pos); |
|
669 print_origin(st, col6_width); |
|
670 |
|
671 #ifndef PRODUCT |
|
672 if (withComments) { |
|
673 fill_to_pos(st, col7_pos); |
|
674 st->print("%s", _doc); |
|
675 } |
|
676 #endif |
|
677 st->cr(); |
|
678 } |
|
679 } |
|
680 |
|
681 void Flag::print_kind(outputStream* st, unsigned int width) { |
|
682 struct Data { |
|
683 int flag; |
|
684 const char* name; |
|
685 }; |
|
686 |
|
687 Data data[] = { |
|
688 { KIND_JVMCI, "JVMCI" }, |
|
689 { KIND_C1, "C1" }, |
|
690 { KIND_C2, "C2" }, |
|
691 { KIND_ARCH, "ARCH" }, |
|
692 { KIND_PLATFORM_DEPENDENT, "pd" }, |
|
693 { KIND_PRODUCT, "product" }, |
|
694 { KIND_MANAGEABLE, "manageable" }, |
|
695 { KIND_DIAGNOSTIC, "diagnostic" }, |
|
696 { KIND_EXPERIMENTAL, "experimental" }, |
|
697 { KIND_COMMERCIAL, "commercial" }, |
|
698 { KIND_NOT_PRODUCT, "notproduct" }, |
|
699 { KIND_DEVELOP, "develop" }, |
|
700 { KIND_LP64_PRODUCT, "lp64_product" }, |
|
701 { KIND_READ_WRITE, "rw" }, |
|
702 { -1, "" } |
|
703 }; |
|
704 |
|
705 if ((_flags & KIND_MASK) != 0) { |
|
706 bool is_first = true; |
|
707 const size_t buffer_size = 64; |
|
708 size_t buffer_used = 0; |
|
709 char kind[buffer_size]; |
|
710 |
|
711 jio_snprintf(kind, buffer_size, "{"); |
|
712 buffer_used++; |
|
713 for (int i = 0; data[i].flag != -1; i++) { |
|
714 Data d = data[i]; |
|
715 if ((_flags & d.flag) != 0) { |
|
716 if (is_first) { |
|
717 is_first = false; |
|
718 } else { |
|
719 assert(buffer_used + 1 < buffer_size, "Too small buffer"); |
|
720 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, " "); |
|
721 buffer_used++; |
|
722 } |
|
723 size_t length = strlen(d.name); |
|
724 assert(buffer_used + length < buffer_size, "Too small buffer"); |
|
725 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "%s", d.name); |
|
726 buffer_used += length; |
|
727 } |
|
728 } |
|
729 assert(buffer_used + 2 <= buffer_size, "Too small buffer"); |
|
730 jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}"); |
|
731 st->print("%*s", width, kind); |
|
732 } |
|
733 } |
|
734 |
|
735 void Flag::print_origin(outputStream* st, unsigned int width) { |
|
736 int origin = _flags & VALUE_ORIGIN_MASK; |
|
737 st->print("{"); |
|
738 switch(origin) { |
|
739 case DEFAULT: |
|
740 st->print("default"); break; |
|
741 case COMMAND_LINE: |
|
742 st->print("command line"); break; |
|
743 case ENVIRON_VAR: |
|
744 st->print("environment"); break; |
|
745 case CONFIG_FILE: |
|
746 st->print("config file"); break; |
|
747 case MANAGEMENT: |
|
748 st->print("management"); break; |
|
749 case ERGONOMIC: |
|
750 if (_flags & ORIG_COMMAND_LINE) { |
|
751 st->print("command line, "); |
|
752 } |
|
753 st->print("ergonomic"); break; |
|
754 case ATTACH_ON_DEMAND: |
|
755 st->print("attach"); break; |
|
756 case INTERNAL: |
|
757 st->print("internal"); break; |
|
758 } |
|
759 st->print("}"); |
|
760 } |
|
761 |
|
762 void Flag::print_as_flag(outputStream* st) { |
|
763 if (is_bool()) { |
|
764 st->print("-XX:%s%s", get_bool() ? "+" : "-", _name); |
|
765 } else if (is_int()) { |
|
766 st->print("-XX:%s=%d", _name, get_int()); |
|
767 } else if (is_uint()) { |
|
768 st->print("-XX:%s=%u", _name, get_uint()); |
|
769 } else if (is_intx()) { |
|
770 st->print("-XX:%s=" INTX_FORMAT, _name, get_intx()); |
|
771 } else if (is_uintx()) { |
|
772 st->print("-XX:%s=" UINTX_FORMAT, _name, get_uintx()); |
|
773 } else if (is_uint64_t()) { |
|
774 st->print("-XX:%s=" UINT64_FORMAT, _name, get_uint64_t()); |
|
775 } else if (is_size_t()) { |
|
776 st->print("-XX:%s=" SIZE_FORMAT, _name, get_size_t()); |
|
777 } else if (is_double()) { |
|
778 st->print("-XX:%s=%f", _name, get_double()); |
|
779 } else if (is_ccstr()) { |
|
780 st->print("-XX:%s=", _name); |
|
781 const char* cp = get_ccstr(); |
|
782 if (cp != NULL) { |
|
783 // Need to turn embedded '\n's back into separate arguments |
|
784 // Not so efficient to print one character at a time, |
|
785 // but the choice is to do the transformation to a buffer |
|
786 // and print that. And this need not be efficient. |
|
787 for (; *cp != '\0'; cp += 1) { |
|
788 switch (*cp) { |
|
789 default: |
|
790 st->print("%c", *cp); |
|
791 break; |
|
792 case '\n': |
|
793 st->print(" -XX:%s=", _name); |
|
794 break; |
|
795 } |
|
796 } |
|
797 } |
|
798 } else { |
|
799 ShouldNotReachHere(); |
|
800 } |
|
801 } |
|
802 |
|
803 const char* Flag::flag_error_str(Flag::Error error) { |
|
804 switch (error) { |
|
805 case Flag::MISSING_NAME: return "MISSING_NAME"; |
|
806 case Flag::MISSING_VALUE: return "MISSING_VALUE"; |
|
807 case Flag::NON_WRITABLE: return "NON_WRITABLE"; |
|
808 case Flag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS"; |
|
809 case Flag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT"; |
|
810 case Flag::INVALID_FLAG: return "INVALID_FLAG"; |
|
811 case Flag::ERR_OTHER: return "ERR_OTHER"; |
|
812 case Flag::SUCCESS: return "SUCCESS"; |
|
813 default: ShouldNotReachHere(); return "NULL"; |
|
814 } |
|
815 } |
|
816 |
|
817 // 4991491 do not "optimize out" the was_set false values: omitting them |
|
818 // tickles a Microsoft compiler bug causing flagTable to be malformed |
|
819 |
|
820 #define RUNTIME_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT) }, |
|
821 #define RUNTIME_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
822 #define RUNTIME_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC) }, |
|
823 #define RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DIAGNOSTIC | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
824 #define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_EXPERIMENTAL) }, |
|
825 #define RUNTIME_MANAGEABLE_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_MANAGEABLE) }, |
|
826 #define RUNTIME_PRODUCT_RW_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_PRODUCT | Flag::KIND_READ_WRITE) }, |
|
827 #define RUNTIME_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP) }, |
|
828 #define RUNTIME_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
829 #define RUNTIME_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_NOT_PRODUCT) }, |
|
830 |
|
831 #define JVMCI_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_PRODUCT) }, |
|
832 #define JVMCI_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
833 #define JVMCI_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DIAGNOSTIC) }, |
|
834 #define JVMCI_PD_DIAGNOSTIC_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DIAGNOSTIC | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
835 #define JVMCI_EXPERIMENTAL_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_EXPERIMENTAL) }, |
|
836 #define JVMCI_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DEVELOP) }, |
|
837 #define JVMCI_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
838 #define JVMCI_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_JVMCI | Flag::KIND_NOT_PRODUCT) }, |
|
839 |
|
840 #ifdef _LP64 |
|
841 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_LP64_PRODUCT) }, |
|
842 #else |
|
843 #define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */ |
|
844 #endif // _LP64 |
|
845 |
|
846 #define C1_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_PRODUCT) }, |
|
847 #define C1_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
848 #define C1_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DIAGNOSTIC) }, |
|
849 #define C1_PD_DIAGNOSTIC_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DIAGNOSTIC | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
850 #define C1_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DEVELOP) }, |
|
851 #define C1_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
852 #define C1_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C1 | Flag::KIND_NOT_PRODUCT) }, |
|
853 |
|
854 #define C2_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_PRODUCT) }, |
|
855 #define C2_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
856 #define C2_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DIAGNOSTIC) }, |
|
857 #define C2_PD_DIAGNOSTIC_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DIAGNOSTIC | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
858 #define C2_EXPERIMENTAL_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_EXPERIMENTAL) }, |
|
859 #define C2_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DEVELOP) }, |
|
860 #define C2_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) }, |
|
861 #define C2_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_C2 | Flag::KIND_NOT_PRODUCT) }, |
|
862 |
|
863 #define ARCH_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_PRODUCT) }, |
|
864 #define ARCH_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DIAGNOSTIC) }, |
|
865 #define ARCH_EXPERIMENTAL_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_EXPERIMENTAL) }, |
|
866 #define ARCH_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DEVELOP) }, |
|
867 #define ARCH_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_NOT_PRODUCT) }, |
|
868 |
|
869 static Flag flagTable[] = { |
|
870 VM_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ |
|
871 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ |
|
872 RUNTIME_PRODUCT_FLAG_STRUCT, \ |
|
873 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ |
|
874 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ |
|
875 RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT, \ |
|
876 RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \ |
|
877 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ |
|
878 RUNTIME_MANAGEABLE_FLAG_STRUCT, \ |
|
879 RUNTIME_PRODUCT_RW_FLAG_STRUCT, \ |
|
880 RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \ |
|
881 IGNORE_RANGE, \ |
|
882 IGNORE_CONSTRAINT, \ |
|
883 IGNORE_WRITEABLE) |
|
884 |
|
885 RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \ |
|
886 RUNTIME_PD_DEVELOP_FLAG_STRUCT, \ |
|
887 RUNTIME_PRODUCT_FLAG_STRUCT, \ |
|
888 RUNTIME_PD_PRODUCT_FLAG_STRUCT, \ |
|
889 RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \ |
|
890 RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT, \ |
|
891 RUNTIME_NOTPRODUCT_FLAG_STRUCT, \ |
|
892 IGNORE_RANGE, \ |
|
893 IGNORE_CONSTRAINT, \ |
|
894 IGNORE_WRITEABLE) |
|
895 #if INCLUDE_JVMCI |
|
896 JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, \ |
|
897 JVMCI_PD_DEVELOP_FLAG_STRUCT, \ |
|
898 JVMCI_PRODUCT_FLAG_STRUCT, \ |
|
899 JVMCI_PD_PRODUCT_FLAG_STRUCT, \ |
|
900 JVMCI_DIAGNOSTIC_FLAG_STRUCT, \ |
|
901 JVMCI_PD_DIAGNOSTIC_FLAG_STRUCT, \ |
|
902 JVMCI_EXPERIMENTAL_FLAG_STRUCT, \ |
|
903 JVMCI_NOTPRODUCT_FLAG_STRUCT, \ |
|
904 IGNORE_RANGE, \ |
|
905 IGNORE_CONSTRAINT, \ |
|
906 IGNORE_WRITEABLE) |
|
907 #endif // INCLUDE_JVMCI |
|
908 #ifdef COMPILER1 |
|
909 C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \ |
|
910 C1_PD_DEVELOP_FLAG_STRUCT, \ |
|
911 C1_PRODUCT_FLAG_STRUCT, \ |
|
912 C1_PD_PRODUCT_FLAG_STRUCT, \ |
|
913 C1_DIAGNOSTIC_FLAG_STRUCT, \ |
|
914 C1_PD_DIAGNOSTIC_FLAG_STRUCT, \ |
|
915 C1_NOTPRODUCT_FLAG_STRUCT, \ |
|
916 IGNORE_RANGE, \ |
|
917 IGNORE_CONSTRAINT, \ |
|
918 IGNORE_WRITEABLE) |
|
919 #endif // COMPILER1 |
|
920 #ifdef COMPILER2 |
|
921 C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \ |
|
922 C2_PD_DEVELOP_FLAG_STRUCT, \ |
|
923 C2_PRODUCT_FLAG_STRUCT, \ |
|
924 C2_PD_PRODUCT_FLAG_STRUCT, \ |
|
925 C2_DIAGNOSTIC_FLAG_STRUCT, \ |
|
926 C2_PD_DIAGNOSTIC_FLAG_STRUCT, \ |
|
927 C2_EXPERIMENTAL_FLAG_STRUCT, \ |
|
928 C2_NOTPRODUCT_FLAG_STRUCT, \ |
|
929 IGNORE_RANGE, \ |
|
930 IGNORE_CONSTRAINT, \ |
|
931 IGNORE_WRITEABLE) |
|
932 #endif // COMPILER2 |
|
933 ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \ |
|
934 ARCH_PRODUCT_FLAG_STRUCT, \ |
|
935 ARCH_DIAGNOSTIC_FLAG_STRUCT, \ |
|
936 ARCH_EXPERIMENTAL_FLAG_STRUCT, \ |
|
937 ARCH_NOTPRODUCT_FLAG_STRUCT, \ |
|
938 IGNORE_RANGE, \ |
|
939 IGNORE_CONSTRAINT, \ |
|
940 IGNORE_WRITEABLE) |
|
941 FLAGTABLE_EXT |
|
942 {0, NULL, NULL} |
|
943 }; |
|
944 |
|
945 Flag* Flag::flags = flagTable; |
|
946 size_t Flag::numFlags = (sizeof(flagTable) / sizeof(Flag)); |
|
947 |
|
948 inline bool str_equal(const char* s, size_t s_len, const char* q, size_t q_len) { |
|
949 if (s_len != q_len) return false; |
|
950 return memcmp(s, q, q_len) == 0; |
|
951 } |
|
952 |
|
953 // Search the flag table for a named flag |
|
954 Flag* Flag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) { |
|
955 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) { |
|
956 if (str_equal(current->_name, current->get_name_length(), name, length)) { |
|
957 // Found a matching entry. |
|
958 // Don't report notproduct and develop flags in product builds. |
|
959 if (current->is_constant_in_binary()) { |
|
960 return (return_flag ? current : NULL); |
|
961 } |
|
962 // Report locked flags only if allowed. |
|
963 if (!(current->is_unlocked() || current->is_unlocker())) { |
|
964 if (!allow_locked) { |
|
965 // disable use of locked flags, e.g. diagnostic, experimental, |
|
966 // commercial... until they are explicitly unlocked |
|
967 return NULL; |
|
968 } |
|
969 } |
|
970 return current; |
|
971 } |
|
972 } |
|
973 // Flag name is not in the flag table |
|
974 return NULL; |
|
975 } |
|
976 |
|
977 // Get or compute the flag name length |
|
978 size_t Flag::get_name_length() { |
|
979 if (_name_len == 0) { |
|
980 _name_len = strlen(_name); |
|
981 } |
|
982 return _name_len; |
|
983 } |
|
984 |
|
985 Flag* Flag::fuzzy_match(const char* name, size_t length, bool allow_locked) { |
|
986 float VMOptionsFuzzyMatchSimilarity = 0.7f; |
|
987 Flag* match = NULL; |
|
988 float score; |
|
989 float max_score = -1; |
|
990 |
|
991 for (Flag* current = &flagTable[0]; current->_name != NULL; current++) { |
|
992 score = StringUtils::similarity(current->_name, strlen(current->_name), name, length); |
|
993 if (score > max_score) { |
|
994 max_score = score; |
|
995 match = current; |
|
996 } |
|
997 } |
|
998 |
|
999 if (!(match->is_unlocked() || match->is_unlocker())) { |
|
1000 if (!allow_locked) { |
|
1001 return NULL; |
|
1002 } |
|
1003 } |
|
1004 |
|
1005 if (max_score < VMOptionsFuzzyMatchSimilarity) { |
|
1006 return NULL; |
|
1007 } |
|
1008 |
|
1009 return match; |
|
1010 } |
|
1011 |
|
1012 // Returns the address of the index'th element |
|
1013 static Flag* address_of_flag(CommandLineFlagWithType flag) { |
|
1014 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); |
|
1015 return &Flag::flags[flag]; |
|
1016 } |
|
1017 |
|
1018 bool CommandLineFlagsEx::is_default(CommandLineFlag flag) { |
|
1019 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); |
|
1020 Flag* f = &Flag::flags[flag]; |
|
1021 return f->is_default(); |
|
1022 } |
|
1023 |
|
1024 bool CommandLineFlagsEx::is_ergo(CommandLineFlag flag) { |
|
1025 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); |
|
1026 Flag* f = &Flag::flags[flag]; |
|
1027 return f->is_ergonomic(); |
|
1028 } |
|
1029 |
|
1030 bool CommandLineFlagsEx::is_cmdline(CommandLineFlag flag) { |
|
1031 assert((size_t)flag < Flag::numFlags, "bad command line flag index"); |
|
1032 Flag* f = &Flag::flags[flag]; |
|
1033 return f->is_command_line(); |
|
1034 } |
|
1035 |
|
1036 bool CommandLineFlags::wasSetOnCmdline(const char* name, bool* value) { |
|
1037 Flag* result = Flag::find_flag((char*)name, strlen(name)); |
|
1038 if (result == NULL) return false; |
|
1039 *value = result->is_command_line(); |
|
1040 return true; |
|
1041 } |
|
1042 |
|
1043 void CommandLineFlagsEx::setOnCmdLine(CommandLineFlagWithType flag) { |
|
1044 Flag* faddr = address_of_flag(flag); |
|
1045 assert(faddr != NULL, "Unknown flag"); |
|
1046 faddr->set_command_line(); |
|
1047 } |
|
1048 |
|
1049 template<class E, class T> |
|
1050 static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) { |
|
1051 E e; |
|
1052 e.set_name(name); |
|
1053 e.set_oldValue(old_value); |
|
1054 e.set_newValue(new_value); |
|
1055 e.set_origin(origin); |
|
1056 e.commit(); |
|
1057 } |
|
1058 |
|
1059 static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose) { |
|
1060 Flag::Error status = Flag::SUCCESS; |
|
1061 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); |
|
1062 if (constraint != NULL) { |
|
1063 status = constraint->apply_bool(new_value, verbose); |
|
1064 } |
|
1065 return status; |
|
1066 } |
|
1067 |
|
1068 Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) { |
|
1069 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1070 if (result == NULL) return Flag::INVALID_FLAG; |
|
1071 if (!result->is_bool()) return Flag::WRONG_FORMAT; |
|
1072 *value = result->get_bool(); |
|
1073 return Flag::SUCCESS; |
|
1074 } |
|
1075 |
|
1076 Flag::Error CommandLineFlags::boolAtPut(Flag* flag, bool* value, Flag::Flags origin) { |
|
1077 const char* name; |
|
1078 if (flag == NULL) return Flag::INVALID_FLAG; |
|
1079 if (!flag->is_bool()) return Flag::WRONG_FORMAT; |
|
1080 name = flag->_name; |
|
1081 Flag::Error check = apply_constraint_and_check_range_bool(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); |
|
1082 if (check != Flag::SUCCESS) return check; |
|
1083 bool old_value = flag->get_bool(); |
|
1084 trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin); |
|
1085 check = flag->set_bool(*value); |
|
1086 *value = old_value; |
|
1087 flag->set_origin(origin); |
|
1088 return check; |
|
1089 } |
|
1090 |
|
1091 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) { |
|
1092 Flag* result = Flag::find_flag(name, len); |
|
1093 return boolAtPut(result, value, origin); |
|
1094 } |
|
1095 |
|
1096 Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) { |
|
1097 Flag* faddr = address_of_flag(flag); |
|
1098 guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type"); |
|
1099 return CommandLineFlags::boolAtPut(faddr, &value, origin); |
|
1100 } |
|
1101 |
|
1102 static Flag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose) { |
|
1103 Flag::Error status = Flag::SUCCESS; |
|
1104 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); |
|
1105 if (range != NULL) { |
|
1106 status = range->check_int(new_value, verbose); |
|
1107 } |
|
1108 if (status == Flag::SUCCESS) { |
|
1109 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); |
|
1110 if (constraint != NULL) { |
|
1111 status = constraint->apply_int(new_value, verbose); |
|
1112 } |
|
1113 } |
|
1114 return status; |
|
1115 } |
|
1116 |
|
1117 Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) { |
|
1118 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1119 if (result == NULL) return Flag::INVALID_FLAG; |
|
1120 if (!result->is_int()) return Flag::WRONG_FORMAT; |
|
1121 *value = result->get_int(); |
|
1122 return Flag::SUCCESS; |
|
1123 } |
|
1124 |
|
1125 Flag::Error CommandLineFlags::intAtPut(Flag* flag, int* value, Flag::Flags origin) { |
|
1126 const char* name; |
|
1127 if (flag == NULL) return Flag::INVALID_FLAG; |
|
1128 if (!flag->is_int()) return Flag::WRONG_FORMAT; |
|
1129 name = flag->_name; |
|
1130 Flag::Error check = apply_constraint_and_check_range_int(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); |
|
1131 if (check != Flag::SUCCESS) return check; |
|
1132 int old_value = flag->get_int(); |
|
1133 trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin); |
|
1134 check = flag->set_int(*value); |
|
1135 *value = old_value; |
|
1136 flag->set_origin(origin); |
|
1137 return check; |
|
1138 } |
|
1139 |
|
1140 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) { |
|
1141 Flag* result = Flag::find_flag(name, len); |
|
1142 return intAtPut(result, value, origin); |
|
1143 } |
|
1144 |
|
1145 Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) { |
|
1146 Flag* faddr = address_of_flag(flag); |
|
1147 guarantee(faddr != NULL && faddr->is_int(), "wrong flag type"); |
|
1148 return CommandLineFlags::intAtPut(faddr, &value, origin); |
|
1149 } |
|
1150 |
|
1151 static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose) { |
|
1152 Flag::Error status = Flag::SUCCESS; |
|
1153 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); |
|
1154 if (range != NULL) { |
|
1155 status = range->check_uint(new_value, verbose); |
|
1156 } |
|
1157 if (status == Flag::SUCCESS) { |
|
1158 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); |
|
1159 if (constraint != NULL) { |
|
1160 status = constraint->apply_uint(new_value, verbose); |
|
1161 } |
|
1162 } |
|
1163 return status; |
|
1164 } |
|
1165 |
|
1166 Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) { |
|
1167 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1168 if (result == NULL) return Flag::INVALID_FLAG; |
|
1169 if (!result->is_uint()) return Flag::WRONG_FORMAT; |
|
1170 *value = result->get_uint(); |
|
1171 return Flag::SUCCESS; |
|
1172 } |
|
1173 |
|
1174 Flag::Error CommandLineFlags::uintAtPut(Flag* flag, uint* value, Flag::Flags origin) { |
|
1175 const char* name; |
|
1176 if (flag == NULL) return Flag::INVALID_FLAG; |
|
1177 if (!flag->is_uint()) return Flag::WRONG_FORMAT; |
|
1178 name = flag->_name; |
|
1179 Flag::Error check = apply_constraint_and_check_range_uint(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); |
|
1180 if (check != Flag::SUCCESS) return check; |
|
1181 uint old_value = flag->get_uint(); |
|
1182 trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin); |
|
1183 check = flag->set_uint(*value); |
|
1184 *value = old_value; |
|
1185 flag->set_origin(origin); |
|
1186 return check; |
|
1187 } |
|
1188 |
|
1189 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) { |
|
1190 Flag* result = Flag::find_flag(name, len); |
|
1191 return uintAtPut(result, value, origin); |
|
1192 } |
|
1193 |
|
1194 Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) { |
|
1195 Flag* faddr = address_of_flag(flag); |
|
1196 guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type"); |
|
1197 return CommandLineFlags::uintAtPut(faddr, &value, origin); |
|
1198 } |
|
1199 |
|
1200 Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) { |
|
1201 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1202 if (result == NULL) return Flag::INVALID_FLAG; |
|
1203 if (!result->is_intx()) return Flag::WRONG_FORMAT; |
|
1204 *value = result->get_intx(); |
|
1205 return Flag::SUCCESS; |
|
1206 } |
|
1207 |
|
1208 static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose) { |
|
1209 Flag::Error status = Flag::SUCCESS; |
|
1210 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); |
|
1211 if (range != NULL) { |
|
1212 status = range->check_intx(new_value, verbose); |
|
1213 } |
|
1214 if (status == Flag::SUCCESS) { |
|
1215 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); |
|
1216 if (constraint != NULL) { |
|
1217 status = constraint->apply_intx(new_value, verbose); |
|
1218 } |
|
1219 } |
|
1220 return status; |
|
1221 } |
|
1222 |
|
1223 Flag::Error CommandLineFlags::intxAtPut(Flag* flag, intx* value, Flag::Flags origin) { |
|
1224 const char* name; |
|
1225 if (flag == NULL) return Flag::INVALID_FLAG; |
|
1226 if (!flag->is_intx()) return Flag::WRONG_FORMAT; |
|
1227 name = flag->_name; |
|
1228 Flag::Error check = apply_constraint_and_check_range_intx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); |
|
1229 if (check != Flag::SUCCESS) return check; |
|
1230 intx old_value = flag->get_intx(); |
|
1231 trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin); |
|
1232 check = flag->set_intx(*value); |
|
1233 *value = old_value; |
|
1234 flag->set_origin(origin); |
|
1235 return check; |
|
1236 } |
|
1237 |
|
1238 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) { |
|
1239 Flag* result = Flag::find_flag(name, len); |
|
1240 return intxAtPut(result, value, origin); |
|
1241 } |
|
1242 |
|
1243 Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) { |
|
1244 Flag* faddr = address_of_flag(flag); |
|
1245 guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type"); |
|
1246 return CommandLineFlags::intxAtPut(faddr, &value, origin); |
|
1247 } |
|
1248 |
|
1249 Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) { |
|
1250 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1251 if (result == NULL) return Flag::INVALID_FLAG; |
|
1252 if (!result->is_uintx()) return Flag::WRONG_FORMAT; |
|
1253 *value = result->get_uintx(); |
|
1254 return Flag::SUCCESS; |
|
1255 } |
|
1256 |
|
1257 static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose) { |
|
1258 Flag::Error status = Flag::SUCCESS; |
|
1259 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); |
|
1260 if (range != NULL) { |
|
1261 status = range->check_uintx(new_value, verbose); |
|
1262 } |
|
1263 if (status == Flag::SUCCESS) { |
|
1264 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); |
|
1265 if (constraint != NULL) { |
|
1266 status = constraint->apply_uintx(new_value, verbose); |
|
1267 } |
|
1268 } |
|
1269 return status; |
|
1270 } |
|
1271 |
|
1272 Flag::Error CommandLineFlags::uintxAtPut(Flag* flag, uintx* value, Flag::Flags origin) { |
|
1273 const char* name; |
|
1274 if (flag == NULL) return Flag::INVALID_FLAG; |
|
1275 if (!flag->is_uintx()) return Flag::WRONG_FORMAT; |
|
1276 name = flag->_name; |
|
1277 Flag::Error check = apply_constraint_and_check_range_uintx(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); |
|
1278 if (check != Flag::SUCCESS) return check; |
|
1279 uintx old_value = flag->get_uintx(); |
|
1280 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); |
|
1281 check = flag->set_uintx(*value); |
|
1282 *value = old_value; |
|
1283 flag->set_origin(origin); |
|
1284 return check; |
|
1285 } |
|
1286 |
|
1287 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) { |
|
1288 Flag* result = Flag::find_flag(name, len); |
|
1289 return uintxAtPut(result, value, origin); |
|
1290 } |
|
1291 |
|
1292 Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) { |
|
1293 Flag* faddr = address_of_flag(flag); |
|
1294 guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type"); |
|
1295 return CommandLineFlags::uintxAtPut(faddr, &value, origin); |
|
1296 } |
|
1297 |
|
1298 Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) { |
|
1299 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1300 if (result == NULL) return Flag::INVALID_FLAG; |
|
1301 if (!result->is_uint64_t()) return Flag::WRONG_FORMAT; |
|
1302 *value = result->get_uint64_t(); |
|
1303 return Flag::SUCCESS; |
|
1304 } |
|
1305 |
|
1306 static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose) { |
|
1307 Flag::Error status = Flag::SUCCESS; |
|
1308 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); |
|
1309 if (range != NULL) { |
|
1310 status = range->check_uint64_t(new_value, verbose); |
|
1311 } |
|
1312 if (status == Flag::SUCCESS) { |
|
1313 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); |
|
1314 if (constraint != NULL) { |
|
1315 status = constraint->apply_uint64_t(new_value, verbose); |
|
1316 } |
|
1317 } |
|
1318 return status; |
|
1319 } |
|
1320 |
|
1321 Flag::Error CommandLineFlags::uint64_tAtPut(Flag* flag, uint64_t* value, Flag::Flags origin) { |
|
1322 const char* name; |
|
1323 if (flag == NULL) return Flag::INVALID_FLAG; |
|
1324 if (!flag->is_uint64_t()) return Flag::WRONG_FORMAT; |
|
1325 name = flag->_name; |
|
1326 Flag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); |
|
1327 if (check != Flag::SUCCESS) return check; |
|
1328 uint64_t old_value = flag->get_uint64_t(); |
|
1329 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); |
|
1330 check = flag->set_uint64_t(*value); |
|
1331 *value = old_value; |
|
1332 flag->set_origin(origin); |
|
1333 return check; |
|
1334 } |
|
1335 |
|
1336 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) { |
|
1337 Flag* result = Flag::find_flag(name, len); |
|
1338 return uint64_tAtPut(result, value, origin); |
|
1339 } |
|
1340 |
|
1341 Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) { |
|
1342 Flag* faddr = address_of_flag(flag); |
|
1343 guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type"); |
|
1344 return CommandLineFlags::uint64_tAtPut(faddr, &value, origin); |
|
1345 } |
|
1346 |
|
1347 Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) { |
|
1348 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1349 if (result == NULL) return Flag::INVALID_FLAG; |
|
1350 if (!result->is_size_t()) return Flag::WRONG_FORMAT; |
|
1351 *value = result->get_size_t(); |
|
1352 return Flag::SUCCESS; |
|
1353 } |
|
1354 |
|
1355 static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose) { |
|
1356 Flag::Error status = Flag::SUCCESS; |
|
1357 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); |
|
1358 if (range != NULL) { |
|
1359 status = range->check_size_t(new_value, verbose); |
|
1360 } |
|
1361 if (status == Flag::SUCCESS) { |
|
1362 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); |
|
1363 if (constraint != NULL) { |
|
1364 status = constraint->apply_size_t(new_value, verbose); |
|
1365 } |
|
1366 } |
|
1367 return status; |
|
1368 } |
|
1369 |
|
1370 |
|
1371 Flag::Error CommandLineFlags::size_tAtPut(Flag* flag, size_t* value, Flag::Flags origin) { |
|
1372 const char* name; |
|
1373 if (flag == NULL) return Flag::INVALID_FLAG; |
|
1374 if (!flag->is_size_t()) return Flag::WRONG_FORMAT; |
|
1375 name = flag->_name; |
|
1376 Flag::Error check = apply_constraint_and_check_range_size_t(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); |
|
1377 if (check != Flag::SUCCESS) return check; |
|
1378 size_t old_value = flag->get_size_t(); |
|
1379 trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin); |
|
1380 check = flag->set_size_t(*value); |
|
1381 *value = old_value; |
|
1382 flag->set_origin(origin); |
|
1383 return check; |
|
1384 } |
|
1385 |
|
1386 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) { |
|
1387 Flag* result = Flag::find_flag(name, len); |
|
1388 return size_tAtPut(result, value, origin); |
|
1389 } |
|
1390 |
|
1391 Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) { |
|
1392 Flag* faddr = address_of_flag(flag); |
|
1393 guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type"); |
|
1394 return CommandLineFlags::size_tAtPut(faddr, &value, origin); |
|
1395 } |
|
1396 |
|
1397 Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) { |
|
1398 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1399 if (result == NULL) return Flag::INVALID_FLAG; |
|
1400 if (!result->is_double()) return Flag::WRONG_FORMAT; |
|
1401 *value = result->get_double(); |
|
1402 return Flag::SUCCESS; |
|
1403 } |
|
1404 |
|
1405 static Flag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose) { |
|
1406 Flag::Error status = Flag::SUCCESS; |
|
1407 CommandLineFlagRange* range = CommandLineFlagRangeList::find(name); |
|
1408 if (range != NULL) { |
|
1409 status = range->check_double(new_value, verbose); |
|
1410 } |
|
1411 if (status == Flag::SUCCESS) { |
|
1412 CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); |
|
1413 if (constraint != NULL) { |
|
1414 status = constraint->apply_double(new_value, verbose); |
|
1415 } |
|
1416 } |
|
1417 return status; |
|
1418 } |
|
1419 |
|
1420 Flag::Error CommandLineFlags::doubleAtPut(Flag* flag, double* value, Flag::Flags origin) { |
|
1421 const char* name; |
|
1422 if (flag == NULL) return Flag::INVALID_FLAG; |
|
1423 if (!flag->is_double()) return Flag::WRONG_FORMAT; |
|
1424 name = flag->_name; |
|
1425 Flag::Error check = apply_constraint_and_check_range_double(name, *value, !CommandLineFlagConstraintList::validated_after_ergo()); |
|
1426 if (check != Flag::SUCCESS) return check; |
|
1427 double old_value = flag->get_double(); |
|
1428 trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin); |
|
1429 check = flag->set_double(*value); |
|
1430 *value = old_value; |
|
1431 flag->set_origin(origin); |
|
1432 return check; |
|
1433 } |
|
1434 |
|
1435 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) { |
|
1436 Flag* result = Flag::find_flag(name, len); |
|
1437 return doubleAtPut(result, value, origin); |
|
1438 } |
|
1439 |
|
1440 Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) { |
|
1441 Flag* faddr = address_of_flag(flag); |
|
1442 guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); |
|
1443 return CommandLineFlags::doubleAtPut(faddr, &value, origin); |
|
1444 } |
|
1445 |
|
1446 Flag::Error CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) { |
|
1447 Flag* result = Flag::find_flag(name, len, allow_locked, return_flag); |
|
1448 if (result == NULL) return Flag::INVALID_FLAG; |
|
1449 if (!result->is_ccstr()) return Flag::WRONG_FORMAT; |
|
1450 *value = result->get_ccstr(); |
|
1451 return Flag::SUCCESS; |
|
1452 } |
|
1453 |
|
1454 Flag::Error CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) { |
|
1455 Flag* result = Flag::find_flag(name, len); |
|
1456 if (result == NULL) return Flag::INVALID_FLAG; |
|
1457 if (!result->is_ccstr()) return Flag::WRONG_FORMAT; |
|
1458 ccstr old_value = result->get_ccstr(); |
|
1459 trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin); |
|
1460 char* new_value = NULL; |
|
1461 if (*value != NULL) { |
|
1462 new_value = os::strdup_check_oom(*value); |
|
1463 } |
|
1464 Flag::Error check = result->set_ccstr(new_value); |
|
1465 if (result->is_default() && old_value != NULL) { |
|
1466 // Prior value is NOT heap allocated, but was a literal constant. |
|
1467 old_value = os::strdup_check_oom(old_value); |
|
1468 } |
|
1469 *value = old_value; |
|
1470 result->set_origin(origin); |
|
1471 return check; |
|
1472 } |
|
1473 |
|
1474 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) { |
|
1475 Flag* faddr = address_of_flag(flag); |
|
1476 guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type"); |
|
1477 ccstr old_value = faddr->get_ccstr(); |
|
1478 trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin); |
|
1479 char* new_value = os::strdup_check_oom(value); |
|
1480 Flag::Error check = faddr->set_ccstr(new_value); |
|
1481 if (!faddr->is_default() && old_value != NULL) { |
|
1482 // Prior value is heap allocated so free it. |
|
1483 FREE_C_HEAP_ARRAY(char, old_value); |
|
1484 } |
|
1485 faddr->set_origin(origin); |
|
1486 return check; |
|
1487 } |
|
1488 |
|
1489 extern "C" { |
|
1490 static int compare_flags(const void* void_a, const void* void_b) { |
|
1491 return strcmp((*((Flag**) void_a))->_name, (*((Flag**) void_b))->_name); |
|
1492 } |
|
1493 } |
|
1494 |
|
1495 void CommandLineFlags::printSetFlags(outputStream* out) { |
|
1496 // Print which flags were set on the command line |
|
1497 // note: this method is called before the thread structure is in place |
|
1498 // which means resource allocation cannot be used. |
|
1499 |
|
1500 // The last entry is the null entry. |
|
1501 const size_t length = Flag::numFlags - 1; |
|
1502 |
|
1503 // Sort |
|
1504 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtArguments); |
|
1505 for (size_t i = 0; i < length; i++) { |
|
1506 array[i] = &flagTable[i]; |
|
1507 } |
|
1508 qsort(array, length, sizeof(Flag*), compare_flags); |
|
1509 |
|
1510 // Print |
|
1511 for (size_t i = 0; i < length; i++) { |
|
1512 if (array[i]->get_origin() /* naked field! */) { |
|
1513 array[i]->print_as_flag(out); |
|
1514 out->print(" "); |
|
1515 } |
|
1516 } |
|
1517 out->cr(); |
|
1518 FREE_C_HEAP_ARRAY(Flag*, array); |
|
1519 } |
|
1520 |
|
1521 #ifndef PRODUCT |
|
1522 |
|
1523 void CommandLineFlags::verify() { |
|
1524 assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict"); |
|
1525 } |
|
1526 |
|
1527 #endif // PRODUCT |
|
1528 |
|
1529 void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) { |
|
1530 // Print the flags sorted by name |
|
1531 // note: this method is called before the thread structure is in place |
|
1532 // which means resource allocation cannot be used. |
|
1533 |
|
1534 // The last entry is the null entry. |
|
1535 const size_t length = Flag::numFlags - 1; |
|
1536 |
|
1537 // Sort |
|
1538 Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtArguments); |
|
1539 for (size_t i = 0; i < length; i++) { |
|
1540 array[i] = &flagTable[i]; |
|
1541 } |
|
1542 qsort(array, length, sizeof(Flag*), compare_flags); |
|
1543 |
|
1544 // Print |
|
1545 if (!printRanges) { |
|
1546 out->print_cr("[Global flags]"); |
|
1547 } else { |
|
1548 out->print_cr("[Global flags ranges]"); |
|
1549 } |
|
1550 |
|
1551 for (size_t i = 0; i < length; i++) { |
|
1552 if (array[i]->is_unlocked()) { |
|
1553 array[i]->print_on(out, withComments, printRanges); |
|
1554 } |
|
1555 } |
|
1556 FREE_C_HEAP_ARRAY(Flag*, array); |
|
1557 } |
|