hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.cpp
changeset 24104 febf9363fb68
parent 23855 c4574075402c
child 25351 7c198a690050
equal deleted inserted replaced
24103:956dc4aa4615 24104:febf9363fb68
    68 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
    68 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
    69 #endif // _MSC_VER
    69 #endif // _MSC_VER
    70 
    70 
    71 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
    71 DirtyCardQueueSet::DirtyCardQueueSet(bool notify_when_complete) :
    72   PtrQueueSet(notify_when_complete),
    72   PtrQueueSet(notify_when_complete),
    73   _closure(NULL),
    73   _mut_process_closure(NULL),
    74   _shared_dirty_card_queue(this, true /*perm*/),
    74   _shared_dirty_card_queue(this, true /*perm*/),
    75   _free_ids(NULL),
    75   _free_ids(NULL),
    76   _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
    76   _processed_buffers_mut(0), _processed_buffers_rs_thread(0)
    77 {
    77 {
    78   _all_active = true;
    78   _all_active = true;
    81 // Determines how many mutator threads can process the buffers in parallel.
    81 // Determines how many mutator threads can process the buffers in parallel.
    82 uint DirtyCardQueueSet::num_par_ids() {
    82 uint DirtyCardQueueSet::num_par_ids() {
    83   return (uint)os::processor_count();
    83   return (uint)os::processor_count();
    84 }
    84 }
    85 
    85 
    86 void DirtyCardQueueSet::initialize(Monitor* cbl_mon, Mutex* fl_lock,
    86 void DirtyCardQueueSet::initialize(CardTableEntryClosure* cl, Monitor* cbl_mon, Mutex* fl_lock,
    87                                    int process_completed_threshold,
    87                                    int process_completed_threshold,
    88                                    int max_completed_queue,
    88                                    int max_completed_queue,
    89                                    Mutex* lock, PtrQueueSet* fl_owner) {
    89                                    Mutex* lock, PtrQueueSet* fl_owner) {
       
    90   _mut_process_closure = cl;
    90   PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
    91   PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold,
    91                           max_completed_queue, fl_owner);
    92                           max_completed_queue, fl_owner);
    92   set_buffer_size(G1UpdateBufferSize);
    93   set_buffer_size(G1UpdateBufferSize);
    93   _shared_dirty_card_queue.set_lock(lock);
    94   _shared_dirty_card_queue.set_lock(lock);
    94   _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
    95   _free_ids = new FreeIdSet((int) num_par_ids(), _cbl_mon);
    96 
    97 
    97 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
    98 void DirtyCardQueueSet::handle_zero_index_for_thread(JavaThread* t) {
    98   t->dirty_card_queue().handle_zero_index();
    99   t->dirty_card_queue().handle_zero_index();
    99 }
   100 }
   100 
   101 
   101 void DirtyCardQueueSet::set_closure(CardTableEntryClosure* closure) {
   102 void DirtyCardQueueSet::iterate_closure_all_threads(CardTableEntryClosure* cl,
   102   _closure = closure;
   103                                                     bool consume,
   103 }
       
   104 
       
   105 void DirtyCardQueueSet::iterate_closure_all_threads(bool consume,
       
   106                                                     uint worker_i) {
   104                                                     uint worker_i) {
   107   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   105   assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
   108   for(JavaThread* t = Threads::first(); t; t = t->next()) {
   106   for(JavaThread* t = Threads::first(); t; t = t->next()) {
   109     bool b = t->dirty_card_queue().apply_closure(_closure, consume);
   107     bool b = t->dirty_card_queue().apply_closure(cl, consume);
   110     guarantee(b, "Should not be interrupted.");
   108     guarantee(b, "Should not be interrupted.");
   111   }
   109   }
   112   bool b = shared_dirty_card_queue()->apply_closure(_closure,
   110   bool b = shared_dirty_card_queue()->apply_closure(cl,
   113                                                     consume,
   111                                                     consume,
   114                                                     worker_i);
   112                                                     worker_i);
   115   guarantee(b, "Should not be interrupted.");
   113   guarantee(b, "Should not be interrupted.");
   116 }
   114 }
   117 
   115 
   141     thread->set_claimed_par_id(worker_i);
   139     thread->set_claimed_par_id(worker_i);
   142   }
   140   }
   143 
   141 
   144   bool b = false;
   142   bool b = false;
   145   if (worker_i != UINT_MAX) {
   143   if (worker_i != UINT_MAX) {
   146     b = DirtyCardQueue::apply_closure_to_buffer(_closure, buf, 0,
   144     b = DirtyCardQueue::apply_closure_to_buffer(_mut_process_closure, buf, 0,
   147                                                 _sz, true, worker_i);
   145                                                 _sz, true, worker_i);
   148     if (b) Atomic::inc(&_processed_buffers_mut);
   146     if (b) Atomic::inc(&_processed_buffers_mut);
   149 
   147 
   150     // If we had not claimed an id before entering the method
   148     // If we had not claimed an id before entering the method
   151     // then we must release the id.
   149     // then we must release the id.
   216   bool res = apply_closure_to_completed_buffer_helper(cl, worker_i, nd);
   214   bool res = apply_closure_to_completed_buffer_helper(cl, worker_i, nd);
   217   if (res) Atomic::inc(&_processed_buffers_rs_thread);
   215   if (res) Atomic::inc(&_processed_buffers_rs_thread);
   218   return res;
   216   return res;
   219 }
   217 }
   220 
   218 
   221 bool DirtyCardQueueSet::apply_closure_to_completed_buffer(uint worker_i,
   219 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) {
   222                                                           int stop_at,
       
   223                                                           bool during_pause) {
       
   224   return apply_closure_to_completed_buffer(_closure, worker_i,
       
   225                                            stop_at, during_pause);
       
   226 }
       
   227 
       
   228 void DirtyCardQueueSet::apply_closure_to_all_completed_buffers() {
       
   229   BufferNode* nd = _completed_buffers_head;
   220   BufferNode* nd = _completed_buffers_head;
   230   while (nd != NULL) {
   221   while (nd != NULL) {
   231     bool b =
   222     bool b =
   232       DirtyCardQueue::apply_closure_to_buffer(_closure,
   223       DirtyCardQueue::apply_closure_to_buffer(cl,
   233                                               BufferNode::make_buffer_from_node(nd),
   224                                               BufferNode::make_buffer_from_node(nd),
   234                                               0, _sz, false);
   225                                               0, _sz, false);
   235     guarantee(b, "Should not stop early.");
   226     guarantee(b, "Should not stop early.");
   236     nd = nd->next();
   227     nd = nd->next();
       
   228   }
       
   229 }
       
   230 
       
   231 void DirtyCardQueueSet::par_apply_closure_to_all_completed_buffers(CardTableEntryClosure* cl) {
       
   232   BufferNode* nd = _cur_par_buffer_node;
       
   233   while (nd != NULL) {
       
   234     BufferNode* next = (BufferNode*)nd->next();
       
   235     BufferNode* actual = (BufferNode*)Atomic::cmpxchg_ptr((void*)next, (volatile void*)&_cur_par_buffer_node, (void*)nd);
       
   236     if (actual == nd) {
       
   237       bool b =
       
   238         DirtyCardQueue::apply_closure_to_buffer(cl,
       
   239                                                 BufferNode::make_buffer_from_node(actual),
       
   240                                                 0, _sz, false);
       
   241       guarantee(b, "Should not stop early.");
       
   242       nd = next;
       
   243     } else {
       
   244       nd = actual;
       
   245     }
   237   }
   246   }
   238 }
   247 }
   239 
   248 
   240 // Deallocates any completed log buffers
   249 // Deallocates any completed log buffers
   241 void DirtyCardQueueSet::clear() {
   250 void DirtyCardQueueSet::clear() {