8055286: Extend CompileCommand=option to handle numeric parameters
Changed CompileCommand=option to handle "extended" parameters: Klass::method,type,flag,value. Types supported are bool, intx, and uintx. Reviewed-by: kvn, roland
This commit is contained in:
parent
da8d847087
commit
fbab0fe16e
@ -168,48 +168,113 @@ bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum OptionType {
|
||||||
|
IntxType,
|
||||||
|
UintxType,
|
||||||
|
BoolType,
|
||||||
|
CcstrType,
|
||||||
|
CcstrListType,
|
||||||
|
UnknownType
|
||||||
|
};
|
||||||
|
|
||||||
class MethodOptionMatcher: public MethodMatcher {
|
/* Methods to map real type names to OptionType */
|
||||||
const char * option;
|
template<typename T>
|
||||||
public:
|
static OptionType get_type_for() {
|
||||||
MethodOptionMatcher(Symbol* class_name, Mode class_mode,
|
return UnknownType;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<> OptionType get_type_for<intx>() {
|
||||||
|
return IntxType;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> OptionType get_type_for<uintx>() {
|
||||||
|
return UintxType;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> OptionType get_type_for<bool>() {
|
||||||
|
return BoolType;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class TypedMethodOptionMatcher : public MethodMatcher {
|
||||||
|
const char* _option;
|
||||||
|
OptionType _type;
|
||||||
|
const T _value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TypedMethodOptionMatcher(Symbol* class_name, Mode class_mode,
|
||||||
Symbol* method_name, Mode method_mode,
|
Symbol* method_name, Mode method_mode,
|
||||||
Symbol* signature, const char * opt, MethodMatcher* next):
|
Symbol* signature, const char* opt,
|
||||||
MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next) {
|
const T value, MethodMatcher* next) :
|
||||||
option = os::strdup_check_oom(opt);
|
MethodMatcher(class_name, class_mode, method_name, method_mode, signature, next),
|
||||||
|
_type(get_type_for<T>()), _value(value) {
|
||||||
|
_option = os::strdup_check_oom(opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~MethodOptionMatcher() {
|
~TypedMethodOptionMatcher() {
|
||||||
os::free((void*)option);
|
os::free((void*)_option);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool match(methodHandle method, const char* opt) {
|
TypedMethodOptionMatcher* match(methodHandle method, const char* opt) {
|
||||||
MethodOptionMatcher* current = this;
|
TypedMethodOptionMatcher* current = this;
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
current = (MethodOptionMatcher*)current->find(method);
|
current = (TypedMethodOptionMatcher*)current->find(method);
|
||||||
if (current == NULL) {
|
if (current == NULL) {
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (strcmp(current->option, opt) == 0) {
|
if (strcmp(current->_option, opt) == 0) {
|
||||||
return true;
|
return current;
|
||||||
}
|
}
|
||||||
current = current->next();
|
current = current->next();
|
||||||
}
|
}
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodOptionMatcher* next() {
|
TypedMethodOptionMatcher* next() {
|
||||||
return (MethodOptionMatcher*)_next;
|
return (TypedMethodOptionMatcher*)_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print() {
|
OptionType get_type(void) {
|
||||||
|
return _type;
|
||||||
|
};
|
||||||
|
|
||||||
|
T value() { return _value; }
|
||||||
|
|
||||||
|
void print() {
|
||||||
|
ttyLocker ttyl;
|
||||||
print_base();
|
print_base();
|
||||||
tty->print(" %s", option);
|
tty->print(" %s", _option);
|
||||||
|
tty->print(" <unknown option type>");
|
||||||
tty->cr();
|
tty->cr();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void TypedMethodOptionMatcher<intx>::print() {
|
||||||
|
ttyLocker ttyl;
|
||||||
|
print_base();
|
||||||
|
tty->print(" %s", _option);
|
||||||
|
tty->print(" " INTX_FORMAT, _value);
|
||||||
|
tty->cr();
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void TypedMethodOptionMatcher<uintx>::print() {
|
||||||
|
ttyLocker ttyl;
|
||||||
|
print_base();
|
||||||
|
tty->print(" %s", _option);
|
||||||
|
tty->print(" " UINTX_FORMAT, _value);
|
||||||
|
tty->cr();
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void TypedMethodOptionMatcher<bool>::print() {
|
||||||
|
ttyLocker ttyl;
|
||||||
|
print_base();
|
||||||
|
tty->print(" %s", _option);
|
||||||
|
tty->print(" %s", _value ? "true" : "false");
|
||||||
|
tty->cr();
|
||||||
|
};
|
||||||
|
|
||||||
// this must parallel the command_names below
|
// this must parallel the command_names below
|
||||||
enum OracleCommand {
|
enum OracleCommand {
|
||||||
@ -264,23 +329,45 @@ static MethodMatcher* add_predicate(OracleCommand command,
|
|||||||
return lists[command];
|
return lists[command];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
|
||||||
static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode,
|
static MethodMatcher* add_option_string(Symbol* class_name, MethodMatcher::Mode c_mode,
|
||||||
Symbol* method_name, MethodMatcher::Mode m_mode,
|
Symbol* method_name, MethodMatcher::Mode m_mode,
|
||||||
Symbol* signature,
|
Symbol* signature,
|
||||||
const char* option) {
|
const char* option,
|
||||||
lists[OptionCommand] = new MethodOptionMatcher(class_name, c_mode, method_name, m_mode,
|
T value) {
|
||||||
signature, option, lists[OptionCommand]);
|
lists[OptionCommand] = new TypedMethodOptionMatcher<T>(class_name, c_mode, method_name, m_mode,
|
||||||
|
signature, option, value, lists[OptionCommand]);
|
||||||
return lists[OptionCommand];
|
return lists[OptionCommand];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
bool CompilerOracle::has_option_string(methodHandle method, const char* option) {
|
static bool get_option_value(methodHandle method, const char* option, T& value) {
|
||||||
return lists[OptionCommand] != NULL &&
|
TypedMethodOptionMatcher<T>* m;
|
||||||
((MethodOptionMatcher*)lists[OptionCommand])->match(method, option);
|
if (lists[OptionCommand] != NULL
|
||||||
|
&& (m = ((TypedMethodOptionMatcher<T>*)lists[OptionCommand])->match(method, option)) != NULL
|
||||||
|
&& m->get_type() == get_type_for<T>()) {
|
||||||
|
value = m->value();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CompilerOracle::has_option_string(methodHandle method, const char* option) {
|
||||||
|
bool value = false;
|
||||||
|
get_option_value(method, option, value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool CompilerOracle::has_option_value(methodHandle method, const char* option, T& value) {
|
||||||
|
return get_option_value(method, option, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicit instantiation for all OptionTypes supported.
|
||||||
|
template bool CompilerOracle::has_option_value<intx>(methodHandle method, const char* option, intx& value);
|
||||||
|
template bool CompilerOracle::has_option_value<uintx>(methodHandle method, const char* option, uintx& value);
|
||||||
|
template bool CompilerOracle::has_option_value<bool>(methodHandle method, const char* option, bool& value);
|
||||||
|
|
||||||
bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) {
|
bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) {
|
||||||
quietly = true;
|
quietly = true;
|
||||||
@ -422,6 +509,61 @@ static bool scan_line(const char * line,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Scan next flag and value in line, return MethodMatcher object on success, NULL on failure.
|
||||||
|
// On failure, error_msg contains description for the first error.
|
||||||
|
// For future extensions: set error_msg on first error.
|
||||||
|
static MethodMatcher* scan_flag_and_value(const char* type, const char* line, int& total_bytes_read,
|
||||||
|
Symbol* c_name, MethodMatcher::Mode c_match,
|
||||||
|
Symbol* m_name, MethodMatcher::Mode m_match,
|
||||||
|
Symbol* signature,
|
||||||
|
char* errorbuf, const int buf_size) {
|
||||||
|
total_bytes_read = 0;
|
||||||
|
int bytes_read = 0;
|
||||||
|
char flag[256];
|
||||||
|
|
||||||
|
// Read flag name.
|
||||||
|
if (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", flag, &bytes_read) == 1) {
|
||||||
|
line += bytes_read;
|
||||||
|
total_bytes_read += bytes_read;
|
||||||
|
|
||||||
|
// Read value.
|
||||||
|
if (strcmp(type, "intx") == 0) {
|
||||||
|
intx value;
|
||||||
|
if (sscanf(line, "%*[ \t]" INTX_FORMAT "%n", &value, &bytes_read) == 1) {
|
||||||
|
total_bytes_read += bytes_read;
|
||||||
|
return add_option_string(c_name, c_match, m_name, m_match, signature, flag, value);
|
||||||
|
} else {
|
||||||
|
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s ", flag, type);
|
||||||
|
}
|
||||||
|
} else if (strcmp(type, "uintx") == 0) {
|
||||||
|
uintx value;
|
||||||
|
if (sscanf(line, "%*[ \t]" UINTX_FORMAT "%n", &value, &bytes_read) == 1) {
|
||||||
|
total_bytes_read += bytes_read;
|
||||||
|
return add_option_string(c_name, c_match, m_name, m_match, signature, flag, value);
|
||||||
|
} else {
|
||||||
|
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
|
||||||
|
}
|
||||||
|
} else if (strcmp(type, "bool") == 0) {
|
||||||
|
char value[256];
|
||||||
|
if (sscanf(line, "%*[ \t]%255[a-zA-Z]%n", value, &bytes_read) == 1) {
|
||||||
|
if (strcmp(value, "true") == 0) {
|
||||||
|
total_bytes_read += bytes_read;
|
||||||
|
return add_option_string(c_name, c_match, m_name, m_match, signature, flag, true);
|
||||||
|
} else {
|
||||||
|
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jio_snprintf(errorbuf, sizeof(errorbuf), " Value cannot be read for flag %s of type %s", flag, type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jio_snprintf(errorbuf, sizeof(errorbuf), " Type %s not supported ", type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jio_snprintf(errorbuf, sizeof(errorbuf), " Flag name for type %s should be alphanumeric ", type);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void CompilerOracle::parse_from_line(char* line) {
|
void CompilerOracle::parse_from_line(char* line) {
|
||||||
if (line[0] == '\0') return;
|
if (line[0] == '\0') return;
|
||||||
if (line[0] == '#') return;
|
if (line[0] == '#') return;
|
||||||
@ -451,8 +593,10 @@ void CompilerOracle::parse_from_line(char* line) {
|
|||||||
int bytes_read;
|
int bytes_read;
|
||||||
OracleCommand command = parse_command_name(line, &bytes_read);
|
OracleCommand command = parse_command_name(line, &bytes_read);
|
||||||
line += bytes_read;
|
line += bytes_read;
|
||||||
|
ResourceMark rm;
|
||||||
|
|
||||||
if (command == UnknownCommand) {
|
if (command == UnknownCommand) {
|
||||||
|
ttyLocker ttyl;
|
||||||
tty->print_cr("CompilerOracle: unrecognized line");
|
tty->print_cr("CompilerOracle: unrecognized line");
|
||||||
tty->print_cr(" \"%s\"", original_line);
|
tty->print_cr(" \"%s\"", original_line);
|
||||||
return;
|
return;
|
||||||
@ -474,7 +618,7 @@ void CompilerOracle::parse_from_line(char* line) {
|
|||||||
char method_name[256];
|
char method_name[256];
|
||||||
char sig[1024];
|
char sig[1024];
|
||||||
char errorbuf[1024];
|
char errorbuf[1024];
|
||||||
const char* error_msg = NULL;
|
const char* error_msg = NULL; // description of first error that appears
|
||||||
MethodMatcher* match = NULL;
|
MethodMatcher* match = NULL;
|
||||||
|
|
||||||
if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) {
|
if (scan_line(line, class_name, &c_match, method_name, &m_match, &bytes_read, error_msg)) {
|
||||||
@ -493,43 +637,78 @@ void CompilerOracle::parse_from_line(char* line) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (command == OptionCommand) {
|
if (command == OptionCommand) {
|
||||||
// Look for trailing options to support
|
// Look for trailing options.
|
||||||
// ciMethod::has_option("string") to control features in the
|
//
|
||||||
// compiler. Multiple options may follow the method name.
|
// Two types of trailing options are
|
||||||
char option[256];
|
// supported:
|
||||||
|
//
|
||||||
|
// (1) CompileCommand=option,Klass::method,flag
|
||||||
|
// (2) CompileCommand=option,Klass::method,type,flag,value
|
||||||
|
//
|
||||||
|
// Type (1) is used to support ciMethod::has_option("someflag")
|
||||||
|
// (i.e., to check if a flag "someflag" is enabled for a method).
|
||||||
|
//
|
||||||
|
// Type (2) is used to support options with a value. Values can have the
|
||||||
|
// the following types: intx, uintx, bool, ccstr, and ccstrlist. Currently,
|
||||||
|
// values of type intx, uintx, and bool are supported.
|
||||||
|
//
|
||||||
|
// For future extensions: extend scan_flag_and_value()
|
||||||
|
char option[256]; // stores flag for Type (1) and type of Type (2)
|
||||||
while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
|
while (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
|
||||||
if (match != NULL && !_quiet) {
|
if (match != NULL && !_quiet) {
|
||||||
// Print out the last match added
|
// Print out the last match added
|
||||||
|
ttyLocker ttyl;
|
||||||
tty->print("CompilerOracle: %s ", command_names[command]);
|
tty->print("CompilerOracle: %s ", command_names[command]);
|
||||||
match->print();
|
match->print();
|
||||||
}
|
}
|
||||||
match = add_option_string(c_name, c_match, m_name, m_match, signature, option);
|
|
||||||
line += bytes_read;
|
line += bytes_read;
|
||||||
}
|
|
||||||
} else {
|
if (strcmp(option, "intx") == 0
|
||||||
bytes_read = 0;
|
|| strcmp(option, "uintx") == 0
|
||||||
sscanf(line, "%*[ \t]%n", &bytes_read);
|
|| strcmp(option, "bool") == 0
|
||||||
if (line[bytes_read] != '\0') {
|
|| strcmp(option, "ccstr") == 0
|
||||||
jio_snprintf(errorbuf, sizeof(errorbuf), " Unrecognized text after command: %s", line);
|
|| strcmp(option, "ccstrlist") == 0
|
||||||
|
) {
|
||||||
|
|
||||||
|
// Type (2) option: parse flag name and value.
|
||||||
|
match = scan_flag_and_value(option, line, bytes_read,
|
||||||
|
c_name, c_match, m_name, m_match, signature,
|
||||||
|
errorbuf, sizeof(errorbuf));
|
||||||
|
if (match == NULL) {
|
||||||
error_msg = errorbuf;
|
error_msg = errorbuf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
line += bytes_read;
|
||||||
|
} else {
|
||||||
|
// Type (1) option
|
||||||
|
match = add_option_string(c_name, c_match, m_name, m_match, signature, option, true);
|
||||||
|
}
|
||||||
|
} // while(
|
||||||
} else {
|
} else {
|
||||||
match = add_predicate(command, c_name, c_match, m_name, m_match, signature);
|
match = add_predicate(command, c_name, c_match, m_name, m_match, signature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (match != NULL) {
|
ttyLocker ttyl;
|
||||||
if (!_quiet) {
|
if (error_msg != NULL) {
|
||||||
ResourceMark rm;
|
// an error has happened
|
||||||
tty->print("CompilerOracle: %s ", command_names[command]);
|
|
||||||
match->print();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tty->print_cr("CompilerOracle: unrecognized line");
|
tty->print_cr("CompilerOracle: unrecognized line");
|
||||||
tty->print_cr(" \"%s\"", original_line);
|
tty->print_cr(" \"%s\"", original_line);
|
||||||
if (error_msg != NULL) {
|
if (error_msg != NULL) {
|
||||||
tty->print_cr("%s", error_msg);
|
tty->print_cr("%s", error_msg);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// check for remaining characters
|
||||||
|
bytes_read = 0;
|
||||||
|
sscanf(line, "%*[ \t]%n", &bytes_read);
|
||||||
|
if (line[bytes_read] != '\0') {
|
||||||
|
tty->print_cr("CompilerOracle: unrecognized line");
|
||||||
|
tty->print_cr(" \"%s\"", original_line);
|
||||||
|
tty->print_cr(" Unrecognized text %s after command ", line);
|
||||||
|
} else if (match != NULL && !_quiet) {
|
||||||
|
tty->print("CompilerOracle: %s ", command_names[command]);
|
||||||
|
match->print();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,11 @@ class CompilerOracle : AllStatic {
|
|||||||
// Check to see if this method has option set for it
|
// Check to see if this method has option set for it
|
||||||
static bool has_option_string(methodHandle method, const char * option);
|
static bool has_option_string(methodHandle method, const char * option);
|
||||||
|
|
||||||
|
// Check if method has option and value set. If yes, overwrite value and return true,
|
||||||
|
// otherwise leave value unchanged and return false.
|
||||||
|
template<typename T>
|
||||||
|
static bool has_option_value(methodHandle method, const char* option, T& value);
|
||||||
|
|
||||||
// Reads from string instead of file
|
// Reads from string instead of file
|
||||||
static void parse_from_string(const char* command_string, void (*parser)(char*));
|
static void parse_from_string(const char* command_string, void (*parser)(char*));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user