Merge
authorcoleenp
Fri, 19 Jun 2015 13:03:58 +0000
changeset 31373 21f527ce09e0
parent 31372 9821df46cf47 (diff)
parent 31370 e27de7435453 (current diff)
child 31374 9280d10f1f26
Merge
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/src/share/vm/runtime/thread.cpp
hotspot/src/share/vm/services/memoryService.cpp
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -63,7 +63,7 @@
 define_pd_global(uintx, TypeProfileLevel, 111);
 
 // Platform dependent flag handling: flags only defined on this platform.
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct)  \
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint)  \
                                                                             \
   /* Load poll address from thread. This is used to implement per-thread */ \
   /* safepoints on platforms != IA64. */                                    \
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -81,7 +81,7 @@
 
 define_pd_global(uintx, TypeProfileLevel, 111);
 
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
                                                                             \
   product(intx, UseVIS, 99,                                                 \
           "Highest supported VIS instructions set on Sparc")                \
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -84,7 +84,7 @@
 
 define_pd_global(bool, PreserveFramePointer, false);
 
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
                                                                             \
   develop(bool, IEEEPrecision, true,                                        \
           "Enables IEEE precision (for INTEL only)")                        \
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -63,7 +63,8 @@
 
 define_pd_global(bool, PreserveFramePointer, false);
 
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct)  \
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint)  \
+                                                                            \
   product(bool, UseFastEmptyMethods, true,                                  \
           "Use fast method entry code for empty methods")                   \
                                                                             \
--- a/hotspot/src/os/aix/vm/globals_aix.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/os/aix/vm/globals_aix.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -29,7 +29,7 @@
 //
 // Defines Aix specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
+#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
                                                                                     \
   /* Use 64K pages for virtual memory (shmat). */                                   \
   product(bool, Use64KPages, true,                                                  \
--- a/hotspot/src/os/bsd/vm/globals_bsd.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/os/bsd/vm/globals_bsd.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -28,19 +28,20 @@
 //
 // Defines Bsd specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
-  product(bool, UseOprofile, false,                                     \
-        "enable support for Oprofile profiler")                         \
-                                                                        \
-  product(bool, UseBsdPosixThreadCPUClocks, true,                     \
-          "enable fast Bsd Posix clocks where available")             \
-/*  NB: The default value of UseBsdPosixThreadCPUClocks may be        \
-    overridden in Arguments::parse_each_vm_init_arg.  */                \
-                                                                        \
-  product(bool, UseHugeTLBFS, false,                                    \
-          "Use MAP_HUGETLB for large pages")                            \
-                                                                        \
-  product(bool, UseSHM, false,                                          \
+#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
+                                                                                \
+  product(bool, UseOprofile, false,                                             \
+        "enable support for Oprofile profiler")                                 \
+                                                                                \
+  /*  NB: The default value of UseBsdPosixThreadCPUClocks may be  */            \
+  /*  overridden in Arguments::parse_each_vm_init_arg.            */            \
+  product(bool, UseBsdPosixThreadCPUClocks, true,                               \
+          "enable fast Bsd Posix clocks where available")                       \
+                                                                                \
+  product(bool, UseHugeTLBFS, false,                                            \
+          "Use MAP_HUGETLB for large pages")                                    \
+                                                                                \
+  product(bool, UseSHM, false,                                                  \
           "Use SYSV shared memory for large pages")
 
 //
--- a/hotspot/src/os/linux/vm/globals_linux.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/os/linux/vm/globals_linux.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -28,14 +28,15 @@
 //
 // Defines Linux specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
+#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
+                                                                        \
   product(bool, UseOprofile, false,                                     \
         "enable support for Oprofile profiler")                         \
                                                                         \
+  /*  NB: The default value of UseLinuxPosixThreadCPUClocks may be   */ \
+  /* overridden in Arguments::parse_each_vm_init_arg.                */ \
   product(bool, UseLinuxPosixThreadCPUClocks, true,                     \
           "enable fast Linux Posix clocks where available")             \
-/*  NB: The default value of UseLinuxPosixThreadCPUClocks may be        \
-    overridden in Arguments::parse_each_vm_init_arg.  */                \
                                                                         \
   product(bool, UseHugeTLBFS, false,                                    \
           "Use MAP_HUGETLB for large pages")                            \
--- a/hotspot/src/os/solaris/vm/globals_solaris.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/os/solaris/vm/globals_solaris.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -28,7 +28,7 @@
 //
 // Defines Solaris specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
+#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
                                                                                \
   product(bool, UseExtendedFileIO, true,                                       \
           "Enable workaround for limitations of stdio FILE structure")
--- a/hotspot/src/os/windows/vm/globals_windows.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/os/windows/vm/globals_windows.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -28,8 +28,7 @@
 //
 // Defines Windows specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd,       \
-                         diagnostic, notproduct)                         \
+#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
                                                                          \
   product(bool, UseUTCFileTimestamp, true,                               \
           "Adjust the timestamp returned from stat() to be UTC")
--- a/hotspot/src/share/vm/c1/c1_globals.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/c1/c1_globals.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -25,4 +25,4 @@
 #include "precompiled.hpp"
 #include "c1/c1_globals.hpp"
 
-C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
+C1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG, IGNORE_RANGE, IGNORE_CONSTRAINT)
--- a/hotspot/src/share/vm/c1/c1_globals.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -60,7 +60,7 @@
 //
 // Defines all global flags used by the client compiler.
 //
-#define C1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
+#define C1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
                                                                             \
   /* Printing */                                                            \
   notproduct(bool, PrintC1Statistics, false,                                \
@@ -148,6 +148,7 @@
                                                                             \
   product(intx, ValueMapInitialSize, 11,                                    \
           "Initial size of a value map")                                    \
+          range(1, NOT_LP64(1*K) LP64_ONLY(32*K))                           \
                                                                             \
   product(intx, ValueMapMaxLoopSize, 8,                                     \
           "maximum size of a loop optimized by global value numbering")     \
@@ -191,6 +192,7 @@
                                                                             \
   develop(intx, NestedInliningSizeRatio, 90,                                \
           "Percentage of prev. allowed inline size in recursive inlining")  \
+          range(0, 100)                                                     \
                                                                             \
   notproduct(bool, PrintIRWithLIR, false,                                   \
           "Print IR instructions with generated LIR")                       \
@@ -338,10 +340,15 @@
   diagnostic(bool, C1PatchInvokeDynamic, true,                              \
              "Patch invokedynamic appendix not known at compile time")      \
                                                                             \
-
-
 // Read default values for c1 globals
 
-C1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
+C1_FLAGS(DECLARE_DEVELOPER_FLAG, \
+         DECLARE_PD_DEVELOPER_FLAG, \
+         DECLARE_PRODUCT_FLAG, \
+         DECLARE_PD_PRODUCT_FLAG, \
+         DECLARE_DIAGNOSTIC_FLAG, \
+         DECLARE_NOTPRODUCT_FLAG, \
+         IGNORE_RANGE, \
+         IGNORE_CONSTRAINT)
 
 #endif // SHARE_VM_C1_C1_GLOBALS_HPP
--- a/hotspot/src/share/vm/gc/g1/g1_globals.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -25,8 +25,14 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1_globals.hpp"
 
-G1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
-         MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG,     \
-         MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
+G1_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
+         MATERIALIZE_PD_DEVELOPER_FLAG, \
+         MATERIALIZE_PRODUCT_FLAG, \
+         MATERIALIZE_PD_PRODUCT_FLAG,     \
+         MATERIALIZE_DIAGNOSTIC_FLAG, \
+         MATERIALIZE_EXPERIMENTAL_FLAG, \
          MATERIALIZE_NOTPRODUCT_FLAG,  \
-         MATERIALIZE_MANAGEABLE_FLAG, MATERIALIZE_PRODUCT_RW_FLAG)
+         MATERIALIZE_MANAGEABLE_FLAG, \
+         MATERIALIZE_PRODUCT_RW_FLAG, \
+         IGNORE_RANGE, \
+         IGNORE_CONSTRAINT)
--- a/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -30,16 +30,19 @@
 // Defines all globals flags used by the garbage-first compiler.
 //
 
-#define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \
+#define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw, range, constraint) \
                                                                             \
   product(uintx, G1ConfidencePercent, 50,                                   \
           "Confidence level for MMU/pause predictions")                     \
+          range(0, 100)                                                     \
                                                                             \
   develop(intx, G1MarkingOverheadPercent, 0,                                \
           "Overhead of concurrent marking")                                 \
+          range(0, 100)                                                     \
                                                                             \
   develop(intx, G1MarkingVerboseLevel, 0,                                   \
           "Level (0-4) of verboseness of the marking code")                 \
+          range(0, 4)                                                       \
                                                                             \
   develop(bool, G1TraceMarkStackOverflow, false,                            \
           "If true, extra debugging code for CM restart for ovflw.")        \
@@ -68,10 +71,12 @@
   product(double, G1ConcMarkStepDurationMillis, 10.0,                       \
           "Target duration of individual concurrent marking steps "         \
           "in milliseconds.")                                               \
+          range(1.0, (double)max_uintx)                                     \
                                                                             \
   product(intx, G1RefProcDrainInterval, 10,                                 \
           "The number of discovered reference objects to process before "   \
           "draining concurrent marking work queues.")                       \
+          range(1, max_intx)                                                \
                                                                             \
   experimental(bool, G1UseConcMarkReferenceProcessing, true,                \
           "If true, enable reference discovery during concurrent "          \
@@ -89,9 +94,11 @@
           "the percentage of retained entries is over this threshold "      \
           "the buffer will be enqueued for processing. A value of 0 "       \
           "specifies that mutator threads should not do such filtering.")   \
+          range(0, 100)                                                     \
                                                                             \
   experimental(intx, G1ExpandByPercentOfAvailable, 20,                      \
           "When expanding, % of uncommitted space to claim.")               \
+          range(0, 100)                                                     \
                                                                             \
   develop(bool, G1RSBarrierRegionFilter, true,                              \
           "If true, generate region filtering code in RS barrier")          \
@@ -138,9 +145,11 @@
                                                                             \
   product(size_t, G1ConcRSLogCacheSize, 10,                                 \
           "Log base 2 of the length of conc RS hot-card cache.")            \
+          range(0, 27)                                                      \
                                                                             \
   product(uintx, G1ConcRSHotCardLimit, 4,                                   \
           "The threshold that defines (>=) a hot card.")                    \
+          range(0, max_jubyte)                                              \
                                                                             \
   develop(intx, G1RSetRegionEntriesBase, 256,                               \
           "Max number of regions in a fine-grain table per MB.")            \
@@ -183,6 +192,7 @@
   product(uintx, G1ReservePercent, 10,                                      \
           "It determines the minimum reserve we should have in the heap "   \
           "to minimize the probability of promotion failure.")              \
+          range(0, 100)                                                     \
                                                                             \
   diagnostic(bool, G1PrintHeapRegions, false,                               \
           "If set G1 will print information on which regions are being "    \
@@ -238,22 +248,27 @@
           "The number of times we'll force an overflow during "             \
           "concurrent marking")                                             \
                                                                             \
+  experimental(uintx, G1MaxNewSizePercent, 60,                              \
+          "Percentage (0-100) of the heap size to use as default "          \
+          " maximum young gen size.")                                       \
+          range(0, 100)                                                     \
+          constraint(G1MaxNewSizePercentConstraintFunc)                     \
+                                                                            \
   experimental(uintx, G1NewSizePercent, 5,                                  \
           "Percentage (0-100) of the heap size to use as default "          \
           "minimum young gen size.")                                        \
-                                                                            \
-  experimental(uintx, G1MaxNewSizePercent, 60,                              \
-          "Percentage (0-100) of the heap size to use as default "          \
-          " maximum young gen size.")                                       \
+          constraint(G1NewSizePercentConstraintFunc)                        \
                                                                             \
   experimental(uintx, G1MixedGCLiveThresholdPercent, 85,                    \
           "Threshold for regions to be considered for inclusion in the "    \
           "collection set of mixed GCs. "                                   \
           "Regions with live bytes exceeding this will not be collected.")  \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, G1HeapWastePercent, 5,                                     \
           "Amount of space, expressed as a percentage of the heap size, "   \
           "that G1 is willing not to collect to avoid expensive GCs.")      \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, G1MixedGCCountTarget, 8,                                   \
           "The target number of mixed GCs after a marking cycle.")          \
@@ -272,6 +287,7 @@
   experimental(uintx, G1OldCSetRegionThresholdPercent, 10,                  \
           "An upper bound for the number of old CSet regions expressed "    \
           "as a percentage of the heap size.")                              \
+          range(0, 100)                                                     \
                                                                             \
   experimental(ccstr, G1LogLevel, NULL,                                     \
           "Log level for G1 logging: fine, finer, finest")                  \
@@ -314,6 +330,16 @@
   develop(bool, G1VerifyBitmaps, false,                                     \
           "Verifies the consistency of the marking bitmaps")
 
-G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
+G1_FLAGS(DECLARE_DEVELOPER_FLAG, \
+         DECLARE_PD_DEVELOPER_FLAG, \
+         DECLARE_PRODUCT_FLAG, \
+         DECLARE_PD_PRODUCT_FLAG, \
+         DECLARE_DIAGNOSTIC_FLAG, \
+         DECLARE_EXPERIMENTAL_FLAG, \
+         DECLARE_NOTPRODUCT_FLAG, \
+         DECLARE_MANAGEABLE_FLAG, \
+         DECLARE_PRODUCT_RW_FLAG, \
+         IGNORE_RANGE, \
+         IGNORE_CONSTRAINT)
 
 #endif // SHARE_VM_GC_G1_G1_GLOBALS_HPP
--- a/hotspot/src/share/vm/opto/c2_globals.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/opto/c2_globals.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -25,4 +25,12 @@
 #include "precompiled.hpp"
 #include "opto/c2_globals.hpp"
 
-C2_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
+C2_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
+         MATERIALIZE_PD_DEVELOPER_FLAG, \
+         MATERIALIZE_PRODUCT_FLAG, \
+         MATERIALIZE_PD_PRODUCT_FLAG, \
+         MATERIALIZE_DIAGNOSTIC_FLAG, \
+         MATERIALIZE_EXPERIMENTAL_FLAG, \
+         MATERIALIZE_NOTPRODUCT_FLAG, \
+         IGNORE_RANGE, \
+         IGNORE_CONSTRAINT)
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -61,7 +61,7 @@
 // Defines all globals flags used by the server compiler.
 //
 
-#define C2_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct) \
+#define C2_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, range, constraint) \
                                                                             \
   develop(bool, StressLCM, false,                                           \
           "Randomize instruction scheduling in LCM")                        \
@@ -94,7 +94,8 @@
           "in generated code (in bytes)")                                   \
                                                                             \
   product(intx, MaxLoopPad, (OptoLoopAlignment-1),                          \
-          "Align a loop if padding size in bytes is less or equal to this value") \
+          "Align a loop if padding size in bytes is less or equal to this " \
+          "value")                                                          \
                                                                             \
   product(intx, MaxVectorSize, 64,                                          \
           "Max vector size in bytes, "                                      \
@@ -108,6 +109,7 @@
                                                                             \
   notproduct(intx, IndexSetWatch, 0,                                        \
           "Trace all operations on this IndexSet (-1 means all, 0 none)")   \
+          range(-1, 0)                                                      \
                                                                             \
   develop(intx, OptoNodeListSize, 4,                                        \
           "Starting allocation size of Node_List data structures")          \
@@ -361,6 +363,7 @@
           "System-wide value, 0=nothing is printed, 3=all details printed. "\
           "Level of detail of printouts can be set on a per-method level "  \
           "as well by using CompileCommand=option.")                        \
+          range(0, 3)                                                       \
                                                                             \
   develop(intx, PrintIdealGraphPort, 4444,                                  \
           "Ideal graph printer to network port")                            \
@@ -382,13 +385,16 @@
           "Insert memory barrier after arraycopy call")                     \
                                                                             \
   develop(bool, SubsumeLoads, true,                                         \
-          "Attempt to compile while subsuming loads into machine instructions.") \
+          "Attempt to compile while subsuming loads into machine "          \
+          "instructions.")                                                  \
                                                                             \
   develop(bool, StressRecompilation, false,                                 \
-          "Recompile each compiled method without subsuming loads or escape analysis.") \
+          "Recompile each compiled method without subsuming loads "         \
+          "or escape analysis.")                                            \
                                                                             \
   develop(intx, ImplicitNullCheckThreshold, 3,                              \
-          "Don't do implicit null checks if NPE's in a method exceeds limit") \
+          "Don't do implicit null checks if NPE's in a method exceeds "     \
+          "limit")                                                          \
                                                                             \
   product(intx, LoopOptsCount, 43,                                          \
           "Set level of loop optimization for tier 1 compiles")             \
@@ -534,15 +540,16 @@
           "Use edge frequencies to drive block ordering")                   \
                                                                             \
   product(intx, BlockLayoutMinDiamondPercentage, 20,                        \
-          "Miniumum %% of a successor (predecessor) for which block layout "\
-          "a will allow a fork (join) in a single chain")                   \
+          "Miniumum %% of a successor (predecessor) for which block "       \
+          "layout a will allow a fork (join) in a single chain")            \
+          range(0, 100)                                                     \
                                                                             \
   product(bool, BlockLayoutRotateLoops, true,                               \
           "Allow back branches to be fall throughs in the block layour")    \
                                                                             \
   develop(bool, InlineReflectionGetCallerClass, true,                       \
-          "inline sun.reflect.Reflection.getCallerClass(), known to be part "\
-          "of base library DLL")                                            \
+          "inline sun.reflect.Reflection.getCallerClass(), known to be "    \
+          "part of base library DLL")                                       \
                                                                             \
   develop(bool, InlineObjectCopy, true,                                     \
           "inline Object.clone and Arrays.copyOf[Range] intrinsics")        \
@@ -604,6 +611,7 @@
                                                                             \
   product(intx, TypeProfileMajorReceiverPercent, 90,                        \
           "% of major receiver type to all profiled receivers")             \
+          range(0, 100)                                                     \
                                                                             \
   diagnostic(bool, PrintIntrinsics, false,                                  \
           "prints attempted and successful inlining of intrinsics")         \
@@ -643,6 +651,8 @@
   product(intx, AliasLevel,     3,                                          \
           "0 for no aliasing, 1 for oop/field/static/array split, "         \
           "2 for class split, 3 for unique instances")                      \
+          range(0, 3)                                                       \
+          constraint(AliasLevelConstraintFunc)                              \
                                                                             \
   develop(bool, VerifyAliases, false,                                       \
           "perform extra checks on the results of alias analysis")          \
@@ -689,6 +699,14 @@
   develop(bool, StressArrayCopyMacroNode, false,                            \
           "Perform ArrayCopy load/store replacement during IGVN only")
 
-C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
+C2_FLAGS(DECLARE_DEVELOPER_FLAG, \
+         DECLARE_PD_DEVELOPER_FLAG, \
+         DECLARE_PRODUCT_FLAG, \
+         DECLARE_PD_PRODUCT_FLAG, \
+         DECLARE_DIAGNOSTIC_FLAG, \
+         DECLARE_EXPERIMENTAL_FLAG, \
+         DECLARE_NOTPRODUCT_FLAG, \
+         IGNORE_RANGE, \
+         IGNORE_CONSTRAINT)
 
 #endif // SHARE_VM_OPTO_C2_GLOBALS_HPP
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -631,27 +631,27 @@
 WB_END
 
 template <typename T>
-static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*, bool, bool)) {
+static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, Flag::Error (*TAt)(const char*, T*, bool, bool)) {
   if (name == NULL) {
     return false;
   }
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
   const char* flag_name = env->GetStringUTFChars(name, NULL);
-  bool result = (*TAt)(flag_name, value, true, true);
+  Flag::Error result = (*TAt)(flag_name, value, true, true);
   env->ReleaseStringUTFChars(name, flag_name);
-  return result;
+  return (result == Flag::SUCCESS);
 }
 
 template <typename T>
-static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAtPut)(const char*, T*, Flag::Flags)) {
+static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, Flag::Error (*TAtPut)(const char*, T*, Flag::Flags)) {
   if (name == NULL) {
     return false;
   }
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
   const char* flag_name = env->GetStringUTFChars(name, NULL);
-  bool result = (*TAtPut)(flag_name, value, Flag::INTERNAL);
+  Flag::Error result = (*TAtPut)(flag_name, value, Flag::INTERNAL);
   env->ReleaseStringUTFChars(name, flag_name);
-  return result;
+  return (result == Flag::SUCCESS);
 }
 
 template <typename T>
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -38,6 +38,9 @@
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/arguments_ext.hpp"
+#include "runtime/commandLineFlagConstraintList.hpp"
+#include "runtime/commandLineFlagRangeList.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
@@ -187,7 +190,6 @@
 
 // Initialize system properties key and value.
 void Arguments::init_system_properties() {
-
   PropertyList_add(&_system_properties, new SystemProperty("java.vm.specification.name",
                                                                  "Java Virtual Machine Specification",  false));
   PropertyList_add(&_system_properties, new SystemProperty("java.vm.version", VM_Version::vm_release(),  false));
@@ -215,8 +217,7 @@
   os::init_system_properties_values();
 }
 
-
-  // Update/Initialize System properties after JDK version number is known
+// Update/Initialize System properties after JDK version number is known
 void Arguments::init_version_specific_system_properties() {
   enum { bufsz = 16 };
   char buffer[bufsz];
@@ -569,7 +570,11 @@
 }
 
 static bool set_bool_flag(char* name, bool value, Flag::Flags origin) {
-  return CommandLineFlags::boolAtPut(name, &value, origin);
+  if (CommandLineFlags::boolAtPut(name, &value, origin) == Flag::SUCCESS) {
+    return true;
+  } else {
+    return false;
+  }
 }
 
 static bool set_fp_numeric_flag(char* name, char* value, Flag::Flags origin) {
@@ -578,7 +583,7 @@
     return false;
   }
 
-  if (CommandLineFlags::doubleAtPut(name, &v, origin)) {
+  if (CommandLineFlags::doubleAtPut(name, &v, origin) == Flag::SUCCESS) {
     return true;
   }
   return false;
@@ -591,7 +596,7 @@
   bool is_neg = false;
   // Check the sign first since atomull() parses only unsigned values.
   if (*value == '-') {
-    if (!CommandLineFlags::intxAt(name, &intx_v) && !CommandLineFlags::intAt(name, &int_v)) {
+    if ((CommandLineFlags::intxAt(name, &intx_v) != Flag::SUCCESS) && (CommandLineFlags::intAt(name, &int_v) != Flag::SUCCESS)) {
       return false;
     }
     value++;
@@ -604,37 +609,37 @@
   if (is_neg) {
     int_v = -int_v;
   }
-  if (CommandLineFlags::intAtPut(name, &int_v, origin)) {
+  if (CommandLineFlags::intAtPut(name, &int_v, origin) == Flag::SUCCESS) {
     return true;
   }
   uint uint_v = (uint) v;
-  if (!is_neg && CommandLineFlags::uintAtPut(name, &uint_v, origin)) {
+  if (!is_neg && CommandLineFlags::uintAtPut(name, &uint_v, origin) == Flag::SUCCESS) {
     return true;
   }
   intx_v = (intx) v;
   if (is_neg) {
     intx_v = -intx_v;
   }
-  if (CommandLineFlags::intxAtPut(name, &intx_v, origin)) {
+  if (CommandLineFlags::intxAtPut(name, &intx_v, origin) == Flag::SUCCESS) {
     return true;
   }
   uintx uintx_v = (uintx) v;
-  if (!is_neg && CommandLineFlags::uintxAtPut(name, &uintx_v, origin)) {
+  if (!is_neg && (CommandLineFlags::uintxAtPut(name, &uintx_v, origin) == Flag::SUCCESS)) {
     return true;
   }
   uint64_t uint64_t_v = (uint64_t) v;
-  if (!is_neg && CommandLineFlags::uint64_tAtPut(name, &uint64_t_v, origin)) {
+  if (!is_neg && (CommandLineFlags::uint64_tAtPut(name, &uint64_t_v, origin) == Flag::SUCCESS)) {
     return true;
   }
   size_t size_t_v = (size_t) v;
-  if (!is_neg && CommandLineFlags::size_tAtPut(name, &size_t_v, origin)) {
+  if (!is_neg && (CommandLineFlags::size_tAtPut(name, &size_t_v, origin) == Flag::SUCCESS)) {
     return true;
   }
   return false;
 }
 
 static bool set_string_flag(char* name, const char* value, Flag::Flags origin) {
-  if (!CommandLineFlags::ccstrAtPut(name, &value, origin))  return false;
+  if (CommandLineFlags::ccstrAtPut(name, &value, origin) != Flag::SUCCESS) return false;
   // Contract:  CommandLineFlags always returns a pointer that needs freeing.
   FREE_C_HEAP_ARRAY(char, value);
   return true;
@@ -642,7 +647,7 @@
 
 static bool append_to_string_flag(char* name, const char* new_value, Flag::Flags origin) {
   const char* old_value = "";
-  if (!CommandLineFlags::ccstrAt(name, &old_value))  return false;
+  if (CommandLineFlags::ccstrAt(name, &old_value) != Flag::SUCCESS) return false;
   size_t old_len = old_value != NULL ? strlen(old_value) : 0;
   size_t new_len = strlen(new_value);
   const char* value;
@@ -1413,61 +1418,16 @@
   // Oop encoding heap max
   OopEncodingHeapMax = (uint64_t(max_juint) + 1) << LogMinObjAlignmentInBytes;
 
+  if (SurvivorAlignmentInBytes == 0) {
+    SurvivorAlignmentInBytes = ObjectAlignmentInBytes;
+  }
+
 #if INCLUDE_ALL_GCS
   // Set CMS global values
   CompactibleFreeListSpace::set_cms_values();
 #endif // INCLUDE_ALL_GCS
 }
 
-bool verify_object_alignment() {
-  // Object alignment.
-  if (!is_power_of_2(ObjectAlignmentInBytes)) {
-    jio_fprintf(defaultStream::error_stream(),
-                "error: ObjectAlignmentInBytes=%d must be power of 2\n",
-                (int)ObjectAlignmentInBytes);
-    return false;
-  }
-  if ((int)ObjectAlignmentInBytes < BytesPerLong) {
-    jio_fprintf(defaultStream::error_stream(),
-                "error: ObjectAlignmentInBytes=%d must be greater or equal %d\n",
-                (int)ObjectAlignmentInBytes, BytesPerLong);
-    return false;
-  }
-  // It does not make sense to have big object alignment
-  // since a space lost due to alignment will be greater
-  // then a saved space from compressed oops.
-  if ((int)ObjectAlignmentInBytes > 256) {
-    jio_fprintf(defaultStream::error_stream(),
-                "error: ObjectAlignmentInBytes=%d must not be greater than 256\n",
-                (int)ObjectAlignmentInBytes);
-    return false;
-  }
-  // In case page size is very small.
-  if ((int)ObjectAlignmentInBytes >= os::vm_page_size()) {
-    jio_fprintf(defaultStream::error_stream(),
-                "error: ObjectAlignmentInBytes=%d must be less than page size %d\n",
-                (int)ObjectAlignmentInBytes, os::vm_page_size());
-    return false;
-  }
-  if(SurvivorAlignmentInBytes == 0) {
-    SurvivorAlignmentInBytes = ObjectAlignmentInBytes;
-  } else {
-    if (!is_power_of_2(SurvivorAlignmentInBytes)) {
-      jio_fprintf(defaultStream::error_stream(),
-            "error: SurvivorAlignmentInBytes=%d must be power of 2\n",
-            (int)SurvivorAlignmentInBytes);
-      return false;
-    }
-    if (SurvivorAlignmentInBytes < ObjectAlignmentInBytes) {
-      jio_fprintf(defaultStream::error_stream(),
-          "error: SurvivorAlignmentInBytes=%d must be greater than ObjectAlignmentInBytes=%d \n",
-          (int)SurvivorAlignmentInBytes, (int)ObjectAlignmentInBytes);
-      return false;
-    }
-  }
-  return true;
-}
-
 size_t Arguments::max_heap_for_compressed_oops() {
   // Avoid sign flip.
   assert(OopEncodingHeapMax > (uint64_t)os::vm_page_size(), "Unusual page size");
@@ -1950,42 +1910,6 @@
 //===========================================================================================================
 // Parsing of main arguments
 
-bool Arguments::verify_interval(uintx val, uintx min,
-                                uintx max, const char* name) {
-  // Returns true iff value is in the inclusive interval [min..max]
-  // false, otherwise.
-  if (val >= min && val <= max) {
-    return true;
-  }
-  jio_fprintf(defaultStream::error_stream(),
-              "%s of " UINTX_FORMAT " is invalid; must be between " UINTX_FORMAT
-              " and " UINTX_FORMAT "\n",
-              name, val, min, max);
-  return false;
-}
-
-bool Arguments::verify_min_value(intx val, intx min, const char* name) {
-  // Returns true if given value is at least specified min threshold
-  // false, otherwise.
-  if (val >= min ) {
-      return true;
-  }
-  jio_fprintf(defaultStream::error_stream(),
-              "%s of " INTX_FORMAT " is invalid; must be at least " INTX_FORMAT "\n",
-              name, val, min);
-  return false;
-}
-
-bool Arguments::verify_percentage(uintx value, const char* name) {
-  if (is_percentage(value)) {
-    return true;
-  }
-  jio_fprintf(defaultStream::error_stream(),
-              "%s of " UINTX_FORMAT " is invalid; must be between 0 and 100\n",
-              name, value);
-  return false;
-}
-
 // check if do gclog rotation
 // +UseGCLogFileRotation is a must,
 // no gc log rotation when log file not supplied or
@@ -2002,9 +1926,10 @@
   }
 
   if (UseGCLogFileRotation && (GCLogFileSize != 0) && (GCLogFileSize < 8*K)) {
-    FLAG_SET_CMDLINE(size_t, GCLogFileSize, 8*K);
-    jio_fprintf(defaultStream::output_stream(),
+    if (FLAG_SET_CMDLINE(size_t, GCLogFileSize, 8*K) == Flag::SUCCESS) {
+      jio_fprintf(defaultStream::output_stream(),
                 "GCLogFileSize changed to minimum 8K\n");
+    }
   }
 }
 
@@ -2053,38 +1978,6 @@
   return count_p < 2 && count_t < 2;
 }
 
-bool Arguments::verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio) {
-  if (!is_percentage(min_heap_free_ratio)) {
-    err_msg.print("MinHeapFreeRatio must have a value between 0 and 100");
-    return false;
-  }
-  if (min_heap_free_ratio > MaxHeapFreeRatio) {
-    err_msg.print("MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
-                  "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")", min_heap_free_ratio,
-                  MaxHeapFreeRatio);
-    return false;
-  }
-  // This does not set the flag itself, but stores the value in a safe place for later usage.
-  _min_heap_free_ratio = min_heap_free_ratio;
-  return true;
-}
-
-bool Arguments::verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio) {
-  if (!is_percentage(max_heap_free_ratio)) {
-    err_msg.print("MaxHeapFreeRatio must have a value between 0 and 100");
-    return false;
-  }
-  if (max_heap_free_ratio < MinHeapFreeRatio) {
-    err_msg.print("MaxHeapFreeRatio (" UINTX_FORMAT ") must be greater than or "
-                  "equal to MinHeapFreeRatio (" UINTX_FORMAT ")", max_heap_free_ratio,
-                  MinHeapFreeRatio);
-    return false;
-  }
-  // This does not set the flag itself, but stores the value in a safe place for later usage.
-  _max_heap_free_ratio = max_heap_free_ratio;
-  return true;
-}
-
 // Check consistency of GC selection
 bool Arguments::check_gc_consistency() {
   check_gclog_consistency();
@@ -2132,17 +2025,6 @@
   }
 }
 
-// Check stack pages settings
-bool Arguments::check_stack_pages()
-{
-  bool status = true;
-  status = status && verify_min_value(StackYellowPages, 1, "StackYellowPages");
-  status = status && verify_min_value(StackRedPages, 1, "StackRedPages");
-  // greater stack shadow pages can't generate instruction to bang stack
-  status = status && verify_interval(StackShadowPages, 1, 50, "StackShadowPages");
-  return status;
-}
-
 // Check the consistency of vm_init_args
 bool Arguments::check_vm_args_consistency() {
   // Method for adding checks for flag consistency.
@@ -2159,50 +2041,6 @@
     status = false;
   }
 
-  status = status && verify_interval(AdaptiveSizePolicyWeight, 0, 100,
-                              "AdaptiveSizePolicyWeight");
-  status = status && verify_percentage(ThresholdTolerance, "ThresholdTolerance");
-
-  // Divide by bucket size to prevent a large size from causing rollover when
-  // calculating amount of memory needed to be allocated for the String table.
-  status = status && verify_interval(StringTableSize, minimumStringTableSize,
-    (max_uintx / StringTable::bucket_size()), "StringTable size");
-
-  status = status && verify_interval(SymbolTableSize, minimumSymbolTableSize,
-    (max_uintx / SymbolTable::bucket_size()), "SymbolTable size");
-
-  {
-    // Using "else if" below to avoid printing two error messages if min > max.
-    // This will also prevent us from reporting both min>100 and max>100 at the
-    // same time, but that is less annoying than printing two identical errors IMHO.
-    FormatBuffer<80> err_msg("%s","");
-    if (!verify_MinHeapFreeRatio(err_msg, MinHeapFreeRatio)) {
-      jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer());
-      status = false;
-    } else if (!verify_MaxHeapFreeRatio(err_msg, MaxHeapFreeRatio)) {
-      jio_fprintf(defaultStream::error_stream(), "%s\n", err_msg.buffer());
-      status = false;
-    }
-  }
-
-  // Min/MaxMetaspaceFreeRatio
-  status = status && verify_percentage(MinMetaspaceFreeRatio, "MinMetaspaceFreeRatio");
-  status = status && verify_percentage(MaxMetaspaceFreeRatio, "MaxMetaspaceFreeRatio");
-
-  if (MinMetaspaceFreeRatio > MaxMetaspaceFreeRatio) {
-    jio_fprintf(defaultStream::error_stream(),
-                "MinMetaspaceFreeRatio (%s" UINTX_FORMAT ") must be less than or "
-                "equal to MaxMetaspaceFreeRatio (%s" UINTX_FORMAT ")\n",
-                FLAG_IS_DEFAULT(MinMetaspaceFreeRatio) ? "Default: " : "",
-                MinMetaspaceFreeRatio,
-                FLAG_IS_DEFAULT(MaxMetaspaceFreeRatio) ? "Default: " : "",
-                MaxMetaspaceFreeRatio);
-    status = false;
-  }
-
-  // Trying to keep 100% free is not practical
-  MinMetaspaceFreeRatio = MIN2(MinMetaspaceFreeRatio, (uintx) 99);
-
   if (FullGCALot && FLAG_IS_DEFAULT(MarkSweepAlwaysCompactCount)) {
     MarkSweepAlwaysCompactCount = 1;  // Move objects every gc.
   }
@@ -2210,10 +2048,14 @@
   if (UseParallelOldGC && ParallelOldGCSplitALot) {
     // Settings to encourage splitting.
     if (!FLAG_IS_CMDLINE(NewRatio)) {
-      FLAG_SET_CMDLINE(uintx, NewRatio, 2);
+      if (FLAG_SET_CMDLINE(uintx, NewRatio, 2) != Flag::SUCCESS) {
+        status = false;
+      }
     }
     if (!FLAG_IS_CMDLINE(ScavengeBeforeFullGC)) {
-      FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
+      if (FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false) != Flag::SUCCESS) {
+        status = false;
+      }
     }
   }
 
@@ -2221,18 +2063,12 @@
     FLAG_SET_DEFAULT(ScavengeBeforeFullGC, false);
   }
 
-  status = status && verify_percentage(GCHeapFreeLimit, "GCHeapFreeLimit");
-  status = status && verify_percentage(GCTimeLimit, "GCTimeLimit");
   if (GCTimeLimit == 100) {
     // Turn off gc-overhead-limit-exceeded checks
     FLAG_SET_DEFAULT(UseGCOverheadLimit, false);
   }
 
   status = status && check_gc_consistency();
-  status = status && check_stack_pages();
-
-  status = status && verify_percentage(CMSIncrementalSafetyFactor,
-                                    "CMSIncrementalSafetyFactor");
 
   // CMS space iteration, which FLSVerifyAllHeapreferences entails,
   // insists that we hold the requisite locks so that the iteration is
@@ -2266,132 +2102,6 @@
     status = false;
   }
 
