< prev index next >

src/share/vm/runtime/arguments.cpp

Print this page

        

@@ -246,102 +246,131 @@
  *      ALIASED: An option that is simply another name for another option. This is often
  *               part of the process of deprecating a flag, but not all aliases need
  *               to be deprecated.
  * 
  *               Create an alias for an option by adding the old and new option names to the 
- *               "aliased_jvm_flags" table. Delete the old variable from globals.hpp (etc),.
+ *               "aliased_jvm_flags" table. Delete the old variable from globals.hpp (etc).
  * 
  *   DEPRECATED: An option that is supported, but a warning is printed to let the user know that
  *               support may be removed in the future. Both regular and aliased options may be
  *               deprecated.
  * 
  *               Add a deprecation warning for an option (or alias) by adding an entry in the 
- *               "deprecated_jvm_flags" table. Often an option "deprecated" in one major release will
- *               be made "obsolete" in the next. In this case the entry should be removed from the 
- *               "deprecated_jvm_flags" table and added to the "obsolete_jvm_flags" table (see below).
+ *               "special_jvm_flags" table and setting the "deprecated_in" field.
+ *               Often an option "deprecated" in one major release will
+ *               be made "obsolete" in the next. In this case the entry should also have it's
+ *               "obsolete_in" field set.
  *
  *     OBSOLETE: An option that has been removed (and deleted from globals.hpp), but is still accepted
  *               on the command line. A warning is printed to let the user know that option might not
  *               be accepted in the future.
  * 
- *               Add an obsolete warning for an option by adding an entry in the "obsolete_jvm_flags"
- *               table.
+ *               Add an obsolete warning for an option by adding an entry in the "special_jvm_flags"
+ *               table and setting the "obsolete_in" field.
  * 
  *      EXPIRED: A deprecated or obsolete option that has an "accept_until" version less than or equal
  *               to the current JDK version. The system will flatly refuse to admit the existence of
  *               the flag. This allows a flag to die automatically over JDK releases. 
  * 
  *               Note that manual cleanup of expired options should be done at major JDK version upgrades:
- *                  - Expired options should be removed from the obsolete_jvm_flags, deprecated_jvm_flags,
- *                    and aliased_jvm_flags tables.
- *                  - Expired deprecated options should have their global variable definitions removed
- *                    (in globals.hpp, etc).
+ *                  - Newly expired options should be removed from the special_jvm_flags and aliased_jvm_flags tables.
+ *                  - Newly obsolete or expired deprecated options should have their global variable
+ *                    definitions removed (from globals.hpp, etc) and related implementations removed.
+ *
+ * Recommended approach for removing options:
+ *
+ * To remove options commonly used by customers (e.g. product, commercial -XX options), use
+ * the 3-step model adding major release numbers to the deprecate, obsolete and expire columns.
+ *
+ * To remove internal options (e.g. diagnostic, experimental, develop options), use
+ * a 2-step model adding major release numbers to the obsolete and expire columns.
+ *
+ * To change the name of an option, use the alias table as well as a 2-step
+ * model adding major release numbers to the deprecate and expire columns.
+ * Think twice about aliasing commonly used customer options.
+ *
+ * There are times when it is appropriate to leave a future release number as undefined.
  * 
  * Tests:  Aliases should be tested in VMAliasOptions.java.
  *         Deprecated options should be tested in VMDeprecatedOptions.java. 
  */
 
 // Obsolete or deprecated -XX flag.
 typedef struct {
   const char* name;
-  JDK_Version warning_started_in; // When the warning started (obsolete or deprecated).
-  JDK_Version accept_until; // Which version to start denying the existence of the flag (if scheduled).
+  JDK_Version deprecated_in; // When the deprecation warning started (or "undefined").
+  JDK_Version obsolete_in;   // When the obsolete warning started (or "undefined").
+  JDK_Version expired_in;    // When the option expires (or "undefined").
 } SpecialFlag;
 
