mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8256508: Improve CompileCommand flag
Reviewed-by: redestad, kvn
This commit is contained in:
parent
7aed9b65d0
commit
cfb175dfdf
22 changed files with 796 additions and 482 deletions
|
@ -3384,7 +3384,7 @@ void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) {
|
||||||
// Notify the runtime very infrequently only to take care of counter overflows
|
// Notify the runtime very infrequently only to take care of counter overflows
|
||||||
int freq_log = Tier23InlineeNotifyFreqLog;
|
int freq_log = Tier23InlineeNotifyFreqLog;
|
||||||
double scale;
|
double scale;
|
||||||
if (_method->has_option_value("CompileThresholdScaling", scale)) {
|
if (_method->has_option_value(CompileCommand::CompileThresholdScaling, scale)) {
|
||||||
freq_log = CompilerConfig::scaled_freq_log(freq_log, scale);
|
freq_log = CompilerConfig::scaled_freq_log(freq_log, scale);
|
||||||
}
|
}
|
||||||
increment_event_counter_impl(info, x->inlinee(), LIR_OprFact::intConst(InvocationCounter::count_increment), right_n_bits(freq_log), InvocationEntryBci, false, true);
|
increment_event_counter_impl(info, x->inlinee(), LIR_OprFact::intConst(InvocationCounter::count_increment), right_n_bits(freq_log), InvocationEntryBci, false, true);
|
||||||
|
@ -3425,7 +3425,7 @@ void LIRGenerator::increment_event_counter(CodeEmitInfo* info, LIR_Opr step, int
|
||||||
}
|
}
|
||||||
// Increment the appropriate invocation/backedge counter and notify the runtime.
|
// Increment the appropriate invocation/backedge counter and notify the runtime.
|
||||||
double scale;
|
double scale;
|
||||||
if (_method->has_option_value("CompileThresholdScaling", scale)) {
|
if (_method->has_option_value(CompileCommand::CompileThresholdScaling, scale)) {
|
||||||
freq_log = CompilerConfig::scaled_freq_log(freq_log, scale);
|
freq_log = CompilerConfig::scaled_freq_log(freq_log, scale);
|
||||||
}
|
}
|
||||||
increment_event_counter_impl(info, info->scope()->method(), step, right_n_bits(freq_log), bci, backedge, true);
|
increment_event_counter_impl(info, info->scope()->method(), step, right_n_bits(freq_log), bci, backedge, true);
|
||||||
|
|
|
@ -1043,17 +1043,17 @@ MethodCounters* ciMethod::ensure_method_counters() {
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciMethod::has_option
|
// ciMethod::has_option
|
||||||
//
|
//
|
||||||
bool ciMethod::has_option(const char* option) {
|
bool ciMethod::has_option(enum CompileCommand option) {
|
||||||
check_is_loaded();
|
check_is_loaded();
|
||||||
VM_ENTRY_MARK;
|
VM_ENTRY_MARK;
|
||||||
methodHandle mh(THREAD, get_Method());
|
methodHandle mh(THREAD, get_Method());
|
||||||
return CompilerOracle::has_option_string(mh, option);
|
return CompilerOracle::has_option(mh, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// ciMethod::has_option_value
|
// ciMethod::has_option_value
|
||||||
//
|
//
|
||||||
bool ciMethod::has_option_value(const char* option, double& value) {
|
bool ciMethod::has_option_value(enum CompileCommand option, double& value) {
|
||||||
check_is_loaded();
|
check_is_loaded();
|
||||||
VM_ENTRY_MARK;
|
VM_ENTRY_MARK;
|
||||||
methodHandle mh(THREAD, get_Method());
|
methodHandle mh(THREAD, get_Method());
|
||||||
|
|
|
@ -293,8 +293,8 @@ class ciMethod : public ciMetadata {
|
||||||
// Find the proper vtable index to invoke this method.
|
// Find the proper vtable index to invoke this method.
|
||||||
int resolve_vtable_index(ciKlass* caller, ciKlass* receiver);
|
int resolve_vtable_index(ciKlass* caller, ciKlass* receiver);
|
||||||
|
|
||||||
bool has_option(const char *option);
|
bool has_option(enum CompileCommand option);
|
||||||
bool has_option_value(const char* option, double& value);
|
bool has_option_value(enum CompileCommand option, double& value);
|
||||||
bool can_be_compiled();
|
bool can_be_compiled();
|
||||||
bool can_be_parsed() const { return _can_be_parsed; }
|
bool can_be_parsed() const { return _can_be_parsed; }
|
||||||
bool has_compiled_code();
|
bool has_compiled_code();
|
||||||
|
|
|
@ -978,15 +978,15 @@ void nmethod::print_nmethod(bool printmethod) {
|
||||||
#if defined(SUPPORT_DATA_STRUCTS)
|
#if defined(SUPPORT_DATA_STRUCTS)
|
||||||
if (AbstractDisassembler::show_structs()) {
|
if (AbstractDisassembler::show_structs()) {
|
||||||
methodHandle mh(Thread::current(), _method);
|
methodHandle mh(Thread::current(), _method);
|
||||||
if (printmethod || PrintDebugInfo || CompilerOracle::has_option_string(mh, "PrintDebugInfo")) {
|
if (printmethod || PrintDebugInfo || CompilerOracle::has_option(mh, CompileCommand::PrintDebugInfo)) {
|
||||||
print_scopes();
|
print_scopes();
|
||||||
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
||||||
}
|
}
|
||||||
if (printmethod || PrintRelocations || CompilerOracle::has_option_string(mh, "PrintRelocations")) {
|
if (printmethod || PrintRelocations || CompilerOracle::has_option(mh, CompileCommand::PrintRelocations)) {
|
||||||
print_relocations();
|
print_relocations();
|
||||||
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
||||||
}
|
}
|
||||||
if (printmethod || PrintDependencies || CompilerOracle::has_option_string(mh, "PrintDependencies")) {
|
if (printmethod || PrintDependencies || CompilerOracle::has_option(mh, CompileCommand::PrintDependencies)) {
|
||||||
print_dependencies();
|
print_dependencies();
|
||||||
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1585,8 +1585,8 @@ bool CompileBroker::compilation_is_prohibited(const methodHandle& method, int os
|
||||||
|
|
||||||
// The method may be explicitly excluded by the user.
|
// The method may be explicitly excluded by the user.
|
||||||
double scale;
|
double scale;
|
||||||
if (excluded || (CompilerOracle::has_option_value(method, "CompileThresholdScaling", scale) && scale == 0)) {
|
if (excluded || (CompilerOracle::has_option_value(method, CompileCommand::CompileThresholdScaling, scale) && scale == 0)) {
|
||||||
bool quietly = CompilerOracle::should_exclude_quietly();
|
bool quietly = CompilerOracle::be_quiet();
|
||||||
if (PrintCompilation && !quietly) {
|
if (PrintCompilation && !quietly) {
|
||||||
// This does not happen quietly...
|
// This does not happen quietly...
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
|
@ -140,7 +140,7 @@ bool CompilerDirectives::match(const methodHandle& method) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerDirectives::add_match(char* str, const char*& error_msg) {
|
bool CompilerDirectives::add_match(char* str, const char*& error_msg) {
|
||||||
BasicMatcher* bm = BasicMatcher::parse_method_pattern(str, error_msg);
|
BasicMatcher* bm = BasicMatcher::parse_method_pattern(str, error_msg, false);
|
||||||
if (bm == NULL) {
|
if (bm == NULL) {
|
||||||
assert(error_msg != NULL, "Must have error message");
|
assert(error_msg != NULL, "Must have error message");
|
||||||
return false;
|
return false;
|
||||||
|
@ -326,7 +326,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
|
||||||
// Early bail out - checking all options is expensive - we rely on them not being used
|
// Early bail out - checking all options is expensive - we rely on them not being used
|
||||||
// Only set a flag if it has not been modified and value changes.
|
// Only set a flag if it has not been modified and value changes.
|
||||||
// Only copy set if a flag needs to be set
|
// Only copy set if a flag needs to be set
|
||||||
if (!CompilerDirectivesIgnoreCompileCommandsOption && CompilerOracle::has_any_option()) {
|
if (!CompilerDirectivesIgnoreCompileCommandsOption && CompilerOracle::has_any_command_set()) {
|
||||||
DirectiveSetPtr set(this);
|
DirectiveSetPtr set(this);
|
||||||
|
|
||||||
// All CompileCommands are not equal so this gets a bit verbose
|
// All CompileCommands are not equal so this gets a bit verbose
|
||||||
|
@ -359,8 +359,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
// inline and dontinline (including exclude) are implemented in the directiveset accessors
|
// inline and dontinline (including exclude) are implemented in the directiveset accessors
|
||||||
// ignore flags whose cc_flags are X
|
#define init_default_cc(name, type, dvalue, cc_flag) { type v; if (!_modified[name##Index] && CompilerOracle::has_option_value(method, CompileCommand::cc_flag, v) && v != this->name##Option) { set.cloned()->name##Option = v; } }
|
||||||
#define init_default_cc(name, type, dvalue, cc_flag) { type v; if (!_modified[name##Index] && CompilerOracle::has_option_value(method, #cc_flag, v) && v != this->name##Option) { set.cloned()->name##Option = v; } }
|
|
||||||
compilerdirectives_common_flags(init_default_cc)
|
compilerdirectives_common_flags(init_default_cc)
|
||||||
compilerdirectives_c2_flags(init_default_cc)
|
compilerdirectives_c2_flags(init_default_cc)
|
||||||
compilerdirectives_c1_flags(init_default_cc)
|
compilerdirectives_c1_flags(init_default_cc)
|
||||||
|
@ -370,7 +369,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
|
||||||
bool need_reset = true; // if Control/DisableIntrinsic redefined, only need to reset control_words once
|
bool need_reset = true; // if Control/DisableIntrinsic redefined, only need to reset control_words once
|
||||||
|
|
||||||
if (!_modified[ControlIntrinsicIndex] &&
|
if (!_modified[ControlIntrinsicIndex] &&
|
||||||
CompilerOracle::has_option_value(method, "ControlIntrinsic", option_value)) {
|
CompilerOracle::has_option_value(method, CompileCommand::ControlIntrinsic, option_value)) {
|
||||||
ControlIntrinsicIter iter(option_value);
|
ControlIntrinsicIter iter(option_value);
|
||||||
|
|
||||||
if (need_reset) {
|
if (need_reset) {
|
||||||
|
@ -390,7 +389,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
|
||||||
|
|
||||||
|
|
||||||
if (!_modified[DisableIntrinsicIndex] &&
|
if (!_modified[DisableIntrinsicIndex] &&
|
||||||
CompilerOracle::has_option_value(method, "DisableIntrinsic", option_value)) {
|
CompilerOracle::has_option_value(method, CompileCommand::DisableIntrinsic, option_value)) {
|
||||||
ControlIntrinsicIter iter(option_value, true/*disable_all*/);
|
ControlIntrinsicIter iter(option_value, true/*disable_all*/);
|
||||||
|
|
||||||
if (need_reset) {
|
if (need_reset) {
|
||||||
|
|
|
@ -34,11 +34,11 @@
|
||||||
|
|
||||||
// Directives flag name, type, default value, compile command name
|
// Directives flag name, type, default value, compile command name
|
||||||
#define compilerdirectives_common_flags(cflags) \
|
#define compilerdirectives_common_flags(cflags) \
|
||||||
cflags(Enable, bool, false, X) \
|
cflags(Enable, bool, false, Unknown) \
|
||||||
cflags(Exclude, bool, false, X) \
|
cflags(Exclude, bool, false, Unknown) \
|
||||||
cflags(BreakAtExecute, bool, false, BreakAtExecute) \
|
cflags(BreakAtExecute, bool, false, BreakAtExecute) \
|
||||||
cflags(BreakAtCompile, bool, false, BreakAtCompile) \
|
cflags(BreakAtCompile, bool, false, BreakAtCompile) \
|
||||||
cflags(Log, bool, LogCompilation, X) \
|
cflags(Log, bool, LogCompilation, Unknown) \
|
||||||
cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly) \
|
cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly) \
|
||||||
cflags(PrintInlining, bool, PrintInlining, PrintInlining) \
|
cflags(PrintInlining, bool, PrintInlining, PrintInlining) \
|
||||||
cflags(PrintNMethods, bool, PrintNMethods, PrintNMethods) \
|
cflags(PrintNMethods, bool, PrintNMethods, PrintNMethods) \
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
cflags(ReplayInline, bool, false, ReplayInline) \
|
cflags(ReplayInline, bool, false, ReplayInline) \
|
||||||
cflags(DumpReplay, bool, false, DumpReplay) \
|
cflags(DumpReplay, bool, false, DumpReplay) \
|
||||||
cflags(DumpInline, bool, false, DumpInline) \
|
cflags(DumpInline, bool, false, DumpInline) \
|
||||||
cflags(CompilerDirectivesIgnoreCompileCommands, bool, CompilerDirectivesIgnoreCompileCommands, X) \
|
cflags(CompilerDirectivesIgnoreCompileCommands, bool, CompilerDirectivesIgnoreCompileCommands, Unknown) \
|
||||||
cflags(DisableIntrinsic, ccstrlist, DisableIntrinsic, DisableIntrinsic) \
|
cflags(DisableIntrinsic, ccstrlist, DisableIntrinsic, DisableIntrinsic) \
|
||||||
cflags(ControlIntrinsic, ccstrlist, ControlIntrinsic, ControlIntrinsic) \
|
cflags(ControlIntrinsic, ccstrlist, ControlIntrinsic, ControlIntrinsic) \
|
||||||
cflags(RepeatCompilation, intx, RepeatCompilation, RepeatCompilation)
|
cflags(RepeatCompilation, intx, RepeatCompilation, RepeatCompilation)
|
||||||
|
|
|
@ -38,83 +38,72 @@
|
||||||
#include "runtime/jniHandles.hpp"
|
#include "runtime/jniHandles.hpp"
|
||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
|
|
||||||
enum OptionType {
|
static const char* optiontype_names[] = {
|
||||||
IntxType,
|
#define enum_of_types(type, name) name,
|
||||||
UintxType,
|
OPTION_TYPES(enum_of_types)
|
||||||
BoolType,
|
#undef enum_of_types
|
||||||
CcstrType,
|
|
||||||
DoubleType,
|
|
||||||
UnknownType
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char* optiontype2name(enum OptionType type) {
|
||||||
|
return optiontype_names[static_cast<int>(type)];
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum OptionType option_types[] = {
|
||||||
|
#define enum_of_options(option, name, ctype) OptionType::ctype,
|
||||||
|
COMPILECOMMAND_OPTIONS(enum_of_options)
|
||||||
|
#undef enum_of_options
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OptionType option2type(enum CompileCommand option) {
|
||||||
|
return option_types[static_cast<int>(option)];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* option_names[] = {
|
||||||
|
#define enum_of_options(option, name, ctype) name,
|
||||||
|
COMPILECOMMAND_OPTIONS(enum_of_options)
|
||||||
|
#undef enum_of_options
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* option2name(enum CompileCommand option) {
|
||||||
|
return option_names[static_cast<int>(option)];
|
||||||
|
}
|
||||||
|
|
||||||
/* Methods to map real type names to OptionType */
|
/* Methods to map real type names to OptionType */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static OptionType get_type_for() {
|
static OptionType get_type_for() {
|
||||||
return UnknownType;
|
return OptionType::Unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> OptionType get_type_for<intx>() {
|
template<> OptionType get_type_for<intx>() {
|
||||||
return IntxType;
|
return OptionType::Intx;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> OptionType get_type_for<uintx>() {
|
template<> OptionType get_type_for<uintx>() {
|
||||||
return UintxType;
|
return OptionType::Uintx;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> OptionType get_type_for<bool>() {
|
template<> OptionType get_type_for<bool>() {
|
||||||
return BoolType;
|
return OptionType::Bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> OptionType get_type_for<ccstr>() {
|
template<> OptionType get_type_for<ccstr>() {
|
||||||
return CcstrType;
|
return OptionType::Ccstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> OptionType get_type_for<double>() {
|
template<> OptionType get_type_for<double>() {
|
||||||
return DoubleType;
|
return OptionType::Double;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this must parallel the command_names below
|
|
||||||
enum OracleCommand {
|
|
||||||
UnknownCommand = -1,
|
|
||||||
OracleFirstCommand = 0,
|
|
||||||
BreakCommand = OracleFirstCommand,
|
|
||||||
PrintCommand,
|
|
||||||
ExcludeCommand,
|
|
||||||
InlineCommand,
|
|
||||||
DontInlineCommand,
|
|
||||||
CompileOnlyCommand,
|
|
||||||
LogCommand,
|
|
||||||
OptionCommand,
|
|
||||||
QuietCommand,
|
|
||||||
HelpCommand,
|
|
||||||
OracleCommandCount
|
|
||||||
};
|
|
||||||
|
|
||||||
// this must parallel the enum OracleCommand
|
|
||||||
static const char * command_names[] = {
|
|
||||||
"break",
|
|
||||||
"print",
|
|
||||||
"exclude",
|
|
||||||
"inline",
|
|
||||||
"dontinline",
|
|
||||||
"compileonly",
|
|
||||||
"log",
|
|
||||||
"option",
|
|
||||||
"quiet",
|
|
||||||
"help"
|
|
||||||
};
|
|
||||||
|
|
||||||
class MethodMatcher;
|
class MethodMatcher;
|
||||||
class TypedMethodOptionMatcher;
|
class TypedMethodOptionMatcher;
|
||||||
|
|
||||||
static BasicMatcher* lists[OracleCommandCount] = { 0, };
|
|
||||||
static TypedMethodOptionMatcher* option_list = NULL;
|
static TypedMethodOptionMatcher* option_list = NULL;
|
||||||
static bool any_set = false;
|
static bool any_set = false;
|
||||||
|
|
||||||
class TypedMethodOptionMatcher : public MethodMatcher {
|
class TypedMethodOptionMatcher : public MethodMatcher {
|
||||||
private:
|
private:
|
||||||
TypedMethodOptionMatcher* _next;
|
TypedMethodOptionMatcher* _next;
|
||||||
const char* _option;
|
enum CompileCommand _option;
|
||||||
OptionType _type;
|
OptionType _type;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -128,29 +117,36 @@ class TypedMethodOptionMatcher : public MethodMatcher {
|
||||||
|
|
||||||
TypedMethodOptionMatcher() : MethodMatcher(),
|
TypedMethodOptionMatcher() : MethodMatcher(),
|
||||||
_next(NULL),
|
_next(NULL),
|
||||||
_type(UnknownType) {
|
_option(CompileCommand::Unknown),
|
||||||
_option = NULL;
|
_type(OptionType::Unknown) {
|
||||||
memset(&_u, 0, sizeof(_u));
|
memset(&_u, 0, sizeof(_u));
|
||||||
}
|
}
|
||||||
|
|
||||||
static TypedMethodOptionMatcher* parse_method_pattern(char*& line, const char*& error_msg);
|
~TypedMethodOptionMatcher();
|
||||||
TypedMethodOptionMatcher* match(const methodHandle& method, const char* opt, OptionType type);
|
static TypedMethodOptionMatcher* parse_method_pattern(char*& line, char* errorbuf, const int buf_size);
|
||||||
|
TypedMethodOptionMatcher* match(const methodHandle &method, enum CompileCommand option, OptionType type);
|
||||||
|
|
||||||
void init(const char* opt, OptionType type, TypedMethodOptionMatcher* next) {
|
void init(enum CompileCommand option, OptionType type, TypedMethodOptionMatcher* next) {
|
||||||
_next = next;
|
_next = next;
|
||||||
_type = type;
|
_type = type;
|
||||||
_option = os::strdup_check_oom(opt);
|
_option = option;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_matcher(Symbol* class_name, Mode class_mode,
|
||||||
|
Symbol* method_name, Mode method_mode,
|
||||||
|
Symbol* signature) {
|
||||||
|
MethodMatcher::init(class_name, class_mode, method_name, method_mode, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_next(TypedMethodOptionMatcher* next) {_next = next; }
|
void set_next(TypedMethodOptionMatcher* next) {_next = next; }
|
||||||
TypedMethodOptionMatcher* next() { return _next; }
|
TypedMethodOptionMatcher* next() { return _next; }
|
||||||
OptionType type() { return _type; }
|
OptionType type() { return _type; }
|
||||||
|
enum CompileCommand option() { return _option; }
|
||||||
template<typename T> T value();
|
template<typename T> T value();
|
||||||
template<typename T> void set_value(T value);
|
template<typename T> void set_value(T value);
|
||||||
void print();
|
void print();
|
||||||
void print_all();
|
void print_all();
|
||||||
TypedMethodOptionMatcher* clone();
|
TypedMethodOptionMatcher* clone();
|
||||||
~TypedMethodOptionMatcher();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A few templated accessors instead of a full template class.
|
// A few templated accessors instead of a full template class.
|
||||||
|
@ -197,21 +193,22 @@ template<> void TypedMethodOptionMatcher::set_value(ccstr value) {
|
||||||
void TypedMethodOptionMatcher::print() {
|
void TypedMethodOptionMatcher::print() {
|
||||||
ttyLocker ttyl;
|
ttyLocker ttyl;
|
||||||
print_base(tty);
|
print_base(tty);
|
||||||
|
const char* name = option2name(_option);
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case IntxType:
|
case OptionType::Intx:
|
||||||
tty->print_cr(" intx %s = " INTX_FORMAT, _option, value<intx>());
|
tty->print_cr(" intx %s = " INTX_FORMAT, name, value<intx>());
|
||||||
break;
|
break;
|
||||||
case UintxType:
|
case OptionType::Uintx:
|
||||||
tty->print_cr(" uintx %s = " UINTX_FORMAT, _option, value<uintx>());
|
tty->print_cr(" uintx %s = " UINTX_FORMAT, name, value<uintx>());
|
||||||
break;
|
break;
|
||||||
case BoolType:
|
case OptionType::Bool:
|
||||||
tty->print_cr(" bool %s = %s", _option, value<bool>() ? "true" : "false");
|
tty->print_cr(" bool %s = %s", name, value<bool>() ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
case DoubleType:
|
case OptionType::Double:
|
||||||
tty->print_cr(" double %s = %f", _option, value<double>());
|
tty->print_cr(" double %s = %f", name, value<double>());
|
||||||
break;
|
break;
|
||||||
case CcstrType:
|
case OptionType::Ccstr:
|
||||||
tty->print_cr(" const char* %s = '%s'", _option, value<ccstr>());
|
tty->print_cr(" const char* %s = '%s'", name, value<ccstr>());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
|
@ -247,78 +244,90 @@ TypedMethodOptionMatcher* TypedMethodOptionMatcher::clone() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedMethodOptionMatcher::~TypedMethodOptionMatcher() {
|
TypedMethodOptionMatcher::~TypedMethodOptionMatcher() {
|
||||||
if (type() == CcstrType) {
|
if (type() == OptionType::Ccstr) {
|
||||||
ccstr v = value<ccstr>();
|
ccstr v = value<ccstr>();
|
||||||
os::free((void*)v);
|
os::free((void*)v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_option != NULL) {
|
|
||||||
os::free((void*)_option);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedMethodOptionMatcher* TypedMethodOptionMatcher::parse_method_pattern(char*& line, const char*& error_msg) {
|
TypedMethodOptionMatcher* TypedMethodOptionMatcher::parse_method_pattern(char*& line, char* errorbuf, const int buf_size) {
|
||||||
assert(error_msg == NULL, "Dont call here with error_msg already set");
|
assert(*errorbuf == '\0', "Dont call here with error_msg already set");
|
||||||
|
const char* error_msg = NULL;
|
||||||
TypedMethodOptionMatcher* tom = new TypedMethodOptionMatcher();
|
TypedMethodOptionMatcher* tom = new TypedMethodOptionMatcher();
|
||||||
MethodMatcher::parse_method_pattern(line, error_msg, tom);
|
MethodMatcher::parse_method_pattern(line, error_msg, tom);
|
||||||
if (error_msg != NULL) {
|
if (error_msg != NULL) {
|
||||||
|
jio_snprintf(errorbuf, buf_size, error_msg);
|
||||||
delete tom;
|
delete tom;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return tom;
|
return tom;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& method, const char* opt, OptionType type) {
|
TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& method, enum CompileCommand option, OptionType type) {
|
||||||
TypedMethodOptionMatcher* current = this;
|
TypedMethodOptionMatcher* current = this;
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
// Fastest compare first.
|
if (current->_option == option) {
|
||||||
if (current->type() == type) {
|
|
||||||
if (strcmp(current->_option, opt) == 0) {
|
|
||||||
if (current->matches(method)) {
|
if (current->matches(method)) {
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
current = current->next();
|
current = current->next();
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void add_option_string(TypedMethodOptionMatcher* matcher,
|
static void register_command(TypedMethodOptionMatcher* matcher,
|
||||||
const char* option,
|
enum CompileCommand option,
|
||||||
T value) {
|
T value) {
|
||||||
assert(matcher != option_list, "No circular lists please");
|
assert(matcher != option_list, "No circular lists please");
|
||||||
matcher->init(option, get_type_for<T>(), option_list);
|
if (option == CompileCommand::Log && !LogCompilation) {
|
||||||
|
tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged with ");
|
||||||
|
tty->print_cr(" CompileCommand=log,<method pattern>");
|
||||||
|
}
|
||||||
|
enum OptionType type = option2type(option);
|
||||||
|
if (type == OptionType::Ccstrlist) {
|
||||||
|
type = OptionType::Ccstr; // ccstrlists are stores as ccstr
|
||||||
|
}
|
||||||
|
assert(type == get_type_for<T>(), "sanity");
|
||||||
|
matcher->init(option, type, option_list);
|
||||||
matcher->set_value<T>(value);
|
matcher->set_value<T>(value);
|
||||||
option_list = matcher;
|
option_list = matcher;
|
||||||
|
if ((option != CompileCommand::DontInline) &&
|
||||||
|
(option != CompileCommand::Inline) &&
|
||||||
|
(option != CompileCommand::Log)) {
|
||||||
any_set = true;
|
any_set = true;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (!CompilerOracle::be_quiet()) {
|
||||||
static bool check_predicate(OracleCommand command, const methodHandle& method) {
|
// Print out the succesful registration of a comile command
|
||||||
return ((lists[command] != NULL) &&
|
ttyLocker ttyl;
|
||||||
!method.is_null() &&
|
tty->print("CompileCommand: %s ", option2name(option));
|
||||||
lists[command]->match(method));
|
matcher->print();
|
||||||
}
|
|
||||||
|
|
||||||
static void add_predicate(OracleCommand command, BasicMatcher* bm) {
|
|
||||||
assert(command != OptionCommand, "must use add_option_string");
|
|
||||||
if (command == LogCommand && !LogCompilation && lists[LogCommand] == NULL) {
|
|
||||||
tty->print_cr("Warning: +LogCompilation must be enabled in order for individual methods to be logged.");
|
|
||||||
}
|
|
||||||
bm->set_next(lists[command]);
|
|
||||||
lists[command] = bm;
|
|
||||||
if ((command != DontInlineCommand) && (command != InlineCommand)) {
|
|
||||||
any_set = true;
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool CompilerOracle::has_option_value(const methodHandle& method, const char* option, T& value) {
|
bool CompilerOracle::has_option_value(const methodHandle& method, enum CompileCommand option, T& value, bool verify_type) {
|
||||||
|
enum OptionType type = option2type(option);
|
||||||
|
if (type == OptionType::Unknown) {
|
||||||
|
return false; // Can't query options with type Unknown.
|
||||||
|
}
|
||||||
|
if (type == OptionType::Ccstrlist) {
|
||||||
|
type = OptionType::Ccstr; // CCstrList type options are stored as Ccstr
|
||||||
|
}
|
||||||
|
if (verify_type) {
|
||||||
|
if (type != get_type_for<T>()) {
|
||||||
|
// Whitebox API expects false if option and type doesn't match
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(type == get_type_for<T>(), "Value type (%s) must match option %s (%s)",
|
||||||
|
optiontype2name(get_type_for<T>()),
|
||||||
|
option2name(option), optiontype2name(option2type(option)));
|
||||||
|
}
|
||||||
if (option_list != NULL) {
|
if (option_list != NULL) {
|
||||||
TypedMethodOptionMatcher* m = option_list->match(method, option, get_type_for<T>());
|
TypedMethodOptionMatcher* m = option_list->match(method, option, type);
|
||||||
if (m != NULL) {
|
if (m != NULL) {
|
||||||
value = m->value<T>();
|
value = m->value<T>();
|
||||||
return true;
|
return true;
|
||||||
|
@ -327,98 +336,144 @@ bool CompilerOracle::has_option_value(const methodHandle& method, const char* op
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerOracle::has_any_option() {
|
static bool check_predicate(enum CompileCommand option, const methodHandle& method) {
|
||||||
|
bool value = false;
|
||||||
|
if (CompilerOracle::has_option_value(method, option, value)) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool has_command(enum CompileCommand option) {
|
||||||
|
TypedMethodOptionMatcher* m = option_list;
|
||||||
|
while (m != NULL) {
|
||||||
|
if (m->option() == option) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
m = m->next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CompilerOracle::has_any_command_set() {
|
||||||
return any_set;
|
return any_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explicit instantiation for all OptionTypes supported.
|
// Explicit instantiation for all OptionTypes supported.
|
||||||
template bool CompilerOracle::has_option_value<intx>(const methodHandle& method, const char* option, intx& value);
|
template bool CompilerOracle::has_option_value<intx>(const methodHandle& method, enum CompileCommand option, intx& value, bool verify_type);
|
||||||
template bool CompilerOracle::has_option_value<uintx>(const methodHandle& method, const char* option, uintx& value);
|
template bool CompilerOracle::has_option_value<uintx>(const methodHandle& method, enum CompileCommand option, uintx& value, bool verify_type);
|
||||||
template bool CompilerOracle::has_option_value<bool>(const methodHandle& method, const char* option, bool& value);
|
template bool CompilerOracle::has_option_value<bool>(const methodHandle& method, enum CompileCommand option, bool& value, bool verify_type);
|
||||||
template bool CompilerOracle::has_option_value<ccstr>(const methodHandle& method, const char* option, ccstr& value);
|
template bool CompilerOracle::has_option_value<ccstr>(const methodHandle& method, enum CompileCommand option, ccstr& value, bool verify_type);
|
||||||
template bool CompilerOracle::has_option_value<double>(const methodHandle& method, const char* option, double& value);
|
template bool CompilerOracle::has_option_value<double>(const methodHandle& method, enum CompileCommand option, double& value, bool verify_type);
|
||||||
|
|
||||||
bool CompilerOracle::has_option_string(const methodHandle& method, const char* option) {
|
bool CompilerOracle::has_option(const methodHandle& method, enum CompileCommand option) {
|
||||||
bool value = false;
|
bool value = false;
|
||||||
has_option_value(method, option, value);
|
has_option_value(method, option, value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerOracle::should_exclude(const methodHandle& method) {
|
bool CompilerOracle::should_exclude(const methodHandle& method) {
|
||||||
if (check_predicate(ExcludeCommand, method)) {
|
if (check_predicate(CompileCommand::Exclude, method)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (lists[CompileOnlyCommand] != NULL) {
|
if (has_command(CompileCommand::CompileOnly)) {
|
||||||
return !lists[CompileOnlyCommand]->match(method);
|
return !check_predicate(CompileCommand::CompileOnly, method);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerOracle::should_inline(const methodHandle& method) {
|
bool CompilerOracle::should_inline(const methodHandle& method) {
|
||||||
return (check_predicate(InlineCommand, method));
|
return (check_predicate(CompileCommand::Inline, method));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerOracle::should_not_inline(const methodHandle& method) {
|
bool CompilerOracle::should_not_inline(const methodHandle& method) {
|
||||||
return check_predicate(DontInlineCommand, method) || check_predicate(ExcludeCommand, method);
|
return check_predicate(CompileCommand::DontInline, method) || check_predicate(CompileCommand::Exclude, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerOracle::should_print(const methodHandle& method) {
|
bool CompilerOracle::should_print(const methodHandle& method) {
|
||||||
return check_predicate(PrintCommand, method);
|
return check_predicate(CompileCommand::Print, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerOracle::should_print_methods() {
|
bool CompilerOracle::should_print_methods() {
|
||||||
return lists[PrintCommand] != NULL;
|
return has_command(CompileCommand::Print);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerOracle::should_log(const methodHandle& method) {
|
bool CompilerOracle::should_log(const methodHandle& method) {
|
||||||
if (!LogCompilation) return false;
|
if (!LogCompilation) return false;
|
||||||
if (lists[LogCommand] == NULL) return true; // by default, log all
|
if (!has_command(CompileCommand::Log)) {
|
||||||
return (check_predicate(LogCommand, method));
|
return true; // by default, log all
|
||||||
|
}
|
||||||
|
return (check_predicate(CompileCommand::Log, method));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerOracle::should_break_at(const methodHandle& method) {
|
bool CompilerOracle::should_break_at(const methodHandle& method) {
|
||||||
return check_predicate(BreakCommand, method);
|
return check_predicate(CompileCommand::Break, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
static OracleCommand parse_command_name(const char * line, int* bytes_read) {
|
static enum CompileCommand parse_option_name(const char* line, int* bytes_read, char* errorbuf, int bufsize) {
|
||||||
assert(ARRAY_SIZE(command_names) == OracleCommandCount,
|
assert(ARRAY_SIZE(option_names) == static_cast<int>(CompileCommand::Count), "option_names size mismatch");
|
||||||
"command_names size mismatch");
|
|
||||||
|
|
||||||
*bytes_read = 0;
|
*bytes_read = 0;
|
||||||
char command[33];
|
char option_buf[256];
|
||||||
int matches = sscanf(line, "%32[a-z]%n", command, bytes_read);
|
int matches = sscanf(line, "%255[a-zA-Z0-9]%n", option_buf, bytes_read);
|
||||||
if (matches > 0) {
|
if (matches > 0) {
|
||||||
for (uint i = 0; i < ARRAY_SIZE(command_names); i++) {
|
for (uint i = 0; i < ARRAY_SIZE(option_names); i++) {
|
||||||
if (strcmp(command, command_names[i]) == 0) {
|
if (strcasecmp(option_buf, option_names[i]) == 0) {
|
||||||
return (OracleCommand)i;
|
return static_cast<enum CompileCommand>(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UnknownCommand;
|
jio_snprintf(errorbuf, bufsize, "Unrecognized option '%s'", option_buf);
|
||||||
|
return CompileCommand::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_tip() { // CMH Update info
|
||||||
|
tty->cr();
|
||||||
|
tty->print_cr("Usage: '-XX:CompileCommand=<option>,<method pattern>' - to set boolean option to true");
|
||||||
|
tty->print_cr("Usage: '-XX:CompileCommand=<option>,<method pattern>,<value>'");
|
||||||
|
tty->print_cr("Use: '-XX:CompileCommand=help' for more information and to list all option.");
|
||||||
|
tty->cr();
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_option(enum CompileCommand option, const char* name, enum OptionType type) {
|
||||||
|
if (type != OptionType::Unknown) {
|
||||||
|
tty->print_cr(" %s (%s)", name, optiontype2name(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_commands() {
|
||||||
|
tty->cr();
|
||||||
|
tty->print_cr("All available options:");
|
||||||
|
#define enum_of_options(option, name, ctype) print_option(CompileCommand::option, name, OptionType::ctype);
|
||||||
|
COMPILECOMMAND_OPTIONS(enum_of_options)
|
||||||
|
#undef enum_of_options
|
||||||
|
tty->cr();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usage() {
|
static void usage() {
|
||||||
tty->cr();
|
tty->cr();
|
||||||
tty->print_cr("The CompileCommand option enables the user of the JVM to control specific");
|
tty->print_cr("The CompileCommand option enables the user of the JVM to control specific");
|
||||||
tty->print_cr("behavior of the dynamic compilers. Many commands require a pattern that defines");
|
tty->print_cr("behavior of the dynamic compilers.");
|
||||||
tty->print_cr("the set of methods the command shall be applied to. The CompileCommand");
|
|
||||||
tty->print_cr("option provides the following commands:");
|
|
||||||
tty->cr();
|
tty->cr();
|
||||||
tty->print_cr(" break,<pattern> - debug breakpoint in compiler and in generated code");
|
tty->print_cr("Compile commands has this general form:");
|
||||||
tty->print_cr(" print,<pattern> - print assembly");
|
tty->print_cr("-XX:CompileCommand=<option><method pattern><value>");
|
||||||
tty->print_cr(" exclude,<pattern> - don't compile or inline");
|
tty->print_cr(" Sets <option> to the specified value for methods matching <method pattern>");
|
||||||
tty->print_cr(" inline,<pattern> - always inline");
|
tty->print_cr(" All options are typed");
|
||||||
tty->print_cr(" dontinline,<pattern> - don't inline");
|
|
||||||
tty->print_cr(" compileonly,<pattern> - compile only");
|
|
||||||
tty->print_cr(" log,<pattern> - log compilation");
|
|
||||||
tty->print_cr(" option,<pattern>,<option type>,<option name>,<value>");
|
|
||||||
tty->print_cr(" - set value of custom option");
|
|
||||||
tty->print_cr(" option,<pattern>,<bool option name>");
|
|
||||||
tty->print_cr(" - shorthand for setting boolean flag");
|
|
||||||
tty->print_cr(" quiet - silence the compile command output");
|
|
||||||
tty->print_cr(" help - print this text");
|
|
||||||
tty->cr();
|
tty->cr();
|
||||||
tty->print_cr("The preferred format for the method matching pattern is:");
|
tty->print_cr("-XX:CompileCommand=<option><method pattern>");
|
||||||
|
tty->print_cr(" Sets <option> to true for methods matching <method pattern>");
|
||||||
|
tty->print_cr(" Only applies to boolean options.");
|
||||||
|
tty->cr();
|
||||||
|
tty->print_cr("-XX:CompileCommand=quiet");
|
||||||
|
tty->print_cr(" Silence the compile command output");
|
||||||
|
tty->cr();
|
||||||
|
tty->print_cr("-XX:CompileCommand=help");
|
||||||
|
tty->print_cr(" Prints this help text");
|
||||||
|
tty->cr();
|
||||||
|
print_commands();
|
||||||
|
tty->cr();
|
||||||
|
tty->print_cr("Method patterns has the format:");
|
||||||
tty->print_cr(" package/Class.method()");
|
tty->print_cr(" package/Class.method()");
|
||||||
tty->cr();
|
tty->cr();
|
||||||
tty->print_cr("For backward compatibility this form is also allowed:");
|
tty->print_cr("For backward compatibility this form is also allowed:");
|
||||||
|
@ -428,7 +483,7 @@ static void usage() {
|
||||||
tty->print_cr(" package/Class.method ()");
|
tty->print_cr(" package/Class.method ()");
|
||||||
tty->cr();
|
tty->cr();
|
||||||
tty->print_cr("The class and method identifier can be used together with leading or");
|
tty->print_cr("The class and method identifier can be used together with leading or");
|
||||||
tty->print_cr("trailing *'s for a small amount of wildcarding:");
|
tty->print_cr("trailing *'s for wildcard matching:");
|
||||||
tty->print_cr(" *ackage/Clas*.*etho*()");
|
tty->print_cr(" *ackage/Clas*.*etho*()");
|
||||||
tty->cr();
|
tty->cr();
|
||||||
tty->print_cr("It is possible to use more than one CompileCommand on the command line:");
|
tty->print_cr("It is possible to use more than one CompileCommand on the command line:");
|
||||||
|
@ -447,59 +502,68 @@ static void usage() {
|
||||||
tty->cr();
|
tty->cr();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Scan next flag and value in line, return MethodMatcher object on success, NULL on failure.
|
int skip_whitespace(char* &line) {
|
||||||
// On failure, error_msg contains description for the first error.
|
// Skip any leading spaces
|
||||||
// For future extensions: set error_msg on first error.
|
int whitespace_read = 0;
|
||||||
static void scan_flag_and_value(const char* type, const char* line, int& total_bytes_read,
|
sscanf(line, "%*[ \t]%n", &whitespace_read);
|
||||||
TypedMethodOptionMatcher* matcher,
|
line += whitespace_read;
|
||||||
char* errorbuf, const int buf_size) {
|
return whitespace_read;
|
||||||
total_bytes_read = 0;
|
}
|
||||||
|
|
||||||
|
void skip_comma(char* &line) {
|
||||||
|
// Skip any leading spaces
|
||||||
|
if (*line == ',') {
|
||||||
|
line++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
|
||||||
|
TypedMethodOptionMatcher* matcher, enum CompileCommand option, char* errorbuf, const int buf_size) {
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
char flag[256];
|
const char* ccname = option2name(option);
|
||||||
|
const char* type_str = optiontype2name(type);
|
||||||
// Read flag name.
|
int skipped = skip_whitespace(line);
|
||||||
if (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", flag, &bytes_read) == 1) {
|
total_bytes_read += skipped;
|
||||||
line += bytes_read;
|
if (type == OptionType::Intx) {
|
||||||
total_bytes_read += bytes_read;
|
|
||||||
|
|
||||||
// Read value.
|
|
||||||
if (strcmp(type, "intx") == 0) {
|
|
||||||
intx value;
|
intx value;
|
||||||
if (sscanf(line, "%*[ \t]" INTX_FORMAT "%n", &value, &bytes_read) == 1) {
|
if (sscanf(line, "" INTX_FORMAT "%n", &value, &bytes_read) == 1) {
|
||||||
total_bytes_read += bytes_read;
|
total_bytes_read += bytes_read;
|
||||||
add_option_string(matcher, flag, value);
|
line += bytes_read;
|
||||||
|
register_command(matcher, option, value);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s ", flag, type);
|
jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str);
|
||||||
}
|
}
|
||||||
} else if (strcmp(type, "uintx") == 0) {
|
} else if (type == OptionType::Uintx) {
|
||||||
uintx value;
|
uintx value;
|
||||||
if (sscanf(line, "%*[ \t]" UINTX_FORMAT "%n", &value, &bytes_read) == 1) {
|
if (sscanf(line, "" UINTX_FORMAT "%n", &value, &bytes_read) == 1) {
|
||||||
total_bytes_read += bytes_read;
|
total_bytes_read += bytes_read;
|
||||||
add_option_string(matcher, flag, value);
|
line += bytes_read;
|
||||||
|
register_command(matcher, option, value);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
|
jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str);
|
||||||
}
|
}
|
||||||
} else if (strcmp(type, "ccstr") == 0) {
|
} else if (type == OptionType::Ccstr) {
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1);
|
char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1);
|
||||||
if (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9]%n", value, &bytes_read) == 1) {
|
if (sscanf(line, "%255[_a-zA-Z0-9]%n", value, &bytes_read) == 1) {
|
||||||
total_bytes_read += bytes_read;
|
total_bytes_read += bytes_read;
|
||||||
add_option_string(matcher, flag, (ccstr)value);
|
line += bytes_read;
|
||||||
|
register_command(matcher, option, (ccstr) value);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
|
jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str);
|
||||||
}
|
}
|
||||||
} else if (strcmp(type, "ccstrlist") == 0) {
|
} else if (type == OptionType::Ccstrlist) {
|
||||||
// Accumulates several strings into one. The internal type is ccstr.
|
// Accumulates several strings into one. The internal type is ccstr.
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1);
|
char* value = NEW_RESOURCE_ARRAY(char, strlen(line) + 1);
|
||||||
char* next_value = value;
|
char* next_value = value;
|
||||||
if (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9+\\-]%n", next_value, &bytes_read) == 1) {
|
if (sscanf(line, "%255[_a-zA-Z0-9+\\-]%n", next_value, &bytes_read) == 1) {
|
||||||
total_bytes_read += bytes_read;
|
total_bytes_read += bytes_read;
|
||||||
line += bytes_read;
|
line += bytes_read;
|
||||||
next_value += bytes_read;
|
next_value += bytes_read + 1;
|
||||||
char* end_value = next_value - 1;
|
char* end_value = next_value - 1;
|
||||||
while (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9+\\-]%n", next_value, &bytes_read) == 1) {
|
while (sscanf(line, "%*[ \t]%255[_a-zA-Z0-9+\\-]%n", next_value, &bytes_read) == 1) {
|
||||||
total_bytes_read += bytes_read;
|
total_bytes_read += bytes_read;
|
||||||
|
@ -508,184 +572,236 @@ static void scan_flag_and_value(const char* type, const char* line, int& total_b
|
||||||
next_value += bytes_read;
|
next_value += bytes_read;
|
||||||
end_value = next_value-1;
|
end_value = next_value-1;
|
||||||
}
|
}
|
||||||
add_option_string(matcher, flag, (ccstr)value);
|
register_command(matcher, option, (ccstr) value);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
|
jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str);
|
||||||
}
|
}
|
||||||
} else if (strcmp(type, "bool") == 0) {
|
} else if (type == OptionType::Bool) {
|
||||||
char value[256];
|
char value[256];
|
||||||
if (sscanf(line, "%*[ \t]%255[a-zA-Z]%n", value, &bytes_read) == 1) {
|
if (*line == '\0') {
|
||||||
if (strcmp(value, "true") == 0) {
|
// Short version of a CompileCommand sets a boolean Option to true
|
||||||
total_bytes_read += bytes_read;
|
// -XXCompileCommand=<Option>,<method pattern>
|
||||||
add_option_string(matcher, flag, true);
|
register_command(matcher, option, true);
|
||||||
return;
|
return;
|
||||||
} else if (strcmp(value, "false") == 0) {
|
}
|
||||||
|
if (sscanf(line, "%255[a-zA-Z]%n", value, &bytes_read) == 1) {
|
||||||
|
if (strcasecmp(value, "true") == 0) {
|
||||||
total_bytes_read += bytes_read;
|
total_bytes_read += bytes_read;
|
||||||
add_option_string(matcher, flag, false);
|
line += bytes_read;
|
||||||
|
register_command(matcher, option, true);
|
||||||
|
return;
|
||||||
|
} else if (strcasecmp(value, "false") == 0) {
|
||||||
|
total_bytes_read += bytes_read;
|
||||||
|
line += bytes_read;
|
||||||
|
register_command(matcher, option, false);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
|
jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
|
jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str);
|
||||||
}
|
}
|
||||||
} else if (strcmp(type, "double") == 0) {
|
} else if (type == OptionType::Double) {
|
||||||
char buffer[2][256];
|
char buffer[2][256];
|
||||||
// Decimal separator '.' has been replaced with ' ' or '/' earlier,
|
// Decimal separator '.' has been replaced with ' ' or '/' earlier,
|
||||||
// so read integer and fraction part of double value separately.
|
// so read integer and fraction part of double value separately.
|
||||||
if (sscanf(line, "%*[ \t]%255[0-9]%*[ /\t]%255[0-9]%n", buffer[0], buffer[1], &bytes_read) == 2) {
|
if (sscanf(line, "%255[0-9]%*[ /\t]%255[0-9]%n", buffer[0], buffer[1], &bytes_read) == 2) {
|
||||||
char value[512] = "";
|
char value[512] = "";
|
||||||
jio_snprintf(value, sizeof(value), "%s.%s", buffer[0], buffer[1]);
|
jio_snprintf(value, sizeof(value), "%s.%s", buffer[0], buffer[1]);
|
||||||
total_bytes_read += bytes_read;
|
total_bytes_read += bytes_read;
|
||||||
add_option_string(matcher, flag, atof(value));
|
line += bytes_read;
|
||||||
|
register_command(matcher, option, atof(value));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type);
|
jio_snprintf(errorbuf, buf_size, "Value cannot be read for option '%s' of type '%s'", ccname, type_str);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Type %s not supported ", type);
|
jio_snprintf(errorbuf, buf_size, "Type '%s' not supported ", type_str);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan next option 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 void scan_option_and_value(enum OptionType type, char* line, int& total_bytes_read,
|
||||||
|
TypedMethodOptionMatcher* matcher,
|
||||||
|
char* errorbuf, const int buf_size) {
|
||||||
|
total_bytes_read = 0;
|
||||||
|
int bytes_read = 0;
|
||||||
|
char option_buf[256];
|
||||||
|
|
||||||
|
// Read option name.
|
||||||
|
if (sscanf(line, "%*[ \t]%255[a-zA-Z0-9]%n", option_buf, &bytes_read) == 1) {
|
||||||
|
line += bytes_read;
|
||||||
|
total_bytes_read += bytes_read;
|
||||||
|
int bytes_read2 = 0;
|
||||||
|
total_bytes_read += skip_whitespace(line);
|
||||||
|
enum CompileCommand option = parse_option_name(option_buf, &bytes_read2, errorbuf, buf_size);
|
||||||
|
if (option == CompileCommand::Unknown) {
|
||||||
|
assert(*errorbuf != '\0', "error must have been set");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
enum OptionType optiontype = option2type(option);
|
||||||
|
if (option2type(option) != type) {
|
||||||
|
const char* optiontype_name = optiontype2name(optiontype);
|
||||||
|
const char* type_name = optiontype2name(type);
|
||||||
|
jio_snprintf(errorbuf, buf_size, "Option '%s' with type '%s' doesn't match supplied type '%s'", option_buf, optiontype_name, type_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
scan_value(type, line, total_bytes_read, matcher, option, errorbuf, buf_size);
|
||||||
} else {
|
} else {
|
||||||
jio_snprintf(errorbuf, buf_size, " Flag name for type %s should be alphanumeric ", type);
|
const char* type_str = optiontype2name(type);
|
||||||
|
jio_snprintf(errorbuf, buf_size, "Option name for type '%s' should be alphanumeric ", type_str);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int skip_whitespace(char* line) {
|
void CompilerOracle::print_parse_error(char* error_msg, char* original_line) {
|
||||||
// Skip any leading spaces
|
assert(*error_msg != '\0', "Must have error_message");
|
||||||
int whitespace_read = 0;
|
|
||||||
sscanf(line, "%*[ \t]%n", &whitespace_read);
|
|
||||||
return whitespace_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CompilerOracle::print_parse_error(const char*& error_msg, char* original_line) {
|
|
||||||
assert(error_msg != NULL, "Must have error_message");
|
|
||||||
|
|
||||||
ttyLocker ttyl;
|
ttyLocker ttyl;
|
||||||
tty->print_cr("CompileCommand: An error occurred during parsing");
|
tty->print_cr("CompileCommand: An error occurred during parsing");
|
||||||
tty->print_cr("Line: %s", original_line);
|
|
||||||
tty->print_cr("Error: %s", error_msg);
|
tty->print_cr("Error: %s", error_msg);
|
||||||
CompilerOracle::print_tip();
|
tty->print_cr("Line: '%s'", original_line);
|
||||||
|
print_tip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum OptionType parse_option_type(const char* type_str) {
|
||||||
|
for (uint i = 0; i < ARRAY_SIZE(optiontype_names); i++) {
|
||||||
|
if (strcasecmp(type_str, optiontype_names[i]) == 0) {
|
||||||
|
return static_cast<enum OptionType>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OptionType::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
class LineCopy : StackObj {
|
||||||
|
const char* _copy;
|
||||||
|
public:
|
||||||
|
LineCopy(char* line) {
|
||||||
|
_copy = os::strdup(line, mtInternal);
|
||||||
|
}
|
||||||
|
~LineCopy() {
|
||||||
|
os::free((void*)_copy);
|
||||||
|
}
|
||||||
|
char* get() {
|
||||||
|
return (char*)_copy;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
char* original_line = line;
|
LineCopy original(line);
|
||||||
int bytes_read;
|
int bytes_read;
|
||||||
OracleCommand command = parse_command_name(line, &bytes_read);
|
char error_buf[1024] = {0};
|
||||||
|
|
||||||
|
enum CompileCommand option = parse_option_name(line, &bytes_read, error_buf, sizeof(error_buf));
|
||||||
line += bytes_read;
|
line += bytes_read;
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
if (command == UnknownCommand) {
|
if (option == CompileCommand::Unknown) {
|
||||||
ttyLocker ttyl;
|
print_parse_error(error_buf, original.get());
|
||||||
tty->print_cr("CompileCommand: unrecognized command");
|
|
||||||
tty->print_cr(" \"%s\"", original_line);
|
|
||||||
CompilerOracle::print_tip();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == QuietCommand) {
|
if (option == CompileCommand::Quiet) {
|
||||||
_quiet = true;
|
_quiet = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == HelpCommand) {
|
if (option == CompileCommand::Help) {
|
||||||
usage();
|
usage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* error_msg = NULL;
|
if (option == CompileCommand::Option) {
|
||||||
if (command == OptionCommand) {
|
|
||||||
// Look for trailing options.
|
// Look for trailing options.
|
||||||
//
|
//
|
||||||
// Two types of trailing options are
|
// Two types of trailing options are
|
||||||
// supported:
|
// supported:
|
||||||
//
|
//
|
||||||
// (1) CompileCommand=option,Klass::method,flag
|
// (1) CompileCommand=option,Klass::method,option
|
||||||
// (2) CompileCommand=option,Klass::method,type,flag,value
|
// (2) CompileCommand=option,Klass::method,type,option,value
|
||||||
//
|
//
|
||||||
// Type (1) is used to enable a boolean flag for a method.
|
// Type (1) is used to enable a boolean option for a method.
|
||||||
//
|
//
|
||||||
// Type (2) is used to support options with a value. Values can have the
|
// Type (2) is used to support options with a value. Values can have the
|
||||||
// the following types: intx, uintx, bool, ccstr, ccstrlist, and double.
|
// the following types: intx, uintx, bool, ccstr, ccstrlist, and double.
|
||||||
//
|
|
||||||
// For future extensions: extend scan_flag_and_value()
|
|
||||||
|
|
||||||
char option[256]; // stores flag for Type (1) and type of Type (2)
|
char option_type[256]; // stores option for Type (1) and type of Type (2)
|
||||||
line++; // skip the ','
|
skip_comma(line);
|
||||||
TypedMethodOptionMatcher* archetype = TypedMethodOptionMatcher::parse_method_pattern(line, error_msg);
|
TypedMethodOptionMatcher* archetype = TypedMethodOptionMatcher::parse_method_pattern(line, error_buf, sizeof(error_buf));
|
||||||
if (archetype == NULL) {
|
if (archetype == NULL) {
|
||||||
assert(error_msg != NULL, "Must have error_message");
|
print_parse_error(error_buf, original.get());
|
||||||
print_parse_error(error_msg, original_line);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
line += skip_whitespace(line);
|
skip_whitespace(line);
|
||||||
|
|
||||||
// This is unnecessarily complex. Should retire multi-option lines and skip while loop
|
// This is unnecessarily complex. Should retire multi-option lines and skip while loop
|
||||||
while (sscanf(line, "%255[a-zA-Z0-9]%n", option, &bytes_read) == 1) {
|
while (sscanf(line, "%255[a-zA-Z0-9]%n", option_type, &bytes_read) == 1) {
|
||||||
line += bytes_read;
|
line += bytes_read;
|
||||||
|
|
||||||
// typed_matcher is used as a blueprint for each option, deleted at the end
|
// typed_matcher is used as a blueprint for each option, deleted at the end
|
||||||
TypedMethodOptionMatcher* typed_matcher = archetype->clone();
|
TypedMethodOptionMatcher* typed_matcher = archetype->clone();
|
||||||
if (strcmp(option, "intx") == 0
|
enum OptionType type = parse_option_type(option_type);
|
||||||
|| strcmp(option, "uintx") == 0
|
if (type != OptionType::Unknown) {
|
||||||
|| strcmp(option, "bool") == 0
|
// Type (2) option: parse option name and value.
|
||||||
|| strcmp(option, "ccstr") == 0
|
scan_option_and_value(type, line, bytes_read, typed_matcher, error_buf, sizeof(error_buf));
|
||||||
|| strcmp(option, "ccstrlist") == 0
|
if (*error_buf != '\0') {
|
||||||
|| strcmp(option, "double") == 0
|
print_parse_error(error_buf, original.get());
|
||||||
) {
|
|
||||||
char errorbuf[1024] = {0};
|
|
||||||
// Type (2) option: parse flag name and value.
|
|
||||||
scan_flag_and_value(option, line, bytes_read, typed_matcher, errorbuf, sizeof(errorbuf));
|
|
||||||
if (*errorbuf != '\0') {
|
|
||||||
error_msg = errorbuf;
|
|
||||||
print_parse_error(error_msg, original_line);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
line += bytes_read;
|
line += bytes_read;
|
||||||
} else {
|
} else {
|
||||||
// Type (1) option
|
// Type (1) option - option_type contains the option name -> bool value = true is implied
|
||||||
add_option_string(typed_matcher, option, true);
|
int bytes_read;
|
||||||
}
|
enum CompileCommand option = parse_option_name(option_type, &bytes_read, error_buf, sizeof(error_buf));
|
||||||
if (typed_matcher != NULL && !_quiet) {
|
if (option == CompileCommand::Unknown) {
|
||||||
// Print out the last match added
|
print_parse_error(error_buf, original.get());
|
||||||
assert(error_msg == NULL, "No error here");
|
|
||||||
ttyLocker ttyl;
|
|
||||||
tty->print("CompileCommand: %s ", command_names[command]);
|
|
||||||
typed_matcher->print();
|
|
||||||
}
|
|
||||||
line += skip_whitespace(line);
|
|
||||||
} // while(
|
|
||||||
delete archetype;
|
|
||||||
} else { // not an OptionCommand)
|
|
||||||
assert(error_msg == NULL, "Don't call here with error_msg already set");
|
|
||||||
|
|
||||||
BasicMatcher* matcher = BasicMatcher::parse_method_pattern(line, error_msg);
|
|
||||||
if (error_msg != NULL) {
|
|
||||||
assert(matcher == NULL, "consistency");
|
|
||||||
print_parse_error(error_msg, original_line);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
register_command(typed_matcher, option, true);
|
||||||
add_predicate(command, matcher);
|
}
|
||||||
if (!_quiet) {
|
assert(typed_matcher != NULL, "sanity");
|
||||||
ttyLocker ttyl;
|
assert(*error_buf == '\0', "No error here");
|
||||||
tty->print("CompileCommand: %s ", command_names[command]);
|
skip_whitespace(line);
|
||||||
matcher->print(tty);
|
} // while(
|
||||||
tty->cr();
|
delete archetype;
|
||||||
|
} else { // not an OptionCommand
|
||||||
|
// Command has the following form:
|
||||||
|
// CompileCommand=<option>,<method pattern><value>
|
||||||
|
// CompileCommand=<option>,<method pattern> (implies option is bool and value is true)
|
||||||
|
assert(*error_buf == '\0', "Don't call here with error_buf already set");
|
||||||
|
enum OptionType type = option2type(option);
|
||||||
|
int bytes_read = 0;
|
||||||
|
skip_comma(line);
|
||||||
|
TypedMethodOptionMatcher* matcher = TypedMethodOptionMatcher::parse_method_pattern(line, error_buf, sizeof(error_buf));
|
||||||
|
if (matcher == NULL) {
|
||||||
|
print_parse_error(error_buf, original.get());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
skip_whitespace(line);
|
||||||
|
if (*line == '\0') {
|
||||||
|
// if this is a bool option this implies true
|
||||||
|
if (option2type(option) == OptionType::Bool) {
|
||||||
|
register_command(matcher, option, true);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
jio_snprintf(error_buf, sizeof(error_buf), " Option '%s' is not followed by a value", option2name(option));
|
||||||
|
print_parse_error(error_buf, original.get());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
scan_value(type, line, bytes_read, matcher, option, error_buf, sizeof(error_buf));
|
||||||
|
if (*error_buf != '\0') {
|
||||||
|
print_parse_error(error_buf, original.get());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assert(matcher != NULL, "consistency");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerOracle::print_tip() {
|
|
||||||
tty->cr();
|
|
||||||
tty->print_cr("Usage: '-XX:CompileCommand=command,\"package/Class.method()\"'");
|
|
||||||
tty->print_cr("Use: '-XX:CompileCommand=help' for more information.");
|
|
||||||
tty->cr();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* default_cc_file = ".hotspot_compiler";
|
static const char* default_cc_file = ".hotspot_compiler";
|
||||||
|
@ -760,7 +876,7 @@ void compilerOracle_init() {
|
||||||
default_cc_file, default_cc_file);
|
default_cc_file, default_cc_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lists[PrintCommand] != NULL) {
|
if (has_command(CompileCommand::Print)) {
|
||||||
if (PrintAssembly) {
|
if (PrintAssembly) {
|
||||||
warning("CompileCommand and/or %s file contains 'print' commands, but PrintAssembly is also enabled", default_cc_file);
|
warning("CompileCommand and/or %s file contains 'print' commands, but PrintAssembly is also enabled", default_cc_file);
|
||||||
} else if (FLAG_IS_DEFAULT(DebugNonSafepoints)) {
|
} else if (FLAG_IS_DEFAULT(DebugNonSafepoints)) {
|
||||||
|
@ -770,7 +886,6 @@ void compilerOracle_init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CompilerOracle::parse_compile_only(char* line) {
|
void CompilerOracle::parse_compile_only(char* line) {
|
||||||
int i;
|
int i;
|
||||||
char name[1024];
|
char name[1024];
|
||||||
|
@ -841,12 +956,12 @@ void CompilerOracle::parse_compile_only(char * line) {
|
||||||
Symbol* m_name = SymbolTable::new_symbol(methodName);
|
Symbol* m_name = SymbolTable::new_symbol(methodName);
|
||||||
Symbol* signature = NULL;
|
Symbol* signature = NULL;
|
||||||
|
|
||||||
BasicMatcher* bm = new BasicMatcher();
|
TypedMethodOptionMatcher* tom = new TypedMethodOptionMatcher();
|
||||||
bm->init(c_name, c_match, m_name, m_match, signature);
|
tom->init_matcher(c_name, c_match, m_name, m_match, signature);
|
||||||
add_predicate(CompileOnlyCommand, bm);
|
register_command(tom, CompileCommand::CompileOnly, true);
|
||||||
if (PrintVMOptions) {
|
if (PrintVMOptions) {
|
||||||
tty->print("CompileOnly: compileonly ");
|
tty->print("CompileOnly: compileonly ");
|
||||||
lists[CompileOnlyCommand]->print_all(tty);
|
tom->print();
|
||||||
}
|
}
|
||||||
|
|
||||||
className = NULL;
|
className = NULL;
|
||||||
|
@ -856,3 +971,9 @@ void CompilerOracle::parse_compile_only(char * line) {
|
||||||
line = *line == '\0' ? line : line + 1;
|
line = *line == '\0' ? line : line + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CompileCommand CompilerOracle::string_to_option(const char* name) {
|
||||||
|
int bytes_read = 0;
|
||||||
|
char errorbuf[1024] = {0};
|
||||||
|
return parse_option_name(name, &bytes_read, errorbuf, sizeof(errorbuf));
|
||||||
|
}
|
||||||
|
|
|
@ -30,17 +30,91 @@
|
||||||
|
|
||||||
class methodHandle;
|
class methodHandle;
|
||||||
|
|
||||||
|
|
||||||
// CompilerOracle is an interface for turning on and off compilation
|
// CompilerOracle is an interface for turning on and off compilation
|
||||||
// for some methods
|
// for some methods
|
||||||
|
|
||||||
|
// OPTION_TYPES: type, name
|
||||||
|
#define OPTION_TYPES(type) \
|
||||||
|
type(Intx, "intx") \
|
||||||
|
type(Uintx, "uintx") \
|
||||||
|
type(Bool, "bool") \
|
||||||
|
type(Ccstr, "ccstr") \
|
||||||
|
type(Ccstrlist, "ccstrlist") \
|
||||||
|
type(Double, "double")
|
||||||
|
|
||||||
|
// COMPILECOMMAND_OPTIONS: option, name, variant, type
|
||||||
|
#define COMPILECOMMAND_OPTIONS(option) \
|
||||||
|
option(Help, "help", Unknown) \
|
||||||
|
option(Quiet, "quiet", Unknown) \
|
||||||
|
option(Log, "log", Bool) \
|
||||||
|
option(Print, "print", Bool) \
|
||||||
|
option(Inline, "inline", Bool) \
|
||||||
|
option(DontInline, "dontinline", Bool) \
|
||||||
|
option(CompileOnly, "compileonly", Bool)\
|
||||||
|
option(Exclude, "exclude", Bool) \
|
||||||
|
option(Break, "break", Bool) \
|
||||||
|
option(BreakAtExecute, "BreakAtExecute", Bool) \
|
||||||
|
option(BreakAtCompile, "BreakAtCompile", Bool) \
|
||||||
|
option(PrintAssembly, "PrintAssembly", Bool) \
|
||||||
|
option(PrintInlining, "PrintInlining", Bool) \
|
||||||
|
option(PrintIntrinsics, "PrintIntrinsics", Bool) \
|
||||||
|
option(PrintNMethods, "PrintNMethods", Bool) \
|
||||||
|
option(PrintOptoAssembly, "PrintOptoAssembly", Bool) \
|
||||||
|
option(PrintDebugInfo, "PrintDebugInfo", Bool) \
|
||||||
|
option(PrintRelocations, "PrintRelocations", Bool) \
|
||||||
|
option(PrintDependencies, "PrintDependencies", Bool) \
|
||||||
|
option(BackgroundCompilation, "BackgroundCompilation", Bool) \
|
||||||
|
option(RepeatCompilation, "RepeatCompilation", Intx) \
|
||||||
|
option(ReplayInline, "ReplayInline", Bool) \
|
||||||
|
option(DumpReplay, "DumpReplay", Bool) \
|
||||||
|
option(DumpInline, "DumpInline", Bool) \
|
||||||
|
option(CompileThresholdScaling, "CompileThresholdScaling", Double) \
|
||||||
|
option(ControlIntrinsic, "ControlIntrinsic", Ccstrlist) \
|
||||||
|
option(DisableIntrinsic, "DisableIntrinsic", Ccstrlist) \
|
||||||
|
option(NoRTMLockEliding, "NoRTMLockEliding", Bool) \
|
||||||
|
option(UseRTMLockEliding, "UseRTMLockEliding", Bool) \
|
||||||
|
option(BlockLayoutByFrequency, "BlockLayoutByFrequency", Bool) \
|
||||||
|
option(TraceOptoPipelining, "TraceOptoPipelining", Bool) \
|
||||||
|
option(TraceOptoOutput, "TraceOptoOutput", Bool) \
|
||||||
|
option(TraceSpilling, "TraceSpilling", Bool) \
|
||||||
|
option(PrintIdeal, "PrintIdeal", Bool) \
|
||||||
|
option(IGVPrintLevel, "IGVPrintLevel", Intx) \
|
||||||
|
option(Vectorize, "Vectorize", Bool) \
|
||||||
|
option(VectorizeDebug, "VectorizeDebug", Uintx) \
|
||||||
|
option(CloneMapDebug, "CloneMapDebug", Bool) \
|
||||||
|
option(MaxNodeLimit, "MaxNodeLimit", Intx) \
|
||||||
|
NOT_PRODUCT(option(TestOptionInt, "TestOptionInt", Intx)) \
|
||||||
|
NOT_PRODUCT(option(TestOptionUint, "TestOptionUint", Uintx)) \
|
||||||
|
NOT_PRODUCT(option(TestOptionBool, "TestOptionBool", Bool)) \
|
||||||
|
NOT_PRODUCT(option(TestOptionBool2, "TestOptionBool2", Bool)) \
|
||||||
|
NOT_PRODUCT(option(TestOptionStr, "TestOptionStr", Ccstr)) \
|
||||||
|
NOT_PRODUCT(option(TestOptionList, "TestOptionList", Ccstrlist)) \
|
||||||
|
NOT_PRODUCT(option(TestOptionDouble, "TestOptionDouble", Double)) \
|
||||||
|
option(Option, "option", Unknown) \
|
||||||
|
option(Unknown, "unknown", Unknown)
|
||||||
|
|
||||||
|
enum class CompileCommand {
|
||||||
|
#define enum_of_options(option, name, ctype) option,
|
||||||
|
COMPILECOMMAND_OPTIONS(enum_of_options)
|
||||||
|
#undef enum_of_options
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class OptionType {
|
||||||
|
#define enum_of_types(type, name) type,
|
||||||
|
OPTION_TYPES(enum_of_types)
|
||||||
|
#undef enum_of_types
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
class CompilerOracle : AllStatic {
|
class CompilerOracle : AllStatic {
|
||||||
private:
|
private:
|
||||||
static bool _quiet;
|
static bool _quiet;
|
||||||
static void print_tip();
|
static void print_parse_error(char* error_msg, char* original_line);
|
||||||
static void print_parse_error(const char*& error_msg, char* original_line);
|
static void print_command(enum CompileCommand option, const char* name, enum OptionType type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// True if the command file has been specified or is implicit
|
// True if the command file has been specified or is implicit
|
||||||
static bool has_command_file();
|
static bool has_command_file();
|
||||||
|
|
||||||
|
@ -49,7 +123,7 @@ class CompilerOracle : AllStatic {
|
||||||
|
|
||||||
// Tells whether we to exclude compilation of method
|
// Tells whether we to exclude compilation of method
|
||||||
static bool should_exclude(const methodHandle& method);
|
static bool should_exclude(const methodHandle& method);
|
||||||
static bool should_exclude_quietly() { return _quiet; }
|
static bool be_quiet() { return _quiet; }
|
||||||
|
|
||||||
// Tells whether we want to inline this method
|
// Tells whether we want to inline this method
|
||||||
static bool should_inline(const methodHandle& method);
|
static bool should_inline(const methodHandle& method);
|
||||||
|
@ -66,25 +140,28 @@ class CompilerOracle : AllStatic {
|
||||||
// Tells whether to break when compiling method
|
// Tells whether to break when compiling method
|
||||||
static bool should_break_at(const methodHandle& method);
|
static bool should_break_at(const methodHandle& method);
|
||||||
|
|
||||||
// Check to see if this method has option set for it
|
// Tells whether there are any methods to print for print_method_statistics()
|
||||||
static bool has_option_string(const methodHandle& method, const char * option);
|
static bool should_print_methods();
|
||||||
|
|
||||||
|
// A wrapper for checking bool options
|
||||||
|
static bool has_option(const methodHandle& method, enum CompileCommand option);
|
||||||
|
|
||||||
// Check if method has option and value set. If yes, overwrite value and return true,
|
// Check if method has option and value set. If yes, overwrite value and return true,
|
||||||
// otherwise leave value unchanged and return false.
|
// otherwise leave value unchanged and return false.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static bool has_option_value(const methodHandle& method, const char* option, T& value);
|
static bool has_option_value(const methodHandle& method, enum CompileCommand option, T& value, bool verfiy_type = false);
|
||||||
|
|
||||||
// Fast check if there is any option available that compile control needs to know about
|
|
||||||
static bool has_any_option();
|
|
||||||
|
|
||||||
// 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* option_string, void (*parser)(char*));
|
||||||
|
|
||||||
static void parse_from_line(char* line);
|
static void parse_from_line(char* line);
|
||||||
static void parse_compile_only(char* line);
|
static void parse_compile_only(char* line);
|
||||||
|
|
||||||
// Tells whether there are any methods to print for print_method_statistics()
|
// Fast check if there is any option set that compile control needs to know about
|
||||||
static bool should_print_methods();
|
static bool has_any_command_set();
|
||||||
|
|
||||||
|
// convert a string to a proper compilecommand option - used from whitebox.
|
||||||
|
// returns CompileCommand::Unknown on names not matching an option.
|
||||||
|
static enum CompileCommand string_to_option(const char* name);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_COMPILER_COMPILERORACLE_HPP
|
#endif // SHARE_COMPILER_COMPILERORACLE_HPP
|
||||||
|
|
|
@ -259,6 +259,10 @@ void MethodMatcher::parse_method_pattern(char*& line, const char*& error_msg, Me
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_leading_spaces(line, &total_bytes_read);
|
skip_leading_spaces(line, &total_bytes_read);
|
||||||
|
if (*line == '\0') {
|
||||||
|
error_msg = "Method pattern missing from command";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (2 == sscanf(line, "%255" RANGESLASH "%*[ ]" "%255" RANGE0 "%n", class_name, method_name, &bytes_read)) {
|
if (2 == sscanf(line, "%255" RANGESLASH "%*[ ]" "%255" RANGE0 "%n", class_name, method_name, &bytes_read)) {
|
||||||
c_match = check_mode(class_name, error_msg);
|
c_match = check_mode(class_name, error_msg);
|
||||||
|
@ -352,7 +356,7 @@ void MethodMatcher::print_base(outputStream* st) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicMatcher* BasicMatcher::parse_method_pattern(char* line, const char*& error_msg) {
|
BasicMatcher* BasicMatcher::parse_method_pattern(char* line, const char*& error_msg, bool expect_trailing_chars) {
|
||||||
assert(error_msg == NULL, "Don't call here with error_msg already set");
|
assert(error_msg == NULL, "Don't call here with error_msg already set");
|
||||||
BasicMatcher *bm = new BasicMatcher();
|
BasicMatcher *bm = new BasicMatcher();
|
||||||
MethodMatcher::parse_method_pattern(line, error_msg, bm);
|
MethodMatcher::parse_method_pattern(line, error_msg, bm);
|
||||||
|
@ -360,7 +364,7 @@ BasicMatcher* BasicMatcher::parse_method_pattern(char* line, const char*& error_
|
||||||
delete bm;
|
delete bm;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (!expect_trailing_chars) {
|
||||||
// check for bad trailing characters
|
// check for bad trailing characters
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
sscanf(line, "%*[ \t]%n", &bytes_read);
|
sscanf(line, "%*[ \t]%n", &bytes_read);
|
||||||
|
@ -369,6 +373,7 @@ BasicMatcher* BasicMatcher::parse_method_pattern(char* line, const char*& error_
|
||||||
delete bm;
|
delete bm;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return bm;
|
return bm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,7 +431,6 @@ InlineMatcher* InlineMatcher::parse_inline_pattern(char* str, const char*& error
|
||||||
}
|
}
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
int bytes_read = 0;
|
|
||||||
assert(error_msg == NULL, "error_msg must not be set yet");
|
assert(error_msg == NULL, "error_msg must not be set yet");
|
||||||
InlineMatcher* im = InlineMatcher::parse_method_pattern(str, error_msg);
|
InlineMatcher* im = InlineMatcher::parse_method_pattern(str, error_msg);
|
||||||
if (im == NULL) {
|
if (im == NULL) {
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
_next(next) {
|
_next(next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static BasicMatcher* parse_method_pattern(char* line, const char*& error_msg);
|
static BasicMatcher* parse_method_pattern(char* line, const char*& error_msg, bool expect_trailing_chars);
|
||||||
bool match(const methodHandle& method);
|
bool match(const methodHandle& method);
|
||||||
void set_next(BasicMatcher* next) { _next = next; }
|
void set_next(BasicMatcher* next) { _next = next; }
|
||||||
BasicMatcher* next() { return _next; }
|
BasicMatcher* next() { return _next; }
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
bool TieredThresholdPolicy::call_predicate_helper(const methodHandle& method, CompLevel cur_level, int i, int b, double scale) {
|
bool TieredThresholdPolicy::call_predicate_helper(const methodHandle& method, CompLevel cur_level, int i, int b, double scale) {
|
||||||
double threshold_scaling;
|
double threshold_scaling;
|
||||||
if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
|
if (CompilerOracle::has_option_value(method, CompileCommand::CompileThresholdScaling, threshold_scaling)) {
|
||||||
scale *= threshold_scaling;
|
scale *= threshold_scaling;
|
||||||
}
|
}
|
||||||
switch(cur_level) {
|
switch(cur_level) {
|
||||||
|
@ -78,7 +78,7 @@ bool TieredThresholdPolicy::call_predicate_helper(const methodHandle& method, Co
|
||||||
|
|
||||||
bool TieredThresholdPolicy::loop_predicate_helper(const methodHandle& method, CompLevel cur_level, int i, int b, double scale) {
|
bool TieredThresholdPolicy::loop_predicate_helper(const methodHandle& method, CompLevel cur_level, int i, int b, double scale) {
|
||||||
double threshold_scaling;
|
double threshold_scaling;
|
||||||
if (CompilerOracle::has_option_value(method, "CompileThresholdScaling", threshold_scaling)) {
|
if (CompilerOracle::has_option_value(method, CompileCommand::CompileThresholdScaling, threshold_scaling)) {
|
||||||
scale *= threshold_scaling;
|
scale *= threshold_scaling;
|
||||||
}
|
}
|
||||||
switch(cur_level) {
|
switch(cur_level) {
|
||||||
|
|
|
@ -94,7 +94,7 @@ class MethodCounters : public Metadata {
|
||||||
|
|
||||||
// Set per-method thresholds.
|
// Set per-method thresholds.
|
||||||
double scale = 1.0;
|
double scale = 1.0;
|
||||||
CompilerOracle::has_option_value(mh, "CompileThresholdScaling", scale);
|
CompilerOracle::has_option_value(mh, CompileCommand::CompileThresholdScaling, scale);
|
||||||
|
|
||||||
int compile_threshold = CompilerConfig::scaled_compile_threshold(CompileThreshold, scale);
|
int compile_threshold = CompilerConfig::scaled_compile_threshold(CompileThreshold, scale);
|
||||||
_interpreter_invocation_limit = compile_threshold << InvocationCounter::count_shift;
|
_interpreter_invocation_limit = compile_threshold << InvocationCounter::count_shift;
|
||||||
|
|
|
@ -1289,7 +1289,7 @@ void MethodData::init() {
|
||||||
// Set per-method invoke- and backedge mask.
|
// Set per-method invoke- and backedge mask.
|
||||||
double scale = 1.0;
|
double scale = 1.0;
|
||||||
methodHandle mh(Thread::current(), _method);
|
methodHandle mh(Thread::current(), _method);
|
||||||
CompilerOracle::has_option_value(mh, "CompileThresholdScaling", scale);
|
CompilerOracle::has_option_value(mh, CompileCommand::CompileThresholdScaling, scale);
|
||||||
_invoke_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
|
_invoke_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0InvokeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
|
||||||
_backedge_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
|
_backedge_mask = right_n_bits(CompilerConfig::scaled_freq_log(Tier0BackedgeNotifyFreqLog, scale)) << InvocationCounter::count_shift;
|
||||||
|
|
||||||
|
@ -1306,8 +1306,8 @@ void MethodData::init() {
|
||||||
#if INCLUDE_RTM_OPT
|
#if INCLUDE_RTM_OPT
|
||||||
_rtm_state = NoRTM; // No RTM lock eliding by default
|
_rtm_state = NoRTM; // No RTM lock eliding by default
|
||||||
if (UseRTMLocking &&
|
if (UseRTMLocking &&
|
||||||
!CompilerOracle::has_option_string(mh, "NoRTMLockEliding")) {
|
!CompilerOracle::has_option(mh, CompileCommand::NoRTMLockEliding)) {
|
||||||
if (CompilerOracle::has_option_string(mh, "UseRTMLockEliding") || !UseRTMDeopt) {
|
if (CompilerOracle::has_option(mh, CompileCommand::UseRTMLockEliding) || !UseRTMDeopt) {
|
||||||
// Generate RTM lock eliding code without abort ratio calculation code.
|
// Generate RTM lock eliding code without abort ratio calculation code.
|
||||||
_rtm_state = UseRTM;
|
_rtm_state = UseRTM;
|
||||||
} else if (UseRTMDeopt) {
|
} else if (UseRTMDeopt) {
|
||||||
|
|
|
@ -953,10 +953,10 @@ void Compile::Init(int aliaslevel) {
|
||||||
#if INCLUDE_RTM_OPT
|
#if INCLUDE_RTM_OPT
|
||||||
if (UseRTMLocking && has_method() && (method()->method_data_or_null() != NULL)) {
|
if (UseRTMLocking && has_method() && (method()->method_data_or_null() != NULL)) {
|
||||||
int rtm_state = method()->method_data()->rtm_state();
|
int rtm_state = method()->method_data()->rtm_state();
|
||||||
if (method_has_option("NoRTMLockEliding") || ((rtm_state & NoRTM) != 0)) {
|
if (method_has_option(CompileCommand::NoRTMLockEliding) || ((rtm_state & NoRTM) != 0)) {
|
||||||
// Don't generate RTM lock eliding code.
|
// Don't generate RTM lock eliding code.
|
||||||
set_rtm_state(NoRTM);
|
set_rtm_state(NoRTM);
|
||||||
} else if (method_has_option("UseRTMLockEliding") || ((rtm_state & UseRTM) != 0) || !UseRTMDeopt) {
|
} else if (method_has_option(CompileCommand::UseRTMLockEliding) || ((rtm_state & UseRTM) != 0) || !UseRTMDeopt) {
|
||||||
// Generate RTM lock eliding code without abort ratio calculation code.
|
// Generate RTM lock eliding code without abort ratio calculation code.
|
||||||
set_rtm_state(UseRTM);
|
set_rtm_state(UseRTM);
|
||||||
} else if (UseRTMDeopt) {
|
} else if (UseRTMDeopt) {
|
||||||
|
|
|
@ -594,7 +594,7 @@ class Compile : public Phase {
|
||||||
void set_clinit_barrier_on_entry(bool z) { _clinit_barrier_on_entry = z; }
|
void set_clinit_barrier_on_entry(bool z) { _clinit_barrier_on_entry = z; }
|
||||||
|
|
||||||
// check the CompilerOracle for special behaviours for this compile
|
// check the CompilerOracle for special behaviours for this compile
|
||||||
bool method_has_option(const char * option) {
|
bool method_has_option(enum CompileCommand option) {
|
||||||
return method() != NULL && method()->has_option(option);
|
return method() != NULL && method()->has_option(option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1056,7 +1056,7 @@ WB_ENTRY(jint, WB_MatchesMethod(JNIEnv* env, jobject o, jobject method, jstring
|
||||||
|
|
||||||
const char* error_msg = NULL;
|
const char* error_msg = NULL;
|
||||||
|
|
||||||
BasicMatcher* m = BasicMatcher::parse_method_pattern(method_str, error_msg);
|
BasicMatcher* m = BasicMatcher::parse_method_pattern(method_str, error_msg, false);
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
assert(error_msg != NULL, "Must have error_msg");
|
assert(error_msg != NULL, "Must have error_msg");
|
||||||
tty->print_cr("Got error: %s", error_msg);
|
tty->print_cr("Got error: %s", error_msg);
|
||||||
|
@ -1810,9 +1810,12 @@ static bool GetMethodOption(JavaThread* thread, JNIEnv* env, jobject method, jst
|
||||||
ThreadToNativeFromVM ttnfv(thread);
|
ThreadToNativeFromVM ttnfv(thread);
|
||||||
const char* flag_name = env->GetStringUTFChars(name, NULL);
|
const char* flag_name = env->GetStringUTFChars(name, NULL);
|
||||||
CHECK_JNI_EXCEPTION_(env, false);
|
CHECK_JNI_EXCEPTION_(env, false);
|
||||||
bool result = CompilerOracle::has_option_value(mh, flag_name, *value);
|
enum CompileCommand option = CompilerOracle::string_to_option(flag_name);
|
||||||
env->ReleaseStringUTFChars(name, flag_name);
|
env->ReleaseStringUTFChars(name, flag_name);
|
||||||
return result;
|
if (option == CompileCommand::Unknown) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return CompilerOracle::has_option_value(mh, option, *value, true /* verify type*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
WB_ENTRY(jobject, WB_GetMethodBooleaneOption(JNIEnv* env, jobject wb, jobject method, jstring name))
|
WB_ENTRY(jobject, WB_GetMethodBooleaneOption(JNIEnv* env, jobject wb, jobject method, jstring name))
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @modules java.base/jdk.internal.misc
|
* @modules java.base/jdk.internal.misc
|
||||||
* java.management
|
* java.management
|
||||||
|
* @requires vm.debug == true
|
||||||
* @run driver compiler.oracle.CheckCompileCommandOption
|
* @run driver compiler.oracle.CheckCompileCommandOption
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -43,12 +44,12 @@ public class CheckCompileCommandOption {
|
||||||
// Currently, two types of trailing options can be used with
|
// Currently, two types of trailing options can be used with
|
||||||
// -XX:CompileCommand=option
|
// -XX:CompileCommand=option
|
||||||
//
|
//
|
||||||
// (1) CompileCommand=option,Klass::method,flag
|
// (1) CompileCommand=option,Klass::method,option
|
||||||
// (2) CompileCommand=option,Klass::method,type,flag,value
|
// (2) CompileCommand=option,Klass::method,type,option,value
|
||||||
//
|
//
|
||||||
// Type (1) is used to enable a boolean flag for a method.
|
// Type (1) is used to enable a boolean option for a method.
|
||||||
//
|
//
|
||||||
// Type (2) is used to support flags with a value. Values can
|
// Type (2) is used to support options with a value. Values can
|
||||||
// have the the following types: intx, uintx, bool, ccstr,
|
// have the the following types: intx, uintx, bool, ccstr,
|
||||||
// ccstrlist, and double.
|
// ccstrlist, and double.
|
||||||
|
|
||||||
|
@ -65,85 +66,145 @@ public class CheckCompileCommandOption {
|
||||||
|
|
||||||
private static final String[][] FILE_EXPECTED_OUTPUT = {
|
private static final String[][] FILE_EXPECTED_OUTPUT = {
|
||||||
{
|
{
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
|
"com/oracle/Test.test1 bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
|
"com/oracle/Test.test2 bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
|
"com/oracle/Test.test3 bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
|
"com/oracle/Test.test4 bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
|
"com/oracle/Test.test4 bool TestOptionBool2 = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
|
"com/oracle/Test.test5 bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption8 = true",
|
"com/oracle/Test.test5 bool TestOptionBool2 = true",
|
||||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption9 = true",
|
"com/oracle/Test.test6(I) bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption10 = true",
|
"com/oracle/Test.test7(I) bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption11 = true",
|
"com/oracle/Test.test8(I) bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption13 = true",
|
"com/oracle/Test.test9(I) bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption14 = true",
|
"com/oracle/Test.test9(I) bool TestOptionBool2 = true",
|
||||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption15 = true",
|
"com/oracle/Test.test10(I) bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption16 = true"
|
"com/oracle/Test.test10(I) bool TestOptionBool2 = true"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
|
"Test.test const char* TestOptionList = '_foo _bar'",
|
||||||
"CompileCommand: option Test.test const char* MyStrOption = '_foo'",
|
"Test.test const char* TestOptionStr = '_foo'",
|
||||||
"CompileCommand: option Test.test bool MyBoolOption = false",
|
"Test.test bool TestOptionBool = false",
|
||||||
"CompileCommand: option Test.test intx MyIntxOption = -1",
|
"Test.test intx TestOptionInt = -1",
|
||||||
"CompileCommand: option Test.test uintx MyUintxOption = 1",
|
"Test.test uintx TestOptionUint = 1",
|
||||||
"CompileCommand: option Test.test bool MyFlag = true",
|
"Test.test bool TestOptionBool2 = true",
|
||||||
"CompileCommand: option Test.test double MyDoubleOption = 1.123000"
|
"Test.test double TestOptionDouble = 1.123000"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[][] TYPE_1_ARGUMENTS = {
|
private static final String[][] TYPE_1_ARGUMENTS = {
|
||||||
{
|
{
|
||||||
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1",
|
"-XX:CompileCommand=option,com/oracle/Test.test,TestOptionBool",
|
||||||
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption2",
|
"-XX:CompileCommand=option,com/oracle/Test,test,TestOptionBool2",
|
||||||
"-XX:CompileCommand=option,com.oracle.Test::test,MyBoolOption3",
|
"-XX:CompileCommand=option,com/oracle/Test.test2,TestOptionBool2,TestOptionBool",
|
||||||
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6",
|
|
||||||
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8",
|
|
||||||
"-version"
|
"-version"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[][] TYPE_1_EXPECTED_OUTPUTS = {
|
private static final String[][] TYPE_1_EXPECTED_OUTPUTS = {
|
||||||
{
|
{
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
|
"com/oracle/Test.test bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
|
"com/oracle/Test.test bool TestOptionBool2 = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
|
"com/oracle/Test.test2 bool TestOptionBool = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
|
"com/oracle/Test.test2 bool TestOptionBool2 = true",
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
|
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
|
|
||||||
"CompileCommand: option com/oracle/Test.test bool MyBoolOption8 = true"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[][] TYPE_2_ARGUMENTS = {
|
private static final String[][] TYPE_2_ARGUMENTS = {
|
||||||
{
|
{
|
||||||
"-XX:CompileCommand=option,Test::test,ccstrlist,MyListOption,_foo,_bar",
|
"-XX:CompileCommand=option,Test::test,ccstrlist,TestOptionList,_foo,_bar",
|
||||||
"-XX:CompileCommand=option,Test::test,ccstr,MyStrOption,_foo",
|
"-XX:CompileCommand=option,Test::test,ccstr,TestOptionStr,_foo",
|
||||||
"-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false",
|
"-XX:CompileCommand=option,Test::test,bool,TestOptionBool,false",
|
||||||
"-XX:CompileCommand=option,Test::test,intx,MyIntxOption,-1",
|
"-XX:CompileCommand=option,Test::test,intx,TestOptionInt,-1",
|
||||||
"-XX:CompileCommand=option,Test::test,uintx,MyUintxOption,1",
|
"-XX:CompileCommand=option,Test::test,uintx,TestOptionUint,1",
|
||||||
"-XX:CompileCommand=option,Test::test,MyFlag",
|
"-XX:CompileCommand=option,Test::test,TestOptionBool2",
|
||||||
"-XX:CompileCommand=option,Test::test,double,MyDoubleOption1,1.123",
|
"-XX:CompileCommand=option,Test::test,double,TestOptionDouble,1.123",
|
||||||
"-XX:CompileCommand=option,Test.test,double,MyDoubleOption2,1.123",
|
"-XX:CompileCommand=option,Test.test2,double,TestOptionDouble,1.123",
|
||||||
"-XX:CompileCommand=option,Test::test,bool,MyBoolOptionX,false,intx,MyIntxOptionX,-1,uintx,MyUintxOptionX,1,MyFlagX,double,MyDoubleOptionX,1.123",
|
|
||||||
"-version"
|
"-version"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final String[][] TYPE_2_EXPECTED_OUTPUTS = {
|
private static final String[][] TYPE_2_EXPECTED_OUTPUTS = {
|
||||||
{
|
{
|
||||||
"CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
|
"Test.test const char* TestOptionList = '_foo _bar'",
|
||||||
"CompileCommand: option Test.test const char* MyStrOption = '_foo'",
|
"Test.test const char* TestOptionStr = '_foo'",
|
||||||
"CompileCommand: option Test.test bool MyBoolOption = false",
|
"Test.test bool TestOptionBool = false",
|
||||||
"CompileCommand: option Test.test intx MyIntxOption = -1",
|
"Test.test intx TestOptionInt = -1",
|
||||||
"CompileCommand: option Test.test uintx MyUintxOption = 1",
|
"Test.test uintx TestOptionUint = 1",
|
||||||
"CompileCommand: option Test.test bool MyFlag = true",
|
"Test.test bool TestOptionBool2 = true",
|
||||||
"CompileCommand: option Test.test double MyDoubleOption1 = 1.123000",
|
"Test.test double TestOptionDouble = 1.123000",
|
||||||
"CompileCommand: option Test.test double MyDoubleOption2 = 1.123000",
|
"Test.test2 double TestOptionDouble = 1.123000"
|
||||||
"CompileCommand: option Test.test bool MyBoolOptionX = false",
|
}
|
||||||
"CompileCommand: option Test.test intx MyIntxOptionX = -1",
|
};
|
||||||
"CompileCommand: option Test.test uintx MyUintxOptionX = 1",
|
|
||||||
"CompileCommand: option Test.test bool MyFlagX = true",
|
private static final String[][] TYPE_3_ARGUMENTS = {
|
||||||
"CompileCommand: option Test.test double MyDoubleOptionX = 1.123000",
|
{
|
||||||
|
"-XX:CompileCommand=option,Test::test,bool,TestOptionBool,false,intx,TestOptionInt,-1,uintx,TestOptionUint,1,TestOptionBool2,double,TestOptionDouble,1.123",
|
||||||
|
"-version"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String[][] TYPE_3_EXPECTED_OUTPUTS = {
|
||||||
|
{
|
||||||
|
"Test.test bool TestOptionBool = false",
|
||||||
|
"Test.test intx TestOptionInt = -1",
|
||||||
|
"Test.test uintx TestOptionUint = 1",
|
||||||
|
"Test.test bool TestOptionBool2 = true",
|
||||||
|
"Test.test double TestOptionDouble = 1.123000"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String[][] TYPE_4_ARGUMENTS = {
|
||||||
|
{
|
||||||
|
"-XX:CompileCommand=TestOptionList,Test::test,_foo,_bar",
|
||||||
|
"-XX:CompileCommand=TestOptionStr,Test::test,_foo",
|
||||||
|
"-XX:CompileCommand=TestOptionBool,Test::test,false",
|
||||||
|
"-XX:CompileCommand=TestOptionInt,Test::test,-1",
|
||||||
|
"-XX:CompileCommand=TestOptionUint,Test::test,1",
|
||||||
|
"-XX:CompileCommand=TestOptionBool2,Test::test",
|
||||||
|
"-XX:CompileCommand=TestOptionDouble,Test::test,1.123",
|
||||||
|
"-XX:CompileCommand=TestOptionDouble,Test.test2,1.123",
|
||||||
|
"-version"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String[][] TYPE_4_EXPECTED_OUTPUTS = {
|
||||||
|
{
|
||||||
|
"CompileCommand: TestOptionList Test.test const char* TestOptionList = '_foo _bar'",
|
||||||
|
"CompileCommand: TestOptionStr Test.test const char* TestOptionStr = '_foo'",
|
||||||
|
"CompileCommand: TestOptionBool Test.test bool TestOptionBool = false",
|
||||||
|
"CompileCommand: TestOptionInt Test.test intx TestOptionInt = -1",
|
||||||
|
"CompileCommand: TestOptionUint Test.test uintx TestOptionUint = 1",
|
||||||
|
"CompileCommand: TestOptionBool2 Test.test bool TestOptionBool2 = true",
|
||||||
|
"CompileCommand: TestOptionDouble Test.test double TestOptionDouble = 1.123000",
|
||||||
|
"CompileCommand: TestOptionDouble Test.test2 double TestOptionDouble = 1.123000"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String[][] TYPE_4_INVALID_ARGUMENTS = {
|
||||||
|
{
|
||||||
|
"-XX:CompileCommand=InvalidOption,Test::test,_foo,_bar",
|
||||||
|
"-XX:CompileCommand=TestOptionInt,Test::test,_foo",
|
||||||
|
"-XX:CompileCommand=TestOptionBool,Test::test,1",
|
||||||
|
"-XX:CompileCommand=TestOptionDouble,Test::test,-1",
|
||||||
|
"-XX:CompileCommand=TestOptionUint,Test::test",
|
||||||
|
"-XX:CompileCommand=TestOptionBool2,Test::test,falsee",
|
||||||
|
"-XX:CompileCommand=TestOptionDouble,Test::test,true",
|
||||||
|
"-XX:CompileCommand=TestOptionDouble,Test.test2,1.f",
|
||||||
|
"-version"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final String[][] TYPE_4_INVALID_OUTPUTS = {
|
||||||
|
{
|
||||||
|
"Unrecognized option 'InvalidOption'",
|
||||||
|
"Value cannot be read for option 'TestOptionInt' of type 'intx'",
|
||||||
|
"Value cannot be read for option 'TestOptionBool' of type 'bool'",
|
||||||
|
"Value cannot be read for option 'TestOptionDouble' of type 'double'",
|
||||||
|
"Option 'TestOptionUint' is not followed by a value",
|
||||||
|
"Value cannot be read for option 'TestOptionBool2' of type 'bool'",
|
||||||
|
"Value cannot be read for option 'TestOptionDouble' of type 'double'",
|
||||||
|
"Value cannot be read for option 'TestOptionDouble' of type 'double'"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -211,6 +272,23 @@ public class CheckCompileCommandOption {
|
||||||
out.shouldHaveExitValue(0);
|
out.shouldHaveExitValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void verifyInvalidOption(String[] arguments, String[] expected_outputs) throws Exception {
|
||||||
|
ProcessBuilder pb;
|
||||||
|
OutputAnalyzer out;
|
||||||
|
|
||||||
|
pb = ProcessTools.createJavaProcessBuilder(arguments);
|
||||||
|
out = new OutputAnalyzer(pb.start());
|
||||||
|
|
||||||
|
for (String expected_output : expected_outputs) {
|
||||||
|
out.shouldContain(expected_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.shouldContain("CompileCommand: An error occurred during parsing");
|
||||||
|
out.shouldHaveExitValue(0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
if (TYPE_1_ARGUMENTS.length != TYPE_1_EXPECTED_OUTPUTS.length) {
|
if (TYPE_1_ARGUMENTS.length != TYPE_1_EXPECTED_OUTPUTS.length) {
|
||||||
|
@ -221,6 +299,14 @@ public class CheckCompileCommandOption {
|
||||||
throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (2) options does not match.");
|
throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (2) options does not match.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (TYPE_3_ARGUMENTS.length != TYPE_3_EXPECTED_OUTPUTS.length) {
|
||||||
|
throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (3) options does not match.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_4_ARGUMENTS.length != TYPE_4_EXPECTED_OUTPUTS.length) {
|
||||||
|
throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (4) options does not match.");
|
||||||
|
}
|
||||||
|
|
||||||
// Check if type (1) options are parsed correctly
|
// Check if type (1) options are parsed correctly
|
||||||
for (int i = 0; i < TYPE_1_ARGUMENTS.length; i++) {
|
for (int i = 0; i < TYPE_1_ARGUMENTS.length; i++) {
|
||||||
verifyValidOption(TYPE_1_ARGUMENTS[i], TYPE_1_EXPECTED_OUTPUTS[i]);
|
verifyValidOption(TYPE_1_ARGUMENTS[i], TYPE_1_EXPECTED_OUTPUTS[i]);
|
||||||
|
@ -231,12 +317,28 @@ public class CheckCompileCommandOption {
|
||||||
verifyValidOption(TYPE_2_ARGUMENTS[i], TYPE_2_EXPECTED_OUTPUTS[i]);
|
verifyValidOption(TYPE_2_ARGUMENTS[i], TYPE_2_EXPECTED_OUTPUTS[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if type (3) options are parsed correctly
|
||||||
|
for (int i = 0; i < TYPE_3_ARGUMENTS.length; i++) {
|
||||||
|
verifyValidOption(TYPE_3_ARGUMENTS[i], TYPE_3_EXPECTED_OUTPUTS[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if type (4) options are parsed correctly
|
||||||
|
for (int i = 0; i < TYPE_4_ARGUMENTS.length; i++) {
|
||||||
|
verifyValidOption(TYPE_4_ARGUMENTS[i], TYPE_4_EXPECTED_OUTPUTS[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if error is reported for invalid type (2) options
|
// Check if error is reported for invalid type (2) options
|
||||||
// (flags with type information specified)
|
// (flags with type information specified)
|
||||||
for (String[] arguments: TYPE_2_INVALID_ARGUMENTS) {
|
for (String[] arguments: TYPE_2_INVALID_ARGUMENTS) {
|
||||||
verifyInvalidOption(arguments);
|
verifyInvalidOption(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if error is reported for invalid type (2) options
|
||||||
|
// (flags with type information specified)
|
||||||
|
for (int i = 0; i < TYPE_4_INVALID_ARGUMENTS.length; i++) {
|
||||||
|
verifyInvalidOption(TYPE_4_INVALID_ARGUMENTS[i], TYPE_4_INVALID_OUTPUTS[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if commands in command file are parsed correctly
|
// Check if commands in command file are parsed correctly
|
||||||
for (int i = 0; i < FILE_ARGUMENTS.length; i++) {
|
for (int i = 0; i < FILE_ARGUMENTS.length; i++) {
|
||||||
verifyValidOption(FILE_ARGUMENTS[i], FILE_EXPECTED_OUTPUT[i]);
|
verifyValidOption(FILE_ARGUMENTS[i], FILE_EXPECTED_OUTPUT[i]);
|
||||||
|
|
|
@ -27,17 +27,30 @@
|
||||||
* @library /test/lib
|
* @library /test/lib
|
||||||
* @modules java.base/jdk.internal.misc
|
* @modules java.base/jdk.internal.misc
|
||||||
* @build sun.hotspot.WhiteBox
|
* @build sun.hotspot.WhiteBox
|
||||||
|
* @requires vm.debug == true
|
||||||
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,ccstrlist,MyListOption,_foo,_bar
|
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,ccstrlist,TestOptionList,_foo,_bar
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,ccstr,MyStrOption,_foo
|
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,ccstr,TestOptionStr,_foo
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,bool,MyBoolOption,false
|
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,bool,TestOptionBool,false
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,intx,MyIntxOption,-1
|
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,intx,TestOptionInt,-1
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,uintx,MyUintxOption,1
|
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,uintx,TestOptionUint,1
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,MyFlag
|
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,TestOptionBool2
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,double,MyDoubleOption1,1.123
|
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,double,TestOptionDouble,1.123
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,double,MyDoubleOption2,1.123
|
* compiler.oracle.GetMethodOptionTest
|
||||||
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,bool,MyBoolOptionX,false,intx,MyIntxOptionX,-1,uintx,MyUintxOptionX,1,MyFlagX,double,MyDoubleOptionX,1.123
|
*
|
||||||
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||||
|
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,bool,TestOptionBool,false,intx,TestOptionInt,-1,uintx,TestOptionUint,1,bool,TestOptionBool2,true,ccstr,TestOptionStr,_foo,double,TestOptionDouble,1.123,ccstrlist,TestOptionList,_foo,_bar
|
||||||
|
* compiler.oracle.GetMethodOptionTest
|
||||||
|
*
|
||||||
|
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||||
|
* -XX:CompileCommand=TestOptionList,compiler.oracle.GetMethodOptionTest::test,_foo,_bar
|
||||||
|
* -XX:CompileCommand=TestOptionStr,compiler.oracle.GetMethodOptionTest::test,_foo
|
||||||
|
* -XX:CompileCommand=TestOptionBool,compiler.oracle.GetMethodOptionTest::test,false
|
||||||
|
-XX:CompileCommand=TestOptionBool2,compiler.oracle.GetMethodOptionTest::test
|
||||||
|
* -XX:CompileCommand=TestOptionInt,compiler.oracle.GetMethodOptionTest::test,-1
|
||||||
|
* -XX:CompileCommand=TestOptionUint,compiler.oracle.GetMethodOptionTest::test,1
|
||||||
|
* -XX:CompileCommand=TestOptionDouble,compiler.oracle.GetMethodOptionTest::test,1.123
|
||||||
* compiler.oracle.GetMethodOptionTest
|
* compiler.oracle.GetMethodOptionTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -72,19 +85,13 @@ public class GetMethodOptionTest {
|
||||||
private static void test2() { }
|
private static void test2() { }
|
||||||
|
|
||||||
private static enum TestCase {
|
private static enum TestCase {
|
||||||
MyListOption("_foo _bar", WB::getMethodStringOption),
|
TestOptionBool(false, WB::getMethodBooleanOption),
|
||||||
MyStrOption("_foo", WB::getMethodStringOption),
|
TestOptionStr("_foo", WB::getMethodStringOption),
|
||||||
MyBoolOption(false, WB::getMethodBooleanOption),
|
TestOptionInt(-1L, WB::getMethodIntxOption),
|
||||||
MyIntxOption(-1L, WB::getMethodIntxOption),
|
TestOptionUint(1L, WB::getMethodUintxOption),
|
||||||
MyUintxOption(1L, WB::getMethodUintxOption),
|
TestOptionBool2(true, WB::getMethodBooleanOption),
|
||||||
MyFlag(true, WB::getMethodBooleanOption),
|
TestOptionDouble(1.123d, WB::getMethodDoubleOption),
|
||||||
MyDoubleOption1(1.123d, WB::getMethodDoubleOption),
|
TestOptionList("_foo _bar", WB::getMethodStringOption);
|
||||||
MyDoubleOption2(1.123d, WB::getMethodDoubleOption),
|
|
||||||
MyBoolOptionX(false, WB::getMethodBooleanOption),
|
|
||||||
MyIntxOptionX(-1L, WB::getMethodIntxOption),
|
|
||||||
MyUintxOptionX(1L, WB::getMethodUintxOption),
|
|
||||||
MyFlagX(true, WB::getMethodBooleanOption),
|
|
||||||
MyDoubleOptionX(1.123d, WB::getMethodDoubleOption);
|
|
||||||
|
|
||||||
public final Object value;
|
public final Object value;
|
||||||
public final BiFunction<Executable, String, Object> getter;
|
public final BiFunction<Executable, String, Object> getter;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
option,com/oracle/Test.test,MyBoolOption1
|
option,com/oracle/Test.test1,TestOptionBool
|
||||||
option,com/oracle/Test,test,MyBoolOption2
|
option,com/oracle/Test,test2,TestOptionBool
|
||||||
option,com.oracle.Test::test,MyBoolOption3
|
option,com.oracle.Test::test3,TestOptionBool
|
||||||
option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6
|
option,com/oracle/Test.test4,TestOptionBool,TestOptionBool2
|
||||||
option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8
|
option,com/oracle/Test,test5,TestOptionBool,TestOptionBool2
|
||||||
option,com/oracle/Test.test(I),MyBoolOption9
|
option,com/oracle/Test.test6(I),TestOptionBool
|
||||||
option,com/oracle/Test,test,(I),MyBoolOption10
|
option,com/oracle/Test,test7,(I),TestOptionBool
|
||||||
option,com.oracle.Test::test(I),MyBoolOption11
|
option,com.oracle.Test::test8(I),TestOptionBool
|
||||||
option,com/oracle/Test.test(I),MyBoolOption13,MyBoolOption14
|
option,com/oracle/Test.test9(I),TestOptionBool,TestOptionBool2
|
||||||
option,com/oracle/Test,test(I),MyBoolOption15,MyBoolOption16
|
option,com/oracle/Test,test10(I),TestOptionBool,TestOptionBool2
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
option,Test::test,ccstrlist,MyListOption,_foo,_bar
|
option,Test::test,ccstrlist,TestOptionList,_foo,_bar
|
||||||
option,Test::test,ccstr,MyStrOption,_foo
|
option,Test::test,ccstr,TestOptionStr,_foo
|
||||||
option,Test::test,bool,MyBoolOption,false
|
option,Test::test,bool,TestOptionBool,false
|
||||||
option,Test::test,intx,MyIntxOption,-1
|
option,Test::test,intx,TestOptionInt,-1
|
||||||
option,Test::test,uintx,MyUintxOption,1
|
option,Test::test,uintx,TestOptionUint,1
|
||||||
option,Test::test,MyFlag
|
option,Test::test,TestOptionBool2
|
||||||
option,Test::test,double,MyDoubleOption,1.123
|
option,Test::test,double,TestOptionDouble,1.123
|
||||||
|
|
|
@ -48,7 +48,8 @@ public class CompilerConfigFileWarning {
|
||||||
|
|
||||||
pb = ProcessTools.createJavaProcessBuilder("-XX:CompileCommandFile=hs_comp.txt", "-version");
|
pb = ProcessTools.createJavaProcessBuilder("-XX:CompileCommandFile=hs_comp.txt", "-version");
|
||||||
output = new OutputAnalyzer(pb.start());
|
output = new OutputAnalyzer(pb.start());
|
||||||
output.shouldContain("CompileCommand: unrecognized command");
|
output.shouldContain("An error occurred during parsing");
|
||||||
|
output.shouldContain("Unrecognized option 'aaa'");
|
||||||
output.shouldContain("aaa, aaa");
|
output.shouldContain("aaa, aaa");
|
||||||
|
|
||||||
// Skip on debug builds since we'll always read the file there
|
// Skip on debug builds since we'll always read the file there
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue