< prev index next >

src/hotspot/share/runtime/sweeper.cpp

Print this page
rev 57156 : imported patch 8234796-v3


 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     }


< prev index next >