Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8255234: ZGC: Bulk allocate forwarding data structures #804

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/hotspot/share/gc/z/zAttachedArray.hpp
Original file line number Diff line number Diff line change
@@ -35,8 +35,9 @@ class ZAttachedArray {
static size_t array_size(size_t length);

public:
static size_t size(size_t length);
static void* alloc(void* placement, size_t length);
template <typename Allocator>
static void* alloc(Allocator* allocator, size_t length);

static void* alloc(size_t length);
static void free(ObjectT* obj);

26 changes: 17 additions & 9 deletions src/hotspot/share/gc/z/zAttachedArray.inline.hpp
Original file line number Diff line number Diff line change
@@ -39,20 +39,28 @@ inline size_t ZAttachedArray<ObjectT, ArrayT>::array_size(size_t length) {
}

template <typename ObjectT, typename ArrayT>
inline size_t ZAttachedArray<ObjectT, ArrayT>::size(size_t length) {
return object_size() + array_size(length);
}
template <typename Allocator>
inline void* ZAttachedArray<ObjectT, ArrayT>::alloc(Allocator* allocator, size_t length) {
// Allocate memory for object and array
const size_t size = object_size() + array_size(length);
void* const addr = allocator->alloc(size);

template <typename ObjectT, typename ArrayT>
inline void* ZAttachedArray<ObjectT, ArrayT>::alloc(void* placement, size_t length) {
::new (reinterpret_cast<char*>(placement) + object_size()) ArrayT[length];
return placement;
// Placement new array
void* const array_addr = reinterpret_cast<char*>(addr) + object_size();
::new (array_addr) ArrayT[length];

// Return pointer to object
return addr;
}

template <typename ObjectT, typename ArrayT>
inline void* ZAttachedArray<ObjectT, ArrayT>::alloc(size_t length) {
void* const placement = AllocateHeap(size(length), mtGC);
return alloc(placement, length);
struct Allocator {
void* alloc(size_t size) const {
return AllocateHeap(size, mtGC);
}
} allocator;
return alloc(&allocator, length);
}

template <typename ObjectT, typename ArrayT>
1 change: 1 addition & 0 deletions src/hotspot/share/gc/z/zForwarding.hpp
Original file line number Diff line number Diff line change
@@ -58,6 +58,7 @@ class ZForwarding {
ZForwarding(ZPage* page, size_t nentries);

public:
static uint32_t nentries(const ZPage* page);
static ZForwarding* alloc(ZForwardingAllocator* allocator, ZPage* page);

uintptr_t start() const;
17 changes: 14 additions & 3 deletions src/hotspot/share/gc/z/zForwarding.inline.hpp
Original file line number Diff line number Diff line change
@@ -33,11 +33,22 @@
#include "gc/z/zVirtualMemory.inline.hpp"
#include "runtime/atomic.hpp"
#include "utilities/debug.hpp"
#include "utilities/powerOfTwo.hpp"

inline uint32_t ZForwarding::nentries(const ZPage* page) {
// The number returned by the function is used to size the hash table of
// forwarding entries for this page. This hash table uses linear probing.
// The size of the table must be a power of two to allow for quick and
// inexpensive indexing/masking. The table is also sized to have a load
// factor of 50%, i.e. sized to have double the number of entries actually
// inserted, to allow for good lookup/insert performance.
return round_up_power_of_2(page->live_objects() * 2);
}

inline ZForwarding* ZForwarding::alloc(ZForwardingAllocator* allocator, ZPage* page) {
const size_t nentries = page->forwarding_entries();
void* const placement = allocator->alloc(AttachedArray::size(nentries));
return ::new (AttachedArray::alloc(placement, nentries)) ZForwarding(page, nentries);
const size_t nentries = ZForwarding::nentries(page);
void* const addr = AttachedArray::alloc(allocator, nentries);
return ::new (addr) ZForwarding(page, nentries);
}

inline ZForwarding::ZForwarding(ZPage* page, size_t nentries) :
1 change: 0 additions & 1 deletion src/hotspot/share/gc/z/zPage.hpp
Original file line number Diff line number Diff line change
@@ -98,7 +98,6 @@ class ZPage : public CHeapObj<mtGC> {
void inc_live(uint32_t objects, size_t bytes);
uint32_t live_objects() const;
size_t live_bytes() const;
uint32_t forwarding_entries() const;

void object_iterate(ObjectClosure* cl);

13 changes: 0 additions & 13 deletions src/hotspot/share/gc/z/zPage.inline.hpp
Original file line number Diff line number Diff line change
@@ -35,7 +35,6 @@
#include "runtime/os.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
#include "utilities/powerOfTwo.hpp"

inline uint8_t ZPage::type_from_size(size_t size) const {
if (size == ZPageSizeSmall) {
@@ -213,18 +212,6 @@ inline size_t ZPage::live_bytes() const {
return _livemap.live_bytes();
}

inline uint32_t ZPage::forwarding_entries() const {
assert(live_objects() > 0, "Invalid value");

// The number returned by the function is used to size the hash table of
// forwarding entries for this page. This hash table uses linear probing.
// The size of the table must be a power of two to allow for quick and
// inexpensive indexing/masking. The table is also sized to have a load
// factor of 50%, i.e. sized to have double the number of entries actually
// inserted, to allow for good lookup/insert performance.
return round_up_power_of_2(live_objects() * 2);
}

inline void ZPage::object_iterate(ObjectClosure* cl) {
_livemap.iterate(cl, ZAddress::good(start()), object_alignment_shift());
}
4 changes: 3 additions & 1 deletion src/hotspot/share/gc/z/zRelocationSetSelector.cpp
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@

#include "precompiled.hpp"
#include "gc/z/zArray.inline.hpp"
#include "gc/z/zForwarding.inline.hpp"
#include "gc/z/zPage.inline.hpp"
#include "gc/z/zRelocationSet.hpp"
#include "gc/z/zRelocationSetSelector.inline.hpp"
@@ -52,6 +53,7 @@ ZRelocationSetSelectorGroup::ZRelocationSetSelectorGroup(const char* name,
_fragmentation_limit(page_size * (ZFragmentationLimit / 100)),
_registered_pages(),
_sorted_pages(NULL),
_nselected(0),
_forwarding_entries(0),
_stats() {}

@@ -153,7 +155,7 @@ void ZRelocationSetSelectorGroup::select_inner() {
// Add page to the candidate relocation set
ZPage* const page = _sorted_pages[from - 1];
from_live_bytes += page->live_bytes();
from_forwarding_entries += page->forwarding_entries();
from_forwarding_entries += ZForwarding::nentries(page);

// Calculate the maximum number of pages needed by the candidate relocation set.
// By subtracting the object size limit from the pages size we get the maximum
3 changes: 2 additions & 1 deletion test/hotspot/gtest/gc/z/test_zForwarding.cpp
Original file line number Diff line number Diff line change
@@ -160,7 +160,8 @@ class ZForwardingTest : public Test {

// Setup allocator
ZForwardingAllocator allocator;
allocator.reset((sizeof(ZForwarding)) + (page.forwarding_entries() * sizeof(ZForwardingEntry)));
const uint32_t nentries = ZForwarding::nentries(&page);
allocator.reset((sizeof(ZForwarding)) + (nentries * sizeof(ZForwardingEntry)));

// Setup forwarding
ZForwarding* const forwarding = ZForwarding::alloc(&allocator, &page);