// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <unordered_map>
#include <vector>

#include "include/v8.h"
#include "src/api/api-inl.h"
#include "src/heap/heap-inl.h"
#include "src/heap/safepoint.h"
#include "src/objects/module.h"
#include "src/objects/objects-inl.h"
#include "src/objects/script.h"
#include "src/objects/shared-function-info.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"

namespace v8 {

namespace internal {
namespace heap {

namespace {

v8::Local<v8::Object> ConstructTraceableJSApiObject(
    v8::Local<v8::Context> context, void* first_field, void* second_field) {
  v8::EscapableHandleScope scope(context->GetIsolate());
  v8::Local<v8::FunctionTemplate> function_t =
      v8::FunctionTemplate::New(context->GetIsolate());
  v8::Local<v8::ObjectTemplate> instance_t = function_t->InstanceTemplate();
  instance_t->SetInternalFieldCount(2);
  v8::Local<v8::Function> function =
      function_t->GetFunction(context).ToLocalChecked();
  v8::Local<v8::Object> instance =
      function->NewInstance(context).ToLocalChecked();
  instance->SetAlignedPointerInInternalField(0, first_field);
  instance->SetAlignedPointerInInternalField(1, second_field);
  CHECK(!instance.IsEmpty());
  i::Handle<i::JSReceiver> js_obj = v8::Utils::OpenHandle(*instance);
  CHECK_EQ(i::JS_API_OBJECT_TYPE, js_obj->map().instance_type());
  return scope.Escape(instance);
}

enum class TracePrologueBehavior { kNoop, kCallV8WriteBarrier };

class TestEmbedderHeapTracer final : public v8::EmbedderHeapTracer {
 public:
  TestEmbedderHeapTracer() = default;
  TestEmbedderHeapTracer(TracePrologueBehavior prologue_behavior,
                         v8::Global<v8::Array> array)
      : prologue_behavior_(prologue_behavior), array_(std::move(array)) {}

  void RegisterV8References(
      const std::vector<std::pair<void*, void*>>& embedder_fields) final {
    registered_from_v8_.insert(registered_from_v8_.end(),
                               embedder_fields.begin(), embedder_fields.end());
  }

  void AddReferenceForTracing(v8::TracedGlobal<v8::Value>* global) {
    to_register_with_v8_.push_back(global);
  }

  void AddReferenceForTracing(v8::TracedReference<v8::Value>* ref) {
    to_register_with_v8_references_.push_back(ref);
  }

  bool AdvanceTracing(double deadline_in_ms) final {
    for (auto global : to_register_with_v8_) {
      RegisterEmbedderReference(global->As<v8::Data>());
    }
    to_register_with_v8_.clear();
    for (auto ref : to_register_with_v8_references_) {
      RegisterEmbedderReference(ref->As<v8::Data>());
    }
    to_register_with_v8_references_.clear();
    return true;
  }

  bool IsTracingDone() final { return to_register_with_v8_.empty(); }

  void TracePrologue(EmbedderHeapTracer::TraceFlags) final {
    if (prologue_behavior_ == TracePrologueBehavior::kCallV8WriteBarrier) {
      auto local = array_.Get(isolate());
      local->Set(local->CreationContext(), 0, v8::Object::New(isolate()))
          .Check();
    }
  }

  void TraceEpilogue(TraceSummary*) final {}
  void EnterFinalPause(EmbedderStackState) final {}

  bool IsRegisteredFromV8(void* first_field) const {
    for (auto pair : registered_from_v8_) {
      if (pair.first == first_field) return true;
    }
    return false;
  }

  void ConsiderTracedGlobalAsRoot(bool value) {
    consider_traced_global_as_root_ = value;
  }

  bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle) final {
    return consider_traced_global_as_root_;
  }

