src/share/vm/code/codeCache.cpp

changeset 1424
148e5441d916
parent 435
a61af66fc99e
child 1637
5f24d0319e54
     1.1 --- a/src/share/vm/code/codeCache.cpp	Tue Sep 15 11:09:34 2009 -0700
     1.2 +++ b/src/share/vm/code/codeCache.cpp	Tue Sep 15 21:53:47 2009 -0700
     1.3 @@ -95,6 +95,7 @@
     1.4  int CodeCache::_number_of_blobs = 0;
     1.5  int CodeCache::_number_of_nmethods_with_dependencies = 0;
     1.6  bool CodeCache::_needs_cache_clean = false;
     1.7 +nmethod* CodeCache::_scavenge_root_nmethods = NULL;
     1.8  
     1.9  
    1.10  CodeBlob* CodeCache::first() {
    1.11 @@ -148,10 +149,7 @@
    1.12      }
    1.13    }
    1.14    verify_if_often();
    1.15 -  if (PrintCodeCache2) {        // Need to add a new flag
    1.16 -      ResourceMark rm;
    1.17 -      tty->print_cr("CodeCache allocation:  addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, size);
    1.18 -  }
    1.19 +  print_trace("allocation", cb, size);
    1.20    return cb;
    1.21  }
    1.22  
    1.23 @@ -159,10 +157,7 @@
    1.24    assert_locked_or_safepoint(CodeCache_lock);
    1.25    verify_if_often();
    1.26  
    1.27 -  if (PrintCodeCache2) {        // Need to add a new flag
    1.28 -      ResourceMark rm;
    1.29 -      tty->print_cr("CodeCache free:  addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, cb->size());
    1.30 -  }
    1.31 +  print_trace("free", cb);
    1.32    if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) {
    1.33      _number_of_nmethods_with_dependencies--;
    1.34    }
    1.35 @@ -260,14 +255,148 @@
    1.36    }
    1.37  }
    1.38  
    1.39 -void CodeCache::oops_do(OopClosure* f) {
    1.40 +void CodeCache::blobs_do(CodeBlobClosure* f) {
    1.41    assert_locked_or_safepoint(CodeCache_lock);
    1.42    FOR_ALL_ALIVE_BLOBS(cb) {
    1.43 -    cb->oops_do(f);
    1.44 +    f->do_code_blob(cb);
    1.45 +
    1.46 +#ifdef ASSERT
    1.47 +    if (cb->is_nmethod())
    1.48 +      ((nmethod*)cb)->verify_scavenge_root_oops();
    1.49 +#endif //ASSERT
    1.50    }
    1.51  }
    1.52  
    1.53 +// Walk the list of methods which might contain non-perm oops.
    1.54 +void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
    1.55 +  assert_locked_or_safepoint(CodeCache_lock);
    1.56 +  debug_only(mark_scavenge_root_nmethods());
    1.57 +
    1.58 +  for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
    1.59 +    debug_only(cur->clear_scavenge_root_marked());
    1.60 +    assert(cur->scavenge_root_not_marked(), "");
    1.61 +    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
    1.62 +
    1.63 +    bool is_live = (!cur->is_zombie() && !cur->is_unloaded());
    1.64 +#ifndef PRODUCT
    1.65 +    if (TraceScavenge) {
    1.66 +      cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr();
    1.67 +    }
    1.68 +#endif //PRODUCT
    1.69 +    if (is_live)
    1.70 +      // Perform cur->oops_do(f), maybe just once per nmethod.
    1.71 +      f->do_code_blob(cur);
    1.72 +  }
    1.73 +
    1.74 +  // Check for stray marks.
    1.75 +  debug_only(verify_perm_nmethods(NULL));
    1.76 +}
    1.77 +
    1.78 +void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
    1.79 +  assert_locked_or_safepoint(CodeCache_lock);
    1.80 +  nm->set_on_scavenge_root_list();
    1.81 +  nm->set_scavenge_root_link(_scavenge_root_nmethods);
    1.82 +  set_scavenge_root_nmethods(nm);
    1.83 +  print_trace("add_scavenge_root", nm);
    1.84 +}
    1.85 +
    1.86 +void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
    1.87 +  assert_locked_or_safepoint(CodeCache_lock);
    1.88 +  print_trace("drop_scavenge_root", nm);
    1.89 +  nmethod* last = NULL;
    1.90 +  nmethod* cur = scavenge_root_nmethods();
    1.91 +  while (cur != NULL) {
    1.92 +    nmethod* next = cur->scavenge_root_link();
    1.93 +    if (cur == nm) {
    1.94 +      if (last != NULL)
    1.95 +            last->set_scavenge_root_link(next);
    1.96 +      else  set_scavenge_root_nmethods(next);
    1.97 +      nm->set_scavenge_root_link(NULL);
    1.98 +      nm->clear_on_scavenge_root_list();
    1.99 +      return;
   1.100 +    }
   1.101 +    last = cur;
   1.102 +    cur = next;
   1.103 +  }
   1.104 +  assert(false, "should have been on list");
   1.105 +}
   1.106 +
   1.107 +void CodeCache::prune_scavenge_root_nmethods() {
   1.108 +  assert_locked_or_safepoint(CodeCache_lock);
   1.109 +  debug_only(mark_scavenge_root_nmethods());
   1.110 +
   1.111 +  nmethod* last = NULL;
   1.112 +  nmethod* cur = scavenge_root_nmethods();
   1.113 +  while (cur != NULL) {
   1.114 +    nmethod* next = cur->scavenge_root_link();
   1.115 +    debug_only(cur->clear_scavenge_root_marked());
   1.116 +    assert(cur->scavenge_root_not_marked(), "");
   1.117 +    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
   1.118 +
   1.119 +    if (!cur->is_zombie() && !cur->is_unloaded()
   1.120 +        && cur->detect_scavenge_root_oops()) {
   1.121 +      // Keep it.  Advance 'last' to prevent deletion.
   1.122 +      last = cur;
   1.123 +    } else {
   1.124 +      // Prune it from the list, so we don't have to look at it any more.
   1.125 +      print_trace("prune_scavenge_root", cur);
   1.126 +      cur->set_scavenge_root_link(NULL);
   1.127 +      cur->clear_on_scavenge_root_list();
   1.128 +      if (last != NULL)
   1.129 +            last->set_scavenge_root_link(next);
   1.130 +      else  set_scavenge_root_nmethods(next);
   1.131 +    }
   1.132 +    cur = next;
   1.133 +  }
   1.134 +
   1.135 +  // Check for stray marks.
   1.136 +  debug_only(verify_perm_nmethods(NULL));
   1.137 +}
   1.138 +
   1.139 +#ifndef PRODUCT
   1.140 +void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) {
   1.141 +  // While we are here, verify the integrity of the list.
   1.142 +  mark_scavenge_root_nmethods();
   1.143 +  for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
   1.144 +    assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
   1.145 +    cur->clear_scavenge_root_marked();
   1.146 +  }
   1.147 +  verify_perm_nmethods(f);
   1.148 +}
   1.149 +
   1.150 +// Temporarily mark nmethods that are claimed to be on the non-perm list.
   1.151 +void CodeCache::mark_scavenge_root_nmethods() {
   1.152 +  FOR_ALL_ALIVE_BLOBS(cb) {
   1.153 +    if (cb->is_nmethod()) {
   1.154 +      nmethod *nm = (nmethod*)cb;
   1.155 +      assert(nm->scavenge_root_not_marked(), "clean state");
   1.156 +      if (nm->on_scavenge_root_list())
   1.157 +        nm->set_scavenge_root_marked();
   1.158 +    }
   1.159 +  }
   1.160 +}
   1.161 +
   1.162 +// If the closure is given, run it on the unlisted nmethods.
   1.163 +// Also make sure that the effects of mark_scavenge_root_nmethods is gone.
   1.164 +void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) {
   1.165 +  FOR_ALL_ALIVE_BLOBS(cb) {
   1.166 +    bool call_f = (f_or_null != NULL);
   1.167 +    if (cb->is_nmethod()) {
   1.168 +      nmethod *nm = (nmethod*)cb;
   1.169 +      assert(nm->scavenge_root_not_marked(), "must be already processed");
   1.170 +      if (nm->on_scavenge_root_list())
   1.171 +        call_f = false;  // don't show this one to the client
   1.172 +      nm->verify_scavenge_root_oops();
   1.173 +    } else {
   1.174 +      call_f = false;   // not an nmethod
   1.175 +    }
   1.176 +    if (call_f)  f_or_null->do_code_blob(cb);
   1.177 +  }
   1.178 +}
   1.179 +#endif //PRODUCT
   1.180 +
   1.181  void CodeCache::gc_prologue() {
   1.182 +  assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
   1.183  }
   1.184  
   1.185  
   1.186 @@ -285,6 +414,8 @@
   1.187      cb->fix_oop_relocations();
   1.188    }
   1.189    set_needs_cache_clean(false);
   1.190 +  prune_scavenge_root_nmethods();
   1.191 +  assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
   1.192  }
   1.193  
   1.194  
   1.195 @@ -508,6 +639,14 @@
   1.196    }
   1.197  }
   1.198  
   1.199 +void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) {
   1.200 +  if (PrintCodeCache2) {  // Need to add a new flag
   1.201 +    ResourceMark rm;
   1.202 +    if (size == 0)  size = cb->size();
   1.203 +    tty->print_cr("CodeCache %s:  addr: " INTPTR_FORMAT ", size: 0x%x", event, cb, size);
   1.204 +  }
   1.205 +}
   1.206 +
   1.207  void CodeCache::print_internals() {
   1.208    int nmethodCount = 0;
   1.209    int runtimeStubCount = 0;

mercurial