112 // matter much. |
117 // matter much. |
113 if (PrintMethodFlushing) { |
118 if (PrintMethodFlushing) { |
114 tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep"); |
119 tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep"); |
115 } |
120 } |
116 } |
121 } |
|
122 |
|
123 if (UseCodeCacheFlushing) { |
|
124 if (!CodeCache::needs_flushing()) { |
|
125 // In a safepoint, no race with setters |
|
126 _advise_to_sweep = 0; |
|
127 } |
|
128 |
|
129 if (was_full()) { |
|
130 // There was some progress so attempt to restart the compiler |
|
131 jlong now = os::javaTimeMillis(); |
|
132 jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; |
|
133 jlong curr_interval = now - _last_was_full; |
|
134 if ((!CodeCache::needs_flushing()) && (curr_interval > max_interval)) { |
|
135 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); |
|
136 set_was_full(false); |
|
137 |
|
138 // Update the _last_was_full time so we can tell how fast the |
|
139 // code cache is filling up |
|
140 _last_was_full = os::javaTimeMillis(); |
|
141 |
|
142 if (PrintMethodFlushing) { |
|
143 tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler", |
|
144 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
145 } |
|
146 if (LogCompilation && (xtty != NULL)) { |
|
147 ttyLocker ttyl; |
|
148 xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
149 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
150 xtty->stamp(); |
|
151 xtty->end_elem(); |
|
152 } |
|
153 } |
|
154 } |
|
155 } |
117 } |
156 } |
118 |
157 |
119 |
158 |
120 void NMethodSweeper::process_nmethod(nmethod *nm) { |
159 void NMethodSweeper::process_nmethod(nmethod *nm) { |
121 // Skip methods that are currently referenced by the VM |
160 // Skip methods that are currently referenced by the VM |
135 // we reclame it. When we have seen a zombie method twice, we know that |
174 // we reclame it. When we have seen a zombie method twice, we know that |
136 // there are no inline caches that referes to it. |
175 // there are no inline caches that referes to it. |
137 if (nm->is_marked_for_reclamation()) { |
176 if (nm->is_marked_for_reclamation()) { |
138 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
177 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
139 if (PrintMethodFlushing && Verbose) { |
178 if (PrintMethodFlushing && Verbose) { |
140 tty->print_cr("### Nmethod 0x%x (marked for reclamation) being flushed", nm); |
179 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); |
141 } |
180 } |
142 nm->flush(); |
181 nm->flush(); |
143 } else { |
182 } else { |
144 if (PrintMethodFlushing && Verbose) { |
183 if (PrintMethodFlushing && Verbose) { |
145 tty->print_cr("### Nmethod 0x%x (zombie) being marked for reclamation", nm); |
184 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); |
146 } |
185 } |
147 nm->mark_for_reclamation(); |
186 nm->mark_for_reclamation(); |
148 _rescan = true; |
187 _rescan = true; |
149 } |
188 } |
150 } else if (nm->is_not_entrant()) { |
189 } else if (nm->is_not_entrant()) { |
151 // If there is no current activations of this method on the |
190 // If there is no current activations of this method on the |
152 // stack we can safely convert it to a zombie method |
191 // stack we can safely convert it to a zombie method |
153 if (nm->can_not_entrant_be_converted()) { |
192 if (nm->can_not_entrant_be_converted()) { |
154 if (PrintMethodFlushing && Verbose) { |
193 if (PrintMethodFlushing && Verbose) { |
155 tty->print_cr("### Nmethod 0x%x (not entrant) being made zombie", nm); |
194 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm); |
156 } |
195 } |
157 nm->make_zombie(); |
196 nm->make_zombie(); |
158 _rescan = true; |
197 _rescan = true; |
159 } else { |
198 } else { |
160 // Still alive, clean up its inline caches |
199 // Still alive, clean up its inline caches |
165 _not_entrant_seen_on_stack++; |
204 _not_entrant_seen_on_stack++; |
166 } |
205 } |
167 } else if (nm->is_unloaded()) { |
206 } else if (nm->is_unloaded()) { |
168 // Unloaded code, just make it a zombie |
207 // Unloaded code, just make it a zombie |
169 if (PrintMethodFlushing && Verbose) |
208 if (PrintMethodFlushing && Verbose) |
170 tty->print_cr("### Nmethod 0x%x (unloaded) being made zombie", nm); |
209 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); |
171 if (nm->is_osr_method()) { |
210 if (nm->is_osr_method()) { |
172 // No inline caches will ever point to osr methods, so we can just remove it |
211 // No inline caches will ever point to osr methods, so we can just remove it |
173 nm->flush(); |
212 nm->flush(); |
174 } else { |
213 } else { |
175 nm->make_zombie(); |
214 nm->make_zombie(); |
176 _rescan = true; |
215 _rescan = true; |
177 } |
216 } |
178 } else { |
217 } else { |
179 assert(nm->is_alive(), "should be alive"); |
218 assert(nm->is_alive(), "should be alive"); |
|
219 |
|
220 if (UseCodeCacheFlushing) { |
|
221 if ((nm->method()->code() != nm) && !(nm->is_locked_by_vm()) && !(nm->is_osr_method()) && |
|
222 (_traversals > _was_full_traversal+2) && (((uint)nm->compile_id()) < _highest_marked) && |
|
223 CodeCache::needs_flushing()) { |
|
224 // This method has not been called since the forced cleanup happened |
|
225 nm->make_not_entrant(); |
|
226 } |
|
227 } |
|
228 |
180 // Clean-up all inline caches that points to zombie/non-reentrant methods |
229 // Clean-up all inline caches that points to zombie/non-reentrant methods |
181 nm->cleanup_inline_caches(); |
230 nm->cleanup_inline_caches(); |
182 } |
231 } |
183 } |
232 } |
|
233 |
|
234 // Code cache unloading: when compilers notice the code cache is getting full, |
|
235 // they will call a vm op that comes here. This code attempts to speculatively |
|
236 // unload the oldest half of the nmethods (based on the compile job id) by |
|
237 // saving the old code in a list in the CodeCache. Then |
|
238 // execution resumes. If a method so marked is not called by the second |
|
239 // safepoint from the current one, the nmethod will be marked non-entrant and |
|
240 // got rid of by normal sweeping. If the method is called, the methodOop's |
|
241 // _code field is restored and the methodOop/nmethod |
|
242 // go back to their normal state. |
|
243 void NMethodSweeper::handle_full_code_cache(bool is_full) { |
|
244 // Only the first one to notice can advise us to start early cleaning |
|
245 if (!is_full){ |
|
246 jint old = Atomic::cmpxchg( 1, &_advise_to_sweep, 0 ); |
|
247 if (old != 0) { |
|
248 return; |
|
249 } |
|
250 } |
|
251 |
|
252 if (is_full) { |
|
253 // Since code cache is full, immediately stop new compiles |
|
254 bool did_set = CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); |
|
255 if (!did_set) { |
|
256 // only the first to notice can start the cleaning, |
|
257 // others will go back and block |
|
258 return; |
|
259 } |
|
260 set_was_full(true); |
|
261 |
|
262 // If we run out within MinCodeCacheFlushingInterval of the last unload time, give up |
|
263 jlong now = os::javaTimeMillis(); |
|
264 jlong max_interval = (jlong)MinCodeCacheFlushingInterval * (jlong)1000; |
|
265 jlong curr_interval = now - _last_was_full; |
|
266 if (curr_interval < max_interval) { |
|
267 _rescan = true; |
|
268 if (PrintMethodFlushing) { |
|
269 tty->print_cr("### handle full too often, turning off compiler"); |
|
270 } |
|
271 if (LogCompilation && (xtty != NULL)) { |
|
272 ttyLocker ttyl; |
|
273 xtty->begin_elem("disable_compiler flushing_interval='" UINT64_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
274 curr_interval/1000, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
275 xtty->stamp(); |
|
276 xtty->end_elem(); |
|
277 } |
|
278 return; |
|
279 } |
|
280 } |
|
281 |
|
282 VM_HandleFullCodeCache op(is_full); |
|
283 VMThread::execute(&op); |
|
284 |
|
285 // rescan again as soon as possible |
|
286 _rescan = true; |
|
287 } |
|
288 |
|
289 void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) { |
|
290 // If there was a race in detecting full code cache, only run |
|
291 // one vm op for it or keep the compiler shut off |
|
292 |
|
293 debug_only(jlong start = os::javaTimeMillis();) |
|
294 |
|
295 if ((!was_full()) && (is_full)) { |
|
296 if (!CodeCache::needs_flushing()) { |
|
297 if (PrintMethodFlushing) { |
|
298 tty->print_cr("### sweeper: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes, restarting compiler", |
|
299 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
300 } |
|
301 if (LogCompilation && (xtty != NULL)) { |
|
302 ttyLocker ttyl; |
|
303 xtty->begin_elem("restart_compiler live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
304 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
305 xtty->stamp(); |
|
306 xtty->end_elem(); |
|
307 } |
|
308 CompileBroker::set_should_compile_new_jobs(CompileBroker::run_compilation); |
|
309 return; |
|
310 } |
|
311 } |
|
312 |
|
313 // Traverse the code cache trying to dump the oldest nmethods |
|
314 uint curr_max_comp_id = CompileBroker::get_compilation_id(); |
|
315 uint flush_target = ((curr_max_comp_id - _highest_marked) >> 1) + _highest_marked; |
|
316 if (PrintMethodFlushing && Verbose) { |
|
317 tty->print_cr("### Cleaning code cache: Live blobs:" UINT32_FORMAT "/Free code cache:" SIZE_FORMAT " bytes", |
|
318 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
319 } |
|
320 if (LogCompilation && (xtty != NULL)) { |
|
321 ttyLocker ttyl; |
|
322 xtty->begin_elem("start_cleaning_code_cache live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
323 CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
324 xtty->stamp(); |
|
325 xtty->end_elem(); |
|
326 } |
|
327 |
|
328 nmethod* nm = CodeCache::alive_nmethod(CodeCache::first()); |
|
329 jint disconnected = 0; |
|
330 jint made_not_entrant = 0; |
|
331 while ((nm != NULL)){ |
|
332 uint curr_comp_id = nm->compile_id(); |
|
333 |
|
334 // OSR methods cannot be flushed like this. Also, don't flush native methods |
|
335 // since they are part of the JDK in most cases |
|
336 if (nm->is_in_use() && (!nm->is_osr_method()) && (!nm->is_locked_by_vm()) && |
|
337 (!nm->is_native_method()) && ((curr_comp_id < flush_target))) { |
|
338 |
|
339 if ((nm->method()->code() == nm)) { |
|
340 // This method has not been previously considered for |
|
341 // unloading or it was restored already |
|
342 CodeCache::speculatively_disconnect(nm); |
|
343 disconnected++; |
|
344 } else if (nm->is_speculatively_disconnected()) { |
|
345 // This method was previously considered for preemptive unloading and was not called since then |
|
346 nm->method()->invocation_counter()->decay(); |
|
347 nm->method()->backedge_counter()->decay(); |
|
348 nm->make_not_entrant(); |
|
349 made_not_entrant++; |
|
350 } |
|
351 |
|
352 if (curr_comp_id > _highest_marked) { |
|
353 _highest_marked = curr_comp_id; |
|
354 } |
|
355 } |
|
356 nm = CodeCache::alive_nmethod(CodeCache::next(nm)); |
|
357 } |
|
358 |
|
359 if (LogCompilation && (xtty != NULL)) { |
|
360 ttyLocker ttyl; |
|
361 xtty->begin_elem("stop_cleaning_code_cache disconnected='" UINT32_FORMAT "' made_not_entrant='" UINT32_FORMAT "' live_blobs='" UINT32_FORMAT "' free_code_cache='" SIZE_FORMAT "'", |
|
362 disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
|
363 xtty->stamp(); |
|
364 xtty->end_elem(); |
|
365 } |
|
366 |
|
367 // Shut off compiler. Sweeper will run exiting from this safepoint |
|
368 // and turn it back on if it clears enough space |
|
369 if (was_full()) { |
|
370 _last_was_full = os::javaTimeMillis(); |
|
371 CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); |
|
372 } |
|
373 |
|
374 // After two more traversals the sweeper will get rid of unrestored nmethods |
|
375 _was_full_traversal = _traversals; |
|
376 #ifdef ASSERT |
|
377 jlong end = os::javaTimeMillis(); |
|
378 if(PrintMethodFlushing && Verbose) { |
|
379 tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start); |
|
380 } |
|
381 #endif |
|
382 } |