564 }
565
566 void ZMark::work(uint64_t timeout_in_millis) {
567 ZMarkCache cache(_stripes.nstripes());
568 ZMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, ZThread::worker_id());
569 ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
570
571 if (timeout_in_millis == 0) {
572 work_without_timeout(&cache, stripe, stacks);
573 } else {
574 work_with_timeout(&cache, stripe, stacks, timeout_in_millis);
575 }
576
577 // Make sure stacks have been flushed
578 assert(stacks->is_empty(&_stripes), "Should be empty");
579
580 // Free remaining stacks
581 stacks->free(&_allocator);
582 }
583
584 class ZMarkTask : public ZTask {
585 private:
586 ZMark* const _mark;
587 const uint64_t _timeout_in_millis;
588
589 public:
590 ZMarkTask(ZMark* mark, uint64_t timeout_in_millis = 0) :
591 ZTask("ZMarkTask"),
592 _mark(mark),
593 _timeout_in_millis(timeout_in_millis) {
594 _mark->prepare_work();
595 }
596
597 ~ZMarkTask() {
598 _mark->finish_work();
599 }
600
601 virtual void work() {
602 _mark->work(_timeout_in_millis);
603 }
604 };
605
606 void ZMark::mark() {
607 ZMarkTask task(this);
608 _workers->run_concurrent(&task);
609 }
610
611 bool ZMark::try_complete() {
612 _ntrycomplete++;
613
614 // Use nconcurrent number of worker threads to maintain the
615 // worker/stripe distribution used during concurrent mark.
616 ZMarkTask task(this, ZMarkCompleteTimeout);
617 _workers->run_concurrent(&task);
618
619 // Successful if all stripes are empty
620 return _stripes.is_empty();
621 }
622
623 bool ZMark::try_end() {
624 // Flush all mark stacks
625 if (!flush(true /* at_safepoint */)) {
|
564 }
565
566 void ZMark::work(uint64_t timeout_in_millis) {
567 ZMarkCache cache(_stripes.nstripes());
568 ZMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, ZThread::worker_id());
569 ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
570
571 if (timeout_in_millis == 0) {
572 work_without_timeout(&cache, stripe, stacks);
573 } else {
574 work_with_timeout(&cache, stripe, stacks, timeout_in_millis);
575 }
576
577 // Make sure stacks have been flushed
578 assert(stacks->is_empty(&_stripes), "Should be empty");
579
580 // Free remaining stacks
581 stacks->free(&_allocator);
582 }
583
584 class ZMarkConcurrentRootsTask : public ZTask {
585 private:
586 ZMark* const _mark;
587 ZConcurrentRootsIterator _roots;
588
589 public:
590 ZMarkConcurrentRootsTask(ZMark* mark) :
591 ZTask("ZMarkConcurrentRootsTask"),
592 _mark(mark),
593 _roots() {}
594
595 virtual void work() {
596 ZMarkBarrierOopClosure<false /* finalizable */> cl;
597 _roots.oops_do(&cl);
598 }
599 };
600
601 class ZMarkTask : public ZTask {
602 private:
603 ZMark* const _mark;
604 const uint64_t _timeout_in_millis;
605
606 public:
607 ZMarkTask(ZMark* mark, uint64_t timeout_in_millis = 0) :
608 ZTask("ZMarkTask"),
609 _mark(mark),
610 _timeout_in_millis(timeout_in_millis) {
611 _mark->prepare_work();
612 }
613
614 ~ZMarkTask() {
615 _mark->finish_work();
616 }
617
618 virtual void work() {
619 _mark->work(_timeout_in_millis);
620 }
621 };
622
623 void ZMark::mark(bool initial) {
624 if (initial) {
625 ZMarkConcurrentRootsTask task(this);
626 _workers->run_concurrent(&task);
627 }
628
629 ZMarkTask task(this);
630 _workers->run_concurrent(&task);
631 }
632
633 bool ZMark::try_complete() {
634 _ntrycomplete++;
635
636 // Use nconcurrent number of worker threads to maintain the
637 // worker/stripe distribution used during concurrent mark.
638 ZMarkTask task(this, ZMarkCompleteTimeout);
639 _workers->run_concurrent(&task);
640
641 // Successful if all stripes are empty
642 return _stripes.is_empty();
643 }
644
645 bool ZMark::try_end() {
646 // Flush all mark stacks
647 if (!flush(true /* at_safepoint */)) {
|