 private:
  std::vector<std::pair<void*, void*>> registered_from_v8_;
  std::vector<v8::TracedGlobal<v8::Value>*> to_register_with_v8_;
  std::vector<v8::TracedReference<v8::Value>*> to_register_with_v8_references_;
  bool consider_traced_global_as_root_ = true;
  TracePrologueBehavior prologue_behavior_ = TracePrologueBehavior::kNoop;
  v8::Global<v8::Array> array_;
};

}  // namespace

TEST(V8RegisteringEmbedderReference) {
  // Tests that wrappers are properly registered with the embedder heap
  // tracer.
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = v8::Context::New(isolate);
  v8::Context::Scope context_scope(context);

  void* first_field = reinterpret_cast<void*>(0x2);
  v8::Local<v8::Object> api_object =
      ConstructTraceableJSApiObject(context, first_field, nullptr);
  CHECK(!api_object.IsEmpty());
  CcTest::CollectGarbage(i::OLD_SPACE);
  CHECK(tracer.IsRegisteredFromV8(first_field));
}

TEST(EmbedderRegisteringV8Reference) {
  // Tests that references that are registered by the embedder heap tracer are
  // considered live by V8.
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = v8::Context::New(isolate);
  v8::Context::Scope context_scope(context);

  v8::TracedGlobal<v8::Value> g;
  {
    v8::HandleScope inner_scope(isolate);
    v8::Local<v8::Value> o =
        v8::Local<v8::Object>::New(isolate, v8::Object::New(isolate));
    g.Reset(isolate, o);
  }
  tracer.AddReferenceForTracing(&g);
  CcTest::CollectGarbage(i::OLD_SPACE);
  CHECK(!g.IsEmpty());
}

namespace {

void ResurrectingFinalizer(
    const v8::WeakCallbackInfo<v8::Global<v8::Object>>& data) {
  data.GetParameter()->ClearWeak();
}

}  // namespace

TEST(TracingInRevivedSubgraph) {
  // Tests that wrappers are traced when they are contained with in a subgraph
  // that is revived by a finalizer.
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = v8::Context::New(isolate);
  v8::Context::Scope context_scope(context);

  v8::Global<v8::Object> g;
  void* first_field = reinterpret_cast<void*>(0x4);
  {
    v8::HandleScope inner_scope(isolate);
    v8::Local<v8::Object> api_object =
        ConstructTraceableJSApiObject(context, first_field, nullptr);
    CHECK(!api_object.IsEmpty());
    v8::Local<v8::Object> o =
        v8::Local<v8::Object>::New(isolate, v8::Object::New(isolate));
    o->Set(context, v8_str("link"), api_object).FromJust();
    g.Reset(isolate, o);
    g.SetWeak(&g, ResurrectingFinalizer, v8::WeakCallbackType::kFinalizer);
  }
  CcTest::CollectGarbage(i::OLD_SPACE);
  CHECK(tracer.IsRegisteredFromV8(first_field));
}

TEST(TracingInEphemerons) {
  // Tests that wrappers that are part of ephemerons are traced.
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = v8::Context::New(isolate);
  v8::Context::Scope context_scope(context);

  v8::Local<v8::Object> key =
      v8::Local<v8::Object>::New(isolate, v8::Object::New(isolate));
  void* first_field = reinterpret_cast<void*>(0x8);
  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
  Handle<JSWeakMap> weak_map = i_isolate->factory()->NewJSWeakMap();
  {
    v8::HandleScope inner_scope(isolate);
    v8::Local<v8::Object> api_object =
        ConstructTraceableJSApiObject(context, first_field, nullptr);
    CHECK(!api_object.IsEmpty());
    Handle<JSObject> js_key =
        handle(JSObject::cast(*v8::Utils::OpenHandle(*key)), i_isolate);
    Handle<JSReceiver> js_api_object = v8::Utils::OpenHandle(*api_object);
    int32_t hash = js_key->GetOrCreateHash(i_isolate).value();
    JSWeakCollection::Set(weak_map, js_key, js_api_object, hash);
  }
  CcTest::CollectGarbage(i::OLD_SPACE);
  CHECK(tracer.IsRegisteredFromV8(first_field));
}

TEST(FinalizeTracingIsNoopWhenNotMarking) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  Isolate* i_isolate = CcTest::i_isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);

  // Finalize a potentially running garbage collection.
  i_isolate->heap()->CollectGarbage(OLD_SPACE,
                                    GarbageCollectionReason::kTesting);
  CHECK(i_isolate->heap()->incremental_marking()->IsStopped());

  int gc_counter = i_isolate->heap()->gc_count();
  tracer.FinalizeTracing();
  CHECK(i_isolate->heap()->incremental_marking()->IsStopped());
  CHECK_EQ(gc_counter, i_isolate->heap()->gc_count());
}

TEST(FinalizeTracingWhenMarking) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  Isolate* i_isolate = CcTest::i_isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);

  // Finalize a potentially running garbage collection.
  i_isolate->heap()->CollectGarbage(OLD_SPACE,
                                    GarbageCollectionReason::kTesting);
  if (i_isolate->heap()->mark_compact_collector()->sweeping_in_progress()) {
    i_isolate->heap()->mark_compact_collector()->EnsureSweepingCompleted();
  }
  CHECK(i_isolate->heap()->incremental_marking()->IsStopped());

  i::IncrementalMarking* marking = i_isolate->heap()->incremental_marking();
  {
    SafepointScope scope(i_isolate->heap());
    marking->Start(i::GarbageCollectionReason::kTesting);
  }

  // Sweeping is not runing so we should immediately start marking.
  CHECK(marking->IsMarking());
  tracer.FinalizeTracing();
  CHECK(marking->IsStopped());
}

TEST(GarbageCollectionForTesting) {
  ManualGCScope manual_gc;
  i::FLAG_expose_gc = true;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  Isolate* i_isolate = CcTest::i_isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);

  int saved_gc_counter = i_isolate->heap()->gc_count();
  tracer.GarbageCollectionForTesting(
      EmbedderHeapTracer::EmbedderStackState::kMayContainHeapPointers);
  CHECK_GT(i_isolate->heap()->gc_count(), saved_gc_counter);
}

