/*
 * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "precompiled.hpp"
#include "classfile/classLoaderData.hpp"
#include "classfile/classLoaderDataGraph.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "code/nmethod.hpp"
#include "gc/shared/continuationGCSupport.inline.hpp"
#include "gc/shared/gc_globals.hpp"
#include "gc/shared/stringdedup/stringDedup.hpp"
#include "gc/shared/suspendibleThreadSet.hpp"
#include "gc/x/xAbort.inline.hpp"
#include "gc/x/xBarrier.inline.hpp"
#include "gc/x/xHeap.inline.hpp"
#include "gc/x/xLock.inline.hpp"
#include "gc/x/xMark.inline.hpp"
#include "gc/x/xMarkCache.inline.hpp"
#include "gc/x/xMarkContext.inline.hpp"
#include "gc/x/xMarkStack.inline.hpp"
#include "gc/x/xMarkTerminate.inline.hpp"
#include "gc/x/xNMethod.hpp"
#include "gc/x/xOop.inline.hpp"
#include "gc/x/xPage.hpp"
#include "gc/x/xPageTable.inline.hpp"
#include "gc/x/xRootsIterator.hpp"
#include "gc/x/xStackWatermark.hpp"
#include "gc/x/xStat.hpp"
#include "gc/x/xTask.hpp"
#include "gc/x/xThread.inline.hpp"
#include "gc/x/xThreadLocalAllocBuffer.hpp"
#include "gc/x/xUtils.inline.hpp"
#include "gc/x/xWorkers.hpp"
#include "logging/log.hpp"
#include "memory/iterator.inline.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/continuation.hpp"
#include "runtime/handshake.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/prefetch.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/stackWatermark.hpp"
#include "runtime/stackWatermarkSet.inline.hpp"
#include "runtime/threads.hpp"
#include "utilities/align.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/powerOfTwo.hpp"
#include "utilities/ticks.hpp"

static const XStatSubPhase XSubPhaseConcurrentMark("Concurrent Mark");
static const XStatSubPhase XSubPhaseConcurrentMarkTryFlush("Concurrent Mark Try Flush");
static const XStatSubPhase XSubPhaseConcurrentMarkTryTerminate("Concurrent Mark Try Terminate");
static const XStatSubPhase XSubPhaseMarkTryComplete("Pause Mark Try Complete");

XMark::XMark(XWorkers* workers, XPageTable* page_table) :
    _workers(workers),
    _page_table(page_table),
    _allocator(),
    _stripes(),
    _terminate(),
    _work_terminateflush(true),
    _work_nproactiveflush(0),
    _work_nterminateflush(0),
    _nproactiveflush(0),
    _nterminateflush(0),
    _ntrycomplete(0),
    _ncontinue(0),
    _nworkers(0) {}

bool XMark::is_initialized() const {
  return _allocator.is_initialized();
}

size_t XMark::calculate_nstripes(uint nworkers) const {
  // Calculate the number of stripes from the number of workers we use,
  // where the number of stripes must be a power of two and we want to
  // have at least one worker per stripe.
  const size_t nstripes = round_down_power_of_2(nworkers);
  return MIN2(nstripes, XMarkStripesMax);
}

void XMark::start() {
  // Verification
  if (ZVerifyMarking) {
    verify_all_stacks_empty();
  }

  // Increment global sequence number to invalidate
  // marking information for all pages.
  XGlobalSeqNum++;

  // Note that we start a marking cycle.
  // Unlike other GCs, the color switch implicitly changes the nmethods
  // to be armed, and the thread-local disarm values are lazily updated
  // when JavaThreads wake up from safepoints.
  CodeCache::on_gc_marking_cycle_start();

  // Reset flush/continue counters
  _nproactiveflush = 0;
  _nterminateflush = 0;
  _ntrycomplete = 0;
  _ncontinue = 0;

  // Set number of workers to use
  _nworkers = _workers->active_workers();

  // Set number of mark stripes to use, based on number
  // of workers we will use in the concurrent mark phase.
  const size_t nstripes = calculate_nstripes(_nworkers);
  _stripes.set_nstripes(nstripes);

  // Update statistics
  XStatMark::set_at_mark_start(nstripes);

  // Print worker/stripe distribution
  LogTarget(Debug, gc, marking) log;
  if (log.is_enabled()) {
    log.print("Mark Worker/Stripe Distribution");
    for (uint worker_id = 0; worker_id < _nworkers; worker_id++) {
      const XMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, worker_id);
      const size_t stripe_id = _stripes.stripe_id(stripe);
      log.print("  Worker %u(%u) -> Stripe " SIZE_FORMAT "(" SIZE_FORMAT ")",
                worker_id, _nworkers, stripe_id, nstripes);
    }
  }
}

void XMark::prepare_work() {
  assert(_nworkers == _workers->active_workers(), "Invalid number of workers");

  // Set number of active workers
  _terminate.reset(_nworkers);

  // Reset flush counters
  _work_nproactiveflush = _work_nterminateflush = 0;
  _work_terminateflush = true;
}

void XMark::finish_work() {
  // Accumulate proactive/terminate flush counters
  _nproactiveflush += _work_nproactiveflush;
  _nterminateflush += _work_nterminateflush;
}

bool XMark::is_array(uintptr_t addr) const {
  return XOop::from_address(addr)->is_objArray();
}

void XMark::push_partial_array(uintptr_t addr, size_t size, bool finalizable) {
  assert(is_aligned(addr, XMarkPartialArrayMinSize), "Address misaligned");
  XMarkThreadLocalStacks* const stacks = XThreadLocalData::stacks(Thread::current());
  XMarkStripe* const stripe = _stripes.stripe_for_addr(addr);
  const uintptr_t offset = XAddress::offset(addr) >> XMarkPartialArrayMinSizeShift;
  const uintptr_t length = size / oopSize;
  const XMarkStackEntry entry(offset, length, finalizable);

  log_develop_trace(gc, marking)("Array push partial: " PTR_FORMAT " (" SIZE_FORMAT "), stripe: " SIZE_FORMAT,
                                 addr, size, _stripes.stripe_id(stripe));

  stacks->push(&_allocator, &_stripes, stripe, entry, false /* publish */);
}

