8073500: Prevent certain commercial flags from being changed at runtime
authorgziemski
Tue, 10 May 2016 12:10:21 -0500
changeset 38273 2634194d7555
parent 38267 29feb145a316
child 38274 3b0097103664
8073500: Prevent certain commercial flags from being changed at runtime Summary: Implement new writeable mechanism for flag control Reviewed-by: coleenp, iklam
hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp
hotspot/src/cpu/ppc/vm/globals_ppc.hpp
hotspot/src/cpu/sparc/vm/globals_sparc.hpp
hotspot/src/cpu/x86/vm/globals_x86.hpp
hotspot/src/cpu/zero/vm/globals_zero.hpp
hotspot/src/os/aix/vm/globals_aix.hpp
hotspot/src/os/bsd/vm/globals_bsd.hpp
hotspot/src/os/linux/vm/globals_linux.hpp
hotspot/src/os/solaris/vm/globals_solaris.hpp
hotspot/src/os/windows/vm/globals_windows.hpp
hotspot/src/share/vm/c1/c1_globals.cpp
hotspot/src/share/vm/c1/c1_globals.hpp
hotspot/src/share/vm/gc/g1/g1_globals.cpp
hotspot/src/share/vm/gc/g1/g1_globals.hpp
hotspot/src/share/vm/jvmci/jvmci_globals.cpp
hotspot/src/share/vm/jvmci/jvmci_globals.hpp
hotspot/src/share/vm/opto/c2_globals.cpp
hotspot/src/share/vm/opto/c2_globals.hpp
hotspot/src/share/vm/runtime/arguments.cpp
hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp
hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp
hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp
hotspot/src/share/vm/runtime/commandLineFlagWriteableList.cpp
hotspot/src/share/vm/runtime/commandLineFlagWriteableList.hpp
hotspot/src/share/vm/runtime/globals.cpp
hotspot/src/share/vm/runtime/globals.hpp
hotspot/src/share/vm/runtime/globals_extension.hpp
hotspot/src/share/vm/runtime/os_ext.hpp
hotspot/src/share/vm/runtime/thread.cpp
--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp	Tue May 10 12:10:21 2016 -0500
@@ -85,7 +85,14 @@
 
 #ifdef BUILTIN_SIM
 #define UseBuiltinSim           true
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
+#define ARCH_FLAGS(develop, \
+                   product, \
+                   diagnostic, \
+                   experimental, \
+                   notproduct, \
+                   range, \
+                   constraint, \
+                   writeable) \
                                                                         \
   product(bool, NotifySimulator, UseBuiltinSim,                         \
          "tell the AArch64 sim where we are in method code")            \
@@ -117,7 +124,14 @@
 #define NotifySimulator         false
 #define UseSimulatorCache       false
 #define DisableBCCheck          true
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
+#define ARCH_FLAGS(develop, \
+                   product, \
+                   diagnostic, \
+                   experimental, \
+                   notproduct, \
+                   range, \
+                   constraint, \
+                   writeable) \
                                                                         \
   product(bool, NearCpool, true,                                        \
          "constant pool is close to instructions")                      \
--- a/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp	Tue May 10 12:10:21 2016 -0500
@@ -79,7 +79,14 @@
 define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
 
 // Platform dependent flag handling: flags only defined on this platform.
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint)  \
+#define ARCH_FLAGS(develop, \
+                   product, \
+                   diagnostic, \
+                   experimental, \
+                   notproduct, \
+                   range, \
+                   constraint, \
+                   writeable)  \
                                                                             \
   /* 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	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp	Tue May 10 12:10:21 2016 -0500
@@ -92,7 +92,14 @@
 
 define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
 
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
+#define ARCH_FLAGS(develop, \
+                   product, \
+                   diagnostic, \
+                   experimental, \
+                   notproduct, \
+                   range, \
+                   constraint, \
+                   writeable) \
                                                                             \
   product(intx, UseVIS, 99,                                                 \
           "Highest supported VIS instructions set on Sparc")                \
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp	Tue May 10 12:10:21 2016 -0500
@@ -99,7 +99,14 @@
 
 define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
 
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint) \
+#define ARCH_FLAGS(develop, \
+                   product, \
+                   diagnostic, \
+                   experimental, \
+                   notproduct, \
+                   range, \
+                   constraint, \
+                   writeable) \
                                                                             \
   develop(bool, IEEEPrecision, true,                                        \
           "Enables IEEE precision (for INTEL only)")                        \
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp	Tue May 10 12:10:21 2016 -0500
@@ -80,7 +80,14 @@
 // No performance work done here yet.
 define_pd_global(bool, CompactStrings, false);
 
-#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct, range, constraint)  \
+#define ARCH_FLAGS(develop, \
+                   product, \
+                   diagnostic, \
+                   experimental, \
+                   notproduct, \
+                   range, \
+                   constraint, \
+                   writeable)  \
                                                                             \
   product(bool, UseFastEmptyMethods, true,                                  \
           "Use fast method entry code for empty methods")                   \
--- a/hotspot/src/os/aix/vm/globals_aix.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/os/aix/vm/globals_aix.hpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -30,7 +30,15 @@
 // Defines Aix specific flags. They are not available on other platforms.
 //
 // (Please keep the switches sorted alphabetically.)
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
+#define RUNTIME_OS_FLAGS(develop, \
+                         develop_pd, \
+                         product, \
+                         product_pd, \
+                         diagnostic, \
+                         notproduct, \
+                         range, \
+                         constraint, \
+                         writeable) \
                                                                                     \
   /* Whether to allow the VM to run if EXTSHM=ON. EXTSHM is an environment */       \
   /* variable used on AIX to activate certain hacks which allow more shm segments */\
--- a/hotspot/src/os/bsd/vm/globals_bsd.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/os/bsd/vm/globals_bsd.hpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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,15 @@
 //
 // Defines Bsd specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
+#define RUNTIME_OS_FLAGS(develop, \
+                         develop_pd, \
+                         product, \
+                         product_pd, \
+                         diagnostic, \
+                         notproduct, \
+                         range, \
+                         constraint, \
+                         writeable) \
                                                                                 \
   product(bool, UseOprofile, false,                                             \
         "enable support for Oprofile profiler")                                 \
--- a/hotspot/src/os/linux/vm/globals_linux.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/os/linux/vm/globals_linux.hpp	Tue May 10 12:10:21 2016 -0500
@@ -28,7 +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, range, constraint) \
+#define RUNTIME_OS_FLAGS(develop, \
+                         develop_pd, \
+                         product, \
+                         product_pd, \
+                         diagnostic, \
+                         notproduct, \
+                         range, \
+                         constraint, \
+                         writeable) \
                                                                         \
   product(bool, UseOprofile, false,                                     \
         "enable support for Oprofile profiler")                         \
--- a/hotspot/src/os/solaris/vm/globals_solaris.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/os/solaris/vm/globals_solaris.hpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, 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,15 @@
 //
 // Defines Solaris specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
+#define RUNTIME_OS_FLAGS(develop, \
+                         develop_pd, \
+                         product, \
+                         product_pd, \
+                         diagnostic, \
+                         notproduct, \
+                         range, \
+                         constraint, \
+                         writeable) \
                                                                                \
   product(bool, UseExtendedFileIO, true,                                       \
           "Enable workaround for limitations of stdio FILE structure")
