Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/hotspot/cpu/ppc/gc/z/zGlobals_ppc.cpp
66646 views
1
/*
2
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2021 SAP SE. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*/
24
25
#include "precompiled.hpp"
26
#include "gc/shared/gcLogPrecious.hpp"
27
#include "gc/shared/gc_globals.hpp"
28
#include "gc/z/zGlobals.hpp"
29
#include "runtime/globals.hpp"
30
#include "runtime/os.hpp"
31
#include "utilities/globalDefinitions.hpp"
32
#include "utilities/powerOfTwo.hpp"
33
#include <cstddef>
34
35
#ifdef LINUX
36
#include <sys/mman.h>
37
#endif // LINUX
38
39
//
40
// The overall memory layouts across different power platforms are similar and only differ with regards to
41
// the position of the highest addressable bit; the position of the metadata bits and the size of the actual
42
// addressable heap address space are adjusted accordingly.
43
//
44
// The following memory schema shows an exemplary layout in which bit '45' is the highest addressable bit.
45
// It is assumed that this virtual memroy address space layout is predominant on the power platform.
46
//
47
// Standard Address Space & Pointer Layout
48
// ---------------------------------------
49
//
50
// +--------------------------------+ 0x00007FFFFFFFFFFF (127 TiB - 1)
51
// . .
52
// . .
53
// . .
54
// +--------------------------------+ 0x0000140000000000 (20 TiB)
55
// | Remapped View |
56
// +--------------------------------+ 0x0000100000000000 (16 TiB)
57
// . .
58
// +--------------------------------+ 0x00000c0000000000 (12 TiB)
59
// | Marked1 View |
60
// +--------------------------------+ 0x0000080000000000 (8 TiB)
61
// | Marked0 View |
62
// +--------------------------------+ 0x0000040000000000 (4 TiB)
63
// . .
64
// +--------------------------------+ 0x0000000000000000
65
//
66
// 6 4 4 4 4
67
// 3 6 5 2 1 0
68
// +--------------------+----+-----------------------------------------------+
69
// |00000000 00000000 00|1111|11 11111111 11111111 11111111 11111111 11111111|
70
// +--------------------+----+-----------------------------------------------+
71
// | | |
72
// | | * 41-0 Object Offset (42-bits, 4TB address space)
73
// | |
74
// | * 45-42 Metadata Bits (4-bits) 0001 = Marked0 (Address view 4-8TB)
75
// | 0010 = Marked1 (Address view 8-12TB)
76
// | 0100 = Remapped (Address view 16-20TB)
77
// | 1000 = Finalizable (Address view N/A)
78
// |
79
// * 63-46 Fixed (18-bits, always zero)
80
//
81
82
// Maximum value as per spec (Power ISA v2.07): 2 ^ 60 bytes, i.e. 1 EiB (exbibyte)
83
static const unsigned int MAXIMUM_MAX_ADDRESS_BIT = 60;
84
85
// Most modern power processors provide an address space with not more than 45 bit addressable bit,
86
// that is an address space of 32 TiB in size.
87
static const unsigned int DEFAULT_MAX_ADDRESS_BIT = 45;
88
89
// Minimum value returned, if probing fails: 64 GiB
90
static const unsigned int MINIMUM_MAX_ADDRESS_BIT = 36;
91
92
// Determines the highest addressable bit of the virtual address space (depends on platform)
93
// by trying to interact with memory in that address range,
94
// i.e. by syncing existing mappings (msync) or by temporarily mapping the memory area (mmap).
95
// If one of those operations succeeds, it is proven that the targeted memory area is within the virtual address space.
96
//
97
// To reduce the number of required system calls to a bare minimum, the DEFAULT_MAX_ADDRESS_BIT is intentionally set
98
// lower than what the ABI would theoretically permit.
99
// Such an avoidance strategy, however, might impose unnecessary limits on processors that exceed this limit.
100
// If DEFAULT_MAX_ADDRESS_BIT is addressable, the next higher bit will be tested as well to ensure that
101
// the made assumption does not artificially restrict the memory availability.
102
static unsigned int probe_valid_max_address_bit(size_t init_bit, size_t min_bit) {
103
assert(init_bit >= min_bit, "Sanity");
104
assert(init_bit <= MAXIMUM_MAX_ADDRESS_BIT, "Test bit is outside the assumed address space range");
105
106
#ifdef LINUX
107
unsigned int max_valid_address_bit = 0;
108
void* last_allocatable_address = nullptr;
109
110
const unsigned int page_size = os::vm_page_size();
111
112
for (size_t i = init_bit; i >= min_bit; --i) {
113
void* base_addr = (void*) (((unsigned long) 1U) << i);
114
115
/* ==== Try msync-ing already mapped memory page ==== */
116
if (msync(base_addr, page_size, MS_ASYNC) == 0) {
117
// The page of the given address was synced by the linux kernel and must thus be both, mapped and valid.
118
max_valid_address_bit = i;
119
break;
120
}
121
if (errno != ENOMEM) {
122
// An unexpected error occurred, i.e. an error not indicating that the targeted memory page is unmapped,
123
// but pointing out another type of issue.
124
// Even though this should never happen, those issues may come up due to undefined behavior.
125
#ifdef ASSERT
126
fatal("Received '%s' while probing the address space for the highest valid bit", os::errno_name(errno));
127
#else // ASSERT
128
log_warning_p(gc)("Received '%s' while probing the address space for the highest valid bit", os::errno_name(errno));
129
#endif // ASSERT
130
continue;
131
}
132
133
/* ==== Try mapping memory page on our own ==== */
134
last_allocatable_address = mmap(base_addr, page_size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0);
135
if (last_allocatable_address != MAP_FAILED) {
136
munmap(last_allocatable_address, page_size);
137
}
138
139
if (last_allocatable_address == base_addr) {
140
// As the linux kernel mapped exactly the page we have requested, the address must be valid.
141
max_valid_address_bit = i;
142
break;
143
}
144
145
log_info_p(gc, init)("Probe failed for bit '%zu'", i);
146
}
147
148
if (max_valid_address_bit == 0) {
149
// Probing did not bring up any usable address bit.
150
// As an alternative, the VM evaluates the address returned by mmap as it is expected that the reserved page
151
// will be close to the probed address that was out-of-range.
152
// As per mmap(2), "the kernel [will take] [the address] as a hint about where to
153
// place the mapping; on Linux, the mapping will be created at a nearby page boundary".
154
// It should thus be a "close enough" approximation to the real virtual memory address space limit.
155
//
156
// This recovery strategy is only applied in production builds.
157
// In debug builds, an assertion in 'ZPlatformAddressOffsetBits' will bail out the VM to indicate that
158
// the assumed address space is no longer up-to-date.
159
if (last_allocatable_address != MAP_FAILED) {
160
const unsigned int bitpos = BitsPerSize_t - count_leading_zeros((size_t) last_allocatable_address) - 1;
161
log_info_p(gc, init)("Did not find any valid addresses within the range, using address '%u' instead", bitpos);
162
return bitpos;
163
}
164
165
#ifdef ASSERT
166
fatal("Available address space can not be determined");
167
#else // ASSERT
168
log_warning_p(gc)("Cannot determine available address space. Falling back to default value.");
169
return DEFAULT_MAX_ADDRESS_BIT;
170
#endif // ASSERT
171
} else {
172
if (max_valid_address_bit == init_bit) {
173
// An usable address bit has been found immediately.
174
// To ensure that the entire virtual address space is exploited, the next highest bit will be tested as well.
175
log_info_p(gc, init)("Hit valid address '%u' on first try, retrying with next higher bit", max_valid_address_bit);
176
return MAX2(max_valid_address_bit, probe_valid_max_address_bit(init_bit + 1, init_bit + 1));
177
}
178
}
179
180
log_info_p(gc, init)("Found valid address '%u'", max_valid_address_bit);
181
return max_valid_address_bit;
182
#else // LINUX
183
return DEFAULT_MAX_ADDRESS_BIT;
184
#endif // LINUX
185
}
186
187
size_t ZPlatformAddressOffsetBits() {
188
const static unsigned int valid_max_address_offset_bits =
189
probe_valid_max_address_bit(DEFAULT_MAX_ADDRESS_BIT, MINIMUM_MAX_ADDRESS_BIT) + 1;
190
assert(valid_max_address_offset_bits >= MINIMUM_MAX_ADDRESS_BIT,
191
"Highest addressable bit is outside the assumed address space range");
192
193
const size_t max_address_offset_bits = valid_max_address_offset_bits - 3;
194
const size_t min_address_offset_bits = max_address_offset_bits - 2;
195
const size_t address_offset = round_up_power_of_2(MaxHeapSize * ZVirtualToPhysicalRatio);
196
const size_t address_offset_bits = log2i_exact(address_offset);
197
198
return clamp(address_offset_bits, min_address_offset_bits, max_address_offset_bits);
199
}
200
201
size_t ZPlatformAddressMetadataShift() {
202
return ZPlatformAddressOffsetBits();
203
}
204
205