8256508: Improve CompileCommand flag

Reviewed-by: redestad, kvn
This commit is contained in:
Nils Eliasson 2020-11-25 14:20:35 +00:00
parent 7aed9b65d0
commit cfb175dfdf
22 changed files with 796 additions and 482 deletions

View File

@ -3384,7 +3384,7 @@ void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) {
// Notify the runtime very infrequently only to take care of counter overflows
int freq_log = Tier23InlineeNotifyFreqLog;
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);
}
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.
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);
}
increment_event_counter_impl(info, info->scope()->method(), step, right_n_bits(freq_log), bci, backedge, true);

View File

@ -1043,17 +1043,17 @@ MethodCounters* ciMethod::ensure_method_counters() {
// ------------------------------------------------------------------
// ciMethod::has_option
//
bool ciMethod::has_option(const char* option) {
bool ciMethod::has_option(enum CompileCommand option) {
check_is_loaded();
VM_ENTRY_MARK;
methodHandle mh(THREAD, get_Method());
return CompilerOracle::has_option_string(mh, option);
return CompilerOracle::has_option(mh, option);
}
// ------------------------------------------------------------------
// 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();
VM_ENTRY_MARK;
methodHandle mh(THREAD, get_Method());

View File

@ -293,8 +293,8 @@ class ciMethod : public ciMetadata {
// Find the proper vtable index to invoke this method.
int resolve_vtable_index(ciKlass* caller, ciKlass* receiver);
bool has_option(const char *option);
bool has_option_value(const char* option, double& value);
bool has_option(enum CompileCommand option);
bool has_option_value(enum CompileCommand option, double& value);
bool can_be_compiled();
bool can_be_parsed() const { return _can_be_parsed; }
bool has_compiled_code();

View File

@ -978,15 +978,15 @@ void nmethod::print_nmethod(bool printmethod) {
#if defined(SUPPORT_DATA_STRUCTS)
if (AbstractDisassembler::show_structs()) {
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();
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
}
if (printmethod || PrintRelocations || CompilerOracle::has_option_string(mh, "PrintRelocations")) {
if (printmethod || PrintRelocations || CompilerOracle::has_option(mh, CompileCommand::PrintRelocations)) {
print_relocations();
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
}
if (printmethod || PrintDependencies || CompilerOracle::has_option_string(mh, "PrintDependencies")) {
if (printmethod || PrintDependencies || CompilerOracle::has_option(mh, CompileCommand::PrintDependencies)) {
print_dependencies();
tty->print_cr("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ");
}

View File

@ -1585,8 +1585,8 @@ bool CompileBroker::compilation_is_prohibited(const methodHandle& method, int os
// The method may be explicitly excluded by the user.
double scale;
if (excluded || (CompilerOracle::has_option_value(method, "CompileThresholdScaling", scale) && scale == 0)) {
bool quietly = CompilerOracle::should_exclude_quietly();
if (excluded || (CompilerOracle::has_option_value(method, CompileCommand::CompileThresholdScaling, scale) && scale == 0)) {
bool quietly = CompilerOracle::be_quiet();
if (PrintCompilation && !quietly) {
// This does not happen quietly...
ResourceMark rm;

View File

@ -140,7 +140,7 @@ bool CompilerDirectives::match(const methodHandle& method) {
}
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) {
assert(error_msg != NULL, "Must have error message");
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
// Only set a flag if it has not been modified and value changes.
// 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);
// 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
// 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, #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, CompileCommand::cc_flag, v) && v != this->name##Option) { set.cloned()->name##Option = v; } }
compilerdirectives_common_flags(init_default_cc)
compilerdirectives_c2_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
if (!_modified[ControlIntrinsicIndex] &&
CompilerOracle::has_option_value(method, "ControlIntrinsic", option_value)) {
CompilerOracle::has_option_value(method, CompileCommand::ControlIntrinsic, option_value)) {
ControlIntrinsicIter iter(option_value);
if (need_reset) {
@ -390,7 +389,7 @@ DirectiveSet* DirectiveSet::compilecommand_compatibility_init(const methodHandle
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*/);
if (need_reset) {

View File

@ -34,11 +34,11 @@
// Directives flag name, type, default value, compile command name
#define compilerdirectives_common_flags(cflags) \
cflags(Enable, bool, false, X) \
cflags(Exclude, bool, false, X) \
cflags(Enable, bool, false, Unknown) \
cflags(Exclude, bool, false, Unknown) \
cflags(BreakAtExecute, bool, false, BreakAtExecute) \
cflags(BreakAtCompile, bool, false, BreakAtCompile) \
cflags(Log, bool, LogCompilation, X) \
cflags(Log, bool, LogCompilation, Unknown) \
cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly) \
cflags(PrintInlining, bool, PrintInlining, PrintInlining) \
cflags(PrintNMethods, bool, PrintNMethods, PrintNMethods) \
@ -46,7 +46,7 @@
cflags(ReplayInline, bool, false, ReplayInline) \
cflags(DumpReplay, bool, false, DumpReplay) \
cflags(DumpInline, bool, false, DumpInline) \
cflags(CompilerDirectivesIgnoreCompileCommands, bool, CompilerDirectivesIgnoreCompileCommands, X) \
cflags(CompilerDirectivesIgnoreCompileCommands, bool, CompilerDirectivesIgnoreCompileCommands, Unknown) \
cflags(DisableIntrinsic, ccstrlist, DisableIntrinsic, DisableIntrinsic) \
cflags(ControlIntrinsic, ccstrlist, ControlIntrinsic, ControlIntrinsic) \
cflags(RepeatCompilation, intx, RepeatCompilation, RepeatCompilation)

File diff suppressed because it is too large Load Diff

View File

@ -30,17 +30,91 @@
class methodHandle;
// CompilerOracle is an interface for turning on and off compilation
// 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 {
private:
static bool _quiet;
static void print_tip();
static void print_parse_error(const char*& error_msg, char* original_line);
static void print_parse_error(char* error_msg, char* original_line);
static void print_command(enum CompileCommand option, const char* name, enum OptionType type);
public:
// True if the command file has been specified or is implicit
static bool has_command_file();
@ -49,7 +123,7 @@ class CompilerOracle : AllStatic {
// Tells whether we to exclude compilation of 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
static bool should_inline(const methodHandle& method);
@ -66,25 +140,28 @@ class CompilerOracle : AllStatic {
// Tells whether to break when compiling method
static bool should_break_at(const methodHandle& method);
// Check to see if this method has option set for it
static bool has_option_string(const methodHandle& method, const char * option);
// Tells whether there are any methods to print for print_method_statistics()
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,
// otherwise leave value unchanged and return false.
template<typename T>
static bool has_option_value(const methodHandle& method, const char* option, T& value);
// Fast check if there is any option available that compile control needs to know about
static bool has_any_option();
static bool has_option_value(const methodHandle& method, enum CompileCommand option, T& value, bool verfiy_type = false);
// 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_compile_only(char * line);
static void parse_compile_only(char* line);
// Tells whether there are any methods to print for print_method_statistics()
static bool should_print_methods();
// Fast check if there is any option set that compile control needs to know about
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

View File

@ -259,6 +259,10 @@ void MethodMatcher::parse_method_pattern(char*& line, const char*& error_msg, Me
}
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)) {
c_match = check_mode(class_name, error_msg);
@ -352,22 +356,23 @@ 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");
BasicMatcher* bm = new BasicMatcher();
BasicMatcher *bm = new BasicMatcher();
MethodMatcher::parse_method_pattern(line, error_msg, bm);
if (error_msg != NULL) {
delete bm;
return NULL;
}
// check for bad trailing characters
int bytes_read = 0;
sscanf(line, "%*[ \t]%n", &bytes_read);
if (line[bytes_read] != '\0') {
error_msg = "Unrecognized trailing text after method pattern";
delete bm;
return NULL;
if (!expect_trailing_chars) {
// check for bad trailing characters
int bytes_read = 0;
sscanf(line, "%*[ \t]%n", &bytes_read);
if (line[bytes_read] != '\0') {
error_msg = "Unrecognized trailing text after method pattern";
delete bm;
return NULL;
}
}
return bm;
}
@ -426,8 +431,7 @@ InlineMatcher* InlineMatcher::parse_inline_pattern(char* str, const char*& error
}
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);
if (im == NULL) {
assert(error_msg != NULL, "Must have error message");

View File

@ -81,7 +81,7 @@ public:
_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);
void set_next(BasicMatcher* next) { _next = next; }
BasicMatcher* next() { return _next; }

View File

@ -47,7 +47,7 @@
bool TieredThresholdPolicy::call_predicate_helper(const methodHandle& method, CompLevel cur_level, int i, int b, double scale) {
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;
}
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) {
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;
}
switch(cur_level) {

View File

@ -94,7 +94,7 @@ class MethodCounters : public Metadata {
// Set per-method thresholds.
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);
_interpreter_invocation_limit = compile_threshold << InvocationCounter::count_shift;

View File

@ -1289,7 +1289,7 @@ void MethodData::init() {
// Set per-method invoke- and backedge mask.
double scale = 1.0;
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;
_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
_rtm_state = NoRTM; // No RTM lock eliding by default
if (UseRTMLocking &&
!CompilerOracle::has_option_string(mh, "NoRTMLockEliding")) {
if (CompilerOracle::has_option_string(mh, "UseRTMLockEliding") || !UseRTMDeopt) {
!CompilerOracle::has_option(mh, CompileCommand::NoRTMLockEliding)) {
if (CompilerOracle::has_option(mh, CompileCommand::UseRTMLockEliding) || !UseRTMDeopt) {
// Generate RTM lock eliding code without abort ratio calculation code.
_rtm_state = UseRTM;
} else if (UseRTMDeopt) {

View File

@ -953,10 +953,10 @@ void Compile::Init(int aliaslevel) {
#if INCLUDE_RTM_OPT
if (UseRTMLocking && has_method() && (method()->method_data_or_null() != NULL)) {
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.
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.
set_rtm_state(UseRTM);
} else if (UseRTMDeopt) {

View File

@ -594,7 +594,7 @@ class Compile : public Phase {
void set_clinit_barrier_on_entry(bool z) { _clinit_barrier_on_entry = z; }
// 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);
}

View File

@ -1056,7 +1056,7 @@ WB_ENTRY(jint, WB_MatchesMethod(JNIEnv* env, jobject o, jobject method, jstring
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) {
assert(error_msg != NULL, "Must have 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);
const char* flag_name = env->GetStringUTFChars(name, NULL);
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);
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))

View File

@ -28,6 +28,7 @@
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.management
* @requires vm.debug == true
* @run driver compiler.oracle.CheckCompileCommandOption
*/
@ -43,12 +44,12 @@ public class CheckCompileCommandOption {
// Currently, two types of trailing options can be used with
// -XX:CompileCommand=option
//
// (1) CompileCommand=option,Klass::method,flag
// (2) CompileCommand=option,Klass::method,type,flag,value
// (1) CompileCommand=option,Klass::method,option
// (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,
// ccstrlist, and double.
@ -65,85 +66,145 @@ public class CheckCompileCommandOption {
private static final String[][] FILE_EXPECTED_OUTPUT = {
{
"CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = 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",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption9 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption10 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption11 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption13 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption14 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption15 = true",
"CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption16 = true"
"com/oracle/Test.test1 bool TestOptionBool = true",
"com/oracle/Test.test2 bool TestOptionBool = true",
"com/oracle/Test.test3 bool TestOptionBool = true",
"com/oracle/Test.test4 bool TestOptionBool = true",
"com/oracle/Test.test4 bool TestOptionBool2 = true",
"com/oracle/Test.test5 bool TestOptionBool = true",
"com/oracle/Test.test5 bool TestOptionBool2 = true",
"com/oracle/Test.test6(I) bool TestOptionBool = true",
"com/oracle/Test.test7(I) bool TestOptionBool = true",
"com/oracle/Test.test8(I) bool TestOptionBool = true",
"com/oracle/Test.test9(I) bool TestOptionBool = true",
"com/oracle/Test.test9(I) bool TestOptionBool2 = true",
"com/oracle/Test.test10(I) bool TestOptionBool = true",
"com/oracle/Test.test10(I) bool TestOptionBool2 = true"
},
{
"CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
"CompileCommand: option Test.test const char* MyStrOption = '_foo'",
"CompileCommand: option Test.test bool MyBoolOption = false",
"CompileCommand: option Test.test intx MyIntxOption = -1",
"CompileCommand: option Test.test uintx MyUintxOption = 1",
"CompileCommand: option Test.test bool MyFlag = true",
"CompileCommand: option Test.test double MyDoubleOption = 1.123000"
"Test.test const char* TestOptionList = '_foo _bar'",
"Test.test const char* TestOptionStr = '_foo'",
"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_1_ARGUMENTS = {
{
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1",
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption2",
"-XX:CompileCommand=option,com.oracle.Test::test,MyBoolOption3",
"-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6",
"-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8",
"-XX:CompileCommand=option,com/oracle/Test.test,TestOptionBool",
"-XX:CompileCommand=option,com/oracle/Test,test,TestOptionBool2",
"-XX:CompileCommand=option,com/oracle/Test.test2,TestOptionBool2,TestOptionBool",
"-version"
}
};
private static final String[][] TYPE_1_EXPECTED_OUTPUTS = {
{
"CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
"CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = 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"
"com/oracle/Test.test bool TestOptionBool = true",
"com/oracle/Test.test bool TestOptionBool2 = true",
"com/oracle/Test.test2 bool TestOptionBool = true",
"com/oracle/Test.test2 bool TestOptionBool2 = true",
}
};
private static final String[][] TYPE_2_ARGUMENTS = {
{
"-XX:CompileCommand=option,Test::test,ccstrlist,MyListOption,_foo,_bar",
"-XX:CompileCommand=option,Test::test,ccstr,MyStrOption,_foo",
"-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false",
"-XX:CompileCommand=option,Test::test,intx,MyIntxOption,-1",
"-XX:CompileCommand=option,Test::test,uintx,MyUintxOption,1",
"-XX:CompileCommand=option,Test::test,MyFlag",
"-XX:CompileCommand=option,Test::test,double,MyDoubleOption1,1.123",
"-XX:CompileCommand=option,Test.test,double,MyDoubleOption2,1.123",
"-XX:CompileCommand=option,Test::test,bool,MyBoolOptionX,false,intx,MyIntxOptionX,-1,uintx,MyUintxOptionX,1,MyFlagX,double,MyDoubleOptionX,1.123",
"-XX:CompileCommand=option,Test::test,ccstrlist,TestOptionList,_foo,_bar",
"-XX:CompileCommand=option,Test::test,ccstr,TestOptionStr,_foo",
"-XX:CompileCommand=option,Test::test,bool,TestOptionBool,false",
"-XX:CompileCommand=option,Test::test,intx,TestOptionInt,-1",
"-XX:CompileCommand=option,Test::test,uintx,TestOptionUint,1",
"-XX:CompileCommand=option,Test::test,TestOptionBool2",
"-XX:CompileCommand=option,Test::test,double,TestOptionDouble,1.123",
"-XX:CompileCommand=option,Test.test2,double,TestOptionDouble,1.123",
"-version"
}
};
private static final String[][] TYPE_2_EXPECTED_OUTPUTS = {
{
"CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
"CompileCommand: option Test.test const char* MyStrOption = '_foo'",
"CompileCommand: option Test.test bool MyBoolOption = false",
"CompileCommand: option Test.test intx MyIntxOption = -1",
"CompileCommand: option Test.test uintx MyUintxOption = 1",
"CompileCommand: option Test.test bool MyFlag = true",
"CompileCommand: option Test.test double MyDoubleOption1 = 1.123000",
"CompileCommand: option Test.test double MyDoubleOption2 = 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",
"CompileCommand: option Test.test double MyDoubleOptionX = 1.123000",
"Test.test const char* TestOptionList = '_foo _bar'",
"Test.test const char* TestOptionStr = '_foo'",
"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",
"Test.test2 double TestOptionDouble = 1.123000"
}
};
private static final String[][] TYPE_3_ARGUMENTS = {
{
"-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);
}
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 {
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.");
}
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
for (int i = 0; i < TYPE_1_ARGUMENTS.length; 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]);
}
// 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
// (flags with type information specified)
for (String[] arguments: TYPE_2_INVALID_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
for (int i = 0; i < FILE_ARGUMENTS.length; i++) {
verifyValidOption(FILE_ARGUMENTS[i], FILE_EXPECTED_OUTPUT[i]);

View File

@ -27,17 +27,30 @@
* @library /test/lib
* @modules java.base/jdk.internal.misc
* @build sun.hotspot.WhiteBox
* @requires vm.debug == true
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
* @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,ccstr,MyStrOption,_foo
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,bool,MyBoolOption,false
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,intx,MyIntxOption,-1
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,uintx,MyUintxOption,1
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,MyFlag
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,double,MyDoubleOption1,1.123
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,double,MyDoubleOption2,1.123
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,bool,MyBoolOptionX,false,intx,MyIntxOptionX,-1,uintx,MyUintxOptionX,1,MyFlagX,double,MyDoubleOptionX,1.123
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,ccstrlist,TestOptionList,_foo,_bar
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,ccstr,TestOptionStr,_foo
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,bool,TestOptionBool,false
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,intx,TestOptionInt,-1
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,uintx,TestOptionUint,1
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,TestOptionBool2
* -XX:CompileCommand=option,compiler.oracle.GetMethodOptionTest::test,double,TestOptionDouble,1.123
* compiler.oracle.GetMethodOptionTest
*
* @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
*/
@ -72,19 +85,13 @@ public class GetMethodOptionTest {
private static void test2() { }
private static enum TestCase {
MyListOption("_foo _bar", WB::getMethodStringOption),
MyStrOption("_foo", WB::getMethodStringOption),
MyBoolOption(false, WB::getMethodBooleanOption),
MyIntxOption(-1L, WB::getMethodIntxOption),
MyUintxOption(1L, WB::getMethodUintxOption),
MyFlag(true, WB::getMethodBooleanOption),
MyDoubleOption1(1.123d, WB::getMethodDoubleOption),
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);
TestOptionBool(false, WB::getMethodBooleanOption),
TestOptionStr("_foo", WB::getMethodStringOption),
TestOptionInt(-1L, WB::getMethodIntxOption),
TestOptionUint(1L, WB::getMethodUintxOption),
TestOptionBool2(true, WB::getMethodBooleanOption),
TestOptionDouble(1.123d, WB::getMethodDoubleOption),
TestOptionList("_foo _bar", WB::getMethodStringOption);
public final Object value;
public final BiFunction<Executable, String, Object> getter;

View File

@ -1,10 +1,10 @@
option,com/oracle/Test.test,MyBoolOption1
option,com/oracle/Test,test,MyBoolOption2
option,com.oracle.Test::test,MyBoolOption3
option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6
option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8
option,com/oracle/Test.test(I),MyBoolOption9
option,com/oracle/Test,test,(I),MyBoolOption10
option,com.oracle.Test::test(I),MyBoolOption11
option,com/oracle/Test.test(I),MyBoolOption13,MyBoolOption14
option,com/oracle/Test,test(I),MyBoolOption15,MyBoolOption16
option,com/oracle/Test.test1,TestOptionBool
option,com/oracle/Test,test2,TestOptionBool
option,com.oracle.Test::test3,TestOptionBool
option,com/oracle/Test.test4,TestOptionBool,TestOptionBool2
option,com/oracle/Test,test5,TestOptionBool,TestOptionBool2
option,com/oracle/Test.test6(I),TestOptionBool
option,com/oracle/Test,test7,(I),TestOptionBool
option,com.oracle.Test::test8(I),TestOptionBool
option,com/oracle/Test.test9(I),TestOptionBool,TestOptionBool2
option,com/oracle/Test,test10(I),TestOptionBool,TestOptionBool2

View File

@ -1,7 +1,7 @@
option,Test::test,ccstrlist,MyListOption,_foo,_bar
option,Test::test,ccstr,MyStrOption,_foo
option,Test::test,bool,MyBoolOption,false
option,Test::test,intx,MyIntxOption,-1
option,Test::test,uintx,MyUintxOption,1
option,Test::test,MyFlag
option,Test::test,double,MyDoubleOption,1.123
option,Test::test,ccstrlist,TestOptionList,_foo,_bar
option,Test::test,ccstr,TestOptionStr,_foo
option,Test::test,bool,TestOptionBool,false
option,Test::test,intx,TestOptionInt,-1
option,Test::test,uintx,TestOptionUint,1
option,Test::test,TestOptionBool2
option,Test::test,double,TestOptionDouble,1.123

View File

@ -48,7 +48,8 @@ public class CompilerConfigFileWarning {
pb = ProcessTools.createJavaProcessBuilder("-XX:CompileCommandFile=hs_comp.txt", "-version");
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");
// Skip on debug builds since we'll always read the file there