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