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;
135 bool result = match_option(option, name, &tail);
136 if (tail != NULL && *tail == '\0') {
137 return result;
138 } else {
139 return false;
140 }
141 }
142
143 // Return true if any of the strings in null-terminated array 'names' matches.
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 }
1182 }
1183 }
1184 c = getc(stream);
1185 }
1186 if (pos > 0) {
1187 token[pos] = '\0';
1188 result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
1189 build_jvm_flags(token);
1190 }
1191 fclose(stream);
1192 return result;
1193 }
1194
1195 //=============================================================================================================
1196 // Parsing of properties (-D)
1197
1198 const char* Arguments::get_property(const char* key) {
1199 return PropertyList_get_value(system_properties(), key);
1200 }
1201
1202 bool Arguments::add_property(const char* prop) {
1203 const char* eq = strchr(prop, '=');
1204 const char* key;
1205 const char* value = "";
1206
1207 if (eq == NULL) {
1208 // property doesn't have a value, thus use passed string
1209 key = prop;
1210 } else {
1211 // property have a value, thus extract it and save to the
1212 // allocated string
1213 size_t key_len = eq - prop;
1214 char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
1215
1216 strncpy(tmp_key, prop, key_len);
1217 tmp_key[key_len] = '\0';
1218 key = tmp_key;
1219
1220 value = &prop[key_len + 1];
1221 }
1222
1223 if (strcmp(key, "java.compiler") == 0) {
1224 process_java_compiler_argument(value);
1225 // Record value in Arguments, but let it get passed to Java.
1226 } else if (strcmp(key, "sun.java.launcher.is_altjvm") == 0 ||
1227 strcmp(key, "sun.java.launcher.pid") == 0) {
1228 // sun.java.launcher.is_altjvm and sun.java.launcher.pid property are
1229 // private and are processed in process_sun_java_launcher_properties();
1230 // the sun.java.launcher property is passed on to the java application
1231 } else if (strcmp(key, "sun.boot.library.path") == 0) {
1232 PropertyList_unique_add(&_system_properties, key, value, true);
1233 } else {
1234 if (strcmp(key, "sun.java.command") == 0) {
1235 char *old_java_command = _java_command;
1236 _java_command = os::strdup_check_oom(value, mtArguments);
1237 if (old_java_command != NULL) {
1238 os::free(old_java_command);
1239 }
1240 } else if (strcmp(key, "java.vendor.url.bug") == 0) {
1241 const char* old_java_vendor_url_bug = _java_vendor_url_bug;
1242 // save it in _java_vendor_url_bug, so JVM fatal error handler can access
1243 // its value without going through the property list or making a Java call.
1244 _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
1245 if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
1246 assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
1247 os::free((void *)old_java_vendor_url_bug);
1248 }
1249 }
1250
1251 // Create new property and add at the end of the list
1252 PropertyList_unique_add(&_system_properties, key, value);
1253 }
1254
1255 if (key != prop) {
1256 // SystemProperty copy passed value, thus free previously allocated
1257 // memory
1258 FreeHeap((void *)key);
1259 }
1260
1261 return true;
1262 }
1263
1264 // sets or adds a module name to the jdk.launcher.addmods property
1265 bool Arguments::append_to_addmods_property(const char* module_name) {
1266 const char* key = "jdk.launcher.addmods";
1267 const char* old_value = Arguments::get_property(key);
1268 size_t buf_len = strlen(key) + strlen(module_name) + 2;
1269 if (old_value != NULL) {
1270 buf_len += strlen(old_value) + 1;
1271 }
1272 char* new_value = AllocateHeap(buf_len, mtArguments);
1273 if (new_value == NULL) {
1274 return false;
1275 }
1276 if (old_value == NULL) {
1277 jio_snprintf(new_value, buf_len, "%s=%s", key, module_name);
1278 } else {
1279 jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
1280 }
1281 bool added = add_property(new_value);
1282 FreeHeap(new_value);
1283 return added;
1284 }
1285
1286 #if INCLUDE_CDS
1287 void Arguments::check_unsupported_dumping_properties() {
1288 assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
1289 const char* unsupported_properties[5] = { "jdk.module.main",
1290 "jdk.module.path",
1291 "jdk.upgrade.module.path",
1292 "jdk.launcher.addmods",
1293 "jdk.launcher.limitmods" };
1294 const char* unsupported_options[5] = { "-m",
1295 "-modulepath",
1296 "-upgrademodulepath",
1297 "-addmods",
1298 "-limitmods" };
1299 SystemProperty* sp = system_properties();
1300 while (sp != NULL) {
1301 for (int i = 0; i < 5; i++) {
1302 if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
1303 vm_exit_during_initialization(
1304 "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
1305 }
1306 }
1307 sp = sp->next();
1308 }
1309 }
1310 #endif
1311
1312 //===========================================================================================================
1313 // Setting int/mixed/comp mode flags
1314
1315 void Arguments::set_mode_flags(Mode mode) {
1316 // Set up default values for all flags.
1317 // If you add a flag to any of the branches below,
1318 // add a default value for it here.
1319 set_java_compiler(false);
1320 _mode = mode;
1321
1322 // Ensure Agent_OnLoad has the correct initial values.
1323 // This may not be the final mode; mode may change later in onload phase.
1324 PropertyList_unique_add(&_system_properties, "java.vm.info",
1325 VM_Version::vm_info_string(), false);
1326
1327 UseInterpreter = true;
1328 UseCompiler = true;
1329 UseLoopCounter = true;
1330
1331 // Default values may be platform/compiler dependent -
1332 // use the saved values
1333 ClipInlining = Arguments::_ClipInlining;
1334 AlwaysCompileLoopMethods = Arguments::_AlwaysCompileLoopMethods;
1335 UseOnStackReplacement = Arguments::_UseOnStackReplacement;
1336 BackgroundCompilation = Arguments::_BackgroundCompilation;
1337 if (TieredCompilation) {
1338 if (FLAG_IS_DEFAULT(Tier3InvokeNotifyFreqLog)) {
1339 Tier3InvokeNotifyFreqLog = Arguments::_Tier3InvokeNotifyFreqLog;
1340 }
1341 if (FLAG_IS_DEFAULT(Tier4InvocationThreshold)) {
1342 Tier4InvocationThreshold = Arguments::_Tier4InvocationThreshold;
1343 }
1344 }
1345
2503
2504 // Check the sign first since atojulong() parses only unsigned values.
2505 bool value_is_positive = !(*value == '-');
2506
2507 if (value_is_positive) {
2508 julong n;
2509 bool good_return = atojulong(value, &n);
2510 if (good_return) {
2511 bool above_minimum = n >= min_size;
2512 bool value_is_too_large = n > max_uintx;
2513
2514 if (above_minimum && !value_is_too_large) {
2515 *uintx_arg = n;
2516 return true;
2517 }
2518 }
2519 }
2520 return false;
2521 }
2522
2523 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
2524 julong* long_arg,
2525 julong min_size) {
2526 if (!atojulong(s, long_arg)) return arg_unreadable;
2527 return check_memory_size(*long_arg, min_size);
2528 }
2529
2530 // Parse JavaVMInitArgs structure
2531
2532 jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
2533 const JavaVMInitArgs *java_options_args,
2534 const JavaVMInitArgs *cmd_line_args) {
2535 bool xpatch_javabase = false;
2536
2537 // Save default settings for some mode flags
2538 Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
2539 Arguments::_UseOnStackReplacement = UseOnStackReplacement;
2540 Arguments::_ClipInlining = ClipInlining;
2541 Arguments::_BackgroundCompilation = BackgroundCompilation;
2542 if (TieredCompilation) {
2543 Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
2544 Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
2545 }
2546
2547 // Setup flags for mixed which is the default
2548 set_mode_flags(_mixed);
2549
2550 // Parse args structure generated from JAVA_TOOL_OPTIONS environment
2551 // variable (if present).
2552 jint result = parse_each_vm_init_arg(java_tool_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
2553 if (result != JNI_OK) {
2554 return result;
2555 }
2556
2557 // Parse args structure generated from the command line flags.
2558 result = parse_each_vm_init_arg(cmd_line_args, &xpatch_javabase, Flag::COMMAND_LINE);
2559 if (result != JNI_OK) {
2560 return result;
2561 }
2562
2563 // Parse args structure generated from the _JAVA_OPTIONS environment
2564 // variable (if present) (mimics classic VM)
2565 result = parse_each_vm_init_arg(java_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
2566 if (result != JNI_OK) {
2567 return result;
2568 }
2569
2570 // Do final processing now that all arguments have been parsed
2571 result = finalize_vm_init_args();
2572 if (result != JNI_OK) {
2573 return result;
2574 }
2575
2576 return JNI_OK;
2577 }
2578
2579 // Checks if name in command-line argument -agent{lib,path}:name[=options]
2580 // represents a valid JDWP agent. is_path==true denotes that we
2581 // are dealing with -agentpath (case where name is a path), otherwise with
2582 // -agentlib
2583 bool valid_jdwp_agent(char *name, bool is_path) {
2584 char *_name;
2585 const char *_jdwp = "jdwp";
2604 _name += _len_jdwp;
2605 }
2606 else {
2607 return false;
2608 }
2609
2610 if (strcmp(_name, JNI_LIB_SUFFIX) != 0) {
2611 return false;
2612 }
2613
2614 return true;
2615 }
2616
2617 if (strcmp(name, _jdwp) == 0) {
2618 return true;
2619 }
2620
2621 return false;
2622 }
2623
2624 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin) {
2625 // For match_option to return remaining or value part of option string
2626 const char* tail;
2627
2628 // iterate over arguments
2629 for (int index = 0; index < args->nOptions; index++) {
2630 bool is_absolute_path = false; // for -agentpath vs -agentlib
2631
2632 const JavaVMOption* option = args->options + index;
2633
2634 if (!match_option(option, "-Djava.class.path", &tail) &&
2635 !match_option(option, "-Dsun.java.command", &tail) &&
2636 !match_option(option, "-Dsun.java.launcher", &tail)) {
2637
2638 // add all jvm options to the jvm_args string. This string
2639 // is used later to set the java.vm.args PerfData string constant.
2640 // the -Djava.class.path and the -Dsun.java.command options are
2641 // omitted from jvm_args string as each have their own PerfData
2642 // string constant object.
2643 build_jvm_args(option->optionString);
2644 }
2689 if (tail != NULL) {
2690 const char* pos = strchr(tail, ':');
2691 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2692 char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2693 name[len] = '\0';
2694
2695 char *options = NULL;
2696 if(pos != NULL) {
2697 size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied.
2698 options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtArguments), pos+1, len2);
2699 }
2700 #if !INCLUDE_JVMTI
2701 if (strcmp(name, "jdwp") == 0) {
2702 jio_fprintf(defaultStream::error_stream(),
2703 "Debugging agents are not supported in this VM\n");
2704 return JNI_ERR;
2705 }
2706 #endif // !INCLUDE_JVMTI
2707 add_init_library(name, options);
2708 }
2709 // -agentlib and -agentpath
2710 } else if (match_option(option, "-agentlib:", &tail) ||
2711 (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
2712 if(tail != NULL) {
2713 const char* pos = strchr(tail, '=');
2714 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2715 char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2716 name[len] = '\0';
2717
2718 char *options = NULL;
2719 if(pos != NULL) {
2720 options = os::strdup_check_oom(pos + 1, mtArguments);
2721 }
2722 #if !INCLUDE_JVMTI
2723 if (valid_jdwp_agent(name, is_absolute_path)) {
2724 jio_fprintf(defaultStream::error_stream(),
2725 "Debugging agents are not supported in this VM\n");
2726 return JNI_ERR;
2727 }
2728 #endif // !INCLUDE_JVMTI
2980 vm_exit(0);
2981 #endif
2982 // -D
2983 } else if (match_option(option, "-D", &tail)) {
2984 const char* value;
2985 if (match_option(option, "-Djava.endorsed.dirs=", &value) &&
2986 *value!= '\0' && strcmp(value, "\"\"") != 0) {
2987 // abort if -Djava.endorsed.dirs is set
2988 jio_fprintf(defaultStream::output_stream(),
2989 "-Djava.endorsed.dirs=%s is not supported. Endorsed standards and standalone APIs\n"
2990 "in modular form will be supported via the concept of upgradeable modules.\n", value);
2991 return JNI_EINVAL;
2992 }
2993 if (match_option(option, "-Djava.ext.dirs=", &value) &&
2994 *value != '\0' && strcmp(value, "\"\"") != 0) {
2995 // abort if -Djava.ext.dirs is set
2996 jio_fprintf(defaultStream::output_stream(),
2997 "-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value);
2998 return JNI_EINVAL;
2999 }
3000
3001 if (!add_property(tail)) {
3002 return JNI_ENOMEM;
3003 }
3004 // Out of the box management support
3005 if (match_option(option, "-Dcom.sun.management", &tail)) {
3006 #if INCLUDE_MANAGEMENT
3007 if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != Flag::SUCCESS) {
3008 return JNI_EINVAL;
3009 }
3010 // management agent in module java.management
3011 if (!Arguments::append_to_addmods_property("java.management")) {
3012 return JNI_ENOMEM;
3013 }
3014 #else
3015 jio_fprintf(defaultStream::output_stream(),
3016 "-Dcom.sun.management is not supported in this VM.\n");
3017 return JNI_ERR;
3018 #endif
3019 }
3020 if (match_option(option, "-Djdk.launcher.patch.", &tail)) {
3021 // -Djdk.launcher.patch.#=<module>=<file>(<pathsep><file>)*
3022 // The number, #, specified will be increasing with each -Xpatch
3023 // specified on the command line.
3024 // Pick up module name, following the -D property's equal sign.
3025 const char* property_equal = strchr(tail, '=');
3026 if (property_equal == NULL) {
3027 jio_fprintf(defaultStream::output_stream(), "Missing '=' in -Xpatch specification\n");
3028 return JNI_ERR;
3029 } else {
3030 // Find the equal sign between the module name and the path specification
3031 const char* module_equal = strchr(property_equal + 1, '=');
3032 if (module_equal == NULL) {
3033 jio_fprintf(defaultStream::output_stream(), "Bad value for -Xpatch, no module name specified\n");
3034 return JNI_ERR;
3035 } else {
3036 // Pick out the module name, in between the two equal signs
3037 size_t module_len = module_equal - property_equal - 1;
3038 char* module_name = NEW_C_HEAP_ARRAY(char, module_len+1, mtArguments);
3039 memcpy(module_name, property_equal + 1, module_len);
3040 *(module_name + module_len) = '\0';
3041 // The path piece begins one past the module_equal sign
3042 Arguments::add_xpatchprefix(module_name, module_equal + 1, xpatch_javabase);
3043 FREE_C_HEAP_ARRAY(char, module_name);
3044 }
3045 }
3046 }
3047 // -Xint
3048 } else if (match_option(option, "-Xint")) {
3049 set_mode_flags(_int);
3050 // -Xmixed
3051 } else if (match_option(option, "-Xmixed")) {
3052 set_mode_flags(_mixed);
3053 // -Xcomp
3054 } else if (match_option(option, "-Xcomp")) {
3055 // for testing the compiler; turn off all flags that inhibit compilation
3056 set_mode_flags(_comp);
3057 // -Xshare:dump
3058 } else if (match_option(option, "-Xshare:dump")) {
3059 if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != Flag::SUCCESS) {
3060 return JNI_EINVAL;
3061 }
3062 set_mode_flags(_int); // Prevent compilation, which creates objects
3063 // -Xshare:on
3064 } else if (match_option(option, "-Xshare:on")) {
3065 if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
3066 return JNI_EINVAL;
3286 return JNI_EINVAL;
3287 }
3288 if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
3289 return JNI_EINVAL;
3290 }
3291 LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(class, path));
3292 }
3293
3294 // Change the default value for flags which have different default values
3295 // when working with older JDKs.
3296 #ifdef LINUX
3297 if (JDK_Version::current().compare_major(6) <= 0 &&
3298 FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) {
3299 FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
3300 }
3301 #endif // LINUX
3302 fix_appclasspath();
3303 return JNI_OK;
3304 }
3305
3306 void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) {
3307 // For java.base check for duplicate -Xpatch options being specified on the command line.
3308 // This check is only required for java.base, all other duplicate module specifications
3309 // will be checked during module system initialization. The module system initialization
3310 // will throw an ExceptionInInitializerError if this situation occurs.
3311 if (strcmp(module_name, "java.base") == 0) {
3312 if (*xpatch_javabase) {
3313 vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch");
3314 } else {
3315 *xpatch_javabase = true;
3316 }
3317 }
3318
3319 // Create GrowableArray lazily, only if -Xpatch has been specified
3320 if (_xpatchprefix == NULL) {
3321 _xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true);
3322 }
3323
3324 _xpatchprefix->push(new ModuleXPatchPath(module_name, path));
3325 }
3326
3327 // Set property jdk.boot.class.path.append to the contents of the bootclasspath
3328 // that follows either the jimage file or exploded module directories. The
3329 // property will contain -Xbootclasspath/a and/or jvmti appended additions.
3330 void Arguments::set_jdkbootclasspath_append() {
3331 char *sysclasspath = get_sysclasspath();
3332 assert(sysclasspath != NULL, "NULL sysclasspath");
3333 int bcp_a_idx = bootclassloader_append_index();
3334 if (bcp_a_idx != -1 && bcp_a_idx < (int)strlen(sysclasspath)) {
3335 _jdk_boot_class_path_append->set_value(sysclasspath + bcp_a_idx);
3336 }
3337 }
3338
3339 // Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
3340 //
3341 // This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
3342 // in their start-up scripts. If XYZ is empty, the classpath will look like "-cp foo.jar::bar.jar".
3343 // Java treats such empty paths as if the user specified "-cp foo.jar:.:bar.jar". I.e., an empty
3344 // path is treated as the current directory.
3441
3442 DIR* dir = os::opendir(path);
3443 if (dir != NULL) {
3444 jio_fprintf(defaultStream::output_stream(),
3445 "<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs\n"
3446 "in modular form will be supported via the concept of upgradeable modules.\n");
3447 os::closedir(dir);
3448 return JNI_ERR;
3449 }
3450
3451 sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
3452 dir = os::opendir(path);
3453 if (dir != NULL) {
3454 jio_fprintf(defaultStream::output_stream(),
3455 "<JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; "
3456 "Use -classpath instead.\n.");
3457 os::closedir(dir);
3458 return JNI_ERR;
3459 }
3460
3461 Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
3462
3463 // This must be done after all arguments have been processed.
3464 // java_compiler() true means set to "NONE" or empty.
3465 if (java_compiler() && !xdebug_mode()) {
3466 // For backwards compatibility, we switch to interpreted mode if
3467 // -Djava.compiler="NONE" or "" is specified AND "-Xdebug" was
3468 // not specified.
3469 set_mode_flags(_int);
3470 }
3471
3472 // CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode),
3473 // but like -Xint, leave compilation thresholds unaffected.
3474 // With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well.
3475 if ((CompileThresholdScaling == 0.0) || (!TieredCompilation && CompileThreshold == 0)) {
3476 set_mode_flags(_int);
3477 }
3478
3479 // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
3480 if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {
3797 // We now have a complete token
3798
3799 JavaVMOption option;
3800 option.optionString = opt_hd;
3801 option.extraInfo = NULL;
3802
3803 options->append(option); // Fill in option
3804
3805 rd++; // Advance to next character
3806 }
3807
3808 // Fill out JavaVMInitArgs structure.
3809 jint status = vm_args->set_args(options);
3810
3811 delete options;
3812 return status;
3813 }
3814
3815 void Arguments::set_shared_spaces_flags() {
3816 if (DumpSharedSpaces) {
3817 if (Arguments::get_xpatchprefix() != NULL) {
3818 vm_exit_during_initialization(
3819 "Cannot use the following option when dumping the shared archive", "-Xpatch");
3820 }
3821
3822 if (RequireSharedSpaces) {
3823 warning("Cannot dump shared archive while using shared archive");
3824 }
3825 UseSharedSpaces = false;
3826 #ifdef _LP64
3827 if (!UseCompressedOops || !UseCompressedClassPointers) {
3828 vm_exit_during_initialization(
3829 "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
3830 }
3831 } else {
3832 if (!UseCompressedOops || !UseCompressedClassPointers) {
3833 no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
3834 }
3835 #endif
3836 }
3837 }
3838
3839 // Sharing support
4459 }
4460 count++;
4461 pl = pl->next();
4462 }
4463
4464 return ret_val;
4465 }
4466
4467 void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p) {
4468 SystemProperty* p = *plist;
4469 if (p == NULL) {
4470 *plist = new_p;
4471 } else {
4472 while (p->next() != NULL) {
4473 p = p->next();
4474 }
4475 p->set_next(new_p);
4476 }
4477 }
4478
4479 void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v) {
4480 if (plist == NULL)
4481 return;
4482
4483 SystemProperty* new_p = new SystemProperty(k, v, true);
4484 PropertyList_add(plist, new_p);
4485 }
4486
4487 void Arguments::PropertyList_add(SystemProperty *element) {
4488 PropertyList_add(&_system_properties, element);
4489 }
4490
4491 // This add maintains unique property key in the list.
4492 void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, jboolean append) {
4493 if (plist == NULL)
4494 return;
4495
4496 // If property key exist then update with new value.
4497 SystemProperty* prop;
4498 for (prop = *plist; prop != NULL; prop = prop->next()) {
4499 if (strcmp(k, prop->key()) == 0) {
4500 if (append) {
4501 prop->append_value(v);
4502 } else {
4503 prop->set_writeable_value(v);
4504 }
4505 return;
4506 }
4507 }
4508
4509 PropertyList_add(plist, k, v);
4510 }
4511
4512 // Copies src into buf, replacing "%%" with "%" and "%p" with pid
4513 // Returns true if all of the source pointed by src has been copied over to
4514 // the destination buffer pointed by buf. Otherwise, returns false.
4515 // Notes:
4516 // 1. If the length (buflen) of the destination buffer excluding the
4517 // NULL terminator character is not long enough for holding the expanded
4518 // pid characters, it also returns false instead of returning the partially
4519 // expanded one.
4520 // 2. The passed in "buflen" should be large enough to hold the null terminator.
4521 bool Arguments::copy_expand_pid(const char* src, size_t srclen,
4522 char* buf, size_t buflen) {
4523 const char* p = src;
4524 char* b = buf;
4525 const char* src_end = &src[srclen];
4526 char* buf_end = &buf[buflen - 1];
4527
4528 while (p < src_end && b < buf_end) {
4529 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;
135 bool result = match_option(option, name, &tail);
136 if (tail != NULL && *tail == '\0') {
137 return result;
138 } else {
139 return false;
140 }
141 }
142
143 #define MODULE_PROPERTY_PREFIX "jdk.module"
144 #define MODULE_PROPERTY_PREFIX_LEN 10
145 #define ADDEXPORTS "addexports"
146 #define ADDEXPORTS_LEN 10
147 #define ADDREADS "addreads"
148 #define ADDREADS_LEN 8
149 #define PATCH "patch"
150 #define PATCH_LEN 5
151 #define ADDMODS "addmods"
152 #define ADDMODS_LEN 7
153 #define LIMITMODS "limitmods"
154 #define LIMITMODS_LEN 9
155 #define PATH "path"
156 #define PATH_LEN 4
157 #define UPGRADE_PATH "upgrade.path"
158 #define UPGRADE_PATH_LEN 12
159
160 // Return TRUE if option matches property.<digits> or matches property.<digits>=.
161 static bool is_matching_numbered_property(const char* option, const char* property, size_t len) {
162 if (strncmp(option, property, len) == 0) {
163 // Check for digits.
164 const char* sptr = option + len;
165 if (isdigit(*sptr)) { // Make sure next char is a digit.
166 while (isdigit(*sptr)) {
167 sptr++;
168 if (*sptr == '=' || *sptr == '\0') {
169 return true;
170 }
171 }
172 }
173 }
174 return false;
175 }
176
177 // Return TRUE if option matches property or matches property=.
178 static bool is_matching_property(const char* option, const char* property, size_t len) {
179 return (strncmp(option, property, len) == 0) && (option[len] == '=' || option[len] == '\0');
180 }
181
182 // Return true if option_end is the name of a module-related java property
183 // with "-Djdk.module." removed.
184 static bool is_internal_module_property_end(const char* option_end) {
185 // For the repeating properties such as (-Djdk.module.patch.0
186 // -Djdk.module.patch.1, etc) return true for "<property_name>.<digit>[=]".
187 if (is_matching_numbered_property(option_end, ADDEXPORTS ".", ADDEXPORTS_LEN + 1) ||
188 is_matching_numbered_property(option_end, ADDREADS ".", ADDREADS_LEN + 1) ||
189 is_matching_numbered_property(option_end, PATCH ".", PATCH_LEN + 1)) {
190 return true;
191 }
192 return (is_matching_property(option_end, ADDMODS, ADDMODS_LEN) ||
193 is_matching_property(option_end, LIMITMODS, LIMITMODS_LEN));
194 }
195
196 // Return true if the option is one of the module-related java properties
197 // that can only be set using the proper module-related option.
198 static bool is_module_property(const JavaVMOption *option) {
199 if (strncmp(option->optionString, "-D" MODULE_PROPERTY_PREFIX ".", MODULE_PROPERTY_PREFIX_LEN + 3) == 0) {
200 const char* option_end = option->optionString + MODULE_PROPERTY_PREFIX_LEN + 3;
201 return (is_internal_module_property_end(option_end) ||
202 is_matching_property(option_end, PATH, PATH_LEN) ||
203 is_matching_property(option_end, UPGRADE_PATH, UPGRADE_PATH_LEN));
204 }
205 return false;
206 }
207
208 // Return true if the option is one of the module-related java properties
209 // that can only be set using the proper module-related option and cannot
210 // be read by jvmti.
211 // It's expected that the caller removed the leading "-D" from 'option'.
212 bool Arguments::is_internal_module_property(const char* option) {
213 assert((strncmp(option, "-D", 2) != 0), "Unexpected leading -D");
214 if (strncmp(option, MODULE_PROPERTY_PREFIX ".", MODULE_PROPERTY_PREFIX_LEN + 1) == 0) {
215 return is_internal_module_property_end(option + MODULE_PROPERTY_PREFIX_LEN + 1);
216 }
217 return false;
218 }
219
220 // Return true if any of the strings in null-terminated array 'names' matches.
221 // If tail_allowed is true, then the tail must begin with a colon; otherwise,
222 // the option must match exactly.
223 static bool match_option(const JavaVMOption* option, const char** names, const char** tail,
224 bool tail_allowed) {
225 for (/* empty */; *names != NULL; ++names) {
226 if (match_option(option, *names, tail)) {
227 if (**tail == '\0' || tail_allowed && **tail == ':') {
228 return true;
229 }
230 }
231 }
232 return false;
233 }
234
235 static void logOption(const char* opt) {
236 if (PrintVMOptions) {
237 jio_fprintf(defaultStream::output_stream(), "VM option '%s'\n", opt);
238 }
239 }
1259 }
1260 }
1261 c = getc(stream);
1262 }
1263 if (pos > 0) {
1264 token[pos] = '\0';
1265 result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
1266 build_jvm_flags(token);
1267 }
1268 fclose(stream);
1269 return result;
1270 }
1271
1272 //=============================================================================================================
1273 // Parsing of properties (-D)
1274
1275 const char* Arguments::get_property(const char* key) {
1276 return PropertyList_get_value(system_properties(), key);
1277 }
1278
1279 bool Arguments::add_property(const char* prop, PropertyWriteable writeable, PropertyInternal internal) {
1280 const char* eq = strchr(prop, '=');
1281 const char* key;
1282 const char* value = "";
1283
1284 if (eq == NULL) {
1285 // property doesn't have a value, thus use passed string
1286 key = prop;
1287 } else {
1288 // property have a value, thus extract it and save to the
1289 // allocated string
1290 size_t key_len = eq - prop;
1291 char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
1292
1293 strncpy(tmp_key, prop, key_len);
1294 tmp_key[key_len] = '\0';
1295 key = tmp_key;
1296
1297 value = &prop[key_len + 1];
1298 }
1299
1300 if (strcmp(key, "java.compiler") == 0) {
1301 process_java_compiler_argument(value);
1302 // Record value in Arguments, but let it get passed to Java.
1303 } else if (strcmp(key, "sun.java.launcher.is_altjvm") == 0 ||
1304 strcmp(key, "sun.java.launcher.pid") == 0) {
1305 // sun.java.launcher.is_altjvm and sun.java.launcher.pid property are
1306 // private and are processed in process_sun_java_launcher_properties();
1307 // the sun.java.launcher property is passed on to the java application
1308 } else if (strcmp(key, "sun.boot.library.path") == 0) {
1309 // append is true, writable is true, internal is false
1310 PropertyList_unique_add(&_system_properties, key, value, AppendProperty,
1311 WriteableProperty, ExternalProperty);
1312 } else {
1313 if (strcmp(key, "sun.java.command") == 0) {
1314 char *old_java_command = _java_command;
1315 _java_command = os::strdup_check_oom(value, mtArguments);
1316 if (old_java_command != NULL) {
1317 os::free(old_java_command);
1318 }
1319 } else if (strcmp(key, "java.vendor.url.bug") == 0) {
1320 const char* old_java_vendor_url_bug = _java_vendor_url_bug;
1321 // save it in _java_vendor_url_bug, so JVM fatal error handler can access
1322 // its value without going through the property list or making a Java call.
1323 _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
1324 if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
1325 assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
1326 os::free((void *)old_java_vendor_url_bug);
1327 }
1328 }
1329
1330 // Create new property and add at the end of the list
1331 PropertyList_unique_add(&_system_properties, key, value, AddProperty, writeable, internal);
1332 }
1333
1334 if (key != prop) {
1335 // SystemProperty copy passed value, thus free previously allocated
1336 // memory
1337 FreeHeap((void *)key);
1338 }
1339
1340 return true;
1341 }
1342
1343 // sets or adds a module name to the jdk.module.addmods property
1344 bool Arguments::append_to_addmods_property(const char* module_name) {
1345 const char* key = "jdk.module.addmods";
1346 const char* old_value = Arguments::get_property(key);
1347 size_t buf_len = strlen(key) + strlen(module_name) + 2;
1348 if (old_value != NULL) {
1349 buf_len += strlen(old_value) + 1;
1350 }
1351 char* new_value = AllocateHeap(buf_len, mtArguments);
1352 if (new_value == NULL) {
1353 return false;
1354 }
1355 if (old_value == NULL) {
1356 jio_snprintf(new_value, buf_len, "%s=%s", key, module_name);
1357 } else {
1358 jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
1359 }
1360 bool added = add_property(new_value, UnwriteableProperty, InternalProperty);
1361 FreeHeap(new_value);
1362 return added;
1363 }
1364
1365 #if INCLUDE_CDS
1366 void Arguments::check_unsupported_dumping_properties() {
1367 assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
1368 const char* unsupported_properties[5] = { "jdk.module.main",
1369 "jdk.module.path",
1370 "jdk.module.upgrade.path",
1371 "jdk.module.addmods",
1372 "jdk.module.limitmods" };
1373 const char* unsupported_options[5] = { "-m",
1374 "--module-path",
1375 "--upgrade-module-path",
1376 "--add-modules",
1377 "--limit-modules" };
1378 SystemProperty* sp = system_properties();
1379 while (sp != NULL) {
1380 for (int i = 0; i < 5; i++) {
1381 if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
1382 vm_exit_during_initialization(
1383 "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
1384 }
1385 }
1386 sp = sp->next();
1387 }
1388 }
1389 #endif
1390
1391 //===========================================================================================================
1392 // Setting int/mixed/comp mode flags
1393
1394 void Arguments::set_mode_flags(Mode mode) {
1395 // Set up default values for all flags.
1396 // If you add a flag to any of the branches below,
1397 // add a default value for it here.
1398 set_java_compiler(false);
1399 _mode = mode;
1400
1401 // Ensure Agent_OnLoad has the correct initial values.
1402 // This may not be the final mode; mode may change later in onload phase.
1403 PropertyList_unique_add(&_system_properties, "java.vm.info",
1404 VM_Version::vm_info_string(), AddProperty, UnwriteableProperty, ExternalProperty);
1405
1406 UseInterpreter = true;
1407 UseCompiler = true;
1408 UseLoopCounter = true;
1409
1410 // Default values may be platform/compiler dependent -
1411 // use the saved values
1412 ClipInlining = Arguments::_ClipInlining;
1413 AlwaysCompileLoopMethods = Arguments::_AlwaysCompileLoopMethods;
1414 UseOnStackReplacement = Arguments::_UseOnStackReplacement;
1415 BackgroundCompilation = Arguments::_BackgroundCompilation;
1416 if (TieredCompilation) {
1417 if (FLAG_IS_DEFAULT(Tier3InvokeNotifyFreqLog)) {
1418 Tier3InvokeNotifyFreqLog = Arguments::_Tier3InvokeNotifyFreqLog;
1419 }
1420 if (FLAG_IS_DEFAULT(Tier4InvocationThreshold)) {
1421 Tier4InvocationThreshold = Arguments::_Tier4InvocationThreshold;
1422 }
1423 }
1424
2582
2583 // Check the sign first since atojulong() parses only unsigned values.
2584 bool value_is_positive = !(*value == '-');
2585
2586 if (value_is_positive) {
2587 julong n;
2588 bool good_return = atojulong(value, &n);
2589 if (good_return) {
2590 bool above_minimum = n >= min_size;
2591 bool value_is_too_large = n > max_uintx;
2592
2593 if (above_minimum && !value_is_too_large) {
2594 *uintx_arg = n;
2595 return true;
2596 }
2597 }
2598 }
2599 return false;
2600 }
2601
2602 unsigned int addreads_count = 0;
2603 unsigned int addexports_count = 0;
2604 unsigned int patch_mod_count = 0;
2605 const char* add_modules_value = NULL;
2606
2607 bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
2608 size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
2609 char* property = AllocateHeap(prop_len, mtArguments);
2610 int ret = jio_snprintf(property, prop_len, "%s=%s", prop_name, prop_value);
2611 if (ret < 0 || ret >= (int)prop_len) {
2612 FreeHeap(property);
2613 return false;
2614 }
2615 bool added = add_property(property, UnwriteableProperty, internal);
2616 FreeHeap(property);
2617 return added;
2618 }
2619
2620 bool Arguments::create_numbered_property(const char* prop_base_name, const char* prop_value, unsigned int count) {
2621 // Make sure count is < 1,000. Otherwise, memory allocation will be too small.
2622 if (count < 1000) {
2623 size_t prop_len = strlen(prop_base_name) + strlen(prop_value) + 5;
2624 char* property = AllocateHeap(prop_len, mtArguments);
2625 int ret = jio_snprintf(property, prop_len, "%s.%d=%s", prop_base_name, count, prop_value);
2626 if (ret < 0 || ret >= (int)prop_len) {
2627 FreeHeap(property);
2628 return false;
2629 }
2630 bool added = add_property(property, UnwriteableProperty, InternalProperty);
2631 FreeHeap(property);
2632 return added;
2633 }
2634 return false;
2635 }
2636
2637 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
2638 julong* long_arg,
2639 julong min_size) {
2640 if (!atojulong(s, long_arg)) return arg_unreadable;
2641 return check_memory_size(*long_arg, min_size);
2642 }
2643
2644 // Parse JavaVMInitArgs structure
2645
2646 jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
2647 const JavaVMInitArgs *java_options_args,
2648 const JavaVMInitArgs *cmd_line_args) {
2649 bool patch_mod_javabase = false;
2650
2651 // Save default settings for some mode flags
2652 Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
2653 Arguments::_UseOnStackReplacement = UseOnStackReplacement;
2654 Arguments::_ClipInlining = ClipInlining;
2655 Arguments::_BackgroundCompilation = BackgroundCompilation;
2656 if (TieredCompilation) {
2657 Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
2658 Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
2659 }
2660
2661 // Setup flags for mixed which is the default
2662 set_mode_flags(_mixed);
2663
2664 // Parse args structure generated from JAVA_TOOL_OPTIONS environment
2665 // variable (if present).
2666 jint result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
2667 if (result != JNI_OK) {
2668 return result;
2669 }
2670
2671 // Parse args structure generated from the command line flags.
2672 result = parse_each_vm_init_arg(cmd_line_args, &patch_mod_javabase, Flag::COMMAND_LINE);
2673 if (result != JNI_OK) {
2674 return result;
2675 }
2676
2677 // Parse args structure generated from the _JAVA_OPTIONS environment
2678 // variable (if present) (mimics classic VM)
2679 result = parse_each_vm_init_arg(java_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
2680 if (result != JNI_OK) {
2681 return result;
2682 }
2683
2684 // Do final processing now that all arguments have been parsed
2685 result = finalize_vm_init_args();
2686 if (result != JNI_OK) {
2687 return result;
2688 }
2689
2690 return JNI_OK;
2691 }
2692
2693 // Checks if name in command-line argument -agent{lib,path}:name[=options]
2694 // represents a valid JDWP agent. is_path==true denotes that we
2695 // are dealing with -agentpath (case where name is a path), otherwise with
2696 // -agentlib
2697 bool valid_jdwp_agent(char *name, bool is_path) {
2698 char *_name;
2699 const char *_jdwp = "jdwp";
2718 _name += _len_jdwp;
2719 }
2720 else {
2721 return false;
2722 }
2723
2724 if (strcmp(_name, JNI_LIB_SUFFIX) != 0) {
2725 return false;
2726 }
2727
2728 return true;
2729 }
2730
2731 if (strcmp(name, _jdwp) == 0) {
2732 return true;
2733 }
2734
2735 return false;
2736 }
2737
2738 int Arguments::process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase) {
2739 // --patch-module=<module>=<file>(<pathsep><file>)*
2740 assert(patch_mod_tail != NULL, "Unexpected NULL patch-module value");
2741 // Find the equal sign between the module name and the path specification
2742 const char* module_equal = strchr(patch_mod_tail, '=');
2743 if (module_equal == NULL) {
2744 jio_fprintf(defaultStream::output_stream(), "Missing '=' in --patch-module specification\n");
2745 return JNI_ERR;
2746 } else {
2747 // Pick out the module name
2748 size_t module_len = module_equal - patch_mod_tail;
2749 char* module_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, module_len+1, mtArguments);
2750 if (module_name != NULL) {
2751 memcpy(module_name, patch_mod_tail, module_len);
2752 *(module_name + module_len) = '\0';
2753 // The path piece begins one past the module_equal sign
2754 add_patch_mod_prefix(module_name, module_equal + 1, patch_mod_javabase);
2755 FREE_C_HEAP_ARRAY(char, module_name);
2756 if (!create_numbered_property("jdk.module.patch", patch_mod_tail, patch_mod_count++)) {
2757 return JNI_ENOMEM;
2758 }
2759 } else {
2760 return JNI_ENOMEM;
2761 }
2762 }
2763 return JNI_OK;
2764 }
2765
2766 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, Flag::Flags origin) {
2767 // For match_option to return remaining or value part of option string
2768 const char* tail;
2769
2770 // iterate over arguments
2771 for (int index = 0; index < args->nOptions; index++) {
2772 bool is_absolute_path = false; // for -agentpath vs -agentlib
2773
2774 const JavaVMOption* option = args->options + index;
2775
2776 if (!match_option(option, "-Djava.class.path", &tail) &&
2777 !match_option(option, "-Dsun.java.command", &tail) &&
2778 !match_option(option, "-Dsun.java.launcher", &tail)) {
2779
2780 // add all jvm options to the jvm_args string. This string
2781 // is used later to set the java.vm.args PerfData string constant.
2782 // the -Djava.class.path and the -Dsun.java.command options are
2783 // omitted from jvm_args string as each have their own PerfData
2784 // string constant object.
2785 build_jvm_args(option->optionString);
2786 }
2831 if (tail != NULL) {
2832 const char* pos = strchr(tail, ':');
2833 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2834 char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2835 name[len] = '\0';
2836
2837 char *options = NULL;
2838 if(pos != NULL) {
2839 size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied.
2840 options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtArguments), pos+1, len2);
2841 }
2842 #if !INCLUDE_JVMTI
2843 if (strcmp(name, "jdwp") == 0) {
2844 jio_fprintf(defaultStream::error_stream(),
2845 "Debugging agents are not supported in this VM\n");
2846 return JNI_ERR;
2847 }
2848 #endif // !INCLUDE_JVMTI
2849 add_init_library(name, options);
2850 }
2851 } else if (match_option(option, "--add-reads=", &tail)) {
2852 if (!create_numbered_property("jdk.module.addreads", tail, addreads_count++)) {
2853 return JNI_ENOMEM;
2854 }
2855 } else if (match_option(option, "--add-exports=", &tail)) {
2856 if (!create_numbered_property("jdk.module.addexports", tail, addexports_count++)) {
2857 return JNI_ENOMEM;
2858 }
2859 } else if (match_option(option, "--add-modules=", &tail)) {
2860 add_modules_value = tail;
2861 } else if (match_option(option, "--limit-modules=", &tail)) {
2862 if (!create_property("jdk.module.limitmods", tail, InternalProperty)) {
2863 return JNI_ENOMEM;
2864 }
2865 } else if (match_option(option, "--module-path=", &tail)) {
2866 if (!create_property("jdk.module.path", tail, ExternalProperty)) {
2867 return JNI_ENOMEM;
2868 }
2869 } else if (match_option(option, "--upgrade-module-path=", &tail)) {
2870 if (!create_property("jdk.module.upgrade.path", tail, ExternalProperty)) {
2871 return JNI_ENOMEM;
2872 }
2873 } else if (match_option(option, "--patch-module=", &tail)) {
2874 // --patch-module=<module>=<file>(<pathsep><file>)*
2875 int res = process_patch_mod_option(tail, patch_mod_javabase);
2876 if (res != JNI_OK) {
2877 return res;
2878 }
2879 // -agentlib and -agentpath
2880 } else if (match_option(option, "-agentlib:", &tail) ||
2881 (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
2882 if(tail != NULL) {
2883 const char* pos = strchr(tail, '=');
2884 size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2885 char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2886 name[len] = '\0';
2887
2888 char *options = NULL;
2889 if(pos != NULL) {
2890 options = os::strdup_check_oom(pos + 1, mtArguments);
2891 }
2892 #if !INCLUDE_JVMTI
2893 if (valid_jdwp_agent(name, is_absolute_path)) {
2894 jio_fprintf(defaultStream::error_stream(),
2895 "Debugging agents are not supported in this VM\n");
2896 return JNI_ERR;
2897 }
2898 #endif // !INCLUDE_JVMTI
3150 vm_exit(0);
3151 #endif
3152 // -D
3153 } else if (match_option(option, "-D", &tail)) {
3154 const char* value;
3155 if (match_option(option, "-Djava.endorsed.dirs=", &value) &&
3156 *value!= '\0' && strcmp(value, "\"\"") != 0) {
3157 // abort if -Djava.endorsed.dirs is set
3158 jio_fprintf(defaultStream::output_stream(),
3159 "-Djava.endorsed.dirs=%s is not supported. Endorsed standards and standalone APIs\n"
3160 "in modular form will be supported via the concept of upgradeable modules.\n", value);
3161 return JNI_EINVAL;
3162 }
3163 if (match_option(option, "-Djava.ext.dirs=", &value) &&
3164 *value != '\0' && strcmp(value, "\"\"") != 0) {
3165 // abort if -Djava.ext.dirs is set
3166 jio_fprintf(defaultStream::output_stream(),
3167 "-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value);
3168 return JNI_EINVAL;
3169 }
3170 // Silently ignore module related properties. They must be set using the modules
3171 // options. For example: use "--add-modules java.sql", not "-Djdk.module.addmods=java.sql"
3172 if (is_module_property(option)) {
3173 continue;
3174 }
3175
3176 if (!add_property(tail)) {
3177 return JNI_ENOMEM;
3178 }
3179 // Out of the box management support
3180 if (match_option(option, "-Dcom.sun.management", &tail)) {
3181 #if INCLUDE_MANAGEMENT
3182 if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != Flag::SUCCESS) {
3183 return JNI_EINVAL;
3184 }
3185 // management agent in module java.management
3186 if (!Arguments::append_to_addmods_property("java.management")) {
3187 return JNI_ENOMEM;
3188 }
3189 #else
3190 jio_fprintf(defaultStream::output_stream(),
3191 "-Dcom.sun.management is not supported in this VM.\n");
3192 return JNI_ERR;
3193 #endif
3194 }
3195 // -Xint
3196 } else if (match_option(option, "-Xint")) {
3197 set_mode_flags(_int);
3198 // -Xmixed
3199 } else if (match_option(option, "-Xmixed")) {
3200 set_mode_flags(_mixed);
3201 // -Xcomp
3202 } else if (match_option(option, "-Xcomp")) {
3203 // for testing the compiler; turn off all flags that inhibit compilation
3204 set_mode_flags(_comp);
3205 // -Xshare:dump
3206 } else if (match_option(option, "-Xshare:dump")) {
3207 if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != Flag::SUCCESS) {
3208 return JNI_EINVAL;
3209 }
3210 set_mode_flags(_int); // Prevent compilation, which creates objects
3211 // -Xshare:on
3212 } else if (match_option(option, "-Xshare:on")) {
3213 if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
3214 return JNI_EINVAL;
3434 return JNI_EINVAL;
3435 }
3436 if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
3437 return JNI_EINVAL;
3438 }
3439 LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(class, path));
3440 }
3441
3442 // Change the default value for flags which have different default values
3443 // when working with older JDKs.
3444 #ifdef LINUX
3445 if (JDK_Version::current().compare_major(6) <= 0 &&
3446 FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) {
3447 FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
3448 }
3449 #endif // LINUX
3450 fix_appclasspath();
3451 return JNI_OK;
3452 }
3453
3454 void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, bool* patch_mod_javabase) {
3455 // For java.base check for duplicate --patch-module options being specified on the command line.
3456 // This check is only required for java.base, all other duplicate module specifications
3457 // will be checked during module system initialization. The module system initialization
3458 // will throw an ExceptionInInitializerError if this situation occurs.
3459 if (strcmp(module_name, "java.base") == 0) {
3460 if (*patch_mod_javabase) {
3461 vm_exit_during_initialization("Cannot specify java.base more than once to --patch-module");
3462 } else {
3463 *patch_mod_javabase = true;
3464 }
3465 }
3466
3467 // Create GrowableArray lazily, only if --patch-module has been specified
3468 if (_patch_mod_prefix == NULL) {
3469 _patch_mod_prefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModulePatchPath*>(10, true);
3470 }
3471
3472 _patch_mod_prefix->push(new ModulePatchPath(module_name, path));
3473 }
3474
3475 // Set property jdk.boot.class.path.append to the contents of the bootclasspath
3476 // that follows either the jimage file or exploded module directories. The
3477 // property will contain -Xbootclasspath/a and/or jvmti appended additions.
3478 void Arguments::set_jdkbootclasspath_append() {
3479 char *sysclasspath = get_sysclasspath();
3480 assert(sysclasspath != NULL, "NULL sysclasspath");
3481 int bcp_a_idx = bootclassloader_append_index();
3482 if (bcp_a_idx != -1 && bcp_a_idx < (int)strlen(sysclasspath)) {
3483 _jdk_boot_class_path_append->set_value(sysclasspath + bcp_a_idx);
3484 }
3485 }
3486
3487 // Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
3488 //
3489 // This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
3490 // in their start-up scripts. If XYZ is empty, the classpath will look like "-cp foo.jar::bar.jar".
3491 // Java treats such empty paths as if the user specified "-cp foo.jar:.:bar.jar". I.e., an empty
3492 // path is treated as the current directory.
3589
3590 DIR* dir = os::opendir(path);
3591 if (dir != NULL) {
3592 jio_fprintf(defaultStream::output_stream(),
3593 "<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs\n"
3594 "in modular form will be supported via the concept of upgradeable modules.\n");
3595 os::closedir(dir);
3596 return JNI_ERR;
3597 }
3598
3599 sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
3600 dir = os::opendir(path);
3601 if (dir != NULL) {
3602 jio_fprintf(defaultStream::output_stream(),
3603 "<JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; "
3604 "Use -classpath instead.\n.");
3605 os::closedir(dir);
3606 return JNI_ERR;
3607 }
3608
3609 // Append the value of the last --add-modules option specified on the command line.
3610 // This needs to be done here, to prevent overwriting possible values written
3611 // to the jdk.module.addmods property by -javaagent and other options.
3612 if (add_modules_value != NULL) {
3613 append_to_addmods_property(add_modules_value);
3614 }
3615
3616 Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
3617
3618 // This must be done after all arguments have been processed.
3619 // java_compiler() true means set to "NONE" or empty.
3620 if (java_compiler() && !xdebug_mode()) {
3621 // For backwards compatibility, we switch to interpreted mode if
3622 // -Djava.compiler="NONE" or "" is specified AND "-Xdebug" was
3623 // not specified.
3624 set_mode_flags(_int);
3625 }
3626
3627 // CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode),
3628 // but like -Xint, leave compilation thresholds unaffected.
3629 // With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well.
3630 if ((CompileThresholdScaling == 0.0) || (!TieredCompilation && CompileThreshold == 0)) {
3631 set_mode_flags(_int);
3632 }
3633
3634 // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
3635 if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {
3952 // We now have a complete token
3953
3954 JavaVMOption option;
3955 option.optionString = opt_hd;
3956 option.extraInfo = NULL;
3957
3958 options->append(option); // Fill in option
3959
3960 rd++; // Advance to next character
3961 }
3962
3963 // Fill out JavaVMInitArgs structure.
3964 jint status = vm_args->set_args(options);
3965
3966 delete options;
3967 return status;
3968 }
3969
3970 void Arguments::set_shared_spaces_flags() {
3971 if (DumpSharedSpaces) {
3972 if (Arguments::get_patch_mod_prefix() != NULL) {
3973 vm_exit_during_initialization(
3974 "Cannot use the following option when dumping the shared archive: --patch-module");
3975 }
3976
3977 if (RequireSharedSpaces) {
3978 warning("Cannot dump shared archive while using shared archive");
3979 }
3980 UseSharedSpaces = false;
3981 #ifdef _LP64
3982 if (!UseCompressedOops || !UseCompressedClassPointers) {
3983 vm_exit_during_initialization(
3984 "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
3985 }
3986 } else {
3987 if (!UseCompressedOops || !UseCompressedClassPointers) {
3988 no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
3989 }
3990 #endif
3991 }
3992 }
3993
3994 // Sharing support
4614 }
4615 count++;
4616 pl = pl->next();
4617 }
4618
4619 return ret_val;
4620 }
4621
4622 void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p) {
4623 SystemProperty* p = *plist;
4624 if (p == NULL) {
4625 *plist = new_p;
4626 } else {
4627 while (p->next() != NULL) {
4628 p = p->next();
4629 }
4630 p->set_next(new_p);
4631 }
4632 }
4633
4634 void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v,
4635 bool writeable, bool internal) {
4636 if (plist == NULL)
4637 return;
4638
4639 SystemProperty* new_p = new SystemProperty(k, v, writeable, internal);
4640 PropertyList_add(plist, new_p);
4641 }
4642
4643 void Arguments::PropertyList_add(SystemProperty *element) {
4644 PropertyList_add(&_system_properties, element);
4645 }
4646
4647 // This add maintains unique property key in the list.
4648 void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
4649 PropertyAppendable append, PropertyWriteable writeable,
4650 PropertyInternal internal) {
4651 if (plist == NULL)
4652 return;
4653
4654 // If property key exist then update with new value.
4655 SystemProperty* prop;
4656 for (prop = *plist; prop != NULL; prop = prop->next()) {
4657 if (strcmp(k, prop->key()) == 0) {
4658 if (append == AppendProperty) {
4659 prop->append_value(v);
4660 } else {
4661 prop->set_value(v);
4662 }
4663 return;
4664 }
4665 }
4666
4667 PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty);
4668 }
4669
4670 // Copies src into buf, replacing "%%" with "%" and "%p" with pid
4671 // Returns true if all of the source pointed by src has been copied over to
4672 // the destination buffer pointed by buf. Otherwise, returns false.
4673 // Notes:
4674 // 1. If the length (buflen) of the destination buffer excluding the
4675 // NULL terminator character is not long enough for holding the expanded
4676 // pid characters, it also returns false instead of returning the partially
4677 // expanded one.
4678 // 2. The passed in "buflen" should be large enough to hold the null terminator.
4679 bool Arguments::copy_expand_pid(const char* src, size_t srclen,
4680 char* buf, size_t buflen) {
4681 const char* p = src;
4682 char* b = buf;
4683 const char* src_end = &src[srclen];
4684 char* buf_end = &buf[buflen - 1];
4685
4686 while (p < src_end && b < buf_end) {
4687 if (*p == '%') {
|