@@ -317,8 +317,10 @@ TypedMethodOptionMatcher* TypedMethodOptionMatcher::match(const methodHandle& me
317317}
318318
319319template <typename T>
320- static void register_command (TypedMethodOptionMatcher* matcher,
320+ static bool register_command (TypedMethodOptionMatcher* matcher,
321321 CompileCommandEnum option,
322+ char * errorbuf,
323+ const int buf_size,
322324 T value) {
323325 assert (matcher != option_list, " No circular lists please" );
324326 if (option == CompileCommandEnum::Log && !LogCompilation) {
@@ -331,7 +333,17 @@ static void register_command(TypedMethodOptionMatcher* matcher,
331333 warning (" Blackhole compile option is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions" );
332334 // Delete matcher as we don't keep it
333335 delete matcher;
334- return ;
336+ return true ;
337+ }
338+
339+ if (!UnlockDiagnosticVMOptions) {
340+ const char * name = option2name (option);
341+ JVMFlag* flag = JVMFlag::find_declared_flag (name);
342+ if (flag != nullptr && flag->is_diagnostic ()) {
343+ jio_snprintf (errorbuf, buf_size, " VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions." , name);
344+ delete matcher;
345+ return false ;
346+ }
335347 }
336348
337349 matcher->init (option, option_list);
@@ -346,7 +358,7 @@ static void register_command(TypedMethodOptionMatcher* matcher,
346358 matcher->print ();
347359 }
348360
349- return ;
361+ return true ;
350362}
351363
352364template <typename T>
@@ -714,7 +726,7 @@ static bool parseMemStat(const char* line, uintx& value, int& bytes_read, char*
714726 return false ;
715727}
716728
717- static void scan_value (enum OptionType type, char * line, int & total_bytes_read,
729+ static bool scan_value (enum OptionType type, char * line, int & total_bytes_read,
718730 TypedMethodOptionMatcher* matcher, CompileCommandEnum option, char * errorbuf, const int buf_size) {
719731 int bytes_read = 0 ;
720732 const char * ccname = option2name (option);
@@ -733,11 +745,10 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
733745 }
734746 if (success) {
735747 total_bytes_read += bytes_read;
736- line += bytes_read;
737- register_command (matcher, option, value);
738- return ;
748+ return register_command (matcher, option, errorbuf, buf_size, value);
739749 } else {
740750 jio_snprintf (errorbuf, buf_size, " Value cannot be read for option '%s' of type '%s'" , ccname, type_str);
751+ return false ;
741752 }
742753 } else if (type == OptionType::Uintx) {
743754 uintx value;
@@ -751,21 +762,20 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
751762 }
752763 if (success) {
753764 total_bytes_read += bytes_read;
754- line += bytes_read;
755- register_command (matcher, option, value);
765+ return register_command (matcher, option, errorbuf, buf_size, value);
756766 } else {
757767 jio_snprintf (errorbuf, buf_size, " Value cannot be read for option '%s' of type '%s'" , ccname, type_str);
768+ return false ;
758769 }
759770 } else if (type == OptionType::Ccstr) {
760771 ResourceMark rm;
761772 char * value = NEW_RESOURCE_ARRAY (char , strlen (line) + 1 );
762773 if (sscanf (line, " %255[_a-zA-Z0-9]%n" , value, &bytes_read) == 1 ) {
763774 total_bytes_read += bytes_read;
764- line += bytes_read;
765- register_command (matcher, option, (ccstr) value);
766- return ;
775+ return register_command (matcher, option, errorbuf, buf_size, (ccstr) value);
767776 } else {
768777 jio_snprintf (errorbuf, buf_size, " Value cannot be read for option '%s' of type '%s'" , ccname, type_str);
778+ return false ;
769779 }
770780 } else if (type == OptionType::Ccstrlist) {
771781 // Accumulates several strings into one. The internal type is ccstr.
@@ -790,6 +800,7 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
790800
791801 if (!validator.is_valid ()) {
792802 jio_snprintf (errorbuf, buf_size, " Unrecognized intrinsic detected in %s: %s" , option2name (option), validator.what ());
803+ return false ;
793804 }
794805 }
795806#if !defined(PRODUCT) && defined(COMPILER2)
@@ -798,18 +809,21 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
798809
799810 if (!validator.is_valid ()) {
800811 jio_snprintf (errorbuf, buf_size, " Unrecognized tag name in %s: %s" , option2name (option), validator.what ());
812+ return false ;
801813 }
802814 } else if (option == CompileCommandEnum::TraceMergeStores) {
803815 TraceMergeStores::TagValidator validator (value, true );
804816
805817 if (!validator.is_valid ()) {
806818 jio_snprintf (errorbuf, buf_size, " Unrecognized tag name in %s: %s" , option2name (option), validator.what ());
819+ return false ;
807820 }
808821 } else if (option == CompileCommandEnum::PrintIdealPhase) {
809822 PhaseNameValidator validator (value);
810823
811824 if (!validator.is_valid ()) {
812825 jio_snprintf (errorbuf, buf_size, " Unrecognized phase name in %s: %s" , option2name (option), validator.what ());
826+ return false ;
813827 }
814828 } else if (option == CompileCommandEnum::TestOptionList) {
815829 // all values are ok
@@ -819,35 +833,32 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
819833 assert (false , " Ccstrlist type option missing validator" );
820834 }
821835
822- register_command (matcher, option, (ccstr) value);
823- return ;
836+ return register_command (matcher, option, errorbuf, buf_size, (ccstr) value);
824837 } else {
825838 jio_snprintf (errorbuf, buf_size, " Value cannot be read for option '%s' of type '%s'" , ccname, type_str);
839+ return false ;
826840 }
827841 } else if (type == OptionType::Bool) {
828842 char value[256 ];
829843 if (*line == ' \0 ' ) {
830844 // Short version of a CompileCommand sets a boolean Option to true
831845 // -XXCompileCommand=<Option>,<method pattern>
832- register_command (matcher, option, true );
833- return ;
846+ return register_command (matcher, option, errorbuf, buf_size,true );
834847 }
835848 if (sscanf (line, " %255[a-zA-Z]%n" , value, &bytes_read) == 1 ) {
836849 if (strcasecmp (value, " true" ) == 0 ) {
837850 total_bytes_read += bytes_read;
838- line += bytes_read;
839- register_command (matcher, option, true );
840- return ;
851+ return register_command (matcher, option, errorbuf, buf_size,true );
841852 } else if (strcasecmp (value, " false" ) == 0 ) {
842853 total_bytes_read += bytes_read;
843- line += bytes_read;
844- register_command (matcher, option, false );
845- return ;
854+ return register_command (matcher, option, errorbuf, buf_size,false );
846855 } else {
847856 jio_snprintf (errorbuf, buf_size, " Value cannot be read for option '%s' of type '%s'" , ccname, type_str);
857+ return false ;
848858 }
849859 } else {
850860 jio_snprintf (errorbuf, buf_size, " Value cannot be read for option '%s' of type '%s'" , ccname, type_str);
861+ return false ;
851862 }
852863 } else if (type == OptionType::Double) {
853864 char buffer[2 ][256 ];
@@ -857,21 +868,21 @@ static void scan_value(enum OptionType type, char* line, int& total_bytes_read,
857868 char value[512 ] = " " ;
858869 jio_snprintf (value, sizeof (value), " %s.%s" , buffer[0 ], buffer[1 ]);
859870 total_bytes_read += bytes_read;
860- line += bytes_read;
861- register_command (matcher, option, atof (value));
862- return ;
871+ return register_command (matcher, option, errorbuf, buf_size, atof (value));
863872 } else {
864873 jio_snprintf (errorbuf, buf_size, " Value cannot be read for option '%s' of type '%s'" , ccname, type_str);
874+ return false ;
865875 }
866876 } else {
867877 jio_snprintf (errorbuf, buf_size, " Type '%s' not supported " , type_str);
878+ return false ;
868879 }
869880}
870881
871882// Scan next option and value in line, return MethodMatcher object on success, nullptr on failure.
872883// On failure, error_msg contains description for the first error.
873884// For future extensions: set error_msg on first error.
874- static void scan_option_and_value (enum OptionType type, char * line, int & total_bytes_read,
885+ static bool scan_option_and_value (enum OptionType type, char * line, int & total_bytes_read,
875886 TypedMethodOptionMatcher* matcher,
876887 char * errorbuf, const int buf_size) {
877888 total_bytes_read = 0 ;
@@ -887,21 +898,21 @@ static void scan_option_and_value(enum OptionType type, char* line, int& total_b
887898 CompileCommandEnum option = match_option_name (option_buf, &bytes_read2, errorbuf, buf_size);
888899 if (option == CompileCommandEnum::Unknown) {
889900 assert (*errorbuf != ' \0 ' , " error must have been set" );
890- return ;
901+ return false ;
891902 }
892903 enum OptionType optiontype = option2type (option);
893904 if (option2type (option) != type) {
894905 const char * optiontype_name = optiontype2name (optiontype);
895906 const char * type_name = optiontype2name (type);
896907 jio_snprintf (errorbuf, buf_size, " Option '%s' with type '%s' doesn't match supplied type '%s'" , option_buf, optiontype_name, type_name);
897- return ;
908+ return false ;
898909 }
899- scan_value (type, line, total_bytes_read, matcher, option, errorbuf, buf_size);
910+ return scan_value (type, line, total_bytes_read, matcher, option, errorbuf, buf_size);
900911 } else {
901912 const char * type_str = optiontype2name (type);
902913 jio_snprintf (errorbuf, buf_size, " Option name for type '%s' should be alphanumeric " , type_str);
914+ return false ;
903915 }
904- return ;
905916}
906917
907918void CompilerOracle::print_parse_error (char * error_msg, char * original_line) {
@@ -996,8 +1007,7 @@ bool CompilerOracle::parse_from_line(char* line) {
9961007 enum OptionType type = parse_option_type (option_type);
9971008 if (type != OptionType::Unknown) {
9981009 // Type (2) option: parse option name and value.
999- scan_option_and_value (type, line, bytes_read, typed_matcher, error_buf, sizeof (error_buf));
1000- if (*error_buf != ' \0 ' ) {
1010+ if (!scan_option_and_value (type, line, bytes_read, typed_matcher, error_buf, sizeof (error_buf))) {
10011011 print_parse_error (error_buf, original.get ());
10021012 return false ;
10031013 }
@@ -1011,7 +1021,10 @@ bool CompilerOracle::parse_from_line(char* line) {
10111021 return false ;
10121022 }
10131023 if (option2type (option) == OptionType::Bool) {
1014- register_command (typed_matcher, option, true );
1024+ if (!register_command (typed_matcher, option, error_buf, sizeof (error_buf), true )) {
1025+ print_parse_error (error_buf, original.get ());
1026+ return false ;
1027+ }
10151028 } else {
10161029 jio_snprintf (error_buf, sizeof (error_buf), " Missing type '%s' before option '%s'" ,
10171030 optiontype2name (option2type (option)), option2name (option));
@@ -1041,20 +1054,25 @@ bool CompilerOracle::parse_from_line(char* line) {
10411054 if (*line == ' \0 ' ) {
10421055 if (option2type (option) == OptionType::Bool) {
10431056 // if this is a bool option this implies true
1044- register_command (matcher, option, true );
1057+ if (!register_command (matcher, option, error_buf, sizeof (error_buf), true )) {
1058+ print_parse_error (error_buf, original.get ());
1059+ return false ;
1060+ }
10451061 return true ;
10461062 } else if (option == CompileCommandEnum::MemStat) {
10471063 // MemStat default action is to collect data but to not print
1048- register_command (matcher, option, (uintx)MemStatAction::collect);
1064+ if (!register_command (matcher, option, error_buf, sizeof (error_buf), (uintx)MemStatAction::collect)) {
1065+ print_parse_error (error_buf, original.get ());
1066+ return false ;
1067+ }
10491068 return true ;
10501069 } else {
10511070 jio_snprintf (error_buf, sizeof (error_buf), " Option '%s' is not followed by a value" , option2name (option));
10521071 print_parse_error (error_buf, original.get ());
10531072 return false ;
10541073 }
10551074 }
1056- scan_value (type, line, bytes_read, matcher, option, error_buf, sizeof (error_buf));
1057- if (*error_buf != ' \0 ' ) {
1075+ if (!scan_value (type, line, bytes_read, matcher, option, error_buf, sizeof (error_buf))) {
10581076 print_parse_error (error_buf, original.get ());
10591077 return false ;
10601078 }
@@ -1161,8 +1179,9 @@ bool CompilerOracle::parse_compile_only(char* line) {
11611179 if (method_pattern != nullptr ) {
11621180 TypedMethodOptionMatcher* matcher = TypedMethodOptionMatcher::parse_method_pattern (method_pattern, error_buf, sizeof (error_buf));
11631181 if (matcher != nullptr ) {
1164- register_command (matcher, CompileCommandEnum::CompileOnly, true );
1165- continue ;
1182+ if (register_command (matcher, CompileCommandEnum::CompileOnly, error_buf, sizeof (error_buf), true )) {
1183+ continue ;
1184+ }
11661185 }
11671186 }
11681187 ttyLocker ttyl;
0 commit comments