8232235: ZGC: Move ZValue inline funtions to zValue.inline.hpp
authorpliden
Mon, 21 Oct 2019 09:56:43 +0200
changeset 58705 f5662bdbee4a
parent 58704 8b16701b4636
child 58706 d8e211419aaf
8232235: ZGC: Move ZValue inline funtions to zValue.inline.hpp Reviewed-by: tschatzl
src/hotspot/share/gc/z/zObjectAllocator.cpp
src/hotspot/share/gc/z/zObjectAllocator.hpp
src/hotspot/share/gc/z/zPageCache.cpp
src/hotspot/share/gc/z/zPageCache.inline.hpp
src/hotspot/share/gc/z/zReferenceProcessor.cpp
src/hotspot/share/gc/z/zRelocate.cpp
src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp
src/hotspot/share/gc/z/zValue.hpp
src/hotspot/share/gc/z/zValue.inline.hpp
src/hotspot/share/gc/z/zWeakRootsProcessor.hpp
--- a/src/hotspot/share/gc/z/zObjectAllocator.cpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zObjectAllocator.cpp	Mon Oct 21 09:56:43 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -30,6 +30,7 @@
 #include "gc/z/zStat.hpp"
 #include "gc/z/zThread.hpp"
 #include "gc/z/zUtils.inline.hpp"
+#include "gc/z/zValue.inline.hpp"
 #include "logging/log.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/safepoint.hpp"
--- a/src/hotspot/share/gc/z/zObjectAllocator.hpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zObjectAllocator.hpp	Mon Oct 21 09:56:43 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
--- a/src/hotspot/share/gc/z/zPageCache.cpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zPageCache.cpp	Mon Oct 21 09:56:43 2019 +0200
@@ -27,6 +27,7 @@
 #include "gc/z/zPage.inline.hpp"
 #include "gc/z/zPageCache.hpp"
 #include "gc/z/zStat.hpp"
+#include "gc/z/zValue.inline.hpp"
 #include "logging/log.hpp"
 
 static const ZStatCounter ZCounterPageCacheHitL1("Memory", "Page Cache Hit L1", ZStatUnitOpsPerSecond);
--- a/src/hotspot/share/gc/z/zPageCache.inline.hpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zPageCache.inline.hpp	Mon Oct 21 09:56:43 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -26,6 +26,7 @@
 
 #include "gc/z/zList.inline.hpp"
 #include "gc/z/zPageCache.hpp"
