/*
 * Copyright (c) 2019, 2023, 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 "memory/allocation.hpp"
#include "precompiled.hpp"
#include "classfile/classLoaderData.hpp"
#include "gc/shared/gc_globals.hpp"
#include "gc/shared/isGCActiveMark.hpp"
#include "gc/z/zAddress.inline.hpp"
#include "gc/z/zGenerationId.hpp"
#include "gc/z/zHeap.inline.hpp"
#include "gc/z/zNMethod.hpp"
#include "gc/z/zPageAllocator.hpp"
#include "gc/z/zResurrection.hpp"
#include "gc/z/zRootsIterator.hpp"
#include "gc/z/zStackWatermark.hpp"
#include "gc/z/zStoreBarrierBuffer.inline.hpp"
#include "gc/z/zStat.hpp"
#include "gc/z/zVerify.hpp"
#include "memory/iterator.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/globals.hpp"
#include "runtime/handles.hpp"
#include "runtime/javaThread.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/stackFrameStream.inline.hpp"
#include "runtime/stackWatermark.inline.hpp"
#include "runtime/stackWatermarkSet.inline.hpp"
#include "runtime/thread.hpp"
#include "utilities/debug.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/preserveException.hpp"
#include "utilities/resourceHash.hpp"

#ifdef ASSERT

// Used to verify that safepoints operations can't be scheduled concurrently
// with callers to this function. Typically used to verify that object oops
// and headers are safe to access.
void z_verify_safepoints_are_blocked() {
  Thread* current = Thread::current();

  if (current->is_ConcurrentGC_thread()) {
    assert(current->is_suspendible_thread(), // Thread prevents safepoints
        "Safepoints are not blocked by current thread");

  } else if (current->is_Worker_thread()) {
    assert(// Check if ...
        // the thread prevents safepoints
        current->is_suspendible_thread() ||
        // the coordinator thread is the safepointing VMThread
        current->is_indirectly_safepoint_thread() ||
        // the coordinator thread prevents safepoints
        current->is_indirectly_suspendible_thread() ||
        // the RelocateQueue prevents safepoints
        //
        // RelocateQueue acts as a pseudo STS leaver/joiner and blocks
        // safepoints. There's currently no infrastructure  to check if the
        // current thread is active or not, so check the global states instead.
        ZGeneration::young()->is_relocate_queue_active() ||
        ZGeneration::old()->is_relocate_queue_active(),
        "Safepoints are not blocked by current thread");

  } else if (current->is_Java_thread()) {
    JavaThreadState state = JavaThread::cast(current)->thread_state();
    assert(state == _thread_in_Java || state == _thread_in_vm || state == _thread_new,
        "Safepoints are not blocked by current thread from state: %d", state);

  } else if (current->is_JfrSampler_thread()) {
    // The JFR sampler thread blocks out safepoints with this lock.
    assert_lock_strong(Threads_lock);

  } else if (current->is_VM_thread()) {
    // The VM Thread doesn't schedule new safepoints while executing
    // other safepoint or handshake operations.

  } else {
    fatal("Unexpected thread type");
  }
}

#endif

#define BAD_OOP_ARG(o, p)   "Bad oop " PTR_FORMAT " found at " PTR_FORMAT, untype(o), p2i(p)

static bool z_is_null_relaxed(zpointer o) {
  const uintptr_t color_mask = ZPointerAllMetadataMask | ZPointerReservedMask;
  return (untype(o) & ~color_mask) == 0;
}

static void z_verify_old_oop(zpointer* p) {
  const zpointer o = *p;
  assert(o != zpointer::null, "Old should not contain raw null");
  if (!z_is_null_relaxed(o)) {
    if (ZPointer::is_mark_good(o)) {
      // Even though the pointer is mark good, we can't verify that it should
      // be in the remembered set in old mark end. We have to wait to the verify
      // safepoint after reference processing, where we hold the driver lock and
      // know there is no concurrent remembered set processing in the young generation.
      const zaddress addr = ZPointer::uncolor(o);
      guarantee(oopDesc::is_oop(to_oop(addr)), BAD_OOP_ARG(o, p));
    } else {
      const zaddress addr = ZBarrier::load_barrier_on_oop_field_preloaded(nullptr, o);
      // Old to young pointers might not be mark good if the young
      // marking has not finished, which is responsible for coloring
      // these pointers.
      if (ZHeap::heap()->is_old(addr) || !ZGeneration::young()->is_phase_mark()) {
        // Old to old pointers are allowed to have bad young bits
        guarantee(ZPointer::is_marked_old(o),  BAD_OOP_ARG(o, p));
        guarantee(ZHeap::heap()->is_old(p), BAD_OOP_ARG(o, p));
      }
    }
  }
}

static void z_verify_young_oop(zpointer* p) {
  const zpointer o = *p;
  if (!z_is_null_relaxed(o)) {
    guarantee(ZHeap::heap()->is_young(p), BAD_OOP_ARG(o, p));
    guarantee(ZPointer::is_marked_young(o),  BAD_OOP_ARG(o, p));

    if (ZPointer::is_load_good(o)) {
      guarantee(oopDesc::is_oop(to_oop(ZPointer::uncolor(o))), BAD_OOP_ARG(o, p));
    }
  }
}

static void z_verify_root_oop_object(zaddress o, void* p) {
  guarantee(oopDesc::is_oop(to_oop(o)), BAD_OOP_ARG(o, p));
}

static void z_verify_uncolored_root_oop(zaddress* p) {
  assert(!ZHeap::heap()->is_in((uintptr_t)p), "Roots shouldn't be in heap");
  const zaddress o = *p;
  if (!is_null(o)) {
    z_verify_root_oop_object(o, p);
  }
}

static void z_verify_possibly_weak_oop(zpointer* p) {
  const zpointer o = *p;
  if (!z_is_null_relaxed(o)) {
    guarantee(ZPointer::is_marked_old(o) || ZPointer::is_marked_finalizable(o), BAD_OOP_ARG(o, p));

    const zaddress addr = ZBarrier::load_barrier_on_oop_field_preloaded(nullptr, o);
    guarantee(ZHeap::heap()->is_old(addr) || ZPointer::is_marked_young(o), BAD_OOP_ARG(o, p));
    guarantee(ZHeap::heap()->is_young(addr) || ZHeap::heap()->is_object_live(addr), BAD_OOP_ARG(o, p));
    guarantee(oopDesc::is_oop(to_oop(addr)), BAD_OOP_ARG(o, p));

    // Verify no missing remset entries. We are holding the driver lock here and that
    // allows us to more precisely verify the remembered set, as there is no concurrent
    // young generation collection going on at this point.
    const uintptr_t remset_bits = untype(o) & ZPointerRememberedMask;
    const uintptr_t prev_remembered = ZPointerRemembered ^ ZPointerRememberedMask;
    guarantee(remset_bits != prev_remembered, BAD_OOP_ARG(o, p));
    guarantee(remset_bits == ZPointerRememberedMask ||
              ZGeneration::young()->is_remembered(p) ||
              ZStoreBarrierBuffer::is_in(p), BAD_OOP_ARG(o, p));
  }
}

class ZVerifyColoredRootClosure : public OopClosure {
private:
  const bool _verify_marked_old;

public:
  ZVerifyColoredRootClosure(bool verify_marked_old)
    : OopClosure(),
      _verify_marked_old(verify_marked_old) {}

  virtual void do_oop(oop* p_) {
    zpointer* const p = (zpointer*)p_;

    assert(!ZHeap::heap()->is_in((uintptr_t)p), "Roots shouldn't be in heap");

    const zpointer o = *p;

    if (z_is_null_relaxed(o)) {
      // Skip verifying nulls
      return;
    }

    assert(is_valid(o), "Catch me!");

    if (_verify_marked_old) {
      guarantee(ZPointer::is_marked_old(o), BAD_OOP_ARG(o, p));

      // Minor collections could have relocated the object;
      // use load barrier to find correct object.
      const zaddress addr = ZBarrier::load_barrier_on_oop_field_preloaded(nullptr, o);
      z_verify_root_oop_object(addr, p);
    } else {
      // Don't know the state of the oop
      if (is_valid(o)) {
        // it looks like a valid colored oop;
        // use load barrier to find correct object.
        const zaddress addr = ZBarrier::load_barrier_on_oop_field_preloaded(nullptr, o);
        z_verify_root_oop_object(addr, p);
      }
    }
  }

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

class ZVerifyUncoloredRootClosure : public OopClosure {
public:
  virtual void do_oop(oop* p_) {
    zaddress* const p = (zaddress*)p_;
    z_verify_uncolored_root_oop(p);
  }

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

class ZVerifyCodeBlobClosure : public CodeBlobToOopClosure {
public:
  ZVerifyCodeBlobClosure(OopClosure* cl)
    : CodeBlobToOopClosure(cl, false /* fix_relocations */) {}

  virtual void do_code_blob(CodeBlob* cb) {
    CodeBlobToOopClosure::do_code_blob(cb);
  }
};

