182 };
183 static SetHotnessClosure set_hotness_closure;
184
185
186 int NMethodSweeper::hotness_counter_reset_val() {
187 if (_hotness_counter_reset_val == 0) {
188 _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
189 }
190 return _hotness_counter_reset_val;
191 }
192 bool NMethodSweeper::wait_for_stack_scanning() {
193 return _current.end();
194 }
195
196 /**
197 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
198 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
199 * safepoint.
200 */
201 void NMethodSweeper::mark_active_nmethods() {
202 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
203 // If we do not want to reclaim not-entrant or zombie methods there is no need
204 // to scan stacks
205 if (!MethodFlushing) {
206 return;
207 }
208
209 // Increase time so that we can estimate when to invoke the sweeper again.
210 _time_counter++;
211
212 // Check for restart
213 if (_current.method() != NULL) {
214 if (_current.method()->is_nmethod()) {
215 assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
216 } else if (_current.method()->is_aot()) {
217 assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
218 } else {
219 ShouldNotReachHere();
220 }
221 }
222
223 if (wait_for_stack_scanning()) {
224 _seen = 0;
225 _current = CompiledMethodIterator();
226 // Initialize to first nmethod
227 _current.next();
228 _traversals += 1;
229 _total_time_this_sweep = Tickspan();
230
231 if (PrintMethodFlushing) {
232 tty->print_cr("### Sweep: stack traversal %ld", _traversals);
233 }
234 Threads::nmethods_do(&mark_activation_closure);
235
236 } else {
237 // Only set hotness counter
238 Threads::nmethods_do(&set_hotness_closure);
239 }
240
241 OrderAccess::storestore();
242 }
243
244 /**
245 * This function triggers a VM operation that does stack scanning of active
246 * methods. Stack scanning is mandatory for the sweeper to make progress.
247 */
248 void NMethodSweeper::do_stack_scanning() {
249 assert(!CodeCache_lock->owned_by_self(), "just checking");
250 if (wait_for_stack_scanning()) {
251 VM_MarkActiveNMethods op;
252 VMThread::execute(&op);
253 _should_sweep = true;
254 }
255 }
256
257 void NMethodSweeper::sweeper_loop() {
258 bool timeout;
259 while (true) {
260 {
261 ThreadBlockInVM tbivm(JavaThread::current());
|
182 };
183 static SetHotnessClosure set_hotness_closure;
184
185
186 int NMethodSweeper::hotness_counter_reset_val() {
187 if (_hotness_counter_reset_val == 0) {
188 _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
189 }
190 return _hotness_counter_reset_val;
191 }
192 bool NMethodSweeper::wait_for_stack_scanning() {
193 return _current.end();
194 }
195
196 /**
197 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
198 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
199 * safepoint.
200 */
201 void NMethodSweeper::mark_active_nmethods() {
202 CodeBlobClosure* cl = prepare_mark_active_nmethods();
203 if (cl != NULL) {
204 Threads::nmethods_do(cl);
205 // TODO: Is this really needed?
206 OrderAccess::storestore();
207 }
208 }
209
210 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
211 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
212 // If we do not want to reclaim not-entrant or zombie methods there is no need
213 // to scan stacks
214 if (!MethodFlushing) {
215 return NULL;
216 }
217
218 // Increase time so that we can estimate when to invoke the sweeper again.
219 _time_counter++;
220
221 // Check for restart
222 if (_current.method() != NULL) {
223 if (_current.method()->is_nmethod()) {
224 assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
225 } else if (_current.method()->is_aot()) {
226 assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
227 } else {
228 ShouldNotReachHere();
229 }
230 }
231
232 if (wait_for_stack_scanning()) {
233 _seen = 0;
234 _current = CompiledMethodIterator();
235 // Initialize to first nmethod
236 _current.next();
237 _traversals += 1;
238 _total_time_this_sweep = Tickspan();
239
240 if (PrintMethodFlushing) {
241 tty->print_cr("### Sweep: stack traversal %ld", _traversals);
242 }
243 return &mark_activation_closure;
244
245 } else {
246 // Only set hotness counter
247 return &set_hotness_closure;
248 }
249
250 }
251
252 /**
253 * This function triggers a VM operation that does stack scanning of active
254 * methods. Stack scanning is mandatory for the sweeper to make progress.
255 */
256 void NMethodSweeper::do_stack_scanning() {
257 assert(!CodeCache_lock->owned_by_self(), "just checking");
258 if (wait_for_stack_scanning()) {
259 VM_MarkActiveNMethods op;
260 VMThread::execute(&op);
261 _should_sweep = true;
262 }
263 }
264
265 void NMethodSweeper::sweeper_loop() {
266 bool timeout;
267 while (true) {
268 {
269 ThreadBlockInVM tbivm(JavaThread::current());
|