@@ -1251,6 +1251,54 @@ void CodeCache::cleanup_inline_caches_whitebox() {
1251
1251
// Keeps track of time spent for checking dependencies
1252
1252
NOT_PRODUCT (static elapsedTimer dependentCheckTime;)
1253
1253
1254
+ #ifndef PRODUCT
1255
+ // Check if any of live methods dependencies have been invalidated.
1256
+ // (this is expensive!)
1257
+ static void check_live_nmethods_dependencies (DepChange& changes) {
1258
+ // Checked dependencies are allocated into this ResourceMark
1259
+ ResourceMark rm;
1260
+
1261
+ // Turn off dependency tracing while actually testing dependencies.
1262
+ FlagSetting fs (Dependencies::_verify_in_progress, true );
1263
+
1264
+ typedef ResourceHashtable<DependencySignature, int , 11027 ,
1265
+ AnyObj::RESOURCE_AREA, mtInternal,
1266
+ &DependencySignature::hash,
1267
+ &DependencySignature::equals> DepTable;
1268
+
1269
+ DepTable* table = new DepTable ();
1270
+
1271
+ // Iterate over live nmethods and check dependencies of all nmethods that are not
1272
+ // marked for deoptimization. A particular dependency is only checked once.
1273
+ NMethodIterator iter (NMethodIterator::only_not_unloading);
1274
+ while (iter.next ()) {
1275
+ nmethod* nm = iter.method ();
1276
+ // Only notify for live nmethods
1277
+ if (!nm->is_marked_for_deoptimization ()) {
1278
+ for (Dependencies::DepStream deps (nm); deps.next (); ) {
1279
+ // Construct abstraction of a dependency.
1280
+ DependencySignature* current_sig = new DependencySignature (deps);
1281
+
1282
+ // Determine if dependency is already checked. table->put(...) returns
1283
+ // 'true' if the dependency is added (i.e., was not in the hashtable).
1284
+ if (table->put (*current_sig, 1 )) {
1285
+ if (deps.check_dependency () != nullptr ) {
1286
+ // Dependency checking failed. Print out information about the failed
1287
+ // dependency and finally fail with an assert. We can fail here, since
1288
+ // dependency checking is never done in a product build.
1289
+ tty->print_cr (" Failed dependency:" );
1290
+ changes.print ();
1291
+ nm->print ();
1292
+ nm->print_dependencies_on (tty);
1293
+ assert (false , " Should have been marked for deoptimization" );
1294
+ }
1295
+ }
1296
+ }
1297
+ }
1298
+ }
1299
+ }
1300
+ #endif
1301
+
1254
1302
void CodeCache::mark_for_deoptimization (DeoptimizationScope* deopt_scope, KlassDepChange& changes) {
1255
1303
MutexLocker mu (CodeCache_lock, Mutex::_no_safepoint_check_flag);
1256
1304
@@ -1272,7 +1320,7 @@ void CodeCache::mark_for_deoptimization(DeoptimizationScope* deopt_scope, KlassD
1272
1320
// Object pointers are used as unique identifiers for dependency arguments. This
1273
1321
// is only possible if no safepoint, i.e., GC occurs during the verification code.
1274
1322
dependentCheckTime.start ();
1275
- nmethod::check_all_dependencies (changes);
1323
+ check_live_nmethods_dependencies (changes);
1276
1324
dependentCheckTime.stop ();
1277
1325
}
1278
1326
#endif
1 commit comments
openjdk-notifier[bot] commentedon Oct 12, 2023
Review
Issues