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