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 |