8220588: ZGC: Convert ZRelocationSet to hold ZForwardings instead of ZPages
Reviewed-by: stefank, eosterlund
--- a/src/hotspot/share/gc/z/zDriver.cpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zDriver.cpp Mon Mar 18 11:50:39 2019 +0100
@@ -45,7 +45,6 @@
static const ZStatPhaseConcurrent ZPhaseConcurrentResetRelocationSet("Concurrent Reset Relocation Set");
static const ZStatPhaseConcurrent ZPhaseConcurrentDestroyDetachedPages("Concurrent Destroy Detached Pages");
static const ZStatPhaseConcurrent ZPhaseConcurrentSelectRelocationSet("Concurrent Select Relocation Set");
-static const ZStatPhaseConcurrent ZPhaseConcurrentPrepareRelocationSet("Concurrent Prepare Relocation Set");
static const ZStatPhasePause ZPhasePauseRelocateStart("Pause Relocate Start");
static const ZStatPhaseConcurrent ZPhaseConcurrentRelocated("Concurrent Relocate");
static const ZStatCriticalPhase ZCriticalPhaseGCLockerStall("GC Locker Stall", false /* verbose */);
@@ -317,11 +316,6 @@
ZHeap::heap()->select_relocation_set();
}
-void ZDriver::concurrent_prepare_relocation_set() {
- ZStatTimer timer(ZPhaseConcurrentPrepareRelocationSet);
- ZHeap::heap()->prepare_relocation_set();
-}
-
void ZDriver::pause_relocate_start() {
pause<VM_ZRelocateStart>();
}
@@ -393,13 +387,10 @@
// Phase 8: Concurrent Select Relocation Set
concurrent_select_relocation_set();
- // Phase 9: Concurrent Prepare Relocation Set
- concurrent_prepare_relocation_set();
-
- // Phase 10: Pause Relocate Start
+ // Phase 9: Pause Relocate Start
pause_relocate_start();
- // Phase 11: Concurrent Relocate
+ // Phase 10: Concurrent Relocate
concurrent_relocate();
}
--- a/src/hotspot/share/gc/z/zDriver.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zDriver.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -46,7 +46,6 @@
void concurrent_destroy_detached_pages();
void pause_verify();
void concurrent_select_relocation_set();
- void concurrent_prepare_relocation_set();
void pause_relocate_start();
void concurrent_relocate();
--- a/src/hotspot/share/gc/z/zForwarding.cpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zForwarding.cpp Mon Mar 18 11:50:39 2019 +0100
@@ -23,30 +23,32 @@
#include "precompiled.hpp"
#include "gc/z/zForwarding.inline.hpp"
+#include "gc/z/zPage.inline.hpp"
#include "gc/z/zUtils.inline.hpp"
#include "memory/allocation.hpp"
#include "utilities/debug.hpp"
-ZForwarding::ZForwarding(uintptr_t start, size_t object_alignment_shift, uint32_t nentries) :
- _start(start),
- _object_alignment_shift(object_alignment_shift),
+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(uintptr_t start, size_t object_alignment_shift, uint32_t live_objects) {
- assert(live_objects > 0, "Invalid value");
+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.
- const uint32_t nentries = ZUtils::round_up_power_of_2(live_objects * 2);
-
+ 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(start, object_alignment_shift, nentries);
+ ZForwarding* const forwarding = ::new (addr) ZForwarding(page, nentries);
+
return forwarding;
}
@@ -54,8 +56,11 @@
FREE_C_HEAP_ARRAY(uint8_t, forwarding);
}
-void ZForwarding::verify(uint32_t object_max_count, uint32_t live_objects) const {
- uint32_t count = 0;
+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++) {
const ZForwardingEntry entry = at(&i);
@@ -65,7 +70,7 @@
}
// Check from index
- guarantee(entry.from_index() < object_max_count, "Invalid from index");
+ guarantee(entry.from_index() < _page->object_max_count(), "Invalid from index");
// Check for duplicates
for (ZForwardingCursor j = i + 1; j < _nentries; j++) {
@@ -74,9 +79,9 @@
guarantee(entry.to_offset() != other.to_offset(), "Duplicate to");
}
- count++;
+ live_objects++;
}
- // Check number of non-null entries
- guarantee(live_objects == count, "Count mismatch");
+ // Check number of non-empty entries
+ guarantee(live_objects == _page->live_objects(), "Invalid number of entries");
}
--- a/src/hotspot/share/gc/z/zForwarding.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zForwarding.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -25,6 +25,9 @@
#define SHARE_GC_Z_ZFORWARDING_HPP
#include "gc/z/zForwardingEntry.hpp"
+#include "gc/z/zVirtualMemory.hpp"
+
+class ZPage;
typedef uint32_t ZForwardingCursor;
@@ -33,37 +36,43 @@
friend class ZForwardingTest;
private:
- const uintptr_t _start;
- const size_t _object_alignment_shift;
- const uint32_t _nentries;
- volatile uint32_t _refcount;
- volatile bool _pinned;
+ const ZVirtualMemory _virtual;
+ const size_t _object_alignment_shift;
+ const uint32_t _nentries;
+ ZPage* _page;
+ volatile uint32_t _refcount;
+ volatile bool _pinned;
+
+ bool inc_refcount();
+ bool dec_refcount();
ZForwardingEntry* entries() const;
ZForwardingEntry at(ZForwardingCursor* cursor) const;
ZForwardingEntry first(uintptr_t from_index, ZForwardingCursor* cursor) const;
ZForwardingEntry next(ZForwardingCursor* cursor) const;
- ZForwarding(uintptr_t start, size_t object_alignment_shift, uint32_t nentries);
+ ZForwarding(ZPage* page, uint32_t nentries);
public:
- static ZForwarding* create(uintptr_t start, size_t object_alignment_shift, uint32_t live_objects);
+ static ZForwarding* create(ZPage* page);
static void destroy(ZForwarding* forwarding);
uintptr_t start() const;
+ size_t size() const;
size_t object_alignment_shift() const;
-
- bool inc_refcount();
- bool dec_refcount();
+ ZPage* page() const;
bool is_pinned() const;
void set_pinned();
+ bool retain_page();
+ void release_page();
+
ZForwardingEntry find(uintptr_t from_index) const;
ZForwardingEntry find(uintptr_t from_index, ZForwardingCursor* cursor) const;
uintptr_t insert(uintptr_t from_index, uintptr_t to_offset, ZForwardingCursor* cursor);
- void verify(uint32_t object_max_count, uint32_t live_objects) const;
+ void verify() const;
};
#endif // SHARE_GC_Z_ZFORWARDING_HPP
--- a/src/hotspot/share/gc/z/zForwarding.inline.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zForwarding.inline.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -27,17 +27,35 @@
#include "gc/z/zForwarding.hpp"
#include "gc/z/zGlobals.hpp"
#include "gc/z/zHash.inline.hpp"
+#include "gc/z/zHeap.hpp"
+#include "gc/z/zVirtualMemory.inline.hpp"
#include "runtime/atomic.hpp"
#include "utilities/debug.hpp"
inline uintptr_t ZForwarding::start() const {
- return _start;
+ return _virtual.start();
+}
+
+inline size_t ZForwarding::size() const {
+ return _virtual.size();
}
inline size_t ZForwarding::object_alignment_shift() const {
return _object_alignment_shift;
}
+inline ZPage* ZForwarding::page() const {
+ return _page;
+}
+
+inline bool ZForwarding::is_pinned() const {
+ return Atomic::load(&_pinned);
+}
+
+inline void ZForwarding::set_pinned() {
+ Atomic::store(true, &_pinned);
+}
+
inline bool ZForwarding::inc_refcount() {
uint32_t refcount = Atomic::load(&_refcount);
@@ -60,12 +78,15 @@
return Atomic::sub(1u, &_refcount) == 0u;
}
-inline bool ZForwarding::is_pinned() const {
- return Atomic::load(&_pinned);
+inline bool ZForwarding::retain_page() {
+ return inc_refcount();
}
-inline void ZForwarding::set_pinned() {
- Atomic::store(true, &_pinned);
+inline void ZForwarding::release_page() {
+ if (dec_refcount()) {
+ ZHeap::heap()->free_page(_page, true /* reclaimed */);
+ _page = NULL;
+ }
}
inline ZForwardingEntry* ZForwarding::entries() const {
--- a/src/hotspot/share/gc/z/zForwardingTable.cpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zForwardingTable.cpp Mon Mar 18 11:50:39 2019 +0100
@@ -22,7 +22,8 @@
*/
#include "precompiled.hpp"
-#include "gc/z/zForwarding.hpp"
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zForwarding.inline.hpp"
#include "gc/z/zForwardingTable.inline.hpp"
#include "gc/z/zGranuleMap.inline.hpp"
#include "utilities/debug.hpp"
@@ -30,41 +31,18 @@
ZForwardingTable::ZForwardingTable() :
_map() {}
-void ZForwardingTable::insert(uintptr_t start,
- size_t size,
- size_t object_alignment_shift,
- uint32_t live_objects) {
- // Allocate forwarding
- ZForwarding* const forwarding = ZForwarding::create(start,
- object_alignment_shift,
- live_objects);
+void ZForwardingTable::insert(ZForwarding* forwarding) {
+ const uintptr_t addr = ZAddress::good(forwarding->start());
+ const size_t size = forwarding->size();
- // Insert into forwarding table
- const uintptr_t addr = ZAddress::good(start);
assert(get(addr) == NULL, "Invalid entry");
_map.put(addr, size, forwarding);
}
-void ZForwardingTable::clear() {
- ZForwarding* prev_forwarding = NULL;
-
- // Clear and destroy all non-NULL entries
- ZGranuleMapIterator<ZForwarding*> iter(&_map);
- for (ZForwarding** entry; iter.next(&entry);) {
- ZForwarding* const forwarding = *entry;
- if (forwarding == NULL) {
- // Skip entry
- continue;
- }
+void ZForwardingTable::remove(ZForwarding* forwarding) {
+ const uintptr_t addr = ZAddress::good(forwarding->start());
+ const size_t size = forwarding->size();
- // Clear entry
- *entry = NULL;
-
- // More than one entry can point to the same
- // forwarding. Make sure we only destroy it once.
- if (forwarding != prev_forwarding) {
- ZForwarding::destroy(forwarding);
- prev_forwarding = forwarding;
- }
- }
+ assert(get(addr) == forwarding, "Invalid entry");
+ _map.put(addr, size, NULL);
}
--- a/src/hotspot/share/gc/z/zForwardingTable.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zForwardingTable.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -37,11 +37,8 @@
ZForwarding* get(uintptr_t addr) const;
- void insert(uintptr_t start,
- size_t size,
- size_t object_alignment_shift,
- uint32_t live_objects);
- void clear();
+ void insert(ZForwarding* forwarding);
+ void remove(ZForwarding* forwarding);
};
#endif // SHARE_GC_Z_ZFORWARDINGTABLE_HPP
--- a/src/hotspot/share/gc/z/zHeap.cpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zHeap.cpp Mon Mar 18 11:50:39 2019 +0100
@@ -417,8 +417,8 @@
void ZHeap::select_relocation_set() {
// Register relocatable pages with selector
ZRelocationSetSelector selector;
- ZPageTableIterator iter(&_pagetable);
- for (ZPage* page; iter.next(&page);) {
+ ZPageTableIterator pt_iter(&_pagetable);
+ for (ZPage* page; pt_iter.next(&page);) {
if (!page->is_relocatable()) {
// Not relocatable, don't register
continue;
@@ -439,6 +439,12 @@
// Select pages to relocate
selector.select(&_relocation_set);
+ // Setup forwarding table
+ ZRelocationSetIterator rs_iter(&_relocation_set);
+ for (ZForwarding* forwarding; rs_iter.next(&forwarding);) {
+ _forwarding_table.insert(forwarding);
+ }
+
// Update statistics
ZStatRelocation::set_at_select_relocation_set(selector.relocating());
ZStatHeap::set_at_select_relocation_set(selector.live(),
@@ -446,20 +452,15 @@
reclaimed());
}
-void ZHeap::prepare_relocation_set() {
+void ZHeap::reset_relocation_set() {
+ // Reset forwarding table
ZRelocationSetIterator iter(&_relocation_set);
- for (ZPage* page; iter.next(&page);) {
- // Setup forwarding for page
- _forwarding_table.insert(page->start(),
- page->size(),
- page->object_alignment_shift(),
- page->live_objects());
+ for (ZForwarding* forwarding; iter.next(&forwarding);) {
+ _forwarding_table.remove(forwarding);
}
-}
-void ZHeap::reset_relocation_set() {
- // Clear forwarding table
- _forwarding_table.clear();
+ // Reset relocation set
+ _relocation_set.reset();
}
void ZHeap::relocate_start() {
--- a/src/hotspot/share/gc/z/zHeap.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zHeap.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -149,11 +149,9 @@
// Relocation set
void select_relocation_set();
- void prepare_relocation_set();
void reset_relocation_set();
// Relocation
- ZForwarding* forwarding(uintptr_t addr);
void relocate_start();
uintptr_t relocate_object(uintptr_t addr);
uintptr_t remap_object(uintptr_t addr);
--- a/src/hotspot/share/gc/z/zHeap.inline.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zHeap.inline.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -44,10 +44,6 @@
return &_reference_processor;
}
-inline ZForwarding* ZHeap::forwarding(uintptr_t addr) {
- return _forwarding_table.get(addr);
-}
-
inline bool ZHeap::is_object_live(uintptr_t addr) const {
ZPage* page = _pagetable.get(addr);
return page->is_object_live(addr);
@@ -101,11 +97,10 @@
}
// Relocate object
- const bool retained = forwarding->inc_refcount();
+ const bool retained = forwarding->retain_page();
const uintptr_t new_addr = _relocate.relocate_object(forwarding, addr);
- if (retained && forwarding->dec_refcount()) {
- ZPage* const page = _pagetable.get(addr);
- free_page(page, true /* reclaimed */);
+ if (retained) {
+ forwarding->release_page();
}
return new_addr;
--- a/src/hotspot/share/gc/z/zRelocate.cpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zRelocate.cpp Mon Mar 18 11:50:39 2019 +0100
@@ -83,11 +83,6 @@
_workers->run_parallel(&task);
}
-ZForwarding* ZRelocate::forwarding_for_page(ZPage* page) const {
- const uintptr_t addr = ZAddress::good(page->start());
- return ZHeap::heap()->forwarding(addr);
-}
-
uintptr_t ZRelocate::relocate_object_inner(ZForwarding* forwarding, uintptr_t from_index, uintptr_t from_offset) const {
ZForwardingCursor cursor;
@@ -178,14 +173,13 @@
bool success = true;
// Relocate pages in the relocation set
- for (ZPage* page; iter->next(&page);) {
+ for (ZForwarding* forwarding; iter->next(&forwarding);) {
// Relocate objects in page
- ZForwarding* const forwarding = forwarding_for_page(page);
ZRelocateObjectClosure cl(this, forwarding);
- page->object_iterate(&cl);
+ forwarding->page()->object_iterate(&cl);
if (ZVerifyForwarding) {
- forwarding->verify(page->object_max_count(), page->live_objects());
+ forwarding->verify();
}
if (forwarding->is_pinned()) {
@@ -193,9 +187,7 @@
success = false;
} else {
// Relocation succeeded, release page
- if (forwarding->dec_refcount()) {
- ZHeap::heap()->free_page(page, true /* reclaimed */);
- }
+ forwarding->release_page();
}
}
--- a/src/hotspot/share/gc/z/zRelocationSet.cpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zRelocationSet.cpp Mon Mar 18 11:50:39 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 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
@@ -22,24 +22,35 @@
*/
#include "precompiled.hpp"
+#include "gc/z/zForwarding.hpp"
#include "gc/z/zRelocationSet.hpp"
-#include "memory/allocation.inline.hpp"
+#include "memory/allocation.hpp"
ZRelocationSet::ZRelocationSet() :
- _pages(NULL),
- _npages(0) {}
+ _forwardings(NULL),
+ _nforwardings(0) {}
-void ZRelocationSet::populate(const ZPage* const* group0, size_t ngroup0,
- const ZPage* const* group1, size_t ngroup1) {
- _npages = ngroup0 + ngroup1;
- _pages = REALLOC_C_HEAP_ARRAY(ZPage*, _pages, _npages, mtGC);
+void ZRelocationSet::populate(ZPage* const* group0, size_t ngroup0,
+ ZPage* const* group1, size_t ngroup1) {
+ _nforwardings = ngroup0 + ngroup1;
+ _forwardings = REALLOC_C_HEAP_ARRAY(ZForwarding*, _forwardings, _nforwardings, mtGC);
- if (_pages != NULL) {
- if (group0 != NULL) {
- memcpy(_pages, group0, ngroup0 * sizeof(ZPage*));
- }
- if (group1 != NULL) {
- memcpy(_pages + ngroup0, group1, ngroup1 * sizeof(ZPage*));
- }
+ size_t j = 0;
+
+ // Populate group 0
+ for (size_t i = 0; i < ngroup0; i++) {
+ _forwardings[j++] = ZForwarding::create(group0[i]);
+ }
+
+ // Populate group 1
+ for (size_t i = 0; i < ngroup1; i++) {
+ _forwardings[j++] = ZForwarding::create(group1[i]);
}
}
+
+void ZRelocationSet::reset() {
+ for (size_t i = 0; i < _nforwardings; i++) {
+ ZForwarding::destroy(_forwardings[i]);
+ _forwardings[i] = NULL;
+ }
+}
--- a/src/hotspot/share/gc/z/zRelocationSet.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zRelocationSet.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 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
@@ -26,20 +26,22 @@
#include "memory/allocation.hpp"
+class ZForwarding;
class ZPage;
class ZRelocationSet {
template <bool> friend class ZRelocationSetIteratorImpl;
private:
- ZPage** _pages;
- size_t _npages;
+ ZForwarding** _forwardings;
+ size_t _nforwardings;
public:
ZRelocationSet();
- void populate(const ZPage* const* group0, size_t ngroup0,
- const ZPage* const* group1, size_t ngroup1);
+ void populate(ZPage* const* group0, size_t ngroup0,
+ ZPage* const* group1, size_t ngroup1);
+ void reset();
};
template <bool parallel>
@@ -51,7 +53,7 @@
public:
ZRelocationSetIteratorImpl(ZRelocationSet* relocation_set);
- bool next(ZPage** page);
+ bool next(ZForwarding** forwarding);
};
// Iterator types
--- a/src/hotspot/share/gc/z/zRelocationSet.inline.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zRelocationSet.inline.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 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
@@ -33,20 +33,20 @@
_next(0) {}
template <bool parallel>
-inline bool ZRelocationSetIteratorImpl<parallel>::next(ZPage** page) {
- const size_t npages = _relocation_set->_npages;
+inline bool ZRelocationSetIteratorImpl<parallel>::next(ZForwarding** forwarding) {
+ const size_t nforwardings = _relocation_set->_nforwardings;
if (parallel) {
- if (_next < npages) {
+ if (_next < nforwardings) {
const size_t next = Atomic::add(1u, &_next) - 1u;
- if (next < npages) {
- *page = _relocation_set->_pages[next];
+ if (next < nforwardings) {
+ *forwarding = _relocation_set->_forwardings[next];
return true;
}
}
} else {
- if (_next < npages) {
- *page = _relocation_set->_pages[_next++];
+ if (_next < nforwardings) {
+ *forwarding = _relocation_set->_forwardings[_next++];
return true;
}
}
--- a/src/hotspot/share/gc/z/zRelocationSetSelector.cpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zRelocationSetSelector.cpp Mon Mar 18 11:50:39 2019 +0100
@@ -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
@@ -44,10 +44,10 @@
_fragmentation(0) {}
ZRelocationSetSelectorGroup::~ZRelocationSetSelectorGroup() {
- FREE_C_HEAP_ARRAY(const ZPage*, _sorted_pages);
+ FREE_C_HEAP_ARRAY(ZPage*, _sorted_pages);
}
-void ZRelocationSetSelectorGroup::register_live_page(const ZPage* page, size_t garbage) {
+void ZRelocationSetSelectorGroup::register_live_page(ZPage* page, size_t garbage) {
if (garbage > _fragmentation_limit) {
_registered_pages.add(page);
} else {
@@ -67,13 +67,13 @@
size_t partitions[npartitions];
// Allocate destination array
- _sorted_pages = REALLOC_C_HEAP_ARRAY(const ZPage*, _sorted_pages, npages, mtGC);
+ _sorted_pages = REALLOC_C_HEAP_ARRAY(ZPage*, _sorted_pages, npages, mtGC);
debug_only(memset(_sorted_pages, 0, npages * sizeof(ZPage*)));
// Calculate partition slots
memset(partitions, 0, sizeof(partitions));
- ZArrayIterator<const ZPage*> iter1(&_registered_pages);
- for (const ZPage* page; iter1.next(&page);) {
+ ZArrayIterator<ZPage*> iter1(&_registered_pages);
+ for (ZPage* page; iter1.next(&page);) {
const size_t index = page->live_bytes() >> partition_size_shift;
partitions[index]++;
}
@@ -87,8 +87,8 @@
}
// Sort pages into partitions
- ZArrayIterator<const ZPage*> iter2(&_registered_pages);
- for (const ZPage* page; iter2.next(&page);) {
+ ZArrayIterator<ZPage*> iter2(&_registered_pages);
+ for (ZPage* page; iter2.next(&page);) {
const size_t index = page->live_bytes() >> partition_size_shift;
const size_t finger = partitions[index]++;
assert(_sorted_pages[finger] == NULL, "Invalid finger");
@@ -140,7 +140,7 @@
// Update statistics
_relocating = from_size;
for (size_t i = _nselected; i < npages; i++) {
- const ZPage* const page = _sorted_pages[i];
+ ZPage* const page = _sorted_pages[i];
_fragmentation += page->size() - page->live_bytes();
}
@@ -148,7 +148,7 @@
_name, selected_from, selected_to, npages - _nselected);
}
-const ZPage* const* ZRelocationSetSelectorGroup::selected() const {
+ZPage* const* ZRelocationSetSelectorGroup::selected() const {
return _sorted_pages;
}
@@ -171,7 +171,7 @@
_garbage(0),
_fragmentation(0) {}
-void ZRelocationSetSelector::register_live_page(const ZPage* page) {
+void ZRelocationSetSelector::register_live_page(ZPage* page) {
const uint8_t type = page->type();
const size_t live = page->live_bytes();
const size_t garbage = page->size() - live;
@@ -188,7 +188,7 @@
_garbage += garbage;
}
-void ZRelocationSetSelector::register_garbage_page(const ZPage* page) {
+void ZRelocationSetSelector::register_garbage_page(ZPage* page) {
_garbage += page->size();
}
--- a/src/hotspot/share/gc/z/zRelocationSetSelector.hpp Mon Mar 18 11:50:39 2019 +0100
+++ b/src/hotspot/share/gc/z/zRelocationSetSelector.hpp Mon Mar 18 11:50:39 2019 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 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
@@ -32,16 +32,16 @@
class ZRelocationSetSelectorGroup {
private:
- const char* const _name;
- const size_t _page_size;
- const size_t _object_size_limit;
- const size_t _fragmentation_limit;
+ const char* const _name;
+ const size_t _page_size;
+ const size_t _object_size_limit;
+ const size_t _fragmentation_limit;
- ZArray<const ZPage*> _registered_pages;
- const ZPage** _sorted_pages;
- size_t _nselected;
- size_t _relocating;
- size_t _fragmentation;
+ ZArray<ZPage*> _registered_pages;
+ ZPage** _sorted_pages;
+ size_t _nselected;
+ size_t _relocating;
+ size_t _fragmentation;
void semi_sort();
@@ -51,10 +51,10 @@
size_t object_size_limit);
~ZRelocationSetSelectorGroup();
- void register_live_page(const ZPage* page, size_t garbage);
+ void register_live_page(ZPage* page, size_t garbage);
void select();
- const ZPage* const* selected() const;
+ ZPage* const* selected() const;
size_t nselected() const;
size_t relocating() const;
size_t fragmentation() const;
@@ -71,8 +71,8 @@
public:
ZRelocationSetSelector();
- void register_live_page(const ZPage* page);
- void register_garbage_page(const ZPage* page);
+ void register_live_page(ZPage* page);
+ void register_garbage_page(ZPage* page);
void select(ZRelocationSet* relocation_set);
size_t live() const;
--- a/test/hotspot/gtest/gc/z/test_zForwarding.cpp Mon Mar 18 11:50:39 2019 +0100
+++ b/test/hotspot/gtest/gc/z/test_zForwarding.cpp Mon Mar 18 11:50:39 2019 +0100
@@ -22,7 +22,10 @@
*/
#include "precompiled.hpp"
+#include "gc/z/zAddress.inline.hpp"
#include "gc/z/zForwarding.inline.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zPage.inline.hpp"
#include "unittest.hpp"
using namespace testing;
@@ -141,16 +144,37 @@
}
static void test(void (*function)(ZForwarding*), uint32_t size) {
- // Setup
- ZForwarding* forwarding = ZForwarding::create(0 /* start */,
- 0 /* object_alignment_shift */,
- size);
+ // Create page
+ const ZVirtualMemory vmem(0, ZPageSizeSmall);
+ const ZPhysicalMemory pmem(ZPhysicalMemorySegment(0, ZPageSizeSmall));
+ ZPage page(ZPageTypeSmall, vmem, pmem);
+
+ page.reset();
+
+ const size_t object_size = 16;
+ const uintptr_t object = page.alloc_object(object_size);
+
+ ZGlobalSeqNum++;
+
+ bool dummy = false;
+ page.mark_object(ZAddress::marked(object), dummy, dummy);
+
+ const uint32_t live_objects = size;
+ const uint32_t live_bytes = live_objects * object_size;
+ page.inc_live_atomic(live_objects, live_bytes);
+
+ // Setup forwarding
+ ZForwarding* const forwarding = ZForwarding::create(&page);
// Actual test function
(*function)(forwarding);
- // Teardown
+ // Teardown forwarding
ZForwarding::destroy(forwarding);
+
+ // Teardown page
+ page.physical_memory().clear();
+ page.set_inactive();
}
// Run the given function with a few different input values.