@@ -214,47 +214,80 @@ void MetaspaceShared::dump_loaded_classes(const char* file_name, TRAPS) {
214
214
}
215
215
}
216
216
217
- static bool shared_base_too_high (char * specified_base, char * aligned_base, size_t cds_max) {
218
- if (specified_base != nullptr && aligned_base < specified_base) {
219
- // SharedBaseAddress is very high (e.g., 0xffffffffffffff00) so
220
- // align_up(SharedBaseAddress, MetaspaceShared::core_region_alignment()) has wrapped around.
221
- return true ;
217
+ // If p is not aligned, move it up to the next address that's aligned with alignment.
218
+ // If this is not possible (because p is too high), return nullptr. Example:
219
+ // p = 0xffffffffffff0000, alignment= 0x10000 => return nullptr.
220
+ static char * align_up_or_null (char * p, size_t alignment) {
221
+ assert (p != nullptr , " sanity" );
222
+ if (is_aligned (p, alignment)) {
223
+ return p;
224
+ }
225
+
226
+ char * down = align_down (p, alignment);
227
+ if (max_uintx - uintx (down) < uintx (alignment)) {
228
+ // Run out of address space to align up.
229
+ return nullptr ;
222
230
}
231
+
232
+ char * aligned = align_up (p, alignment);
233
+ assert (aligned >= p, " sanity" );
234
+ assert (aligned != nullptr , " sanity" );
235
+ return aligned;
236
+ }
237
+
238
+ static bool shared_base_too_high (char * specified_base, char * aligned_base, size_t cds_max) {
239
+ // Caller should have checked if align_up_or_null( returns nullptr (comparing specified_base
240
+ // with nullptr is UB).
241
+ assert (aligned_base != nullptr , " sanity" );
242
+ assert (aligned_base >= specified_base, " sanity" );
243
+
223
244
if (max_uintx - uintx (aligned_base) < uintx (cds_max)) {
224
- // The end of the archive will wrap around
245
+ // Not enough address space to hold an archive of cds_max bytes from aligned_base.
225
246
return true ;
247
+ } else {
248
+ return false ;
226
249
}
227
-
228
- return false ;
229
250
}
230
251
231
252
static char * compute_shared_base (size_t cds_max) {
232
253
char * specified_base = (char *)SharedBaseAddress;
233
- char * aligned_base = align_up (specified_base, MetaspaceShared::core_region_alignment () );
254
+ size_t alignment = MetaspaceShared::core_region_alignment ();
234
255
if (UseCompressedClassPointers) {
235
- aligned_base = align_up (specified_base , Metaspace::reserve_alignment ());
256
+ alignment = MAX2 (alignment , Metaspace::reserve_alignment ());
236
257
}
237
258
259
+ if (SharedBaseAddress == 0 ) {
260
+ // Special meaning of -XX:SharedBaseAddress=0 -> Always map archive at os-selected address.
261
+ return specified_base;
262
+ }
263
+
264
+ char * aligned_base = align_up_or_null (specified_base, alignment);
265
+
238
266
if (aligned_base != specified_base) {
239
267
log_info (cds)(" SharedBaseAddress (" INTPTR_FORMAT " ) aligned up to " INTPTR_FORMAT,
240
268
p2i (specified_base), p2i (aligned_base));
241
269
}
242
270
243
271
const char * err = nullptr ;
244
- if (shared_base_too_high (specified_base, aligned_base, cds_max)) {
272
+ if (aligned_base == nullptr ) {
273
+ err = " too high" ;
274
+ } else if (shared_base_too_high (specified_base, aligned_base, cds_max)) {
245
275
err = " too high" ;
246
276
} else if (!shared_base_valid (aligned_base)) {
247
277
err = " invalid for this platform" ;
248
278
} else {
249
279
return aligned_base;
250
280
}
251
281
282
+ // Arguments::default_SharedBaseAddress() is hard-coded in cds_globals.hpp. It must be carefully
283
+ // picked that (a) the align_up() below will always return a valid value; (b) none of
284
+ // the following asserts will fail.
252
285
log_warning (cds)(" SharedBaseAddress (" INTPTR_FORMAT " ) is %s. Reverted to " INTPTR_FORMAT,
253
286
p2i ((void *)SharedBaseAddress), err,
254
287
p2i ((void *)Arguments::default_SharedBaseAddress ()));
255
288
256
289
specified_base = (char *)Arguments::default_SharedBaseAddress ();
257
- aligned_base = align_up (specified_base, MetaspaceShared::core_region_alignment () );
290
+ aligned_base = align_up (specified_base, alignment );
258
291
259
292
// Make sure the default value of SharedBaseAddress specified in globals.hpp is sane.
260
293
assert (!shared_base_too_high (specified_base, aligned_base, cds_max), " Sanity" );
0 commit comments