-  status = status && verify_min_value(ParGCArrayScanChunk, 1, "ParGCArrayScanChunk");
-
-#if INCLUDE_ALL_GCS
-  if (UseG1GC) {
-    status = status && verify_percentage(G1NewSizePercent, "G1NewSizePercent");
-    status = status && verify_percentage(G1MaxNewSizePercent, "G1MaxNewSizePercent");
-    status = status && verify_interval(G1NewSizePercent, 0, G1MaxNewSizePercent, "G1NewSizePercent");
-
-    status = status && verify_percentage(G1ConfidencePercent, "G1ConfidencePercent");
-    status = status && verify_percentage(InitiatingHeapOccupancyPercent,
-                                         "InitiatingHeapOccupancyPercent");
-    status = status && verify_min_value(G1RefProcDrainInterval, 1,
-                                        "G1RefProcDrainInterval");
-    status = status && verify_min_value((intx)G1ConcMarkStepDurationMillis, 1,
-                                        "G1ConcMarkStepDurationMillis");
-    status = status && verify_interval(G1ConcRSHotCardLimit, 0, max_jubyte,
-                                       "G1ConcRSHotCardLimit");
-    status = status && verify_interval(G1ConcRSLogCacheSize, 0, 27,
-                                       "G1ConcRSLogCacheSize");
-    status = status && verify_interval(StringDeduplicationAgeThreshold, 1, markOopDesc::max_age,
-                                       "StringDeduplicationAgeThreshold");
-  }
-  if (UseConcMarkSweepGC) {
-    status = status && verify_min_value(CMSOldPLABNumRefills, 1, "CMSOldPLABNumRefills");
-    status = status && verify_min_value(CMSOldPLABToleranceFactor, 1, "CMSOldPLABToleranceFactor");
-    status = status && verify_min_value(CMSOldPLABMax, 1, "CMSOldPLABMax");
-    status = status && verify_interval(CMSOldPLABMin, 1, CMSOldPLABMax, "CMSOldPLABMin");
-
-    status = status && verify_min_value(CMSYoungGenPerWorker, 1, "CMSYoungGenPerWorker");
-
-    status = status && verify_min_value(CMSSamplingGrain, 1, "CMSSamplingGrain");
-    status = status && verify_interval(CMS_SweepWeight, 0, 100, "CMS_SweepWeight");
-    status = status && verify_interval(CMS_FLSWeight, 0, 100, "CMS_FLSWeight");
-
-    status = status && verify_interval(FLSCoalescePolicy, 0, 4, "FLSCoalescePolicy");
-
-    status = status && verify_min_value(CMSRescanMultiple, 1, "CMSRescanMultiple");
-    status = status && verify_min_value(CMSConcMarkMultiple, 1, "CMSConcMarkMultiple");
-
-    status = status && verify_interval(CMSPrecleanIter, 0, 9, "CMSPrecleanIter");
-    status = status && verify_min_value(CMSPrecleanDenominator, 1, "CMSPrecleanDenominator");
-    status = status && verify_interval(CMSPrecleanNumerator, 0, CMSPrecleanDenominator - 1, "CMSPrecleanNumerator");
-
-    status = status && verify_percentage(CMSBootstrapOccupancy, "CMSBootstrapOccupancy");
-
-    status = status && verify_min_value(CMSPrecleanThreshold, 100, "CMSPrecleanThreshold");
-
-    status = status && verify_percentage(CMSScheduleRemarkEdenPenetration, "CMSScheduleRemarkEdenPenetration");
-    status = status && verify_min_value(CMSScheduleRemarkSamplingRatio, 1, "CMSScheduleRemarkSamplingRatio");
-    status = status && verify_min_value(CMSBitMapYieldQuantum, 1, "CMSBitMapYieldQuantum");
-    status = status && verify_percentage(CMSTriggerRatio, "CMSTriggerRatio");
-    status = status && verify_percentage(CMSIsTooFullPercentage, "CMSIsTooFullPercentage");
-  }
-
-  if (UseParallelGC || UseParallelOldGC) {
-    status = status && verify_interval(ParallelOldDeadWoodLimiterMean, 0, 100, "ParallelOldDeadWoodLimiterMean");
-    status = status && verify_interval(ParallelOldDeadWoodLimiterStdDev, 0, 100, "ParallelOldDeadWoodLimiterStdDev");
-
-    status = status && verify_percentage(YoungGenerationSizeIncrement, "YoungGenerationSizeIncrement");
-    status = status && verify_percentage(TenuredGenerationSizeIncrement, "TenuredGenerationSizeIncrement");
-
-    status = status && verify_min_value(YoungGenerationSizeSupplementDecay, 1, "YoungGenerationSizeSupplementDecay");
-    status = status && verify_min_value(TenuredGenerationSizeSupplementDecay, 1, "TenuredGenerationSizeSupplementDecay");
-
-    status = status && verify_min_value(ParGCCardsPerStrideChunk, 1, "ParGCCardsPerStrideChunk");
-
-    status = status && verify_min_value(ParallelOldGCSplitInterval, 0, "ParallelOldGCSplitInterval");
-  }
-#endif // INCLUDE_ALL_GCS
-
-  status = status && verify_interval(RefDiscoveryPolicy,
-                                     ReferenceProcessor::DiscoveryPolicyMin,
-                                     ReferenceProcessor::DiscoveryPolicyMax,
-                                     "RefDiscoveryPolicy");
-
-  // Limit the lower bound of this flag to 1 as it is used in a division
-  // expression.
-  status = status && verify_interval(TLABWasteTargetPercent,
-                                     1, 100, "TLABWasteTargetPercent");
-
-  status = status && verify_object_alignment();
-
-  status = status && verify_interval(CompressedClassSpaceSize, 1*M, 3*G,
-                                      "CompressedClassSpaceSize");
-
-  status = status && verify_interval(MarkStackSizeMax,
-                                  1, (max_jint - 1), "MarkStackSizeMax");
-  status = status && verify_interval(NUMAChunkResizeWeight, 0, 100, "NUMAChunkResizeWeight");
-
-  status = status && verify_min_value(LogEventsBufferEntries, 1, "LogEventsBufferEntries");
-
-  status = status && verify_min_value(HeapSizePerGCThread, (size_t) os::vm_page_size(), "HeapSizePerGCThread");
-
-  status = status && verify_min_value(GCTaskTimeStampEntries, 1, "GCTaskTimeStampEntries");
-
-  status = status && verify_percentage(ParallelGCBufferWastePct, "ParallelGCBufferWastePct");
-  status = status && verify_interval(TargetPLABWastePct, 1, 100, "TargetPLABWastePct");
-
-  status = status && verify_min_value(ParGCStridesPerThread, 1, "ParGCStridesPerThread");
-
-  status = status && verify_min_value(MinRAMFraction, 1, "MinRAMFraction");
-  status = status && verify_min_value(InitialRAMFraction, 1, "InitialRAMFraction");
-  status = status && verify_min_value(MaxRAMFraction, 1, "MaxRAMFraction");
-  status = status && verify_min_value(DefaultMaxRAMFraction, 1, "DefaultMaxRAMFraction");
-
-  status = status && verify_interval(AdaptiveTimeWeight, 0, 100, "AdaptiveTimeWeight");
-  status = status && verify_min_value(AdaptiveSizeDecrementScaleFactor, 1, "AdaptiveSizeDecrementScaleFactor");
-
-  status = status && verify_interval(TLABAllocationWeight, 0, 100, "TLABAllocationWeight");
-  status = status && verify_min_value(MinTLABSize, 1, "MinTLABSize");
-  status = status && verify_min_value(TLABRefillWasteFraction, 1, "TLABRefillWasteFraction");
-
-  status = status && verify_percentage(YoungGenerationSizeSupplement, "YoungGenerationSizeSupplement");
-  status = status && verify_percentage(TenuredGenerationSizeSupplement, "TenuredGenerationSizeSupplement");
-
-  status = status && verify_interval(MaxTenuringThreshold, 0, markOopDesc::max_age + 1, "MaxTenuringThreshold");
-  status = status && verify_interval(InitialTenuringThreshold, 0, MaxTenuringThreshold, "InitialTenuringThreshold");
-  status = status && verify_percentage(TargetSurvivorRatio, "TargetSurvivorRatio");
-  status = status && verify_percentage(MarkSweepDeadRatio, "MarkSweepDeadRatio");
-
-  status = status && verify_min_value(MarkSweepAlwaysCompactCount, 1, "MarkSweepAlwaysCompactCount");
-#ifdef COMPILER1
-  status = status && verify_min_value(ValueMapInitialSize, 1, "ValueMapInitialSize");
-#endif
-  status = status && verify_min_value(HeapSearchSteps, 1, "HeapSearchSteps");
-
   if (PrintNMTStatistics) {
 #if INCLUDE_NMT
     if (MemTracker::tracking_level() == NMT_off) {
@@ -2403,26 +2113,6 @@
 #endif
   }
 
-  // Need to limit the extent of the padding to reasonable size.
-  // 8K is well beyond the reasonable HW cache line size, even with the
-  // aggressive prefetching, while still leaving the room for segregating
-  // among the distinct pages.
-  if (ContendedPaddingWidth < 0 || ContendedPaddingWidth > 8192) {
-    jio_fprintf(defaultStream::error_stream(),
-                "ContendedPaddingWidth=" INTX_FORMAT " must be in between %d and %d\n",
-                ContendedPaddingWidth, 0, 8192);
-    status = false;
-  }
-
-  // Need to enforce the padding not to break the existing field alignments.
-  // It is sufficient to check against the largest type size.
-  if ((ContendedPaddingWidth % BytesPerLong) != 0) {
-    jio_fprintf(defaultStream::error_stream(),
-                "ContendedPaddingWidth=" INTX_FORMAT " must be a multiple of %d\n",
-                ContendedPaddingWidth, BytesPerLong);
-    status = false;
-  }
-
   // Check lower bounds of the code cache
   // Template Interpreter code is approximately 3X larger in debug builds.
   uint min_code_cache_size = CodeCacheMinimumUseSpace DEBUG_ONLY(* 3);
@@ -2461,17 +2151,9 @@
     status = false;
   }
 
-  status &= verify_interval(NmethodSweepActivity, 0, 2000, "NmethodSweepActivity");
-  status &= verify_interval(CodeCacheMinBlockLength, 1, 100, "CodeCacheMinBlockLength");
-  status &= verify_interval(CodeCacheSegmentSize, 1, 1024, "CodeCacheSegmentSize");
-  status &= verify_interval(StartAggressiveSweepingAt, 0, 100, "StartAggressiveSweepingAt");
-
-
   int min_number_of_compiler_threads = get_min_number_of_compiler_threads();
   // The default CICompilerCount's value is CI_COMPILER_COUNT.
   assert(min_number_of_compiler_threads <= CI_COMPILER_COUNT, "minimum should be less or equal default number");