--- a/hotspot/src/os/windows/vm/globals_windows.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/os/windows/vm/globals_windows.hpp	Tue May 10 12:10:21 2016 -0500
@@ -28,7 +28,15 @@
 //
 // Defines Windows specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
+#define RUNTIME_OS_FLAGS(develop, \
+                         develop_pd, \
+                         product, \
+                         product_pd, \
+                         diagnostic, \
+                         notproduct, \
+                         range, \
+                         constraint, \
+                         writeable) \
                                                                          \
   product(bool, UseUTCFileTimestamp, true,                               \
           "Adjust the timestamp returned from stat() to be UTC")
--- a/hotspot/src/share/vm/c1/c1_globals.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_globals.cpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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 "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, IGNORE_RANGE, IGNORE_CONSTRAINT)
+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, \
+         IGNORE_WRITEABLE)
--- a/hotspot/src/share/vm/c1/c1_globals.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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,15 @@
 //
 // Defines all global flags used by the client compiler.
 //
-#define C1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct, range, constraint) \
+#define C1_FLAGS(develop, \
+                 develop_pd, \
+                 product, \
+                 product_pd, \
+                 diagnostic, \
+                 notproduct, \
+                 range, \
+                 constraint, \
+                 writeable) \
                                                                             \
   /* Printing */                                                            \
   notproduct(bool, PrintC1Statistics, false,                                \
@@ -350,6 +358,7 @@
          DECLARE_DIAGNOSTIC_FLAG, \
          DECLARE_NOTPRODUCT_FLAG, \
          IGNORE_RANGE, \
-         IGNORE_CONSTRAINT)
+         IGNORE_CONSTRAINT, \
+         IGNORE_WRITEABLE)
 
 #endif // SHARE_VM_C1_C1_GLOBALS_HPP
--- a/hotspot/src/share/vm/gc/g1/g1_globals.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.cpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -35,4 +35,5 @@
          MATERIALIZE_MANAGEABLE_FLAG, \
          MATERIALIZE_PRODUCT_RW_FLAG, \
          IGNORE_RANGE, \
-         IGNORE_CONSTRAINT)
+         IGNORE_CONSTRAINT, \
+         IGNORE_WRITEABLE)
--- a/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp	Tue May 10 12:10:21 2016 -0500
@@ -31,7 +31,18 @@
 // 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, range, constraint) \
+#define G1_FLAGS(develop, \
+                 develop_pd, \
+                 product, \
+                 product_pd, \
+                 diagnostic, \
+                 experimental, \
+                 notproduct, \
+                 manageable, \
+                 product_rw, \
+                 range, \
+                 constraint, \
+                 writeable) \
                                                                             \
   product(bool, G1UseAdaptiveIHOP, true,                                    \
           "Adaptively adjust the initiating heap occupancy from the "       \
@@ -317,6 +328,7 @@
          DECLARE_MANAGEABLE_FLAG, \
          DECLARE_PRODUCT_RW_FLAG, \
          IGNORE_RANGE, \
-         IGNORE_CONSTRAINT)
+         IGNORE_CONSTRAINT, \
+         IGNORE_WRITEABLE)
 
 #endif // SHARE_VM_GC_G1_G1_GLOBALS_HPP
--- a/hotspot/src/share/vm/jvmci/jvmci_globals.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.cpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -35,7 +35,8 @@
             MATERIALIZE_EXPERIMENTAL_FLAG, \
             MATERIALIZE_NOTPRODUCT_FLAG,
             IGNORE_RANGE, \
-            IGNORE_CONSTRAINT)
+            IGNORE_CONSTRAINT, \
+            IGNORE_WRITEABLE)
 
 #define JVMCI_IGNORE_FLAG_FOUR_PARAM(type, name, value, doc)
 #define JVMCI_IGNORE_FLAG_THREE_PARAM(type, name, doc)
@@ -91,7 +92,8 @@
                 JVMCI_IGNORE_FLAG_FOUR_PARAM, \
                 JVMCI_IGNORE_FLAG_FOUR_PARAM, \
                 IGNORE_RANGE, \
-                IGNORE_CONSTRAINT)
+                IGNORE_CONSTRAINT, \
+                IGNORE_WRITEABLE)
   }
 
   // Check consistency of experimental flags if UnlockExperimentalVMOptions is
@@ -105,7 +107,8 @@
                 JVMCI_EXPERIMENTAL_FLAG_VALUE_CHANGED_CHECK_CODE, \
                 JVMCI_IGNORE_FLAG_FOUR_PARAM, \
                 IGNORE_RANGE, \
-                IGNORE_CONSTRAINT)
+                IGNORE_CONSTRAINT, \
+                IGNORE_WRITEABLE)
   }
 
 #ifndef PRODUCT
@@ -129,7 +132,8 @@
               JVMCI_IGNORE_FLAG_FOUR_PARAM, \
               JVMCI_NOTPRODUCT_FLAG_VALUE_CHANGED_CHECK_CODE, \
               IGNORE_RANGE, \
-              IGNORE_CONSTRAINT)
+              IGNORE_CONSTRAINT, \
+              IGNORE_WRITEABLE)
 
 #undef EMIT_FLAG_VALUE_CHANGED_CHECK_CODE
 #undef JVMCI_DEVELOP_FLAG_VALUE_CHANGED_CHECK_CODE
@@ -167,7 +171,8 @@
                 JVMCI_IGNORE_FLAG_FOUR_PARAM, \
                 JVMCI_IGNORE_FLAG_FOUR_PARAM, \
                 IGNORE_RANGE, \
-                IGNORE_CONSTRAINT)
+                IGNORE_CONSTRAINT, \
+                IGNORE_WRITEABLE)
   }
 
   if (UnlockExperimentalVMOptions || !FLAG_IS_DEFAULT(UnlockExperimentalVMOptions)) {
@@ -179,7 +184,8 @@
                 JVMCI_EXPERIMENTAL_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
                 JVMCI_IGNORE_FLAG_FOUR_PARAM, \
                 IGNORE_RANGE, \
-                IGNORE_CONSTRAINT)
+                IGNORE_CONSTRAINT, \
+                IGNORE_WRITEABLE)
   }
 
 #ifndef PRODUCT
@@ -203,7 +209,8 @@
               JVMCI_IGNORE_FLAG_FOUR_PARAM, \
               JVMCI_NOTPRODUCT_FLAG_CHECK_PRINT_ERR_MSG_CODE, \
               IGNORE_RANGE, \
-              IGNORE_CONSTRAINT)
+              IGNORE_CONSTRAINT, \
+              IGNORE_WRITEABLE)
 
 #undef EMIT_CHECK_PRINT_ERR_MSG_CODE
 #undef JVMCI_DEVELOP_FLAG_CHECK_PRINT_ERR_MSG_CODE
--- a/hotspot/src/share/vm/jvmci/jvmci_globals.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.hpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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,7 +32,16 @@
 // to be accessible to the JVMCI C++ code should be defined here. All other
 // JVMCI flags should be defined in JVMCIOptions.java.
 //
-#define JVMCI_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, range, constraint) \
+#define JVMCI_FLAGS(develop, \
+                    develop_pd, \
+                    product, \
+                    product_pd, \
+                    diagnostic, \
+                    experimental, \
+                    notproduct, \
+                    range, \
+                    constraint, \
+                    writeable) \
                                                                             \
   experimental(bool, EnableJVMCI, false,                                    \
           "Enable JVMCI")                                                   \
@@ -96,7 +105,8 @@
             DECLARE_EXPERIMENTAL_FLAG, \
             DECLARE_NOTPRODUCT_FLAG, \
             IGNORE_RANGE, \
