hotspot/src/share/vm/oops/instanceKlass.cpp
changeset 34195 89011d12ebd3
parent 33638 ef49ed90010b
child 34221 3c271ee8fb98
equal deleted inserted replaced
34194:213af0859e7e 34195:89011d12ebd3
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "classfile/javaClasses.hpp"
    26 #include "classfile/javaClasses.hpp"
    27 #include "classfile/systemDictionary.hpp"
    27 #include "classfile/systemDictionary.hpp"
    28 #include "classfile/verifier.hpp"
    28 #include "classfile/verifier.hpp"
    29 #include "classfile/vmSymbols.hpp"
    29 #include "classfile/vmSymbols.hpp"
       
    30 #include "code/dependencyContext.hpp"
    30 #include "compiler/compileBroker.hpp"
    31 #include "compiler/compileBroker.hpp"
    31 #include "gc/shared/collectedHeap.inline.hpp"
    32 #include "gc/shared/collectedHeap.inline.hpp"
    32 #include "gc/shared/specialized_oop_closures.hpp"
    33 #include "gc/shared/specialized_oop_closures.hpp"
    33 #include "interpreter/oopMapCache.hpp"
    34 #include "interpreter/oopMapCache.hpp"
    34 #include "interpreter/rewriter.hpp"
    35 #include "interpreter/rewriter.hpp"
   201                              bool is_anonymous) {
   202                              bool is_anonymous) {
   202   No_Safepoint_Verifier no_safepoint; // until k becomes parsable
   203   No_Safepoint_Verifier no_safepoint; // until k becomes parsable
   203 
   204 
   204   int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
   205   int iksize = InstanceKlass::size(vtable_len, itable_len, nonstatic_oop_map_size,
   205                                    access_flags.is_interface(), is_anonymous);
   206                                    access_flags.is_interface(), is_anonymous);
   206 
       
   207   set_vtable_length(vtable_len);
   207   set_vtable_length(vtable_len);
   208   set_itable_length(itable_len);
   208   set_itable_length(itable_len);
   209   set_static_field_size(static_field_size);
   209   set_static_field_size(static_field_size);
   210   set_nonstatic_oop_map_size(nonstatic_oop_map_size);
   210   set_nonstatic_oop_map_size(nonstatic_oop_map_size);
   211   set_access_flags(access_flags);
   211   set_access_flags(access_flags);
   230   set_array_name(NULL);
   230   set_array_name(NULL);
   231   set_inner_classes(NULL);
   231   set_inner_classes(NULL);
   232   set_static_oop_field_count(0);
   232   set_static_oop_field_count(0);
   233   set_nonstatic_field_size(0);
   233   set_nonstatic_field_size(0);
   234   set_is_marked_dependent(false);
   234   set_is_marked_dependent(false);
   235   set_has_unloaded_dependent(false);
   235   _dep_context = DependencyContext::EMPTY;
   236   set_init_state(InstanceKlass::allocated);
   236   set_init_state(InstanceKlass::allocated);
   237   set_init_thread(NULL);
   237   set_init_thread(NULL);
   238   set_reference_type(rt);
   238   set_reference_type(rt);
   239   set_oop_map_cache(NULL);
   239   set_oop_map_cache(NULL);
   240   set_jni_ids(NULL);
   240   set_jni_ids(NULL);
   244   set_generic_signature_index(0);
   244   set_generic_signature_index(0);
   245   release_set_methods_jmethod_ids(NULL);
   245   release_set_methods_jmethod_ids(NULL);
   246   set_annotations(NULL);
   246   set_annotations(NULL);
   247   set_jvmti_cached_class_field_map(NULL);
   247   set_jvmti_cached_class_field_map(NULL);
   248   set_initial_method_idnum(0);
   248   set_initial_method_idnum(0);
   249   _dependencies = NULL;
       
   250   set_jvmti_cached_class_field_map(NULL);
   249   set_jvmti_cached_class_field_map(NULL);
   251   set_cached_class_file(NULL);
   250   set_cached_class_file(NULL);
   252   set_initial_method_idnum(0);
   251   set_initial_method_idnum(0);
   253   set_minor_version(0);
   252   set_minor_version(0);
   254   set_major_version(0);
   253   set_major_version(0);
  1852     id = jmeths[idnum+1];                       // Look up the id (may be NULL)
  1851     id = jmeths[idnum+1];                       // Look up the id (may be NULL)
  1853   }
  1852   }
  1854   return id;
  1853   return id;
  1855 }
  1854 }
  1856 
  1855 
  1857 int nmethodBucket::decrement() {
  1856 inline DependencyContext InstanceKlass::dependencies() {
  1858   return Atomic::add(-1, (volatile int *)&_count);
  1857   DependencyContext dep_context(&_dep_context);
  1859 }
  1858   return dep_context;
  1860 
  1859 }
  1861 //
       
  1862 // Walk the list of dependent nmethods searching for nmethods which
       
  1863 // are dependent on the changes that were passed in and mark them for
       
  1864 // deoptimization.  Returns the number of nmethods found.
       
  1865 //
       
  1866 int nmethodBucket::mark_dependent_nmethods(nmethodBucket* deps, DepChange& changes) {
       
  1867   assert_locked_or_safepoint(CodeCache_lock);
       
  1868   int found = 0;
       
  1869   for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
       
  1870     nmethod* nm = b->get_nmethod();
       
  1871     // since dependencies aren't removed until an nmethod becomes a zombie,
       
  1872     // the dependency list may contain nmethods which aren't alive.
       
  1873     if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) {
       
  1874       if (TraceDependencies) {
       
  1875         ResourceMark rm;
       
  1876         tty->print_cr("Marked for deoptimization");
       
  1877         changes.print();
       
  1878         nm->print();
       
  1879         nm->print_dependencies();
       
  1880       }
       
  1881       nm->mark_for_deoptimization();
       
  1882       found++;
       
  1883     }
       
  1884   }
       
  1885   return found;
       
  1886 }
       
  1887 
       
  1888 //
       
  1889 // Add an nmethodBucket to the list of dependencies for this nmethod.
       
  1890 // It's possible that an nmethod has multiple dependencies on this klass
       
  1891 // so a count is kept for each bucket to guarantee that creation and
       
  1892 // deletion of dependencies is consistent. Returns new head of the list.
       
  1893 //
       
  1894 nmethodBucket* nmethodBucket::add_dependent_nmethod(nmethodBucket* deps, nmethod* nm) {
       
  1895   assert_locked_or_safepoint(CodeCache_lock);
       
  1896   for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
       
  1897     if (nm == b->get_nmethod()) {
       
  1898       b->increment();
       
  1899       return deps;
       
  1900     }
       
  1901   }
       
  1902   return new nmethodBucket(nm, deps);
       
  1903 }
       
  1904 
       
  1905 //
       
  1906 // Decrement count of the nmethod in the dependency list and remove
       
  1907 // the bucket completely when the count goes to 0.  This method must
       
  1908 // find a corresponding bucket otherwise there's a bug in the
       
  1909 // recording of dependencies. Returns true if the bucket was deleted,
       
  1910 // or marked ready for reclaimation.
       
  1911 bool nmethodBucket::remove_dependent_nmethod(nmethodBucket** deps, nmethod* nm, bool delete_immediately) {
       
  1912   assert_locked_or_safepoint(CodeCache_lock);
       
  1913 
       
  1914   nmethodBucket* first = *deps;
       
  1915   nmethodBucket* last = NULL;
       
  1916 
       
  1917   for (nmethodBucket* b = first; b != NULL; b = b->next()) {
       
  1918     if (nm == b->get_nmethod()) {
       
  1919       int val = b->decrement();
       
  1920       guarantee(val >= 0, "Underflow: %d", val);
       
  1921       if (val == 0) {
       
  1922         if (delete_immediately) {
       
  1923           if (last == NULL) {
       
  1924             *deps = b->next();
       
  1925           } else {
       
  1926             last->set_next(b->next());
       
  1927           }
       
  1928           delete b;
       
  1929         }
       
  1930       }
       
  1931       return true;
       
  1932     }
       
  1933     last = b;
       
  1934   }
       
  1935 
       
  1936 #ifdef ASSERT
       
  1937   tty->print_raw_cr("### can't find dependent nmethod");
       
  1938   nm->print();
       
  1939 #endif // ASSERT
       
  1940   ShouldNotReachHere();
       
  1941   return false;
       
  1942 }
       
  1943 
       
  1944 // Convenience overload, for callers that don't want to delete the nmethodBucket entry.
       
  1945 bool nmethodBucket::remove_dependent_nmethod(nmethodBucket* deps, nmethod* nm) {
       
  1946   nmethodBucket** deps_addr = &deps;
       
  1947   return remove_dependent_nmethod(deps_addr, nm, false /* Don't delete */);
       
  1948 }
       
  1949 
       
  1950 //
       
  1951 // Reclaim all unused buckets. Returns new head of the list.
       
  1952 //
       
  1953 nmethodBucket* nmethodBucket::clean_dependent_nmethods(nmethodBucket* deps) {
       
  1954   nmethodBucket* first = deps;
       
  1955   nmethodBucket* last = NULL;
       
  1956   nmethodBucket* b = first;
       
  1957 
       
  1958   while (b != NULL) {
       
  1959     assert(b->count() >= 0, "bucket count: %d", b->count());
       
  1960     nmethodBucket* next = b->next();
       
  1961     if (b->count() == 0) {
       
  1962       if (last == NULL) {
       
  1963         first = next;
       
  1964       } else {
       
  1965         last->set_next(next);
       
  1966       }
       
  1967       delete b;
       
  1968       // last stays the same.
       
  1969     } else {
       
  1970       last = b;
       
  1971     }
       
  1972     b = next;
       
  1973   }
       
  1974   return first;
       
  1975 }
       
  1976 
       
  1977 #ifndef PRODUCT
       
  1978 void nmethodBucket::print_dependent_nmethods(nmethodBucket* deps, bool verbose) {
       
  1979   int idx = 0;
       
  1980   for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
       
  1981     nmethod* nm = b->get_nmethod();
       
  1982     tty->print("[%d] count=%d { ", idx++, b->count());
       
  1983     if (!verbose) {
       
  1984       nm->print_on(tty, "nmethod");
       
  1985       tty->print_cr(" } ");
       
  1986     } else {
       
  1987       nm->print();
       
  1988       nm->print_dependencies();
       
  1989       tty->print_cr("--- } ");
       
  1990     }
       
  1991   }
       
  1992 }
       
  1993 
       
  1994 bool nmethodBucket::is_dependent_nmethod(nmethodBucket* deps, nmethod* nm) {
       
  1995   for (nmethodBucket* b = deps; b != NULL; b = b->next()) {
       
  1996     if (nm == b->get_nmethod()) {
       
  1997 #ifdef ASSERT
       
  1998       int count = b->count();
       
  1999       assert(count >= 0, "count shouldn't be negative: %d", count);
       
  2000 #endif
       
  2001       return true;
       
  2002     }
       
  2003   }
       
  2004   return false;
       
  2005 }
       
  2006 #endif //PRODUCT
       
  2007 
  1860 
  2008 int InstanceKlass::mark_dependent_nmethods(DepChange& changes) {
  1861 int InstanceKlass::mark_dependent_nmethods(DepChange& changes) {
  2009   assert_locked_or_safepoint(CodeCache_lock);
  1862   return dependencies().mark_dependent_nmethods(changes);
  2010   return nmethodBucket::mark_dependent_nmethods(_dependencies, changes);
       
  2011 }
       
  2012 
       
  2013 void InstanceKlass::clean_dependent_nmethods() {
       
  2014   assert_locked_or_safepoint(CodeCache_lock);
       
  2015 
       
  2016   if (has_unloaded_dependent()) {
       
  2017     _dependencies = nmethodBucket::clean_dependent_nmethods(_dependencies);
       
  2018     set_has_unloaded_dependent(false);
       
  2019   }
       
  2020 #ifdef ASSERT
       
  2021   else {
       
  2022     // Verification
       
  2023     for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) {
       
  2024       assert(b->count() >= 0, "bucket count: %d", b->count());
       
  2025       assert(b->count() != 0, "empty buckets need to be cleaned");
       
  2026     }
       
  2027   }
       
  2028 #endif
       
  2029 }
  1863 }
  2030 
  1864 
  2031 void InstanceKlass::add_dependent_nmethod(nmethod* nm) {
  1865 void InstanceKlass::add_dependent_nmethod(nmethod* nm) {
  2032   assert_locked_or_safepoint(CodeCache_lock);
  1866   dependencies().add_dependent_nmethod(nm);
  2033   _dependencies = nmethodBucket::add_dependent_nmethod(_dependencies, nm);
       
  2034 }
  1867 }
  2035 
  1868 
  2036 void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) {
  1869 void InstanceKlass::remove_dependent_nmethod(nmethod* nm, bool delete_immediately) {
  2037   assert_locked_or_safepoint(CodeCache_lock);
  1870   dependencies().remove_dependent_nmethod(nm, delete_immediately);
  2038 
       
  2039   if (nmethodBucket::remove_dependent_nmethod(&_dependencies, nm, delete_immediately)) {
       
  2040     set_has_unloaded_dependent(true);
       
  2041   }
       
  2042 }
  1871 }
  2043 
  1872 
  2044 #ifndef PRODUCT
  1873 #ifndef PRODUCT
  2045 void InstanceKlass::print_dependent_nmethods(bool verbose) {
  1874 void InstanceKlass::print_dependent_nmethods(bool verbose) {
  2046   nmethodBucket::print_dependent_nmethods(_dependencies, verbose);
  1875   dependencies().print_dependent_nmethods(verbose);
  2047 }
  1876 }
  2048 
  1877 
  2049 bool InstanceKlass::is_dependent_nmethod(nmethod* nm) {
  1878 bool InstanceKlass::is_dependent_nmethod(nmethod* nm) {
  2050   return nmethodBucket::is_dependent_nmethod(_dependencies, nm);
  1879   return dependencies().is_dependent_nmethod(nm);
  2051 }
  1880 }
  2052 #endif //PRODUCT
  1881 #endif //PRODUCT
  2053 
  1882 
  2054 void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) {
  1883 void InstanceKlass::clean_weak_instanceklass_links(BoolObjectClosure* is_alive) {
  2055   clean_implementors_list(is_alive);
  1884   clean_implementors_list(is_alive);
  2056   clean_method_data(is_alive);
  1885   clean_method_data(is_alive);
  2057 
  1886 
  2058   clean_dependent_nmethods();
  1887   // Since GC iterates InstanceKlasses sequentially, it is safe to remove stale entries here.
       
  1888   DependencyContext dep_context(&_dep_context);
       
  1889   dep_context.expunge_stale_entries();
  2059 }
  1890 }
  2060 
  1891 
  2061 void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
  1892 void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
  2062   assert(class_loader_data()->is_alive(is_alive), "this klass should be live");
  1893   assert(class_loader_data()->is_alive(is_alive), "this klass should be live");
  2063   if (is_interface()) {
  1894   if (is_interface()) {
  2100   }
  1931   }
  2101   init_implementor();
  1932   init_implementor();
  2102 
  1933 
  2103   constants()->remove_unshareable_info();
  1934   constants()->remove_unshareable_info();
  2104 
  1935 
       
  1936   assert(_dep_context == DependencyContext::EMPTY, "dependency context is not shareable");
       
  1937 
  2105   for (int i = 0; i < methods()->length(); i++) {
  1938   for (int i = 0; i < methods()->length(); i++) {
  2106     Method* m = methods()->at(i);
  1939     Method* m = methods()->at(i);
  2107     m->remove_unshareable_info();
  1940     m->remove_unshareable_info();
  2108   }
  1941   }
  2109 
  1942 
  2229       set_member_names(NULL);
  2062       set_member_names(NULL);
  2230     }
  2063     }
  2231   }
  2064   }
  2232 
  2065 
  2233   // release dependencies
  2066   // release dependencies
  2234   nmethodBucket* b = _dependencies;
  2067   {
  2235   _dependencies = NULL;
  2068     DependencyContext ctx(&_dep_context);
  2236   while (b != NULL) {
  2069     int marked = ctx.remove_all_dependents();
  2237     nmethodBucket* next = b->next();
  2070     assert(marked == 0, "all dependencies should be already invalidated");
  2238     delete b;
       
  2239     b = next;
       
  2240   }
  2071   }
  2241 
  2072 
  2242   // Deallocate breakpoint records
  2073   // Deallocate breakpoint records
  2243   if (breakpoints() != 0x0) {
  2074   if (breakpoints() != 0x0) {
  2244     methods_do(clear_all_breakpoints);
  2075     methods_do(clear_all_breakpoints);
  3556 }
  3387 }
  3557 
  3388 
  3558 unsigned char * InstanceKlass::get_cached_class_file_bytes() {
  3389 unsigned char * InstanceKlass::get_cached_class_file_bytes() {
  3559   return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
  3390   return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
  3560 }
  3391 }
  3561 
       
  3562 
       
  3563 /////////////// Unit tests ///////////////
       
  3564 
       
  3565 #ifndef PRODUCT
       
  3566 
       
  3567 class TestNmethodBucketContext {
       
  3568  public:
       
  3569   nmethod* _nmethodLast;
       
  3570   nmethod* _nmethodMiddle;
       
  3571   nmethod* _nmethodFirst;
       
  3572 
       
  3573   nmethodBucket* _bucketLast;
       
  3574   nmethodBucket* _bucketMiddle;
       
  3575   nmethodBucket* _bucketFirst;
       
  3576 
       
  3577   nmethodBucket* _bucketList;
       
  3578 
       
  3579   TestNmethodBucketContext() {
       
  3580     CodeCache_lock->lock_without_safepoint_check();
       
  3581 
       
  3582     _nmethodLast   = reinterpret_cast<nmethod*>(0x8 * 0);
       
  3583     _nmethodMiddle = reinterpret_cast<nmethod*>(0x8 * 1);
       
  3584     _nmethodFirst  = reinterpret_cast<nmethod*>(0x8 * 2);
       
  3585 
       
  3586     _bucketLast   = new nmethodBucket(_nmethodLast,   NULL);
       
  3587     _bucketMiddle = new nmethodBucket(_nmethodMiddle, _bucketLast);
       
  3588     _bucketFirst  = new nmethodBucket(_nmethodFirst,   _bucketMiddle);
       
  3589 
       
  3590     _bucketList = _bucketFirst;
       
  3591   }
       
  3592 
       
  3593   ~TestNmethodBucketContext() {
       
  3594     delete _bucketLast;
       
  3595     delete _bucketMiddle;
       
  3596     delete _bucketFirst;
       
  3597 
       
  3598     CodeCache_lock->unlock();
       
  3599   }
       
  3600 };
       
  3601 
       
  3602 class TestNmethodBucket {
       
  3603  public:
       
  3604   static void testRemoveDependentNmethodFirstDeleteImmediately() {
       
  3605     TestNmethodBucketContext c;
       
  3606 
       
  3607     nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodFirst, true /* delete */);
       
  3608 
       
  3609     assert(c._bucketList == c._bucketMiddle, "check");
       
  3610     assert(c._bucketList->next() == c._bucketLast, "check");
       
  3611     assert(c._bucketList->next()->next() == NULL, "check");
       
  3612 
       
  3613     // Cleanup before context is deleted.
       
  3614     c._bucketFirst = NULL;
       
  3615   }
       
  3616 
       
  3617   static void testRemoveDependentNmethodMiddleDeleteImmediately() {
       
  3618     TestNmethodBucketContext c;
       
  3619 
       
  3620     nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodMiddle, true /* delete */);
       
  3621 
       
  3622     assert(c._bucketList == c._bucketFirst, "check");
       
  3623     assert(c._bucketList->next() == c._bucketLast, "check");
       
  3624     assert(c._bucketList->next()->next() == NULL, "check");
       
  3625 
       
  3626     // Cleanup before context is deleted.
       
  3627     c._bucketMiddle = NULL;
       
  3628   }
       
  3629 
       
  3630   static void testRemoveDependentNmethodLastDeleteImmediately() {
       
  3631     TestNmethodBucketContext c;
       
  3632 
       
  3633     nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodLast, true /* delete */);
       
  3634 
       
  3635     assert(c._bucketList == c._bucketFirst, "check");
       
  3636     assert(c._bucketList->next() == c._bucketMiddle, "check");
       
  3637     assert(c._bucketList->next()->next() == NULL, "check");
       
  3638 
       
  3639     // Cleanup before context is deleted.
       
  3640     c._bucketLast = NULL;
       
  3641   }
       
  3642 
       
  3643   static void testRemoveDependentNmethodFirstDeleteDeferred() {
       
  3644     TestNmethodBucketContext c;
       
  3645 
       
  3646     nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodFirst, false /* delete */);
       
  3647 
       
  3648     assert(c._bucketList                         == c._bucketFirst,  "check");
       
  3649     assert(c._bucketList->next()                 == c._bucketMiddle, "check");
       
  3650     assert(c._bucketList->next()->next()         == c._bucketLast,   "check");
       
  3651     assert(c._bucketList->next()->next()->next() == NULL,            "check");
       
  3652 
       
  3653     assert(c._bucketFirst->count()  == 0, "check");
       
  3654     assert(c._bucketMiddle->count() == 1, "check");
       
  3655     assert(c._bucketLast->count()   == 1, "check");
       
  3656   }
       
  3657 
       
  3658   static void testRemoveDependentNmethodMiddleDeleteDeferred() {
       
  3659     TestNmethodBucketContext c;
       
  3660 
       
  3661     nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodMiddle, false /* delete */);
       
  3662 
       
  3663     assert(c._bucketList                         == c._bucketFirst,  "check");
       
  3664     assert(c._bucketList->next()                 == c._bucketMiddle, "check");
       
  3665     assert(c._bucketList->next()->next()         == c._bucketLast,   "check");
       
  3666     assert(c._bucketList->next()->next()->next() == NULL,            "check");
       
  3667 
       
  3668     assert(c._bucketFirst->count()  == 1, "check");
       
  3669     assert(c._bucketMiddle->count() == 0, "check");
       
  3670     assert(c._bucketLast->count()   == 1, "check");
       
  3671   }
       
  3672 
       
  3673   static void testRemoveDependentNmethodLastDeleteDeferred() {
       
  3674     TestNmethodBucketContext c;
       
  3675 
       
  3676     nmethodBucket::remove_dependent_nmethod(&c._bucketList, c._nmethodLast, false /* delete */);
       
  3677 
       
  3678     assert(c._bucketList                         == c._bucketFirst,  "check");
       
  3679     assert(c._bucketList->next()                 == c._bucketMiddle, "check");
       
  3680     assert(c._bucketList->next()->next()         == c._bucketLast,   "check");
       
  3681     assert(c._bucketList->next()->next()->next() == NULL,            "check");
       
  3682 
       
  3683     assert(c._bucketFirst->count()  == 1, "check");
       
  3684     assert(c._bucketMiddle->count() == 1, "check");
       
  3685     assert(c._bucketLast->count()   == 0, "check");
       
  3686   }
       
  3687 
       
  3688   static void testRemoveDependentNmethodConvenienceFirst() {
       
  3689     TestNmethodBucketContext c;
       
  3690 
       
  3691     nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodFirst);
       
  3692 
       
  3693     assert(c._bucketList                         == c._bucketFirst,  "check");
       
  3694     assert(c._bucketList->next()                 == c._bucketMiddle, "check");
       
  3695     assert(c._bucketList->next()->next()         == c._bucketLast,   "check");
       
  3696     assert(c._bucketList->next()->next()->next() == NULL,            "check");
       
  3697 
       
  3698     assert(c._bucketFirst->count()  == 0, "check");
       
  3699     assert(c._bucketMiddle->count() == 1, "check");
       
  3700     assert(c._bucketLast->count()   == 1, "check");
       
  3701   }
       
  3702 
       
  3703   static void testRemoveDependentNmethodConvenienceMiddle() {
       
  3704     TestNmethodBucketContext c;
       
  3705 
       
  3706     nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodMiddle);
       
  3707 
       
  3708     assert(c._bucketList                         == c._bucketFirst,  "check");
       
  3709     assert(c._bucketList->next()                 == c._bucketMiddle, "check");
       
  3710     assert(c._bucketList->next()->next()         == c._bucketLast,   "check");
       
  3711     assert(c._bucketList->next()->next()->next() == NULL,            "check");
       
  3712 
       
  3713     assert(c._bucketFirst->count()  == 1, "check");
       
  3714     assert(c._bucketMiddle->count() == 0, "check");
       
  3715     assert(c._bucketLast->count()   == 1, "check");
       
  3716   }
       
  3717 
       
  3718   static void testRemoveDependentNmethodConvenienceLast() {
       
  3719     TestNmethodBucketContext c;
       
  3720 
       
  3721     nmethodBucket::remove_dependent_nmethod(c._bucketList, c._nmethodLast);
       
  3722 
       
  3723     assert(c._bucketList                         == c._bucketFirst,  "check");
       
  3724     assert(c._bucketList->next()                 == c._bucketMiddle, "check");
       
  3725     assert(c._bucketList->next()->next()         == c._bucketLast,   "check");
       
  3726     assert(c._bucketList->next()->next()->next() == NULL,            "check");
       
  3727 
       
  3728     assert(c._bucketFirst->count()  == 1, "check");
       
  3729     assert(c._bucketMiddle->count() == 1, "check");
       
  3730     assert(c._bucketLast->count()   == 0, "check");
       
  3731   }
       
  3732 
       
  3733   static void testRemoveDependentNmethod() {
       
  3734     testRemoveDependentNmethodFirstDeleteImmediately();
       
  3735     testRemoveDependentNmethodMiddleDeleteImmediately();
       
  3736     testRemoveDependentNmethodLastDeleteImmediately();
       
  3737 
       
  3738     testRemoveDependentNmethodFirstDeleteDeferred();
       
  3739     testRemoveDependentNmethodMiddleDeleteDeferred();
       
  3740     testRemoveDependentNmethodLastDeleteDeferred();
       
  3741 
       
  3742     testRemoveDependentNmethodConvenienceFirst();
       
  3743     testRemoveDependentNmethodConvenienceMiddle();
       
  3744     testRemoveDependentNmethodConvenienceLast();
       
  3745   }
       
  3746 
       
  3747   static void test() {
       
  3748     testRemoveDependentNmethod();
       
  3749   }
       
  3750 };
       
  3751 
       
  3752 void TestNmethodBucket_test() {
       
  3753   TestNmethodBucket::test();
       
  3754 }
       
  3755 
       
  3756 #endif