+#include "gc/z/zValue.inline.hpp"
 
 inline size_t ZPageCache::available() const {
   return _available;
--- a/src/hotspot/share/gc/z/zReferenceProcessor.cpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zReferenceProcessor.cpp	Mon Oct 21 09:56:43 2019 +0200
@@ -32,6 +32,7 @@
 #include "gc/z/zTask.hpp"
 #include "gc/z/zTracer.inline.hpp"
 #include "gc/z/zUtils.inline.hpp"
+#include "gc/z/zValue.inline.hpp"
 #include "memory/universe.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/share/gc/z/zRelocate.cpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zRelocate.cpp	Mon Oct 21 09:56:43 2019 +0200
@@ -33,6 +33,7 @@
 #include "gc/z/zRootsIterator.hpp"
 #include "gc/z/zStat.hpp"
 #include "gc/z/zTask.hpp"
+#include "gc/z/zThread.hpp"
 #include "gc/z/zThreadLocalAllocBuffer.hpp"
 #include "gc/z/zWorkers.hpp"
 #include "logging/log.hpp"
--- a/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zThreadLocalAllocBuffer.cpp	Mon Oct 21 09:56:43 2019 +0200
@@ -24,6 +24,7 @@
 #include "precompiled.hpp"
 #include "gc/z/zAddress.inline.hpp"
 #include "gc/z/zThreadLocalAllocBuffer.hpp"
+#include "gc/z/zValue.inline.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/thread.hpp"
 
--- a/src/hotspot/share/gc/z/zValue.hpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zValue.hpp	Mon Oct 21 09:56:43 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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,13 +25,11 @@
 #define SHARE_GC_Z_ZVALUE_HPP
 
 #include "memory/allocation.hpp"
-#include "gc/z/zCPU.hpp"
-#include "gc/z/zGlobals.hpp"
-#include "gc/z/zNUMA.hpp"
-#include "gc/z/zThread.hpp"
-#include "gc/z/zUtils.hpp"
-#include "runtime/globals.hpp"
-#include "utilities/align.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+//
+// Storage
+//
 
 template <typename S>
 class ZValueStorage : public AllStatic {
@@ -42,202 +40,93 @@
 public:
   static const size_t offset = 4 * K;
 
-  static uintptr_t alloc(size_t size) {
-    guarantee(size <= offset, "Allocation too large");
-
-    // Allocate entry in existing memory block
-    const uintptr_t addr = align_up(_top, S::alignment());
-    _top = addr + size;
-
-    if (_top < _end) {
-      // Success
-      return addr;
-    }
-
-    // Allocate new block of memory
-    const size_t block_alignment = offset;
-    const size_t block_size = offset * S::count();
-    _top = ZUtils::alloc_aligned(block_alignment, block_size);
-    _end = _top + offset;
-
-    // Retry allocation
-    return alloc(size);
-  }
+  static uintptr_t alloc(size_t size);
 };
 
-template <typename T> uintptr_t ZValueStorage<T>::_end = 0;
-template <typename T> uintptr_t ZValueStorage<T>::_top = 0;
-
 class ZContendedStorage : public ZValueStorage<ZContendedStorage> {
 public:
-  static size_t alignment() {
-    return ZCacheLineSize;
-  }
-
-  static uint32_t count() {
-    return 1;
-  }
-
-  static uint32_t id() {
-    return 0;
-  }
+  static size_t alignment();
+  static uint32_t count();
+  static uint32_t id();
 };
 
 class ZPerCPUStorage : public ZValueStorage<ZPerCPUStorage> {
 public:
-  static size_t alignment() {
-    return sizeof(uintptr_t);
-  }
-
-  static uint32_t count() {
-    return ZCPU::count();
-  }
-
-  static uint32_t id() {
-    return ZCPU::id();
-  }
+  static size_t alignment();
+  static uint32_t count();
+  static uint32_t id();
 };
 
 class ZPerNUMAStorage : public ZValueStorage<ZPerNUMAStorage> {
 public:
-  static size_t alignment() {
-    return sizeof(uintptr_t);
-  }
-
-  static uint32_t count() {
-    return ZNUMA::count();
-  }
-
-  static uint32_t id() {
-    return ZNUMA::id();
-  }
+  static size_t alignment();
+  static uint32_t count();
+  static uint32_t id();
 };
 
 class ZPerWorkerStorage : public ZValueStorage<ZPerWorkerStorage> {
 public:
-  static size_t alignment() {
-    return sizeof(uintptr_t);
-  }
-
-  static uint32_t count() {
-    return MAX2(ParallelGCThreads, ConcGCThreads);
-  }
-
-  static uint32_t id() {
-    return ZThread::worker_id();
-  }
+  static size_t alignment();
+  static uint32_t count();
+  static uint32_t id();
 };
 
-template <typename S, typename T>
-class ZValueIterator;
+//
+// Value
+//
 
 template <typename S, typename T>
 class ZValue : public CHeapObj<mtGC> {
 private:
   const uintptr_t _addr;
 
-  uintptr_t value_addr(uint32_t value_id) const {
-    return _addr + (value_id * S::offset);
-  }
+  uintptr_t value_addr(uint32_t value_id) const;
 
 public:
-  ZValue() :
-      _addr(S::alloc(sizeof(T))) {
-    // Initialize all instances
-    ZValueIterator<S, T> iter(this);
-    for (T* addr; iter.next(&addr);) {
-      ::new (addr) T;
-    }
-  }
+  ZValue();
+  ZValue(const T& value);
 
-  ZValue(const T& value) :
-      _addr(S::alloc(sizeof(T))) {
-    // Initialize all instances
-    ZValueIterator<S, T> iter(this);
-    for (T* addr; iter.next(&addr);) {
-      ::new (addr) T(value);
-    }
-  }
-
-  // Not implemented
-  ZValue(const ZValue<S, T>& value);
-  ZValue<S, T>& operator=(const ZValue<S, T>& value);
+  const T* addr(uint32_t value_id = S::id()) const;
+  T* addr(uint32_t value_id = S::id());
 
-  const T* addr(uint32_t value_id = S::id()) const {
-    return reinterpret_cast<const T*>(value_addr(value_id));
-  }
-
-  T* addr(uint32_t value_id = S::id()) {
-    return reinterpret_cast<T*>(value_addr(value_id));
-  }
-
-  const T& get(uint32_t value_id = S::id()) const {
-    return *addr(value_id);
-  }
+  const T& get(uint32_t value_id = S::id()) const;
+  T& get(uint32_t value_id = S::id());
 
-  T& get(uint32_t value_id = S::id()) {
-    return *addr(value_id);
-  }
-
-  void set(const T& value, uint32_t value_id = S::id()) {
-    get(value_id) = value;
-  }
-
-  void set_all(const T& value) {
-    ZValueIterator<S, T> iter(this);
-    for (T* addr; iter.next(&addr);) {
-      *addr = value;
-    }
-  }
+  void set(const T& value, uint32_t value_id = S::id());
+  void set_all(const T& value);
 };
 
 template <typename T>
 class ZContended : public ZValue<ZContendedStorage, T> {
 public:
-  ZContended() :
-      ZValue<ZContendedStorage, T>() {}
-
-  ZContended(const T& value) :
-      ZValue<ZContendedStorage, T>(value) {}
-
-  using ZValue<ZContendedStorage, T>::operator=;
+  ZContended();
+  ZContended(const T& value);
 };
 
 template <typename T>
 class ZPerCPU : public ZValue<ZPerCPUStorage, T> {
 public:
-  ZPerCPU() :
-      ZValue<ZPerCPUStorage, T>() {}
-
-  ZPerCPU(const T& value) :
-      ZValue<ZPerCPUStorage, T>(value) {}
-
-  using ZValue<ZPerCPUStorage, T>::operator=;
+  ZPerCPU();
+  ZPerCPU(const T& value);
 };
 
 template <typename T>
 class ZPerNUMA : public ZValue<ZPerNUMAStorage, T> {
 public:
-  ZPerNUMA() :
-      ZValue<ZPerNUMAStorage, T>() {}
-
-  ZPerNUMA(const T& value) :
-      ZValue<ZPerNUMAStorage, T>(value) {}
-
-  using ZValue<ZPerNUMAStorage, T>::operator=;
+  ZPerNUMA();
+  ZPerNUMA(const T& value);
 };
 
 template <typename T>
 class ZPerWorker : public ZValue<ZPerWorkerStorage, T> {
 public:
-  ZPerWorker() :
-      ZValue<ZPerWorkerStorage, T>() {}
+  ZPerWorker();
+  ZPerWorker(const T& value);
+};
 
-  ZPerWorker(const T& value) :
-      ZValue<ZPerWorkerStorage, T>(value) {}
-
-  using ZValue<ZPerWorkerStorage, T>::operator=;
-};
+//
+// Iterator
+//
 
 template <typename S, typename T>
 class ZValueIterator {
@@ -246,38 +135,27 @@
   uint32_t            _value_id;
 
 public:
-  ZValueIterator(ZValue<S, T>* value) :
-      _value(value),
-      _value_id(0) {}
+  ZValueIterator(ZValue<S, T>* value);
 
-  bool next(T** value) {
-    if (_value_id < S::count()) {
-      *value = _value->addr(_value_id++);
-      return true;
-    }
-    return false;
-  }
+  bool next(T** value);
 };
 
 template <typename T>
 class ZPerCPUIterator : public ZValueIterator<ZPerCPUStorage, T> {
 public:
-  ZPerCPUIterator(ZPerCPU<T>* value) :
-      ZValueIterator<ZPerCPUStorage, T>(value) {}
+  ZPerCPUIterator(ZPerCPU<T>* value);
 };
 
 template <typename T>
 class ZPerNUMAIterator : public ZValueIterator<ZPerNUMAStorage, T> {
 public:
-  ZPerNUMAIterator(ZPerNUMA<T>* value) :
-      ZValueIterator<ZPerNUMAStorage, T>(value) {}
+  ZPerNUMAIterator(ZPerNUMA<T>* value);
 };
 
 template <typename T>
 class ZPerWorkerIterator : public ZValueIterator<ZPerWorkerStorage, T> {
 public:
-  ZPerWorkerIterator(ZPerWorker<T>* value) :
-      ZValueIterator<ZPerWorkerStorage, T>(value) {}
+  ZPerWorkerIterator(ZPerWorker<T>* value);
 };
 
 template <typename S, typename T>
