< prev index next >

src/share/vm/runtime/arguments.cpp

Print this page




  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 == '%') {


< prev index next >