< prev index next >

src/share/vm/runtime/arguments.cpp

Print this page
rev 11608 : Harold's patch v1
rev 11609 : imported patch bug_8136930.hs2.patch


  94 bool   Arguments::_ClipInlining                 = ClipInlining;
  95 intx   Arguments::_Tier3InvokeNotifyFreqLog     = Tier3InvokeNotifyFreqLog;
  96 intx   Arguments::_Tier4InvocationThreshold     = Tier4InvocationThreshold;
  97 
  98 char*  Arguments::SharedArchivePath             = NULL;
  99 
 100 AgentLibraryList Arguments::_libraryList;
 101 AgentLibraryList Arguments::_agentList;
 102 
 103 abort_hook_t     Arguments::_abort_hook         = NULL;
 104 exit_hook_t      Arguments::_exit_hook          = NULL;
 105 vfprintf_hook_t  Arguments::_vfprintf_hook      = NULL;
 106 
 107 
 108 SystemProperty *Arguments::_sun_boot_library_path = NULL;
 109 SystemProperty *Arguments::_java_library_path = NULL;
 110 SystemProperty *Arguments::_java_home = NULL;
 111 SystemProperty *Arguments::_java_class_path = NULL;
 112 SystemProperty *Arguments::_jdk_boot_class_path_append = NULL;
 113 
 114 GrowableArray<ModuleXPatchPath*> *Arguments::_xpatchprefix = NULL;
 115 PathString *Arguments::_system_boot_class_path = NULL;
 116 
 117 char* Arguments::_ext_dirs = NULL;
 118 
 119 // Check if head of 'option' matches 'name', and sets 'tail' to the remaining
 120 // part of the option string.
 121 static bool match_option(const JavaVMOption *option, const char* name,
 122                          const char** tail) {
 123   size_t len = strlen(name);
 124   if (strncmp(option->optionString, name, len) == 0) {
 125     *tail = option->optionString + len;
 126     return true;
 127   } else {
 128     return false;
 129   }
 130 }
 131 
 132 // Check if 'option' matches 'name'. No "tail" is allowed.
 133 static bool match_option(const JavaVMOption *option, const char* name) {
 134   const char* tail = NULL;


 144 // If tail_allowed is true, then the tail must begin with a colon; otherwise,
 145 // the option must match exactly.
 146 static bool match_option(const JavaVMOption* option, const char** names, const char** tail,
 147   bool tail_allowed) {
 148   for (/* empty */; *names != NULL; ++names) {
 149     if (match_option(option, *names, tail)) {
 150       if (**tail == '\0' || tail_allowed && **tail == ':') {
 151         return true;
 152       }
 153     }
 154   }
 155   return false;
 156 }
 157 
 158 static void logOption(const char* opt) {
 159   if (PrintVMOptions) {
 160     jio_fprintf(defaultStream::output_stream(), "VM option '%s'\n", opt);
 161   }
 162 }
 163 
























 164 // Process java launcher properties.
 165 void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) {
 166   // See if sun.java.launcher, sun.java.launcher.is_altjvm or
 167   // sun.java.launcher.pid is defined.
 168   // Must do this before setting up other system properties,
 169   // as some of them may depend on launcher type.
 170   for (int index = 0; index < args->nOptions; index++) {
 171     const JavaVMOption* option = args->options + index;
 172     const char* tail;
 173 
 174     if (match_option(option, "-Dsun.java.launcher=", &tail)) {
 175       process_java_launcher_argument(tail, option->extraInfo);
 176       continue;
 177     }
 178     if (match_option(option, "-Dsun.java.launcher.is_altjvm=", &tail)) {
 179       if (strcmp(tail, "true") == 0) {
 180         _sun_java_launcher_is_altjvm = true;
 181       }
 182       continue;
 183     }


1181       }
1182     }
1183     c = getc(stream);
1184   }
1185   if (pos > 0) {
1186     token[pos] = '\0';
1187     result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
1188     build_jvm_flags(token);
1189   }
1190   fclose(stream);
1191   return result;
1192 }
1193 
1194 //=============================================================================================================
1195 // Parsing of properties (-D)
1196 
1197 const char* Arguments::get_property(const char* key) {
1198   return PropertyList_get_value(system_properties(), key);
1199 }
1200 
1201 bool Arguments::add_property(const char* prop) {
1202   const char* eq = strchr(prop, '=');
1203   const char* key;
1204   const char* value = "";
1205 
1206   if (eq == NULL) {
1207     // property doesn't have a value, thus use passed string
1208     key = prop;
1209   } else {
1210     // property have a value, thus extract it and save to the
1211     // allocated string
1212     size_t key_len = eq - prop;
1213     char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
1214 
1215     strncpy(tmp_key, prop, key_len);
1216     tmp_key[key_len] = '\0';
1217     key = tmp_key;
1218 
1219     value = &prop[key_len + 1];
1220   }
1221 
1222   if (strcmp(key, "java.compiler") == 0) {
1223     process_java_compiler_argument(value);
1224     // Record value in Arguments, but let it get passed to Java.
1225   } else if (strcmp(key, "sun.java.launcher.is_altjvm") == 0 ||
1226              strcmp(key, "sun.java.launcher.pid") == 0) {
1227     // sun.java.launcher.is_altjvm and sun.java.launcher.pid property are
1228     // private and are processed in process_sun_java_launcher_properties();
1229     // the sun.java.launcher property is passed on to the java application
1230   } else if (strcmp(key, "sun.boot.library.path") == 0) {
1231     PropertyList_unique_add(&_system_properties, key, value, true);


1232   } else {
1233     if (strcmp(key, "sun.java.command") == 0) {
1234       char *old_java_command = _java_command;
1235       _java_command = os::strdup_check_oom(value, mtArguments);
1236       if (old_java_command != NULL) {
1237         os::free(old_java_command);
1238       }
1239     } else if (strcmp(key, "java.vendor.url.bug") == 0) {
1240       const char* old_java_vendor_url_bug = _java_vendor_url_bug;
1241       // save it in _java_vendor_url_bug, so JVM fatal error handler can access
1242       // its value without going through the property list or making a Java call.
1243       _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
1244       if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
1245         assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
1246         os::free((void *)old_java_vendor_url_bug);
1247       }
1248     }
1249 
1250     // Create new property and add at the end of the list
1251     PropertyList_unique_add(&_system_properties, key, value);
1252   }
1253 
1254   if (key != prop) {
1255     // SystemProperty copy passed value, thus free previously allocated
1256     // memory
1257     FreeHeap((void *)key);
1258   }
1259 
1260   return true;
1261 }
1262 
1263 // sets or adds a module name to the jdk.launcher.addmods property
1264 bool Arguments::append_to_addmods_property(const char* module_name) {
1265   const char* key = "jdk.launcher.addmods";
1266   const char* old_value = Arguments::get_property(key);
1267   size_t buf_len = strlen(key) + strlen(module_name) + 2;
1268   if (old_value != NULL) {
1269     buf_len += strlen(old_value) + 1;
1270   }
1271   char* new_value = AllocateHeap(buf_len, mtArguments);
1272   if (new_value == NULL) {
1273     return false;
1274   }
1275   if (old_value == NULL) {
1276     jio_snprintf(new_value, buf_len, "%s=%s", key, module_name);
1277   } else {
1278     jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
1279   }
1280   bool added = add_property(new_value);
1281   FreeHeap(new_value);
1282   return added;
1283 }
1284 
1285 #if INCLUDE_CDS
1286 void Arguments::check_unsupported_dumping_properties() {
1287   assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
1288   const char* unsupported_properties[5] = { "jdk.module.main",
1289                                            "jdk.module.path",
1290                                            "jdk.upgrade.module.path",
1291                                            "jdk.launcher.addmods",
1292                                            "jdk.launcher.limitmods" };
1293   const char* unsupported_options[5] = { "-m",
1294                                         "-modulepath",
1295                                         "-upgrademodulepath",
1296                                         "-addmods",
1297                                         "-limitmods" };
1298   SystemProperty* sp = system_properties();
1299   while (sp != NULL) {
1300     for (int i = 0; i < 5; i++) {
1301       if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
1302           vm_exit_during_initialization(
1303             "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
1304       }
1305     }
1306     sp = sp->next();
1307   }
1308 }
1309 #endif
1310 
1311 //===========================================================================================================
1312 // Setting int/mixed/comp mode flags
1313 
1314 void Arguments::set_mode_flags(Mode mode) {
1315   // Set up default values for all flags.
1316   // If you add a flag to any of the branches below,
1317   // add a default value for it here.
1318   set_java_compiler(false);
1319   _mode                      = mode;
1320 
1321   // Ensure Agent_OnLoad has the correct initial values.
1322   // This may not be the final mode; mode may change later in onload phase.
1323   PropertyList_unique_add(&_system_properties, "java.vm.info",
1324                           VM_Version::vm_info_string(), false);
1325 
1326   UseInterpreter             = true;
1327   UseCompiler                = true;
1328   UseLoopCounter             = true;
1329 
1330   // Default values may be platform/compiler dependent -
1331   // use the saved values
1332   ClipInlining               = Arguments::_ClipInlining;
1333   AlwaysCompileLoopMethods   = Arguments::_AlwaysCompileLoopMethods;
1334   UseOnStackReplacement      = Arguments::_UseOnStackReplacement;
1335   BackgroundCompilation      = Arguments::_BackgroundCompilation;
1336   if (TieredCompilation) {
1337     if (FLAG_IS_DEFAULT(Tier3InvokeNotifyFreqLog)) {
1338       Tier3InvokeNotifyFreqLog = Arguments::_Tier3InvokeNotifyFreqLog;
1339     }
1340     if (FLAG_IS_DEFAULT(Tier4InvocationThreshold)) {
1341       Tier4InvocationThreshold = Arguments::_Tier4InvocationThreshold;
1342     }
1343   }
1344 


2502 
2503   // Check the sign first since atojulong() parses only unsigned values.
2504   bool value_is_positive = !(*value == '-');
2505 
2506   if (value_is_positive) {
2507     julong n;
2508     bool good_return = atojulong(value, &n);
2509     if (good_return) {
2510       bool above_minimum = n >= min_size;
2511       bool value_is_too_large = n > max_uintx;
2512 
2513       if (above_minimum && !value_is_too_large) {
2514         *uintx_arg = n;
2515         return true;
2516       }
2517     }
2518   }
2519   return false;
2520 }
2521 



































