# HG changeset patch # User pliden # Date 1522229927 -7200 # Node ID b786280276dcb6ec896b86ff3ea348914049821e # Parent 88478047bc8facb282aca8699029ed4e812a5fe7 8199925: Break out GC selection logic from GCArguments to GCConfig Reviewed-by: eosterlund, rkennke diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/cms/cmsArguments.cpp --- a/src/hotspot/share/gc/cms/cmsArguments.cpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/cms/cmsArguments.cpp Wed Mar 28 11:38:47 2018 +0200 @@ -80,8 +80,8 @@ // sparc/solaris for certain applications, but would gain from // further optimization and tuning efforts, and would almost // certainly gain from analysis of platform and environment. -void CMSArguments::initialize_flags() { - GCArguments::initialize_flags(); +void CMSArguments::initialize() { + GCArguments::initialize(); assert(!UseSerialGC && !UseParallelOldGC && !UseParallelGC, "Error"); assert(UseConcMarkSweepGC, "CMS is expected to be on here"); diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/cms/cmsArguments.hpp --- a/src/hotspot/share/gc/cms/cmsArguments.hpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/cms/cmsArguments.hpp Wed Mar 28 11:38:47 2018 +0200 @@ -34,7 +34,7 @@ void disable_adaptive_size_policy(const char* collector_name); void set_parnew_gc_flags(); public: - virtual void initialize_flags(); + virtual void initialize(); virtual size_t conservative_max_heap_alignment(); virtual CollectedHeap* create_heap(); }; diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/g1/g1Arguments.cpp --- a/src/hotspot/share/gc/g1/g1Arguments.cpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1Arguments.cpp Wed Mar 28 11:38:47 2018 +0200 @@ -72,8 +72,8 @@ } } -void G1Arguments::initialize_flags() { - GCArguments::initialize_flags(); +void G1Arguments::initialize() { + GCArguments::initialize(); assert(UseG1GC, "Error"); FLAG_SET_DEFAULT(ParallelGCThreads, Abstract_VM_Version::parallel_worker_threads()); if (ParallelGCThreads == 0) { diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/g1/g1Arguments.hpp --- a/src/hotspot/share/gc/g1/g1Arguments.hpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/g1/g1Arguments.hpp Wed Mar 28 11:38:47 2018 +0200 @@ -38,7 +38,7 @@ static void parse_verification_type(const char* type); public: - virtual void initialize_flags(); + virtual void initialize(); virtual size_t conservative_max_heap_alignment(); virtual CollectedHeap* create_heap(); }; diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/parallel/parallelArguments.cpp --- a/src/hotspot/share/gc/parallel/parallelArguments.cpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp Wed Mar 28 11:38:47 2018 +0200 @@ -38,8 +38,8 @@ return CollectorPolicy::compute_heap_alignment(); } -void ParallelArguments::initialize_flags() { - GCArguments::initialize_flags(); +void ParallelArguments::initialize() { + GCArguments::initialize(); assert(UseParallelGC || UseParallelOldGC, "Error"); // Enable ParallelOld unless it was explicitly disabled (cmd line or rc file). if (FLAG_IS_DEFAULT(UseParallelOldGC)) { diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/parallel/parallelArguments.hpp --- a/src/hotspot/share/gc/parallel/parallelArguments.hpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/parallel/parallelArguments.hpp Wed Mar 28 11:38:47 2018 +0200 @@ -31,7 +31,7 @@ class ParallelArguments : public GCArguments { public: - virtual void initialize_flags(); + virtual void initialize(); virtual size_t conservative_max_heap_alignment(); virtual CollectedHeap* create_heap(); }; diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/shared/collectedHeap.hpp --- a/src/hotspot/share/gc/shared/collectedHeap.hpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp Wed Mar 28 11:38:47 2018 +0200 @@ -187,6 +187,7 @@ public: enum Name { + None, Serial, Parallel, CMS, diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/shared/gcArguments.cpp --- a/src/hotspot/share/gc/shared/gcArguments.cpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/shared/gcArguments.cpp Wed Mar 28 11:38:47 2018 +0200 @@ -25,68 +25,12 @@ #include "precompiled.hpp" #include "gc/shared/gcArguments.hpp" -#include "gc/serial/serialArguments.hpp" -#include "logging/log.hpp" -#include "memory/allocation.inline.hpp" #include "runtime/arguments.hpp" #include "runtime/globals.hpp" #include "runtime/globals_extension.hpp" -#include "runtime/java.hpp" -#include "runtime/os.hpp" -#include "utilities/defaultStream.hpp" #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS -#include "gc/parallel/parallelArguments.hpp" -#include "gc/cms/cmsArguments.hpp" -#include "gc/g1/g1Arguments.hpp" -#endif - -GCArguments* GCArguments::_instance = NULL; - -GCArguments* GCArguments::arguments() { - assert(is_initialized(), "Heap factory not yet created"); - return _instance; -} - -bool GCArguments::is_initialized() { - return _instance != NULL; -} - -bool GCArguments::gc_selected() { -#if INCLUDE_ALL_GCS - return UseSerialGC || UseParallelGC || UseParallelOldGC || UseConcMarkSweepGC || UseG1GC; -#else - return UseSerialGC; -#endif // INCLUDE_ALL_GCS -} - -void GCArguments::select_gc() { - if (!gc_selected()) { - select_gc_ergonomically(); - if (!gc_selected()) { - vm_exit_during_initialization("Garbage collector not selected (default collector explicitly disabled)", NULL); - } - } -} - -void GCArguments::select_gc_ergonomically() { -#if INCLUDE_ALL_GCS - if (os::is_server_class_machine()) { - FLAG_SET_ERGO_IF_DEFAULT(bool, UseG1GC, true); - } else { - FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true); - } -#else - UNSUPPORTED_OPTION(UseG1GC); - UNSUPPORTED_OPTION(UseParallelGC); - UNSUPPORTED_OPTION(UseParallelOldGC); - UNSUPPORTED_OPTION(UseConcMarkSweepGC); - FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true); -#endif // INCLUDE_ALL_GCS -} - -void GCArguments::initialize_flags() { +void GCArguments::initialize() { #if INCLUDE_ALL_GCS if (MinHeapFreeRatio == 100) { // Keeping the heap 100% free is hard ;-) so limit it to 99%. @@ -100,34 +44,3 @@ } #endif // INCLUDE_ALL_GCS } - -jint GCArguments::initialize() { - assert(!is_initialized(), "GC arguments already initialized"); - - select_gc(); - -#if !INCLUDE_ALL_GCS - if (UseParallelGC || UseParallelOldGC) { - jio_fprintf(defaultStream::error_stream(), "UseParallelGC not supported in this VM.\n"); - return JNI_ERR; - } else if (UseG1GC) { - jio_fprintf(defaultStream::error_stream(), "UseG1GC not supported in this VM.\n"); - return JNI_ERR; - } else if (UseConcMarkSweepGC) { - jio_fprintf(defaultStream::error_stream(), "UseConcMarkSweepGC not supported in this VM.\n"); - return JNI_ERR; -#else - if (UseParallelGC || UseParallelOldGC) { - _instance = new ParallelArguments(); - } else if (UseG1GC) { - _instance = new G1Arguments(); - } else if (UseConcMarkSweepGC) { - _instance = new CMSArguments(); -#endif - } else if (UseSerialGC) { - _instance = new SerialArguments(); - } else { - ShouldNotReachHere(); - } - return JNI_OK; -} diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/shared/gcArguments.hpp --- a/src/hotspot/share/gc/shared/gcArguments.hpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/gc/shared/gcArguments.hpp Wed Mar 28 11:38:47 2018 +0200 @@ -30,27 +30,14 @@ class CollectedHeap; -class GCArguments : public CHeapObj { -private: - static GCArguments* _instance; - - static void select_gc(); - static void select_gc_ergonomically(); - static bool gc_selected(); - +class GCArguments { protected: template CollectedHeap* create_heap_with_policy(); public: - static jint initialize(); - static bool is_initialized(); - static GCArguments* arguments(); - - virtual void initialize_flags(); - + virtual void initialize(); virtual size_t conservative_max_heap_alignment() = 0; - virtual CollectedHeap* create_heap() = 0; }; diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/shared/gcConfig.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/shared/gcConfig.cpp Wed Mar 28 11:38:47 2018 +0200 @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2018, 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 "gc/serial/serialArguments.hpp" +#include "gc/shared/gcConfig.hpp" +#include "runtime/java.hpp" +#include "runtime/os.hpp" +#include "utilities/macros.hpp" +#if INCLUDE_ALL_GCS +#include "gc/parallel/parallelArguments.hpp" +#include "gc/cms/cmsArguments.hpp" +#include "gc/g1/g1Arguments.hpp" +#endif // INCLUDE_ALL_GCS + +struct SupportedGC { + bool& _flag; + CollectedHeap::Name _name; + GCArguments& _arguments; + + SupportedGC(bool& flag, CollectedHeap::Name name, GCArguments& arguments) : + _flag(flag), _name(name), _arguments(arguments) {} +}; + +static SerialArguments serialArguments; +#if INCLUDE_ALL_GCS +static ParallelArguments parallelArguments; +static CMSArguments cmsArguments; +static G1Arguments g1Arguments; +#endif // INCLUDE_ALL_GCS + +// Table of supported GCs, for translating between command +// line flag, CollectedHeap::Name and GCArguments instance. +static const SupportedGC SupportedGCs[] = { + SupportedGC(UseSerialGC, CollectedHeap::Serial, serialArguments), +#if INCLUDE_ALL_GCS + SupportedGC(UseParallelGC, CollectedHeap::Parallel, parallelArguments), + SupportedGC(UseParallelOldGC, CollectedHeap::Parallel, parallelArguments), + SupportedGC(UseConcMarkSweepGC, CollectedHeap::CMS, cmsArguments), + SupportedGC(UseG1GC, CollectedHeap::G1, g1Arguments), +#endif // INCLUDE_ALL_GCS +}; + +GCArguments* GCConfig::_arguments = NULL; +bool GCConfig::_gc_selected_ergonomically = false; + +void GCConfig::select_gc_ergonomically() { +#if INCLUDE_ALL_GCS + if (os::is_server_class_machine()) { + FLAG_SET_ERGO_IF_DEFAULT(bool, UseG1GC, true); + } else { + FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true); + } +#else + UNSUPPORTED_OPTION(UseG1GC); + UNSUPPORTED_OPTION(UseParallelGC); + UNSUPPORTED_OPTION(UseParallelOldGC); + UNSUPPORTED_OPTION(UseConcMarkSweepGC); + FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true); +#endif // INCLUDE_ALL_GCS +} + +bool GCConfig::is_no_gc_selected() { + for (size_t i = 0; i < ARRAY_SIZE(SupportedGCs); i++) { + if (SupportedGCs[i]._flag) { + return false; + } + } + + return true; +} + +bool GCConfig::is_exactly_one_gc_selected() { + CollectedHeap::Name selected = CollectedHeap::None; + + for (size_t i = 0; i < ARRAY_SIZE(SupportedGCs); i++) { + if (SupportedGCs[i]._flag) { + if (SupportedGCs[i]._name == selected || selected == CollectedHeap::None) { + // Selected + selected = SupportedGCs[i]._name; + } else { + // More than one selected + return false; + } + } + } + + return selected != CollectedHeap::None; +} + +GCArguments* GCConfig::select_gc() { + if (is_no_gc_selected()) { + // Try select GC ergonomically + select_gc_ergonomically(); + + if (is_no_gc_selected()) { + // Failed to select GC ergonomically + vm_exit_during_initialization("Garbage collector not selected " + "(default collector explicitly disabled)", NULL); + } + + // Succeeded to select GC ergonomically + _gc_selected_ergonomically = true; + } + + if (is_exactly_one_gc_selected()) { + // Exacly one GC selected + for (size_t i = 0; i < ARRAY_SIZE(SupportedGCs); i++) { + if (SupportedGCs[i]._flag) { + return &SupportedGCs[i]._arguments; + } + } + } + + // More than one GC selected + vm_exit_during_initialization("Multiple garbage collectors selected", NULL); + + return NULL; +} + +void GCConfig::initialize() { + assert(_arguments == NULL, "Already initialized"); + _arguments = select_gc(); +} + +bool GCConfig::is_gc_supported(CollectedHeap::Name name) { + for (size_t i = 0; i < ARRAY_SIZE(SupportedGCs); i++) { + if (SupportedGCs[i]._name == name) { + // Supported + return true; + } + } + + // Not supported + return false; +} + +bool GCConfig::is_gc_selected(CollectedHeap::Name name) { + for (size_t i = 0; i < ARRAY_SIZE(SupportedGCs); i++) { + if (SupportedGCs[i]._name == name && SupportedGCs[i]._flag) { + // Selected + return true; + } + } + + // Not selected + return false; +} + +bool GCConfig::is_gc_selected_ergonomically() { + return _gc_selected_ergonomically; +} + +GCArguments* GCConfig::arguments() { + assert(_arguments != NULL, "Not initialized"); + return _arguments; +} diff -r 88478047bc8f -r b786280276dc src/hotspot/share/gc/shared/gcConfig.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/share/gc/shared/gcConfig.hpp Wed Mar 28 11:38:47 2018 +0200 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2018, 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_GC_SHARED_GCCONFIG_HPP +#define SHARE_GC_SHARED_GCCONFIG_HPP + +#include "gc/shared/collectedHeap.hpp" +#include "memory/allocation.hpp" + +class GCArguments; + +class GCConfig : public AllStatic { +private: + static GCArguments* _arguments; + static bool _gc_selected_ergonomically; + + static bool is_no_gc_selected(); + static bool is_exactly_one_gc_selected(); + + static void select_gc_ergonomically(); + static GCArguments* select_gc(); + +public: + static void initialize(); + + static bool is_gc_supported(CollectedHeap::Name name); + static bool is_gc_selected(CollectedHeap::Name name); + static bool is_gc_selected_ergonomically(); + + static GCArguments* arguments(); +}; + +#endif // SHARE_GC_SHARED_GCCONFIG_HPP diff -r 88478047bc8f -r b786280276dc src/hotspot/share/memory/universe.cpp --- a/src/hotspot/share/memory/universe.cpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/memory/universe.cpp Wed Mar 28 11:38:47 2018 +0200 @@ -35,6 +35,7 @@ #include "gc/shared/cardTableBarrierSet.hpp" #include "gc/shared/collectedHeap.inline.hpp" #include "gc/shared/gcArguments.hpp" +#include "gc/shared/gcConfig.hpp" #include "gc/shared/gcLocker.hpp" #include "gc/shared/generation.hpp" #include "gc/shared/gcTraceTime.inline.hpp" @@ -745,8 +746,7 @@ CollectedHeap* Universe::create_heap() { assert(_collectedHeap == NULL, "Heap already created"); - assert(GCArguments::is_initialized(), "GC must be initialized here"); - return GCArguments::arguments()->create_heap(); + return GCConfig::arguments()->create_heap(); } // Choose the heap base address and oop encoding mode diff -r 88478047bc8f -r b786280276dc src/hotspot/share/runtime/arguments.cpp --- a/src/hotspot/share/runtime/arguments.cpp Wed Mar 28 11:38:47 2018 +0200 +++ b/src/hotspot/share/runtime/arguments.cpp Wed Mar 28 11:38:47 2018 +0200 @@ -30,6 +30,7 @@ #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "gc/shared/gcArguments.hpp" +#include "gc/shared/gcConfig.hpp" #include "gc/shared/genCollectedHeap.hpp" #include "gc/shared/referenceProcessor.hpp" #include "gc/shared/taskqueue.hpp" @@ -1749,7 +1750,7 @@ // the alignments imposed by several sources: any requirements from the heap // itself, the collector policy and the maximum page size we may run the VM // with. - size_t heap_alignment = GCArguments::arguments()->conservative_max_heap_alignment(); + size_t heap_alignment = GCConfig::arguments()->conservative_max_heap_alignment(); _conservative_max_heap_alignment = MAX4(heap_alignment, (size_t)os::vm_allocation_granularity(), os::max_page_size(), @@ -1815,10 +1816,7 @@ } #endif - jint gc_result = GCArguments::initialize(); - if (gc_result != JNI_OK) { - return gc_result; - } + GCConfig::initialize(); #if COMPILER2_OR_JVMCI // Shared spaces work fine with other GCs but causes bytecode rewriting @@ -2176,26 +2174,6 @@ } #endif //INCLUDE_JVMCI -// Check consistency of GC selection -bool Arguments::check_gc_consistency() { - // Ensure that the user has not selected conflicting sets - // of collectors. - uint i = 0; - if (UseSerialGC) i++; - if (UseConcMarkSweepGC) i++; - if (UseParallelGC || UseParallelOldGC) i++; - if (UseG1GC) i++; - if (i > 1) { - jio_fprintf(defaultStream::error_stream(), - "Conflicting collector combinations in option list; " - "please refer to the release notes for the combinations " - "allowed\n"); - return false; - } - - return true; -} - // Check the consistency of vm_init_args bool Arguments::check_vm_args_consistency() { // Method for adding checks for flag consistency. @@ -2225,8 +2203,6 @@ FLAG_SET_DEFAULT(UseGCOverheadLimit, false); } - status = status && check_gc_consistency(); - // CMS space iteration, which FLSVerifyAllHeapreferences entails, // insists that we hold the requisite locks so that the iteration is // MT-safe. For the verification at start-up and shut-down, we don't @@ -4241,11 +4217,6 @@ set_shared_spaces_flags(); - // Check the GC selections again. - if (!check_gc_consistency()) { - return JNI_EINVAL; - } - if (TieredCompilation) { set_tiered_flags(); } else { @@ -4278,7 +4249,7 @@ // Set heap size based on available physical memory set_heap_size(); - GCArguments::arguments()->initialize_flags(); + GCConfig::arguments()->initialize(); // Initialize Metaspace flags and alignments Metaspace::ergo_initialize(); diff -r 88478047bc8f -r b786280276dc test/hotspot/jtreg/serviceability/sa/TestIntConstant.java --- a/test/hotspot/jtreg/serviceability/sa/TestIntConstant.java Wed Mar 28 11:38:47 2018 +0200 +++ b/test/hotspot/jtreg/serviceability/sa/TestIntConstant.java Wed Mar 28 11:38:47 2018 +0200 @@ -110,7 +110,7 @@ // with names and the values derived from enums and #define preprocessor // macros in hotspot. String[] defaultOutputStrings = - {"CollectedHeap::G1 3", + {"CollectedHeap::G1 4", "RUNNABLE 2", "Deoptimization::Reason_class_check 4", "InstanceKlass::_misc_is_anonymous 32",