class ZVerifyOldOopClosure : public BasicOopIterateClosure {
private:
  const bool _verify_weaks;

public:
  ZVerifyOldOopClosure(bool verify_weaks)
    : _verify_weaks(verify_weaks) {}

  virtual void do_oop(oop* p_) {
    zpointer* const p = (zpointer*)p_;
    if (_verify_weaks) {
      z_verify_possibly_weak_oop(p);
    } else {
      // We should never encounter finalizable oops through strong
      // paths. This assumes we have only visited strong roots.
      z_verify_old_oop(p);
    }
  }

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

  virtual ReferenceIterationMode reference_iteration_mode() {
    return _verify_weaks ? DO_FIELDS : DO_FIELDS_EXCEPT_REFERENT;
  }
};

class ZVerifyYoungOopClosure : public BasicOopIterateClosure {
private:
  const bool _verify_weaks;

public:
  ZVerifyYoungOopClosure(bool verify_weaks)
    : _verify_weaks(verify_weaks) {}

  virtual void do_oop(oop* p_) {
    zpointer* const p = (zpointer*)p_;
    if (_verify_weaks) {
      //z_verify_possibly_weak_oop(p);
      z_verify_young_oop(p);
    } else {
      // We should never encounter finalizable oops through strong
      // paths. This assumes we have only visited strong roots.
      z_verify_young_oop(p);
    }
  }

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