void XMark::follow_small_array(uintptr_t addr, size_t size, bool finalizable) {
  assert(size <= XMarkPartialArrayMinSize, "Too large, should be split");
  const size_t length = size / oopSize;

  log_develop_trace(gc, marking)("Array follow small: " PTR_FORMAT " (" SIZE_FORMAT ")", addr, size);

  XBarrier::mark_barrier_on_oop_array((oop*)addr, length, finalizable);
}

void XMark::follow_large_array(uintptr_t addr, size_t size, bool finalizable) {
  assert(size <= (size_t)arrayOopDesc::max_array_length(T_OBJECT) * oopSize, "Too large");
  assert(size > XMarkPartialArrayMinSize, "Too small, should not be split");
  const uintptr_t start = addr;
  const uintptr_t end = start + size;

  // Calculate the aligned middle start/end/size, where the middle start
  // should always be greater than the start (hence the +1 below) to make
  // sure we always do some follow work, not just split the array into pieces.
  const uintptr_t middle_start = align_up(start + 1, XMarkPartialArrayMinSize);
  const size_t    middle_size = align_down(end - middle_start, XMarkPartialArrayMinSize);
  const uintptr_t middle_end = middle_start + middle_size;

  log_develop_trace(gc, marking)("Array follow large: " PTR_FORMAT "-" PTR_FORMAT" (" SIZE_FORMAT "), "
                                 "middle: " PTR_FORMAT "-" PTR_FORMAT " (" SIZE_FORMAT ")",
                                 start, end, size, middle_start, middle_end, middle_size);

  // Push unaligned trailing part
  if (end > middle_end) {
    const uintptr_t trailing_addr = middle_end;
    const size_t trailing_size = end - middle_end;
    push_partial_array(trailing_addr, trailing_size, finalizable);
  }

  // Push aligned middle part(s)
  uintptr_t partial_addr = middle_end;
  while (partial_addr > middle_start) {
    const size_t parts = 2;
    const size_t partial_size = align_up((partial_addr - middle_start) / parts, XMarkPartialArrayMinSize);
    partial_addr -= partial_size;
    push_partial_array(partial_addr, partial_size, finalizable);
  }

  // Follow leading part
  assert(start < middle_start, "Miscalculated middle start");
  const uintptr_t leading_addr = start;
  const size_t leading_size = middle_start - start;
  follow_small_array(leading_addr, leading_size, finalizable);
}

void XMark::follow_array(uintptr_t addr, size_t size, bool finalizable) {
  if (size <= XMarkPartialArrayMinSize) {
    follow_small_array(addr, size, finalizable);
  } else {
    follow_large_array(addr, size, finalizable);
  }
}

