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