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