// Copyright 2016 The Chromium 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 "third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/core/testing/death_aware_script_wrappable.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"

namespace blink {

namespace {

// Temporarily swaps out the underlying ScriptWrappableMarkingVisitor from a
// given v8::Isolate. Gracefully finalized potentially running garbage
// collections.
class TemporaryScriptWrappableVisitorScope {
  WTF_MAKE_NONCOPYABLE(TemporaryScriptWrappableVisitorScope);
  STACK_ALLOCATED();

 public:
  TemporaryScriptWrappableVisitorScope(
      v8::Isolate* isolate,
      std::unique_ptr<ScriptWrappableMarkingVisitor> controller)
      : isolate_(isolate), saved_controller_(std::move(controller)) {
    SwapWithV8PerIsolateDataVisitor();
  }
  ~TemporaryScriptWrappableVisitorScope() { SwapWithV8PerIsolateDataVisitor(); }

  ScriptWrappableMarkingVisitor* CurrentVisitor() {
    return V8PerIsolateData::From(isolate_)->GetScriptWrappableMarkingVisitor();
  }

 private:
  void SwapWithV8PerIsolateDataVisitor() {
    ScriptWrappableMarkingVisitor* current = CurrentVisitor();
    if (current)
      ScriptWrappableMarkingVisitor::PerformCleanup(isolate_);

    V8PerIsolateData::From(isolate_)->SwapScriptWrappableMarkingVisitor(
        saved_controller_);
    isolate_->SetEmbedderHeapTracer(CurrentVisitor());
  }

  v8::Isolate* const isolate_;
  std::unique_ptr<ScriptWrappableMarkingVisitor> saved_controller_;
};

class InterceptingScriptWrappableMarkingVisitor
    : public blink::ScriptWrappableMarkingVisitor {
 public:
  InterceptingScriptWrappableMarkingVisitor()
      : ScriptWrappableMarkingVisitor(ThreadState::Current()),
        marked_wrappers_(new size_t(0)) {}
  ~InterceptingScriptWrappableMarkingVisitor() override {
    delete marked_wrappers_;
  }

  void Visit(const TraceWrapperV8Reference<v8::Value>&) override {
    *marked_wrappers_ += 1;
    // Do not actually mark this visitor, as this would call into v8, which
    // would require executing an actual GC.
  }

  size_t NumberOfMarkedWrappers() const { return *marked_wrappers_; }

  void Start() { TracePrologue(); }

  void end() {
    // Gracefully terminate tracing.
    AdvanceTracing(std::numeric_limits<double>::infinity());
    AbortTracingForTermination();
  }

 private:
  size_t* marked_wrappers_;  // Indirection required because of const override.
};

class InterceptingScriptWrappableMarkingVisitorScope
    : public TemporaryScriptWrappableVisitorScope {
  WTF_MAKE_NONCOPYABLE(InterceptingScriptWrappableMarkingVisitorScope);
  STACK_ALLOCATED();

 public:
  InterceptingScriptWrappableMarkingVisitorScope(v8::Isolate* isolate)
      : TemporaryScriptWrappableVisitorScope(
            isolate,
            std::unique_ptr<InterceptingScriptWrappableMarkingVisitor>(
                new InterceptingScriptWrappableMarkingVisitor())) {
    Visitor()->Start();
  }

  virtual ~InterceptingScriptWrappableMarkingVisitorScope() {
    Visitor()->end();
  }

  InterceptingScriptWrappableMarkingVisitor* Visitor() {
    return reinterpret_cast<InterceptingScriptWrappableMarkingVisitor*>(
        CurrentVisitor());
  }
};

void PreciselyCollectGarbage() {
  ThreadState::Current()->CollectAllGarbage();
}

}  // namespace

// =============================================================================
// Wrapper tracing tests for Blink handling. ===================================
// =============================================================================

TEST(ScriptWrappableMarkingVisitorTest,
     ScriptWrappableMarkingVisitorTracesWrappers) {
  V8TestingScope scope;

  DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create();
  DeathAwareScriptWrappable* dependency = DeathAwareScriptWrappable::Create();
  target->SetWrappedDependency(dependency);

  // The graph needs to be set up before starting tracing as otherwise the
  // conservative write barrier would trigger.
  InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
      scope.GetIsolate());
  ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();

  HeapObjectHeader* target_header = HeapObjectHeader::FromPayload(target);
  HeapObjectHeader* dependency_header =
      HeapObjectHeader::FromPayload(dependency);

  EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());
  EXPECT_FALSE(target_header->IsWrapperHeaderMarked());
  EXPECT_FALSE(dependency_header->IsWrapperHeaderMarked());

  std::pair<void*, void*> pair = std::make_pair(
      const_cast<WrapperTypeInfo*>(target->GetWrapperTypeInfo()), target);
  visitor->RegisterV8Reference(pair);
  EXPECT_EQ(visitor->MarkingDeque()->size(), 1ul);

  visitor->AdvanceTracing(std::numeric_limits<double>::infinity());
  EXPECT_EQ(visitor->MarkingDeque()->size(), 0ul);
  EXPECT_TRUE(target_header->IsWrapperHeaderMarked());
  EXPECT_TRUE(dependency_header->IsWrapperHeaderMarked());
}

TEST(ScriptWrappableMarkingVisitorTest,
     OilpanClearsMarkingDequeWhenObjectDied) {
  V8TestingScope scope;

  DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
  InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
      scope.GetIsolate());
  ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();

  visitor->TraceWithWrappers(object);

  EXPECT_EQ(visitor->MarkingDeque()->front().RawObjectPointer(), object);

  PreciselyCollectGarbage();

  EXPECT_EQ(visitor->MarkingDeque()->front().RawObjectPointer(), nullptr);
}

TEST(ScriptWrappableMarkingVisitorTest,
     MarkedObjectDoesNothingOnWriteBarrierHitWhenDependencyIsMarkedToo) {
  V8TestingScope scope;

  InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
      scope.GetIsolate());
  ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();

  DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create();
  DeathAwareScriptWrappable* dependencies[] = {
      DeathAwareScriptWrappable::Create(), DeathAwareScriptWrappable::Create(),
      DeathAwareScriptWrappable::Create(), DeathAwareScriptWrappable::Create()};

  HeapObjectHeader::FromPayload(target)->MarkWrapperHeader();
  for (int i = 0; i < 4; i++) {
    HeapObjectHeader::FromPayload(dependencies[i])->MarkWrapperHeader();
  }

  EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());

  target->SetWrappedDependency(dependencies[0]);
  target->AddWrappedVectorDependency(dependencies[1]);
  target->AddWrappedHashMapDependency(dependencies[2], dependencies[3]);

  EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());
}

TEST(ScriptWrappableMarkingVisitorTest,
     MarkedObjectMarksDependencyOnWriteBarrierHitWhenNotMarked) {
  V8TestingScope scope;

  InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
      scope.GetIsolate());
  ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();

  DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create();
  DeathAwareScriptWrappable* dependencies[] = {
      DeathAwareScriptWrappable::Create(), DeathAwareScriptWrappable::Create(),
      DeathAwareScriptWrappable::Create(), DeathAwareScriptWrappable::Create()};

  HeapObjectHeader::FromPayload(target)->MarkWrapperHeader();

  EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());

  target->SetWrappedDependency(dependencies[0]);
  target->AddWrappedVectorDependency(dependencies[1]);
  target->AddWrappedHashMapDependency(dependencies[2], dependencies[3]);

  for (int i = 0; i < 4; i++) {
    EXPECT_TRUE(visitor->MarkingDequeContains(dependencies[i]));
  }
}

namespace {

class HandleContainer
    : public blink::GarbageCollectedFinalized<HandleContainer> {
 public:
  static HandleContainer* Create() { return new HandleContainer(); }
  virtual ~HandleContainer() = default;

  void Trace(blink::Visitor* visitor) {
    visitor->Trace(handle_.Cast<v8::Value>());
  }

  void SetValue(v8::Isolate* isolate, v8::Local<v8::String> string) {
    handle_.Set(isolate, string);
  }

 private:
  HandleContainer() = default;

  TraceWrapperV8Reference<v8::String> handle_;
};

}  // namespace

TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnUnmarkedContainer) {
  V8TestingScope scope;
  InterceptingScriptWrappableMarkingVisitorScope visitor_scope(
      scope.GetIsolate());
  auto* raw_visitor = visitor_scope.Visitor();

  v8::Local<v8::String> str =
      v8::String::NewFromUtf8(scope.GetIsolate(), "teststring",
                              v8::NewStringType::kNormal, sizeof("teststring"))
          .ToLocalChecked();
  HandleContainer* container = HandleContainer::Create();
  CHECK_EQ(0u, raw_visitor->NumberOfMarkedWrappers());
  container->SetValue(scope.GetIsolate(), str);
  // The write barrier is conservative and does not check the mark bits of the
  // source container.
  CHECK_EQ(1u, raw_visitor->NumberOfMarkedWrappers());
}

TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierTriggersOnMarkedContainer) {
  V8TestingScope scope;
  InterceptingScriptWrappableMarkingVisitorScope visitor_scope(
      scope.GetIsolate());
  auto* raw_visitor = visitor_scope.Visitor();

  v8::Local<v8::String> str =
      v8::String::NewFromUtf8(scope.GetIsolate(), "teststring",
                              v8::NewStringType::kNormal, sizeof("teststring"))
          .ToLocalChecked();
  HandleContainer* container = HandleContainer::Create();
  HeapObjectHeader::FromPayload(container)->MarkWrapperHeader();
  CHECK_EQ(0u, raw_visitor->NumberOfMarkedWrappers());
  container->SetValue(scope.GetIsolate(), str);
  CHECK_EQ(1u, raw_visitor->NumberOfMarkedWrappers());
}

TEST(ScriptWrappableMarkingVisitorTest, VtableAtObjectStart) {
  // This test makes sure that the subobject v8::EmbedderHeapTracer is placed
  // at the start of a ScriptWrappableMarkingVisitor object. We do this to
  // mitigate potential problems that could be caused by LTO when passing
  // v8::EmbedderHeapTracer across the API boundary.
  std::unique_ptr<blink::ScriptWrappableMarkingVisitor> visitor(
      new ScriptWrappableMarkingVisitor(ThreadState::Current()));
  CHECK_EQ(
      static_cast<void*>(visitor.get()),
      static_cast<void*>(dynamic_cast<v8::EmbedderHeapTracer*>(visitor.get())));
}

TEST(ScriptWrappableMarkingVisitor, WriteBarrierForScriptWrappable) {
  // Regression test for crbug.com/702490.
  V8TestingScope scope;
  InterceptingScriptWrappableMarkingVisitorScope visitor_scope(
      scope.GetIsolate());
  auto* raw_visitor = visitor_scope.Visitor();

  // Mark the ScriptWrappable.
  DeathAwareScriptWrappable* target = DeathAwareScriptWrappable::Create();
  HeapObjectHeader::FromPayload(target)->MarkWrapperHeader();

  // Create a 'wrapper' object.
  v8::Local<v8::Object> wrapper = V8DOMWrapper::CreateWrapper(
      scope.GetIsolate(), scope.GetContext()->Global(),
      target->GetWrapperTypeInfo());

  // Upon setting the wrapper we should have executed the write barrier.
  CHECK_EQ(0u, raw_visitor->NumberOfMarkedWrappers());
  v8::Local<v8::Object> final_wrapper =
      V8DOMWrapper::AssociateObjectWithWrapper(
          scope.GetIsolate(), target, target->GetWrapperTypeInfo(), wrapper);
  CHECK(!final_wrapper.IsEmpty());
  CHECK_EQ(1u, raw_visitor->NumberOfMarkedWrappers());
}

TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap1) {
  V8TestingScope scope;

  HeapVector<DeathAwareScriptWrappable::Wrapper> vector1;
  DeathAwareScriptWrappable* entry1 = DeathAwareScriptWrappable::Create();
  vector1.push_back(entry1);
  HeapVector<DeathAwareScriptWrappable::Wrapper> vector2;
  DeathAwareScriptWrappable* entry2 = DeathAwareScriptWrappable::Create();
  vector2.push_back(entry2);

  InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
      scope.GetIsolate());
  ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();

  EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());
  swap(vector1, vector2);

  EXPECT_TRUE(visitor->MarkingDequeContains(entry1));
  EXPECT_TRUE(visitor->MarkingDequeContains(entry2));
}

TEST(ScriptWrappableMarkingVisitorTest, WriteBarrierOnHeapVectorSwap2) {
  V8TestingScope scope;

  HeapVector<DeathAwareScriptWrappable::Wrapper> vector1;
  DeathAwareScriptWrappable* entry1 = DeathAwareScriptWrappable::Create();
  vector1.push_back(entry1);
  HeapVector<Member<DeathAwareScriptWrappable>> vector2;
  DeathAwareScriptWrappable* entry2 = DeathAwareScriptWrappable::Create();
  vector2.push_back(entry2);

  InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
      scope.GetIsolate());
  ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();

  EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());
  swap(vector1, vector2);

  // Only entry2 is held alive by TraceWrapperMember, so we only expect this
  // barrier to fire.
  EXPECT_TRUE(visitor->MarkingDequeContains(entry2));
}