-            IGNORE_CONSTRAINT)
+            IGNORE_CONSTRAINT, \
+            IGNORE_WRITEABLE)
 
 class JVMCIGlobals {
  public:
--- a/hotspot/src/share/vm/opto/c2_globals.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/opto/c2_globals.cpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -33,4 +33,5 @@
          MATERIALIZE_EXPERIMENTAL_FLAG, \
          MATERIALIZE_NOTPRODUCT_FLAG, \
          IGNORE_RANGE, \
-         IGNORE_CONSTRAINT)
+         IGNORE_CONSTRAINT, \
+         IGNORE_WRITEABLE)
--- a/hotspot/src/share/vm/opto/c2_globals.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp	Tue May 10 12:10:21 2016 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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,16 @@
 // Defines all globals flags used by the server compiler.
 //
 
-#define C2_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, range, constraint) \
+#define C2_FLAGS(develop, \
+                 develop_pd, \
+                 product, \
+                 product_pd, \
+                 diagnostic, \
+                 experimental, \
+                 notproduct, \
+                 range, \
+                 constraint, \
+                 writeable) \
                                                                             \
   develop(bool, StressLCM, false,                                           \
           "Randomize instruction scheduling in LCM")                        \
@@ -758,6 +767,7 @@
          DECLARE_EXPERIMENTAL_FLAG, \
          DECLARE_NOTPRODUCT_FLAG, \
          IGNORE_RANGE, \
-         IGNORE_CONSTRAINT)
+         IGNORE_CONSTRAINT, \
+         IGNORE_WRITEABLE)
 
 #endif // SHARE_VM_OPTO_C2_GLOBALS_HPP
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Tue May 10 12:10:21 2016 -0500
@@ -42,6 +42,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/arguments_ext.hpp"
 #include "runtime/commandLineFlagConstraintList.hpp"
+#include "runtime/commandLineFlagWriteableList.hpp"
 #include "runtime/commandLineFlagRangeList.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
@@ -4081,9 +4082,10 @@
 jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
   assert(verify_special_jvm_flags(), "deprecated and obsolete flag table inconsistent");
 
-  // Initialize ranges and constraints
+  // Initialize ranges, constraints and writeables
   CommandLineFlagRangeList::init();
   CommandLineFlagConstraintList::init();
+  CommandLineFlagWriteableList::init();
 
   // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
   const char* hotspotrc = ".hotspotrc";
--- a/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp	Tue May 10 12:10:21 2016 -0500
@@ -217,7 +217,7 @@
 #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, type)                               , func, CommandLineFlagConstraint::type
+#define EMIT_CONSTRAINT_CHECK(func, type)                         , func, CommandLineFlagConstraint::type
 
 // the "name" argument must be a string literal
 #define INITIAL_CONSTRAINTS_SIZE 72
@@ -239,7 +239,8 @@
                                         EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
                                         EMIT_CONSTRAINT_LP64_PRODUCT_FLAG,
                                         IGNORE_RANGE,
-                                        EMIT_CONSTRAINT_CHECK));
+                                        EMIT_CONSTRAINT_CHECK,
+                                        IGNORE_WRITEABLE));
 
   EMIT_CONSTRAINTS_FOR_GLOBALS_EXT
 
@@ -249,7 +250,8 @@
                                      EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
                                      EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
                                      IGNORE_RANGE,
-                                     EMIT_CONSTRAINT_CHECK));
+                                     EMIT_CONSTRAINT_CHECK,
+                                     IGNORE_WRITEABLE));
 
 
 #ifdef COMPILER1
@@ -260,7 +262,8 @@
                                    EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
                                    EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
                                    IGNORE_RANGE,
-                                   EMIT_CONSTRAINT_CHECK));
+                                   EMIT_CONSTRAINT_CHECK,
+                                   IGNORE_WRITEABLE));
 #endif // COMPILER1
 
 #ifdef COMPILER2
@@ -272,7 +275,8 @@
                                    EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
                                    EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
                                    IGNORE_RANGE,
-                                   EMIT_CONSTRAINT_CHECK));
+                                   EMIT_CONSTRAINT_CHECK,
+                                   IGNORE_WRITEABLE));
 #endif // COMPILER2
 
 #if INCLUDE_ALL_GCS
@@ -286,7 +290,8 @@
                                    EMIT_CONSTRAINT_MANAGEABLE_FLAG,
                                    EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
                                    IGNORE_RANGE,
-                                   EMIT_CONSTRAINT_CHECK));
+                                   EMIT_CONSTRAINT_CHECK,
+                                   IGNORE_WRITEABLE));
 #endif // INCLUDE_ALL_GCS
 }
 
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp	Tue May 10 12:10:21 2016 -0500
@@ -305,7 +305,8 @@
                                    EMIT_RANGE_PRODUCT_RW_FLAG,
                                    EMIT_RANGE_LP64_PRODUCT_FLAG,
                                    EMIT_RANGE_CHECK,
-                                   IGNORE_CONSTRAINT) );
+                                   IGNORE_CONSTRAINT,
+                                   IGNORE_WRITEABLE));
 
   EMIT_RANGES_FOR_GLOBALS_EXT
 
@@ -315,7 +316,8 @@
                                 EMIT_RANGE_EXPERIMENTAL_FLAG,
                                 EMIT_RANGE_NOTPRODUCT_FLAG,
                                 EMIT_RANGE_CHECK,
-                                IGNORE_CONSTRAINT));
+                                IGNORE_CONSTRAINT,
+                                IGNORE_WRITEABLE));
 
 #if INCLUDE_JVMCI
   emit_range_no(NULL JVMCI_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
@@ -326,7 +328,8 @@
                                  EMIT_RANGE_EXPERIMENTAL_FLAG,
                                  EMIT_RANGE_NOTPRODUCT_FLAG,
                                  EMIT_RANGE_CHECK,
-                                 IGNORE_CONSTRAINT));
+                                 IGNORE_CONSTRAINT,
+                                 IGNORE_WRITEABLE));
 #endif // INCLUDE_JVMCI
 
 #ifdef COMPILER1
@@ -337,7 +340,8 @@
                               EMIT_RANGE_DIAGNOSTIC_FLAG,
                               EMIT_RANGE_NOTPRODUCT_FLAG,
                               EMIT_RANGE_CHECK,
-                              IGNORE_CONSTRAINT));
+                              IGNORE_CONSTRAINT,
+                              IGNORE_WRITEABLE));
 #endif // COMPILER1
 
 #ifdef COMPILER2
@@ -349,7 +353,8 @@
                               EMIT_RANGE_EXPERIMENTAL_FLAG,
                               EMIT_RANGE_NOTPRODUCT_FLAG,
                               EMIT_RANGE_CHECK,
-                              IGNORE_CONSTRAINT));
+                              IGNORE_CONSTRAINT,
+                              IGNORE_WRITEABLE));
 #endif // COMPILER2
 
 #if INCLUDE_ALL_GCS
@@ -363,7 +368,8 @@
                               EMIT_RANGE_MANAGEABLE_FLAG,
                               EMIT_RANGE_PRODUCT_RW_FLAG,
                               EMIT_RANGE_CHECK,
-                              IGNORE_CONSTRAINT));
+                              IGNORE_CONSTRAINT,
+                              IGNORE_WRITEABLE));
 #endif // INCLUDE_ALL_GCS
 }
 