-  // Check the minimum number of compiler threads
-  status &=verify_min_value(CICompilerCount, min_number_of_compiler_threads, "CICompilerCount");
 
   if (!FLAG_IS_DEFAULT(CICompilerCount) && !FLAG_IS_DEFAULT(CICompilerCountPerCPU) && CICompilerCountPerCPU) {
     warning("The VM option CICompilerCountPerCPU overrides CICompilerCount.");
@@ -2664,12 +2346,20 @@
     // -verbose:[class/gc/jni]
     if (match_option(option, "-verbose", &tail)) {
       if (!strcmp(tail, ":class") || !strcmp(tail, "")) {
-        FLAG_SET_CMDLINE(bool, TraceClassLoading, true);
-        FLAG_SET_CMDLINE(bool, TraceClassUnloading, true);
+        if (FLAG_SET_CMDLINE(bool, TraceClassLoading, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
+        if (FLAG_SET_CMDLINE(bool, TraceClassUnloading, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       } else if (!strcmp(tail, ":gc")) {
-        FLAG_SET_CMDLINE(bool, PrintGC, true);
+        if (FLAG_SET_CMDLINE(bool, PrintGC, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       } else if (!strcmp(tail, ":jni")) {
-        FLAG_SET_CMDLINE(bool, PrintJNIResolving, true);
+        if (FLAG_SET_CMDLINE(bool, PrintJNIResolving, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       }
     // -da / -ea / -disableassertions / -enableassertions
     // These accept an optional class/package name separated by a colon, e.g.,
@@ -2756,16 +2446,24 @@
 #endif // !INCLUDE_JVMTI
     // -Xnoclassgc
     } else if (match_option(option, "-Xnoclassgc")) {
-      FLAG_SET_CMDLINE(bool, ClassUnloading, false);
+      if (FLAG_SET_CMDLINE(bool, ClassUnloading, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xconcgc
     } else if (match_option(option, "-Xconcgc")) {
-      FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true);
+      if (FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xnoconcgc
     } else if (match_option(option, "-Xnoconcgc")) {
-      FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false);
+      if (FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xbatch
     } else if (match_option(option, "-Xbatch")) {
-      FLAG_SET_CMDLINE(bool, BackgroundCompilation, false);
+      if (FLAG_SET_CMDLINE(bool, BackgroundCompilation, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xmn for compatibility with other JVM vendors
     } else if (match_option(option, "-Xmn", &tail)) {
       julong long_initial_young_size = 0;
@@ -2776,8 +2474,12 @@
         describe_range_error(errcode);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(size_t, MaxNewSize, (size_t)long_initial_young_size);
-      FLAG_SET_CMDLINE(size_t, NewSize, (size_t)long_initial_young_size);
+      if (FLAG_SET_CMDLINE(size_t, MaxNewSize, (size_t)long_initial_young_size) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(size_t, NewSize, (size_t)long_initial_young_size) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xms
     } else if (match_option(option, "-Xms", &tail)) {
       julong long_initial_heap_size = 0;
@@ -2792,7 +2494,9 @@
       set_min_heap_size((size_t)long_initial_heap_size);
       // Currently the minimum size and the initial heap sizes are the same.
       // Can be overridden with -XX:InitialHeapSize.
-      FLAG_SET_CMDLINE(size_t, InitialHeapSize, (size_t)long_initial_heap_size);
+      if (FLAG_SET_CMDLINE(size_t, InitialHeapSize, (size_t)long_initial_heap_size) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xmx
     } else if (match_option(option, "-Xmx", &tail) || match_option(option, "-XX:MaxHeapSize=", &tail)) {
       julong long_max_heap_size = 0;
@@ -2803,30 +2507,36 @@
         describe_range_error(errcode);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(size_t, MaxHeapSize, (size_t)long_max_heap_size);
+      if (FLAG_SET_CMDLINE(size_t, MaxHeapSize, (size_t)long_max_heap_size) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // Xmaxf
     } else if (match_option(option, "-Xmaxf", &tail)) {
       char* err;
       int maxf = (int)(strtod(tail, &err) * 100);
-      if (*err != '\0' || *tail == '\0' || maxf < 0 || maxf > 100) {
+      if (*err != '\0' || *tail == '\0') {
         jio_fprintf(defaultStream::error_stream(),
                     "Bad max heap free percentage size: %s\n",
                     option->optionString);
         return JNI_EINVAL;
       } else {
-        FLAG_SET_CMDLINE(uintx, MaxHeapFreeRatio, maxf);
+        if (FLAG_SET_CMDLINE(uintx, MaxHeapFreeRatio, maxf) != Flag::SUCCESS) {
+            return JNI_EINVAL;
+        }
       }
     // Xminf
     } else if (match_option(option, "-Xminf", &tail)) {
       char* err;
       int minf = (int)(strtod(tail, &err) * 100);
-      if (*err != '\0' || *tail == '\0' || minf < 0 || minf > 100) {
+      if (*err != '\0' || *tail == '\0') {
         jio_fprintf(defaultStream::error_stream(),
                     "Bad min heap free percentage size: %s\n",
                     option->optionString);
         return JNI_EINVAL;
       } else {
-        FLAG_SET_CMDLINE(uintx, MinHeapFreeRatio, minf);
+        if (FLAG_SET_CMDLINE(uintx, MinHeapFreeRatio, minf) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       }
     // -Xss
     } else if (match_option(option, "-Xss", &tail)) {
@@ -2839,8 +2549,10 @@
         return JNI_EINVAL;
       }
       // Internally track ThreadStackSize in units of 1024 bytes.
-      FLAG_SET_CMDLINE(intx, ThreadStackSize,
-                              round_to((int)long_ThreadStackSize, K) / K);
+      if (FLAG_SET_CMDLINE(intx, ThreadStackSize,
+                       round_to((int)long_ThreadStackSize, K) / K) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xoss
     } else if (match_option(option, "-Xoss", &tail)) {
           // HotSpot does not have separate native and Java stacks, ignore silently for compatibility
@@ -2853,7 +2565,9 @@
                    os::vm_page_size()/K);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(uintx, CodeCacheExpansionSize, (uintx)long_CodeCacheExpansionSize);
+      if (FLAG_SET_CMDLINE(uintx, CodeCacheExpansionSize, (uintx)long_CodeCacheExpansionSize) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
                match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
       julong long_ReservedCodeCacheSize = 0;
@@ -2864,7 +2578,9 @@
                     "Invalid maximum code cache size: %s.\n", option->optionString);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize);
+      if (FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
       // -XX:NonNMethodCodeHeapSize=
     } else if (match_option(option, "-XX:NonNMethodCodeHeapSize=", &tail)) {
       julong long_NonNMethodCodeHeapSize = 0;
@@ -2875,7 +2591,9 @@
                     "Invalid maximum non-nmethod code heap size: %s.\n", option->optionString);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(uintx, NonNMethodCodeHeapSize, (uintx)long_NonNMethodCodeHeapSize);
+      if (FLAG_SET_CMDLINE(uintx, NonNMethodCodeHeapSize, (uintx)long_NonNMethodCodeHeapSize) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
       // -XX:ProfiledCodeHeapSize=
     } else if (match_option(option, "-XX:ProfiledCodeHeapSize=", &tail)) {
       julong long_ProfiledCodeHeapSize = 0;
@@ -2886,7 +2604,9 @@
                     "Invalid maximum profiled code heap size: %s.\n", option->optionString);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(uintx, ProfiledCodeHeapSize, (uintx)long_ProfiledCodeHeapSize);
+      if (FLAG_SET_CMDLINE(uintx, ProfiledCodeHeapSize, (uintx)long_ProfiledCodeHeapSize) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
       // -XX:NonProfiledCodeHeapSizee=
     } else if (match_option(option, "-XX:NonProfiledCodeHeapSize=", &tail)) {
       julong long_NonProfiledCodeHeapSize = 0;
@@ -2897,17 +2617,9 @@
                     "Invalid maximum non-profiled code heap size: %s.\n", option->optionString);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(uintx, NonProfiledCodeHeapSize, (uintx)long_NonProfiledCodeHeapSize);
-      //-XX:IncreaseFirstTierCompileThresholdAt=
-    } else if (match_option(option, "-XX:IncreaseFirstTierCompileThresholdAt=", &tail)) {
-        uintx uint_IncreaseFirstTierCompileThresholdAt = 0;
-        if (!parse_uintx(tail, &uint_IncreaseFirstTierCompileThresholdAt, 0) || uint_IncreaseFirstTierCompileThresholdAt > 99) {
-          jio_fprintf(defaultStream::error_stream(),
-                      "Invalid value for IncreaseFirstTierCompileThresholdAt: %s. Should be between 0 and 99.\n",
-                      option->optionString);
-          return JNI_EINVAL;
-        }
-        FLAG_SET_CMDLINE(uintx, IncreaseFirstTierCompileThresholdAt, (uintx)uint_IncreaseFirstTierCompileThresholdAt);
+      if (FLAG_SET_CMDLINE(uintx, NonProfiledCodeHeapSize, (uintx)long_NonProfiledCodeHeapSize) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -green
     } else if (match_option(option, "-green")) {
       jio_fprintf(defaultStream::error_stream(),
@@ -2922,10 +2634,14 @@
     // -Xrs
     } else if (match_option(option, "-Xrs")) {
           // Classic/EVM option, new functionality
-      FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true);
+      if (FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-Xusealtsigs")) {
           // change default internal VM signals used - lower case for back compat
-      FLAG_SET_CMDLINE(bool, UseAltSigs, true);
+      if (FLAG_SET_CMDLINE(bool, UseAltSigs, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xoptimize
     } else if (match_option(option, "-Xoptimize")) {
           // EVM option, ignore silently for compatibility
@@ -2940,11 +2656,21 @@
 #endif // INCLUDE_FPROF
     // -Xconcurrentio
     } else if (match_option(option, "-Xconcurrentio")) {
-      FLAG_SET_CMDLINE(bool, UseLWPSynchronization, true);
-      FLAG_SET_CMDLINE(bool, BackgroundCompilation, false);
-      FLAG_SET_CMDLINE(intx, DeferThrSuspendLoopCount, 1);
-      FLAG_SET_CMDLINE(bool, UseTLAB, false);
-      FLAG_SET_CMDLINE(size_t, NewSizeThreadIncrease, 16 * K);  // 20Kb per thread added to new generation
+      if (FLAG_SET_CMDLINE(bool, UseLWPSynchronization, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, BackgroundCompilation, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(intx, DeferThrSuspendLoopCount, 1) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, UseTLAB, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(size_t, NewSizeThreadIncrease, 16 * K) != Flag::SUCCESS) {  // 20Kb per thread added to new generation
+        return JNI_EINVAL;
+      }
 
       // -Xinternalversion
     } else if (match_option(option, "-Xinternalversion")) {
@@ -2982,7 +2708,9 @@
       // Out of the box management support
       if (match_option(option, "-Dcom.sun.management", &tail)) {
 #if INCLUDE_MANAGEMENT
-        FLAG_SET_CMDLINE(bool, ManagementServer, true);
+        if (FLAG_SET_CMDLINE(bool, ManagementServer, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
 #else
         jio_fprintf(defaultStream::output_stream(),
           "-Dcom.sun.management is not supported in this VM.\n");
@@ -3001,31 +2729,57 @@
           set_mode_flags(_comp);
     // -Xshare:dump
     } else if (match_option(option, "-Xshare:dump")) {
-      FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true);
+      if (FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
       set_mode_flags(_int);     // Prevent compilation, which creates objects
     // -Xshare:on
     } else if (match_option(option, "-Xshare:on")) {
-      FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
-      FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
+      if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xshare:auto
     } else if (match_option(option, "-Xshare:auto")) {
-      FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
-      FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
+      if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xshare:off
     } else if (match_option(option, "-Xshare:off")) {
-      FLAG_SET_CMDLINE(bool, UseSharedSpaces, false);
-      FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false);
+      if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // -Xverify
     } else if (match_option(option, "-Xverify", &tail)) {
       if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) {
-        FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, true);
-        FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true);
+        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
+        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       } else if (strcmp(tail, ":remote") == 0) {
-        FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false);
-        FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true);
+        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
+        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       } else if (strcmp(tail, ":none") == 0) {
-        FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false);
-        FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, false);
+        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationLocal, false) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
+        if (FLAG_SET_CMDLINE(bool, BytecodeVerificationRemote, false) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       } else if (is_bad_option(option, args->ignoreUnrecognized, "verification")) {
         return JNI_EINVAL;
       }
@@ -3050,9 +2804,12 @@
                   "Note %%p or %%t can only be used once\n", _gc_log_filename);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(bool, PrintGC, true);
-      FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true);
-
+      if (FLAG_SET_CMDLINE(bool, PrintGC, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, PrintGCTimeStamps, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     // JNI hooks
     } else if (match_option(option, "-Xcheck", &tail)) {
       if (!strcmp(tail, ":jni")) {
@@ -3104,16 +2861,24 @@
       initHeapSize = limit_by_allocatable_memory(initHeapSize);
 
       if (FLAG_IS_DEFAULT(MaxHeapSize)) {
-         FLAG_SET_CMDLINE(size_t, MaxHeapSize, initHeapSize);
-         FLAG_SET_CMDLINE(size_t, InitialHeapSize, initHeapSize);
+         if (FLAG_SET_CMDLINE(size_t, MaxHeapSize, initHeapSize) != Flag::SUCCESS) {
+           return JNI_EINVAL;
+         }
+         if (FLAG_SET_CMDLINE(size_t, InitialHeapSize, initHeapSize) != Flag::SUCCESS) {
+           return JNI_EINVAL;
+         }
          // Currently the minimum size and the initial heap sizes are the same.
          set_min_heap_size(initHeapSize);
       }
       if (FLAG_IS_DEFAULT(NewSize)) {
          // Make the young generation 3/8ths of the total heap.
-         FLAG_SET_CMDLINE(size_t, NewSize,
-                                ((julong)MaxHeapSize / (julong)8) * (julong)3);
-         FLAG_SET_CMDLINE(size_t, MaxNewSize, NewSize);
+         if (FLAG_SET_CMDLINE(size_t, NewSize,
+                                ((julong)MaxHeapSize / (julong)8) * (julong)3) != Flag::SUCCESS) {
+           return JNI_EINVAL;
+         }
+         if (FLAG_SET_CMDLINE(size_t, MaxNewSize, NewSize) != Flag::SUCCESS) {
+           return JNI_EINVAL;
+         }
       }
 
 #if !defined(_ALLBSD_SOURCE) && !defined(AIX)  // UseLargePages is not yet supported on BSD and AIX.
@@ -3121,14 +2886,22 @@
 #endif
 
       // Increase some data structure sizes for efficiency
-      FLAG_SET_CMDLINE(size_t, BaseFootPrintEstimate, MaxHeapSize);
-      FLAG_SET_CMDLINE(bool, ResizeTLAB, false);
-      FLAG_SET_CMDLINE(size_t, TLABSize, 256*K);
+      if (FLAG_SET_CMDLINE(size_t, BaseFootPrintEstimate, MaxHeapSize) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, ResizeTLAB, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(size_t, TLABSize, 256*K) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
 
       // See the OldPLABSize comment below, but replace 'after promotion'
       // with 'after copying'.  YoungPLABSize is the size of the survivor
       // space per-gc-thread buffers.  The default is 4kw.
-      FLAG_SET_CMDLINE(size_t, YoungPLABSize, 256*K);      // Note: this is in words
+      if (FLAG_SET_CMDLINE(size_t, YoungPLABSize, 256*K) != Flag::SUCCESS) {      // Note: this is in words
+        return JNI_EINVAL;
+      }
 
       // OldPLABSize is the size of the buffers in the old gen that
       // UseParallelGC uses to promote live data that doesn't fit in the
@@ -3143,62 +2916,111 @@
       // locality.  A minor effect may be that larger PLABs reduce the
       // number of PLAB allocation events during gc.  The value of 8kw
       // was arrived at by experimenting with specjbb.
-      FLAG_SET_CMDLINE(size_t, OldPLABSize, 8*K);  // Note: this is in words
+      if (FLAG_SET_CMDLINE(size_t, OldPLABSize, 8*K) != Flag::SUCCESS) {  // Note: this is in words
+        return JNI_EINVAL;
+      }
 
       // Enable parallel GC and adaptive generation sizing
-      FLAG_SET_CMDLINE(bool, UseParallelGC, true);
+      if (FLAG_SET_CMDLINE(bool, UseParallelGC, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
       FLAG_SET_DEFAULT(ParallelGCThreads,
                        Abstract_VM_Version::parallel_worker_threads());
 
       // Encourage steady state memory management
-      FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100);
+      if (FLAG_SET_CMDLINE(uintx, ThresholdTolerance, 100) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
 
       // This appears to improve mutator locality
-      FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
+      if (FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
 
       // Get around early Solaris scheduling bug
       // (affinity vs other jobs on system)
       // but disallow DR and offlining (5008695).
-      FLAG_SET_CMDLINE(bool, BindGCTaskThreadsToCPUs, true);
+      if (FLAG_SET_CMDLINE(bool, BindGCTaskThreadsToCPUs, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
 
     // Need to keep consistency of MaxTenuringThreshold and AlwaysTenure/NeverTenure;
     // and the last option wins.
     } else if (match_option(option, "-XX:+NeverTenure")) {
-      FLAG_SET_CMDLINE(bool, NeverTenure, true);
-      FLAG_SET_CMDLINE(bool, AlwaysTenure, false);
-      FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, markOopDesc::max_age + 1);
+      if (FLAG_SET_CMDLINE(bool, NeverTenure, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, AlwaysTenure, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, markOopDesc::max_age + 1) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-XX:+AlwaysTenure")) {
-      FLAG_SET_CMDLINE(bool, NeverTenure, false);
-      FLAG_SET_CMDLINE(bool, AlwaysTenure, true);
-      FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0);
+      if (FLAG_SET_CMDLINE(bool, NeverTenure, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, AlwaysTenure, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-XX:MaxTenuringThreshold=", &tail)) {
       uintx max_tenuring_thresh = 0;
-      if(!parse_uintx(tail, &max_tenuring_thresh, 0)) {
+      if (!parse_uintx(tail, &max_tenuring_thresh, 0)) {
         jio_fprintf(defaultStream::error_stream(),
-          "Improperly specified VM option 'MaxTenuringThreshold=%s'\n", tail);
+                    "Improperly specified VM option \'MaxTenuringThreshold=%s\'\n", tail);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, max_tenuring_thresh);
+
+      if (FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, max_tenuring_thresh) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
 
       if (MaxTenuringThreshold == 0) {
-        FLAG_SET_CMDLINE(bool, NeverTenure, false);
-        FLAG_SET_CMDLINE(bool, AlwaysTenure, true);
+        if (FLAG_SET_CMDLINE(bool, NeverTenure, false) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
+        if (FLAG_SET_CMDLINE(bool, AlwaysTenure, true) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       } else {
-        FLAG_SET_CMDLINE(bool, NeverTenure, false);
-        FLAG_SET_CMDLINE(bool, AlwaysTenure, false);
+        if (FLAG_SET_CMDLINE(bool, NeverTenure, false) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
+        if (FLAG_SET_CMDLINE(bool, AlwaysTenure, false) != Flag::SUCCESS) {
+          return JNI_EINVAL;
+        }
       }
     } else if (match_option(option, "-XX:+DisplayVMOutputToStderr")) {
-      FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, false);
-      FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, true);
+      if (FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-XX:+DisplayVMOutputToStdout")) {
-      FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, false);
-      FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, true);
+      if (FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-XX:+ExtendedDTraceProbes")) {
 #if defined(DTRACE_ENABLED)
-      FLAG_SET_CMDLINE(bool, ExtendedDTraceProbes, true);
-      FLAG_SET_CMDLINE(bool, DTraceMethodProbes, true);
-      FLAG_SET_CMDLINE(bool, DTraceAllocProbes, true);
-      FLAG_SET_CMDLINE(bool, DTraceMonitorProbes, true);
+      if (FLAG_SET_CMDLINE(bool, ExtendedDTraceProbes, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, DTraceMethodProbes, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, DTraceAllocProbes, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
+      if (FLAG_SET_CMDLINE(bool, DTraceMonitorProbes, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
 #else // defined(DTRACE_ENABLED)
       jio_fprintf(defaultStream::error_stream(),
                   "ExtendedDTraceProbes flag is not applicable for this configuration\n");
@@ -3206,9 +3028,13 @@
 #endif // defined(DTRACE_ENABLED)
 #ifdef ASSERT
     } else if (match_option(option, "-XX:+FullGCALot")) {
-      FLAG_SET_CMDLINE(bool, FullGCALot, true);
+      if (FLAG_SET_CMDLINE(bool, FullGCALot, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
       // disable scavenge before parallel mark-compact
-      FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false);
+      if (FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
 #endif
     } else if (match_option(option, "-XX:CMSMarkStackSize=", &tail) ||
                match_option(option, "-XX:G1MarkStackSize=", &tail)) {
@@ -3223,7 +3049,9 @@
       jio_fprintf(defaultStream::error_stream(),
         "Please use -XX:MarkStackSize in place of "
         "-XX:CMSMarkStackSize or -XX:G1MarkStackSize in the future\n");
-      FLAG_SET_CMDLINE(size_t, MarkStackSize, stack_size);
+      if (FLAG_SET_CMDLINE(size_t, MarkStackSize, stack_size) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-XX:CMSMarkStackSizeMax=", &tail)) {
       julong max_stack_size = 0;
       ArgsRange errcode = parse_memory_size(tail, &max_stack_size, 1);
@@ -3237,7 +3065,9 @@
       jio_fprintf(defaultStream::error_stream(),
          "Please use -XX:MarkStackSizeMax in place of "
          "-XX:CMSMarkStackSizeMax in the future\n");
-      FLAG_SET_CMDLINE(size_t, MarkStackSizeMax, max_stack_size);
+      if (FLAG_SET_CMDLINE(size_t, MarkStackSizeMax, max_stack_size) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-XX:ParallelMarkingThreads=", &tail) ||
                match_option(option, "-XX:ParallelCMSThreads=", &tail)) {
       uintx conc_threads = 0;
@@ -3249,7 +3079,9 @@
       jio_fprintf(defaultStream::error_stream(),
         "Please use -XX:ConcGCThreads in place of "
         "-XX:ParallelMarkingThreads or -XX:ParallelCMSThreads in the future\n");
-      FLAG_SET_CMDLINE(uint, ConcGCThreads, conc_threads);
+      if (FLAG_SET_CMDLINE(uint, ConcGCThreads, conc_threads) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
     } else if (match_option(option, "-XX:MaxDirectMemorySize=", &tail)) {
       julong max_direct_memory_size = 0;
       ArgsRange errcode = parse_memory_size(tail, &max_direct_memory_size, 0);
@@ -3260,7 +3092,9 @@
         describe_range_error(errcode);
         return JNI_EINVAL;
       }
-      FLAG_SET_CMDLINE(size_t, MaxDirectMemorySize, max_direct_memory_size);
+      if (FLAG_SET_CMDLINE(size_t, MaxDirectMemorySize, max_direct_memory_size) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
 #if !INCLUDE_MANAGEMENT
     } else if (match_option(option, "-XX:+ManagementServer")) {
         jio_fprintf(defaultStream::error_stream(),
@@ -3269,11 +3103,15 @@
 #endif // INCLUDE_MANAGEMENT
     // CreateMinidumpOnCrash is removed, and replaced by CreateCoredumpOnCrash
     } else if (match_option(option, "-XX:+CreateMinidumpOnCrash")) {
-      FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, true);
+      if (FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, true) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
       jio_fprintf(defaultStream::output_stream(),
           "CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is on\n");
     } else if (match_option(option, "-XX:-CreateMinidumpOnCrash")) {
-      FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, false);
+      if (FLAG_SET_CMDLINE(bool, CreateCoredumpOnCrash, false) != Flag::SUCCESS) {
+        return JNI_EINVAL;
+      }
       jio_fprintf(defaultStream::output_stream(),
           "CreateMinidumpOnCrash is replaced by CreateCoredumpOnCrash: CreateCoredumpOnCrash is off\n");
     } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
@@ -3293,9 +3131,15 @@
   //   -Xshare:on
   //   -XX:+TraceClassPaths
   if (PrintSharedArchiveAndExit) {
-    FLAG_SET_CMDLINE(bool, UseSharedSpaces, true);
-    FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true);
-    FLAG_SET_CMDLINE(bool, TraceClassPaths, true);
+    if (FLAG_SET_CMDLINE(bool, UseSharedSpaces, true) != Flag::SUCCESS) {
+      return JNI_EINVAL;
+    }
+    if (FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true) != Flag::SUCCESS) {
+      return JNI_EINVAL;
+    }
+    if (FLAG_SET_CMDLINE(bool, TraceClassPaths, true) != Flag::SUCCESS) {
+      return JNI_EINVAL;
+    }
   }
 
   // Change the default value for flags  which have different default values
@@ -3702,6 +3546,10 @@
 
 jint Arguments::parse(const JavaVMInitArgs* args) {
 
+  // Initialize ranges and constraints
+  CommandLineFlagRangeList::init();
+  CommandLineFlagConstraintList::init();
+
   // Remaining part of option string
   const char* tail;
 
@@ -4036,6 +3884,15 @@
   return JNI_OK;
 }
 
+// Any custom code post the final range and constraint check
+// can be done here. We pass a flag that specifies whether
+// the check passed successfully
+void Arguments::post_final_range_and_constraint_check(bool check_passed) {
+  // This does not set the flag itself, but stores the value in a safe place for later usage.
+  _min_heap_free_ratio = MinHeapFreeRatio;
+  _max_heap_free_ratio = MaxHeapFreeRatio;
+}
+
 int Arguments::PropertyList_count(SystemProperty* pl) {
   int count = 0;
   while(pl != NULL) {
--- a/hotspot/src/share/vm/runtime/arguments.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/runtime/arguments.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -328,7 +328,6 @@
 
   // Tiered
   static void set_tiered_flags();
-  static int  get_min_number_of_compiler_threads();
   // CMS/ParNew garbage collectors
   static void set_parnew_gc_flags();
   static void set_cms_and_parnew_gc_flags();
@@ -384,14 +383,6 @@
     return is_bad_option(option, ignore, NULL);
   }
 
-  static bool is_percentage(uintx val) {
-    return val <= 100;
-  }
-
-  static bool verify_interval(uintx val, uintx min,
-                              uintx max, const char* name);
-  static bool verify_min_value(intx val, intx min, const char* name);
-  static bool verify_percentage(uintx value, const char* name);
   static void describe_range_error(ArgsRange errcode);
   static ArgsRange check_memory_size(julong size, julong min_size);
   static ArgsRange parse_memory_size(const char* s, julong* long_arg,
@@ -447,6 +438,9 @@
   static char*  SharedArchivePath;
 
  public:
+  // Tiered
+  static int  get_min_number_of_compiler_threads();
+
   // Scale compile thresholds
   // Returns threshold scaled with CompileThresholdScaling
   static intx scaled_compile_threshold(intx threshold, double scale);
@@ -465,26 +459,18 @@
   static jint apply_ergo();
   // Adjusts the arguments after the OS have adjusted the arguments
   static jint adjust_after_os();
+  // Set any arguments that need to be set after the final range and constraint check
+  static void post_final_range_and_constraint_check(bool check_passed);
 
   static void set_gc_specific_flags();
   static inline bool gc_selected(); // whether a gc has been selected
   static void select_gc_ergonomically();
 
-  // Verifies that the given value will fit as a MinHeapFreeRatio. If not, an error
-  // message is returned in the provided buffer.
-  static bool verify_MinHeapFreeRatio(FormatBuffer<80>& err_msg, uintx min_heap_free_ratio);
-
-  // Verifies that the given value will fit as a MaxHeapFreeRatio. If not, an error
-  // message is returned in the provided buffer.
-  static bool verify_MaxHeapFreeRatio(FormatBuffer<80>& err_msg, uintx max_heap_free_ratio);
-
   // Check for consistency in the selection of the garbage collector.
   static bool check_gc_consistency();        // Check user-selected gc
   static void check_deprecated_gc_flags();
   // Check consistency or otherwise of VM argument settings
   static bool check_vm_args_consistency();
-  // Check stack pages settings
-  static bool check_stack_pages();
   // Used by os_solaris
   static bool process_settings_file(const char* file_name, bool should_exist, jboolean ignore_unrecognized);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,286 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/stringTable.hpp"
+#include "classfile/symbolTable.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/commandLineFlagConstraintList.hpp"
+#include "runtime/commandLineFlagConstraintsCompiler.hpp"
+#include "runtime/commandLineFlagConstraintsGC.hpp"
+#include "runtime/commandLineFlagConstraintsRuntime.hpp"
+#include "runtime/os.hpp"
+#include "utilities/macros.hpp"
+
+class CommandLineFlagConstraint_bool : public CommandLineFlagConstraint {
+  CommandLineFlagConstraintFunc_bool _constraint;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func) : CommandLineFlagConstraint(name) {
+    _constraint=func;
+  }
+
+  Flag::Error apply_bool(bool* value, bool verbose) {
+    return _constraint(verbose, value);
+  }
+};
+
+class CommandLineFlagConstraint_int : public CommandLineFlagConstraint {
+  CommandLineFlagConstraintFunc_int _constraint;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint_int(const char* name, CommandLineFlagConstraintFunc_int func) : CommandLineFlagConstraint(name) {
+    _constraint=func;
+  }
+
+  Flag::Error apply_int(int* value, bool verbose) {
+    return _constraint(verbose, value);
+  }
+};
+
+class CommandLineFlagConstraint_intx : public CommandLineFlagConstraint {
+  CommandLineFlagConstraintFunc_intx _constraint;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func) : CommandLineFlagConstraint(name) {
+    _constraint=func;
+  }
+
+  Flag::Error apply_intx(intx* value, bool verbose) {
+    return _constraint(verbose, value);
+  }
+};
+
+class CommandLineFlagConstraint_uint : public CommandLineFlagConstraint {
+  CommandLineFlagConstraintFunc_uint _constraint;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func) : CommandLineFlagConstraint(name) {
+    _constraint=func;
+  }
+
+  Flag::Error apply_uint(uint* value, bool verbose) {
+    return _constraint(verbose, value);
+  }
+};
+
+class CommandLineFlagConstraint_uintx : public CommandLineFlagConstraint {
+  CommandLineFlagConstraintFunc_uintx _constraint;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func) : CommandLineFlagConstraint(name) {
+    _constraint=func;
+  }
+
+  Flag::Error apply_uintx(uintx* value, bool verbose) {
+    return _constraint(verbose, value);
+  }
+};
+
+class CommandLineFlagConstraint_uint64_t : public CommandLineFlagConstraint {
+  CommandLineFlagConstraintFunc_uint64_t _constraint;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func) : CommandLineFlagConstraint(name) {
+    _constraint=func;
+  }
+
+  Flag::Error apply_uint64_t(uint64_t* value, bool verbose) {
+    return _constraint(verbose, value);
+  }
+};
+
+class CommandLineFlagConstraint_size_t : public CommandLineFlagConstraint {
+  CommandLineFlagConstraintFunc_size_t _constraint;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func) : CommandLineFlagConstraint(name) {
+    _constraint=func;
+  }
+
+  Flag::Error apply_size_t(size_t* value, bool verbose) {
+    return _constraint(verbose, value);
+  }
+};
+
+class CommandLineFlagConstraint_double : public CommandLineFlagConstraint {
+  CommandLineFlagConstraintFunc_double _constraint;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint_double(const char* name, CommandLineFlagConstraintFunc_double func) : CommandLineFlagConstraint(name) {
+    _constraint=func;
+  }
+
+  Flag::Error apply_double(double* value, bool verbose) {
+    return _constraint(verbose, value);
+  }
+};
+
+// No constraint emitting
+void emit_constraint_no(...)                          { /* NOP */ }
+
+// No constraint emitting if function argument is NOT provided
+void emit_constraint_bool(const char* /*name*/)       { /* NOP */ }
+void emit_constraint_ccstr(const char* /*name*/)      { /* NOP */ }
+void emit_constraint_ccstrlist(const char* /*name*/)  { /* NOP */ }
+void emit_constraint_int(const char* /*name*/)        { /* NOP */ }
+void emit_constraint_intx(const char* /*name*/)       { /* NOP */ }
+void emit_constraint_uint(const char* /*name*/)       { /* NOP */ }
+void emit_constraint_uintx(const char* /*name*/)      { /* NOP */ }
+void emit_constraint_uint64_t(const char* /*name*/)   { /* NOP */ }
+void emit_constraint_size_t(const char* /*name*/)     { /* NOP */ }
+void emit_constraint_double(const char* /*name*/)     { /* NOP */ }
+
+// CommandLineFlagConstraint emitting code functions if function argument is provided
+void emit_constraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func) {
+  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_bool(name, func));
+}
+void emit_constraint_int(const char* name, CommandLineFlagConstraintFunc_int func) {
+  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_int(name, func));
+}
+void emit_constraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func) {
+  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_intx(name, func));
+}
+void emit_constraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func) {
+  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint(name, func));
+}
+void emit_constraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func) {
+  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uintx(name, func));
+}
+void emit_constraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func) {
+  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint64_t(name, func));
+}
+void emit_constraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func) {
+  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_size_t(name, func));
+}
+void emit_constraint_double(const char* name, CommandLineFlagConstraintFunc_double func) {
+  CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_double(name, func));
+}
+
+// Generate code to call emit_constraint_xxx function
+#define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc)      ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_COMMERCIAL_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc)          ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_constraint_##type(#name
+#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name
+
+// Generate func argument to pass into emit_constraint_xxx functions
+#define EMIT_CONSTRAINT_CHECK(func)                               , func
+
+// the "name" argument must be a string literal
+#define INITIAL_CONTRAINTS_SIZE 16
+GrowableArray<CommandLineFlagConstraint*>* CommandLineFlagConstraintList::_constraints = NULL;
+
+// Check the ranges of all flags that have them or print them out and exit if requested
+void CommandLineFlagConstraintList::init(void) {
+
+  _constraints = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagConstraint*>(INITIAL_CONTRAINTS_SIZE, true);
+
+  emit_constraint_no(NULL RUNTIME_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
+                                        EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
+                                        EMIT_CONSTRAINT_PRODUCT_FLAG,
+                                        EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
+                                        EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
+                                        EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
+                                        EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
+                                        EMIT_CONSTRAINT_MANAGEABLE_FLAG,
+                                        EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
+                                        EMIT_CONSTRAINT_LP64_PRODUCT_FLAG,
+                                        IGNORE_RANGE,
+                                        EMIT_CONSTRAINT_CHECK));
+
+  EMIT_CONSTRAINTS_FOR_GLOBALS_EXT
+
+  emit_constraint_no(NULL ARCH_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
+                                     EMIT_CONSTRAINT_PRODUCT_FLAG,
+                                     EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
+                                     EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
+                                     EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
+                                     IGNORE_RANGE,
+                                     EMIT_CONSTRAINT_CHECK));
+
+#ifdef COMPILER1
+  emit_constraint_no(NULL C1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
+                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
+                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
+                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
+                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
+                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
+                                   IGNORE_RANGE,
+                                   EMIT_CONSTRAINT_CHECK));
+#endif // COMPILER1
+
+#ifdef COMPILER2
+  emit_constraint_no(NULL C2_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
+                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
+                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
+                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
+                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
+                                   EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
+                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
+                                   IGNORE_RANGE,
+                                   EMIT_CONSTRAINT_CHECK));
+#endif // COMPILER2
+
+#ifndef INCLUDE_ALL_GCS
+  emit_constraint_no(NULL G1_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
+                                   EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
+                                   EMIT_CONSTRAINT_PRODUCT_FLAG,
+                                   EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
+                                   EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
+                                   EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
+                                   EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
+                                   EMIT_CONSTRAINT_MANAGEABLE_FLAG,
+                                   EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
+                                   IGNORE_RANGE,
+                                   EMIT_CONSTRAINT_CHECK));
+#endif // INCLUDE_ALL_GCS
+}
+
+CommandLineFlagConstraint* CommandLineFlagConstraintList::find(const char* name) {
+  CommandLineFlagConstraint* found = NULL;
+  for (int i=0; i<length(); i++) {
+    CommandLineFlagConstraint* constraint = at(i);
+    if (strcmp(constraint->name(), name) == 0) {
+      found = constraint;
+      break;
+    }
+  }
+  return found;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTLIST_HPP
+#define SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTLIST_HPP
+
+#include "runtime/globals.hpp"
+#include "utilities/growableArray.hpp"
+
+/*
+ * Here we have a mechanism for extracting constraints (as custom functions) for flags,
+ * which otherwise can not be expressed via simple range check, specified in flag macro tables.
+ *
+ * An example of a constraint is "flag1 < flag2" where both flag1 and flag2 can change.
+ *
+ * See runtime "runtime/commandLineFlagConstraintsCompiler.hpp",
+ * "runtime/commandLineFlagConstraintsGC.hpp" and
+ * "runtime/commandLineFlagConstraintsRuntime.hpp" for the functions themselves.
+ */
+
+typedef Flag::Error (*CommandLineFlagConstraintFunc_bool)(bool verbose, bool* value);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_int)(bool verbose, int* value);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_intx)(bool verbose, intx* value);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_uint)(bool verbose, uint* value);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_uintx)(bool verbose, uintx* value);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_uint64_t)(bool verbose, uint64_t* value);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_size_t)(bool verbose, size_t* value);
+typedef Flag::Error (*CommandLineFlagConstraintFunc_double)(bool verbose, double* value);
+
+class CommandLineFlagConstraint : public CHeapObj<mtInternal> {
+private:
+  const char* _name;
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagConstraint(const char* name) { _name=name; };
+  ~CommandLineFlagConstraint() {};
+  const char* name() { return _name; }
+  virtual Flag::Error apply_bool(bool* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+  virtual Flag::Error apply_int(int* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+  virtual Flag::Error apply_intx(intx* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+  virtual Flag::Error apply_uint(uint* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+  virtual Flag::Error apply_uintx(uintx* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+  virtual Flag::Error apply_uint64_t(uint64_t* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+  virtual Flag::Error apply_size_t(size_t* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+  virtual Flag::Error apply_double(double* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; };
+};
+
+class CommandLineFlagConstraintList : public AllStatic {
+private:
+  static GrowableArray<CommandLineFlagConstraint*>* _constraints;
+public:
+  static void init();
+  static int length() { return (_constraints != NULL) ? _constraints->length() : 0; }
+  static CommandLineFlagConstraint* at(int i) { return (_constraints != NULL) ? _constraints->at(i) : NULL; }
+  static CommandLineFlagConstraint* find(const char* name);
+  static void add(CommandLineFlagConstraint* constraint) { _constraints->append(constraint); }
+};
+
+#endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTLIST_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/commandLineFlagConstraintsCompiler.hpp"
+#include "runtime/globals.hpp"
+#include "utilities/defaultStream.hpp"
+
+Flag::Error AliasLevelConstraintFunc(bool verbose, intx* value) {
+  if (CommandLineFlags::finishedInitializing() == true) {
+    if ((*value <= 1) && (Arguments::mode() == Arguments::_comp)) {
+      if (verbose == true) {
+        jio_fprintf(defaultStream::error_stream(),
+                  "AliasLevel (" INTX_FORMAT ") is not compatible "
+                  "with -Xcomp \n",
+                  *value);
+      }
+      return Flag::VIOLATES_CONSTRAINT;
+    }
+  }
+  return Flag::SUCCESS;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsCompiler.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSCOMPILER_HPP
+#define SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSCOMPILER_HPP
+
+#include "runtime/globals.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+/*
+ * Here we have compiler arguments constraints functions, which are called automatically
+ * whenever flag's value changes. If the constraint fails the function should return
+ * an appropriate error value.
+ */
+
+Flag::Error AliasLevelConstraintFunc(bool verbose, intx* value);
+
+#endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSCOMPILER_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/commandLineFlagConstraintsGC.hpp"
+#include "runtime/globals.hpp"
+#include "utilities/defaultStream.hpp"
+
+#if INCLUDE_ALL_GCS
+#include "gc/g1/g1_globals.hpp"
+#endif // INCLUDE_ALL_GCS
+#ifdef COMPILER1
+#include "c1/c1_globals.hpp"
+#endif // COMPILER1
+#ifdef COMPILER2
+#include "opto/c2_globals.hpp"
+#endif // COMPILER2
+
+Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value > MaxHeapFreeRatio)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or "
+                  "equal to MaxHeapFreeRatio (" UINTX_FORMAT ")\n",
+                  *value, MaxHeapFreeRatio);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error MaxHeapFreeRatioConstraintFunc(bool verbose, uintx* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value < MinHeapFreeRatio)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "MaxHeapFreeRatio (" UINTX_FORMAT ") must be greater than or "
+                  "equal to MinHeapFreeRatio (" UINTX_FORMAT ")\n",
+                  *value, MinHeapFreeRatio);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error MinMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value > MaxMetaspaceFreeRatio)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "MinMetaspaceFreeRatio (" UINTX_FORMAT ") must be less than or "
+                  "equal to MaxMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
+                  *value, MaxMetaspaceFreeRatio);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error MaxMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value < MinMetaspaceFreeRatio)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "MaxMetaspaceFreeRatio (" UINTX_FORMAT ") must be greater than or "
+                  "equal to MinMetaspaceFreeRatio (" UINTX_FORMAT ")\n",
+                  *value, MinMetaspaceFreeRatio);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+// GC workaround for "-XX:+UseConcMarkSweepGC"
+// which sets InitialTenuringThreshold to 7 but leaves MaxTenuringThreshold remaining at 6
+// and therefore would invalidate the constraint
+#define UseConcMarkSweepGCWorkaroundIfNeeded(initial, max) { \
+  if ((initial == 7) && (max == 6)) { \
+    return Flag::SUCCESS; \
+  } \
+}
+
+Flag::Error InitialTenuringThresholdConstraintFunc(bool verbose, uintx* value) {
+  UseConcMarkSweepGCWorkaroundIfNeeded(*value, MaxTenuringThreshold);
+
+  if ((CommandLineFlags::finishedInitializing()) && (*value > MaxTenuringThreshold)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "InitialTenuringThreshold (" UINTX_FORMAT ") must be less than or "
+                  "equal to MaxTenuringThreshold (" UINTX_FORMAT ")\n",
+                  *value, MaxTenuringThreshold);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error MaxTenuringThresholdConstraintFunc(bool verbose, uintx* value) {
+  UseConcMarkSweepGCWorkaroundIfNeeded(InitialTenuringThreshold, *value);
+
+  if ((CommandLineFlags::finishedInitializing()) && (*value < InitialTenuringThreshold)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "MaxTenuringThreshold (" UINTX_FORMAT ") must be greater than or "
+                  "equal to InitialTenuringThreshold (" UINTX_FORMAT ")\n",
+                  *value, InitialTenuringThreshold);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+#if INCLUDE_ALL_GCS
+
+Flag::Error G1NewSizePercentConstraintFunc(bool verbose, uintx* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value > G1MaxNewSizePercent)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "G1NewSizePercent (" UINTX_FORMAT ") must be less than or "
+                  "equal to G1MaxNewSizePercent (" UINTX_FORMAT ")\n",
+                  *value, G1MaxNewSizePercent);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error G1MaxNewSizePercentConstraintFunc(bool verbose, uintx* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value < G1NewSizePercent)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "G1MaxNewSizePercent (" UINTX_FORMAT ") must be greater than or "
+                  "equal to G1NewSizePercent (" UINTX_FORMAT ")\n",
+                  *value, G1NewSizePercent);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+#endif // INCLUDE_ALL_GCS
+
+Flag::Error CMSOldPLABMinConstraintFunc(bool verbose, size_t* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value > CMSOldPLABMax)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "CMSOldPLABMin (" SIZE_FORMAT ") must be less than or "
+                  "equal to CMSOldPLABMax (" SIZE_FORMAT ")\n",
+                  *value, CMSOldPLABMax);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error CMSPrecleanDenominatorConstraintFunc(bool verbose, uintx* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value <= CMSPrecleanNumerator)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "CMSPrecleanDenominator (" UINTX_FORMAT ") must be strickly greater than "
+                  "CMSPrecleanNumerator (" UINTX_FORMAT ")\n",
+                  *value, CMSPrecleanNumerator);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error CMSPrecleanNumeratorConstraintFunc(bool verbose, uintx* value) {
+  if ((CommandLineFlags::finishedInitializing()) && (*value > (CMSPrecleanDenominator - 1))) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                  "CMSPrecleanNumerator (" UINTX_FORMAT ") must be less than or "
+                  "equal to CMSPrecleanDenominator - 1 (" UINTX_FORMAT ")\n", *value,
+                  CMSPrecleanDenominator - 1);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
+
+Flag::Error SurvivorAlignmentInBytesConstraintFunc(bool verbose, intx* value) {
+  if (CommandLineFlags::finishedInitializing()) {
+    if (*value != 0) {
+      if (!is_power_of_2(*value)) {
+        if (verbose == true) {
+          jio_fprintf(defaultStream::error_stream(),
+                    "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be power of 2\n",
+                    *value);
+        }
+        return Flag::VIOLATES_CONSTRAINT;
+      }
+      if (*value < ObjectAlignmentInBytes) {
+        if (verbose == true) {
+          jio_fprintf(defaultStream::error_stream(),
+                    "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be greater than or "
+                    "equal to ObjectAlignmentInBytes (" INTX_FORMAT ") \n",
+                    *value, ObjectAlignmentInBytes);
+        }
+        return Flag::VIOLATES_CONSTRAINT;
+      }
+    }
+  }
+  return Flag::SUCCESS;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSGC_HPP
+#define SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSGC_HPP
+
+#include "runtime/globals.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+/*
+ * Here we have GC arguments constraints functions, which are called automatically
+ * whenever flag's value changes. If the constraint fails the function should return
+ * an appropriate error value.
+ */
+
+Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx* value);
+Flag::Error MaxHeapFreeRatioConstraintFunc(bool verbose, uintx* value);
+
+Flag::Error MinMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value);
+Flag::Error MaxMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value);
+
+Flag::Error InitialTenuringThresholdConstraintFunc(bool verbose, uintx* value);
+Flag::Error MaxTenuringThresholdConstraintFunc(bool verbose, uintx* value);
+
+#if INCLUDE_ALL_GCS
+Flag::Error G1NewSizePercentConstraintFunc(bool verbose, uintx* value);
+Flag::Error G1MaxNewSizePercentConstraintFunc(bool verbose, uintx* value);
+#endif // INCLUDE_ALL_GCS
+
+Flag::Error CMSOldPLABMinConstraintFunc(bool verbose, size_t* value);
+
+Flag::Error CMSPrecleanDenominatorConstraintFunc(bool verbose, uintx* value);
+Flag::Error CMSPrecleanNumeratorConstraintFunc(bool verbose, uintx* value);
+
+Flag::Error SurvivorAlignmentInBytesConstraintFunc(bool verbose, intx* value);
+
+#endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSGC_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsRuntime.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/commandLineFlagConstraintsRuntime.hpp"
+#include "runtime/globals.hpp"
+#include "utilities/defaultStream.hpp"
+
+Flag::Error ObjectAlignmentInBytesConstraintFunc(bool verbose, intx* value) {
+  if (!is_power_of_2(*value)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                "ObjectAlignmentInBytes=" INTX_FORMAT " must be power of 2\n",
+                *value);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+  // In case page size is very small.
+  if (*value >= (intx)os::vm_page_size()) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                "ObjectAlignmentInBytes=" INTX_FORMAT " must be less than page size " INTX_FORMAT "\n",
+                *value, (intx)os::vm_page_size());
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  }
+  return Flag::SUCCESS;
+}
+
+// Need to enforce the padding not to break the existing field alignments.
+// It is sufficient to check against the largest type size.
+Flag::Error ContendedPaddingWidthConstraintFunc(bool verbose, intx* value) {
+  if ((*value != 0) && ((*value % BytesPerLong) != 0)) {
+    if (verbose == true) {
+      jio_fprintf(defaultStream::error_stream(),
+                "ContendedPaddingWidth=" INTX_FORMAT " must be a multiple of %d\n",
+                *value, BytesPerLong);
+    }
+    return Flag::VIOLATES_CONSTRAINT;
+  } else {
+    return Flag::SUCCESS;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintsRuntime.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSRUNTIME_HPP
+#define SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSRUNTIME_HPP
+
+#include "runtime/globals.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+/*
+ * Here we have runtime arguments constraints functions, which are called automatically
+ * whenever flag's value changes. If the constraint fails the function should return
+ * an appropriate error value.
+ */
+
+Flag::Error ObjectAlignmentInBytesConstraintFunc(bool verbose, intx* value);
+
+Flag::Error ContendedPaddingWidthConstraintFunc(bool verbose, intx* value);
+
+#endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTSRUNTIME_HPP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,367 @@
+/*
+ * 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "classfile/stringTable.hpp"
+#include "classfile/symbolTable.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "runtime/arguments.hpp"
+#include "runtime/commandLineFlagRangeList.hpp"
+#include "runtime/os.hpp"
+#include "utilities/defaultStream.hpp"
+#include "utilities/macros.hpp"
+
+class CommandLineFlagRange_int : public CommandLineFlagRange {
+  int _min;
+  int _max;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagRange_int(const char* name, int min, int max) : CommandLineFlagRange(name) {
+    _min=min, _max=max;
+  }
+
+  Flag::Error check_int(int value, bool verbose = true) {
+    if ((value < _min) || (value > _max)) {
+      if (verbose == true) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "int %s=%d is outside the allowed range [ %d ... %d ]\n",
+                    name(), value, _min, _max);
+      }
+      return Flag::OUT_OF_BOUNDS;
+    } else {
+      return Flag::SUCCESS;
+    }
+  }
+
+  void print(outputStream* st) {
+    st->print("[ %-25d ... %25d ]", _min, _max);
+  }
+};
+
+class CommandLineFlagRange_intx : public CommandLineFlagRange {
+  intx _min;
+  intx _max;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagRange_intx(const char* name, intx min, intx max) : CommandLineFlagRange(name) {
+    _min=min, _max=max;
+  }
+
+  Flag::Error check_intx(intx value, bool verbose = true) {
+    if ((value < _min) || (value > _max)) {
+      if (verbose == true) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "intx %s=" INTX_FORMAT " is outside the allowed range [ " INTX_FORMAT " ... " INTX_FORMAT " ]\n",
+                    name(), value, _min, _max);
+      }
+      return Flag::OUT_OF_BOUNDS;
+    } else {
+      return Flag::SUCCESS;
+    }
+  }
+
+  void print(outputStream* st) {
+    st->print("[ "INTX_FORMAT_W(-25)" ... "INTX_FORMAT_W(25)" ]", _min, _max);
+  }
+};
+
+class CommandLineFlagRange_uint : public CommandLineFlagRange {
+  uint _min;
+  uint _max;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagRange_uint(const char* name, uint min, uint max) : CommandLineFlagRange(name) {
+    _min=min, _max=max;
+  }
+
+  Flag::Error check_uint(uint value, bool verbose = true) {
+    if ((value < _min) || (value > _max)) {
+      if (verbose == true) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "uintx %s=%u is outside the allowed range [ %u ... %u ]\n",
+                    name(), value, _min, _max);
+      }
+      return Flag::OUT_OF_BOUNDS;
+    } else {
+      return Flag::SUCCESS;
+    }
+  }
+
+  void print(outputStream* st) {
+    st->print("[ %-25u ... %25u ]", _min, _max);
+  }
+};
+
+class CommandLineFlagRange_uintx : public CommandLineFlagRange {
+  uintx _min;
+  uintx _max;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagRange_uintx(const char* name, uintx min, uintx max) : CommandLineFlagRange(name) {
+    _min=min, _max=max;
+  }
+
+  Flag::Error check_uintx(uintx value, bool verbose = true) {
+    if ((value < _min) || (value > _max)) {
+      if (verbose == true) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "uintx %s=" UINTX_FORMAT " is outside the allowed range [ " UINTX_FORMAT " ... " UINTX_FORMAT " ]\n",
+                    name(), value, _min, _max);
+      }
+      return Flag::OUT_OF_BOUNDS;
+    } else {
+      return Flag::SUCCESS;
+    }
+  }
+
+  void print(outputStream* st) {
+    st->print("[ "UINTX_FORMAT_W(-25)" ... "UINTX_FORMAT_W(25)" ]", _min, _max);
+  }
+};
+
+class CommandLineFlagRange_uint64_t : public CommandLineFlagRange {
+  uint64_t _min;
+  uint64_t _max;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagRange_uint64_t(const char* name, uint64_t min, uint64_t max) : CommandLineFlagRange(name) {
+    _min=min, _max=max;
+  }
+
+  Flag::Error check_uint64_t(uint64_t value, bool verbose = true) {
+    if ((value < _min) || (value > _max)) {
+      if (verbose == true) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "uint64_t %s=" UINT64_FORMAT " is outside the allowed range [ " UINT64_FORMAT " ... " UINT64_FORMAT " ]\n",
+                    name(), value, _min, _max);
+      }
+      return Flag::OUT_OF_BOUNDS;
+    } else {
+      return Flag::SUCCESS;
+    }
+  }
+
+  void print(outputStream* st) {
+    st->print("[ "UINT64_FORMAT_W(-25)" ... "UINT64_FORMAT_W(25)" ]", _min, _max);
+  }
+};
+
+class CommandLineFlagRange_size_t : public CommandLineFlagRange {
+  size_t _min;
+  size_t _max;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagRange_size_t(const char* name, size_t min, size_t max) : CommandLineFlagRange(name) {
+    _min=min, _max=max;
+  }
+
+  Flag::Error check_size_t(size_t value, bool verbose = true) {
+    if ((value < _min) || (value > _max)) {
+      if (verbose == true) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "size_t %s=" SIZE_FORMAT " is outside the allowed range [ " SIZE_FORMAT " ... " SIZE_FORMAT " ]\n",
+                    name(), value, _min, _max);
+      }
+      return Flag::OUT_OF_BOUNDS;
+    } else {
+      return Flag::SUCCESS;
+    }
+  }
+
+  void print(outputStream* st) {
+    st->print("[ "SIZE_FORMAT_W(-25)" ... "SIZE_FORMAT_W(25)" ]", _min, _max);
+  }
+};
+
+class CommandLineFlagRange_double : public CommandLineFlagRange {
+  double _min;
+  double _max;
+
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagRange_double(const char* name, double min, double max) : CommandLineFlagRange(name) {
+    _min=min, _max=max;
+  }
+
+  Flag::Error check_double(double value, bool verbose = true) {
+    if ((value < _min) || (value > _max)) {
+      if (verbose == true) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "double %s=%f is outside the allowed range [ %f ... %f ]\n",
+                    name(), value, _min, _max);
+      }
+      return Flag::OUT_OF_BOUNDS;
+    } else {
+      return Flag::SUCCESS;
+    }
+  }
+
+  void print(outputStream* st) {
+    st->print("[ %-25.3f ... %25.3f ]", _min, _max);
+  }
+};
+
+// No constraint emitting
+void emit_range_no(...)                         { /* NOP */ }
+
+// No constraint emitting if function argument is NOT provided
+void emit_range_bool(const char* /*name*/)      { /* NOP */ }
+void emit_range_ccstr(const char* /*name*/)     { /* NOP */ }
+void emit_range_ccstrlist(const char* /*name*/) { /* NOP */ }
+void emit_range_int(const char* /*name*/)       { /* NOP */ }
+void emit_range_intx(const char* /*name*/)      { /* NOP */ }
+void emit_range_uint(const char* /*name*/)      { /* NOP */ }
+void emit_range_uintx(const char* /*name*/)     { /* NOP */ }
+void emit_range_uint64_t(const char* /*name*/)  { /* NOP */ }
+void emit_range_size_t(const char* /*name*/)    { /* NOP */ }
+void emit_range_double(const char* /*name*/)    { /* NOP */ }
+
+// CommandLineFlagRange emitting code functions if range arguments are provided
+void emit_range_intx(const char* name, intx min, intx max) {
+  CommandLineFlagRangeList::add(new CommandLineFlagRange_intx(name, min, max));
+}
+void emit_range_uintx(const char* name, uintx min, uintx max) {
+  CommandLineFlagRangeList::add(new CommandLineFlagRange_uintx(name, min, max));
+}
+void emit_range_uint64_t(const char* name, uint64_t min, uint64_t max) {
+  CommandLineFlagRangeList::add(new CommandLineFlagRange_uint64_t(name, min, max));
+}
+void emit_range_size_t(const char* name, size_t min, size_t max) {
+  CommandLineFlagRangeList::add(new CommandLineFlagRange_size_t(name, min, max));
+}
+void emit_range_double(const char* name, double min, double max) {
+  CommandLineFlagRangeList::add(new CommandLineFlagRange_double(name, min, max));
+}
+
+// Generate code to call emit_range_xxx function
+#define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc)      ); emit_range_##type(#name
+#define EMIT_RANGE_COMMERCIAL_FLAG(type, name, value, doc)   ); emit_range_##type(#name
+#define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_range_##type(#name
+#define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_range_##type(#name
+#define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_range_##type(#name
+#define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_range_##type(#name
+#define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc)          ); emit_range_##type(#name
+#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_range_##type(#name
+#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_range_##type(#name
+#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_range_##type(#name
+#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_range_##type(#name
+
+// Generate func argument to pass into emit_range_xxx functions
+#define EMIT_RANGE_CHECK(a, b)                               , a, b
+
+#define INITIAL_RANGES_SIZE 128
+GrowableArray<CommandLineFlagRange*>* CommandLineFlagRangeList::_ranges = NULL;
+
+// Check the ranges of all flags that have them
+void CommandLineFlagRangeList::init(void) {
+
+  _ranges = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<CommandLineFlagRange*>(INITIAL_RANGES_SIZE, true);
+
+  emit_range_no(NULL RUNTIME_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
+                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
+                                   EMIT_RANGE_PRODUCT_FLAG,
+                                   EMIT_RANGE_PD_PRODUCT_FLAG,
+                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
+                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
+                                   EMIT_RANGE_NOTPRODUCT_FLAG,
+                                   EMIT_RANGE_MANAGEABLE_FLAG,
+                                   EMIT_RANGE_PRODUCT_RW_FLAG,
+                                   EMIT_RANGE_LP64_PRODUCT_FLAG,
+                                   EMIT_RANGE_CHECK,
+                                   IGNORE_CONSTRAINT) );
+
+  EMIT_RANGES_FOR_GLOBALS_EXT
+
+  emit_range_no(NULL ARCH_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
+                                     EMIT_RANGE_PRODUCT_FLAG,
+                                     EMIT_RANGE_DIAGNOSTIC_FLAG,
+                                     EMIT_RANGE_EXPERIMENTAL_FLAG,
+                                     EMIT_RANGE_NOTPRODUCT_FLAG,
+                                     EMIT_RANGE_CHECK,
+                                     IGNORE_CONSTRAINT));
+
+#ifdef COMPILER1
+  emit_range_no(NULL C1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
+                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
+                                   EMIT_RANGE_PRODUCT_FLAG,
+                                   EMIT_RANGE_PD_PRODUCT_FLAG,
+                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
+                                   EMIT_RANGE_NOTPRODUCT_FLAG,
+                                   EMIT_RANGE_CHECK,
+                                   IGNORE_CONSTRAINT));
+#endif // COMPILER1
+
+#ifdef COMPILER2
+  emit_range_no(NULL C2_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
+                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
+                                   EMIT_RANGE_PRODUCT_FLAG,
+                                   EMIT_RANGE_PD_PRODUCT_FLAG,
+                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
+                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
+                                   EMIT_RANGE_NOTPRODUCT_FLAG,
+                                   EMIT_RANGE_CHECK,
+                                   IGNORE_CONSTRAINT));
+#endif // COMPILER2
+
+#if INCLUDE_ALL_GCS
+  emit_range_no(NULL G1_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
+                                   EMIT_RANGE_PD_DEVELOPER_FLAG,
+                                   EMIT_RANGE_PRODUCT_FLAG,
+                                   EMIT_RANGE_PD_PRODUCT_FLAG,
+                                   EMIT_RANGE_DIAGNOSTIC_FLAG,
+                                   EMIT_RANGE_EXPERIMENTAL_FLAG,
+                                   EMIT_RANGE_NOTPRODUCT_FLAG,
+                                   EMIT_RANGE_MANAGEABLE_FLAG,
+                                   EMIT_RANGE_PRODUCT_RW_FLAG,
+                                   EMIT_RANGE_CHECK,
+                                   IGNORE_CONSTRAINT));
+#endif // INCLUDE_ALL_GCS
+}
+
+CommandLineFlagRange* CommandLineFlagRangeList::find(const char* name) {
+  CommandLineFlagRange* found = NULL;
+  for (int i=0; i<length(); i++) {
+    CommandLineFlagRange* range = at(i);
+    if (strcmp(range->name(), name) == 0) {
+      found = range;
+      break;
+    }
+  }
+  return found;
+}
+
+void CommandLineFlagRangeList::print(const char* name, outputStream* st, bool unspecified) {
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    range->print(st);
+  } else if (unspecified == true) {
+    st->print("[                           ...                           ]");
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_RUNTIME_COMMANDLINEFLAGRANGELIST_HPP
+#define SHARE_VM_RUNTIME_COMMANDLINEFLAGRANGELIST_HPP
+
+#include "runtime/globals.hpp"
+#include "utilities/growableArray.hpp"
+
+/*
+ * Here we have a mechanism for extracting ranges specified in flag macro tables.
+ *
+ * The specified ranges are used to verify that flags have valid values.
+ *
+ * An example of a range is "min <= flag <= max". Both "min" and "max" must be
+ * constant and can not change. If either "min" or "max" can change,
+ * then we need to use constraint instead.
+ */
+
+class CommandLineFlagRange : public CHeapObj<mtInternal> {
+private:
+  const char* _name;
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagRange(const char* name) { _name=name; }
+  ~CommandLineFlagRange() {}
+  const char* name() { return _name; }
+  virtual Flag::Error check_int(int value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }
+  virtual Flag::Error check_intx(intx value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }
+  virtual Flag::Error check_uint(uint value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }
+  virtual Flag::Error check_uintx(uintx value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }
+  virtual Flag::Error check_uint64_t(uint64_t value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }
+  virtual Flag::Error check_size_t(size_t value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }
+  virtual Flag::Error check_double(double value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }
+  virtual void print(outputStream* st) { ; }
+};
+
+class CommandLineFlagRangeList : public AllStatic {
+  static GrowableArray<CommandLineFlagRange*>* _ranges;
+public:
+  static void init();
+  static void add_globals_ext();
+  static int length() { return (_ranges != NULL) ? _ranges->length() : 0; }
+  static CommandLineFlagRange* at(int i) { return (_ranges != NULL) ? _ranges->at(i) : NULL; }
+  static CommandLineFlagRange* find(const char* name);
+  static void add(CommandLineFlagRange* range) { _ranges->append(range); }
+  static void print(const char* name, outputStream* st, bool unspecified = false);
+};
+
+#endif // SHARE_VM_RUNTIME_COMMANDLINEFLAGRANGELIST_HPP
--- a/hotspot/src/share/vm/runtime/globals.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -28,7 +28,10 @@
 #include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
+#include "runtime/commandLineFlagConstraintList.hpp"
+#include "runtime/commandLineFlagRangeList.hpp"
 #include "runtime/os.hpp"
+#include "runtime/sharedRuntime.hpp"
 #include "trace/tracing.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
@@ -48,24 +51,38 @@
 
 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
 
-RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
-              MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
-              MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
+RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
+              MATERIALIZE_PD_DEVELOPER_FLAG, \
+              MATERIALIZE_PRODUCT_FLAG, \
+              MATERIALIZE_PD_PRODUCT_FLAG, \
+              MATERIALIZE_DIAGNOSTIC_FLAG, \
+              MATERIALIZE_EXPERIMENTAL_FLAG, \
               MATERIALIZE_NOTPRODUCT_FLAG, \
-              MATERIALIZE_MANAGEABLE_FLAG, MATERIALIZE_PRODUCT_RW_FLAG, \
-              MATERIALIZE_LP64_PRODUCT_FLAG)
+              MATERIALIZE_MANAGEABLE_FLAG, \
+              MATERIALIZE_PRODUCT_RW_FLAG, \
+              MATERIALIZE_LP64_PRODUCT_FLAG, \
+              IGNORE_RANGE, \
+              IGNORE_CONSTRAINT)
 
-RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
-                 MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
-                 MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
+RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
+                 MATERIALIZE_PD_DEVELOPER_FLAG, \
+                 MATERIALIZE_PRODUCT_FLAG, \
+                 MATERIALIZE_PD_PRODUCT_FLAG, \
+                 MATERIALIZE_DIAGNOSTIC_FLAG, \
+                 MATERIALIZE_NOTPRODUCT_FLAG, \
+                 IGNORE_RANGE, \
+                 IGNORE_CONSTRAINT)
 
-ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, \
-           MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
-           MATERIALIZE_NOTPRODUCT_FLAG)
+ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
+           MATERIALIZE_PRODUCT_FLAG, \
+           MATERIALIZE_DIAGNOSTIC_FLAG, \
+           MATERIALIZE_EXPERIMENTAL_FLAG, \
+           MATERIALIZE_NOTPRODUCT_FLAG, \
+           IGNORE_RANGE, \
+           IGNORE_CONSTRAINT)
 
 MATERIALIZE_FLAGS_EXT
 
-
 static bool is_product_build() {
 #ifdef PRODUCT
   return true;
@@ -331,69 +348,86 @@
 #define FORMAT_BUFFER_LEN 16
 
 PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
-void Flag::print_on(outputStream* st, bool withComments) {
+void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
   // Don't print notproduct and develop flags in a product build.
   if (is_constant_in_binary()) {
     return;
   }
 
-  st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
+  if (!printRanges) {
+
+    st->print("%9s %-40s %c= ", _type, _name, (!is_default() ? ':' : ' '));
 
-  if (is_bool()) {
-    st->print("%-16s", get_bool() ? "true" : "false");
-  }
-  if (is_int()) {
-    st->print("%-16d", get_int());
-  }
-  if (is_uint()) {
-    st->print("%-16u", get_uint());
-  }
-  if (is_intx()) {
-    st->print("%-16ld", get_intx());
-  }
-  if (is_uintx()) {
-    st->print("%-16lu", get_uintx());
-  }
-  if (is_uint64_t()) {
-    st->print("%-16lu", get_uint64_t());
-  }
-  if (is_size_t()) {
-    st->print(SIZE_FORMAT_W(-16), get_size_t());
-  }
-  if (is_double()) {
-    st->print("%-16f", get_double());
+    if (is_bool()) {
+      st->print("%-16s", get_bool() ? "true" : "false");
+    } else if (is_int()) {
+      st->print("%-16d", get_int());
+    } else if (is_uint()) {
+      st->print("%-16u", get_uint());
+    } else if (is_intx()) {
+      st->print("%-16ld", get_intx());
+    } else if (is_uintx()) {
+      st->print("%-16lu", get_uintx());
+    } else if (is_uint64_t()) {
+      st->print("%-16lu", get_uint64_t());
+    } else if (is_size_t()) {
+      st->print(SIZE_FORMAT_W(-16), get_size_t());
+    } else if (is_double()) {
+      st->print("%-16f", get_double());
+    } else if (is_ccstr()) {
+      const char* cp = get_ccstr();
+      if (cp != NULL) {
+        const char* eol;
+        while ((eol = strchr(cp, '\n')) != NULL) {
+          char format_buffer[FORMAT_BUFFER_LEN];
+          size_t llen = pointer_delta(eol, cp, sizeof(char));
+          jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
+                       "%%." SIZE_FORMAT "s", llen);
+          PRAGMA_DIAG_PUSH
+          PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
+          st->print(format_buffer, cp);
+          PRAGMA_DIAG_POP
+          st->cr();
+          cp = eol+1;
+          st->print("%5s %-35s += ", "", _name);
+        }
+        st->print("%-16s", cp);
+      }
+      else st->print("%-16s", "");
+    }
+
+    st->print("%-20s", " ");
+    print_kind(st);
+
+#ifndef PRODUCT
+    if (withComments) {
+      st->print("%s", _doc);
+    }
+#endif
+
+    st->cr();
+
+  } else if (!is_bool() && !is_ccstr()) {
+
+    if (printRanges) {
+
+      st->print("%9s %-50s ", _type, _name);
+
+      CommandLineFlagRangeList::print(_name, st, true);
+
+      st->print(" %-20s", " ");
+      print_kind(st);
+
+#ifndef PRODUCT
+      if (withComments) {
+        st->print("%s", _doc);
+      }
+#endif
+
+      st->cr();
+
+    }
   }
-  if (is_ccstr()) {
-    const char* cp = get_ccstr();
-    if (cp != NULL) {
-      const char* eol;
-      while ((eol = strchr(cp, '\n')) != NULL) {
-        char format_buffer[FORMAT_BUFFER_LEN];
-        size_t llen = pointer_delta(eol, cp, sizeof(char));
-        jio_snprintf(format_buffer, FORMAT_BUFFER_LEN,
-            "%%." SIZE_FORMAT "s", llen);
-PRAGMA_DIAG_PUSH
-PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
-        st->print(format_buffer, cp);
-PRAGMA_DIAG_POP
-        st->cr();
-        cp = eol+1;
-        st->print("%5s %-35s += ", "", _name);
-      }
-      st->print("%-16s", cp);
-    }
-    else st->print("%-16s", "");
-  }
-
-  st->print("%-20s", " ");
-  print_kind(st);
-
-  if (withComments) {
-#ifndef PRODUCT
-    st->print("%s", _doc);
-#endif
-  }
-  st->cr();
 }
 
 void Flag::print_kind(outputStream* st) {
@@ -531,21 +565,75 @@
 #define SHARK_NOTPRODUCT_FLAG_STRUCT(    type, name, value, doc) { #type, XSTR(name), NAME(name), NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_NOT_PRODUCT) },
 
 static Flag flagTable[] = {
- RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT)
- RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT)
+ RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
+               RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
+               RUNTIME_PRODUCT_FLAG_STRUCT, \
+               RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
+               RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
+               RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
+               RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
+               RUNTIME_MANAGEABLE_FLAG_STRUCT, \
+               RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
+               RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \
+               IGNORE_RANGE, \
+               IGNORE_CONSTRAINT)
+ RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
+                  RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
+                  RUNTIME_PRODUCT_FLAG_STRUCT, \
+                  RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
+                  RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
+                  RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
+                  IGNORE_RANGE, \
+                  IGNORE_CONSTRAINT)
 #if INCLUDE_ALL_GCS
- G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT)
+ G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
+          RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
+          RUNTIME_PRODUCT_FLAG_STRUCT, \
+          RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
+          RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
+          RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
+          RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
+          RUNTIME_MANAGEABLE_FLAG_STRUCT, \
+          RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
+          IGNORE_RANGE, \
+          IGNORE_CONSTRAINT)
 #endif // INCLUDE_ALL_GCS
 #ifdef COMPILER1
- C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, C1_PD_DEVELOP_FLAG_STRUCT, C1_PRODUCT_FLAG_STRUCT, C1_PD_PRODUCT_FLAG_STRUCT, C1_DIAGNOSTIC_FLAG_STRUCT, C1_NOTPRODUCT_FLAG_STRUCT)
-#endif
+ C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \
+          C1_PD_DEVELOP_FLAG_STRUCT, \
+          C1_PRODUCT_FLAG_STRUCT, \
+          C1_PD_PRODUCT_FLAG_STRUCT, \
+          C1_DIAGNOSTIC_FLAG_STRUCT, \
+          C1_NOTPRODUCT_FLAG_STRUCT, \
+          IGNORE_RANGE, \
+          IGNORE_CONSTRAINT)
+#endif // COMPILER1
 #ifdef COMPILER2
- C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT)
-#endif
+ C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \
+          C2_PD_DEVELOP_FLAG_STRUCT, \
+          C2_PRODUCT_FLAG_STRUCT, \
+          C2_PD_PRODUCT_FLAG_STRUCT, \
+          C2_DIAGNOSTIC_FLAG_STRUCT, \
+          C2_EXPERIMENTAL_FLAG_STRUCT, \
+          C2_NOTPRODUCT_FLAG_STRUCT, \
+          IGNORE_RANGE, \
+          IGNORE_CONSTRAINT)
+#endif // COMPILER2
 #ifdef SHARK
- SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, SHARK_PD_DEVELOP_FLAG_STRUCT, SHARK_PRODUCT_FLAG_STRUCT, SHARK_PD_PRODUCT_FLAG_STRUCT, SHARK_DIAGNOSTIC_FLAG_STRUCT, SHARK_NOTPRODUCT_FLAG_STRUCT)
-#endif
- ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, ARCH_PRODUCT_FLAG_STRUCT, ARCH_DIAGNOSTIC_FLAG_STRUCT, ARCH_EXPERIMENTAL_FLAG_STRUCT, ARCH_NOTPRODUCT_FLAG_STRUCT)
+ SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, \
+             SHARK_PD_DEVELOP_FLAG_STRUCT, \
+             SHARK_PRODUCT_FLAG_STRUCT, \
+             SHARK_PD_PRODUCT_FLAG_STRUCT, \
+             SHARK_DIAGNOSTIC_FLAG_STRUCT, \
+             SHARK_NOTPRODUCT_FLAG_STRUCT)
+#endif // SHARK
+ ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \
+            ARCH_PRODUCT_FLAG_STRUCT, \
+            ARCH_DIAGNOSTIC_FLAG_STRUCT, \
+            ARCH_EXPERIMENTAL_FLAG_STRUCT, \
+            ARCH_NOTPRODUCT_FLAG_STRUCT, \
+            IGNORE_RANGE, \
+            IGNORE_CONSTRAINT)
  FLAGTABLE_EXT
  {0, NULL, NULL}
 };
@@ -566,7 +654,7 @@
       // Found a matching entry.
       // Don't report notproduct and develop flags in product builds.
       if (current->is_constant_in_binary()) {
-        return (return_flag == true ? current : NULL);
+        return (return_flag ? current : NULL);
       }
       // Report locked flags only if allowed.
       if (!(current->is_unlocked() || current->is_unlocker())) {
@@ -661,8 +749,7 @@
 }
 
 template<class E, class T>
-static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin)
-{
+static void trace_flag_changed(const char* name, const T old_value, const T new_value, const Flag::Flags origin) {
   E e;
   e.set_name(name);
   e.set_old_value(old_value);
@@ -671,242 +758,395 @@
   e.commit();
 }
 
-bool CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
-  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_bool()) return false;
-  *value = result->get_bool();
-  return true;
+static Flag::Error get_status_error(Flag::Error status_range, Flag::Error status_constraint) {
+  if (status_range != Flag::SUCCESS) {
+    return status_range;
+  } else if (status_constraint != Flag::SUCCESS) {
+    return status_constraint;
+  } else {
+    return Flag::SUCCESS;
+  }
 }
 
-bool CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
+static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool* new_value, bool verbose = true) {
+  Flag::Error status = Flag::SUCCESS;
+  CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
+  if (constraint != NULL) {
+    status = constraint->apply_bool(new_value, verbose);
+  }
+  return status;
+}
+
+Flag::Error CommandLineFlags::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
+  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_bool()) return Flag::WRONG_FORMAT;
+  *value = result->get_bool();
+  return Flag::SUCCESS;
+}
+
+Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_bool()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_bool()) return Flag::WRONG_FORMAT;
+  Flag::Error check = apply_constraint_and_check_range_bool(name, value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   bool old_value = result->get_bool();
   trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
   result->set_bool(*value);
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
+  Flag::Error check = apply_constraint_and_check_range_bool(faddr->_name, &value);
+  if (check != Flag::SUCCESS) return check;
   trace_flag_changed<EventBooleanFlagChanged, bool>(faddr->_name, faddr->get_bool(), value, origin);
   faddr->set_bool(value);
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
-  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_int()) return false;
-  *value = result->get_int();
-  return true;
+static Flag::Error apply_constraint_and_check_range_int(const char* name, int* new_value, bool verbose = true) {
+  Flag::Error range_status = Flag::SUCCESS;
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    range_status = range->check_int(*new_value, verbose);
+  }
+  Flag::Error constraint_status = Flag::SUCCESS;
+  CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
+  if (constraint != NULL) {
+    constraint_status = constraint->apply_int(new_value, verbose);
+  }
+  return get_status_error(range_status, constraint_status);
 }
 
-bool CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
+Flag::Error CommandLineFlags::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
+  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_int()) return Flag::WRONG_FORMAT;
+  *value = result->get_int();
+  return Flag::SUCCESS;
+}
+
+Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_int()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_int()) return Flag::WRONG_FORMAT;
+  Flag::Error check = apply_constraint_and_check_range_int(name, value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   int old_value = result->get_int();
   trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
   result->set_int(*value);
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
   trace_flag_changed<EventIntFlagChanged, s4>(faddr->_name, faddr->get_int(), value, origin);
   faddr->set_int(value);
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
-  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_uint()) return false;
-  *value = result->get_uint();
-  return true;
+static Flag::Error apply_constraint_and_check_range_uint(const char* name, uint* new_value, bool verbose = true) {
+  Flag::Error range_status = Flag::SUCCESS;
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    range_status = range->check_uint(*new_value, verbose);
+  }
+  Flag::Error constraint_status = Flag::SUCCESS;
+  CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
+  if (constraint != NULL) {
+    constraint_status = constraint->apply_uint(new_value, verbose);
+  }
+  return get_status_error(range_status, constraint_status);
 }
 
-bool CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
+Flag::Error CommandLineFlags::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
+  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_uint()) return Flag::WRONG_FORMAT;
+  *value = result->get_uint();
+  return Flag::SUCCESS;
+}
+
+Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_uint()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_uint()) return Flag::WRONG_FORMAT;
+  Flag::Error check = apply_constraint_and_check_range_uint(name, value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   uint old_value = result->get_uint();
   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
   result->set_uint(*value);
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(faddr->_name, faddr->get_uint(), value, origin);
   faddr->set_uint(value);
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
+}
+
+Flag::Error CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
+  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_intx()) return Flag::WRONG_FORMAT;
+  *value = result->get_intx();
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
-  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_intx()) return false;
-  *value = result->get_intx();
-  return true;
+static Flag::Error apply_constraint_and_check_range_intx(const char* name, intx* new_value, bool verbose = true) {
+  Flag::Error range_status = Flag::SUCCESS;
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    range_status = range->check_intx(*new_value, verbose);
+  }
+  Flag::Error constraint_status = Flag::SUCCESS;
+  CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
+  if (constraint != NULL) {
+    constraint_status = constraint->apply_intx(new_value, verbose);
+  }
+  return get_status_error(range_status, constraint_status);
 }
 
-bool CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
+Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_intx()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_intx()) return Flag::WRONG_FORMAT;
+  Flag::Error check = apply_constraint_and_check_range_intx(name, value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   intx old_value = result->get_intx();
-  trace_flag_changed<EventLongFlagChanged, s8>(name, old_value, *value, origin);
+  trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
   result->set_intx(*value);
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
-  trace_flag_changed<EventLongFlagChanged, s8>(faddr->_name, faddr->get_intx(), value, origin);
+  Flag::Error check = apply_constraint_and_check_range_intx(faddr->_name, &value);
+  if (check != Flag::SUCCESS) return check;
+  trace_flag_changed<EventLongFlagChanged, intx>(faddr->_name, faddr->get_intx(), value, origin);
   faddr->set_intx(value);
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
+Flag::Error CommandLineFlags::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_uintx()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_uintx()) return Flag::WRONG_FORMAT;
   *value = result->get_uintx();
-  return true;
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
+static Flag::Error apply_constraint_and_check_range_uintx(const char* name, uintx* new_value, bool verbose = true) {
+  Flag::Error range_status = Flag::SUCCESS;
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    range_status = range->check_uintx(*new_value, verbose);
+  }
+  Flag::Error constraint_status = Flag::SUCCESS;
+  CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
+  if (constraint != NULL) {
+    constraint_status = constraint->apply_uintx(new_value, verbose);
+  }
+  return get_status_error(range_status, constraint_status);
+}
+
+Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_uintx()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_uintx()) return Flag::WRONG_FORMAT;
+  Flag::Error check = apply_constraint_and_check_range_uintx(name, value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   uintx old_value = result->get_uintx();
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
   result->set_uintx(*value);
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
+  Flag::Error check = apply_constraint_and_check_range_uintx(faddr->_name, &value);
+  if (check != Flag::SUCCESS) return check;
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uintx(), value, origin);
   faddr->set_uintx(value);
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
+}
+
+Flag::Error CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
+  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
+  *value = result->get_uint64_t();
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
-  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_uint64_t()) return false;
-  *value = result->get_uint64_t();
-  return true;
+static Flag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t* new_value, bool verbose = true) {
+  Flag::Error range_status = Flag::SUCCESS;
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    range_status = range->check_uint64_t(*new_value, verbose);
+  }
+  Flag::Error constraint_status = Flag::SUCCESS;
+  CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
+  if (constraint != NULL) {
+    constraint_status = constraint->apply_uint64_t(new_value, verbose);
+  }
+  return get_status_error(range_status, constraint_status);
 }
 
-bool CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
+Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_uint64_t()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_uint64_t()) return Flag::WRONG_FORMAT;
+  Flag::Error check = apply_constraint_and_check_range_uint64_t(name, value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   uint64_t old_value = result->get_uint64_t();
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
   result->set_uint64_t(*value);
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
+  Flag::Error check = apply_constraint_and_check_range_uint64_t(faddr->_name, &value);
+  if (check != Flag::SUCCESS) return check;
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_uint64_t(), value, origin);
   faddr->set_uint64_t(value);
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
+}
+
+Flag::Error CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
+  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_size_t()) return Flag::WRONG_FORMAT;
+  *value = result->get_size_t();
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
-  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_size_t()) return false;
-  *value = result->get_size_t();
-  return true;
+static Flag::Error apply_constraint_and_check_range_size_t(const char* name, size_t* new_value, bool verbose = true) {
+  Flag::Error range_status = Flag::SUCCESS;
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    range_status = range->check_size_t(*new_value, verbose);
+  }
+  Flag::Error constraint_status = Flag::SUCCESS;
+  CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
+  if (constraint != NULL) {
+    constraint_status = constraint->apply_size_t(new_value, verbose);
+  }
+  return get_status_error(range_status, constraint_status);
 }
 
-bool CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
+Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_size_t()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_size_t()) return Flag::WRONG_FORMAT;
+  Flag::Error check = apply_constraint_and_check_range_size_t(name, value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   size_t old_value = result->get_size_t();
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
   result->set_size_t(*value);
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
+  Flag::Error check = apply_constraint_and_check_range_size_t(faddr->_name, &value);
+  if (check != Flag::SUCCESS) return check;
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(faddr->_name, faddr->get_size_t(), value, origin);
   faddr->set_size_t(value);
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
+}
+
+Flag::Error CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
+  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_double()) return Flag::WRONG_FORMAT;
+  *value = result->get_double();
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
-  Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_double()) return false;
-  *value = result->get_double();
-  return true;
+static Flag::Error apply_constraint_and_check_range_double(const char* name, double* new_value, bool verbose = true) {
+  Flag::Error range_status = Flag::SUCCESS;
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    range_status = range->check_double(*new_value, verbose);
+  }
+  Flag::Error constraint_status = Flag::SUCCESS;
+  CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name);
+  if (constraint != NULL) {
+    constraint_status = constraint->apply_double(new_value, verbose);
+  }
+  return get_status_error(range_status, constraint_status);
 }
 
-bool CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
+Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_double()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_double()) return Flag::WRONG_FORMAT;
+  Flag::Error check = apply_constraint_and_check_range_double(name, value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   double old_value = result->get_double();
   trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
   result->set_double(*value);
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
+  Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, &value, !CommandLineFlags::finishedInitializing());
+  if (check != Flag::SUCCESS) return check;
   trace_flag_changed<EventDoubleFlagChanged, double>(faddr->_name, faddr->get_double(), value, origin);
   faddr->set_double(value);
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) {
+Flag::Error CommandLineFlags::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) {
   Flag* result = Flag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return false;
-  if (!result->is_ccstr()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
   *value = result->get_ccstr();
-  return true;
+  return Flag::SUCCESS;
 }
 
-bool CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) {
+Flag::Error CommandLineFlags::ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin) {
   Flag* result = Flag::find_flag(name, len);
-  if (result == NULL) return false;
-  if (!result->is_ccstr()) return false;
+  if (result == NULL) return Flag::INVALID_FLAG;
+  if (!result->is_ccstr()) return Flag::WRONG_FORMAT;
   ccstr old_value = result->get_ccstr();
   trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
   char* new_value = NULL;
@@ -920,10 +1160,10 @@
   }
   *value = old_value;
   result->set_origin(origin);
-  return true;
+  return Flag::SUCCESS;
 }
 
-void CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
+Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
   ccstr old_value = faddr->get_ccstr();
@@ -935,6 +1175,7 @@
     FREE_C_HEAP_ARRAY(char, old_value);
   }
   faddr->set_origin(origin);
+  return Flag::SUCCESS;
 }
 
 extern "C" {
@@ -969,16 +1210,140 @@
   FREE_C_HEAP_ARRAY(Flag*, array);
 }
 
