Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hotspot/src/share/vm/ci/ciMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,7 @@ template bool ciMethod::has_option_value<intx>(const char* option, intx& value);
template bool ciMethod::has_option_value<uintx>(const char* option, uintx& value);
template bool ciMethod::has_option_value<bool>(const char* option, bool& value);
template bool ciMethod::has_option_value<ccstr>(const char* option, ccstr& value);
template bool ciMethod::has_option_value<double>(const char* option, double& value);

// ------------------------------------------------------------------
// ciMethod::can_be_compiled
Expand Down
35 changes: 32 additions & 3 deletions hotspot/src/share/vm/compiler/compilerOracle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ enum OptionType {
UintxType,
BoolType,
CcstrType,
DoubleType,
UnknownType
};

Expand All @@ -197,6 +198,10 @@ template<> OptionType get_type_for<ccstr>() {
return CcstrType;
}

template<> OptionType get_type_for<double>() {
return DoubleType;
}

template<typename T>
static const T copy_value(const T value) {
return value;
Expand Down Expand Up @@ -296,6 +301,15 @@ void TypedMethodOptionMatcher<ccstr>::print() {
tty->cr();
};

template<>
void TypedMethodOptionMatcher<double>::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,
Expand Down Expand Up @@ -389,6 +403,7 @@ template bool CompilerOracle::has_option_value<intx>(methodHandle method, const
template bool CompilerOracle::has_option_value<uintx>(methodHandle method, const char* option, uintx& value);
template bool CompilerOracle::has_option_value<bool>(methodHandle method, const char* option, bool& value);
template bool CompilerOracle::has_option_value<ccstr>(methodHandle method, const char* option, ccstr& value);
template bool CompilerOracle::has_option_value<double>(methodHandle method, const char* option, double& value);

bool CompilerOracle::should_exclude(methodHandle method, bool& quietly) {
quietly = true;
Expand Down Expand Up @@ -606,6 +621,20 @@ static MethodMatcher* scan_flag_and_value(const char* type, const char* line, in
} 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);
}
Expand Down Expand Up @@ -696,11 +725,10 @@ void CompilerOracle::parse_from_line(char* line) {
// (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)
Expand All @@ -718,6 +746,7 @@ void CompilerOracle::parse_from_line(char* line) {
|| strcmp(option, "bool") == 0
|| strcmp(option, "ccstr") == 0
|| strcmp(option, "ccstrlist") == 0
|| strcmp(option, "double") == 0
) {

// Type (2) option: parse flag name and value.
Expand Down
2 changes: 1 addition & 1 deletion hotspot/src/share/vm/runtime/globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ class CommandLineFlags {
// 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.

Expand Down
216 changes: 216 additions & 0 deletions hotspot/test/compiler/oracle/CheckCompileCommandOption.java
Original file line number Diff line number Diff line change
@@ -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);
}
}
}