hotspot/src/share/vm/gc/g1/dirtyCardQueue.cpp
changeset 33762 3d1dd03dfd3f
parent 33759 8a0e9139a9c5
parent 33761 329db4b51480
child 34141 1030e4216817
equal deleted inserted replaced
33760:e2acc6d959f5 33762:3d1dd03dfd3f
    30 #include "runtime/atomic.inline.hpp"
    30 #include "runtime/atomic.inline.hpp"
    31 #include "runtime/mutexLocker.hpp"
    31 #include "runtime/mutexLocker.hpp"
    32 #include "runtime/safepoint.hpp"
    32 #include "runtime/safepoint.hpp"
    33 #include "runtime/thread.inline.hpp"
    33 #include "runtime/thread.inline.hpp"
    34 
    34 
       
    35 DirtyCardQueue::DirtyCardQueue(DirtyCardQueueSet* qset, bool permanent) :
       
    36   // Dirty card queues are always active, so we create them with their
       
    37   // active field set to true.
       
    38   PtrQueue(qset, permanent, true /* active */)
       
    39 { }
       
    40 
       
    41 DirtyCardQueue::~DirtyCardQueue() {
       
    42   if (!is_permanent()) {
       
    43     flush();
       
    44   }
       
    45 }
       
    46 
    35 bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
    47 bool DirtyCardQueue::apply_closure(CardTableEntryClosure* cl,
    36                                    bool consume,
    48                                    bool consume,
    37                                    uint worker_i) {
    49                                    uint worker_i) {
    38   bool res = true;
    50   bool res = true;
    39   if (_buf != NULL) {
    51   if (_buf != NULL) {
    40     res = apply_closure_to_buffer(cl, _buf, _index, _sz,
    52     res = apply_closure_to_buffer(cl, _buf, _index, _sz,
    41                                   consume,
    53                                   consume,
    42                                   worker_i);
    54                                   worker_i);
    43     if (res && consume) _index = _sz;
    55     if (res && consume) {
       
    56       _index = _sz;
       
    57     }
    44   }
    58   }
    45   return res;
    59   return res;
    46 }
    60 }
    47 
    61 
    48 bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
    62 bool DirtyCardQueue::apply_closure_to_buffer(CardTableEntryClosure* cl,
    49                                              void** buf,
    63                                              void** buf,
    50                                              size_t index, size_t sz,
    64                                              size_t index, size_t sz,
    51                                              bool consume,
    65                                              bool consume,
    52                                              uint worker_i) {
    66                                              uint worker_i) {
    53   if (cl == NULL) return true;
    67   if (cl == NULL) return true;
    54   for (size_t i = index; i < sz; i += oopSize) {
    68   size_t limit = byte_index_to_index(sz);
    55     int ind = byte_index_to_index((int)i);
    69   for (size_t i = byte_index_to_index(index); i < limit; ++i) {
    56     jbyte* card_ptr = (jbyte*)buf[ind];
    70     jbyte* card_ptr = static_cast<jbyte*>(buf[i]);
    57     if (card_ptr != NULL) {
    71     if (card_ptr != NULL) {
    58       // Set the entry to null, so we don't do it again (via the test
    72       // Set the entry to null, so we don't do it again (via the test
    59       // above) if we reconsider this buffer.
    73       // above) if we reconsider this buffer.
    60       if (consume) buf[ind] = NULL;
    74       if (consume) {
    61       if (!cl->do_card_ptr(card_ptr, worker_i)) return false;
    75         buf[i] = NULL;
       
    76       }
       
    77       if (!cl->do_card_ptr(card_ptr, worker_i)) {
       
    78         return false;
       
    79       }
    62     }
    80     }
    63   }
    81   }
    64   return true;
    82   return true;
    65 }
    83 }
    66 
    84 
    67 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
    85 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
    68   PtrQueueSet(notify_when_complete),
    86   PtrQueueSet(notify_when_complete),
    69   _mut_process_closure(NULL),
    87   _mut_process_closure(NULL),
    70   _shared_dirty_card_queue(this, true /*perm*/),
    88   _shared_dirty_card_queue(this, true /* permanent */),
    71   _free_ids(NULL),
    89   _free_ids(NULL),
    72   _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
    90   _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
    73 {
    91 {
    74   _all_active = true;
    92   _all_active = true;
    75 }
    93 }
    77 // Determines how many mutator threads can process the buffers in parallel.
    95 // Determines how many mutator threads can process the buffers in parallel.
    78 uint DirtyCardQueueSet::num_par_ids() {
    96 uint DirtyCardQueueSet::num_par_ids() {
    79   return (uint)os::processor_count();
    97   return (uint)os::processor_count();
    80 }
    98 }
    81 
    99 
    82 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
   100 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl,
       
   101                                    Monitor* cbl_mon,
       
   102                                    Mutex* fl_lock,
    83                                    int process_completed_threshold,
   103                                    int process_completed_threshold,
    84                                    int max_completed_queue,
   104                                    int max_completed_queue,
    85                                    Mutex* lock, PtrQueueSet* fl_owner) {
   105                                    Mutex* lock,
       
   106                                    DirtyCardQueueSet* fl_owner) {
    86   _mut_process_closure = cl;
   107   _mut_process_closure = cl;
    87   PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
   108   PtrQueueSet::initialize(cbl_mon,
    88                           max_completed_queue, fl_owner);
   109                           fl_lock,
       
   110                           process_completed_threshold,
       
   111                           max_completed_queue,
       
   112                           fl_owner);
    89   set_buffer_size(G1UpdateBufferSize);
   113   set_buffer_size(G1UpdateBufferSize);
    90   _shared_dirty_card_queue.set_lock(lock);
   114   _shared_dirty_card_queue.set_lock(lock);
    91   _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
   115   _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
    92 }
   116 }
    93 
   117 
    97 
   121 
    98 void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl,
   122 void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl,
    99                                                     bool consume,
   123                                                     bool consume,
   100                                                     uint worker_i) {
   124                                                     uint worker_i) {
   101   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   125   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   102   for(JavaThread* t = Threads::first(); t; t = t->next()) {
   126   for (JavaThread* t = Threads::first(); t; t = t->next()) {
   103     bool b = t->dirty_card_queue().apply_closure(cl, consume);
   127     bool b = t->dirty_card_queue().apply_closure(cl, consume);
   104     guarantee(b, "Should not be interrupted.");
   128     guarantee(b, "Should not be interrupted.");
   105   }
   129   }
   106   bool b = shared_dirty_card_queue()->apply_closure(cl,
   130   bool b = shared_dirty_card_queue()->apply_closure(cl,
   107                                                     consume,
   131                                                     consume,
   154   }
   178   }
   155   return b;
   179   return b;
   156 }
   180 }
   157 
   181 
   158 
   182 
   159 BufferNode*
   183 BufferNode* DirtyCardQueueSet::get_completed_buffer(int stop_at) {
   160 DirtyCardQueueSet::get_completed_buffer(int stop_at) {
       
   161   BufferNode* nd = NULL;
   184   BufferNode* nd = NULL;
   162   MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
   185   MutexLockerEx x(_cbl_mon, Mutex::_no_safepoint_check_flag);
   163 
   186 
   164   if ((int)_n_completed_buffers <= stop_at) {
   187   if ((int)_n_completed_buffers <= stop_at) {
   165     _process_completed = false;
   188     _process_completed = false;
   172     if (_completed_buffers_head == NULL)
   195     if (_completed_buffers_head == NULL)
   173       _completed_buffers_tail = NULL;
   196       _completed_buffers_tail = NULL;
   174     _n_completed_buffers--;
   197     _n_completed_buffers--;
   175     assert(_n_completed_buffers >= 0, "Invariant");
   198     assert(_n_completed_buffers >= 0, "Invariant");
   176   }
   199   }
   177   debug_only(assert_completed_buffer_list_len_correct_locked());
   200   DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
   178   return nd;
   201   return nd;
   179 }
   202 }
   180 
   203 
   181 bool DirtyCardQueueSet::
   204 bool DirtyCardQueueSet::apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl,
   182 apply_closure_to_completed_buffer_helper(CardTableEntryClosure* cl,
   205                                                                  uint worker_i,
   183                                          uint worker_i,
   206                                                                  BufferNode* nd) {
   184                                          BufferNode* nd) {
       
   185   if (nd != NULL) {
   207   if (nd != NULL) {
   186     void **buf = BufferNode::make_buffer_from_node(nd);
   208     void **buf = BufferNode::make_buffer_from_node(nd);
   187     size_t index = nd->index();
   209     size_t index = nd->index();
   188     bool b =
   210     bool b =
   189       DirtyCardQueue::apply_closure_to_buffer(cl, buf,
   211       DirtyCardQueue::apply_closure_to_buffer(cl, buf,
   253       nd->set_next(buffers_to_delete);
   275       nd->set_next(buffers_to_delete);
   254       buffers_to_delete = nd;
   276       buffers_to_delete = nd;
   255     }
   277     }
   256     _n_completed_buffers = 0;
   278     _n_completed_buffers = 0;
   257     _completed_buffers_tail = NULL;
   279     _completed_buffers_tail = NULL;
   258     debug_only(assert_completed_buffer_list_len_correct_locked());
   280     DEBUG_ONLY(assert_completed_buffer_list_len_correct_locked());
   259   }
   281   }
   260   while (buffers_to_delete != NULL) {
   282   while (buffers_to_delete != NULL) {
   261     BufferNode* nd = buffers_to_delete;
   283     BufferNode* nd = buffers_to_delete;
   262     buffers_to_delete = nd->next();
   284     buffers_to_delete = nd->next();
   263     deallocate_buffer(BufferNode::make_buffer_from_node(nd));
   285     deallocate_buffer(BufferNode::make_buffer_from_node(nd));
   285   _max_completed_queue = max_jint;
   307   _max_completed_queue = max_jint;
   286   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   308   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   287   for (JavaThread* t = Threads::first(); t; t = t->next()) {
   309   for (JavaThread* t = Threads::first(); t; t = t->next()) {
   288     DirtyCardQueue& dcq = t->dirty_card_queue();
   310     DirtyCardQueue& dcq = t->dirty_card_queue();
   289     if (dcq.size() != 0) {
   311     if (dcq.size() != 0) {
   290       void **buf = t->dirty_card_queue().get_buf();
   312       void** buf = dcq.get_buf();
   291       // We must NULL out the unused entries, then enqueue.
   313       // We must NULL out the unused entries, then enqueue.
   292       for (size_t i = 0; i < t->dirty_card_queue().get_index(); i += oopSize) {
   314       size_t limit = dcq.byte_index_to_index(dcq.get_index());
   293         buf[PtrQueue::byte_index_to_index((int)i)] = NULL;
   315       for (size_t i = 0; i < limit; ++i) {
       
   316         buf[i] = NULL;
   294       }
   317       }
   295       enqueue_complete_buffer(dcq.get_buf(), dcq.get_index());
   318       enqueue_complete_buffer(dcq.get_buf(), dcq.get_index());
   296       dcq.reinitialize();
   319       dcq.reinitialize();
   297     }
   320     }
   298   }
   321   }