namespace {

void ConstructJSObject(v8::Isolate* isolate, v8::Local<v8::Context> context,
                       v8::TracedGlobal<v8::Object>* global) {
  v8::HandleScope scope(isolate);
  v8::Local<v8::Object> object(v8::Object::New(isolate));
  CHECK(!object.IsEmpty());
  *global = v8::TracedGlobal<v8::Object>(isolate, object);
  CHECK(!global->IsEmpty());
}

template <typename T>
void ConstructJSApiObject(v8::Isolate* isolate, v8::Local<v8::Context> context,
                          T* global) {
  v8::HandleScope scope(isolate);
  v8::Local<v8::Object> object(
      ConstructTraceableJSApiObject(context, nullptr, nullptr));
  CHECK(!object.IsEmpty());
  *global = T(isolate, object);
  CHECK(!global->IsEmpty());
}

enum class SurvivalMode { kSurvives, kDies };

template <typename ModifierFunction, typename ConstructTracedGlobalFunction>
void TracedGlobalTest(v8::Isolate* isolate,
                      ConstructTracedGlobalFunction construct_function,
                      ModifierFunction modifier_function, void (*gc_function)(),
                      SurvivalMode survives) {
  v8::HandleScope scope(isolate);
  v8::Local<v8::Context> context = v8::Context::New(isolate);
  v8::Context::Scope context_scope(context);

  auto global = std::make_unique<v8::TracedGlobal<v8::Object>>();
  construct_function(isolate, context, global.get());
  CHECK(InCorrectGeneration(isolate, *global));
  modifier_function(*global);
  gc_function();
  CHECK_IMPLIES(survives == SurvivalMode::kSurvives, !global->IsEmpty());
  CHECK_IMPLIES(survives == SurvivalMode::kDies, global->IsEmpty());
}

}  // namespace

TEST(TracedGlobalReset) {
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);

  v8::TracedGlobal<v8::Object> traced;
  ConstructJSObject(isolate, isolate->GetCurrentContext(), &traced);
  CHECK(!traced.IsEmpty());
  traced.Reset();
  CHECK(traced.IsEmpty());
}

TEST(TracedGlobalInStdVector) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);

  std::vector<v8::TracedGlobal<v8::Object>> vec;
  {
    v8::HandleScope scope(isolate);
    vec.emplace_back(isolate, v8::Object::New(isolate));
  }
  CHECK(!vec[0].IsEmpty());
  InvokeMarkSweep();
  CHECK(vec[0].IsEmpty());
}

TEST(TracedGlobalCopyWithDestructor) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();

  const size_t initial_count = global_handles->handles_count();
  auto global1 = std::make_unique<v8::TracedGlobal<v8::Object>>();
  {
    v8::HandleScope scope(isolate);
    global1->Reset(isolate, v8::Object::New(isolate));
  }
  auto global2 = std::make_unique<v8::TracedGlobal<v8::Object>>(*global1);
  auto global3 = std::make_unique<v8::TracedGlobal<v8::Object>>();
  *global3 = *global2;
  CHECK_EQ(initial_count + 3, global_handles->handles_count());
  CHECK(!global1->IsEmpty());
  CHECK_EQ(*global1, *global2);
  CHECK_EQ(*global2, *global3);
  {
    v8::HandleScope scope(isolate);
    auto tmp = v8::Local<v8::Object>::New(isolate, *global3);
    CHECK(!tmp.IsEmpty());
    InvokeMarkSweep();
  }
  CHECK_EQ(initial_count + 3, global_handles->handles_count());
  CHECK(!global1->IsEmpty());
  CHECK_EQ(*global1, *global2);
  CHECK_EQ(*global2, *global3);
  InvokeMarkSweep();
  CHECK_EQ(initial_count, global_handles->handles_count());
  CHECK(global1->IsEmpty());
  CHECK_EQ(*global1, *global2);
  CHECK_EQ(*global2, *global3);
}

TEST(TracedGlobalCopyNoDestructor) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();

  const size_t initial_count = global_handles->handles_count();
  auto global1 = std::make_unique<v8::TracedReference<v8::Value>>();
  {
    v8::HandleScope scope(isolate);
    global1->Reset(isolate, v8::Object::New(isolate));
  }
  auto global2 = std::make_unique<v8::TracedReference<v8::Value>>(*global1);
  auto global3 = std::make_unique<v8::TracedReference<v8::Value>>();
  *global3 = *global2;
  CHECK_EQ(initial_count + 3, global_handles->handles_count());
  CHECK(!global1->IsEmpty());
  CHECK_EQ(*global1, *global2);
  CHECK_EQ(*global2, *global3);
  {
    v8::HandleScope scope(isolate);
    auto tmp = v8::Local<v8::Value>::New(isolate, *global3);
    CHECK(!tmp.IsEmpty());
    InvokeMarkSweep();
  }
  CHECK_EQ(initial_count + 3, global_handles->handles_count());
  CHECK(!global1->IsEmpty());
  CHECK_EQ(*global1, *global2);
  CHECK_EQ(*global2, *global3);
  InvokeMarkSweep();
  CHECK_EQ(initial_count, global_handles->handles_count());
}

TEST(TracedGlobalInStdUnorderedMap) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);

  std::unordered_map<int, v8::TracedGlobal<v8::Object>> map;
  {
    v8::HandleScope scope(isolate);
    map.emplace(std::piecewise_construct, std::forward_as_tuple(1),
                std::forward_as_tuple(isolate, v8::Object::New(isolate)));
  }
  CHECK(!map[1].IsEmpty());
  InvokeMarkSweep();
  CHECK(map[1].IsEmpty());
}

TEST(TracedGlobalToUnmodifiedJSObjectDiesOnMarkSweep) {
  CcTest::InitializeVM();
  TracedGlobalTest(
      CcTest::isolate(), ConstructJSObject,
      [](const TracedGlobal<v8::Object>& global) {}, [] { InvokeMarkSweep(); },
      SurvivalMode::kDies);
}

