src/hotspot/share/code/compiledMethod.cpp
changeset 54839 e9db10a375d9
parent 54150 5529640c5f67
child 55293 d19dc5b10fbb
child 58678 9cf78a70fa4f
equal deleted inserted replaced
54838:d7819bedfaaf 54839:e9db10a375d9
   466   }
   466   }
   467 
   467 
   468   return ic->set_to_clean();
   468   return ic->set_to_clean();
   469 }
   469 }
   470 
   470 
   471 // static_stub_Relocations may have dangling references to
       
   472 // nmethods so trim them out here.  Otherwise it looks like
       
   473 // compiled code is maintaining a link to dead metadata.
       
   474 void CompiledMethod::clean_ic_stubs() {
       
   475 #ifdef ASSERT
       
   476   address low_boundary = oops_reloc_begin();
       
   477   RelocIterator iter(this, low_boundary);
       
   478   while (iter.next()) {
       
   479     address static_call_addr = NULL;
       
   480     if (iter.type() == relocInfo::opt_virtual_call_type) {
       
   481       CompiledIC* cic = CompiledIC_at(&iter);
       
   482       if (!cic->is_call_to_interpreted()) {
       
   483         static_call_addr = iter.addr();
       
   484       }
       
   485     } else if (iter.type() == relocInfo::static_call_type) {
       
   486       CompiledStaticCall* csc = compiledStaticCall_at(iter.reloc());
       
   487       if (!csc->is_call_to_interpreted()) {
       
   488         static_call_addr = iter.addr();
       
   489       }
       
   490     }
       
   491     if (static_call_addr != NULL) {
       
   492       RelocIterator sciter(this, low_boundary);
       
   493       while (sciter.next()) {
       
   494         if (sciter.type() == relocInfo::static_stub_type &&
       
   495             sciter.static_stub_reloc()->static_call() == static_call_addr) {
       
   496           sciter.static_stub_reloc()->clear_inline_cache();
       
   497         }
       
   498       }
       
   499     }
       
   500   }
       
   501 #endif
       
   502 }
       
   503 
       
   504 // Clean references to unloaded nmethods at addr from this one, which is not unloaded.
   471 // Clean references to unloaded nmethods at addr from this one, which is not unloaded.
   505 template <class CompiledICorStaticCall>
   472 template <class CompiledICorStaticCall>
   506 static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from,
   473 static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from,
   507                                          bool clean_all) {
   474                                          bool clean_all) {
   508   // Ok, to lookup references to zombies here
   475   // Ok, to lookup references to zombies here
   547 
   514 
   548   if (!cleanup_inline_caches_impl(unloading_occurred, false)) {
   515   if (!cleanup_inline_caches_impl(unloading_occurred, false)) {
   549     return false;
   516     return false;
   550   }
   517   }
   551 
   518 
   552   // All static stubs need to be cleaned.
       
   553   clean_ic_stubs();
       
   554 
       
   555 #ifdef ASSERT
   519 #ifdef ASSERT
   556   // Check that the metadata embedded in the nmethod is alive
   520   // Check that the metadata embedded in the nmethod is alive
   557   CheckClass check_class;
   521   CheckClass check_class;
   558   metadata_do(&check_class);
   522   metadata_do(&check_class);
   559 #endif
   523 #endif
   579   ResourceMark rm;
   543   ResourceMark rm;
   580 
   544 
   581   // Find all calls in an nmethod and clear the ones that point to non-entrant,
   545   // Find all calls in an nmethod and clear the ones that point to non-entrant,
   582   // zombie and unloaded nmethods.
   546   // zombie and unloaded nmethods.
   583   RelocIterator iter(this, oops_reloc_begin());
   547   RelocIterator iter(this, oops_reloc_begin());
       
   548   bool is_in_static_stub = false;
   584   while(iter.next()) {
   549   while(iter.next()) {
   585 
   550 
   586     switch (iter.type()) {
   551     switch (iter.type()) {
   587 
   552 
   588     case relocInfo::virtual_call_type:
   553     case relocInfo::virtual_call_type:
   608     case relocInfo::static_call_type:
   573     case relocInfo::static_call_type:
   609       if (!clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, clean_all)) {
   574       if (!clean_if_nmethod_is_unloaded(compiledStaticCall_at(iter.reloc()), this, clean_all)) {
   610         return false;
   575         return false;
   611       }
   576       }
   612       break;
   577       break;
       
   578 
       
   579     case relocInfo::static_stub_type: {
       
   580       is_in_static_stub = true;
       
   581       break;
       
   582     }
       
   583 
       
   584     case relocInfo::metadata_type: {
       
   585       // Only the metadata relocations contained in static/opt virtual call stubs
       
   586       // contains the Method* passed to c2i adapters. It is the only metadata
       
   587       // relocation that needs to be walked, as it is the one metadata relocation
       
   588       // that violates the invariant that all metadata relocations have an oop
       
   589       // in the compiled method (due to deferred resolution and code patching).
       
   590 
       
   591       // This causes dead metadata to remain in compiled methods that are not
       
   592       // unloading. Unless these slippery metadata relocations of the static
       
   593       // stubs are at least cleared, subsequent class redefinition operations
       
   594       // will access potentially free memory, and JavaThread execution
       
   595       // concurrent to class unloading may call c2i adapters with dead methods.
       
   596       if (!is_in_static_stub) {
       
   597         // The first metadata relocation after a static stub relocation is the
       
   598         // metadata relocation of the static stub used to pass the Method* to
       
   599         // c2i adapters.
       
   600         continue;
       
   601       }
       
   602       is_in_static_stub = false;
       
   603       metadata_Relocation* r = iter.metadata_reloc();
       
   604       Metadata* md = r->metadata_value();
       
   605       if (md != NULL && md->is_method()) {
       
   606         Method* method = static_cast<Method*>(md);
       
   607         if (!method->method_holder()->is_loader_alive()) {
       
   608           Atomic::store((Method*)NULL, r->metadata_addr());
       
   609 
       
   610           if (!r->metadata_is_immediate()) {
       
   611             r->fix_metadata_relocation();
       
   612           }
       
   613         }
       
   614       }
       
   615       break;
       
   616     }
   613 
   617 
   614     default:
   618     default:
   615       break;
   619       break;
   616     }
   620     }
   617   }
   621   }