2522 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
2523                                                   julong* long_arg,
2524                                                   julong min_size) {
2525   if (!atojulong(s, long_arg)) return arg_unreadable;
2526   return check_memory_size(*long_arg, min_size);
2527 }
2528 
2529 // Parse JavaVMInitArgs structure
2530 
2531 jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
2532                                    const JavaVMInitArgs *java_options_args,
2533                                    const JavaVMInitArgs *cmd_line_args) {
2534   bool xpatch_javabase = false;
2535 
2536   // Save default settings for some mode flags
2537   Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
2538   Arguments::_UseOnStackReplacement    = UseOnStackReplacement;
2539   Arguments::_ClipInlining             = ClipInlining;
2540   Arguments::_BackgroundCompilation    = BackgroundCompilation;
2541   if (TieredCompilation) {
2542     Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
2543     Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
2544   }
2545 
2546   // Setup flags for mixed which is the default
2547   set_mode_flags(_mixed);
2548 
2549   // Parse args structure generated from JAVA_TOOL_OPTIONS environment
2550   // variable (if present).
2551   jint result = parse_each_vm_init_arg(java_tool_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
2552   if (result != JNI_OK) {
2553     return result;
2554   }
2555 
2556   // Parse args structure generated from the command line flags.
2557   result = parse_each_vm_init_arg(cmd_line_args, &xpatch_javabase, Flag::COMMAND_LINE);
2558   if (result != JNI_OK) {
2559     return result;
2560   }
2561 
2562   // Parse args structure generated from the _JAVA_OPTIONS environment
2563   // variable (if present) (mimics classic VM)
2564   result = parse_each_vm_init_arg(java_options_args, &xpatch_javabase, Flag::ENVIRON_VAR);
2565   if (result != JNI_OK) {
2566     return result;
2567   }
2568 
2569   // Do final processing now that all arguments have been parsed
2570   result = finalize_vm_init_args();
2571   if (result != JNI_OK) {
2572     return result;
2573   }
2574 
2575   return JNI_OK;
2576 }
2577 
2578 // Checks if name in command-line argument -agent{lib,path}:name[=options]
2579 // represents a valid JDWP agent.  is_path==true denotes that we
2580 // are dealing with -agentpath (case where name is a path), otherwise with
2581 // -agentlib
2582 bool valid_jdwp_agent(char *name, bool is_path) {
2583   char *_name;
2584   const char *_jdwp = "jdwp";


2603       _name += _len_jdwp;
2604     }
2605     else {
2606       return false;
2607     }
2608 
2609     if (strcmp(_name, JNI_LIB_SUFFIX) != 0) {
2610       return false;
2611     }
2612 
2613     return true;
2614   }
2615 
2616   if (strcmp(name, _jdwp) == 0) {
2617     return true;
2618   }
2619 
2620   return false;
2621 }
2622 
2623 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* xpatch_javabase, Flag::Flags origin) {




























2624   // For match_option to return remaining or value part of option string
2625   const char* tail;
2626 
2627   // iterate over arguments
2628   for (int index = 0; index < args->nOptions; index++) {
2629     bool is_absolute_path = false;  // for -agentpath vs -agentlib
2630 
2631     const JavaVMOption* option = args->options + index;
2632 
2633     if (!match_option(option, "-Djava.class.path", &tail) &&
2634         !match_option(option, "-Dsun.java.command", &tail) &&
2635         !match_option(option, "-Dsun.java.launcher", &tail)) {
2636 
2637         // add all jvm options to the jvm_args string. This string
2638         // is used later to set the java.vm.args PerfData string constant.
2639         // the -Djava.class.path and the -Dsun.java.command options are
2640         // omitted from jvm_args string as each have their own PerfData
2641         // string constant object.
2642         build_jvm_args(option->optionString);
2643     }


2688       if (tail != NULL) {
2689         const char* pos = strchr(tail, ':');
2690         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2691         char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2692         name[len] = '\0';
2693 
2694         char *options = NULL;
2695         if(pos != NULL) {
2696           size_t len2 = strlen(pos+1) + 1; // options start after ':'.  Final zero must be copied.
2697           options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtArguments), pos+1, len2);
2698         }
2699 #if !INCLUDE_JVMTI
2700         if (strcmp(name, "jdwp") == 0) {
2701           jio_fprintf(defaultStream::error_stream(),
2702             "Debugging agents are not supported in this VM\n");
2703           return JNI_ERR;
2704         }
2705 #endif // !INCLUDE_JVMTI
2706         add_init_library(name, options);
2707       }




























