39 #include "runtime/arguments.hpp"
40 #include "runtime/arguments_ext.hpp"
41 #include "runtime/globals_extension.hpp"
42 #include "runtime/java.hpp"
43 #include "runtime/os.hpp"
44 #include "runtime/vm_version.hpp"
45 #include "services/management.hpp"
46 #include "services/memTracker.hpp"
47 #include "utilities/defaultStream.hpp"
48 #include "utilities/macros.hpp"
49 #include "utilities/stringUtils.hpp"
50 #if INCLUDE_ALL_GCS
51 #include "gc/cms/compactibleFreeListSpace.hpp"
52 #include "gc/g1/g1CollectedHeap.inline.hpp"
53 #include "gc/parallel/parallelScavengeHeap.hpp"
54 #endif // INCLUDE_ALL_GCS
55
56 // Note: This is a special bug reporting site for the JVM
57 #define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp"
58 #define DEFAULT_JAVA_LAUNCHER "generic"
59
60 #define UNSUPPORTED_GC_OPTION(gc) \
61 do { \
62 if (gc) { \
63 if (FLAG_IS_CMDLINE(gc)) { \
64 warning(#gc " is not supported in this VM. Using Serial GC."); \
65 } \
66 FLAG_SET_DEFAULT(gc, false); \
67 } \
68 } while(0)
69
70 char** Arguments::_jvm_flags_array = NULL;
71 int Arguments::_num_jvm_flags = 0;
72 char** Arguments::_jvm_args_array = NULL;
73 int Arguments::_num_jvm_args = 0;
74 char* Arguments::_java_command = NULL;
75 SystemProperty* Arguments::_system_properties = NULL;
76 const char* Arguments::_gc_log_filename = NULL;
77 bool Arguments::_has_profile = false;
78 size_t Arguments::_conservative_max_heap_alignment = 0;
95 intx Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
96 intx Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
97
98 char* Arguments::SharedArchivePath = NULL;
99
100 AgentLibraryList Arguments::_libraryList;
101 AgentLibraryList Arguments::_agentList;
102
103 abort_hook_t Arguments::_abort_hook = NULL;
104 exit_hook_t Arguments::_exit_hook = NULL;
105 vfprintf_hook_t Arguments::_vfprintf_hook = NULL;
106
107
108 SystemProperty *Arguments::_sun_boot_library_path = NULL;
109 SystemProperty *Arguments::_java_library_path = NULL;
110 SystemProperty *Arguments::_java_home = NULL;
111 SystemProperty *Arguments::_java_class_path = NULL;
112 SystemProperty *Arguments::_sun_boot_class_path = NULL;
113
114 char* Arguments::_ext_dirs = NULL;
115
116 // Check if head of 'option' matches 'name', and sets 'tail' to the remaining
117 // part of the option string.
118 static bool match_option(const JavaVMOption *option, const char* name,
119 const char** tail) {
120 int len = (int)strlen(name);
121 if (strncmp(option->optionString, name, len) == 0) {
122 *tail = option->optionString + len;
123 return true;
124 } else {
125 return false;
126 }
127 }
128
129 // Check if 'option' matches 'name'. No "tail" is allowed.
130 static bool match_option(const JavaVMOption *option, const char* name) {
131 const char* tail = NULL;
132 bool result = match_option(option, name, &tail);
133 if (tail != NULL && *tail == '\0') {
134 return result;
135 } else {
2627 }
2628
2629 return true;
2630 }
2631
2632 if (strcmp(name, _hprof) == 0 || strcmp(name, _jdwp) == 0) {
2633 return true;
2634 }
2635
2636 return false;
2637 }
2638
2639 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
2640 SysClassPath* scp_p,
2641 bool* scp_assembly_required_p,
2642 Flag::Flags origin) {
2643 // Remaining part of option string
2644 const char* tail;
2645
2646 // iterate over arguments
2647 for (int index = 0; index < args->nOptions; index++) {
2648 bool is_absolute_path = false; // for -agentpath vs -agentlib
2649
2650 const JavaVMOption* option = args->options + index;
2651
2652 if (!match_option(option, "-Djava.class.path", &tail) &&
2653 !match_option(option, "-Dsun.java.command", &tail) &&
2654 !match_option(option, "-Dsun.java.launcher", &tail)) {
2655
2656 // add all jvm options to the jvm_args string. This string
2657 // is used later to set the java.vm.args PerfData string constant.
2658 // the -Djava.class.path and the -Dsun.java.command options are
2659 // omitted from jvm_args string as each have their own PerfData
2660 // string constant object.
2661 build_jvm_args(option->optionString);
2662 }
2663
2664 // -verbose:[class/gc/jni]
2665 if (match_option(option, "-verbose", &tail)) {
2666 if (!strcmp(tail, ":class") || !strcmp(tail, "")) {
3260 describe_range_error(errcode);
3261 return JNI_EINVAL;
3262 }
3263 FLAG_SET_CMDLINE(size_t, MaxDirectMemorySize, max_direct_memory_size);
3264 #if !INCLUDE_MANAGEMENT
3265 } else if (match_option(option, "-XX:+ManagementServer")) {
3266 jio_fprintf(defaultStream::error_stream(),
3267 "ManagementServer is not supported in this VM.\n");
3268 return JNI_ERR;
3269 #endif // INCLUDE_MANAGEMENT
3270 // CreateMinidumpOnCrash is removed, and replaced by CreateCoredumpOnCrash
3271 } else if (match_option(option, "-XX:+CreateMinidumpOnCrash")) {
3272 FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, true);
3273 jio_fprintf(defaultStream::output_stream(),
3274 "CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is on\n");
3275 } else if (match_option(option, "-XX:-CreateMinidumpOnCrash")) {
3276 FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, false);
3277 jio_fprintf(defaultStream::output_stream(),
3278 "CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is off\n");
3279 } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
3280 // Skip -XX:Flags= since that case has already been handled
3281 if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) {
3282 if (!process_argument(tail, args->ignoreUnrecognized, origin)) {
3283 return JNI_EINVAL;
3284 }
3285 }
3286 // Unknown option
3287 } else if (is_bad_option(option, args->ignoreUnrecognized)) {
3288 return JNI_ERR;
3289 }
3290 }
3291
3292 // PrintSharedArchiveAndExit will turn on
3293 // -Xshare:on
3294 // -XX:+TraceClassPaths
3295 if (PrintSharedArchiveAndExit) {
3296 FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
3297 FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
3298 FLAG_SET_CMDLINE(bool, TraceClassPaths, true);
3299 }
3300
3301 // Change the default value for flags which have different default values
3681 (VerifyDependencies && FLAG_IS_CMDLINE(VerifyDependencies))) {
3682 return true;
3683 }
3684
3685 #ifdef COMPILER1
3686 if (PrintC1Statistics) {
3687 return true;
3688 }
3689 #endif // COMPILER1
3690
3691 #ifdef COMPILER2
3692 if (PrintOptoAssembly || PrintOptoStatistics) {
3693 return true;
3694 }
3695 #endif // COMPILER2
3696
3697 return false;
3698 }
3699 #endif // PRODUCT
3700
3701 // Parse entry point called from JNI_CreateJavaVM
3702
3703 jint Arguments::parse(const JavaVMInitArgs* args) {
3704
3705 // Remaining part of option string
3706 const char* tail;
3707
3708 // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
3709 const char* hotspotrc = ".hotspotrc";
3710 bool settings_file_specified = false;
3711 bool needs_hotspotrc_warning = false;
3712
3713 const char* flags_file;
3714 int index;
3715 for (index = 0; index < args->nOptions; index++) {
3716 const JavaVMOption *option = args->options + index;
3717 if (ArgumentsExt::process_options(option)) {
3718 continue;
3719 }
3720 if (match_option(option, "-XX:Flags=", &tail)) {
3721 flags_file = tail;
3722 settings_file_specified = true;
3723 continue;
3724 }
3725 if (match_option(option, "-XX:+PrintVMOptions")) {
3726 PrintVMOptions = true;
3727 continue;
3728 }
3729 if (match_option(option, "-XX:-PrintVMOptions")) {
3730 PrintVMOptions = false;
3731 continue;
3732 }
3733 if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions")) {
3734 IgnoreUnrecognizedVMOptions = true;
3735 continue;
3736 }
3765 return JNI_ERR;
3766 #endif
3767 }
3768
3769 #ifndef PRODUCT
3770 if (match_option(option, "-XX:+PrintFlagsWithComments")) {
3771 CommandLineFlags::printFlags(tty, true);
3772 vm_exit(0);
3773 }
3774 #endif
3775 }
3776
3777 if (IgnoreUnrecognizedVMOptions) {
3778 // uncast const to modify the flag args->ignoreUnrecognized
3779 *(jboolean*)(&args->ignoreUnrecognized) = true;
3780 }
3781
3782 // Parse specified settings file
3783 if (settings_file_specified) {
3784 if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) {
3785 return JNI_EINVAL;
3786 }
3787 } else {
3788 #ifdef ASSERT
3789 // Parse default .hotspotrc settings file
3790 if (!process_settings_file(".hotspotrc", false, args->ignoreUnrecognized)) {
3791 return JNI_EINVAL;
3792 }
3793 #else
3794 struct stat buf;
3795 if (os::stat(hotspotrc, &buf) == 0) {
3796 needs_hotspotrc_warning = true;
3797 }
3798 #endif
3799 }
3800
3801 if (PrintVMOptions) {
3802 for (index = 0; index < args->nOptions; index++) {
3803 const JavaVMOption *option = args->options + index;
3804 if (match_option(option, "-XX:", &tail)) {
3805 logOption(tail);
3806 }
3807 }
3808 }
3809
3810 // Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
3811 jint result = parse_vm_init_args(args);
3812 if (result != JNI_OK) {
3813 return result;
3814 }
3815
3816 // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
3817 SharedArchivePath = get_shared_archive_path();
3818 if (SharedArchivePath == NULL) {
3819 return JNI_ENOMEM;
3820 }
3821
3822 // Set up VerifySharedSpaces
3823 if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
3824 VerifySharedSpaces = true;
3825 }
3826
3827 // Delay warning until here so that we've had a chance to process
3828 // the -XX:-PrintWarnings flag
3829 if (needs_hotspotrc_warning) {
3830 warning("%s file is present but has been ignored. "
3831 "Run with -XX:Flags=%s to load the file.",
3832 hotspotrc, hotspotrc);
3833 }
3834
3835 #if defined(_ALLBSD_SOURCE) || defined(AIX) // UseLargePages is not yet supported on BSD and AIX.
|
39 #include "runtime/arguments.hpp"
40 #include "runtime/arguments_ext.hpp"
41 #include "runtime/globals_extension.hpp"
42 #include "runtime/java.hpp"
43 #include "runtime/os.hpp"
44 #include "runtime/vm_version.hpp"
45 #include "services/management.hpp"
46 #include "services/memTracker.hpp"
47 #include "utilities/defaultStream.hpp"
48 #include "utilities/macros.hpp"
49 #include "utilities/stringUtils.hpp"
50 #if INCLUDE_ALL_GCS
51 #include "gc/cms/compactibleFreeListSpace.hpp"
52 #include "gc/g1/g1CollectedHeap.inline.hpp"
53 #include "gc/parallel/parallelScavengeHeap.hpp"
54 #endif // INCLUDE_ALL_GCS
55
56 // Note: This is a special bug reporting site for the JVM
57 #define DEFAULT_VENDOR_URL_BUG "http://bugreport.java.com/bugreport/crash.jsp"
58 #define DEFAULT_JAVA_LAUNCHER "generic"
59 #define N_MAX_OPTIONS 64
60 #define OPTION_BUFFER_SIZE 1024
61
62 #define UNSUPPORTED_GC_OPTION(gc) \
63 do { \
64 if (gc) { \
65 if (FLAG_IS_CMDLINE(gc)) { \
66 warning(#gc " is not supported in this VM. Using Serial GC."); \
67 } \
68 FLAG_SET_DEFAULT(gc, false); \
69 } \
70 } while(0)
71
72 char** Arguments::_jvm_flags_array = NULL;
73 int Arguments::_num_jvm_flags = 0;
74 char** Arguments::_jvm_args_array = NULL;
75 int Arguments::_num_jvm_args = 0;
76 char* Arguments::_java_command = NULL;
77 SystemProperty* Arguments::_system_properties = NULL;
78 const char* Arguments::_gc_log_filename = NULL;
79 bool Arguments::_has_profile = false;
80 size_t Arguments::_conservative_max_heap_alignment = 0;
97 intx Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
98 intx Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
99
100 char* Arguments::SharedArchivePath = NULL;
101
102 AgentLibraryList Arguments::_libraryList;
103 AgentLibraryList Arguments::_agentList;
104
105 abort_hook_t Arguments::_abort_hook = NULL;
106 exit_hook_t Arguments::_exit_hook = NULL;
107 vfprintf_hook_t Arguments::_vfprintf_hook = NULL;
108
109
110 SystemProperty *Arguments::_sun_boot_library_path = NULL;
111 SystemProperty *Arguments::_java_library_path = NULL;
112 SystemProperty *Arguments::_java_home = NULL;
113 SystemProperty *Arguments::_java_class_path = NULL;
114 SystemProperty *Arguments::_sun_boot_class_path = NULL;
115
116 char* Arguments::_ext_dirs = NULL;
117 // change the 0 on next line to 1 to enable argument tracing
118 #if 0
119 #define JVM_ARGS_ETRACE(x) x
120 #else
121 #define JVM_ARGS_ETRACE(x)
122 #endif
123
124 // Dump VM Option with a tag
125 void DumpOption(const JavaVMOption *option_p,
126 const int index, const char *tag) {
127 if (PrintVMOptions && Verbose) {
128 if (index >= 0) {
129 jio_fprintf(defaultStream::output_stream(),
130 "%s:[%d]='%s'\n", tag, index, option_p->optionString);
131 }
132 }
133 }
134
135 // Dump VM Option with a tag
136 void DumpVMOption(const JavaVMInitArgs* args_p,
137 const int index, const char *tag) {
138 if (PrintVMOptions && Verbose) {
139 if (args_p->options != NULL) {
140 if ((index >= 0) && (index < args_p->nOptions)) {
141 JavaVMOption *option_p = args_p->options + index;
142 jio_fprintf(defaultStream::output_stream(),
143 "%s:[%d]='%s'\n", tag, index, option_p->optionString);
144 }
145 }
146 }
147 }
148
149 // Dump VM Options with a tag
150 void DumpVMOptions(const JavaVMInitArgs* args_p, const char *tag) {
151 if (PrintVMOptions && Verbose) {
152 if (args_p->options != NULL) {
153 for (int index = 0; index < args_p->nOptions; index++) {
154 JavaVMOption *option_p = args_p->options + index;
155 jio_fprintf(defaultStream::output_stream(),
156 "%s:[%d]='%s'\n", tag, index, option_p->optionString);
157 }
158 }
159 }
160 }
161
162 // Free memory associated with an options list
163 void FreeVMOptions(JavaVMInitArgs **args_pp, const JavaVMInitArgs *args_base_p) {
164 assert(args_pp != NULL, "args_pp must not be NULL");
165 assert(*args_pp != NULL, "*args_pp must not be NULL");
166 if (args_base_p == (*args_pp)) {
167 // Do not free memory we did not allocate
168 return;
169 }
170 assert((*args_pp)->options != NULL, "(*args_pp)->options must not be NULL");
171 for (int index = 0; index < (*args_pp)->nOptions; index++) {
172 JavaVMOption *option_p = (*args_pp)->options + index;
173 if (option_p->optionString != NULL) {
174 os::free(option_p->optionString);
175 option_p->optionString = NULL;
176 }
177 }
178 os::free((void *)(*args_pp)->options);
179 (*args_pp)->options = NULL;
180 os::free((void *)(*args_pp));
181 (*args_pp) = NULL;
182 }
183
184 // Check if head of 'option' matches 'name', and sets 'tail' to the remaining
185 // part of the option string.
186 static bool match_option(const JavaVMOption *option, const char* name,
187 const char** tail) {
188 int len = (int)strlen(name);
189 if (strncmp(option->optionString, name, len) == 0) {
190 *tail = option->optionString + len;
191 return true;
192 } else {
193 return false;
194 }
195 }
196
197 // Check if 'option' matches 'name'. No "tail" is allowed.
198 static bool match_option(const JavaVMOption *option, const char* name) {
199 const char* tail = NULL;
200 bool result = match_option(option, name, &tail);
201 if (tail != NULL && *tail == '\0') {
202 return result;
203 } else {
2695 }
2696
2697 return true;
2698 }
2699
2700 if (strcmp(name, _hprof) == 0 || strcmp(name, _jdwp) == 0) {
2701 return true;
2702 }
2703
2704 return false;
2705 }
2706
2707 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
2708 SysClassPath* scp_p,
2709 bool* scp_assembly_required_p,
2710 Flag::Flags origin) {
2711 // Remaining part of option string
2712 const char* tail;
2713
2714 // iterate over arguments
2715 DumpVMOptions(args, "Parse each");
2716 for (int index = 0; index < args->nOptions; index++) {
2717 bool is_absolute_path = false; // for -agentpath vs -agentlib
2718
2719 const JavaVMOption* option = args->options + index;
2720
2721 if (!match_option(option, "-Djava.class.path", &tail) &&
2722 !match_option(option, "-Dsun.java.command", &tail) &&
2723 !match_option(option, "-Dsun.java.launcher", &tail)) {
2724
2725 // add all jvm options to the jvm_args string. This string
2726 // is used later to set the java.vm.args PerfData string constant.
2727 // the -Djava.class.path and the -Dsun.java.command options are
2728 // omitted from jvm_args string as each have their own PerfData
2729 // string constant object.
2730 build_jvm_args(option->optionString);
2731 }
2732
2733 // -verbose:[class/gc/jni]
2734 if (match_option(option, "-verbose", &tail)) {
2735 if (!strcmp(tail, ":class") || !strcmp(tail, "")) {
3329 describe_range_error(errcode);
3330 return JNI_EINVAL;
3331 }
3332 FLAG_SET_CMDLINE(size_t, MaxDirectMemorySize, max_direct_memory_size);
3333 #if !INCLUDE_MANAGEMENT
3334 } else if (match_option(option, "-XX:+ManagementServer")) {
3335 jio_fprintf(defaultStream::error_stream(),
3336 "ManagementServer is not supported in this VM.\n");
3337 return JNI_ERR;
3338 #endif // INCLUDE_MANAGEMENT
3339 // CreateMinidumpOnCrash is removed, and replaced by CreateCoredumpOnCrash
3340 } else if (match_option(option, "-XX:+CreateMinidumpOnCrash")) {
3341 FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, true);
3342 jio_fprintf(defaultStream::output_stream(),
3343 "CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is on\n");
3344 } else if (match_option(option, "-XX:-CreateMinidumpOnCrash")) {
3345 FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, false);
3346 jio_fprintf(defaultStream::output_stream(),
3347 "CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is off\n");
3348 } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
3349 // Skip -XX:Flags= and -XX:VMOptionsFile= since those cases have
3350 // already been handled
3351 if ((strncmp(tail, "Flags=", strlen("Flags=")) != 0) &&
3352 (strncmp(tail, "VMOptionsFile=", strlen("VMOptionsFile=")) != 0)) {
3353 if (!process_argument(tail, args->ignoreUnrecognized, origin)) {
3354 return JNI_EINVAL;
3355 }
3356 }
3357 // Unknown option
3358 } else if (is_bad_option(option, args->ignoreUnrecognized)) {
3359 return JNI_ERR;
3360 }
3361 }
3362
3363 // PrintSharedArchiveAndExit will turn on
3364 // -Xshare:on
3365 // -XX:+TraceClassPaths
3366 if (PrintSharedArchiveAndExit) {
3367 FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
3368 FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
3369 FLAG_SET_CMDLINE(bool, TraceClassPaths, true);
3370 }
3371
3372 // Change the default value for flags which have different default values
3752 (VerifyDependencies && FLAG_IS_CMDLINE(VerifyDependencies))) {
3753 return true;
3754 }
3755
3756 #ifdef COMPILER1
3757 if (PrintC1Statistics) {
3758 return true;
3759 }
3760 #endif // COMPILER1
3761
3762 #ifdef COMPILER2
3763 if (PrintOptoAssembly || PrintOptoStatistics) {
3764 return true;
3765 }
3766 #endif // COMPILER2
3767
3768 return false;
3769 }
3770 #endif // PRODUCT
3771
3772 jint Arguments::alloc_JVM_options_list(const int needed_slots,
3773 const int version,
3774 struct JavaVMInitArgs **ret_args_head) {
3775 assert(needed_slots > 0, "needed_slots must greater than zero");
3776 assert(ret_args_head != NULL, "ret_args_head must not be NULL");
3777
3778 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
3779 "Allocating %d option slots\n", needed_slots));
3780 JavaVMInitArgs *new_args_head =
3781 (JavaVMInitArgs *) os::malloc(sizeof (JavaVMInitArgs), mtInternal);
3782 if (new_args_head == NULL) {
3783 jio_fprintf(defaultStream::error_stream(),
3784 "Could not allocate arguments list head\n");
3785 return JNI_ENOMEM;
3786 }
3787
3788 memset(new_args_head, 0, sizeof (struct JavaVMInitArgs));
3789
3790 int bytes_needed = needed_slots * (sizeof (struct JavaVMOption));
3791 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
3792 "to allocate options list %d %d\n",
3793 needed_slots, bytes_needed));
3794
3795 JavaVMOption *new_options_head =
3796 (struct JavaVMOption *) os::malloc(bytes_needed, mtInternal);
3797
3798 if (new_options_head == NULL) {
3799 jio_fprintf(defaultStream::error_stream(),
3800 "Could not allocate options list with %d entries"
3801 " and %d bytes\n",
3802 needed_slots, bytes_needed);
3803
3804 os::free(new_args_head);
3805 new_args_head = NULL;
3806
3807 return JNI_ENOMEM;
3808 }
3809
3810 memset(new_options_head, 0, bytes_needed);
3811
3812 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
3813 "allocation need for options list %d %d\n",
3814 needed_slots, bytes_needed));
3815
3816 // Assemble the args object
3817 new_args_head->options = new_options_head;
3818 new_args_head->nOptions = 0;
3819 new_args_head->version = version;
3820
3821 // Return newly allocated but not populated options list
3822 *ret_args_head = new_args_head;
3823
3824 return JNI_OK;
3825 }
3826
3827 // Copy num_slots NULL separated JVM options from buffer to
3828 // new_options[0] through new_options[num_slots - 1].
3829 // The byte_cnt includes null termination.
3830 jint Arguments::copy_JVM_options_from_buf(const char *buffer,
3831 const size_t byte_cnt,
3832 const int num_slots,
3833 int *cur_slot_p,
3834 struct JavaVMOption *new_options) {
3835
3836 assert(buffer != NULL, "buffer must not be NULL");
3837 assert(byte_cnt > 1, "byte_cnt must be greater than one");
3838 assert(num_slots > 0, "num_slots must be greater than zero");
3839 assert(cur_slot_p != NULL, "cur_slot_p must not be NULL");
3840 assert(new_options != NULL, "new_options must not be NULL");
3841
3842 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
3843 "Copying %d options from buffer\n",
3844 num_slots));
3845 (*cur_slot_p) = 0;
3846 const char *head = buffer;
3847 const char *tail = buffer + byte_cnt - 1;
3848
3849 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
3850 "Copying option %d %d %d\n",
3851 byte_cnt, *cur_slot_p, num_slots));
3852
3853 while ((head < tail) && (*cur_slot_p < num_slots)) {
3854 // Skip null character separator(s)
3855 while ((head < tail) && (*head == '\0')) {
3856 head++;
3857 }
3858
3859 if (head >= tail) {
3860 break;
3861 }
3862
3863 // save a copy of the string in the options list
3864 new_options[(*cur_slot_p)].optionString =
3865 os::strdup_check_oom(head, mtInternal);
3866
3867 if (new_options[(*cur_slot_p)].optionString == NULL) {
3868 jio_fprintf(defaultStream::error_stream(),
3869 "Could not copy file option string '%s'\n", head);
3870 return JNI_ENOMEM;
3871 }
3872
3873 DumpOption(new_options, *cur_slot_p, "copy");
3874 const char *dummy;
3875 if (match_option(&new_options[(*cur_slot_p)],
3876 "-XX:VMOptionsFile=", &dummy)) {
3877 jio_fprintf(defaultStream::error_stream(),
3878 "VM options file is only supported on the command line\n");
3879
3880 (*cur_slot_p)++; // We do not need this slot, but count it on the
3881 // list so the error handling can clean this up
3882 return JNI_EINVAL;
3883 }
3884
3885 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
3886 "Copying option %d %d %s\n",
3887 *cur_slot_p,
3888 num_slots,
3889 new_options[(*cur_slot_p)].optionString));
3890 (*cur_slot_p)++; // Done with current slot
3891
3892 while ((head < tail) && (*head != '\0')) {
3893 head++;
3894 }
3895 }
3896
3897 return JNI_OK;
3898 }
3899
3900 // Parse the JVM options from file_name into ret_buff. The
3901 // options in ret_buff are NULL separated in order to preserve
3902 // any embedded white space that was quoted in file_name.
3903 jint Arguments::parse_JVM_options_file(const char *file_name,
3904 char **ret_buff,
3905 size_t *ret_bytes,
3906 int *ret_opt_cnt) {
3907
3908 assert(file_name != NULL, "file_name must not be NULL.");
3909 assert(ret_buff != NULL, "ret_buff must not be NULL.");
3910 assert(ret_bytes != NULL, "ret_bytes must not be NULL.");
3911 assert(ret_opt_cnt != NULL, "ret_opt_cnt must not be NULL.");
3912
3913 // Default all return params to not return data
3914 *ret_buff = NULL;
3915 *ret_bytes = 0;
3916 *ret_opt_cnt = 0;
3917
3918 int fd = ::open(file_name, O_RDONLY);
3919 if (fd < 0) {
3920 jio_fprintf(defaultStream::error_stream(),
3921 "Could not open options file '%s'\n",
3922 file_name);
3923 return JNI_ERR;
3924 }
3925
3926 // '+ 1' for NULL termination even with max bytes
3927 int bytes_alloc = OPTION_BUFFER_SIZE + 1;
3928
3929 char *buf = (char *)os::malloc(bytes_alloc, mtInternal);
3930
3931 if (buf == NULL) {
3932 jio_fprintf(defaultStream::error_stream(),
3933 "Could not allocate read buffer for options file parse\n");
3934 os::close(fd);
3935 return JNI_ENOMEM;
3936 }
3937
3938 memset(buf, 0, (unsigned)bytes_alloc);
3939
3940 // Fill buffer
3941 // Use ::read() instead of os::read because os::read()
3942 // might do a thead state transition
3943 // and it is too early for that here
3944
3945 int bytes_read = ::read(fd, (void *)buf,
3946 (unsigned)bytes_alloc);
3947 if (bytes_read < 0) {
3948 os::free(buf);
3949 buf = NULL;
3950 os::close(fd);
3951 jio_fprintf(defaultStream::error_stream(),
3952 "Could not read options file '%s'\n", file_name);
3953 return JNI_ERR;
3954 }
3955
3956 if (bytes_read == 0) {
3957 // tell caller there is no option data and that is ok
3958 os::free(buf);
3959 buf = NULL;
3960 os::close(fd);
3961 return JNI_OK;
3962 }
3963
3964 // file is larger than OPTION_BUFFER_SIZE
3965 if (bytes_read > bytes_alloc - 1) {
3966 os::free(buf);
3967 buf = NULL;
3968 os::close(fd);
3969 jio_fprintf(defaultStream::error_stream(),
3970 "Options file '%s' is larger than %d bytes.\n",
3971 file_name, bytes_alloc - 1);
3972 return JNI_EINVAL;
3973 }
3974
3975 os::close(fd);
3976
3977 // some pointers to help with parsing
3978 char *buf_end = buf + bytes_read;
3979 char *cur_token_head = buf;
3980 char *wrt = buf;
3981 char *rd = buf;
3982
3983 // count tokens
3984 int token_cnt = 0;
3985
3986 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
3987 "Parse buf loop > '%s'\n",
3988 buf));
3989 // parse all options
3990 while (rd < buf_end) {
3991 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
3992 "Parse buf loop white > >%s<\n", rd));
3993 // skip leading white space from the input string
3994 while (rd < buf_end && iswhite(*rd)) {
3995 rd++;
3996 }
3997
3998 if (rd >= buf_end) {
3999 break;
4000 }
4001
4002 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4003 "Parse next token > %s\n", rd));
4004 // Remember this is where we found the head of the token.
4005 cur_token_head = wrt;
4006
4007 // Tokens are strings of non white space characters separated
4008 // by one or more white spaces.
4009 while (rd < buf_end && !iswhite(*rd)) {
4010 if (*rd == '\'' || *rd == '"') { // handle a quoted string
4011 int quote = *rd; // matching quote to look for
4012 rd++; // don't copy open quote
4013 while (rd < buf_end && *rd != quote) {
4014 // include everything (even spaces)
4015 // up until the close quote
4016 *wrt++ = *rd++; // copy to option string
4017 }
4018
4019 if (rd < buf_end) {
4020 rd++; // don't copy close quote
4021 } else {
4022 // did not see closing quote
4023 jio_fprintf(defaultStream::error_stream(),
4024 "Unmatched quote in '%s'\n", file_name);
4025 os::free(buf);
4026 buf = NULL;
4027 return JNI_EINVAL;
4028 }
4029 } else {
4030 *wrt++ = *rd++; // copy to option string
4031 }
4032 }
4033
4034 // steal a white space character and set it to NULL
4035 *wrt++ = '\0';
4036 token_cnt++;
4037 // We now have a complete token
4038 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4039 "Current parsed token > %s\n",
4040 cur_token_head));
4041
4042 rd++; // Advance to next character
4043 }
4044
4045 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4046 "Done parsing tokens > %d\n",
4047 token_cnt));
4048
4049 if (token_cnt > N_MAX_OPTIONS) {
4050 jio_fprintf(defaultStream::error_stream(),
4051 "Options file has more than %d options.\n",
4052 N_MAX_OPTIONS);
4053 os::free(buf);
4054 buf = NULL;
4055 return JNI_EINVAL;
4056 }
4057
4058 // Pass the data the back to the caller
4059 *ret_buff = buf;
4060 *ret_opt_cnt = token_cnt;
4061 *ret_bytes = (size_t)(wrt - buf);
4062
4063 return JNI_OK;
4064 }
4065
4066 // Merge options from a JVM options file with the options provided
4067 // by argsin and return the merge results via *argsout. If the
4068 // '-XX:VMOptionsFile=...' option is not specified on the command
4069 // line, then there is nothing to merge and *argsout is set to NULL.
4070 jint Arguments::merge_JVM_options_file(const JavaVMInitArgs *argsin,
4071 JavaVMInitArgs **argsout) {
4072
4073 assert(argsin != NULL, "argsin should not be NULL");
4074 assert(argsout != NULL, "argsout should not be NULL");
4075
4076 JavaVMInitArgs *new_args_head = NULL;
4077 char *options_file = NULL;
4078 bool options_file_found = false;
4079
4080 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4081 "Found %d existing option(s)\n",
4082 argsin->nOptions));
4083
4084 // Take a peak at options passed in, looking for an options file
4085 int old_index = 0;
4086 const char *tail = NULL;
4087 while (old_index < argsin->nOptions) {
4088 JavaVMOption *option = argsin->options + old_index;
4089
4090 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4091 "Found existing option %s\n",
4092 option->optionString));
4093
4094 if (match_option(option, "-XX:VMOptionsFile=", &tail)) {
4095 // Only one options file allowed on the command line.
4096 if (options_file_found) {
4097 jio_fprintf(defaultStream::error_stream(),
4098 "Only one VM Options file is supported "
4099 "on the command line\n");
4100
4101 *argsout = NULL;
4102 os::free(options_file);
4103 options_file = NULL;
4104 return JNI_EINVAL;
4105 } else {
4106 options_file_found = true;
4107 }
4108 options_file = os::strdup_check_oom(tail, mtInternal);
4109 if (options_file == NULL) {
4110 jio_fprintf(defaultStream::error_stream(),
4111 "Could not copy options file path\n");
4112
4113 return JNI_ENOMEM;
4114 }
4115 }
4116 old_index++;
4117 }
4118
4119 // No option file specified so nothing more to do
4120 if (options_file == NULL) {
4121 *argsout = NULL;
4122 return JNI_OK;
4123 }
4124
4125 DumpVMOptions(argsin, "Premerge");
4126
4127 char *buff; // Contents of the options file
4128 size_t byte_cnt = 0; // bytes in buffer
4129 int file_slots = 0; // # options found in file
4130
4131 // We have requested an options file, so we need to read it
4132 // and do a simple white space parse on it.
4133 jint result = parse_JVM_options_file(options_file,
4134 &buff,
4135 &byte_cnt,
4136 &file_slots);
4137 if (result != JNI_OK) {
4138 // the option file processing failed
4139 jio_fprintf(defaultStream::error_stream(),
4140 "Options file '%s', parsing error\n",
4141 options_file);
4142
4143 os::free(options_file);
4144 options_file = NULL;
4145 *argsout = NULL;
4146 return result;
4147 }
4148
4149 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4150 "Found %d bytes and %d options\n",
4151 byte_cnt, file_slots));
4152 // no options but that is ok
4153 if (file_slots == 0) {
4154 os::free(options_file);
4155 options_file = NULL;
4156 *argsout = NULL;
4157 return JNI_OK;
4158 }
4159
4160 // Combine cmd line slot count and the options file slots passed to us
4161 // We need one less because the "-XX:VMOptionsFile" is not included
4162 // in the new list.
4163 int num_slots = argsin->nOptions + file_slots - 1;
4164
4165 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4166 "Allocate option list with %d slots, %d file,"
4167 " %d exist\n",
4168 num_slots, file_slots, argsin->nOptions));
4169
4170 // Allocate a new option list
4171 result = Arguments::alloc_JVM_options_list(num_slots, argsin->version,
4172 &new_args_head);
4173 if (result != JNI_OK) {
4174 // the option file processing failed
4175 jio_fprintf(defaultStream::error_stream(),
4176 "Memory error in options processing\n");
4177 os::free(buff);
4178 buff = NULL;
4179 os::free(options_file);
4180 options_file = NULL;
4181 *argsout = NULL;
4182 return result;
4183 }
4184
4185 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4186 "merge option list > %d %d\n",
4187 argsin->nOptions, num_slots));
4188
4189 old_index = 0;
4190 while ((old_index < argsin->nOptions) &&
4191 (new_args_head->nOptions < num_slots)) {
4192
4193 JavaVMOption *old_option_p = argsin->options + old_index;
4194 JavaVMOption *new_option_p = new_args_head->options +
4195 new_args_head->nOptions;
4196
4197 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4198 "Merge option %s old %d new %d\n",
4199 old_option_p->optionString,
4200 old_index, new_args_head->nOptions));
4201
4202 // Allow the VM option tracing to come on early.
4203 if (match_option(old_option_p, "-XX:+PrintVMOptions")) {
4204 PrintVMOptions = true;
4205 }
4206
4207 if (match_option(old_option_p, "-XX:VMOptionsFile=", &tail)) {
4208 int file_slots_used = 0;
4209 result = Arguments::copy_JVM_options_from_buf(buff,
4210 byte_cnt,
4211 file_slots,
4212 &file_slots_used,
4213 new_option_p);
4214 // Update option count for success and failure.
4215 // The initialized count is required to free the new args object
4216 new_args_head->nOptions += file_slots_used;
4217
4218 if (result != JNI_OK) {
4219 // the option file processing failed
4220 jio_fprintf(defaultStream::error_stream(),
4221 "Options copy error '%s'\n",
4222 options_file);
4223
4224 os::free(buff);
4225 buff = NULL;
4226 os::free(options_file);
4227 options_file = NULL;
4228 FreeVMOptions(&new_args_head, argsin);
4229 *argsout = NULL;
4230 return result;
4231 }
4232
4233 old_index++; // Next slot in the input list
4234
4235 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4236 "old %d new %d file %d\n",
4237 old_index,
4238 new_args_head->nOptions,
4239 file_slots));
4240 } else {
4241 // We only increment the index if the option preexisted.
4242 // The options file copying increments the index too
4243 new_option_p->optionString =
4244 os::strdup_check_oom(old_option_p->optionString, mtInternal);
4245
4246 if (new_option_p->optionString == NULL) {
4247 jio_fprintf(defaultStream::error_stream(),
4248 "Could not allocate command option string '%s'\n",
4249 old_option_p->optionString);
4250
4251 FreeVMOptions(&new_args_head, argsin);
4252 *argsout = NULL;
4253 os::free(buff);
4254 buff = NULL;
4255 os::free(options_file);
4256 options_file = NULL;
4257 return JNI_ENOMEM;
4258 }
4259
4260 new_option_p->extraInfo = NULL;
4261
4262 DumpOption(old_option_p, old_index, "old");
4263 DumpOption(new_option_p, new_args_head->nOptions, "new");
4264
4265 DumpVMOption(new_args_head, new_args_head->nOptions, "new");
4266 DumpVMOption(argsin, old_index, "old");
4267 old_index++; // Next slot in the input list
4268 new_args_head->nOptions++; // Next slot in the new args list
4269 }
4270
4271 }
4272
4273 os::free(buff);
4274 buff = NULL;
4275 os::free(options_file);
4276 options_file = NULL;
4277
4278 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4279 "trace final num ops %d\n",
4280 new_args_head->nOptions));
4281
4282 // We have a list of options that is ready to be returned to the caller.
4283 *argsout = new_args_head;
4284 DumpVMOptions(*argsout, "Postmerge");
4285 return JNI_OK;
4286 }
4287
4288 // Parse entry point called from JNI_CreateJavaVM
4289
4290 jint Arguments::parse(const struct JavaVMInitArgs *argsin) {
4291 const char* hotspotrc = ".hotspotrc";
4292 bool settings_file_specified = false;
4293 bool needs_hotspotrc_warning = false;
4294
4295 // If flag "-XX:Flags=flags-file" is used it will be the
4296 // first option to be processed.
4297 const char* flags_file;
4298 int index;
4299 struct JavaVMInitArgs *args = NULL;
4300
4301 jint result = Arguments::merge_JVM_options_file(argsin, &args);
4302 if (result != JNI_OK) {
4303 // A more specific error message has been printed to the error stream
4304 jio_fprintf(defaultStream::error_stream(),
4305 "Options merge error, VM will exit\n");
4306 vm_exit(1);
4307 }
4308
4309 if (args == NULL) {
4310 args = (JavaVMInitArgs *)argsin;
4311 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4312 "no file options merged\n"));
4313 } else {
4314 JVM_ARGS_ETRACE(jio_fprintf(defaultStream::error_stream(),
4315 "file options merged\n"));
4316 }
4317
4318 DumpVMOptions(args, "Final Command Line");
4319 const char* tail = NULL;
4320 for (index = 0; index < args->nOptions; index++) {
4321 const JavaVMOption *option = args->options + index;
4322 if (match_option(option, "-XX:VMOptionsFile=", &tail)) {
4323 // -XX:VMOptionsFile= can only appear here if the option file
4324 // is empty or if there are no options to process, ignore it.
4325 continue;
4326 }
4327 if (ArgumentsExt::process_options(option)) {
4328 continue;
4329 }
4330 if (match_option(option, "-XX:Flags=", &tail)) {
4331 flags_file = tail;
4332 settings_file_specified = true;
4333 continue;
4334 }
4335 if (match_option(option, "-XX:+PrintVMOptions")) {
4336 PrintVMOptions = true;
4337 continue;
4338 }
4339 if (match_option(option, "-XX:-PrintVMOptions")) {
4340 PrintVMOptions = false;
4341 continue;
4342 }
4343 if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions")) {
4344 IgnoreUnrecognizedVMOptions = true;
4345 continue;
4346 }
4375 return JNI_ERR;
4376 #endif
4377 }
4378
4379 #ifndef PRODUCT
4380 if (match_option(option, "-XX:+PrintFlagsWithComments")) {
4381 CommandLineFlags::printFlags(tty, true);
4382 vm_exit(0);
4383 }
4384 #endif
4385 }
4386
4387 if (IgnoreUnrecognizedVMOptions) {
4388 // uncast const to modify the flag args->ignoreUnrecognized
4389 *(jboolean*)(&args->ignoreUnrecognized) = true;
4390 }
4391
4392 // Parse specified settings file
4393 if (settings_file_specified) {
4394 if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) {
4395 FreeVMOptions(&args, argsin);
4396 return JNI_EINVAL;
4397 }
4398 } else {
4399 #ifdef ASSERT
4400 // Parse default .hotspotrc settings file
4401 if (!process_settings_file(".hotspotrc", false, args->ignoreUnrecognized)) {
4402 FreeVMOptions(&args, argsin);
4403 return JNI_EINVAL;
4404 }
4405 #else
4406 struct stat buf;
4407 if (os::stat(hotspotrc, &buf) == 0) {
4408 needs_hotspotrc_warning = true;
4409 }
4410 #endif
4411 }
4412
4413 if (PrintVMOptions) {
4414 for (index = 0; index < args->nOptions; index++) {
4415 const JavaVMOption *option = args->options + index;
4416 if (match_option(option, "-XX:", &tail)) {
4417 logOption(tail);
4418 }
4419 }
4420 }
4421
4422 // Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS
4423 result = parse_vm_init_args(args);
4424 if (result != JNI_OK) {
4425 FreeVMOptions(&args, argsin);
4426 return result;
4427 }
4428
4429 FreeVMOptions(&args, argsin);
4430
4431 // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
4432 SharedArchivePath = get_shared_archive_path();
4433 if (SharedArchivePath == NULL) {
4434 return JNI_ENOMEM;
4435 }
4436
4437 // Set up VerifySharedSpaces
4438 if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
4439 VerifySharedSpaces = true;
4440 }
4441
4442 // Delay warning until here so that we've had a chance to process
4443 // the -XX:-PrintWarnings flag
4444 if (needs_hotspotrc_warning) {
4445 warning("%s file is present but has been ignored. "
4446 "Run with -XX:Flags=%s to load the file.",
4447 hotspotrc, hotspotrc);
4448 }
4449
4450 #if defined(_ALLBSD_SOURCE) || defined(AIX) // UseLargePages is not yet supported on BSD and AIX.
|