# HG changeset patch # User anoll # Date 1412945310 -7200 # Node ID feee4a6106bc57718af1959af17b84cbfb3ae091 # Parent bae5d661dd4be0f74ad2b9e32af07d3847f8a964 8059847: complement JDK-8055286 and JDK-8056964 changes Summary: Extend scan_flag_and_value() to process flag of type double. Add regression test compiler/oracle/CheckCompileCommandOption.java. Reviewed-by: kvn, anoll diff -r bae5d661dd4b -r feee4a6106bc hotspot/src/share/vm/ci/ciMethod.cpp --- a/hotspot/src/share/vm/ci/ciMethod.cpp Wed Oct 08 09:23:18 2014 +0200 +++ b/hotspot/src/share/vm/ci/ciMethod.cpp Fri Oct 10 14:48:30 2014 +0200 @@ -1116,6 +1116,7 @@ template bool ciMethod::has_option_value(const char* option, uintx& value); template bool ciMethod::has_option_value(const char* option, bool& value); template bool ciMethod::has_option_value(const char* option, ccstr& value); +template bool ciMethod::has_option_value(const char* option, double& value); // ------------------------------------------------------------------ // ciMethod::can_be_compiled diff -r bae5d661dd4b -r feee4a6106bc hotspot/src/share/vm/compiler/compilerOracle.cpp --- a/hotspot/src/share/vm/compiler/compilerOracle.cpp Wed Oct 08 09:23:18 2014 +0200 +++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp Fri Oct 10 14:48:30 2014 +0200 @@ -173,6 +173,7 @@ UintxType, BoolType, CcstrType, + DoubleType, UnknownType }; @@ -198,6 +199,10 @@ return CcstrType; } +template<> OptionType get_type_for() { + return DoubleType; +} + template static const T copy_value(const T value) { return value; @@ -297,6 +302,15 @@ tty->cr(); }; +template<> +void TypedMethodOptionMatcher::print() { + ttyLocker ttyl; + print_base(); + tty->print(" double %s", _option); + tty->print(" = %f", _value); + tty->cr(); +}; + // this must parallel the command_names below enum OracleCommand { UnknownCommand = -1, @@ -390,6 +404,7 @@ template bool CompilerOracle::has_option_value(methodHandle method, const char* option, uintx& value); template bool CompilerOracle::has_option_value(methodHandle method, const char* option, bool& value); template bool CompilerOracle::has_option_value(methodHandle method, const char* option, ccstr& value); +template bool CompilerOracle::has_option_value(methodHandle method, const char* option, double& value); bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) { quietly = true; @@ -610,6 +625,20 @@ } else { jio_snprintf(errorbuf, sizeof(errorbuf), " Value cannot be read for flag %s of type %s", flag, type); } + } else if (strcmp(type, "double") == 0) { + char buffer[2][256]; + // Decimal separator '.' has been replaced with ' ' or '/' earlier, + // 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) { + char value[512] = ""; + strncat(value, buffer[0], 255); + strcat(value, "."); + strncat(value, buffer[1], 255); + total_bytes_read += bytes_read; + return add_option_string(c_name, c_match, m_name, m_match, signature, flag, atof(value)); + } else { + jio_snprintf(errorbuf, buf_size, " Value cannot be read for flag %s of type %s", flag, type); + } } else { jio_snprintf(errorbuf, sizeof(errorbuf), " Type %s not supported ", type); } @@ -700,11 +729,10 @@ // (1) CompileCommand=option,Klass::method,flag // (2) CompileCommand=option,Klass::method,type,flag,value // - // Type (1) is used to support ciMethod::has_option("someflag") - // (i.e., to check if a flag "someflag" is enabled for a method). + // Type (1) is used to enable a boolean flag for a method. // // Type (2) is used to support options with a value. Values can have the - // the following types: intx, uintx, bool, ccstr, and ccstrlist. + // 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) @@ -722,6 +750,7 @@ || strcmp(option, "bool") == 0 || strcmp(option, "ccstr") == 0 || strcmp(option, "ccstrlist") == 0 + || strcmp(option, "double") == 0 ) { // Type (2) option: parse flag name and value. diff -r bae5d661dd4b -r feee4a6106bc hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Wed Oct 08 09:23:18 2014 +0200 +++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Oct 10 14:48:30 2014 +0200 @@ -454,7 +454,7 @@ // notproduct flags are settable / visible only during development and are not declared in the PRODUCT version // A flag must be declared with one of the following types: -// bool, intx, uintx, ccstr. +// bool, intx, uintx, ccstr, double, or uint64_t. // The type "ccstr" is an alias for "const char*" and is used // only in this file, because the macrology requires single-token type names. diff -r bae5d661dd4b -r feee4a6106bc hotspot/test/compiler/oracle/CheckCompileCommandOption.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/oracle/CheckCompileCommandOption.java Fri Oct 10 14:48:30 2014 +0200 @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.*; + +/* + * @test CheckCompileCommandOption + * @bug 8055286 8056964 8059847 + * @summary "Checks parsing of -XX:+CompileCommand=option" + * @library /testlibrary + * @run main CheckCompileCommandOption + */ + +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 + // + // Type (1) is used to enable a boolean flag for a method. + // + // Type (2) is used to support flags with a value. Values can + // have the the following types: intx, uintx, bool, ccstr, + // ccstrlist, and double. + + 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,MyBoolOption4", + "-version" + }, + { + "-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1,MyBoolOption2", + "-version" + }, + { + "-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption1,MyBoolOption2", + "-version" + } + }; + + private static final String[][] TYPE_1_EXPECTED_OUTPUTS = { + { + "CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true", + "CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = true", + "CompilerOracle: option com/oracle/Test.test bool MyBoolOption3 = true", + "CompilerOracle: option com/oracle/Test.test bool MyBoolOption4 = true" + }, + { + "CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true", + "CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = true", + }, + { + "CompilerOracle: option com/oracle/Test.test bool MyBoolOption1 = true", + "CompilerOracle: option com/oracle/Test.test bool MyBoolOption2 = 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,MyDoubleOption,1.123", + "-version" + }, + { + "-XX:CompileCommand=option,Test.test,double,MyDoubleOption,1.123", + "-version" + }, + { + "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx,MyIntxOption,-1,uintx,MyUintxOption,1,MyFlag,double,MyDoubleOption,1.123", + "-version" + } + }; + + private static final String[][] TYPE_2_EXPECTED_OUTPUTS = { + { + "CompilerOracle: option Test.test const char* MyListOption = '_foo _bar'", + "CompilerOracle: option Test.test const char* MyStrOption = '_foo'", + "CompilerOracle: option Test.test bool MyBoolOption = false", + "CompilerOracle: option Test.test intx MyIntxOption = -1", + "CompilerOracle: option Test.test uintx MyUintxOption = 1", + "CompilerOracle: option Test.test bool MyFlag = true", + "CompilerOracle: option Test.test double MyDoubleOption = 1.123000" + }, + { + "CompilerOracle: option Test.test double MyDoubleOption = 1.123000" + }, + { + "CompilerOracle: option Test.test bool MyBoolOption = false", + "CompilerOracle: option Test.test intx MyIntxOption = -1", + "CompilerOracle: option Test.test uintx MyUintxOption = 1", + "CompilerOracle: option Test.test bool MyFlag = true", + "CompilerOracle: option Test.test double MyDoubleOption = 1.123000", + } + }; + + private static final String[][] TYPE_2_INVALID_ARGUMENTS = { + { + // bool flag name missing + "-XX:CompileCommand=option,Test::test,bool", + "-version" + }, + { + // bool flag value missing + "-XX:CompileCommand=option,Test::test,bool,MyBoolOption", + "-version" + }, + { + // wrong value for bool flag + "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,100", + "-version" + }, + { + // intx flag name missing + "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx", + "-version" + }, + { + // intx flag value missing + "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx,MyIntOption", + "-version" + }, + { + // wrong value for intx flag + "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx,MyIntOption,true", + "-version" + }, + { + // wrong value for flag double flag + "-XX:CompileCommand=option,Test::test,double,MyDoubleOption,1", + "-version" + } + }; + + private static void verifyValidOption(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.shouldNotContain("CompilerOracle: unrecognized line"); + out.shouldHaveExitValue(0); + } + + private static void verifyInvalidOption(String[] arguments) throws Exception { + ProcessBuilder pb; + OutputAnalyzer out; + + pb = ProcessTools.createJavaProcessBuilder(arguments); + out = new OutputAnalyzer(pb.start()); + + out.shouldContain("CompilerOracle: unrecognized line"); + out.shouldHaveExitValue(0); + } + + public static void main(String[] args) throws Exception { + + if (TYPE_1_ARGUMENTS.length != TYPE_1_EXPECTED_OUTPUTS.length) { + throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (1) options does not match."); + } + + if (TYPE_2_ARGUMENTS.length != TYPE_2_EXPECTED_OUTPUTS.length) { + throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (2) 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]); + } + + // Check if type (2) options are parsed correctly + for (int i = 0; i < TYPE_2_ARGUMENTS.length; i++) { + verifyValidOption(TYPE_2_ARGUMENTS[i], TYPE_2_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); + } + } +}