1357 1358 if (to_dealloc_indices != NULL) { 1359 // we allocated a new cache so free the old one 1360 FreeHeap(to_dealloc_indices); 1361 } 1362 } 1363 1364 1365 // Retrieve a cached itable index 1366 int instanceKlass::cached_itable_index(size_t idnum) { 1367 int* indices = methods_cached_itable_indices_acquire(); 1368 if (indices != NULL && ((size_t)indices[0]) > idnum) { 1369 // indices exist and are long enough, retrieve possible cached 1370 return indices[idnum+1]; 1371 } 1372 return -1; 1373 } 1374 1375 1376 // 1377 // nmethodBucket is used to record dependent nmethods for 1378 // deoptimization. nmethod dependencies are actually <klass, method> 1379 // pairs but we really only care about the klass part for purposes of 1380 // finding nmethods which might need to be deoptimized. Instead of 1381 // recording the method, a count of how many times a particular nmethod 1382 // was recorded is kept. This ensures that any recording errors are 1383 // noticed since an nmethod should be removed as many times are it's 1384 // added. 1385 // 1386 class nmethodBucket { 1387 private: 1388 nmethod* _nmethod; 1389 int _count; 1390 nmethodBucket* _next; 1391 1392 public: 1393 nmethodBucket(nmethod* nmethod, nmethodBucket* next) { 1394 _nmethod = nmethod; 1395 _next = next; 1396 _count = 1; 1397 } 1398 int count() { return _count; } 1399 int increment() { _count += 1; return _count; } 1400 int decrement() { _count -= 1; assert(_count >= 0, "don't underflow"); return _count; } 1401 nmethodBucket* next() { return _next; } 1402 void set_next(nmethodBucket* b) { _next = b; } 1403 nmethod* get_nmethod() { return _nmethod; } 1404 }; 1405 1406 1407 // 1408 // Walk the list of dependent nmethods searching for nmethods which 1409 // are dependent on the changes that were passed in and mark them for 1410 // deoptimization. Returns the number of nmethods found. 1411 // 1412 int instanceKlass::mark_dependent_nmethods(DepChange& changes) { 1413 assert_locked_or_safepoint(CodeCache_lock); 1414 int found = 0; 1415 nmethodBucket* b = _dependencies; 1416 while (b != NULL) { 1417 nmethod* nm = b->get_nmethod(); 1418 // since dependencies aren't removed until an nmethod becomes a zombie, 1419 // the dependency list may contain nmethods which aren't alive. 1420 if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) { 1421 if (TraceDependencies) { 1422 ResourceMark rm; 1423 tty->print_cr("Marked for deoptimization"); 1424 tty->print_cr(" context = %s", this->external_name()); 1425 changes.print(); 1426 nm->print(); 1427 nm->print_dependencies(); | 1357 1358 if (to_dealloc_indices != NULL) { 1359 // we allocated a new cache so free the old one 1360 FreeHeap(to_dealloc_indices); 1361 } 1362 } 1363 1364 1365 // Retrieve a cached itable index 1366 int instanceKlass::cached_itable_index(size_t idnum) { 1367 int* indices = methods_cached_itable_indices_acquire(); 1368 if (indices != NULL && ((size_t)indices[0]) > idnum) { 1369 // indices exist and are long enough, retrieve possible cached 1370 return indices[idnum+1]; 1371 } 1372 return -1; 1373 } 1374 1375 1376 // 1377 // Walk the list of dependent nmethods searching for nmethods which 1378 // are dependent on the changes that were passed in and mark them for 1379 // deoptimization. Returns the number of nmethods found. 1380 // 1381 int instanceKlass::mark_dependent_nmethods(DepChange& changes) { 1382 assert_locked_or_safepoint(CodeCache_lock); 1383 int found = 0; 1384 nmethodBucket* b = _dependencies; 1385 while (b != NULL) { 1386 nmethod* nm = b->get_nmethod(); 1387 // since dependencies aren't removed until an nmethod becomes a zombie, 1388 // the dependency list may contain nmethods which aren't alive. 1389 if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) { 1390 if (TraceDependencies) { 1391 ResourceMark rm; 1392 tty->print_cr("Marked for deoptimization"); 1393 tty->print_cr(" context = %s", this->external_name()); 1394 changes.print(); 1395 nm->print(); 1396 nm->print_dependencies(); |