8129855: "-XX:+IgnoreUnrecognizedVMOptions" hides out of range VM options.
authorgziemski
Fri, 23 Oct 2015 11:17:23 -0500
changeset 33592 ceda4a796f5d
parent 33591 4a2823c696ce
child 33594 8c87ef3e5497
8129855: "-XX:+IgnoreUnrecognizedVMOptions" hides out of range VM options. Summary: Implement strict spec rgarding how IgnoreUnrecognizedVMOptions works, supplied with the corresponding test case. Reviewed-by: dcubed, ddmitriev
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/src/share/vm/runtime/globals.cpp
hotspot/src/share/vm/runtime/globals.hpp
hotspot/test/compiler/membars/DekkerTest.java
hotspot/test/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue Oct 20 14:37:59 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Fri Oct 23 11:17:23 2015 -0500
@@ -1120,7 +1120,7 @@
                                  Flag::Flags origin) {
   JDK_Version since = JDK_Version();
 
-  if (parse_argument(arg, origin) || ignore_unrecognized) {
+  if (parse_argument(arg, origin)) {
     return true;
   }
 
@@ -1156,7 +1156,7 @@
   Flag* found_flag = Flag::find_flag((const char*)argname, arg_len, true, true);
   if (found_flag != NULL) {
     char locked_message_buf[BUFLEN];
-    found_flag->get_locked_message(locked_message_buf, BUFLEN);
+    Flag::MsgType msg_type = found_flag->get_locked_message(locked_message_buf, BUFLEN);
     if (strlen(locked_message_buf) == 0) {
       if (found_flag->is_bool() && !has_plus_minus) {
         jio_fprintf(defaultStream::error_stream(),
@@ -1169,9 +1169,19 @@
           "Improperly specified VM option '%s'\n", argname);
       }
     } else {
+#ifdef PRODUCT
+      bool mismatched = ((msg_type == Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD) ||
+                         (msg_type == Flag::DEVELOPER_FLAG_BUT_PRODUCT_BUILD));
+      if (ignore_unrecognized && mismatched) {
+        return true;
+      }
+#endif
       jio_fprintf(defaultStream::error_stream(), "%s", locked_message_buf);
     }
   } else {
+    if (ignore_unrecognized) {
+      return true;
+    }
     jio_fprintf(defaultStream::error_stream(),
                 "Unrecognized VM option '%s'\n", argname);
     Flag* fuzzy_matched = Flag::fuzzy_match((const char*)argname, arg_len, true);
--- a/hotspot/src/share/vm/runtime/globals.cpp	Tue Oct 20 14:37:59 2015 +0200
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Fri Oct 23 11:17:23 2015 -0500
@@ -306,35 +306,36 @@
   _flags = Flags(_flags & ~KIND_DIAGNOSTIC);
 }
 
-// Get custom message for this locked flag, or return NULL if
-// none is available.
-void Flag::get_locked_message(char* buf, int buflen) const {
+// Get custom message for this locked flag, or NULL if
+// none is available. Returns message type produced.
+Flag::MsgType Flag::get_locked_message(char* buf, int buflen) const {
   buf[0] = '\0';
   if (is_diagnostic() && !is_unlocked()) {
     jio_snprintf(buf, buflen,
                  "Error: VM option '%s' is diagnostic and must be enabled via -XX:+UnlockDiagnosticVMOptions.\n"
                  "Error: The unlock option must precede '%s'.\n",
                  _name, _name);
-    return;
+    return Flag::DIAGNOSTIC_FLAG_BUT_LOCKED;
   }
   if (is_experimental() && !is_unlocked()) {
     jio_snprintf(buf, buflen,
                  "Error: VM option '%s' is experimental and must be enabled via -XX:+UnlockExperimentalVMOptions.\n"
                  "Error: The unlock option must precede '%s'.\n",
                  _name, _name);
-    return;
+    return Flag::EXPERIMENTAL_FLAG_BUT_LOCKED;
   }
   if (is_develop() && is_product_build()) {
     jio_snprintf(buf, buflen, "Error: VM option '%s' is develop and is available only in debug version of VM.\n",
                  _name);
-    return;
+    return Flag::DEVELOPER_FLAG_BUT_PRODUCT_BUILD;
   }
   if (is_notproduct() && is_product_build()) {
     jio_snprintf(buf, buflen, "Error: VM option '%s' is notproduct and is available only in debug version of VM.\n",
                  _name);
-    return;
+    return Flag::NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD;
   }
   get_locked_message_ext(buf, buflen);
+  return Flag::NONE;
 }
 
 bool Flag::is_writeable() const {
--- a/hotspot/src/share/vm/runtime/globals.hpp	Tue Oct 20 14:37:59 2015 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Fri Oct 23 11:17:23 2015 -0500
@@ -282,6 +282,14 @@
     ERR_OTHER
   };
 
+  enum MsgType {
+    NONE = 0,
+    DIAGNOSTIC_FLAG_BUT_LOCKED,
+    EXPERIMENTAL_FLAG_BUT_LOCKED,
+    DEVELOPER_FLAG_BUT_PRODUCT_BUILD,
+    NOTPRODUCT_FLAG_BUT_PRODUCT_BUILD
+  };
+
   const char* _type;
   const char* _name;
   void* _addr;
@@ -367,7 +375,7 @@
 
   void unlock_diagnostic();
 
-  void get_locked_message(char*, int) const;
+  Flag::MsgType get_locked_message(char*, int) const;
   void get_locked_message_ext(char*, int) const;
 
   // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
--- a/hotspot/test/compiler/membars/DekkerTest.java	Tue Oct 20 14:37:59 2015 +0200
+++ b/hotspot/test/compiler/membars/DekkerTest.java	Fri Oct 23 11:17:23 2015 -0500
@@ -25,9 +25,9 @@
  * @test
  * @bug 8007898
  * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM DekkerTest
  * @author Martin Doerr martin DOT doerr AT sap DOT com
  *
  * Run 3 times since the failure is intermittent.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/IgnoreUnrecognizedVMOptions.java	Fri Oct 23 11:17:23 2015 -0500
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.test.lib.*;
+
+/*
+ * @test
+ * @bug 8129855
+ * @summary -XX:+IgnoreUnrecognizedVMOptions should work according to the spec from JDK-8129855
+ *
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management
+ * @run main IgnoreUnrecognizedVMOptions
+ */
+public class IgnoreUnrecognizedVMOptions {
+
+  private static void runJavaAndCheckExitValue(boolean shouldSucceed, String... args) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(args);
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    if (shouldSucceed) {
+      output.shouldHaveExitValue(0);
+    } else {
+      output.shouldHaveExitValue(1);
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    boolean product = !Platform.isDebugBuild();
+
+    /*
+      #1.1 wrong value and non-existing flag:
+                                    exists, invalid value           does not exist
+                                    -XX:MinHeapFreeRatio=notnum     -XX:THIS_FLAG_DOESNT_EXIST
+      -IgnoreUnrecognizedVMOptions               ERR                           ERR
+      +IgnoreUnrecognizedVMOptions               ERR                           OK
+    */
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:MinHeapFreeRatio=notnum", "-version");
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:THIS_FLAG_DOESNT_EXIST", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:MinHeapFreeRatio=notnum", "-version");
+    runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:THIS_FLAG_DOESNT_EXIST", "-version");
+
+    /*
+      #1.2 normal flag with ranges:
+                                      exists, in range                exists, out of range
+                                      -XX:StackRedPages=1             -XX:StackRedPages=0
+      -IgnoreUnrecognizedVMOptions               OK                            ERR
+      +IgnoreUnrecognizedVMOptions               OK                            ERR
+    */
+    runJavaAndCheckExitValue(true, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:StackRedPages=1", "-version");
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:StackRedPages=0", "-version");
+    runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:StackRedPages=1", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:StackRedPages=0", "-version");
+
+    /*
+      #1.3 develop & notproduct flag on debug VM:
+                                      develop & !product_build        notproduct & !product_build
+                                      -XX:+DeoptimizeALot             -XX:+VerifyCodeCache
+      -IgnoreUnrecognizedVMOptions               OK                            OK
+      +IgnoreUnrecognizedVMOptions               OK                            OK
+    */
+    if (!product) {
+      runJavaAndCheckExitValue(true, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:+DeoptimizeALot", "-version");
+      runJavaAndCheckExitValue(true, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:+VerifyCodeCache", "-version");
+      runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+DeoptimizeALot", "-version");
+      runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+VerifyCodeCache", "-version");
+    }
+
+    /*
+      #1.4 develop & notproduct flag on product VM:
+                                    develop & !product_build        notproduct & !product_build
+                                    -XX:+DeoptimizeALot             -XX:+VerifyCodeCache
+      -IgnoreUnrecognizedVMOptions               ERR                           ERR
+      +IgnoreUnrecognizedVMOptions               OK                            OK
+    */
+    if (product) {
+      runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:+DeoptimizeALot", "-version");
+      runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:+VerifyCodeCache", "-version");
+      runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+DeoptimizeALot", "-version");
+      runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+VerifyCodeCache", "-version");
+    }
+
+
+    /*
+      #1.5 malformed develop & notproduct flag on debug VM:
+                                  develop & !product_build          notproduct & !product_build
+                                  -XX:DeoptimizeALot                -XX:VerifyCodeCache
+      -IgnoreUnrecognizedVMOptions               ERR                           ERR
+      +IgnoreUnrecognizedVMOptions               ERR                           ERR
+    */
+    if (!product) {
+      runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:DeoptimizeALot", "-version");
+      runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:VerifyCodeCache", "-version");
+      runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:DeoptimizeALot", "-version");
+      runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:VerifyCodeCache", "-version");
+    }
+
+    /*
+      #1.6 malformed develop & notproduct flag on product VM:
+                                    develop & !product_build          .notproduct & !product_build
+                                    -XX:DeoptimizeALot                  -XX:VerifyCodeCache
+      -IgnoreUnrecognizedVMOptions               ERR                           ERR
+      +IgnoreUnrecognizedVMOptions               OK                            OK
+    */
+    if (product) {
+      runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:DeoptimizeALot", "-version");
+      runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:VerifyCodeCache", "-version");
+      runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:DeoptimizeALot", "-version");
+      runJavaAndCheckExitValue(true, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:VerifyCodeCache", "-version");
+    }
+
+    /*
+      #1.7 locked flag:
+                                      diagnostic & locked             experimental & locked             commercial & locked
+                                      -XX:-UnlockDiagnosticVMOptions  -XX:-UnlockExperimentalVMOptions  -XX:-UnlockCommercialFeatures
+                                      -XX:+PrintInlining              -XX:+AlwaysSafeConstructors       -XX:+FlightRecorder
+      -IgnoreUnrecognizedVMOptions               ERR                           ERR                                 ERR
+      +IgnoreUnrecognizedVMOptions               ERR                           ERR                                 ERR
+    */
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:+PrintInlining", "-version");
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:+AlwaysSafeConstructors", "-version");
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:+FlightRecorder", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:+PrintInlining", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:+AlwaysSafeConstructors", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:+FlightRecorder", "-version");
+
+    /*
+      #1.8 malformed locked flag:
+                                    diagnostic & locked             experimental & locked             commercial & locked
+                                    -XX:-UnlockDiagnosticVMOptions  -XX:-UnlockExperimentalVMOptions  -XX:-UnlockCommercialFeatures
+                                    -XX:PrintInlining               -XX:AlwaysSafeConstructors        -XX:FlightRecorder
+      -IgnoreUnrecognizedVMOptions               ERR                           ERR                                 ERR
+      +IgnoreUnrecognizedVMOptions               ERR                           ERR                                 ERR
+    */
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:PrintInlining", "-version");
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:AlwaysSafeConstructors", "-version");
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:FlightRecorder", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:PrintInlining", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:AlwaysSafeConstructors", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:FlightRecorder", "-version");
+
+    /*
+      #1.9 malformed unlocked flag:
+                                    diagnostic & locked             experimental & locked             commercial & locked
+                                    -XX:+UnlockDiagnosticVMOptions  -XX:+UnlockExperimentalVMOptions  -XX:+UnlockCommercialFeatures
+                                    -XX:PrintInlining               -XX:AlwaysSafeConstructors        -XX:FlightRecorder
+      -IgnoreUnrecognizedVMOptions               ERR                           ERR                                 ERR
+      +IgnoreUnrecognizedVMOptions               ERR                           ERR                                 ERR
+    */
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:PrintInlining", "-version");
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:AlwaysSafeConstructors", "-version");
+    runJavaAndCheckExitValue(false, "-XX:-IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:FlightRecorder", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockDiagnosticVMOptions", "-XX:PrintInlining", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockExperimentalVMOptions", "-XX:AlwaysSafeConstructors", "-version");
+    runJavaAndCheckExitValue(false, "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-UnlockCommercialFeatures", "-XX:FlightRecorder", "-version");
+  }
+}