diff a/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp
--- /dev/null
+++ b/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp
@@ -0,0 +1,146 @@
+/*
+ * Copyright Amazon.com Inc. 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/shenandoah/shenandoahAgeCensus.hpp"
+#include "gc/shenandoah/heuristics/shenandoahGlobalHeuristics.hpp"
+#include "gc/shenandoah/shenandoahFreeSet.hpp"
+#include "gc/shenandoah/shenandoahGlobalGeneration.hpp"
+#include "gc/shenandoah/shenandoahHeap.hpp"
+#include "gc/shenandoah/shenandoahHeapRegion.inline.hpp"
+#include "gc/shenandoah/shenandoahUtils.hpp"
+#include "gc/shenandoah/shenandoahVerifier.hpp"
+
+
+const char* ShenandoahGlobalGeneration::name() const {
+  return type() == NON_GEN ? "" : "Global";
+}
+
+size_t ShenandoahGlobalGeneration::max_capacity() const {
+  return ShenandoahHeap::heap()->max_capacity();
+}
+
+size_t ShenandoahGlobalGeneration::used_regions() const {
+  ShenandoahGenerationalHeap* heap = ShenandoahGenerationalHeap::heap();
+  assert(heap->mode()->is_generational(), "Region usage accounting is only for generational mode");
+  return heap->old_generation()->used_regions() + heap->young_generation()->used_regions();
+}
+
+size_t ShenandoahGlobalGeneration::used_regions_size() const {
+  return ShenandoahHeap::heap()->capacity();
+}
+
+size_t ShenandoahGlobalGeneration::soft_max_capacity() const {
+  return ShenandoahHeap::heap()->soft_max_capacity();
+}
+
+size_t ShenandoahGlobalGeneration::available() const {
+  return ShenandoahHeap::heap()->free_set()->available();
+}
+
+size_t ShenandoahGlobalGeneration::soft_available() const {
+  size_t available = this->available();
+
+  // Make sure the code below treats available without the soft tail.
+  assert(max_capacity() >= soft_max_capacity(), "Max capacity must be greater than soft max capacity.");
+  size_t soft_tail = max_capacity() - soft_max_capacity();
+  return (available > soft_tail) ? (available - soft_tail) : 0;
+}
+
+void ShenandoahGlobalGeneration::set_concurrent_mark_in_progress(bool in_progress) {
+  ShenandoahHeap* heap = ShenandoahHeap::heap();
+  if (in_progress && heap->mode()->is_generational()) {
+    // Global collection has preempted an old generation mark. This is fine
+    // because the global generation includes the old generation, but we
+    // want the global collect to start from a clean slate and we don't want
+    // any stale state in the old generation.
+    assert(!heap->is_concurrent_old_mark_in_progress(), "Old cycle should not be running.");
+  }
+
+  heap->set_concurrent_young_mark_in_progress(in_progress);
+}
+
+bool ShenandoahGlobalGeneration::contains(ShenandoahAffiliation affiliation) const {
+  return true;
+}
+
+bool ShenandoahGlobalGeneration::contains(ShenandoahHeapRegion* region) const {
+  return true;
+}
+
+void ShenandoahGlobalGeneration::parallel_heap_region_iterate(ShenandoahHeapRegionClosure* cl) {
+  ShenandoahHeap::heap()->parallel_heap_region_iterate(cl);
+}
+
+void ShenandoahGlobalGeneration::heap_region_iterate(ShenandoahHeapRegionClosure* cl) {
+  ShenandoahHeap::heap()->heap_region_iterate(cl);
+}
+
+bool ShenandoahGlobalGeneration::is_concurrent_mark_in_progress() {
+  ShenandoahHeap* heap = ShenandoahHeap::heap();
+  return heap->is_concurrent_mark_in_progress();
+}
+
+ShenandoahHeuristics* ShenandoahGlobalGeneration::initialize_heuristics(ShenandoahMode* gc_mode) {
+  if (gc_mode->is_generational()) {
+    _heuristics = new ShenandoahGlobalHeuristics(this);
+  } else {
+    _heuristics = gc_mode->initialize_heuristics(this);
+  }
+
+  _heuristics->set_guaranteed_gc_interval(ShenandoahGuaranteedGCInterval);
+  confirm_heuristics_mode();
+  return _heuristics;
+}
+
+void ShenandoahGlobalGeneration::set_mark_complete() {
+  ShenandoahGeneration::set_mark_complete();
+  if (ShenandoahHeap::heap()->mode()->is_generational()) {
+    ShenandoahGenerationalHeap* heap = ShenandoahGenerationalHeap::heap();
+    heap->young_generation()->set_mark_complete();
+    heap->old_generation()->set_mark_complete();
+  }
+}
+
+void ShenandoahGlobalGeneration::set_mark_incomplete() {
+  ShenandoahGeneration::set_mark_incomplete();
+  if (ShenandoahHeap::heap()->mode()->is_generational()) {
+    ShenandoahGenerationalHeap* heap = ShenandoahGenerationalHeap::heap();
+    heap->young_generation()->set_mark_incomplete();
+    heap->old_generation()->set_mark_incomplete();
+  }
+}
+
+void ShenandoahGlobalGeneration::prepare_gc() {
+  ShenandoahGeneration::prepare_gc();
+
+  if (ShenandoahHeap::heap()->mode()->is_generational()) {
+    assert(type() == GLOBAL, "Unexpected generation type");
+    // Clear any stale/partial local census data before the start of a
+    // new marking cycle
+    ShenandoahGenerationalHeap::heap()->age_census()->reset_local();
+  } else {
+    assert(type() == NON_GEN, "Unexpected generation type");
+  }
+}