TEST(TracedGlobalToUnmodifiedJSObjectSurvivesMarkSweepWhenHeldAliveOtherwise) {
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::Global<v8::Object> strong_global;
  TracedGlobalTest(
      CcTest::isolate(), ConstructJSObject,
      [isolate, &strong_global](const TracedGlobal<v8::Object>& global) {
        v8::HandleScope scope(isolate);
        strong_global = v8::Global<v8::Object>(isolate, global.Get(isolate));
      },
      []() { InvokeMarkSweep(); }, SurvivalMode::kSurvives);
}

TEST(TracedGlobalToUnmodifiedJSObjectSurvivesScavenge) {
  if (FLAG_single_generation) return;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TracedGlobalTest(
      CcTest::isolate(), ConstructJSObject,
      [](const TracedGlobal<v8::Object>& global) {}, []() { InvokeScavenge(); },
      SurvivalMode::kSurvives);
}

TEST(TracedGlobalToUnmodifiedJSObjectSurvivesScavengeWhenExcludedFromRoots) {
  if (FLAG_single_generation) return;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  tracer.ConsiderTracedGlobalAsRoot(false);
  TracedGlobalTest(
      CcTest::isolate(), ConstructJSObject,
      [](const TracedGlobal<v8::Object>& global) {}, []() { InvokeScavenge(); },
      SurvivalMode::kSurvives);
}

TEST(TracedGlobalToUnmodifiedJSApiObjectSurvivesScavengePerDefault) {
  if (FLAG_single_generation) return;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  tracer.ConsiderTracedGlobalAsRoot(true);
  TracedGlobalTest(
      CcTest::isolate(), ConstructJSApiObject<TracedGlobal<v8::Object>>,
      [](const TracedGlobal<v8::Object>& global) {}, []() { InvokeScavenge(); },
      SurvivalMode::kSurvives);
}

TEST(TracedGlobalToUnmodifiedJSApiObjectDiesOnScavengeWhenExcludedFromRoots) {
  if (FLAG_single_generation) return;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  tracer.ConsiderTracedGlobalAsRoot(false);
  TracedGlobalTest(
      CcTest::isolate(), ConstructJSApiObject<TracedGlobal<v8::Object>>,
      [](const TracedGlobal<v8::Object>& global) {}, []() { InvokeScavenge(); },
      SurvivalMode::kDies);
}

TEST(TracedGlobalWrapperClassId) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);

  v8::TracedGlobal<v8::Object> traced;
  ConstructJSObject(isolate, isolate->GetCurrentContext(), &traced);
  CHECK_EQ(0, traced.WrapperClassId());
  traced.SetWrapperClassId(17);
  CHECK_EQ(17, traced.WrapperClassId());
}

TEST(TracedReferenceHandlesMarking) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  auto live = std::make_unique<v8::TracedReference<v8::Value>>();
  auto dead = std::make_unique<v8::TracedReference<v8::Value>>();
  live->Reset(isolate, v8::Undefined(isolate));
  dead->Reset(isolate, v8::Undefined(isolate));
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();
  {
    TestEmbedderHeapTracer tracer;
    heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
    tracer.AddReferenceForTracing(live.get());
    const size_t initial_count = global_handles->handles_count();
    InvokeMarkSweep();
    const size_t final_count = global_handles->handles_count();
    // Handles are black allocated, so the first GC does not collect them.
    CHECK_EQ(initial_count, final_count);
  }

  {
    TestEmbedderHeapTracer tracer;
    heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
    tracer.AddReferenceForTracing(live.get());
    const size_t initial_count = global_handles->handles_count();
    InvokeMarkSweep();
    const size_t final_count = global_handles->handles_count();
    CHECK_EQ(initial_count, final_count + 1);
  }
}

TEST(TracedReferenceHandlesDoNotLeak) {
  // TracedReference handles are not cleared by the destructor of the embedder
  // object. To avoid leaks we need to mark these handles during GC.
  // This test checks that unmarked handles do not leak.
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  auto ref = std::make_unique<v8::TracedReference<v8::Value>>();
  ref->Reset(isolate, v8::Undefined(isolate));
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();
  const size_t initial_count = global_handles->handles_count();
  // We need two GCs because handles are black allocated.
  InvokeMarkSweep();
  InvokeMarkSweep();
  const size_t final_count = global_handles->handles_count();
  CHECK_EQ(initial_count, final_count + 1);
}

TEST(TracedGlobalHandlesAreRetained) {
  // TracedGlobal handles are cleared by the destructor of the embedder object.
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  v8::TracedGlobal<v8::Value> global;
  global.Reset(isolate, v8::Undefined(isolate));
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();
  const size_t initial_count = global_handles->handles_count();
  // We need two GCs because handles are black allocated.
  InvokeMarkSweep();
  InvokeMarkSweep();
  const size_t final_count = global_handles->handles_count();
  CHECK_EQ(initial_count, final_count);
}

namespace {

class TracedGlobalVisitor final
    : public v8::EmbedderHeapTracer::TracedGlobalHandleVisitor {
 public:
  ~TracedGlobalVisitor() override = default;
  void VisitTracedGlobalHandle(const TracedGlobal<Value>& value) final {
    if (value.WrapperClassId() == 57) {
      count_++;
    }
  }

  size_t count() const { return count_; }

 private:
  size_t count_ = 0;
};

}  // namespace