2708     // -agentlib and -agentpath
2709     } else if (match_option(option, "-agentlib:", &tail) ||
2710           (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
2711       if(tail != NULL) {
2712         const char* pos = strchr(tail, '=');
2713         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2714         char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2715         name[len] = '\0';
2716 
2717         char *options = NULL;
2718         if(pos != NULL) {
2719           options = os::strdup_check_oom(pos + 1, mtArguments);
2720         }
2721 #if !INCLUDE_JVMTI
2722         if (valid_jdwp_agent(name, is_absolute_path)) {
2723           jio_fprintf(defaultStream::error_stream(),
2724             "Debugging agents are not supported in this VM\n");
2725           return JNI_ERR;
2726         }
2727 #endif // !INCLUDE_JVMTI


2979       vm_exit(0);
2980 #endif
2981     // -D
2982     } else if (match_option(option, "-D", &tail)) {
2983       const char* value;
2984       if (match_option(option, "-Djava.endorsed.dirs=", &value) &&
2985             *value!= '\0' && strcmp(value, "\"\"") != 0) {
2986         // abort if -Djava.endorsed.dirs is set
2987         jio_fprintf(defaultStream::output_stream(),
2988           "-Djava.endorsed.dirs=%s is not supported. Endorsed standards and standalone APIs\n"
2989           "in modular form will be supported via the concept of upgradeable modules.\n", value);
2990         return JNI_EINVAL;
2991       }
2992       if (match_option(option, "-Djava.ext.dirs=", &value) &&
2993             *value != '\0' && strcmp(value, "\"\"") != 0) {
2994         // abort if -Djava.ext.dirs is set
2995         jio_fprintf(defaultStream::output_stream(),
2996           "-Djava.ext.dirs=%s is not supported.  Use -classpath instead.\n", value);
2997         return JNI_EINVAL;
2998       }







2999 
3000       if (!add_property(tail)) {
3001         return JNI_ENOMEM;
3002       }
3003       // Out of the box management support
3004       if (match_option(option, "-Dcom.sun.management", &tail)) {
3005 #if INCLUDE_MANAGEMENT
3006         if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != Flag::SUCCESS) {
3007           return JNI_EINVAL;
3008         }
3009         // management agent in module java.management
3010         if (!Arguments::append_to_addmods_property("java.management")) {
3011           return JNI_ENOMEM;
3012         }
3013 #else
3014         jio_fprintf(defaultStream::output_stream(),
3015           "-Dcom.sun.management is not supported in this VM.\n");
3016         return JNI_ERR;
3017 #endif
3018       }
3019       if (match_option(option, "-Djdk.launcher.patch.", &tail)) {
3020         // -Djdk.launcher.patch.#=<module>=<file>(<pathsep><file>)*
3021         // The number, #, specified will be increasing with each -Xpatch
3022         // specified on the command line.
3023         // Pick up module name, following the -D property's equal sign.
3024         const char* property_equal = strchr(tail, '=');
3025         if (property_equal == NULL) {
3026           jio_fprintf(defaultStream::output_stream(), "Missing '=' in -Xpatch specification\n");
3027           return JNI_ERR;
3028         } else {
3029           // Find the equal sign between the module name and the path specification
3030           const char* module_equal = strchr(property_equal + 1, '=');
3031           if (module_equal == NULL) {
3032             jio_fprintf(defaultStream::output_stream(), "Bad value for -Xpatch, no module name specified\n");
3033             return JNI_ERR;
3034           } else {
3035             // Pick out the module name, in between the two equal signs
3036             size_t module_len = module_equal - property_equal - 1;
3037             char* module_name = NEW_C_HEAP_ARRAY(char, module_len+1, mtArguments);
3038             memcpy(module_name, property_equal + 1, module_len);
3039             *(module_name + module_len) = '\0';
3040             // The path piece begins one past the module_equal sign
3041             Arguments::add_xpatchprefix(module_name, module_equal + 1, xpatch_javabase);
3042             FREE_C_HEAP_ARRAY(char, module_name);
3043           }
3044         }
3045       }
3046     // -Xint
3047     } else if (match_option(option, "-Xint")) {
3048           set_mode_flags(_int);
3049     // -Xmixed
3050     } else if (match_option(option, "-Xmixed")) {
3051           set_mode_flags(_mixed);
3052     // -Xcomp
3053     } else if (match_option(option, "-Xcomp")) {
3054       // for testing the compiler; turn off all flags that inhibit compilation
3055           set_mode_flags(_comp);
3056     // -Xshare:dump
3057     } else if (match_option(option, "-Xshare:dump")) {
3058       if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != Flag::SUCCESS) {
3059         return JNI_EINVAL;
3060       }
3061       set_mode_flags(_int);     // Prevent compilation, which creates objects
3062     // -Xshare:on
3063     } else if (match_option(option, "-Xshare:on")) {
3064       if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
3065         return JNI_EINVAL;


3285       return JNI_EINVAL;
3286     }
3287     if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
3288       return JNI_EINVAL;
3289     }
3290     LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(class, path));
3291   }
3292 
3293   // Change the default value for flags  which have different default values
3294   // when working with older JDKs.
3295 #ifdef LINUX
3296  if (JDK_Version::current().compare_major(6) <= 0 &&
3297       FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) {
3298     FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
3299   }
3300 #endif // LINUX
3301   fix_appclasspath();
3302   return JNI_OK;
3303 }
3304 
3305 void Arguments::add_xpatchprefix(const char* module_name, const char* path, bool* xpatch_javabase) {
3306   // For java.base check for duplicate -Xpatch options being specified on the command line.
3307   // This check is only required for java.base, all other duplicate module specifications
3308   // will be checked during module system initialization.  The module system initialization
3309   // will throw an ExceptionInInitializerError if this situation occurs.
3310   if (strcmp(module_name, "java.base") == 0) {
3311     if (*xpatch_javabase) {
3312       vm_exit_during_initialization("Cannot specify java.base more than once to -Xpatch");
3313     } else {
3314       *xpatch_javabase = true;
3315     }
3316   }
3317 
3318   // Create GrowableArray lazily, only if -Xpatch has been specified
3319   if (_xpatchprefix == NULL) {
3320     _xpatchprefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModuleXPatchPath*>(10, true);
3321   }
3322 
3323   _xpatchprefix->push(new ModuleXPatchPath(module_name, path));
3324 }
3325 
3326 // Set property jdk.boot.class.path.append to the contents of the bootclasspath
3327 // that follows either the jimage file or exploded module directories.  The
3328 // property will contain -Xbootclasspath/a and/or jvmti appended additions.
3329 void Arguments::set_jdkbootclasspath_append() {
3330   char *sysclasspath = get_sysclasspath();
3331   assert(sysclasspath != NULL, "NULL sysclasspath");
3332   int bcp_a_idx = bootclassloader_append_index();
3333   if (bcp_a_idx != -1 && bcp_a_idx < (int)strlen(sysclasspath)) {
3334     _jdk_boot_class_path_append->set_value(sysclasspath + bcp_a_idx);
3335   }
3336 }
3337 
3338 // Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
3339 //
3340 // This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
3341 // in their start-up scripts. If XYZ is empty, the classpath will look like "-cp foo.jar::bar.jar".
3342 // Java treats such empty paths as if the user specified "-cp foo.jar:.:bar.jar". I.e., an empty
3343 // path is treated as the current directory.


3440 
3441   DIR* dir = os::opendir(path);
3442   if (dir != NULL) {
3443     jio_fprintf(defaultStream::output_stream(),
3444       "<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs\n"
3445       "in modular form will be supported via the concept of upgradeable modules.\n");
3446     os::closedir(dir);
3447     return JNI_ERR;
3448   }
3449 
3450   sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
3451   dir = os::opendir(path);
3452   if (dir != NULL) {
3453     jio_fprintf(defaultStream::output_stream(),
3454       "<JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; "
3455       "Use -classpath instead.\n.");
3456     os::closedir(dir);
3457     return JNI_ERR;
3458   }
3459 









3460   Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
3461 
3462   // This must be done after all arguments have been processed.
3463   // java_compiler() true means set to "NONE" or empty.
3464   if (java_compiler() && !xdebug_mode()) {
3465     // For backwards compatibility, we switch to interpreted mode if
3466     // -Djava.compiler="NONE" or "" is specified AND "-Xdebug" was
3467     // not specified.
3468     set_mode_flags(_int);
3469   }
3470 
3471   // CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode),
3472   // but like -Xint, leave compilation thresholds unaffected.
3473   // With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well.
3474   if ((CompileThresholdScaling == 0.0) || (!TieredCompilation && CompileThreshold == 0)) {
3475     set_mode_flags(_int);
3476   }
3477 
3478   // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
3479   if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {


3796     // We now have a complete token
3797 
3798     JavaVMOption option;
3799     option.optionString = opt_hd;
3800     option.extraInfo = NULL;
3801 
3802     options->append(option);                // Fill in option
3803 
3804     rd++;  // Advance to next character
3805   }
3806 
3807   // Fill out JavaVMInitArgs structure.
3808   jint status = vm_args->set_args(options);
3809 
3810   delete options;
3811   return status;
3812 }
3813 
3814 void Arguments::set_shared_spaces_flags() {
3815   if (DumpSharedSpaces) {
3816     if (Arguments::get_xpatchprefix() != NULL) {
3817       vm_exit_during_initialization(
3818         "Cannot use the following option when dumping the shared archive", "-Xpatch");
3819     }
3820 
3821     if (RequireSharedSpaces) {
3822       warning("Cannot dump shared archive while using shared archive");
3823     }
3824     UseSharedSpaces = false;
3825 #ifdef _LP64
3826     if (!UseCompressedOops || !UseCompressedClassPointers) {
3827       vm_exit_during_initialization(
3828         "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
3829     }
3830   } else {
3831     if (!UseCompressedOops || !UseCompressedClassPointers) {
3832       no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
3833     }
3834 #endif
3835   }
3836 }
3837 
3838 // Sharing support


4181 
4182   // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
4183   SharedArchivePath = get_shared_archive_path();
4184   if (SharedArchivePath == NULL) {
4185     return JNI_ENOMEM;
4186   }
4187 
4188   // Set up VerifySharedSpaces
4189   if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
4190     VerifySharedSpaces = true;
4191   }
4192 
4193   // Delay warning until here so that we've had a chance to process
4194   // the -XX:-PrintWarnings flag
4195   if (needs_hotspotrc_warning) {
4196     warning("%s file is present but has been ignored.  "
4197             "Run with -XX:Flags=%s to load the file.",
4198             hotspotrc, hotspotrc);
4199   }
4200 