--- a/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp	Tue May 10 12:10:21 2016 -0500
@@ -66,7 +66,6 @@
   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);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagWriteableList.cpp	Tue May 10 12:10:21 2016 -0500
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2015, 2016, 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/commandLineFlagWriteableList.hpp"
+#include "runtime/os.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc/cms/concurrentMarkSweepGeneration.inline.hpp"
+#include "gc/g1/g1_globals.hpp"
+#include "gc/g1/heapRegionBounds.inline.hpp"
+#include "gc/shared/plab.hpp"
+#endif // INCLUDE_ALL_GCS
+#ifdef COMPILER1
+#include "c1/c1_globals.hpp"
+#endif // COMPILER1
+#ifdef COMPILER2
+#include "opto/c2_globals.hpp"
+#endif // COMPILER2
+#if INCLUDE_JVMCI
+#include "jvmci/jvmci_globals.hpp"
+#endif
+
+bool CommandLineFlagWriteable::is_writeable(void) {
+  return _writeable;
+}
+
+void CommandLineFlagWriteable::mark_once(void) {
+  if (_type == Once) {
+    _writeable = false;
+  }
+}
+
+void CommandLineFlagWriteable::mark_startup(void) {
+  if (_type == CommandLineFlagWriteable::CommandLineOnly) {
+    _writeable = false;
+  }
+}
+
+// No control emitting
+void emit_writeable_no(...)                         { /* NOP */ }
+
+// No control emitting if type argument is NOT provided
+void emit_writeable_bool(const char* /*name*/)      { /* NOP */ }
+void emit_writeable_ccstr(const char* /*name*/)     { /* NOP */ }
+void emit_writeable_ccstrlist(const char* /*name*/) { /* NOP */ }
+void emit_writeable_int(const char* /*name*/)       { /* NOP */ }
+void emit_writeable_intx(const char* /*name*/)      { /* NOP */ }
+void emit_writeable_uint(const char* /*name*/)      { /* NOP */ }
+void emit_writeable_uintx(const char* /*name*/)     { /* NOP */ }
+void emit_writeable_uint64_t(const char* /*name*/)  { /* NOP */ }
+void emit_writeable_size_t(const char* /*name*/)    { /* NOP */ }
+void emit_writeable_double(const char* /*name*/)    { /* NOP */ }
+
+// CommandLineFlagWriteable emitting code functions if range arguments are provided
+void emit_writeable_bool(const char* name, CommandLineFlagWriteable::WriteableType type) {
+  CommandLineFlagWriteableList::add(new CommandLineFlagWriteable(name, type));
+}
+void emit_writeable_int(const char* name, CommandLineFlagWriteable::WriteableType type) {
+  CommandLineFlagWriteableList::add(new CommandLineFlagWriteable(name, type));
+}
+void emit_writeable_intx(const char* name, CommandLineFlagWriteable::WriteableType type) {
+  CommandLineFlagWriteableList::add(new CommandLineFlagWriteable(name, type));
+}
+void emit_writeable_uint(const char* name, CommandLineFlagWriteable::WriteableType type) {
+  CommandLineFlagWriteableList::add(new CommandLineFlagWriteable(name, type));
+}
+void emit_writeable_uintx(const char* name, CommandLineFlagWriteable::WriteableType type) {
+  CommandLineFlagWriteableList::add(new CommandLineFlagWriteable(name, type));
+}
+void emit_writeable_uint64_t(const char* name, CommandLineFlagWriteable::WriteableType type) {
+  CommandLineFlagWriteableList::add(new CommandLineFlagWriteable(name, type));
+}
+void emit_writeable_size_t(const char* name, CommandLineFlagWriteable::WriteableType type) {
+  CommandLineFlagWriteableList::add(new CommandLineFlagWriteable(name, type));
+}
+void emit_writeable_double(const char* name, CommandLineFlagWriteable::WriteableType type) {
+  CommandLineFlagWriteableList::add(new CommandLineFlagWriteable(name, type));
+}
+
+// Generate code to call emit_writeable_xxx function
+#define EMIT_WRITEABLE_PRODUCT_FLAG(type, name, value, doc)      ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_COMMERCIAL_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_DIAGNOSTIC_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_EXPERIMENTAL_FLAG(type, name, value, doc) ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_MANAGEABLE_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_PRODUCT_RW_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_PD_PRODUCT_FLAG(type, name, doc)          ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_DEVELOPER_FLAG(type, name, value, doc)    ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_PD_DEVELOPER_FLAG(type, name, doc)        ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_NOTPRODUCT_FLAG(type, name, value, doc)   ); emit_writeable_##type(#name
+#define EMIT_WRITEABLE_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_writeable_##type(#name
+
+// Generate type argument to pass into emit_writeable_xxx functions
+#define EMIT_WRITEABLE(a)                                      , CommandLineFlagWriteable::a
+
+#define INITIAL_WRITEABLES_SIZE 2
+GrowableArray<CommandLineFlagWriteable*>* CommandLineFlagWriteableList::_controls = NULL;
+
+void CommandLineFlagWriteableList::init(void) {
+
+  _controls = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<CommandLineFlagWriteable*>(INITIAL_WRITEABLES_SIZE, true);
+
+  emit_writeable_no(NULL RUNTIME_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
+                                   EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
+                                   EMIT_WRITEABLE_PRODUCT_FLAG,
+                                   EMIT_WRITEABLE_PD_PRODUCT_FLAG,
+                                   EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
+                                   EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
+                                   EMIT_WRITEABLE_NOTPRODUCT_FLAG,
+                                   EMIT_WRITEABLE_MANAGEABLE_FLAG,
+                                   EMIT_WRITEABLE_PRODUCT_RW_FLAG,
+                                   EMIT_WRITEABLE_LP64_PRODUCT_FLAG,
+                                   IGNORE_RANGE,
+                                   IGNORE_CONSTRAINT,
+                                   EMIT_WRITEABLE));
+
+  EMIT_WRITEABLES_FOR_GLOBALS_EXT
+
+  emit_writeable_no(NULL ARCH_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
+                                EMIT_WRITEABLE_PRODUCT_FLAG,
+                                EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
+                                EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
+                                EMIT_WRITEABLE_NOTPRODUCT_FLAG,
+                                IGNORE_RANGE,
+                                IGNORE_CONSTRAINT,
+                                EMIT_WRITEABLE));
+
+#if INCLUDE_JVMCI
+  emit_writeable_no(NULL JVMCI_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
+                                 EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
+                                 EMIT_WRITEABLE_PRODUCT_FLAG,
+                                 EMIT_WRITEABLE_PD_PRODUCT_FLAG,
+                                 EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
+                                 EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
+                                 EMIT_WRITEABLE_NOTPRODUCT_FLAG,
+                                 IGNORE_RANGE,
+                                 IGNORE_CONSTRAINT,
+                                 EMIT_WRITEABLE));
+#endif // INCLUDE_JVMCI
+
+#ifdef COMPILER1
+  emit_writeable_no(NULL C1_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
+                              EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
+                              EMIT_WRITEABLE_PRODUCT_FLAG,
+                              EMIT_WRITEABLE_PD_PRODUCT_FLAG,
+                              EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
+                              EMIT_WRITEABLE_NOTPRODUCT_FLAG,
+                              IGNORE_RANGE,
+                              IGNORE_CONSTRAINT,
+                              EMIT_WRITEABLE));
+#endif // COMPILER1
+
+#ifdef COMPILER2
+  emit_writeable_no(NULL C2_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
+                              EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
+                              EMIT_WRITEABLE_PRODUCT_FLAG,
+                              EMIT_WRITEABLE_PD_PRODUCT_FLAG,
+                              EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
+                              EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
+                              EMIT_WRITEABLE_NOTPRODUCT_FLAG,
+                              IGNORE_RANGE,
+                              IGNORE_CONSTRAINT,
+                              EMIT_WRITEABLE));
+#endif // COMPILER2
+
+#if INCLUDE_ALL_GCS
+  emit_writeable_no(NULL G1_FLAGS(EMIT_WRITEABLE_DEVELOPER_FLAG,
+                              EMIT_WRITEABLE_PD_DEVELOPER_FLAG,
+                              EMIT_WRITEABLE_PRODUCT_FLAG,
+                              EMIT_WRITEABLE_PD_PRODUCT_FLAG,
+                              EMIT_WRITEABLE_DIAGNOSTIC_FLAG,
+                              EMIT_WRITEABLE_EXPERIMENTAL_FLAG,
+                              EMIT_WRITEABLE_NOTPRODUCT_FLAG,
+                              EMIT_WRITEABLE_MANAGEABLE_FLAG,
+                              EMIT_WRITEABLE_PRODUCT_RW_FLAG,
+                              IGNORE_RANGE,
+                              IGNORE_CONSTRAINT,
+                              EMIT_WRITEABLE));
+#endif // INCLUDE_ALL_GCS
+}
+
+CommandLineFlagWriteable* CommandLineFlagWriteableList::find(const char* name) {
+  CommandLineFlagWriteable* found = NULL;
+  for (int i=0; i<length(); i++) {
+    CommandLineFlagWriteable* writeable = at(i);
+    if (strcmp(writeable->name(), name) == 0) {
+      found = writeable;
+      break;
+    }
+  }
+  return found;
+}
+
+void CommandLineFlagWriteableList::mark_startup(void) {
+  for (int i=0; i<length(); i++) {
+    CommandLineFlagWriteable* writeable = at(i);
+    writeable->mark_startup();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagWriteableList.hpp	Tue May 10 12:10:21 2016 -0500
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015, 2016, 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_COMMANDLINEFLAGWRITEABLE_HPP
+#define SHARE_VM_RUNTIME_COMMANDLINEFLAGWRITEABLE_HPP
+
+#include "runtime/globals.hpp"
+#include "utilities/growableArray.hpp"
+
+class CommandLineFlagWriteable : public CHeapObj<mtArguments> {
+public:
+  enum WriteableType {
+    // can be set without any limits
+    Always           = 0,
+    // can only be set once, either via command lines or during runtime
+    Once             = 1,
+    // can only be set on command line (multiple times allowed)
+    CommandLineOnly  = 2
+  };
+private:
+  const char* _name;
+  WriteableType _type;
+  bool _writeable;
+  bool _startup_done;
+public:
+  // the "name" argument must be a string literal
+  CommandLineFlagWriteable(const char* name, WriteableType type) { _name=name; _type=type; _writeable=true; _startup_done=false; }
+  ~CommandLineFlagWriteable() {}
+  const char* name() { return _name; }
+  const WriteableType type() { return _type; }
+  bool is_writeable(void);
+  void mark_once(void);
+  void mark_startup(void);
+};
+
+class CommandLineFlagWriteableList : public AllStatic {
+  static GrowableArray<CommandLineFlagWriteable*>* _controls;
+public:
+  static void init();
+  static int length() { return (_controls != NULL) ? _controls->length() : 0; }
+  static CommandLineFlagWriteable* at(int i) { return (_controls != NULL) ? _controls->at(i) : NULL; }
+  static CommandLineFlagWriteable* find(const char* name);
+  static void add(CommandLineFlagWriteable* range) { _controls->append(range); }
+  static void mark_startup(void);
+};
+
+#endif // SHARE_VM_RUNTIME_COMMANDLINEFLAGWRITEABLE_HPP
--- a/hotspot/src/share/vm/runtime/globals.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Tue May 10 12:10:21 2016 -0500
@@ -29,10 +29,12 @@
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
 #include "runtime/commandLineFlagConstraintList.hpp"
+#include "runtime/commandLineFlagWriteableList.hpp"
 #include "runtime/commandLineFlagRangeList.hpp"
 #include "runtime/os.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "trace/tracing.hpp"
+#include "utilities/defaultStream.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
 #if INCLUDE_ALL_GCS
@@ -62,7 +64,8 @@
               MATERIALIZE_PRODUCT_RW_FLAG, \
               MATERIALIZE_LP64_PRODUCT_FLAG, \
               IGNORE_RANGE, \
-              IGNORE_CONSTRAINT)
+              IGNORE_CONSTRAINT, \
+              IGNORE_WRITEABLE)
 
 RUNTIME_OS_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
                  MATERIALIZE_PD_DEVELOPER_FLAG, \
