180 public:
181 virtual void do_code_blob(CodeBlob* cb) {
182 assert(cb->is_nmethod(), "CodeBlob should be nmethod");
183 nmethod* nm = (nmethod*)cb;
184 nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
185 }
186 };
187 static SetHotnessClosure set_hotness_closure;
188
189
190 int NMethodSweeper::hotness_counter_reset_val() {
191 if (_hotness_counter_reset_val == 0) {
192 _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
193 }
194 return _hotness_counter_reset_val;
195 }
196 bool NMethodSweeper::wait_for_stack_scanning() {
197 return _current.end();
198 }
199
200 class NMethodMarkingThreadClosure : public ThreadClosure {
201 private:
202 CodeBlobClosure* _cl;
203 public:
204 NMethodMarkingThreadClosure(CodeBlobClosure* cl) : _cl(cl) {}
205 void do_thread(Thread* thread) {
206 if (thread->is_Java_thread() && ! thread->is_Code_cache_sweeper_thread()) {
207 JavaThread* jt = (JavaThread*) thread;
208 jt->nmethods_do(_cl);
209 }
210 }
211 };
212
213 class NMethodMarkingTask : public AbstractGangTask {
214 private:
215 NMethodMarkingThreadClosure* _cl;
216 public:
217 NMethodMarkingTask(NMethodMarkingThreadClosure* cl) :
218 AbstractGangTask("Parallel NMethod Marking"),
219 _cl(cl) {
220 Threads::change_thread_claim_token();
221 }
222
223 ~NMethodMarkingTask() {
224 Threads::assert_all_threads_claimed();
225 }
226
227 void work(uint worker_id) {
228 Threads::possibly_parallel_threads_do(true, _cl);
229 }
230 };
231
232 /**
233 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
234 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
235 * safepoint.
236 */
237 void NMethodSweeper::mark_active_nmethods() {
238 CodeBlobClosure* cl = prepare_mark_active_nmethods();
239 if (cl != NULL) {
240 WorkGang* workers = Universe::heap()->get_safepoint_workers();
241 if (workers != NULL) {
242 NMethodMarkingThreadClosure tcl(cl);
243 NMethodMarkingTask task(&tcl);
244 workers->run_task(&task);
245 } else {
246 Threads::nmethods_do(cl);
247 }
248 }
249 }
250
251 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
252 #ifdef ASSERT
253 if (ThreadLocalHandshakes) {
254 assert(Thread::current()->is_Code_cache_sweeper_thread(), "must be executed under CodeCache_lock and in sweeper thread");
255 assert_lock_strong(CodeCache_lock);
256 } else {
257 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
258 }
259 #endif
260
261 // If we do not want to reclaim not-entrant or zombie methods there is no need
262 // to scan stacks
307 }
308 }
309
310 return &set_hotness_closure;
311 }
312
313 /**
314 * This function triggers a VM operation that does stack scanning of active
315 * methods. Stack scanning is mandatory for the sweeper to make progress.
316 */
317 void NMethodSweeper::do_stack_scanning() {
318 assert(!CodeCache_lock->owned_by_self(), "just checking");
319 if (wait_for_stack_scanning()) {
320 if (ThreadLocalHandshakes) {
321 CodeBlobClosure* code_cl;
322 {
323 MutexLocker ccl(CodeCache_lock, Mutex::_no_safepoint_check_flag);
324 code_cl = prepare_mark_active_nmethods();
325 }
326 if (code_cl != NULL) {
327 NMethodMarkingThreadClosure tcl(code_cl);
328 Handshake::execute(&tcl);
329 }
330 } else {
331 VM_MarkActiveNMethods op;
332 VMThread::execute(&op);
333 }
334 }
335 }
336
337 void NMethodSweeper::sweeper_loop() {
338 bool timeout;
339 while (true) {
340 {
341 ThreadBlockInVM tbivm(JavaThread::current());
342 MonitorLocker waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
343 const long wait_time = 60*60*24 * 1000;
344 timeout = waiter.wait(wait_time);
345 }
346 if (!timeout) {
347 possibly_sweep();
348 }
|
180 public:
181 virtual void do_code_blob(CodeBlob* cb) {
182 assert(cb->is_nmethod(), "CodeBlob should be nmethod");
183 nmethod* nm = (nmethod*)cb;
184 nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
185 }
186 };
187 static SetHotnessClosure set_hotness_closure;
188
189
190 int NMethodSweeper::hotness_counter_reset_val() {
191 if (_hotness_counter_reset_val == 0) {
192 _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
193 }
194 return _hotness_counter_reset_val;
195 }
196 bool NMethodSweeper::wait_for_stack_scanning() {
197 return _current.end();
198 }
199
200 class NMethodMarkingClosure : public HandshakeClosure {
201 private:
202 CodeBlobClosure* _cl;
203 public:
204 NMethodMarkingClosure(CodeBlobClosure* cl) : HandshakeClosure("NMethodMarking"), _cl(cl) {}
205 void do_thread(Thread* thread) {
206 if (thread->is_Java_thread() && ! thread->is_Code_cache_sweeper_thread()) {
207 JavaThread* jt = (JavaThread*) thread;
208 jt->nmethods_do(_cl);
209 }
210 }
211 };
212
213 class NMethodMarkingTask : public AbstractGangTask {
214 private:
215 NMethodMarkingClosure* _cl;
216 public:
217 NMethodMarkingTask(NMethodMarkingClosure* cl) :
218 AbstractGangTask("Parallel NMethod Marking"),
219 _cl(cl) {
220 Threads::change_thread_claim_token();
221 }
222
223 ~NMethodMarkingTask() {
224 Threads::assert_all_threads_claimed();
225 }
226
227 void work(uint worker_id) {
228 Threads::possibly_parallel_threads_do(true, _cl);
229 }
230 };
231
232 /**
233 * Scans the stacks of all Java threads and marks activations of not-entrant methods.
234 * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
235 * safepoint.
236 */
237 void NMethodSweeper::mark_active_nmethods() {
238 CodeBlobClosure* cl = prepare_mark_active_nmethods();
239 if (cl != NULL) {
240 WorkGang* workers = Universe::heap()->get_safepoint_workers();
241 if (workers != NULL) {
242 NMethodMarkingClosure tcl(cl);
243 NMethodMarkingTask task(&tcl);
244 workers->run_task(&task);
245 } else {
246 Threads::nmethods_do(cl);
247 }
248 }
249 }
250
251 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
252 #ifdef ASSERT
253 if (ThreadLocalHandshakes) {
254 assert(Thread::current()->is_Code_cache_sweeper_thread(), "must be executed under CodeCache_lock and in sweeper thread");
255 assert_lock_strong(CodeCache_lock);
256 } else {
257 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
258 }
259 #endif
260
261 // If we do not want to reclaim not-entrant or zombie methods there is no need
262 // to scan stacks
307 }
308 }
309
310 return &set_hotness_closure;
311 }
312
313 /**
314 * This function triggers a VM operation that does stack scanning of active
315 * methods. Stack scanning is mandatory for the sweeper to make progress.
316 */
317 void NMethodSweeper::do_stack_scanning() {
318 assert(!CodeCache_lock->owned_by_self(), "just checking");
319 if (wait_for_stack_scanning()) {
320 if (ThreadLocalHandshakes) {
321 CodeBlobClosure* code_cl;
322 {
323 MutexLocker ccl(CodeCache_lock, Mutex::_no_safepoint_check_flag);
324 code_cl = prepare_mark_active_nmethods();
325 }
326 if (code_cl != NULL) {
327 NMethodMarkingClosure nm_cl(code_cl);
328 Handshake::execute(&nm_cl);
329 }
330 } else {
331 VM_MarkActiveNMethods op;
332 VMThread::execute(&op);
333 }
334 }
335 }
336
337 void NMethodSweeper::sweeper_loop() {
338 bool timeout;
339 while (true) {
340 {
341 ThreadBlockInVM tbivm(JavaThread::current());
342 MonitorLocker waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
343 const long wait_time = 60*60*24 * 1000;
344 timeout = waiter.wait(wait_time);
345 }
346 if (!timeout) {
347 possibly_sweep();
348 }
|