4201 #if defined(_ALLBSD_SOURCE) || defined(AIX)  // UseLargePages is not yet supported on BSD and AIX.
4202   UNSUPPORTED_OPTION(UseLargePages);
4203 #endif
4204 
4205   ArgumentsExt::report_unsupported_options();
4206 
4207 #ifndef PRODUCT
4208   if (TraceBytecodesAt != 0) {
4209     TraceBytecodes = true;
4210   }
4211   if (CountCompiledCalls) {
4212     if (UseCounterDecay) {
4213       warning("UseCounterDecay disabled because CountCalls is set");
4214       UseCounterDecay = false;
4215     }
4216   }
4217 #endif // PRODUCT
4218 
4219   if (ScavengeRootsInCode == 0) {
4220     if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) {


4405     // allocation policy for the eden space.
4406     // Non NUMA-aware collectors such as CMS, G1 and Serial-GC on
4407     // all platforms and ParallelGC on Windows will interleave all
4408     // of the heap spaces across NUMA nodes.
4409     if (FLAG_IS_DEFAULT(UseNUMAInterleaving)) {
4410       FLAG_SET_ERGO(bool, UseNUMAInterleaving, true);
4411     }
4412   }
4413   return JNI_OK;
4414 }
4415 
4416 int Arguments::PropertyList_count(SystemProperty* pl) {
4417   int count = 0;
4418   while(pl != NULL) {
4419     count++;
4420     pl = pl->next();
4421   }
4422   return count;
4423 }
4424 












4425 const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) {
4426   assert(key != NULL, "just checking");
4427   SystemProperty* prop;
4428   for (prop = pl; prop != NULL; prop = prop->next()) {
4429     if (strcmp(key, prop->key()) == 0) return prop->value();
4430   }
4431   return NULL;
4432 }
4433 





















