8198608: Improvements to command-line flags printing
Re-implemented Flag::print_on() Reviewed-by: dholmes, mikael, gziemski
This commit is contained in:
parent
d574a06345
commit
f5d589fe63
@ -462,6 +462,18 @@ bool Flag::is_external() const {
|
||||
return is_manageable() || is_external_ext();
|
||||
}
|
||||
|
||||
// Helper function for Flag::print_on().
|
||||
// Fills current line up to requested position.
|
||||
// Should the current position already be past the requested position,
|
||||
// one separator blank is enforced.
|
||||
void 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_on(outputStream* st, bool withComments, bool printRanges) {
|
||||
// Don't print notproduct and develop flags in a product build.
|
||||
if (is_constant_in_binary()) {
|
||||
@ -469,36 +481,82 @@ void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
|
||||
}
|
||||
|
||||
if (!printRanges) {
|
||||
// Use some named constants to make code more readable.
|
||||
const unsigned int nSpaces = 10;
|
||||
const unsigned int maxFlagLen = 40 + nSpaces;
|
||||
// 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.
|
||||
//
|
||||
// Sample output:
|
||||
// bool CMSScavengeBeforeRemark = false {product} {default}
|
||||
// uintx CMSScheduleRemarkEdenPenetration = 50 {product} {default}
|
||||
// size_t CMSScheduleRemarkEdenSizeThreshold = 2097152 {product} {default}
|
||||
// uintx CMSScheduleRemarkSamplingRatio = 5 {product} {default}
|
||||
// double CMSSmallCoalSurplusPercent = 1.050000 {product} {default}
|
||||
// ccstr CompileCommandFile = MyFile.cmd {product} {command line}
|
||||
// ccstrlist CompileOnly = Method1
|
||||
// CompileOnly += Method2 {product} {command line}
|
||||
// | | | | | | |
|
||||
// | | | | | | +-- col7
|
||||
// | | | | | +-- col6
|
||||
// | | | | +-- col5
|
||||
// | | | +-- col4
|
||||
// | | +-- col3
|
||||
// | +-- col2
|
||||
// +-- col1
|
||||
|
||||
// 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);
|
||||
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("%-20s", get_bool() ? "true" : "false");
|
||||
st->print("%s", get_bool() ? "true" : "false");
|
||||
} else if (is_int()) {
|
||||
st->print("%-20d", get_int());
|
||||
st->print("%d", get_int());
|
||||
} else if (is_uint()) {
|
||||
st->print("%-20u", get_uint());
|
||||
st->print("%u", get_uint());
|
||||
} else if (is_intx()) {
|
||||
st->print(INTX_FORMAT_W(-20), get_intx());
|
||||
st->print(INTX_FORMAT, get_intx());
|
||||
} else if (is_uintx()) {
|
||||
st->print(UINTX_FORMAT_W(-20), get_uintx());
|
||||
st->print(UINTX_FORMAT, get_uintx());
|
||||
} else if (is_uint64_t()) {
|
||||
st->print(UINT64_FORMAT_W(-20), get_uint64_t());
|
||||
st->print(UINT64_FORMAT, get_uint64_t());
|
||||
} else if (is_size_t()) {
|
||||
st->print(SIZE_FORMAT_W(-20), get_size_t());
|
||||
st->print(SIZE_FORMAT, get_size_t());
|
||||
} else if (is_double()) {
|
||||
st->print("%-20f", get_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;
|
||||
@ -507,31 +565,85 @@ void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
|
||||
st->print("%.*s", (int)llen, cp);
|
||||
st->cr();
|
||||
cp = eol+1;
|
||||
st->print("%5s %-35s += ", "", _name);
|
||||
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("%-20s", cp);
|
||||
st->print("%s", cp);
|
||||
}
|
||||
else st->print("%-20s", "");
|
||||
} else {
|
||||
st->print("unhandled type %s", _type);
|
||||
st->cr();
|
||||
return;
|
||||
}
|
||||
// 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);
|
||||
|
||||
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()) {
|
||||
st->print("%9s %-50s ", _type, _name);
|
||||
// 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.
|
||||
//
|
||||
// Sample output:
|
||||
// intx MinPassesBeforeFlush [ 0 ... 9223372036854775807 ] {diagnostic} {default}
|
||||
// uintx MinRAMFraction [ 1 ... 18446744073709551615 ] {product} {default}
|
||||
// double MinRAMPercentage [ 0.000 ... 100.000 ] {product} {default}
|
||||
// uintx MinSurvivorRatio [ 3 ... 18446744073709551615 ] {product} {default}
|
||||
// size_t MinTLABSize [ 1 ... 9223372036854775807 ] {product} {default}
|
||||
// intx MonitorBound [ 0 ... 2147483647 ] {product} {default}
|
||||
// | | | | | |
|
||||
// | | | | | +-- col7
|
||||
// | | | | +-- col6
|
||||
// | | | +-- col5
|
||||
// | | +-- col4
|
||||
// | +-- col2
|
||||
// +-- col1
|
||||
|
||||
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;
|
||||
@ -548,24 +660,29 @@ void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
|
||||
} else if (is_double()) {
|
||||
func = Flag::get_double_default_range_str;
|
||||
} else {
|
||||
ShouldNotReachHere();
|
||||
st->print("unhandled type %s", _type);
|
||||
st->cr();
|
||||
return;
|
||||
}
|
||||
CommandLineFlagRangeList::print(st, _name, func);
|
||||
|
||||
st->print(" %-16s", " ");
|
||||
print_kind_and_origin(st);
|
||||
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_and_origin(outputStream* st) {
|
||||
void Flag::print_kind(outputStream* st, unsigned int width) {
|
||||
struct Data {
|
||||
int flag;
|
||||
const char* name;
|
||||
@ -615,9 +732,11 @@ void Flag::print_kind_and_origin(outputStream* st) {
|
||||
}
|
||||
assert(buffer_used + 2 <= buffer_size, "Too small buffer");
|
||||
jio_snprintf(kind + buffer_used, buffer_size - buffer_used, "}");
|
||||
st->print("%20s", kind);
|
||||
st->print("%*s", width, kind);
|
||||
}
|
||||
}
|
||||
|
||||
void Flag::print_origin(outputStream* st, unsigned int width) {
|
||||
int origin = _flags & VALUE_ORIGIN_MASK;
|
||||
st->print("{");
|
||||
switch(origin) {
|
||||
|
@ -289,7 +289,8 @@ struct Flag {
|
||||
|
||||
// printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
|
||||
void print_on(outputStream* st, bool withComments = false, bool printRanges = false);
|
||||
void print_kind_and_origin(outputStream* st);
|
||||
void print_kind(outputStream* st, unsigned int width);
|
||||
void print_origin(outputStream* st, unsigned int width);
|
||||
void print_as_flag(outputStream* st);
|
||||
|
||||
static const char* flag_error_str(Flag::Error error);
|
||||
|
Loading…
Reference in New Issue
Block a user