void XMark::follow_partial_array(XMarkStackEntry entry, bool finalizable) {
  const uintptr_t addr = XAddress::good(entry.partial_array_offset() << XMarkPartialArrayMinSizeShift);
  const size_t size = entry.partial_array_length() * oopSize;

  follow_array(addr, size, finalizable);
}

template <bool finalizable>
class XMarkBarrierOopClosure : public ClaimMetadataVisitingOopIterateClosure {
public:
  XMarkBarrierOopClosure() :
      ClaimMetadataVisitingOopIterateClosure(finalizable
                                                 ? ClassLoaderData::_claim_finalizable
                                                 : ClassLoaderData::_claim_strong,
                                             finalizable
                                                 ? nullptr
                                                 : XHeap::heap()->reference_discoverer()) {}

  virtual void do_oop(oop* p) {
    XBarrier::mark_barrier_on_oop_field(p, finalizable);
  }

  virtual void do_oop(narrowOop* p) {
    ShouldNotReachHere();
  }

  virtual void do_nmethod(nmethod* nm) {
    assert(!finalizable, "Can't handle finalizable marking of nmethods");
    nm->run_nmethod_entry_barrier();
  }
};

void XMark::follow_array_object(objArrayOop obj, bool finalizable) {
  if (finalizable) {
    XMarkBarrierOopClosure<true /* finalizable */> cl;
    cl.do_klass(obj->klass());
  } else {
    XMarkBarrierOopClosure<false /* finalizable */> cl;
    cl.do_klass(obj->klass());
  }

  const uintptr_t addr = (uintptr_t)obj->base();
  const size_t size = (size_t)obj->length() * oopSize;

  follow_array(addr, size, finalizable);
}

void XMark::follow_object(oop obj, bool finalizable) {
  if (ContinuationGCSupport::relativize_stack_chunk(obj)) {
    // Loom doesn't support mixing of finalizable marking and strong marking of
    // stack chunks. See: RelativizeDerivedOopClosure.
    XMarkBarrierOopClosure<false /* finalizable */> cl;
    obj->oop_iterate(&cl);
    return;
  }

  if (finalizable) {
    XMarkBarrierOopClosure<true /* finalizable */> cl;
    obj->oop_iterate(&cl);
  } else {
    XMarkBarrierOopClosure<false /* finalizable */> cl;
    obj->oop_iterate(&cl);
  }
}

static void try_deduplicate(XMarkContext* context, oop obj) {
  if (!StringDedup::is_enabled()) {
    // Not enabled
    return;
  }

  if (!java_lang_String::is_instance(obj)) {
    // Not a String object
    return;
  }

  if (java_lang_String::test_and_set_deduplication_requested(obj)) {
    // Already requested deduplication
    return;
  }

  // Request deduplication
  context->string_dedup_requests()->add(obj);
}

void XMark::mark_and_follow(XMarkContext* context, XMarkStackEntry entry) {
  // Decode flags
  const bool finalizable = entry.finalizable();
  const bool partial_array = entry.partial_array();

  if (partial_array) {
    follow_partial_array(entry, finalizable);
    return;
  }

  // Decode object address and additional flags
  const uintptr_t addr = entry.object_address();
  const bool mark = entry.mark();
  bool inc_live = entry.inc_live();
  const bool follow = entry.follow();

  XPage* const page = _page_table->get(addr);
  assert(page->is_relocatable(), "Invalid page state");

  // Mark
  if (mark && !page->mark_object(addr, finalizable, inc_live)) {
    // Already marked
    return;
  }

  // Increment live
  if (inc_live) {
    // Update live objects/bytes for page. We use the aligned object
    // size since that is the actual number of bytes used on the page
    // and alignment paddings can never be reclaimed.
    const size_t size = XUtils::object_size(addr);
    const size_t aligned_size = align_up(size, page->object_alignment());
    context->cache()->inc_live(page, aligned_size);
  }

  // Follow
  if (follow) {
    if (is_array(addr)) {
      follow_array_object(objArrayOop(XOop::from_address(addr)), finalizable);
    } else {
      const oop obj = XOop::from_address(addr);
      follow_object(obj, finalizable);

      // Try deduplicate
      try_deduplicate(context, obj);
    }
  }
}

template <typename T>
bool XMark::drain(XMarkContext* context, T* timeout) {
  XMarkStripe* const stripe = context->stripe();
  XMarkThreadLocalStacks* const stacks = context->stacks();
  XMarkStackEntry entry;

  // Drain stripe stacks
  while (stacks->pop(&_allocator, &_stripes, stripe, entry)) {
    mark_and_follow(context, entry);

    // Check timeout
    if (timeout->has_expired()) {
      // Timeout
      return false;
    }
  }

  // Success
  return !timeout->has_expired();
}

