Skip to content

Commit 2c9dfc7

Browse files
plidenalbertnetymk
andcommitted
8255234: ZGC: Bulk allocate forwarding data structures
Co-authored-by: Albert Mingkun Yang <ayang@openjdk.org> Co-authored-by: Per Liden <pliden@openjdk.org> Reviewed-by: ayang, stefank
1 parent b7d483c commit 2c9dfc7

16 files changed

+283
-68
lines changed

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

Lines changed: 5 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
@@ -32,8 +32,12 @@ class ZAttachedArray {
3232
const size_t _length;
3333

3434
static size_t object_size();
35+
static size_t array_size(size_t length);
3536

3637
public:
38+
template <typename Allocator>
39+
static void* alloc(Allocator* allocator, size_t length);
40+
3741
static void* alloc(size_t length);
3842
static void free(ObjectT* obj);
3943

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

Lines changed: 27 additions & 5 deletions
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
@@ -34,13 +34,35 @@ inline size_t ZAttachedArray<ObjectT, ArrayT>::object_size() {
3434
}
3535

3636
template <typename ObjectT, typename ArrayT>
37-
inline void* ZAttachedArray<ObjectT, ArrayT>::alloc(size_t length) {
38-
const size_t array_size = sizeof(ArrayT) * length;
39-
char* const addr = AllocateHeap(object_size() + array_size, mtGC);
40-
::new (addr + object_size()) ArrayT[length];
37+
inline size_t ZAttachedArray<ObjectT, ArrayT>::array_size(size_t length) {
38+
return sizeof(ArrayT) * length;
39+
}
40+
41+
template <typename ObjectT, typename ArrayT>
42+
template <typename Allocator>
43+
inline void* ZAttachedArray<ObjectT, ArrayT>::alloc(Allocator* allocator, size_t length) {
44+
// Allocate memory for object and array
45+
const size_t size = object_size() + array_size(length);
46+
void* const addr = allocator->alloc(size);
47+
48+
// Placement new array
49+
void* const array_addr = reinterpret_cast<char*>(addr) + object_size();
50+
::new (array_addr) ArrayT[length];
51+
52+
// Return pointer to object
4153
return addr;
4254
}
4355

56+
template <typename ObjectT, typename ArrayT>
57+
inline void* ZAttachedArray<ObjectT, ArrayT>::alloc(size_t length) {
58+
struct Allocator {
59+
void* alloc(size_t size) const {
60+
return AllocateHeap(size, mtGC);
61+
}
62+
} allocator;
63+
return alloc(&allocator, length);
64+
}
65+
4466
template <typename ObjectT, typename ArrayT>
4567
inline void ZAttachedArray<ObjectT, ArrayT>::free(ObjectT* obj) {
4668
FreeHeap(obj);

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

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,31 +23,7 @@
2323

2424
#include "precompiled.hpp"
2525
#include "gc/z/zForwarding.inline.hpp"
26-
#include "gc/z/zPage.inline.hpp"
2726
#include "utilities/debug.hpp"
28-
#include "utilities/powerOfTwo.hpp"
29-
30-
ZForwarding* ZForwarding::create(ZPage* page) {
31-
// Allocate table for linear probing. The size of the table must be
32-
// a power of two to allow for quick and inexpensive indexing/masking.
33-
// The table is sized to have a load factor of 50%, i.e. sized to have
34-
// double the number of entries actually inserted.
35-
assert(page->live_objects() > 0, "Invalid value");
36-
const size_t nentries = round_up_power_of_2(page->live_objects() * 2);
37-
return ::new (AttachedArray::alloc(nentries)) ZForwarding(page, nentries);
38-
}
39-
40-
void ZForwarding::destroy(ZForwarding* forwarding) {
41-
AttachedArray::free(forwarding);
42-
}
43-
44-
ZForwarding::ZForwarding(ZPage* page, size_t nentries) :
45-
_virtual(page->virtual_memory()),
46-
_object_alignment_shift(page->object_alignment_shift()),
47-
_entries(nentries),
48-
_page(page),
49-
_refcount(1),
50-
_pinned(false) {}
5127

5228
void ZForwarding::verify() const {
5329
guarantee(_refcount > 0, "Invalid refcount");

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 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
@@ -28,6 +28,7 @@
2828
#include "gc/z/zForwardingEntry.hpp"
2929
#include "gc/z/zVirtualMemory.hpp"
3030

31+
class ZForwardingAllocator;
3132
class ZPage;
3233

3334
typedef size_t ZForwardingCursor;
@@ -57,8 +58,8 @@ class ZForwarding {
5758
ZForwarding(ZPage* page, size_t nentries);
5859

5960
public:
60-
static ZForwarding* create(ZPage* page);
61-
static void destroy(ZForwarding* forwarding);
61+
static uint32_t nentries(const ZPage* page);
62+
static ZForwarding* alloc(ZForwardingAllocator* allocator, ZPage* page);
6263

6364
uintptr_t start() const;
6465
size_t size() const;

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,38 @@
2626

2727
#include "gc/z/zAttachedArray.inline.hpp"
2828
#include "gc/z/zForwarding.hpp"
29+
#include "gc/z/zForwardingAllocator.inline.hpp"
2930
#include "gc/z/zHash.inline.hpp"
3031
#include "gc/z/zHeap.hpp"
32+
#include "gc/z/zPage.inline.hpp"
3133
#include "gc/z/zVirtualMemory.inline.hpp"
3234
#include "runtime/atomic.hpp"
3335
#include "utilities/debug.hpp"
36+
#include "utilities/powerOfTwo.hpp"
37+
38+
inline uint32_t ZForwarding::nentries(const ZPage* page) {
39+
// The number returned by the function is used to size the hash table of
40+
// forwarding entries for this page. This hash table uses linear probing.
41+
// The size of the table must be a power of two to allow for quick and
42+
// inexpensive indexing/masking. The table is also sized to have a load
43+
// factor of 50%, i.e. sized to have double the number of entries actually
44+
// inserted, to allow for good lookup/insert performance.
45+
return round_up_power_of_2(page->live_objects() * 2);
46+
}
47+
48+
inline ZForwarding* ZForwarding::alloc(ZForwardingAllocator* allocator, ZPage* page) {
49+
const size_t nentries = ZForwarding::nentries(page);
50+
void* const addr = AttachedArray::alloc(allocator, nentries);
51+
return ::new (addr) ZForwarding(page, nentries);
52+
}
53+
54+
inline ZForwarding::ZForwarding(ZPage* page, size_t nentries) :
55+
_virtual(page->virtual_memory()),
56+
_object_alignment_shift(page->object_alignment_shift()),
57+
_entries(nentries),
58+
_page(page),
59+
_refcount(1),
60+
_pinned(false) {}
3461

3562
inline uintptr_t ZForwarding::start() const {
3663
return _virtual.start();
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#include "precompiled.hpp"
25+
#include "gc/z/zForwardingAllocator.hpp"
26+
#include "memory/allocation.inline.hpp"
27+
28+
ZForwardingAllocator::ZForwardingAllocator() :
29+
_start(NULL),
30+
_end(NULL),
31+
_top(NULL) {}
32+
33+
ZForwardingAllocator::~ZForwardingAllocator() {
34+
FREE_C_HEAP_ARRAY(char, _start);
35+
}
36+
37+
void ZForwardingAllocator::reset(size_t size) {
38+
_start = _top = REALLOC_C_HEAP_ARRAY(char, _start, size, mtGC);
39+
_end = _start + size;
40+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#ifndef SHARE_GC_Z_ZFORWARDINGALLOCATOR_HPP
25+
#define SHARE_GC_Z_ZFORWARDINGALLOCATOR_HPP
26+
27+
#include "utilities/globalDefinitions.hpp"
28+
29+
class ZForwardingAllocator {
30+
private:
31+
char* _start;
32+
char* _end;
33+
char* _top;
34+
35+
public:
36+
ZForwardingAllocator();
37+
~ZForwardingAllocator();
38+
39+
void reset(size_t size);
40+
size_t size() const;
41+
bool is_full() const;
42+
43+
void* alloc(size_t size);
44+
};
45+
46+
#endif // SHARE_GC_Z_ZFORWARDINGALLOCATOR_HPP
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
#ifndef SHARE_GC_Z_ZFORWARDINGALLOCATOR_INLINE_HPP
25+
#define SHARE_GC_Z_ZFORWARDINGALLOCATOR_INLINE_HPP
26+
27+
#include "gc/z/zForwardingAllocator.hpp"
28+
#include "utilities/debug.hpp"
29+
30+
inline size_t ZForwardingAllocator::size() const {
31+
return _end - _start;
32+
}
33+
34+
inline bool ZForwardingAllocator::is_full() const {
35+
return _top == _end;
36+
}
37+
38+
inline void* ZForwardingAllocator::alloc(size_t size) {
39+
char* const addr = _top;
40+
_top += size;
41+
assert(_top <= _end, "Allocation should never fail");
42+
return addr;
43+
}
44+
45+
#endif // SHARE_GC_Z_ZFORWARDINGALLOCATOR_INLINE_HPP
Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 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
@@ -22,35 +22,53 @@
2222
*/
2323

2424
#include "precompiled.hpp"
25-
#include "gc/z/zForwarding.hpp"
25+
#include "gc/z/zForwarding.inline.hpp"
26+
#include "gc/z/zForwardingAllocator.inline.hpp"
2627
#include "gc/z/zRelocationSet.hpp"
28+
#include "gc/z/zStat.hpp"
2729
#include "memory/allocation.hpp"
30+
#include "utilities/debug.hpp"
2831

2932
ZRelocationSet::ZRelocationSet() :
33+
_allocator(),
3034
_forwardings(NULL),
3135
_nforwardings(0) {}
3236

33-
void ZRelocationSet::populate(ZPage* const* group0, size_t ngroup0,
34-
ZPage* const* group1, size_t ngroup1) {
35-
_nforwardings = ngroup0 + ngroup1;
36-
_forwardings = REALLOC_C_HEAP_ARRAY(ZForwarding*, _forwardings, _nforwardings, mtGC);
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;
3742

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);
49+
50+
// Allocate relocation set
51+
_forwardings = new (_allocator.alloc(relocation_set_size)) ZForwarding*[_nforwardings];
52+
53+
// Populate relocation set array
3854
size_t j = 0;
3955

40-
// Populate group 0
41-
for (size_t i = 0; i < ngroup0; i++) {
42-
_forwardings[j++] = ZForwarding::create(group0[i]);
56+
// Populate medium pages
57+
for (size_t i = 0; i < nmedium; i++) {
58+
_forwardings[j++] = ZForwarding::alloc(&_allocator, medium[i]);
4359
}
4460

45-
// Populate group 1
46-
for (size_t i = 0; i < ngroup1; i++) {
47-
_forwardings[j++] = ZForwarding::create(group1[i]);
61+
// Populate small pages
62+
for (size_t i = 0; i < nsmall; i++) {
63+
_forwardings[j++] = ZForwarding::alloc(&_allocator, small[i]);
4864
}
65+
66+
assert(_allocator.is_full(), "Should be full");
67+
68+
// Update statistics
69+
ZStatRelocation::set_at_populate_relocation_set(_allocator.size());
4970
}
5071

5172
void ZRelocationSet::reset() {
52-
for (size_t i = 0; i < _nforwardings; i++) {
53-
ZForwarding::destroy(_forwardings[i]);
54-
_forwardings[i] = NULL;
55-
}
73+
_nforwardings = 0;
5674
}

0 commit comments

Comments
 (0)