This commit is contained in:
Coleen Phillimore 2015-07-18 04:53:32 +02:00
commit a692c78dfc
2 changed files with 161 additions and 81 deletions

View File

@ -91,7 +91,7 @@ const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER;
int Arguments::_sun_java_launcher_pid = -1; int Arguments::_sun_java_launcher_pid = -1;
bool Arguments::_sun_java_launcher_is_altjvm = false; 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::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
bool Arguments::_UseOnStackReplacement = UseOnStackReplacement; bool Arguments::_UseOnStackReplacement = UseOnStackReplacement;
bool Arguments::_BackgroundCompilation = BackgroundCompilation; bool Arguments::_BackgroundCompilation = BackgroundCompilation;
@ -2251,7 +2251,9 @@ Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
// Parse JavaVMInitArgs structure // 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. // For components of the system classpath.
SysClassPath scp(Arguments::get_sysclasspath()); SysClassPath scp(Arguments::get_sysclasspath());
bool scp_assembly_required = false; 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 // Setup flags for mixed which is the default
set_mode_flags(_mixed); set_mode_flags(_mixed);
// Parse JAVA_TOOL_OPTIONS environment variable (if present) // Parse args structure generated from JAVA_TOOL_OPTIONS environment
jint result = parse_java_tool_options_environment_variable(&scp, &scp_assembly_required); // 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) { if (result != JNI_OK) {
return result; return result;
} }
// Parse JavaVMInitArgs structure passed in // Parse args structure generated from the command line flags.
result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, Flag::COMMAND_LINE); result = parse_each_vm_init_arg(cmd_line_args, &scp, &scp_assembly_required,
Flag::COMMAND_LINE);
if (result != JNI_OK) { if (result != JNI_OK) {
return result; return result;
} }
// Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) // Parse args structure generated from the _JAVA_OPTIONS environment
result = parse_java_options_environment_variable(&scp, &scp_assembly_required); // 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) { if (result != JNI_OK) {
return result; return result;
} }
@ -3385,20 +3392,73 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
return JNI_OK; return JNI_OK;
} }
jint Arguments::parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p) { // Helper class for controlling the lifetime of JavaVMInitArgs
return parse_options_environment_variable("_JAVA_OPTIONS", scp_p, // objects. The contents of the JavaVMInitArgs are guaranteed to be
scp_assembly_required_p); // 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) { // Populates the JavaVMInitArgs object represented by this
return parse_options_environment_variable("JAVA_TOOL_OPTIONS", scp_p, // ScopedVMInitArgs object with the arguments in options. The
scp_assembly_required_p); // 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); 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). // (e.g. unix su command).
if (buffer == NULL || os::have_special_privileges()) { if (buffer == NULL || os::have_special_privileges()) {
return JNI_OK; return JNI_OK;
@ -3443,48 +3503,20 @@ jint Arguments::parse_options_environment_variable(const char* name, SysClassPat
*wrt++ = *rd++; // copy to option string *wrt++ = *rd++; // copy to option string
} }
} }
// Need to check if we're done before writing a NULL, if (*rd != 0) {
// because the write could be to the byte that rd is pointing to. // In this case, the assignment to wrt below will make *rd nul,
if (*rd++ == 0) { // which will interfere with the next loop iteration.
*wrt = 0; rd++;
break;
} }
*wrt = 0; // Zero terminate option *wrt = 0; // Zero terminate option
} }
JavaVMOption* options_arr =
NEW_C_HEAP_ARRAY_RETURN_NULL(JavaVMOption, options->length(), mtInternal); // Fill out JavaVMInitArgs structure.
if (options_arr == NULL) { jint status = vm_args->set_args(options);
delete options; delete options;
os::free(buffer); os::free(buffer);
return JNI_ENOMEM; return status;
}
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;
} }
void Arguments::set_shared_spaces_flags() { void Arguments::set_shared_spaces_flags() {
@ -3567,32 +3599,18 @@ static bool use_vm_log() {
} }
#endif // PRODUCT #endif // PRODUCT
// Parse entry point called from JNI_CreateJavaVM static jint match_special_option_and_act(const JavaVMInitArgs* args,
char** flags_file) {
jint Arguments::parse(const JavaVMInitArgs* args) {
// Initialize ranges and constraints
CommandLineFlagRangeList::init();
CommandLineFlagConstraintList::init();
// Remaining part of option string // Remaining part of option string
const char* tail; const char* tail;
// If flag "-XX:Flags=flags-file" is used it will be the first option to be processed. for (int index = 0; index < args->nOptions; index++) {
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; const JavaVMOption* option = args->options + index;
if (ArgumentsExt::process_options(option)) { if (ArgumentsExt::process_options(option)) {
continue; continue;
} }
if (match_option(option, "-XX:Flags=", &tail)) { if (match_option(option, "-XX:Flags=", &tail)) {
flags_file = tail; *flags_file = (char *) tail;
settings_file_specified = true;
continue; continue;
} }
if (match_option(option, "-XX:+PrintVMOptions")) { if (match_option(option, "-XX:+PrintVMOptions")) {
@ -3646,10 +3664,69 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
} }
#endif #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) { if (IgnoreUnrecognizedVMOptions) {
// uncast const to modify the flag args->ignoreUnrecognized // uncast const to modify the flag args->ignoreUnrecognized
*(jboolean*)(&args->ignoreUnrecognized) = true; *(jboolean*)(&args->ignoreUnrecognized) = true;
java_tool_options_args.get()->ignoreUnrecognized = true;
java_options_args.get()->ignoreUnrecognized = true;
} }
// Parse specified settings file // Parse specified settings file
@ -3672,16 +3749,15 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
} }
if (PrintVMOptions) { if (PrintVMOptions) {
for (index = 0; index < args->nOptions; index++) { print_options(java_tool_options_args.get());
const JavaVMOption *option = args->options + index; print_options(args);
if (match_option(option, "-XX:", &tail)) { print_options(java_options_args.get());
logOption(tail);
}
}
} }
// Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS // 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) { if (result != JNI_OK) {
return result; return result;
} }

View File

@ -220,6 +220,8 @@ class AgentLibraryList VALUE_OBJ_CLASS_SPEC {
} }
}; };
// Helper class for controlling the lifetime of JavaVMInitArgs objects.
class ScopedVMInitArgs;
class Arguments : AllStatic { class Arguments : AllStatic {
friend class VMStructs; friend class VMStructs;
@ -374,10 +376,12 @@ class Arguments : AllStatic {
static bool process_argument(const char* arg, jboolean ignore_unrecognized, Flag::Flags origin); 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_launcher_argument(const char*, void*);
static void process_java_compiler_argument(char* arg); 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_options_environment_variable(const char* name, ScopedVMInitArgs* vm_args);
static jint parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p); static jint parse_java_tool_options_environment_variable(ScopedVMInitArgs* vm_args);
static jint parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p); static jint parse_java_options_environment_variable(ScopedVMInitArgs* vm_args);
static jint parse_vm_init_args(const JavaVMInitArgs* 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 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 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); static bool is_bad_option(const JavaVMOption* option, jboolean ignore, const char* option_type);