  virtual ReferenceIterationMode reference_iteration_mode() {
    return _verify_weaks ? DO_FIELDS : DO_FIELDS_EXCEPT_REFERENT;
  }

  // Don't follow this metadata when verifying oops
  virtual void do_method(Method* m) {}
  virtual void do_nmethod(nmethod* nm) {}
};

typedef ClaimingCLDToOopClosure<ClassLoaderData::_claim_none> ZVerifyCLDClosure;

class ZVerifyThreadClosure : public ThreadClosure {
private:
  OopClosure* const _verify_cl;

public:
  ZVerifyThreadClosure(OopClosure* verify_cl)
    : _verify_cl(verify_cl) {}

  virtual void do_thread(Thread* thread) {
    JavaThread* const jt = JavaThread::cast(thread);
    const ZStackWatermark* const watermark = StackWatermarkSet::get<ZStackWatermark>(jt, StackWatermarkKind::gc);
    if (watermark->processing_started_acquire()) {
      thread->oops_do_no_frames(_verify_cl, nullptr);

       if (watermark->processing_completed_acquire()) {
         thread->oops_do_frames(_verify_cl, nullptr);
       }
    }
  }
};

class ZVerifyNMethodClosure : public NMethodClosure {
private:
  OopClosure* const        _cl;
  BarrierSetNMethod* const _bs_nm;

public:
  ZVerifyNMethodClosure(OopClosure* cl)
    : _cl(cl),
      _bs_nm(BarrierSet::barrier_set()->barrier_set_nmethod()) {}

  virtual void do_nmethod(nmethod* nm) {
    if (_bs_nm->is_armed(nm)) {
      // Can't verify
      return;
    }

    ZNMethod::nmethod_oops_do(nm, _cl);
  }
};

void ZVerify::roots_strong(bool verify_after_old_mark) {
  assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");

  {
    ZVerifyColoredRootClosure cl(verify_after_old_mark);
    ZVerifyCLDClosure cld_cl(&cl);

    ZRootsIteratorStrongColored roots_strong_colored(ZGenerationIdOptional::none);
    roots_strong_colored.apply(&cl,
                               &cld_cl);
  }

  {
    ZVerifyUncoloredRootClosure cl;
    ZVerifyThreadClosure thread_cl(&cl);
    ZVerifyNMethodClosure nm_cl(&cl);

    ZRootsIteratorStrongUncolored roots_strong_uncolored(ZGenerationIdOptional::none);
    roots_strong_uncolored.apply(&thread_cl,
                                 &nm_cl);
  }
}

void ZVerify::roots_weak() {
  assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
  assert(!ZResurrection::is_blocked(), "Invalid phase");

  ZVerifyColoredRootClosure cl(true /* verify_after_old_mark*/);
  ZRootsIteratorWeakColored roots_weak_colored(ZGenerationIdOptional::none);
  roots_weak_colored.apply(&cl);
}

