8220597: ZGC: Convert ZForwarding to use ZAttachedArray

Reviewed-by: stefank, eosterlund
This commit is contained in:
Per Lidén 2019-03-18 11:50:40 +01:00
parent 8aa6e7538c
commit 4a83447db2
5 changed files with 30 additions and 29 deletions

@ -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 @@ public:
};
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 @@ typedef ZGranuleMap<ZPage*> ZGranuleMapForPageTable;
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 @@ typedef ZGranuleMap<ZPage*> ZGranuleMapForPageTable;
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) \

@ -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 @@ void ZForwarding::verify() const {
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");

@ -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 @@ class ZForwarding {
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;

@ -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 void ZForwarding::release_page() {
}
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::at(ZForwardingCursor* cursor) const {
}
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 ZForwardingEntry ZForwarding::find(uintptr_t from_index, ZForwardingCurso
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);

@ -60,11 +60,11 @@ public:
// 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 @@ public:
}
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 @@ public:
}
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