hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
changeset 2881 74a1337e4acc
parent 2249 fb8abed44792
child 2882 d508a8bac491
equal deleted inserted replaced
2748:986f111ef897 2881:74a1337e4acc
    23  */
    23  */
    24 
    24 
    25 #include "incls/_precompiled.incl"
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_concurrentG1Refine.cpp.incl"
    26 #include "incls/_concurrentG1Refine.cpp.incl"
    27 
    27 
    28 bool ConcurrentG1Refine::_enabled = false;
       
    29 
       
    30 ConcurrentG1Refine::ConcurrentG1Refine() :
    28 ConcurrentG1Refine::ConcurrentG1Refine() :
    31   _pya(PYA_continue), _last_pya(PYA_continue),
       
    32   _last_cards_during(), _first_traversal(false),
       
    33   _card_counts(NULL), _cur_card_count_histo(NULL), _cum_card_count_histo(NULL),
    29   _card_counts(NULL), _cur_card_count_histo(NULL), _cum_card_count_histo(NULL),
    34   _hot_cache(NULL),
    30   _hot_cache(NULL),
    35   _def_use_cache(false), _use_cache(false),
    31   _def_use_cache(false), _use_cache(false),
    36   _n_periods(0), _total_cards(0), _total_travs(0)
    32   _n_periods(0), _total_cards(0), _total_travs(0),
       
    33   _threads(NULL), _n_threads(0)
    37 {
    34 {
    38   if (G1ConcRefine) {
    35   if (G1ConcRefine) {
    39     _cg1rThread = new ConcurrentG1RefineThread(this);
    36     _n_threads = (G1ParallelRSetThreads > 0) ? G1ParallelRSetThreads : ParallelGCThreads;
    40     assert(cg1rThread() != NULL, "Conc refine should have been created");
    37     if (_n_threads > 0) {
    41     assert(cg1rThread()->cg1r() == this,
    38       _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
    42            "Conc refine thread should refer to this");
    39       ConcurrentG1RefineThread *next = NULL;
    43   } else {
    40       for (int i = _n_threads - 1; i >= 0; i--) {
    44     _cg1rThread = NULL;
    41         ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, i);
       
    42         assert(t != NULL, "Conc refine should have been created");
       
    43         assert(t->cg1r() == this, "Conc refine thread should refer to this");
       
    44         _threads[i] = t;
       
    45         next = t;
       
    46       }
       
    47     }
    45   }
    48   }
    46 }
    49 }
    47 
    50 
    48 void ConcurrentG1Refine::init() {
    51 void ConcurrentG1Refine::init() {
    49   if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
    52   if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
    73     _n_hot = 0;
    76     _n_hot = 0;
    74     _hot_cache_idx = 0;
    77     _hot_cache_idx = 0;
    75   }
    78   }
    76 }
    79 }
    77 
    80 
       
    81 void ConcurrentG1Refine::stop() {
       
    82   if (_threads != NULL) {
       
    83     for (int i = 0; i < _n_threads; i++) {
       
    84       _threads[i]->stop();
       
    85     }
       
    86   }
       
    87 }
       
    88 
    78 ConcurrentG1Refine::~ConcurrentG1Refine() {
    89 ConcurrentG1Refine::~ConcurrentG1Refine() {
    79   if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
    90   if (G1ConcRSLogCacheSize > 0 || G1ConcRSCountTraversals) {
    80     assert(_card_counts != NULL, "Logic");
    91     assert(_card_counts != NULL, "Logic");
    81     FREE_C_HEAP_ARRAY(unsigned char, _card_counts);
    92     FREE_C_HEAP_ARRAY(unsigned char, _card_counts);
    82     assert(_cur_card_count_histo != NULL, "Logic");
    93     assert(_cur_card_count_histo != NULL, "Logic");
    86   }
    97   }
    87   if (G1ConcRSLogCacheSize > 0) {
    98   if (G1ConcRSLogCacheSize > 0) {
    88     assert(_hot_cache != NULL, "Logic");
    99     assert(_hot_cache != NULL, "Logic");
    89     FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
   100     FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
    90   }
   101   }
    91 }
   102   if (_threads != NULL) {
    92 
   103     for (int i = 0; i < _n_threads; i++) {
    93 bool ConcurrentG1Refine::refine() {
   104       delete _threads[i];
    94   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   105     }
    95   unsigned cards_before = g1h->g1_rem_set()->conc_refine_cards();
   106     FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
    96   clear_hot_cache();  // Any previous values in this are now invalid.
   107   }
    97   g1h->g1_rem_set()->concurrentRefinementPass(this);
   108 }
    98   _traversals++;
   109 
    99   unsigned cards_after = g1h->g1_rem_set()->conc_refine_cards();
   110 void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
   100   unsigned cards_during = cards_after-cards_before;
   111   if (_threads != NULL) {
   101   // If this is the first traversal in the current enabling
   112     for (int i = 0; i < _n_threads; i++) {
   102   // and we did some cards, or if the number of cards found is decreasing
   113       tc->do_thread(_threads[i]);
   103   // sufficiently quickly, then keep going.  Otherwise, sleep a while.
   114     }
   104   bool res =
   115   }
   105     (_first_traversal && cards_during > 0)
   116 }
   106     ||
   117 
   107     (!_first_traversal && cards_during * 3 < _last_cards_during * 2);
       
   108   _last_cards_during = cards_during;
       
   109   _first_traversal = false;
       
   110   return res;
       
   111 }
       
   112 
       
   113 void ConcurrentG1Refine::enable() {
       
   114   MutexLocker x(G1ConcRefine_mon);
       
   115   if (!_enabled) {
       
   116     _enabled = true;
       
   117     _first_traversal = true; _last_cards_during = 0;
       
   118     G1ConcRefine_mon->notify_all();
       
   119   }
       
   120 }
       
   121 
       
   122 unsigned ConcurrentG1Refine::disable() {
       
   123   MutexLocker x(G1ConcRefine_mon);
       
   124   if (_enabled) {
       
   125     _enabled = false;
       
   126     return _traversals;
       
   127   } else {
       
   128     return 0;
       
   129   }
       
   130 }
       
   131 
       
   132 void ConcurrentG1Refine::wait_for_ConcurrentG1Refine_enabled() {
       
   133   G1ConcRefine_mon->lock();
       
   134   while (!_enabled) {
       
   135     G1ConcRefine_mon->wait(Mutex::_no_safepoint_check_flag);
       
   136   }
       
   137   G1ConcRefine_mon->unlock();
       
   138   _traversals = 0;
       
   139 };
       
   140 
       
   141 void ConcurrentG1Refine::set_pya_restart() {
       
   142   // If we're using the log-based RS barrier, the above will cause
       
   143   // in-progress traversals of completed log buffers to quit early; we will
       
   144   // also abandon all other buffers.
       
   145   if (G1RSBarrierUseQueue) {
       
   146     DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
       
   147     dcqs.abandon_logs();
       
   148     // Reset the post-yield actions.
       
   149     _pya = PYA_continue;
       
   150     _last_pya = PYA_continue;
       
   151   } else {
       
   152     _pya = PYA_restart;
       
   153   }
       
   154 }
       
   155 
       
   156 void ConcurrentG1Refine::set_pya_cancel() {
       
   157   _pya = PYA_cancel;
       
   158 }
       
   159 
       
   160 PostYieldAction ConcurrentG1Refine::get_pya() {
       
   161   if (_pya != PYA_continue) {
       
   162     jint val = _pya;
       
   163     while (true) {
       
   164       jint val_read = Atomic::cmpxchg(PYA_continue, &_pya, val);
       
   165       if (val_read == val) {
       
   166         PostYieldAction res = (PostYieldAction)val;
       
   167         assert(res != PYA_continue, "Only the refine thread should reset.");
       
   168         _last_pya = res;
       
   169         return res;
       
   170       } else {
       
   171         val = val_read;
       
   172       }
       
   173     }
       
   174   }
       
   175   // QQQ WELL WHAT DO WE RETURN HERE???
       
   176   // make up something!
       
   177   return PYA_continue;
       
   178 }
       
   179 
       
   180 PostYieldAction ConcurrentG1Refine::get_last_pya() {
       
   181   PostYieldAction res = _last_pya;
       
   182   _last_pya = PYA_continue;
       
   183   return res;
       
   184 }
       
   185 
       
   186 bool ConcurrentG1Refine::do_traversal() {
       
   187   return _cg1rThread->do_traversal();
       
   188 }
       
   189 
   118 
   190 int ConcurrentG1Refine::add_card_count(jbyte* card_ptr) {
   119 int ConcurrentG1Refine::add_card_count(jbyte* card_ptr) {
   191   size_t card_num = (card_ptr - _ct_bot);
   120   size_t card_num = (card_ptr - _ct_bot);
   192   guarantee(0 <= card_num && card_num < _n_card_counts, "Bounds");
   121   guarantee(0 <= card_num && card_num < _n_card_counts, "Bounds");
   193   unsigned char cnt = _card_counts[card_num];
   122   unsigned char cnt = _card_counts[card_num];