duke@435: /* kevinw@2449: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #include "precompiled.hpp" stefank@2314: #include "classfile/javaAssertions.hpp" stefank@2314: #include "compiler/compilerOracle.hpp" stefank@2314: #include "memory/allocation.inline.hpp" stefank@2314: #include "memory/cardTableRS.hpp" stefank@2314: #include "memory/referenceProcessor.hpp" stefank@2314: #include "memory/universe.inline.hpp" stefank@2314: #include "oops/oop.inline.hpp" stefank@2314: #include "prims/jvmtiExport.hpp" stefank@2314: #include "runtime/arguments.hpp" stefank@2314: #include "runtime/globals_extension.hpp" stefank@2314: #include "runtime/java.hpp" stefank@2314: #include "services/management.hpp" stefank@2314: #include "utilities/defaultStream.hpp" stefank@2314: #include "utilities/taskqueue.hpp" stefank@2314: #ifdef TARGET_OS_FAMILY_linux stefank@2314: # include "os_linux.inline.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_OS_FAMILY_solaris stefank@2314: # include "os_solaris.inline.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_OS_FAMILY_windows stefank@2314: # include "os_windows.inline.hpp" stefank@2314: #endif never@3156: #ifdef TARGET_OS_FAMILY_bsd never@3156: # include "os_bsd.inline.hpp" never@3156: #endif stefank@2314: #ifndef SERIALGC stefank@2314: #include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp" stefank@2314: #endif duke@435: ohair@2756: // Note: This is a special bug reporting site for the JVM ohair@2756: #define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp" duke@435: #define DEFAULT_JAVA_LAUNCHER "generic" duke@435: duke@435: char** Arguments::_jvm_flags_array = NULL; duke@435: int Arguments::_num_jvm_flags = 0; duke@435: char** Arguments::_jvm_args_array = NULL; duke@435: int Arguments::_num_jvm_args = 0; duke@435: char* Arguments::_java_command = NULL; duke@435: SystemProperty* Arguments::_system_properties = NULL; duke@435: const char* Arguments::_gc_log_filename = NULL; duke@435: bool Arguments::_has_profile = false; duke@435: bool Arguments::_has_alloc_profile = false; duke@435: uintx Arguments::_min_heap_size = 0; duke@435: Arguments::Mode Arguments::_mode = _mixed; duke@435: bool Arguments::_java_compiler = false; duke@435: bool Arguments::_xdebug_mode = false; duke@435: const char* Arguments::_java_vendor_url_bug = DEFAULT_VENDOR_URL_BUG; duke@435: const char* Arguments::_sun_java_launcher = DEFAULT_JAVA_LAUNCHER; duke@435: int Arguments::_sun_java_launcher_pid = -1; sla@2584: bool Arguments::_created_by_gamma_launcher = false; duke@435: duke@435: // These parameters are reset in method parse_vm_init_args(JavaVMInitArgs*) duke@435: bool Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods; duke@435: bool Arguments::_UseOnStackReplacement = UseOnStackReplacement; duke@435: bool Arguments::_BackgroundCompilation = BackgroundCompilation; duke@435: bool Arguments::_ClipInlining = ClipInlining; duke@435: duke@435: char* Arguments::SharedArchivePath = NULL; duke@435: duke@435: AgentLibraryList Arguments::_libraryList; duke@435: AgentLibraryList Arguments::_agentList; duke@435: duke@435: abort_hook_t Arguments::_abort_hook = NULL; duke@435: exit_hook_t Arguments::_exit_hook = NULL; duke@435: vfprintf_hook_t Arguments::_vfprintf_hook = NULL; duke@435: duke@435: duke@435: SystemProperty *Arguments::_java_ext_dirs = NULL; duke@435: SystemProperty *Arguments::_java_endorsed_dirs = NULL; duke@435: SystemProperty *Arguments::_sun_boot_library_path = NULL; duke@435: SystemProperty *Arguments::_java_library_path = NULL; duke@435: SystemProperty *Arguments::_java_home = NULL; duke@435: SystemProperty *Arguments::_java_class_path = NULL; duke@435: SystemProperty *Arguments::_sun_boot_class_path = NULL; duke@435: duke@435: char* Arguments::_meta_index_path = NULL; duke@435: char* Arguments::_meta_index_dir = NULL; duke@435: duke@435: static bool force_client_mode = false; duke@435: duke@435: // Check if head of 'option' matches 'name', and sets 'tail' remaining part of option string duke@435: duke@435: static bool match_option(const JavaVMOption *option, const char* name, duke@435: const char** tail) { duke@435: int len = (int)strlen(name); duke@435: if (strncmp(option->optionString, name, len) == 0) { duke@435: *tail = option->optionString + len; duke@435: return true; duke@435: } else { duke@435: return false; duke@435: } duke@435: } duke@435: duke@435: static void logOption(const char* opt) { duke@435: if (PrintVMOptions) { duke@435: jio_fprintf(defaultStream::output_stream(), "VM option '%s'\n", opt); duke@435: } duke@435: } duke@435: duke@435: // Process java launcher properties. duke@435: void Arguments::process_sun_java_launcher_properties(JavaVMInitArgs* args) { duke@435: // See if sun.java.launcher or sun.java.launcher.pid is defined. duke@435: // Must do this before setting up other system properties, duke@435: // as some of them may depend on launcher type. duke@435: for (int index = 0; index < args->nOptions; index++) { duke@435: const JavaVMOption* option = args->options + index; duke@435: const char* tail; duke@435: duke@435: if (match_option(option, "-Dsun.java.launcher=", &tail)) { duke@435: process_java_launcher_argument(tail, option->extraInfo); duke@435: continue; duke@435: } duke@435: if (match_option(option, "-Dsun.java.launcher.pid=", &tail)) { duke@435: _sun_java_launcher_pid = atoi(tail); duke@435: continue; duke@435: } duke@435: } duke@435: } duke@435: duke@435: // Initialize system properties key and value. duke@435: void Arguments::init_system_properties() { duke@435: duke@435: PropertyList_add(&_system_properties, new SystemProperty("java.vm.specification.name", duke@435: "Java Virtual Machine Specification", false)); duke@435: PropertyList_add(&_system_properties, new SystemProperty("java.vm.version", VM_Version::vm_release(), false)); duke@435: PropertyList_add(&_system_properties, new SystemProperty("java.vm.name", VM_Version::vm_name(), false)); duke@435: PropertyList_add(&_system_properties, new SystemProperty("java.vm.info", VM_Version::vm_info_string(), true)); duke@435: duke@435: // following are JVMTI agent writeable properties. duke@435: // Properties values are set to NULL and they are duke@435: // os specific they are initialized in os::init_system_properties_values(). duke@435: _java_ext_dirs = new SystemProperty("java.ext.dirs", NULL, true); duke@435: _java_endorsed_dirs = new SystemProperty("java.endorsed.dirs", NULL, true); duke@435: _sun_boot_library_path = new SystemProperty("sun.boot.library.path", NULL, true); duke@435: _java_library_path = new SystemProperty("java.library.path", NULL, true); duke@435: _java_home = new SystemProperty("java.home", NULL, true); duke@435: _sun_boot_class_path = new SystemProperty("sun.boot.class.path", NULL, true); duke@435: duke@435: _java_class_path = new SystemProperty("java.class.path", "", true); duke@435: duke@435: // Add to System Property list. duke@435: PropertyList_add(&_system_properties, _java_ext_dirs); duke@435: PropertyList_add(&_system_properties, _java_endorsed_dirs); duke@435: PropertyList_add(&_system_properties, _sun_boot_library_path); duke@435: PropertyList_add(&_system_properties, _java_library_path); duke@435: PropertyList_add(&_system_properties, _java_home); duke@435: PropertyList_add(&_system_properties, _java_class_path); duke@435: PropertyList_add(&_system_properties, _sun_boot_class_path); duke@435: duke@435: // Set OS specific system properties values duke@435: os::init_system_properties_values(); duke@435: } duke@435: zgu@2219: zgu@2219: // Update/Initialize System properties after JDK version number is known zgu@2219: void Arguments::init_version_specific_system_properties() { kamg@2298: enum { bufsz = 16 }; kamg@2298: char buffer[bufsz]; kamg@2298: const char* spec_vendor = "Sun Microsystems Inc."; kamg@2298: uint32_t spec_version = 0; kamg@2298: kamg@2298: if (JDK_Version::is_gte_jdk17x_version()) { kamg@2298: spec_vendor = "Oracle Corporation"; kamg@2298: spec_version = JDK_Version::current().major_version(); kamg@2298: } kamg@2298: jio_snprintf(buffer, bufsz, "1." UINT32_FORMAT, spec_version); kamg@2298: kamg@2298: PropertyList_add(&_system_properties, kamg@2298: new SystemProperty("java.vm.specification.vendor", spec_vendor, false)); kamg@2298: PropertyList_add(&_system_properties, kamg@2298: new SystemProperty("java.vm.specification.version", buffer, false)); kamg@2298: PropertyList_add(&_system_properties, kamg@2298: new SystemProperty("java.vm.vendor", VM_Version::vm_vendor(), false)); zgu@2219: } zgu@2219: kamg@677: /** kamg@677: * Provide a slightly more user-friendly way of eliminating -XX flags. kamg@677: * When a flag is eliminated, it can be added to this list in order to kamg@677: * continue accepting this flag on the command-line, while issuing a warning kamg@677: * and ignoring the value. Once the JDK version reaches the 'accept_until' kamg@677: * limit, we flatly refuse to admit the existence of the flag. This allows kamg@677: * a flag to die correctly over JDK releases using HSX. kamg@677: */ kamg@677: typedef struct { kamg@677: const char* name; kamg@677: JDK_Version obsoleted_in; // when the flag went away kamg@677: JDK_Version accept_until; // which version to start denying the existence kamg@677: } ObsoleteFlag; duke@435: kamg@677: static ObsoleteFlag obsolete_jvm_flags[] = { kamg@677: { "UseTrainGC", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "UseSpecialLargeObjectHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "UseOversizedCarHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "TraceCarAllocation", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "PrintTrainGCProcessingStats", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "LogOfCarSpaceSize", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "OversizedCarThreshold", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "MinTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "DefaultTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "MaxTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "DelayTickAdjustment", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "ProcessingToTenuringRatio", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "MinTrainLength", JDK_Version::jdk(5), JDK_Version::jdk(7) }, kamg@677: { "AppendRatio", JDK_Version::jdk_update(6,10), JDK_Version::jdk(7) }, phh@1499: { "DefaultMaxRAM", JDK_Version::jdk_update(6,18), JDK_Version::jdk(7) }, phh@1499: { "DefaultInitialRAMFraction", phh@1499: JDK_Version::jdk_update(6,18), JDK_Version::jdk(7) }, tonyp@2061: { "UseDepthFirstScavengeOrder", tonyp@2061: JDK_Version::jdk_update(6,22), JDK_Version::jdk(7) }, ysr@2243: { "HandlePromotionFailure", ysr@2243: JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) }, ysr@2243: { "MaxLiveObjectEvacuationRatio", ysr@2243: JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) }, jcoomes@2644: { "ForceSharedSpaces", JDK_Version::jdk_update(6,25), JDK_Version::jdk(8) }, jcoomes@2783: { "UseParallelOldGCCompacting", jcoomes@2783: JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) }, jcoomes@2783: { "UseParallelDensePrefixUpdate", jcoomes@2783: JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) }, jcoomes@2783: { "UseParallelOldGCDensePrefix", jcoomes@2783: JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) }, jrose@2742: { "AllowTransitionalJSR292", JDK_Version::jdk(7), JDK_Version::jdk(8) }, jcoomes@2994: { "UseCompressedStrings", JDK_Version::jdk(7), JDK_Version::jdk(8) }, jcoomes@2994: #ifdef PRODUCT jcoomes@2994: { "DesiredMethodLimit", jcoomes@2994: JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) }, jcoomes@2994: #endif // PRODUCT kamg@677: { NULL, JDK_Version(0), JDK_Version(0) } kamg@677: }; kamg@677: kamg@677: // Returns true if the flag is obsolete and fits into the range specified kamg@677: // for being ignored. In the case that the flag is ignored, the 'version' kamg@677: // value is filled in with the version number when the flag became kamg@677: // obsolete so that that value can be displayed to the user. kamg@677: bool Arguments::is_newly_obsolete(const char *s, JDK_Version* version) { duke@435: int i = 0; kamg@677: assert(version != NULL, "Must provide a version buffer"); kamg@677: while (obsolete_jvm_flags[i].name != NULL) { kamg@677: const ObsoleteFlag& flag_status = obsolete_jvm_flags[i]; duke@435: // =xxx form duke@435: // [-|+] form kamg@677: if ((strncmp(flag_status.name, s, strlen(flag_status.name)) == 0) || duke@435: ((s[0] == '+' || s[0] == '-') && kamg@677: (strncmp(flag_status.name, &s[1], strlen(flag_status.name)) == 0))) { kamg@677: if (JDK_Version::current().compare(flag_status.accept_until) == -1) { kamg@677: *version = flag_status.obsoleted_in; kamg@677: return true; kamg@677: } duke@435: } duke@435: i++; duke@435: } duke@435: return false; duke@435: } duke@435: duke@435: // Constructs the system class path (aka boot class path) from the following duke@435: // components, in order: duke@435: // duke@435: // prefix // from -Xbootclasspath/p:... duke@435: // endorsed // the expansion of -Djava.endorsed.dirs=... duke@435: // base // from os::get_system_properties() or -Xbootclasspath= duke@435: // suffix // from -Xbootclasspath/a:... duke@435: // duke@435: // java.endorsed.dirs is a list of directories; any jar or zip files in the duke@435: // directories are added to the sysclasspath just before the base. duke@435: // duke@435: // This could be AllStatic, but it isn't needed after argument processing is duke@435: // complete. duke@435: class SysClassPath: public StackObj { duke@435: public: duke@435: SysClassPath(const char* base); duke@435: ~SysClassPath(); duke@435: duke@435: inline void set_base(const char* base); duke@435: inline void add_prefix(const char* prefix); phh@966: inline void add_suffix_to_prefix(const char* suffix); duke@435: inline void add_suffix(const char* suffix); duke@435: inline void reset_path(const char* base); duke@435: duke@435: // Expand the jar/zip files in each directory listed by the java.endorsed.dirs duke@435: // property. Must be called after all command-line arguments have been duke@435: // processed (in particular, -Djava.endorsed.dirs=...) and before calling duke@435: // combined_path(). duke@435: void expand_endorsed(); duke@435: duke@435: inline const char* get_base() const { return _items[_scp_base]; } duke@435: inline const char* get_prefix() const { return _items[_scp_prefix]; } duke@435: inline const char* get_suffix() const { return _items[_scp_suffix]; } duke@435: inline const char* get_endorsed() const { return _items[_scp_endorsed]; } duke@435: duke@435: // Combine all the components into a single c-heap-allocated string; caller duke@435: // must free the string if/when no longer needed. duke@435: char* combined_path(); duke@435: duke@435: private: duke@435: // Utility routines. duke@435: static char* add_to_path(const char* path, const char* str, bool prepend); duke@435: static char* add_jars_to_path(char* path, const char* directory); duke@435: duke@435: inline void reset_item_at(int index); duke@435: duke@435: // Array indices for the items that make up the sysclasspath. All except the duke@435: // base are allocated in the C heap and freed by this class. duke@435: enum { duke@435: _scp_prefix, // from -Xbootclasspath/p:... duke@435: _scp_endorsed, // the expansion of -Djava.endorsed.dirs=... duke@435: _scp_base, // the default sysclasspath duke@435: _scp_suffix, // from -Xbootclasspath/a:... duke@435: _scp_nitems // the number of items, must be last. duke@435: }; duke@435: duke@435: const char* _items[_scp_nitems]; duke@435: DEBUG_ONLY(bool _expansion_done;) duke@435: }; duke@435: duke@435: SysClassPath::SysClassPath(const char* base) { duke@435: memset(_items, 0, sizeof(_items)); duke@435: _items[_scp_base] = base; duke@435: DEBUG_ONLY(_expansion_done = false;) duke@435: } duke@435: duke@435: SysClassPath::~SysClassPath() { duke@435: // Free everything except the base. duke@435: for (int i = 0; i < _scp_nitems; ++i) { duke@435: if (i != _scp_base) reset_item_at(i); duke@435: } duke@435: DEBUG_ONLY(_expansion_done = false;) duke@435: } duke@435: duke@435: inline void SysClassPath::set_base(const char* base) { duke@435: _items[_scp_base] = base; duke@435: } duke@435: duke@435: inline void SysClassPath::add_prefix(const char* prefix) { duke@435: _items[_scp_prefix] = add_to_path(_items[_scp_prefix], prefix, true); duke@435: } duke@435: phh@966: inline void SysClassPath::add_suffix_to_prefix(const char* suffix) { phh@966: _items[_scp_prefix] = add_to_path(_items[_scp_prefix], suffix, false); phh@966: } phh@966: duke@435: inline void SysClassPath::add_suffix(const char* suffix) { duke@435: _items[_scp_suffix] = add_to_path(_items[_scp_suffix], suffix, false); duke@435: } duke@435: duke@435: inline void SysClassPath::reset_item_at(int index) { duke@435: assert(index < _scp_nitems && index != _scp_base, "just checking"); duke@435: if (_items[index] != NULL) { duke@435: FREE_C_HEAP_ARRAY(char, _items[index]); duke@435: _items[index] = NULL; duke@435: } duke@435: } duke@435: duke@435: inline void SysClassPath::reset_path(const char* base) { duke@435: // Clear the prefix and suffix. duke@435: reset_item_at(_scp_prefix); duke@435: reset_item_at(_scp_suffix); duke@435: set_base(base); duke@435: } duke@435: duke@435: //------------------------------------------------------------------------------ duke@435: duke@435: void SysClassPath::expand_endorsed() { duke@435: assert(_items[_scp_endorsed] == NULL, "can only be called once."); duke@435: duke@435: const char* path = Arguments::get_property("java.endorsed.dirs"); duke@435: if (path == NULL) { duke@435: path = Arguments::get_endorsed_dir(); duke@435: assert(path != NULL, "no default for java.endorsed.dirs"); duke@435: } duke@435: duke@435: char* expanded_path = NULL; duke@435: const char separator = *os::path_separator(); duke@435: const char* const end = path + strlen(path); duke@435: while (path < end) { duke@435: const char* tmp_end = strchr(path, separator); duke@435: if (tmp_end == NULL) { duke@435: expanded_path = add_jars_to_path(expanded_path, path); duke@435: path = end; duke@435: } else { duke@435: char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1); duke@435: memcpy(dirpath, path, tmp_end - path); duke@435: dirpath[tmp_end - path] = '\0'; duke@435: expanded_path = add_jars_to_path(expanded_path, dirpath); duke@435: FREE_C_HEAP_ARRAY(char, dirpath); duke@435: path = tmp_end + 1; duke@435: } duke@435: } duke@435: _items[_scp_endorsed] = expanded_path; duke@435: DEBUG_ONLY(_expansion_done = true;) duke@435: } duke@435: duke@435: // Combine the bootclasspath elements, some of which may be null, into a single duke@435: // c-heap-allocated string. duke@435: char* SysClassPath::combined_path() { duke@435: assert(_items[_scp_base] != NULL, "empty default sysclasspath"); duke@435: assert(_expansion_done, "must call expand_endorsed() first."); duke@435: duke@435: size_t lengths[_scp_nitems]; duke@435: size_t total_len = 0; duke@435: duke@435: const char separator = *os::path_separator(); duke@435: duke@435: // Get the lengths. duke@435: int i; duke@435: for (i = 0; i < _scp_nitems; ++i) { duke@435: if (_items[i] != NULL) { duke@435: lengths[i] = strlen(_items[i]); duke@435: // Include space for the separator char (or a NULL for the last item). duke@435: total_len += lengths[i] + 1; duke@435: } duke@435: } duke@435: assert(total_len > 0, "empty sysclasspath not allowed"); duke@435: duke@435: // Copy the _items to a single string. duke@435: char* cp = NEW_C_HEAP_ARRAY(char, total_len); duke@435: char* cp_tmp = cp; duke@435: for (i = 0; i < _scp_nitems; ++i) { duke@435: if (_items[i] != NULL) { duke@435: memcpy(cp_tmp, _items[i], lengths[i]); duke@435: cp_tmp += lengths[i]; duke@435: *cp_tmp++ = separator; duke@435: } duke@435: } duke@435: *--cp_tmp = '\0'; // Replace the extra separator. duke@435: return cp; duke@435: } duke@435: duke@435: // Note: path must be c-heap-allocated (or NULL); it is freed if non-null. duke@435: char* duke@435: SysClassPath::add_to_path(const char* path, const char* str, bool prepend) { duke@435: char *cp; duke@435: duke@435: assert(str != NULL, "just checking"); duke@435: if (path == NULL) { duke@435: size_t len = strlen(str) + 1; duke@435: cp = NEW_C_HEAP_ARRAY(char, len); duke@435: memcpy(cp, str, len); // copy the trailing null duke@435: } else { duke@435: const char separator = *os::path_separator(); duke@435: size_t old_len = strlen(path); duke@435: size_t str_len = strlen(str); duke@435: size_t len = old_len + str_len + 2; duke@435: duke@435: if (prepend) { duke@435: cp = NEW_C_HEAP_ARRAY(char, len); duke@435: char* cp_tmp = cp; duke@435: memcpy(cp_tmp, str, str_len); duke@435: cp_tmp += str_len; duke@435: *cp_tmp = separator; duke@435: memcpy(++cp_tmp, path, old_len + 1); // copy the trailing null duke@435: FREE_C_HEAP_ARRAY(char, path); duke@435: } else { duke@435: cp = REALLOC_C_HEAP_ARRAY(char, path, len); duke@435: char* cp_tmp = cp + old_len; duke@435: *cp_tmp = separator; duke@435: memcpy(++cp_tmp, str, str_len + 1); // copy the trailing null duke@435: } duke@435: } duke@435: return cp; duke@435: } duke@435: duke@435: // Scan the directory and append any jar or zip files found to path. duke@435: // Note: path must be c-heap-allocated (or NULL); it is freed if non-null. duke@435: char* SysClassPath::add_jars_to_path(char* path, const char* directory) { duke@435: DIR* dir = os::opendir(directory); duke@435: if (dir == NULL) return path; duke@435: duke@435: char dir_sep[2] = { '\0', '\0' }; duke@435: size_t directory_len = strlen(directory); duke@435: const char fileSep = *os::file_separator(); duke@435: if (directory[directory_len - 1] != fileSep) dir_sep[0] = fileSep; duke@435: duke@435: /* Scan the directory for jars/zips, appending them to path. */ duke@435: struct dirent *entry; duke@435: char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory)); duke@435: while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) { duke@435: const char* name = entry->d_name; duke@435: const char* ext = name + strlen(name) - 4; duke@435: bool isJarOrZip = ext > name && duke@435: (os::file_name_strcmp(ext, ".jar") == 0 || duke@435: os::file_name_strcmp(ext, ".zip") == 0); duke@435: if (isJarOrZip) { duke@435: char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name)); duke@435: sprintf(jarpath, "%s%s%s", directory, dir_sep, name); duke@435: path = add_to_path(path, jarpath, false); duke@435: FREE_C_HEAP_ARRAY(char, jarpath); duke@435: } duke@435: } duke@435: FREE_C_HEAP_ARRAY(char, dbuf); duke@435: os::closedir(dir); duke@435: return path; duke@435: } duke@435: duke@435: // Parses a memory size specification string. swamyv@924: static bool atomull(const char *s, julong* result) { swamyv@924: julong n = 0; swamyv@924: int args_read = sscanf(s, os::julong_format_specifier(), &n); duke@435: if (args_read != 1) { duke@435: return false; duke@435: } duke@435: while (*s != '\0' && isdigit(*s)) { duke@435: s++; duke@435: } duke@435: // 4705540: illegal if more characters are found after the first non-digit duke@435: if (strlen(s) > 1) { duke@435: return false; duke@435: } duke@435: switch (*s) { duke@435: case 'T': case 't': duke@435: *result = n * G * K; swamyv@924: // Check for overflow. swamyv@924: if (*result/((julong)G * K) != n) return false; duke@435: return true; duke@435: case 'G': case 'g': duke@435: *result = n * G; swamyv@924: if (*result/G != n) return false; duke@435: return true; duke@435: case 'M': case 'm': duke@435: *result = n * M; swamyv@924: if (*result/M != n) return false; duke@435: return true; duke@435: case 'K': case 'k': duke@435: *result = n * K; swamyv@924: if (*result/K != n) return false; duke@435: return true; duke@435: case '\0': duke@435: *result = n; duke@435: return true; duke@435: default: duke@435: return false; duke@435: } duke@435: } duke@435: swamyv@924: Arguments::ArgsRange Arguments::check_memory_size(julong size, julong min_size) { duke@435: if (size < min_size) return arg_too_small; duke@435: // Check that size will fit in a size_t (only relevant on 32-bit) swamyv@924: if (size > max_uintx) return arg_too_big; duke@435: return arg_in_range; duke@435: } duke@435: duke@435: // Describe an argument out of range error duke@435: void Arguments::describe_range_error(ArgsRange errcode) { duke@435: switch(errcode) { duke@435: case arg_too_big: duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "The specified size exceeds the maximum " duke@435: "representable size.\n"); duke@435: break; duke@435: case arg_too_small: duke@435: case arg_unreadable: duke@435: case arg_in_range: duke@435: // do nothing for now duke@435: break; duke@435: default: duke@435: ShouldNotReachHere(); duke@435: } duke@435: } duke@435: duke@435: static bool set_bool_flag(char* name, bool value, FlagValueOrigin origin) { duke@435: return CommandLineFlags::boolAtPut(name, &value, origin); duke@435: } duke@435: duke@435: static bool set_fp_numeric_flag(char* name, char* value, FlagValueOrigin origin) { duke@435: double v; duke@435: if (sscanf(value, "%lf", &v) != 1) { duke@435: return false; duke@435: } duke@435: duke@435: if (CommandLineFlags::doubleAtPut(name, &v, origin)) { duke@435: return true; duke@435: } duke@435: return false; duke@435: } duke@435: duke@435: static bool set_numeric_flag(char* name, char* value, FlagValueOrigin origin) { swamyv@924: julong v; duke@435: intx intx_v; duke@435: bool is_neg = false; swamyv@924: // Check the sign first since atomull() parses only unsigned values. duke@435: if (*value == '-') { duke@435: if (!CommandLineFlags::intxAt(name, &intx_v)) { duke@435: return false; duke@435: } duke@435: value++; duke@435: is_neg = true; duke@435: } swamyv@924: if (!atomull(value, &v)) { duke@435: return false; duke@435: } duke@435: intx_v = (intx) v; duke@435: if (is_neg) { duke@435: intx_v = -intx_v; duke@435: } duke@435: if (CommandLineFlags::intxAtPut(name, &intx_v, origin)) { duke@435: return true; duke@435: } duke@435: uintx uintx_v = (uintx) v; duke@435: if (!is_neg && CommandLineFlags::uintxAtPut(name, &uintx_v, origin)) { duke@435: return true; duke@435: } phh@1499: uint64_t uint64_t_v = (uint64_t) v; phh@1499: if (!is_neg && CommandLineFlags::uint64_tAtPut(name, &uint64_t_v, origin)) { phh@1499: return true; phh@1499: } duke@435: return false; duke@435: } duke@435: duke@435: static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) { duke@435: if (!CommandLineFlags::ccstrAtPut(name, &value, origin)) return false; duke@435: // Contract: CommandLineFlags always returns a pointer that needs freeing. duke@435: FREE_C_HEAP_ARRAY(char, value); duke@435: return true; duke@435: } duke@435: duke@435: static bool append_to_string_flag(char* name, const char* new_value, FlagValueOrigin origin) { duke@435: const char* old_value = ""; duke@435: if (!CommandLineFlags::ccstrAt(name, &old_value)) return false; duke@435: size_t old_len = old_value != NULL ? strlen(old_value) : 0; duke@435: size_t new_len = strlen(new_value); duke@435: const char* value; duke@435: char* free_this_too = NULL; duke@435: if (old_len == 0) { duke@435: value = new_value; duke@435: } else if (new_len == 0) { duke@435: value = old_value; duke@435: } else { duke@435: char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1); duke@435: // each new setting adds another LINE to the switch: duke@435: sprintf(buf, "%s\n%s", old_value, new_value); duke@435: value = buf; duke@435: free_this_too = buf; duke@435: } duke@435: (void) CommandLineFlags::ccstrAtPut(name, &value, origin); duke@435: // CommandLineFlags always returns a pointer that needs freeing. duke@435: FREE_C_HEAP_ARRAY(char, value); duke@435: if (free_this_too != NULL) { duke@435: // CommandLineFlags made its own copy, so I must delete my own temp. buffer. duke@435: FREE_C_HEAP_ARRAY(char, free_this_too); duke@435: } duke@435: return true; duke@435: } duke@435: duke@435: bool Arguments::parse_argument(const char* arg, FlagValueOrigin origin) { duke@435: duke@435: // range of acceptable characters spelled out for portability reasons duke@435: #define NAME_RANGE "[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]" duke@435: #define BUFLEN 255 duke@435: char name[BUFLEN+1]; duke@435: char dummy; duke@435: duke@435: if (sscanf(arg, "-%" XSTR(BUFLEN) NAME_RANGE "%c", name, &dummy) == 1) { duke@435: return set_bool_flag(name, false, origin); duke@435: } duke@435: if (sscanf(arg, "+%" XSTR(BUFLEN) NAME_RANGE "%c", name, &dummy) == 1) { duke@435: return set_bool_flag(name, true, origin); duke@435: } duke@435: duke@435: char punct; duke@435: if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "%c", name, &punct) == 2 && punct == '=') { duke@435: const char* value = strchr(arg, '=') + 1; duke@435: Flag* flag = Flag::find_flag(name, strlen(name)); duke@435: if (flag != NULL && flag->is_ccstr()) { duke@435: if (flag->ccstr_accumulates()) { duke@435: return append_to_string_flag(name, value, origin); duke@435: } else { duke@435: if (value[0] == '\0') { duke@435: value = NULL; duke@435: } duke@435: return set_string_flag(name, value, origin); duke@435: } duke@435: } duke@435: } duke@435: duke@435: if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE ":%c", name, &punct) == 2 && punct == '=') { duke@435: const char* value = strchr(arg, '=') + 1; duke@435: // -XX:Foo:=xxx will reset the string flag to the given value. duke@435: if (value[0] == '\0') { duke@435: value = NULL; duke@435: } duke@435: return set_string_flag(name, value, origin); duke@435: } duke@435: duke@435: #define SIGNED_FP_NUMBER_RANGE "[-0123456789.]" duke@435: #define SIGNED_NUMBER_RANGE "[-0123456789]" duke@435: #define NUMBER_RANGE "[0123456789]" duke@435: char value[BUFLEN + 1]; duke@435: char value2[BUFLEN + 1]; duke@435: if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) SIGNED_NUMBER_RANGE "." "%" XSTR(BUFLEN) NUMBER_RANGE "%c", name, value, value2, &dummy) == 3) { duke@435: // Looks like a floating-point number -- try again with more lenient format string duke@435: if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) SIGNED_FP_NUMBER_RANGE "%c", name, value, &dummy) == 2) { duke@435: return set_fp_numeric_flag(name, value, origin); duke@435: } duke@435: } duke@435: duke@435: #define VALUE_RANGE "[-kmgtKMGT0123456789]" duke@435: if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "=" "%" XSTR(BUFLEN) VALUE_RANGE "%c", name, value, &dummy) == 2) { duke@435: return set_numeric_flag(name, value, origin); duke@435: } duke@435: duke@435: return false; duke@435: } duke@435: duke@435: void Arguments::add_string(char*** bldarray, int* count, const char* arg) { duke@435: assert(bldarray != NULL, "illegal argument"); duke@435: duke@435: if (arg == NULL) { duke@435: return; duke@435: } duke@435: duke@435: int index = *count; duke@435: duke@435: // expand the array and add arg to the last element duke@435: (*count)++; duke@435: if (*bldarray == NULL) { duke@435: *bldarray = NEW_C_HEAP_ARRAY(char*, *count); duke@435: } else { duke@435: *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, *count); duke@435: } duke@435: (*bldarray)[index] = strdup(arg); duke@435: } duke@435: duke@435: void Arguments::build_jvm_args(const char* arg) { duke@435: add_string(&_jvm_args_array, &_num_jvm_args, arg); duke@435: } duke@435: duke@435: void Arguments::build_jvm_flags(const char* arg) { duke@435: add_string(&_jvm_flags_array, &_num_jvm_flags, arg); duke@435: } duke@435: duke@435: // utility function to return a string that concatenates all duke@435: // strings in a given char** array duke@435: const char* Arguments::build_resource_string(char** args, int count) { duke@435: if (args == NULL || count == 0) { duke@435: return NULL; duke@435: } duke@435: size_t length = strlen(args[0]) + 1; // add 1 for the null terminator duke@435: for (int i = 1; i < count; i++) { duke@435: length += strlen(args[i]) + 1; // add 1 for a space duke@435: } duke@435: char* s = NEW_RESOURCE_ARRAY(char, length); duke@435: strcpy(s, args[0]); duke@435: for (int j = 1; j < count; j++) { duke@435: strcat(s, " "); duke@435: strcat(s, args[j]); duke@435: } duke@435: return (const char*) s; duke@435: } duke@435: duke@435: void Arguments::print_on(outputStream* st) { duke@435: st->print_cr("VM Arguments:"); duke@435: if (num_jvm_flags() > 0) { duke@435: st->print("jvm_flags: "); print_jvm_flags_on(st); duke@435: } duke@435: if (num_jvm_args() > 0) { duke@435: st->print("jvm_args: "); print_jvm_args_on(st); duke@435: } duke@435: st->print_cr("java_command: %s", java_command() ? java_command() : ""); duke@435: st->print_cr("Launcher Type: %s", _sun_java_launcher); duke@435: } duke@435: duke@435: void Arguments::print_jvm_flags_on(outputStream* st) { duke@435: if (_num_jvm_flags > 0) { duke@435: for (int i=0; i < _num_jvm_flags; i++) { duke@435: st->print("%s ", _jvm_flags_array[i]); duke@435: } duke@435: st->print_cr(""); duke@435: } duke@435: } duke@435: duke@435: void Arguments::print_jvm_args_on(outputStream* st) { duke@435: if (_num_jvm_args > 0) { duke@435: for (int i=0; i < _num_jvm_args; i++) { duke@435: st->print("%s ", _jvm_args_array[i]); duke@435: } duke@435: st->print_cr(""); duke@435: } duke@435: } duke@435: kamg@677: bool Arguments::process_argument(const char* arg, kamg@677: jboolean ignore_unrecognized, FlagValueOrigin origin) { kamg@677: kamg@677: JDK_Version since = JDK_Version(); duke@435: jcoomes@2782: if (parse_argument(arg, origin) || ignore_unrecognized) { jcoomes@2782: return true; duke@435: } jcoomes@2782: jcoomes@2782: const char * const argname = *arg == '+' || *arg == '-' ? arg + 1 : arg; jcoomes@2782: if (is_newly_obsolete(arg, &since)) { jcoomes@2782: char version[256]; jcoomes@2782: since.to_string(version, sizeof(version)); jcoomes@2782: warning("ignoring option %s; support was removed in %s", argname, version); jcoomes@2782: return true; jcoomes@2782: } jcoomes@2782: jcoomes@2782: jio_fprintf(defaultStream::error_stream(), jcoomes@2782: "Unrecognized VM option '%s'\n", argname); jcoomes@2782: // allow for commandline "commenting out" options like -XX:#+Verbose jcoomes@2782: return arg[0] == '#'; duke@435: } duke@435: duke@435: bool Arguments::process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized) { duke@435: FILE* stream = fopen(file_name, "rb"); duke@435: if (stream == NULL) { duke@435: if (should_exist) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Could not open settings file %s\n", file_name); duke@435: return false; duke@435: } else { duke@435: return true; duke@435: } duke@435: } duke@435: duke@435: char token[1024]; duke@435: int pos = 0; duke@435: duke@435: bool in_white_space = true; duke@435: bool in_comment = false; duke@435: bool in_quote = false; duke@435: char quote_c = 0; duke@435: bool result = true; duke@435: duke@435: int c = getc(stream); duke@435: while(c != EOF) { duke@435: if (in_white_space) { duke@435: if (in_comment) { duke@435: if (c == '\n') in_comment = false; duke@435: } else { duke@435: if (c == '#') in_comment = true; duke@435: else if (!isspace(c)) { duke@435: in_white_space = false; duke@435: token[pos++] = c; duke@435: } duke@435: } duke@435: } else { duke@435: if (c == '\n' || (!in_quote && isspace(c))) { duke@435: // token ends at newline, or at unquoted whitespace duke@435: // this allows a way to include spaces in string-valued options duke@435: token[pos] = '\0'; duke@435: logOption(token); duke@435: result &= process_argument(token, ignore_unrecognized, CONFIG_FILE); duke@435: build_jvm_flags(token); duke@435: pos = 0; duke@435: in_white_space = true; duke@435: in_quote = false; duke@435: } else if (!in_quote && (c == '\'' || c == '"')) { duke@435: in_quote = true; duke@435: quote_c = c; duke@435: } else if (in_quote && (c == quote_c)) { duke@435: in_quote = false; duke@435: } else { duke@435: token[pos++] = c; duke@435: } duke@435: } duke@435: c = getc(stream); duke@435: } duke@435: if (pos > 0) { duke@435: token[pos] = '\0'; duke@435: result &= process_argument(token, ignore_unrecognized, CONFIG_FILE); duke@435: build_jvm_flags(token); duke@435: } duke@435: fclose(stream); duke@435: return result; duke@435: } duke@435: duke@435: //============================================================================================================= duke@435: // Parsing of properties (-D) duke@435: duke@435: const char* Arguments::get_property(const char* key) { duke@435: return PropertyList_get_value(system_properties(), key); duke@435: } duke@435: duke@435: bool Arguments::add_property(const char* prop) { duke@435: const char* eq = strchr(prop, '='); duke@435: char* key; duke@435: // ns must be static--its address may be stored in a SystemProperty object. duke@435: const static char ns[1] = {0}; duke@435: char* value = (char *)ns; duke@435: duke@435: size_t key_len = (eq == NULL) ? strlen(prop) : (eq - prop); duke@435: key = AllocateHeap(key_len + 1, "add_property"); duke@435: strncpy(key, prop, key_len); duke@435: key[key_len] = '\0'; duke@435: duke@435: if (eq != NULL) { duke@435: size_t value_len = strlen(prop) - key_len - 1; duke@435: value = AllocateHeap(value_len + 1, "add_property"); duke@435: strncpy(value, &prop[key_len + 1], value_len + 1); duke@435: } duke@435: duke@435: if (strcmp(key, "java.compiler") == 0) { duke@435: process_java_compiler_argument(value); duke@435: FreeHeap(key); duke@435: if (eq != NULL) { duke@435: FreeHeap(value); duke@435: } duke@435: return true; phh@1126: } else if (strcmp(key, "sun.java.command") == 0) { duke@435: _java_command = value; duke@435: kevinw@2449: // Record value in Arguments, but let it get passed to Java. phh@1126: } else if (strcmp(key, "sun.java.launcher.pid") == 0) { duke@435: // launcher.pid property is private and is processed duke@435: // in process_sun_java_launcher_properties(); duke@435: // the sun.java.launcher property is passed on to the java application duke@435: FreeHeap(key); duke@435: if (eq != NULL) { duke@435: FreeHeap(value); duke@435: } duke@435: return true; phh@1126: } else if (strcmp(key, "java.vendor.url.bug") == 0) { duke@435: // save it in _java_vendor_url_bug, so JVM fatal error handler can access duke@435: // its value without going through the property list or making a Java call. duke@435: _java_vendor_url_bug = value; phh@1126: } else if (strcmp(key, "sun.boot.library.path") == 0) { phh@1126: PropertyList_unique_add(&_system_properties, key, value, true); phh@1126: return true; duke@435: } duke@435: // Create new property and add at the end of the list duke@435: PropertyList_unique_add(&_system_properties, key, value); duke@435: return true; duke@435: } duke@435: duke@435: //=========================================================================================================== duke@435: // Setting int/mixed/comp mode flags duke@435: duke@435: void Arguments::set_mode_flags(Mode mode) { duke@435: // Set up default values for all flags. duke@435: // If you add a flag to any of the branches below, duke@435: // add a default value for it here. duke@435: set_java_compiler(false); duke@435: _mode = mode; duke@435: duke@435: // Ensure Agent_OnLoad has the correct initial values. duke@435: // This may not be the final mode; mode may change later in onload phase. duke@435: PropertyList_unique_add(&_system_properties, "java.vm.info", dholmes@2858: (char*)VM_Version::vm_info_string(), false); duke@435: duke@435: UseInterpreter = true; duke@435: UseCompiler = true; duke@435: UseLoopCounter = true; duke@435: never@2740: #ifndef ZERO never@2740: // Turn these off for mixed and comp. Leave them on for Zero. never@2740: if (FLAG_IS_DEFAULT(UseFastAccessorMethods)) { never@2873: UseFastAccessorMethods = (mode == _int); never@2740: } never@2740: if (FLAG_IS_DEFAULT(UseFastEmptyMethods)) { never@2873: UseFastEmptyMethods = (mode == _int); never@2740: } never@2740: #endif never@2740: duke@435: // Default values may be platform/compiler dependent - duke@435: // use the saved values duke@435: ClipInlining = Arguments::_ClipInlining; duke@435: AlwaysCompileLoopMethods = Arguments::_AlwaysCompileLoopMethods; duke@435: UseOnStackReplacement = Arguments::_UseOnStackReplacement; duke@435: BackgroundCompilation = Arguments::_BackgroundCompilation; duke@435: duke@435: // Change from defaults based on mode duke@435: switch (mode) { duke@435: default: duke@435: ShouldNotReachHere(); duke@435: break; duke@435: case _int: duke@435: UseCompiler = false; duke@435: UseLoopCounter = false; duke@435: AlwaysCompileLoopMethods = false; duke@435: UseOnStackReplacement = false; duke@435: break; duke@435: case _mixed: duke@435: // same as default duke@435: break; duke@435: case _comp: duke@435: UseInterpreter = false; duke@435: BackgroundCompilation = false; duke@435: ClipInlining = false; duke@435: break; duke@435: } duke@435: } duke@435: duke@435: // Conflict: required to use shared spaces (-Xshare:on), but duke@435: // incompatible command line options were chosen. duke@435: duke@435: static void no_shared_spaces() { duke@435: if (RequireSharedSpaces) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Class data sharing is inconsistent with other specified options.\n"); duke@435: vm_exit_during_initialization("Unable to use shared archive.", NULL); duke@435: } else { duke@435: FLAG_SET_DEFAULT(UseSharedSpaces, false); duke@435: } duke@435: } duke@435: iveresov@2138: void Arguments::set_tiered_flags() { iveresov@2630: // With tiered, set default policy to AdvancedThresholdPolicy, which is 3. iveresov@2138: if (FLAG_IS_DEFAULT(CompilationPolicyChoice)) { iveresov@2630: FLAG_SET_DEFAULT(CompilationPolicyChoice, 3); iveresov@2138: } iveresov@2138: if (CompilationPolicyChoice < 2) { iveresov@2138: vm_exit_during_initialization( iveresov@2138: "Incompatible compilation policy selected", NULL); iveresov@2138: } iveresov@2246: // Increase the code cache size - tiered compiles a lot more. iveresov@2138: if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) { iveresov@2138: FLAG_SET_DEFAULT(ReservedCodeCacheSize, ReservedCodeCacheSize * 2); iveresov@2138: } iveresov@2138: } iveresov@2138: ysr@1580: #ifndef KERNEL duke@435: // If the user has chosen ParallelGCThreads > 0, we set UseParNewGC duke@435: // if it's not explictly set or unset. If the user has chosen duke@435: // UseParNewGC and not explicitly set ParallelGCThreads we duke@435: // set it, unless this is a single cpu machine. duke@435: void Arguments::set_parnew_gc_flags() { phh@1499: assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC && !UseG1GC, ysr@777: "control point invariant"); ysr@777: assert(UseParNewGC, "Error"); duke@435: jmasa@445: // Turn off AdaptiveSizePolicy by default for parnew until it is jmasa@445: // complete. ysr@777: if (FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) { jmasa@445: FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false); jmasa@445: } jmasa@445: ysr@777: if (ParallelGCThreads == 0) { jmasa@445: FLAG_SET_DEFAULT(ParallelGCThreads, jmasa@445: Abstract_VM_Version::parallel_worker_threads()); phh@1499: if (ParallelGCThreads == 1) { duke@435: FLAG_SET_DEFAULT(UseParNewGC, false); phh@1499: FLAG_SET_DEFAULT(ParallelGCThreads, 0); duke@435: } duke@435: } phh@1499: if (UseParNewGC) { phh@1499: // CDS doesn't work with ParNew yet duke@435: no_shared_spaces(); duke@435: ysr@1130: // By default YoungPLABSize and OldPLABSize are set to 4096 and 1024 respectively, duke@435: // these settings are default for Parallel Scavenger. For ParNew+Tenured configuration duke@435: // we set them to 1024 and 1024. duke@435: // See CR 6362902. duke@435: if (FLAG_IS_DEFAULT(YoungPLABSize)) { duke@435: FLAG_SET_DEFAULT(YoungPLABSize, (intx)1024); duke@435: } duke@435: if (FLAG_IS_DEFAULT(OldPLABSize)) { duke@435: FLAG_SET_DEFAULT(OldPLABSize, (intx)1024); duke@435: } duke@435: phh@1499: // AlwaysTenure flag should make ParNew promote all at first collection. duke@435: // See CR 6362902. duke@435: if (AlwaysTenure) { duke@435: FLAG_SET_CMDLINE(intx, MaxTenuringThreshold, 0); duke@435: } ysr@1130: // When using compressed oops, we use local overflow stacks, ysr@1130: // rather than using a global overflow list chained through ysr@1130: // the klass word of the object's pre-image. ysr@1130: if (UseCompressedOops && !ParGCUseLocalOverflow) { ysr@1130: if (!FLAG_IS_DEFAULT(ParGCUseLocalOverflow)) { ysr@1130: warning("Forcing +ParGCUseLocalOverflow: needed if using compressed references"); ysr@1130: } ysr@1130: FLAG_SET_DEFAULT(ParGCUseLocalOverflow, true); ysr@1130: } ysr@1130: assert(ParGCUseLocalOverflow || !UseCompressedOops, "Error"); duke@435: } duke@435: } duke@435: duke@435: // Adjust some sizes to suit CMS and/or ParNew needs; these work well on duke@435: // sparc/solaris for certain applications, but would gain from duke@435: // further optimization and tuning efforts, and would almost duke@435: // certainly gain from analysis of platform and environment. duke@435: void Arguments::set_cms_and_parnew_gc_flags() { phh@1499: assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC, "Error"); jmasa@445: assert(UseConcMarkSweepGC, "CMS is expected to be on here"); jmasa@445: duke@435: // If we are using CMS, we prefer to UseParNewGC, duke@435: // unless explicitly forbidden. ysr@777: if (FLAG_IS_DEFAULT(UseParNewGC)) { jmasa@445: FLAG_SET_ERGO(bool, UseParNewGC, true); duke@435: } duke@435: duke@435: // Turn off AdaptiveSizePolicy by default for cms until it is jmasa@445: // complete. jmasa@445: if (FLAG_IS_DEFAULT(UseAdaptiveSizePolicy)) { duke@435: FLAG_SET_DEFAULT(UseAdaptiveSizePolicy, false); duke@435: } duke@435: duke@435: // In either case, adjust ParallelGCThreads and/or UseParNewGC duke@435: // as needed. jmasa@445: if (UseParNewGC) { jmasa@445: set_parnew_gc_flags(); duke@435: } duke@435: ysr@2650: // MaxHeapSize is aligned down in collectorPolicy ysr@2650: size_t max_heap = align_size_down(MaxHeapSize, ysr@2650: CardTableRS::ct_max_alignment_constraint()); ysr@2650: duke@435: // Now make adjustments for CMS ysr@2650: intx tenuring_default = (intx)6; ysr@2650: size_t young_gen_per_worker = CMSYoungGenPerWorker; ysr@2650: ysr@2650: // Preferred young gen size for "short" pauses: ysr@2650: // upper bound depends on # of threads and NewRatio. duke@435: const uintx parallel_gc_threads = duke@435: (ParallelGCThreads == 0 ? 1 : ParallelGCThreads); duke@435: const size_t preferred_max_new_size_unaligned = ysr@2650: MIN2(max_heap/(NewRatio+1), ScaleForWordSize(young_gen_per_worker * parallel_gc_threads)); ysr@2650: size_t preferred_max_new_size = duke@435: align_size_up(preferred_max_new_size_unaligned, os::vm_page_size()); duke@435: duke@435: // Unless explicitly requested otherwise, size young gen ysr@2650: // for "short" pauses ~ CMSYoungGenPerWorker*ParallelGCThreads jmasa@1321: jmasa@1321: // If either MaxNewSize or NewRatio is set on the command line, jmasa@1321: // assume the user is trying to set the size of the young gen. jmasa@1321: if (FLAG_IS_DEFAULT(MaxNewSize) && FLAG_IS_DEFAULT(NewRatio)) { jmasa@1321: jmasa@1321: // Set MaxNewSize to our calculated preferred_max_new_size unless jmasa@1321: // NewSize was set on the command line and it is larger than jmasa@1321: // preferred_max_new_size. duke@435: if (!FLAG_IS_DEFAULT(NewSize)) { // NewSize explicitly set at command-line jmasa@448: FLAG_SET_ERGO(uintx, MaxNewSize, MAX2(NewSize, preferred_max_new_size)); duke@435: } else { jmasa@448: FLAG_SET_ERGO(uintx, MaxNewSize, preferred_max_new_size); duke@435: } phh@1499: if (PrintGCDetails && Verbose) { jmasa@448: // Too early to use gclog_or_tty ysr@2650: tty->print_cr("CMS ergo set MaxNewSize: " SIZE_FORMAT, MaxNewSize); jmasa@1321: } jmasa@1321: jmasa@1321: // Code along this path potentially sets NewSize and OldSize jmasa@1321: ysr@2650: assert(max_heap >= InitialHeapSize, "Error"); ysr@2650: assert(max_heap >= NewSize, "Error"); duke@435: phh@1499: if (PrintGCDetails && Verbose) { jmasa@448: // Too early to use gclog_or_tty jmasa@448: tty->print_cr("CMS set min_heap_size: " SIZE_FORMAT jmasa@448: " initial_heap_size: " SIZE_FORMAT jmasa@448: " max_heap: " SIZE_FORMAT, phh@1499: min_heap_size(), InitialHeapSize, max_heap); jmasa@448: } ysr@2650: size_t min_new = preferred_max_new_size; ysr@2650: if (FLAG_IS_CMDLINE(NewSize)) { ysr@2650: min_new = NewSize; ysr@2650: } ysr@2650: if (max_heap > min_new && min_heap_size() > min_new) { duke@435: // Unless explicitly requested otherwise, make young gen duke@435: // at least min_new, and at most preferred_max_new_size. duke@435: if (FLAG_IS_DEFAULT(NewSize)) { jmasa@448: FLAG_SET_ERGO(uintx, NewSize, MAX2(NewSize, min_new)); jmasa@448: FLAG_SET_ERGO(uintx, NewSize, MIN2(preferred_max_new_size, NewSize)); phh@1499: if (PrintGCDetails && Verbose) { jmasa@448: // Too early to use gclog_or_tty ysr@2650: tty->print_cr("CMS ergo set NewSize: " SIZE_FORMAT, NewSize); jmasa@448: } duke@435: } duke@435: // Unless explicitly requested otherwise, size old gen ysr@2650: // so it's NewRatio x of NewSize. duke@435: if (FLAG_IS_DEFAULT(OldSize)) { duke@435: if (max_heap > NewSize) { ysr@2650: FLAG_SET_ERGO(uintx, OldSize, MIN2(NewRatio*NewSize, max_heap - NewSize)); phh@1499: if (PrintGCDetails && Verbose) { jmasa@448: // Too early to use gclog_or_tty ysr@2650: tty->print_cr("CMS ergo set OldSize: " SIZE_FORMAT, OldSize); jmasa@448: } duke@435: } duke@435: } duke@435: } duke@435: } duke@435: // Unless explicitly requested otherwise, definitely duke@435: // promote all objects surviving "tenuring_default" scavenges. duke@435: if (FLAG_IS_DEFAULT(MaxTenuringThreshold) && duke@435: FLAG_IS_DEFAULT(SurvivorRatio)) { jmasa@448: FLAG_SET_ERGO(intx, MaxTenuringThreshold, tenuring_default); duke@435: } duke@435: // If we decided above (or user explicitly requested) duke@435: // `promote all' (via MaxTenuringThreshold := 0), duke@435: // prefer minuscule survivor spaces so as not to waste duke@435: // space for (non-existent) survivors duke@435: if (FLAG_IS_DEFAULT(SurvivorRatio) && MaxTenuringThreshold == 0) { jmasa@448: FLAG_SET_ERGO(intx, SurvivorRatio, MAX2((intx)1024, SurvivorRatio)); duke@435: } duke@435: // If OldPLABSize is set and CMSParPromoteBlocksToClaim is not, duke@435: // set CMSParPromoteBlocksToClaim equal to OldPLABSize. duke@435: // This is done in order to make ParNew+CMS configuration to work duke@435: // with YoungPLABSize and OldPLABSize options. duke@435: // See CR 6362902. duke@435: if (!FLAG_IS_DEFAULT(OldPLABSize)) { duke@435: if (FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim)) { jmasa@448: // OldPLABSize is not the default value but CMSParPromoteBlocksToClaim jmasa@448: // is. In this situtation let CMSParPromoteBlocksToClaim follow jmasa@448: // the value (either from the command line or ergonomics) of jmasa@448: // OldPLABSize. Following OldPLABSize is an ergonomics decision. jmasa@448: FLAG_SET_ERGO(uintx, CMSParPromoteBlocksToClaim, OldPLABSize); ysr@1580: } else { duke@435: // OldPLABSize and CMSParPromoteBlocksToClaim are both set. duke@435: // CMSParPromoteBlocksToClaim is a collector-specific flag, so duke@435: // we'll let it to take precedence. duke@435: jio_fprintf(defaultStream::error_stream(), jmasa@1321: "Both OldPLABSize and CMSParPromoteBlocksToClaim" jmasa@1321: " options are specified for the CMS collector." jmasa@1321: " CMSParPromoteBlocksToClaim will take precedence.\n"); duke@435: } duke@435: } ysr@1580: if (!FLAG_IS_DEFAULT(ResizeOldPLAB) && !ResizeOldPLAB) { ysr@1580: // OldPLAB sizing manually turned off: Use a larger default setting, ysr@1580: // unless it was manually specified. This is because a too-low value ysr@1580: // will slow down scavenges. ysr@1580: if (FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim)) { ysr@1580: FLAG_SET_ERGO(uintx, CMSParPromoteBlocksToClaim, 50); // default value before 6631166 ysr@1580: } ysr@1580: } ysr@1580: // Overwrite OldPLABSize which is the variable we will internally use everywhere. ysr@1580: FLAG_SET_ERGO(uintx, OldPLABSize, CMSParPromoteBlocksToClaim); ysr@1580: // If either of the static initialization defaults have changed, note this ysr@1580: // modification. ysr@1580: if (!FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim) || !FLAG_IS_DEFAULT(OldPLABWeight)) { ysr@1580: CFLS_LAB::modify_initialization(OldPLABSize, OldPLABWeight); ysr@1580: } jmasa@1719: if (PrintGCDetails && Verbose) { jmasa@1719: tty->print_cr("MarkStackSize: %uk MarkStackSizeMax: %uk", jmasa@1719: MarkStackSize / K, MarkStackSizeMax / K); jmasa@1719: tty->print_cr("ConcGCThreads: %u", ConcGCThreads); jmasa@1719: } duke@435: } ysr@1580: #endif // KERNEL duke@435: kvn@1926: void set_object_alignment() { kvn@1926: // Object alignment. kvn@1926: assert(is_power_of_2(ObjectAlignmentInBytes), "ObjectAlignmentInBytes must be power of 2"); kvn@1926: MinObjAlignmentInBytes = ObjectAlignmentInBytes; kvn@1926: assert(MinObjAlignmentInBytes >= HeapWordsPerLong * HeapWordSize, "ObjectAlignmentInBytes value is too small"); kvn@1926: MinObjAlignment = MinObjAlignmentInBytes / HeapWordSize; kvn@1926: assert(MinObjAlignmentInBytes == MinObjAlignment * HeapWordSize, "ObjectAlignmentInBytes value is incorrect"); kvn@1926: MinObjAlignmentInBytesMask = MinObjAlignmentInBytes - 1; kvn@1926: kvn@1926: LogMinObjAlignmentInBytes = exact_log2(ObjectAlignmentInBytes); kvn@1926: LogMinObjAlignment = LogMinObjAlignmentInBytes - LogHeapWordSize; kvn@1926: kvn@1926: // Oop encoding heap max kvn@1926: OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes; kvn@1926: kvn@1926: #ifndef KERNEL kvn@1926: // Set CMS global values kvn@1926: CompactibleFreeListSpace::set_cms_values(); kvn@1926: #endif // KERNEL kvn@1926: } kvn@1926: kvn@1926: bool verify_object_alignment() { kvn@1926: // Object alignment. kvn@1926: if (!is_power_of_2(ObjectAlignmentInBytes)) { kvn@1926: jio_fprintf(defaultStream::error_stream(), kvn@2184: "error: ObjectAlignmentInBytes=%d must be power of 2\n", kvn@2184: (int)ObjectAlignmentInBytes); kvn@1926: return false; kvn@1926: } kvn@1926: if ((int)ObjectAlignmentInBytes < BytesPerLong) { kvn@1926: jio_fprintf(defaultStream::error_stream(), kvn@2184: "error: ObjectAlignmentInBytes=%d must be greater or equal %d\n", kvn@2184: (int)ObjectAlignmentInBytes, BytesPerLong); kvn@2184: return false; kvn@2184: } kvn@2184: // It does not make sense to have big object alignment kvn@2184: // since a space lost due to alignment will be greater kvn@2184: // then a saved space from compressed oops. kvn@2184: if ((int)ObjectAlignmentInBytes > 256) { kvn@2184: jio_fprintf(defaultStream::error_stream(), kvn@2184: "error: ObjectAlignmentInBytes=%d must not be greater then 256\n", kvn@2184: (int)ObjectAlignmentInBytes); kvn@2184: return false; kvn@2184: } kvn@2184: // In case page size is very small. kvn@2184: if ((int)ObjectAlignmentInBytes >= os::vm_page_size()) { kvn@2184: jio_fprintf(defaultStream::error_stream(), kvn@2184: "error: ObjectAlignmentInBytes=%d must be less then page size %d\n", kvn@2184: (int)ObjectAlignmentInBytes, os::vm_page_size()); kvn@1926: return false; kvn@1926: } kvn@1926: return true; kvn@1926: } kvn@1926: coleenp@570: inline uintx max_heap_for_compressed_oops() { kvn@2305: // Avoid sign flip. kvn@2305: if (OopEncodingHeapMax < MaxPermSize + os::vm_page_size()) { kvn@2305: return 0; kvn@2305: } kvn@2305: LP64_ONLY(return OopEncodingHeapMax - MaxPermSize - os::vm_page_size()); phh@1499: NOT_LP64(ShouldNotReachHere(); return 0); coleenp@570: } coleenp@570: duke@435: bool Arguments::should_auto_select_low_pause_collector() { duke@435: if (UseAutoGCSelectPolicy && duke@435: !FLAG_IS_DEFAULT(MaxGCPauseMillis) && duke@435: (MaxGCPauseMillis <= AutoGCSelectPauseMillis)) { duke@435: if (PrintGCDetails) { duke@435: // Cannot use gclog_or_tty yet. duke@435: tty->print_cr("Automatic selection of the low pause collector" duke@435: " based on pause goal of %d (ms)", MaxGCPauseMillis); duke@435: } duke@435: return true; duke@435: } duke@435: return false; duke@435: } duke@435: duke@435: void Arguments::set_ergonomics_flags() { duke@435: // Parallel GC is not compatible with sharing. If one specifies phh@1499: // that they want sharing explicitly, do not set ergonomics flags. jcoomes@2644: if (DumpSharedSpaces || RequireSharedSpaces) { duke@435: return; duke@435: } duke@435: duke@435: if (os::is_server_class_machine() && !force_client_mode ) { duke@435: // If no other collector is requested explicitly, duke@435: // let the VM select the collector based on duke@435: // machine class and automatic selection policy. duke@435: if (!UseSerialGC && duke@435: !UseConcMarkSweepGC && ysr@777: !UseG1GC && duke@435: !UseParNewGC && duke@435: !DumpSharedSpaces && duke@435: FLAG_IS_DEFAULT(UseParallelGC)) { duke@435: if (should_auto_select_low_pause_collector()) { duke@435: FLAG_SET_ERGO(bool, UseConcMarkSweepGC, true); duke@435: } else { duke@435: FLAG_SET_ERGO(bool, UseParallelGC, true); duke@435: } duke@435: no_shared_spaces(); duke@435: } duke@435: } coleenp@548: never@1445: #ifndef ZERO coleenp@548: #ifdef _LP64 coleenp@548: // Check that UseCompressedOops can be set with the max heap size allocated coleenp@548: // by ergonomics. coleenp@622: if (MaxHeapSize <= max_heap_for_compressed_oops()) { iveresov@2138: #if !defined(COMPILER1) || defined(TIERED) dcubed@3307: // disable UseCompressedOops by default on MacOS X until 7118647 is fixed dcubed@3307: #ifndef __APPLE__ johnc@2535: if (FLAG_IS_DEFAULT(UseCompressedOops)) { kvn@1367: FLAG_SET_ERGO(bool, UseCompressedOops, true); coleenp@548: } dcubed@3307: #endif // !__APPLE__ roland@1495: #endif coleenp@760: #ifdef _WIN64 coleenp@760: if (UseLargePages && UseCompressedOops) { coleenp@760: // Cannot allocate guard pages for implicit checks in indexed addressing coleenp@760: // mode, when large pages are specified on windows. kvn@1077: // This flag could be switched ON if narrow oop base address is set to 0, kvn@1077: // see code in Universe::initialize_heap(). kvn@1077: Universe::set_narrow_oop_use_implicit_null_checks(false); coleenp@760: } coleenp@760: #endif // _WIN64 coleenp@548: } else { coleenp@548: if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) { ysr@779: warning("Max heap size too large for Compressed Oops"); coleenp@548: FLAG_SET_DEFAULT(UseCompressedOops, false); coleenp@548: } coleenp@548: } coleenp@548: // Also checks that certain machines are slower with compressed oops coleenp@548: // in vm_version initialization code. coleenp@548: #endif // _LP64 never@1445: #endif // !ZERO duke@435: } duke@435: duke@435: void Arguments::set_parallel_gc_flags() { ysr@777: assert(UseParallelGC || UseParallelOldGC, "Error"); duke@435: // If parallel old was requested, automatically enable parallel scavenge. duke@435: if (UseParallelOldGC && !UseParallelGC && FLAG_IS_DEFAULT(UseParallelGC)) { duke@435: FLAG_SET_DEFAULT(UseParallelGC, true); duke@435: } duke@435: duke@435: // If no heap maximum was requested explicitly, use some reasonable fraction duke@435: // of the physical memory, up to a maximum of 1GB. duke@435: if (UseParallelGC) { jmasa@3294: FLAG_SET_DEFAULT(ParallelGCThreads, jmasa@3294: Abstract_VM_Version::parallel_worker_threads()); jmasa@445: duke@435: // If InitialSurvivorRatio or MinSurvivorRatio were not specified, but the duke@435: // SurvivorRatio has been set, reset their default values to SurvivorRatio + duke@435: // 2. By doing this we make SurvivorRatio also work for Parallel Scavenger. duke@435: // See CR 6362902 for details. duke@435: if (!FLAG_IS_DEFAULT(SurvivorRatio)) { duke@435: if (FLAG_IS_DEFAULT(InitialSurvivorRatio)) { duke@435: FLAG_SET_DEFAULT(InitialSurvivorRatio, SurvivorRatio + 2); duke@435: } duke@435: if (FLAG_IS_DEFAULT(MinSurvivorRatio)) { duke@435: FLAG_SET_DEFAULT(MinSurvivorRatio, SurvivorRatio + 2); duke@435: } duke@435: } duke@435: duke@435: if (UseParallelOldGC) { duke@435: // Par compact uses lower default values since they are treated as jmasa@448: // minimums. These are different defaults because of the different jmasa@448: // interpretation and are not ergonomically set. duke@435: if (FLAG_IS_DEFAULT(MarkSweepDeadRatio)) { jmasa@448: FLAG_SET_DEFAULT(MarkSweepDeadRatio, 1); duke@435: } duke@435: if (FLAG_IS_DEFAULT(PermMarkSweepDeadRatio)) { jmasa@448: FLAG_SET_DEFAULT(PermMarkSweepDeadRatio, 5); duke@435: } duke@435: } duke@435: } iveresov@2854: if (UseNUMA) { iveresov@2854: if (FLAG_IS_DEFAULT(MinHeapDeltaBytes)) { iveresov@2854: FLAG_SET_DEFAULT(MinHeapDeltaBytes, 64*M); iveresov@2854: } iveresov@3085: // For those collectors or operating systems (eg, Windows) that do iveresov@3085: // not support full UseNUMA, we will map to UseNUMAInterleaving for now iveresov@3085: UseNUMAInterleaving = true; iveresov@2854: } duke@435: } duke@435: ysr@777: void Arguments::set_g1_gc_flags() { ysr@777: assert(UseG1GC, "Error"); ysr@777: #ifdef COMPILER1 ysr@777: FastTLABRefill = false; ysr@777: #endif ysr@777: FLAG_SET_DEFAULT(ParallelGCThreads, ysr@777: Abstract_VM_Version::parallel_worker_threads()); ysr@777: if (ParallelGCThreads == 0) { ysr@777: FLAG_SET_DEFAULT(ParallelGCThreads, johnc@1186: Abstract_VM_Version::parallel_worker_threads()); ysr@777: } ysr@777: no_shared_spaces(); johnc@1186: jmasa@1719: if (FLAG_IS_DEFAULT(MarkStackSize)) { jcoomes@1746: FLAG_SET_DEFAULT(MarkStackSize, 128 * TASKQUEUE_SIZE); jmasa@1719: } jmasa@1719: if (PrintGCDetails && Verbose) { jmasa@1719: tty->print_cr("MarkStackSize: %uk MarkStackSizeMax: %uk", jmasa@1719: MarkStackSize / K, MarkStackSizeMax / K); jmasa@1719: tty->print_cr("ConcGCThreads: %u", ConcGCThreads); jmasa@1719: } tonyp@1791: tonyp@1791: if (FLAG_IS_DEFAULT(GCTimeRatio) || GCTimeRatio == 0) { tonyp@1791: // In G1, we want the default GC overhead goal to be higher than tonyp@1791: // say in PS. So we set it here to 10%. Otherwise the heap might tonyp@1791: // be expanded more aggressively than we would like it to. In tonyp@1791: // fact, even 10% seems to not be high enough in some cases tonyp@1791: // (especially small GC stress tests that the main thing they do tonyp@1791: // is allocation). We might consider increase it further. tonyp@1791: FLAG_SET_DEFAULT(GCTimeRatio, 9); tonyp@1791: } ysr@777: } ysr@777: phh@1499: void Arguments::set_heap_size() { phh@1499: if (!FLAG_IS_DEFAULT(DefaultMaxRAMFraction)) { phh@1499: // Deprecated flag phh@1499: FLAG_SET_CMDLINE(uintx, MaxRAMFraction, DefaultMaxRAMFraction); phh@1499: } phh@1499: phh@1499: const julong phys_mem = phh@1499: FLAG_IS_DEFAULT(MaxRAM) ? MIN2(os::physical_memory(), (julong)MaxRAM) phh@1499: : (julong)MaxRAM; phh@1499: phh@1499: // If the maximum heap size has not been set with -Xmx, phh@1499: // then set it as fraction of the size of physical memory, phh@1499: // respecting the maximum and minimum sizes of the heap. ysr@777: if (FLAG_IS_DEFAULT(MaxHeapSize)) { phh@1499: julong reasonable_max = phys_mem / MaxRAMFraction; phh@1499: phh@1499: if (phys_mem <= MaxHeapSize * MinRAMFraction) { phh@1499: // Small physical memory, so use a minimum fraction of it for the heap phh@1499: reasonable_max = phys_mem / MinRAMFraction; phh@1499: } else { phh@1499: // Not-small physical memory, so require a heap at least phh@1499: // as large as MaxHeapSize phh@1499: reasonable_max = MAX2(reasonable_max, (julong)MaxHeapSize); ysr@777: } phh@1499: if (!FLAG_IS_DEFAULT(ErgoHeapSizeLimit) && ErgoHeapSizeLimit != 0) { phh@1499: // Limit the heap size to ErgoHeapSizeLimit phh@1499: reasonable_max = MIN2(reasonable_max, (julong)ErgoHeapSizeLimit); phh@1499: } phh@1499: if (UseCompressedOops) { phh@1499: // Limit the heap size to the maximum possible when using compressed oops kvn@2305: julong max_coop_heap = (julong)max_heap_for_compressed_oops(); kvn@2305: if (HeapBaseMinAddress + MaxHeapSize < max_coop_heap) { kvn@2305: // Heap should be above HeapBaseMinAddress to get zero based compressed oops kvn@2305: // but it should be not less than default MaxHeapSize. kvn@2305: max_coop_heap -= HeapBaseMinAddress; kvn@2305: } kvn@2305: reasonable_max = MIN2(reasonable_max, max_coop_heap); phh@1499: } phh@1499: reasonable_max = os::allocatable_physical_memory(reasonable_max); phh@1499: phh@1499: if (!FLAG_IS_DEFAULT(InitialHeapSize)) { phh@1499: // An initial heap size was specified on the command line, phh@1499: // so be sure that the maximum size is consistent. Done phh@1499: // after call to allocatable_physical_memory because that phh@1499: // method might reduce the allocation size. phh@1499: reasonable_max = MAX2(reasonable_max, (julong)InitialHeapSize); phh@1499: } phh@1499: ysr@777: if (PrintGCDetails && Verbose) { ysr@777: // Cannot use gclog_or_tty yet. phh@1499: tty->print_cr(" Maximum heap size " SIZE_FORMAT, reasonable_max); ysr@777: } phh@1499: FLAG_SET_ERGO(uintx, MaxHeapSize, (uintx)reasonable_max); phh@1499: } phh@1499: phh@1499: // If the initial_heap_size has not been set with InitialHeapSize phh@1499: // or -Xms, then set it as fraction of the size of physical memory, phh@1499: // respecting the maximum and minimum sizes of the heap. phh@1499: if (FLAG_IS_DEFAULT(InitialHeapSize)) { phh@1509: julong reasonable_minimum = (julong)(OldSize + NewSize); phh@1509: phh@1509: reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize); phh@1509: phh@1509: reasonable_minimum = os::allocatable_physical_memory(reasonable_minimum); phh@1509: phh@1499: julong reasonable_initial = phys_mem / InitialRAMFraction; phh@1499: phh@1509: reasonable_initial = MAX2(reasonable_initial, reasonable_minimum); phh@1499: reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize); phh@1499: phh@1499: reasonable_initial = os::allocatable_physical_memory(reasonable_initial); phh@1499: phh@1499: if (PrintGCDetails && Verbose) { phh@1499: // Cannot use gclog_or_tty yet. phh@1499: tty->print_cr(" Initial heap size " SIZE_FORMAT, (uintx)reasonable_initial); phh@1509: tty->print_cr(" Minimum heap size " SIZE_FORMAT, (uintx)reasonable_minimum); ysr@777: } phh@1499: FLAG_SET_ERGO(uintx, InitialHeapSize, (uintx)reasonable_initial); phh@1509: set_min_heap_size((uintx)reasonable_minimum); ysr@777: } ysr@777: } ysr@777: duke@435: // This must be called after ergonomics because we want bytecode rewriting duke@435: // if the server compiler is used, or if UseSharedSpaces is disabled. duke@435: void Arguments::set_bytecode_flags() { duke@435: // Better not attempt to store into a read-only space. duke@435: if (UseSharedSpaces) { duke@435: FLAG_SET_DEFAULT(RewriteBytecodes, false); duke@435: FLAG_SET_DEFAULT(RewriteFrequentPairs, false); duke@435: } duke@435: duke@435: if (!RewriteBytecodes) { duke@435: FLAG_SET_DEFAULT(RewriteFrequentPairs, false); duke@435: } duke@435: } duke@435: duke@435: // Aggressive optimization flags -XX:+AggressiveOpts duke@435: void Arguments::set_aggressive_opts_flags() { never@452: #ifdef COMPILER2 never@452: if (AggressiveOpts || !FLAG_IS_DEFAULT(AutoBoxCacheMax)) { never@452: if (FLAG_IS_DEFAULT(EliminateAutoBox)) { never@452: FLAG_SET_DEFAULT(EliminateAutoBox, true); never@452: } never@452: if (FLAG_IS_DEFAULT(AutoBoxCacheMax)) { never@452: FLAG_SET_DEFAULT(AutoBoxCacheMax, 20000); never@452: } never@452: never@452: // Feed the cache size setting into the JDK never@452: char buffer[1024]; xlu@948: sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax); never@452: add_property(buffer); never@452: } never@851: if (AggressiveOpts && FLAG_IS_DEFAULT(BiasedLockingStartupDelay)) { never@851: FLAG_SET_DEFAULT(BiasedLockingStartupDelay, 500); never@851: } never@452: #endif never@452: duke@435: if (AggressiveOpts) { sbohne@496: // Sample flag setting code sbohne@496: // if (FLAG_IS_DEFAULT(EliminateZeroing)) { sbohne@496: // FLAG_SET_DEFAULT(EliminateZeroing, true); sbohne@496: // } duke@435: } duke@435: } duke@435: duke@435: //=========================================================================================================== duke@435: // Parsing of java.compiler property duke@435: duke@435: void Arguments::process_java_compiler_argument(char* arg) { duke@435: // For backwards compatibility, Djava.compiler=NONE or "" duke@435: // causes us to switch to -Xint mode UNLESS -Xdebug duke@435: // is also specified. duke@435: if (strlen(arg) == 0 || strcasecmp(arg, "NONE") == 0) { duke@435: set_java_compiler(true); // "-Djava.compiler[=...]" most recently seen. duke@435: } duke@435: } duke@435: duke@435: void Arguments::process_java_launcher_argument(const char* launcher, void* extra_info) { duke@435: _sun_java_launcher = strdup(launcher); sla@2584: if (strcmp("gamma", _sun_java_launcher) == 0) { sla@2584: _created_by_gamma_launcher = true; sla@2584: } duke@435: } duke@435: duke@435: bool Arguments::created_by_java_launcher() { duke@435: assert(_sun_java_launcher != NULL, "property must have value"); duke@435: return strcmp(DEFAULT_JAVA_LAUNCHER, _sun_java_launcher) != 0; duke@435: } duke@435: sla@2584: bool Arguments::created_by_gamma_launcher() { sla@2584: return _created_by_gamma_launcher; sla@2584: } sla@2584: duke@435: //=========================================================================================================== duke@435: // Parsing of main arguments duke@435: johnc@1679: bool Arguments::verify_interval(uintx val, uintx min, johnc@1679: uintx max, const char* name) { johnc@1679: // Returns true iff value is in the inclusive interval [min..max] johnc@1679: // false, otherwise. johnc@1679: if (val >= min && val <= max) { johnc@1679: return true; johnc@1679: } johnc@1679: jio_fprintf(defaultStream::error_stream(), johnc@1679: "%s of " UINTX_FORMAT " is invalid; must be between " UINTX_FORMAT johnc@1679: " and " UINTX_FORMAT "\n", johnc@1679: name, val, min, max); johnc@1679: return false; johnc@1679: } johnc@1679: ptisnovs@2099: bool Arguments::verify_min_value(intx val, intx min, const char* name) { jwilhelm@2648: // Returns true if given value is at least specified min threshold ptisnovs@2099: // false, otherwise. ptisnovs@2099: if (val >= min ) { ptisnovs@2099: return true; ptisnovs@2099: } ptisnovs@2099: jio_fprintf(defaultStream::error_stream(), jwilhelm@2648: "%s of " INTX_FORMAT " is invalid; must be at least " INTX_FORMAT "\n", ptisnovs@2099: name, val, min); ptisnovs@2099: return false; ptisnovs@2099: } ptisnovs@2099: duke@435: bool Arguments::verify_percentage(uintx value, const char* name) { duke@435: if (value <= 100) { duke@435: return true; duke@435: } duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "%s of " UINTX_FORMAT " is invalid; must be between 0 and 100\n", duke@435: name, value); duke@435: return false; duke@435: } duke@435: phh@1499: static void force_serial_gc() { duke@435: FLAG_SET_DEFAULT(UseSerialGC, true); duke@435: FLAG_SET_DEFAULT(UseParNewGC, false); duke@435: FLAG_SET_DEFAULT(UseConcMarkSweepGC, false); ysr@1380: FLAG_SET_DEFAULT(CMSIncrementalMode, false); // special CMS suboption duke@435: FLAG_SET_DEFAULT(UseParallelGC, false); duke@435: FLAG_SET_DEFAULT(UseParallelOldGC, false); ysr@777: FLAG_SET_DEFAULT(UseG1GC, false); duke@435: } duke@435: duke@435: static bool verify_serial_gc_flags() { duke@435: return (UseSerialGC && ysr@1380: !(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC || ysr@777: UseParallelGC || UseParallelOldGC)); duke@435: } duke@435: minqi@2964: // check if do gclog rotation minqi@2964: // +UseGCLogFileRotation is a must, minqi@2964: // no gc log rotation when log file not supplied or minqi@2964: // NumberOfGCLogFiles is 0, or GCLogFileSize is 0 minqi@2964: void check_gclog_consistency() { minqi@2964: if (UseGCLogFileRotation) { minqi@2964: if ((Arguments::gc_log_filename() == NULL) || minqi@2964: (NumberOfGCLogFiles == 0) || minqi@2964: (GCLogFileSize == 0)) { minqi@2964: jio_fprintf(defaultStream::output_stream(), ysr@2966: "To enable GC log rotation, use -Xloggc: -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=\n" minqi@2964: "where num_of_file > 0 and num_of_size > 0\n" minqi@2964: "GC log rotation is turned off\n"); minqi@2964: UseGCLogFileRotation = false; minqi@2964: } minqi@2964: } minqi@2964: minqi@2964: if (UseGCLogFileRotation && GCLogFileSize < 8*K) { minqi@2964: FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K); minqi@2964: jio_fprintf(defaultStream::output_stream(), minqi@2964: "GCLogFileSize changed to minimum 8K\n"); minqi@2964: } minqi@2964: } minqi@2964: jmasa@445: // Check consistency of GC selection jmasa@445: bool Arguments::check_gc_consistency() { minqi@2964: check_gclog_consistency(); jmasa@445: bool status = true; jmasa@445: // Ensure that the user has not selected conflicting sets jmasa@445: // of collectors. [Note: this check is merely a user convenience; jmasa@445: // collectors over-ride each other so that only a non-conflicting jmasa@445: // set is selected; however what the user gets is not what they jmasa@445: // may have expected from the combination they asked for. It's jmasa@445: // better to reduce user confusion by not allowing them to jmasa@445: // select conflicting combinations. jmasa@445: uint i = 0; jmasa@445: if (UseSerialGC) i++; jmasa@445: if (UseConcMarkSweepGC || UseParNewGC) i++; jmasa@445: if (UseParallelGC || UseParallelOldGC) i++; ysr@1280: if (UseG1GC) i++; jmasa@445: if (i > 1) { jmasa@445: jio_fprintf(defaultStream::error_stream(), jmasa@445: "Conflicting collector combinations in option list; " jmasa@445: "please refer to the release notes for the combinations " jmasa@445: "allowed\n"); jmasa@445: status = false; jmasa@445: } jmasa@445: jmasa@445: return status; jmasa@445: } jmasa@445: ptisnovs@2099: // Check stack pages settings ptisnovs@2099: bool Arguments::check_stack_pages() ptisnovs@2099: { ptisnovs@2099: bool status = true; ptisnovs@2099: status = status && verify_min_value(StackYellowPages, 1, "StackYellowPages"); ptisnovs@2099: status = status && verify_min_value(StackRedPages, 1, "StackRedPages"); coleenp@2222: // greater stack shadow pages can't generate instruction to bang stack coleenp@2222: status = status && verify_interval(StackShadowPages, 1, 50, "StackShadowPages"); ptisnovs@2099: return status; ptisnovs@2099: } ptisnovs@2099: duke@435: // Check the consistency of vm_init_args duke@435: bool Arguments::check_vm_args_consistency() { duke@435: // Method for adding checks for flag consistency. duke@435: // The intent is to warn the user of all possible conflicts, duke@435: // before returning an error. duke@435: // Note: Needs platform-dependent factoring. duke@435: bool status = true; duke@435: duke@435: #if ( (defined(COMPILER2) && defined(SPARC))) duke@435: // NOTE: The call to VM_Version_init depends on the fact that VM_Version_init duke@435: // on sparc doesn't require generation of a stub as is the case on, e.g., duke@435: // x86. Normally, VM_Version_init must be called from init_globals in duke@435: // init.cpp, which is called by the initial java thread *after* arguments duke@435: // have been parsed. VM_Version_init gets called twice on sparc. duke@435: extern void VM_Version_init(); duke@435: VM_Version_init(); duke@435: if (!VM_Version::has_v9()) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "V8 Machine detected, Server requires V9\n"); duke@435: status = false; duke@435: } duke@435: #endif /* COMPILER2 && SPARC */ duke@435: duke@435: // Allow both -XX:-UseStackBanging and -XX:-UseBoundThreads in non-product duke@435: // builds so the cost of stack banging can be measured. duke@435: #if (defined(PRODUCT) && defined(SOLARIS)) duke@435: if (!UseBoundThreads && !UseStackBanging) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "-UseStackBanging conflicts with -UseBoundThreads\n"); duke@435: duke@435: status = false; duke@435: } duke@435: #endif duke@435: duke@435: if (TLABRefillWasteFraction == 0) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "TLABRefillWasteFraction should be a denominator, " duke@435: "not " SIZE_FORMAT "\n", duke@435: TLABRefillWasteFraction); duke@435: status = false; duke@435: } duke@435: jmasa@445: status = status && verify_percentage(AdaptiveSizePolicyWeight, duke@435: "AdaptiveSizePolicyWeight"); jmasa@445: status = status && verify_percentage(AdaptivePermSizeWeight, "AdaptivePermSizeWeight"); jmasa@445: status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance"); jmasa@445: status = status && verify_percentage(MinHeapFreeRatio, "MinHeapFreeRatio"); jmasa@445: status = status && verify_percentage(MaxHeapFreeRatio, "MaxHeapFreeRatio"); duke@435: duke@435: if (MinHeapFreeRatio > MaxHeapFreeRatio) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or " duke@435: "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n", duke@435: MinHeapFreeRatio, MaxHeapFreeRatio); duke@435: status = false; duke@435: } duke@435: // Keeping the heap 100% free is hard ;-) so limit it to 99%. duke@435: MinHeapFreeRatio = MIN2(MinHeapFreeRatio, (uintx) 99); duke@435: duke@435: if (FullGCALot && FLAG_IS_DEFAULT(MarkSweepAlwaysCompactCount)) { duke@435: MarkSweepAlwaysCompactCount = 1; // Move objects every gc. duke@435: } duke@435: jcoomes@918: if (UseParallelOldGC && ParallelOldGCSplitALot) { jcoomes@918: // Settings to encourage splitting. jcoomes@918: if (!FLAG_IS_CMDLINE(NewRatio)) { jcoomes@918: FLAG_SET_CMDLINE(intx, NewRatio, 2); jcoomes@918: } jcoomes@918: if (!FLAG_IS_CMDLINE(ScavengeBeforeFullGC)) { jcoomes@918: FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false); jcoomes@918: } jcoomes@918: } jcoomes@918: jmasa@445: status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit"); jmasa@445: status = status && verify_percentage(GCTimeLimit, "GCTimeLimit"); duke@435: if (GCTimeLimit == 100) { duke@435: // Turn off gc-overhead-limit-exceeded checks duke@435: FLAG_SET_DEFAULT(UseGCOverheadLimit, false); duke@435: } duke@435: jmasa@445: status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit"); duke@435: jmasa@445: status = status && check_gc_consistency(); ptisnovs@2099: status = status && check_stack_pages(); duke@435: duke@435: if (_has_alloc_profile) { duke@435: if (UseParallelGC || UseParallelOldGC) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "error: invalid argument combination.\n" duke@435: "Allocation profiling (-Xaprof) cannot be used together with " duke@435: "Parallel GC (-XX:+UseParallelGC or -XX:+UseParallelOldGC).\n"); duke@435: status = false; duke@435: } duke@435: if (UseConcMarkSweepGC) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "error: invalid argument combination.\n" duke@435: "Allocation profiling (-Xaprof) cannot be used together with " duke@435: "the CMS collector (-XX:+UseConcMarkSweepGC).\n"); duke@435: status = false; duke@435: } duke@435: } duke@435: duke@435: if (CMSIncrementalMode) { duke@435: if (!UseConcMarkSweepGC) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "error: invalid argument combination.\n" duke@435: "The CMS collector (-XX:+UseConcMarkSweepGC) must be " duke@435: "selected in order\nto use CMSIncrementalMode.\n"); duke@435: status = false; duke@435: } else { jmasa@445: status = status && verify_percentage(CMSIncrementalDutyCycle, duke@435: "CMSIncrementalDutyCycle"); jmasa@445: status = status && verify_percentage(CMSIncrementalDutyCycleMin, duke@435: "CMSIncrementalDutyCycleMin"); jmasa@445: status = status && verify_percentage(CMSIncrementalSafetyFactor, duke@435: "CMSIncrementalSafetyFactor"); jmasa@445: status = status && verify_percentage(CMSIncrementalOffset, duke@435: "CMSIncrementalOffset"); jmasa@445: status = status && verify_percentage(CMSExpAvgFactor, duke@435: "CMSExpAvgFactor"); duke@435: // If it was not set on the command line, set duke@435: // CMSInitiatingOccupancyFraction to 1 so icms can initiate cycles early. duke@435: if (CMSInitiatingOccupancyFraction < 0) { duke@435: FLAG_SET_DEFAULT(CMSInitiatingOccupancyFraction, 1); duke@435: } duke@435: } duke@435: } duke@435: duke@435: // CMS space iteration, which FLSVerifyAllHeapreferences entails, duke@435: // insists that we hold the requisite locks so that the iteration is duke@435: // MT-safe. For the verification at start-up and shut-down, we don't duke@435: // yet have a good way of acquiring and releasing these locks, duke@435: // which are not visible at the CollectedHeap level. We want to duke@435: // be able to acquire these locks and then do the iteration rather duke@435: // than just disable the lock verification. This will be fixed under duke@435: // bug 4788986. duke@435: if (UseConcMarkSweepGC && FLSVerifyAllHeapReferences) { duke@435: if (VerifyGCStartAt == 0) { duke@435: warning("Heap verification at start-up disabled " duke@435: "(due to current incompatibility with FLSVerifyAllHeapReferences)"); duke@435: VerifyGCStartAt = 1; // Disable verification at start-up duke@435: } duke@435: if (VerifyBeforeExit) { duke@435: warning("Heap verification at shutdown disabled " duke@435: "(due to current incompatibility with FLSVerifyAllHeapReferences)"); duke@435: VerifyBeforeExit = false; // Disable verification at shutdown duke@435: } duke@435: } duke@435: duke@435: // Note: only executed in non-PRODUCT mode duke@435: if (!UseAsyncConcMarkSweepGC && duke@435: (ExplicitGCInvokesConcurrent || duke@435: ExplicitGCInvokesConcurrentAndUnloadsClasses)) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "error: +ExplictGCInvokesConcurrent[AndUnloadsClasses] conflicts" duke@435: " with -UseAsyncConcMarkSweepGC"); duke@435: status = false; duke@435: } duke@435: jwilhelm@2648: status = status && verify_min_value(ParGCArrayScanChunk, 1, "ParGCArrayScanChunk"); jwilhelm@2648: johnc@2494: #ifndef SERIALGC tonyp@1718: if (UseG1GC) { tonyp@1718: status = status && verify_percentage(InitiatingHeapOccupancyPercent, tonyp@1718: "InitiatingHeapOccupancyPercent"); johnc@2494: status = status && verify_min_value(G1RefProcDrainInterval, 1, johnc@2494: "G1RefProcDrainInterval"); johnc@2494: status = status && verify_min_value((intx)G1ConcMarkStepDurationMillis, 1, johnc@2494: "G1ConcMarkStepDurationMillis"); tonyp@1718: } johnc@2494: #endif tonyp@1718: johnc@1679: status = status && verify_interval(RefDiscoveryPolicy, johnc@1679: ReferenceProcessor::DiscoveryPolicyMin, johnc@1679: ReferenceProcessor::DiscoveryPolicyMax, johnc@1679: "RefDiscoveryPolicy"); johnc@1679: johnc@1679: // Limit the lower bound of this flag to 1 as it is used in a division johnc@1679: // expression. johnc@1679: status = status && verify_interval(TLABWasteTargetPercent, johnc@1679: 1, 100, "TLABWasteTargetPercent"); johnc@1679: kvn@1926: status = status && verify_object_alignment(); kvn@1926: duke@435: return status; duke@435: } duke@435: duke@435: bool Arguments::is_bad_option(const JavaVMOption* option, jboolean ignore, duke@435: const char* option_type) { duke@435: if (ignore) return false; duke@435: duke@435: const char* spacer = " "; duke@435: if (option_type == NULL) { duke@435: option_type = ++spacer; // Set both to the empty string. duke@435: } duke@435: duke@435: if (os::obsolete_option(option)) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Obsolete %s%soption: %s\n", option_type, spacer, duke@435: option->optionString); duke@435: return false; duke@435: } else { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Unrecognized %s%soption: %s\n", option_type, spacer, duke@435: option->optionString); duke@435: return true; duke@435: } duke@435: } duke@435: duke@435: static const char* user_assertion_options[] = { duke@435: "-da", "-ea", "-disableassertions", "-enableassertions", 0 duke@435: }; duke@435: duke@435: static const char* system_assertion_options[] = { duke@435: "-dsa", "-esa", "-disablesystemassertions", "-enablesystemassertions", 0 duke@435: }; duke@435: duke@435: // Return true if any of the strings in null-terminated array 'names' matches. duke@435: // If tail_allowed is true, then the tail must begin with a colon; otherwise, duke@435: // the option must match exactly. duke@435: static bool match_option(const JavaVMOption* option, const char** names, const char** tail, duke@435: bool tail_allowed) { duke@435: for (/* empty */; *names != NULL; ++names) { duke@435: if (match_option(option, *names, tail)) { duke@435: if (**tail == '\0' || tail_allowed && **tail == ':') { duke@435: return true; duke@435: } duke@435: } duke@435: } duke@435: return false; duke@435: } duke@435: jmasa@1719: bool Arguments::parse_uintx(const char* value, jmasa@1719: uintx* uintx_arg, jmasa@1719: uintx min_size) { jmasa@1719: jmasa@1719: // Check the sign first since atomull() parses only unsigned values. jmasa@1719: bool value_is_positive = !(*value == '-'); jmasa@1719: jmasa@1719: if (value_is_positive) { jmasa@1719: julong n; jmasa@1719: bool good_return = atomull(value, &n); jmasa@1719: if (good_return) { jmasa@1719: bool above_minimum = n >= min_size; jmasa@1719: bool value_is_too_large = n > max_uintx; jmasa@1719: jmasa@1719: if (above_minimum && !value_is_too_large) { jmasa@1719: *uintx_arg = n; jmasa@1719: return true; jmasa@1719: } jmasa@1719: } jmasa@1719: } jmasa@1719: return false; jmasa@1719: } jmasa@1719: duke@435: Arguments::ArgsRange Arguments::parse_memory_size(const char* s, swamyv@924: julong* long_arg, swamyv@924: julong min_size) { swamyv@924: if (!atomull(s, long_arg)) return arg_unreadable; duke@435: return check_memory_size(*long_arg, min_size); duke@435: } duke@435: duke@435: // Parse JavaVMInitArgs structure duke@435: duke@435: jint Arguments::parse_vm_init_args(const JavaVMInitArgs* args) { duke@435: // For components of the system classpath. duke@435: SysClassPath scp(Arguments::get_sysclasspath()); duke@435: bool scp_assembly_required = false; duke@435: duke@435: // Save default settings for some mode flags duke@435: Arguments::_AlwaysCompileLoopMethods = AlwaysCompileLoopMethods; duke@435: Arguments::_UseOnStackReplacement = UseOnStackReplacement; duke@435: Arguments::_ClipInlining = ClipInlining; duke@435: Arguments::_BackgroundCompilation = BackgroundCompilation; duke@435: never@2873: // Setup flags for mixed which is the default never@2873: set_mode_flags(_mixed); never@2873: duke@435: // Parse JAVA_TOOL_OPTIONS environment variable (if present) duke@435: jint result = parse_java_tool_options_environment_variable(&scp, &scp_assembly_required); duke@435: if (result != JNI_OK) { duke@435: return result; duke@435: } duke@435: duke@435: // Parse JavaVMInitArgs structure passed in duke@435: result = parse_each_vm_init_arg(args, &scp, &scp_assembly_required, COMMAND_LINE); duke@435: if (result != JNI_OK) { duke@435: return result; duke@435: } duke@435: phh@966: if (AggressiveOpts) { phh@966: // Insert alt-rt.jar between user-specified bootclasspath phh@966: // prefix and the default bootclasspath. os::set_boot_path() phh@966: // uses meta_index_dir as the default bootclasspath directory. phh@966: const char* altclasses_jar = "alt-rt.jar"; phh@966: size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 + phh@966: strlen(altclasses_jar); phh@966: char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len); phh@966: strcpy(altclasses_path, get_meta_index_dir()); phh@966: strcat(altclasses_path, altclasses_jar); phh@966: scp.add_suffix_to_prefix(altclasses_path); phh@966: scp_assembly_required = true; phh@966: FREE_C_HEAP_ARRAY(char, altclasses_path); phh@966: } phh@966: duke@435: // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) duke@435: result = parse_java_options_environment_variable(&scp, &scp_assembly_required); duke@435: if (result != JNI_OK) { duke@435: return result; duke@435: } duke@435: duke@435: // Do final processing now that all arguments have been parsed duke@435: result = finalize_vm_init_args(&scp, scp_assembly_required); duke@435: if (result != JNI_OK) { duke@435: return result; duke@435: } duke@435: duke@435: return JNI_OK; duke@435: } duke@435: duke@435: jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, duke@435: SysClassPath* scp_p, duke@435: bool* scp_assembly_required_p, duke@435: FlagValueOrigin origin) { duke@435: // Remaining part of option string duke@435: const char* tail; duke@435: duke@435: // iterate over arguments duke@435: for (int index = 0; index < args->nOptions; index++) { duke@435: bool is_absolute_path = false; // for -agentpath vs -agentlib duke@435: duke@435: const JavaVMOption* option = args->options + index; duke@435: duke@435: if (!match_option(option, "-Djava.class.path", &tail) && duke@435: !match_option(option, "-Dsun.java.command", &tail) && duke@435: !match_option(option, "-Dsun.java.launcher", &tail)) { duke@435: duke@435: // add all jvm options to the jvm_args string. This string duke@435: // is used later to set the java.vm.args PerfData string constant. duke@435: // the -Djava.class.path and the -Dsun.java.command options are duke@435: // omitted from jvm_args string as each have their own PerfData duke@435: // string constant object. duke@435: build_jvm_args(option->optionString); duke@435: } duke@435: duke@435: // -verbose:[class/gc/jni] duke@435: if (match_option(option, "-verbose", &tail)) { duke@435: if (!strcmp(tail, ":class") || !strcmp(tail, "")) { duke@435: FLAG_SET_CMDLINE(bool, TraceClassLoading, true); duke@435: FLAG_SET_CMDLINE(bool, TraceClassUnloading, true); duke@435: } else if (!strcmp(tail, ":gc")) { duke@435: FLAG_SET_CMDLINE(bool, PrintGC, true); duke@435: } else if (!strcmp(tail, ":jni")) { duke@435: FLAG_SET_CMDLINE(bool, PrintJNIResolving, true); duke@435: } duke@435: // -da / -ea / -disableassertions / -enableassertions duke@435: // These accept an optional class/package name separated by a colon, e.g., duke@435: // -da:java.lang.Thread. duke@435: } else if (match_option(option, user_assertion_options, &tail, true)) { duke@435: bool enable = option->optionString[1] == 'e'; // char after '-' is 'e' duke@435: if (*tail == '\0') { duke@435: JavaAssertions::setUserClassDefault(enable); duke@435: } else { duke@435: assert(*tail == ':', "bogus match by match_option()"); duke@435: JavaAssertions::addOption(tail + 1, enable); duke@435: } duke@435: // -dsa / -esa / -disablesystemassertions / -enablesystemassertions duke@435: } else if (match_option(option, system_assertion_options, &tail, false)) { duke@435: bool enable = option->optionString[1] == 'e'; // char after '-' is 'e' duke@435: JavaAssertions::setSystemClassDefault(enable); duke@435: // -bootclasspath: duke@435: } else if (match_option(option, "-Xbootclasspath:", &tail)) { duke@435: scp_p->reset_path(tail); duke@435: *scp_assembly_required_p = true; duke@435: // -bootclasspath/a: duke@435: } else if (match_option(option, "-Xbootclasspath/a:", &tail)) { duke@435: scp_p->add_suffix(tail); duke@435: *scp_assembly_required_p = true; duke@435: // -bootclasspath/p: duke@435: } else if (match_option(option, "-Xbootclasspath/p:", &tail)) { duke@435: scp_p->add_prefix(tail); duke@435: *scp_assembly_required_p = true; duke@435: // -Xrun duke@435: } else if (match_option(option, "-Xrun", &tail)) { phh@966: if (tail != NULL) { duke@435: const char* pos = strchr(tail, ':'); duke@435: size_t len = (pos == NULL) ? strlen(tail) : pos - tail; duke@435: char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1), tail, len); duke@435: name[len] = '\0'; duke@435: duke@435: char *options = NULL; duke@435: if(pos != NULL) { duke@435: size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied. duke@435: options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2), pos+1, len2); duke@435: } duke@435: #ifdef JVMTI_KERNEL duke@435: if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { duke@435: warning("profiling and debugging agents are not supported with Kernel VM"); duke@435: } else duke@435: #endif // JVMTI_KERNEL duke@435: add_init_library(name, options); duke@435: } duke@435: // -agentlib and -agentpath duke@435: } else if (match_option(option, "-agentlib:", &tail) || duke@435: (is_absolute_path = match_option(option, "-agentpath:", &tail))) { duke@435: if(tail != NULL) { duke@435: const char* pos = strchr(tail, '='); duke@435: size_t len = (pos == NULL) ? strlen(tail) : pos - tail; duke@435: char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1), tail, len); duke@435: name[len] = '\0'; duke@435: duke@435: char *options = NULL; duke@435: if(pos != NULL) { duke@435: options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(pos + 1) + 1), pos + 1); duke@435: } duke@435: #ifdef JVMTI_KERNEL duke@435: if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { duke@435: warning("profiling and debugging agents are not supported with Kernel VM"); duke@435: } else duke@435: #endif // JVMTI_KERNEL duke@435: add_init_agent(name, options, is_absolute_path); duke@435: duke@435: } duke@435: // -javaagent duke@435: } else if (match_option(option, "-javaagent:", &tail)) { duke@435: if(tail != NULL) { duke@435: char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1), tail); duke@435: add_init_agent("instrument", options, false); duke@435: } duke@435: // -Xnoclassgc duke@435: } else if (match_option(option, "-Xnoclassgc", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, ClassUnloading, false); duke@435: // -Xincgc: i-CMS duke@435: } else if (match_option(option, "-Xincgc", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true); duke@435: FLAG_SET_CMDLINE(bool, CMSIncrementalMode, true); duke@435: // -Xnoincgc: no i-CMS duke@435: } else if (match_option(option, "-Xnoincgc", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false); duke@435: FLAG_SET_CMDLINE(bool, CMSIncrementalMode, false); duke@435: // -Xconcgc duke@435: } else if (match_option(option, "-Xconcgc", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true); duke@435: // -Xnoconcgc duke@435: } else if (match_option(option, "-Xnoconcgc", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false); duke@435: // -Xbatch duke@435: } else if (match_option(option, "-Xbatch", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, BackgroundCompilation, false); duke@435: // -Xmn for compatibility with other JVM vendors duke@435: } else if (match_option(option, "-Xmn", &tail)) { swamyv@924: julong long_initial_eden_size = 0; duke@435: ArgsRange errcode = parse_memory_size(tail, &long_initial_eden_size, 1); duke@435: if (errcode != arg_in_range) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Invalid initial eden size: %s\n", option->optionString); duke@435: describe_range_error(errcode); duke@435: return JNI_EINVAL; duke@435: } phh@1499: FLAG_SET_CMDLINE(uintx, MaxNewSize, (uintx)long_initial_eden_size); phh@1499: FLAG_SET_CMDLINE(uintx, NewSize, (uintx)long_initial_eden_size); duke@435: // -Xms duke@435: } else if (match_option(option, "-Xms", &tail)) { swamyv@924: julong long_initial_heap_size = 0; duke@435: ArgsRange errcode = parse_memory_size(tail, &long_initial_heap_size, 1); duke@435: if (errcode != arg_in_range) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Invalid initial heap size: %s\n", option->optionString); duke@435: describe_range_error(errcode); duke@435: return JNI_EINVAL; duke@435: } phh@1499: FLAG_SET_CMDLINE(uintx, InitialHeapSize, (uintx)long_initial_heap_size); duke@435: // Currently the minimum size and the initial heap sizes are the same. phh@1499: set_min_heap_size(InitialHeapSize); duke@435: // -Xmx duke@435: } else if (match_option(option, "-Xmx", &tail)) { swamyv@924: julong long_max_heap_size = 0; duke@435: ArgsRange errcode = parse_memory_size(tail, &long_max_heap_size, 1); duke@435: if (errcode != arg_in_range) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Invalid maximum heap size: %s\n", option->optionString); duke@435: describe_range_error(errcode); duke@435: return JNI_EINVAL; duke@435: } phh@1499: FLAG_SET_CMDLINE(uintx, MaxHeapSize, (uintx)long_max_heap_size); duke@435: // Xmaxf duke@435: } else if (match_option(option, "-Xmaxf", &tail)) { duke@435: int maxf = (int)(atof(tail) * 100); duke@435: if (maxf < 0 || maxf > 100) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Bad max heap free percentage size: %s\n", duke@435: option->optionString); duke@435: return JNI_EINVAL; duke@435: } else { duke@435: FLAG_SET_CMDLINE(uintx, MaxHeapFreeRatio, maxf); duke@435: } duke@435: // Xminf duke@435: } else if (match_option(option, "-Xminf", &tail)) { duke@435: int minf = (int)(atof(tail) * 100); duke@435: if (minf < 0 || minf > 100) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Bad min heap free percentage size: %s\n", duke@435: option->optionString); duke@435: return JNI_EINVAL; duke@435: } else { duke@435: FLAG_SET_CMDLINE(uintx, MinHeapFreeRatio, minf); duke@435: } duke@435: // -Xss duke@435: } else if (match_option(option, "-Xss", &tail)) { swamyv@924: julong long_ThreadStackSize = 0; duke@435: ArgsRange errcode = parse_memory_size(tail, &long_ThreadStackSize, 1000); duke@435: if (errcode != arg_in_range) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Invalid thread stack size: %s\n", option->optionString); duke@435: describe_range_error(errcode); duke@435: return JNI_EINVAL; duke@435: } duke@435: // Internally track ThreadStackSize in units of 1024 bytes. duke@435: FLAG_SET_CMDLINE(intx, ThreadStackSize, duke@435: round_to((int)long_ThreadStackSize, K) / K); duke@435: // -Xoss duke@435: } else if (match_option(option, "-Xoss", &tail)) { duke@435: // HotSpot does not have separate native and Java stacks, ignore silently for compatibility duke@435: // -Xmaxjitcodesize coleenp@2418: } else if (match_option(option, "-Xmaxjitcodesize", &tail) || coleenp@2418: match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) { swamyv@924: julong long_ReservedCodeCacheSize = 0; duke@435: ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize, swamyv@924: (size_t)InitialCodeCacheSize); duke@435: if (errcode != arg_in_range) { duke@435: jio_fprintf(defaultStream::error_stream(), coleenp@2418: "Invalid maximum code cache size: %s. Should be greater than InitialCodeCacheSize=%dK\n", coleenp@2418: option->optionString, InitialCodeCacheSize/K); duke@435: describe_range_error(errcode); duke@435: return JNI_EINVAL; duke@435: } duke@435: FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize); duke@435: // -green duke@435: } else if (match_option(option, "-green", &tail)) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Green threads support not available\n"); duke@435: return JNI_EINVAL; duke@435: // -native duke@435: } else if (match_option(option, "-native", &tail)) { duke@435: // HotSpot always uses native threads, ignore silently for compatibility duke@435: // -Xsqnopause duke@435: } else if (match_option(option, "-Xsqnopause", &tail)) { duke@435: // EVM option, ignore silently for compatibility duke@435: // -Xrs duke@435: } else if (match_option(option, "-Xrs", &tail)) { duke@435: // Classic/EVM option, new functionality duke@435: FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true); duke@435: } else if (match_option(option, "-Xusealtsigs", &tail)) { duke@435: // change default internal VM signals used - lower case for back compat duke@435: FLAG_SET_CMDLINE(bool, UseAltSigs, true); duke@435: // -Xoptimize duke@435: } else if (match_option(option, "-Xoptimize", &tail)) { duke@435: // EVM option, ignore silently for compatibility duke@435: // -Xprof duke@435: } else if (match_option(option, "-Xprof", &tail)) { duke@435: #ifndef FPROF_KERNEL duke@435: _has_profile = true; duke@435: #else // FPROF_KERNEL duke@435: // do we have to exit? duke@435: warning("Kernel VM does not support flat profiling."); duke@435: #endif // FPROF_KERNEL duke@435: // -Xaprof duke@435: } else if (match_option(option, "-Xaprof", &tail)) { duke@435: _has_alloc_profile = true; duke@435: // -Xconcurrentio duke@435: } else if (match_option(option, "-Xconcurrentio", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseLWPSynchronization, true); duke@435: FLAG_SET_CMDLINE(bool, BackgroundCompilation, false); duke@435: FLAG_SET_CMDLINE(intx, DeferThrSuspendLoopCount, 1); duke@435: FLAG_SET_CMDLINE(bool, UseTLAB, false); duke@435: FLAG_SET_CMDLINE(uintx, NewSizeThreadIncrease, 16 * K); // 20Kb per thread added to new generation duke@435: duke@435: // -Xinternalversion duke@435: } else if (match_option(option, "-Xinternalversion", &tail)) { duke@435: jio_fprintf(defaultStream::output_stream(), "%s\n", duke@435: VM_Version::internal_vm_info_string()); duke@435: vm_exit(0); duke@435: #ifndef PRODUCT duke@435: // -Xprintflags duke@435: } else if (match_option(option, "-Xprintflags", &tail)) { fparain@3402: CommandLineFlags::printFlags(tty, false); duke@435: vm_exit(0); duke@435: #endif duke@435: // -D duke@435: } else if (match_option(option, "-D", &tail)) { duke@435: if (!add_property(tail)) { duke@435: return JNI_ENOMEM; duke@435: } duke@435: // Out of the box management support duke@435: if (match_option(option, "-Dcom.sun.management", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, ManagementServer, true); duke@435: } duke@435: // -Xint duke@435: } else if (match_option(option, "-Xint", &tail)) { duke@435: set_mode_flags(_int); duke@435: // -Xmixed duke@435: } else if (match_option(option, "-Xmixed", &tail)) { duke@435: set_mode_flags(_mixed); duke@435: // -Xcomp duke@435: } else if (match_option(option, "-Xcomp", &tail)) { duke@435: // for testing the compiler; turn off all flags that inhibit compilation duke@435: set_mode_flags(_comp); duke@435: duke@435: // -Xshare:dump duke@435: } else if (match_option(option, "-Xshare:dump", &tail)) { duke@435: #ifdef TIERED duke@435: FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true); duke@435: set_mode_flags(_int); // Prevent compilation, which creates objects duke@435: #elif defined(COMPILER2) duke@435: vm_exit_during_initialization( duke@435: "Dumping a shared archive is not supported on the Server JVM.", NULL); duke@435: #elif defined(KERNEL) duke@435: vm_exit_during_initialization( duke@435: "Dumping a shared archive is not supported on the Kernel JVM.", NULL); duke@435: #else duke@435: FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true); duke@435: set_mode_flags(_int); // Prevent compilation, which creates objects duke@435: #endif duke@435: // -Xshare:on duke@435: } else if (match_option(option, "-Xshare:on", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseSharedSpaces, true); duke@435: FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true); duke@435: // -Xshare:auto duke@435: } else if (match_option(option, "-Xshare:auto", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseSharedSpaces, true); duke@435: FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false); duke@435: // -Xshare:off duke@435: } else if (match_option(option, "-Xshare:off", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseSharedSpaces, false); duke@435: FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false); duke@435: duke@435: // -Xverify duke@435: } else if (match_option(option, "-Xverify", &tail)) { duke@435: if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) { duke@435: FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, true); duke@435: FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true); duke@435: } else if (strcmp(tail, ":remote") == 0) { duke@435: FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false); duke@435: FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true); duke@435: } else if (strcmp(tail, ":none") == 0) { duke@435: FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false); duke@435: FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, false); duke@435: } else if (is_bad_option(option, args->ignoreUnrecognized, "verification")) { duke@435: return JNI_EINVAL; duke@435: } duke@435: // -Xdebug duke@435: } else if (match_option(option, "-Xdebug", &tail)) { duke@435: // note this flag has been used, then ignore duke@435: set_xdebug_mode(true); duke@435: // -Xnoagent duke@435: } else if (match_option(option, "-Xnoagent", &tail)) { duke@435: // For compatibility with classic. HotSpot refuses to load the old style agent.dll. duke@435: } else if (match_option(option, "-Xboundthreads", &tail)) { duke@435: // Bind user level threads to kernel threads (Solaris only) duke@435: FLAG_SET_CMDLINE(bool, UseBoundThreads, true); duke@435: } else if (match_option(option, "-Xloggc:", &tail)) { duke@435: // Redirect GC output to the file. -Xloggc: duke@435: // ostream_init_log(), when called will use this filename duke@435: // to initialize a fileStream. duke@435: _gc_log_filename = strdup(tail); duke@435: FLAG_SET_CMDLINE(bool, PrintGC, true); duke@435: FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true); duke@435: duke@435: // JNI hooks duke@435: } else if (match_option(option, "-Xcheck", &tail)) { duke@435: if (!strcmp(tail, ":jni")) { duke@435: CheckJNICalls = true; duke@435: } else if (is_bad_option(option, args->ignoreUnrecognized, duke@435: "check")) { duke@435: return JNI_EINVAL; duke@435: } duke@435: } else if (match_option(option, "vfprintf", &tail)) { duke@435: _vfprintf_hook = CAST_TO_FN_PTR(vfprintf_hook_t, option->extraInfo); duke@435: } else if (match_option(option, "exit", &tail)) { duke@435: _exit_hook = CAST_TO_FN_PTR(exit_hook_t, option->extraInfo); duke@435: } else if (match_option(option, "abort", &tail)) { duke@435: _abort_hook = CAST_TO_FN_PTR(abort_hook_t, option->extraInfo); duke@435: // -XX:+AggressiveHeap duke@435: } else if (match_option(option, "-XX:+AggressiveHeap", &tail)) { duke@435: duke@435: // This option inspects the machine and attempts to set various duke@435: // parameters to be optimal for long-running, memory allocation duke@435: // intensive jobs. It is intended for machines with large duke@435: // amounts of cpu and memory. duke@435: duke@435: // initHeapSize is needed since _initial_heap_size is 4 bytes on a 32 bit duke@435: // VM, but we may not be able to represent the total physical memory duke@435: // available (like having 8gb of memory on a box but using a 32bit VM). duke@435: // Thus, we need to make sure we're using a julong for intermediate duke@435: // calculations. duke@435: julong initHeapSize; duke@435: julong total_memory = os::physical_memory(); duke@435: duke@435: if (total_memory < (julong)256*M) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "You need at least 256mb of memory to use -XX:+AggressiveHeap\n"); duke@435: vm_exit(1); duke@435: } duke@435: duke@435: // The heap size is half of available memory, or (at most) duke@435: // all of possible memory less 160mb (leaving room for the OS duke@435: // when using ISM). This is the maximum; because adaptive sizing duke@435: // is turned on below, the actual space used may be smaller. duke@435: duke@435: initHeapSize = MIN2(total_memory / (julong)2, duke@435: total_memory - (julong)160*M); duke@435: duke@435: // Make sure that if we have a lot of memory we cap the 32 bit duke@435: // process space. The 64bit VM version of this function is a nop. duke@435: initHeapSize = os::allocatable_physical_memory(initHeapSize); duke@435: duke@435: // The perm gen is separate but contiguous with the duke@435: // object heap (and is reserved with it) so subtract it duke@435: // from the heap size. duke@435: if (initHeapSize > MaxPermSize) { duke@435: initHeapSize = initHeapSize - MaxPermSize; duke@435: } else { duke@435: warning("AggressiveHeap and MaxPermSize values may conflict"); duke@435: } duke@435: duke@435: if (FLAG_IS_DEFAULT(MaxHeapSize)) { duke@435: FLAG_SET_CMDLINE(uintx, MaxHeapSize, initHeapSize); phh@1499: FLAG_SET_CMDLINE(uintx, InitialHeapSize, initHeapSize); duke@435: // Currently the minimum size and the initial heap sizes are the same. phh@1499: set_min_heap_size(initHeapSize); duke@435: } duke@435: if (FLAG_IS_DEFAULT(NewSize)) { duke@435: // Make the young generation 3/8ths of the total heap. duke@435: FLAG_SET_CMDLINE(uintx, NewSize, duke@435: ((julong)MaxHeapSize / (julong)8) * (julong)3); duke@435: FLAG_SET_CMDLINE(uintx, MaxNewSize, NewSize); duke@435: } duke@435: duke@435: FLAG_SET_DEFAULT(UseLargePages, true); duke@435: duke@435: // Increase some data structure sizes for efficiency duke@435: FLAG_SET_CMDLINE(uintx, BaseFootPrintEstimate, MaxHeapSize); duke@435: FLAG_SET_CMDLINE(bool, ResizeTLAB, false); duke@435: FLAG_SET_CMDLINE(uintx, TLABSize, 256*K); duke@435: duke@435: // See the OldPLABSize comment below, but replace 'after promotion' duke@435: // with 'after copying'. YoungPLABSize is the size of the survivor duke@435: // space per-gc-thread buffers. The default is 4kw. duke@435: FLAG_SET_CMDLINE(uintx, YoungPLABSize, 256*K); // Note: this is in words duke@435: duke@435: // OldPLABSize is the size of the buffers in the old gen that duke@435: // UseParallelGC uses to promote live data that doesn't fit in the duke@435: // survivor spaces. At any given time, there's one for each gc thread. duke@435: // The default size is 1kw. These buffers are rarely used, since the duke@435: // survivor spaces are usually big enough. For specjbb, however, there duke@435: // are occasions when there's lots of live data in the young gen duke@435: // and we end up promoting some of it. We don't have a definite duke@435: // explanation for why bumping OldPLABSize helps, but the theory duke@435: // is that a bigger PLAB results in retaining something like the duke@435: // original allocation order after promotion, which improves mutator duke@435: // locality. A minor effect may be that larger PLABs reduce the duke@435: // number of PLAB allocation events during gc. The value of 8kw duke@435: // was arrived at by experimenting with specjbb. duke@435: FLAG_SET_CMDLINE(uintx, OldPLABSize, 8*K); // Note: this is in words duke@435: duke@435: // CompilationPolicyChoice=0 causes the server compiler to adopt duke@435: // a more conservative which-method-do-I-compile policy when one duke@435: // of the counters maintained by the interpreter trips. The duke@435: // result is reduced startup time and improved specjbb and duke@435: // alacrity performance. Zero is the default, but we set it duke@435: // explicitly here in case the default changes. duke@435: // See runtime/compilationPolicy.*. duke@435: FLAG_SET_CMDLINE(intx, CompilationPolicyChoice, 0); duke@435: duke@435: // Enable parallel GC and adaptive generation sizing duke@435: FLAG_SET_CMDLINE(bool, UseParallelGC, true); jmasa@445: FLAG_SET_DEFAULT(ParallelGCThreads, jmasa@445: Abstract_VM_Version::parallel_worker_threads()); duke@435: duke@435: // Encourage steady state memory management duke@435: FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100); duke@435: duke@435: // This appears to improve mutator locality duke@435: FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false); duke@435: duke@435: // Get around early Solaris scheduling bug duke@435: // (affinity vs other jobs on system) duke@435: // but disallow DR and offlining (5008695). duke@435: FLAG_SET_CMDLINE(bool, BindGCTaskThreadsToCPUs, true); duke@435: duke@435: } else if (match_option(option, "-XX:+NeverTenure", &tail)) { duke@435: // The last option must always win. duke@435: FLAG_SET_CMDLINE(bool, AlwaysTenure, false); duke@435: FLAG_SET_CMDLINE(bool, NeverTenure, true); duke@435: } else if (match_option(option, "-XX:+AlwaysTenure", &tail)) { duke@435: // The last option must always win. duke@435: FLAG_SET_CMDLINE(bool, NeverTenure, false); duke@435: FLAG_SET_CMDLINE(bool, AlwaysTenure, true); duke@435: } else if (match_option(option, "-XX:+CMSPermGenSweepingEnabled", &tail) || duke@435: match_option(option, "-XX:-CMSPermGenSweepingEnabled", &tail)) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Please use CMSClassUnloadingEnabled in place of " duke@435: "CMSPermGenSweepingEnabled in the future\n"); duke@435: } else if (match_option(option, "-XX:+UseGCTimeLimit", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseGCOverheadLimit, true); duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Please use -XX:+UseGCOverheadLimit in place of " duke@435: "-XX:+UseGCTimeLimit in the future\n"); duke@435: } else if (match_option(option, "-XX:-UseGCTimeLimit", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseGCOverheadLimit, false); duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Please use -XX:-UseGCOverheadLimit in place of " duke@435: "-XX:-UseGCTimeLimit in the future\n"); duke@435: // The TLE options are for compatibility with 1.3 and will be duke@435: // removed without notice in a future release. These options duke@435: // are not to be documented. duke@435: } else if (match_option(option, "-XX:MaxTLERatio=", &tail)) { duke@435: // No longer used. duke@435: } else if (match_option(option, "-XX:+ResizeTLE", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, ResizeTLAB, true); duke@435: } else if (match_option(option, "-XX:-ResizeTLE", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, ResizeTLAB, false); duke@435: } else if (match_option(option, "-XX:+PrintTLE", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, PrintTLAB, true); duke@435: } else if (match_option(option, "-XX:-PrintTLE", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, PrintTLAB, false); duke@435: } else if (match_option(option, "-XX:TLEFragmentationRatio=", &tail)) { duke@435: // No longer used. duke@435: } else if (match_option(option, "-XX:TLESize=", &tail)) { swamyv@924: julong long_tlab_size = 0; duke@435: ArgsRange errcode = parse_memory_size(tail, &long_tlab_size, 1); duke@435: if (errcode != arg_in_range) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Invalid TLAB size: %s\n", option->optionString); duke@435: describe_range_error(errcode); duke@435: return JNI_EINVAL; duke@435: } duke@435: FLAG_SET_CMDLINE(uintx, TLABSize, long_tlab_size); duke@435: } else if (match_option(option, "-XX:TLEThreadRatio=", &tail)) { duke@435: // No longer used. duke@435: } else if (match_option(option, "-XX:+UseTLE", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseTLAB, true); duke@435: } else if (match_option(option, "-XX:-UseTLE", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseTLAB, false); duke@435: SOLARIS_ONLY( duke@435: } else if (match_option(option, "-XX:+UsePermISM", &tail)) { duke@435: warning("-XX:+UsePermISM is obsolete."); duke@435: FLAG_SET_CMDLINE(bool, UseISM, true); duke@435: } else if (match_option(option, "-XX:-UsePermISM", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, UseISM, false); duke@435: ) duke@435: } else if (match_option(option, "-XX:+DisplayVMOutputToStderr", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, false); duke@435: FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, true); duke@435: } else if (match_option(option, "-XX:+DisplayVMOutputToStdout", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, false); duke@435: FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, true); duke@435: } else if (match_option(option, "-XX:+ExtendedDTraceProbes", &tail)) { dcubed@3202: #if defined(DTRACE_ENABLED) duke@435: FLAG_SET_CMDLINE(bool, ExtendedDTraceProbes, true); duke@435: FLAG_SET_CMDLINE(bool, DTraceMethodProbes, true); duke@435: FLAG_SET_CMDLINE(bool, DTraceAllocProbes, true); duke@435: FLAG_SET_CMDLINE(bool, DTraceMonitorProbes, true); dcubed@3202: #else // defined(DTRACE_ENABLED) duke@435: jio_fprintf(defaultStream::error_stream(), dcubed@3202: "ExtendedDTraceProbes flag is not applicable for this configuration\n"); duke@435: return JNI_EINVAL; dcubed@3202: #endif // defined(DTRACE_ENABLED) duke@435: #ifdef ASSERT ysr@1580: } else if (match_option(option, "-XX:+FullGCALot", &tail)) { duke@435: FLAG_SET_CMDLINE(bool, FullGCALot, true); duke@435: // disable scavenge before parallel mark-compact duke@435: FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false); duke@435: #endif ysr@1580: } else if (match_option(option, "-XX:CMSParPromoteBlocksToClaim=", &tail)) { duke@435: julong cms_blocks_to_claim = (julong)atol(tail); duke@435: FLAG_SET_CMDLINE(uintx, CMSParPromoteBlocksToClaim, cms_blocks_to_claim); duke@435: jio_fprintf(defaultStream::error_stream(), ysr@1580: "Please use -XX:OldPLABSize in place of " ysr@1580: "-XX:CMSParPromoteBlocksToClaim in the future\n"); ysr@1580: } else if (match_option(option, "-XX:ParCMSPromoteBlocksToClaim=", &tail)) { ysr@1580: julong cms_blocks_to_claim = (julong)atol(tail); ysr@1580: FLAG_SET_CMDLINE(uintx, CMSParPromoteBlocksToClaim, cms_blocks_to_claim); ysr@1580: jio_fprintf(defaultStream::error_stream(), ysr@1580: "Please use -XX:OldPLABSize in place of " duke@435: "-XX:ParCMSPromoteBlocksToClaim in the future\n"); ysr@1580: } else if (match_option(option, "-XX:ParallelGCOldGenAllocBufferSize=", &tail)) { swamyv@924: julong old_plab_size = 0; duke@435: ArgsRange errcode = parse_memory_size(tail, &old_plab_size, 1); duke@435: if (errcode != arg_in_range) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Invalid old PLAB size: %s\n", option->optionString); duke@435: describe_range_error(errcode); duke@435: return JNI_EINVAL; duke@435: } swamyv@924: FLAG_SET_CMDLINE(uintx, OldPLABSize, old_plab_size); duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Please use -XX:OldPLABSize in place of " duke@435: "-XX:ParallelGCOldGenAllocBufferSize in the future\n"); ysr@1580: } else if (match_option(option, "-XX:ParallelGCToSpaceAllocBufferSize=", &tail)) { swamyv@924: julong young_plab_size = 0; duke@435: ArgsRange errcode = parse_memory_size(tail, &young_plab_size, 1); duke@435: if (errcode != arg_in_range) { duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Invalid young PLAB size: %s\n", option->optionString); duke@435: describe_range_error(errcode); duke@435: return JNI_EINVAL; duke@435: } swamyv@924: FLAG_SET_CMDLINE(uintx, YoungPLABSize, young_plab_size); duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Please use -XX:YoungPLABSize in place of " duke@435: "-XX:ParallelGCToSpaceAllocBufferSize in the future\n"); jmasa@1719: } else if (match_option(option, "-XX:CMSMarkStackSize=", &tail) || jmasa@1719: match_option(option, "-XX:G1MarkStackSize=", &tail)) { jmasa@1719: julong stack_size = 0; jmasa@1719: ArgsRange errcode = parse_memory_size(tail, &stack_size, 1); jmasa@1719: if (errcode != arg_in_range) { jmasa@1719: jio_fprintf(defaultStream::error_stream(), jmasa@1719: "Invalid mark stack size: %s\n", option->optionString); jmasa@1719: describe_range_error(errcode); jmasa@1719: return JNI_EINVAL; jmasa@1719: } jmasa@1719: FLAG_SET_CMDLINE(uintx, MarkStackSize, stack_size); jmasa@1719: } else if (match_option(option, "-XX:CMSMarkStackSizeMax=", &tail)) { jmasa@1719: julong max_stack_size = 0; jmasa@1719: ArgsRange errcode = parse_memory_size(tail, &max_stack_size, 1); jmasa@1719: if (errcode != arg_in_range) { jmasa@1719: jio_fprintf(defaultStream::error_stream(), jmasa@1719: "Invalid maximum mark stack size: %s\n", jmasa@1719: option->optionString); jmasa@1719: describe_range_error(errcode); jmasa@1719: return JNI_EINVAL; jmasa@1719: } jmasa@1719: FLAG_SET_CMDLINE(uintx, MarkStackSizeMax, max_stack_size); jmasa@1719: } else if (match_option(option, "-XX:ParallelMarkingThreads=", &tail) || jmasa@1719: match_option(option, "-XX:ParallelCMSThreads=", &tail)) { jmasa@1719: uintx conc_threads = 0; jmasa@1719: if (!parse_uintx(tail, &conc_threads, 1)) { jmasa@1719: jio_fprintf(defaultStream::error_stream(), jmasa@1719: "Invalid concurrent threads: %s\n", option->optionString); jmasa@1719: return JNI_EINVAL; jmasa@1719: } jmasa@1719: FLAG_SET_CMDLINE(uintx, ConcGCThreads, conc_threads); ysr@1580: } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx duke@435: // Skip -XX:Flags= since that case has already been handled duke@435: if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) { duke@435: if (!process_argument(tail, args->ignoreUnrecognized, origin)) { duke@435: return JNI_EINVAL; duke@435: } duke@435: } duke@435: // Unknown option duke@435: } else if (is_bad_option(option, args->ignoreUnrecognized)) { duke@435: return JNI_ERR; duke@435: } duke@435: } minqi@2964: xlu@884: // Change the default value for flags which have different default values xlu@884: // when working with older JDKs. xlu@884: if (JDK_Version::current().compare_major(6) <= 0 && xlu@884: FLAG_IS_DEFAULT(UseVMInterruptibleIO)) { xlu@884: FLAG_SET_DEFAULT(UseVMInterruptibleIO, true); xlu@884: } aph@2034: #ifdef LINUX aph@2034: if (JDK_Version::current().compare_major(6) <= 0 && aph@2034: FLAG_IS_DEFAULT(UseLinuxPosixThreadCPUClocks)) { aph@2034: FLAG_SET_DEFAULT(UseLinuxPosixThreadCPUClocks, false); aph@2034: } aph@2034: #endif // LINUX duke@435: return JNI_OK; duke@435: } duke@435: duke@435: jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_required) { duke@435: // This must be done after all -D arguments have been processed. duke@435: scp_p->expand_endorsed(); duke@435: duke@435: if (scp_assembly_required || scp_p->get_endorsed() != NULL) { duke@435: // Assemble the bootclasspath elements into the final path. duke@435: Arguments::set_sysclasspath(scp_p->combined_path()); duke@435: } duke@435: duke@435: // This must be done after all arguments have been processed. duke@435: // java_compiler() true means set to "NONE" or empty. duke@435: if (java_compiler() && !xdebug_mode()) { duke@435: // For backwards compatibility, we switch to interpreted mode if duke@435: // -Djava.compiler="NONE" or "" is specified AND "-Xdebug" was duke@435: // not specified. duke@435: set_mode_flags(_int); duke@435: } duke@435: if (CompileThreshold == 0) { duke@435: set_mode_flags(_int); duke@435: } duke@435: duke@435: #ifndef COMPILER2 duke@435: // Don't degrade server performance for footprint duke@435: if (FLAG_IS_DEFAULT(UseLargePages) && duke@435: MaxHeapSize < LargePageHeapSizeThreshold) { duke@435: // No need for large granularity pages w/small heaps. duke@435: // Note that large pages are enabled/disabled for both the duke@435: // Java heap and the code cache. duke@435: FLAG_SET_DEFAULT(UseLargePages, false); duke@435: SOLARIS_ONLY(FLAG_SET_DEFAULT(UseMPSS, false)); duke@435: SOLARIS_ONLY(FLAG_SET_DEFAULT(UseISM, false)); duke@435: } ysr@777: kvn@1686: // Tiered compilation is undefined with C1. kvn@1686: TieredCompilation = false; duke@435: #else duke@435: if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) { duke@435: FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1); duke@435: } duke@435: #endif duke@435: bobv@2036: // If we are running in a headless jre, force java.awt.headless property bobv@2036: // to be true unless the property has already been set. bobv@2036: // Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state. bobv@2036: if (os::is_headless_jre()) { bobv@2036: const char* headless = Arguments::get_property("java.awt.headless"); bobv@2036: if (headless == NULL) { bobv@2036: char envbuffer[128]; bobv@2036: if (!os::getenv("JAVA_AWT_HEADLESS", envbuffer, sizeof(envbuffer))) { bobv@2036: if (!add_property("java.awt.headless=true")) { bobv@2036: return JNI_ENOMEM; bobv@2036: } bobv@2036: } else { bobv@2036: char buffer[256]; bobv@2036: strcpy(buffer, "java.awt.headless="); bobv@2036: strcat(buffer, envbuffer); bobv@2036: if (!add_property(buffer)) { bobv@2036: return JNI_ENOMEM; bobv@2036: } bobv@2036: } bobv@2036: } bobv@2036: } bobv@2036: duke@435: if (!check_vm_args_consistency()) { duke@435: return JNI_ERR; duke@435: } duke@435: duke@435: return JNI_OK; duke@435: } duke@435: duke@435: jint Arguments::parse_java_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p) { duke@435: return parse_options_environment_variable("_JAVA_OPTIONS", scp_p, duke@435: scp_assembly_required_p); duke@435: } duke@435: duke@435: jint Arguments::parse_java_tool_options_environment_variable(SysClassPath* scp_p, bool* scp_assembly_required_p) { duke@435: return parse_options_environment_variable("JAVA_TOOL_OPTIONS", scp_p, duke@435: scp_assembly_required_p); duke@435: } duke@435: duke@435: jint Arguments::parse_options_environment_variable(const char* name, SysClassPath* scp_p, bool* scp_assembly_required_p) { duke@435: const int N_MAX_OPTIONS = 64; duke@435: const int OPTION_BUFFER_SIZE = 1024; duke@435: char buffer[OPTION_BUFFER_SIZE]; duke@435: duke@435: // The variable will be ignored if it exceeds the length of the buffer. duke@435: // Don't check this variable if user has special privileges duke@435: // (e.g. unix su command). duke@435: if (os::getenv(name, buffer, sizeof(buffer)) && duke@435: !os::have_special_privileges()) { duke@435: JavaVMOption options[N_MAX_OPTIONS]; // Construct option array duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Picked up %s: %s\n", name, buffer); duke@435: char* rd = buffer; // pointer to the input string (rd) duke@435: int i; duke@435: for (i = 0; i < N_MAX_OPTIONS;) { // repeat for all options in the input string duke@435: while (isspace(*rd)) rd++; // skip whitespace duke@435: if (*rd == 0) break; // we re done when the input string is read completely duke@435: duke@435: // The output, option string, overwrites the input string. duke@435: // Because of quoting, the pointer to the option string (wrt) may lag the pointer to duke@435: // input string (rd). duke@435: char* wrt = rd; duke@435: duke@435: options[i++].optionString = wrt; // Fill in option duke@435: while (*rd != 0 && !isspace(*rd)) { // unquoted strings terminate with a space or NULL duke@435: if (*rd == '\'' || *rd == '"') { // handle a quoted string duke@435: int quote = *rd; // matching quote to look for duke@435: rd++; // don't copy open quote duke@435: while (*rd != quote) { // include everything (even spaces) up until quote duke@435: if (*rd == 0) { // string termination means unmatched string duke@435: jio_fprintf(defaultStream::error_stream(), duke@435: "Unmatched quote in %s\n", name); duke@435: return JNI_ERR; duke@435: } duke@435: *wrt++ = *rd++; // copy to option string duke@435: } duke@435: rd++; // don't copy close quote duke@435: } else { duke@435: *wrt++ = *rd++; // copy to option string duke@435: } duke@435: } duke@435: // Need to check if we're done before writing a NULL, duke@435: // because the write could be to the byte that rd is pointing to. duke@435: if (*rd++ == 0) { duke@435: *wrt = 0; duke@435: break; duke@435: } duke@435: *wrt = 0; // Zero terminate option duke@435: } duke@435: // Construct JavaVMInitArgs structure and parse as if it was part of the command line duke@435: JavaVMInitArgs vm_args; duke@435: vm_args.version = JNI_VERSION_1_2; duke@435: vm_args.options = options; duke@435: vm_args.nOptions = i; kvn@999: vm_args.ignoreUnrecognized = IgnoreUnrecognizedVMOptions; duke@435: duke@435: if (PrintVMOptions) { duke@435: const char* tail; duke@435: for (int i = 0; i < vm_args.nOptions; i++) { duke@435: const JavaVMOption *option = vm_args.options + i; duke@435: if (match_option(option, "-XX:", &tail)) { duke@435: logOption(tail); duke@435: } duke@435: } duke@435: } duke@435: duke@435: return(parse_each_vm_init_arg(&vm_args, scp_p, scp_assembly_required_p, ENVIRON_VAR)); duke@435: } duke@435: return JNI_OK; duke@435: } duke@435: jcoomes@2644: void Arguments::set_shared_spaces_flags() { jcoomes@2660: const bool must_share = DumpSharedSpaces || RequireSharedSpaces; jcoomes@2660: const bool might_share = must_share || UseSharedSpaces; jcoomes@2660: jcoomes@2660: // The string table is part of the shared archive so the size must match. jcoomes@2660: if (!FLAG_IS_DEFAULT(StringTableSize)) { jcoomes@2660: // Disable sharing. jcoomes@2660: if (must_share) { jcoomes@2660: warning("disabling shared archive %s because of non-default " jcoomes@2660: "StringTableSize", DumpSharedSpaces ? "creation" : "use"); jcoomes@2660: } jcoomes@2660: if (might_share) { jcoomes@2660: FLAG_SET_DEFAULT(DumpSharedSpaces, false); jcoomes@2660: FLAG_SET_DEFAULT(RequireSharedSpaces, false); jcoomes@2660: FLAG_SET_DEFAULT(UseSharedSpaces, false); jcoomes@2660: } jcoomes@2660: return; jcoomes@2660: } jcoomes@2660: jcoomes@2644: // Check whether class data sharing settings conflict with GC, compressed oops jcoomes@2644: // or page size, and fix them up. Explicit sharing options override other jcoomes@2644: // settings. jcoomes@2644: const bool cannot_share = UseConcMarkSweepGC || CMSIncrementalMode || jcoomes@2644: UseG1GC || UseParNewGC || UseParallelGC || UseParallelOldGC || jcoomes@2644: UseCompressedOops || UseLargePages && FLAG_IS_CMDLINE(UseLargePages); jcoomes@2644: if (cannot_share) { jcoomes@2644: if (must_share) { jcoomes@2660: warning("selecting serial gc and disabling large pages %s" jcoomes@2660: "because of %s", "" LP64_ONLY("and compressed oops "), jcoomes@2660: DumpSharedSpaces ? "-Xshare:dump" : "-Xshare:on"); jcoomes@2660: force_serial_gc(); jcoomes@2660: FLAG_SET_CMDLINE(bool, UseLargePages, false); jcoomes@2660: LP64_ONLY(FLAG_SET_CMDLINE(bool, UseCompressedOops, false)); jcoomes@2644: } else { jcoomes@2644: if (UseSharedSpaces && Verbose) { jcoomes@2644: warning("turning off use of shared archive because of " jcoomes@2644: "choice of garbage collector or large pages"); jcoomes@2644: } jcoomes@2644: no_shared_spaces(); jcoomes@2644: } jcoomes@2644: } else if (UseLargePages && might_share) { jcoomes@2644: // Disable large pages to allow shared spaces. This is sub-optimal, since jcoomes@2644: // there may not even be a shared archive to use. jcoomes@2644: FLAG_SET_DEFAULT(UseLargePages, false); jcoomes@2644: } jcoomes@2644: } iveresov@2246: jcoomes@2994: // Disable options not supported in this release, with a warning if they jcoomes@2994: // were explicitly requested on the command-line jcoomes@2994: #define UNSUPPORTED_OPTION(opt, description) \ jcoomes@2994: do { \ jcoomes@2994: if (opt) { \ jcoomes@2994: if (FLAG_IS_CMDLINE(opt)) { \ jcoomes@2994: warning(description " is disabled in this release."); \ jcoomes@2994: } \ jcoomes@2994: FLAG_SET_DEFAULT(opt, false); \ jcoomes@2994: } \ jcoomes@2994: } while(0) jcoomes@2994: duke@435: // Parse entry point called from JNI_CreateJavaVM duke@435: duke@435: jint Arguments::parse(const JavaVMInitArgs* args) { duke@435: duke@435: // Sharing support duke@435: // Construct the path to the archive duke@435: char jvm_path[JVM_MAXPATHLEN]; duke@435: os::jvm_path(jvm_path, sizeof(jvm_path)); duke@435: #ifdef TIERED duke@435: if (strstr(jvm_path, "client") != NULL) { duke@435: force_client_mode = true; duke@435: } duke@435: #endif // TIERED duke@435: char *end = strrchr(jvm_path, *os::file_separator()); duke@435: if (end != NULL) *end = '\0'; duke@435: char *shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(jvm_path) + duke@435: strlen(os::file_separator()) + 20); duke@435: if (shared_archive_path == NULL) return JNI_ENOMEM; duke@435: strcpy(shared_archive_path, jvm_path); duke@435: strcat(shared_archive_path, os::file_separator()); duke@435: strcat(shared_archive_path, "classes"); duke@435: DEBUG_ONLY(strcat(shared_archive_path, "_g");) duke@435: strcat(shared_archive_path, ".jsa"); duke@435: SharedArchivePath = shared_archive_path; duke@435: duke@435: // Remaining part of option string duke@435: const char* tail; duke@435: duke@435: // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed. duke@435: bool settings_file_specified = false; kvn@999: const char* flags_file; duke@435: int index; duke@435: for (index = 0; index < args->nOptions; index++) { duke@435: const JavaVMOption *option = args->options + index; duke@435: if (match_option(option, "-XX:Flags=", &tail)) { kvn@999: flags_file = tail; duke@435: settings_file_specified = true; duke@435: } duke@435: if (match_option(option, "-XX:+PrintVMOptions", &tail)) { duke@435: PrintVMOptions = true; duke@435: } kvn@688: if (match_option(option, "-XX:-PrintVMOptions", &tail)) { kvn@688: PrintVMOptions = false; kvn@688: } kvn@999: if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions", &tail)) { kvn@999: IgnoreUnrecognizedVMOptions = true; kvn@999: } kvn@999: if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions", &tail)) { kvn@999: IgnoreUnrecognizedVMOptions = false; kvn@999: } kvn@1585: if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) { fparain@3402: CommandLineFlags::printFlags(tty, false); kvn@1585: vm_exit(0); kvn@1585: } ikrylov@2123: ikrylov@2123: #ifndef PRODUCT ikrylov@2123: if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) { fparain@3402: CommandLineFlags::printFlags(tty, true); ikrylov@2123: vm_exit(0); ikrylov@2123: } ikrylov@2123: #endif kvn@999: } kvn@999: kvn@999: if (IgnoreUnrecognizedVMOptions) { kvn@999: // uncast const to modify the flag args->ignoreUnrecognized kvn@999: *(jboolean*)(&args->ignoreUnrecognized) = true; kvn@999: } kvn@999: kvn@999: // Parse specified settings file kvn@999: if (settings_file_specified) { kvn@999: if (!process_settings_file(flags_file, true, args->ignoreUnrecognized)) { kvn@999: return JNI_EINVAL; kvn@999: } duke@435: } duke@435: duke@435: // Parse default .hotspotrc settings file duke@435: if (!settings_file_specified) { duke@435: if (!process_settings_file(".hotspotrc", false, args->ignoreUnrecognized)) { duke@435: return JNI_EINVAL; duke@435: } duke@435: } duke@435: duke@435: if (PrintVMOptions) { duke@435: for (index = 0; index < args->nOptions; index++) { duke@435: const JavaVMOption *option = args->options + index; duke@435: if (match_option(option, "-XX:", &tail)) { duke@435: logOption(tail); duke@435: } duke@435: } duke@435: } duke@435: duke@435: // Parse JavaVMInitArgs structure passed in, as well as JAVA_TOOL_OPTIONS and _JAVA_OPTIONS duke@435: jint result = parse_vm_init_args(args); duke@435: if (result != JNI_OK) { duke@435: return result; duke@435: } duke@435: jcoomes@2994: #ifdef JAVASE_EMBEDDED jcoomes@2994: UNSUPPORTED_OPTION(UseG1GC, "G1 GC"); jcoomes@2994: #endif jcoomes@2994: duke@435: #ifndef PRODUCT duke@435: if (TraceBytecodesAt != 0) { duke@435: TraceBytecodes = true; duke@435: } duke@435: if (CountCompiledCalls) { duke@435: if (UseCounterDecay) { duke@435: warning("UseCounterDecay disabled because CountCalls is set"); duke@435: UseCounterDecay = false; duke@435: } duke@435: } duke@435: #endif // PRODUCT duke@435: twisti@2698: // Transitional twisti@2698: if (EnableMethodHandles || AnonymousClasses) { twisti@2698: if (!EnableInvokeDynamic && !FLAG_IS_DEFAULT(EnableInvokeDynamic)) { twisti@2698: warning("EnableMethodHandles and AnonymousClasses are obsolete. Keeping EnableInvokeDynamic disabled."); twisti@2698: } else { twisti@2698: EnableInvokeDynamic = true; jrose@1161: } jrose@1161: } twisti@2698: twisti@2698: // JSR 292 is not supported before 1.7 twisti@2698: if (!JDK_Version::is_gte_jdk17x_version()) { twisti@2698: if (EnableInvokeDynamic) { twisti@2698: if (!FLAG_IS_DEFAULT(EnableInvokeDynamic)) { twisti@2698: warning("JSR 292 is not supported before 1.7. Disabling support."); twisti@2698: } twisti@2698: EnableInvokeDynamic = false; jrose@1145: } jrose@1145: } twisti@2698: twisti@2698: if (EnableInvokeDynamic && ScavengeRootsInCode == 0) { jrose@1424: if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) { twisti@2698: warning("forcing ScavengeRootsInCode non-zero because EnableInvokeDynamic is true"); jrose@1424: } jrose@1424: ScavengeRootsInCode = 1; jrose@1424: } never@2658: if (!JavaObjectsInPerm && ScavengeRootsInCode == 0) { never@2658: if (!FLAG_IS_DEFAULT(ScavengeRootsInCode)) { never@2658: warning("forcing ScavengeRootsInCode non-zero because JavaObjectsInPerm is false"); never@2658: } never@2658: ScavengeRootsInCode = 1; never@2658: } jrose@1145: duke@435: if (PrintGCDetails) { duke@435: // Turn on -verbose:gc options as well duke@435: PrintGC = true; duke@435: } duke@435: kvn@1926: // Set object alignment values. kvn@1926: set_object_alignment(); kvn@1926: duke@435: #ifdef SERIALGC phh@1499: force_serial_gc(); duke@435: #endif // SERIALGC duke@435: #ifdef KERNEL duke@435: no_shared_spaces(); duke@435: #endif // KERNEL duke@435: duke@435: // Set flags based on ergonomics. duke@435: set_ergonomics_flags(); duke@435: jcoomes@2644: set_shared_spaces_flags(); twisti@1570: jmasa@445: // Check the GC selections again. jmasa@445: if (!check_gc_consistency()) { jmasa@445: return JNI_EINVAL; jmasa@445: } jmasa@445: iveresov@2138: if (TieredCompilation) { iveresov@2138: set_tiered_flags(); iveresov@2138: } else { iveresov@2138: // Check if the policy is valid. Policies 0 and 1 are valid for non-tiered setup. iveresov@2138: if (CompilationPolicyChoice >= 2) { iveresov@2138: vm_exit_during_initialization( iveresov@2138: "Incompatible compilation policy selected", NULL); iveresov@2138: } iveresov@2138: } iveresov@2138: ysr@1580: #ifndef KERNEL ysr@2650: // Set heap size based on available physical memory ysr@2650: set_heap_size(); ysr@2650: // Set per-collector flags ysr@2650: if (UseParallelGC || UseParallelOldGC) { ysr@2650: set_parallel_gc_flags(); ysr@2650: } else if (UseConcMarkSweepGC) { // should be done before ParNew check below jmasa@445: set_cms_and_parnew_gc_flags(); ysr@2650: } else if (UseParNewGC) { // skipped if CMS is set above ysr@2650: set_parnew_gc_flags(); ysr@2650: } else if (UseG1GC) { ysr@2650: set_g1_gc_flags(); ysr@777: } ysr@1580: #endif // KERNEL jmasa@445: duke@435: #ifdef SERIALGC duke@435: assert(verify_serial_gc_flags(), "SerialGC unset"); duke@435: #endif // SERIALGC duke@435: duke@435: // Set bytecode rewriting flags duke@435: set_bytecode_flags(); duke@435: duke@435: // Set flags if Aggressive optimization flags (-XX:+AggressiveOpts) enabled. duke@435: set_aggressive_opts_flags(); duke@435: coleenp@2546: // Turn off biased locking for locking debug mode flags, coleenp@2546: // which are subtlely different from each other but neither works with coleenp@2546: // biased locking. coleenp@2613: if (UseHeavyMonitors coleenp@2613: #ifdef COMPILER1 coleenp@2613: || !UseFastLocking coleenp@2613: #endif // COMPILER1 coleenp@2613: ) { coleenp@2546: if (!FLAG_IS_DEFAULT(UseBiasedLocking) && UseBiasedLocking) { coleenp@2546: // flag set to true on command line; warn the user that they coleenp@2546: // can't enable biased locking here coleenp@2546: warning("Biased Locking is not supported with locking debug flags" coleenp@2546: "; ignoring UseBiasedLocking flag." ); coleenp@2546: } coleenp@2546: UseBiasedLocking = false; coleenp@2546: } coleenp@2546: duke@435: #ifdef CC_INTERP twisti@1566: // Clear flags not supported by the C++ interpreter twisti@1566: FLAG_SET_DEFAULT(ProfileInterpreter, false); duke@435: FLAG_SET_DEFAULT(UseBiasedLocking, false); twisti@1566: LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false)); twisti@1566: #endif // CC_INTERP twisti@1566: kvn@855: #ifdef COMPILER2 kvn@855: if (!UseBiasedLocking || EmitSync != 0) { kvn@855: UseOptoBiasInlining = false; kvn@855: } kvn@855: #endif kvn@855: jrose@1590: if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) { jrose@1590: warning("PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output"); jrose@1590: DebugNonSafepoints = true; jrose@1590: } jrose@1590: kvn@1623: #ifndef PRODUCT kvn@1623: if (CompileTheWorld) { kvn@1623: // Force NmethodSweeper to sweep whole CodeCache each time. kvn@1623: if (FLAG_IS_DEFAULT(NmethodSweepFraction)) { kvn@1623: NmethodSweepFraction = 1; kvn@1623: } kvn@1623: } kvn@1623: #endif kvn@1623: duke@435: if (PrintCommandLineFlags) { fparain@3402: CommandLineFlags::printSetFlags(tty); duke@435: } duke@435: bobv@2036: // Apply CPU specific policy for the BiasedLocking bobv@2036: if (UseBiasedLocking) { bobv@2036: if (!VM_Version::use_biased_locking() && bobv@2036: !(FLAG_IS_CMDLINE(UseBiasedLocking))) { bobv@2036: UseBiasedLocking = false; bobv@2036: } bobv@2036: } bobv@2036: sla@2584: // set PauseAtExit if the gamma launcher was used and a debugger is attached sla@2584: // but only if not already set on the commandline sla@2584: if (Arguments::created_by_gamma_launcher() && os::is_debugger_attached()) { sla@2584: bool set = false; sla@2584: CommandLineFlags::wasSetOnCmdline("PauseAtExit", &set); sla@2584: if (!set) { sla@2584: FLAG_SET_DEFAULT(PauseAtExit, true); sla@2584: } sla@2584: } sla@2584: duke@435: return JNI_OK; duke@435: } duke@435: duke@435: int Arguments::PropertyList_count(SystemProperty* pl) { duke@435: int count = 0; duke@435: while(pl != NULL) { duke@435: count++; duke@435: pl = pl->next(); duke@435: } duke@435: return count; duke@435: } duke@435: duke@435: const char* Arguments::PropertyList_get_value(SystemProperty *pl, const char* key) { duke@435: assert(key != NULL, "just checking"); duke@435: SystemProperty* prop; duke@435: for (prop = pl; prop != NULL; prop = prop->next()) { duke@435: if (strcmp(key, prop->key()) == 0) return prop->value(); duke@435: } duke@435: return NULL; duke@435: } duke@435: duke@435: const char* Arguments::PropertyList_get_key_at(SystemProperty *pl, int index) { duke@435: int count = 0; duke@435: const char* ret_val = NULL; duke@435: duke@435: while(pl != NULL) { duke@435: if(count >= index) { duke@435: ret_val = pl->key(); duke@435: break; duke@435: } duke@435: count++; duke@435: pl = pl->next(); duke@435: } duke@435: duke@435: return ret_val; duke@435: } duke@435: duke@435: char* Arguments::PropertyList_get_value_at(SystemProperty* pl, int index) { duke@435: int count = 0; duke@435: char* ret_val = NULL; duke@435: duke@435: while(pl != NULL) { duke@435: if(count >= index) { duke@435: ret_val = pl->value(); duke@435: break; duke@435: } duke@435: count++; duke@435: pl = pl->next(); duke@435: } duke@435: duke@435: return ret_val; duke@435: } duke@435: duke@435: void Arguments::PropertyList_add(SystemProperty** plist, SystemProperty *new_p) { duke@435: SystemProperty* p = *plist; duke@435: if (p == NULL) { duke@435: *plist = new_p; duke@435: } else { duke@435: while (p->next() != NULL) { duke@435: p = p->next(); duke@435: } duke@435: p->set_next(new_p); duke@435: } duke@435: } duke@435: duke@435: void Arguments::PropertyList_add(SystemProperty** plist, const char* k, char* v) { duke@435: if (plist == NULL) duke@435: return; duke@435: duke@435: SystemProperty* new_p = new SystemProperty(k, v, true); duke@435: PropertyList_add(plist, new_p); duke@435: } duke@435: duke@435: // This add maintains unique property key in the list. phh@1126: void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, char* v, jboolean append) { duke@435: if (plist == NULL) duke@435: return; duke@435: duke@435: // If property key exist then update with new value. duke@435: SystemProperty* prop; duke@435: for (prop = *plist; prop != NULL; prop = prop->next()) { duke@435: if (strcmp(k, prop->key()) == 0) { phh@1126: if (append) { phh@1126: prop->append_value(v); phh@1126: } else { phh@1126: prop->set_value(v); phh@1126: } duke@435: return; duke@435: } duke@435: } duke@435: duke@435: PropertyList_add(plist, k, v); duke@435: } duke@435: duke@435: #ifdef KERNEL duke@435: char *Arguments::get_kernel_properties() { duke@435: // Find properties starting with kernel and append them to string duke@435: // We need to find out how long they are first because the URL's that they duke@435: // might point to could get long. duke@435: int length = 0; duke@435: SystemProperty* prop; duke@435: for (prop = _system_properties; prop != NULL; prop = prop->next()) { duke@435: if (strncmp(prop->key(), "kernel.", 7 ) == 0) { duke@435: length += (strlen(prop->key()) + strlen(prop->value()) + 5); // "-D =" duke@435: } duke@435: } duke@435: // Add one for null terminator. duke@435: char *props = AllocateHeap(length + 1, "get_kernel_properties"); duke@435: if (length != 0) { duke@435: int pos = 0; duke@435: for (prop = _system_properties; prop != NULL; prop = prop->next()) { duke@435: if (strncmp(prop->key(), "kernel.", 7 ) == 0) { duke@435: jio_snprintf(&props[pos], length-pos, duke@435: "-D%s=%s ", prop->key(), prop->value()); duke@435: pos = strlen(props); duke@435: } duke@435: } duke@435: } duke@435: // null terminate props in case of null duke@435: props[length] = '\0'; duke@435: return props; duke@435: } duke@435: #endif // KERNEL duke@435: duke@435: // Copies src into buf, replacing "%%" with "%" and "%p" with pid duke@435: // Returns true if all of the source pointed by src has been copied over to duke@435: // the destination buffer pointed by buf. Otherwise, returns false. duke@435: // Notes: duke@435: // 1. If the length (buflen) of the destination buffer excluding the duke@435: // NULL terminator character is not long enough for holding the expanded duke@435: // pid characters, it also returns false instead of returning the partially duke@435: // expanded one. duke@435: // 2. The passed in "buflen" should be large enough to hold the null terminator. duke@435: bool Arguments::copy_expand_pid(const char* src, size_t srclen, duke@435: char* buf, size_t buflen) { duke@435: const char* p = src; duke@435: char* b = buf; duke@435: const char* src_end = &src[srclen]; duke@435: char* buf_end = &buf[buflen - 1]; duke@435: duke@435: while (p < src_end && b < buf_end) { duke@435: if (*p == '%') { duke@435: switch (*(++p)) { duke@435: case '%': // "%%" ==> "%" duke@435: *b++ = *p++; duke@435: break; duke@435: case 'p': { // "%p" ==> current process id duke@435: // buf_end points to the character before the last character so duke@435: // that we could write '\0' to the end of the buffer. duke@435: size_t buf_sz = buf_end - b + 1; duke@435: int ret = jio_snprintf(b, buf_sz, "%d", os::current_process_id()); duke@435: duke@435: // if jio_snprintf fails or the buffer is not long enough to hold duke@435: // the expanded pid, returns false. duke@435: if (ret < 0 || ret >= (int)buf_sz) { duke@435: return false; duke@435: } else { duke@435: b += ret; duke@435: assert(*b == '\0', "fail in copy_expand_pid"); duke@435: if (p == src_end && b == buf_end + 1) { duke@435: // reach the end of the buffer. duke@435: return true; duke@435: } duke@435: } duke@435: p++; duke@435: break; duke@435: } duke@435: default : duke@435: *b++ = '%'; duke@435: } duke@435: } else { duke@435: *b++ = *p++; duke@435: } duke@435: } duke@435: *b = '\0'; duke@435: return (p == src_end); // return false if not all of the source was copied duke@435: }