4434 const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) {
4435   int count = 0;
4436   const char* ret_val = NULL;
4437 
4438   while(pl != NULL) {
4439     if(count >= index) {
4440       ret_val = pl->key();
4441       break;
4442     }
4443     count++;
4444     pl = pl->next();
4445   }
4446 
4447   return ret_val;
4448 }
4449 
4450 char* Arguments::PropertyList_get_value_at(SystemProperty* pl, int index) {
4451   int count = 0;
4452   char* ret_val = NULL;
4453 


4458     }
4459     count++;
4460     pl = pl->next();
4461   }
4462 
4463   return ret_val;
4464 }
4465 
4466 void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p) {
4467   SystemProperty* p = *plist;
4468   if (p == NULL) {
4469     *plist = new_p;
4470   } else {
4471     while (p->next() != NULL) {
4472       p = p->next();
4473     }
4474     p->set_next(new_p);
4475   }
4476 }
4477 
4478 void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v) {

4479   if (plist == NULL)
4480     return;
4481 
4482   SystemProperty* new_p = new SystemProperty(k, v, true);
4483   PropertyList_add(plist, new_p);
4484 }
4485 
4486 void Arguments::PropertyList_add(SystemProperty *element) {
4487   PropertyList_add(&_system_properties, element);
4488 }
4489 
4490 // This add maintains unique property key in the list.
4491 void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v, jboolean append) {


4492   if (plist == NULL)
4493     return;
4494 
4495   // If property key exist then update with new value.
4496   SystemProperty* prop;
4497   for (prop = *plist; prop != NULL; prop = prop->next()) {
4498     if (strcmp(k, prop->key()) == 0) {
4499       if (append) {
4500         prop->append_value(v);
4501       } else {
4502         prop->set_writeable_value(v);
4503       }
4504       return;
4505     }
4506   }
4507 
4508   PropertyList_add(plist, k, v);
4509 }
4510 
4511 // Copies src into buf, replacing "%%" with "%" and "%p" with pid
4512 // Returns true if all of the source pointed by src has been copied over to
4513 // the destination buffer pointed by buf. Otherwise, returns false.
4514 // Notes:
4515 // 1. If the length (buflen) of the destination buffer excluding the
4516 // NULL terminator character is not long enough for holding the expanded
4517 // pid characters, it also returns false instead of returning the partially
4518 // expanded one.
4519 // 2. The passed in "buflen" should be large enough to hold the null terminator.
4520 bool Arguments::copy_expand_pid(const char* src, size_t srclen,
4521                                 char* buf, size_t buflen) {
4522   const char* p = src;
4523   char* b = buf;
4524   const char* src_end = &src[srclen];
4525   char* buf_end = &buf[buflen - 1];
4526 
4527   while (p < src_end && b < buf_end) {
4528     if (*p == '%') {




  94 bool   Arguments::_ClipInlining                 = ClipInlining;
  95 intx   Arguments::_Tier3InvokeNotifyFreqLog     = Tier3InvokeNotifyFreqLog;
  96 intx   Arguments::_Tier4InvocationThreshold     = Tier4InvocationThreshold;
  97 
  98 char*  Arguments::SharedArchivePath             = NULL;
  99 
 100 AgentLibraryList Arguments::_libraryList;
 101 AgentLibraryList Arguments::_agentList;
 102 
 103 abort_hook_t     Arguments::_abort_hook         = NULL;
 104 exit_hook_t      Arguments::_exit_hook          = NULL;
 105 vfprintf_hook_t  Arguments::_vfprintf_hook      = NULL;
 106 
 107 
 108 SystemProperty *Arguments::_sun_boot_library_path = NULL;
 109 SystemProperty *Arguments::_java_library_path = NULL;
 110 SystemProperty *Arguments::_java_home = NULL;
 111 SystemProperty *Arguments::_java_class_path = NULL;
 112 SystemProperty *Arguments::_jdk_boot_class_path_append = NULL;
 113 
 114 GrowableArray<ModulePatchPath*> *Arguments::_patch_mod_prefix = NULL;
 115 PathString *Arguments::_system_boot_class_path = NULL;
 116 
 117 char* Arguments::_ext_dirs = NULL;
 118 
 119 // Check if head of 'option' matches 'name', and sets 'tail' to the remaining
 120 // part of the option string.
 121 static bool match_option(const JavaVMOption *option, const char* name,
 122                          const char** tail) {
 123   size_t len = strlen(name);
 124   if (strncmp(option->optionString, name, len) == 0) {
 125     *tail = option->optionString + len;
 126     return true;
 127   } else {
 128     return false;
 129   }
 130 }
 131 
 132 // Check if 'option' matches 'name'. No "tail" is allowed.
 133 static bool match_option(const JavaVMOption *option, const char* name) {
 134   const char* tail = NULL;


 144 // If tail_allowed is true, then the tail must begin with a colon; otherwise,
 145 // the option must match exactly.
 146 static bool match_option(const JavaVMOption* option, const char** names, const char** tail,
 147   bool tail_allowed) {
 148   for (/* empty */; *names != NULL; ++names) {
 149     if (match_option(option, *names, tail)) {
 150       if (**tail == '\0' || tail_allowed && **tail == ':') {
 151         return true;
 152       }
 153     }
 154   }
 155   return false;
 156 }
 157 
 158 static void logOption(const char* opt) {
 159   if (PrintVMOptions) {
 160     jio_fprintf(defaultStream::output_stream(), "VM option '%s'\n", opt);
 161   }
 162 }
 163 
 164 bool needs_module_property_warning = false;
 165 
 166 #define MODULE_PROPERTY_PREFIX "jdk.module"
 167 #define MODULE_PROPERTY_PREFIX_LEN 10
 168 #define MODULE_MAIN_PROPERTY "jdk.module.main"
 169 #define MODULE_MAIN_PROPERTY_LEN 15
 170 
 171 // Return TRUE if option matches property, or property=, or property..
 172 static bool matches_property_prefix(const char* option, const char* property, size_t len) {
 173   return (strncmp(option, property, len) == 0) &&
 174           (option[len] == '=' || option[len] == '.' || option[len] == '\0');
 175 }
 176 
 177 // Return true if the property is either "jdk.module" or starts with "jdk.module.",
 178 // but does not start with "jdk.module.main".
 179 // Return false if jdk.module.main because jdk.module.main and jdk.module.main.class
 180 // are valid non-internal system properties.
 181 // "property" should be passed without the leading "-D".
 182 bool Arguments::is_internal_module_property(const char* property) {
 183   assert((strncmp(property, "-D", 2) != 0), "Unexpected leading -D");
 184   return (matches_property_prefix(property, MODULE_PROPERTY_PREFIX, MODULE_PROPERTY_PREFIX_LEN) &&
 185           !matches_property_prefix(property, MODULE_MAIN_PROPERTY, MODULE_MAIN_PROPERTY_LEN));
 186 }
 187 
 188 // Process java launcher properties.
 189 void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) {
 190   // See if sun.java.launcher, sun.java.launcher.is_altjvm or
 191   // sun.java.launcher.pid is defined.
 192   // Must do this before setting up other system properties,
 193   // as some of them may depend on launcher type.
 194   for (int index = 0; index < args->nOptions; index++) {
 195     const JavaVMOption* option = args->options + index;
 196     const char* tail;
 197 
 198     if (match_option(option, "-Dsun.java.launcher=", &tail)) {
 199       process_java_launcher_argument(tail, option->extraInfo);
 200       continue;
 201     }
 202     if (match_option(option, "-Dsun.java.launcher.is_altjvm=", &tail)) {
 203       if (strcmp(tail, "true") == 0) {
 204         _sun_java_launcher_is_altjvm = true;
 205       }
 206       continue;
 207     }


1205       }
1206     }
1207     c = getc(stream);
1208   }
1209   if (pos > 0) {
1210     token[pos] = '\0';
1211     result &= process_argument(token, ignore_unrecognized, Flag::CONFIG_FILE);
1212     build_jvm_flags(token);
1213   }
1214   fclose(stream);
1215   return result;
1216 }
1217 
1218 //=============================================================================================================
1219 // Parsing of properties (-D)
1220 
1221 const char* Arguments::get_property(const char* key) {
1222   return PropertyList_get_value(system_properties(), key);
1223 }
1224 
1225 bool Arguments::add_property(const char* prop, PropertyWriteable writeable, PropertyInternal internal) {
1226   const char* eq = strchr(prop, '=');
1227   const char* key;
1228   const char* value = "";
1229 
1230   if (eq == NULL) {
1231     // property doesn't have a value, thus use passed string
1232     key = prop;
1233   } else {
1234     // property have a value, thus extract it and save to the
1235     // allocated string
1236     size_t key_len = eq - prop;
1237     char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
1238 
1239     strncpy(tmp_key, prop, key_len);
1240     tmp_key[key_len] = '\0';
1241     key = tmp_key;
1242 
1243     value = &prop[key_len + 1];
1244   }
1245 
1246   if (strcmp(key, "java.compiler") == 0) {
1247     process_java_compiler_argument(value);
1248     // Record value in Arguments, but let it get passed to Java.
1249   } else if (strcmp(key, "sun.java.launcher.is_altjvm") == 0 ||
1250              strcmp(key, "sun.java.launcher.pid") == 0) {
1251     // sun.java.launcher.is_altjvm and sun.java.launcher.pid property are
1252     // private and are processed in process_sun_java_launcher_properties();
1253     // the sun.java.launcher property is passed on to the java application
1254   } else if (strcmp(key, "sun.boot.library.path") == 0) {
1255     // append is true, writable is true, internal is false
1256     PropertyList_unique_add(&_system_properties, key, value, AppendProperty,
1257                             WriteableProperty, ExternalProperty);
1258   } else {
1259     if (strcmp(key, "sun.java.command") == 0) {
1260       char *old_java_command = _java_command;
1261       _java_command = os::strdup_check_oom(value, mtArguments);
1262       if (old_java_command != NULL) {
1263         os::free(old_java_command);
1264       }
1265     } else if (strcmp(key, "java.vendor.url.bug") == 0) {
1266       const char* old_java_vendor_url_bug = _java_vendor_url_bug;
1267       // save it in _java_vendor_url_bug, so JVM fatal error handler can access
1268       // its value without going through the property list or making a Java call.
1269       _java_vendor_url_bug = os::strdup_check_oom(value, mtArguments);
1270       if (old_java_vendor_url_bug != DEFAULT_VENDOR_URL_BUG) {
1271         assert(old_java_vendor_url_bug != NULL, "_java_vendor_url_bug is NULL");
1272         os::free((void *)old_java_vendor_url_bug);
1273       }
1274     }
1275 
1276     // Create new property and add at the end of the list
1277     PropertyList_unique_add(&_system_properties, key, value, AddProperty, writeable, internal);
1278   }
1279 
1280   if (key != prop) {
1281     // SystemProperty copy passed value, thus free previously allocated
1282     // memory
1283     FreeHeap((void *)key);
1284   }
1285 
1286   return true;
1287 }
1288 
1289 // sets or adds a module name to the jdk.module.addmods property
1290 bool Arguments::append_to_addmods_property(const char* module_name) {
1291   const char* key = "jdk.module.addmods";
1292   const char* old_value = Arguments::get_property(key);
1293   size_t buf_len = strlen(key) + strlen(module_name) + 2;
1294   if (old_value != NULL) {
1295     buf_len += strlen(old_value) + 1;
1296   }
1297   char* new_value = AllocateHeap(buf_len, mtArguments);
1298   if (new_value == NULL) {
1299     return false;
1300   }
1301   if (old_value == NULL) {
1302     jio_snprintf(new_value, buf_len, "%s=%s", key, module_name);
1303   } else {
1304     jio_snprintf(new_value, buf_len, "%s=%s,%s", key, old_value, module_name);
1305   }
1306   bool added = add_property(new_value, UnwriteableProperty, InternalProperty);
1307   FreeHeap(new_value);
1308   return added;
1309 }
1310 
1311 #if INCLUDE_CDS
1312 void Arguments::check_unsupported_dumping_properties() {
1313   assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
1314   const char* unsupported_properties[5] = { "jdk.module.main",
1315                                            "jdk.module.path",
1316                                            "jdk.module.upgrade.path",
1317                                            "jdk.module.addmods",
1318                                            "jdk.module.limitmods" };
1319   const char* unsupported_options[5] = { "-m",
1320                                         "--module-path",
1321                                         "--upgrade-module-path",
1322                                         "--add-modules",
1323                                         "--limit-modules" };
1324   SystemProperty* sp = system_properties();
1325   while (sp != NULL) {
1326     for (int i = 0; i < 5; i++) {
1327       if (strcmp(sp->key(), unsupported_properties[i]) == 0) {
1328           vm_exit_during_initialization(
1329             "Cannot use the following option when dumping the shared archive", unsupported_options[i]);
1330       }
1331     }
1332     sp = sp->next();
1333   }
1334 }
1335 #endif
1336 
1337 //===========================================================================================================
1338 // Setting int/mixed/comp mode flags
1339 
1340 void Arguments::set_mode_flags(Mode mode) {
1341   // Set up default values for all flags.
1342   // If you add a flag to any of the branches below,
1343   // add a default value for it here.
1344   set_java_compiler(false);
1345   _mode                      = mode;
1346 
1347   // Ensure Agent_OnLoad has the correct initial values.
1348   // This may not be the final mode; mode may change later in onload phase.
1349   PropertyList_unique_add(&_system_properties, "java.vm.info",
1350                           VM_Version::vm_info_string(), AddProperty, UnwriteableProperty, ExternalProperty);
1351 
1352   UseInterpreter             = true;
1353   UseCompiler                = true;
1354   UseLoopCounter             = true;
1355 
1356   // Default values may be platform/compiler dependent -
1357   // use the saved values
1358   ClipInlining               = Arguments::_ClipInlining;
1359   AlwaysCompileLoopMethods   = Arguments::_AlwaysCompileLoopMethods;
1360   UseOnStackReplacement      = Arguments::_UseOnStackReplacement;
1361   BackgroundCompilation      = Arguments::_BackgroundCompilation;
1362   if (TieredCompilation) {
1363     if (FLAG_IS_DEFAULT(Tier3InvokeNotifyFreqLog)) {
1364       Tier3InvokeNotifyFreqLog = Arguments::_Tier3InvokeNotifyFreqLog;
1365     }
1366     if (FLAG_IS_DEFAULT(Tier4InvocationThreshold)) {
1367       Tier4InvocationThreshold = Arguments::_Tier4InvocationThreshold;
1368     }
1369   }
1370 


2528 
2529   // Check the sign first since atojulong() parses only unsigned values.
2530   bool value_is_positive = !(*value == '-');
2531 
2532   if (value_is_positive) {
2533     julong n;
2534     bool good_return = atojulong(value, &n);
2535     if (good_return) {
2536       bool above_minimum = n >= min_size;
2537       bool value_is_too_large = n > max_uintx;
2538 
2539       if (above_minimum && !value_is_too_large) {
2540         *uintx_arg = n;
2541         return true;
2542       }
2543     }
2544   }
2545   return false;
2546 }
2547 
2548 unsigned int addreads_count = 0;
2549 unsigned int addexports_count = 0;
2550 unsigned int patch_mod_count = 0;
2551 const char* add_modules_value = NULL;
2552 
2553 bool Arguments::create_property(const char* prop_name, const char* prop_value, PropertyInternal internal) {
2554   size_t prop_len = strlen(prop_name) + strlen(prop_value) + 2;
2555   char* property = AllocateHeap(prop_len, mtArguments);
2556   int ret = jio_snprintf(property, prop_len, "%s=%s", prop_name, prop_value);
2557   if (ret < 0 || ret >= (int)prop_len) {
2558     FreeHeap(property);
2559     return false;
2560   }
2561   bool added = add_property(property, UnwriteableProperty, internal);
2562   FreeHeap(property);
2563   return added;
2564 }
2565 
2566 bool Arguments::create_numbered_property(const char* prop_base_name, const char* prop_value, unsigned int count) {
2567   // Make sure count is < 1,000. Otherwise, memory allocation will be too small.
2568   if (count < 1000) {
2569     size_t prop_len = strlen(prop_base_name) + strlen(prop_value) + 5;
2570     char* property = AllocateHeap(prop_len, mtArguments);
2571     int ret = jio_snprintf(property, prop_len, "%s.%d=%s", prop_base_name, count, prop_value);
2572     if (ret < 0 || ret >= (int)prop_len) {
2573       FreeHeap(property);
2574       return false;
2575     }
2576     bool added = add_property(property, UnwriteableProperty, InternalProperty);
2577     FreeHeap(property);
2578     return added;
2579   }
2580   return false;
2581 }
2582 
2583 Arguments::ArgsRange Arguments::parse_memory_size(const char* s,
2584                                                   julong* long_arg,
2585                                                   julong min_size) {
2586   if (!atojulong(s, long_arg)) return arg_unreadable;
2587   return check_memory_size(*long_arg, min_size);
2588 }
2589 
2590 // Parse JavaVMInitArgs structure
2591 
2592 jint Arguments::parse_vm_init_args(const JavaVMInitArgs *java_tool_options_args,
2593                                    const JavaVMInitArgs *java_options_args,
2594                                    const JavaVMInitArgs *cmd_line_args) {
2595   bool patch_mod_javabase = false;
2596 
2597   // Save default settings for some mode flags
2598   Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods;
2599   Arguments::_UseOnStackReplacement    = UseOnStackReplacement;
2600   Arguments::_ClipInlining             = ClipInlining;
2601   Arguments::_BackgroundCompilation    = BackgroundCompilation;
2602   if (TieredCompilation) {
2603     Arguments::_Tier3InvokeNotifyFreqLog = Tier3InvokeNotifyFreqLog;
2604     Arguments::_Tier4InvocationThreshold = Tier4InvocationThreshold;
2605   }
2606 
2607   // Setup flags for mixed which is the default
2608   set_mode_flags(_mixed);
2609 
2610   // Parse args structure generated from JAVA_TOOL_OPTIONS environment
2611   // variable (if present).
2612   jint result = parse_each_vm_init_arg(java_tool_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
2613   if (result != JNI_OK) {
2614     return result;
2615   }
2616 
2617   // Parse args structure generated from the command line flags.
2618   result = parse_each_vm_init_arg(cmd_line_args, &patch_mod_javabase, Flag::COMMAND_LINE);
2619   if (result != JNI_OK) {
2620     return result;
2621   }
2622 
2623   // Parse args structure generated from the _JAVA_OPTIONS environment
2624   // variable (if present) (mimics classic VM)
2625   result = parse_each_vm_init_arg(java_options_args, &patch_mod_javabase, Flag::ENVIRON_VAR);
2626   if (result != JNI_OK) {
2627     return result;
2628   }
2629 
2630   // Do final processing now that all arguments have been parsed
2631   result = finalize_vm_init_args();
2632   if (result != JNI_OK) {
2633     return result;
2634   }
2635 
2636   return JNI_OK;
2637 }
2638 
2639 // Checks if name in command-line argument -agent{lib,path}:name[=options]
2640 // represents a valid JDWP agent.  is_path==true denotes that we
2641 // are dealing with -agentpath (case where name is a path), otherwise with
2642 // -agentlib
2643 bool valid_jdwp_agent(char *name, bool is_path) {
2644   char *_name;
2645   const char *_jdwp = "jdwp";


2664       _name += _len_jdwp;
2665     }
2666     else {
2667       return false;
2668     }
2669 
2670     if (strcmp(_name, JNI_LIB_SUFFIX) != 0) {
2671       return false;
2672     }
2673 
2674     return true;
2675   }
2676 
2677   if (strcmp(name, _jdwp) == 0) {
2678     return true;
2679   }
2680 
2681   return false;
2682 }
2683 
2684 int Arguments::process_patch_mod_option(const char* patch_mod_tail, bool* patch_mod_javabase) {
2685   // --patch-module=<module>=<file>(<pathsep><file>)*
2686   assert(patch_mod_tail != NULL, "Unexpected NULL patch-module value");
2687   // Find the equal sign between the module name and the path specification
2688   const char* module_equal = strchr(patch_mod_tail, '=');
2689   if (module_equal == NULL) {
2690     jio_fprintf(defaultStream::output_stream(), "Missing '=' in --patch-module specification\n");
2691     return JNI_ERR;
2692   } else {
2693     // Pick out the module name
2694     size_t module_len = module_equal - patch_mod_tail;
2695     char* module_name = NEW_C_HEAP_ARRAY_RETURN_NULL(char, module_len+1, mtArguments);
2696     if (module_name != NULL) {
2697       memcpy(module_name, patch_mod_tail, module_len);
2698       *(module_name + module_len) = '\0';
2699       // The path piece begins one past the module_equal sign
2700       add_patch_mod_prefix(module_name, module_equal + 1, patch_mod_javabase);
2701       FREE_C_HEAP_ARRAY(char, module_name);
2702       if (!create_numbered_property("jdk.module.patch", patch_mod_tail, patch_mod_count++)) {
2703         return JNI_ENOMEM;
2704       }
2705     } else {
2706       return JNI_ENOMEM;
2707     }
2708   }
2709   return JNI_OK;
2710 }
2711 
2712 jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_mod_javabase, Flag::Flags origin) {
2713   // For match_option to return remaining or value part of option string
2714   const char* tail;
2715 
2716   // iterate over arguments
2717   for (int index = 0; index < args->nOptions; index++) {
2718     bool is_absolute_path = false;  // for -agentpath vs -agentlib
2719 
2720     const JavaVMOption* option = args->options + index;
2721 
2722     if (!match_option(option, "-Djava.class.path", &tail) &&
2723         !match_option(option, "-Dsun.java.command", &tail) &&
2724         !match_option(option, "-Dsun.java.launcher", &tail)) {
2725 
2726         // add all jvm options to the jvm_args string. This string
2727         // is used later to set the java.vm.args PerfData string constant.
2728         // the -Djava.class.path and the -Dsun.java.command options are
2729         // omitted from jvm_args string as each have their own PerfData
2730         // string constant object.
2731         build_jvm_args(option->optionString);
2732     }


2777       if (tail != NULL) {
2778         const char* pos = strchr(tail, ':');
2779         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2780         char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2781         name[len] = '\0';
2782 
2783         char *options = NULL;
2784         if(pos != NULL) {
2785           size_t len2 = strlen(pos+1) + 1; // options start after ':'.  Final zero must be copied.
2786           options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtArguments), pos+1, len2);
2787         }
2788 #if !INCLUDE_JVMTI
2789         if (strcmp(name, "jdwp") == 0) {
2790           jio_fprintf(defaultStream::error_stream(),
2791             "Debugging agents are not supported in this VM\n");
2792           return JNI_ERR;
2793         }
2794 #endif // !INCLUDE_JVMTI
2795         add_init_library(name, options);
2796       }
2797     } else if (match_option(option, "--add-reads=", &tail)) {
2798       if (!create_numbered_property("jdk.module.addreads", tail, addreads_count++)) {
2799         return JNI_ENOMEM;
2800       }
2801     } else if (match_option(option, "--add-exports=", &tail)) {
2802       if (!create_numbered_property("jdk.module.addexports", tail, addexports_count++)) {
2803         return JNI_ENOMEM;
2804       }
2805     } else if (match_option(option, "--add-modules=", &tail)) {
2806       add_modules_value = tail;
2807     } else if (match_option(option, "--limit-modules=", &tail)) {
2808       if (!create_property("jdk.module.limitmods", tail, InternalProperty)) {
2809         return JNI_ENOMEM;
2810       }
2811     } else if (match_option(option, "--module-path=", &tail)) {
2812       if (!create_property("jdk.module.path", tail, ExternalProperty)) {
2813         return JNI_ENOMEM;
2814       }
2815     } else if (match_option(option, "--upgrade-module-path=", &tail)) {
2816       if (!create_property("jdk.module.upgrade.path", tail, ExternalProperty)) {
2817         return JNI_ENOMEM;
2818       }
2819     } else if (match_option(option, "--patch-module=", &tail)) {
2820       // --patch-module=<module>=<file>(<pathsep><file>)*
2821       int res = process_patch_mod_option(tail, patch_mod_javabase);
2822       if (res != JNI_OK) {
2823         return res;
2824       }
2825     // -agentlib and -agentpath
2826     } else if (match_option(option, "-agentlib:", &tail) ||
2827           (is_absolute_path = match_option(option, "-agentpath:", &tail))) {
2828       if(tail != NULL) {
2829         const char* pos = strchr(tail, '=');
2830         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
2831         char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
2832         name[len] = '\0';
2833 
2834         char *options = NULL;
2835         if(pos != NULL) {
2836           options = os::strdup_check_oom(pos + 1, mtArguments);
2837         }
2838 #if !INCLUDE_JVMTI
2839         if (valid_jdwp_agent(name, is_absolute_path)) {
2840           jio_fprintf(defaultStream::error_stream(),
2841             "Debugging agents are not supported in this VM\n");
2842           return JNI_ERR;
2843         }
2844 #endif // !INCLUDE_JVMTI


3096       vm_exit(0);
3097 #endif
3098     // -D
3099     } else if (match_option(option, "-D", &tail)) {
3100       const char* value;
3101       if (match_option(option, "-Djava.endorsed.dirs=", &value) &&
3102             *value!= '\0' && strcmp(value, "\"\"") != 0) {
3103         // abort if -Djava.endorsed.dirs is set
3104         jio_fprintf(defaultStream::output_stream(),
3105           "-Djava.endorsed.dirs=%s is not supported. Endorsed standards and standalone APIs\n"
3106           "in modular form will be supported via the concept of upgradeable modules.\n", value);
3107         return JNI_EINVAL;
3108       }
3109       if (match_option(option, "-Djava.ext.dirs=", &value) &&
3110             *value != '\0' && strcmp(value, "\"\"") != 0) {
3111         // abort if -Djava.ext.dirs is set
3112         jio_fprintf(defaultStream::output_stream(),
3113           "-Djava.ext.dirs=%s is not supported.  Use -classpath instead.\n", value);
3114         return JNI_EINVAL;
3115       }
3116       // Check for module related properties.  They must be set using the modules
3117       // options. For example: use "--add-modules=java.sql", not
3118       // "-Djdk.module.addmods=java.sql"
3119       if (is_internal_module_property(option->optionString + 2)) {
3120         needs_module_property_warning = true;
3121         continue;
3122       }
3123 
3124       if (!add_property(tail)) {
3125         return JNI_ENOMEM;
3126       }
3127       // Out of the box management support
3128       if (match_option(option, "-Dcom.sun.management", &tail)) {
3129 #if INCLUDE_MANAGEMENT
3130         if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != Flag::SUCCESS) {
3131           return JNI_EINVAL;
3132         }
3133         // management agent in module java.management
3134         if (!Arguments::append_to_addmods_property("java.management")) {
3135           return JNI_ENOMEM;
3136         }
3137 #else
3138         jio_fprintf(defaultStream::output_stream(),
3139           "-Dcom.sun.management is not supported in this VM.\n");
3140         return JNI_ERR;
3141 #endif
3142       }



























3143     // -Xint
3144     } else if (match_option(option, "-Xint")) {
3145           set_mode_flags(_int);
3146     // -Xmixed
3147     } else if (match_option(option, "-Xmixed")) {
3148           set_mode_flags(_mixed);
3149     // -Xcomp
3150     } else if (match_option(option, "-Xcomp")) {
3151       // for testing the compiler; turn off all flags that inhibit compilation
3152           set_mode_flags(_comp);
3153     // -Xshare:dump
3154     } else if (match_option(option, "-Xshare:dump")) {
3155       if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != Flag::SUCCESS) {
3156         return JNI_EINVAL;
3157       }
3158       set_mode_flags(_int);     // Prevent compilation, which creates objects
3159     // -Xshare:on
3160     } else if (match_option(option, "-Xshare:on")) {
3161       if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
3162         return JNI_EINVAL;


3382       return JNI_EINVAL;
3383     }
3384     if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
3385       return JNI_EINVAL;
3386     }
3387     LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(class, path));
3388   }
3389 
3390   // Change the default value for flags  which have different default values
3391   // when working with older JDKs.
3392 #ifdef LINUX
3393  if (JDK_Version::current().compare_major(6) <= 0 &&
3394       FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) {
3395     FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false);
3396   }
3397 #endif // LINUX
3398   fix_appclasspath();
3399   return JNI_OK;
3400 }
3401 
3402 void Arguments::add_patch_mod_prefix(const char* module_name, const char* path, bool* patch_mod_javabase) {
3403   // For java.base check for duplicate --patch-module options being specified on the command line.
3404   // This check is only required for java.base, all other duplicate module specifications
3405   // will be checked during module system initialization.  The module system initialization
3406   // will throw an ExceptionInInitializerError if this situation occurs.
3407   if (strcmp(module_name, "java.base") == 0) {
3408     if (*patch_mod_javabase) {
3409       vm_exit_during_initialization("Cannot specify java.base more than once to --patch-module");
3410     } else {
3411       *patch_mod_javabase = true;
3412     }
3413   }
3414 
3415   // Create GrowableArray lazily, only if --patch-module has been specified
3416   if (_patch_mod_prefix == NULL) {
3417     _patch_mod_prefix = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<ModulePatchPath*>(10, true);
3418   }
3419 
3420   _patch_mod_prefix->push(new ModulePatchPath(module_name, path));
3421 }
3422 
3423 // Set property jdk.boot.class.path.append to the contents of the bootclasspath
3424 // that follows either the jimage file or exploded module directories.  The
3425 // property will contain -Xbootclasspath/a and/or jvmti appended additions.
3426 void Arguments::set_jdkbootclasspath_append() {
3427   char *sysclasspath = get_sysclasspath();
3428   assert(sysclasspath != NULL, "NULL sysclasspath");
3429   int bcp_a_idx = bootclassloader_append_index();
3430   if (bcp_a_idx != -1 && bcp_a_idx < (int)strlen(sysclasspath)) {
3431     _jdk_boot_class_path_append->set_value(sysclasspath + bcp_a_idx);
3432   }
3433 }
3434 
3435 // Remove all empty paths from the app classpath (if IgnoreEmptyClassPaths is enabled)
3436 //
3437 // This is necessary because some apps like to specify classpath like -cp foo.jar:${XYZ}:bar.jar
3438 // in their start-up scripts. If XYZ is empty, the classpath will look like "-cp foo.jar::bar.jar".
3439 // Java treats such empty paths as if the user specified "-cp foo.jar:.:bar.jar". I.e., an empty
3440 // path is treated as the current directory.