@@ -71,7 +74,8 @@
                  MATERIALIZE_DIAGNOSTIC_FLAG, \
                  MATERIALIZE_NOTPRODUCT_FLAG, \
                  IGNORE_RANGE, \
-                 IGNORE_CONSTRAINT)
+                 IGNORE_CONSTRAINT, \
+                 IGNORE_WRITEABLE)
 
 ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
            MATERIALIZE_PRODUCT_FLAG, \
@@ -79,7 +83,8 @@
            MATERIALIZE_EXPERIMENTAL_FLAG, \
            MATERIALIZE_NOTPRODUCT_FLAG, \
            IGNORE_RANGE, \
-           IGNORE_CONSTRAINT)
+           IGNORE_CONSTRAINT, \
+           IGNORE_WRITEABLE)
 
 MATERIALIZE_FLAGS_EXT
 
@@ -141,10 +146,35 @@
 #endif
 }
 
-void Flag::check_writable() {
+Flag::Error Flag::check_writable(bool changed) {
   if (is_constant_in_binary()) {
     fatal("flag is constant: %s", _name);
   }
+
+  Flag::Error error = Flag::SUCCESS;
+  if (changed) {
+    CommandLineFlagWriteable* writeable = CommandLineFlagWriteableList::find(_name);
+    if (writeable) {
+      if (writeable->is_writeable() == false) {
+        switch (writeable->type())
+        {
+          case CommandLineFlagWriteable::Once:
+            error = Flag::SET_ONLY_ONCE;
+            jio_fprintf(defaultStream::error_stream(), "Error: %s may not be set more than once\n", _name);
+            break;
+          case CommandLineFlagWriteable::CommandLineOnly:
+            error = Flag::COMMAND_LINE_ONLY;
+            jio_fprintf(defaultStream::error_stream(), "Error: %s may be modified only from commad line\n", _name);
+            break;
+          default:
+            ShouldNotReachHere();
+            break;
+        }
+      }
+      writeable->mark_once();
+    }
+  }
+  return error;
 }
 
 bool Flag::is_bool() const {
@@ -155,9 +185,12 @@
   return *((bool*) _addr);
 }
 
-void Flag::set_bool(bool value) {
-  check_writable();
-  *((bool*) _addr) = value;
+Flag::Error Flag::set_bool(bool value) {
+  Flag::Error error = check_writable(value!=get_bool());
+  if (error == Flag::SUCCESS) {
+    *((bool*) _addr) = value;
+  }
+  return error;
 }
 
 bool Flag::is_int() const {
@@ -168,9 +201,12 @@
   return *((int*) _addr);
 }
 
-void Flag::set_int(int value) {
-  check_writable();
-  *((int*) _addr) = value;
+Flag::Error Flag::set_int(int value) {
+  Flag::Error error = check_writable(value!=get_int());
+  if (error == Flag::SUCCESS) {
+    *((int*) _addr) = value;
+  }
+  return error;
 }
 
 bool Flag::is_uint() const {
@@ -181,9 +217,12 @@
   return *((uint*) _addr);
 }
 
-void Flag::set_uint(uint value) {
-  check_writable();
-  *((uint*) _addr) = value;
+Flag::Error Flag::set_uint(uint value) {
+  Flag::Error error = check_writable(value!=get_uint());
+  if (error == Flag::SUCCESS) {
+    *((uint*) _addr) = value;
+  }
+  return error;
 }
 
 bool Flag::is_intx() const {
@@ -194,9 +233,12 @@
   return *((intx*) _addr);
 }
 
-void Flag::set_intx(intx value) {
-  check_writable();
-  *((intx*) _addr) = value;
+Flag::Error Flag::set_intx(intx value) {
+  Flag::Error error = check_writable(value!=get_intx());
+  if (error == Flag::SUCCESS) {
+    *((intx*) _addr) = value;
+  }
+  return error;
 }
 
 bool Flag::is_uintx() const {
@@ -207,9 +249,12 @@
   return *((uintx*) _addr);
 }
 
-void Flag::set_uintx(uintx value) {
-  check_writable();
-  *((uintx*) _addr) = value;
+Flag::Error Flag::set_uintx(uintx value) {
+  Flag::Error error = check_writable(value!=get_uintx());
+  if (error == Flag::SUCCESS) {
+    *((uintx*) _addr) = value;
+  }
+  return error;
 }
 
 bool Flag::is_uint64_t() const {
@@ -220,9 +265,12 @@
   return *((uint64_t*) _addr);
 }
 
-void Flag::set_uint64_t(uint64_t value) {
-  check_writable();
-  *((uint64_t*) _addr) = value;
+Flag::Error Flag::set_uint64_t(uint64_t value) {
+  Flag::Error error = check_writable(value!=get_uint64_t());
+  if (error == Flag::SUCCESS) {
+    *((uint64_t*) _addr) = value;
+  }
+  return error;
 }
 
 bool Flag::is_size_t() const {
@@ -233,9 +281,12 @@
   return *((size_t*) _addr);
 }
 
-void Flag::set_size_t(size_t value) {
-  check_writable();
-  *((size_t*) _addr) = value;
+Flag::Error Flag::set_size_t(size_t value) {
+  Flag::Error error = check_writable(value!=get_size_t());
+  if (error == Flag::SUCCESS) {
+    *((size_t*) _addr) = value;
+  }
+  return error;
 }
 
 bool Flag::is_double() const {
@@ -246,9 +297,12 @@
   return *((double*) _addr);
 }
 
-void Flag::set_double(double value) {
-  check_writable();
-  *((double*) _addr) = value;
+Flag::Error Flag::set_double(double value) {
+  Flag::Error error = check_writable(value!=get_double());
+  if (error == Flag::SUCCESS) {
+    *((double*) _addr) = value;
+  }
+  return error;
 }
 
 bool Flag::is_ccstr() const {
@@ -263,9 +317,12 @@
   return *((ccstr*) _addr);
 }
 
-void Flag::set_ccstr(ccstr value) {
-  check_writable();
-  *((ccstr*) _addr) = value;
+Flag::Error Flag::set_ccstr(ccstr value) {
+  Flag::Error error = check_writable(value!=get_ccstr());
+  if (error == Flag::SUCCESS) {
+    *((ccstr*) _addr) = value;
+  }
+  return error;
 }
 
 
@@ -654,7 +711,8 @@
                RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
                RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \
                IGNORE_RANGE, \
-               IGNORE_CONSTRAINT)
+               IGNORE_CONSTRAINT, \
+               IGNORE_WRITEABLE)
  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
                   RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
                   RUNTIME_PRODUCT_FLAG_STRUCT, \
@@ -662,7 +720,8 @@
                   RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
                   RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
                   IGNORE_RANGE, \
-                  IGNORE_CONSTRAINT)
+                  IGNORE_CONSTRAINT, \
+                  IGNORE_WRITEABLE)
 #if INCLUDE_ALL_GCS
  G1_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
           RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
@@ -674,7 +733,8 @@
           RUNTIME_MANAGEABLE_FLAG_STRUCT, \
           RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
           IGNORE_RANGE, \
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT, \
+          IGNORE_WRITEABLE)
 #endif // INCLUDE_ALL_GCS
 #if INCLUDE_JVMCI
  JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, \
@@ -685,7 +745,8 @@
              JVMCI_EXPERIMENTAL_FLAG_STRUCT, \
              JVMCI_NOTPRODUCT_FLAG_STRUCT, \
              IGNORE_RANGE, \
-             IGNORE_CONSTRAINT)
+             IGNORE_CONSTRAINT, \
+             IGNORE_WRITEABLE)
 #endif // INCLUDE_JVMCI
 #ifdef COMPILER1
  C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \
@@ -695,7 +756,8 @@
           C1_DIAGNOSTIC_FLAG_STRUCT, \
           C1_NOTPRODUCT_FLAG_STRUCT, \
           IGNORE_RANGE, \
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT, \
+          IGNORE_WRITEABLE)
 #endif // COMPILER1
 #ifdef COMPILER2
  C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \
@@ -706,7 +768,8 @@
           C2_EXPERIMENTAL_FLAG_STRUCT, \
           C2_NOTPRODUCT_FLAG_STRUCT, \
           IGNORE_RANGE, \
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT, \
+          IGNORE_WRITEABLE)
 #endif // COMPILER2
 #ifdef SHARK
  SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, \
@@ -714,7 +777,10 @@
              SHARK_PRODUCT_FLAG_STRUCT, \
              SHARK_PD_PRODUCT_FLAG_STRUCT, \
              SHARK_DIAGNOSTIC_FLAG_STRUCT, \
-             SHARK_NOTPRODUCT_FLAG_STRUCT)
+             SHARK_NOTPRODUCT_FLAG_STRUCT, \
+             IGNORE_RANGE, \
+             IGNORE_CONSTRAINT, \
+             IGNORE_WRITEABLE)
 #endif // SHARK
  ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \
             ARCH_PRODUCT_FLAG_STRUCT, \
