8220597: ZGC: Convert ZForwarding to use ZAttachedArray
Reviewed-by: stefank, eosterlund
This commit is contained in:
parent
8aa6e7538c
commit
4a83447db2
src/hotspot/share/gc/z
test/hotspot/gtest/gc/z
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user