8220597: ZGC: Convert ZForwarding to use ZAttachedArray
authorpliden
Mon, 18 Mar 2019 11:50:40 +0100
changeset 54172 f92f1f1045ad
parent 54171 07943af21b96
child 54173 e6a92f2f37a9
8220597: ZGC: Convert ZForwarding to use ZAttachedArray Reviewed-by: stefank, eosterlund
src/hotspot/share/gc/z/vmStructs_z.hpp
src/hotspot/share/gc/z/zForwarding.cpp
src/hotspot/share/gc/z/zForwarding.hpp
src/hotspot/share/gc/z/zForwarding.inline.hpp
test/hotspot/gtest/gc/z/test_zForwarding.cpp
--- a/src/hotspot/share/gc/z/vmStructs_z.hpp	Mon Mar 18 11:50:40 2019 +0100
+++ b/src/hotspot/share/gc/z/vmStructs_z.hpp	Mon Mar 18 11:50:40 2019 +0100
@@ -24,6 +24,7 @@
 #ifndef SHARE_GC_Z_VMSTRUCTS_Z_HPP
 #define SHARE_GC_Z_VMSTRUCTS_Z_HPP
 
+#include "gc/z/zAttachedArray.hpp"
 #include "gc/z/zCollectedHeap.hpp"
 #include "gc/z/zForwarding.hpp"
 #include "gc/z/zGranuleMap.hpp"
@@ -54,6 +55,7 @@
 };
 
 typedef ZGranuleMap<ZPage*> ZGranuleMapForPageTable;
+typedef ZAttachedArray<ZForwarding, ZForwardingEntry> ZAttachedArrayForForwarding;
 
 #define VM_STRUCTS_ZGC(nonstatic_field, volatile_nonstatic_field, static_field)                      \
   static_field(ZGlobalsForVMStructs,            _instance_p,          ZGlobalsForVMStructs*)         \
@@ -85,7 +87,7 @@
   nonstatic_field(ZVirtualMemory,               _start,               uintptr_t)                     \
   nonstatic_field(ZVirtualMemory,               _end,                 uintptr_t)                     \
                                                                                                      \
-  nonstatic_field(ZForwarding,                  _nentries,            const uint32_t)                \
+  nonstatic_field(ZForwarding,                  _entries,             const ZAttachedArrayForForwarding) \
                                                                                                      \
   nonstatic_field(ZPhysicalMemoryManager,       _max_capacity,        const size_t)                  \
   nonstatic_field(ZPhysicalMemoryManager,       _capacity,            size_t)
@@ -115,6 +117,7 @@
   declare_toplevel_type(ZPage)                                                                       \
   declare_toplevel_type(ZPageAllocator)                                                              \
   declare_toplevel_type(ZPageTable)                                                                  \
+  declare_toplevel_type(ZAttachedArrayForForwarding)                                                 \
   declare_toplevel_type(ZGranuleMapForPageTable)                                                     \
   declare_toplevel_type(ZVirtualMemory)                                                              \
   declare_toplevel_type(ZForwardingTable)                                                            \
--- a/src/hotspot/share/gc/z/zForwarding.cpp	Mon Mar 18 11:50:40 2019 +0100
+++ b/src/hotspot/share/gc/z/zForwarding.cpp	Mon Mar 18 11:50:40 2019 +0100
@@ -28,41 +28,35 @@
 #include "memory/allocation.hpp"
 #include "utilities/debug.hpp"
 
-ZForwarding::ZForwarding(ZPage* page, uint32_t nentries) :
-    _virtual(page->virtual_memory()),
-    _object_alignment_shift(page->object_alignment_shift()),
-    _nentries(nentries),
-    _page(page),
-    _refcount(1),
-    _pinned(false) {}
-
 ZForwarding* ZForwarding::create(ZPage* page) {
-  assert(page->live_objects() > 0, "Invalid value");
-
   // Allocate table for linear probing. The size of the table must be
   // a power of two to allow for quick and inexpensive indexing/masking.
   // The table is sized to have a load factor of 50%, i.e. sized to have
   // double the number of entries actually inserted.
+  assert(page->live_objects() > 0, "Invalid value");
   const uint32_t nentries = ZUtils::round_up_power_of_2(page->live_objects() * 2);
-  const size_t size = sizeof(ZForwarding) + (sizeof(ZForwardingEntry) * nentries);
-  uint8_t* const addr = NEW_C_HEAP_ARRAY(uint8_t, size, mtGC);
-  ZForwardingEntry* const entries = ::new (addr + sizeof(ZForwarding)) ZForwardingEntry[nentries];
-  ZForwarding* const forwarding = ::new (addr) ZForwarding(page, nentries);
-
-  return forwarding;
+  return ::new (AttachedArray::alloc(nentries)) ZForwarding(page, nentries);
 }
 
 void ZForwarding::destroy(ZForwarding* forwarding) {
-  FREE_C_HEAP_ARRAY(uint8_t, forwarding);
+  AttachedArray::free(forwarding);
 }
 