@@ -722,7 +788,8 @@
             ARCH_EXPERIMENTAL_FLAG_STRUCT, \
             ARCH_NOTPRODUCT_FLAG_STRUCT, \
             IGNORE_RANGE, \
-            IGNORE_CONSTRAINT)
+            IGNORE_CONSTRAINT, \
+            IGNORE_WRITEABLE)
  FLAGTABLE_EXT
  {0, NULL, NULL}
 };
@@ -873,10 +940,10 @@
   if (check != Flag::SUCCESS) return check;
   bool old_value = flag->get_bool();
   trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
-  flag->set_bool(*value);
+  check = flag->set_bool(*value);
   *value = old_value;
   flag->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlags::boolAtPut(const char* name, size_t len, bool* value, Flag::Flags origin) {
@@ -922,10 +989,10 @@
   if (check != Flag::SUCCESS) return check;
   int old_value = flag->get_int();
   trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
-  flag->set_int(*value);
+  check = flag->set_int(*value);
   *value = old_value;
   flag->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlags::intAtPut(const char* name, size_t len, int* value, Flag::Flags origin) {
@@ -971,10 +1038,10 @@
   if (check != Flag::SUCCESS) return check;
   uint old_value = flag->get_uint();
   trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
-  flag->set_uint(*value);
+  check = flag->set_uint(*value);
   *value = old_value;
   flag->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlags::uintAtPut(const char* name, size_t len, uint* value, Flag::Flags origin) {
@@ -1020,10 +1087,10 @@
   if (check != Flag::SUCCESS) return check;
   intx old_value = flag->get_intx();
   trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
-  flag->set_intx(*value);
+  check = flag->set_intx(*value);
   *value = old_value;
   flag->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlags::intxAtPut(const char* name, size_t len, intx* value, Flag::Flags origin) {
@@ -1069,10 +1136,10 @@
   if (check != Flag::SUCCESS) return check;
   uintx old_value = flag->get_uintx();
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
-  flag->set_uintx(*value);
+  check = flag->set_uintx(*value);
   *value = old_value;
   flag->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlags::uintxAtPut(const char* name, size_t len, uintx* value, Flag::Flags origin) {
@@ -1118,10 +1185,10 @@
   if (check != Flag::SUCCESS) return check;
   uint64_t old_value = flag->get_uint64_t();
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
-  flag->set_uint64_t(*value);
+  check = flag->set_uint64_t(*value);
   *value = old_value;
   flag->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlags::uint64_tAtPut(const char* name, size_t len, uint64_t* value, Flag::Flags origin) {
@@ -1168,10 +1235,10 @@
   if (check != Flag::SUCCESS) return check;
   size_t old_value = flag->get_size_t();
   trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
-  flag->set_size_t(*value);
+  check = flag->set_size_t(*value);
   *value = old_value;
   flag->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlags::size_tAtPut(const char* name, size_t len, size_t* value, Flag::Flags origin) {
@@ -1217,10 +1284,10 @@
   if (check != Flag::SUCCESS) return check;
   double old_value = flag->get_double();
   trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
-  flag->set_double(*value);
+  check = flag->set_double(*value);
   *value = old_value;
   flag->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlags::doubleAtPut(const char* name, size_t len, double* value, Flag::Flags origin) {
@@ -1252,14 +1319,14 @@
   if (*value != NULL) {
     new_value = os::strdup_check_oom(*value);
   }
-  result->set_ccstr(new_value);
+  Flag::Error check = result->set_ccstr(new_value);
   if (result->is_default() && old_value != NULL) {
     // Prior value is NOT heap allocated, but was a literal constant.
     old_value = os::strdup_check_oom(old_value);
   }
   *value = old_value;
   result->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 Flag::Error CommandLineFlagsEx::ccstrAtPut(CommandLineFlagWithType flag, ccstr value, Flag::Flags origin) {
@@ -1268,13 +1335,13 @@
   ccstr old_value = faddr->get_ccstr();
   trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
   char* new_value = os::strdup_check_oom(value);
-  faddr->set_ccstr(new_value);
+  Flag::Error check = faddr->set_ccstr(new_value);
   if (!faddr->is_default() && old_value != NULL) {
     // Prior value is heap allocated so free it.
     FREE_C_HEAP_ARRAY(char, old_value);
   }
   faddr->set_origin(origin);
-  return Flag::SUCCESS;
+  return check;
 }
 
 extern "C" {
--- a/hotspot/src/share/vm/runtime/globals.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Tue May 10 12:10:21 2016 -0500
@@ -280,6 +280,12 @@
     VIOLATES_CONSTRAINT,
     // there is no flag with the given name
     INVALID_FLAG,
+    // the flag can only be set only on command line during invocation of the VM
+    COMMAND_LINE_ONLY,
+    // the flag may only be set once
+    SET_ONLY_ONCE,
+    // the flag is not writable in this combination of product/debug build
+    CONSTANT,
     // other, unspecified error related to setting the flag
     ERR_OTHER
   };
@@ -316,44 +322,44 @@
   static const char* get_size_t_default_range_str();
   static const char* get_double_default_range_str();
 
-  void check_writable();
+  Flag::Error check_writable(bool changed);
 
   bool is_bool() const;
   bool get_bool() const;
-  void set_bool(bool value);
+  Flag::Error set_bool(bool value);
 
   bool is_int() const;
   int get_int() const;
-  void set_int(int value);
+  Flag::Error set_int(int value);
 
   bool is_uint() const;
   uint get_uint() const;
-  void set_uint(uint value);
+  Flag::Error set_uint(uint value);
 
   bool is_intx() const;
   intx get_intx() const;
-  void set_intx(intx value);
+  Flag::Error set_intx(intx value);
 
   bool is_uintx() const;
   uintx get_uintx() const;
-  void set_uintx(uintx value);
+  Flag::Error set_uintx(uintx value);
 
   bool is_uint64_t() const;
   uint64_t get_uint64_t() const;
-  void set_uint64_t(uint64_t value);
+  Flag::Error set_uint64_t(uint64_t value);
 
   bool is_size_t() const;
   size_t get_size_t() const;
-  void set_size_t(size_t value);
+  Flag::Error set_size_t(size_t value);
 
   bool is_double() const;
   double get_double() const;
-  void set_double(double value);
+  Flag::Error set_double(double value);
 
   bool is_ccstr() const;
   bool ccstr_accumulates() const;
   ccstr get_ccstr() const;
-  void set_ccstr(ccstr value);
+  Flag::Error set_ccstr(ccstr value);
 
   Flags get_origin();
   void set_origin(Flags origin);
@@ -621,8 +627,31 @@
 // constraint is a macro that will expand to custom function call
 //    for constraint checking if provided - see commandLineFlagConstraintList.hpp
 //
+// writeable is a macro that controls if and how the value can change during the runtime
+//
+// writeable(Always) is optional and allows the flag to have its value changed
+//    without any limitations at any time
+//
+// writeable(Once) flag value's can be only set once during the lifetime of VM
+//
+// writeable(CommandLineOnly) flag value's can be only set from command line
+//    (multiple times allowed)
+//
 
-#define RUNTIME_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw, lp64_product, range, constraint) \
+
+#define RUNTIME_FLAGS(develop, \
+                      develop_pd, \
+                      product, \
+                      product_pd, \
+                      diagnostic, \
+                      experimental, \
+                      notproduct, \
+                      manageable, \
+                      product_rw, \
+                      lp64_product, \
+                      range, \
+                      constraint, \
+                      writeable) \
                                                                             \
   lp64_product(bool, UseCompressedOops, false,                              \
           "Use 32-bit object references in 64-bit VM. "                     \
@@ -4185,6 +4214,8 @@
 // Only materialize src code for contraint checking when required, ignore otherwise
 #define IGNORE_CONSTRAINT(func,type)
 
+#define IGNORE_WRITEABLE(type)
+
 RUNTIME_FLAGS(DECLARE_DEVELOPER_FLAG, \
               DECLARE_PD_DEVELOPER_FLAG, \
               DECLARE_PRODUCT_FLAG, \
@@ -4196,7 +4227,8 @@
               DECLARE_PRODUCT_RW_FLAG, \
               DECLARE_LP64_PRODUCT_FLAG, \
               IGNORE_RANGE, \
-              IGNORE_CONSTRAINT)
+              IGNORE_CONSTRAINT, \
+              IGNORE_WRITEABLE)
 
 RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, \
                  DECLARE_PD_DEVELOPER_FLAG, \
@@ -4205,7 +4237,8 @@
                  DECLARE_DIAGNOSTIC_FLAG, \
                  DECLARE_NOTPRODUCT_FLAG, \
                  IGNORE_RANGE, \
-                 IGNORE_CONSTRAINT)
+                 IGNORE_CONSTRAINT, \
+                 IGNORE_WRITEABLE)
 
 ARCH_FLAGS(DECLARE_DEVELOPER_FLAG, \
            DECLARE_PRODUCT_FLAG, \
@@ -4213,7 +4246,8 @@
            DECLARE_EXPERIMENTAL_FLAG, \
            DECLARE_NOTPRODUCT_FLAG, \
            IGNORE_RANGE, \
-           IGNORE_CONSTRAINT)
+           IGNORE_CONSTRAINT, \
+           IGNORE_WRITEABLE)
 
 // Extensions
 
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp	Tue May 10 12:10:21 2016 -0500
@@ -103,7 +103,8 @@
                RUNTIME_PRODUCT_RW_FLAG_MEMBER, \
                RUNTIME_LP64_PRODUCT_FLAG_MEMBER, \
                IGNORE_RANGE, \
-               IGNORE_CONSTRAINT)
+               IGNORE_CONSTRAINT, \
+               IGNORE_WRITEABLE)
  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, \
                   RUNTIME_PD_DEVELOP_FLAG_MEMBER, \
                   RUNTIME_PRODUCT_FLAG_MEMBER, \
@@ -111,7 +112,8 @@
                   RUNTIME_DIAGNOSTIC_FLAG_MEMBER, \
                   RUNTIME_NOTPRODUCT_FLAG_MEMBER, \
                   IGNORE_RANGE, \
-                  IGNORE_CONSTRAINT)
+                  IGNORE_CONSTRAINT, \
+                  IGNORE_WRITEABLE)
 #if INCLUDE_ALL_GCS
  G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, \
           RUNTIME_PD_DEVELOP_FLAG_MEMBER, \
