// Copyright 2019 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/heap/marking-worklist.h"

#include <cmath>
#include <limits>

#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
#include "src/heap/marking-worklist-inl.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace v8 {
namespace internal {

using MarkingWorklistTest = TestWithContext;

TEST_F(MarkingWorklistTest, PushPop) {
  MarkingWorklists holder;
  MarkingWorklists::Local worklists(&holder);
  HeapObject pushed_object =
      ReadOnlyRoots(i_isolate()->heap()).undefined_value();
  worklists.Push(pushed_object);
  HeapObject popped_object;
  EXPECT_TRUE(worklists.Pop(&popped_object));
  EXPECT_EQ(popped_object, pushed_object);
}

TEST_F(MarkingWorklistTest, PushPopOnHold) {
  MarkingWorklists holder;
  MarkingWorklists::Local worklists(&holder);
  HeapObject pushed_object =
      ReadOnlyRoots(i_isolate()->heap()).undefined_value();
  worklists.PushOnHold(pushed_object);
  HeapObject popped_object;
  EXPECT_TRUE(worklists.PopOnHold(&popped_object));
  EXPECT_EQ(popped_object, pushed_object);
}

TEST_F(MarkingWorklistTest, PushPopEmbedder) {
  MarkingWorklists holder;
  MarkingWorklists::Local worklists(&holder);
  HeapObject pushed_object =
      ReadOnlyRoots(i_isolate()->heap()).undefined_value();
  worklists.PushEmbedder(pushed_object);
  HeapObject popped_object;
  EXPECT_TRUE(worklists.PopEmbedder(&popped_object));
  EXPECT_EQ(popped_object, pushed_object);
}

TEST_F(MarkingWorklistTest, MergeOnHold) {
  MarkingWorklists holder;
  MarkingWorklists::Local main_worklists(&holder);
  MarkingWorklists::Local worker_worklists(&holder);
  HeapObject pushed_object =
      ReadOnlyRoots(i_isolate()->heap()).undefined_value();
  worker_worklists.PushOnHold(pushed_object);
  worker_worklists.Publish();
  main_worklists.MergeOnHold();
  HeapObject popped_object;
  EXPECT_TRUE(main_worklists.Pop(&popped_object));
  EXPECT_EQ(popped_object, pushed_object);
}

TEST_F(MarkingWorklistTest, ShareWorkIfGlobalPoolIsEmpty) {
  MarkingWorklists holder;
  MarkingWorklists::Local main_worklists(&holder);
  MarkingWorklists::Local worker_worklists(&holder);
  HeapObject pushed_object =
      ReadOnlyRoots(i_isolate()->heap()).undefined_value();
  main_worklists.Push(pushed_object);
  main_worklists.ShareWork();
  HeapObject popped_object;
  EXPECT_TRUE(worker_worklists.Pop(&popped_object));
  EXPECT_EQ(popped_object, pushed_object);
}

TEST_F(MarkingWorklistTest, ContextWorklistsPushPop) {
  const Address context = 0xabcdef;
  MarkingWorklists holder;
  holder.CreateContextWorklists({context});
  MarkingWorklists::Local worklists(&holder);
  HeapObject pushed_object =
      ReadOnlyRoots(i_isolate()->heap()).undefined_value();
  worklists.SwitchToContext(context);
  worklists.Push(pushed_object);
  worklists.SwitchToShared();
  HeapObject popped_object;
  EXPECT_TRUE(worklists.Pop(&popped_object));
  EXPECT_EQ(popped_object, pushed_object);
  holder.ReleaseContextWorklists();
}

TEST_F(MarkingWorklistTest, ContextWorklistsEmpty) {
  const Address context = 0xabcdef;
  MarkingWorklists holder;
  holder.CreateContextWorklists({context});
  MarkingWorklists::Local worklists(&holder);
  HeapObject pushed_object =
      ReadOnlyRoots(i_isolate()->heap()).undefined_value();
  worklists.SwitchToContext(context);
  worklists.Push(pushed_object);
  EXPECT_FALSE(worklists.IsEmpty());
  worklists.SwitchToShared();
  EXPECT_FALSE(worklists.IsEmpty());
  HeapObject popped_object;
  EXPECT_TRUE(worklists.Pop(&popped_object));
  EXPECT_EQ(popped_object, pushed_object);
  EXPECT_TRUE(worklists.IsEmpty());
  holder.ReleaseContextWorklists();
}

TEST_F(MarkingWorklistTest, ContextWorklistCrossTask) {
  const Address context1 = 0x1abcdef;
  const Address context2 = 0x2abcdef;
  MarkingWorklists holder;
  holder.CreateContextWorklists({context1, context2});
  MarkingWorklists::Local main_worklists(&holder);
  MarkingWorklists::Local worker_worklists(&holder);
  HeapObject pushed_object =
      ReadOnlyRoots(i_isolate()->heap()).undefined_value();
  main_worklists.SwitchToContext(context1);
  main_worklists.Push(pushed_object);
  main_worklists.ShareWork();
  worker_worklists.SwitchToContext(context2);
  HeapObject popped_object;
  EXPECT_TRUE(worker_worklists.Pop(&popped_object));
  EXPECT_EQ(popped_object, pushed_object);
  EXPECT_EQ(context1, worker_worklists.Context());
  holder.ReleaseContextWorklists();
}

}  // namespace internal
}  // namespace v8