@@ -287,38 +165,27 @@
   uint32_t                  _value_id;
 
 public:
-  ZValueConstIterator(const ZValue<S, T>* value) :
-      _value(value),
-      _value_id(0) {}
+  ZValueConstIterator(const ZValue<S, T>* value);
 
-  bool next(const T** value) {
-    if (_value_id < S::count()) {
-      *value = _value->addr(_value_id++);
-      return true;
-    }
-    return false;
-  }
+  bool next(const T** value);
 };
 
 template <typename T>
 class ZPerCPUConstIterator : public ZValueConstIterator<ZPerCPUStorage, T> {
 public:
-  ZPerCPUConstIterator(const ZPerCPU<T>* value) :
-      ZValueConstIterator<ZPerCPUStorage, T>(value) {}
+  ZPerCPUConstIterator(const ZPerCPU<T>* value);
 };
 
 template <typename T>
 class ZPerNUMAConstIterator : public ZValueConstIterator<ZPerNUMAStorage, T> {
 public:
-  ZPerNUMAConstIterator(const ZPerNUMA<T>* value) :
-      ZValueConstIterator<ZPerNUMAStorage, T>(value) {}
+  ZPerNUMAConstIterator(const ZPerNUMA<T>* value);
 };
 
 template <typename T>
 class ZPerWorkerConstIterator : public ZValueConstIterator<ZPerWorkerStorage, T> {
 public:
-  ZPerWorkerConstIterator(const ZPerWorker<T>* value) :
-      ZValueConstIterator<ZPerWorkerStorage, T>(value) {}
+  ZPerWorkerConstIterator(const ZPerWorker<T>* value);
 };
 
 #endif // SHARE_GC_Z_ZVALUE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zValue.inline.hpp	Mon Oct 21 09:56:43 2019 +0200
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2015, 2019, 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_Z_ZVALUE_INLINE_HPP
+#define SHARE_GC_Z_ZVALUE_INLINE_HPP
+
+#include "gc/z/zCPU.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "gc/z/zThread.hpp"
+#include "gc/z/zUtils.hpp"
+#include "gc/z/zValue.hpp"
+#include "runtime/globals.hpp"
+#include "utilities/align.hpp"
+
+//
+// Storage
+//
+
+template <typename T> uintptr_t ZValueStorage<T>::_end = 0;
+template <typename T> uintptr_t ZValueStorage<T>::_top = 0;
+
+template <typename S>
+uintptr_t ZValueStorage<S>::alloc(size_t size) {
+  assert(size <= offset, "Allocation too large");
+
+  // Allocate entry in existing memory block
+  const uintptr_t addr = align_up(_top, S::alignment());
+  _top = addr + size;
+
+  if (_top < _end) {
+    // Success
+    return addr;
+  }
+
+  // Allocate new block of memory
+  const size_t block_alignment = offset;
+  const size_t block_size = offset * S::count();
+  _top = ZUtils::alloc_aligned(block_alignment, block_size);
+  _end = _top + offset;
+
+  // Retry allocation
+  return alloc(size);
+}
+
+inline size_t ZContendedStorage::alignment() {
+  return ZCacheLineSize;
+}
+
+inline uint32_t ZContendedStorage::count() {
+  return 1;
+}
+
+inline uint32_t ZContendedStorage::id() {
+  return 0;
+}
+
+inline size_t ZPerCPUStorage::alignment() {
+  return sizeof(uintptr_t);
+}
+
+inline uint32_t ZPerCPUStorage::count() {
+  return ZCPU::count();
+}
+
+inline uint32_t ZPerCPUStorage::id() {
+  return ZCPU::id();
+}
+
+inline size_t ZPerNUMAStorage::alignment() {
+  return sizeof(uintptr_t);
+}
+
+inline uint32_t ZPerNUMAStorage::count() {
+  return ZNUMA::count();
+}
+
+inline uint32_t ZPerNUMAStorage::id() {
+  return ZNUMA::id();
+}
+
+inline size_t ZPerWorkerStorage::alignment() {
+  return sizeof(uintptr_t);
+}
+
+inline uint32_t ZPerWorkerStorage::count() {
+  return MAX2(ParallelGCThreads, ConcGCThreads);
+}
+
+inline uint32_t ZPerWorkerStorage::id() {
+  return ZThread::worker_id();
+}
+
+//
+// Value
+//
+
+template <typename S, typename T>
+inline uintptr_t ZValue<S, T>::value_addr(uint32_t value_id) const {
+  return _addr + (value_id * S::offset);
+}
+
+template <typename S, typename T>
+inline ZValue<S, T>::ZValue() :
+    _addr(S::alloc(sizeof(T))) {
+  // Initialize all instances
+  ZValueIterator<S, T> iter(this);
+  for (T* addr; iter.next(&addr);) {
+    ::new (addr) T;
+  }
+}
+
+template <typename S, typename T>
+inline ZValue<S, T>::ZValue(const T& value) :
+    _addr(S::alloc(sizeof(T))) {
+  // Initialize all instances
+  ZValueIterator<S, T> iter(this);
+  for (T* addr; iter.next(&addr);) {
+    ::new (addr) T(value);
+  }
+}
+
+template <typename S, typename T>
+inline const T* ZValue<S, T>::addr(uint32_t value_id) const {
+  return reinterpret_cast<const T*>(value_addr(value_id));
+}
+
+template <typename S, typename T>
+inline T* ZValue<S, T>::addr(uint32_t value_id) {
+  return reinterpret_cast<T*>(value_addr(value_id));
+}
+
+template <typename S, typename T>
+inline const T& ZValue<S, T>::get(uint32_t value_id) const {
+  return *addr(value_id);
+}
+
+template <typename S, typename T>
+inline T& ZValue<S, T>::get(uint32_t value_id) {
+  return *addr(value_id);
+}
+
+template <typename S, typename T>
+inline void ZValue<S, T>::set(const T& value, uint32_t value_id) {
+  get(value_id) = value;
+}
+
+template <typename S, typename T>
+inline void ZValue<S, T>::set_all(const T& value) {
+  ZValueIterator<S, T> iter(this);
+  for (T* addr; iter.next(&addr);) {
+    *addr = value;
+  }
+}
+
+template <typename T>
+inline ZContended<T>::ZContended() :
+    ZValue<ZContendedStorage, T>() {}
+
+template <typename T>
+inline ZContended<T>::ZContended(const T& value) :
+    ZValue<ZContendedStorage, T>(value) {}
+
+template <typename T>
+inline ZPerCPU<T>::ZPerCPU() :
+    ZValue<ZPerCPUStorage, T>() {}
+
+template <typename T>
+inline ZPerCPU<T>::ZPerCPU(const T& value) :
+    ZValue<ZPerCPUStorage, T>(value) {}
+
+template <typename T>
+inline ZPerNUMA<T>::ZPerNUMA() :
+    ZValue<ZPerNUMAStorage, T>() {}
+
+template <typename T>
+inline ZPerNUMA<T>::ZPerNUMA(const T& value) :
+    ZValue<ZPerNUMAStorage, T>(value) {}
+
+template <typename T>
+inline ZPerWorker<T>::ZPerWorker() :
+    ZValue<ZPerWorkerStorage, T>() {}
+
+template <typename T>
+inline ZPerWorker<T>::ZPerWorker(const T& value) :
+    ZValue<ZPerWorkerStorage, T>(value) {}
+
+//
+// Iterator
+//
+
+template <typename S, typename T>
+inline ZValueIterator<S, T>::ZValueIterator(ZValue<S, T>* value) :
+    _value(value),
+    _value_id(0) {}
+
+template <typename S, typename T>
+inline bool ZValueIterator<S, T>::next(T** value) {
+  if (_value_id < S::count()) {
+    *value = _value->addr(_value_id++);
+    return true;
+  }
+  return false;
+}
+
+template <typename T>
+inline ZPerCPUIterator<T>::ZPerCPUIterator(ZPerCPU<T>* value) :
+    ZValueIterator<ZPerCPUStorage, T>(value) {}
+
+template <typename T>
+inline ZPerNUMAIterator<T>::ZPerNUMAIterator(ZPerNUMA<T>* value) :
+    ZValueIterator<ZPerNUMAStorage, T>(value) {}
+
+template <typename T>
+inline ZPerWorkerIterator<T>::ZPerWorkerIterator(ZPerWorker<T>* value) :
+    ZValueIterator<ZPerWorkerStorage, T>(value) {}
+
+template <typename S, typename T>
+inline ZValueConstIterator<S, T>::ZValueConstIterator(const ZValue<S, T>* value) :
+    _value(value),
+    _value_id(0) {}
+
+template <typename S, typename T>
+inline bool ZValueConstIterator<S, T>::next(const T** value) {
+  if (_value_id < S::count()) {
+    *value = _value->addr(_value_id++);
+    return true;
+  }
+  return false;
+}
+
+template <typename T>
+inline ZPerCPUConstIterator<T>::ZPerCPUConstIterator(const ZPerCPU<T>* value) :
+    ZValueConstIterator<ZPerCPUStorage, T>(value) {}
+
+template <typename T>
+inline ZPerNUMAConstIterator<T>::ZPerNUMAConstIterator(const ZPerNUMA<T>* value) :
+    ZValueConstIterator<ZPerNUMAStorage, T>(value) {}
+
+template <typename T>
+inline ZPerWorkerConstIterator<T>::ZPerWorkerConstIterator(const ZPerWorker<T>* value) :
+    ZValueConstIterator<ZPerWorkerStorage, T>(value) {}
+
+#endif // SHARE_GC_Z_ZVALUE_INLINE_HPP
--- a/src/hotspot/share/gc/z/zWeakRootsProcessor.hpp	Mon Oct 21 09:55:58 2019 +0200
+++ b/src/hotspot/share/gc/z/zWeakRootsProcessor.hpp	Mon Oct 21 09:56:43 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -24,8 +24,6 @@
 #ifndef SHARE_GC_Z_ZWEAKROOTSPROCESSOR_HPP
 #define SHARE_GC_Z_ZWEAKROOTSPROCESSOR_HPP
 
-#include "gc/z/zValue.hpp"
-
 class ZWorkers;
 
 class ZWeakRootsProcessor {