+bool CommandLineFlags::_finished_initializing = false;
+
+bool CommandLineFlags::check_all_ranges_and_constraints() {
+
+//#define PRINT_RANGES_AND_CONSTRAINTS_SIZES
+#ifdef PRINT_RANGES_AND_CONSTRAINTS_SIZES
+  {
+    size_t size_ranges = sizeof(CommandLineFlagRangeList);
+    for (int i=0; i<CommandLineFlagRangeList::length(); i++) {
+      size_ranges += sizeof(CommandLineFlagRange);
+      CommandLineFlagRange* range = CommandLineFlagRangeList::at(i);
+      const char* name = range->name();
+      Flag* flag = Flag::find_flag(name, strlen(name), true, true);
+      if (flag->is_intx()) {
+        size_ranges += 2*sizeof(intx);
+        size_ranges += sizeof(CommandLineFlagRange*);
+      } else if (flag->is_uintx()) {
+        size_ranges += 2*sizeof(uintx);
+        size_ranges += sizeof(CommandLineFlagRange*);
+      } else if (flag->is_uint64_t()) {
+        size_ranges += 2*sizeof(uint64_t);
+        size_ranges += sizeof(CommandLineFlagRange*);
+      } else if (flag->is_size_t()) {
+        size_ranges += 2*sizeof(size_t);
+        size_ranges += sizeof(CommandLineFlagRange*);
+      } else if (flag->is_double()) {
+        size_ranges += 2*sizeof(double);
+        size_ranges += sizeof(CommandLineFlagRange*);
+      }
+    }
+    fprintf(stderr, "Size of %d ranges: "SIZE_FORMAT" bytes\n",
+            CommandLineFlagRangeList::length(), size_ranges);
+  }
+  {
+    size_t size_constraints = sizeof(CommandLineFlagConstraintList);
+    for (int i=0; i<CommandLineFlagConstraintList::length(); i++) {
+      size_constraints += sizeof(CommandLineFlagConstraint);
+      CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::at(i);
+      const char* name = constraint->name();
+      Flag* flag = Flag::find_flag(name, strlen(name), true, true);
+      if (flag->is_bool()) {
+        size_constraints += sizeof(CommandLineFlagConstraintFunc_bool);
+        size_constraints += sizeof(CommandLineFlagConstraint*);
+      } else if (flag->is_intx()) {
+        size_constraints += sizeof(CommandLineFlagConstraintFunc_intx);
+        size_constraints += sizeof(CommandLineFlagConstraint*);
+      } else if (flag->is_uintx()) {
+        size_constraints += sizeof(CommandLineFlagConstraintFunc_uintx);
+        size_constraints += sizeof(CommandLineFlagConstraint*);
+      } else if (flag->is_uint64_t()) {
+        size_constraints += sizeof(CommandLineFlagConstraintFunc_uint64_t);
+        size_constraints += sizeof(CommandLineFlagConstraint*);
+      } else if (flag->is_size_t()) {
+        size_constraints += sizeof(CommandLineFlagConstraintFunc_size_t);
+        size_constraints += sizeof(CommandLineFlagConstraint*);
+      } else if (flag->is_double()) {
+        size_constraints += sizeof(CommandLineFlagConstraintFunc_double);
+        size_constraints += sizeof(CommandLineFlagConstraint*);
+      }
+    }
+    fprintf(stderr, "Size of %d constraints: "SIZE_FORMAT" bytes\n",
+            CommandLineFlagConstraintList::length(), size_constraints);
+  }
+#endif // PRINT_RANGES_AND_CONSTRAINTS_SIZES
+
+  _finished_initializing = true;
+
+  bool status = true;
+  for (int i=0; i<CommandLineFlagRangeList::length(); i++) {
+    CommandLineFlagRange* range = CommandLineFlagRangeList::at(i);
+    const char* name = range->name();
+    Flag* flag = Flag::find_flag(name, strlen(name), true, true);
+    if (flag != NULL) {
+      if (flag->is_intx()) {
+        intx value = flag->get_intx();
+        if (range->check_intx(value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_uintx()) {
+        uintx value = flag->get_uintx();
+        if (range->check_uintx(value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_uint64_t()) {
+        uint64_t value = flag->get_uint64_t();
+        if (range->check_uint64_t(value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_size_t()) {
+        size_t value = flag->get_size_t();
+        if (range->check_size_t(value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_double()) {
+        double value = flag->get_double();
+        if (range->check_double(value, true) != Flag::SUCCESS) status = false;
+      }
+    }
+  }
+  for (int i=0; i<CommandLineFlagConstraintList::length(); i++) {
+    CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::at(i);
+    const char*name = constraint->name();
+    Flag* flag = Flag::find_flag(name, strlen(name), true, true);
+    if (flag != NULL) {
+      if (flag->is_bool()) {
+        bool value = flag->get_bool();
+        if (constraint->apply_bool(&value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_intx()) {
+        intx value = flag->get_intx();
+        if (constraint->apply_intx(&value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_uintx()) {
+        uintx value = flag->get_uintx();
+        if (constraint->apply_uintx(&value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_uint64_t()) {
+        uint64_t value = flag->get_uint64_t();
+        if (constraint->apply_uint64_t(&value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_size_t()) {
+        size_t value = flag->get_size_t();
+        if (constraint->apply_size_t(&value, true) != Flag::SUCCESS) status = false;
+      } else if (flag->is_double()) {
+        double value = flag->get_double();
+        if (constraint->apply_double(&value, true) != Flag::SUCCESS) status = false;
+      }
+    }
+  }
+
+  Arguments::post_final_range_and_constraint_check(status);
+
+  return status;
+}
+
 #ifndef PRODUCT
 
-
 void CommandLineFlags::verify() {
   assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict");
 }
 
 #endif // PRODUCT
 
-void CommandLineFlags::printFlags(outputStream* out, bool withComments) {
+#define ONLY_PRINT_PRODUCT_FLAGS
+
+void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) {
   // Print the flags sorted by name
   // note: this method is called before the thread structure is in place
   //       which means resource allocation cannot be used.
@@ -994,10 +1359,18 @@
   qsort(array, length, sizeof(Flag*), compare_flags);
 
   // Print
-  out->print_cr("[Global flags]");
+  if (!printRanges) {
+    out->print_cr("[Global flags]");
+  } else {
+    out->print_cr("[Global flags ranges]");
+  }
+
   for (size_t i = 0; i < length; i++) {
     if (array[i]->is_unlocked()) {
-      array[i]->print_on(out, withComments);
+#ifdef ONLY_PRINT_PRODUCT_FLAGS
+      if (!array[i]->is_notproduct() && !array[i]->is_develop())
+#endif // ONLY_PRINT_PRODUCT_FLAGS
+      array[i]->print_on(out, withComments, printRanges);
     }
   }
   FREE_C_HEAP_ARRAY(Flag*, array);
--- a/hotspot/src/share/vm/runtime/globals.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -258,6 +258,27 @@
     KIND_MASK = ~VALUE_ORIGIN_MASK
   };
 
+  enum Error {
+    // no error
+    SUCCESS = 0,
+    // flag name is missing
+    MISSING_NAME,
+    // flag value is missing
+    MISSING_VALUE,
+    // error parsing the textual form of the value
+    WRONG_FORMAT,
+    // flag is not writeable
+    NON_WRITABLE,
+    // flag value is outside of its bounds
+    OUT_OF_BOUNDS,
+    // flag value violates its constraint
+    VIOLATES_CONSTRAINT,
+    // there is no flag with the given name
+    INVALID_FLAG,
+    // other, unspecified error related to setting the flag
+    ERR_OTHER
+  };
+
   const char* _type;
   const char* _name;
   void* _addr;
@@ -270,6 +291,7 @@
   // number of flags
   static size_t numFlags;
 
+  static Flag* find_flag(const char* name) { return find_flag(name, strlen(name), true, true); };
   static Flag* find_flag(const char* name, size_t length, bool allow_locked = false, bool return_flag = false);
   static Flag* fuzzy_match(const char* name, size_t length, bool allow_locked = false);
 
@@ -345,9 +367,24 @@
   void get_locked_message(char*, int) const;
   void get_locked_message_ext(char*, int) const;
 
-  void print_on(outputStream* st, bool withComments = false );
+  // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
+  void print_on(outputStream* st, bool withComments = false, bool printRanges = false);
   void print_kind(outputStream* st);
   void print_as_flag(outputStream* st);
+
+  static const char* flag_error_str(Flag::Error error) {
+    switch (error) {
+      case Flag::MISSING_NAME: return "MISSING_NAME";
+      case Flag::MISSING_VALUE: return "MISSING_VALUE";
+      case Flag::NON_WRITABLE: return "NON_WRITABLE";
+      case Flag::OUT_OF_BOUNDS: return "OUT_OF_BOUNDS";
+      case Flag::VIOLATES_CONSTRAINT: return "VIOLATES_CONSTRAINT";
+      case Flag::INVALID_FLAG: return "INVALID_FLAG";
+      case Flag::ERR_OTHER: return "ERR_OTHER";
+      case Flag::SUCCESS: return "SUCCESS";
+      default: return "NULL";
+    }
+  }
 };
 
 // debug flags control various aspects of the VM and are global accessible
@@ -413,59 +450,67 @@
 
 
 class CommandLineFlags {
- public:
-  static bool boolAt(const char* name, size_t len, bool* value, bool allow_locked = false, bool return_flag = false);
-  static bool boolAt(const char* name, bool* value, bool allow_locked = false, bool return_flag = false)      { return boolAt(name, strlen(name), value, allow_locked, return_flag); }
-  static bool boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin);
-  static bool boolAtPut(const char* name, bool* value, Flag::Flags origin)   { return boolAtPut(name, strlen(name), value, origin); }
+  static bool _finished_initializing;
+public:
+  static Flag::Error boolAt(const char* name, size_t len, bool* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error boolAt(const char* name, bool* value, bool allow_locked = false, bool return_flag = false)      { return boolAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin);
+  static Flag::Error boolAtPut(const char* name, bool* value, Flag::Flags origin)   { return boolAtPut(name, strlen(name), value, origin); }
 
-  static bool intAt(const char* name, size_t len, int* value, bool allow_locked = false, bool return_flag = false);
-  static bool intAt(const char* name, int* value, bool allow_locked = false, bool return_flag = false)      { return intAt(name, strlen(name), value, allow_locked, return_flag); }
-  static bool intAtPut(const char* name, size_t len, int* value, Flag::Flags origin);
-  static bool intAtPut(const char* name, int* value, Flag::Flags origin)   { return intAtPut(name, strlen(name), value, origin); }
+  static Flag::Error intAt(const char* name, size_t len, int* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error intAt(const char* name, int* value, bool allow_locked = false, bool return_flag = false)      { return intAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error intAtPut(const char* name, size_t len, int* value, Flag::Flags origin);
+  static Flag::Error intAtPut(const char* name, int* value, Flag::Flags origin)   { return intAtPut(name, strlen(name), value, origin); }
 
-  static bool uintAt(const char* name, size_t len, uint* value, bool allow_locked = false, bool return_flag = false);
-  static bool uintAt(const char* name, uint* value, bool allow_locked = false, bool return_flag = false)      { return uintAt(name, strlen(name), value, allow_locked, return_flag); }
-  static bool uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin);
-  static bool uintAtPut(const char* name, uint* value, Flag::Flags origin)   { return uintAtPut(name, strlen(name), value, origin); }
+  static Flag::Error uintAt(const char* name, size_t len, uint* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error uintAt(const char* name, uint* value, bool allow_locked = false, bool return_flag = false)      { return uintAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin);
+  static Flag::Error uintAtPut(const char* name, uint* value, Flag::Flags origin)   { return uintAtPut(name, strlen(name), value, origin); }
 
-  static bool intxAt(const char* name, size_t len, intx* value, bool allow_locked = false, bool return_flag = false);
-  static bool intxAt(const char* name, intx* value, bool allow_locked = false, bool return_flag = false)      { return intxAt(name, strlen(name), value, allow_locked, return_flag); }
-  static bool intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin);
-  static bool intxAtPut(const char* name, intx* value, Flag::Flags origin)   { return intxAtPut(name, strlen(name), value, origin); }
+  static Flag::Error intxAt(const char* name, size_t len, intx* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error intxAt(const char* name, intx* value, bool allow_locked = false, bool return_flag = false)      { return intxAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin);
+  static Flag::Error intxAtPut(const char* name, intx* value, Flag::Flags origin)   { return intxAtPut(name, strlen(name), value, origin); }
 
-  static bool uintxAt(const char* name, size_t len, uintx* value, bool allow_locked = false, bool return_flag = false);
-  static bool uintxAt(const char* name, uintx* value, bool allow_locked = false, bool return_flag = false)    { return uintxAt(name, strlen(name), value, allow_locked, return_flag); }
-  static bool uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin);
-  static bool uintxAtPut(const char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
+  static Flag::Error uintxAt(const char* name, size_t len, uintx* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error uintxAt(const char* name, uintx* value, bool allow_locked = false, bool return_flag = false)    { return uintxAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin);
+  static Flag::Error uintxAtPut(const char* name, uintx* value, Flag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
 
-  static bool size_tAt(const char* name, size_t len, size_t* value, bool allow_locked = false, bool return_flag = false);
-  static bool size_tAt(const char* name, size_t* value, bool allow_locked = false, bool return_flag = false)    { return size_tAt(name, strlen(name), value, allow_locked, return_flag); }
-  static bool size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin);
-  static bool size_tAtPut(const char* name, size_t* value, Flag::Flags origin) { return size_tAtPut(name, strlen(name), value, origin); }
+  static Flag::Error size_tAt(const char* name, size_t len, size_t* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error size_tAt(const char* name, size_t* value, bool allow_locked = false, bool return_flag = false)    { return size_tAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin);
+  static Flag::Error size_tAtPut(const char* name, size_t* value, Flag::Flags origin) { return size_tAtPut(name, strlen(name), value, origin); }
 
-  static bool uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked = false, bool return_flag = false);
-  static bool uint64_tAt(const char* name, uint64_t* value, bool allow_locked = false, bool return_flag = false) { return uint64_tAt(name, strlen(name), value, allow_locked, return_flag); }
-  static bool uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin);
-  static bool uint64_tAtPut(const char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
+  static Flag::Error uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error uint64_tAt(const char* name, uint64_t* value, bool allow_locked = false, bool return_flag = false) { return uint64_tAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin);
+  static Flag::Error uint64_tAtPut(const char* name, uint64_t* value, Flag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
 
-  static bool doubleAt(const char* name, size_t len, double* value, bool allow_locked = false, bool return_flag = false);
-  static bool doubleAt(const char* name, double* value, bool allow_locked = false, bool return_flag = false)    { return doubleAt(name, strlen(name), value, allow_locked, return_flag); }
-  static bool doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin);
-  static bool doubleAtPut(const char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
+  static Flag::Error doubleAt(const char* name, size_t len, double* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error doubleAt(const char* name, double* value, bool allow_locked = false, bool return_flag = false)    { return doubleAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin);
+  static Flag::Error doubleAtPut(const char* name, double* value, Flag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
 
-  static bool ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked = false, bool return_flag = false);
-  static bool ccstrAt(const char* name, ccstr* value, bool allow_locked = false, bool return_flag = false)    { return ccstrAt(name, strlen(name), value, allow_locked, return_flag); }
+  static Flag::Error ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked = false, bool return_flag = false);
+  static Flag::Error ccstrAt(const char* name, ccstr* value, bool allow_locked = false, bool return_flag = false)    { return ccstrAt(name, strlen(name), value, allow_locked, return_flag); }
   // Contract:  Flag will make private copy of the incoming value.
   // Outgoing value is always malloc-ed, and caller MUST call free.
-  static bool ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin);
-  static bool ccstrAtPut(const char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); }
+  static Flag::Error ccstrAtPut(const char* name, size_t len, ccstr* value, Flag::Flags origin);
+  static Flag::Error ccstrAtPut(const char* name, ccstr* value, Flag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); }
 
   // Returns false if name is not a command line flag.
   static bool wasSetOnCmdline(const char* name, bool* value);
   static void printSetFlags(outputStream* out);
 
-  static void printFlags(outputStream* out, bool withComments);
+  // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
+  static void printFlags(outputStream* out, bool withComments, bool printRanges = false);
+
+  // Returns true if all flags have their final values set (ready for ranges and constraint check)
+  static bool finishedInitializing() { return _finished_initializing; }
+
+  // Check the final values of all flags for ranges and constraints
+  static bool check_all_ranges_and_constraints();
 
   static void verify() PRODUCT_RETURN;
 };
@@ -559,8 +604,15 @@
 //
 // Note that when there is a need to support develop flags to be writeable,
 // it can be done in the same way as product_rw.
+//
+// range is a macro that will expand to min and max arguments for range
+//    checking code if provided - see commandLineFlagRangeList.hpp
+//
+// constraint is a macro that will expand to custom function call
+//    for constraint checking if provided - see commandLineFlagConstraintList.hpp
+//
 
-#define RUNTIME_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw, lp64_product) \
+#define RUNTIME_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw, lp64_product, range, constraint) \
                                                                             \
   lp64_product(bool, UseCompressedOops, false,                              \
           "Use 32-bit object references in 64-bit VM. "                     \
@@ -580,19 +632,22 @@
           "Heap allocation steps through preferred address regions to find" \
           " where it can allocate the heap. Number of steps to take per "   \
           "region.")                                                        \
+          range(1, max_uintx)                                               \
                                                                             \
   diagnostic(bool, PrintCompressedOopsMode, false,                          \
           "Print compressed oops base address and encoding mode")           \
                                                                             \
   lp64_product(intx, ObjectAlignmentInBytes, 8,                             \
           "Default object alignment in bytes, 8 is minimum")                \
+          range(8, 256)                                                     \
+          constraint(ObjectAlignmentInBytesConstraintFunc)                  \
                                                                             \
   product(bool, AssumeMP, false,                                            \
           "Instruct the VM to assume multiple processors are available")    \
                                                                             \
-  /* UseMembar is theoretically a temp flag used for memory barrier         \
-   * removal testing.  It was supposed to be removed before FCS but has     \
-   * been re-added (see 6401008) */                                         \
+  /* UseMembar is theoretically a temp flag used for memory barrier      */ \
+  /* removal testing.  It was supposed to be removed before FCS but has  */ \
+  /* been re-added (see 6401008)                                         */ \
   product_pd(bool, UseMembar,                                               \
           "(Unstable) Issues membars on thread state transitions")          \
                                                                             \
@@ -649,6 +704,7 @@
           "Percentage (0-100) used to weight the current sample when "      \
           "computing exponentially decaying average for "                   \
           "AdaptiveNUMAChunkSizing")                                        \
+          range(0, 100)                                                     \
                                                                             \
   product(size_t, NUMASpaceResizeRate, 1*G,                                 \
           "Do not reallocate more than this amount per collection")         \
@@ -838,7 +894,7 @@
           "Die upon failure to reach safepoint (see SafepointTimeout)")     \
                                                                             \
   /* 50 retries * (5 * current_retry_count) millis = ~6.375 seconds */      \
-  /* typically, at most a few retries are needed */                         \
+  /* typically, at most a few retries are needed                    */      \
   product(intx, SuspendRetryCount, 50,                                      \
           "Maximum retry count for an external suspend request")            \
                                                                             \
@@ -859,6 +915,7 @@
                                                                             \
   diagnostic(uintx, LogEventsBufferEntries, 10,                             \
           "Number of ring buffer event logs")                               \
+          range(1, NOT_LP64(1*K) LP64_ONLY(1*M))                            \
                                                                             \
   product(bool, BytecodeVerificationRemote, true,                           \
           "Enable the Java bytecode verifier for remote classes")           \
@@ -1031,6 +1088,7 @@
           "0: do not allow scavengable oops in the code cache; "            \
           "1: allow scavenging from the code cache; "                       \
           "2: emit as many constants as the compiler can see")              \
+          range(0, 2)                                                       \
                                                                             \
   product(bool, AlwaysRestoreFPU, false,                                    \
           "Restore the FPU control word after every JNI call (expensive)")  \
@@ -1304,8 +1362,10 @@
           "Use SSE2 MOVQ instruction for Arraycopy")                        \
                                                                             \
   product(intx, FieldsAllocationStyle, 1,                                   \
-          "0 - type based with oops first, 1 - with oops last, "            \
+          "0 - type based with oops first, "                                \
+          "1 - with oops last, "                                            \
           "2 - oops in super and sub classes are together")                 \
+          range(0, 2)                                                       \
                                                                             \
   product(bool, CompactFields, true,                                        \
           "Allocate nonstatic fields in gaps between previous fields")      \
@@ -1313,8 +1373,14 @@
   notproduct(bool, PrintFieldLayout, false,                                 \
           "Print field layout for each class")                              \
                                                                             \
+  /* Need to limit the extent of the padding to reasonable size.          */\
+  /* 8K is well beyond the reasonable HW cache line size, even with       */\
+  /* aggressive prefetching, while still leaving the room for segregating */\
+  /* among the distinct pages.                                            */\
   product(intx, ContendedPaddingWidth, 128,                                 \
           "How many bytes to pad the fields/classes marked @Contended with")\
+          range(0, 8192)                                                    \
+          constraint(ContendedPaddingWidthConstraintFunc)                   \
                                                                             \
   product(bool, EnableContended, true,                                      \
           "Enable @Contended annotation support")                           \
@@ -1362,7 +1428,7 @@
                                                                             \
   /* This option can change an EMCP method into an obsolete method. */      \
   /* This can affect tests that except specific methods to be EMCP. */      \
-  /* This option should be used with caution. */                            \
+  /* This option should be used with caution.                       */      \
   product(bool, StressLdcRewrite, false,                                    \
           "Force ldc -> ldc_w rewrite during RedefineClasses")              \
                                                                             \
@@ -1476,10 +1542,12 @@
   product(uintx, ParallelOldDeadWoodLimiterMean, 50,                        \
           "The mean used by the parallel compact dead wood "                \
           "limiter (a number between 0-100)")                               \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, ParallelOldDeadWoodLimiterStdDev, 80,                      \
           "The standard deviation used by the parallel compact dead wood "  \
           "limiter (a number between 0-100)")                               \
+          range(0, 100)                                                     \
                                                                             \
   product(uint, ParallelGCThreads, 0,                                       \
           "Number of parallel threads parallel gc will use")                \
@@ -1495,6 +1563,7 @@
   product(size_t, HeapSizePerGCThread, ScaleForWordSize(64*M),              \
           "Size of heap (bytes) per GC thread used in calculating the "     \
           "number of GC threads")                                           \
+          range((uintx)os::vm_page_size(), max_uintx)                       \
                                                                             \
   product(bool, TraceDynamicGCThreads, false,                               \
           "Trace the dynamic GC thread usage")                              \
@@ -1505,6 +1574,7 @@
                                                                             \
   develop(uintx, ParallelOldGCSplitInterval, 3,                             \
           "How often to provoke splitting a young gen space")               \
+          range(0, max_uintx)                                               \
                                                                             \
   product(uint, ConcGCThreads, 0,                                           \
           "Number of threads concurrent gc will use")                       \
@@ -1518,6 +1588,7 @@
                                                                             \
   product(uintx, GCTaskTimeStampEntries, 200,                               \
           "Number of time stamp entries per gc worker thread")              \
+          range(1, max_uintx)                                               \
                                                                             \
   product(bool, AlwaysTenure, false,                                        \
           "Always tenure objects in eden (ParallelGC only)")                \
@@ -1551,6 +1622,7 @@
   product(uintx, GCLockerEdenExpansionPercent, 5,                           \
           "How much the GC can expand the eden by while the GC locker "     \
           "is active (as a percentage)")                                    \
+          range(0, 100)                                                     \
                                                                             \
   diagnostic(uintx, GCLockerRetryAllocationCount, 2,                        \
           "Number of times to retry allocations when "                      \
@@ -1576,14 +1648,17 @@
                                                                             \
   product(uintx, ParallelGCBufferWastePct, 10,                              \
           "Wasted fraction of parallel allocation buffer")                  \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, TargetPLABWastePct, 10,                                    \
           "Target wasted space in last buffer as percent of overall "       \
           "allocation")                                                     \
+          range(1, 100)                                                     \
                                                                             \
   product(uintx, PLABWeight, 75,                                            \
           "Percentage (0-100) used to weight the current sample when "      \
           "computing exponentially decaying average for ResizePLAB")        \
+          range(0, 100)                                                     \
                                                                             \
   product(bool, ResizePLAB, true,                                           \
           "Dynamically resize (survivor space) promotion LAB's")            \
@@ -1594,6 +1669,7 @@
   product(intx, ParGCArrayScanChunk, 50,                                    \
           "Scan a subset of object array and push remainder, if array is "  \
           "bigger than this")                                               \
+          range(1, max_intx)                                                \
                                                                             \
   product(bool, ParGCUseLocalOverflow, false,                               \
           "Instead of a global overflow list, use local overflow stacks")   \
@@ -1615,15 +1691,18 @@
   diagnostic(uintx, ParGCStridesPerThread, 2,                               \
           "The number of strides per worker thread that we divide up the "  \
           "card table scanning work into")                                  \
+          range(1, max_uintx)                                               \
                                                                             \
   diagnostic(intx, ParGCCardsPerStrideChunk, 256,                           \
           "The number of cards in each chunk of the parallel chunks used "  \
           "during card table scanning")                                     \
+          range(1, max_intx)                                                \
                                                                             \
   product(uintx, OldPLABWeight, 50,                                         \
           "Percentage (0-100) used to weight the current sample when "      \
           "computing exponentially decaying average for resizing "          \
           "OldPLABSize")                                                    \
+          range(0, 100)                                                     \
                                                                             \
   product(bool, ResizeOldPLAB, true,                                        \
           "Dynamically resize (old gen) promotion LAB's")                   \
@@ -1631,17 +1710,21 @@
   product(bool, PrintOldPLAB, false,                                        \
           "Print (old gen) promotion LAB's sizing decisions")               \
                                                                             \
+  product(size_t, CMSOldPLABMax, 1024,                                      \
+          "Maximum size of CMS gen promotion LAB caches per worker "        \
+          "per block size")                                                 \
+          range(1, max_uintx)                                               \
+                                                                            \
   product(size_t, CMSOldPLABMin, 16,                                        \
           "Minimum size of CMS gen promotion LAB caches per worker "        \
           "per block size")                                                 \
-                                                                            \
-  product(size_t, CMSOldPLABMax, 1024,                                      \
-          "Maximum size of CMS gen promotion LAB caches per worker "        \
-          "per block size")                                                 \
+          range(1, max_uintx)                                               \
+          constraint(CMSOldPLABMinConstraintFunc)                           \
                                                                             \
   product(uintx, CMSOldPLABNumRefills, 4,                                   \
           "Nominal number of refills of CMS gen promotion LAB cache "       \
           "per worker per block size")                                      \
+          range(1, max_uintx)                                               \
                                                                             \
   product(bool, CMSOldPLABResizeQuicker, false,                             \
           "React on-the-fly during a scavenge to a sudden "                 \
@@ -1650,6 +1733,7 @@
   product(uintx, CMSOldPLABToleranceFactor, 4,                              \
           "The tolerance of the phase-change detector for on-the-fly "      \
           "PLAB resizing during a scavenge")                                \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, CMSOldPLABReactivityFactor, 2,                             \
           "The gain in the feedback loop for on-the-fly PLAB resizing "     \
@@ -1661,19 +1745,23 @@
   product_pd(size_t, CMSYoungGenPerWorker,                                  \
           "The maximum size of young gen chosen by default per GC worker "  \
           "thread available")                                               \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, CMSIncrementalSafetyFactor, 10,                            \
           "Percentage (0-100) used to add conservatism when computing the " \
           "duty cycle")                                                     \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, CMSExpAvgFactor, 50,                                       \
           "Percentage (0-100) used to weight the current sample when "      \
           "computing exponential averages for CMS statistics")              \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, CMS_FLSWeight, 75,                                         \
           "Percentage (0-100) used to weight the current sample when "      \
           "computing exponentially decaying averages for CMS FLS "          \
           "statistics")                                                     \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, CMS_FLSPadding, 1,                                         \
           "The multiple of deviation from mean to use for buffering "       \
@@ -1682,6 +1770,7 @@
   product(uintx, FLSCoalescePolicy, 2,                                      \
           "CMS: aggressiveness level for coalescing, increasing "           \
           "from 0 to 4")                                                    \
+          range(0, 4)                                                       \
                                                                             \
   product(bool, FLSAlwaysCoalesceLarge, false,                              \
           "CMS: larger free blocks are always available for coalescing")    \
@@ -1715,6 +1804,7 @@
           "Percentage (0-100) used to weight the current sample when "      \
           "computing exponentially decaying average for inter-sweep "       \
           "duration")                                                       \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, CMS_SweepPadding, 1,                                       \
           "The multiple of deviation from mean to use for buffering "       \
@@ -1755,6 +1845,7 @@
                                                                             \
   product(size_t, MarkStackSizeMax, NOT_LP64(4*M) LP64_ONLY(512*M),         \
           "Maximum size of marking stack")                                  \
+          range(1, (max_jint - 1))                                          \
                                                                             \
   notproduct(bool, CMSMarkStackOverflowALot, false,                         \
           "Simulate frequent marking stack / work queue overflow")          \
@@ -1778,9 +1869,11 @@
                                                                             \
   product(size_t, CMSRescanMultiple, 32,                                    \
           "Size (in cards) of CMS parallel rescan task")                    \
+          range(1, max_uintx)                                               \
                                                                             \
   product(size_t, CMSConcMarkMultiple, 32,                                  \
           "Size (in cards) of CMS concurrent MT marking task")              \
+          range(1, max_uintx)                                               \
                                                                             \
   product(bool, CMSAbortSemantics, false,                                   \
           "Whether abort-on-overflow semantics is implemented")             \
@@ -1816,14 +1909,19 @@
                                                                             \
   product(uintx, CMSPrecleanIter, 3,                                        \
           "Maximum number of precleaning iteration passes")                 \
+          range(0, 9)                                                       \
+                                                                            \
+  product(uintx, CMSPrecleanDenominator, 3,                                 \
+          "CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence " \
+          "ratio")                                                          \
+          range(1, max_uintx)                                               \
+          constraint(CMSPrecleanDenominatorConstraintFunc)                  \
                                                                             \
   product(uintx, CMSPrecleanNumerator, 2,                                   \
           "CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence " \
           "ratio")                                                          \
-                                                                            \
-  product(uintx, CMSPrecleanDenominator, 3,                                 \
-          "CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence " \
-          "ratio")                                                          \
+          range(0, max_uintx-1)                                             \
+          constraint(CMSPrecleanNumeratorConstraintFunc)                    \
                                                                             \
   product(bool, CMSPrecleanRefLists1, true,                                 \
           "Preclean ref lists during (initial) preclean phase")             \
@@ -1839,12 +1937,14 @@
                                                                             \
   product(uintx, CMSPrecleanThreshold, 1000,                                \
           "Do not iterate again if number of dirty cards is less than this")\
+          range(100, max_uintx)                                             \
                                                                             \
   product(bool, CMSCleanOnEnter, true,                                      \
           "Clean-on-enter optimization for reducing number of dirty cards") \
                                                                             \
   product(uintx, CMSRemarkVerifyVariant, 1,                                 \
           "Choose variant (1,2) of verification following remark")          \
+          range(1, 2)                                                       \
                                                                             \
   product(size_t, CMSScheduleRemarkEdenSizeThreshold, 2*M,                  \
           "If Eden size is below this, do not try to schedule remark")      \
@@ -1852,14 +1952,17 @@
   product(uintx, CMSScheduleRemarkEdenPenetration, 50,                      \
           "The Eden occupancy percentage (0-100) at which "                 \
           "to try and schedule remark pause")                               \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, CMSScheduleRemarkSamplingRatio, 5,                         \
           "Start sampling eden top at least before young gen "              \
           "occupancy reaches 1/<ratio> of the size at which "               \
           "we plan to schedule remark")                                     \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, CMSSamplingGrain, 16*K,                                    \
           "The minimum distance between eden samples for CMS (see above)")  \
+          range(1, max_uintx)                                               \
                                                                             \
   product(bool, CMSScavengeBeforeRemark, false,                             \
           "Attempt scavenge before the CMS remark step")                    \
@@ -1883,6 +1986,7 @@
   product(size_t, CMSBitMapYieldQuantum, 10*M,                              \
           "Bitmap operations should process at most this many bits "        \
           "between yields")                                                 \
+          range(1, max_uintx)                                               \
                                                                             \
   product(bool, CMSDumpAtPromotionFailure, false,                           \
           "Dump useful information about the state of the CMS old "         \
@@ -1922,6 +2026,8 @@
   product(intx, RefDiscoveryPolicy, 0,                                      \
           "Select type of reference discovery policy: "                     \
           "reference-based(0) or referent-based(1)")                        \
+          range(ReferenceProcessor::DiscoveryPolicyMin,                     \
+                ReferenceProcessor::DiscoveryPolicyMax)                     \
                                                                             \
   product(bool, ParallelRefProcEnabled, false,                              \
           "Enable parallel reference processing whenever possible")         \
@@ -1932,14 +2038,17 @@
   product(uintx, CMSTriggerRatio, 80,                                       \
           "Percentage of MinHeapFreeRatio in CMS generation that is "       \
           "allocated before a CMS collection cycle commences")              \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, CMSBootstrapOccupancy, 50,                                 \
           "Percentage CMS generation occupancy at which to "                \
           "initiate CMS collection for bootstrapping collection stats")     \
+          range(0, 100)                                                     \
                                                                             \
   product(intx, CMSInitiatingOccupancyFraction, -1,                         \
           "Percentage CMS generation occupancy to start a CMS collection "  \
           "cycle. A negative value means that CMSTriggerRatio is used")     \
+          range(min_intx, 100)                                              \
                                                                             \
   product(uintx, InitiatingHeapOccupancyPercent, 45,                        \
           "Percentage of the (entire) heap occupancy to start a "           \
@@ -1947,10 +2056,12 @@
           "concurrent GC cycle based on the occupancy of the entire heap, " \
           "not just one of the generations (e.g., G1). A value of 0 "       \
           "denotes 'do constant GC cycles'.")                               \
+          range(0, 100)                                                     \
                                                                             \
   manageable(intx, CMSTriggerInterval, -1,                                  \
           "Commence a CMS collection cycle (at least) every so many "       \
           "milliseconds (0 permanently, -1 disabled)")                      \
+          range(-1, max_intx)                                               \
                                                                             \
   product(bool, UseCMSInitiatingOccupancyOnly, false,                       \
           "Only use occupancy as a criterion for starting a CMS collection")\
@@ -1958,6 +2069,7 @@
   product(uintx, CMSIsTooFullPercentage, 98,                                \
           "An absolute ceiling above which CMS will always consider the "   \
           "unloading of classes when class unloading is enabled")           \
+          range(0, 100)                                                     \
                                                                             \
   develop(bool, CMSTestInFreeList, false,                                   \
           "Check if the coalesced range is already in the "                 \
@@ -2067,17 +2179,21 @@
   product(uintx, MaxRAMFraction, 4,                                         \
           "Maximum fraction (1/n) of real memory used for maximum heap "    \
           "size")                                                           \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, DefaultMaxRAMFraction, 4,                                  \
           "Maximum fraction (1/n) of real memory used for maximum heap "    \
           "size; deprecated: to be renamed to MaxRAMFraction")              \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, MinRAMFraction, 2,                                         \
           "Minimum fraction (1/n) of real memory used for maximum heap "    \
           "size on systems with small physical memory size")                \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, InitialRAMFraction, 64,                                    \
           "Fraction (1/n) of real memory used for initial heap size")       \
+          range(1, max_uintx)                                               \
                                                                             \
   develop(uintx, MaxVirtMemFraction, 2,                                     \
           "Maximum fraction (1/n) of virtual memory used for ergonomically "\
@@ -2136,9 +2252,11 @@
                                                                             \
   product(uintx, AdaptiveSizePolicyWeight, 10,                              \
           "Weight given to exponential resizing, between 0 and 100")        \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, AdaptiveTimeWeight,       25,                              \
           "Weight given to time in adaptive policy, between 0 and 100")     \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, PausePadding, 1,                                           \
           "How much buffer to keep for pause time")                         \
@@ -2151,6 +2269,7 @@
                                                                             \
   product(uintx, ThresholdTolerance, 10,                                    \
           "Allowed collection cost difference between generations")         \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, AdaptiveSizePolicyCollectionCostMargin, 50,                \
           "If collection costs are within margin, reduce both by full "     \
@@ -2158,21 +2277,27 @@
                                                                             \
   product(uintx, YoungGenerationSizeIncrement, 20,                          \
           "Adaptive size percentage change in young generation")            \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, YoungGenerationSizeSupplement, 80,                         \
           "Supplement to YoungedGenerationSizeIncrement used at startup")   \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, YoungGenerationSizeSupplementDecay, 8,                     \
           "Decay factor to YoungedGenerationSizeSupplement")                \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, TenuredGenerationSizeIncrement, 20,                        \
           "Adaptive size percentage change in tenured generation")          \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, TenuredGenerationSizeSupplement, 80,                       \
           "Supplement to TenuredGenerationSizeIncrement used at startup")   \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, TenuredGenerationSizeSupplementDecay, 2,                   \
           "Decay factor to TenuredGenerationSizeIncrement")                 \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, MaxGCPauseMillis, max_uintx,                               \
           "Adaptive size policy maximum GC pause time goal in millisecond, "\
