src/share/vm/code/nmethod.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/code

src/share/vm/code/nmethod.cpp

Print this page
rev 5099 : 8016277: Crash in nmethod::is_compiled_by_c1() on x86
Summary: Method pointer for zombie methods may be invalid
Reviewed-by:


  76     Method* m = (method);                                                 \
  77     if (m != NULL) {                                                      \
  78       Symbol* klass_name = m->klass_name();                               \
  79       Symbol* name = m->name();                                           \
  80       Symbol* signature = m->signature();                                 \
  81       HOTSPOT_COMPILED_METHOD_UNLOAD(                                     \
  82         (char *) klass_name->bytes(), klass_name->utf8_length(),                   \
  83         (char *) name->bytes(), name->utf8_length(),                               \
  84         (char *) signature->bytes(), signature->utf8_length());                    \
  85     }                                                                     \
  86   }
  87 #endif /* USDT2 */
  88 
  89 #else //  ndef DTRACE_ENABLED
  90 
  91 #define DTRACE_METHOD_UNLOAD_PROBE(method)
  92 
  93 #endif
  94 
  95 bool nmethod::is_compiled_by_c1() const {
  96   if (compiler() == NULL || method() == NULL)  return false;  // can happen during debug printing
  97   if (is_native_method()) return false;

  98   return compiler()->is_c1();
  99 }
 100 bool nmethod::is_compiled_by_c2() const {
 101   if (compiler() == NULL || method() == NULL)  return false;  // can happen during debug printing
 102   if (is_native_method()) return false;

 103   return compiler()->is_c2();
 104 }
 105 bool nmethod::is_compiled_by_shark() const {
 106   if (is_native_method()) return false;
 107   assert(compiler() != NULL, "must be");

 108   return compiler()->is_shark();
 109 }
 110 
 111 
 112 
 113 //---------------------------------------------------------------------------------
 114 // NMethod statistics
 115 // They are printed under various flags, including:
 116 //   PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation.
 117 // (In the latter two cases, they like other stats are printed to the log only.)
 118 
 119 #ifndef PRODUCT
 120 // These variables are put into one block to reduce relocations
 121 // and make it simpler to print from the debugger.
 122 static
 123 struct nmethod_stats_struct {
 124   int nmethod_count;
 125   int total_size;
 126   int relocation_size;
 127   int consts_size;


1365     {
1366       // Flushing dependecies must be done before any possible
1367       // safepoint can sneak in, otherwise the oops used by the
1368       // dependency logic could have become stale.
1369       MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1370       flush_dependencies(NULL);
1371     }
1372 
1373     // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload
1374     // event and it hasn't already been reported for this nmethod then
1375     // report it now. The event may have been reported earilier if the GC
1376     // marked it for unloading). JvmtiDeferredEventQueue support means
1377     // we no longer go to a safepoint here.
1378     post_compiled_method_unload();
1379 
1380 #ifdef ASSERT
1381     // It's no longer safe to access the oops section since zombie
1382     // nmethods aren't scanned for GC.
1383     _oops_are_stale = true;
1384 #endif


1385   } else {
1386     assert(state == not_entrant, "other cases may need to be handled differently");
1387   }
1388 
1389   if (TraceCreateZombies) {
1390     tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie");
1391   }
1392 
1393   // Make sweeper aware that there is a zombie method that needs to be removed
1394   NMethodSweeper::notify(this);
1395 
1396   return true;
1397 }
1398 
1399 void nmethod::flush() {
1400   // Note that there are no valid oops in the nmethod anymore.
1401   assert(is_zombie() || (is_osr_method() && is_unloaded()), "must be a zombie method");
1402   assert(is_marked_for_reclamation() || (is_osr_method() && is_unloaded()), "must be marked for reclamation");
1403 
1404   assert (!is_locked_by_vm(), "locked methods shouldn't be flushed");




  76     Method* m = (method);                                                 \
  77     if (m != NULL) {                                                      \
  78       Symbol* klass_name = m->klass_name();                               \
  79       Symbol* name = m->name();                                           \
  80       Symbol* signature = m->signature();                                 \
  81       HOTSPOT_COMPILED_METHOD_UNLOAD(                                     \
  82         (char *) klass_name->bytes(), klass_name->utf8_length(),                   \
  83         (char *) name->bytes(), name->utf8_length(),                               \
  84         (char *) signature->bytes(), signature->utf8_length());                    \
  85     }                                                                     \
  86   }
  87 #endif /* USDT2 */
  88 
  89 #else //  ndef DTRACE_ENABLED
  90 
  91 #define DTRACE_METHOD_UNLOAD_PROBE(method)
  92 
  93 #endif
  94 
  95 bool nmethod::is_compiled_by_c1() const {
  96   if (compiler() == NULL)  return false;
  97   // method() == NULL can happen during debug printing or if the nmethod is zombie
  98   assert(method() == NULL || !is_native_method(), "native methods have no compiler");
  99   return compiler()->is_c1();
 100 }
 101 bool nmethod::is_compiled_by_c2() const {
 102   if (compiler() == NULL)  return false;
 103   // method() == NULL can happen during debug printing or if the nmethod is zombie
 104   assert(method() == NULL || !is_native_method(), "native methods have no compiler");
 105   return compiler()->is_c2();
 106 }
 107 bool nmethod::is_compiled_by_shark() const {
 108   if (compiler() == NULL)  return false;
 109   // method() == NULL can happen during debug printing or if the nmethod is zombie
 110   assert(method() == NULL || !is_native_method(), "native methods have no compiler");
 111   return compiler()->is_shark();
 112 }
 113 
 114 
 115 
 116 //---------------------------------------------------------------------------------
 117 // NMethod statistics
 118 // They are printed under various flags, including:
 119 //   PrintC1Statistics, PrintOptoStatistics, LogVMOutput, and LogCompilation.
 120 // (In the latter two cases, they like other stats are printed to the log only.)
 121 
 122 #ifndef PRODUCT
 123 // These variables are put into one block to reduce relocations
 124 // and make it simpler to print from the debugger.
 125 static
 126 struct nmethod_stats_struct {
 127   int nmethod_count;
 128   int total_size;
 129   int relocation_size;
 130   int consts_size;


1368     {
1369       // Flushing dependecies must be done before any possible
1370       // safepoint can sneak in, otherwise the oops used by the
1371       // dependency logic could have become stale.
1372       MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1373       flush_dependencies(NULL);
1374     }
1375 
1376     // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload
1377     // event and it hasn't already been reported for this nmethod then
1378     // report it now. The event may have been reported earilier if the GC
1379     // marked it for unloading). JvmtiDeferredEventQueue support means
1380     // we no longer go to a safepoint here.
1381     post_compiled_method_unload();
1382 
1383 #ifdef ASSERT
1384     // It's no longer safe to access the oops section since zombie
1385     // nmethods aren't scanned for GC.
1386     _oops_are_stale = true;
1387 #endif
1388     _method = NULL; // the Method may be reclaimed by class unloading
1389                     // now that the nmethod is in zombie state
1390   } else {
1391     assert(state == not_entrant, "other cases may need to be handled differently");
1392   }
1393 
1394   if (TraceCreateZombies) {
1395     tty->print_cr("nmethod <" INTPTR_FORMAT "> code made %s", this, (state == not_entrant) ? "not entrant" : "zombie");
1396   }
1397 
1398   // Make sweeper aware that there is a zombie method that needs to be removed
1399   NMethodSweeper::notify(this);
1400 
1401   return true;
1402 }
1403 
1404 void nmethod::flush() {
1405   // Note that there are no valid oops in the nmethod anymore.
1406   assert(is_zombie() || (is_osr_method() && is_unloaded()), "must be a zombie method");
1407   assert(is_marked_for_reclamation() || (is_osr_method() && is_unloaded()), "must be marked for reclamation");
1408 
1409   assert (!is_locked_by_vm(), "locked methods shouldn't be flushed");


src/share/vm/code/nmethod.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File