src/share/vm/oops/instanceKlass.cpp

changeset 6992
2c6ef90f030a
parent 6982
4c1b88a53c74
child 6993
870c03421152
     1.1 --- a/src/share/vm/oops/instanceKlass.cpp	Tue Jul 01 09:03:55 2014 +0200
     1.2 +++ b/src/share/vm/oops/instanceKlass.cpp	Mon Jul 07 10:12:40 2014 +0200
     1.3 @@ -289,6 +289,7 @@
     1.4    set_static_oop_field_count(0);
     1.5    set_nonstatic_field_size(0);
     1.6    set_is_marked_dependent(false);
     1.7 +  set_has_unloaded_dependent(false);
     1.8    set_init_state(InstanceKlass::allocated);
     1.9    set_init_thread(NULL);
    1.10    set_reference_type(rt);
    1.11 @@ -1819,6 +1820,9 @@
    1.12    return id;
    1.13  }
    1.14  
    1.15 +int nmethodBucket::decrement() {
    1.16 +  return Atomic::add(-1, (volatile int *)&_count);
    1.17 +}
    1.18  
    1.19  //
    1.20  // Walk the list of dependent nmethods searching for nmethods which
    1.21 @@ -1833,7 +1837,7 @@
    1.22      nmethod* nm = b->get_nmethod();
    1.23      // since dependencies aren't removed until an nmethod becomes a zombie,
    1.24      // the dependency list may contain nmethods which aren't alive.
    1.25 -    if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) {
    1.26 +    if (b->count() > 0 && nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) {
    1.27        if (TraceDependencies) {
    1.28          ResourceMark rm;
    1.29          tty->print_cr("Marked for deoptimization");
    1.30 @@ -1850,6 +1854,43 @@
    1.31    return found;
    1.32  }
    1.33  
    1.34 +void InstanceKlass::clean_dependent_nmethods() {
    1.35 +  assert_locked_or_safepoint(CodeCache_lock);
    1.36 +
    1.37 +  if (has_unloaded_dependent()) {
    1.38 +    nmethodBucket* b = _dependencies;
    1.39 +    nmethodBucket* last = NULL;
    1.40 +    while (b != NULL) {
    1.41 +      assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
    1.42 +
    1.43 +      nmethodBucket* next = b->next();
    1.44 +
    1.45 +      if (b->count() == 0) {
    1.46 +        if (last == NULL) {
    1.47 +          _dependencies = next;
    1.48 +        } else {
    1.49 +          last->set_next(next);
    1.50 +        }
    1.51 +        delete b;
    1.52 +        // last stays the same.
    1.53 +      } else {
    1.54 +        last = b;
    1.55 +      }
    1.56 +
    1.57 +      b = next;
    1.58 +    }
    1.59 +    set_has_unloaded_dependent(false);
    1.60 +  }
    1.61 +#ifdef ASSERT
    1.62 +  else {
    1.63 +    // Verification
    1.64 +    for (nmethodBucket* b = _dependencies; b != NULL; b = b->next()) {
    1.65 +      assert(b->count() >= 0, err_msg("bucket count: %d", b->count()));
    1.66 +      assert(b->count() != 0, "empty buckets need to be cleaned");
    1.67 +    }
    1.68 +  }
    1.69 +#endif
    1.70 +}
    1.71  
    1.72  //
    1.73  // Add an nmethodBucket to the list of dependencies for this nmethod.
    1.74 @@ -1884,13 +1925,10 @@
    1.75    nmethodBucket* last = NULL;
    1.76    while (b != NULL) {
    1.77      if (nm == b->get_nmethod()) {
    1.78 -      if (b->decrement() == 0) {
    1.79 -        if (last == NULL) {
    1.80 -          _dependencies = b->next();
    1.81 -        } else {
    1.82 -          last->set_next(b->next());
    1.83 -        }
    1.84 -        delete b;
    1.85 +      int val = b->decrement();
    1.86 +      guarantee(val >= 0, err_msg("Underflow: %d", val));
    1.87 +      if (val == 0) {
    1.88 +        set_has_unloaded_dependent(true);
    1.89        }
    1.90        return;
    1.91      }
    1.92 @@ -1929,6 +1967,11 @@
    1.93    nmethodBucket* b = _dependencies;
    1.94    while (b != NULL) {
    1.95      if (nm == b->get_nmethod()) {
    1.96 +#ifdef ASSERT
    1.97 +      int count = b->count();
    1.98 +      assert(count >= 0, "Just check if we ever get here 1");
    1.99 +      assert(count > 0,  "Just check if we ever get here 2");
   1.100 +#endif
   1.101        return true;
   1.102      }
   1.103      b = b->next();
   1.104 @@ -2227,7 +2270,7 @@
   1.105  #endif // INCLUDE_ALL_GCS
   1.106  
   1.107  void InstanceKlass::clean_implementors_list(BoolObjectClosure* is_alive) {
   1.108 -  assert(is_loader_alive(is_alive), "this klass should be live");
   1.109 +  assert(class_loader_data()->is_alive(is_alive), "this klass should be live");
   1.110    if (is_interface()) {
   1.111      if (ClassUnloading) {
   1.112        Klass* impl = implementor();

mercurial