@@ -2190,6 +2315,7 @@
                                                                             \
   product(uintx, AdaptiveSizeDecrementScaleFactor, 4,                       \
           "Adaptive size scale down factor for shrinking")                  \
+          range(1, max_uintx)                                               \
                                                                             \
   product(bool, UseAdaptiveSizeDecayMajorGCCost, true,                      \
           "Adaptive size decays the major cost for long major intervals")   \
@@ -2213,10 +2339,12 @@
   product(uintx, GCTimeLimit, 98,                                           \
           "Limit of the proportion of time spent in GC before "             \
           "an OutOfMemoryError is thrown (used with GCHeapFreeLimit)")      \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, GCHeapFreeLimit, 2,                                        \
           "Minimum percentage of free space after a full GC before an "     \
           "OutOfMemoryError is thrown (used with GCTimeLimit)")             \
+          range(0, 100)                                                     \
                                                                             \
   develop(uintx, AdaptiveSizePolicyGCTimeLimitThreshold, 5,                 \
           "Number of consecutive collections before gc time limit fires")   \
@@ -2501,11 +2629,16 @@
                                                                             \
   /* compiler */                                                            \
                                                                             \
+  /* notice: the max range value here is max_jint, not max_intx  */         \
+  /* because of overflow issue                                   */         \
   product(intx, CICompilerCount, CI_COMPILER_COUNT,                         \
           "Number of compiler threads to run")                              \
+          range((intx)Arguments::get_min_number_of_compiler_threads(),      \
+                max_jint)                                                   \
                                                                             \
   product(intx, CompilationPolicyChoice, 0,                                 \
           "which compilation policy (0-3)")                                 \
+          range(0, 3)                                                       \
                                                                             \
   develop(bool, UseStackBanging, true,                                      \
           "use stack banging for stack overflow checks (required for "      \
@@ -2622,6 +2755,9 @@
           "Print all VM flags with default values and descriptions and "    \
           "exit")                                                           \
                                                                             \
+  product(bool, PrintFlagsRanges, false,                                    \
+          "Print VM flags and their ranges and exit VM")                    \
+                                                                            \
   diagnostic(bool, SerializeVMOutput, true,                                 \
           "Use a mutex to serialize output to tty and LogFile")             \
                                                                             \
@@ -2860,6 +2996,7 @@
   product(intx, ProfileMaturityPercentage, 20,                              \
           "number of method invocations/branches (expressed as % of "       \
           "CompileThreshold) before using the method's profile")            \
+          range(0, 100)                                                     \
                                                                             \
   diagnostic(bool, PrintMethodData, false,                                  \
           "Print the results of +ProfileInterpreter at end of run")         \
@@ -2920,6 +3057,7 @@
           "1 = prefetch instructions for each allocation, "                 \
           "2 = use TLAB watermark to gate allocation prefetch, "            \
           "3 = use BIS instruction on Sparc for allocation prefetch")       \
+          range(0, 3)                                                       \
                                                                             \
   product(intx,  AllocatePrefetchDistance, -1,                              \
           "Distance to prefetch ahead of allocation pointer")               \
@@ -2966,6 +3104,7 @@
   product(intx, NmethodSweepActivity, 10,                                   \
           "Removes cold nmethods from code cache if > 0. Higher values "    \
           "result in more aggressive sweeping")                             \
+          range(0, 2000)                                                    \
                                                                             \
   notproduct(bool, LogSweeper, false,                                       \
           "Keep a ring buffer of sweeper activity")                         \
@@ -3094,15 +3233,18 @@
                                                                             \
   product(intx, PerMethodRecompilationCutoff, 400,                          \
           "After recompiling N times, stay in the interpreter (-1=>'Inf')") \
+          range(-1, max_intx)                                               \
                                                                             \
   product(intx, PerBytecodeRecompilationCutoff, 200,                        \
           "Per-BCI limit on repeated recompilation (-1=>'Inf')")            \
+          range(-1, max_intx)                                               \
                                                                             \
   product(intx, PerMethodTrapLimit,  100,                                   \
           "Limit on traps (of one kind) in a method (includes inlines)")    \
                                                                             \
   experimental(intx, PerMethodSpecTrapLimit,  5000,                         \
-          "Limit on speculative traps (of one kind) in a method (includes inlines)") \
+          "Limit on speculative traps (of one kind) in a method "           \
+          "(includes inlines)")                                             \
                                                                             \
   product(intx, PerBytecodeTrapLimit,  4,                                   \
           "Limit on traps (of one kind) at a particular BCI")               \
@@ -3155,15 +3297,21 @@
                                                                             \
   product(size_t, MinTLABSize, 2*K,                                         \
           "Minimum allowed TLAB size (in bytes)")                           \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, TLABAllocationWeight, 35,                                  \
           "Allocation averaging weight")                                    \
-                                                                            \
+          range(0, 100)                                                     \
+                                                                            \
+  /* Limit the lower bound of this flag to 1 as it is used  */              \
+  /* in a division expression.                              */              \
   product(uintx, TLABWasteTargetPercent, 1,                                 \
           "Percentage of Eden that can be wasted")                          \
+          range(1, 100)                                                     \
                                                                             \
   product(uintx, TLABRefillWasteFraction,    64,                            \
           "Maximum TLAB waste at a refill (internal fragmentation)")        \
+          range(1, max_uintx)                                               \
                                                                             \
   product(uintx, TLABWasteIncrement,    4,                                  \
           "Increment allowed waste at slow allocation")                     \
@@ -3187,16 +3335,21 @@
   product(size_t, CompressedClassSpaceSize, 1*G,                            \
           "Maximum size of class area in Metaspace when compressed "        \
           "class pointers are used")                                        \
+          range(1*M, 3*G)                                                   \
                                                                             \
   manageable(uintx, MinHeapFreeRatio, 40,                                   \
           "The minimum percentage of heap free after GC to avoid expansion."\
           " For most GCs this applies to the old generation. In G1 and"     \
           " ParallelGC it applies to the whole heap.")                      \
+          range(0, 100)                                                     \
+          constraint(MinHeapFreeRatioConstraintFunc)                        \
                                                                             \
   manageable(uintx, MaxHeapFreeRatio, 70,                                   \
           "The maximum percentage of heap free after GC to avoid shrinking."\
           " For most GCs this applies to the old generation. In G1 and"     \
           " ParallelGC it applies to the whole heap.")                      \
+          range(0, 100)                                                     \
+          constraint(MaxHeapFreeRatioConstraintFunc)                        \
                                                                             \
   product(intx, SoftRefLRUPolicyMSPerMB, 1000,                              \
           "Number of milliseconds per MB of free space in the heap")        \
@@ -3207,13 +3360,17 @@
   product(size_t, MinMetaspaceExpansion, ScaleForWordSize(256*K),           \
           "The minimum expansion of Metaspace (in bytes)")                  \
                                                                             \
+  product(uintx, MaxMetaspaceFreeRatio,    70,                              \
+          "The maximum percentage of Metaspace free after GC to avoid "     \
+          "shrinking")                                                      \
+          range(0, 100)                                                     \
+          constraint(MaxMetaspaceFreeRatioConstraintFunc)                   \
+                                                                            \
   product(uintx, MinMetaspaceFreeRatio,    40,                              \
           "The minimum percentage of Metaspace free after GC to avoid "     \
           "expansion")                                                      \
-                                                                            \
-  product(uintx, MaxMetaspaceFreeRatio,    70,                              \
-          "The maximum percentage of Metaspace free after GC to avoid "     \
-          "shrinking")                                                      \
+          range(0, 99)                                                      \
+          constraint(MinMetaspaceFreeRatioConstraintFunc)                   \
                                                                             \
   product(size_t, MaxMetaspaceExpansion, ScaleForWordSize(4*M),             \
           "The maximum expansion of Metaspace without full GC (in bytes)")  \
@@ -3230,12 +3387,17 @@
                                                                             \
   product(uintx, MaxTenuringThreshold,    15,                               \
           "Maximum value for tenuring threshold")                           \
+          range(0, markOopDesc::max_age + 1)                                \
+          constraint(MaxTenuringThresholdConstraintFunc)                    \
                                                                             \
   product(uintx, InitialTenuringThreshold,    7,                            \
           "Initial value for tenuring threshold")                           \
+          range(0, markOopDesc::max_age + 1)                                \
+          constraint(InitialTenuringThresholdConstraintFunc)                \
                                                                             \
   product(uintx, TargetSurvivorRatio,    50,                                \
           "Desired percentage of survivor space used after scavenge")       \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, MarkSweepDeadRatio,     5,                                 \
           "Percentage (0-100) of the old gen allowed as dead wood. "        \
@@ -3246,10 +3408,12 @@
           "generation and treats this as the maximum value when the heap "  \
           "is either completely full or completely empty.  Par compact "    \
           "also has a smaller default value; see arguments.cpp.")           \
+          range(0, 100)                                                     \
                                                                             \
   product(uintx, MarkSweepAlwaysCompactCount,     4,                        \
           "How often should we fully compact the heap (ignoring the dead "  \
           "space parameters)")                                              \
+          range(1, max_uintx)                                               \
                                                                             \
   product(intx, PrintCMSStatistics, 0,                                      \
           "Statistics for CMS")                                             \
@@ -3289,13 +3453,17 @@
   /* stack parameters */                                                    \
   product_pd(intx, StackYellowPages,                                        \
           "Number of yellow zone (recoverable overflows) pages")            \
+          range(1, max_intx)                                                \
                                                                             \
   product_pd(intx, StackRedPages,                                           \
           "Number of red zone (unrecoverable overflows) pages")             \
-                                                                            \
+          range(1, max_intx)                                                \
+                                                                            \
+  /* greater stack shadow pages can't generate instruction to bang stack */ \
   product_pd(intx, StackShadowPages,                                        \
           "Number of shadow zone (for overflow checking) pages "            \
           "this should exceed the depth of the VM and native call stack")   \
+          range(1, 50)                                                      \
                                                                             \
   product_pd(intx, ThreadStackSize,                                         \
           "Thread Stack Size (in Kbytes)")                                  \
@@ -3314,11 +3482,12 @@
           "Linux/x86 only) to prevent heap-stack collision. Set to 0 to "   \
           "disable this feature")                                           \
                                                                             \
-  /* code cache parameters */                                               \
+  /* code cache parameters                                    */            \
   /* ppc64/tiered compilation has large code-entry alignment. */            \
   develop(uintx, CodeCacheSegmentSize, 64 PPC64_ONLY(+64) NOT_PPC64(TIERED_ONLY(+64)),\
           "Code cache segment size (in bytes) - smallest unit of "          \
           "allocation")                                                     \
+          range(1, 1024)                                                    \
                                                                             \
   develop_pd(intx, CodeEntryAlignment,                                      \
           "Code entry alignment for generated code (in bytes)")             \
@@ -3352,6 +3521,7 @@
                                                                             \
   develop_pd(uintx, CodeCacheMinBlockLength,                                \
           "Minimum number of segments in a code cache block")               \
+          range(1, 100)                                                     \
                                                                             \
   notproduct(bool, ExitOnFullCodeCache, false,                              \
           "Exit the VM if we fill the code cache")                          \
@@ -3363,6 +3533,7 @@
           "Start aggressive sweeping if X[%] of the code cache is free."    \
           "Segmented code cache: X[%] of the non-profiled heap."            \
           "Non-segmented code cache: X[%] of the total code cache")         \
+          range(0, 100)                                                     \
                                                                             \
   /* interpreter debugging */                                               \
   develop(intx, BinarySwitchThreshold, 5,                                   \
@@ -3423,6 +3594,7 @@
           "2 - treat class initializers for application classes as empty; " \
           "3 - allow all class initializers to run during bootstrap but "   \
           "    pretend they are empty after starting replay")               \
+          range(0, 3)                                                       \
                                                                             \
   develop(bool, ReplayIgnoreInitErrors, false,                              \
           "Ignore exceptions thrown during initialization for replay")      \
@@ -3467,6 +3639,7 @@
           "    used with care, as sometimes it can cause performance       "\
           "    degradation in the application and/or the entire system. On "\
           "    Linux this policy requires root privilege.")                 \
+          range(0, 1)                                                       \
                                                                             \
   product(bool, ThreadPriorityVerbose, false,                               \
           "Print priority changes")                                         \
@@ -3650,6 +3823,7 @@
   product(uintx, IncreaseFirstTierCompileThresholdAt, 50,                   \
           "Increase the compile threshold for C1 compilation if the code "  \
           "cache is filled by the specified percentage")                    \
+          range(0, 99)                                                      \
                                                                             \
   product(intx, TieredRateUpdateMinTime, 1,                                 \
           "Minimum rate sampling interval (in milliseconds)")               \
@@ -3670,6 +3844,7 @@
   product(intx, InterpreterProfilePercentage, 33,                           \
           "NON_TIERED number of method invocations/branches (expressed as " \
           "% of CompileThreshold) before profiling in the interpreter")     \
+          range(0, 100)                                                     \
                                                                             \
   develop(intx, MaxRecompilationSearchLength,    10,                        \
           "The maximum number of frames to inspect when searching for "     \
@@ -3749,6 +3924,7 @@
   product(intx, UnguardOnExecutionViolation, 0,                             \
           "Unguard page and retry on no-execute fault (Win32 only) "        \
           "0=off, 1=conservative, 2=aggressive")                            \
+          range(0, 2)                                                       \
                                                                             \
   /* Serviceability Support */                                              \
                                                                             \
@@ -3869,9 +4045,11 @@
                                                                             \
   product(uintx, StringTableSize, defaultStringTableSize,                   \
           "Number of buckets in the interned String table")                 \
+          range(minimumStringTableSize, 111*defaultStringTableSize)         \
                                                                             \
   experimental(uintx, SymbolTableSize, defaultSymbolTableSize,              \
           "Number of buckets in the JVM internal Symbol table")             \
+          range(minimumSymbolTableSize, 111*defaultSymbolTableSize)         \
                                                                             \
   product(bool, UseStringDeduplication, false,                              \
           "Use string deduplication")                                       \
@@ -3882,6 +4060,7 @@
   product(uintx, StringDeduplicationAgeThreshold, 3,                        \
           "A string must reach this age (or be promoted to an old region) " \
           "to be considered for deduplication")                             \
+          range(1, markOopDesc::max_age)                                    \
                                                                             \
   diagnostic(bool, StringDeduplicationResizeALot, false,                    \
           "Force table resize every time the table is scanned")             \
@@ -3903,6 +4082,7 @@
                                                                             \
   experimental(intx, SurvivorAlignmentInBytes, 0,                           \
            "Default survivor space alignment in bytes")                     \
+           constraint(SurvivorAlignmentInBytesConstraintFunc)               \
                                                                             \
   product(bool , AllowNonVirtualCalls, false,                               \
           "Obey the ACC_SUPER flag and allow invokenonvirtual calls")       \
@@ -3960,7 +4140,7 @@
 #define DECLARE_DEVELOPER_FLAG(type, name, value, doc)    extern "C" type name;
 #define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)        extern "C" type name;
 #define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)   extern "C" type name;
-#endif
+#endif // PRODUCT
 // Special LP64 flags, product only needed for now.
 #ifdef _LP64
 #define DECLARE_LP64_PRODUCT_FLAG(type, name, value, doc) extern "C" type name;
@@ -3983,18 +4163,47 @@
 #define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)    type name = value;
 #define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)        type name = pd_##name;
 #define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)   type name = value;
-#endif
+#endif // PRODUCT
 #ifdef _LP64
 #define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value;
 #else
 #define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) /* flag is constant */
 #endif // _LP64
 
-RUNTIME_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG, DECLARE_LP64_PRODUCT_FLAG)
+// Only materialize src code for range checking when required, ignore otherwise
+#define IGNORE_RANGE(a, b)
+// Only materialize src code for contraint checking when required, ignore otherwise
+#define IGNORE_CONSTRAINT(func)
 
-RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
+RUNTIME_FLAGS(DECLARE_DEVELOPER_FLAG, \
+              DECLARE_PD_DEVELOPER_FLAG, \
+              DECLARE_PRODUCT_FLAG, \
+              DECLARE_PD_PRODUCT_FLAG, \
+              DECLARE_DIAGNOSTIC_FLAG, \
+              DECLARE_EXPERIMENTAL_FLAG, \
+              DECLARE_NOTPRODUCT_FLAG, \
+              DECLARE_MANAGEABLE_FLAG, \
+              DECLARE_PRODUCT_RW_FLAG, \
+              DECLARE_LP64_PRODUCT_FLAG, \
+              IGNORE_RANGE, \
+              IGNORE_CONSTRAINT)
 
-ARCH_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
+RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, \
+                 DECLARE_PD_DEVELOPER_FLAG, \
+                 DECLARE_PRODUCT_FLAG, \
+                 DECLARE_PD_PRODUCT_FLAG, \
+                 DECLARE_DIAGNOSTIC_FLAG, \
+                 DECLARE_NOTPRODUCT_FLAG, \
+                 IGNORE_RANGE, \
+                 IGNORE_CONSTRAINT)
+
+ARCH_FLAGS(DECLARE_DEVELOPER_FLAG, \
+           DECLARE_PRODUCT_FLAG, \
+           DECLARE_DIAGNOSTIC_FLAG, \
+           DECLARE_EXPERIMENTAL_FLAG, \
+           DECLARE_NOTPRODUCT_FLAG, \
+           IGNORE_RANGE, \
+           IGNORE_CONSTRAINT)
 
 // Extensions
 
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -72,18 +72,67 @@
 #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
 
 typedef enum {
- RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER, RUNTIME_LP64_PRODUCT_FLAG_MEMBER)
- RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER)
+ RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, \
+               RUNTIME_PD_DEVELOP_FLAG_MEMBER, \
+               RUNTIME_PRODUCT_FLAG_MEMBER, \
+               RUNTIME_PD_PRODUCT_FLAG_MEMBER, \
+               RUNTIME_DIAGNOSTIC_FLAG_MEMBER, \
+               RUNTIME_EXPERIMENTAL_FLAG_MEMBER, \
+               RUNTIME_NOTPRODUCT_FLAG_MEMBER, \
+               RUNTIME_MANAGEABLE_FLAG_MEMBER, \
+               RUNTIME_PRODUCT_RW_FLAG_MEMBER, \
+               RUNTIME_LP64_PRODUCT_FLAG_MEMBER, \
+               IGNORE_RANGE, \
+               IGNORE_CONSTRAINT)
+ RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, \
+                  RUNTIME_PD_DEVELOP_FLAG_MEMBER, \
+                  RUNTIME_PRODUCT_FLAG_MEMBER, \
+                  RUNTIME_PD_PRODUCT_FLAG_MEMBER, \
+                  RUNTIME_DIAGNOSTIC_FLAG_MEMBER, \
+                  RUNTIME_NOTPRODUCT_FLAG_MEMBER, \
+                  IGNORE_RANGE, \
+                  IGNORE_CONSTRAINT)
 #if INCLUDE_ALL_GCS
- G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER)
+ G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, \
+          RUNTIME_PD_DEVELOP_FLAG_MEMBER, \
+          RUNTIME_PRODUCT_FLAG_MEMBER, \
+          RUNTIME_PD_PRODUCT_FLAG_MEMBER, \
+          RUNTIME_DIAGNOSTIC_FLAG_MEMBER, \
+          RUNTIME_EXPERIMENTAL_FLAG_MEMBER, \
+          RUNTIME_NOTPRODUCT_FLAG_MEMBER, \
+          RUNTIME_MANAGEABLE_FLAG_MEMBER, \
+          RUNTIME_PRODUCT_RW_FLAG_MEMBER, \
+          IGNORE_RANGE, \
+          IGNORE_CONSTRAINT)
 #endif // INCLUDE_ALL_GCS
 #ifdef COMPILER1
- C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, C1_PD_DEVELOP_FLAG_MEMBER, C1_PRODUCT_FLAG_MEMBER, C1_PD_PRODUCT_FLAG_MEMBER, C1_DIAGNOSTIC_FLAG_MEMBER, C1_NOTPRODUCT_FLAG_MEMBER)
+ C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, \
+          C1_PD_DEVELOP_FLAG_MEMBER, \
+          C1_PRODUCT_FLAG_MEMBER, \
+          C1_PD_PRODUCT_FLAG_MEMBER, \
+          C1_DIAGNOSTIC_FLAG_MEMBER, \
+          C1_NOTPRODUCT_FLAG_MEMBER, \
+          IGNORE_RANGE, \
+          IGNORE_CONSTRAINT)
 #endif
 #ifdef COMPILER2
- C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, C2_PD_DEVELOP_FLAG_MEMBER, C2_PRODUCT_FLAG_MEMBER, C2_PD_PRODUCT_FLAG_MEMBER, C2_DIAGNOSTIC_FLAG_MEMBER, C2_EXPERIMENTAL_FLAG_MEMBER, C2_NOTPRODUCT_FLAG_MEMBER)
+ C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, \
+          C2_PD_DEVELOP_FLAG_MEMBER, \
+          C2_PRODUCT_FLAG_MEMBER, \
+          C2_PD_PRODUCT_FLAG_MEMBER, \
+          C2_DIAGNOSTIC_FLAG_MEMBER, \
+          C2_EXPERIMENTAL_FLAG_MEMBER, \
+          C2_NOTPRODUCT_FLAG_MEMBER, \
+          IGNORE_RANGE, \
+          IGNORE_CONSTRAINT)
 #endif
- ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER, ARCH_PRODUCT_FLAG_MEMBER, ARCH_DIAGNOSTIC_FLAG_MEMBER, ARCH_EXPERIMENTAL_FLAG_MEMBER, ARCH_NOTPRODUCT_FLAG_MEMBER)
+ ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER, \
+            ARCH_PRODUCT_FLAG_MEMBER, \
+            ARCH_DIAGNOSTIC_FLAG_MEMBER, \
+            ARCH_EXPERIMENTAL_FLAG_MEMBER, \
+            ARCH_NOTPRODUCT_FLAG_MEMBER, \
+            IGNORE_RANGE, \
+            IGNORE_CONSTRAINT)
  COMMANDLINEFLAG_EXT
  NUM_CommandLineFlag
 } CommandLineFlag;
@@ -139,13 +188,17 @@
                RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
                RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE,
                RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE,
-               RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE)
+               RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE,
+               IGNORE_RANGE,
+               IGNORE_CONSTRAINT)
  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
                   RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
                   RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE,
                   RUNTIME_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
                   RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-                  RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
+                  RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
+                  IGNORE_RANGE,
+                  IGNORE_CONSTRAINT)
 #if INCLUDE_ALL_GCS
  G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
           RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -155,7 +208,9 @@
           RUNTIME_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
           RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
           RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE,
-          RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE)
+          RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE,
+          IGNORE_RANGE,
+          IGNORE_CONSTRAINT)
 #endif // INCLUDE_ALL_GCS
 #ifdef COMPILER1
  C1_FLAGS(C1_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -163,7 +218,9 @@
           C1_PRODUCT_FLAG_MEMBER_WITH_TYPE,
           C1_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
           C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
-          C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
+          C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
+          IGNORE_RANGE,
+          IGNORE_CONSTRAINT)
 #endif
 #ifdef COMPILER2
  C2_FLAGS(C2_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -172,13 +229,17 @@
           C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE,
           C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
           C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
-          C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
+          C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
+          IGNORE_RANGE,
+          IGNORE_CONSTRAINT)
 #endif
  ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE,
           ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE,
           ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
           ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
-          ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
+          ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
+          IGNORE_RANGE,
+          IGNORE_CONSTRAINT)
  COMMANDLINEFLAGWITHTYPE_EXT
  NUM_CommandLineFlagWithType
 } CommandLineFlagWithType;
@@ -196,16 +257,16 @@
 // of a circular dependency on the enum definition.
 class CommandLineFlagsEx : CommandLineFlags {
  public:
-  static void boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin);
-  static void intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin);
-  static void uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin);
-  static void intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin);
-  static void uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin);
-  static void uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin);
-  static void size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin);
-  static void doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin);
+  static Flag::Error boolAtPut(CommandLineFlagWithType flag, bool value, Flag::Flags origin);
+  static Flag::Error intAtPut(CommandLineFlagWithType flag, int value, Flag::Flags origin);
+  static Flag::Error uintAtPut(CommandLineFlagWithType flag, uint value, Flag::Flags origin);
+  static Flag::Error intxAtPut(CommandLineFlagWithType flag, intx value, Flag::Flags origin);
+  static Flag::Error uintxAtPut(CommandLineFlagWithType flag, uintx value, Flag::Flags origin);
+  static Flag::Error uint64_tAtPut(CommandLineFlagWithType flag, uint64_t value, Flag::Flags origin);
+  static Flag::Error size_tAtPut(CommandLineFlagWithType flag, size_t value, Flag::Flags origin);
+  static Flag::Error doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin);
   // Contract:  Flag will make private copy of the incoming value
-  static void ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin);
+  static Flag::Error ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin);
 
   static bool is_default(CommandLineFlag flag);
   static bool is_ergo(CommandLineFlag flag);
--- a/hotspot/src/share/vm/runtime/init.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/runtime/init.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -29,6 +29,7 @@
 #include "interpreter/bytecodes.hpp"
 #include "memory/universe.hpp"
 #include "prims/methodHandles.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/init.hpp"
@@ -141,8 +142,8 @@
 
   // All the flags that get adjusted by VM_Version_init and os::init_2
   // have been set so dump the flags now.