zaddress zverify_broken_object = zaddress::null;

class ZVerifyObjectClosure : public ObjectClosure, public OopFieldClosure {
private:
  const bool         _verify_weaks;

  zaddress           _visited_base;
  volatile zpointer* _visited_p;
  zpointer           _visited_ptr_pre_loaded;

public:
  ZVerifyObjectClosure(bool verify_weaks)
    : _verify_weaks(verify_weaks),
      _visited_base(),
      _visited_p(),
      _visited_ptr_pre_loaded() {}

  void log_dead_object(zaddress addr) {
    tty->print_cr("ZVerify found dead object: " PTR_FORMAT " at p: " PTR_FORMAT " ptr: " PTR_FORMAT, untype(addr), p2i((void*)_visited_p), untype(_visited_ptr_pre_loaded));
    to_oop(addr)->print();
    tty->print_cr("--- From --- ");
    if (_visited_base != zaddress::null) {
      to_oop(_visited_base)->print();
    }
    tty->cr();

    if (zverify_broken_object == zaddress::null) {
      zverify_broken_object = addr;
    }
  }

  void verify_live_object(oop obj) {
    // Verify that its pointers are sane
    ZVerifyOldOopClosure cl(_verify_weaks);
    ZIterator::oop_iterate_safe(obj, &cl);
  }

  virtual void do_object(oop obj) {
    guarantee(oopDesc::is_oop_or_null(obj), "Must be");

    const zaddress addr = to_zaddress(obj);
    if (ZHeap::heap()->is_old(addr)) {
      if (ZHeap::heap()->is_object_live(addr)) {
        verify_live_object(obj);
      } else {
        log_dead_object(addr);
      }
    } else {
      // Young object - no verification
    }
  }

  virtual void do_field(oop base, oop* p) {
    _visited_base = to_zaddress(base);
    _visited_p = (volatile zpointer*)p;
    _visited_ptr_pre_loaded = Atomic::load(_visited_p);
  }
};

void ZVerify::threads_start_processing() {
  class StartProcessingClosure : public ThreadClosure {
  public:
    void do_thread(Thread* thread) {
      StackWatermarkSet::start_processing(JavaThread::cast(thread), StackWatermarkKind::gc);
    }
  };

  ZJavaThreadsIterator threads_iterator(ZGenerationIdOptional::none);
  StartProcessingClosure cl;
  threads_iterator.apply(&cl);
}

void ZVerify::objects(bool verify_weaks) {
  if (ZAbort::should_abort()) {
    // Invariants might be a bit mushy if the young generation
    // collection was forced to shut down. So let's be a bit forgiving here.
    return;
  }
  assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint");
  assert(ZGeneration::young()->is_phase_mark_complete() ||
         ZGeneration::old()->is_phase_mark_complete(), "Invalid phase");
  assert(!ZResurrection::is_blocked(), "Invalid phase");

  // Note that object verification will fix the pointers and
  // only verify that the resulting objects are sane.

  // The verification VM_Operation doesn't start the thread processing.
  // Do it here, after the roots have been verified.
  threads_start_processing();

  ZVerifyObjectClosure object_cl(verify_weaks);
  ZHeap::heap()->object_and_field_iterate_for_verify(&object_cl, &object_cl, verify_weaks);
}

void ZVerify::before_zoperation() {
  // Verify strong roots
  if (ZVerifyRoots) {
    roots_strong(false /* verify_after_old_mark */);
  }
}

void ZVerify::after_mark() {
  // Verify all strong roots and strong references
  if (ZVerifyRoots) {
    roots_strong(true /* verify_after_old_mark */);
  }
  if (ZVerifyObjects) {
    // Workaround OopMapCacheAlloc_lock reordering with the StackWatermark_lock
    DisableIsGCActiveMark mark;

    objects(false /* verify_weaks */);
    guarantee(zverify_broken_object == zaddress::null, "Verification failed");
  }
}

void ZVerify::after_weak_processing() {
  // Verify all roots and all references
  if (ZVerifyRoots) {
    roots_strong(true /* verify_after_old_mark */);
    roots_weak();
  }
  if (ZVerifyObjects) {
    objects(true /* verify_weaks */);
  }
}

//
// Remembered set verification
//

typedef ResourceHashtable<volatile zpointer*, bool, 1009, AnyObj::C_HEAP, mtGC> ZStoreBarrierBufferTable;

static ZStoreBarrierBufferTable* z_verify_store_barrier_buffer_table = nullptr;

