94 bool Arguments::_ClipInlining = ClipInlining;
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::_jdk_boot_class_path_append = NULL;
113
114 GrowableArray<ModuleXPatchPath*> *Arguments::_xpatchprefix = NULL;
115 PathString *Arguments::_system_boot_class_path = NULL;
116
117 char* Arguments::_ext_dirs = NULL;
118
119 // Check if head of 'option' matches 'name', and sets 'tail' to the remaining
120 // part of the option string.
121 static bool match_option(const JavaVMOption *option, const char* name,
122 const char** tail) {
123 size_t len = strlen(name);
124 if (strncmp(option->optionString, name, len) == 0) {
125 *tail = option->optionString + len;
126 return true;
127 } else {
128 return false;
129 }
130 }
131
132 // Check if 'option' matches 'name'. No "tail" is allowed.
133 static bool match_option(const JavaVMOption *option, const char* name) {
134 const char* tail = NULL;
144 // If tail_allowed is true, then the tail must begin with a colon; otherwise,
145 // the option must match exactly.
146 static bool match_option(const JavaVMOption* option, const char** names, const char** tail,
147 bool tail_allowed) {
148 for (/* empty */; *names != NULL; ++names) {
149 if (match_option(option, *names, tail)) {
150 if (**tail == '\0' || tail_allowed && **tail == ':') {
151 return true;
152 }
153 }
154 }
155 return false;
156 }
157
158 static void logOption(const char* opt) {
159 if (PrintVMOptions) {
160 jio_fprintf(defaultStream::output_stream(), "VM option '%s'\n", opt);
161 }
162 }
163
164 // Process java launcher properties.
165 void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) {
166 // See if sun.java.launcher, sun.java.launcher.is_altjvm or
167 // sun.java.launcher.pid is defined.
168 // Must do this before setting up other system properties,
169 // as some of them may depend on launcher type.
170 for (int index = 0; index < args->nOptions; index++) {
171 const JavaVMOption* option = args->options + index;
172 const char* tail;
173
174 if (match_option(option, "-Dsun.java.launcher=", &tail)) {
175 process_java_launcher_argument(tail, option->extraInfo);
176 continue;
177 }
178 if (match_option(option, "-Dsun.java.launcher.is_altjvm=", &tail)) {
179 if (strcmp(tail, "true") == 0) {
180 _sun_java_launcher_is_altjvm = true;
181 }
182 continue;
183 }
1181 }
1182 }
1183 c = getc(stream);
1184 }
1185 if (pos > 0) {
1186 token[pos] = '\0';
1187 result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
1188 build_jvm_flags(token);
1189 }
1190 fclose(stream);
1191 return result;
1192 }
1193
1194 //=============================================================================================================
1195 // Parsing of properties (-D)
1196
1197 const char* Arguments::get_property(const char* key) {
1198 return PropertyList_get_value(system_properties(), key);
1199 }
1200
1201 bool Arguments::add_property(const char* prop) {
1202 const char* eq = strchr(prop, '=');
1203 const char* key;
1204 const char* value = "";
1205
1206 if (eq == NULL) {
1207 // property doesn't have a value, thus use passed string
1208 key = prop;
1209 } else {
1210 // property have a value, thus extract it and save to the
1211 // allocated string
1212 size_t key_len = eq - prop;
1213 char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
1214
1215 strncpy(tmp_key, prop, key_len);
1216 tmp_key[key_len] = '\0';
1217 key = tmp_key;
1218
1219 value = &prop[key_len + 1];
1220 }
1221
1222 if (strcmp(key, "java.compiler") == 0) {
1223 process_java_compiler_argument(value);
1224 // Record value in Arguments, but let it get passed to Java.
1225 } else if (strcmp(key, "sun.java.launcher.is_altjvm") == 0 ||
1226 strcmp(key, "sun.java.launcher.pid") == 0) {
1227 // sun.java.launcher.is_altjvm and sun.java.launcher.pid property are
1228 // private and are processed in process_sun_java_launcher_properties();
1229 // the sun.java.launcher property is passed on to the java application
1230 } else if (strcmp(key, "sun.boot.library.path") == 0) {
1231 PropertyList_unique_add(&_system_properties, key, value, true);
1232 } else {
1233 if (strcmp(key, "sun.java.command") == 0) {
1234 char *old_java_command = _java_command;
1235 _java_command = os::strdup_check_oom(value, mtArguments);
1236 if (old_java_command != NULL) {
1237 os::free(old_java_command);
1238 }
1239 } else if (strcmp(key, "java.vendor.url.bug") == 0) {
1240 const char* old_java_vendor_url_bug = _java_vendor_url_bug;
1241 // save it in _java_vendor_url_bug, so JVM fatal error handler can access
1242 // its value without going through the property list or making a Java call.
1243 _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
1244 if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
1245 assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
1246 os::free((void *)old_java_vendor_url_bug);
1247 }
1248 }
1249
1250 // Create new property and add at the end of the list
1251 PropertyList_unique_add(&_system_properties, key, value);
1252 }
1253
1254 if (key != prop) {
1255 // SystemProperty copy passed value, thus free previously allocated
1256 // memory
1257 FreeHeap((void *)key);
1258 }
1259
1260 return true;
1261 }
1262
1263 // sets or adds a module name to the jdk.launcher.addmods property
1264 bool Arguments::append_to_addmods_property(const char* module_name) {
1265 const char* key = "jdk.launcher.addmods";
1266 const char* old_value = Arguments::get_property(key);
1267 size_t buf_len = strlen(key) + strlen(module_name) + 2;
1268 if (old_value != NULL) {
1269 buf_len += strlen(old_value) + 1;
1270 }
1271 char* new_value = AllocateHeap(buf_len, mtArguments);
1272 if (new_value == NULL) {
1273 return false;
1274 }
1275 if (old_value == NULL) {
1276 jio_snprintf(new_value, buf_len, "%s=%s", key, module_name);
1277 } else {
1278 jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
1279 }
1280 bool added = add_property(new_value);
1281 FreeHeap(new_value);
1282 return added;
1283 }
1284
1285 #if INCLUDE_CDS
1286 void Arguments::check_unsupported_dumping_properties() {
1287 assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
1288 const char* unsupported_properties[5] = { "jdk.module.main",
1289 "jdk.module.path",
1290 "jdk.upgrade.module.path",
1291 "jdk.launcher.addmods",
1292 "jdk.launcher.limitmods" };
1293 const char* unsupported_options[5] = { "-m",
1294 "-modulepath",
1295 "-upgrademodulepath",
1296 "-addmods",
1297 "-limitmods" };
1298 SystemProperty* sp = system_properties();
1299 while (sp != NULL) {
1300 for (int i = 0; i < 5; i++) {
1301 if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
1302 vm_exit_during_initialization(
1303 "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
1304 }
1305 }
1306 sp = sp->next();
1307 }
1308 }
1309 #endif
1310
1311 //===========================================================================================================
1312 // Setting int/mixed/comp mode flags
1313
1314 void Arguments::set_mode_flags(Mode mode) {
1315 // Set up default values for all flags.
1316 // If you add a flag to any of the branches below,
1317 // add a default value for it here.
1318 set_java_compiler(false);
1319 _mode = mode;
1320
1321 // Ensure Agent_OnLoad has the correct initial values.
1322 // This may not be the final mode; mode may change later in onload phase.
1323 PropertyList_unique_add(&_system_properties, "java.vm.info",
1324 VM_Version::vm_info_string(), false);
1325
1326 UseInterpreter = true;
1327 UseCompiler = true;
1328 UseLoopCounter = true;
1329
1330 // Default values may be platform/compiler dependent -
1331 // use the saved values
1332 ClipInlining = Arguments::_ClipInlining;
1333 AlwaysCompileLoopMethods = Arguments::_AlwaysCompileLoopMethods;
1334 UseOnStackReplacement = Arguments::_UseOnStackReplacement;
1335 BackgroundCompilation = Arguments::_BackgroundCompilation;
1336 if (TieredCompilation) {
1337 if (FLAG_IS_DEFAULT(Tier3InvokeNotifyFreqLog)) {
1338 Tier3InvokeNotifyFreqLog = Arguments::_Tier3InvokeNotifyFreqLog;
1339 }
1340 if (FLAG_IS_DEFAULT(Tier4InvocationThreshold)) {
1341 Tier4InvocationThreshold = Arguments::_Tier4InvocationThreshold;
1342 }
1343 }
1344
2502
2503 // Check the sign first since atojulong() parses only unsigned values.
2504 bool value_is_positive = !(*value == '-');
2505
2506 if (value_is_positive) {
2507 julong n;
2508 bool good_return = atojulong(value, &n);
2509 if (good_return) {
2510 bool above_minimum = n >= min_size;
2511 bool value_is_too_large = n > max_uintx;
2512
2513 if (above_minimum && !value_is_too_large) {
2514 *uintx_arg = n;
2515 return true;
2516 }
2517 }
2518 }
2519 return false;
2520 }
2521
2522 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
2523 julong* long_arg,
2524 julong min_size) {
2525 if (!atojulong(s, long_arg)) return arg_unreadable;
2526 return check_memory_size(*long_arg, min_size);
2527 }
2528
2529 // Parse JavaVMInitArgs structure
2530
2531 jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
2532 const JavaVMInitArgs *java_options_args,
2533 const JavaVMInitArgs *cmd_line_args) {
2534 bool xpatch_javabase = false;
2535
2536 // Save default settings for some mode flags
2537 Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
2538 Arguments::_UseOnStackReplacement = UseOnStackReplacement;
2539 Arguments::_ClipInlining = ClipInlining;
2540 Arguments::_BackgroundCompilation = BackgroundCompilation;
2541 if (TieredCompilation) {
2542 Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
2543 Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
2544 }
2545
2546 // Setup flags for mixed which is the default
2547 set_mode_flags(_mixed);
2548
2549 // Parse args structure generated from JAVA_TOOL_OPTIONS environment
2550 // variable (if present).
2551 jint result = parse_each_vm_init_arg(java_tool_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
2552 if (result != JNI_OK) {
2553 return result;
2554 }
2555
2556 // Parse args structure generated from the command line flags.
2557 result = parse_each_vm_init_arg(cmd_line_args, &xpatch_javabase, Flag::COMMAND_LINE);
2558 if (result != JNI_OK) {
2559 return result;
2560 }
2561
2562 // Parse args structure generated from the _JAVA_OPTIONS environment
2563 // variable (if present) (mimics classic VM)
2564 result = parse_each_vm_init_arg(java_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
2565 if (result != JNI_OK) {
2566 return result;
2567 }
2568
2569 // Do final processing now that all arguments have been parsed
2570 result = finalize_vm_init_args();
2571 if (result != JNI_OK) {
2572 return result;
2573 }
2574
2575 return JNI_OK;
2576 }
2577
2578 // Checks if name in command-line argument -agent{lib,path}:name[=options]
2579 // represents a valid JDWP agent. is_path==true denotes that we
2580 // are dealing with -agentpath (case where name is a path), otherwise with
2581 // -agentlib
2582 bool valid_jdwp_agent(char *name, bool is_path) {
2583 char *_name;
2584 const char *_jdwp = "jdwp";
2603 _name += _len_jdwp;
2604 }
2605 else {
2606 return false;
2607 }
2608
2609 if (strcmp(_name, JNI_LIB_SUFFIX) != 0) {
2610 return false;
2611 }
2612
2613 return true;
2614 }
2615
2616 if (strcmp(name, _jdwp) == 0) {
2617 return true;
2618 }
2619
2620 return false;
2621 }
2622
2623 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin) {
2624 // For match_option to return remaining or value part of option string
2625 const char* tail;
2626
2627 // iterate over arguments
2628 for (int index = 0; index < args->nOptions; index++) {
2629 bool is_absolute_path = false; // for -agentpath vs -agentlib
2630
2631 const JavaVMOption* option = args->options + index;
2632
2633 if (!match_option(option, "-Djava.class.path", &tail) &&
2634 !match_option(option, "-Dsun.java.command", &tail) &&
2635 !match_option(option, "-Dsun.java.launcher", &tail)) {
2636
2637 // add all jvm options to the jvm_args string. This string
2638 // is used later to set the java.vm.args PerfData string constant.
2639 // the -Djava.class.path and the -Dsun.java.command options are
2640 // omitted from jvm_args string as each have their own PerfData
2641 // string constant object.
2642 build_jvm_args(option->optionString);
2643 }
2688 if (tail != NULL) {
2689 const char* pos = strchr(tail, ':');
2690 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2691 char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2692 name[len] = '\0';
2693
2694 char *options = NULL;
2695 if(pos != NULL) {
2696 size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied.
2697 options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtArguments), pos+1, len2);
2698 }
2699 #if !INCLUDE_JVMTI
2700 if (strcmp(name, "jdwp") == 0) {
2701 jio_fprintf(defaultStream::error_stream(),
2702 "Debugging agents are not supported in this VM\n");
2703 return JNI_ERR;
2704 }
2705 #endif // !INCLUDE_JVMTI
2706 add_init_library(name, options);
2707 }
2708 // -agentlib and -agentpath
2709 } else if (match_option(option, "-agentlib:", &tail) ||
2710 (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
2711 if(tail != NULL) {
2712 const char* pos = strchr(tail, '=');
2713 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2714 char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2715 name[len] = '\0';
2716
2717 char *options = NULL;
2718 if(pos != NULL) {
2719 options = os::strdup_check_oom(pos + 1, mtArguments);
2720 }
2721 #if !INCLUDE_JVMTI
2722 if (valid_jdwp_agent(name, is_absolute_path)) {
2723 jio_fprintf(defaultStream::error_stream(),
2724 "Debugging agents are not supported in this VM\n");
2725 return JNI_ERR;
2726 }
2727 #endif // !INCLUDE_JVMTI
2979 vm_exit(0);
2980 #endif
2981 // -D
2982 } else if (match_option(option, "-D", &tail)) {
2983 const char* value;
2984 if (match_option(option, "-Djava.endorsed.dirs=", &value) &&
2985 *value!= '\0' && strcmp(value, "\"\"") != 0) {
2986 // abort if -Djava.endorsed.dirs is set
2987 jio_fprintf(defaultStream::output_stream(),
2988 "-Djava.endorsed.dirs=%s is not supported. Endorsed standards and standalone APIs\n"
2989 "in modular form will be supported via the concept of upgradeable modules.\n", value);
2990 return JNI_EINVAL;
2991 }
2992 if (match_option(option, "-Djava.ext.dirs=", &value) &&
2993 *value != '\0' && strcmp(value, "\"\"") != 0) {
2994 // abort if -Djava.ext.dirs is set
2995 jio_fprintf(defaultStream::output_stream(),
2996 "-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value);
2997 return JNI_EINVAL;
2998 }
2999
3000 if (!add_property(tail)) {
3001 return JNI_ENOMEM;
3002 }
3003 // Out of the box management support
3004 if (match_option(option, "-Dcom.sun.management", &tail)) {
3005 #if INCLUDE_MANAGEMENT
3006 if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != Flag::SUCCESS) {
3007 return JNI_EINVAL;
3008 }
3009 // management agent in module java.management
3010 if (!Arguments::append_to_addmods_property("java.management")) {
3011 return JNI_ENOMEM;
3012 }
3013 #else
3014 jio_fprintf(defaultStream::output_stream(),
3015 "-Dcom.sun.management is not supported in this VM.\n");
3016 return JNI_ERR;
3017 #endif
3018 }
3019 if (match_option(option, "-Djdk.launcher.patch.", &tail)) {
3020 // -Djdk.launcher.patch.#=<module>=<file>(<pathsep><file>)*
3021 // The number, #, specified will be increasing with each -Xpatch
3022 // specified on the command line.
3023 // Pick up module name, following the -D property's equal sign.
3024 const char* property_equal = strchr(tail, '=');
3025 if (property_equal == NULL) {
3026 jio_fprintf(defaultStream::output_stream(), "Missing '=' in -Xpatch specification\n");
3027 return JNI_ERR;
3028 } else {
3029 // Find the equal sign between the module name and the path specification
3030 const char* module_equal = strchr(property_equal + 1, '=');
3031 if (module_equal == NULL) {
3032 jio_fprintf(defaultStream::output_stream(), "Bad value for -Xpatch, no module name specified\n");
3033 return JNI_ERR;
3034 } else {
3035 // Pick out the module name, in between the two equal signs
3036 size_t module_len = module_equal - property_equal - 1;
3037 char* module_name = NEW_C_HEAP_ARRAY(char, module_len+1, mtArguments);
3038 memcpy(module_name, property_equal + 1, module_len);
3039 *(module_name + module_len) = '\0';
3040 // The path piece begins one past the module_equal sign
3041 Arguments::add_xpatchprefix(module_name, module_equal + 1, xpatch_javabase);
3042 FREE_C_HEAP_ARRAY(char, module_name);
3043 }
3044 }
3045 }
3046 // -Xint
3047 } else if (match_option(option, "-Xint")) {
3048 set_mode_flags(_int);
3049 // -Xmixed
3050 } else if (match_option(option, "-Xmixed")) {
3051 set_mode_flags(_mixed);
3052 // -Xcomp
3053 } else if (match_option(option, "-Xcomp")) {
3054 // for testing the compiler; turn off all flags that inhibit compilation
3055 set_mode_flags(_comp);
3056 // -Xshare:dump
3057 } else if (match_option(option, "-Xshare:dump")) {
3058 if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != Flag::SUCCESS) {
3059 return JNI_EINVAL;
3060 }
3061 set_mode_flags(_int); // Prevent compilation, which creates objects
3062 // -Xshare:on
3063 } else if (match_option(option, "-Xshare:on")) {
3064 if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
3065 return JNI_EINVAL;
3285 return JNI_EINVAL;
3286 }
3287 if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
3288 return JNI_EINVAL;
3289 }
3290 LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(class, path));
3291 }
3292
3293 // Change the default value for flags which have different default values
3294 // when working with older JDKs.
3295 #ifdef LINUX
3296 if (JDK_Version::current().compare_major(6) <= 0 &&
3297 FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) {
3298 FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
3299 }
3300 #endif // LINUX
3301 fix_appclasspath();
3302 return JNI_OK;
3303 }
3304
3305 void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) {
3306 // For java.base check for duplicate -Xpatch options being specified on the command line.
3307 // This check is only required for java.base, all other duplicate module specifications
3308 // will be checked during module system initialization. The module system initialization
3309 // will throw an ExceptionInInitializerError if this situation occurs.
3310 if (strcmp(module_name, "java.base") == 0) {
3311 if (*xpatch_javabase) {
3312 vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch");
3313 } else {
3314 *xpatch_javabase = true;
3315 }
3316 }
3317
3318 // Create GrowableArray lazily, only if -Xpatch has been specified
3319 if (_xpatchprefix == NULL) {
3320 _xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true);
3321 }
3322
3323 _xpatchprefix->push(new ModuleXPatchPath(module_name, path));
3324 }
3325
3326 // Set property jdk.boot.class.path.append to the contents of the bootclasspath
3327 // that follows either the jimage file or exploded module directories. The
3328 // property will contain -Xbootclasspath/a and/or jvmti appended additions.
3329 void Arguments::set_jdkbootclasspath_append() {
3330 char *sysclasspath = get_sysclasspath();
3331 assert(sysclasspath != NULL, "NULL sysclasspath");
3332 int bcp_a_idx = bootclassloader_append_index();
3333 if (bcp_a_idx != -1 && bcp_a_idx < (int)strlen(sysclasspath)) {
3334 _jdk_boot_class_path_append->set_value(sysclasspath + bcp_a_idx);
3335 }
3336 }
3337
3338 // Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
3339 //
3340 // This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
3341 // in their start-up scripts. If XYZ is empty, the classpath will look like "-cp foo.jar::bar.jar".
3342 // Java treats such empty paths as if the user specified "-cp foo.jar:.:bar.jar". I.e., an empty
3343 // path is treated as the current directory.
3440
3441 DIR* dir = os::opendir(path);
3442 if (dir != NULL) {
3443 jio_fprintf(defaultStream::output_stream(),
3444 "<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs\n"
3445 "in modular form will be supported via the concept of upgradeable modules.\n");
3446 os::closedir(dir);
3447 return JNI_ERR;
3448 }
3449
3450 sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
3451 dir = os::opendir(path);
3452 if (dir != NULL) {
3453 jio_fprintf(defaultStream::output_stream(),
3454 "<JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; "
3455 "Use -classpath instead.\n.");
3456 os::closedir(dir);
3457 return JNI_ERR;
3458 }
3459
3460 Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
3461
3462 // This must be done after all arguments have been processed.
3463 // java_compiler() true means set to "NONE" or empty.
3464 if (java_compiler() && !xdebug_mode()) {
3465 // For backwards compatibility, we switch to interpreted mode if
3466 // -Djava.compiler="NONE" or "" is specified AND "-Xdebug" was
3467 // not specified.
3468 set_mode_flags(_int);
3469 }
3470
3471 // CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode),
3472 // but like -Xint, leave compilation thresholds unaffected.
3473 // With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well.
3474 if ((CompileThresholdScaling == 0.0) || (!TieredCompilation && CompileThreshold == 0)) {
3475 set_mode_flags(_int);
3476 }
3477
3478 // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
3479 if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {
3796 // We now have a complete token
3797
3798 JavaVMOption option;
3799 option.optionString = opt_hd;
3800 option.extraInfo = NULL;
3801
3802 options->append(option); // Fill in option
3803
3804 rd++; // Advance to next character
3805 }
3806
3807 // Fill out JavaVMInitArgs structure.
3808 jint status = vm_args->set_args(options);
3809
3810 delete options;
3811 return status;
3812 }
3813
3814 void Arguments::set_shared_spaces_flags() {
3815 if (DumpSharedSpaces) {
3816 if (Arguments::get_xpatchprefix() != NULL) {
3817 vm_exit_during_initialization(
3818 "Cannot use the following option when dumping the shared archive", "-Xpatch");
3819 }
3820
3821 if (RequireSharedSpaces) {
3822 warning("Cannot dump shared archive while using shared archive");
3823 }
3824 UseSharedSpaces = false;
3825 #ifdef _LP64
3826 if (!UseCompressedOops || !UseCompressedClassPointers) {
3827 vm_exit_during_initialization(
3828 "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
3829 }
3830 } else {
3831 if (!UseCompressedOops || !UseCompressedClassPointers) {
3832 no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
3833 }
3834 #endif
3835 }
3836 }
3837
3838 // Sharing support
4181
4182 // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
4183 SharedArchivePath = get_shared_archive_path();
4184 if (SharedArchivePath == NULL) {
4185 return JNI_ENOMEM;
4186 }
4187
4188 // Set up VerifySharedSpaces
4189 if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
4190 VerifySharedSpaces = true;
4191 }
4192
4193 // Delay warning until here so that we've had a chance to process
4194 // the -XX:-PrintWarnings flag
4195 if (needs_hotspotrc_warning) {
4196 warning("%s file is present but has been ignored. "
4197 "Run with -XX:Flags=%s to load the file.",
4198 hotspotrc, hotspotrc);
4199 }
4200
4201 #if defined(_ALLBSD_SOURCE) || defined(AIX) // UseLargePages is not yet supported on BSD and AIX.
4202 UNSUPPORTED_OPTION(UseLargePages);
4203 #endif
4204
4205 ArgumentsExt::report_unsupported_options();
4206
4207 #ifndef PRODUCT
4208 if (TraceBytecodesAt != 0) {
4209 TraceBytecodes = true;
4210 }
4211 if (CountCompiledCalls) {
4212 if (UseCounterDecay) {
4213 warning("UseCounterDecay disabled because CountCalls is set");
4214 UseCounterDecay = false;
4215 }
4216 }
4217 #endif // PRODUCT
4218
4219 if (ScavengeRootsInCode == 0) {
4220 if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) {
4405 // allocation policy for the eden space.
4406 // Non NUMA-aware collectors such as CMS, G1 and Serial-GC on
4407 // all platforms and ParallelGC on Windows will interleave all
4408 // of the heap spaces across NUMA nodes.
4409 if (FLAG_IS_DEFAULT(UseNUMAInterleaving)) {
4410 FLAG_SET_ERGO(bool, UseNUMAInterleaving, true);
4411 }
4412 }
4413 return JNI_OK;
4414 }
4415
4416 int Arguments::PropertyList_count(SystemProperty* pl) {
4417 int count = 0;
4418 while(pl != NULL) {
4419 count++;
4420 pl = pl->next();
4421 }
4422 return count;
4423 }
4424
4425 const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) {
4426 assert(key != NULL, "just checking");
4427 SystemProperty* prop;
4428 for (prop = pl; prop != NULL; prop = prop->next()) {
4429 if (strcmp(key, prop->key()) == 0) return prop->value();
4430 }
4431 return NULL;
4432 }
4433
4434 const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) {
4435 int count = 0;
4436 const char* ret_val = NULL;
4437
4438 while(pl != NULL) {
4439 if(count >= index) {
4440 ret_val = pl->key();
4441 break;
4442 }
4443 count++;
4444 pl = pl->next();
4445 }
4446
4447 return ret_val;
4448 }
4449
4450 char* Arguments::PropertyList_get_value_at(SystemProperty* pl, int index) {
4451 int count = 0;
4452 char* ret_val = NULL;
4453
4458 }
4459 count++;
4460 pl = pl->next();
4461 }
4462
4463 return ret_val;
4464 }
4465
4466 void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p) {
4467 SystemProperty* p = *plist;
4468 if (p == NULL) {
4469 *plist = new_p;
4470 } else {
4471 while (p->next() != NULL) {
4472 p = p->next();
4473 }
4474 p->set_next(new_p);
4475 }
4476 }
4477
4478 void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v) {
4479 if (plist == NULL)
4480 return;
4481
4482 SystemProperty* new_p = new SystemProperty(k, v, true);
4483 PropertyList_add(plist, new_p);
4484 }
4485
4486 void Arguments::PropertyList_add(SystemProperty *element) {
4487 PropertyList_add(&_system_properties, element);
4488 }
4489
4490 // This add maintains unique property key in the list.
4491 void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, jboolean append) {
4492 if (plist == NULL)
4493 return;
4494
4495 // If property key exist then update with new value.
4496 SystemProperty* prop;
4497 for (prop = *plist; prop != NULL; prop = prop->next()) {
4498 if (strcmp(k, prop->key()) == 0) {
4499 if (append) {
4500 prop->append_value(v);
4501 } else {
4502 prop->set_writeable_value(v);
4503 }
4504 return;
4505 }
4506 }
4507
4508 PropertyList_add(plist, k, v);
4509 }
4510
4511 // Copies src into buf, replacing "%%" with "%" and "%p" with pid
4512 // Returns true if all of the source pointed by src has been copied over to
4513 // the destination buffer pointed by buf. Otherwise, returns false.
4514 // Notes:
4515 // 1. If the length (buflen) of the destination buffer excluding the
4516 // NULL terminator character is not long enough for holding the expanded
4517 // pid characters, it also returns false instead of returning the partially
4518 // expanded one.
4519 // 2. The passed in "buflen" should be large enough to hold the null terminator.
4520 bool Arguments::copy_expand_pid(const char* src, size_t srclen,
4521 char* buf, size_t buflen) {
4522 const char* p = src;
4523 char* b = buf;
4524 const char* src_end = &src[srclen];
4525 char* buf_end = &buf[buflen - 1];
4526
4527 while (p < src_end && b < buf_end) {
4528 if (*p == '%') {
|
94 bool Arguments::_ClipInlining = ClipInlining;
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::_jdk_boot_class_path_append = NULL;
113
114 GrowableArray<ModulePatchPath*> *Arguments::_patch_mod_prefix = NULL;
115 PathString *Arguments::_system_boot_class_path = NULL;
116
117 char* Arguments::_ext_dirs = NULL;
118
119 // Check if head of 'option' matches 'name', and sets 'tail' to the remaining
120 // part of the option string.
121 static bool match_option(const JavaVMOption *option, const char* name,
122 const char** tail) {
123 size_t len = strlen(name);
124 if (strncmp(option->optionString, name, len) == 0) {
125 *tail = option->optionString + len;
126 return true;
127 } else {
128 return false;
129 }
130 }
131
132 // Check if 'option' matches 'name'. No "tail" is allowed.
133 static bool match_option(const JavaVMOption *option, const char* name) {
134 const char* tail = NULL;
144 // If tail_allowed is true, then the tail must begin with a colon; otherwise,
145 // the option must match exactly.
146 static bool match_option(const JavaVMOption* option, const char** names, const char** tail,
147 bool tail_allowed) {
148 for (/* empty */; *names != NULL; ++names) {
149 if (match_option(option, *names, tail)) {
150 if (**tail == '\0' || tail_allowed && **tail == ':') {
151 return true;
152 }
153 }
154 }
155 return false;
156 }
157
158 static void logOption(const char* opt) {
159 if (PrintVMOptions) {
160 jio_fprintf(defaultStream::output_stream(), "VM option '%s'\n", opt);
161 }
162 }
163
164 bool needs_module_property_warning = false;
165
166 #define MODULE_PROPERTY_PREFIX "jdk.module"
167 #define MODULE_PROPERTY_PREFIX_LEN 10
168 #define MODULE_MAIN_PROPERTY "jdk.module.main"
169 #define MODULE_MAIN_PROPERTY_LEN 15
170
171 // Return TRUE if option matches property, or property=, or property..
172 static bool matches_property_prefix(const char* option, const char* property, size_t len) {
173 return (strncmp(option, property, len) == 0) &&
174 (option[len] == '=' || option[len] == '.' || option[len] == '\0');
175 }
176
177 // Return true if the property is either "jdk.module" or starts with "jdk.module.",
178 // but does not start with "jdk.module.main".
179 // Return false if jdk.module.main because jdk.module.main and jdk.module.main.class
180 // are valid non-internal system properties.
181 // "property" should be passed without the leading "-D".
182 bool Arguments::is_internal_module_property(const char* property) {
183 assert((strncmp(property, "-D", 2) != 0), "Unexpected leading -D");
184 return (matches_property_prefix(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) &&
185 !matches_property_prefix(property, MODULE_MAIN_PROPERTY, MODULE_MAIN_PROPERTY_LEN));
186 }
187
188 // Process java launcher properties.
189 void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) {
190 // See if sun.java.launcher, sun.java.launcher.is_altjvm or
191 // sun.java.launcher.pid is defined.
192 // Must do this before setting up other system properties,
193 // as some of them may depend on launcher type.
194 for (int index = 0; index < args->nOptions; index++) {
195 const JavaVMOption* option = args->options + index;
196 const char* tail;
197
198 if (match_option(option, "-Dsun.java.launcher=", &tail)) {
199 process_java_launcher_argument(tail, option->extraInfo);
200 continue;
201 }
202 if (match_option(option, "-Dsun.java.launcher.is_altjvm=", &tail)) {
203 if (strcmp(tail, "true") == 0) {
204 _sun_java_launcher_is_altjvm = true;
205 }
206 continue;
207 }
1205 }
1206 }
1207 c = getc(stream);
1208 }
1209 if (pos > 0) {
1210 token[pos] = '\0';
1211 result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
1212 build_jvm_flags(token);
1213 }
1214 fclose(stream);
1215 return result;
1216 }
1217
1218 //=============================================================================================================
1219 // Parsing of properties (-D)
1220
1221 const char* Arguments::get_property(const char* key) {
1222 return PropertyList_get_value(system_properties(), key);
1223 }
1224
1225 bool Arguments::add_property(const char* prop, PropertyWriteable writeable, PropertyInternal internal) {
1226 const char* eq = strchr(prop, '=');
1227 const char* key;
1228 const char* value = "";
1229
1230 if (eq == NULL) {
1231 // property doesn't have a value, thus use passed string
1232 key = prop;
1233 } else {
1234 // property have a value, thus extract it and save to the
1235 // allocated string
1236 size_t key_len = eq - prop;
1237 char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
1238
1239 strncpy(tmp_key, prop, key_len);
1240 tmp_key[key_len] = '\0';
1241 key = tmp_key;
1242
1243 value = &prop[key_len + 1];
1244 }
1245
1246 if (strcmp(key, "java.compiler") == 0) {
1247 process_java_compiler_argument(value);
1248 // Record value in Arguments, but let it get passed to Java.
1249 } else if (strcmp(key, "sun.java.launcher.is_altjvm") == 0 ||
1250 strcmp(key, "sun.java.launcher.pid") == 0) {
1251 // sun.java.launcher.is_altjvm and sun.java.launcher.pid property are
1252 // private and are processed in process_sun_java_launcher_properties();
1253 // the sun.java.launcher property is passed on to the java application
1254 } else if (strcmp(key, "sun.boot.library.path") == 0) {
1255 // append is true, writable is true, internal is false
1256 PropertyList_unique_add(&_system_properties, key, value, AppendProperty,
1257 WriteableProperty, ExternalProperty);
1258 } else {
1259 if (strcmp(key, "sun.java.command") == 0) {
1260 char *old_java_command = _java_command;
1261 _java_command = os::strdup_check_oom(value, mtArguments);
1262 if (old_java_command != NULL) {
1263 os::free(old_java_command);
1264 }
1265 } else if (strcmp(key, "java.vendor.url.bug") == 0) {
1266 const char* old_java_vendor_url_bug = _java_vendor_url_bug;
1267 // save it in _java_vendor_url_bug, so JVM fatal error handler can access
1268 // its value without going through the property list or making a Java call.
1269 _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
1270 if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
1271 assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
1272 os::free((void *)old_java_vendor_url_bug);
1273 }
1274 }
1275
1276 // Create new property and add at the end of the list
1277 PropertyList_unique_add(&_system_properties, key, value, AddProperty, writeable, internal);
1278 }
1279
1280 if (key != prop) {
1281 // SystemProperty copy passed value, thus free previously allocated
1282 // memory
1283 FreeHeap((void *)key);
1284 }
1285
1286 return true;
1287 }
1288
1289 // sets or adds a module name to the jdk.module.addmods property
1290 bool Arguments::append_to_addmods_property(const char* module_name) {
1291 const char* key = "jdk.module.addmods";
1292 const char* old_value = Arguments::get_property(key);
1293 size_t buf_len = strlen(key) + strlen(module_name) + 2;
1294 if (old_value != NULL) {
1295 buf_len += strlen(old_value) + 1;
1296 }
1297 char* new_value = AllocateHeap(buf_len, mtArguments);
1298 if (new_value == NULL) {
1299 return false;
1300 }
1301 if (old_value == NULL) {
1302 jio_snprintf(new_value, buf_len, "%s=%s", key, module_name);
1303 } else {
1304 jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
1305 }
1306 bool added = add_property(new_value, UnwriteableProperty, InternalProperty);
1307 FreeHeap(new_value);
1308 return added;
1309 }
1310
1311 #if INCLUDE_CDS
1312 void Arguments::check_unsupported_dumping_properties() {
1313 assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
1314 const char* unsupported_properties[5] = { "jdk.module.main",
1315 "jdk.module.path",
1316 "jdk.module.upgrade.path",
1317 "jdk.module.addmods",
1318 "jdk.module.limitmods" };
1319 const char* unsupported_options[5] = { "-m",
1320 "--module-path",
1321 "--upgrade-module-path",
1322 "--add-modules",
1323 "--limit-modules" };
1324 SystemProperty* sp = system_properties();
1325 while (sp != NULL) {
1326 for (int i = 0; i < 5; i++) {
1327 if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
1328 vm_exit_during_initialization(
1329 "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
1330 }
1331 }
1332 sp = sp->next();
1333 }
1334 }
1335 #endif
1336
1337 //===========================================================================================================
1338 // Setting int/mixed/comp mode flags
1339
1340 void Arguments::set_mode_flags(Mode mode) {
1341 // Set up default values for all flags.
1342 // If you add a flag to any of the branches below,
1343 // add a default value for it here.
1344 set_java_compiler(false);
1345 _mode = mode;
1346
1347 // Ensure Agent_OnLoad has the correct initial values.
1348 // This may not be the final mode; mode may change later in onload phase.
1349 PropertyList_unique_add(&_system_properties, "java.vm.info",
1350 VM_Version::vm_info_string(), AddProperty, UnwriteableProperty, ExternalProperty);
1351
1352 UseInterpreter = true;
1353 UseCompiler = true;
1354 UseLoopCounter = true;
1355
1356 // Default values may be platform/compiler dependent -
1357 // use the saved values
1358 ClipInlining = Arguments::_ClipInlining;
1359 AlwaysCompileLoopMethods = Arguments::_AlwaysCompileLoopMethods;
1360 UseOnStackReplacement = Arguments::_UseOnStackReplacement;
1361 BackgroundCompilation = Arguments::_BackgroundCompilation;
1362 if (TieredCompilation) {
1363 if (FLAG_IS_DEFAULT(Tier3InvokeNotifyFreqLog)) {
1364 Tier3InvokeNotifyFreqLog = Arguments::_Tier3InvokeNotifyFreqLog;
1365 }
1366 if (FLAG_IS_DEFAULT(Tier4InvocationThreshold)) {
1367 Tier4InvocationThreshold = Arguments::_Tier4InvocationThreshold;
1368 }
1369 }
1370
2528
2529 // Check the sign first since atojulong() parses only unsigned values.
2530 bool value_is_positive = !(*value == '-');
2531
2532 if (value_is_positive) {
2533 julong n;
2534 bool good_return = atojulong(value, &n);
2535 if (good_return) {
2536 bool above_minimum = n >= min_size;
2537 bool value_is_too_large = n > max_uintx;
2538
2539 if (above_minimum && !value_is_too_large) {
2540 *uintx_arg = n;
2541 return true;
2542 }
2543 }
2544 }
2545 return false;
2546 }
2547
2548 unsigned int addreads_count = 0;
2549 unsigned int addexports_count = 0;
2550 unsigned int patch_mod_count = 0;
2551 const char* add_modules_value = NULL;
2552
2553 bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
2554 size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
2555 char* property = AllocateHeap(prop_len, mtArguments);
2556 int ret = jio_snprintf(property, prop_len, "%s=%s", prop_name, prop_value);
2557 if (ret < 0 || ret >= (int)prop_len) {
2558 FreeHeap(property);
2559 return false;
2560 }
2561 bool added = add_property(property, UnwriteableProperty, internal);
2562 FreeHeap(property);
2563 return added;
2564 }
2565
2566 bool Arguments::create_numbered_property(const char* prop_base_name, const char* prop_value, unsigned int count) {
2567 // Make sure count is < 1,000. Otherwise, memory allocation will be too small.
2568 if (count < 1000) {
2569 size_t prop_len = strlen(prop_base_name) + strlen(prop_value) + 5;
2570 char* property = AllocateHeap(prop_len, mtArguments);
2571 int ret = jio_snprintf(property, prop_len, "%s.%d=%s", prop_base_name, count, prop_value);
2572 if (ret < 0 || ret >= (int)prop_len) {
2573 FreeHeap(property);
2574 return false;
2575 }
2576 bool added = add_property(property, UnwriteableProperty, InternalProperty);
2577 FreeHeap(property);
2578 return added;
2579 }
2580 return false;
2581 }
2582
2583 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
2584 julong* long_arg,
2585 julong min_size) {
2586 if (!atojulong(s, long_arg)) return arg_unreadable;
2587 return check_memory_size(*long_arg, min_size);
2588 }
2589
2590 // Parse JavaVMInitArgs structure
2591
2592 jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
2593 const JavaVMInitArgs *java_options_args,
2594 const JavaVMInitArgs *cmd_line_args) {
2595 bool patch_mod_javabase = false;
2596
2597 // Save default settings for some mode flags
2598 Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
2599 Arguments::_UseOnStackReplacement = UseOnStackReplacement;
2600 Arguments::_ClipInlining = ClipInlining;
2601 Arguments::_BackgroundCompilation = BackgroundCompilation;
2602 if (TieredCompilation) {
2603 Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
2604 Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
2605 }
2606
2607 // Setup flags for mixed which is the default
2608 set_mode_flags(_mixed);
2609
2610 // Parse args structure generated from JAVA_TOOL_OPTIONS environment
2611 // variable (if present).
2612 jint result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
2613 if (result != JNI_OK) {
2614 return result;
2615 }
2616
2617 // Parse args structure generated from the command line flags.
2618 result = parse_each_vm_init_arg(cmd_line_args, &patch_mod_javabase, Flag::COMMAND_LINE);
2619 if (result != JNI_OK) {
2620 return result;
2621 }
2622
2623 // Parse args structure generated from the _JAVA_OPTIONS environment
2624 // variable (if present) (mimics classic VM)
2625 result = parse_each_vm_init_arg(java_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
2626 if (result != JNI_OK) {
2627 return result;
2628 }
2629
2630 // Do final processing now that all arguments have been parsed
2631 result = finalize_vm_init_args();
2632 if (result != JNI_OK) {
2633 return result;
2634 }
2635
2636 return JNI_OK;
2637 }
2638
2639 // Checks if name in command-line argument -agent{lib,path}:name[=options]
2640 // represents a valid JDWP agent. is_path==true denotes that we
2641 // are dealing with -agentpath (case where name is a path), otherwise with
2642 // -agentlib
2643 bool valid_jdwp_agent(char *name, bool is_path) {
2644 char *_name;
2645 const char *_jdwp = "jdwp";
2664 _name += _len_jdwp;
2665 }
2666 else {
2667 return false;
2668 }
2669
2670 if (strcmp(_name, JNI_LIB_SUFFIX) != 0) {
2671 return false;
2672 }
2673
2674 return true;
2675 }
2676
2677 if (strcmp(name, _jdwp) == 0) {
2678 return true;
2679 }
2680
2681 return false;
2682 }
2683
2684 int Arguments::process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase) {
2685 // --patch-module=<module>=<file>(<pathsep><file>)*
2686 assert(patch_mod_tail != NULL, "Unexpected NULL patch-module value");
2687 // Find the equal sign between the module name and the path specification
2688 const char* module_equal = strchr(patch_mod_tail, '=');
2689 if (module_equal == NULL) {
2690 jio_fprintf(defaultStream::output_stream(), "Missing '=' in --patch-module specification\n");
2691 return JNI_ERR;
2692 } else {
2693 // Pick out the module name
2694 size_t module_len = module_equal - patch_mod_tail;
2695 char* module_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, module_len+1, mtArguments);
2696 if (module_name != NULL) {
2697 memcpy(module_name, patch_mod_tail, module_len);
2698 *(module_name + module_len) = '\0';
2699 // The path piece begins one past the module_equal sign
2700 add_patch_mod_prefix(module_name, module_equal + 1, patch_mod_javabase);
2701 FREE_C_HEAP_ARRAY(char, module_name);
2702 if (!create_numbered_property("jdk.module.patch", patch_mod_tail, patch_mod_count++)) {
2703 return JNI_ENOMEM;
2704 }
2705 } else {
2706 return JNI_ENOMEM;
2707 }
2708 }
2709 return JNI_OK;
2710 }
2711
2712 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, Flag::Flags origin) {
2713 // For match_option to return remaining or value part of option string
2714 const char* tail;
2715
2716 // iterate over arguments
2717 for (int index = 0; index < args->nOptions; index++) {
2718 bool is_absolute_path = false; // for -agentpath vs -agentlib
2719
2720 const JavaVMOption* option = args->options + index;
2721
2722 if (!match_option(option, "-Djava.class.path", &tail) &&
2723 !match_option(option, "-Dsun.java.command", &tail) &&
2724 !match_option(option, "-Dsun.java.launcher", &tail)) {
2725
2726 // add all jvm options to the jvm_args string. This string
2727 // is used later to set the java.vm.args PerfData string constant.
2728 // the -Djava.class.path and the -Dsun.java.command options are
2729 // omitted from jvm_args string as each have their own PerfData
2730 // string constant object.
2731 build_jvm_args(option->optionString);
2732 }
2777 if (tail != NULL) {
2778 const char* pos = strchr(tail, ':');
2779 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2780 char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2781 name[len] = '\0';
2782
2783 char *options = NULL;
2784 if(pos != NULL) {
2785 size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied.
2786 options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtArguments), pos+1, len2);
2787 }
2788 #if !INCLUDE_JVMTI
2789 if (strcmp(name, "jdwp") == 0) {
2790 jio_fprintf(defaultStream::error_stream(),
2791 "Debugging agents are not supported in this VM\n");
2792 return JNI_ERR;
2793 }
2794 #endif // !INCLUDE_JVMTI
2795 add_init_library(name, options);
2796 }
2797 } else if (match_option(option, "--add-reads=", &tail)) {
2798 if (!create_numbered_property("jdk.module.addreads", tail, addreads_count++)) {
2799 return JNI_ENOMEM;
2800 }
2801 } else if (match_option(option, "--add-exports=", &tail)) {
2802 if (!create_numbered_property("jdk.module.addexports", tail, addexports_count++)) {
2803 return JNI_ENOMEM;
2804 }
2805 } else if (match_option(option, "--add-modules=", &tail)) {
2806 add_modules_value = tail;
2807 } else if (match_option(option, "--limit-modules=", &tail)) {
2808 if (!create_property("jdk.module.limitmods", tail, InternalProperty)) {
2809 return JNI_ENOMEM;
2810 }
2811 } else if (match_option(option, "--module-path=", &tail)) {
2812 if (!create_property("jdk.module.path", tail, ExternalProperty)) {
2813 return JNI_ENOMEM;
2814 }
2815 } else if (match_option(option, "--upgrade-module-path=", &tail)) {
2816 if (!create_property("jdk.module.upgrade.path", tail, ExternalProperty)) {
2817 return JNI_ENOMEM;
2818 }
2819 } else if (match_option(option, "--patch-module=", &tail)) {
2820 // --patch-module=<module>=<file>(<pathsep><file>)*
2821 int res = process_patch_mod_option(tail, patch_mod_javabase);
2822 if (res != JNI_OK) {
2823 return res;
2824 }
2825 // -agentlib and -agentpath
2826 } else if (match_option(option, "-agentlib:", &tail) ||
2827 (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
2828 if(tail != NULL) {
2829 const char* pos = strchr(tail, '=');
2830 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2831 char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2832 name[len] = '\0';
2833
2834 char *options = NULL;
2835 if(pos != NULL) {
2836 options = os::strdup_check_oom(pos + 1, mtArguments);
2837 }
2838 #if !INCLUDE_JVMTI
2839 if (valid_jdwp_agent(name, is_absolute_path)) {
2840 jio_fprintf(defaultStream::error_stream(),
2841 "Debugging agents are not supported in this VM\n");
2842 return JNI_ERR;
2843 }
2844 #endif // !INCLUDE_JVMTI
3096 vm_exit(0);
3097 #endif
3098 // -D
3099 } else if (match_option(option, "-D", &tail)) {
3100 const char* value;
3101 if (match_option(option, "-Djava.endorsed.dirs=", &value) &&
3102 *value!= '\0' && strcmp(value, "\"\"") != 0) {
3103 // abort if -Djava.endorsed.dirs is set
3104 jio_fprintf(defaultStream::output_stream(),
3105 "-Djava.endorsed.dirs=%s is not supported. Endorsed standards and standalone APIs\n"
3106 "in modular form will be supported via the concept of upgradeable modules.\n", value);
3107 return JNI_EINVAL;
3108 }
3109 if (match_option(option, "-Djava.ext.dirs=", &value) &&
3110 *value != '\0' && strcmp(value, "\"\"") != 0) {
3111 // abort if -Djava.ext.dirs is set
3112 jio_fprintf(defaultStream::output_stream(),
3113 "-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value);
3114 return JNI_EINVAL;
3115 }
3116 // Check for module related properties. They must be set using the modules
3117 // options. For example: use "--add-modules=java.sql", not
3118 // "-Djdk.module.addmods=java.sql"
3119 if (is_internal_module_property(option->optionString + 2)) {
3120 needs_module_property_warning = true;
3121 continue;
3122 }
3123
3124 if (!add_property(tail)) {
3125 return JNI_ENOMEM;
3126 }
3127 // Out of the box management support
3128 if (match_option(option, "-Dcom.sun.management", &tail)) {
3129 #if INCLUDE_MANAGEMENT
3130 if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != Flag::SUCCESS) {
3131 return JNI_EINVAL;
3132 }
3133 // management agent in module java.management
3134 if (!Arguments::append_to_addmods_property("java.management")) {
3135 return JNI_ENOMEM;
3136 }
3137 #else
3138 jio_fprintf(defaultStream::output_stream(),
3139 "-Dcom.sun.management is not supported in this VM.\n");
3140 return JNI_ERR;
3141 #endif
3142 }
3143 // -Xint
3144 } else if (match_option(option, "-Xint")) {
3145 set_mode_flags(_int);
3146 // -Xmixed
3147 } else if (match_option(option, "-Xmixed")) {
3148 set_mode_flags(_mixed);
3149 // -Xcomp
3150 } else if (match_option(option, "-Xcomp")) {
3151 // for testing the compiler; turn off all flags that inhibit compilation
3152 set_mode_flags(_comp);
3153 // -Xshare:dump
3154 } else if (match_option(option, "-Xshare:dump")) {
3155 if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != Flag::SUCCESS) {
3156 return JNI_EINVAL;
3157 }
3158 set_mode_flags(_int); // Prevent compilation, which creates objects
3159 // -Xshare:on
3160 } else if (match_option(option, "-Xshare:on")) {
3161 if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
3162 return JNI_EINVAL;
3382 return JNI_EINVAL;
3383 }
3384 if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
3385 return JNI_EINVAL;
3386 }
3387 LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(class, path));
3388 }
3389
3390 // Change the default value for flags which have different default values
3391 // when working with older JDKs.
3392 #ifdef LINUX
3393 if (JDK_Version::current().compare_major(6) <= 0 &&
3394 FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) {
3395 FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
3396 }
3397 #endif // LINUX
3398 fix_appclasspath();
3399 return JNI_OK;
3400 }
3401
3402 void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, bool* patch_mod_javabase) {
3403 // For java.base check for duplicate --patch-module options being specified on the command line.
3404 // This check is only required for java.base, all other duplicate module specifications
3405 // will be checked during module system initialization. The module system initialization
3406 // will throw an ExceptionInInitializerError if this situation occurs.
3407 if (strcmp(module_name, "java.base") == 0) {
3408 if (*patch_mod_javabase) {
3409 vm_exit_during_initialization("Cannot specify java.base more than once to --patch-module");
3410 } else {
3411 *patch_mod_javabase = true;
3412 }
3413 }
3414
3415 // Create GrowableArray lazily, only if --patch-module has been specified
3416 if (_patch_mod_prefix == NULL) {
3417 _patch_mod_prefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModulePatchPath*>(10, true);
3418 }
3419
3420 _patch_mod_prefix->push(new ModulePatchPath(module_name, path));
3421 }
3422
3423 // Set property jdk.boot.class.path.append to the contents of the bootclasspath
3424 // that follows either the jimage file or exploded module directories. The
3425 // property will contain -Xbootclasspath/a and/or jvmti appended additions.
3426 void Arguments::set_jdkbootclasspath_append() {
3427 char *sysclasspath = get_sysclasspath();
3428 assert(sysclasspath != NULL, "NULL sysclasspath");
3429 int bcp_a_idx = bootclassloader_append_index();
3430 if (bcp_a_idx != -1 && bcp_a_idx < (int)strlen(sysclasspath)) {
3431 _jdk_boot_class_path_append->set_value(sysclasspath + bcp_a_idx);
3432 }
3433 }
3434
3435 // Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
3436 //
3437 // This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
3438 // in their start-up scripts. If XYZ is empty, the classpath will look like "-cp foo.jar::bar.jar".
3439 // Java treats such empty paths as if the user specified "-cp foo.jar:.:bar.jar". I.e., an empty
3440 // path is treated as the current directory.
3537
3538 DIR* dir = os::opendir(path);
3539 if (dir != NULL) {
3540 jio_fprintf(defaultStream::output_stream(),
3541 "<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs\n"
3542 "in modular form will be supported via the concept of upgradeable modules.\n");
3543 os::closedir(dir);
3544 return JNI_ERR;
3545 }
3546
3547 sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
3548 dir = os::opendir(path);
3549 if (dir != NULL) {
3550 jio_fprintf(defaultStream::output_stream(),
3551 "<JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; "
3552 "Use -classpath instead.\n.");
3553 os::closedir(dir);
3554 return JNI_ERR;
3555 }
3556
3557 // Append the value of the last --add-modules option specified on the command line.
3558 // This needs to be done here, to prevent overwriting possible values written
3559 // to the jdk.module.addmods property by -javaagent and other options.
3560 if (add_modules_value != NULL) {
3561 if (!append_to_addmods_property(add_modules_value)) {
3562 return JNI_ENOMEM;
3563 }
3564 }
3565
3566 Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
3567
3568 // This must be done after all arguments have been processed.
3569 // java_compiler() true means set to "NONE" or empty.
3570 if (java_compiler() && !xdebug_mode()) {
3571 // For backwards compatibility, we switch to interpreted mode if
3572 // -Djava.compiler="NONE" or "" is specified AND "-Xdebug" was
3573 // not specified.
3574 set_mode_flags(_int);
3575 }
3576
3577 // CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode),
3578 // but like -Xint, leave compilation thresholds unaffected.
3579 // With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well.
3580 if ((CompileThresholdScaling == 0.0) || (!TieredCompilation && CompileThreshold == 0)) {
3581 set_mode_flags(_int);
3582 }
3583
3584 // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
3585 if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {
3902 // We now have a complete token
3903
3904 JavaVMOption option;
3905 option.optionString = opt_hd;
3906 option.extraInfo = NULL;
3907
3908 options->append(option); // Fill in option
3909
3910 rd++; // Advance to next character
3911 }
3912
3913 // Fill out JavaVMInitArgs structure.
3914 jint status = vm_args->set_args(options);
3915
3916 delete options;
3917 return status;
3918 }
3919
3920 void Arguments::set_shared_spaces_flags() {
3921 if (DumpSharedSpaces) {
3922 if (Arguments::get_patch_mod_prefix() != NULL) {
3923 vm_exit_during_initialization(
3924 "Cannot use the following option when dumping the shared archive: --patch-module");
3925 }
3926
3927 if (RequireSharedSpaces) {
3928 warning("Cannot dump shared archive while using shared archive");
3929 }
3930 UseSharedSpaces = false;
3931 #ifdef _LP64
3932 if (!UseCompressedOops || !UseCompressedClassPointers) {
3933 vm_exit_during_initialization(
3934 "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
3935 }
3936 } else {
3937 if (!UseCompressedOops || !UseCompressedClassPointers) {
3938 no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
3939 }
3940 #endif
3941 }
3942 }
3943
3944 // Sharing support
4287
4288 // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
4289 SharedArchivePath = get_shared_archive_path();
4290 if (SharedArchivePath == NULL) {
4291 return JNI_ENOMEM;
4292 }
4293
4294 // Set up VerifySharedSpaces
4295 if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
4296 VerifySharedSpaces = true;
4297 }
4298
4299 // Delay warning until here so that we've had a chance to process
4300 // the -XX:-PrintWarnings flag
4301 if (needs_hotspotrc_warning) {
4302 warning("%s file is present but has been ignored. "
4303 "Run with -XX:Flags=%s to load the file.",
4304 hotspotrc, hotspotrc);
4305 }
4306
4307 if (needs_module_property_warning) {
4308 warning("Ignoring system property options whose names start with '-Djdk.module'."
4309 " They are reserved for internal use.");
4310 }
4311
4312 #if defined(_ALLBSD_SOURCE) || defined(AIX) // UseLargePages is not yet supported on BSD and AIX.
4313 UNSUPPORTED_OPTION(UseLargePages);
4314 #endif
4315
4316 ArgumentsExt::report_unsupported_options();
4317
4318 #ifndef PRODUCT
4319 if (TraceBytecodesAt != 0) {
4320 TraceBytecodes = true;
4321 }
4322 if (CountCompiledCalls) {
4323 if (UseCounterDecay) {
4324 warning("UseCounterDecay disabled because CountCalls is set");
4325 UseCounterDecay = false;
4326 }
4327 }
4328 #endif // PRODUCT
4329
4330 if (ScavengeRootsInCode == 0) {
4331 if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) {
4516 // allocation policy for the eden space.
4517 // Non NUMA-aware collectors such as CMS, G1 and Serial-GC on
4518 // all platforms and ParallelGC on Windows will interleave all
4519 // of the heap spaces across NUMA nodes.
4520 if (FLAG_IS_DEFAULT(UseNUMAInterleaving)) {
4521 FLAG_SET_ERGO(bool, UseNUMAInterleaving, true);
4522 }
4523 }
4524 return JNI_OK;
4525 }
4526
4527 int Arguments::PropertyList_count(SystemProperty* pl) {
4528 int count = 0;
4529 while(pl != NULL) {
4530 count++;
4531 pl = pl->next();
4532 }
4533 return count;
4534 }
4535
4536 // Return the number of readable properties.
4537 int Arguments::PropertyList_readable_count(SystemProperty* pl) {
4538 int count = 0;
4539 while(pl != NULL) {
4540 if (pl->is_readable()) {
4541 count++;
4542 }
4543 pl = pl->next();
4544 }
4545 return count;
4546 }
4547
4548 const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) {
4549 assert(key != NULL, "just checking");
4550 SystemProperty* prop;
4551 for (prop = pl; prop != NULL; prop = prop->next()) {
4552 if (strcmp(key, prop->key()) == 0) return prop->value();
4553 }
4554 return NULL;
4555 }
4556
4557 // Return the value of the requested property provided that it is a readable property.
4558 const char* Arguments::PropertyList_get_readable_value(SystemProperty *pl, const char* key) {
4559 assert(key != NULL, "just checking");
4560 SystemProperty* prop;
4561 // Return the property value if the keys match and the property is not internal or
4562 // it's the special internal property "jdk.boot.class.path.append".
4563 for (prop = pl; prop != NULL; prop = prop->next()) {
4564 if (strcmp(key, prop->key()) == 0) {
4565 if (!prop->internal()) {
4566 return prop->value();
4567 } else if (strcmp(key, "jdk.boot.class.path.append") == 0) {
4568 return prop->value();
4569 } else {
4570 // Property is internal and not jdk.boot.class.path.append so return NULL.
4571 return NULL;
4572 }
4573 }
4574 }
4575 return NULL;
4576 }
4577
4578 const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) {
4579 int count = 0;
4580 const char* ret_val = NULL;
4581
4582 while(pl != NULL) {
4583 if(count >= index) {
4584 ret_val = pl->key();
4585 break;
4586 }
4587 count++;
4588 pl = pl->next();
4589 }
4590
4591 return ret_val;
4592 }
4593
4594 char* Arguments::PropertyList_get_value_at(SystemProperty* pl, int index) {
4595 int count = 0;
4596 char* ret_val = NULL;
4597
4602 }
4603 count++;
4604 pl = pl->next();
4605 }
4606
4607 return ret_val;
4608 }
4609
4610 void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p) {
4611 SystemProperty* p = *plist;
4612 if (p == NULL) {
4613 *plist = new_p;
4614 } else {
4615 while (p->next() != NULL) {
4616 p = p->next();
4617 }
4618 p->set_next(new_p);
4619 }
4620 }
4621
4622 void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v,
4623 bool writeable, bool internal) {
4624 if (plist == NULL)
4625 return;
4626
4627 SystemProperty* new_p = new SystemProperty(k, v, writeable, internal);
4628 PropertyList_add(plist, new_p);
4629 }
4630
4631 void Arguments::PropertyList_add(SystemProperty *element) {
4632 PropertyList_add(&_system_properties, element);
4633 }
4634
4635 // This add maintains unique property key in the list.
4636 void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
4637 PropertyAppendable append, PropertyWriteable writeable,
4638 PropertyInternal internal) {
4639 if (plist == NULL)
4640 return;
4641
4642 // If property key exist then update with new value.
4643 SystemProperty* prop;
4644 for (prop = *plist; prop != NULL; prop = prop->next()) {
4645 if (strcmp(k, prop->key()) == 0) {
4646 if (append == AppendProperty) {
4647 prop->append_value(v);
4648 } else {
4649 prop->set_value(v);
4650 }
4651 return;
4652 }
4653 }
4654
4655 PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty);
4656 }
4657
4658 // Copies src into buf, replacing "%%" with "%" and "%p" with pid
4659 // Returns true if all of the source pointed by src has been copied over to
4660 // the destination buffer pointed by buf. Otherwise, returns false.
4661 // Notes:
4662 // 1. If the length (buflen) of the destination buffer excluding the
4663 // NULL terminator character is not long enough for holding the expanded
4664 // pid characters, it also returns false instead of returning the partially
4665 // expanded one.
4666 // 2. The passed in "buflen" should be large enough to hold the null terminator.
4667 bool Arguments::copy_expand_pid(const char* src, size_t srclen,
4668 char* buf, size_t buflen) {
4669 const char* p = src;
4670 char* b = buf;
4671 const char* src_end = &src[srclen];
4672 char* buf_end = &buf[buflen - 1];
4673
4674 while (p < src_end && b < buf_end) {
4675 if (*p == '%') {
|