// Copyright 2020 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 "src/api/api.h"
#include "src/base/platform/semaphore.h"
#include "src/handles/handles-inl.h"
#include "src/handles/persistent-handles.h"
#include "src/heap/heap.h"
#include "src/heap/local-heap.h"
#include "src/objects/transitions-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/heap/heap-utils.h"
#include "test/cctest/test-transitions.h"

namespace v8 {
namespace internal {

namespace {

// Background search thread class
class ConcurrentSearchThread : public v8::base::Thread {
 public:
  ConcurrentSearchThread(Heap* heap, base::Semaphore* background_thread_started,
                         std::unique_ptr<PersistentHandles> ph,
                         Handle<Name> name, Handle<Map> map,
                         base::Optional<Handle<Map>> result_map)
      : v8::base::Thread(base::Thread::Options("ThreadWithLocalHeap")),
        heap_(heap),
        background_thread_started_(background_thread_started),
        ph_(std::move(ph)),
        name_(name),
        map_(map),
        result_map_(result_map) {}

  void Run() override {
    LocalHeap local_heap(heap_, ThreadKind::kBackground, std::move(ph_));
    UnparkedScope scope(&local_heap);

    background_thread_started_->Signal();

    CHECK_EQ(TransitionsAccessor(CcTest::i_isolate(), map_, true)
                 .SearchTransition(*name_, kData, NONE),
             result_map_ ? **result_map_ : Map());
  }

  // protected instead of private due to having a subclass.
 protected:
  Heap* heap_;
  base::Semaphore* background_thread_started_;
  std::unique_ptr<PersistentHandles> ph_;
  Handle<Name> name_;
  Handle<Map> map_;
  base::Optional<Handle<Map>> result_map_;
};

// Background search thread class that creates the transitions accessor before
// the main thread modifies the TransitionArray, and searches the transition
// only after the main thread finished.
class ConcurrentSearchOnOutdatedAccessorThread final
    : public ConcurrentSearchThread {
 public:
  ConcurrentSearchOnOutdatedAccessorThread(
      Heap* heap, base::Semaphore* background_thread_started,
      base::Semaphore* main_thread_finished,
      std::unique_ptr<PersistentHandles> ph, Handle<Name> name, Handle<Map> map,
      Handle<Map> result_map)
      : ConcurrentSearchThread(heap, background_thread_started, std::move(ph),
                               name, map, result_map),
        main_thread_finished_(main_thread_finished) {}

  void Run() override {
    LocalHeap local_heap(heap_, ThreadKind::kBackground, std::move(ph_));
    UnparkedScope scope(&local_heap);

    TransitionsAccessor accessor(CcTest::i_isolate(), map_, true);
    background_thread_started_->Signal();
    main_thread_finished_->Wait();

    CHECK_EQ(accessor.SearchTransition(*name_, kData, NONE),
             result_map_ ? **result_map_ : Map());
  }

  base::Semaphore* main_thread_finished_;
};

// Search on the main thread and in the background thread at the same time.
TEST(FullFieldTransitions_OnlySearch) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();

  Handle<String> name = CcTest::MakeString("name");
  const PropertyAttributes attributes = NONE;
  const PropertyKind kind = kData;

  // Set map0 to be a full transition array with transition 'name' to map1.
  Handle<Map> map0 = Map::Create(isolate, 0);
  Handle<Map> map1 =
      Map::CopyWithField(isolate, map0, name, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  TransitionsAccessor(isolate, map0).Insert(name, map1, PROPERTY_TRANSITION);
  {
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK(transitions.IsFullTransitionArrayEncoding());
  }

  std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();

  Handle<Name> persistent_name = ph->NewHandle(name);
  Handle<Map> persistent_map0 = ph->NewHandle(map0);
  Handle<Map> persistent_result_map1 = ph->NewHandle(map1);

  base::Semaphore background_thread_started(0);

  // Pass persistent handles to background thread.
  std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
      isolate->heap(), &background_thread_started, std::move(ph),
      persistent_name, persistent_map0, persistent_result_map1));
  CHECK(thread->Start());

  background_thread_started.Wait();

  CHECK_EQ(*map1, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name, kind, attributes));

  thread->Join();
}