TEST(TracedGlobalIteration) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);

  auto traced = std::make_unique<v8::TracedGlobal<v8::Object>>();
  ConstructJSObject(isolate, isolate->GetCurrentContext(), traced.get());
  CHECK(!traced->IsEmpty());
  traced->SetWrapperClassId(57);
  TracedGlobalVisitor visitor;
  {
    v8::HandleScope scope(isolate);
    tracer.IterateTracedGlobalHandles(&visitor);
  }
  CHECK_EQ(1, visitor.count());
}

namespace {

void FinalizationCallback(const WeakCallbackInfo<void>& data) {
  v8::TracedGlobal<v8::Object>* traced =
      reinterpret_cast<v8::TracedGlobal<v8::Object>*>(data.GetParameter());
  CHECK_EQ(reinterpret_cast<void*>(0x4), data.GetInternalField(0));
  CHECK_EQ(reinterpret_cast<void*>(0x8), data.GetInternalField(1));
  traced->Reset();
}

}  // namespace

TEST(TracedGlobalSetFinalizationCallbackScavenge) {
  if (FLAG_single_generation) return;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  TestEmbedderHeapTracer tracer;
  tracer.ConsiderTracedGlobalAsRoot(false);
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);

  auto traced = std::make_unique<v8::TracedGlobal<v8::Object>>();
  ConstructJSApiObject(isolate, isolate->GetCurrentContext(), traced.get());
  CHECK(!traced->IsEmpty());
  {
    v8::HandleScope scope(isolate);
    auto local = traced->Get(isolate);
    local->SetAlignedPointerInInternalField(0, reinterpret_cast<void*>(0x4));
    local->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(0x8));
  }
  traced->SetFinalizationCallback(traced.get(), FinalizationCallback);
  heap::InvokeScavenge();
  CHECK(traced->IsEmpty());
}

TEST(TracedGlobalSetFinalizationCallbackMarkSweep) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);

  auto traced = std::make_unique<v8::TracedGlobal<v8::Object>>();
  ConstructJSApiObject(isolate, isolate->GetCurrentContext(), traced.get());
  CHECK(!traced->IsEmpty());
  {
    v8::HandleScope scope(isolate);
    auto local = traced->Get(isolate);
    local->SetAlignedPointerInInternalField(0, reinterpret_cast<void*>(0x4));
    local->SetAlignedPointerInInternalField(1, reinterpret_cast<void*>(0x8));
  }
  traced->SetFinalizationCallback(traced.get(), FinalizationCallback);
  heap::InvokeMarkSweep();
  CHECK(traced->IsEmpty());
}

TEST(TracePrologueCallingIntoV8WriteBarrier) {
  // Regression test: https://crbug.com/940003
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  v8::Global<v8::Array> global;
  {
    v8::HandleScope scope(isolate);
    auto local = v8::Array::New(isolate, 10);
    global.Reset(isolate, local);
  }
  TestEmbedderHeapTracer tracer(TracePrologueBehavior::kCallV8WriteBarrier,
                                std::move(global));
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  SimulateIncrementalMarking(CcTest::i_isolate()->heap());
  // Finish GC to avoid removing the tracer while GC is running which may end up
  // in an infinite loop because of unprocessed objects.
  heap::InvokeMarkSweep();
}

TEST(TracedGlobalWithDestructor) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();

  const size_t initial_count = global_handles->handles_count();
  auto* traced = new v8::TracedGlobal<v8::Object>();
  {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Object> object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    CHECK(traced->IsEmpty());
    *traced = v8::TracedGlobal<v8::Object>(isolate, object);
    CHECK(!traced->IsEmpty());
    CHECK_EQ(initial_count + 1, global_handles->handles_count());
  }
  delete traced;
  CHECK_EQ(initial_count, global_handles->handles_count());
  // GC should not need to clear the handle.
  heap::InvokeMarkSweep();
  CHECK_EQ(initial_count, global_handles->handles_count());
}

TEST(TracedGlobalNoDestructor) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();

  const size_t initial_count = global_handles->handles_count();
  char* memory = new char[sizeof(v8::TracedReference<v8::Value>)];
  auto* traced = new (memory) v8::TracedReference<v8::Value>();
  {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Value> object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    CHECK(traced->IsEmpty());
    *traced = v8::TracedReference<v8::Value>(isolate, object);
    CHECK(!traced->IsEmpty());
    CHECK_EQ(initial_count + 1, global_handles->handles_count());
  }
  traced->~TracedReference<v8::Value>();
  CHECK_EQ(initial_count + 1, global_handles->handles_count());
  // GC should clear the handle.
  heap::InvokeMarkSweep();
  CHECK_EQ(initial_count, global_handles->handles_count());
  delete[] memory;
}

namespace {

class EmptyEmbedderHeapTracer : public v8::EmbedderHeapTracer {
 public:
  void RegisterV8References(
      const std::vector<std::pair<void*, void*>>& embedder_fields) final {}

  bool AdvanceTracing(double deadline_in_ms) final { return true; }
  bool IsTracingDone() final { return true; }
  void TracePrologue(EmbedderHeapTracer::TraceFlags) final {}
  void TraceEpilogue(TraceSummary*) final {}
  void EnterFinalPause(EmbedderStackState) final {}
};

// EmbedderHeapTracer that can optimize Scavenger handling when used with
// TraceGlobal handles that have destructors.
class EmbedderHeapTracerDestructorNonTracingClearing final
    : public EmptyEmbedderHeapTracer {
 public:
  explicit EmbedderHeapTracerDestructorNonTracingClearing(
      uint16_t class_id_to_optimize)
      : class_id_to_optimize_(class_id_to_optimize) {}

  bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle) final {
    return handle.WrapperClassId() != class_id_to_optimize_;
  }