bool XMark::try_steal_local(XMarkContext* context) {
  XMarkStripe* const stripe = context->stripe();
  XMarkThreadLocalStacks* const stacks = context->stacks();

  // Try to steal a local stack from another stripe
  for (XMarkStripe* victim_stripe = _stripes.stripe_next(stripe);
       victim_stripe != stripe;
       victim_stripe = _stripes.stripe_next(victim_stripe)) {
    XMarkStack* const stack = stacks->steal(&_stripes, victim_stripe);
    if (stack != nullptr) {
      // Success, install the stolen stack
      stacks->install(&_stripes, stripe, stack);
      return true;
    }
  }

  // Nothing to steal
  return false;
}

bool XMark::try_steal_global(XMarkContext* context) {
  XMarkStripe* const stripe = context->stripe();
  XMarkThreadLocalStacks* const stacks = context->stacks();

  // Try to steal a stack from another stripe
  for (XMarkStripe* victim_stripe = _stripes.stripe_next(stripe);
       victim_stripe != stripe;
       victim_stripe = _stripes.stripe_next(victim_stripe)) {
    XMarkStack* const stack = victim_stripe->steal_stack();
    if (stack != nullptr) {
      // Success, install the stolen stack
      stacks->install(&_stripes, stripe, stack);
      return true;
    }
  }

  // Nothing to steal
  return false;
}

bool XMark::try_steal(XMarkContext* context) {
  return try_steal_local(context) || try_steal_global(context);
}

void XMark::idle() const {
  os::naked_short_sleep(1);
}

class XMarkFlushAndFreeStacksClosure : public HandshakeClosure {
private:
  XMark* const _mark;
  bool         _flushed;

public:
  XMarkFlushAndFreeStacksClosure(XMark* mark) :
      HandshakeClosure("XMarkFlushAndFreeStacks"),
      _mark(mark),
      _flushed(false) {}

  void do_thread(Thread* thread) {
    if (_mark->flush_and_free(thread)) {
      _flushed = true;
    }
  }

  bool flushed() const {
    return _flushed;
  }
};

bool XMark::flush(bool at_safepoint) {
  XMarkFlushAndFreeStacksClosure cl(this);
  if (at_safepoint) {
    Threads::threads_do(&cl);
  } else {
    Handshake::execute(&cl);
  }

  // Returns true if more work is available
  return cl.flushed() || !_stripes.is_empty();
}

bool XMark::try_flush(volatile size_t* nflush) {
  Atomic::inc(nflush);

  XStatTimer timer(XSubPhaseConcurrentMarkTryFlush);
  return flush(false /* at_safepoint */);
}

bool XMark::try_proactive_flush() {
  // Only do proactive flushes from worker 0
  if (XThread::worker_id() != 0) {
    return false;
  }

  if (Atomic::load(&_work_nproactiveflush) == XMarkProactiveFlushMax ||
      Atomic::load(&_work_nterminateflush) != 0) {
    // Limit reached or we're trying to terminate
    return false;
  }

  return try_flush(&_work_nproactiveflush);
}

bool XMark::try_terminate() {
  XStatTimer timer(XSubPhaseConcurrentMarkTryTerminate);

  if (_terminate.enter_stage0()) {
    // Last thread entered stage 0, flush
    if (Atomic::load(&_work_terminateflush) &&
        Atomic::load(&_work_nterminateflush) != XMarkTerminateFlushMax) {
      // Exit stage 0 to allow other threads to continue marking
      _terminate.exit_stage0();

      // Flush before termination
      if (!try_flush(&_work_nterminateflush)) {
        // No more work available, skip further flush attempts
        Atomic::store(&_work_terminateflush, false);
      }

      // Don't terminate, regardless of whether we successfully
      // flushed out more work or not. We've already exited
      // termination stage 0, to allow other threads to continue
      // marking, so this thread has to return false and also
      // make another round of attempted marking.
      return false;
    }
  }

  for (;;) {
    if (_terminate.enter_stage1()) {
      // Last thread entered stage 1, terminate
      return true;
    }

    // Idle to give the other threads
    // a chance to enter termination.
    idle();

    if (!_terminate.try_exit_stage1()) {
      // All workers in stage 1, terminate
      return true;
    }

    if (_terminate.try_exit_stage0()) {
      // More work available, don't terminate
      return false;
    }
  }
}