namespace {

class Mixin : public GarbageCollectedMixin {
 public:
  explicit Mixin(DeathAwareScriptWrappable* wrapper_in_mixin)
      : wrapper_in_mixin_(wrapper_in_mixin) {}

  void Trace(Visitor* visitor) override { visitor->Trace(wrapper_in_mixin_); }

 protected:
  DeathAwareScriptWrappable::Wrapper wrapper_in_mixin_;
};

class ClassWithField {
 protected:
  int field_;
};

class Base : public blink::GarbageCollected<Base>,
             public NameClient,  // Force vtable on Base.
             public ClassWithField,
             public Mixin {
  USING_GARBAGE_COLLECTED_MIXIN(Base);

 public:
  static Base* Create(DeathAwareScriptWrappable* wrapper_in_base,
                      DeathAwareScriptWrappable* wrapper_in_mixin) {
    return new Base(wrapper_in_base, wrapper_in_mixin);
  }

  void Trace(Visitor* visitor) override {
    visitor->Trace(wrapper_in_base_);
    Mixin::Trace(visitor);
  }

  const char* NameInHeapSnapshot() const override { return "HandleContainer"; }

 protected:
  Base(DeathAwareScriptWrappable* wrapper_in_base,
       DeathAwareScriptWrappable* wrapper_in_mixin)
      : Mixin(wrapper_in_mixin), wrapper_in_base_(wrapper_in_base) {
    // Use field_;
    field_ = 0;
  }

  DeathAwareScriptWrappable::Wrapper wrapper_in_base_;
};

}  // namespace

TEST(ScriptWrappableMarkingVisitorTest, MixinTracing) {
  V8TestingScope scope;

  DeathAwareScriptWrappable* base_wrapper = DeathAwareScriptWrappable::Create();
  DeathAwareScriptWrappable* mixin_wrapper =
      DeathAwareScriptWrappable::Create();
  Base* base = Base::Create(base_wrapper, mixin_wrapper);
  Mixin* mixin = static_cast<Mixin*>(base);
  HeapObjectHeader* base_header = HeapObjectHeader::FromPayload(base);
  EXPECT_FALSE(base_header->IsWrapperHeaderMarked());

  // Make sure that mixin does not point to the object header.
  EXPECT_NE(static_cast<void*>(base), static_cast<void*>(mixin));

  InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
      scope.GetIsolate());
  ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();

  EXPECT_TRUE(visitor->MarkingDeque()->IsEmpty());

  // TraceWrapperMember itself is not required to live in an Oilpan object.
  TraceWrapperMember<Mixin> mixin_handle = mixin;
  EXPECT_TRUE(base_header->IsWrapperHeaderMarked());
  EXPECT_FALSE(visitor->MarkingDeque()->IsEmpty());
  EXPECT_TRUE(visitor->MarkingDequeContains(base));

  visitor->AdvanceTracing(std::numeric_limits<double>::infinity());
  EXPECT_EQ(visitor->MarkingDeque()->size(), 0ul);
  EXPECT_TRUE(base_header->IsWrapperHeaderMarked());
  EXPECT_TRUE(
      HeapObjectHeader::FromPayload(base_wrapper)->IsWrapperHeaderMarked());
  EXPECT_TRUE(
      HeapObjectHeader::FromPayload(mixin_wrapper)->IsWrapperHeaderMarked());

  mixin_handle = nullptr;
}

TEST(ScriptWrappableMarkingVisitorTest, OilpanClearsHeadersWhenObjectDied) {
  V8TestingScope scope;

  DeathAwareScriptWrappable* object = DeathAwareScriptWrappable::Create();
  InterceptingScriptWrappableMarkingVisitorScope intercepting_scope(
      scope.GetIsolate());
  ScriptWrappableMarkingVisitor* visitor = intercepting_scope.Visitor();
  auto* header = HeapObjectHeader::FromPayload(object);
  visitor->headers_to_unmark_.push_back(header);
  object = nullptr;

  PreciselyCollectGarbage();

  EXPECT_FALSE(visitor->headers_to_unmark_.Contains(header));
}

}  // namespace blink
