comparison src/share/vm/interpreter/oopMapCache.cpp @ 48:d8b3ef7ee3e5

6599425: 4/3 OopMapCache::lookup() can cause later crash or assert() failure Summary: Add should_not_be_cached() to markOop and methodOop and query that status inOopMapCache::lookup() Reviewed-by: coleenp, sspitsyn, jmasa
author dcubed
date Wed, 12 Mar 2008 18:07:46 -0700
parents a61af66fc99e
children d1605aabd0a1
comparison
equal deleted inserted replaced
47:2c106685d6d0 48:d8b3ef7ee3e5
530 void OopMapCache::flush_obsolete_entries() { 530 void OopMapCache::flush_obsolete_entries() {
531 for (int i = 0; i < _size; i++) 531 for (int i = 0; i < _size; i++)
532 if (!_array[i].is_empty() && _array[i].method()->is_old()) { 532 if (!_array[i].is_empty() && _array[i].method()->is_old()) {
533 // Cache entry is occupied by an old redefined method and we don't want 533 // Cache entry is occupied by an old redefined method and we don't want
534 // to pin it down so flush the entry. 534 // to pin it down so flush the entry.
535 RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d",
536 _array[i].method()->name()->as_C_string(),
537 _array[i].method()->signature()->as_C_string(), i));
538
535 _array[i].flush(); 539 _array[i].flush();
536 } 540 }
537 } 541 }
538 542
539 void OopMapCache::oop_iterate(OopClosure *blk) { 543 void OopMapCache::oop_iterate(OopClosure *blk) {
575 } 579 }
576 580
577 // Entry is not in hashtable. 581 // Entry is not in hashtable.
578 // Compute entry and return it 582 // Compute entry and return it
579 583
584 if (method->should_not_be_cached()) {
585 // It is either not safe or not a good idea to cache this methodOop
586 // at this time. We give the caller of lookup() a copy of the
587 // interesting info via parameter entry_for, but we don't add it to
588 // the cache. See the gory details in methodOop.cpp.
589 compute_one_oop_map(method, bci, entry_for);
590 return;
591 }
592
580 // First search for an empty slot 593 // First search for an empty slot
581 for(i = 0; i < _probe_depth; i++) { 594 for(i = 0; i < _probe_depth; i++) {
582 entry = entry_at(probe + i); 595 entry = entry_at(probe + i);
583 if (entry->is_empty()) { 596 if (entry->is_empty()) {
584 entry->fill(method, bci); 597 entry->fill(method, bci);
585 entry_for->resource_copy(entry); 598 entry_for->resource_copy(entry);
586 assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); 599 assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
587 if (method->is_old()) {
588 // The caller of lookup() will receive a copy of the interesting
589 // info via entry_for, but we don't keep an old redefined method in
590 // the cache to avoid pinning down the method.
591 entry->flush();
592 }
593 return; 600 return;
594 } 601 }
595 } 602 }
596 603
597 if (TraceOopMapGeneration) { 604 if (TraceOopMapGeneration) {
621 tty->print("Done with "); 628 tty->print("Done with ");
622 method->print_value(); tty->cr(); 629 method->print_value(); tty->cr();
623 } 630 }
624 assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); 631 assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
625 632
626 if (method->is_old()) {
627 // The caller of lookup() will receive a copy of the interesting
628 // info via entry_for, but we don't keep an old redefined method in
629 // the cache to avoid pinning down the method.
630 entry->flush();
631 }
632
633 return; 633 return;
634 } 634 }
635 635
636 void OopMapCache::compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry) { 636 void OopMapCache::compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry) {
637 // Due to the invariants above it's tricky to allocate a temporary OopMapCacheEntry on the stack 637 // Due to the invariants above it's tricky to allocate a temporary OopMapCacheEntry on the stack