@@ -123,7 +125,8 @@
           RUNTIME_MANAGEABLE_FLAG_MEMBER, \
           RUNTIME_PRODUCT_RW_FLAG_MEMBER, \
           IGNORE_RANGE, \
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT, \
+          IGNORE_WRITEABLE)
 #endif // INCLUDE_ALL_GCS
 #if INCLUDE_JVMCI
  JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_MEMBER, \
@@ -134,7 +137,8 @@
              JVMCI_EXPERIMENTAL_FLAG_MEMBER, \
              JVMCI_NOTPRODUCT_FLAG_MEMBER, \
              IGNORE_RANGE, \
-             IGNORE_CONSTRAINT)
+             IGNORE_CONSTRAINT, \
+             IGNORE_WRITEABLE)
 #endif // INCLUDE_JVMCI
 #ifdef COMPILER1
  C1_FLAGS(C1_DEVELOP_FLAG_MEMBER, \
@@ -144,7 +148,8 @@
           C1_DIAGNOSTIC_FLAG_MEMBER, \
           C1_NOTPRODUCT_FLAG_MEMBER, \
           IGNORE_RANGE, \
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT, \
+          IGNORE_WRITEABLE)
 #endif
 #ifdef COMPILER2
  C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, \
@@ -155,7 +160,8 @@
           C2_EXPERIMENTAL_FLAG_MEMBER, \
           C2_NOTPRODUCT_FLAG_MEMBER, \
           IGNORE_RANGE, \
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT, \
+          IGNORE_WRITEABLE)
 #endif
  ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER, \
             ARCH_PRODUCT_FLAG_MEMBER, \