 private:
  uint16_t class_id_to_optimize_;
};

// EmbedderHeapTracer that can optimize Scavenger handling when used with
// TraceGlobal handles without destructors.
class EmbedderHeapTracerNoDestructorNonTracingClearing final
    : public EmptyEmbedderHeapTracer {
 public:
  explicit EmbedderHeapTracerNoDestructorNonTracingClearing(
      uint16_t class_id_to_optimize)
      : class_id_to_optimize_(class_id_to_optimize) {}

  bool IsRootForNonTracingGC(
      const v8::TracedReference<v8::Value>& handle) final {
    return handle.WrapperClassId() != class_id_to_optimize_;
  }

  void ResetHandleInNonTracingGC(
      const v8::TracedReference<v8::Value>& handle) final {
    if (handle.WrapperClassId() != class_id_to_optimize_) return;

    // Convention (for test): Objects that are optimized have their first field
    // set as a back pointer.
    BasicTracedReference<v8::Value>* original_handle =
        reinterpret_cast<BasicTracedReference<v8::Value>*>(
            v8::Object::GetAlignedPointerFromInternalField(
                handle.As<v8::Object>(), 0));
    original_handle->Reset();
  }

 private:
  uint16_t class_id_to_optimize_;
};

template <typename T>
void SetupOptimizedAndNonOptimizedHandle(v8::Isolate* isolate,
                                         uint16_t optimized_class_id,
                                         T* optimized_handle,
                                         T* non_optimized_handle) {
  v8::HandleScope scope(isolate);

  v8::Local<v8::Object> optimized_object(ConstructTraceableJSApiObject(
      isolate->GetCurrentContext(), optimized_handle, nullptr));
  CHECK(optimized_handle->IsEmpty());
  *optimized_handle = T(isolate, optimized_object);
  CHECK(!optimized_handle->IsEmpty());
  optimized_handle->SetWrapperClassId(optimized_class_id);

  v8::Local<v8::Object> non_optimized_object(ConstructTraceableJSApiObject(
      isolate->GetCurrentContext(), nullptr, nullptr));
  CHECK(non_optimized_handle->IsEmpty());
  *non_optimized_handle = T(isolate, non_optimized_object);
  CHECK(!non_optimized_handle->IsEmpty());
}

}  // namespace

TEST(TracedGlobalDestructorReclaimedOnScavenge) {
  if (FLAG_single_generation) return;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  constexpr uint16_t kClassIdToOptimize = 17;
  EmbedderHeapTracerDestructorNonTracingClearing tracer(kClassIdToOptimize);
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();

  const size_t initial_count = global_handles->handles_count();
  auto* optimized_handle = new v8::TracedGlobal<v8::Object>();
  auto* non_optimized_handle = new v8::TracedGlobal<v8::Object>();
  SetupOptimizedAndNonOptimizedHandle(isolate, kClassIdToOptimize,
                                      optimized_handle, non_optimized_handle);
  CHECK_EQ(initial_count + 2, global_handles->handles_count());
  heap::InvokeScavenge();
  CHECK_EQ(initial_count + 1, global_handles->handles_count());
  CHECK(optimized_handle->IsEmpty());
  delete optimized_handle;
  CHECK(!non_optimized_handle->IsEmpty());
  delete non_optimized_handle;
  CHECK_EQ(initial_count, global_handles->handles_count());
}

TEST(TracedGlobalNoDestructorReclaimedOnScavenge) {
  if (FLAG_single_generation) return;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  constexpr uint16_t kClassIdToOptimize = 23;
  EmbedderHeapTracerNoDestructorNonTracingClearing tracer(kClassIdToOptimize);
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(isolate, &tracer);
  i::GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();

  const size_t initial_count = global_handles->handles_count();
  auto* optimized_handle = new v8::TracedReference<v8::Value>();
  auto* non_optimized_handle = new v8::TracedReference<v8::Value>();
  SetupOptimizedAndNonOptimizedHandle(isolate, kClassIdToOptimize,
                                      optimized_handle, non_optimized_handle);
  CHECK_EQ(initial_count + 2, global_handles->handles_count());
  heap::InvokeScavenge();
  CHECK_EQ(initial_count + 1, global_handles->handles_count());
  CHECK(optimized_handle->IsEmpty());
  delete optimized_handle;
  CHECK(!non_optimized_handle->IsEmpty());
  non_optimized_handle->Reset();
  delete non_optimized_handle;
  CHECK_EQ(initial_count, global_handles->handles_count());
}

