Print this page
rev 6875 : 8056240: Investigate increased GC remark time after class unloading changes in CRM Fuse
Reviewed-by: mgerdin, coleenp, bdelsart

Split Split Close
Expand all
Collapse all
          --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
          +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
↓ open down ↓ 19 lines elided ↑ open up ↑
  20   20   * or visit www.oracle.com if you need additional information or have any
  21   21   * questions.
  22   22   *
  23   23   */
  24   24  
  25   25  #if !defined(__clang_major__) && defined(__GNUC__)
  26   26  #define ATTRIBUTE_PRINTF(x,y) // FIXME, formats are a mess.
  27   27  #endif
  28   28  
  29   29  #include "precompiled.hpp"
       30 +#include "classfile/metadataOnStackMark.hpp"
  30   31  #include "code/codeCache.hpp"
  31   32  #include "code/icBuffer.hpp"
  32   33  #include "gc_implementation/g1/bufferingOopClosure.hpp"
  33   34  #include "gc_implementation/g1/concurrentG1Refine.hpp"
  34   35  #include "gc_implementation/g1/concurrentG1RefineThread.hpp"
  35   36  #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
  36   37  #include "gc_implementation/g1/g1AllocRegion.inline.hpp"
  37   38  #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  38   39  #include "gc_implementation/g1/g1CollectorPolicy.hpp"
  39   40  #include "gc_implementation/g1/g1ErgoVerbose.hpp"
↓ open down ↓ 5086 lines elided ↑ open up ↑
5126 5127        claim_nmethods(claimed_nmethods, &num_claimed_nmethods);
5127 5128  
5128 5129        if (num_claimed_nmethods == 0) {
5129 5130          break;
5130 5131        }
5131 5132  
5132 5133        for (int i = 0; i < num_claimed_nmethods; i++) {
5133 5134          clean_nmethod(claimed_nmethods[i]);
5134 5135        }
5135 5136      }
     5137 +
     5138 +    // The nmethod cleaning helps out and does the CodeCache part of MetadataOnStackMark.
     5139 +    // Need to retire the buffers now that this thread has stopped cleaning nmethods.
     5140 +    MetadataOnStackMark::retire_buffer_for_thread(Thread::current());
5136 5141    }
5137 5142  
5138 5143    void work_second_pass(uint worker_id) {
5139 5144      nmethod* nm;
5140 5145      // Take care of postponed nmethods.
5141 5146      while ((nm = claim_postponed_nmethod()) != NULL) {
5142 5147        clean_nmethod_postponed(nm);
5143 5148      }
5144 5149    }
5145 5150  };
↓ open down ↓ 32 lines elided ↑ open up ↑
5178 5183  
5179 5184  public:
5180 5185  
5181 5186    void clean_klass(InstanceKlass* ik) {
5182 5187      ik->clean_implementors_list(_is_alive);
5183 5188      ik->clean_method_data(_is_alive);
5184 5189  
5185 5190      // G1 specific cleanup work that has
5186 5191      // been moved here to be done in parallel.
5187 5192      ik->clean_dependent_nmethods();
     5193 +    if (JvmtiExport::has_redefined_a_class()) {
     5194 +      InstanceKlass::purge_previous_versions(ik);
     5195 +    }
5188 5196    }
5189 5197  
5190 5198    void work() {
5191 5199      ResourceMark rm;
5192 5200  
5193 5201      // One worker will clean the subklass/sibling klass tree.
5194 5202      if (claim_clean_klass_tree_task()) {
5195 5203        Klass::clean_subklass_tree(_is_alive);
5196 5204      }
5197 5205  
↓ open down ↓ 14 lines elided ↑ open up ↑
5212 5220  
5213 5221  public:
5214 5222    // The constructor is run in the VMThread.
5215 5223    G1ParallelCleaningTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols, uint num_workers, bool unloading_occurred) :
5216 5224        AbstractGangTask("Parallel Cleaning"),
5217 5225        _string_symbol_task(is_alive, process_strings, process_symbols),
5218 5226        _code_cache_task(num_workers, is_alive, unloading_occurred),
5219 5227        _klass_cleaning_task(is_alive) {
5220 5228    }
5221 5229  
     5230 +  void pre_work_verification() {
     5231 +    assert(!MetadataOnStackMark::has_buffer_for_thread(Thread::current()), "Should be empty");
     5232 +  }
     5233 +
     5234 +  void post_work_verification() {
     5235 +    assert(!MetadataOnStackMark::has_buffer_for_thread(Thread::current()), "Should be empty");
     5236 +  }
     5237 +
5222 5238    // The parallel work done by all worker threads.
5223 5239    void work(uint worker_id) {
     5240 +    pre_work_verification();
     5241 +
5224 5242      // Do first pass of code cache cleaning.
5225 5243      _code_cache_task.work_first_pass(worker_id);
5226 5244  
5227 5245      // Let the threads mark that the first pass is done.
5228 5246      _code_cache_task.barrier_mark(worker_id);
5229 5247  
5230 5248      // Clean the Strings and Symbols.
5231 5249      _string_symbol_task.work(worker_id);
5232 5250  
5233 5251      // Wait for all workers to finish the first code cache cleaning pass.
5234 5252      _code_cache_task.barrier_wait(worker_id);
5235 5253  
5236 5254      // Do the second code cache cleaning work, which realize on
5237 5255      // the liveness information gathered during the first pass.
5238 5256      _code_cache_task.work_second_pass(worker_id);
5239 5257  
5240 5258      // Clean all klasses that were not unloaded.
5241 5259      _klass_cleaning_task.work();
     5260 +
     5261 +    post_work_verification();
5242 5262    }
5243 5263  };
5244 5264  
5245 5265  
5246 5266  void G1CollectedHeap::parallel_cleaning(BoolObjectClosure* is_alive,
5247 5267                                          bool process_strings,
5248 5268                                          bool process_symbols,
5249 5269                                          bool class_unloading_occurred) {
5250 5270    uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
5251 5271                      workers()->active_workers() : 1);
↓ open down ↓ 1765 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX