< prev index next >

src/hotspot/share/gc/z/zMark.cpp

Print this page

 91 }
 92 
 93 size_t ZMark::calculate_nstripes(uint nworkers) const {
 94   // Calculate the number of stripes from the number of workers we use,
 95   // where the number of stripes must be a power of two and we want to
 96   // have at least one worker per stripe.
 97   const size_t nstripes = round_down_power_of_2(nworkers);
 98   return MIN2(nstripes, ZMarkStripesMax);
 99 }
100 
101 void ZMark::start() {
102   // Verification
103   if (ZVerifyMarking) {
104     verify_all_stacks_empty();
105   }
106 
107   // Increment global sequence number to invalidate
108   // marking information for all pages.
109   ZGlobalSeqNum++;
110 


111   // Reset flush/continue counters
112   _nproactiveflush = 0;
113   _nterminateflush = 0;
114   _ntrycomplete = 0;
115   _ncontinue = 0;
116 
117   // Set number of workers to use
118   _nworkers = _workers->active_workers();
119 
120   // Set number of mark stripes to use, based on number
121   // of workers we will use in the concurrent mark phase.
122   const size_t nstripes = calculate_nstripes(_nworkers);
123   _stripes.set_nstripes(nstripes);
124 
125   // Update statistics
126   ZStatMark::set_at_mark_start(nstripes);
127 
128   // Print worker/stripe distribution
129   LogTarget(Debug, gc, marking) log;
130   if (log.is_enabled()) {

238 }
239 
240 template <bool finalizable>
241 class ZMarkBarrierOopClosure : public ClaimMetadataVisitingOopIterateClosure {
242 public:
243   ZMarkBarrierOopClosure() :
244       ClaimMetadataVisitingOopIterateClosure(finalizable
245                                                  ? ClassLoaderData::_claim_finalizable
246                                                  : ClassLoaderData::_claim_strong,
247                                              finalizable
248                                                  ? NULL
249                                                  : ZHeap::heap()->reference_discoverer()) {}
250 
251   virtual void do_oop(oop* p) {
252     ZBarrier::mark_barrier_on_oop_field(p, finalizable);
253   }
254 
255   virtual void do_oop(narrowOop* p) {
256     ShouldNotReachHere();
257   }




258 };
259 
260 void ZMark::follow_array_object(objArrayOop obj, bool finalizable) {
261   if (finalizable) {
262     ZMarkBarrierOopClosure<true /* finalizable */> cl;
263     cl.do_klass(obj->klass());
264   } else {
265     ZMarkBarrierOopClosure<false /* finalizable */> cl;
266     cl.do_klass(obj->klass());
267   }
268 
269   const uintptr_t addr = (uintptr_t)obj->base();
270   const size_t size = (size_t)obj->length() * oopSize;
271 
272   follow_array(addr, size, finalizable);
273 }
274 
275 void ZMark::follow_object(oop obj, bool finalizable) {
276   if (finalizable) {
277     ZMarkBarrierOopClosure<true /* finalizable */> cl;

662     ZThreadLocalAllocBuffer::update_stats(jt);
663   }
664 };
665 
666 class ZMarkNMethodClosure : public NMethodClosure {
667 private:
668   OopClosure* const _cl;
669 
670 public:
671   ZMarkNMethodClosure(OopClosure* cl) :
672       _cl(cl) {}
673 
674   virtual void do_nmethod(nmethod* nm) {
675     ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
676     if (!nm->is_alive()) {
677       return;
678     }
679 
680     if (ZNMethod::is_armed(nm)) {
681       ZNMethod::nmethod_oops_do_inner(nm, _cl);

682       ZNMethod::disarm(nm);
683     }
684   }
685 };
686 
687 typedef ClaimingCLDToOopClosure<ClassLoaderData::_claim_strong> ZMarkCLDClosure;
688 
689 class ZMarkRootsTask : public ZTask {
690 private:
691   ZMark* const               _mark;
692   SuspendibleThreadSetJoiner _sts_joiner;
693   ZRootsIterator             _roots;
694 
695   ZMarkOopClosure            _cl;
696   ZMarkCLDClosure            _cld_cl;
697   ZMarkThreadClosure         _thread_cl;
698   ZMarkNMethodClosure        _nm_cl;
699 
700 public:
701   ZMarkRootsTask(ZMark* mark) :

783   // amount of mark work in this phase.
784   return try_complete();
785 }
786 
787 bool ZMark::end() {
788   // Try end marking
789   if (!try_end()) {
790     // Mark not completed
791     _ncontinue++;
792     return false;
793   }
794 
795   // Verification
796   if (ZVerifyMarking) {
797     verify_all_stacks_empty();
798   }
799 
800   // Update statistics
801   ZStatMark::set_at_mark_end(_nproactiveflush, _nterminateflush, _ntrycomplete, _ncontinue);
802 


803   // Mark completed
804   return true;
805 }
806 
807 void ZMark::free() {
808   // Free any unused mark stack space
809   _allocator.free();
810 
811   // Update statistics
812   ZStatMark::set_at_mark_free(_allocator.size());
813 }
814 
815 void ZMark::flush_and_free() {
816   Thread* const thread = Thread::current();
817   flush_and_free(thread);
818 }
819 
820 bool ZMark::flush_and_free(Thread* thread) {
821   ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(thread);
822   const bool flushed = stacks->flush(&_allocator, &_stripes);

 91 }
 92 
 93 size_t ZMark::calculate_nstripes(uint nworkers) const {
 94   // Calculate the number of stripes from the number of workers we use,
 95   // where the number of stripes must be a power of two and we want to
 96   // have at least one worker per stripe.
 97   const size_t nstripes = round_down_power_of_2(nworkers);
 98   return MIN2(nstripes, ZMarkStripesMax);
 99 }
100 
101 void ZMark::start() {
102   // Verification
103   if (ZVerifyMarking) {
104     verify_all_stacks_empty();
105   }
106 
107   // Increment global sequence number to invalidate
108   // marking information for all pages.
109   ZGlobalSeqNum++;
110 
111   CodeCache::increment_marking_cycle();
112 
113   // Reset flush/continue counters
114   _nproactiveflush = 0;
115   _nterminateflush = 0;
116   _ntrycomplete = 0;
117   _ncontinue = 0;
118 
119   // Set number of workers to use
120   _nworkers = _workers->active_workers();
121 
122   // Set number of mark stripes to use, based on number
123   // of workers we will use in the concurrent mark phase.
124   const size_t nstripes = calculate_nstripes(_nworkers);
125   _stripes.set_nstripes(nstripes);
126 
127   // Update statistics
128   ZStatMark::set_at_mark_start(nstripes);
129 
130   // Print worker/stripe distribution
131   LogTarget(Debug, gc, marking) log;
132   if (log.is_enabled()) {

240 }
241 
242 template <bool finalizable>
243 class ZMarkBarrierOopClosure : public ClaimMetadataVisitingOopIterateClosure {
244 public:
245   ZMarkBarrierOopClosure() :
246       ClaimMetadataVisitingOopIterateClosure(finalizable
247                                                  ? ClassLoaderData::_claim_finalizable
248                                                  : ClassLoaderData::_claim_strong,
249                                              finalizable
250                                                  ? NULL
251                                                  : ZHeap::heap()->reference_discoverer()) {}
252 
253   virtual void do_oop(oop* p) {
254     ZBarrier::mark_barrier_on_oop_field(p, finalizable);
255   }
256 
257   virtual void do_oop(narrowOop* p) {
258     ShouldNotReachHere();
259   }
260 
261   virtual void do_nmethod(nmethod* nm) {
262     nm->run_nmethod_entry_barrier();
263   }
264 };
265 
266 void ZMark::follow_array_object(objArrayOop obj, bool finalizable) {
267   if (finalizable) {
268     ZMarkBarrierOopClosure<true /* finalizable */> cl;
269     cl.do_klass(obj->klass());
270   } else {
271     ZMarkBarrierOopClosure<false /* finalizable */> cl;
272     cl.do_klass(obj->klass());
273   }
274 
275   const uintptr_t addr = (uintptr_t)obj->base();
276   const size_t size = (size_t)obj->length() * oopSize;
277 
278   follow_array(addr, size, finalizable);
279 }
280 
281 void ZMark::follow_object(oop obj, bool finalizable) {
282   if (finalizable) {
283     ZMarkBarrierOopClosure<true /* finalizable */> cl;

668     ZThreadLocalAllocBuffer::update_stats(jt);
669   }
670 };
671 
672 class ZMarkNMethodClosure : public NMethodClosure {
673 private:
674   OopClosure* const _cl;
675 
676 public:
677   ZMarkNMethodClosure(OopClosure* cl) :
678       _cl(cl) {}
679 
680   virtual void do_nmethod(nmethod* nm) {
681     ZLocker<ZReentrantLock> locker(ZNMethod::lock_for_nmethod(nm));
682     if (!nm->is_alive()) {
683       return;
684     }
685 
686     if (ZNMethod::is_armed(nm)) {
687       ZNMethod::nmethod_oops_do_inner(nm, _cl);
688       nm->mark_as_maybe_on_continuation();
689       ZNMethod::disarm(nm);
690     }
691   }
692 };
693 
694 typedef ClaimingCLDToOopClosure<ClassLoaderData::_claim_strong> ZMarkCLDClosure;
695 
696 class ZMarkRootsTask : public ZTask {
697 private:
698   ZMark* const               _mark;
699   SuspendibleThreadSetJoiner _sts_joiner;
700   ZRootsIterator             _roots;
701 
702   ZMarkOopClosure            _cl;
703   ZMarkCLDClosure            _cld_cl;
704   ZMarkThreadClosure         _thread_cl;
705   ZMarkNMethodClosure        _nm_cl;
706 
707 public:
708   ZMarkRootsTask(ZMark* mark) :

790   // amount of mark work in this phase.
791   return try_complete();
792 }
793 
794 bool ZMark::end() {
795   // Try end marking
796   if (!try_end()) {
797     // Mark not completed
798     _ncontinue++;
799     return false;
800   }
801 
802   // Verification
803   if (ZVerifyMarking) {
804     verify_all_stacks_empty();
805   }
806 
807   // Update statistics
808   ZStatMark::set_at_mark_end(_nproactiveflush, _nterminateflush, _ntrycomplete, _ncontinue);
809 
810   CodeCache::increment_marking_cycle();
811 
812   // Mark completed
813   return true;
814 }
815 
816 void ZMark::free() {
817   // Free any unused mark stack space
818   _allocator.free();
819 
820   // Update statistics
821   ZStatMark::set_at_mark_free(_allocator.size());
822 }
823 
824 void ZMark::flush_and_free() {
825   Thread* const thread = Thread::current();
826   flush_and_free(thread);
827 }
828 
829 bool ZMark::flush_and_free(Thread* thread) {
830   ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(thread);
831   const bool flushed = stacks->flush(&_allocator, &_stripes);
< prev index next >