hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
changeset 24104 febf9363fb68
parent 24103 956dc4aa4615
child 24105 93ea1c7cae36
equal deleted inserted replaced
24103:956dc4aa4615 24104:febf9363fb68
    91 //
    91 //
    92 
    92 
    93 // Local to this file.
    93 // Local to this file.
    94 
    94 
    95 class RefineCardTableEntryClosure: public CardTableEntryClosure {
    95 class RefineCardTableEntryClosure: public CardTableEntryClosure {
    96   G1RemSet* _g1rs;
       
    97   ConcurrentG1Refine* _cg1r;
       
    98   bool _concurrent;
    96   bool _concurrent;
    99 public:
    97 public:
   100   RefineCardTableEntryClosure(G1RemSet* g1rs,
    98   RefineCardTableEntryClosure() : _concurrent(true) { }
   101                               ConcurrentG1Refine* cg1r) :
    99 
   102     _g1rs(g1rs), _cg1r(cg1r), _concurrent(true)
       
   103   {}
       
   104   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
   100   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
   105     bool oops_into_cset = _g1rs->refine_card(card_ptr, worker_i, false);
   101     bool oops_into_cset = G1CollectedHeap::heap()->g1_rem_set()->refine_card(card_ptr, worker_i, false);
   106     // This path is executed by the concurrent refine or mutator threads,
   102     // This path is executed by the concurrent refine or mutator threads,
   107     // concurrently, and so we do not care if card_ptr contains references
   103     // concurrently, and so we do not care if card_ptr contains references
   108     // that point into the collection set.
   104     // that point into the collection set.
   109     assert(!oops_into_cset, "should be");
   105     assert(!oops_into_cset, "should be");
   110 
   106 
   113       return false;
   109       return false;
   114     }
   110     }
   115     // Otherwise, we finished successfully; return true.
   111     // Otherwise, we finished successfully; return true.
   116     return true;
   112     return true;
   117   }
   113   }
       
   114 
   118   void set_concurrent(bool b) { _concurrent = b; }
   115   void set_concurrent(bool b) { _concurrent = b; }
   119 };
   116 };
   120 
   117 
   121 
   118 
   122 class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure {
   119 class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure {
   476   ct_bs->mod_card_iterate(&count1);
   473   ct_bs->mod_card_iterate(&count1);
   477   int orig_count = count1.n();
   474   int orig_count = count1.n();
   478 
   475 
   479   // First clear the logged cards.
   476   // First clear the logged cards.
   480   ClearLoggedCardTableEntryClosure clear;
   477   ClearLoggedCardTableEntryClosure clear;
   481   dcqs.set_closure(&clear);
   478   dcqs.apply_closure_to_all_completed_buffers(&clear);
   482   dcqs.apply_closure_to_all_completed_buffers();
   479   dcqs.iterate_closure_all_threads(&clear, false);
   483   dcqs.iterate_closure_all_threads(false);
       
   484   clear.print_histo();
   480   clear.print_histo();
   485 
   481 
   486   // Now ensure that there's no dirty cards.
   482   // Now ensure that there's no dirty cards.
   487   CountNonCleanMemRegionClosure count2(this);
   483   CountNonCleanMemRegionClosure count2(this);
   488   ct_bs->mod_card_iterate(&count2);
   484   ct_bs->mod_card_iterate(&count2);
   491                            count2.n(), orig_count);
   487                            count2.n(), orig_count);
   492   }
   488   }
   493   guarantee(count2.n() == 0, "Card table should be clean.");
   489   guarantee(count2.n() == 0, "Card table should be clean.");
   494 
   490 
   495   RedirtyLoggedCardTableEntryClosure redirty;
   491   RedirtyLoggedCardTableEntryClosure redirty;
   496   JavaThread::dirty_card_queue_set().set_closure(&redirty);
   492   dcqs.apply_closure_to_all_completed_buffers(&redirty);
   497   dcqs.apply_closure_to_all_completed_buffers();
   493   dcqs.iterate_closure_all_threads(&redirty, false);
   498   dcqs.iterate_closure_all_threads(false);
       
   499   gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.",
   494   gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.",
   500                          clear.calls(), orig_count);
   495                          clear.calls(), orig_count);
   501   guarantee(redirty.calls() == clear.calls(),
   496   guarantee(redirty.calls() == clear.calls(),
   502             "Or else mechanism is broken.");
   497             "Or else mechanism is broken.");
   503 
   498 
   506   if (count3.n() != orig_count) {
   501   if (count3.n() != orig_count) {
   507     gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.",
   502     gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.",
   508                            orig_count, count3.n());
   503                            orig_count, count3.n());
   509     guarantee(count3.n() >= orig_count, "Should have restored them all.");
   504     guarantee(count3.n() >= orig_count, "Should have restored them all.");
   510   }
   505   }
   511 
       
   512   JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl);
       
   513 }
   506 }
   514 
   507 
   515 // Private class members.
   508 // Private class members.
   516 
   509 
   517 G1CollectedHeap* G1CollectedHeap::_g1h;
   510 G1CollectedHeap* G1CollectedHeap::_g1h;
  2001   // Ensure that the sizes are properly aligned.
  1994   // Ensure that the sizes are properly aligned.
  2002   Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
  1995   Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap");
  2003   Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
  1996   Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap");
  2004   Universe::check_alignment(max_byte_size, heap_alignment, "g1 heap");
  1997   Universe::check_alignment(max_byte_size, heap_alignment, "g1 heap");
  2005 
  1998 
  2006   _cg1r = new ConcurrentG1Refine(this);
  1999   _refine_cte_cl = new RefineCardTableEntryClosure();
       
  2000 
       
  2001   _cg1r = new ConcurrentG1Refine(this, _refine_cte_cl);
  2007 
  2002 
  2008   // Reserve the maximum.
  2003   // Reserve the maximum.
  2009 
  2004 
  2010   // When compressed oops are enabled, the preferred heap base
  2005   // When compressed oops are enabled, the preferred heap base
  2011   // is calculated by subtracting the requested size from the
  2006   // is calculated by subtracting the requested size from the
  2096   }
  2091   }
  2097 
  2092 
  2098   // Perform any initialization actions delegated to the policy.
  2093   // Perform any initialization actions delegated to the policy.
  2099   g1_policy()->init();
  2094   g1_policy()->init();
  2100 
  2095 
  2101   _refine_cte_cl =
       
  2102     new RefineCardTableEntryClosure(g1_rem_set(),
       
  2103                                     concurrent_g1_refine());
       
  2104   JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl);
       
  2105 
       
  2106   JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon,
  2096   JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon,
  2107                                                SATB_Q_FL_lock,
  2097                                                SATB_Q_FL_lock,
  2108                                                G1SATBProcessCompletedThreshold,
  2098                                                G1SATBProcessCompletedThreshold,
  2109                                                Shared_SATB_Q_lock);
  2099                                                Shared_SATB_Q_lock);
  2110 
  2100 
  2111   JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
  2101   JavaThread::dirty_card_queue_set().initialize(_refine_cte_cl,
       
  2102                                                 DirtyCardQ_CBL_mon,
  2112                                                 DirtyCardQ_FL_lock,
  2103                                                 DirtyCardQ_FL_lock,
  2113                                                 concurrent_g1_refine()->yellow_zone(),
  2104                                                 concurrent_g1_refine()->yellow_zone(),
  2114                                                 concurrent_g1_refine()->red_zone(),
  2105                                                 concurrent_g1_refine()->red_zone(),
  2115                                                 Shared_DirtyCardQ_lock);
  2106                                                 Shared_DirtyCardQ_lock);
  2116 
  2107 
  2117   if (G1DeferredRSUpdate) {
  2108   if (G1DeferredRSUpdate) {
  2118     dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon,
  2109     dirty_card_queue_set().initialize(NULL, // Should never be called by the Java code
       
  2110                                       DirtyCardQ_CBL_mon,
  2119                                       DirtyCardQ_FL_lock,
  2111                                       DirtyCardQ_FL_lock,
  2120                                       -1, // never trigger processing
  2112                                       -1, // never trigger processing
  2121                                       -1, // no limit on length
  2113                                       -1, // no limit on length
  2122                                       Shared_DirtyCardQ_lock,
  2114                                       Shared_DirtyCardQ_lock,
  2123                                       &JavaThread::dirty_card_queue_set());
  2115                                       &JavaThread::dirty_card_queue_set());
  2124   }
  2116   }
  2125 
  2117 
  2126   // Initialize the card queue set used to hold cards containing
  2118   // Initialize the card queue set used to hold cards containing
  2127   // references into the collection set.
  2119   // references into the collection set.
  2128   _into_cset_dirty_card_queue_set.initialize(DirtyCardQ_CBL_mon,
  2120   _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
       
  2121                                              DirtyCardQ_CBL_mon,
  2129                                              DirtyCardQ_FL_lock,
  2122                                              DirtyCardQ_FL_lock,
  2130                                              -1, // never trigger processing
  2123                                              -1, // never trigger processing
  2131                                              -1, // no limit on length
  2124                                              -1, // no limit on length
  2132                                              Shared_DirtyCardQ_lock,
  2125                                              Shared_DirtyCardQ_lock,
  2133                                              &JavaThread::dirty_card_queue_set());
  2126                                              &JavaThread::dirty_card_queue_set());
  5261     G1StringDedup::unlink(is_alive);
  5254     G1StringDedup::unlink(is_alive);
  5262   }
  5255   }
  5263 }
  5256 }
  5264 
  5257 
  5265 class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure {
  5258 class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure {
  5266 public:
  5259  private:
       
  5260   size_t _num_processed;
       
  5261 
       
  5262  public:
       
  5263   RedirtyLoggedCardTableEntryFastClosure() : CardTableEntryClosure(), _num_processed(0) { }
       
  5264 
  5267   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
  5265   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
  5268     *card_ptr = CardTableModRefBS::dirty_card_val();
  5266     *card_ptr = CardTableModRefBS::dirty_card_val();
       
  5267     _num_processed++;
  5269     return true;
  5268     return true;
       
  5269   }
       
  5270 
       
  5271   size_t num_processed() const { return _num_processed; }
       
  5272 };
       
  5273 
       
  5274 class G1RedirtyLoggedCardsTask : public AbstractGangTask {
       
  5275  private:
       
  5276   DirtyCardQueueSet* _queue;
       
  5277  public:
       
  5278   G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { }
       
  5279 
       
  5280   virtual void work(uint worker_id) {
       
  5281     double start_time = os::elapsedTime();
       
  5282 
       
  5283     RedirtyLoggedCardTableEntryFastClosure cl;
       
  5284     if (G1CollectedHeap::heap()->use_parallel_gc_threads()) {
       
  5285       _queue->par_apply_closure_to_all_completed_buffers(&cl);
       
  5286     } else {
       
  5287       _queue->apply_closure_to_all_completed_buffers(&cl);
       
  5288     }
       
  5289 
       
  5290     G1GCPhaseTimes* timer = G1CollectedHeap::heap()->g1_policy()->phase_times();
       
  5291     timer->record_redirty_logged_cards_time_ms(worker_id, (os::elapsedTime() - start_time) * 1000.0);
       
  5292     timer->record_redirty_logged_cards_processed_cards(worker_id, cl.num_processed());
  5270   }
  5293   }
  5271 };
  5294 };
  5272 
  5295 
  5273 void G1CollectedHeap::redirty_logged_cards() {
  5296 void G1CollectedHeap::redirty_logged_cards() {
  5274   guarantee(G1DeferredRSUpdate, "Must only be called when using deferred RS updates.");
  5297   guarantee(G1DeferredRSUpdate, "Must only be called when using deferred RS updates.");
  5275   double redirty_logged_cards_start = os::elapsedTime();
  5298   double redirty_logged_cards_start = os::elapsedTime();
  5276 
  5299 
  5277   RedirtyLoggedCardTableEntryFastClosure redirty;
  5300   uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
  5278   dirty_card_queue_set().set_closure(&redirty);
  5301                    _g1h->workers()->active_workers() : 1);
  5279   dirty_card_queue_set().apply_closure_to_all_completed_buffers();
  5302 
       
  5303   G1RedirtyLoggedCardsTask redirty_task(&dirty_card_queue_set());
       
  5304   dirty_card_queue_set().reset_for_par_iteration();
       
  5305   if (use_parallel_gc_threads()) {
       
  5306     set_par_threads(n_workers);
       
  5307     workers()->run_task(&redirty_task);
       
  5308     set_par_threads(0);
       
  5309   } else {
       
  5310     redirty_task.work(0);
       
  5311   }
  5280 
  5312 
  5281   DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set();
  5313   DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set();
  5282   dcq.merge_bufferlists(&dirty_card_queue_set());
  5314   dcq.merge_bufferlists(&dirty_card_queue_set());
  5283   assert(dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
  5315   assert(dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed");
  5284 
  5316