8079301: Some command line options not settable via JAVA_TOOL_OPTIONS
Ensures special-cased command line options are settable via _JAVA_OPTIONS and JAVA_TOOL_OPTIONS. Reviewed-by: coleenp, ddmitriev
This commit is contained in:
parent
b02b2c4d5b
commit
8d6eb32eee
@ -91,7 +91,7 @@ const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER;
|
||||
int Arguments::_sun_java_launcher_pid = -1;
|
||||
bool Arguments::_sun_java_launcher_is_altjvm = false;
|
||||
|
||||
// These parameters are reset in method parse_vm_init_args(JavaVMInitArgs*)
|
||||
// These parameters are reset in method parse_vm_init_args()
|
||||
bool Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
|
||||
bool Arguments::_UseOnStackReplacement = UseOnStackReplacement;
|
||||
bool Arguments::_BackgroundCompilation = BackgroundCompilation;
|
||||
@ -2251,7 +2251,9 @@ Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
|
||||
|
||||
// Parse JavaVMInitArgs structure
|
||||
|
||||
jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) {
|
||||
jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
|
||||
const JavaVMInitArgs *java_options_args,
|
||||
const JavaVMInitArgs *cmd_line_args) {
|
||||
// For components of the system classpath.
|
||||
SysClassPath scp(Arguments::get_sysclasspath());
|
||||
bool scp_assembly_required = false;
|
||||
@ -2269,20 +2271,25 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) {
|
||||
// Setup flags for mixed which is the default
|
||||
set_mode_flags(_mixed);
|
||||
|
||||
// Parse JAVA_TOOL_OPTIONS environment variable (if present)
|
||||
jint result = parse_java_tool_options_environment_variable(&scp, &scp_assembly_required);
|
||||
// Parse args structure generated from JAVA_TOOL_OPTIONS environment
|
||||
// variable (if present).
|
||||
jint result = parse_each_vm_init_arg(
|
||||
java_tool_options_args, &scp, &scp_assembly_required, Flag::ENVIRON_VAR);
|
||||
if (result != JNI_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parse JavaVMInitArgs structure passed in
|
||||
result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, Flag::COMMAND_LINE);
|
||||
// Parse args structure generated from the command line flags.
|
||||
result = parse_each_vm_init_arg(cmd_line_args, &scp, &scp_assembly_required,
|
||||
Flag::COMMAND_LINE);
|
||||
if (result != JNI_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
|
||||
result = parse_java_options_environment_variable(&scp, &scp_assembly_required);
|
||||
// Parse args structure generated from the _JAVA_OPTIONS environment
|
||||
// variable (if present) (mimics classic VM)
|
||||
result = parse_each_vm_init_arg(
|
||||
java_options_args, &scp, &scp_assembly_required, Flag::ENVIRON_VAR);
|
||||
if (result != JNI_OK) {
|
||||
return result;
|
||||
}
|
||||
@ -3385,20 +3392,73 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
jint Arguments::parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p) {
|
||||
return parse_options_environment_variable("_JAVA_OPTIONS", scp_p,
|
||||
scp_assembly_required_p);
|
||||
// Helper class for controlling the lifetime of JavaVMInitArgs
|
||||
// objects. The contents of the JavaVMInitArgs are guaranteed to be
|
||||
// deleted on the destruction of the ScopedVMInitArgs object.
|
||||
class ScopedVMInitArgs : public StackObj {
|
||||
private:
|
||||
JavaVMInitArgs _args;
|
||||
|
||||
public:
|
||||
ScopedVMInitArgs() {
|
||||
_args.version = JNI_VERSION_1_2;
|
||||
_args.nOptions = 0;
|
||||
_args.options = NULL;
|
||||
_args.ignoreUnrecognized = false;
|
||||
}
|
||||
|
||||
jint Arguments::parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p) {
|
||||
return parse_options_environment_variable("JAVA_TOOL_OPTIONS", scp_p,
|
||||
scp_assembly_required_p);
|
||||
// Populates the JavaVMInitArgs object represented by this
|
||||
// ScopedVMInitArgs object with the arguments in options. The
|
||||
// allocated memory is deleted by the destructor. If this method
|
||||
// returns anything other than JNI_OK, then this object is in a
|
||||
// partially constructed state, and should be abandoned.
|
||||
jint set_args(GrowableArray<JavaVMOption>* options) {
|
||||
JavaVMOption* options_arr = NEW_C_HEAP_ARRAY_RETURN_NULL(
|
||||
JavaVMOption, options->length(), mtInternal);
|
||||
if (options_arr == NULL) {
|
||||
return JNI_ENOMEM;
|
||||
}
|
||||
_args.options = options_arr;
|
||||
|
||||
for (int i = 0; i < options->length(); i++) {
|
||||
options_arr[i] = options->at(i);
|
||||
options_arr[i].optionString = os::strdup(options_arr[i].optionString);
|
||||
if (options_arr[i].optionString == NULL) {
|
||||
// Rely on the destructor to do cleanup.
|
||||
_args.nOptions = i;
|
||||
return JNI_ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
jint Arguments::parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p) {
|
||||
_args.nOptions = options->length();
|
||||
_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions;
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
JavaVMInitArgs* get() { return &_args; }
|
||||
|
||||
~ScopedVMInitArgs() {
|
||||
if (_args.options == NULL) return;
|
||||
for (int i = 0; i < _args.nOptions; i++) {
|
||||
os::free(_args.options[i].optionString);
|
||||
}
|
||||
FREE_C_HEAP_ARRAY(JavaVMOption, _args.options);
|
||||
}
|
||||
};
|
||||
|
||||
jint Arguments::parse_java_options_environment_variable(ScopedVMInitArgs* args) {
|
||||
return parse_options_environment_variable("_JAVA_OPTIONS", args);
|
||||
}
|
||||
|
||||
jint Arguments::parse_java_tool_options_environment_variable(ScopedVMInitArgs* args) {
|
||||
return parse_options_environment_variable("JAVA_TOOL_OPTIONS", args);
|
||||
}
|
||||
|
||||
jint Arguments::parse_options_environment_variable(const char* name,
|
||||
ScopedVMInitArgs* vm_args) {
|
||||
char *buffer = ::getenv(name);
|
||||
|
||||
// Don't check this variable if user has special privileges
|
||||
// Don't check this environment variable if user has special privileges
|
||||
// (e.g. unix su command).
|
||||
if (buffer == NULL || os::have_special_privileges()) {
|
||||
return JNI_OK;
|
||||
@ -3443,48 +3503,20 @@ jint Arguments::parse_options_environment_variable(const char* name, SysClassPat
|
||||
*wrt++ = *rd++; // copy to option string
|
||||
}
|
||||
}
|
||||
// Need to check if we're done before writing a NULL,
|
||||
// because the write could be to the byte that rd is pointing to.
|
||||
if (*rd++ == 0) {
|
||||
*wrt = 0;
|
||||
break;
|
||||
if (*rd != 0) {
|
||||
// In this case, the assignment to wrt below will make *rd nul,
|
||||
// which will interfere with the next loop iteration.
|
||||
rd++;
|
||||
}
|
||||
*wrt = 0; // Zero terminate option
|
||||
}
|
||||
JavaVMOption* options_arr =
|
||||
NEW_C_HEAP_ARRAY_RETURN_NULL(JavaVMOption, options->length(), mtInternal);
|
||||
if (options_arr == NULL) {
|
||||
|
||||
// Fill out JavaVMInitArgs structure.
|
||||
jint status = vm_args->set_args(options);
|
||||
|
||||
delete options;
|
||||
os::free(buffer);
|
||||
return JNI_ENOMEM;
|
||||
}
|
||||
for (int i = 0; i < options->length(); i++) {
|
||||
options_arr[i] = options->at(i);
|
||||
}
|
||||
|
||||
// Construct JavaVMInitArgs structure and parse as if it was part of the command line
|
||||
JavaVMInitArgs vm_args;
|
||||
vm_args.version = JNI_VERSION_1_2;
|
||||
vm_args.options = options_arr;
|
||||
vm_args.nOptions = options->length();
|
||||
vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions;
|
||||
|
||||
if (PrintVMOptions) {
|
||||
const char* tail;
|
||||
for (int i = 0; i < vm_args.nOptions; i++) {
|
||||
const JavaVMOption *option = vm_args.options + i;
|
||||
if (match_option(option, "-XX:", &tail)) {
|
||||
logOption(tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jint result = parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p,
|
||||
Flag::ENVIRON_VAR);
|
||||
FREE_C_HEAP_ARRAY(JavaVMOption, options_arr);
|
||||
delete options;
|
||||
os::free(buffer);
|
||||
return result;
|
||||
return status;
|
||||
}
|
||||
|
||||
void Arguments::set_shared_spaces_flags() {
|
||||
@ -3567,32 +3599,18 @@ static bool use_vm_log() {
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
// Parse entry point called from JNI_CreateJavaVM
|
||||
|
||||
jint Arguments::parse(const JavaVMInitArgs* args) {
|
||||
|
||||
// Initialize ranges and constraints
|
||||
CommandLineFlagRangeList::init();
|
||||
CommandLineFlagConstraintList::init();
|
||||
|
||||
static jint match_special_option_and_act(const JavaVMInitArgs* args,
|
||||
char** flags_file) {
|
||||
// Remaining part of option string
|
||||
const char* tail;
|
||||
|
||||
// If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
|
||||
const char* hotspotrc = ".hotspotrc";
|
||||
bool settings_file_specified = false;
|
||||
bool needs_hotspotrc_warning = false;
|
||||
|
||||
const char* flags_file;
|
||||
int index;
|
||||
for (index = 0; index < args->nOptions; index++) {
|
||||
for (int index = 0; index < args->nOptions; index++) {
|
||||
const JavaVMOption* option = args->options + index;
|
||||
if (ArgumentsExt::process_options(option)) {
|
||||
continue;
|
||||
}
|
||||
if (match_option(option, "-XX:Flags=", &tail)) {
|
||||
flags_file = tail;
|
||||
settings_file_specified = true;
|
||||
*flags_file = (char *) tail;
|
||||
continue;
|
||||
}
|
||||
if (match_option(option, "-XX:+PrintVMOptions")) {
|
||||
@ -3646,10 +3664,69 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return JNI_OK;
|
||||
}
|
||||
|
||||
static void print_options(const JavaVMInitArgs *args) {
|
||||
const char* tail;
|
||||
for (int index = 0; index < args->nOptions; index++) {
|
||||
const JavaVMOption *option = args->options + index;
|
||||
if (match_option(option, "-XX:", &tail)) {
|
||||
logOption(tail);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Parse entry point called from JNI_CreateJavaVM
|
||||
|
||||
jint Arguments::parse(const JavaVMInitArgs* args) {
|
||||
|
||||
// Initialize ranges and constraints
|
||||
CommandLineFlagRangeList::init();
|
||||
CommandLineFlagConstraintList::init();
|
||||
|
||||
// If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
|
||||
const char* hotspotrc = ".hotspotrc";
|
||||
char* flags_file = NULL;
|
||||
bool settings_file_specified = false;
|
||||
bool needs_hotspotrc_warning = false;
|
||||
ScopedVMInitArgs java_tool_options_args;
|
||||
ScopedVMInitArgs java_options_args;
|
||||
|
||||
jint code =
|
||||
parse_java_tool_options_environment_variable(&java_tool_options_args);
|
||||
if (code != JNI_OK) {
|
||||
return code;
|
||||
}
|
||||
|
||||
code = parse_java_options_environment_variable(&java_options_args);
|
||||
if (code != JNI_OK) {
|
||||
return code;
|
||||
}
|
||||
|
||||
code =
|
||||
match_special_option_and_act(java_tool_options_args.get(), &flags_file);
|
||||
if (code != JNI_OK) {
|
||||
return code;
|
||||
}
|
||||
|
||||
code = match_special_option_and_act(args, &flags_file);
|
||||
if (code != JNI_OK) {
|
||||
return code;
|
||||
}
|
||||
|
||||
code = match_special_option_and_act(java_options_args.get(), &flags_file);
|
||||
if (code != JNI_OK) {
|
||||
return code;
|
||||
}
|
||||
|
||||
settings_file_specified = (flags_file != NULL);
|
||||
|
||||
if (IgnoreUnrecognizedVMOptions) {
|
||||
// uncast const to modify the flag args->ignoreUnrecognized
|
||||
*(jboolean*)(&args->ignoreUnrecognized) = true;
|
||||
java_tool_options_args.get()->ignoreUnrecognized = true;
|
||||
java_options_args.get()->ignoreUnrecognized = true;
|
||||
}
|
||||
|
||||
// Parse specified settings file
|
||||
@ -3672,16 +3749,15 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
|
||||
}
|
||||
|
||||
if (PrintVMOptions) {
|
||||
for (index = 0; index < args->nOptions; index++) {
|
||||
const JavaVMOption *option = args->options + index;
|
||||
if (match_option(option, "-XX:", &tail)) {
|
||||
logOption(tail);
|
||||
}
|
||||
}
|
||||
print_options(java_tool_options_args.get());
|
||||
print_options(args);
|
||||
print_options(java_options_args.get());
|
||||
}
|
||||
|
||||
// Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
|
||||
jint result = parse_vm_init_args(args);
|
||||
jint result = parse_vm_init_args(java_tool_options_args.get(),
|
||||
java_options_args.get(), args);
|
||||
|
||||
if (result != JNI_OK) {
|
||||
return result;
|
||||
}
|
||||
|
@ -220,6 +220,8 @@ class AgentLibraryList VALUE_OBJ_CLASS_SPEC {
|
||||
}
|
||||
};
|
||||
|
||||
// Helper class for controlling the lifetime of JavaVMInitArgs objects.
|
||||
class ScopedVMInitArgs;
|
||||
|
||||
class Arguments : AllStatic {
|
||||
friend class VMStructs;
|
||||
@ -374,10 +376,12 @@ class Arguments : AllStatic {
|
||||
static bool process_argument(const char* arg, jboolean ignore_unrecognized, Flag::Flags origin);
|
||||
static void process_java_launcher_argument(const char*, void*);
|
||||
static void process_java_compiler_argument(char* arg);
|
||||
static jint parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p);
|
||||
static jint parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p);
|
||||
static jint parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p);
|
||||
static jint parse_vm_init_args(const JavaVMInitArgs* args);
|
||||
static jint parse_options_environment_variable(const char* name, ScopedVMInitArgs* vm_args);
|
||||
static jint parse_java_tool_options_environment_variable(ScopedVMInitArgs* vm_args);
|
||||
static jint parse_java_options_environment_variable(ScopedVMInitArgs* vm_args);
|
||||
static jint parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
|
||||
const JavaVMInitArgs *java_options_args,
|
||||
const JavaVMInitArgs *cmd_line_args);
|
||||
static jint parse_each_vm_init_arg(const JavaVMInitArgs* args, SysClassPath* scp_p, bool* scp_assembly_required_p, Flag::Flags origin);
|
||||
static jint finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required);
|
||||
static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);
|
||||
|
Loading…
Reference in New Issue
Block a user