@@ -460,7 +460,14 @@ JITServerLocalSCCAOTDeserializer::cacheRecord(const ClassSerializationRecord *re
460
460
uintptr_t loaderOffset = (uintptr_t )-1 ;
461
461
J9ClassLoader *loader = getClassLoader (record->classLoaderId (), loaderOffset, comp, wasReset);
462
462
if (!loader)
463
+ {
464
+ if (TR::Options::getVerboseOption (TR_VerboseJITServer))
465
+ TR_VerboseLog::writeLineLocked (TR_Vlog_JITServer,
466
+ " ERROR: Class loader for class %.*s ID %zu was marked invalid" ,
467
+ RECORD_NAME (record), record->id ()
468
+ );
463
469
return false ;
470
+ }
464
471
465
472
// Lookup the RAMClass by name in the class loader
466
473
J9Class *ramClass = jitGetClassInClassloaderFromUTF8 (comp->j9VMThread (), loader, (char *)record->name (),
@@ -1072,7 +1079,14 @@ JITServerNoSCCAOTDeserializer::cacheRecord(const ClassSerializationRecord *recor
1072
1079
// we simply fail to deserialize here.
1073
1080
auto loader = findInMap (_classLoaderIdMap, record->classLoaderId (), getClassLoaderMonitor (), comp, wasReset);
1074
1081
if (!loader)
1082
+ {
1083
+ if (TR::Options::getVerboseOption (TR_VerboseJITServer))
1084
+ TR_VerboseLog::writeLineLocked (TR_Vlog_JITServer,
1085
+ " ERROR: Class loader for class %.*s ID %zu was marked invalid" ,
1086
+ RECORD_NAME (record), record->id ()
1087
+ );
1075
1088
return false ;
1089
+ }
1076
1090
1077
1091
// Lookup the RAMClass by name in the class loader
1078
1092
J9Class *ramClass = jitGetClassInClassloaderFromUTF8 (comp->j9VMThread (), loader, (char *)record->name (),
@@ -1156,24 +1170,6 @@ JITServerNoSCCAOTDeserializer::cacheRecord(const MethodSerializationRecord *reco
1156
1170
return true ;
1157
1171
}
1158
1172
1159
- // We confirmed that the first class in the chain had a RAM class chain that was equal to
1160
- // what was recorded at compile time, but that may have changed (due to class redefinition or
1161
- // invalidation somewhere along the chain). Since we don't support class reloading, we only
1162
- // have to check that the individual class entries remain valid.
1163
- bool
1164
- JITServerNoSCCAOTDeserializer::revalidateClassChain (uintptr_t *classChain, TR::Compilation *comp, bool &wasReset)
1165
- {
1166
- size_t chainLength = classChain[0 ] / sizeof (classChain[0 ]) - 1 ;
1167
- uintptr_t *chainData = classChain + 1 ;
1168
- for (size_t i = 0 ; i < chainLength; ++i)
1169
- {
1170
- auto ramClass = findInMap (_classIdMap, offsetId (chainData[i]), getClassMonitor (), comp, wasReset)._ramClass ;
1171
- if (!ramClass)
1172
- return false ;
1173
- }
1174
- return true ;
1175
- }
1176
-
1177
1173
void
1178
1174
JITServerNoSCCAOTDeserializer::getRAMClassChain (TR::Compilation *comp, J9Class *clazz, J9Class **chainBuffer, size_t &chainLength)
1179
1175
{
@@ -1214,22 +1210,7 @@ JITServerNoSCCAOTDeserializer::cacheRecord(const ClassChainSerializationRecord *
1214
1210
1215
1211
auto it = _classChainMap.find (record->id ());
1216
1212
if (it != _classChainMap.end ())
1217
- {
1218
- if (revalidateClassChain (it->second , comp, wasReset))
1219
- {
1220
- return true ;
1221
- }
1222
- else
1223
- {
1224
- TR::Compiler->persistentGlobalMemory ()->freePersistentMemory (it->second );
1225
- it->second = NULL ;
1226
- if (TR::Options::getVerboseOption (TR_VerboseJITServer))
1227
- TR_VerboseLog::writeLineLocked (TR_Vlog_JITServer,
1228
- " Invalidated cached class chain record ID %zu" , record->id ()
1229
- );
1230
- return false ;
1231
- }
1232
- }
1213
+ return true ;
1233
1214
isNew = true ;
1234
1215
1235
1216
// Get the RAM class chain for the first class referenced in the class chain serialization record
@@ -1298,21 +1279,6 @@ JITServerNoSCCAOTDeserializer::cacheRecord(const ClassChainSerializationRecord *
1298
1279
return true ;
1299
1280
}
1300
1281
1301
- // See revalidateClassChain()
1302
- bool
1303
- JITServerNoSCCAOTDeserializer::revalidateWellKnownClasses (uintptr_t *wellKnownClassesChain, TR::Compilation *comp, bool &wasReset)
1304
- {
1305
- size_t chainLength = wellKnownClassesChain[0 ];
1306
- uintptr_t *chainData = wellKnownClassesChain + 1 ;
1307
- for (size_t i = 0 ; i < chainLength; ++i)
1308
- {
1309
- auto classChain = findInMap (_classChainMap, offsetId (chainData[i]), getClassChainMonitor (), comp, wasReset);
1310
- if (!classChain)
1311
- return false ;
1312
- }
1313
- return true ;
1314
- }
1315
-
1316
1282
bool
1317
1283
JITServerNoSCCAOTDeserializer::cacheRecord (const WellKnownClassesSerializationRecord *record, TR::Compilation *comp, bool &isNew, bool &wasReset)
1318
1284
{
@@ -1322,22 +1288,7 @@ JITServerNoSCCAOTDeserializer::cacheRecord(const WellKnownClassesSerializationRe
1322
1288
1323
1289
auto it = _wellKnownClassesMap.find (record->id ());
1324
1290
if (it != _wellKnownClassesMap.end ())
1325
- {
1326
- if (revalidateWellKnownClasses (it->second , comp, wasReset))
1327
- {
1328
- return true ;
1329
- }
1330
- else
1331
- {
1332
- TR::Compiler->persistentGlobalMemory ()->freePersistentMemory (it->second );
1333
- it->second = NULL ;
1334
- if (TR::Options::getVerboseOption (TR_VerboseJITServer))
1335
- TR_VerboseLog::writeLineLocked (TR_Vlog_JITServer,
1336
- " Invalidated cached well-known classes record ID %zu" , record->id ()
1337
- );
1338
- return false ;
1339
- }
1340
- }
1291
+ return true ;
1341
1292
isNew = true ;
1342
1293
1343
1294
// Initialize the "well-known classes" object (see SymbolValidationManager::populateWellKnownClasses()).
@@ -1414,6 +1365,8 @@ JITServerNoSCCAOTDeserializer::updateSCCOffsets(SerializedAOTMethod *method, TR:
1414
1365
if (serializedOffset.recordType () == AOTSerializationRecordType::Thunk)
1415
1366
continue ;
1416
1367
1368
+ if (!revalidateRecord (serializedOffset.recordType (), serializedOffset.recordId (), comp, wasReset))
1369
+ return false ;
1417
1370
uintptr_t offset = encodeOffset (serializedOffset);
1418
1371
1419
1372
// Update the SCC offset stored in AOT method relocation data
@@ -1435,6 +1388,101 @@ JITServerNoSCCAOTDeserializer::updateSCCOffsets(SerializedAOTMethod *method, TR:
1435
1388
return true ;
1436
1389
}
1437
1390
1391
+ bool
1392
+ JITServerNoSCCAOTDeserializer::revalidateRecord (AOTSerializationRecordType type, uintptr_t id, TR::Compilation *comp, bool &wasReset)
1393
+ {
1394
+ switch (type)
1395
+ {
1396
+ case ClassLoader:
1397
+ {
1398
+ auto loader = findInMap (_classLoaderIdMap, id, getClassLoaderMonitor (), comp, wasReset);
1399
+ return !wasReset && (loader != NULL );
1400
+ }
1401
+ case Class:
1402
+ {
1403
+ auto clazz = findInMap (_classIdMap, id, getClassMonitor (), comp, wasReset)._ramClass ;
1404
+ return !wasReset && (clazz != NULL );
1405
+ }
1406
+ case Method:
1407
+ {
1408
+ auto method = findInMap (_methodIdMap, id, getMethodMonitor (), comp, wasReset);
1409
+ return !wasReset && (method != NULL );
1410
+ }
1411
+ case ClassChain:
1412
+ {
1413
+ // Why do we need to revalidate the entire chain here?
1414
+ // Note that only serialization records the server thinks the client needs are sent to the client,
1415
+ // and only offsets used in the method's relocation records get serialized SCC offsets. That means
1416
+ // that we aren't guaranteed to have revalidated every class mentioned in this class chain, and so
1417
+ // we must check the entire chain here.
1418
+ OMR::CriticalSection cs (getClassChainMonitor ());
1419
+ if (deserializerWasReset (comp, wasReset))
1420
+ return false ;
1421
+
1422
+ auto it = _classChainMap.find (id);
1423
+ if (it == _classChainMap.end () || !it->second )
1424
+ return false ;
1425
+
1426
+ size_t chainLength = it->second [0 ] / sizeof (it->second [0 ]) - 1 ;
1427
+ uintptr_t *chainData = it->second + 1 ;
1428
+ for (size_t i = 0 ; i < chainLength; ++i)
1429
+ {
1430
+ auto ramClass = findInMap (_classIdMap, offsetId (chainData[i]), getClassMonitor (), comp, wasReset)._ramClass ;
1431
+ if (!ramClass)
1432
+ {
1433
+ TR::Compiler->persistentGlobalMemory ()->freePersistentMemory (it->second );
1434
+ it->second = NULL ;
1435
+ if (TR::Options::getVerboseOption (TR_VerboseJITServer))
1436
+ TR_VerboseLog::writeLineLocked (TR_Vlog_JITServer,
1437
+ " Invalidated cached class chain record ID %zu" , id
1438
+ );
1439
+ return false ;
1440
+ }
1441
+ }
1442
+ return true ;
1443
+ }
1444
+ case WellKnownClasses:
1445
+ {
1446
+ // See the note for case ClassChain
1447
+ OMR::CriticalSection cs (getWellKnownClassesMonitor ());
1448
+ if (deserializerWasReset (comp, wasReset))
1449
+ return false ;
1450
+
1451
+ auto it = _wellKnownClassesMap.find (id);
1452
+ if ((it == _wellKnownClassesMap.end ()) || !it->second )
1453
+ return false ;
1454
+
1455
+ size_t chainLength = it->second [0 ];
1456
+ uintptr_t *chainData = it->second + 1 ;
1457
+ for (size_t i = 0 ; i < chainLength; ++i)
1458
+ {
1459
+ auto classChain = findInMap (_classChainMap, offsetId (chainData[i]), getClassChainMonitor (), comp, wasReset);
1460
+ if (!classChain)
1461
+ {
1462
+ TR::Compiler->persistentGlobalMemory ()->freePersistentMemory (it->second );
1463
+ it->second = NULL ;
1464
+ if (TR::Options::getVerboseOption (TR_VerboseJITServer))
1465
+ TR_VerboseLog::writeLineLocked (TR_Vlog_JITServer,
1466
+ " Invalidated cached well-known classes record ID %zu" , id
1467
+ );
1468
+ return false ;
1469
+ }
1470
+ }
1471
+ return true ;
1472
+ }
1473
+ case Thunk:
1474
+ {
1475
+ // Thunks are not cached, so do not need to be revalidated
1476
+ return true ;
1477
+ }
1478
+ default :
1479
+ {
1480
+ TR_ASSERT_FATAL (false , " Invalid record type: %u" , type);
1481
+ return false ;
1482
+ }
1483
+ }
1484
+ }
1485
+
1438
1486
J9ROMClass *
1439
1487
JITServerNoSCCAOTDeserializer::romClassFromOffsetInSharedCache (uintptr_t offset, TR::Compilation *comp, bool &wasReset)
1440
1488
{
0 commit comments