@@ -147,6 +147,10 @@ size_t MetaspaceShared::core_region_alignment() {
147
147
return os::cds_core_region_alignment ();
148
148
}
149
149
150
+ size_t MetaspaceShared::protection_zone_size () {
151
+ return os::cds_core_region_alignment ();
152
+ }
153
+
150
154
static bool shared_base_valid (char * shared_base) {
151
155
// We check user input for SharedBaseAddress at dump time.
152
156
@@ -1280,6 +1284,7 @@ MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, File
1280
1284
1281
1285
ReservedSpace total_space_rs, archive_space_rs, class_space_rs;
1282
1286
MapArchiveResult result = MAP_ARCHIVE_OTHER_FAILURE;
1287
+ size_t prot_zone_size = 0 ;
1283
1288
char * mapped_base_address = reserve_address_space_for_archives (static_mapinfo,
1284
1289
dynamic_mapinfo,
1285
1290
use_requested_addr,
@@ -1291,14 +1296,29 @@ MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, File
1291
1296
log_debug (cds)(" Failed to reserve spaces (use_requested_addr=%u)" , (unsigned )use_requested_addr);
1292
1297
} else {
1293
1298
1299
+ if (Metaspace::using_class_space ()) {
1300
+ prot_zone_size = protection_zone_size ();
1301
+ #ifdef ASSERT
1302
+ // Before mapping the core regions into the newly established address space, we mark
1303
+ // start and the end of the future protection zone with canaries. That way we easily
1304
+ // catch mapping errors (accidentally mapping data into the future protection zone).
1305
+ os::commit_memory (mapped_base_address, prot_zone_size, false );
1306
+ *(mapped_base_address) = ' P' ;
1307
+ *(mapped_base_address + prot_zone_size - 1 ) = ' P' ;
1308
+ #endif
1309
+ }
1310
+
1294
1311
#ifdef ASSERT
1295
1312
// Some sanity checks after reserving address spaces for archives
1296
1313
// and class space.
1297
1314
assert (archive_space_rs.is_reserved (), " Sanity" );
1298
1315
if (Metaspace::using_class_space ()) {
1316
+ assert (archive_space_rs.base () == mapped_base_address &&
1317
+ archive_space_rs.size () > protection_zone_size (),
1318
+ " Archive space must lead and include the protection zone" );
1299
1319
// Class space must closely follow the archive space. Both spaces
1300
1320
// must be aligned correctly.
1301
- assert (class_space_rs.is_reserved (),
1321
+ assert (class_space_rs.is_reserved () && class_space_rs. size () > 0 ,
1302
1322
" A class space should have been reserved" );
1303
1323
assert (class_space_rs.base () >= archive_space_rs.end (),
1304
1324
" class space should follow the cds archive space" );
@@ -1311,8 +1331,9 @@ MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, File
1311
1331
}
1312
1332
#endif // ASSERT
1313
1333
1314
- log_info (cds)(" Reserved archive_space_rs [" INTPTR_FORMAT " - " INTPTR_FORMAT " ] (%zu) bytes" ,
1315
- p2i (archive_space_rs.base ()), p2i (archive_space_rs.end ()), archive_space_rs.size ());
1334
+ log_info (cds)(" Reserved archive_space_rs [" INTPTR_FORMAT " - " INTPTR_FORMAT " ] (%zu) bytes%s" ,
1335
+ p2i (archive_space_rs.base ()), p2i (archive_space_rs.end ()), archive_space_rs.size (),
1336
+ (prot_zone_size > 0 ? " (includes protection zone)" : " " ));
1316
1337
log_info (cds)(" Reserved class_space_rs [" INTPTR_FORMAT " - " INTPTR_FORMAT " ] (%zu) bytes" ,
1317
1338
p2i (class_space_rs.base ()), p2i (class_space_rs.end ()), class_space_rs.size ());
1318
1339
@@ -1384,38 +1405,40 @@ MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, File
1384
1405
if (result == MAP_ARCHIVE_SUCCESS) {
1385
1406
SharedBaseAddress = (size_t )mapped_base_address;
1386
1407
#ifdef _LP64
1387
- if (Metaspace::using_class_space ()) {
1388
- // Set up ccs in metaspace.
1389
- Metaspace::initialize_class_space (class_space_rs);
1390
-
1391
- // Set up compressed Klass pointer encoding: the encoding range must
1392
- // cover both archive and class space.
1393
- address cds_base = (address)static_mapinfo->mapped_base ();
1394
- address ccs_end = (address)class_space_rs.end ();
1395
- assert (ccs_end > cds_base, " Sanity check" );
1396
- if (INCLUDE_CDS_JAVA_HEAP || UseCompactObjectHeaders) {
1397
- // The CDS archive may contain narrow Klass IDs that were precomputed at archive generation time:
1398
- // - every archived java object header (only if INCLUDE_CDS_JAVA_HEAP)
1399
- // - every archived Klass' prototype (only if +UseCompactObjectHeaders)
1400
- //
1401
- // In order for those IDs to still be valid, we need to dictate base and shift: base should be the
1402
- // mapping start, shift the shift used at archive generation time.
1403
- address precomputed_narrow_klass_base = cds_base;
1404
- const int precomputed_narrow_klass_shift = ArchiveBuilder::precomputed_narrow_klass_shift ();
1405
- CompressedKlassPointers::initialize_for_given_encoding (
1406
- cds_base, ccs_end - cds_base, // Klass range
1407
- precomputed_narrow_klass_base, precomputed_narrow_klass_shift // precomputed encoding, see ArchiveBuilder
1408
- );
1409
- } else {
1410
- // Let JVM freely chose encoding base and shift
1411
- CompressedKlassPointers::initialize (
1412
- cds_base, ccs_end - cds_base // Klass range
1413
- );
1414
- }
1415
- // map_or_load_heap_region() compares the current narrow oop and klass encodings
1416
- // with the archived ones, so it must be done after all encodings are determined.
1417
- static_mapinfo->map_or_load_heap_region ();
1418
- }
1408
+ if (Metaspace::using_class_space ()) {
1409
+ assert (*(mapped_base_address) == ' P' &&
1410
+ *(mapped_base_address + prot_zone_size - 1 ) == ' P' ,
1411
+ " Protection zone was overwritten?" );
1412
+
1413
+ // Set up ccs in metaspace.
1414
+ Metaspace::initialize_class_space (class_space_rs);
1415
+
1416
+ // Set up compressed Klass pointer encoding: the encoding range must
1417
+ // cover both archive and class space.
1418
+ const address encoding_base = (address)mapped_base_address;
1419
+ const address klass_range_start = encoding_base + prot_zone_size;
1420
+ const size_t klass_range_size = (address)class_space_rs.end () - klass_range_start;
1421
+ if (INCLUDE_CDS_JAVA_HEAP || UseCompactObjectHeaders) {
1422
+ // The CDS archive may contain narrow Klass IDs that were precomputed at archive generation time:
1423
+ // - every archived java object header (only if INCLUDE_CDS_JAVA_HEAP)
1424
+ // - every archived Klass' prototype (only if +UseCompactObjectHeaders)
1425
+ //
1426
+ // In order for those IDs to still be valid, we need to dictate base and shift: base should be the
1427
+ // mapping start (including protection zone), shift should be the shift used at archive generation time.
1428
+ CompressedKlassPointers::initialize_for_given_encoding (
1429
+ klass_range_start, klass_range_size,
1430
+ encoding_base, ArchiveBuilder::precomputed_narrow_klass_shift () // precomputed encoding, see ArchiveBuilder
1431
+ );
1432
+ } else {
1433
+ // Let JVM freely chose encoding base and shift
1434
+ CompressedKlassPointers::initialize (klass_range_start, klass_range_size);
1435
+ }
1436
+ CompressedKlassPointers::establish_protection_zone (encoding_base, prot_zone_size);
1437
+
1438
+ // map_or_load_heap_region() compares the current narrow oop and klass encodings
1439
+ // with the archived ones, so it must be done after all encodings are determined.
1440
+ static_mapinfo->map_or_load_heap_region ();
1441
+ }
1419
1442
#endif // _LP64
1420
1443
log_info (cds)(" initial optimized module handling: %s" , CDSConfig::is_using_optimized_module_handling () ? " enabled" : " disabled" );
1421
1444
log_info (cds)(" initial full module graph: %s" , CDSConfig::is_using_full_module_graph () ? " enabled" : " disabled" );
@@ -1497,7 +1520,6 @@ char* MetaspaceShared::reserve_address_space_for_archives(FileMapInfo* static_ma
1497
1520
const size_t archive_space_alignment = core_region_alignment ();
1498
1521
1499
1522
// Size and requested location of the archive_space_rs (for both static and dynamic archives)
1500
- assert (static_mapinfo->mapping_base_offset () == 0 , " Must be" );
1501
1523
size_t archive_end_offset = (dynamic_mapinfo == nullptr ) ? static_mapinfo->mapping_end_offset () : dynamic_mapinfo->mapping_end_offset ();
1502
1524
size_t archive_space_size = align_up (archive_end_offset, archive_space_alignment);
1503
1525
0 commit comments