@@ -163,7 +169,8 @@
             ARCH_EXPERIMENTAL_FLAG_MEMBER, \
             ARCH_NOTPRODUCT_FLAG_MEMBER, \
             IGNORE_RANGE, \
-            IGNORE_CONSTRAINT)
+            IGNORE_CONSTRAINT, \
+            IGNORE_WRITEABLE)
  COMMANDLINEFLAG_EXT
  NUM_CommandLineFlag
 } CommandLineFlag;
@@ -229,7 +236,8 @@
                RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE,
                RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE,
                IGNORE_RANGE,
-               IGNORE_CONSTRAINT)
+               IGNORE_CONSTRAINT,
+               IGNORE_WRITEABLE)
  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
                   RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
                   RUNTIME_PRODUCT_FLAG_MEMBER_WITH_TYPE,
@@ -237,7 +245,8 @@
                   RUNTIME_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
                   RUNTIME_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
                   IGNORE_RANGE,
-                  IGNORE_CONSTRAINT)
+                  IGNORE_CONSTRAINT,
+                  IGNORE_WRITEABLE)
 #if INCLUDE_ALL_GCS
  G1_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
           RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -249,7 +258,8 @@
           RUNTIME_MANAGEABLE_FLAG_MEMBER_WITH_TYPE,
           RUNTIME_PRODUCT_RW_FLAG_MEMBER_WITH_TYPE,
           IGNORE_RANGE,
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT,
+          IGNORE_WRITEABLE)
 #endif // INCLUDE_ALL_GCS
 #if INCLUDE_JVMCI
  JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -260,7 +270,8 @@
              JVMCI_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
              JVMCI_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
              IGNORE_RANGE,
-             IGNORE_CONSTRAINT)
+             IGNORE_CONSTRAINT,
+             IGNORE_WRITEABLE)
 #endif // INCLUDE_JVMCI
 #ifdef COMPILER1
  C1_FLAGS(C1_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -270,7 +281,8 @@
           C1_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
           C1_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
           IGNORE_RANGE,
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT,
+          IGNORE_WRITEABLE)
 #endif
 #ifdef COMPILER2
  C2_FLAGS(C2_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -281,7 +293,8 @@
           C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
           C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
           IGNORE_RANGE,
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT,
+          IGNORE_WRITEABLE)
 #endif
  ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE,
           ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE,
@@ -289,7 +302,8 @@
           ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
           ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE,
           IGNORE_RANGE,
-          IGNORE_CONSTRAINT)
+          IGNORE_CONSTRAINT,
+          IGNORE_WRITEABLE)
  COMMANDLINEFLAGWITHTYPE_EXT
  NUM_CommandLineFlagWithType
 } CommandLineFlagWithType;
--- a/hotspot/src/share/vm/runtime/os_ext.hpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/os_ext.hpp	Tue May 10 12:10:21 2016 -0500
@@ -27,6 +27,7 @@
 
 #define EMIT_RANGES_FOR_GLOBALS_EXT // NOP
 #define EMIT_CONSTRAINTS_FOR_GLOBALS_EXT // NOP
+#define EMIT_WRITEABLES_FOR_GLOBALS_EXT // NOP
 
 public:
   static void init_globals_ext() {} // Run from init_globals().
--- a/hotspot/src/share/vm/runtime/thread.cpp	Tue May 10 14:26:31 2016 +0000
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Tue May 10 12:10:21 2016 -0500
@@ -60,6 +60,7 @@
 #include "runtime/atomic.inline.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/commandLineFlagConstraintList.hpp"
+#include "runtime/commandLineFlagWriteableList.hpp"
 #include "runtime/commandLineFlagRangeList.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/fprofiler.hpp"
@@ -3544,6 +3545,8 @@
     return JNI_EINVAL;
   }
 
+  CommandLineFlagWriteableList::mark_startup();
+
   if (PauseAtStartup) {
     os::pause();
   }