3537 
3538   DIR* dir = os::opendir(path);
3539   if (dir != NULL) {
3540     jio_fprintf(defaultStream::output_stream(),
3541       "<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs\n"
3542       "in modular form will be supported via the concept of upgradeable modules.\n");
3543     os::closedir(dir);
3544     return JNI_ERR;
3545   }
3546 
3547   sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
3548   dir = os::opendir(path);
3549   if (dir != NULL) {
3550     jio_fprintf(defaultStream::output_stream(),
3551       "<JAVA_HOME>/lib/ext exists, extensions mechanism no longer supported; "
3552       "Use -classpath instead.\n.");
3553     os::closedir(dir);
3554     return JNI_ERR;
3555   }
3556 
3557   // Append the value of the last --add-modules option specified on the command line.
3558   // This needs to be done here, to prevent overwriting possible values written
3559   // to the jdk.module.addmods property by -javaagent and other options.
3560   if (add_modules_value != NULL) {
3561     if (!append_to_addmods_property(add_modules_value)) {
3562       return JNI_ENOMEM;
3563     }
3564   }
3565 
3566   Arguments::set_bootclassloader_append_index(((int)strlen(Arguments::get_sysclasspath()))+1);
3567 
3568   // This must be done after all arguments have been processed.
3569   // java_compiler() true means set to "NONE" or empty.
3570   if (java_compiler() && !xdebug_mode()) {
3571     // For backwards compatibility, we switch to interpreted mode if
3572     // -Djava.compiler="NONE" or "" is specified AND "-Xdebug" was
3573     // not specified.
3574     set_mode_flags(_int);
3575   }
3576 
3577   // CompileThresholdScaling == 0.0 is same as -Xint: Disable compilation (enable interpreter-only mode),
3578   // but like -Xint, leave compilation thresholds unaffected.
3579   // With tiered compilation disabled, setting CompileThreshold to 0 disables compilation as well.
3580   if ((CompileThresholdScaling == 0.0) || (!TieredCompilation && CompileThreshold == 0)) {
3581     set_mode_flags(_int);
3582   }
3583 
3584   // eventually fix up InitialTenuringThreshold if only MaxTenuringThreshold is set
3585   if (FLAG_IS_DEFAULT(InitialTenuringThreshold) && (InitialTenuringThreshold > MaxTenuringThreshold)) {


3902     // We now have a complete token
3903 
3904     JavaVMOption option;
3905     option.optionString = opt_hd;
3906     option.extraInfo = NULL;
3907 
3908     options->append(option);                // Fill in option
3909 
3910     rd++;  // Advance to next character
3911   }
3912 
3913   // Fill out JavaVMInitArgs structure.
3914   jint status = vm_args->set_args(options);
3915 
3916   delete options;
3917   return status;
3918 }
3919 
3920 void Arguments::set_shared_spaces_flags() {
3921   if (DumpSharedSpaces) {
3922     if (Arguments::get_patch_mod_prefix() != NULL) {
3923       vm_exit_during_initialization(
3924         "Cannot use the following option when dumping the shared archive: --patch-module");
3925     }
3926 
3927     if (RequireSharedSpaces) {
3928       warning("Cannot dump shared archive while using shared archive");
3929     }
3930     UseSharedSpaces = false;
3931 #ifdef _LP64
3932     if (!UseCompressedOops || !UseCompressedClassPointers) {
3933       vm_exit_during_initialization(
3934         "Cannot dump shared archive when UseCompressedOops or UseCompressedClassPointers is off.", NULL);
3935     }
3936   } else {
3937     if (!UseCompressedOops || !UseCompressedClassPointers) {
3938       no_shared_spaces("UseCompressedOops and UseCompressedClassPointers must be on for UseSharedSpaces.");
3939     }
3940 #endif
3941   }
3942 }
3943 
3944 // Sharing support