class XMarkNoTimeout : public StackObj {
public:
  bool has_expired() {
    // No timeout, but check for signal to abort
    return XAbort::should_abort();
  }
};

void XMark::work_without_timeout(XMarkContext* context) {
  XStatTimer timer(XSubPhaseConcurrentMark);
  XMarkNoTimeout no_timeout;

  for (;;) {
    if (!drain(context, &no_timeout)) {
      // Abort
      break;
    }

    if (try_steal(context)) {
      // Stole work
      continue;
    }

    if (try_proactive_flush()) {
      // Work available
      continue;
    }

    if (try_terminate()) {
      // Terminate
      break;
    }
  }
}

class XMarkTimeout : public StackObj {
private:
  const Ticks    _start;
  const uint64_t _timeout;
  const uint64_t _check_interval;
  uint64_t       _check_at;
  uint64_t       _check_count;
  bool           _expired;

public:
  XMarkTimeout(uint64_t timeout_in_micros) :
      _start(Ticks::now()),
      _timeout(_start.value() + TimeHelper::micros_to_counter(timeout_in_micros)),
      _check_interval(200),
      _check_at(_check_interval),
      _check_count(0),
      _expired(false) {}

  ~XMarkTimeout() {
    const Tickspan duration = Ticks::now() - _start;
    log_debug(gc, marking)("Mark With Timeout (%s): %s, " UINT64_FORMAT " oops, %.3fms",
                           XThread::name(), _expired ? "Expired" : "Completed",
                           _check_count, TimeHelper::counter_to_millis(duration.value()));
  }

  bool has_expired() {
    if (++_check_count == _check_at) {
      _check_at += _check_interval;
      if ((uint64_t)Ticks::now().value() >= _timeout) {
        // Timeout
        _expired = true;
      }
    }

    return _expired;
  }
};

void XMark::work_with_timeout(XMarkContext* context, uint64_t timeout_in_micros) {
  XStatTimer timer(XSubPhaseMarkTryComplete);
  XMarkTimeout timeout(timeout_in_micros);

  for (;;) {
    if (!drain(context, &timeout)) {
      // Timed out
      break;
    }

    if (try_steal(context)) {
      // Stole work
      continue;
    }

    // Terminate
    break;
  }
}

void XMark::work(uint64_t timeout_in_micros) {
  XMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, XThread::worker_id());
  XMarkThreadLocalStacks* const stacks = XThreadLocalData::stacks(Thread::current());
  XMarkContext context(_stripes.nstripes(), stripe, stacks);

  if (timeout_in_micros == 0) {
    work_without_timeout(&context);
  } else {
    work_with_timeout(&context, timeout_in_micros);
  }

  // Flush and publish stacks
  stacks->flush(&_allocator, &_stripes);

  // Free remaining stacks
  stacks->free(&_allocator);
}

class XMarkOopClosure : public OopClosure {
  virtual void do_oop(oop* p) {
    XBarrier::mark_barrier_on_oop_field(p, false /* finalizable */);
  }

  virtual void do_oop(narrowOop* p) {
    ShouldNotReachHere();
  }
};

class XMarkThreadClosure : public ThreadClosure {
private:
  OopClosure* const _cl;

public:
  XMarkThreadClosure(OopClosure* cl) :
      _cl(cl) {
    XThreadLocalAllocBuffer::reset_statistics();
  }
  ~XMarkThreadClosure() {
    XThreadLocalAllocBuffer::publish_statistics();
  }
  virtual void do_thread(Thread* thread) {
    JavaThread* const jt = JavaThread::cast(thread);
    StackWatermarkSet::finish_processing(jt, _cl, StackWatermarkKind::gc);
    XThreadLocalAllocBuffer::update_stats(jt);
  }
};

class XMarkNMethodClosure : public NMethodClosure {
private:
  OopClosure* const _cl;

public:
  XMarkNMethodClosure(OopClosure* cl) :
      _cl(cl) {}

  virtual void do_nmethod(nmethod* nm) {
    XLocker<XReentrantLock> locker(XNMethod::lock_for_nmethod(nm));
    if (XNMethod::is_armed(nm)) {
      XNMethod::nmethod_oops_do_inner(nm, _cl);

      // CodeCache unloading support
      nm->mark_as_maybe_on_stack();

      XNMethod::disarm(nm);
    }
  }
};