namespace {

template <typename T>
V8_NOINLINE void OnStackTest(TestEmbedderHeapTracer* tracer) {
  v8::Isolate* isolate = CcTest::isolate();
  v8::Global<v8::Object> observer;
  T stack_ref;
  {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Object> object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    stack_ref.Reset(isolate, object);
    observer.Reset(isolate, object);
    observer.SetWeak();
  }
  CHECK(!observer.IsEmpty());
  heap::InvokeMarkSweep();
  CHECK(!observer.IsEmpty());
}

V8_NOINLINE void CreateTracedReferenceInDeepStack(
    v8::Isolate* isolate, v8::Global<v8::Object>* observer) {
  v8::TracedReference<v8::Value> stack_ref;
  v8::HandleScope scope(isolate);
  v8::Local<v8::Object> object(ConstructTraceableJSApiObject(
      isolate->GetCurrentContext(), nullptr, nullptr));
  stack_ref.Reset(isolate, object);
  observer->Reset(isolate, object);
  observer->SetWeak();
}

V8_NOINLINE void TracedReferenceNotifyEmptyStackTest(
    TestEmbedderHeapTracer* tracer) {
  v8::Isolate* isolate = CcTest::isolate();
  v8::Global<v8::Object> observer;
  CreateTracedReferenceInDeepStack(isolate, &observer);
  CHECK(!observer.IsEmpty());
  tracer->NotifyEmptyEmbedderStack();
  heap::InvokeMarkSweep();
  CHECK(observer.IsEmpty());
}

enum class Operation {
  kCopy,
  kMove,
};

template <typename T>
void PerformOperation(Operation op, T* lhs, T* rhs) {
  switch (op) {
    case Operation::kMove:
      *lhs = std::move(*rhs);
      break;
    case Operation::kCopy:
      *lhs = *rhs;
      rhs->Reset();
      break;
  }
}

enum class TargetHandling {
  kNonInitialized,
  kInitializedYoungGen,
  kInitializedOldGen
};

template <typename T>
V8_NOINLINE void StackToHeapTest(TestEmbedderHeapTracer* tracer, Operation op,
                                 TargetHandling target_handling) {
  v8::Isolate* isolate = CcTest::isolate();
  v8::Global<v8::Object> observer;
  T stack_handle;
  T* heap_handle = new T();
  if (target_handling != TargetHandling::kNonInitialized) {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Object> to_object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    CHECK(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object)));
    if (!FLAG_single_generation &&
        target_handling == TargetHandling::kInitializedOldGen) {
      heap::InvokeScavenge();
      heap::InvokeScavenge();
      CHECK(!i::Heap::InYoungGeneration(*v8::Utils::OpenHandle(*to_object)));
    }
    heap_handle->Reset(isolate, to_object);
  }
  {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Object> object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    stack_handle.Reset(isolate, object);
    observer.Reset(isolate, object);
    observer.SetWeak();
  }
  CHECK(!observer.IsEmpty());
  tracer->AddReferenceForTracing(heap_handle);
  heap::InvokeMarkSweep();
  CHECK(!observer.IsEmpty());
  tracer->AddReferenceForTracing(heap_handle);
  PerformOperation(op, heap_handle, &stack_handle);
  heap::InvokeMarkSweep();
  CHECK(!observer.IsEmpty());
  heap::InvokeMarkSweep();
  CHECK(observer.IsEmpty());
  delete heap_handle;
}

template <typename T>
V8_NOINLINE void HeapToStackTest(TestEmbedderHeapTracer* tracer, Operation op,
                                 TargetHandling target_handling) {
  v8::Isolate* isolate = CcTest::isolate();
  v8::Global<v8::Object> observer;
  T stack_handle;
  T* heap_handle = new T();
  if (target_handling != TargetHandling::kNonInitialized) {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Object> to_object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    CHECK(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object)));
    if (!FLAG_single_generation &&
        target_handling == TargetHandling::kInitializedOldGen) {
      heap::InvokeScavenge();
      heap::InvokeScavenge();
      CHECK(!i::Heap::InYoungGeneration(*v8::Utils::OpenHandle(*to_object)));
    }
    stack_handle.Reset(isolate, to_object);
  }
  {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Object> object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    heap_handle->Reset(isolate, object);
    observer.Reset(isolate, object);
    observer.SetWeak();
  }
  CHECK(!observer.IsEmpty());
  tracer->AddReferenceForTracing(heap_handle);
  heap::InvokeMarkSweep();
  CHECK(!observer.IsEmpty());
  PerformOperation(op, &stack_handle, heap_handle);
  heap::InvokeMarkSweep();
  CHECK(!observer.IsEmpty());
  stack_handle.Reset();
  heap::InvokeMarkSweep();
  CHECK(observer.IsEmpty());
  delete heap_handle;
}

template <typename T>
V8_NOINLINE void StackToStackTest(TestEmbedderHeapTracer* tracer, Operation op,
                                  TargetHandling target_handling) {
  v8::Isolate* isolate = CcTest::isolate();
  v8::Global<v8::Object> observer;
  T stack_handle1;
  T stack_handle2;
  if (target_handling != TargetHandling::kNonInitialized) {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Object> to_object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    CHECK(InCorrectGeneration(*v8::Utils::OpenHandle(*to_object)));
    if (!FLAG_single_generation &&
        target_handling == TargetHandling::kInitializedOldGen) {
      heap::InvokeScavenge();
      heap::InvokeScavenge();
      CHECK(!i::Heap::InYoungGeneration(*v8::Utils::OpenHandle(*to_object)));
    }
    stack_handle2.Reset(isolate, to_object);
  }
  {
    v8::HandleScope scope(isolate);
    v8::Local<v8::Object> object(ConstructTraceableJSApiObject(
        isolate->GetCurrentContext(), nullptr, nullptr));
    stack_handle1.Reset(isolate, object);
    observer.Reset(isolate, object);
    observer.SetWeak();
  }
  CHECK(!observer.IsEmpty());
  heap::InvokeMarkSweep();
  CHECK(!observer.IsEmpty());
  PerformOperation(op, &stack_handle2, &stack_handle1);
  heap::InvokeMarkSweep();
  CHECK(!observer.IsEmpty());
  stack_handle2.Reset();
  heap::InvokeMarkSweep();
  CHECK(observer.IsEmpty());
}

