--- a/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp Tue May 10 21:38:44 2016 +0000
+++ b/hotspot/src/cpu/aarch64/vm/globals_aarch64.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/cpu/ppc/vm/globals_ppc.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/os/aix/vm/globals_aix.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/os/bsd/vm/globals_bsd.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/os/linux/vm/globals_linux.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/os/solaris/vm/globals_solaris.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/os/windows/vm/globals_windows.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_globals.cpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.cpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/gc/g1/g1_globals.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.cpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/jvmci/jvmci_globals.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/opto/c2_globals.cpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagConstraintList.cpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.cpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/commandLineFlagRangeList.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 Wed May 11 00:40:59 2016 +0000
@@ -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 Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/globals.cpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/os_ext.hpp Wed May 11 00:40:59 2016 +0000
@@ -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 21:38:44 2016 +0000
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed May 11 00:40:59 2016 +0000
@@ -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();
}
--- a/hotspot/test/TEST.groups Tue May 10 21:38:44 2016 +0000
+++ b/hotspot/test/TEST.groups Wed May 11 00:40:59 2016 +0000
@@ -338,6 +338,7 @@
sanity/ExecuteInternalVMTests.java \
gc/ \
-gc/g1/ \
+ -gc/logging/TestUnifiedLoggingSwitchStress.java \
-gc/stress \
-gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java \
-gc/cms/TestMBeanCMS.java \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/logging/TestUnifiedLoggingSwitchStress.java Wed May 11 00:40:59 2016 +0000
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 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.
+ *
+ */
+
+package gc.logging;
+
+import jdk.test.lib.Utils;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import java.lang.management.ManagementFactory;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+
+
+/**
+ * @test TestUnifiedLoggingSwitchStress
+ * @summary Switches gc log level on fly while stressing memory/gc
+ * @key gc
+ * @key stress
+ * @library /testlibrary /test/lib /
+ * @modules java.management java.base/jdk.internal.misc
+ *
+ * @run main/othervm -Xmx256M -Xms256M
+ * gc.logging.TestUnifiedLoggingSwitchStress 60
+ */
+
+class MemoryStresser implements Runnable {
+ public static volatile boolean shouldStop = false;
+
+ private final List<byte[]> liveObjects = new LinkedList<>();
+ private final List<byte[]> liveHObjects = new LinkedList<>();
+ private int maxSimpleAllocationMemory = 0;
+ private int usedMemory = 0;
+
+ /**
+ * Maximum amount of huge allocations
+ */
+ private static int H_ALLOCATION_MAX_COUNT = 4;
+ /**
+ * Maximum regions in one huge allocation
+ */
+ private static int H_ALLOCATION_REGION_SIZE = 2;
+ private static final int G1_REGION_SIZE = 1024 * 1024;
+ /**
+ * Maximum size of simple allocation
+ */
+ private static final int MAX_SIMPLE_ALLOCATION_SIZE = (int) (G1_REGION_SIZE / 2 * 0.9);
+
+ /**
+ * Maximum size of dead (i.e. one which is made unreachable right after allocation) object
+ */
+ private static final int DEAD_OBJECT_MAX_SIZE = G1_REGION_SIZE / 10;
+ private static final Random RND = Utils.getRandomInstance();
+
+ /**
+ * @param maxMemory maximum memory that could be allocated
+ */
+ public MemoryStresser(int maxMemory) {
+ maxSimpleAllocationMemory = maxMemory - G1_REGION_SIZE * H_ALLOCATION_MAX_COUNT * H_ALLOCATION_REGION_SIZE;
+ }
+
+ public final Runnable[] actions = new Runnable[]{
+ // Huge allocation
+ () -> {
+ if (liveHObjects.size() < H_ALLOCATION_MAX_COUNT) {
+ int allocationSize = RND.nextInt((int) (G1_REGION_SIZE * (H_ALLOCATION_REGION_SIZE - 0.5)
+ * 0.9));
+ liveHObjects.add(new byte[allocationSize + G1_REGION_SIZE / 2]);
+ }
+ },
+
+ // Huge deallocation
+ () -> {
+ if (liveHObjects.size() > 0) {
+ int elementNum = RND.nextInt(liveHObjects.size());
+ liveHObjects.remove(elementNum);
+ }
+ },
+
+ // Simple allocation
+ () -> {
+ if (maxSimpleAllocationMemory - usedMemory != 0) {
+ int arraySize = RND.nextInt(Math.min(maxSimpleAllocationMemory - usedMemory,
+ MAX_SIMPLE_ALLOCATION_SIZE));
+ if (arraySize != 0) {
+ liveObjects.add(new byte[arraySize]);
+ usedMemory += arraySize;
+ }
+ }
+ },
+
+ // Simple deallocation
+ () -> {
+ if (liveObjects.size() != 0) {
+ int elementNum = RND.nextInt(liveObjects.size());
+ int shouldFree = liveObjects.get(elementNum).length;
+ liveObjects.remove(elementNum);
+ usedMemory -= shouldFree;
+ }
+ },
+
+ // Dead object allocation
+ () -> {
+ int size = RND.nextInt(DEAD_OBJECT_MAX_SIZE);
+ byte[] deadObject = new byte[size];
+ }
+ };
+
+ @Override
+ public void run() {
+ while (!shouldStop) {
+ actions[RND.nextInt(actions.length)].run();
+ Thread.yield();
+ }
+
+ System.out.println("Memory Stresser finished");
+ }
+}
+
+class LogLevelSwitcher implements Runnable {
+
+ public static volatile boolean shouldStop = false;
+ private final int logCount; // how many various log files will be used
+ private final String logFilePrefix; // name of log file will be logFilePrefix + index
+ private final Random RND = Utils.getRandomInstance();
+ private final MBeanServer MBS = ManagementFactory.getPlatformMBeanServer();
+
+ /**
+ * @param logFilePrefix prefix for log files
+ * @param logCount amount of log files
+ */
+ public LogLevelSwitcher(String logFilePrefix, int logCount) {
+ this.logCount = logCount;
+ this.logFilePrefix = logFilePrefix;
+
+ }
+
+ private static final String[] LOG_LEVELS = {"error", "warning", "info", "debug", "trace"};
+
+ @Override
+ public void run() {
+
+ while (!shouldStop) {
+ int fileNum = RND.nextInt(logCount);
+ int logLevel = RND.nextInt(LOG_LEVELS.length);
+
+ String outputCommand = String.format("output=%s_%d.log", logFilePrefix, fileNum);
+ String logLevelCommand = "what='gc*=" + LOG_LEVELS[logLevel] + "'";
+
+ try {
+ Object out = MBS.invoke(new ObjectName("com.sun.management:type=DiagnosticCommand"),
+ "vmLog",
+ new Object[]{new String[]{outputCommand, logLevelCommand}},
+ new String[]{String[].class.getName()});
+
+ if (!out.toString().isEmpty()) {
+ System.out.format("WARNING: Diagnostic command vmLog with arguments %s,%s returned not empty"
+ + " output %s\n",
+ outputCommand, logLevelCommand, out);
+ }
+ } catch (InstanceNotFoundException | MBeanException | ReflectionException | MalformedObjectNameException e) {
+ System.out.println("Got exception trying to change log level:" + e);
+ e.printStackTrace();
+ throw new Error(e);
+ }
+ Thread.yield();
+ }
+ System.out.println("Log Switcher finished");
+ }
+}
+
+
+public class TestUnifiedLoggingSwitchStress {
+ /**
+ * Count of memory stressing threads
+ */
+ private static final int MEMORY_STRESSERS_COUNT = 3;
+ /**
+ * Count of log switching threads
+ */
+ private static final int LOG_LEVEL_SWITCHERS_COUNT = 2;
+ /**
+ * Count of log files created by each log switching thread
+ */
+ private static final int LOG_FILES_COUNT = 2;
+ /**
+ * Maximum amount memory allocated by each stressing thread
+ */
+ private static final int MAX_MEMORY_PER_STRESSER = (int) (Runtime.getRuntime().freeMemory()
+ / MEMORY_STRESSERS_COUNT * 0.7);
+
+ public static void main(String[] args) throws InterruptedException {
+ if (args.length != 1) {
+ throw new Error("Test Bug: Expected duration (in seconds) wasn't provided as command line argument");
+ }
+ long duration = Integer.parseInt(args[0]) * 1000;
+
+ long startTime = System.currentTimeMillis();
+
+ List<Thread> threads = new LinkedList<>();
+
+ for (int i = 0; i < LOG_LEVEL_SWITCHERS_COUNT; i++) {
+ threads.add(new Thread(new LogLevelSwitcher("Output_" + i, LOG_FILES_COUNT)));
+ }
+
+ for (int i = 0; i < MEMORY_STRESSERS_COUNT; i++) {
+ threads.add(new Thread(new MemoryStresser(MAX_MEMORY_PER_STRESSER)));
+ }
+
+ threads.stream().forEach(Thread::start);
+
+ while (System.currentTimeMillis() - startTime < duration) {
+ Thread.yield();
+ }
+
+ MemoryStresser.shouldStop = true;
+ LogLevelSwitcher.shouldStop = true;
+ }
+}