< prev index next >

src/hotspot/share/runtime/sweeper.cpp

Print this page
rev 51807 : imported patch nmethod-marking.patch
rev 51808 : 8132849: Increased stop time in cleanup phase because of single-threaded walk of thread stacks in NMethodSweeper::mark_active_nmethods()
rev 51809 : [mq]: JDK-8132849-01.patch


  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "code/codeCache.hpp"
  27 #include "code/compiledIC.hpp"
  28 #include "code/icBuffer.hpp"
  29 #include "code/nmethod.hpp"
  30 #include "compiler/compileBroker.hpp"


  31 #include "jfr/jfrEvents.hpp"
  32 #include "logging/log.hpp"
  33 #include "logging/logStream.hpp"
  34 #include "memory/allocation.inline.hpp"
  35 #include "memory/resourceArea.hpp"

  36 #include "oops/method.hpp"
  37 #include "runtime/atomic.hpp"
  38 #include "runtime/compilationPolicy.hpp"
  39 #include "runtime/interfaceSupport.inline.hpp"

  40 #include "runtime/mutexLocker.hpp"
  41 #include "runtime/orderAccess.hpp"
  42 #include "runtime/os.hpp"
  43 #include "runtime/sweeper.hpp"
  44 #include "runtime/thread.inline.hpp"
  45 #include "runtime/vm_operations.hpp"
  46 #include "runtime/vmThread.hpp"
  47 #include "utilities/events.hpp"
  48 #include "utilities/xmlstream.hpp"
  49 
  50 #ifdef ASSERT
  51 
  52 #define SWEEP(nm) record_sweep(nm, __LINE__)
  53 // Sweeper logging code
  54 class SweeperRecord {
  55  public:
  56   int traversal;
  57   int compile_id;
  58   long traversal_mark;
  59   int state;


 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 /**
 201   * Scans the stacks of all Java threads and marks activations of not-entrant methods.
 202   * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
 203   * safepoint.
 204   */
 205 void NMethodSweeper::mark_active_nmethods() {
 206   CodeBlobClosure* cl = prepare_mark_active_nmethods();
 207   if (cl != NULL) {






 208     Threads::nmethods_do(cl);
 209   }

 210 }
 211 
 212 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
 213   assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");

 214   // If we do not want to reclaim not-entrant or zombie methods there is no need
 215   // to scan stacks
 216   if (!MethodFlushing) {
 217     return NULL;
 218   }
 219 
 220   // Increase time so that we can estimate when to invoke the sweeper again.
 221   _time_counter++;
 222 
 223   // Check for restart
 224   if (_current.method() != NULL) {
 225     if (_current.method()->is_nmethod()) {
 226       assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
 227     } else if (_current.method()->is_aot()) {
 228       assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
 229     } else {
 230       ShouldNotReachHere();
 231     }
 232   }
 233 


 241 
 242     if (PrintMethodFlushing) {
 243       tty->print_cr("### Sweep: stack traversal %ld", _traversals);
 244     }
 245     return &mark_activation_closure;
 246 
 247   } else {
 248     // Only set hotness counter
 249     return &set_hotness_closure;
 250   }
 251 
 252 }
 253 
 254 /**
 255   * This function triggers a VM operation that does stack scanning of active
 256   * methods. Stack scanning is mandatory for the sweeper to make progress.
 257   */
 258 void NMethodSweeper::do_stack_scanning() {
 259   assert(!CodeCache_lock->owned_by_self(), "just checking");
 260   if (wait_for_stack_scanning()) {







 261     VM_MarkActiveNMethods op;
 262     VMThread::execute(&op);

 263     _should_sweep = true;
 264   }
 265 }
 266 
 267 void NMethodSweeper::sweeper_loop() {
 268   bool timeout;
 269   while (true) {
 270     {
 271       ThreadBlockInVM tbivm(JavaThread::current());
 272       MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 273       const long wait_time = 60*60*24 * 1000;
 274       timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time);
 275     }
 276     if (!timeout) {
 277       possibly_sweep();
 278     }
 279   }
 280 }
 281 
 282 /**




  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "code/codeCache.hpp"
  27 #include "code/compiledIC.hpp"
  28 #include "code/icBuffer.hpp"
  29 #include "code/nmethod.hpp"
  30 #include "compiler/compileBroker.hpp"
  31 #include "gc/shared/collectedHeap.hpp"
  32 #include "gc/shared/workgroup.hpp"
  33 #include "jfr/jfrEvents.hpp"
  34 #include "logging/log.hpp"
  35 #include "logging/logStream.hpp"
  36 #include "memory/allocation.inline.hpp"
  37 #include "memory/resourceArea.hpp"
  38 #include "memory/universe.hpp"
  39 #include "oops/method.hpp"
  40 #include "runtime/atomic.hpp"
  41 #include "runtime/compilationPolicy.hpp"
  42 #include "runtime/interfaceSupport.inline.hpp"
  43 #include "runtime/handshake.hpp"
  44 #include "runtime/mutexLocker.hpp"
  45 #include "runtime/orderAccess.hpp"
  46 #include "runtime/os.hpp"
  47 #include "runtime/sweeper.hpp"
  48 #include "runtime/thread.inline.hpp"
  49 #include "runtime/vm_operations.hpp"
  50 #include "runtime/vmThread.hpp"
  51 #include "utilities/events.hpp"
  52 #include "utilities/xmlstream.hpp"
  53 
  54 #ifdef ASSERT
  55 
  56 #define SWEEP(nm) record_sweep(nm, __LINE__)
  57 // Sweeper logging code
  58 class SweeperRecord {
  59  public:
  60   int traversal;
  61   int compile_id;
  62   long traversal_mark;
  63   int state;


 184 public:
 185   virtual void do_code_blob(CodeBlob* cb) {
 186     assert(cb->is_nmethod(), "CodeBlob should be nmethod");
 187     nmethod* nm = (nmethod*)cb;
 188     nm->set_hotness_counter(NMethodSweeper::hotness_counter_reset_val());
 189   }
 190 };
 191 static SetHotnessClosure set_hotness_closure;
 192 
 193 
 194 int NMethodSweeper::hotness_counter_reset_val() {
 195   if (_hotness_counter_reset_val == 0) {
 196     _hotness_counter_reset_val = (ReservedCodeCacheSize < M) ? 1 : (ReservedCodeCacheSize / M) * 2;
 197   }
 198   return _hotness_counter_reset_val;
 199 }
 200 bool NMethodSweeper::wait_for_stack_scanning() {
 201   return _current.end();
 202 }
 203 
 204 class ThreadToCodeBlobClosure : public ThreadClosure {
 205 private:
 206   CodeBlobClosure* _cl;
 207 public:
 208   ThreadToCodeBlobClosure(CodeBlobClosure* cl) : _cl(cl) {}
 209   void do_thread(Thread* thread) {
 210     if (thread->is_Java_thread() &&
 211         ! thread->is_Code_cache_sweeper_thread()) {
 212       JavaThread* jt = (JavaThread*) thread;
 213       jt->nmethods_do(_cl);
 214     }
 215   }
 216 };
 217 
 218 class NMethodMarkingTask : public AbstractGangTask {
 219 private:
 220   ThreadToCodeBlobClosure* _cl;
 221 public:
 222   NMethodMarkingTask(ThreadToCodeBlobClosure* cl) :
 223     AbstractGangTask("Parallel NMethod Marking"),
 224     _cl(cl) {}
 225   void work(uint worker_id) {
 226     Threads::possibly_parallel_threads_do(true, _cl);
 227   }
 228 };
 229 
 230 /**
 231   * Scans the stacks of all Java threads and marks activations of not-entrant methods.
 232   * No need to synchronize access, since 'mark_active_nmethods' is always executed at a
 233   * safepoint.
 234   */
 235 void NMethodSweeper::mark_active_nmethods() {
 236   CodeBlobClosure* cl = prepare_mark_active_nmethods();
 237   if (cl != NULL) {
 238     WorkGang* workers = Universe::heap()->get_safepoint_workers();
 239     if (workers != NULL) {
 240       ThreadToCodeBlobClosure tcl(cl);
 241       NMethodMarkingTask task(&tcl);
 242       workers->run_task(&task);
 243     } else {
 244       Threads::nmethods_do(cl);
 245     }
 246   }
 247 }
 248 
 249 CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
 250   assert(SafepointSynchronize::is_at_safepoint() ||
 251          Thread::current()->is_Code_cache_sweeper_thread(), "must be executed at a safepoint");
 252   // If we do not want to reclaim not-entrant or zombie methods there is no need
 253   // to scan stacks
 254   if (!MethodFlushing) {
 255     return NULL;
 256   }
 257 
 258   // Increase time so that we can estimate when to invoke the sweeper again.
 259   _time_counter++;
 260 
 261   // Check for restart
 262   if (_current.method() != NULL) {
 263     if (_current.method()->is_nmethod()) {
 264       assert(CodeCache::find_blob_unsafe(_current.method()) == _current.method(), "Sweeper nmethod cached state invalid");
 265     } else if (_current.method()->is_aot()) {
 266       assert(CodeCache::find_blob_unsafe(_current.method()->code_begin()) == _current.method(), "Sweeper AOT method cached state invalid");
 267     } else {
 268       ShouldNotReachHere();
 269     }
 270   }
 271 


 279 
 280     if (PrintMethodFlushing) {
 281       tty->print_cr("### Sweep: stack traversal %ld", _traversals);
 282     }
 283     return &mark_activation_closure;
 284 
 285   } else {
 286     // Only set hotness counter
 287     return &set_hotness_closure;
 288   }
 289 
 290 }
 291 
 292 /**
 293   * This function triggers a VM operation that does stack scanning of active
 294   * methods. Stack scanning is mandatory for the sweeper to make progress.
 295   */
 296 void NMethodSweeper::do_stack_scanning() {
 297   assert(!CodeCache_lock->owned_by_self(), "just checking");
 298   if (wait_for_stack_scanning()) {
 299     if (ThreadLocalHandshakes) {
 300       CodeBlobClosure* code_cl = prepare_mark_active_nmethods();
 301       if (code_cl != NULL) {
 302         ThreadToCodeBlobClosure tcl(code_cl);
 303         Handshake::execute(&tcl);
 304       }
 305     } else {
 306       VM_MarkActiveNMethods op;
 307       VMThread::execute(&op);
 308     }
 309     _should_sweep = true;
 310   }
 311 }
 312 
 313 void NMethodSweeper::sweeper_loop() {
 314   bool timeout;
 315   while (true) {
 316     {
 317       ThreadBlockInVM tbivm(JavaThread::current());
 318       MutexLockerEx waiter(CodeCache_lock, Mutex::_no_safepoint_check_flag);
 319       const long wait_time = 60*60*24 * 1000;
 320       timeout = CodeCache_lock->wait(Mutex::_no_safepoint_check_flag, wait_time);
 321     }
 322     if (!timeout) {
 323       possibly_sweep();
 324     }
 325   }
 326 }
 327 
 328 /**


< prev index next >