#define BAD_REMSET_ARG(p, ptr, addr) \
  "Missing remembered set at " PTR_FORMAT " pointing at " PTR_FORMAT \
  " (" PTR_FORMAT " + " INTX_FORMAT ")" \
  , p2i(p), untype(ptr), untype(addr), p2i(p) - untype(addr)

class ZVerifyRemsetBeforeOopClosure : public BasicOopIterateClosure {
private:
  ZForwarding*    _forwarding;
  zaddress_unsafe _from_addr;

public:
  ZVerifyRemsetBeforeOopClosure(ZForwarding* forwarding)
    : _forwarding(forwarding),
      _from_addr(zaddress_unsafe::null) {}

  void set_from_addr(zaddress_unsafe addr) {
    _from_addr = addr;
  }

  virtual void do_oop(oop* p_) {
    volatile zpointer* const p = (volatile zpointer*)p_;
    const zpointer ptr = *p;

    if (ZPointer::is_remembered_exact(ptr)) {
      // When the remembered bits are 11, it means that it is intentionally
      // not part of the remembered set
      return;
    }

    if (ZBufferStoreBarriers && z_verify_store_barrier_buffer_table->get(p) != nullptr) {
      // If this oop location is in the store barrier buffer, we can't assume
      // that it should have a remset entry
      return;
    }

    if (_forwarding->find(_from_addr) != zaddress::null) {
      // If the mutator has already relocated the object to to-space, we defer
      // and do to-space verification afterwards instead, because store barrier
      // buffers could have installed the remembered set entry in to-space and
      // then flushed the store barrier buffer, and then start young marking
      return;
    }

    ZPage* page = _forwarding->page();

    if (ZGeneration::old()->active_remset_is_current()) {
      guarantee(page->is_remembered(p), BAD_REMSET_ARG(p, ptr, _from_addr));
    } else {
      guarantee(page->was_remembered(p), BAD_REMSET_ARG(p, ptr, _from_addr));
    }
  }

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

  virtual ReferenceIterationMode reference_iteration_mode() {
    return DO_FIELDS;
  }
};

void ZVerify::on_color_flip() {
  if (!ZVerifyRemembered || !ZBufferStoreBarriers) {
    return;
  }

  // Reset the table tracking the stale stores of the store barrier buffer
  delete z_verify_store_barrier_buffer_table;
  z_verify_store_barrier_buffer_table = new (mtGC) ZStoreBarrierBufferTable();

  // Gather information from store barrier buffers as we currently can't verify
  // remset entries for oop locations touched by the store barrier buffer

  for (JavaThreadIteratorWithHandle jtiwh; JavaThread* const jt = jtiwh.next(); ) {
    const ZStoreBarrierBuffer* const buffer = ZThreadLocalData::store_barrier_buffer(jt);

    for (int i = buffer->current(); i < (int)ZStoreBarrierBuffer::_buffer_length; ++i) {
      volatile zpointer* const p = buffer->_buffer[i]._p;
      bool created = false;
      z_verify_store_barrier_buffer_table->put_if_absent(p, true, &created);
    }
  }
}

void ZVerify::before_relocation(ZForwarding* forwarding) {
  if (!ZVerifyRemembered) {
    return;
  }

  if (forwarding->from_age() != ZPageAge::old) {
    // Only supports verification of old-to-old relocations now
    return;
  }

  // Verify that the inactive remset is cleared
  if (ZGeneration::old()->active_remset_is_current()) {
    forwarding->page()->verify_remset_cleared_previous();
  } else {
    forwarding->page()->verify_remset_cleared_current();
  }

  ZVerifyRemsetBeforeOopClosure cl(forwarding);

  forwarding->object_iterate([&](oop obj) {
    const zaddress_unsafe addr = to_zaddress_unsafe(cast_from_oop<uintptr_t>(obj));
    cl.set_from_addr(addr);
    obj->oop_iterate(&cl);
  });
}

class ZVerifyRemsetAfterOopClosure : public BasicOopIterateClosure {
private:
  ZForwarding* const _forwarding;
  zaddress_unsafe    _from_addr;
  zaddress           _to_addr;

public:
  ZVerifyRemsetAfterOopClosure(ZForwarding* forwarding)
    : _forwarding(forwarding),
      _from_addr(zaddress_unsafe::null),
      _to_addr(zaddress::null) {}

  void set_from_addr(zaddress_unsafe addr) {
    _from_addr = addr;
  }

