// 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/heap/cppgc/heap-growing.h"

#include "include/cppgc/platform.h"
#include "src/heap/cppgc/heap.h"
#include "src/heap/cppgc/stats-collector.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cppgc {
namespace internal {

namespace {

class FakeGarbageCollector : public GarbageCollector {
 public:
  explicit FakeGarbageCollector(StatsCollector* stats_collector)
      : stats_collector_(stats_collector) {}

  void SetLiveBytes(size_t live_bytes) { live_bytes_ = live_bytes; }

  void CollectGarbage(GarbageCollector::Config config) override {
    stats_collector_->NotifyMarkingStarted();
    stats_collector_->NotifyMarkingCompleted(live_bytes_);
    stats_collector_->NotifySweepingCompleted();
    callcount_++;
  }

  void StartIncrementalGarbageCollection(
      GarbageCollector::Config config) override {
    UNREACHABLE();
  }

  size_t epoch() const override { return callcount_; }

 private:
  StatsCollector* stats_collector_;
  size_t live_bytes_ = 0;
  size_t callcount_ = 0;
};

class MockGarbageCollector : public GarbageCollector {
 public:
  MOCK_METHOD(void, CollectGarbage, (GarbageCollector::Config), (override));
  MOCK_METHOD(void, StartIncrementalGarbageCollection,
              (GarbageCollector::Config), (override));
  MOCK_METHOD(size_t, epoch, (), (const, override));
};

void FakeAllocate(StatsCollector* stats_collector, size_t bytes) {
  stats_collector->NotifyAllocation(bytes);
  stats_collector->NotifySafePointForConservativeCollection();
}

}  // namespace

TEST(HeapGrowingTest, ConservativeGCInvoked) {
  StatsCollector stats_collector;
  MockGarbageCollector gc;
  cppgc::Heap::ResourceConstraints constraints;
  // Force GC at the first update.
  constraints.initial_heap_size_bytes = 1;
  HeapGrowing growing(&gc, &stats_collector, constraints);
  EXPECT_CALL(gc, CollectGarbage(::testing::_));
  FakeAllocate(&stats_collector, 100 * kMB);
}

TEST(HeapGrowingTest, InitialHeapSize) {
  StatsCollector stats_collector;
  MockGarbageCollector gc;
  cppgc::Heap::ResourceConstraints constraints;
  // Use larger size to avoid running into small heap optimizations.
  constexpr size_t kObjectSize = 10 * HeapGrowing::kMinLimitIncrease;
  constraints.initial_heap_size_bytes = kObjectSize;
  HeapGrowing growing(&gc, &stats_collector, constraints);
  FakeAllocate(&stats_collector, kObjectSize - 1);
  EXPECT_CALL(gc, CollectGarbage(::testing::_));
  FakeAllocate(&stats_collector, kObjectSize);
}

TEST(HeapGrowingTest, ConstantGrowingFactor) {
  // Use larger size to avoid running into small heap optimizations.
  constexpr size_t kObjectSize = 10 * HeapGrowing::kMinLimitIncrease;
  StatsCollector stats_collector;
  FakeGarbageCollector gc(&stats_collector);
  cppgc::Heap::ResourceConstraints constraints;
  // Force GC at the first update.
  constraints.initial_heap_size_bytes = HeapGrowing::kMinLimitIncrease;
  HeapGrowing growing(&gc, &stats_collector, constraints);
  EXPECT_EQ(0u, gc.epoch());
  gc.SetLiveBytes(kObjectSize);
  FakeAllocate(&stats_collector, kObjectSize + 1);
  EXPECT_EQ(1u, gc.epoch());
  EXPECT_EQ(1.5 * kObjectSize, growing.limit_for_atomic_gc());
}

TEST(HeapGrowingTest, SmallHeapGrowing) {
  // Larger constant to avoid running into special handling for smaller heaps.
  constexpr size_t kLargeAllocation = 100 * kMB;
  StatsCollector stats_collector;
  FakeGarbageCollector gc(&stats_collector);
  cppgc::Heap::ResourceConstraints constraints;
  // Force GC at the first update.
  constraints.initial_heap_size_bytes = 1;
  HeapGrowing growing(&gc, &stats_collector, constraints);
  EXPECT_EQ(0u, gc.epoch());
  gc.SetLiveBytes(1);
  FakeAllocate(&stats_collector, kLargeAllocation);
  EXPECT_EQ(1u, gc.epoch());
  EXPECT_EQ(1 + HeapGrowing::kMinLimitIncrease, growing.limit_for_atomic_gc());
}

TEST(HeapGrowingTest, IncrementalGCStarted) {
  StatsCollector stats_collector;
  MockGarbageCollector gc;
  cppgc::Heap::ResourceConstraints constraints;
  HeapGrowing growing(&gc, &stats_collector, constraints);
  EXPECT_CALL(gc, CollectGarbage(::testing::_)).Times(0);
  EXPECT_CALL(gc, StartIncrementalGarbageCollection(::testing::_));
  // Allocate 1 byte less the limit for atomic gc to trigger incremental gc.
  FakeAllocate(&stats_collector, growing.limit_for_atomic_gc() - 1);
}

TEST(HeapGrowingTest, IncrementalGCFinalized) {
  StatsCollector stats_collector;
  MockGarbageCollector gc;
  cppgc::Heap::ResourceConstraints constraints;
  HeapGrowing growing(&gc, &stats_collector, constraints);
  EXPECT_CALL(gc, CollectGarbage(::testing::_)).Times(0);
  EXPECT_CALL(gc, StartIncrementalGarbageCollection(::testing::_));
  // Allocate 1 byte less the limit for atomic gc to trigger incremental gc.
  size_t bytes_for_incremental_gc = growing.limit_for_atomic_gc() - 1;
  FakeAllocate(&stats_collector, bytes_for_incremental_gc);
  ::testing::Mock::VerifyAndClearExpectations(&gc);
  EXPECT_CALL(gc, CollectGarbage(::testing::_));
  EXPECT_CALL(gc, StartIncrementalGarbageCollection(::testing::_)).Times(0);
  // Allocate the rest needed to trigger atomic gc ().
  FakeAllocate(&stats_collector, StatsCollector::kAllocationThresholdBytes);
}

}  // namespace internal
}  // namespace cppgc