-// When a flag is made obsolete, it can be added to this list in order to
-// continue accepting this flag on the command-line, while issuing a warning
-// and ignoring the value.  Once the JDK version reaches the 'accept_until'
-// limit, we flatly refuse to admit the existence of the flag. The 'accept_until'
-// field can be set to undefined() if the expiration date has not yet been set.
-// This table should be scrubbed of expired options on major JDK releases.
-static SpecialFlag const obsolete_jvm_flags[] = {
-  { "UseOldInlining",                JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "SafepointPollOffset",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "UseBoundThreads",               JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "DefaultThreadPriority",         JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "NoYieldsInMicrolock",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "BackEdgeThreshold",             JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "UseNewReflection",              JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "ReflectionWrapResolutionErrors",JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "VerifyReflectionBytecodes",     JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "AutoShutdownNMT",               JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "NmethodSweepFraction",          JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "NmethodSweepCheckInterval",     JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "CodeCacheMinimumFreeSpace",     JDK_Version::jdk(9), JDK_Version::jdk(10) },
+// The special_jvm_flags table declares options that are being deprecated and/or obsoleted. The
+// "deprecated_in" or "obsolete_in" fields may be set to "undefined", but not both.
+// When the JDK version reaches 'deprecated_in' limit, the JVM will process this flag on
+// the command-line as usual, but will issue a warning.
+// When the JDK version reaches 'obsolete_in' limit, the JVM will continue accepting this flag on
+// the command-line, while issuing a warning and ignoring the flag value.
+// Once the JDK version reaches 'expired_in' limit, the JVM will flatly refuse to admit the
+// existence of the flag.
+//
+// MANUAL CLEANUP ON JDK VERSION UPDATES:
+// This table ensures that the handling of options will update automatically when the JDK
+// version is incremented, but the source code needs to be cleanup up manually:
+// - As "deprecated" options age into "obsolete" or "expired" options, the associated "globals"
+//   variable should be removed, as well as users of the variable.
+// - As "deprecated" options age into "obsolete" options, move the entry into the
+//   "Obsolete Flags" section of the table.
+// - All expired options should be removed from the table.
+static SpecialFlag const special_jvm_flags[] = {
+#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
+  { "dep > obs",                    JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
+  { "dep > exp ",                   JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(8) },
+  { "obs > exp ",                   JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(8) },
+  { "not deprecated or obsolete",   JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::undefined() },
+  { "dup option",                   JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::undefined() },
+  { "dup option",                   JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::undefined() },
+  { "BytecodeVerificationRemote",   JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::undefined() },
+#endif
+
+  // -------------- Deprecated Flags --------------
+  // --- Non-alias flags - sorted by obsolete_in then expired_in:
+  { "MaxGCMinorPauseMillis",        JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
+  { "UseParNewGC",                  JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
+
+  // --- Deprecated alias flags (see also aliased_jvm_flags) - sorted by obsolete_in then expired_in:
+  { "DefaultMaxRAMFraction",        JDK_Version::jdk(8), JDK_Version::undefined(), JDK_Version::undefined() },
+  { "CreateMinidumpOnCrash",        JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::undefined() },
+  { "CMSMarkStackSizeMax",          JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
+  { "CMSMarkStackSize",             JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
+  { "G1MarkStackSize",              JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
+  { "ParallelMarkingThreads",       JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
+  { "ParallelCMSThreads",           JDK_Version::jdk(9), JDK_Version::undefined(), JDK_Version::jdk(10) },
+
+  // -------------- Obsolete Flags - sorted by expired_in --------------
+  { "UseOldInlining",                JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "SafepointPollOffset",           JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "UseBoundThreads",               JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "DefaultThreadPriority",         JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "NoYieldsInMicrolock",           JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "BackEdgeThreshold",             JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "UseNewReflection",              JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "ReflectionWrapResolutionErrors",JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "VerifyReflectionBytecodes",     JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "AutoShutdownNMT",               JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "NmethodSweepFraction",          JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "NmethodSweepCheckInterval",     JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "CodeCacheMinimumFreeSpace",     JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
 #ifndef ZERO
-  { "UseFastAccessorMethods",        JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "UseFastEmptyMethods",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "UseFastAccessorMethods",        JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "UseFastEmptyMethods",           JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
 #endif // ZERO
-  { "UseCompilerSafepoints",         JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "AdaptiveSizePausePolicy",       JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "ParallelGCRetainPLAB",          JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "ThreadSafetyMargin",            JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "LazyBootClassLoader",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "StarvationMonitorInterval",     JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "PreInflateSpin",                JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { NULL, JDK_Version(0), JDK_Version(0) }
-};
-
-// When a flag is deprecated, it can be added to this list in order to issue a warning when the flag is used.
-// Once the JDK version reaches the 'accept_until' limit, we flatly refuse to admit the existence of the flag.
-// The 'accept_until' field can be set to undefined() if the expiration date has not yet been set.
-// If a deprecated option should be treated as obsolete before it is expired, it needs to be removed
-// from this table and added to the obsolete_jvm_flags table.
-// This table should be scrubbed of expired options on major JDK releases.
-static SpecialFlag const deprecated_jvm_flags[] = {
-  // deprecated non-alias flags:
-  { "MaxGCMinorPauseMillis",        JDK_Version::jdk(8), JDK_Version::undefined() },
-  { "UseParNewGC",                  JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  
-  // deprecated alias flags (see also aliased_jvm_flags):
-  { "DefaultMaxRAMFraction",        JDK_Version::jdk(8), JDK_Version::undefined() },
-  { "CMSMarkStackSizeMax",          JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "CMSMarkStackSize",             JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "G1MarkStackSize",              JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "ParallelMarkingThreads",       JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "ParallelCMSThreads",           JDK_Version::jdk(9), JDK_Version::jdk(10) },
-  { "CreateMinidumpOnCrash",        JDK_Version::jdk(9), JDK_Version::undefined() },
+  { "UseCompilerSafepoints",         JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "AdaptiveSizePausePolicy",       JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "ParallelGCRetainPLAB",          JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "ThreadSafetyMargin",            JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "LazyBootClassLoader",           JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "StarvationMonitorInterval",     JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+  { "PreInflateSpin",                JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
   { NULL, JDK_Version(0), JDK_Version(0) }
 };
 
 // Flags that are aliases for other flags.
 typedef struct {

@@ -358,39 +387,59 @@
   { "ParallelCMSThreads",       "ConcGCThreads"     },
   { "CreateMinidumpOnCrash",    "CreateCoredumpOnCrash" },
   { NULL, NULL}
 };
 
-// Returns 1 if the flag is special and jdk version is in the range specified.
-//     In this case the 'version' buffer is filled in with the version number when 
-//     the flag became special.
-// Returns -1 if the flag is special and has expired (should be ignored).
-// Returns 0 if the flag is not special.
-// Flag "flag_name" is a flag name stripped of '+', '-', and '='.
-static int is_special_flag(const SpecialFlag special_table[], const char *flag_name, JDK_Version* version) {
-  assert(version != NULL, "Must provide a version buffer");
-  for (size_t i = 0; special_table[i].name != NULL; i++) {
-    const SpecialFlag& flag_status = special_table[i];
-    if ((strcmp(flag_status.name, flag_name) == 0)) {
-      if (flag_status.accept_until.is_undefined() ||
-          JDK_Version::current().compare(flag_status.accept_until) == -1) {
-        *version = flag_status.warning_started_in;
-        return 1;
+// Return true if "v" is less than "other", where "other" may be "undefined".
+static bool version_less_than(JDK_Version v, JDK_Version other) {
+  assert(!v.is_undefined(), "must be defined");
+  if (!other.is_undefined() && v.compare(other) >= 0) {
+    return false;
       } else {
-        return -1;
+    return true;
       }
+}
+
+static bool lookup_special_flag(const char *flag_name, SpecialFlag& flag) {
+  for (size_t i = 0; special_jvm_flags[i].name != NULL; i++) {
+    if ((strcmp(special_jvm_flags[i].name, flag_name) == 0)) {
+      flag = special_jvm_flags[i];
+      return true;
     }
   }
-  return 0;
+  return false;
 }
 
 bool Arguments::is_obsolete_flag(const char *flag_name, JDK_Version* version) {
-  return (is_special_flag(obsolete_jvm_flags, flag_name, version) == 1);
+  assert(version != NULL, "Must provide a version buffer");
+  SpecialFlag flag;
+  if (lookup_special_flag(flag_name, flag)) {
+    if (!flag.obsolete_in.is_undefined()) {
+      if (version_less_than(JDK_Version::current(), flag.expired_in)) {
+        *version = flag.obsolete_in;
+        return true;
+      }
+    }
+  }
+  return false;
 }
 
 int Arguments::is_deprecated_flag(const char *flag_name, JDK_Version* version) {
-  return is_special_flag(deprecated_jvm_flags, flag_name, version);
+  assert(version != NULL, "Must provide a version buffer");
+  SpecialFlag flag;
+  if (lookup_special_flag(flag_name, flag)) {
+    if (!flag.deprecated_in.is_undefined()) {
+      if (version_less_than(JDK_Version::current(), flag.obsolete_in) &&
+          version_less_than(JDK_Version::current(), flag.expired_in)) {
+        *version = flag.deprecated_in;
+        return 1;
+      } else {
+        return -1;
+      }
+    }
+  }
+  return 0;
 }
 
 const char* Arguments::real_flag_name(const char *flag_name) {
   for (size_t i = 0; aliased_jvm_flags[i].alias_name != NULL; i++) {
     const AliasedFlag& flag_status = aliased_jvm_flags[i];

@@ -399,10 +448,76 @@
     }
   }
   return flag_name;
 }
 
+#ifndef PRODUCT
+static bool lookup_special_flag(const char *flag_name, size_t skip_index) {
+  for (size_t i = 0; special_jvm_flags[i].name != NULL; i++) {
+    if ((i != skip_index) && (strcmp(special_jvm_flags[i].name, flag_name) == 0)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static bool verify_special_jvm_flags() {
+  bool success = true;
+  for (size_t i = 0; special_jvm_flags[i].name != NULL; i++) {
+    const SpecialFlag& flag = special_jvm_flags[i];
+    if (lookup_special_flag(flag.name, i)) {
+      warning("Duplicate special flag declaration \"%s\"", flag.name);
+      success = false;
+    }
+    if (flag.deprecated_in.is_undefined() &&
+        flag.obsolete_in.is_undefined()) {
+      warning("Special flag entry \"%s\" must declare version deprecated and/or obsoleted in.", flag.name);
+      success = false;
+    }
+
+    if (!flag.deprecated_in.is_undefined()) {
+      if (!version_less_than(flag.deprecated_in, flag.obsolete_in)) {
+        warning("Special flag entry \"%s\" must be deprecated before obsoleted.", flag.name);
+        success = false;
+      }
+
+      if (!version_less_than(flag.deprecated_in, flag.expired_in)) {
+        warning("Special flag entry \"%s\" must be deprecated before expired.", flag.name);
+        success = false;
+      }
+    }
+
+    if (!flag.obsolete_in.is_undefined()) {
+      if (!version_less_than(flag.obsolete_in, flag.expired_in)) {
+        warning("Special flag entry \"%s\" must be obsoleted before expired.", flag.name);
+        success = false;
+      }
+
+      // if flag has become obsolete it should not have a "globals" flag defined anymore.
+      if (!version_less_than(JDK_Version::current(), flag.obsolete_in)) {
+        if (Flag::find_flag(flag.name) != NULL) {
+          warning("Global variable for obsolete special flag entry \"%s\" should be removed", flag.name);
+          success = false;
+        }
+      }
+    }
+
+    if (!flag.expired_in.is_undefined()) {
+      // if flag has become expired it should not have a "globals" flag defined anymore.
+      if (!version_less_than(JDK_Version::current(), flag.expired_in)) {
+        if (Flag::find_flag(flag.name) != NULL) {
+          warning("Global variable for expired flag entry \"%s\" should be removed", flag.name);
+          success = false;
+        }
+      }
+    }
+
+  }
+  return success;
+}
+#endif
+
 // Constructs the system class path (aka boot class path) from the following
 // components, in order:
 //
 //     prefix           // from -Xbootclasspath/p:...
 //     base             // from os::get_system_properties() or -Xbootclasspath=

@@ -776,11 +891,11 @@
 const char* Arguments::handle_aliases_and_deprecation(const char* arg, bool warn) {
   const char* real_name = real_flag_name(arg);
   JDK_Version since = JDK_Version();
   switch (is_deprecated_flag(arg, &since)) {
     case -1:
-      return NULL;
+      return NULL; // obsolete or expired, don't process normally
     case 0:
       return real_name;
     case 1: {
       if (warn) {
         char version[256];

@@ -3745,10 +3860,11 @@
 }
 
 // Parse entry point called from JNI_CreateJavaVM
 
 jint Arguments::parse(const JavaVMInitArgs* args) {
+  assert(verify_special_jvm_flags(), "deprecated and obsolete flag table inconsistent");
 
   // Initialize ranges and constraints
   CommandLineFlagRangeList::init();
   CommandLineFlagConstraintList::init();
 
< prev index next >