--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Jul 16 15:01:12 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Jul 17 19:40:21 2015 -0400
@@ -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;
@@ -2251,7 +2251,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;
@@ -2269,20 +2271,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;
}
@@ -3385,20 +3392,73 @@
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;
+ }
+
+ // 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;
+ }
+ }
+
+ _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(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(ScopedVMInitArgs* 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,
+ 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 @@
*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) {
- 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);
+
+ // Fill out JavaVMInitArgs structure.
+ jint status = vm_args->set_args(options);
+
delete options;
os::free(buffer);
- return result;
+ return status;
}
void Arguments::set_shared_spaces_flags() {
@@ -3567,32 +3599,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 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++) {
- 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")) {
@@ -3646,10 +3664,69 @@
}
#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 @@
}
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;
}
--- a/hotspot/src/share/vm/runtime/arguments.hpp Thu Jul 16 15:01:12 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.hpp Fri Jul 17 19:40:21 2015 -0400
@@ -220,6 +220,8 @@
}
};
+// Helper class for controlling the lifetime of JavaVMInitArgs objects.
+class ScopedVMInitArgs;
class Arguments : AllStatic {
friend class VMStructs;
@@ -374,10 +376,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, 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);