+ZForwarding::ZForwarding(ZPage* page, uint32_t nentries) :
+    _virtual(page->virtual_memory()),
+    _object_alignment_shift(page->object_alignment_shift()),
+    _entries(nentries),
+    _page(page),
+    _refcount(1),
+    _pinned(false) {}
+
 void ZForwarding::verify() const {
   guarantee(_refcount > 0, "Invalid refcount");
   guarantee(_page != NULL, "Invalid page");
 
   uint32_t live_objects = 0;
 
-  for (ZForwardingCursor i = 0; i < _nentries; i++) {
+  for (ZForwardingCursor i = 0; i < _entries.length(); i++) {
     const ZForwardingEntry entry = at(&i);
     if (entry.is_empty()) {
       // Skip empty entries
@@ -73,7 +67,7 @@
     guarantee(entry.from_index() < _page->object_max_count(), "Invalid from index");
 
     // Check for duplicates
-    for (ZForwardingCursor j = i + 1; j < _nentries; j++) {
+    for (ZForwardingCursor j = i + 1; j < _entries.length(); j++) {
       const ZForwardingEntry other = at(&j);
       guarantee(entry.from_index() != other.from_index(), "Duplicate from");
       guarantee(entry.to_offset() != other.to_offset(), "Duplicate to");
--- a/src/hotspot/share/gc/z/zForwarding.hpp	Mon Mar 18 11:50:40 2019 +0100
+++ b/src/hotspot/share/gc/z/zForwarding.hpp	Mon Mar 18 11:50:40 2019 +0100
@@ -24,6 +24,7 @@
 #ifndef SHARE_GC_Z_ZFORWARDING_HPP
 #define SHARE_GC_Z_ZFORWARDING_HPP
 
+#include "gc/z/zAttachedArray.hpp"
 #include "gc/z/zForwardingEntry.hpp"
 #include "gc/z/zVirtualMemory.hpp"
 
@@ -36,9 +37,11 @@
   friend class ZForwardingTest;
 
 private:
+  typedef ZAttachedArray<ZForwarding, ZForwardingEntry> AttachedArray;
+
   const ZVirtualMemory _virtual;
   const size_t         _object_alignment_shift;
-  const uint32_t       _nentries;
+  const AttachedArray  _entries;
   ZPage*               _page;
   volatile uint32_t    _refcount;
   volatile bool        _pinned;
--- a/src/hotspot/share/gc/z/zForwarding.inline.hpp	Mon Mar 18 11:50:40 2019 +0100
+++ b/src/hotspot/share/gc/z/zForwarding.inline.hpp	Mon Mar 18 11:50:40 2019 +0100
@@ -24,6 +24,7 @@
 #ifndef SHARE_GC_Z_ZFORWARDING_INLINE_HPP
 #define SHARE_GC_Z_ZFORWARDING_INLINE_HPP
 
+#include "gc/z/zAttachedArray.inline.hpp"
 #include "gc/z/zForwarding.hpp"
 #include "gc/z/zGlobals.hpp"
 #include "gc/z/zHash.inline.hpp"
@@ -90,7 +91,7 @@
 }
 
 inline ZForwardingEntry* ZForwarding::entries() const {
-  return reinterpret_cast<ZForwardingEntry*>(reinterpret_cast<uintptr_t>(this) + sizeof(*this));
+  return _entries(this);
 }
 
 inline ZForwardingEntry ZForwarding::at(ZForwardingCursor* cursor) const {
@@ -98,14 +99,14 @@
 }
 
 inline ZForwardingEntry ZForwarding::first(uintptr_t from_index, ZForwardingCursor* cursor) const {
-  const uint32_t mask = _nentries - 1;
+  const uint32_t mask = _entries.length() - 1;
   const uint32_t hash = ZHash::uint32_to_uint32((uint32_t)from_index);
   *cursor = hash & mask;
   return at(cursor);
 }
 
 inline ZForwardingEntry ZForwarding::next(ZForwardingCursor* cursor) const {
-  const uint32_t mask = _nentries - 1;
+  const uint32_t mask = _entries.length() - 1;
   *cursor = (*cursor + 1) & mask;
   return at(cursor);
 }
@@ -135,7 +136,7 @@
 
 inline uintptr_t ZForwarding::insert(uintptr_t from_index, uintptr_t to_offset, ZForwardingCursor* cursor) {
   const ZForwardingEntry new_entry(from_index, to_offset);
-  const ZForwardingEntry old_entry; // empty
+  const ZForwardingEntry old_entry; // Empty
 
   for (;;) {
     const ZForwardingEntry prev_entry = Atomic::cmpxchg(new_entry, entries() + *cursor, old_entry);
--- a/test/hotspot/gtest/gc/z/test_zForwarding.cpp	Mon Mar 18 11:50:40 2019 +0100
+++ b/test/hotspot/gtest/gc/z/test_zForwarding.cpp	Mon Mar 18 11:50:40 2019 +0100
@@ -60,11 +60,11 @@
   // Test functions
 
   static void setup(ZForwarding* forwarding) {
-    EXPECT_PRED1(is_power_of_2, forwarding->_nentries) << CAPTURE(forwarding->_nentries);
+    EXPECT_PRED1(is_power_of_2, forwarding->_entries.length()) << CAPTURE(forwarding->_entries.length());
   }
 
   static void find_empty(ZForwarding* forwarding) {
-    uint32_t size = forwarding->_nentries;
+    uint32_t size = forwarding->_entries.length();
     uint32_t entries_to_check = size * 2;
 
     for (uint32_t i = 0; i < entries_to_check; i++) {
@@ -77,7 +77,7 @@
   }
 
   static void find_full(ZForwarding* forwarding) {
-    uint32_t size = forwarding->_nentries;
+    uint32_t size = forwarding->_entries.length();
     uint32_t entries_to_populate = size;
 
     // Populate
@@ -104,7 +104,7 @@
   }
 
   static void find_every_other(ZForwarding* forwarding) {
-    uint32_t size = forwarding->_nentries;
+    uint32_t size = forwarding->_entries.length();
     uint32_t entries_to_populate = size / 2;
 
     // Populate even from indices