--- old/src/share/vm/gc/g1/g1_globals.hpp 2015-07-20 12:40:10.703901337 -0700 +++ new/src/share/vm/gc/g1/g1_globals.hpp 2015-07-20 12:40:10.467901329 -0700 @@ -252,12 +252,12 @@ "Percentage (0-100) of the heap size to use as default " \ " maximum young gen size.") \ range(0, 100) \ - constraint(G1MaxNewSizePercentConstraintFunc) \ + constraint(G1MaxNewSizePercentConstraintFunc,AfterErgo) \ \ experimental(uintx, G1NewSizePercent, 5, \ "Percentage (0-100) of the heap size to use as default " \ "minimum young gen size.") \ - constraint(G1NewSizePercentConstraintFunc) \ + constraint(G1NewSizePercentConstraintFunc,AfterErgo) \ \ experimental(uintx, G1MixedGCLiveThresholdPercent, 85, \ "Threshold for regions to be considered for inclusion in the " \ --- old/src/share/vm/memory/universe.cpp 2015-07-20 12:40:12.063901381 -0700 +++ new/src/share/vm/memory/universe.cpp 2015-07-20 12:40:11.867901375 -0700 @@ -656,6 +656,11 @@ Metaspace::global_initialize(); + // Checks 'AfterMemoryInit' constraints. + if (!CommandLineFlags::check_constraints_of_after_memory_init()) { + return JNI_EINVAL; + } + // Create memory for metadata. Must be after initializing heap for // DumpSharedSpaces. ClassLoaderData::init_null_class_loader_data(); --- old/src/share/vm/opto/c2_globals.hpp 2015-07-20 12:40:13.263901421 -0700 +++ new/src/share/vm/opto/c2_globals.hpp 2015-07-20 12:40:13.071901414 -0700 @@ -659,7 +659,7 @@ "0 for no aliasing, 1 for oop/field/static/array split, " \ "2 for class split, 3 for unique instances") \ range(0, 3) \ - constraint(AliasLevelConstraintFunc) \ + constraint(AliasLevelConstraintFunc,AfterErgo) \ \ develop(bool, VerifyAliases, false, \ "perform extra checks on the results of alias analysis") \ --- old/src/share/vm/runtime/arguments.cpp 2015-07-20 12:40:14.683901467 -0700 +++ new/src/share/vm/runtime/arguments.cpp 2015-07-20 12:40:14.339901456 -0700 @@ -3913,10 +3913,10 @@ return JNI_OK; } -// Any custom code post the final range and constraint check +// Any custom code post the 'CommandLineFlagConstraint::AfterErgo' constraint check // can be done here. We pass a flag that specifies whether // the check passed successfully -void Arguments::post_final_range_and_constraint_check(bool check_passed) { +void Arguments::post_after_ergo_constraint_check(bool check_passed) { // This does not set the flag itself, but stores the value in a safe place for later usage. _min_heap_free_ratio = MinHeapFreeRatio; _max_heap_free_ratio = MaxHeapFreeRatio; --- old/src/share/vm/runtime/arguments.hpp 2015-07-20 12:40:15.995901510 -0700 +++ new/src/share/vm/runtime/arguments.hpp 2015-07-20 12:40:15.771901503 -0700 @@ -462,8 +462,8 @@ static jint apply_ergo(); // Adjusts the arguments after the OS have adjusted the arguments static jint adjust_after_os(); - // Set any arguments that need to be set after the final range and constraint check - static void post_final_range_and_constraint_check(bool check_passed); + // Set any arguments that need to be set after the 'CommandLineFlagConstraint::AfterErgo' constraint check + static void post_after_ergo_constraint_check(bool check_passed); static void set_gc_specific_flags(); static inline bool gc_selected(); // whether a gc has been selected --- old/src/share/vm/runtime/commandLineFlagConstraintList.cpp 2015-07-20 12:40:17.311901553 -0700 +++ new/src/share/vm/runtime/commandLineFlagConstraintList.cpp 2015-07-20 12:40:17.011901543 -0700 @@ -39,7 +39,9 @@ public: // the "name" argument must be a string literal - CommandLineFlagConstraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func) : CommandLineFlagConstraint(name) { + CommandLineFlagConstraint_bool(const char* name, + CommandLineFlagConstraintFunc_bool func, + ConstraintType type) : CommandLineFlagConstraint(name, type) { _constraint=func; } @@ -53,7 +55,9 @@ public: // the "name" argument must be a string literal - CommandLineFlagConstraint_int(const char* name, CommandLineFlagConstraintFunc_int func) : CommandLineFlagConstraint(name) { + CommandLineFlagConstraint_int(const char* name, + CommandLineFlagConstraintFunc_int func, + ConstraintType type) : CommandLineFlagConstraint(name, type) { _constraint=func; } @@ -67,7 +71,9 @@ public: // the "name" argument must be a string literal - CommandLineFlagConstraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func) : CommandLineFlagConstraint(name) { + CommandLineFlagConstraint_intx(const char* name, + CommandLineFlagConstraintFunc_intx func, + ConstraintType type) : CommandLineFlagConstraint(name, type) { _constraint=func; } @@ -81,7 +87,9 @@ public: // the "name" argument must be a string literal - CommandLineFlagConstraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func) : CommandLineFlagConstraint(name) { + CommandLineFlagConstraint_uint(const char* name, + CommandLineFlagConstraintFunc_uint func, + ConstraintType type) : CommandLineFlagConstraint(name, type) { _constraint=func; } @@ -95,7 +103,9 @@ public: // the "name" argument must be a string literal - CommandLineFlagConstraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func) : CommandLineFlagConstraint(name) { + CommandLineFlagConstraint_uintx(const char* name, + CommandLineFlagConstraintFunc_uintx func, + ConstraintType type) : CommandLineFlagConstraint(name, type) { _constraint=func; } @@ -109,7 +119,9 @@ public: // the "name" argument must be a string literal - CommandLineFlagConstraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func) : CommandLineFlagConstraint(name) { + CommandLineFlagConstraint_uint64_t(const char* name, + CommandLineFlagConstraintFunc_uint64_t func, + ConstraintType type) : CommandLineFlagConstraint(name, type) { _constraint=func; } @@ -123,7 +135,9 @@ public: // the "name" argument must be a string literal - CommandLineFlagConstraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func) : CommandLineFlagConstraint(name) { + CommandLineFlagConstraint_size_t(const char* name, + CommandLineFlagConstraintFunc_size_t func, + ConstraintType type) : CommandLineFlagConstraint(name, type) { _constraint=func; } @@ -137,7 +151,9 @@ public: // the "name" argument must be a string literal - CommandLineFlagConstraint_double(const char* name, CommandLineFlagConstraintFunc_double func) : CommandLineFlagConstraint(name) { + CommandLineFlagConstraint_double(const char* name, + CommandLineFlagConstraintFunc_double func, + ConstraintType type) : CommandLineFlagConstraint(name, type) { _constraint=func; } @@ -162,29 +178,29 @@ void emit_constraint_double(const char* /*name*/) { /* NOP */ } // CommandLineFlagConstraint emitting code functions if function argument is provided -void emit_constraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func) { - CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_bool(name, func)); +void emit_constraint_bool(const char* name, CommandLineFlagConstraintFunc_bool func, CommandLineFlagConstraint::ConstraintType type) { + CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_bool(name, func, type)); } -void emit_constraint_int(const char* name, CommandLineFlagConstraintFunc_int func) { - CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_int(name, func)); +void emit_constraint_int(const char* name, CommandLineFlagConstraintFunc_int func, CommandLineFlagConstraint::ConstraintType type) { + CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_int(name, func, type)); } -void emit_constraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func) { - CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_intx(name, func)); +void emit_constraint_intx(const char* name, CommandLineFlagConstraintFunc_intx func, CommandLineFlagConstraint::ConstraintType type) { + CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_intx(name, func, type)); } -void emit_constraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func) { - CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint(name, func)); +void emit_constraint_uint(const char* name, CommandLineFlagConstraintFunc_uint func, CommandLineFlagConstraint::ConstraintType type) { + CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint(name, func, type)); } -void emit_constraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func) { - CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uintx(name, func)); +void emit_constraint_uintx(const char* name, CommandLineFlagConstraintFunc_uintx func, CommandLineFlagConstraint::ConstraintType type) { + CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uintx(name, func, type)); } -void emit_constraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func) { - CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint64_t(name, func)); +void emit_constraint_uint64_t(const char* name, CommandLineFlagConstraintFunc_uint64_t func, CommandLineFlagConstraint::ConstraintType type) { + CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_uint64_t(name, func, type)); } -void emit_constraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func) { - CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_size_t(name, func)); +void emit_constraint_size_t(const char* name, CommandLineFlagConstraintFunc_size_t func, CommandLineFlagConstraint::ConstraintType type) { + CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_size_t(name, func, type)); } -void emit_constraint_double(const char* name, CommandLineFlagConstraintFunc_double func) { - CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_double(name, func)); +void emit_constraint_double(const char* name, CommandLineFlagConstraintFunc_double func, CommandLineFlagConstraint::ConstraintType type) { + CommandLineFlagConstraintList::add(new CommandLineFlagConstraint_double(name, func, type)); } // Generate code to call emit_constraint_xxx function @@ -201,11 +217,12 @@ #define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) ); emit_constraint_##type(#name // Generate func argument to pass into emit_constraint_xxx functions -#define EMIT_CONSTRAINT_CHECK(func) , func +#define EMIT_CONSTRAINT_CHECK(func, type) , func, CommandLineFlagConstraint::type // the "name" argument must be a string literal #define INITIAL_CONTRAINTS_SIZE 16 GrowableArray* CommandLineFlagConstraintList::_constraints = NULL; +CommandLineFlagConstraint::ConstraintType CommandLineFlagConstraintList::_validating_type = CommandLineFlagConstraint::AtParse; // Check the ranges of all flags that have them or print them out and exit if requested void CommandLineFlagConstraintList::init(void) { @@ -273,11 +290,13 @@ #endif // INCLUDE_ALL_GCS } -CommandLineFlagConstraint* CommandLineFlagConstraintList::find(const char* name) { +// Find constraints by name and return only if found constraint's type is equal or lower than current validating type. +CommandLineFlagConstraint* CommandLineFlagConstraintList::find_if_needs_check(const char* name) { CommandLineFlagConstraint* found = NULL; for (int i=0; iname(), name) == 0) { + if ((strcmp(constraint->name(), name) == 0) && + (constraint->type() <= _validating_type)) { found = constraint; break; } --- old/src/share/vm/runtime/commandLineFlagConstraintList.hpp 2015-07-20 12:40:18.487901591 -0700 +++ new/src/share/vm/runtime/commandLineFlagConstraintList.hpp 2015-07-20 12:40:18.279901584 -0700 @@ -49,13 +49,27 @@ typedef Flag::Error (*CommandLineFlagConstraintFunc_double)(bool verbose, double* value); class CommandLineFlagConstraint : public CHeapObj { +public: + // During VM initialization, constraint validation will be done order of ConstraintType. + enum ConstraintType { + // Will be validated during argument processing (Arguments::parse_argument). + AtParse = 0, + // Will be validated by CommandLineFlags::check_constraints_of_after_ergo(). + AfterErgo = 1, + // Will be validated by CommandLineFlags::check_constraints_of_after_memory_init(). + AfterMemoryInit = 2 + }; + private: const char* _name; + ConstraintType _validate_type; + public: // the "name" argument must be a string literal - CommandLineFlagConstraint(const char* name) { _name=name; }; + CommandLineFlagConstraint(const char* name, ConstraintType type) { _name=name; _validate_type=type; }; ~CommandLineFlagConstraint() {}; const char* name() { return _name; } + ConstraintType type() { return _validate_type; } virtual Flag::Error apply_bool(bool* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }; virtual Flag::Error apply_int(int* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }; virtual Flag::Error apply_intx(intx* value, bool verbose = true) { ShouldNotReachHere(); return Flag::ERR_OTHER; }; @@ -69,12 +83,18 @@ class CommandLineFlagConstraintList : public AllStatic { private: static GrowableArray* _constraints; + // Latest constraint validation type. + static CommandLineFlagConstraint::ConstraintType _validating_type; public: static void init(); static int length() { return (_constraints != NULL) ? _constraints->length() : 0; } static CommandLineFlagConstraint* at(int i) { return (_constraints != NULL) ? _constraints->at(i) : NULL; } - static CommandLineFlagConstraint* find(const char* name); + static CommandLineFlagConstraint* find_if_needs_check(const char* name); static void add(CommandLineFlagConstraint* constraint) { _constraints->append(constraint); } + // True if 'AfterErgo' or later constraint functions are validated. + static bool validated_after_ergo() { return _validating_type >= CommandLineFlagConstraint::AfterErgo; }; + // Set current validation type + static void set_validating_type(CommandLineFlagConstraint::ConstraintType type) { _validating_type = type; }; }; #endif /* SHARE_VM_RUNTIME_COMMANDLINEFLAGCONSTRAINTLIST_HPP */ --- old/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp 2015-07-20 12:40:19.747901632 -0700 +++ new/src/share/vm/runtime/commandLineFlagConstraintsCompiler.cpp 2015-07-20 12:40:19.539901626 -0700 @@ -29,16 +29,15 @@ #include "utilities/defaultStream.hpp" Flag::Error AliasLevelConstraintFunc(bool verbose, intx* value) { - if (CommandLineFlags::finishedInitializing() == true) { - if ((*value <= 1) && (Arguments::mode() == Arguments::_comp)) { - if (verbose == true) { - jio_fprintf(defaultStream::error_stream(), - "AliasLevel (" INTX_FORMAT ") is not compatible " - "with -Xcomp \n", - *value); - } - return Flag::VIOLATES_CONSTRAINT; + if ((*value <= 1) && (Arguments::mode() == Arguments::_comp)) { + if (verbose == true) { + jio_fprintf(defaultStream::error_stream(), + "AliasLevel (" INTX_FORMAT ") is not compatible " + "with -Xcomp \n", + *value); } + return Flag::VIOLATES_CONSTRAINT; + } else { + return Flag::SUCCESS; } - return Flag::SUCCESS; } --- old/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp 2015-07-20 12:40:20.895901670 -0700 +++ new/src/share/vm/runtime/commandLineFlagConstraintsGC.cpp 2015-07-20 12:40:20.699901663 -0700 @@ -30,6 +30,9 @@ #if INCLUDE_ALL_GCS #include "gc/g1/g1_globals.hpp" +#include "gc/g1/heapRegionBounds.inline.hpp" +#include "gc/parallel/parallelScavengeHeap.hpp" +#include "gc/shared/plab.hpp" #endif // INCLUDE_ALL_GCS #ifdef COMPILER1 #include "c1/c1_globals.hpp" @@ -38,8 +41,49 @@ #include "opto/c2_globals.hpp" #endif // COMPILER2 +static Flag::Error MinPLABSizeBounds(const char* name, bool verbose, size_t* value) { +#if INCLUDE_ALL_GCS + if ((UseConcMarkSweepGC || UseG1GC) && (*value < PLAB::min_size())) { + if (verbose == true) { + jio_fprintf(defaultStream::error_stream(), + "%s (" SIZE_FORMAT ") must be greater than " + "ergornomic PLAB minimum size (" SIZE_FORMAT ")\n", + name, *value, PLAB::min_size()); + } + return Flag::VIOLATES_CONSTRAINT; + } +#endif // INCLUDE_ALL_GCS + return Flag::SUCCESS; +} + +static Flag::Error MaxPLABSizeBounds(const char* name, bool verbose, size_t* value) { +#if INCLUDE_ALL_GCS + if ((UseConcMarkSweepGC || UseG1GC) && (*value > PLAB::max_size())) { + if (verbose == true) { + jio_fprintf(defaultStream::error_stream(), + "%s (" SIZE_FORMAT ") must be less than " + "ergornomic PLAB maximum size (" SIZE_FORMAT ")\n", + name, *value, PLAB::max_size()); + } + return Flag::VIOLATES_CONSTRAINT; + } +#endif // INCLUDE_ALL_GCS + return Flag::SUCCESS; +} + +static Flag::Error MinMaxPLABSizeBounds(const char* name, bool verbose, size_t* value) { + if (MinPLABSizeBounds(name, verbose, value) == Flag::SUCCESS) { + return MaxPLABSizeBounds(name, verbose, value); + } + return Flag::VIOLATES_CONSTRAINT; +} + +Flag::Error YoungPLABSizeConstraintFunc(bool verbose, size_t* value) { + return MinMaxPLABSizeBounds("YoungPLABSize", verbose, value); +} + Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value > MaxHeapFreeRatio)) { + if (*value > MaxHeapFreeRatio) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "MinHeapFreeRatio (" UINTX_FORMAT ") must be less than or " @@ -53,7 +97,7 @@ } Flag::Error MaxHeapFreeRatioConstraintFunc(bool verbose, uintx* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value < MinHeapFreeRatio)) { + if (*value < MinHeapFreeRatio) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "MaxHeapFreeRatio (" UINTX_FORMAT ") must be greater than or " @@ -67,7 +111,7 @@ } Flag::Error MinMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value > MaxMetaspaceFreeRatio)) { + if (*value > MaxMetaspaceFreeRatio) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "MinMetaspaceFreeRatio (" UINTX_FORMAT ") must be less than or " @@ -81,7 +125,7 @@ } Flag::Error MaxMetaspaceFreeRatioConstraintFunc(bool verbose, uintx* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value < MinMetaspaceFreeRatio)) { + if (*value < MinMetaspaceFreeRatio) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "MaxMetaspaceFreeRatio (" UINTX_FORMAT ") must be greater than or " @@ -106,7 +150,7 @@ Flag::Error InitialTenuringThresholdConstraintFunc(bool verbose, uintx* value) { UseConcMarkSweepGCWorkaroundIfNeeded(*value, MaxTenuringThreshold); - if ((CommandLineFlags::finishedInitializing()) && (*value > MaxTenuringThreshold)) { + if (*value > MaxTenuringThreshold) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "InitialTenuringThreshold (" UINTX_FORMAT ") must be less than or " @@ -122,7 +166,7 @@ Flag::Error MaxTenuringThresholdConstraintFunc(bool verbose, uintx* value) { UseConcMarkSweepGCWorkaroundIfNeeded(InitialTenuringThreshold, *value); - if ((CommandLineFlags::finishedInitializing()) && (*value < InitialTenuringThreshold)) { + if (*value < InitialTenuringThreshold) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "MaxTenuringThreshold (" UINTX_FORMAT ") must be greater than or " @@ -136,9 +180,8 @@ } #if INCLUDE_ALL_GCS - Flag::Error G1NewSizePercentConstraintFunc(bool verbose, uintx* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value > G1MaxNewSizePercent)) { + if (*value > G1MaxNewSizePercent) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "G1NewSizePercent (" UINTX_FORMAT ") must be less than or " @@ -152,7 +195,7 @@ } Flag::Error G1MaxNewSizePercentConstraintFunc(bool verbose, uintx* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value < G1NewSizePercent)) { + if (*value < G1NewSizePercent) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "G1MaxNewSizePercent (" UINTX_FORMAT ") must be greater than or " @@ -168,7 +211,7 @@ #endif // INCLUDE_ALL_GCS Flag::Error CMSOldPLABMinConstraintFunc(bool verbose, size_t* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value > CMSOldPLABMax)) { + if (*value > CMSOldPLABMax) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "CMSOldPLABMin (" SIZE_FORMAT ") must be less than or " @@ -182,7 +225,7 @@ } Flag::Error CMSPrecleanDenominatorConstraintFunc(bool verbose, uintx* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value <= CMSPrecleanNumerator)) { + if (*value <= CMSPrecleanNumerator) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "CMSPrecleanDenominator (" UINTX_FORMAT ") must be strickly greater than " @@ -196,7 +239,7 @@ } Flag::Error CMSPrecleanNumeratorConstraintFunc(bool verbose, uintx* value) { - if ((CommandLineFlags::finishedInitializing()) && (*value > (CMSPrecleanDenominator - 1))) { + if (*value > (CMSPrecleanDenominator - 1)) { if (verbose == true) { jio_fprintf(defaultStream::error_stream(), "CMSPrecleanNumerator (" UINTX_FORMAT ") must be less than or " @@ -210,25 +253,23 @@ } Flag::Error SurvivorAlignmentInBytesConstraintFunc(bool verbose, intx* value) { - if (CommandLineFlags::finishedInitializing()) { - if (*value != 0) { - if (!is_power_of_2(*value)) { - if (verbose == true) { - jio_fprintf(defaultStream::error_stream(), - "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be power of 2\n", - *value); - } - return Flag::VIOLATES_CONSTRAINT; + if (*value != 0) { + if (!is_power_of_2(*value)) { + if (verbose == true) { + jio_fprintf(defaultStream::error_stream(), + "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be power of 2\n", + *value); } - if (*value < ObjectAlignmentInBytes) { - if (verbose == true) { - jio_fprintf(defaultStream::error_stream(), - "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be greater than or " - "equal to ObjectAlignmentInBytes (" INTX_FORMAT ") \n", - *value, ObjectAlignmentInBytes); - } - return Flag::VIOLATES_CONSTRAINT; + return Flag::VIOLATES_CONSTRAINT; + } + if (*value < ObjectAlignmentInBytes) { + if (verbose == true) { + jio_fprintf(defaultStream::error_stream(), + "SurvivorAlignmentInBytes (" INTX_FORMAT ") must be greater than or " + "equal to ObjectAlignmentInBytes (" INTX_FORMAT ")\n", + *value, ObjectAlignmentInBytes); } + return Flag::VIOLATES_CONSTRAINT; } } return Flag::SUCCESS; --- old/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp 2015-07-20 12:40:22.231901714 -0700 +++ new/src/share/vm/runtime/commandLineFlagConstraintsGC.hpp 2015-07-20 12:40:22.003901706 -0700 @@ -34,6 +34,8 @@ * an appropriate error value. */ +Flag::Error YoungPLABSizeConstraintFunc(bool verbose, size_t* value); + Flag::Error MinHeapFreeRatioConstraintFunc(bool verbose, uintx* value); Flag::Error MaxHeapFreeRatioConstraintFunc(bool verbose, uintx* value); --- old/src/share/vm/runtime/globals.cpp 2015-07-20 12:40:23.519901756 -0700 +++ new/src/share/vm/runtime/globals.cpp 2015-07-20 12:40:23.275901748 -0700 @@ -770,7 +770,7 @@ static Flag::Error apply_constraint_and_check_range_bool(const char* name, bool* new_value, bool verbose = true) { Flag::Error status = Flag::SUCCESS; - CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); + CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); if (constraint != NULL) { status = constraint->apply_bool(new_value, verbose); } @@ -789,7 +789,7 @@ Flag* result = Flag::find_flag(name, len); if (result == NULL) return Flag::INVALID_FLAG; if (!result->is_bool()) return Flag::WRONG_FORMAT; - Flag::Error check = apply_constraint_and_check_range_bool(name, value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_bool(name, value, !CommandLineFlagConstraintList::validated_after_ergo()); if (check != Flag::SUCCESS) return check; bool old_value = result->get_bool(); trace_flag_changed(name, old_value, *value, origin); @@ -817,7 +817,7 @@ range_status = range->check_int(*new_value, verbose); } Flag::Error constraint_status = Flag::SUCCESS; - CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); + CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); if (constraint != NULL) { constraint_status = constraint->apply_int(new_value, verbose); } @@ -836,7 +836,7 @@ Flag* result = Flag::find_flag(name, len); if (result == NULL) return Flag::INVALID_FLAG; if (!result->is_int()) return Flag::WRONG_FORMAT; - Flag::Error check = apply_constraint_and_check_range_int(name, value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_int(name, value, !CommandLineFlagConstraintList::validated_after_ergo()); if (check != Flag::SUCCESS) return check; int old_value = result->get_int(); trace_flag_changed(name, old_value, *value, origin); @@ -862,7 +862,7 @@ range_status = range->check_uint(*new_value, verbose); } Flag::Error constraint_status = Flag::SUCCESS; - CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); + CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); if (constraint != NULL) { constraint_status = constraint->apply_uint(new_value, verbose); } @@ -881,7 +881,7 @@ Flag* result = Flag::find_flag(name, len); if (result == NULL) return Flag::INVALID_FLAG; if (!result->is_uint()) return Flag::WRONG_FORMAT; - Flag::Error check = apply_constraint_and_check_range_uint(name, value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_uint(name, value, !CommandLineFlagConstraintList::validated_after_ergo()); if (check != Flag::SUCCESS) return check; uint old_value = result->get_uint(); trace_flag_changed(name, old_value, *value, origin); @@ -915,7 +915,7 @@ range_status = range->check_intx(*new_value, verbose); } Flag::Error constraint_status = Flag::SUCCESS; - CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); + CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); if (constraint != NULL) { constraint_status = constraint->apply_intx(new_value, verbose); } @@ -926,7 +926,7 @@ Flag* result = Flag::find_flag(name, len); if (result == NULL) return Flag::INVALID_FLAG; if (!result->is_intx()) return Flag::WRONG_FORMAT; - Flag::Error check = apply_constraint_and_check_range_intx(name, value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_intx(name, value, !CommandLineFlagConstraintList::validated_after_ergo()); if (check != Flag::SUCCESS) return check; intx old_value = result->get_intx(); trace_flag_changed(name, old_value, *value, origin); @@ -962,7 +962,7 @@ range_status = range->check_uintx(*new_value, verbose); } Flag::Error constraint_status = Flag::SUCCESS; - CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); + CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); if (constraint != NULL) { constraint_status = constraint->apply_uintx(new_value, verbose); } @@ -973,7 +973,7 @@ Flag* result = Flag::find_flag(name, len); if (result == NULL) return Flag::INVALID_FLAG; if (!result->is_uintx()) return Flag::WRONG_FORMAT; - Flag::Error check = apply_constraint_and_check_range_uintx(name, value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_uintx(name, value, !CommandLineFlagConstraintList::validated_after_ergo()); if (check != Flag::SUCCESS) return check; uintx old_value = result->get_uintx(); trace_flag_changed(name, old_value, *value, origin); @@ -1009,7 +1009,7 @@ range_status = range->check_uint64_t(*new_value, verbose); } Flag::Error constraint_status = Flag::SUCCESS; - CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); + CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); if (constraint != NULL) { constraint_status = constraint->apply_uint64_t(new_value, verbose); } @@ -1020,7 +1020,7 @@ Flag* result = Flag::find_flag(name, len); if (result == NULL) return Flag::INVALID_FLAG; if (!result->is_uint64_t()) return Flag::WRONG_FORMAT; - Flag::Error check = apply_constraint_and_check_range_uint64_t(name, value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_uint64_t(name, value, !CommandLineFlagConstraintList::validated_after_ergo()); if (check != Flag::SUCCESS) return check; uint64_t old_value = result->get_uint64_t(); trace_flag_changed(name, old_value, *value, origin); @@ -1056,7 +1056,7 @@ range_status = range->check_size_t(*new_value, verbose); } Flag::Error constraint_status = Flag::SUCCESS; - CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); + CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); if (constraint != NULL) { constraint_status = constraint->apply_size_t(new_value, verbose); } @@ -1067,7 +1067,7 @@ Flag* result = Flag::find_flag(name, len); if (result == NULL) return Flag::INVALID_FLAG; if (!result->is_size_t()) return Flag::WRONG_FORMAT; - Flag::Error check = apply_constraint_and_check_range_size_t(name, value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_size_t(name, value, !CommandLineFlagConstraintList::validated_after_ergo()); if (check != Flag::SUCCESS) return check; size_t old_value = result->get_size_t(); trace_flag_changed(name, old_value, *value, origin); @@ -1103,7 +1103,7 @@ range_status = range->check_double(*new_value, verbose); } Flag::Error constraint_status = Flag::SUCCESS; - CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find(name); + CommandLineFlagConstraint* constraint = CommandLineFlagConstraintList::find_if_needs_check(name); if (constraint != NULL) { constraint_status = constraint->apply_double(new_value, verbose); } @@ -1114,7 +1114,7 @@ Flag* result = Flag::find_flag(name, len); if (result == NULL) return Flag::INVALID_FLAG; if (!result->is_double()) return Flag::WRONG_FORMAT; - Flag::Error check = apply_constraint_and_check_range_double(name, value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_double(name, value, !CommandLineFlagConstraintList::validated_after_ergo()); if (check != Flag::SUCCESS) return check; double old_value = result->get_double(); trace_flag_changed(name, old_value, *value, origin); @@ -1127,7 +1127,7 @@ Flag::Error CommandLineFlagsEx::doubleAtPut(CommandLineFlagWithType flag, double value, Flag::Flags origin) { Flag* faddr = address_of_flag(flag); guarantee(faddr != NULL && faddr->is_double(), "wrong flag type"); - Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, &value, !CommandLineFlags::finishedInitializing()); + Flag::Error check = apply_constraint_and_check_range_double(faddr->_name, &value); if (check != Flag::SUCCESS) return check; trace_flag_changed(faddr->_name, faddr->get_double(), value, origin); faddr->set_double(value); @@ -1210,12 +1210,9 @@ FREE_C_HEAP_ARRAY(Flag*, array); } -bool CommandLineFlags::_finished_initializing = false; - -bool CommandLineFlags::check_all_ranges_and_constraints() { - -//#define PRINT_RANGES_AND_CONSTRAINTS_SIZES -#ifdef PRINT_RANGES_AND_CONSTRAINTS_SIZES +bool CommandLineFlags::check_ranges() { +//#define PRINT_RANGES_SIZES +#ifdef PRINT_RANGES_SIZES { size_t size_ranges = sizeof(CommandLineFlagRangeList); for (int i=0; iname(); + Flag* flag = Flag::find_flag(name, strlen(name), true, true); + if (flag != NULL) { + if (flag->is_intx()) { + intx value = flag->get_intx(); + if (range->check_intx(value, true) != Flag::SUCCESS) status = false; + } else if (flag->is_uintx()) { + uintx value = flag->get_uintx(); + if (range->check_uintx(value, true) != Flag::SUCCESS) status = false; + } else if (flag->is_uint64_t()) { + uint64_t value = flag->get_uint64_t(); + if (range->check_uint64_t(value, true) != Flag::SUCCESS) status = false; + } else if (flag->is_size_t()) { + size_t value = flag->get_size_t(); + if (range->check_size_t(value, true) != Flag::SUCCESS) status = false; + } else if (flag->is_double()) { + double value = flag->get_double(); + if (range->check_double(value, true) != Flag::SUCCESS) status = false; + } + } + } + return status; +} + +// Check constraints for specific constraint type. +static bool check_constraints(CommandLineFlagConstraint::ConstraintType constraint_type) { +//#define PRINT_CONSTRAINTS_SIZES +#ifdef PRINT_CONSTRAINTS_SIZES { size_t size_constraints = sizeof(CommandLineFlagConstraintList); for (int i=0; iname(); - Flag* flag = Flag::find_flag(name, strlen(name), true, true); - if (flag != NULL) { - if (flag->is_intx()) { - intx value = flag->get_intx(); - if (range->check_intx(value, true) != Flag::SUCCESS) status = false; - } else if (flag->is_uintx()) { - uintx value = flag->get_uintx(); - if (range->check_uintx(value, true) != Flag::SUCCESS) status = false; - } else if (flag->is_uint64_t()) { - uint64_t value = flag->get_uint64_t(); - if (range->check_uint64_t(value, true) != Flag::SUCCESS) status = false; - } else if (flag->is_size_t()) { - size_t value = flag->get_size_t(); - if (range->check_size_t(value, true) != Flag::SUCCESS) status = false; - } else if (flag->is_double()) { - double value = flag->get_double(); - if (range->check_double(value, true) != Flag::SUCCESS) status = false; - } - } - } for (int i=0; itype()) continue; const char*name = constraint->name(); Flag* flag = Flag::find_flag(name, strlen(name), true, true); if (flag != NULL) { @@ -1327,12 +1334,27 @@ } } } + return status; +} + +// Check constraints and do post work of 'AfterErgo'. +bool CommandLineFlags::check_constraints_of_after_ergo() { + CommandLineFlagConstraintList::set_validating_type(CommandLineFlagConstraint::AfterErgo); + + bool status = check_constraints(CommandLineFlagConstraint::AfterErgo); - Arguments::post_final_range_and_constraint_check(status); + Arguments::post_after_ergo_constraint_check(status); return status; } +// Check constraints of 'AfterMemoryInit'. +bool CommandLineFlags::check_constraints_of_after_memory_init() { + CommandLineFlagConstraintList::set_validating_type(CommandLineFlagConstraint::AfterMemoryInit); + + return check_constraints(CommandLineFlagConstraint::AfterMemoryInit); +} + #ifndef PRODUCT void CommandLineFlags::verify() { --- old/src/share/vm/runtime/globals.hpp 2015-07-20 12:40:25.323901814 -0700 +++ new/src/share/vm/runtime/globals.hpp 2015-07-20 12:40:25.003901804 -0700 @@ -450,7 +450,6 @@ class CommandLineFlags { - static bool _finished_initializing; public: static Flag::Error boolAt(const char* name, size_t len, bool* value, bool allow_locked = false, bool return_flag = false); static Flag::Error boolAt(const char* name, bool* value, bool allow_locked = false, bool return_flag = false) { return boolAt(name, strlen(name), value, allow_locked, return_flag); } @@ -506,11 +505,14 @@ // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges static void printFlags(outputStream* out, bool withComments, bool printRanges = false); - // Returns true if all flags have their final values set (ready for ranges and constraint check) - static bool finishedInitializing() { return _finished_initializing; } + // Check the final values of all flags for ranges. + static bool check_ranges(); - // Check the final values of all flags for ranges and constraints - static bool check_all_ranges_and_constraints(); + // Check the final values of all flags for 'AfterErgo' constraints. + static bool check_constraints_of_after_ergo(); + + // Check the final values of all flags for 'AfterMemoryInit' constraints. + static bool check_constraints_of_after_memory_init(); static void verify() PRODUCT_RETURN; }; @@ -640,7 +642,7 @@ lp64_product(intx, ObjectAlignmentInBytes, 8, \ "Default object alignment in bytes, 8 is minimum") \ range(8, 256) \ - constraint(ObjectAlignmentInBytesConstraintFunc) \ + constraint(ObjectAlignmentInBytesConstraintFunc,AtParse) \ \ product(bool, AssumeMP, false, \ "Instruct the VM to assume multiple processors are available") \ @@ -1394,7 +1396,7 @@ product(intx, ContendedPaddingWidth, 128, \ "How many bytes to pad the fields/classes marked @Contended with")\ range(0, 8192) \ - constraint(ContendedPaddingWidthConstraintFunc) \ + constraint(ContendedPaddingWidthConstraintFunc,AtParse) \ \ product(bool, EnableContended, true, \ "Enable @Contended annotation support") \ @@ -1595,6 +1597,7 @@ \ product(size_t, YoungPLABSize, 4096, \ "Size of young gen promotion LAB's (in HeapWords)") \ + constraint(YoungPLABSizeConstraintFunc,AfterMemoryInit) \ \ product(size_t, OldPLABSize, 1024, \ "Size of old gen promotion LAB's (in HeapWords), or Number \ @@ -1733,7 +1736,7 @@ "Minimum size of CMS gen promotion LAB caches per worker " \ "per block size") \ range(1, max_uintx) \ - constraint(CMSOldPLABMinConstraintFunc) \ + constraint(CMSOldPLABMinConstraintFunc,AfterErgo) \ \ product(uintx, CMSOldPLABNumRefills, 4, \ "Nominal number of refills of CMS gen promotion LAB cache " \ @@ -1929,13 +1932,13 @@ "CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence " \ "ratio") \ range(1, max_uintx) \ - constraint(CMSPrecleanDenominatorConstraintFunc) \ + constraint(CMSPrecleanDenominatorConstraintFunc,AfterErgo) \ \ product(uintx, CMSPrecleanNumerator, 2, \ "CMSPrecleanNumerator:CMSPrecleanDenominator yields convergence " \ "ratio") \ range(0, max_uintx-1) \ - constraint(CMSPrecleanNumeratorConstraintFunc) \ + constraint(CMSPrecleanNumeratorConstraintFunc,AfterErgo) \ \ product(bool, CMSPrecleanRefLists1, true, \ "Preclean ref lists during (initial) preclean phase") \ @@ -3359,14 +3362,14 @@ " For most GCs this applies to the old generation. In G1 and" \ " ParallelGC it applies to the whole heap.") \ range(0, 100) \ - constraint(MinHeapFreeRatioConstraintFunc) \ + constraint(MinHeapFreeRatioConstraintFunc,AfterErgo) \ \ manageable(uintx, MaxHeapFreeRatio, 70, \ "The maximum percentage of heap free after GC to avoid shrinking."\ " For most GCs this applies to the old generation. In G1 and" \ " ParallelGC it applies to the whole heap.") \ range(0, 100) \ - constraint(MaxHeapFreeRatioConstraintFunc) \ + constraint(MaxHeapFreeRatioConstraintFunc,AfterErgo) \ \ product(intx, SoftRefLRUPolicyMSPerMB, 1000, \ "Number of milliseconds per MB of free space in the heap") \ @@ -3381,13 +3384,13 @@ "The maximum percentage of Metaspace free after GC to avoid " \ "shrinking") \ range(0, 100) \ - constraint(MaxMetaspaceFreeRatioConstraintFunc) \ + constraint(MaxMetaspaceFreeRatioConstraintFunc,AfterErgo) \ \ product(uintx, MinMetaspaceFreeRatio, 40, \ "The minimum percentage of Metaspace free after GC to avoid " \ "expansion") \ range(0, 99) \ - constraint(MinMetaspaceFreeRatioConstraintFunc) \ + constraint(MinMetaspaceFreeRatioConstraintFunc,AfterErgo) \ \ product(size_t, MaxMetaspaceExpansion, ScaleForWordSize(4*M), \ "The maximum expansion of Metaspace without full GC (in bytes)") \ @@ -3405,12 +3408,12 @@ product(uintx, MaxTenuringThreshold, 15, \ "Maximum value for tenuring threshold") \ range(0, markOopDesc::max_age + 1) \ - constraint(MaxTenuringThresholdConstraintFunc) \ + constraint(MaxTenuringThresholdConstraintFunc,AfterErgo) \ \ product(uintx, InitialTenuringThreshold, 7, \ "Initial value for tenuring threshold") \ range(0, markOopDesc::max_age + 1) \ - constraint(InitialTenuringThresholdConstraintFunc) \ + constraint(InitialTenuringThresholdConstraintFunc,AfterErgo) \ \ product(uintx, TargetSurvivorRatio, 50, \ "Desired percentage of survivor space used after scavenge") \ @@ -4088,7 +4091,7 @@ \ experimental(intx, SurvivorAlignmentInBytes, 0, \ "Default survivor space alignment in bytes") \ - constraint(SurvivorAlignmentInBytesConstraintFunc) \ + constraint(SurvivorAlignmentInBytesConstraintFunc,AfterErgo) \ \ product(bool , AllowNonVirtualCalls, false, \ "Obey the ACC_SUPER flag and allow invokenonvirtual calls") \ @@ -4188,7 +4191,7 @@ // Only materialize src code for range checking when required, ignore otherwise #define IGNORE_RANGE(a, b) // Only materialize src code for contraint checking when required, ignore otherwise -#define IGNORE_CONSTRAINT(func) +#define IGNORE_CONSTRAINT(func,type) RUNTIME_FLAGS(DECLARE_DEVELOPER_FLAG, \ DECLARE_PD_DEVELOPER_FLAG, \ --- old/src/share/vm/runtime/thread.cpp 2015-07-20 12:40:27.075901872 -0700 +++ new/src/share/vm/runtime/thread.cpp 2015-07-20 12:40:26.739901861 -0700 @@ -3319,8 +3319,13 @@ jint ergo_result = Arguments::apply_ergo(); if (ergo_result != JNI_OK) return ergo_result; - // Final check of all arguments after ergonomics which may change values. - if (!CommandLineFlags::check_all_ranges_and_constraints()) { + // Final check of all ranges after ergonomics which may change values. + if (!CommandLineFlags::check_ranges()) { + return JNI_EINVAL; + } + + // Final check of all 'AfterErgo' constraints after ergonomics which may change values. + if (!CommandLineFlags::check_constraints_of_after_ergo()) { return JNI_EINVAL; } --- old/test/runtime/CompressedOops/ObjectAlignment.java 2015-07-20 12:40:28.579901921 -0700 +++ new/test/runtime/CompressedOops/ObjectAlignment.java 2015-07-20 12:40:28.239901910 -0700 @@ -48,7 +48,6 @@ .shouldHaveExitValue(1); testObjectAlignment(-1) - .shouldContain("must be power of 2") .shouldContain("outside the allowed range") .shouldHaveExitValue(1); @@ -75,4 +74,4 @@ "-version"); return new OutputAnalyzer(pb.start()); } -} \ No newline at end of file +} --- old/test/runtime/contended/Options.java 2015-07-20 12:40:29.931901965 -0700 +++ new/test/runtime/contended/Options.java 2015-07-20 12:40:29.651901956 -0700 @@ -55,7 +55,6 @@ output = new OutputAnalyzer(pb.start()); output.shouldContain("ContendedPaddingWidth"); output.shouldContain("outside the allowed range"); - output.shouldContain("must be a multiple of 8"); output.shouldHaveExitValue(1); pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=0", "-version"); @@ -90,7 +89,6 @@ output = new OutputAnalyzer(pb.start()); output.shouldContain("ContendedPaddingWidth"); output.shouldContain("outside the allowed range"); - output.shouldContain("must be a multiple of 8"); output.shouldHaveExitValue(1); pb = ProcessTools.createJavaProcessBuilder("-XX:ContendedPaddingWidth=8200", "-version"); // 8192+8 = 8200