31 int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass |
31 int NMethodSweeper::_invocations = 0; // No. of invocations left until we are completed with this pass |
32 |
32 |
33 jint NMethodSweeper::_locked_seen = 0; |
33 jint NMethodSweeper::_locked_seen = 0; |
34 jint NMethodSweeper::_not_entrant_seen_on_stack = 0; |
34 jint NMethodSweeper::_not_entrant_seen_on_stack = 0; |
35 bool NMethodSweeper::_rescan = false; |
35 bool NMethodSweeper::_rescan = false; |
|
36 bool NMethodSweeper::_do_sweep = false; |
|
37 jint NMethodSweeper::_sweep_started = 0; |
36 bool NMethodSweeper::_was_full = false; |
38 bool NMethodSweeper::_was_full = false; |
37 jint NMethodSweeper::_advise_to_sweep = 0; |
39 jint NMethodSweeper::_advise_to_sweep = 0; |
38 jlong NMethodSweeper::_last_was_full = 0; |
40 jlong NMethodSweeper::_last_was_full = 0; |
39 uint NMethodSweeper::_highest_marked = 0; |
41 uint NMethodSweeper::_highest_marked = 0; |
40 long NMethodSweeper::_was_full_traversal = 0; |
42 long NMethodSweeper::_was_full_traversal = 0; |
48 } |
50 } |
49 } |
51 } |
50 }; |
52 }; |
51 static MarkActivationClosure mark_activation_closure; |
53 static MarkActivationClosure mark_activation_closure; |
52 |
54 |
53 void NMethodSweeper::sweep() { |
55 void NMethodSweeper::scan_stacks() { |
54 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); |
56 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); |
55 if (!MethodFlushing) return; |
57 if (!MethodFlushing) return; |
|
58 _do_sweep = true; |
56 |
59 |
57 // No need to synchronize access, since this is always executed at a |
60 // No need to synchronize access, since this is always executed at a |
58 // safepoint. If we aren't in the middle of scan and a rescan |
61 // safepoint. If we aren't in the middle of scan and a rescan |
59 // hasn't been requested then just return. |
62 // hasn't been requested then just return. If UseCodeCacheFlushing is on and |
60 if (_current == NULL && !_rescan) return; |
63 // code cache flushing is in progress, don't skip sweeping to help make progress |
|
64 // clearing space in the code cache. |
|
65 if ((_current == NULL && !_rescan) && !(UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs())) { |
|
66 _do_sweep = false; |
|
67 return; |
|
68 } |
61 |
69 |
62 // Make sure CompiledIC_lock in unlocked, since we might update some |
70 // Make sure CompiledIC_lock in unlocked, since we might update some |
63 // inline caches. If it is, we just bail-out and try later. |
71 // inline caches. If it is, we just bail-out and try later. |
64 if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return; |
72 if (CompiledIC_lock->is_locked() || Patching_lock->is_locked()) return; |
65 |
73 |
66 // Check for restart |
74 // Check for restart |
67 assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid"); |
75 assert(CodeCache::find_blob_unsafe(_current) == _current, "Sweeper nmethod cached state invalid"); |
68 if (_current == NULL) { |
76 if (_current == NULL) { |
69 _seen = 0; |
77 _seen = 0; |
70 _invocations = NmethodSweepFraction; |
78 _invocations = NmethodSweepFraction; |
71 _current = CodeCache::first(); |
79 _current = CodeCache::first_nmethod(); |
72 _traversals += 1; |
80 _traversals += 1; |
73 if (PrintMethodFlushing) { |
81 if (PrintMethodFlushing) { |
74 tty->print_cr("### Sweep: stack traversal %d", _traversals); |
82 tty->print_cr("### Sweep: stack traversal %d", _traversals); |
75 } |
83 } |
76 Threads::nmethods_do(&mark_activation_closure); |
84 Threads::nmethods_do(&mark_activation_closure); |
79 _rescan = false; |
87 _rescan = false; |
80 _locked_seen = 0; |
88 _locked_seen = 0; |
81 _not_entrant_seen_on_stack = 0; |
89 _not_entrant_seen_on_stack = 0; |
82 } |
90 } |
83 |
91 |
84 if (PrintMethodFlushing && Verbose) { |
|
85 tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_blobs(), _invocations); |
|
86 } |
|
87 |
|
88 // We want to visit all nmethods after NmethodSweepFraction invocations. |
|
89 // If invocation is 1 we do the rest |
|
90 int todo = CodeCache::nof_blobs(); |
|
91 if (_invocations != 1) { |
|
92 todo = (CodeCache::nof_blobs() - _seen) / _invocations; |
|
93 _invocations--; |
|
94 } |
|
95 |
|
96 for(int i = 0; i < todo && _current != NULL; i++) { |
|
97 CodeBlob* next = CodeCache::next(_current); // Read next before we potentially delete current |
|
98 if (_current->is_nmethod()) { |
|
99 process_nmethod((nmethod *)_current); |
|
100 } |
|
101 _seen++; |
|
102 _current = next; |
|
103 } |
|
104 // Because we could stop on a codeBlob other than an nmethod we skip forward |
|
105 // to the next nmethod (if any). codeBlobs other than nmethods can be freed |
|
106 // async to us and make _current invalid while we sleep. |
|
107 while (_current != NULL && !_current->is_nmethod()) { |
|
108 _current = CodeCache::next(_current); |
|
109 } |
|
110 |
|
111 if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) { |
|
112 // we've completed a scan without making progress but there were |
|
113 // nmethods we were unable to process either because they were |
|
114 // locked or were still on stack. We don't have to aggresively |
|
115 // clean them up so just stop scanning. We could scan once more |
|
116 // but that complicates the control logic and it's unlikely to |
|
117 // matter much. |
|
118 if (PrintMethodFlushing) { |
|
119 tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep"); |
|
120 } |
|
121 } |
|
122 |
|
123 if (UseCodeCacheFlushing) { |
92 if (UseCodeCacheFlushing) { |
124 if (!CodeCache::needs_flushing()) { |
93 if (!CodeCache::needs_flushing()) { |
125 // In a safepoint, no race with setters |
94 // scan_stacks() runs during a safepoint, no race with setters |
126 _advise_to_sweep = 0; |
95 _advise_to_sweep = 0; |
127 } |
96 } |
128 |
97 |
129 if (was_full()) { |
98 if (was_full()) { |
130 // There was some progress so attempt to restart the compiler |
99 // There was some progress so attempt to restart the compiler |
153 } |
122 } |
154 } |
123 } |
155 } |
124 } |
156 } |
125 } |
157 |
126 |
|
127 void NMethodSweeper::possibly_sweep() { |
|
128 if ((!MethodFlushing) || (!_do_sweep)) return; |
|
129 |
|
130 if (_invocations > 0) { |
|
131 // Only one thread at a time will sweep |
|
132 jint old = Atomic::cmpxchg( 1, &_sweep_started, 0 ); |
|
133 if (old != 0) { |
|
134 return; |
|
135 } |
|
136 sweep_code_cache(); |
|
137 } |
|
138 _sweep_started = 0; |
|
139 } |
|
140 |
|
141 void NMethodSweeper::sweep_code_cache() { |
|
142 #ifdef ASSERT |
|
143 jlong sweep_start; |
|
144 if(PrintMethodFlushing) { |
|
145 sweep_start = os::javaTimeMillis(); |
|
146 } |
|
147 #endif |
|
148 if (PrintMethodFlushing && Verbose) { |
|
149 tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_blobs(), _invocations); |
|
150 } |
|
151 |
|
152 // We want to visit all nmethods after NmethodSweepFraction invocations. |
|
153 // If invocation is 1 we do the rest |
|
154 int todo = CodeCache::nof_blobs(); |
|
155 if (_invocations > 1) { |
|
156 todo = (CodeCache::nof_blobs() - _seen) / _invocations; |
|
157 } |
|
158 |
|
159 // Compilers may check to sweep more often than stack scans happen, |
|
160 // don't keep trying once it is all scanned |
|
161 _invocations--; |
|
162 |
|
163 assert(!SafepointSynchronize::is_at_safepoint(), "should not be in safepoint when we get here"); |
|
164 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
|
165 |
|
166 { |
|
167 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
|
168 |
|
169 for(int i = 0; i < todo && _current != NULL; i++) { |
|
170 |
|
171 // Since we will give up the CodeCache_lock, always skip ahead to an nmethod. |
|
172 // Other blobs can be deleted by other threads |
|
173 // Read next before we potentially delete current |
|
174 CodeBlob* next = CodeCache::next_nmethod(_current); |
|
175 |
|
176 // Now ready to process nmethod and give up CodeCache_lock |
|
177 { |
|
178 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
|
179 process_nmethod((nmethod *)_current); |
|
180 } |
|
181 _seen++; |
|
182 _current = next; |
|
183 } |
|
184 |
|
185 // Skip forward to the next nmethod (if any). Code blobs other than nmethods |
|
186 // can be freed async to us and make _current invalid while we sleep. |
|
187 _current = CodeCache::next_nmethod(_current); |
|
188 } |
|
189 |
|
190 if (_current == NULL && !_rescan && (_locked_seen || _not_entrant_seen_on_stack)) { |
|
191 // we've completed a scan without making progress but there were |
|
192 // nmethods we were unable to process either because they were |
|
193 // locked or were still on stack. We don't have to aggresively |
|
194 // clean them up so just stop scanning. We could scan once more |
|
195 // but that complicates the control logic and it's unlikely to |
|
196 // matter much. |
|
197 if (PrintMethodFlushing) { |
|
198 tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep"); |
|
199 } |
|
200 } |
|
201 |
|
202 #ifdef ASSERT |
|
203 if(PrintMethodFlushing) { |
|
204 jlong sweep_end = os::javaTimeMillis(); |
|
205 tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start); |
|
206 } |
|
207 #endif |
|
208 } |
|
209 |
158 |
210 |
159 void NMethodSweeper::process_nmethod(nmethod *nm) { |
211 void NMethodSweeper::process_nmethod(nmethod *nm) { |
|
212 assert(!CodeCache_lock->owned_by_self(), "just checking"); |
|
213 |
160 // Skip methods that are currently referenced by the VM |
214 // Skip methods that are currently referenced by the VM |
161 if (nm->is_locked_by_vm()) { |
215 if (nm->is_locked_by_vm()) { |
162 // But still remember to clean-up inline caches for alive nmethods |
216 // But still remember to clean-up inline caches for alive nmethods |
163 if (nm->is_alive()) { |
217 if (nm->is_alive()) { |
164 // Clean-up all inline caches that points to zombie/non-reentrant methods |
218 // Clean-up all inline caches that points to zombie/non-reentrant methods |
|
219 MutexLocker cl(CompiledIC_lock); |
165 nm->cleanup_inline_caches(); |
220 nm->cleanup_inline_caches(); |
166 } else { |
221 } else { |
167 _locked_seen++; |
222 _locked_seen++; |
168 } |
223 } |
169 return; |
224 return; |
176 if (nm->is_marked_for_reclamation()) { |
231 if (nm->is_marked_for_reclamation()) { |
177 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
232 assert(!nm->is_locked_by_vm(), "must not flush locked nmethods"); |
178 if (PrintMethodFlushing && Verbose) { |
233 if (PrintMethodFlushing && Verbose) { |
179 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); |
234 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm); |
180 } |
235 } |
|
236 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
181 nm->flush(); |
237 nm->flush(); |
182 } else { |
238 } else { |
183 if (PrintMethodFlushing && Verbose) { |
239 if (PrintMethodFlushing && Verbose) { |
184 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); |
240 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm); |
185 } |
241 } |
195 } |
251 } |
196 nm->make_zombie(); |
252 nm->make_zombie(); |
197 _rescan = true; |
253 _rescan = true; |
198 } else { |
254 } else { |
199 // Still alive, clean up its inline caches |
255 // Still alive, clean up its inline caches |
|
256 MutexLocker cl(CompiledIC_lock); |
200 nm->cleanup_inline_caches(); |
257 nm->cleanup_inline_caches(); |
201 // we coudn't transition this nmethod so don't immediately |
258 // we coudn't transition this nmethod so don't immediately |
202 // request a rescan. If this method stays on the stack for a |
259 // request a rescan. If this method stays on the stack for a |
203 // long time we don't want to keep rescanning at every safepoint. |
260 // long time we don't want to keep rescanning the code cache. |
204 _not_entrant_seen_on_stack++; |
261 _not_entrant_seen_on_stack++; |
205 } |
262 } |
206 } else if (nm->is_unloaded()) { |
263 } else if (nm->is_unloaded()) { |
207 // Unloaded code, just make it a zombie |
264 // Unloaded code, just make it a zombie |
208 if (PrintMethodFlushing && Verbose) |
265 if (PrintMethodFlushing && Verbose) |
209 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); |
266 tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm); |
210 if (nm->is_osr_method()) { |
267 if (nm->is_osr_method()) { |
211 // No inline caches will ever point to osr methods, so we can just remove it |
268 // No inline caches will ever point to osr methods, so we can just remove it |
|
269 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
212 nm->flush(); |
270 nm->flush(); |
213 } else { |
271 } else { |
214 nm->make_zombie(); |
272 nm->make_zombie(); |
215 _rescan = true; |
273 _rescan = true; |
216 } |
274 } |
225 nm->make_not_entrant(); |
283 nm->make_not_entrant(); |
226 } |
284 } |
227 } |
285 } |
228 |
286 |
229 // Clean-up all inline caches that points to zombie/non-reentrant methods |
287 // Clean-up all inline caches that points to zombie/non-reentrant methods |
|
288 MutexLocker cl(CompiledIC_lock); |
230 nm->cleanup_inline_caches(); |
289 nm->cleanup_inline_caches(); |
231 } |
290 } |
232 } |
291 } |
233 |
292 |
234 // Code cache unloading: when compilers notice the code cache is getting full, |
293 // 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 |
294 // 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 |
295 // 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 |
296 // 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 |
297 // execution resumes. If a method so marked is not called by the second sweeper |
239 // safepoint from the current one, the nmethod will be marked non-entrant and |
298 // stack traversal after 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 |
299 // got rid of by normal sweeping. If the method is called, the methodOop's |
241 // _code field is restored and the methodOop/nmethod |
300 // _code field is restored and the methodOop/nmethod |
242 // go back to their normal state. |
301 // go back to their normal state. |
243 void NMethodSweeper::handle_full_code_cache(bool is_full) { |
302 void NMethodSweeper::handle_full_code_cache(bool is_full) { |
244 // Only the first one to notice can advise us to start early cleaning |
303 // Only the first one to notice can advise us to start early cleaning |
362 disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
421 disconnected, made_not_entrant, CodeCache::nof_blobs(), CodeCache::unallocated_capacity()); |
363 xtty->stamp(); |
422 xtty->stamp(); |
364 xtty->end_elem(); |
423 xtty->end_elem(); |
365 } |
424 } |
366 |
425 |
367 // Shut off compiler. Sweeper will run exiting from this safepoint |
426 // Shut off compiler. Sweeper will start over with a new stack scan and |
368 // and turn it back on if it clears enough space |
427 // traversal cycle and turn it back on if it clears enough space. |
369 if (was_full()) { |
428 if (was_full()) { |
370 _last_was_full = os::javaTimeMillis(); |
429 _last_was_full = os::javaTimeMillis(); |
371 CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); |
430 CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation); |
372 } |
431 } |
373 |
432 |