typedef ClaimingCLDToOopClosure<ClassLoaderData::_claim_strong> XMarkCLDClosure;

class XMarkRootsTask : public XTask {
private:
  XMark* const               _mark;
  SuspendibleThreadSetJoiner _sts_joiner;
  XRootsIterator             _roots;

  XMarkOopClosure            _cl;
  XMarkCLDClosure            _cld_cl;
  XMarkThreadClosure         _thread_cl;
  XMarkNMethodClosure        _nm_cl;

public:
  XMarkRootsTask(XMark* mark) :
      XTask("XMarkRootsTask"),
      _mark(mark),
      _sts_joiner(),
      _roots(ClassLoaderData::_claim_strong),
      _cl(),
      _cld_cl(&_cl),
      _thread_cl(&_cl),
      _nm_cl(&_cl) {
    ClassLoaderDataGraph_lock->lock();
  }

  ~XMarkRootsTask() {
    ClassLoaderDataGraph_lock->unlock();
  }

  virtual void work() {
    _roots.apply(&_cl,
                 &_cld_cl,
                 &_thread_cl,
                 &_nm_cl);

    // Flush and free worker stacks. Needed here since
    // the set of workers executing during root scanning
    // can be different from the set of workers executing
    // during mark.
    _mark->flush_and_free();
  }
};

class XMarkTask : public XTask {
private:
  XMark* const   _mark;
  const uint64_t _timeout_in_micros;

public:
  XMarkTask(XMark* mark, uint64_t timeout_in_micros = 0) :
      XTask("XMarkTask"),
      _mark(mark),
      _timeout_in_micros(timeout_in_micros) {
    _mark->prepare_work();
  }

  ~XMarkTask() {
    _mark->finish_work();
  }

  virtual void work() {
    _mark->work(_timeout_in_micros);
  }
};

void XMark::mark(bool initial) {
  if (initial) {
    XMarkRootsTask task(this);
    _workers->run(&task);
  }

  XMarkTask task(this);
  _workers->run(&task);
}

bool XMark::try_complete() {
  _ntrycomplete++;

  // Use nconcurrent number of worker threads to maintain the
  // worker/stripe distribution used during concurrent mark.
  XMarkTask task(this, XMarkCompleteTimeout);
  _workers->run(&task);

  // Successful if all stripes are empty
  return _stripes.is_empty();
}

bool XMark::try_end() {
  // Flush all mark stacks
  if (!flush(true /* at_safepoint */)) {
    // Mark completed
    return true;
  }

  // Try complete marking by doing a limited
  // amount of mark work in this phase.
  return try_complete();
}

bool XMark::end() {
  // Try end marking
  if (!try_end()) {
    // Mark not completed
    _ncontinue++;
    return false;
  }

  // Verification
  if (ZVerifyMarking) {
    verify_all_stacks_empty();
  }

  // Update statistics
  XStatMark::set_at_mark_end(_nproactiveflush, _nterminateflush, _ntrycomplete, _ncontinue);

  // Note that we finished a marking cycle.
  // Unlike other GCs, we do not arm the nmethods
  // when marking terminates.
  CodeCache::on_gc_marking_cycle_finish();

  // Mark completed
  return true;
}

void XMark::free() {
  // Free any unused mark stack space
  _allocator.free();

  // Update statistics
  XStatMark::set_at_mark_free(_allocator.size());
}

void XMark::flush_and_free() {
  Thread* const thread = Thread::current();
  flush_and_free(thread);
}

bool XMark::flush_and_free(Thread* thread) {
  XMarkThreadLocalStacks* const stacks = XThreadLocalData::stacks(thread);
  const bool flushed = stacks->flush(&_allocator, &_stripes);
  stacks->free(&_allocator);
  return flushed;
}

class XVerifyMarkStacksEmptyClosure : public ThreadClosure {
private:
  const XMarkStripeSet* const _stripes;

public:
  XVerifyMarkStacksEmptyClosure(const XMarkStripeSet* stripes) :
      _stripes(stripes) {}

  void do_thread(Thread* thread) {
    XMarkThreadLocalStacks* const stacks = XThreadLocalData::stacks(thread);
    guarantee(stacks->is_empty(_stripes), "Should be empty");
  }
};

void XMark::verify_all_stacks_empty() const {
  // Verify thread stacks
  XVerifyMarkStacksEmptyClosure cl(&_stripes);
  Threads::threads_do(&cl);

  // Verify stripe stacks
  guarantee(_stripes.is_empty(), "Should be empty");
}
