Skip to content

Commit 4c66b15

Browse files
committed
8255235: ZGC: Allocate and initialize forwarding data structures in parallel
Reviewed-by: ayang, eosterlund
1 parent 1019581 commit 4c66b15

11 files changed

+168
-149
lines changed

src/hotspot/share/gc/z/zForwardingAllocator.inline.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#define SHARE_GC_Z_ZFORWARDINGALLOCATOR_INLINE_HPP
2626

2727
#include "gc/z/zForwardingAllocator.hpp"
28+
#include "runtime/atomic.hpp"
2829
#include "utilities/debug.hpp"
2930

3031
inline size_t ZForwardingAllocator::size() const {
@@ -36,9 +37,8 @@ inline bool ZForwardingAllocator::is_full() const {
3637
}
3738

3839
inline void* ZForwardingAllocator::alloc(size_t size) {
39-
char* const addr = _top;
40-
_top += size;
41-
assert(_top <= _end, "Allocation should never fail");
40+
char* const addr = Atomic::fetch_and_add(&_top, size);
41+
assert(addr + size <= _end, "Allocation should never fail");
4242
return addr;
4343
}
4444

src/hotspot/share/gc/z/zForwardingTable.cpp

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/hotspot/share/gc/z/zForwardingTable.inline.hpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,34 @@
2525
#define SHARE_GC_Z_ZFORWARDINGTABLE_INLINE_HPP
2626

2727
#include "gc/z/zAddress.inline.hpp"
28+
#include "gc/z/zForwarding.inline.hpp"
2829
#include "gc/z/zForwardingTable.hpp"
30+
#include "gc/z/zGlobals.hpp"
2931
#include "gc/z/zGranuleMap.inline.hpp"
32+
#include "utilities/debug.hpp"
33+
34+
inline ZForwardingTable::ZForwardingTable() :
35+
_map(ZAddressOffsetMax) {}
3036

3137
inline ZForwarding* ZForwardingTable::get(uintptr_t addr) const {
3238
assert(!ZAddress::is_null(addr), "Invalid address");
3339
return _map.get(ZAddress::offset(addr));
3440
}
3541

42+
inline void ZForwardingTable::insert(ZForwarding* forwarding) {
43+
const uintptr_t offset = forwarding->start();
44+
const size_t size = forwarding->size();
45+
46+
assert(_map.get(offset) == NULL, "Invalid entry");
47+
_map.put(offset, size, forwarding);
48+
}
49+
50+
inline void ZForwardingTable::remove(ZForwarding* forwarding) {
51+
const uintptr_t offset = forwarding->start();
52+
const size_t size = forwarding->size();
53+
54+
assert(_map.get(offset) == forwarding, "Invalid entry");
55+
_map.put(offset, size, NULL);
56+
}
57+
3658
#endif // SHARE_GC_Z_ZFORWARDINGTABLE_INLINE_HPP

src/hotspot/share/gc/z/zHeap.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ ZHeap::ZHeap() :
6565
_reference_processor(&_workers),
6666
_weak_roots_processor(&_workers),
6767
_relocate(&_workers),
68-
_relocation_set(),
68+
_relocation_set(&_workers),
6969
_unload(&_workers),
7070
_serviceability(min_capacity(), max_capacity()) {
7171
// Install global heap instance
@@ -377,8 +377,11 @@ void ZHeap::select_relocation_set() {
377377
// Allow pages to be deleted
378378
_page_allocator.disable_deferred_delete();
379379

380-
// Select pages to relocate
381-
selector.select(&_relocation_set);
380+
// Select relocation set
381+
selector.select();
382+
383+
// Install relocation set
384+
_relocation_set.install(&selector);
382385

383386
// Setup forwarding table
384387
ZRelocationSetIterator rs_iter(&_relocation_set);

src/hotspot/share/gc/z/zRelocationSet.cpp

Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,51 +22,106 @@
2222
*/
2323

2424
#include "precompiled.hpp"
25+
#include "gc/z/zArray.inline.hpp"
2526
#include "gc/z/zForwarding.inline.hpp"
2627
#include "gc/z/zForwardingAllocator.inline.hpp"
2728
#include "gc/z/zRelocationSet.hpp"
29+
#include "gc/z/zRelocationSetSelector.inline.hpp"
2830
#include "gc/z/zStat.hpp"
29-
#include "memory/allocation.hpp"
31+
#include "gc/z/zTask.hpp"
32+
#include "gc/z/zWorkers.hpp"
33+
#include "runtime/atomic.hpp"
3034
#include "utilities/debug.hpp"
3135

32-
ZRelocationSet::ZRelocationSet() :
33-
_allocator(),
34-
_forwardings(NULL),
35-
_nforwardings(0) {}
36+
class ZRelocationSetInstallTask : public ZTask {
37+
private:
38+
ZForwardingAllocator* const _allocator;
39+
ZForwarding** _forwardings;
40+
const size_t _nforwardings;
41+
ZArrayParallelIterator<ZPage*> _small_iter;
42+
ZArrayParallelIterator<ZPage*> _medium_iter;
43+
volatile size_t _small_next;
44+
volatile size_t _medium_next;
45+
46+
void install(ZForwarding* forwarding, volatile size_t* next) {
47+
const size_t index = Atomic::fetch_and_add(next, 1u);
48+
assert(index < _nforwardings, "Invalid index");
49+
_forwardings[index] = forwarding;
50+
}
3651

37-
void ZRelocationSet::populate(ZPage* const* small, size_t nsmall,
38-
ZPage* const* medium, size_t nmedium,
39-
size_t forwarding_entries) {
40-
// Set relocation set length
41-
_nforwardings = nsmall + nmedium;
52+
void install_small(ZForwarding* forwarding) {
53+
install(forwarding, &_small_next);
54+
}
4255

43-
// Initialize forwarding allocator to have room for the
44-
// relocation set, all forwardings, and all forwarding entries.
45-
const size_t relocation_set_size = _nforwardings * sizeof(ZForwarding*);
46-
const size_t forwardings_size = _nforwardings * sizeof(ZForwarding);
47-
const size_t forwarding_entries_size = forwarding_entries * sizeof(ZForwardingEntry);
48-
_allocator.reset(relocation_set_size + forwardings_size + forwarding_entries_size);
56+
void install_medium(ZForwarding* forwarding) {
57+
install(forwarding, &_medium_next);
58+
}
4959

50-
// Allocate relocation set
51-
_forwardings = new (_allocator.alloc(relocation_set_size)) ZForwarding*[_nforwardings];
60+
public:
61+
ZRelocationSetInstallTask(ZForwardingAllocator* allocator, const ZRelocationSetSelector* selector) :
62+
ZTask("ZRelocationSetInstallTask"),
63+
_allocator(allocator),
64+
_forwardings(NULL),
65+
_nforwardings(selector->small()->length() + selector->medium()->length()),
66+
_small_iter(selector->small()),
67+
_medium_iter(selector->medium()),
68+
_small_next(selector->medium()->length()),
69+
_medium_next(0) {
5270

53-
// Populate relocation set array
54-
size_t j = 0;
71+
// Reset the allocator to have room for the relocation
72+
// set, all forwardings, and all forwarding entries.
73+
const size_t relocation_set_size = _nforwardings * sizeof(ZForwarding*);
74+
const size_t forwardings_size = _nforwardings * sizeof(ZForwarding);
75+
const size_t forwarding_entries_size = selector->forwarding_entries() * sizeof(ZForwardingEntry);
76+
_allocator->reset(relocation_set_size + forwardings_size + forwarding_entries_size);
5577

56-
// Populate medium pages
57-
for (size_t i = 0; i < nmedium; i++) {
58-
_forwardings[j++] = ZForwarding::alloc(&_allocator, medium[i]);
78+
// Allocate relocation set
79+
_forwardings = new (_allocator->alloc(relocation_set_size)) ZForwarding*[_nforwardings];
5980
}
6081

61-
// Populate small pages
62-
for (size_t i = 0; i < nsmall; i++) {
63-
_forwardings[j++] = ZForwarding::alloc(&_allocator, small[i]);
82+
~ZRelocationSetInstallTask() {
83+
assert(_allocator->is_full(), "Should be full");
84+
}
85+
86+
virtual void work() {
87+
// Allocate and install forwardings for small pages
88+
for (ZPage* page; _small_iter.next(&page);) {
89+
ZForwarding* const forwarding = ZForwarding::alloc(_allocator, page);
90+
install_small(forwarding);
91+
}
92+
93+
// Allocate and install forwardings for medium pages
94+
for (ZPage* page; _medium_iter.next(&page);) {
95+
ZForwarding* const forwarding = ZForwarding::alloc(_allocator, page);
96+
install_medium(forwarding);
97+
}
6498
}
6599

66-
assert(_allocator.is_full(), "Should be full");
100+
ZForwarding** forwardings() const {
101+
return _forwardings;
102+
}
103+
104+
size_t nforwardings() const {
105+
return _nforwardings;
106+
}
107+
};
108+
109+
ZRelocationSet::ZRelocationSet(ZWorkers* workers) :
110+
_workers(workers),
111+
_allocator(),
112+
_forwardings(NULL),
113+
_nforwardings(0) {}
114+
115+
void ZRelocationSet::install(const ZRelocationSetSelector* selector) {
116+
// Install relocation set
117+
ZRelocationSetInstallTask task(&_allocator, selector);
118+
_workers->run_concurrent(&task);
119+
120+
_forwardings = task.forwardings();
121+
_nforwardings = task.nforwardings();
67122

68123
// Update statistics
69-
ZStatRelocation::set_at_populate_relocation_set(_allocator.size());
124+
ZStatRelocation::set_at_install_relocation_set(_allocator.size());
70125
}
71126

72127
void ZRelocationSet::reset() {

src/hotspot/share/gc/z/zRelocationSet.hpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,24 @@
2626

2727
#include "gc/z/zArray.hpp"
2828
#include "gc/z/zForwardingAllocator.hpp"
29-
#include "memory/allocation.hpp"
3029

3130
class ZForwarding;
32-
class ZPage;
31+
class ZRelocationSetSelector;
32+
class ZWorkers;
3333

3434
class ZRelocationSet {
3535
template <bool> friend class ZRelocationSetIteratorImpl;
3636

3737
private:
38+
ZWorkers* _workers;
3839
ZForwardingAllocator _allocator;
3940
ZForwarding** _forwardings;
4041
size_t _nforwardings;
4142

4243
public:
43-
ZRelocationSet();
44+
ZRelocationSet(ZWorkers* workers);
4445

45-
void populate(ZPage* const* small, size_t nsmall,
46-
ZPage* const* medium, size_t nmedium,
47-
size_t forwarding_entries);
46+
void install(const ZRelocationSetSelector* selector);
4847
void reset();
4948
};
5049

0 commit comments

Comments
 (0)