// Search and insert on the main thread, while the background thread searches at
// the same time.
TEST(FullFieldTransitions) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();

  Handle<String> name1 = CcTest::MakeString("name1");
  Handle<String> name2 = CcTest::MakeString("name2");
  const PropertyAttributes attributes = NONE;
  const PropertyKind kind = kData;

  // Set map0 to be a full transition array with transition 'name1' to map1.
  Handle<Map> map0 = Map::Create(isolate, 0);
  Handle<Map> map1 =
      Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  Handle<Map> map2 =
      Map::CopyWithField(isolate, map0, name2, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  TransitionsAccessor(isolate, map0).Insert(name1, map1, PROPERTY_TRANSITION);
  {
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK(transitions.IsFullTransitionArrayEncoding());
  }

  std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();

  Handle<Name> persistent_name1 = ph->NewHandle(name1);
  Handle<Map> persistent_map0 = ph->NewHandle(map0);
  Handle<Map> persistent_result_map1 = ph->NewHandle(map1);

  base::Semaphore background_thread_started(0);

  // Pass persistent handles to background thread.
  std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
      isolate->heap(), &background_thread_started, std::move(ph),
      persistent_name1, persistent_map0, persistent_result_map1));
  CHECK(thread->Start());

  background_thread_started.Wait();

  CHECK_EQ(*map1, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name1, kind, attributes));
  TransitionsAccessor(isolate, map0).Insert(name2, map2, PROPERTY_TRANSITION);
  CHECK_EQ(*map2, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name2, kind, attributes));

  thread->Join();
}

// Search and insert on the main thread which changes the encoding from kWeakRef
// to kFullTransitionArray, while the background thread searches at the same
// time.
TEST(WeakRefToFullFieldTransitions) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();

  Handle<String> name1 = CcTest::MakeString("name1");
  Handle<String> name2 = CcTest::MakeString("name2");
  const PropertyAttributes attributes = NONE;
  const PropertyKind kind = kData;

  // Set map0 to be a simple transition array with transition 'name1' to map1.
  Handle<Map> map0 = Map::Create(isolate, 0);
  Handle<Map> map1 =
      Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  Handle<Map> map2 =
      Map::CopyWithField(isolate, map0, name2, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  TransitionsAccessor(isolate, map0)
      .Insert(name1, map1, SIMPLE_PROPERTY_TRANSITION);
  {
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK(transitions.IsWeakRefEncoding());
  }

  std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();

  Handle<Name> persistent_name1 = ph->NewHandle(name1);
  Handle<Map> persistent_map0 = ph->NewHandle(map0);
  Handle<Map> persistent_result_map1 = ph->NewHandle(map1);

  base::Semaphore background_thread_started(0);

  // Pass persistent handles to background thread.
  std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
      isolate->heap(), &background_thread_started, std::move(ph),
      persistent_name1, persistent_map0, persistent_result_map1));
  CHECK(thread->Start());

  background_thread_started.Wait();

  CHECK_EQ(*map1, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name1, kind, attributes));
  TransitionsAccessor(isolate, map0)
      .Insert(name2, map2, SIMPLE_PROPERTY_TRANSITION);
  {
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK(transitions.IsFullTransitionArrayEncoding());
  }
  CHECK_EQ(*map2, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name2, kind, attributes));

  thread->Join();
}

// Search and insert on the main thread, while the background thread searches at
// the same time. In this case, we have a kFullTransitionArray with enough slack
// when we are concurrently writing.
TEST(FullFieldTransitions_withSlack) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();

  Handle<String> name1 = CcTest::MakeString("name1");
  Handle<String> name2 = CcTest::MakeString("name2");
  Handle<String> name3 = CcTest::MakeString("name3");
  const PropertyAttributes attributes = NONE;
  const PropertyKind kind = kData;

  // Set map0 to be a full transition array with transition 'name1' to map1.
  Handle<Map> map0 = Map::Create(isolate, 0);
  Handle<Map> map1 =
      Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  Handle<Map> map2 =
      Map::CopyWithField(isolate, map0, name2, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  Handle<Map> map3 =
      Map::CopyWithField(isolate, map0, name3, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  TransitionsAccessor(isolate, map0).Insert(name1, map1, PROPERTY_TRANSITION);
  TransitionsAccessor(isolate, map0).Insert(name2, map2, PROPERTY_TRANSITION);
  {
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK(transitions.IsFullTransitionArrayEncoding());
  }

  std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();

  Handle<Name> persistent_name1 = ph->NewHandle(name1);
  Handle<Map> persistent_map0 = ph->NewHandle(map0);
  Handle<Map> persistent_result_map1 = ph->NewHandle(map1);

  base::Semaphore background_thread_started(0);

  // Pass persistent handles to background thread.
  std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
      isolate->heap(), &background_thread_started, std::move(ph),
      persistent_name1, persistent_map0, persistent_result_map1));
  CHECK(thread->Start());

  background_thread_started.Wait();

  CHECK_EQ(*map1, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name1, kind, attributes));
  CHECK_EQ(*map2, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name2, kind, attributes));
  {
    // Check that we have enough slack for the 3rd insertion into the
    // TransitionArray.
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK_GE(transitions.Capacity(), 3);
  }
  TransitionsAccessor(isolate, map0).Insert(name3, map3, PROPERTY_TRANSITION);
  CHECK_EQ(*map3, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name3, kind, attributes));

  thread->Join();
}

