hotspot/src/share/vm/runtime/sweeper.cpp
changeset 18025 b7bcf7497f93
parent 17132 dffd513b2a8c
child 20019 3e9220f93c61
equal deleted inserted replaced
18024:f9e300086063 18025:b7bcf7497f93
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    34 #include "runtime/compilationPolicy.hpp"
    34 #include "runtime/compilationPolicy.hpp"
    35 #include "runtime/mutexLocker.hpp"
    35 #include "runtime/mutexLocker.hpp"
    36 #include "runtime/os.hpp"
    36 #include "runtime/os.hpp"
    37 #include "runtime/sweeper.hpp"
    37 #include "runtime/sweeper.hpp"
    38 #include "runtime/vm_operations.hpp"
    38 #include "runtime/vm_operations.hpp"
       
    39 #include "trace/tracing.hpp"
    39 #include "utilities/events.hpp"
    40 #include "utilities/events.hpp"
    40 #include "utilities/xmlstream.hpp"
    41 #include "utilities/xmlstream.hpp"
    41 
    42 
    42 #ifdef ASSERT
    43 #ifdef ASSERT
    43 
    44 
   128 
   129 
   129 
   130 
   130 long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
   131 long      NMethodSweeper::_traversals = 0;   // No. of stack traversals performed
   131 nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
   132 nmethod*  NMethodSweeper::_current = NULL;   // Current nmethod
   132 int       NMethodSweeper::_seen = 0 ;        // No. of nmethods we have currently processed in current pass of CodeCache
   133 int       NMethodSweeper::_seen = 0 ;        // No. of nmethods we have currently processed in current pass of CodeCache
       
   134 int       NMethodSweeper::_flushed_count = 0;   // Nof. nmethods flushed in current sweep
       
   135 int       NMethodSweeper::_zombified_count = 0; // Nof. nmethods made zombie in current sweep
       
   136 int       NMethodSweeper::_marked_count = 0;    // Nof. nmethods marked for reclaim in current sweep
   133 
   137 
   134 volatile int NMethodSweeper::_invocations = 0;   // No. of invocations left until we are completed with this pass
   138 volatile int NMethodSweeper::_invocations = 0;   // No. of invocations left until we are completed with this pass
   135 volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
   139 volatile int NMethodSweeper::_sweep_started = 0; // Whether a sweep is in progress.
   136 
   140 
   137 jint      NMethodSweeper::_locked_seen = 0;
   141 jint      NMethodSweeper::_locked_seen = 0;
   141 jlong     NMethodSweeper::_last_full_flush_time = 0;
   145 jlong     NMethodSweeper::_last_full_flush_time = 0;
   142 int       NMethodSweeper::_highest_marked = 0;
   146 int       NMethodSweeper::_highest_marked = 0;
   143 int       NMethodSweeper::_dead_compile_ids = 0;
   147 int       NMethodSweeper::_dead_compile_ids = 0;
   144 long      NMethodSweeper::_last_flush_traversal_id = 0;
   148 long      NMethodSweeper::_last_flush_traversal_id = 0;
   145 
   149 
       
   150 int       NMethodSweeper::_number_of_flushes = 0; // Total of full traversals caused by full cache
       
   151 int       NMethodSweeper::_total_nof_methods_reclaimed = 0;
       
   152 jlong     NMethodSweeper::_total_time_sweeping = 0;
       
   153 jlong     NMethodSweeper::_total_time_this_sweep = 0;
       
   154 jlong     NMethodSweeper::_peak_sweep_time = 0;
       
   155 jlong     NMethodSweeper::_peak_sweep_fraction_time = 0;
       
   156 jlong     NMethodSweeper::_total_disconnect_time = 0;
       
   157 jlong     NMethodSweeper::_peak_disconnect_time = 0;
       
   158 
   146 class MarkActivationClosure: public CodeBlobClosure {
   159 class MarkActivationClosure: public CodeBlobClosure {
   147 public:
   160 public:
   148   virtual void do_code_blob(CodeBlob* cb) {
   161   virtual void do_code_blob(CodeBlob* cb) {
   149     // If we see an activation belonging to a non_entrant nmethod, we mark it.
   162     // If we see an activation belonging to a non_entrant nmethod, we mark it.
   150     if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) {
   163     if (cb->is_nmethod() && ((nmethod*)cb)->is_not_entrant()) {
   174   if (!sweep_in_progress() && _resweep) {
   187   if (!sweep_in_progress() && _resweep) {
   175     _seen        = 0;
   188     _seen        = 0;
   176     _invocations = NmethodSweepFraction;
   189     _invocations = NmethodSweepFraction;
   177     _current     = CodeCache::first_nmethod();
   190     _current     = CodeCache::first_nmethod();
   178     _traversals  += 1;
   191     _traversals  += 1;
       
   192     _total_time_this_sweep = 0;
       
   193 
   179     if (PrintMethodFlushing) {
   194     if (PrintMethodFlushing) {
   180       tty->print_cr("### Sweep: stack traversal %d", _traversals);
   195       tty->print_cr("### Sweep: stack traversal %d", _traversals);
   181     }
   196     }
   182     Threads::nmethods_do(&mark_activation_closure);
   197     Threads::nmethods_do(&mark_activation_closure);
   183 
   198 
   227     _sweep_started = 0;
   242     _sweep_started = 0;
   228   }
   243   }
   229 }
   244 }
   230 
   245 
   231 void NMethodSweeper::sweep_code_cache() {
   246 void NMethodSweeper::sweep_code_cache() {
   232 #ifdef ASSERT
   247 
   233   jlong sweep_start;
   248   jlong sweep_start_counter = os::elapsed_counter();
   234   if (PrintMethodFlushing) {
   249 
   235     sweep_start = os::javaTimeMillis();
   250   _flushed_count   = 0;
   236   }
   251   _zombified_count = 0;
   237 #endif
   252   _marked_count    = 0;
       
   253 
   238   if (PrintMethodFlushing && Verbose) {
   254   if (PrintMethodFlushing && Verbose) {
   239     tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations);
   255     tty->print_cr("### Sweep at %d out of %d. Invocations left: %d", _seen, CodeCache::nof_nmethods(), _invocations);
   240   }
   256   }
   241 
   257 
   242   if (!CompileBroker::should_compile_new_jobs()) {
   258   if (!CompileBroker::should_compile_new_jobs()) {
   300     if (PrintMethodFlushing) {
   316     if (PrintMethodFlushing) {
   301       tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep");
   317       tty->print_cr("### Couldn't make progress on some nmethods so stopping sweep");
   302     }
   318     }
   303   }
   319   }
   304 
   320 
       
   321   jlong sweep_end_counter = os::elapsed_counter();
       
   322   jlong sweep_time = sweep_end_counter - sweep_start_counter;
       
   323   _total_time_sweeping  += sweep_time;
       
   324   _total_time_this_sweep += sweep_time;
       
   325   _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time);
       
   326   _total_nof_methods_reclaimed += _flushed_count;
       
   327 
       
   328   EventSweepCodeCache event(UNTIMED);
       
   329   if (event.should_commit()) {
       
   330     event.set_starttime(sweep_start_counter);
       
   331     event.set_endtime(sweep_end_counter);
       
   332     event.set_sweepIndex(_traversals);
       
   333     event.set_sweepFractionIndex(NmethodSweepFraction - _invocations + 1);
       
   334     event.set_sweptCount(todo);
       
   335     event.set_flushedCount(_flushed_count);
       
   336     event.set_markedCount(_marked_count);
       
   337     event.set_zombifiedCount(_zombified_count);
       
   338     event.commit();
       
   339   }
       
   340 
   305 #ifdef ASSERT
   341 #ifdef ASSERT
   306   if(PrintMethodFlushing) {
   342   if(PrintMethodFlushing) {
   307     jlong sweep_end             = os::javaTimeMillis();
   343     tty->print_cr("### sweeper:      sweep time(%d): " INT64_FORMAT, _invocations, (jlong)sweep_time);
   308     tty->print_cr("### sweeper:      sweep time(%d): " INT64_FORMAT, _invocations, sweep_end - sweep_start);
       
   309   }
   344   }
   310 #endif
   345 #endif
   311 
   346 
   312   if (_invocations == 1) {
   347   if (_invocations == 1) {
       
   348     _peak_sweep_time = MAX2(_peak_sweep_time, _total_time_this_sweep);
   313     log_sweep("finished");
   349     log_sweep("finished");
   314   }
   350   }
   315 
   351 
   316   // Sweeper is the only case where memory is released,
   352   // Sweeper is the only case where memory is released,
   317   // check here if it is time to restart the compiler.
   353   // check here if it is time to restart the compiler.
   386       assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
   422       assert(!nm->is_locked_by_vm(), "must not flush locked nmethods");
   387       if (PrintMethodFlushing && Verbose) {
   423       if (PrintMethodFlushing && Verbose) {
   388         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
   424         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (marked for reclamation) being flushed", nm->compile_id(), nm);
   389       }
   425       }
   390       release_nmethod(nm);
   426       release_nmethod(nm);
       
   427       _flushed_count++;
   391     } else {
   428     } else {
   392       if (PrintMethodFlushing && Verbose) {
   429       if (PrintMethodFlushing && Verbose) {
   393         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
   430         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (zombie) being marked for reclamation", nm->compile_id(), nm);
   394       }
   431       }
   395       nm->mark_for_reclamation();
   432       nm->mark_for_reclamation();
   396       _resweep = true;
   433       _resweep = true;
       
   434       _marked_count++;
   397       SWEEP(nm);
   435       SWEEP(nm);
   398     }
   436     }
   399   } else if (nm->is_not_entrant()) {
   437   } else if (nm->is_not_entrant()) {
   400     // If there is no current activations of this method on the
   438     // If there is no current activations of this method on the
   401     // stack we can safely convert it to a zombie method
   439     // stack we can safely convert it to a zombie method
   403       if (PrintMethodFlushing && Verbose) {
   441       if (PrintMethodFlushing && Verbose) {
   404         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
   442         tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (not entrant) being made zombie", nm->compile_id(), nm);
   405       }
   443       }
   406       nm->make_zombie();
   444       nm->make_zombie();
   407       _resweep = true;
   445       _resweep = true;
       
   446       _zombified_count++;
   408       SWEEP(nm);
   447       SWEEP(nm);
   409     } else {
   448     } else {
   410       // Still alive, clean up its inline caches
   449       // Still alive, clean up its inline caches
   411       MutexLocker cl(CompiledIC_lock);
   450       MutexLocker cl(CompiledIC_lock);
   412       nm->cleanup_inline_caches();
   451       nm->cleanup_inline_caches();
   418     }
   457     }
   419   } else if (nm->is_unloaded()) {
   458   } else if (nm->is_unloaded()) {
   420     // Unloaded code, just make it a zombie
   459     // Unloaded code, just make it a zombie
   421     if (PrintMethodFlushing && Verbose)
   460     if (PrintMethodFlushing && Verbose)
   422       tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
   461       tty->print_cr("### Nmethod %3d/" PTR_FORMAT " (unloaded) being made zombie", nm->compile_id(), nm);
       
   462 
   423     if (nm->is_osr_method()) {
   463     if (nm->is_osr_method()) {
   424       SWEEP(nm);
   464       SWEEP(nm);
   425       // No inline caches will ever point to osr methods, so we can just remove it
   465       // No inline caches will ever point to osr methods, so we can just remove it
   426       release_nmethod(nm);
   466       release_nmethod(nm);
       
   467       _flushed_count++;
   427     } else {
   468     } else {
   428       nm->make_zombie();
   469       nm->make_zombie();
   429       _resweep = true;
   470       _resweep = true;
       
   471       _zombified_count++;
   430       SWEEP(nm);
   472       SWEEP(nm);
   431     }
   473     }
   432   } else {
   474   } else {
   433     assert(nm->is_alive(), "should be alive");
   475     assert(nm->is_alive(), "should be alive");
   434 
   476 
   482 
   524 
   483 void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
   525 void NMethodSweeper::speculative_disconnect_nmethods(bool is_full) {
   484   // If there was a race in detecting full code cache, only run
   526   // If there was a race in detecting full code cache, only run
   485   // one vm op for it or keep the compiler shut off
   527   // one vm op for it or keep the compiler shut off
   486 
   528 
   487   debug_only(jlong start = os::javaTimeMillis();)
   529   jlong disconnect_start_counter = os::elapsed_counter();
   488 
   530 
   489   // Traverse the code cache trying to dump the oldest nmethods
   531   // Traverse the code cache trying to dump the oldest nmethods
   490   int curr_max_comp_id = CompileBroker::get_compilation_id();
   532   int curr_max_comp_id = CompileBroker::get_compilation_id();
   491   int flush_target = ((curr_max_comp_id - _dead_compile_ids) / CodeCacheFlushingFraction) + _dead_compile_ids;
   533   int flush_target = ((curr_max_comp_id - _dead_compile_ids) / CodeCacheFlushingFraction) + _dead_compile_ids;
   492 
   534 
   539   // traversal cycle and turn it back on if it clears enough space.
   581   // traversal cycle and turn it back on if it clears enough space.
   540   if (is_full) {
   582   if (is_full) {
   541     _last_full_flush_time = os::javaTimeMillis();
   583     _last_full_flush_time = os::javaTimeMillis();
   542   }
   584   }
   543 
   585 
       
   586   jlong disconnect_end_counter = os::elapsed_counter();
       
   587   jlong disconnect_time = disconnect_end_counter - disconnect_start_counter;
       
   588   _total_disconnect_time += disconnect_time;
       
   589   _peak_disconnect_time = MAX2(disconnect_time, _peak_disconnect_time);
       
   590 
       
   591   EventCleanCodeCache event(UNTIMED);
       
   592   if (event.should_commit()) {
       
   593     event.set_starttime(disconnect_start_counter);
       
   594     event.set_endtime(disconnect_end_counter);
       
   595     event.set_disconnectedCount(disconnected);
       
   596     event.set_madeNonEntrantCount(made_not_entrant);
       
   597     event.commit();
       
   598   }
       
   599   _number_of_flushes++;
       
   600 
   544   // After two more traversals the sweeper will get rid of unrestored nmethods
   601   // After two more traversals the sweeper will get rid of unrestored nmethods
   545   _last_flush_traversal_id = _traversals;
   602   _last_flush_traversal_id = _traversals;
   546   _resweep = true;
   603   _resweep = true;
   547 #ifdef ASSERT
   604 #ifdef ASSERT
   548   jlong end = os::javaTimeMillis();
   605 
   549   if(PrintMethodFlushing && Verbose) {
   606   if(PrintMethodFlushing && Verbose) {
   550     tty->print_cr("### sweeper: unload time: " INT64_FORMAT, end-start);
   607     tty->print_cr("### sweeper: unload time: " INT64_FORMAT, (jlong)disconnect_time);
   551   }
   608   }
   552 #endif
   609 #endif
   553 }
   610 }
   554 
   611 
   555 
   612