hotspot/src/share/vm/code/nmethod.cpp
changeset 4479 5686407cde7a
parent 3913 e049e6b81e11
child 4564 55dfb20908d0
equal deleted inserted replaced
4478:c3a8af0fc6b0 4479:5686407cde7a
   412     handler_table_size() +
   412     handler_table_size() +
   413     nul_chk_table_size();
   413     nul_chk_table_size();
   414 }
   414 }
   415 
   415 
   416 const char* nmethod::compile_kind() const {
   416 const char* nmethod::compile_kind() const {
   417   if (method() == NULL)    return "unloaded";
       
   418   if (is_native_method())  return "c2n";
       
   419   if (is_osr_method())     return "osr";
   417   if (is_osr_method())     return "osr";
       
   418   if (method() != NULL && is_native_method())  return "c2n";
   420   return NULL;
   419   return NULL;
   421 }
   420 }
   422 
   421 
   423 // %%% This variable is no longer used?
   422 // %%% This variable is no longer used?
   424 int nmethod::_zombie_instruction_size = NativeJump::instruction_size;
   423 int nmethod::_zombie_instruction_size = NativeJump::instruction_size;
  1125     // for later on.
  1124     // for later on.
  1126     CodeCache::set_needs_cache_clean(true);
  1125     CodeCache::set_needs_cache_clean(true);
  1127   }
  1126   }
  1128   flags.state = unloaded;
  1127   flags.state = unloaded;
  1129 
  1128 
       
  1129   // Log the unloading.
       
  1130   log_state_change();
       
  1131 
  1130   // The methodOop is gone at this point
  1132   // The methodOop is gone at this point
  1131   assert(_method == NULL, "Tautology");
  1133   assert(_method == NULL, "Tautology");
  1132 
  1134 
  1133   set_osr_link(NULL);
  1135   set_osr_link(NULL);
  1134   //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
  1136   //set_scavenge_root_link(NULL); // done by prune_scavenge_root_nmethods
  1135   NMethodSweeper::notify(this);
  1137   NMethodSweeper::notify(this);
  1136 }
  1138 }
  1137 
  1139 
  1138 void nmethod::invalidate_osr_method() {
  1140 void nmethod::invalidate_osr_method() {
  1139   assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
  1141   assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod");
  1140   if (_entry_bci != InvalidOSREntryBci)
       
  1141     inc_decompile_count();
       
  1142   // Remove from list of active nmethods
  1142   // Remove from list of active nmethods
  1143   if (method() != NULL)
  1143   if (method() != NULL)
  1144     instanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this);
  1144     instanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this);
  1145   // Set entry as invalid
  1145   // Set entry as invalid
  1146   _entry_bci = InvalidOSREntryBci;
  1146   _entry_bci = InvalidOSREntryBci;
  1147 }
  1147 }
  1148 
  1148 
  1149 void nmethod::log_state_change(int state) const {
  1149 void nmethod::log_state_change() const {
  1150   if (LogCompilation) {
  1150   if (LogCompilation) {
  1151     if (xtty != NULL) {
  1151     if (xtty != NULL) {
  1152       ttyLocker ttyl;  // keep the following output all in one block
  1152       ttyLocker ttyl;  // keep the following output all in one block
  1153       xtty->begin_elem("make_not_entrant %sthread='" UINTX_FORMAT "'",
  1153       if (flags.state == unloaded) {
  1154                        (state == zombie ? "zombie='1' " : ""),
  1154         xtty->begin_elem("make_unloaded thread='" UINTX_FORMAT "'",
  1155                        os::current_thread_id());
  1155                          os::current_thread_id());
       
  1156       } else {
       
  1157         xtty->begin_elem("make_not_entrant thread='" UINTX_FORMAT "'%s",
       
  1158                          os::current_thread_id(),
       
  1159                          (flags.state == zombie ? " zombie='1'" : ""));
       
  1160       }
  1156       log_identity(xtty);
  1161       log_identity(xtty);
  1157       xtty->stamp();
  1162       xtty->stamp();
  1158       xtty->end_elem();
  1163       xtty->end_elem();
  1159     }
  1164     }
  1160   }
  1165   }
  1161   if (PrintCompilation) {
  1166   if (PrintCompilation && flags.state != unloaded) {
  1162     print_on(tty, state == zombie ? "made zombie " : "made not entrant ");
  1167     print_on(tty, flags.state == zombie ? "made zombie " : "made not entrant ");
  1163     tty->cr();
  1168     tty->cr();
  1164   }
  1169   }
  1165 }
  1170 }
  1166 
  1171 
  1167 // Common functionality for both make_not_entrant and make_zombie
  1172 // Common functionality for both make_not_entrant and make_zombie
  1168 void nmethod::make_not_entrant_or_zombie(int state) {
  1173 bool nmethod::make_not_entrant_or_zombie(int state) {
  1169   assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
  1174   assert(state == zombie || state == not_entrant, "must be zombie or not_entrant");
  1170 
  1175 
  1171   // Code for an on-stack-replacement nmethod is removed when a class gets unloaded.
  1176   // If the method is already zombie there is nothing to do
  1172   // They never become zombie/non-entrant, so the nmethod sweeper will never remove
  1177   if (is_zombie()) {
  1173   // them. Instead the entry_bci is set to InvalidOSREntryBci, so the osr nmethod
  1178     return false;
  1174   // will never be used anymore. That the nmethods only gets removed when class unloading
  1179   }
  1175   // happens, make life much simpler, since the nmethods are not just going to disappear
       
  1176   // out of the blue.
       
  1177   if (is_osr_method()) {
       
  1178     if (osr_entry_bci() != InvalidOSREntryBci) {
       
  1179       // only log this once
       
  1180       log_state_change(state);
       
  1181     }
       
  1182     invalidate_osr_method();
       
  1183     return;
       
  1184   }
       
  1185 
       
  1186   // If the method is already zombie or set to the state we want, nothing to do
       
  1187   if (is_zombie() || (state == not_entrant && is_not_entrant())) {
       
  1188     return;
       
  1189   }
       
  1190 
       
  1191   log_state_change(state);
       
  1192 
  1180 
  1193   // Make sure the nmethod is not flushed in case of a safepoint in code below.
  1181   // Make sure the nmethod is not flushed in case of a safepoint in code below.
  1194   nmethodLocker nml(this);
  1182   nmethodLocker nml(this);
  1195 
  1183 
  1196   {
  1184   {
       
  1185     // invalidate osr nmethod before acquiring the patching lock since
       
  1186     // they both acquire leaf locks and we don't want a deadlock.
       
  1187     // This logic is equivalent to the logic below for patching the
       
  1188     // verified entry point of regular methods.
       
  1189     if (is_osr_method()) {
       
  1190       // this effectively makes the osr nmethod not entrant
       
  1191       invalidate_osr_method();
       
  1192     }
       
  1193 
  1197     // Enter critical section.  Does not block for safepoint.
  1194     // Enter critical section.  Does not block for safepoint.
  1198     MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
  1195     MutexLockerEx pl(Patching_lock, Mutex::_no_safepoint_check_flag);
       
  1196 
       
  1197     if (flags.state == state) {
       
  1198       // another thread already performed this transition so nothing
       
  1199       // to do, but return false to indicate this.
       
  1200       return false;
       
  1201     }
       
  1202 
  1199     // The caller can be calling the method statically or through an inline
  1203     // The caller can be calling the method statically or through an inline
  1200     // cache call.
  1204     // cache call.
  1201     if (!is_not_entrant()) {
  1205     if (!is_osr_method() && !is_not_entrant()) {
  1202       NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
  1206       NativeJump::patch_verified_entry(entry_point(), verified_entry_point(),
  1203                   SharedRuntime::get_handle_wrong_method_stub());
  1207                   SharedRuntime::get_handle_wrong_method_stub());
  1204       assert (NativeJump::instruction_size == nmethod::_zombie_instruction_size, "");
  1208       assert (NativeJump::instruction_size == nmethod::_zombie_instruction_size, "");
  1205     }
  1209     }
  1206 
  1210 
  1215       assert(state == not_entrant, "other cases may need to be handled differently");
  1219       assert(state == not_entrant, "other cases may need to be handled differently");
  1216     }
  1220     }
  1217 
  1221 
  1218     // Change state
  1222     // Change state
  1219     flags.state = state;
  1223     flags.state = state;
       
  1224 
       
  1225     // Log the transition once
       
  1226     log_state_change();
       
  1227 
  1220   } // leave critical region under Patching_lock
  1228   } // leave critical region under Patching_lock
  1221 
  1229 
  1222   if (state == not_entrant) {
  1230   if (state == not_entrant) {
  1223     Events::log("Make nmethod not entrant " INTPTR_FORMAT, this);
  1231     Events::log("Make nmethod not entrant " INTPTR_FORMAT, this);
  1224   } else {
  1232   } else {
  1237     mark_as_seen_on_stack();
  1245     mark_as_seen_on_stack();
  1238   }
  1246   }
  1239 
  1247 
  1240   // It's a true state change, so mark the method as decompiled.
  1248   // It's a true state change, so mark the method as decompiled.
  1241   inc_decompile_count();
  1249   inc_decompile_count();
  1242 
       
  1243 
  1250 
  1244   // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
  1251   // zombie only - if a JVMTI agent has enabled the CompiledMethodUnload event
  1245   // and it hasn't already been reported for this nmethod then report it now.
  1252   // and it hasn't already been reported for this nmethod then report it now.
  1246   // (the event may have been reported earilier if the GC marked it for unloading).
  1253   // (the event may have been reported earilier if the GC marked it for unloading).
  1247   if (state == zombie) {
  1254   if (state == zombie) {
  1266     VTune::delete_nmethod(this);
  1273     VTune::delete_nmethod(this);
  1267   }
  1274   }
  1268 
  1275 
  1269   // Check whether method got unloaded at a safepoint before this,
  1276   // Check whether method got unloaded at a safepoint before this,
  1270   // if so we can skip the flushing steps below
  1277   // if so we can skip the flushing steps below
  1271   if (method() == NULL) return;
  1278   if (method() == NULL) return true;
  1272 
  1279 
  1273   // Remove nmethod from method.
  1280   // Remove nmethod from method.
  1274   // We need to check if both the _code and _from_compiled_code_entry_point
  1281   // We need to check if both the _code and _from_compiled_code_entry_point
  1275   // refer to this nmethod because there is a race in setting these two fields
  1282   // refer to this nmethod because there is a race in setting these two fields
  1276   // in methodOop as seen in bugid 4947125.
  1283   // in methodOop as seen in bugid 4947125.
  1280   if (method()->code() == this ||
  1287   if (method()->code() == this ||
  1281       method()->from_compiled_entry() == verified_entry_point()) {
  1288       method()->from_compiled_entry() == verified_entry_point()) {
  1282     HandleMark hm;
  1289     HandleMark hm;
  1283     method()->clear_code();
  1290     method()->clear_code();
  1284   }
  1291   }
       
  1292 
       
  1293   return true;
  1285 }
  1294 }
  1286 
  1295 
  1287 
  1296 
  1288 #ifndef PRODUCT
  1297 #ifndef PRODUCT
  1289 void nmethod::check_safepoint() {
  1298 void nmethod::check_safepoint() {