template <typename T>
V8_NOINLINE void TracedReferenceCleanedTest(TestEmbedderHeapTracer* tracer) {
  v8::Isolate* isolate = CcTest::isolate();
  v8::HandleScope scope(isolate);
  v8::Local<v8::Object> object(ConstructTraceableJSApiObject(
      isolate->GetCurrentContext(), nullptr, nullptr));
  const size_t before =
      CcTest::i_isolate()->global_handles()->NumberOfOnStackHandlesForTesting();
  for (int i = 0; i < 100; i++) {
    T stack_handle;
    stack_handle.Reset(isolate, object);
  }
  CHECK_EQ(before + 1, CcTest::i_isolate()
                           ->global_handles()
                           ->NumberOfOnStackHandlesForTesting());
}

V8_NOINLINE void TracedGlobalDestructorTest(TestEmbedderHeapTracer* tracer) {
  v8::Isolate* isolate = CcTest::isolate();
  v8::Global<v8::Object> observer;
  {
    v8::TracedGlobal<v8::Value> stack_handle;
    {
      v8::HandleScope scope(isolate);
      v8::Local<v8::Object> object(ConstructTraceableJSApiObject(
          isolate->GetCurrentContext(), nullptr, nullptr));
      stack_handle.Reset(isolate, object);
      observer.Reset(isolate, object);
      observer.SetWeak();
    }
    CHECK(!observer.IsEmpty());
    heap::InvokeMarkSweep();
    CHECK(!observer.IsEmpty());
  }
  heap::InvokeMarkSweep();
  CHECK(observer.IsEmpty());
}

}  // namespace

TEST(TracedReferenceOnStack) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  OnStackTest<v8::TracedReference<v8::Value>>(&tracer);
}

TEST(TracedGlobalOnStack) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  OnStackTest<v8::TracedGlobal<v8::Value>>(&tracer);
}

TEST(TracedReferenceCleaned) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  TracedReferenceCleanedTest<v8::TracedReference<v8::Value>>(&tracer);
}

TEST(TracedGlobalCleaned) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  TracedReferenceCleanedTest<v8::TracedGlobal<v8::Value>>(&tracer);
}

TEST(TracedReferenceMove) {
  using ReferenceType = v8::TracedReference<v8::Value>;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kNonInitialized);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kInitializedYoungGen);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kInitializedOldGen);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kNonInitialized);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kInitializedYoungGen);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kInitializedOldGen);
  StackToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                  TargetHandling::kNonInitialized);
  StackToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                  TargetHandling::kInitializedYoungGen);
  StackToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                  TargetHandling::kInitializedOldGen);
}

TEST(TracedReferenceCopy) {
  using ReferenceType = v8::TracedReference<v8::Value>;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kNonInitialized);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kInitializedYoungGen);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kInitializedOldGen);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kNonInitialized);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kInitializedYoungGen);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kInitializedOldGen);
  StackToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                  TargetHandling::kNonInitialized);
  StackToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                  TargetHandling::kInitializedYoungGen);
  StackToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                  TargetHandling::kInitializedOldGen);
}

TEST(TracedGlobalMove) {
  using ReferenceType = v8::TracedGlobal<v8::Value>;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kNonInitialized);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kInitializedYoungGen);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kInitializedOldGen);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kNonInitialized);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kInitializedYoungGen);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                 TargetHandling::kInitializedOldGen);
  StackToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                  TargetHandling::kNonInitialized);
  StackToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                  TargetHandling::kInitializedYoungGen);
  StackToStackTest<ReferenceType>(&tracer, Operation::kMove,
                                  TargetHandling::kInitializedOldGen);
}

TEST(TracedGlobalCopy) {
  using ReferenceType = v8::TracedGlobal<v8::Value>;
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kNonInitialized);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kInitializedYoungGen);
  StackToHeapTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kInitializedOldGen);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kNonInitialized);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kInitializedYoungGen);
  HeapToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                 TargetHandling::kInitializedOldGen);
  StackToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                  TargetHandling::kNonInitialized);
  StackToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                  TargetHandling::kInitializedYoungGen);
  StackToStackTest<ReferenceType>(&tracer, Operation::kCopy,
                                  TargetHandling::kInitializedOldGen);
}

TEST(TracedGlobalDestructor) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  TracedGlobalDestructorTest(&tracer);
}

TEST(NotifyEmptyStack) {
  ManualGCScope manual_gc;
  CcTest::InitializeVM();
  TestEmbedderHeapTracer tracer;
  heap::TemporaryEmbedderHeapTracerScope tracer_scope(CcTest::isolate(),
                                                      &tracer);
  tracer.SetStackStart(&manual_gc);
  TracedReferenceNotifyEmptyStackTest(&tracer);
}

}  // namespace heap
}  // namespace internal
}  // namespace v8