-  if (PrintFlagsFinal) {
-    CommandLineFlags::printFlags(tty, false);
+  if (PrintFlagsFinal || PrintFlagsRanges) {
+    CommandLineFlags::printFlags(tty, false, PrintFlagsRanges);
   }
 
   return JNI_OK;
--- a/hotspot/src/share/vm/runtime/os_ext.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/runtime/os_ext.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,7 +25,10 @@
 #ifndef SHARE_VM_RUNTIME_OS_EXT_HPP
 #define SHARE_VM_RUNTIME_OS_EXT_HPP
 
- public:
+#define EMIT_RANGES_FOR_GLOBALS_EXT // NOP
+#define EMIT_CONSTRAINTS_FOR_GLOBALS_EXT // NOP
+
+public:
   static void init_globals_ext() {} // Run from init_globals().
                                     // See os.hpp/cpp and init.cpp.
 
--- a/hotspot/src/share/vm/runtime/thread.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -54,6 +54,7 @@
 #include "runtime/deoptimization.hpp"
 #include "runtime/fprofiler.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/java.hpp"
@@ -3306,6 +3307,11 @@
   jint ergo_result = Arguments::apply_ergo();
   if (ergo_result != JNI_OK) return ergo_result;
 
+  // Final check of all arguments after ergonomics which may change values.
+  if (!CommandLineFlags::check_all_ranges_and_constraints()) {
+    return JNI_EINVAL;
+  }
+
   if (PauseAtStartup) {
     os::pause();
   }
--- a/hotspot/src/share/vm/services/attachListener.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/services/attachListener.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -243,8 +243,8 @@
   FormatBuffer<80> err_msg("%s", "");
 
   int ret = WriteableFlags::set_flag(op->arg(0), op->arg(1), Flag::ATTACH_ON_DEMAND, err_msg);
-  if (ret != WriteableFlags::SUCCESS) {
-    if (ret == WriteableFlags::NON_WRITABLE) {
+  if (ret != Flag::SUCCESS) {
+    if (ret == Flag::NON_WRITABLE) {
       // if the flag is not manageable try to change it through
       // the platform dependent implementation
       return AttachListener::pd_set_flag(op, out);
--- a/hotspot/src/share/vm/services/classLoadingService.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/services/classLoadingService.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -32,6 +32,7 @@
 #include "services/memoryService.hpp"
 #include "utilities/dtrace.hpp"
 #include "utilities/macros.hpp"
+#include "utilities/defaultStream.hpp"
 
 #ifdef DTRACE_ENABLED
 
@@ -176,13 +177,12 @@
   return class_size * oopSize;
 }
 
-
 bool ClassLoadingService::set_verbose(bool verbose) {
   MutexLocker m(Management_lock);
 
   // verbose will be set to the previous value
-  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, Flag::MANAGEMENT);
-  assert(succeed, "Setting TraceClassLoading flag fails");
+  Flag::Error error = CommandLineFlags::boolAtPut("TraceClassLoading", &verbose, Flag::MANAGEMENT);
+  assert(error==Flag::SUCCESS, err_msg("Setting TraceClassLoading flag failed with error %s", Flag::flag_error_str(error)));
   reset_trace_class_unloading();
 
   return verbose;
@@ -192,8 +192,8 @@
 void ClassLoadingService::reset_trace_class_unloading() {
   assert(Management_lock->owned_by_self(), "Must own the Management_lock");
   bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
-  bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, Flag::MANAGEMENT);
-  assert(succeed, "Setting TraceClassUnLoading flag fails");
+  Flag::Error error = CommandLineFlags::boolAtPut("TraceClassUnloading", &value, Flag::MANAGEMENT);
+  assert(error==Flag::SUCCESS, err_msg("Setting TraceClassUnLoading flag failed with error %s", Flag::flag_error_str(error)));
 }
 
 GrowableArray<KlassHandle>* LoadedClassesEnumerator::_loaded_classes = NULL;
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -27,6 +27,7 @@
 #include "classfile/compactHashtable.hpp"
 #include "gc/shared/vmGCOperations.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/os.hpp"
 #include "services/diagnosticArgument.hpp"
@@ -221,7 +222,7 @@
   FormatBuffer<80> err_msg("%s", "");
   int ret = WriteableFlags::set_flag(_flag.value(), val, Flag::MANAGEMENT, err_msg);
 
-  if (ret != WriteableFlags::SUCCESS) {
+  if (ret != Flag::SUCCESS) {
     output()->print_cr("%s", err_msg.buffer());
   }
 }
--- a/hotspot/src/share/vm/services/management.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/services/management.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -1703,8 +1703,8 @@
   FormatBuffer<80> err_msg("%s", "");
   int succeed = WriteableFlags::set_flag(name, new_value, Flag::MANAGEMENT, err_msg);
 
-  if (succeed != WriteableFlags::SUCCESS) {
-    if (succeed == WriteableFlags::MISSING_VALUE) {
+  if (succeed != Flag::SUCCESS) {
+    if (succeed == Flag::MISSING_VALUE) {
       // missing value causes NPE to be thrown
       THROW(vmSymbols::java_lang_NullPointerException());
     } else {
@@ -1713,7 +1713,7 @@
                 err_msg.buffer());
     }
   }
-  assert(succeed == WriteableFlags::SUCCESS, "Setting flag should succeed");
+  assert(succeed == Flag::SUCCESS, "Setting flag should succeed");
 JVM_END
 
 class ThreadTimesClosure: public ThreadClosure {
--- a/hotspot/src/share/vm/services/memoryService.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/services/memoryService.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -517,8 +517,8 @@
 bool MemoryService::set_verbose(bool verbose) {
   MutexLocker m(Management_lock);
   // verbose will be set to the previous value
-  bool succeed = CommandLineFlags::boolAtPut((char*)"PrintGC", &verbose, Flag::MANAGEMENT);
-  assert(succeed, "Setting PrintGC flag fails");
+  Flag::Error error = CommandLineFlags::boolAtPut("PrintGC", &verbose, Flag::MANAGEMENT);
+  assert(error==Flag::SUCCESS, err_msg("Setting PrintGC flag failed with error %s", Flag::flag_error_str(error)));
   ClassLoadingService::reset_trace_class_unloading();
 
   return verbose;
--- a/hotspot/src/share/vm/services/writeableFlags.cpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/services/writeableFlags.cpp	Fri Jun 19 13:03:58 2015 +0000
@@ -25,129 +25,200 @@
 #include "precompiled.hpp"
 #include "classfile/javaClasses.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/commandLineFlagRangeList.hpp"
 #include "runtime/java.hpp"
 #include "runtime/jniHandles.hpp"
 #include "services/writeableFlags.hpp"
 
+#define TEMP_BUF_SIZE 80
+
+static void buffer_concat(char* buffer, const char* src) {
+  strncat(buffer, src, TEMP_BUF_SIZE - 1 - strlen(buffer));
+}
+
+static void print_flag_error_message_bounds(const char* name, char* buffer) {
+  CommandLineFlagRange* range = CommandLineFlagRangeList::find(name);
+  if (range != NULL) {
+    buffer_concat(buffer, "must have value in range ");
+
+    stringStream stream;
+    range->print(&stream);
+    const char* range_string = stream.as_string();
+    size_t j = strlen(buffer);
+    for (size_t i=0; j<TEMP_BUF_SIZE-1; i++) {
+      if (range_string[i] == '\0') {
+        break;
+      } else if (range_string[i] != ' ') {
+        buffer[j] = range_string[i];
+        j++;
+      }
+    }
+    buffer[j] = '\0';
+  }
+}
+
+PRAGMA_FORMAT_NONLITERAL_IGNORED_EXTERNAL
+static void print_flag_error_message_if_needed(Flag::Error error, const char* name, FormatBuffer<80>& err_msg) {
+  if (error == Flag::SUCCESS) {
+    return;
+  }
+
+  char buffer[TEMP_BUF_SIZE] = {'\0'};
+  if ((error != Flag::MISSING_NAME) && (name != NULL)) {
+    buffer_concat(buffer, name);
+    buffer_concat(buffer, " error: ");
+  } else {
+    buffer_concat(buffer, "Error: ");
+  }
+  switch (error) {
+    case Flag::MISSING_NAME:
+      buffer_concat(buffer, "flag name is missing."); break;
+    case Flag::MISSING_VALUE:
+      buffer_concat(buffer, "parsing the textual form of the value."); break;
+    case Flag::NON_WRITABLE:
+      buffer_concat(buffer, "flag is not writeable."); break;
+    case Flag::OUT_OF_BOUNDS:
+      print_flag_error_message_bounds(name, buffer); break;
+    case Flag::VIOLATES_CONSTRAINT:
+      buffer_concat(buffer, "value violates its flag's constraint."); break;
+    case Flag::INVALID_FLAG:
+      buffer_concat(buffer, "there is no flag with the given name."); break;
+    case Flag::ERR_OTHER:
+      buffer_concat(buffer, "other, unspecified error related to setting the flag."); break;
+    case Flag::SUCCESS:
+      break;
+  }
+
+  PRAGMA_DIAG_PUSH
+  PRAGMA_FORMAT_NONLITERAL_IGNORED_INTERNAL
+  err_msg.print(buffer);
+  PRAGMA_DIAG_POP
+}
+
 // set a boolean global flag
-int WriteableFlags::set_bool_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_bool_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   int value = true;
 
   if (sscanf(arg, "%d", &value)) {
     return set_bool_flag(name, value != 0, origin, err_msg);
   }
   err_msg.print("flag value must be a boolean (1 or 0)");
-  return WRONG_FORMAT;
+  return Flag::WRONG_FORMAT;
 }
 
-int WriteableFlags::set_bool_flag(const char* name, bool value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
-  return CommandLineFlags::boolAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
+Flag::Error WriteableFlags::set_bool_flag(const char* name, bool value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+  Flag::Error err = CommandLineFlags::boolAtPut(name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
 }
 
 // set a int global flag
-int WriteableFlags::set_int_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_int_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   int value;
 
   if (sscanf(arg, "%d", &value)) {
     return set_int_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an integer");
-  return WRONG_FORMAT;
+  return Flag::WRONG_FORMAT;
 }
 
-int WriteableFlags::set_int_flag(const char* name, int value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
-  return CommandLineFlags::intAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
+Flag::Error WriteableFlags::set_int_flag(const char* name, int value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+  Flag::Error err = CommandLineFlags::intAtPut(name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
 }
 
 // set a uint global flag
-int WriteableFlags::set_uint_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_uint_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   uint value;
 
   if (sscanf(arg, "%u", &value)) {
     return set_uint_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an unsigned integer");
-  return WRONG_FORMAT;
+  return Flag::WRONG_FORMAT;
 }
 
-int WriteableFlags::set_uint_flag(const char* name, uint value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
-  return CommandLineFlags::uintAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
+Flag::Error WriteableFlags::set_uint_flag(const char* name, uint value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+  Flag::Error err = CommandLineFlags::uintAtPut(name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
 }
 
 // set a intx global flag
-int WriteableFlags::set_intx_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_intx_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   intx value;
 
   if (sscanf(arg, INTX_FORMAT, &value)) {
     return set_intx_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an integer");
-  return WRONG_FORMAT;
+  return Flag::WRONG_FORMAT;
 }
 
-int WriteableFlags::set_intx_flag(const char* name, intx value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
-  return CommandLineFlags::intxAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
+Flag::Error WriteableFlags::set_intx_flag(const char* name, intx value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+  Flag::Error err = CommandLineFlags::intxAtPut(name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
 }
 
 // set a uintx global flag
-int WriteableFlags::set_uintx_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_uintx_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   uintx value;
 
   if (sscanf(arg, UINTX_FORMAT, &value)) {
     return set_uintx_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an unsigned integer");
-  return WRONG_FORMAT;
+  return Flag::WRONG_FORMAT;
 }
 
-int WriteableFlags::set_uintx_flag(const char* name, uintx value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
-  if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) {
-      if (!Arguments::verify_MaxHeapFreeRatio(err_msg, value)) {
-        return OUT_OF_BOUNDS;
-      }
-    } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) {
-      if (!Arguments::verify_MinHeapFreeRatio(err_msg, value)) {
-        return OUT_OF_BOUNDS;
-      }
-    }
-    return CommandLineFlags::uintxAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
+Flag::Error WriteableFlags::set_uintx_flag(const char* name, uintx value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+  Flag::Error err = CommandLineFlags::uintxAtPut(name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
 }
 
 // set a uint64_t global flag
-int WriteableFlags::set_uint64_t_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_uint64_t_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   uint64_t value;
 
   if (sscanf(arg, UINT64_FORMAT, &value)) {
     return set_uint64_t_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an unsigned 64-bit integer");
-  return WRONG_FORMAT;
+  return Flag::WRONG_FORMAT;
 }
 
-int WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
-  return CommandLineFlags::uint64_tAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
+Flag::Error WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+  Flag::Error err = CommandLineFlags::uint64_tAtPut(name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
 }
 
 // set a size_t global flag
-int WriteableFlags::set_size_t_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_size_t_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   size_t value;
 
   if (sscanf(arg, SIZE_FORMAT, &value)) {
     return set_size_t_flag(name, value, origin, err_msg);
   }
   err_msg.print("flag value must be an unsigned integer");
-  return WRONG_FORMAT;
+  return Flag::WRONG_FORMAT;
 }
 
-int WriteableFlags::set_size_t_flag(const char* name, size_t value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
-  return CommandLineFlags::size_tAtPut((char*)name, &value, origin) ? SUCCESS : ERR_OTHER;
+Flag::Error WriteableFlags::set_size_t_flag(const char* name, size_t value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+  Flag::Error err = CommandLineFlags::size_tAtPut(name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
 }
 
 // set a string global flag using value from AttachOperation
-int WriteableFlags::set_ccstr_flag(const char* name, const char* arg, Flag::Flags origin, FormatBuffer<80>& err_msg) {
-  bool res = CommandLineFlags::ccstrAtPut((char*)name, &arg, origin);
-
-  return res? SUCCESS : ERR_OTHER;
+Flag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+  Flag::Error err = CommandLineFlags::ccstrAtPut((char*)name, &value, origin);
+  print_flag_error_message_if_needed(err, name, err_msg);
+  return err;
 }
 
 /* sets a writeable flag to the provided value
@@ -155,7 +226,7 @@
  * - return status is one of the WriteableFlags::err enum values
  * - an eventual error message will be generated to the provided err_msg buffer
  */
-int WriteableFlags::set_flag(const char* flag_name, const char* flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_flag(const char* flag_name, const char* flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   return set_flag(flag_name, &flag_value, set_flag_from_char, origin, err_msg);
 }
 
@@ -164,19 +235,19 @@
  * - return status is one of the WriteableFlags::err enum values
  * - an eventual error message will be generated to the provided err_msg buffer
  */
-int WriteableFlags::set_flag(const char* flag_name, jvalue flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_flag(const char* flag_name, jvalue flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   return set_flag(flag_name, &flag_value, set_flag_from_jvalue, origin, err_msg);
 }
 
 // a writeable flag setter accepting either 'jvalue' or 'char *' values
-int WriteableFlags::set_flag(const char* name, const void* value, int(*setter)(Flag*,const void*,Flag::Flags,FormatBuffer<80>&), Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_flag(const char* name, const void* value, Flag::Error(*setter)(Flag*,const void*,Flag::Flags,FormatBuffer<80>&), Flag::Flags origin, FormatBuffer<80>& err_msg) {
   if (name == NULL) {
     err_msg.print("flag name is missing");
-    return MISSING_NAME;
+    return Flag::MISSING_NAME;
   }
   if (value == NULL) {
     err_msg.print("flag value is missing");
-    return MISSING_VALUE;
+    return Flag::MISSING_VALUE;
   }
 
   Flag* f = Flag::find_flag((char*)name, strlen(name));
@@ -186,20 +257,20 @@
       return setter(f, value, origin, err_msg);
     } else {
       err_msg.print("only 'writeable' flags can be set");
-      return NON_WRITABLE;
+      return Flag::NON_WRITABLE;
     }
   }
 
   err_msg.print("flag %s does not exist", name);
-  return INVALID_FLAG;
+  return Flag::INVALID_FLAG;
 }
 
 // a writeable flag setter accepting 'char *' values
-int WriteableFlags::set_flag_from_char(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_flag_from_char(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   char* flag_value = *(char**)value;
   if (flag_value == NULL) {
     err_msg.print("flag value is missing");
-    return MISSING_VALUE;
+    return Flag::MISSING_VALUE;
   }
   if (f->is_bool()) {
     return set_bool_flag(f->_name, flag_value, origin, err_msg);
@@ -220,11 +291,11 @@
   } else {
     ShouldNotReachHere();
   }
-  return ERR_OTHER;
+  return Flag::ERR_OTHER;
 }
 
 // a writeable flag setter accepting 'jvalue' values
-int WriteableFlags::set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
+Flag::Error WriteableFlags::set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg) {
   jvalue new_value = *(jvalue*)value;
   if (f->is_bool()) {
     bool bvalue = (new_value.z == JNI_TRUE ? true : false);
@@ -251,17 +322,16 @@
     oop str = JNIHandles::resolve_external_guard(new_value.l);
     if (str == NULL) {
       err_msg.print("flag value is missing");
-      return MISSING_VALUE;
+      return Flag::MISSING_VALUE;
     }
     ccstr svalue = java_lang_String::as_utf8_string(str);
-    int ret = WriteableFlags::set_ccstr_flag(f->_name, svalue, origin, err_msg);
-    if (ret != SUCCESS) {
+    Flag::Error ret = WriteableFlags::set_ccstr_flag(f->_name, svalue, origin, err_msg);
+    if (ret != Flag::SUCCESS) {
       FREE_C_HEAP_ARRAY(char, svalue);
     }
     return ret;
   } else {
     ShouldNotReachHere();
   }
-  return ERR_OTHER;
+  return Flag::ERR_OTHER;
 }
-
--- a/hotspot/src/share/vm/services/writeableFlags.hpp	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/src/share/vm/services/writeableFlags.hpp	Fri Jun 19 13:03:58 2015 +0000
@@ -26,64 +26,44 @@
 #define SHARE_VM_SERVICES_WRITEABLEFLAG_HPP
 
 class WriteableFlags : AllStatic {
-public:
-  enum error {
-    // no error
-    SUCCESS,
-    // flag name is missing
-    MISSING_NAME,
-    // flag value is missing
-    MISSING_VALUE,
-    // error parsing the textual form of the value
-    WRONG_FORMAT,
-    // flag is not writeable
-    NON_WRITABLE,
-    // flag value is outside of its bounds
-    OUT_OF_BOUNDS,
-    // there is no flag with the given name
-    INVALID_FLAG,
-    // other, unspecified error related to setting the flag
-    ERR_OTHER
-  } err;
-
 private:
   // a writeable flag setter accepting either 'jvalue' or 'char *' values
-  static int set_flag(const char* name, const void* value, int(*setter)(Flag*, const void*, Flag::Flags, FormatBuffer<80>&), Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_flag(const char* name, const void* value, Flag::Error(*setter)(Flag*, const void*, Flag::Flags, FormatBuffer<80>&), Flag::Flags origin, FormatBuffer<80>& err_msg);
   // a writeable flag setter accepting 'char *' values
-  static int set_flag_from_char(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_flag_from_char(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // a writeable flag setter accepting 'jvalue' values
-  static int set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_flag_from_jvalue(Flag* f, const void* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
 
   // set a boolean global flag
-  static int set_bool_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_bool_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a int global flag
-  static int set_int_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_int_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a uint global flag
-  static int set_uint_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_uint_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a intx global flag
-  static int set_intx_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_intx_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a uintx global flag
-  static int set_uintx_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_uintx_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a uint64_t global flag
-  static int set_uint64_t_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_uint64_t_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a size_t global flag using value from AttachOperation
-  static int set_size_t_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_size_t_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a boolean global flag
-  static int set_bool_flag(const char* name, bool value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_bool_flag(const char* name, bool value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a int global flag
-  static int set_int_flag(const char* name, int value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_int_flag(const char* name, int value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a uint global flag
-  static int set_uint_flag(const char* name, uint value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_uint_flag(const char* name, uint value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a intx global flag
-  static int set_intx_flag(const char* name, intx value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_intx_flag(const char* name, intx value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a uintx global flag
-  static int set_uintx_flag(const char* name, uintx value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_uintx_flag(const char* name, uintx value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a uint64_t global flag
-  static int set_uint64_t_flag(const char* name, uint64_t value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_uint64_t_flag(const char* name, uint64_t value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a size_t global flag using value from AttachOperation
-  static int set_size_t_flag(const char* name, size_t value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_size_t_flag(const char* name, size_t value, Flag::Flags origin, FormatBuffer<80>& err_msg);
   // set a string global flag
-  static int set_ccstr_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_ccstr_flag(const char* name, const char* value, Flag::Flags origin, FormatBuffer<80>& err_msg);
 
 public:
   /* sets a writeable flag to the provided value
@@ -91,15 +71,14 @@
    * - return status is one of the WriteableFlags::err enum values
    * - an eventual error message will be generated to the provided err_msg buffer
    */
-  static int set_flag(const char* flag_name, const char* flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_flag(const char* flag_name, const char* flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg);
 
   /* sets a writeable flag to the provided value
    *
    * - return status is one of the WriteableFlags::err enum values
    * - an eventual error message will be generated to the provided err_msg buffer
    */
-  static int set_flag(const char* flag_name, jvalue flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg);
+  static Flag::Error set_flag(const char* flag_name, jvalue flag_value, Flag::Flags origin, FormatBuffer<80>& err_msg);
 };
 
 #endif /* SHARE_VM_SERVICES_WRITEABLEFLAG_HPP */
-
--- a/hotspot/test/TEST.groups	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/TEST.groups	Fri Jun 19 13:03:58 2015 +0000
@@ -420,6 +420,7 @@
  -runtime/SharedArchiveFile/DefaultUseWithClient.java \
  -runtime/Thread/CancellableThreadTest.java \
  -runtime/7158988/FieldMonitor.java \
+ -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \
   sanity/ \
   testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java
 
--- a/hotspot/test/compiler/c2/7200264/Test7200264.sh	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/compiler/c2/7200264/Test7200264.sh	Fri Jun 19 13:03:58 2015 +0000
@@ -1,6 +1,6 @@
 #!/bin/sh
 # 
-# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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
@@ -55,7 +55,8 @@
 cp ${TESTSRC}${FS}TestIntVect.java .
 ${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} -d . TestIntVect.java
 
-${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+PrintCompilation -XX:+TraceNewVectors TestIntVect > test.out 2>&1
+# CICompilerCount must be at least 2 with -TieredCompilation
+${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=2 -XX:+PrintCompilation -XX:+TraceNewVectors TestIntVect > test.out 2>&1
 
 COUNT=`grep AddVI test.out | wc -l | awk '{print $1}'`
 if [ $COUNT -lt 4 ]
--- a/hotspot/test/compiler/startup/NumCompilerThreadsCheck.java	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/compiler/startup/NumCompilerThreadsCheck.java	Fri Jun 19 13:03:58 2015 +0000
@@ -37,7 +37,7 @@
     ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:CICompilerCount=-1");
     OutputAnalyzer out = new OutputAnalyzer(pb.start());
 
-    String expectedOutput = "CICompilerCount of -1 is invalid";
+    String expectedOutput = "outside the allowed range";
     out.shouldContain(expectedOutput);
 
     if (Platform.isZero()) {
--- a/hotspot/test/gc/arguments/TestHeapFreeRatio.java	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/gc/arguments/TestHeapFreeRatio.java	Fri Jun 19 13:03:58 2015 +0000
@@ -40,6 +40,7 @@
     VALID,
     MIN_INVALID,
     MAX_INVALID,
+    OUT_OF_RANGE,
     COMBINATION_INVALID
   }
 
@@ -65,8 +66,13 @@
       output.shouldContain("Error");
       output.shouldHaveExitValue(1);
       break;
+    case OUT_OF_RANGE:
+      output.shouldContain("outside the allowed range");
+      output.shouldContain("Error");
+      output.shouldHaveExitValue(1);
+      break;
     case COMBINATION_INVALID:
-      output.shouldContain("must be less than or equal to MaxHeapFreeRatio");
+      output.shouldContain("must be greater than or equal to MinHeapFreeRatio");
       output.shouldContain("Error");
       output.shouldHaveExitValue(1);
       break;
@@ -82,23 +88,24 @@
     testMinMaxFreeRatio(  ".1",  ".5", Validation.VALID);
     testMinMaxFreeRatio( "0.5", "0.5", Validation.VALID);
 
-    testMinMaxFreeRatio("-0.1", "0.5", Validation.MIN_INVALID);
-    testMinMaxFreeRatio( "1.1", "0.5", Validation.MIN_INVALID);
     testMinMaxFreeRatio("=0.1", "0.5", Validation.MIN_INVALID);
     testMinMaxFreeRatio("0.1f", "0.5", Validation.MIN_INVALID);
     testMinMaxFreeRatio(
                      "INVALID", "0.5", Validation.MIN_INVALID);
-    testMinMaxFreeRatio(
-                  "2147483647", "0.5", Validation.MIN_INVALID);
 
-    testMinMaxFreeRatio( "0.1", "-0.5", Validation.MAX_INVALID);
-    testMinMaxFreeRatio( "0.1",  "1.5", Validation.MAX_INVALID);
     testMinMaxFreeRatio( "0.1", "0.5f", Validation.MAX_INVALID);
     testMinMaxFreeRatio( "0.1", "=0.5", Validation.MAX_INVALID);
     testMinMaxFreeRatio(
                      "0.1",  "INVALID", Validation.MAX_INVALID);
+
+    testMinMaxFreeRatio("-0.1", "0.5", Validation.OUT_OF_RANGE);
+    testMinMaxFreeRatio( "1.1", "0.5", Validation.OUT_OF_RANGE);
     testMinMaxFreeRatio(
-                   "0.1", "2147483647", Validation.MAX_INVALID);
+                  "2147483647", "0.5", Validation.OUT_OF_RANGE);
+    testMinMaxFreeRatio( "0.1", "-0.5", Validation.OUT_OF_RANGE);
+    testMinMaxFreeRatio( "0.1",  "1.5", Validation.OUT_OF_RANGE);
+    testMinMaxFreeRatio(
+                   "0.1", "2147483647", Validation.OUT_OF_RANGE);
 
     testMinMaxFreeRatio( "0.5",  "0.1", Validation.COMBINATION_INVALID);
     testMinMaxFreeRatio(  ".5",  ".10", Validation.COMBINATION_INVALID);
--- a/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java	Fri Jun 19 13:03:58 2015 +0000
@@ -45,9 +45,9 @@
         String optionIsExperimental
                 = CommandLineOptionTest.getExperimentalOptionErrorMessage(
                 optionName);
-        String valueIsTooSmall= ".*SurvivorAlignmentInBytes=.*must be greater"
-                + " than ObjectAlignmentInBytes.*";
-        String mustBePowerOf2 = ".*SurvivorAlignmentInBytes=.*must be "
+        String valueIsTooSmall= ".*SurvivorAlignmentInBytes.*must be greater"
+                + " than or equal to ObjectAlignmentInBytes.*";
+        String mustBePowerOf2 = ".*SurvivorAlignmentInBytes.*must be "
                 + "power of 2.*";
 
         // Verify that without -XX:+UnlockExperimentalVMOptions usage of
--- a/hotspot/test/gc/g1/TestStringDeduplicationTools.java	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/gc/g1/TestStringDeduplicationTools.java	Fri Jun 19 13:03:58 2015 +0000
@@ -412,16 +412,14 @@
         output = DeduplicationTest.run(SmallNumberOfStrings,
                                        TooLowAgeThreshold,
                                        YoungGC);
-        output.shouldContain("StringDeduplicationAgeThreshold of " + TooLowAgeThreshold +
-                             " is invalid; must be between " + MinAgeThreshold + " and " + MaxAgeThreshold);
+        output.shouldContain("outside the allowed range");
         output.shouldHaveExitValue(1);
 
         // Test with too high age threshold
         output = DeduplicationTest.run(SmallNumberOfStrings,
                                        TooHighAgeThreshold,
                                        YoungGC);
-        output.shouldContain("StringDeduplicationAgeThreshold of " + TooHighAgeThreshold +
-                             " is invalid; must be between " + MinAgeThreshold + " and " + MaxAgeThreshold);
+        output.shouldContain("outside the allowed range");
         output.shouldHaveExitValue(1);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Verify jcmd error message for out-of-range value and for
+ *          value which is not allowed by constraint. Also check that
+ *          jcmd does not print an error message to the target process output.
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management
+ *          jdk.management
+ * @run main TestJcmdOutput
+ */
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.DynamicVMOption;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.dcmd.PidJcmdExecutor;
+
+public class TestJcmdOutput {
+
+    /* Message printed by jcmd for value which is out-of-range */
+    static final String JCMD_OUT_OF_RANGE_MESSAGE = "error: must have value in range";
+    /* Message printed by jcmd for value which is not allowed by constraint */
+    static final String JCMD_CONSTRAINT_MESSAGE = "value violates its flag's constraint";
+
+    public static void main(String[] args) throws Exception {
+        OutputAnalyzer output;
+
+        System.out.println("Verify jcmd error message and that jcmd does not write errors to the target process output");
+        output = new OutputAnalyzer((ProcessTools.createJavaProcessBuilder(
+                "-Dtest.jdk=" + System.getProperty("test.jdk"),
+                "-XX:MinHeapFreeRatio=20", "-XX:MaxHeapFreeRatio=80", runJcmd.class.getName())).start());
+
+        output.shouldHaveExitValue(0);
+        /* Verify that jcmd not print error message to the target process output */
+        output.shouldNotContain(JCMD_OUT_OF_RANGE_MESSAGE);
+        output.shouldNotContain(JCMD_CONSTRAINT_MESSAGE);
+    }
+
+    public static class runJcmd {
+
+        public static void main(String[] args) throws Exception {
+            int minHeapFreeRatio = new Integer((new DynamicVMOption("MinHeapFreeRatio")).getValue());
+            int maxHeapFreeRatio = new Integer((new DynamicVMOption("MaxHeapFreeRatio")).getValue());
+            PidJcmdExecutor executor = new PidJcmdExecutor();
+
+            Asserts.assertGT(minHeapFreeRatio, 0, "MinHeapFreeRatio must be greater than 0");
+            Asserts.assertLT(maxHeapFreeRatio, 100, "MaxHeapFreeRatio must be less than 100");
+
+            /* Check out-of-range values */
+            executor.execute("VM.set_flag MinHeapFreeRatio -1", true).shouldContain(JCMD_OUT_OF_RANGE_MESSAGE);
+            executor.execute("VM.set_flag MaxHeapFreeRatio 101", true).shouldContain(JCMD_OUT_OF_RANGE_MESSAGE);
+
+            /* Check values which not allowed by constraint */
+            executor.execute(
+                    String.format("VM.set_flag MinHeapFreeRatio %d", maxHeapFreeRatio + 1), true)
+                    .shouldContain(JCMD_CONSTRAINT_MESSAGE);
+            executor.execute(
+                    String.format("VM.set_flag MaxHeapFreeRatio %d", minHeapFreeRatio - 1), true)
+                    .shouldContain(JCMD_CONSTRAINT_MESSAGE);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Test VM Options with ranges
+ * @library /testlibrary /runtime/CommandLine/OptionsValidation/common
+ * @modules java.base/sun.misc
+ *          java.management
+ *          jdk.attach
+ *          jdk.management/sun.tools.attach
+ * @run main/othervm/timeout=600 TestOptionsWithRanges
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import jdk.test.lib.Asserts;
+import optionsvalidation.JVMOption;
+import optionsvalidation.JVMOptionsUtils;
+
+public class TestOptionsWithRanges {
+
+    public static void main(String[] args) throws Exception {
+        int failedTests;
+        Map<String, JVMOption> allOptionsAsMap = JVMOptionsUtils.getOptionsWithRangeAsMap();
+        List<JVMOption> allOptions;
+
+        /*
+         * Remove CICompilerCount from testing because currently it can hang system
+         */
+        allOptionsAsMap.remove("CICompilerCount");
+
+        allOptions = new ArrayList<>(allOptionsAsMap.values());
+
+        Asserts.assertGT(allOptions.size(), 0, "Options with ranges not found!");
+
+        System.out.println("Parsed " + allOptions.size() + " options with ranges. Start test!");
+
+        failedTests = JVMOptionsUtils.runCommandLineTests(allOptions);
+
+        Asserts.assertEQ(failedTests, 0,
+                String.format("%d tests failed! %s", failedTests, JVMOptionsUtils.getMessageWithFailures()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @summary Test writeable VM Options with ranges.
+ * @library /testlibrary /runtime/CommandLine/OptionsValidation/common
+ * @modules java.base/sun.misc
+ *          java.management
+ *          jdk.attach
+ *          jdk.management/sun.tools.attach
+ * @run main/othervm -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 TestOptionsWithRangesDynamic
+ */
+
+import java.util.List;
+import jdk.test.lib.Asserts;
+import optionsvalidation.JVMOption;
+import optionsvalidation.JVMOptionsUtils;
+
+public class TestOptionsWithRangesDynamic {
+
+    public static void main(String[] args) throws Exception {
+        int failedTests;
+        List<JVMOption> allWriteableOptions;
+
+        /* Get only writeable options */
+        allWriteableOptions = JVMOptionsUtils.getOptionsWithRange(origin -> (origin.contains("manageable") || origin.contains("rw")));
+
+        Asserts.assertGT(allWriteableOptions.size(), 0, "Options with ranges not found!");
+
+        System.out.println("Test " + allWriteableOptions.size() + " writeable options with ranges. Start test!");
+
+        failedTests = JVMOptionsUtils.runDynamicTests(allWriteableOptions);
+
+        failedTests += JVMOptionsUtils.runJcmdTests(allWriteableOptions);
+
+        failedTests += JVMOptionsUtils.runAttachTests(allWriteableOptions);
+
+        Asserts.assertEQ(failedTests, 0,
+                String.format("%d tests failed! %s", failedTests, JVMOptionsUtils.getMessageWithFailures()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/DoubleJVMOption.java	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,202 @@
+/*
+ * 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.
+ */
+
+package optionsvalidation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DoubleJVMOption extends JVMOption {
+
+    /**
+     * Additional double values to test
+     */
+    private static final double ADDITIONAL_TEST_DOUBLE_NEGATIVE = -1.5;
+    private static final double ADDITIONAL_TEST_DOUBLE_ZERO = 0.0;
+    private static final double ADDITIONAL_TEST_DOUBLE_POSITIVE = 1.75;
+
+    /**
+     * Mininum option value
+     */
+    private double min;
+    /**
+     * Maximum option value
+     */
+    private double max;
+
+    /**
+     * Initialize double option with passed name
+     *
+     * @param name name of the option
+     */
+    DoubleJVMOption(String name) {
+        this.name = name;
+        min = Double.MIN_VALUE;
+        max = Double.MAX_VALUE;
+    }
+
+    /**
+     * Initialize double option with passed name, min and max values
+     *
+     * @param name name of the option
+     * @param min minimum value of the option
+     * @param max maximum value of the option
+     */
+    public DoubleJVMOption(String name, double min, double max) {
+        this(name);
+        this.min = min;
+        this.max = max;
+    }
+
+    /**
+     * Set new minimum option value
+     *
+     * @param min new minimum value
+     */
+    @Override
+    void setMin(String min) {
+        this.min = new Double(min);
+    }
+
+    /**
+     * Get string with minimum value of the option
+     *
+     * @return string with minimum value of the option
+     */
+    @Override
+    String getMin() {
+        return formatValue(min);
+    }
+
+    /**
+     * Set new maximum option value
+     *
+     * @param max new maximum value
+     */
+    @Override
+    void setMax(String max) {
+        this.max = new Double(max);
+    }
+
+    /**
+     * Get string with maximum value of the option
+     *
+     * @return string with maximum value of the option
+     */
+    @Override
+    String getMax() {
+        return formatValue(max);
+    }
+
+    private String formatValue(double value) {
+        return String.format("%f", value);
+    }
+
+    /**
+     * Return list of strings with valid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain valid values for option
+     */
+    @Override
+    protected List<String> getValidValues() {
+        List<String> validValues = new ArrayList<>();
+
+        validValues.add(formatValue(min));
+        validValues.add(formatValue(max));
+
+        if ((Double.compare(min, ADDITIONAL_TEST_DOUBLE_NEGATIVE) < 0)
+                && (Double.compare(max, ADDITIONAL_TEST_DOUBLE_NEGATIVE) > 0)) {
+            validValues.add(formatValue(ADDITIONAL_TEST_DOUBLE_NEGATIVE));
+        }
+
+        if ((Double.compare(min, ADDITIONAL_TEST_DOUBLE_ZERO) < 0)
+                && (Double.compare(max, ADDITIONAL_TEST_DOUBLE_ZERO) > 0)) {
+            validValues.add(formatValue(ADDITIONAL_TEST_DOUBLE_ZERO));
+        }
+
+        if ((Double.compare(min, ADDITIONAL_TEST_DOUBLE_POSITIVE) < 0)
+                && (Double.compare(max, ADDITIONAL_TEST_DOUBLE_POSITIVE) > 0)) {
+            validValues.add(formatValue(ADDITIONAL_TEST_DOUBLE_POSITIVE));
+        }
+
+        return validValues;
+    }
+
+    /**
+     * Return list of strings with invalid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain invalid values for option
+     */
+    @Override
+    protected List<String> getInvalidValues() {
+        List<String> invalidValues = new ArrayList<>();
+
+        if (withRange) {
+            /* Return invalid values only for options which have defined range in VM */
+            if (Double.compare(min, Double.MIN_VALUE) != 0) {
+                if ((Double.compare(min, 0.0) > 0)
+                        && (Double.isNaN(min * 0.999) == false)) {
+                    invalidValues.add(formatValue(min * 0.999));
+                } else if ((Double.compare(min, 0.0) < 0)
+                        && (Double.isNaN(min * 1.001) == false)) {
+                    invalidValues.add(formatValue(min * 1.001));
+                }
+            }
+
+            if (Double.compare(max, Double.MAX_VALUE) != 0) {
+                if ((Double.compare(max, 0.0) > 0)
+                        && (Double.isNaN(max * 1.001) == false)) {
+                    invalidValues.add(formatValue(max * 1.001));
+                } else if ((Double.compare(max, 0.0) < 0)
+                        && (Double.isNaN(max * 0.999) == false)) {
+                    invalidValues.add(formatValue(max * 0.999));
+                }
+            }
+        }
+
+        return invalidValues;
+    }
+
+    /**
+     * Return expected error message for option with value "value" when it used
+     * on command line with passed value
+     *
+     * @param value option value
+     * @return expected error message
+     */
+    @Override
+    protected String getErrorMessageCommandLine(String value) {
+        String errorMsg;
+
+        if (withRange) {
+            /* Option have defined range in VM */
+            errorMsg = "is outside the allowed range";
+        } else {
+            errorMsg = "";
+        }
+
+        return errorMsg;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/IntJVMOption.java	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,309 @@
+/*
+ * 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.
+ */
+
+package optionsvalidation;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.test.lib.Platform;
+
+public class IntJVMOption extends JVMOption {
+
+    private static final BigInteger MIN_LONG;
+    private static final BigInteger MAX_LONG;
+    private static final BigInteger MAX_UNSIGNED_LONG;
+    private static final BigInteger MAX_UNSIGNED_LONG_64;
+    private static final BigInteger MINUS_ONE = new BigInteger("-1");
+    private static final BigInteger TWO = new BigInteger("2");
+    private static final BigInteger MIN_4_BYTE_INT = new BigInteger("-2147483648");
+    private static final BigInteger MAX_4_BYTE_INT = new BigInteger("2147483647");
+    private static final BigInteger MAX_4_BYTE_INT_PLUS_ONE = new BigInteger("2147483648");
+    private static final BigInteger MAX_4_BYTE_UNSIGNED_INT = new BigInteger("4294967295");
+    private static final BigInteger MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE = new BigInteger("4294967296");
+
+    /**
+     * Mininum option value
+     */
+    private BigInteger min;
+
+    /**
+     * Maximum option value
+     */
+    private BigInteger max;
+
+    /**
+     * Option type: intx, uintx, size_t or uint64_t
+     */
+    private String type;
+
+    /**
+     * Is this value signed or unsigned
+     */
+    private boolean unsigned;
+
+    /**
+     * Is this 32 bit type
+     */
+    private boolean is32Bit = false;
+
+    /**
+     * Is this value 64 bit unsigned
+     */
+    private boolean uint64 = false;
+
+    static {
+        if (Platform.is32bit()) {
+            MIN_LONG = new BigInteger(String.valueOf(Integer.MIN_VALUE));
+            MAX_LONG = new BigInteger(String.valueOf(Integer.MAX_VALUE));
+            MAX_UNSIGNED_LONG = MAX_LONG.multiply(TWO).add(BigInteger.ONE);
+        } else {
+            MIN_LONG = new BigInteger(String.valueOf(Long.MIN_VALUE));
+            MAX_LONG = new BigInteger(String.valueOf(Long.MAX_VALUE));
+            MAX_UNSIGNED_LONG = MAX_LONG.multiply(TWO).add(BigInteger.ONE);
+        }
+
+        MAX_UNSIGNED_LONG_64 = (new BigInteger(String.valueOf(Long.MAX_VALUE)))
+                .multiply(TWO).add(BigInteger.ONE);
+    }
+
+    private IntJVMOption() {
+        type = "";
+    }
+
+    /**
+     * Initialize new integer option with given type. Type can be: INTX -
+     * integer signed option UINTX - unsigned integer option UINT64_T - unsigned
+     * 64 bit integer option
+     *
+     * @param name name of the option
+     * @param type type of the option
+     */
+    IntJVMOption(String name, String type) {
+        this.name = name;
+        this.type = type;
+
+        switch (type) {
+            case "uint64_t":
+                unsigned = true;
+                uint64 = true;
+                max = MAX_UNSIGNED_LONG_64;
+                break;
+            case "uintx":
+            case "size_t":
+                unsigned = true;
+                max = MAX_UNSIGNED_LONG;
+                break;
+            case "uint":
+                unsigned = true;
+                is32Bit = true;
+                max = MAX_4_BYTE_UNSIGNED_INT;
+                break;
+            case "int":
+                min = MIN_4_BYTE_INT;
+                max = MAX_4_BYTE_INT;
+                is32Bit = true;
+                break;
+            default:
+                min = MIN_LONG;
+                max = MAX_LONG;
+                break;
+        }
+
+        if (unsigned) {
+            min = BigInteger.ZERO;
+        }
+    }
+
+    /**
+     * Initialize integer option with passed name, min and max values. Min and
+     * max are string because they can be very big, bigger than long.
+     *
+     * @param name name of the option
+     * @param min minimum value of the option
+     * @param max maximum value of the option
+     */
+    public IntJVMOption(String name, String min, String max) {
+        this();
+        this.name = name;
+        this.min = new BigInteger(min);
+        this.max = new BigInteger(max);
+    }
+
+    /**
+     * Set new minimum option value
+     *
+     * @param min new minimum value
+     */
+    @Override
+    void setMin(String min) {
+        this.min = new BigInteger(min);
+    }
+
+    /**
+     * Get string with minimum value of the option
+     *
+     * @return string with minimum value of the option
+     */
+    @Override
+    String getMin() {
+        return min.toString();
+    }
+
+    /**
+     * Set new maximum option value
+     *
+     * @param max new maximum value
+     */
+    @Override
+    void setMax(String max) {
+        this.max = new BigInteger(max);
+    }
+
+    /**
+     * Get string with maximum value of the option
+     *
+     * @return string with maximum value of the option
+     */
+    @Override
+    String getMax() {
+        return max.toString();
+    }
+
+    /**
+     * Return list of strings with valid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain valid values for option
+     */
+    @Override
+    protected List<String> getValidValues() {
+        List<String> validValues = new ArrayList<>();
+
+        validValues.add(min.toString());
+        validValues.add(max.toString());
+
+        if ((min.compareTo(MINUS_ONE) == -1) && (max.compareTo(MINUS_ONE) == 1)) {
+            /*
+             * Add -1 as valid value if min is less than -1 and max is greater than -1
+             */
+            validValues.add("-1");
+        }
+
+        if ((min.compareTo(BigInteger.ZERO) == -1) && (max.compareTo(BigInteger.ZERO) == 1)) {
+            /*
+             * Add 0 as valid value if min is less than 0 and max is greater than 0
+             */
+            validValues.add("0");
+        }
+        if ((min.compareTo(BigInteger.ONE) == -1) && (max.compareTo(BigInteger.ONE) == 1)) {
+            /*
+             * Add 1 as valid value if min is less than 1 and max is greater than 1
+             */
+            validValues.add("1");
+        }
+
+        if (max.compareTo(MAX_4_BYTE_INT_PLUS_ONE) == 1) {
+            /*
+             * Check for overflow when flag is assigned to the
+             * 4 byte int variable
+             */
+            validValues.add(MAX_4_BYTE_INT_PLUS_ONE.toString());
+        }
+
+        if (max.compareTo(MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE) == 1) {
+            /*
+             * Check for overflow when flag is assigned to the
+             * 4 byte unsigned int variable
+             */
+            validValues.add(MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE.toString());
+        }
+
+        return validValues;
+    }
+
+    /**
+     * Return list of strings with invalid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain invalid values for option
+     */
+    @Override
+    protected List<String> getInvalidValues() {
+        List<String> invalidValues = new ArrayList<>();
+
+        if (withRange) {
+            /* Return invalid values only for options which have defined range in VM */
+            if ((is32Bit && min.compareTo(MIN_4_BYTE_INT) != 0)
+                    || (!is32Bit && min.compareTo(MIN_LONG) != 0)) {
+                invalidValues.add(min.subtract(BigInteger.ONE).toString());
+            }
+
+            if (!unsigned
+                    && ((is32Bit && (max.compareTo(MAX_4_BYTE_INT) != 0))
+                    || (!is32Bit && (max.compareTo(MAX_LONG) != 0)))) {
+                invalidValues.add(max.add(BigInteger.ONE).toString());
+            }
+
+            if (unsigned
+                    && ((is32Bit && (max.compareTo(MAX_4_BYTE_UNSIGNED_INT) != 0))
+                    || (!is32Bit && !uint64 && (max.compareTo(MAX_UNSIGNED_LONG) != 0))
+                    || (uint64 && (max.compareTo(MAX_UNSIGNED_LONG_64) != 0)))) {
+                invalidValues.add(max.add(BigInteger.ONE).toString());
+            }
+        }
+
+        return invalidValues;
+    }
+
+    /**
+     * Return expected error message for option with value "value" when it used
+     * on command line with passed value
+     *
+     * @param value Option value
+     * @return expected error message
+     */
+    @Override
+    protected String getErrorMessageCommandLine(String value) {
+        String errorMsg;
+
+        if (withRange) {
+            /* Option have defined range in VM */
+            if (unsigned && ((new BigInteger(value)).compareTo(BigInteger.ZERO) < 0)) {
+                /*
+                 * Special case for unsigned options with lower range equal to 0. If
+                 * passed value is negative then error will be caught earlier for
+                 * such options. Thus use different error message.
+                 */
+                errorMsg = String.format("Improperly specified VM option '%s=%s'", name, value);
+            } else {
+                errorMsg = String.format("%s %s=%s is outside the allowed range [ %s ... %s ]",
+                        type, name, value, min.toString(), max.toString());
+            }
+        } else {
+            errorMsg = "";
+        }
+
+        return errorMsg;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOption.java	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,477 @@
+/*
+ * 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.
+ */
+package optionsvalidation;
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.AttachOperationFailedException;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.test.lib.DynamicVMOption;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.dcmd.CommandExecutor;
+import jdk.test.lib.dcmd.JMXExecutor;
+import sun.tools.attach.HotSpotVirtualMachine;
+
+import static optionsvalidation.JVMOptionsUtils.failedMessage;
+import static optionsvalidation.JVMOptionsUtils.printOutputContent;
+import static optionsvalidation.JVMOptionsUtils.VMType;
+
+public abstract class JVMOption {
+
+    /**
+     * Executor for JCMD
+     */
+    private final static CommandExecutor executor = new JMXExecutor();
+
+    /**
+     * Name of the tested parameter
+     */
+    protected String name;
+
+    /**
+     * Range is defined for option inside VM
+     */
+    protected boolean withRange;
+
+    /**
+     * Prepend string which added before testing option to the command line
+     */
+    private final List<String> prepend;
+    private final StringBuilder prependString;
+
+    protected JVMOption() {
+        this.prepend = new ArrayList<>();
+        prependString = new StringBuilder();
+        withRange = false;
+    }
+
+    /**
+     * Create JVM Option with given type and name.
+     *
+     * @param type type: "intx", "size_t", "uintx", "uint64_t" or "double"
+     * @param name name of the option
+     * @return created JVMOption
+     */
+    static JVMOption createVMOption(String type, String name) {
+        JVMOption parameter;
+
+        switch (type) {
+            case "int":
+            case "intx":
+            case "size_t":
+            case "uint":
+            case "uintx":
+            case "uint64_t":
+                parameter = new IntJVMOption(name, type);
+                break;
+            case "double":
+                parameter = new DoubleJVMOption(name);
+                break;
+            default:
+                throw new Error("Expected only \"int\", \"intx\", \"size_t\", "
+                        + "\"uint\", \"uintx\", \"uint64_t\", or \"double\" "
+                        + "option types! Got " + type + " type!");
+        }
+
+        return parameter;
+    }
+
+    /**
+     * Add passed options to the prepend options of the option. Prepend options
+     * will be added before testing option to the command line.
+     *
+     * @param options array of prepend options
+     */
+    public final void addPrepend(String... options) {
+        String toAdd;
+
+        for (String option : options) {
+            if (option.startsWith("-")) {
+                toAdd = option;
+            } else {
+                /* Add "-" before parameter name */
+                toAdd = "-" + option;
+
+            }
+            prepend.add(toAdd);
+            prependString.append(toAdd).append(" ");
+        }
+    }
+
+    /**
+     * Get name of the option
+     *
+     * @return name of the option
+     */
+    final String getName() {
+        return name;
+    }
+
+    /**
+     * Mark this option as option which range is defined inside VM
+     */
+    final void optionWithRange() {
+        withRange = true;
+    }
+
+    /**
+     * Set new minimum option value
+     *
+     * @param min new minimum value
+     */
+    abstract void setMin(String min);
+
+    /**
+     * Get string with minimum value of the option
+     *
+     * @return string with minimum value of the option
+     */
+    abstract String getMin();
+
+    /**
+     * Set new maximum option value
+     *
+     * @param max new maximum value
+     */
+    abstract void setMax(String min);
+
+    /**
+     * Get string with maximum value of the option
+     *
+     * @return string with maximum value of the option
+     */
+    abstract String getMax();
+
+    /**
+     * Return list of strings with valid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain valid values for option
+     */
+    protected abstract List<String> getValidValues();
+
+    /**
+     * Return list of strings with invalid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain invalid values for option
+     */
+    protected abstract List<String> getInvalidValues();
+
+    /**
+     * Return expected error message for option with value "value" when it used
+     * on command line with passed value
+     *
+     * @param value option value
+     * @return expected error message
+     */
+    protected abstract String getErrorMessageCommandLine(String value);
+
+    /**
+     * Testing writeable option using DynamicVMOption isValidValue and
+     * isInvalidValue methods
+     *
+     * @return number of failed tests
+     */
+    public int testDynamic() {
+        DynamicVMOption option = new DynamicVMOption(name);
+        int failedTests = 0;
+        String origValue;
+
+        if (option.isWriteable()) {
+
+            System.out.println("Testing " + name + " option dynamically by DynamicVMOption");
+
+            origValue = option.getValue();
+
+            for (String value : getValidValues()) {
+                if (!option.isValidValue(value)) {
+                    failedMessage(String.format("Option %s: Valid value \"%s\" is invalid", name, value));
+                    failedTests++;
+                }
+            }
+
+            for (String value : getInvalidValues()) {
+                if (option.isValidValue(value)) {
+                    failedMessage(String.format("Option %s: Invalid value \"%s\" is valid", name, value));
+                    failedTests++;
+                }
+            }
+
+            option.setValue(origValue);
+        }
+
+        return failedTests;
+    }
+
+    /**
+     * Testing writeable option using Jcmd
+     *
+     * @return number of failed tests
+     */
+    public int testJcmd() {
+        DynamicVMOption option = new DynamicVMOption(name);
+        int failedTests = 0;
+        OutputAnalyzer out;
+        String origValue;
+
+        if (option.isWriteable()) {
+
+            System.out.println("Testing " + name + " option dynamically by jcmd");
+
+            origValue = option.getValue();
+
+            for (String value : getValidValues()) {
+                out = executor.execute(String.format("VM.set_flag %s %s", name, value), true);
+
+                if (out.getOutput().contains(name + " error")) {
+                    failedMessage(String.format("Option %s: Can not change "
+                            + "option to valid value \"%s\" via jcmd", name, value));
+                    printOutputContent(out);
+                    failedTests++;
+                }
+            }
+
+            for (String value : getInvalidValues()) {
+                out = executor.execute(String.format("VM.set_flag %s %s", name, value), true);
+
+                if (!out.getOutput().contains(name + " error")) {
+                    failedMessage(String.format("Option %s: Error not reported for "
+                            + "option when it chagned to invalid value \"%s\" via jcmd", name, value));
+                    printOutputContent(out);
+                    failedTests++;
+                }
+            }
+
+            option.setValue(origValue);
+        }
+
+        return failedTests;
+    }
+
+    private boolean setFlagAttach(HotSpotVirtualMachine vm, String flagName, String flagValue) throws Exception {
+        boolean result;
+
+        try {
+            vm.setFlag(flagName, flagValue);
+            result = true;
+        } catch (AttachOperationFailedException e) {
+            result = false;
+        }
+
+        return result;
+    }
+
+    /**
+     * Testing writeable option using attach method
+     *
+     * @return number of failed tests
+     * @throws Exception if an error occurred while attaching to the target JVM
+     */
+    public int testAttach() throws Exception {
+        DynamicVMOption option = new DynamicVMOption(name);
+        int failedTests = 0;
+        String origValue;
+
+        if (option.isWriteable()) {
+
+            System.out.println("Testing " + name + " option dynamically via attach");
+
+            origValue = option.getValue();
+
+            HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine.attach(String.valueOf(ProcessTools.getProcessId()));
+
+            for (String value : getValidValues()) {
+                if (!setFlagAttach(vm, name, value)) {
+                    failedMessage(String.format("Option %s: Can not change option to valid value \"%s\" via attach", name, value));
+                    failedTests++;
+                }
+            }
+
+            for (String value : getInvalidValues()) {
+                if (setFlagAttach(vm, name, value)) {
+                    failedMessage(String.format("Option %s: Option changed to invalid value \"%s\" via attach", name, value));
+                    failedTests++;
+                }
+            }
+
+            vm.detach();
+
+            option.setValue(origValue);
+        }
+
+        return failedTests;
+    }
+
+    /**
+     * Run java with passed parameter and check the result depending on the
+     * 'valid' parameter
+     *
+     * @param param tested parameter passed to the JVM
+     * @param valid indicates whether the JVM should fail or not
+     * @return true - if test passed
+     * @throws Exception if java process can not be started
+     */
+    private boolean runJavaWithParam(String optionValue, boolean valid) throws Exception {
+        int exitCode;
+        boolean result = true;
+        String value = optionValue.substring(optionValue.lastIndexOf("=") + 1);
+        String fullOptionString = prependString.toString() + optionValue;
+        List<String> runJava = new ArrayList<>();
+        OutputAnalyzer out;
+
+        if (VMType != null) {
+            runJava.add(VMType);
+        }
+        runJava.addAll(prepend);
+        runJava.add(optionValue);
+        runJava.add(JVMOptionsUtils.class.getName());
+
+        out = new OutputAnalyzer(ProcessTools.createJavaProcessBuilder(runJava.toArray(new String[0])).start());
+
+        exitCode = out.getExitValue();
+
+        if (out.getOutput().contains("A fatal error has been detected by the Java Runtime Environment")) {
+            /* Always consider "fatal error" in output as fail */
+            failedMessage(name, fullOptionString, valid, "JVM output reports a fatal error. JVM exited with code " + exitCode + "!");
+            printOutputContent(out);
+            result = false;
+        } else if (valid == true) {
+            if ((exitCode != 0) && (exitCode != 1)) {
+                failedMessage(name, fullOptionString, valid, "JVM exited with unexpected error code = " + exitCode);
+                printOutputContent(out);
+                result = false;
+            } else if ((exitCode == 1) && (out.getOutput().isEmpty() == true)) {
+                failedMessage(name, fullOptionString, valid, "JVM exited with error(exitcode == 1)"
+                        + ", but with empty stdout and stderr. Description of error is needed!");
+                result = false;
+            } else if (out.getOutput().contains("is outside the allowed range")) {
+                failedMessage(name, fullOptionString, valid, "JVM output contains \"is outside the allowed range\"");
+                printOutputContent(out);
+                result = false;
+            }
+        } else {
+            // valid == false
+            if (exitCode == 0) {
+                failedMessage(name, fullOptionString, valid, "JVM successfully exit");
+                result = false;
+            } else if (exitCode != 1) {
+                failedMessage(name, fullOptionString, valid, "JVM exited with code "
+                        + exitCode + " which not equal to 1");
+                result = false;
+            } else if (!out.getOutput().contains(getErrorMessageCommandLine(value))) {
+                failedMessage(name, fullOptionString, valid, "JVM output does not contain "
+                        + "expected output \"" + getErrorMessageCommandLine(value) + "\"");
+                printOutputContent(out);
+                result = false;
+            }
+        }
+
+        System.out.println("");
+
+        return result;
+    }
+
+    /**
+     * Construct option string with passed value
+     *
+     * @param value parameter value
+     * @return string containing option with passed value
+     */
+    private String constructOption(String value) {
+        return "-XX:" + name + "=" + value;
+    }
+
+    /**
+     * Return list of strings which contain options with valid values which can
+     * be used for testing on command line
+     *
+     * @return list of strings which contain options with valid values
+     */
+    private List<String> getValidCommandLineOptions() {
+        List<String> validParameters = new ArrayList<>();
+
+        for (String value : getValidValues()) {
+            validParameters.add(constructOption(value));
+        }
+
+        return validParameters;
+    }
+
+    /**
+     * Return list of strings which contain options with invalid values which
+     * can be used for testing on command line
+     *
+     * @return list of strings which contain options with invalid values
+     */
+    private List<String> getInvalidCommandLineOptions() {
+        List<String> invalidParameters = new ArrayList<>();
+
+        for (String value : getInvalidValues()) {
+            invalidParameters.add(constructOption(value));
+        }
+
+        return invalidParameters;
+    }
+
+    /**
+     * Perform test of the parameter. Call java with valid option values and
+     * with invalid option values.
+     *
+     * @return number of failed tests
+     * @throws Exception if java process can not be started
+     */
+    public int testCommandLine() throws Exception {
+        ProcessBuilder pb;
+        int failed = 0;
+        List<String> optionValuesList;
+
+        optionValuesList = getValidCommandLineOptions();
+
+        if (optionValuesList.isEmpty() != true) {
+            System.out.println("Testing valid " + name + " values.");
+            for (String optionValid : optionValuesList) {
+                if (runJavaWithParam(optionValid, true) == false) {
+                    failed++;
+                }
+            }
+        }
+
+        optionValuesList = getInvalidCommandLineOptions();
+
+        if (optionValuesList.isEmpty() != true) {
+            System.out.println("Testing invalid " + name + " values.");
+
+            for (String optionInvalid : optionValuesList) {
+                if (runJavaWithParam(optionInvalid, false) == false) {
+                    failed++;
+                }
+            }
+        }
+
+        /* return number of failed tests for this option */
+        return failed;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java	Fri Jun 19 13:03:58 2015 +0000
@@ -0,0 +1,450 @@
+/*
+ * 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.
+ */
+
+package optionsvalidation;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.function.Predicate;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.Platform;
+import jdk.test.lib.ProcessTools;
+
+public class JVMOptionsUtils {
+
+    /* Java option which print options with ranges */
+    private static final String PRINT_FLAGS_RANGES = "-XX:+PrintFlagsRanges";
+
+    /* StringBuilder to accumulate failed message */
+    private static final StringBuilder finalFailedMessage = new StringBuilder();
+
+    /* Used to start the JVM with the same type as current */
+    static String VMType;
+
+    static {
+        if (Platform.isServer()) {
+            VMType = "-server";
+        } else if (Platform.isClient()) {
+            VMType = "-client";
+        } else if (Platform.isMinimal()) {
+            VMType = "-minimal";
+        } else if (Platform.isGraal()) {
+            VMType = "-graal";
+        } else {
+            VMType = null;
+        }
+    }
+
+    /**
+     * Add dependency for option depending on it's name. E.g. enable G1 GC for
+     * G1 options or add prepend options to not hit constraints.
+     *
+     * @param option option
+     */
+    private static void addNameDependency(JVMOption option) {
+        String name = option.getName();
+
+        if (name.startsWith("G1")) {
+            option.addPrepend("-XX:+UseG1GC");
+        }
+
+        if (name.startsWith("CMS")) {
+            option.addPrepend("-XX:+UseConcMarkSweepGC");
+        }
+
+        switch (name) {
+            case "MinHeapFreeRatio":
+                option.addPrepend("-XX:MaxHeapFreeRatio=100");
+                break;
+            case "MaxHeapFreeRatio":
+                option.addPrepend("-XX:MinHeapFreeRatio=0");
+                break;
+            case "MinMetaspaceFreeRatio":
+                option.addPrepend("-XX:MaxMetaspaceFreeRatio=100");
+                break;
+            case "MaxMetaspaceFreeRatio":
+                option.addPrepend("-XX:MinMetaspaceFreeRatio=0");
+                break;
+            case "CMSOldPLABMin":
+                option.addPrepend("-XX:CMSOldPLABMax=" + option.getMax());
+                break;
+            case "CMSOldPLABMax":
+                option.addPrepend("-XX:CMSOldPLABMin=" + option.getMin());
+                break;
+            case "CMSPrecleanNumerator":
+                option.addPrepend("-XX:CMSPrecleanDenominator=" + option.getMax());
+                break;
+            case "CMSPrecleanDenominator":
+                option.addPrepend("-XX:CMSPrecleanNumerator=" + ((new Integer(option.getMin())) - 1));
+                break;
+            case "InitialTenuringThreshold":
+                option.addPrepend("-XX:MaxTenuringThreshold=" + option.getMax());
+                break;
+            default:
+                /* Do nothing */
+                break;
+        }
+
+    }
+
+    /**
+     * Add dependency for option depending on it's type. E.g. run the JVM in
+     * compilation mode for compiler options.
+     *
+     * @param option option
+     * @param type type of the option
+     */
+    private static void addTypeDependency(JVMOption option, String type) {
+        if (type.contains("C1") || type.contains("C2")) {
+            /* Run in compiler mode for compiler flags */
+            option.addPrepend("-Xcomp");
+        }
+    }
+
+    /**
+     * Parse JVM Options. Get input from "inputReader". Parse using
+     * "-XX:+PrintFlagsRanges" output format.
+     *
+     * @param inputReader input data for parsing
+     * @param withRanges true if needed options with defined ranges inside JVM
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @return map from option name to the JVMOption object
+     * @throws IOException if an error occurred while reading the data
+     */
+    private static Map<String, JVMOption> getJVMOptions(Reader inputReader,
+            boolean withRanges, Predicate<String> acceptOrigin) throws IOException {
+        BufferedReader reader = new BufferedReader(inputReader);
+        String type;
+        String line;
+        String token;
+        String name;
+        StringTokenizer st;
+        JVMOption option;
+        Map<String, JVMOption> allOptions = new LinkedHashMap<>();
+
+        // Skip first line
+        line = reader.readLine();
+
+        while ((line = reader.readLine()) != null) {
+            /*
+             * Parse option from following line:
+             * <type> <name> [ <min, optional> ... <max, optional> ] {<origin>}
+             */
+            st = new StringTokenizer(line);
+
+            type = st.nextToken();
+
+            name = st.nextToken();
+
+            option = JVMOption.createVMOption(type, name);
+
+            /* Skip '[' */
+            token = st.nextToken();
+
+            /* Read min range or "..." if range is absent */
+            token = st.nextToken();
+
+            if (token.equals("...") == false) {
+                if (!withRanges) {
+                    /*
+                     * Option have range, but asked for options without
+                     * ranges => skip it
+                     */
+                    continue;
+                }
+
+                /* Mark this option as option which range is defined in VM */
+                option.optionWithRange();
+
+                option.setMin(token);
+
+                /* Read "..." and skip it */
+                token = st.nextToken();
+
+                /* Get max value */
+                token = st.nextToken();
+                option.setMax(token);
+            } else if (withRanges) {
+                /*
+                 * Option not have range, but asked for options with
+                 * ranges => skip it
+                 */
+                continue;
+            }
+
+            /* Skip ']' */
+            token = st.nextToken();
+
+            /* Read origin of the option */
+            token = st.nextToken();
+
+            while (st.hasMoreTokens()) {
+                token += st.nextToken();
+            };
+            token = token.substring(1, token.indexOf("}"));
+
+            if (acceptOrigin.test(token)) {
+                addTypeDependency(option, token);
+                addNameDependency(option);
+
+                allOptions.put(name, option);
+            }
+        }
+
+        return allOptions;
+    }
+
+    static void failedMessage(String optionName, String value, boolean valid, String message) {
+        String temp;
+
+        if (valid) {
+            temp = "valid";
+        } else {
+            temp = "invalid";
+        }
+
+        failedMessage(String.format("Error processing option %s with %s value '%s'! %s",
+                optionName, temp, value, message));
+    }
+
+    static void failedMessage(String message) {
+        System.err.println("TEST FAILED: " + message);
+        finalFailedMessage.append(String.format("(%s)%n", message));
+    }
+
+    static void printOutputContent(OutputAnalyzer output) {
+        System.err.println(String.format("stdout content[%s]", output.getStdout()));
+        System.err.println(String.format("stderr content[%s]%n", output.getStderr()));
+    }
+
+    /**
+     * Return string with accumulated failure messages
+     *
+     * @return string with accumulated failure messages
+     */
+    public static String getMessageWithFailures() {
+        return finalFailedMessage.toString();
+    }
+
+    /**
+     * Run command line tests for options passed in the list
+     *
+     * @param options list of options to test
+     * @return number of failed tests
+     * @throws Exception if java process can not be started
+     */
+    public static int runCommandLineTests(List<? extends JVMOption> options) throws Exception {
+        int failed = 0;
+
+        for (JVMOption option : options) {
+            failed += option.testCommandLine();
+        }
+
+        return failed;
+    }
+
+    /**
+     * Test passed options using DynamicVMOption isValidValue and isInvalidValue
+     * methods. Only tests writeable options.
+     *
+     * @param options list of options to test
+     * @return number of failed tests
+     */
+    public static int runDynamicTests(List<? extends JVMOption> options) {
+        int failed = 0;
+
+        for (JVMOption option : options) {
+            failed += option.testDynamic();
+        }
+
+        return failed;
+    }
+
+    /**
+     * Test passed options using Jcmd. Only tests writeable options.
+     *
+     * @param options list of options to test
+     * @return number of failed tests
+     */
+    public static int runJcmdTests(List<? extends JVMOption> options) {
+        int failed = 0;
+
+        for (JVMOption option : options) {
+            failed += option.testJcmd();
+        }
+
+        return failed;
+    }
+
+    /**
+     * Test passed option using attach method. Only tests writeable options.
+     *
+     * @param options list of options to test
+     * @return number of failed tests
+     * @throws Exception if an error occurred while attaching to the target JVM
+     */
+    public static int runAttachTests(List<? extends JVMOption> options) throws Exception {
+        int failed = 0;
+
+        for (JVMOption option : options) {
+            failed += option.testAttach();
+        }
+
+        return failed;
+    }
+
+    /**
+     * Get JVM options as map. Can return options with defined ranges or options
+     * without range depending on "withRanges" argument. "acceptOrigin"
+     * predicate can be used to filter option origin.
+     *
+     * @param withRanges true if needed options with defined ranges inside JVM
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return map from option name to the JVMOption object
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static Map<String, JVMOption> getOptionsAsMap(boolean withRanges, Predicate<String> acceptOrigin,
+            String... additionalArgs) throws Exception {
+        Map<String, JVMOption> result;
+        Process p;
+        List<String> runJava = new ArrayList<>();
+
+        if (additionalArgs.length > 0) {
+            runJava.addAll(Arrays.asList(additionalArgs));
+        }
+
+        if (VMType != null) {
+            runJava.add(VMType);
+        }
+        runJava.add(PRINT_FLAGS_RANGES);
+        runJava.add("-version");
+
+        p = ProcessTools.createJavaProcessBuilder(runJava.toArray(new String[0])).start();
+
+        result = getJVMOptions(new InputStreamReader(p.getInputStream()), withRanges, acceptOrigin);
+
+        p.waitFor();
+
+        return result;
+    }
+
+    /**
+     * Get JVM options as list. Can return options with defined ranges or
+     * options without range depending on "withRanges" argument. "acceptOrigin"
+     * predicate can be used to filter option origin.
+     *
+     * @param withRanges true if needed options with defined ranges inside JVM
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return List of options
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static List<JVMOption> getOptions(boolean withRanges, Predicate<String> acceptOrigin,
+            String... additionalArgs) throws Exception {
+        return new ArrayList<>(getOptionsAsMap(withRanges, acceptOrigin, additionalArgs).values());
+    }
+
+    /**
+     * Get JVM options with ranges as list. "acceptOrigin" predicate can be used
+     * to filter option origin.
+     *
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return List of options
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static List<JVMOption> getOptionsWithRange(Predicate<String> acceptOrigin, String... additionalArgs) throws Exception {
+        return getOptions(true, acceptOrigin, additionalArgs);
+    }
+
+    /**
+     * Get JVM options with ranges as list.
+     *
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return list of options
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static List<JVMOption> getOptionsWithRange(String... additionalArgs) throws Exception {
+        return getOptionsWithRange(origin -> true, additionalArgs);
+    }
+
+    /**
+     * Get JVM options with range as map. "acceptOrigin" predicate can be used
+     * to filter option origin.
+     *
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return Map from option name to the JVMOption object
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static Map<String, JVMOption> getOptionsWithRangeAsMap(Predicate<String> acceptOrigin, String... additionalArgs) throws Exception {
+        return getOptionsAsMap(true, acceptOrigin, additionalArgs);
+    }
+
+    /**
+     * Get JVM options with range as map
+     *
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return map from option name to the JVMOption object
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static Map<String, JVMOption> getOptionsWithRangeAsMap(String... additionalArgs) throws Exception {
+        return getOptionsWithRangeAsMap(origin -> true, additionalArgs);
+    }
+
+    /* Simple method to test that java start-up. Used for testing options. */
+    public static void main(String[] args) {
+        System.out.print("Java start-up!");
+    }
+}
--- a/hotspot/test/runtime/CompressedOops/CompressedClassSpaceSize.java	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/runtime/CompressedOops/CompressedClassSpaceSize.java	Fri Jun 19 13:03:58 2015 +0000
@@ -42,7 +42,7 @@
             pb = ProcessTools.createJavaProcessBuilder("-XX:CompressedClassSpaceSize=0",
                                                        "-version");
             output = new OutputAnalyzer(pb.start());
-            output.shouldContain("CompressedClassSpaceSize of 0 is invalid")
+            output.shouldContain("outside the allowed range")
                   .shouldHaveExitValue(1);
 
             // Invalid size of -1 should be handled correctly
@@ -57,7 +57,7 @@
             pb = ProcessTools.createJavaProcessBuilder("-XX:CompressedClassSpaceSize=4g",
                                                        "-version");
             output = new OutputAnalyzer(pb.start());
-            output.shouldContain("CompressedClassSpaceSize of 4294967296 is invalid")
+            output.shouldContain("outside the allowed range")
                   .shouldHaveExitValue(1);
 
 
--- a/hotspot/test/runtime/CompressedOops/ObjectAlignment.java	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/runtime/CompressedOops/ObjectAlignment.java	Fri Jun 19 13:03:58 2015 +0000
@@ -39,21 +39,22 @@
         if (Platform.is64bit()) {
             // Minimum alignment should be 8
             testObjectAlignment(4)
-                .shouldContain("error: ObjectAlignmentInBytes=4 must be greater or equal 8")
+                .shouldContain("outside the allowed range")
                 .shouldHaveExitValue(1);
 
             // Alignment has to be a power of 2
             testObjectAlignment(9)
-                .shouldContain("error: ObjectAlignmentInBytes=9 must be power of 2")
+                .shouldContain("must be power of 2")
                 .shouldHaveExitValue(1);
 
             testObjectAlignment(-1)
-                .shouldContain("error: ObjectAlignmentInBytes=-1 must be power of 2")
+                .shouldContain("must be power of 2")
+                .shouldContain("outside the allowed range")
                 .shouldHaveExitValue(1);
 
             // Maximum alignment allowed is 256
             testObjectAlignment(512)
-                .shouldContain("error: ObjectAlignmentInBytes=512 must not be greater than 256")
+                .shouldContain("outside the allowed range")
                 .shouldHaveExitValue(1);
 
             // Valid alignments should work
@@ -74,4 +75,4 @@
                                                                   "-version");
         return new OutputAnalyzer(pb.start());
     }
-}
+}
\ No newline at end of file
--- a/hotspot/test/runtime/contended/Options.java	Fri Jun 19 11:27:07 2015 +0200
+++ b/hotspot/test/runtime/contended/Options.java	Fri Jun 19 13:03:58 2015 +0000
@@ -42,19 +42,19 @@
         pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-128", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("ContendedPaddingWidth");
-        output.shouldContain("must be in between");
+        output.shouldContain("outside the allowed range");
         output.shouldHaveExitValue(1);
 
         pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-8", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("ContendedPaddingWidth");
-        output.shouldContain("must be in between");
+        output.shouldContain("outside the allowed range");
         output.shouldHaveExitValue(1);
 
         pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=-1", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("ContendedPaddingWidth");
-        output.shouldContain("must be in between");
+        output.shouldContain("outside the allowed range");
         output.shouldContain("must be a multiple of 8");
         output.shouldHaveExitValue(1);
 
@@ -89,17 +89,16 @@
         pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8193", "-version");
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("ContendedPaddingWidth");
-        output.shouldContain("must be in between");
+        output.shouldContain("outside the allowed range");
         output.shouldContain("must be a multiple of 8");
         output.shouldHaveExitValue(1);
 
         pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8200", "-version"); // 8192+8 = 8200
         output = new OutputAnalyzer(pb.start());
         output.shouldContain("ContendedPaddingWidth");
-        output.shouldContain("must be in between");
+        output.shouldContain("outside the allowed range");
         output.shouldHaveExitValue(1);
 
    }
 
 }
-