< prev index next >
src/hotspot/share/runtime/globals.cpp
Print this page
rev 49218 : 8198608: Improvements to command-line flags printing
*** 467,539 ****
if (is_constant_in_binary()) {
return;
}
if (!printRanges) {
! // Use some named constants to make code more readable.
! const unsigned int nSpaces = 10;
! const unsigned int maxFlagLen = 40 + nSpaces;
!
! // The print below assumes that the flag name is 40 characters or less.
! // This works for most flags, but there are exceptions. Our longest flag
! // name right now is UseAdaptiveGenerationSizePolicyAtMajorCollection and
! // its minor collection buddy. These are 48 characters. We use a buffer of
! // nSpaces spaces below to adjust the space between the flag value and the
! // column of flag type and origin that is printed in the end of the line.
! char spaces[nSpaces + 1] = " ";
! st->print("%9s %-*s = ", _type, maxFlagLen-nSpaces, _name);
if (is_bool()) {
! st->print("%-20s", get_bool() ? "true" : "false");
} else if (is_int()) {
! st->print("%-20d", get_int());
} else if (is_uint()) {
! st->print("%-20u", get_uint());
} else if (is_intx()) {
! st->print(INTX_FORMAT_W(-20), get_intx());
} else if (is_uintx()) {
! st->print(UINTX_FORMAT_W(-20), get_uintx());
} else if (is_uint64_t()) {
! st->print(UINT64_FORMAT_W(-20), get_uint64_t());
} else if (is_size_t()) {
! st->print(SIZE_FORMAT_W(-20), get_size_t());
} else if (is_double()) {
! st->print("%-20f", get_double());
} else if (is_ccstr()) {
const char* cp = get_ccstr();
if (cp != NULL) {
const char* eol;
while ((eol = strchr(cp, '\n')) != NULL) {
size_t llen = pointer_delta(eol, cp, sizeof(char));
st->print("%.*s", (int)llen, cp);
st->cr();
cp = eol+1;
! st->print("%5s %-35s += ", "", _name);
! }
! st->print("%-20s", cp);
}
! else st->print("%-20s", "");
}
! // Make sure we do not punch a '\0' at a negative char array index.
! unsigned int nameLen = (unsigned int)strlen(_name);
! if (nameLen <= maxFlagLen) {
! spaces[maxFlagLen - MAX2(maxFlagLen-nSpaces, nameLen)] = '\0';
! st->print("%s", spaces);
}
! print_kind_and_origin(st);
#ifndef PRODUCT
if (withComments) {
st->print("%s", _doc);
}
#endif
-
st->cr();
-
} else if (!is_bool() && !is_ccstr()) {
! st->print("%9s %-50s ", _type, _name);
RangeStrFunc func = NULL;
if (is_int()) {
func = Flag::get_int_default_range_str;
} else if (is_uint()) {
func = Flag::get_uint_default_range_str;
--- 467,606 ----
if (is_constant_in_binary()) {
return;
}
if (!printRanges) {
! // The command line options -XX:+PrintFlags* cause this function to be called
! // for each existing flag to print information pertinent to this flag. The data
! // is displayed in columnar form, with the following layout:
! // col1 - data type, right-justified
! // col2 - name, left-justified
! // col3 - ' =' double-char, leading space to align with possible '+='
! // col4 - value left-justified
! // col5 - kind right-justified
! // col6 - origin left-justified
! // col7 - comments left-justified
! //
! // The column widths are fixed. They are defined such that, for most cases,
! // an eye-pleasing tabular output is created.
!
! const unsigned int col_spacing = 1;
! const unsigned int col1_pos = 0;
! const unsigned int col1_width = 9;
! const unsigned int col2_pos = col1_pos + col1_width + col_spacing;
! const unsigned int col2_width = 39;
! const unsigned int col3_pos = col2_pos + col2_width + col_spacing;
! const unsigned int col3_width = 2;
! const unsigned int col4_pos = col3_pos + col3_width + col_spacing;
! const unsigned int col4_width = 30;
! const unsigned int col5_pos = col4_pos + col4_width + col_spacing;
! const unsigned int col5_width = 20;
! const unsigned int col6_pos = col5_pos + col5_width + col_spacing;
! const unsigned int col6_width = 15;
! const unsigned int col7_pos = col6_pos + col6_width + col_spacing;
! const unsigned int col7_width = 1;
!
! st->fill_to(col1_pos);
! st->print("%*s", col1_width, _type); // right-justified, therefore width is required.
+ fill_to_pos(st, col2_pos);
+ st->print("%s", _name);
+
+ fill_to_pos(st, col3_pos);
+ st->print(" ="); // use " =" for proper alignment with multiline ccstr output.
+
+ fill_to_pos(st, col4_pos);
if (is_bool()) {
! st->print("%s", get_bool() ? "true" : "false");
} else if (is_int()) {
! st->print("%d", get_int());
} else if (is_uint()) {
! st->print("%u", get_uint());
} else if (is_intx()) {
! st->print(INTX_FORMAT, get_intx());
} else if (is_uintx()) {
! st->print(UINTX_FORMAT, get_uintx());
} else if (is_uint64_t()) {
! st->print(UINT64_FORMAT, get_uint64_t());
} else if (is_size_t()) {
! st->print(SIZE_FORMAT, get_size_t());
} else if (is_double()) {
! st->print("%f", get_double());
} else if (is_ccstr()) {
+ // Honor <newline> characters in ccstr: print multiple lines.
const char* cp = get_ccstr();
if (cp != NULL) {
const char* eol;
while ((eol = strchr(cp, '\n')) != NULL) {
size_t llen = pointer_delta(eol, cp, sizeof(char));
st->print("%.*s", (int)llen, cp);
st->cr();
cp = eol+1;
! fill_to_pos(st, col2_pos);
! st->print("%s", _name);
! fill_to_pos(st, col3_pos);
! st->print("+=");
! fill_to_pos(st, col4_pos);
}
! st->print("%s", cp);
}
! } else {
! st->print("unhandled type %s", _type);
! st->cr();
! return;
}
!
! fill_to_pos(st, col5_pos);
! print_kind(st, col5_width);
!
! fill_to_pos(st, col6_pos);
! print_origin(st, col6_width);
#ifndef PRODUCT
if (withComments) {
+ fill_to_pos(st, col7_pos);
st->print("%s", _doc);
}
#endif
st->cr();
} else if (!is_bool() && !is_ccstr()) {
! // The command line options -XX:+PrintFlags* cause this function to be called
! // for each existing flag to print information pertinent to this flag. The data
! // is displayed in columnar form, with the following layout:
! // col1 - data type, right-justified
! // col2 - name, left-justified
! // col4 - range [ min ... max]
! // col5 - kind right-justified
! // col6 - origin left-justified
! // col7 - comments left-justified
! //
! // The column widths are fixed. They are defined such that, for most cases,
! // an eye-pleasing tabular output is created.
!
! const unsigned int col_spacing = 1;
! const unsigned int col1_pos = 0;
! const unsigned int col1_width = 9;
! const unsigned int col2_pos = col1_pos + col1_width + col_spacing;
! const unsigned int col2_width = 49;
! const unsigned int col3_pos = col2_pos + col2_width + col_spacing;
! const unsigned int col3_width = 0;
! const unsigned int col4_pos = col3_pos + col3_width + col_spacing;
! const unsigned int col4_width = 60;
! const unsigned int col5_pos = col4_pos + col4_width + col_spacing;
! const unsigned int col5_width = 35;
! const unsigned int col6_pos = col5_pos + col5_width + col_spacing;
! const unsigned int col6_width = 15;
! const unsigned int col7_pos = col6_pos + col6_width + col_spacing;
! const unsigned int col7_width = 1;
!
! st->fill_to(col1_pos);
! st->print("%*s", col1_width, _type); // right-justified, therefore width is required.
+ fill_to_pos(st, col2_pos);
+ st->print("%s", _name);
+
+ fill_to_pos(st, col4_pos);
RangeStrFunc func = NULL;
if (is_int()) {
func = Flag::get_int_default_range_str;
} else if (is_uint()) {
func = Flag::get_uint_default_range_str;
*** 546,573 ****
} else if (is_size_t()) {
func = Flag::get_size_t_default_range_str;
} else if (is_double()) {
func = Flag::get_double_default_range_str;
} else {
! ShouldNotReachHere();
}
CommandLineFlagRangeList::print(st, _name, func);
! st->print(" %-16s", " ");
! print_kind_and_origin(st);
#ifndef PRODUCT
if (withComments) {
st->print("%s", _doc);
}
#endif
-
st->cr();
}
}
! void Flag::print_kind_and_origin(outputStream* st) {
struct Data {
int flag;
const char* name;
};
--- 613,645 ----
} else if (is_size_t()) {
func = Flag::get_size_t_default_range_str;
} else if (is_double()) {
func = Flag::get_double_default_range_str;
} else {
! st->print("unhandled type %s", _type);
! st->cr();
! return;
}
CommandLineFlagRangeList::print(st, _name, func);
! fill_to_pos(st, col5_pos);
! print_kind(st, col5_width);
!
! fill_to_pos(st, col6_pos);
! print_origin(st, col6_width);
#ifndef PRODUCT
if (withComments) {
+ fill_to_pos(st, col7_pos);
st->print("%s", _doc);
}
#endif
st->cr();
}
}
! void Flag::print_kind(outputStream* st, unsigned int width) {
struct Data {
int flag;
const char* name;
};
*** 613,627 ****
buffer_used += length;
}
}
assert(buffer_used + 2 <= buffer_size, "Too small buffer");
jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}");
! st->print("%20s", kind);
}
int origin = _flags & VALUE_ORIGIN_MASK;
! st->print(" {");
switch(origin) {
case DEFAULT:
st->print("default"); break;
case COMMAND_LINE:
st->print("command line"); break;
--- 685,701 ----
buffer_used += length;
}
}
assert(buffer_used + 2 <= buffer_size, "Too small buffer");
jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}");
! st->print("%*s", width, kind);
}
+ }
+ void Flag::print_origin(outputStream* st, unsigned int width) {
int origin = _flags & VALUE_ORIGIN_MASK;
! st->print("{");
switch(origin) {
case DEFAULT:
st->print("default"); break;
case COMMAND_LINE:
st->print("command line"); break;
*** 642,651 ****
--- 716,733 ----
st->print("internal"); break;
}
st->print("}");
}
+ void Flag::fill_to_pos(outputStream* st, unsigned int req_pos) {
+ if ((unsigned int)st->position() < req_pos) {
+ st->fill_to(req_pos); // need to fill with blanks to reach req_pos
+ } else {
+ st->print(" "); // enforce blank separation. Previous field too long.
+ }
+ }
+
void Flag::print_as_flag(outputStream* st) {
if (is_bool()) {
st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
} else if (is_int()) {
st->print("-XX:%s=%d", _name, get_int());
< prev index next >