  void set_to_addr(zaddress addr) {
    _to_addr = addr;
  }

  virtual void do_oop(oop* p_) {
    volatile zpointer* const p = (volatile zpointer*)p_;
    const zpointer ptr = Atomic::load(p);

    // Order this load w.r.t. the was_remembered load which can race when
    // the remset scanning of the to-space object is concurrently forgetting
    // an entry.
    OrderAccess::loadload();

    if (ZPointer::is_remembered_exact(ptr)) {
      // When the remembered bits are 11, it means that it is intentionally
      // not part of the remembered set
      return;
    }

    if (ZPointer::is_store_good(ptr)) {
      // In to-space, there could be stores racing with the verification.
      // Such stores may not have reliably manifested in the remembered
      // sets yet.
      return;
    }

    if (ZBufferStoreBarriers && z_verify_store_barrier_buffer_table->get(p) != nullptr) {
      // If this to-space oop location is in the store barrier buffer, we
      // can't assume that it should have a remset entry
      return;
    }

    const uintptr_t p_offset = uintptr_t(p) - untype(_to_addr);
    volatile zpointer* const fromspace_p = (volatile zpointer*)(untype(_from_addr) + p_offset);

    if (ZBufferStoreBarriers && z_verify_store_barrier_buffer_table->get(fromspace_p) != nullptr) {
      // If this from-space oop location is in the store barrier buffer, we
      // can't assume that it should have a remset entry
      return;
    }

    ZPage* page = ZHeap::heap()->page(p);

    if (page->is_remembered(p) || page->was_remembered(p)) {
      // No missing remembered set entry
      return;
    }

    OrderAccess::loadload();
    if (Atomic::load(p) != ptr) {
      // Order the was_remembered bitmap load w.r.t. the reload of the zpointer.
      // Sometimes the was_remembered() call above races with clearing of the
      // previous bits, when the to-space object is concurrently forgetting
      // remset entries because they were not so useful. When that happens,
      // we have already self healed the pointers to have 11 in the remset
      // bits.
      return;
    }

    guarantee(ZGeneration::young()->is_phase_mark(), "Should be in the mark phase " BAD_REMSET_ARG(p, ptr, _to_addr));
    guarantee(_forwarding->relocated_remembered_fields_published_contains(p), BAD_REMSET_ARG(p, ptr, _to_addr));
  }

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

  virtual ReferenceIterationMode reference_iteration_mode() {
    return DO_FIELDS;
  }
};

void ZVerify::after_relocation_internal(ZForwarding* forwarding) {
  ZVerifyRemsetAfterOopClosure cl(forwarding);

  forwarding->address_unsafe_iterate_via_table([&](zaddress_unsafe from_addr) {
    // If no field in this object was in the store barrier buffer
    // when relocation started, we should be able to verify trivially
    ZGeneration* const from_generation = forwarding->from_age() == ZPageAge::old ? (ZGeneration*)ZGeneration::old()
                                                                           : (ZGeneration*)ZGeneration::young();
    const zaddress to_addr = from_generation->remap_object(from_addr);

    cl.set_from_addr(from_addr);
    cl.set_to_addr(to_addr);
    const oop to_obj = to_oop(to_addr);
    to_obj->oop_iterate(&cl);
  });
}

void ZVerify::after_relocation(ZForwarding* forwarding) {
  if (!ZVerifyRemembered) {
    return;
  }

  if (forwarding->to_age() != ZPageAge::old) {
    // No remsets to verify in the young gen
    return;
  }

  if (ZGeneration::young()->is_phase_mark() &&
      forwarding->relocated_remembered_fields_is_concurrently_scanned()) {
    // Can't verify to-space objects if concurrent YC rejected published
    // remset information, because that data is incomplete. The YC might
    // not have finished scanning the forwarding, and might be about to
    // insert required remembered set entries.
    return;
  }

  after_relocation_internal(forwarding);
}

void ZVerify::after_scan(ZForwarding* forwarding) {
  if (!ZVerifyRemembered) {
    return;
  }

  if (ZAbort::should_abort()) {
    // We can't verify remembered set accurately when shutting down the VM
    return;
  }

  if (!ZGeneration::old()->is_phase_relocate() ||
      !forwarding->relocated_remembered_fields_is_concurrently_scanned()) {
    // Only verify remembered set from remembered set scanning, when the
    // remembered set scanning rejected the publishing information of concurrent
    // old generation relocation
    return;
  }

  after_relocation_internal(forwarding);
}