4287 
4288   // Call get_shared_archive_path() here, after possible SharedArchiveFile option got parsed.
4289   SharedArchivePath = get_shared_archive_path();
4290   if (SharedArchivePath == NULL) {
4291     return JNI_ENOMEM;
4292   }
4293 
4294   // Set up VerifySharedSpaces
4295   if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
4296     VerifySharedSpaces = true;
4297   }
4298 
4299   // Delay warning until here so that we've had a chance to process
4300   // the -XX:-PrintWarnings flag
4301   if (needs_hotspotrc_warning) {
4302     warning("%s file is present but has been ignored.  "
4303             "Run with -XX:Flags=%s to load the file.",
4304             hotspotrc, hotspotrc);
4305   }
4306 
4307   if (needs_module_property_warning) {
4308     warning("Ignoring system property options whose names start with '-Djdk.module'."
4309             "  They are reserved for internal use.");
4310   }
4311 
4312 #if defined(_ALLBSD_SOURCE) || defined(AIX)  // UseLargePages is not yet supported on BSD and AIX.
4313   UNSUPPORTED_OPTION(UseLargePages);
4314 #endif
4315 
4316   ArgumentsExt::report_unsupported_options();
4317 
4318 #ifndef PRODUCT
4319   if (TraceBytecodesAt != 0) {
4320     TraceBytecodes = true;
4321   }
4322   if (CountCompiledCalls) {
4323     if (UseCounterDecay) {
4324       warning("UseCounterDecay disabled because CountCalls is set");
4325       UseCounterDecay = false;
4326     }
4327   }
4328 #endif // PRODUCT
4329 
4330   if (ScavengeRootsInCode == 0) {
4331     if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) {


4516     // allocation policy for the eden space.
4517     // Non NUMA-aware collectors such as CMS, G1 and Serial-GC on
4518     // all platforms and ParallelGC on Windows will interleave all
4519     // of the heap spaces across NUMA nodes.
4520     if (FLAG_IS_DEFAULT(UseNUMAInterleaving)) {
4521       FLAG_SET_ERGO(bool, UseNUMAInterleaving, true);
4522     }
4523   }
4524   return JNI_OK;
4525 }
4526 
4527 int Arguments::PropertyList_count(SystemProperty* pl) {
4528   int count = 0;
4529   while(pl != NULL) {
4530     count++;
4531     pl = pl->next();
4532   }
4533   return count;
4534 }
4535 
4536 // Return the number of readable properties.
4537 int Arguments::PropertyList_readable_count(SystemProperty* pl) {
4538   int count = 0;
4539   while(pl != NULL) {
4540     if (pl->is_readable()) {
4541       count++;
4542     }
4543     pl = pl->next();
4544   }
4545   return count;
4546 }
4547 
4548 const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) {
4549   assert(key != NULL, "just checking");
4550   SystemProperty* prop;
4551   for (prop = pl; prop != NULL; prop = prop->next()) {
4552     if (strcmp(key, prop->key()) == 0) return prop->value();
4553   }
4554   return NULL;
4555 }
4556 
4557 // Return the value of the requested property provided that it is a readable property.
4558 const char* Arguments::PropertyList_get_readable_value(SystemProperty *pl, const char* key) {
4559   assert(key != NULL, "just checking");
4560   SystemProperty* prop;
4561   // Return the property value if the keys match and the property is not internal or
4562   // it's the special internal property "jdk.boot.class.path.append".
4563   for (prop = pl; prop != NULL; prop = prop->next()) {
4564     if (strcmp(key, prop->key()) == 0) {
4565       if (!prop->internal()) {
4566         return prop->value();
4567       } else if (strcmp(key, "jdk.boot.class.path.append") == 0) {
4568         return prop->value();
4569       } else {
4570         // Property is internal and not jdk.boot.class.path.append so return NULL.
4571         return NULL;
4572       }
4573     }
4574   }
4575   return NULL;
4576 }
4577 
4578 const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) {
4579   int count = 0;
4580   const char* ret_val = NULL;
4581 
4582   while(pl != NULL) {
4583     if(count >= index) {
4584       ret_val = pl->key();
4585       break;
4586     }
4587     count++;
4588     pl = pl->next();
4589   }
4590 
4591   return ret_val;
4592 }
4593 
4594 char* Arguments::PropertyList_get_value_at(SystemProperty* pl, int index) {
4595   int count = 0;
4596   char* ret_val = NULL;
4597 


4602     }
4603     count++;
4604     pl = pl->next();
4605   }
4606 
4607   return ret_val;
4608 }
4609 
4610 void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p) {
4611   SystemProperty* p = *plist;
4612   if (p == NULL) {
4613     *plist = new_p;
4614   } else {
4615     while (p->next() != NULL) {
4616       p = p->next();
4617     }
4618     p->set_next(new_p);
4619   }
4620 }
4621 
4622 void Arguments::PropertyList_add(SystemProperty** plist, const char* k, const char* v,
4623                                  bool writeable, bool internal) {
4624   if (plist == NULL)
4625     return;
4626 
4627   SystemProperty* new_p = new SystemProperty(k, v, writeable, internal);
4628   PropertyList_add(plist, new_p);
4629 }
4630 
4631 void Arguments::PropertyList_add(SystemProperty *element) {
4632   PropertyList_add(&_system_properties, element);
4633 }
4634 
4635 // This add maintains unique property key in the list.
4636 void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
4637                                         PropertyAppendable append, PropertyWriteable writeable,
4638                                         PropertyInternal internal) {
4639   if (plist == NULL)
4640     return;
4641 
4642   // If property key exist then update with new value.
4643   SystemProperty* prop;
4644   for (prop = *plist; prop != NULL; prop = prop->next()) {
4645     if (strcmp(k, prop->key()) == 0) {
4646       if (append == AppendProperty) {
4647         prop->append_value(v);
4648       } else {
4649         prop->set_value(v);
4650       }
4651       return;
4652     }
4653   }
4654 
4655   PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty);
4656 }
4657 
4658 // Copies src into buf, replacing "%%" with "%" and "%p" with pid
4659 // Returns true if all of the source pointed by src has been copied over to
4660 // the destination buffer pointed by buf. Otherwise, returns false.
4661 // Notes:
4662 // 1. If the length (buflen) of the destination buffer excluding the
4663 // NULL terminator character is not long enough for holding the expanded
4664 // pid characters, it also returns false instead of returning the partially
4665 // expanded one.
4666 // 2. The passed in "buflen" should be large enough to hold the null terminator.
4667 bool Arguments::copy_expand_pid(const char* src, size_t srclen,
4668                                 char* buf, size_t buflen) {
4669   const char* p = src;
4670   char* b = buf;
4671   const char* src_end = &src[srclen];
4672   char* buf_end = &buf[buflen - 1];
4673 
4674   while (p < src_end && b < buf_end) {
4675     if (*p == '%') {


< prev index next >