--- old/src/share/vm/runtime/arguments.cpp 2015-07-10 10:12:09.928591000 -0700 +++ new/src/share/vm/runtime/arguments.cpp 2015-07-10 10:12:09.822582000 -0700 @@ -91,7 +91,7 @@ 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; @@ -2249,7 +2249,9 @@ // 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; @@ -2267,20 +2269,25 @@ // 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; } @@ -3383,20 +3390,23 @@ 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); +jint Arguments::parse_java_options_environment_variable(JavaVMInitArgs* args) { + return parse_options_environment_variable("_JAVA_OPTIONS", args); } -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); +jint Arguments::parse_java_tool_options_environment_variable(JavaVMInitArgs* args) { + return parse_options_environment_variable("JAVA_TOOL_OPTIONS", args); } -jint Arguments::parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p) { +jint Arguments::parse_options_environment_variable(const char* name, JavaVMInitArgs* vm_args) { char *buffer = ::getenv(name); - // Don't check this variable if user has special privileges + vm_args->version = JNI_VERSION_1_2; + vm_args->options = NULL; + vm_args->nOptions = 0; + vm_args->ignoreUnrecognized = false; + + // 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; @@ -3422,6 +3432,7 @@ JavaVMOption option; option.optionString = wrt; options->append(option); // Fill in option + while (*rd != 0 && !isspace(*rd)) { // unquoted strings terminate with a space or NULL if (*rd == '\'' || *rd == '"') { // handle a quoted string int quote = *rd; // matching quote to look for @@ -3441,14 +3452,15 @@ *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 } + + // Fill out JavaVMInitArgs structure. JavaVMOption* options_arr = NEW_C_HEAP_ARRAY_RETURN_NULL(JavaVMOption, options->length(), mtInternal); if (options_arr == NULL) { @@ -3458,31 +3470,23 @@ } for (int i = 0; i < options->length(); i++) { options_arr[i] = options->at(i); + options_arr[i].optionString = os::strdup(options_arr[i].optionString); } - // 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); - } - } - } + vm_args->options = options_arr; + vm_args->nOptions = options->length(); + vm_args->ignoreUnrecognized = IgnoreUnrecognizedVMOptions; - 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 JNI_OK; +} + +static void free_memory_for_vm_init_args(JavaVMInitArgs* args) { + for (int i = 0; i < args->nOptions; i++) { + os::free(args->options[i].optionString); + } + FREE_C_HEAP_ARRAY(JavaVMOption, args->options); } void Arguments::set_shared_spaces_flags() { @@ -3565,32 +3569,18 @@ } #endif // PRODUCT -// Parse entry point called from JNI_CreateJavaVM - -jint Arguments::parse(const JavaVMInitArgs* args) { - - // Initialize ranges and constraints - CommandLineFlagRangeList::init(); - CommandLineFlagConstraintList::init(); - +static int 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++) { - const JavaVMOption *option = args->options + 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")) { @@ -3644,15 +3634,59 @@ } #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) { + // 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; + JavaVMInitArgs java_tool_options_args; + JavaVMInitArgs java_options_args; + + int 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) { + free_memory_for_vm_init_args(&java_tool_options_args); + return code; + } + + match_special_option_and_act(&java_tool_options_args, &flags_file); + match_special_option_and_act(args, &flags_file); + match_special_option_and_act(&java_options_args, &flags_file); + settings_file_specified = (flags_file != NULL); if (IgnoreUnrecognizedVMOptions) { // uncast const to modify the flag args->ignoreUnrecognized *(jboolean*)(&args->ignoreUnrecognized) = true; + java_tool_options_args.ignoreUnrecognized = true; + java_options_args.ignoreUnrecognized = true; } // Parse specified settings file if (settings_file_specified) { if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) { + free_memory_for_vm_init_args(&java_tool_options_args); + free_memory_for_vm_init_args(&java_options_args); return JNI_EINVAL; } } else { @@ -3670,16 +3704,19 @@ } 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); + print_options(args); + print_options(&java_options_args); } // 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, &java_options_args, args); + + // Done with the envvars + free_memory_for_vm_init_args(&java_tool_options_args); + free_memory_for_vm_init_args(&java_options_args); + if (result != JNI_OK) { return result; } --- old/src/share/vm/runtime/arguments.hpp 2015-07-10 10:12:10.607588000 -0700 +++ new/src/share/vm/runtime/arguments.hpp 2015-07-10 10:12:10.501583000 -0700 @@ -374,10 +374,12 @@ 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, JavaVMInitArgs* vm_args); + static jint parse_java_tool_options_environment_variable(JavaVMInitArgs* vm_args); + static jint parse_java_options_environment_variable(JavaVMInitArgs* 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);