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; +}