hotspot/src/share/vm/code/codeCache.cpp
changeset 3908 24b55ad4c228
parent 1 489c9b5090e2
child 4750 71fd601907dc
equal deleted inserted replaced
3906:6767b0c66883 3908:24b55ad4c228
    93 
    93 
    94 CodeHeap * CodeCache::_heap = new CodeHeap();
    94 CodeHeap * CodeCache::_heap = new CodeHeap();
    95 int CodeCache::_number_of_blobs = 0;
    95 int CodeCache::_number_of_blobs = 0;
    96 int CodeCache::_number_of_nmethods_with_dependencies = 0;
    96 int CodeCache::_number_of_nmethods_with_dependencies = 0;
    97 bool CodeCache::_needs_cache_clean = false;
    97 bool CodeCache::_needs_cache_clean = false;
       
    98 nmethod* CodeCache::_scavenge_root_nmethods = NULL;
    98 
    99 
    99 
   100 
   100 CodeBlob* CodeCache::first() {
   101 CodeBlob* CodeCache::first() {
   101   assert_locked_or_safepoint(CodeCache_lock);
   102   assert_locked_or_safepoint(CodeCache_lock);
   102   return (CodeBlob*)_heap->first();
   103   return (CodeBlob*)_heap->first();
   146                     (intptr_t)_heap->begin(), (intptr_t)_heap->end(),
   147                     (intptr_t)_heap->begin(), (intptr_t)_heap->end(),
   147                     (address)_heap->end() - (address)_heap->begin());
   148                     (address)_heap->end() - (address)_heap->begin());
   148     }
   149     }
   149   }
   150   }
   150   verify_if_often();
   151   verify_if_often();
   151   if (PrintCodeCache2) {        // Need to add a new flag
   152   print_trace("allocation", cb, size);
   152       ResourceMark rm;
       
   153       tty->print_cr("CodeCache allocation:  addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, size);
       
   154   }
       
   155   return cb;
   153   return cb;
   156 }
   154 }
   157 
   155 
   158 void CodeCache::free(CodeBlob* cb) {
   156 void CodeCache::free(CodeBlob* cb) {
   159   assert_locked_or_safepoint(CodeCache_lock);
   157   assert_locked_or_safepoint(CodeCache_lock);
   160   verify_if_often();
   158   verify_if_often();
   161 
   159 
   162   if (PrintCodeCache2) {        // Need to add a new flag
   160   print_trace("free", cb);
   163       ResourceMark rm;
       
   164       tty->print_cr("CodeCache free:  addr: " INTPTR_FORMAT ", size: 0x%x\n", cb, cb->size());
       
   165   }
       
   166   if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) {
   161   if (cb->is_nmethod() && ((nmethod *)cb)->has_dependencies()) {
   167     _number_of_nmethods_with_dependencies--;
   162     _number_of_nmethods_with_dependencies--;
   168   }
   163   }
   169   _number_of_blobs--;
   164   _number_of_blobs--;
   170 
   165 
   258   FOR_ALL_ALIVE_BLOBS(cb) {
   253   FOR_ALL_ALIVE_BLOBS(cb) {
   259     cb->do_unloading(is_alive, keep_alive, unloading_occurred);
   254     cb->do_unloading(is_alive, keep_alive, unloading_occurred);
   260   }
   255   }
   261 }
   256 }
   262 
   257 
   263 void CodeCache::oops_do(OopClosure* f) {
   258 void CodeCache::blobs_do(CodeBlobClosure* f) {
   264   assert_locked_or_safepoint(CodeCache_lock);
   259   assert_locked_or_safepoint(CodeCache_lock);
   265   FOR_ALL_ALIVE_BLOBS(cb) {
   260   FOR_ALL_ALIVE_BLOBS(cb) {
   266     cb->oops_do(f);
   261     f->do_code_blob(cb);
   267   }
   262 
   268 }
   263 #ifdef ASSERT
       
   264     if (cb->is_nmethod())
       
   265       ((nmethod*)cb)->verify_scavenge_root_oops();
       
   266 #endif //ASSERT
       
   267   }
       
   268 }
       
   269 
       
   270 // Walk the list of methods which might contain non-perm oops.
       
   271 void CodeCache::scavenge_root_nmethods_do(CodeBlobClosure* f) {
       
   272   assert_locked_or_safepoint(CodeCache_lock);
       
   273   debug_only(mark_scavenge_root_nmethods());
       
   274 
       
   275   for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
       
   276     debug_only(cur->clear_scavenge_root_marked());
       
   277     assert(cur->scavenge_root_not_marked(), "");
       
   278     assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
       
   279 
       
   280     bool is_live = (!cur->is_zombie() && !cur->is_unloaded());
       
   281 #ifndef PRODUCT
       
   282     if (TraceScavenge) {
       
   283       cur->print_on(tty, is_live ? "scavenge root" : "dead scavenge root"); tty->cr();
       
   284     }
       
   285 #endif //PRODUCT
       
   286     if (is_live)
       
   287       // Perform cur->oops_do(f), maybe just once per nmethod.
       
   288       f->do_code_blob(cur);
       
   289   }
       
   290 
       
   291   // Check for stray marks.
       
   292   debug_only(verify_perm_nmethods(NULL));
       
   293 }
       
   294 
       
   295 void CodeCache::add_scavenge_root_nmethod(nmethod* nm) {
       
   296   assert_locked_or_safepoint(CodeCache_lock);
       
   297   nm->set_on_scavenge_root_list();
       
   298   nm->set_scavenge_root_link(_scavenge_root_nmethods);
       
   299   set_scavenge_root_nmethods(nm);
       
   300   print_trace("add_scavenge_root", nm);
       
   301 }
       
   302 
       
   303 void CodeCache::drop_scavenge_root_nmethod(nmethod* nm) {
       
   304   assert_locked_or_safepoint(CodeCache_lock);
       
   305   print_trace("drop_scavenge_root", nm);
       
   306   nmethod* last = NULL;
       
   307   nmethod* cur = scavenge_root_nmethods();
       
   308   while (cur != NULL) {
       
   309     nmethod* next = cur->scavenge_root_link();
       
   310     if (cur == nm) {
       
   311       if (last != NULL)
       
   312             last->set_scavenge_root_link(next);
       
   313       else  set_scavenge_root_nmethods(next);
       
   314       nm->set_scavenge_root_link(NULL);
       
   315       nm->clear_on_scavenge_root_list();
       
   316       return;
       
   317     }
       
   318     last = cur;
       
   319     cur = next;
       
   320   }
       
   321   assert(false, "should have been on list");
       
   322 }
       
   323 
       
   324 void CodeCache::prune_scavenge_root_nmethods() {
       
   325   assert_locked_or_safepoint(CodeCache_lock);
       
   326   debug_only(mark_scavenge_root_nmethods());
       
   327 
       
   328   nmethod* last = NULL;
       
   329   nmethod* cur = scavenge_root_nmethods();
       
   330   while (cur != NULL) {
       
   331     nmethod* next = cur->scavenge_root_link();
       
   332     debug_only(cur->clear_scavenge_root_marked());
       
   333     assert(cur->scavenge_root_not_marked(), "");
       
   334     assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
       
   335 
       
   336     if (!cur->is_zombie() && !cur->is_unloaded()
       
   337         && cur->detect_scavenge_root_oops()) {
       
   338       // Keep it.  Advance 'last' to prevent deletion.
       
   339       last = cur;
       
   340     } else {
       
   341       // Prune it from the list, so we don't have to look at it any more.
       
   342       print_trace("prune_scavenge_root", cur);
       
   343       cur->set_scavenge_root_link(NULL);
       
   344       cur->clear_on_scavenge_root_list();
       
   345       if (last != NULL)
       
   346             last->set_scavenge_root_link(next);
       
   347       else  set_scavenge_root_nmethods(next);
       
   348     }
       
   349     cur = next;
       
   350   }
       
   351 
       
   352   // Check for stray marks.
       
   353   debug_only(verify_perm_nmethods(NULL));
       
   354 }
       
   355 
       
   356 #ifndef PRODUCT
       
   357 void CodeCache::asserted_non_scavengable_nmethods_do(CodeBlobClosure* f) {
       
   358   // While we are here, verify the integrity of the list.
       
   359   mark_scavenge_root_nmethods();
       
   360   for (nmethod* cur = scavenge_root_nmethods(); cur != NULL; cur = cur->scavenge_root_link()) {
       
   361     assert(cur->on_scavenge_root_list(), "else shouldn't be on this list");
       
   362     cur->clear_scavenge_root_marked();
       
   363   }
       
   364   verify_perm_nmethods(f);
       
   365 }
       
   366 
       
   367 // Temporarily mark nmethods that are claimed to be on the non-perm list.
       
   368 void CodeCache::mark_scavenge_root_nmethods() {
       
   369   FOR_ALL_ALIVE_BLOBS(cb) {
       
   370     if (cb->is_nmethod()) {
       
   371       nmethod *nm = (nmethod*)cb;
       
   372       assert(nm->scavenge_root_not_marked(), "clean state");
       
   373       if (nm->on_scavenge_root_list())
       
   374         nm->set_scavenge_root_marked();
       
   375     }
       
   376   }
       
   377 }
       
   378 
       
   379 // If the closure is given, run it on the unlisted nmethods.
       
   380 // Also make sure that the effects of mark_scavenge_root_nmethods is gone.
       
   381 void CodeCache::verify_perm_nmethods(CodeBlobClosure* f_or_null) {
       
   382   FOR_ALL_ALIVE_BLOBS(cb) {
       
   383     bool call_f = (f_or_null != NULL);
       
   384     if (cb->is_nmethod()) {
       
   385       nmethod *nm = (nmethod*)cb;
       
   386       assert(nm->scavenge_root_not_marked(), "must be already processed");
       
   387       if (nm->on_scavenge_root_list())
       
   388         call_f = false;  // don't show this one to the client
       
   389       nm->verify_scavenge_root_oops();
       
   390     } else {
       
   391       call_f = false;   // not an nmethod
       
   392     }
       
   393     if (call_f)  f_or_null->do_code_blob(cb);
       
   394   }
       
   395 }
       
   396 #endif //PRODUCT
   269 
   397 
   270 void CodeCache::gc_prologue() {
   398 void CodeCache::gc_prologue() {
       
   399   assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_epilogue must be called");
   271 }
   400 }
   272 
   401 
   273 
   402 
   274 void CodeCache::gc_epilogue() {
   403 void CodeCache::gc_epilogue() {
   275   assert_locked_or_safepoint(CodeCache_lock);
   404   assert_locked_or_safepoint(CodeCache_lock);
   283       debug_only(nm->verify();)
   412       debug_only(nm->verify();)
   284     }
   413     }
   285     cb->fix_oop_relocations();
   414     cb->fix_oop_relocations();
   286   }
   415   }
   287   set_needs_cache_clean(false);
   416   set_needs_cache_clean(false);
       
   417   prune_scavenge_root_nmethods();
       
   418   assert(!nmethod::oops_do_marking_is_active(), "oops_do_marking_prologue must be called");
   288 }
   419 }
   289 
   420 
   290 
   421 
   291 address CodeCache::first_address() {
   422 address CodeCache::first_address() {
   292   assert_locked_or_safepoint(CodeCache_lock);
   423   assert_locked_or_safepoint(CodeCache_lock);
   503 #ifndef PRODUCT
   634 #ifndef PRODUCT
   504 
   635 
   505 void CodeCache::verify_if_often() {
   636 void CodeCache::verify_if_often() {
   506   if (VerifyCodeCacheOften) {
   637   if (VerifyCodeCacheOften) {
   507     _heap->verify();
   638     _heap->verify();
       
   639   }
       
   640 }
       
   641 
       
   642 void CodeCache::print_trace(const char* event, CodeBlob* cb, int size) {
       
   643   if (PrintCodeCache2) {  // Need to add a new flag
       
   644     ResourceMark rm;
       
   645     if (size == 0)  size = cb->size();
       
   646     tty->print_cr("CodeCache %s:  addr: " INTPTR_FORMAT ", size: 0x%x", event, cb, size);
   508   }
   647   }
   509 }
   648 }
   510 
   649 
   511 void CodeCache::print_internals() {
   650 void CodeCache::print_internals() {
   512   int nmethodCount = 0;
   651   int nmethodCount = 0;