// Search and insert on the main thread which changes the encoding from
// kUninitialized to kFullTransitionArray, while the background thread searches
// at the same time.
TEST(UninitializedToFullFieldTransitions) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();

  Handle<String> name1 = CcTest::MakeString("name1");
  Handle<String> name2 = CcTest::MakeString("name2");
  const PropertyAttributes attributes = NONE;
  const PropertyKind kind = kData;

  // Set map0 to be a full transition array with transition 'name1' to map1.
  Handle<Map> map0 = Map::Create(isolate, 0);
  Handle<Map> map1 =
      Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  {
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK(transitions.IsUninitializedEncoding());
  }

  std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();

  Handle<Name> persistent_name2 = ph->NewHandle(name2);
  Handle<Map> persistent_map0 = ph->NewHandle(map0);

  base::Semaphore background_thread_started(0);

  // Pass persistent handles to background thread.
  // Background thread will search for name2, guaranteed to *not* be on the map.
  std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
      isolate->heap(), &background_thread_started, std::move(ph),
      persistent_name2, persistent_map0, base::nullopt));
  CHECK(thread->Start());

  background_thread_started.Wait();

  TransitionsAccessor(isolate, map0).Insert(name1, map1, PROPERTY_TRANSITION);
  CHECK_EQ(*map1, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name1, kind, attributes));
  {
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK(transitions.IsFullTransitionArrayEncoding());
  }
  thread->Join();
}

// In this test the background search will hold a pointer to an old transition
// array with no slack, while the main thread will try to insert a value into
// it. This makes it so that the main thread will create a new array, and the
// background thread will have a pointer to the old one.
TEST(FullFieldTransitions_BackgroundSearchOldPointer) {
  CcTest::InitializeVM();
  v8::HandleScope scope(CcTest::isolate());
  Isolate* isolate = CcTest::i_isolate();

  Handle<String> name1 = CcTest::MakeString("name1");
  Handle<String> name2 = CcTest::MakeString("name2");
  const PropertyAttributes attributes = NONE;
  const PropertyKind kind = kData;

  // Set map0 to be a full transition array with transition 'name1' to map1.
  Handle<Map> map0 = Map::Create(isolate, 0);
  Handle<Map> map1 =
      Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  Handle<Map> map2 =
      Map::CopyWithField(isolate, map0, name2, FieldType::Any(isolate),
                         attributes, PropertyConstness::kMutable,
                         Representation::Tagged(), OMIT_TRANSITION)
          .ToHandleChecked();
  TransitionsAccessor(isolate, map0).Insert(name1, map1, PROPERTY_TRANSITION);
  {
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK(transitions.IsFullTransitionArrayEncoding());
  }

  std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();

  Handle<Name> persistent_name1 = ph->NewHandle(name1);
  Handle<Map> persistent_map0 = ph->NewHandle(map0);
  Handle<Map> persistent_result_map1 = ph->NewHandle(map1);

  base::Semaphore background_thread_started(0);
  base::Semaphore main_thread_finished(0);

  // Pass persistent handles to background thread.
  std::unique_ptr<ConcurrentSearchThread> thread(
      new ConcurrentSearchOnOutdatedAccessorThread(
          isolate->heap(), &background_thread_started, &main_thread_finished,
          std::move(ph), persistent_name1, persistent_map0,
          persistent_result_map1));
  CHECK(thread->Start());

  background_thread_started.Wait();

  CHECK_EQ(*map1, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name1, kind, attributes));
  {
    // Check that we do not have enough slack for the 2nd insertion into the
    // TransitionArray.
    TestTransitionsAccessor transitions(isolate, map0);
    CHECK_EQ(transitions.Capacity(), 1);
  }
  TransitionsAccessor(isolate, map0).Insert(name2, map2, PROPERTY_TRANSITION);
  CHECK_EQ(*map2, TransitionsAccessor(isolate, map0)
                      .SearchTransition(*name2, kind, attributes));
  main_thread_finished.Signal();

  thread->Join();
}

}  // anonymous namespace

}  // namespace internal
}  // namespace v8
