// Copyright 2017 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/heap/impl/heap_page.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"

namespace blink {

namespace {

bool IsEmpty(const ObjectStartBitmap& bitmap) {
  size_t count = 0;
  bitmap.Iterate([&count](Address) { count++; });
  return count == 0;
}

// Abstraction for objects that hides ObjectStartBitmap::kGranularity and
// the base address as getting either of it wrong will result in failed DCHECKs.
class Object {
  STACK_ALLOCATED();

 public:
  static Address kBaseOffset;

  Object(size_t number) : number_(number) {
    const size_t max_entries = ObjectStartBitmap::MaxEntries();
    EXPECT_GE(max_entries, number_);
  }

  Address address() const {
    return kBaseOffset + ObjectStartBitmap::Granularity() * number_;
  }

  // Allow implicitly converting Object to Address.
  operator Address() const { return address(); }

 private:
  const size_t number_;
};

Address Object::kBaseOffset = reinterpret_cast<Address>(0x4000);

}  // namespace

TEST(ObjectStartBitmapTest, MoreThanZeroEntriesPossible) {
  const size_t max_entries = ObjectStartBitmap::MaxEntries();
  EXPECT_LT(0u, max_entries);
}

TEST(ObjectStartBitmapTest, InitialEmpty) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  EXPECT_TRUE(IsEmpty(bitmap));
}

TEST(ObjectStartBitmapTest, SetBitImpliesNonEmpty) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  bitmap.SetBit(Object(0));
  EXPECT_FALSE(IsEmpty(bitmap));
}

TEST(ObjectStartBitmapTest, SetBitCheckBit) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object(7);
  bitmap.SetBit(object);
  EXPECT_TRUE(bitmap.CheckBit(object));
}

TEST(ObjectStartBitmapTest, SetBitClearbitCheckBit) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object(77);
  bitmap.SetBit(object);
  bitmap.ClearBit(object);
  EXPECT_FALSE(bitmap.CheckBit(object));
}

TEST(ObjectStartBitmapTest, SetBitClearBitImpliesEmpty) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object(123);
  bitmap.SetBit(object);
  bitmap.ClearBit(object);
  EXPECT_TRUE(IsEmpty(bitmap));
}

TEST(ObjectStartBitmapTest, AdjacentObjectsAtBegin) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object0(0);
  Object object1(1);
  bitmap.SetBit(object0);
  bitmap.SetBit(object1);
  EXPECT_FALSE(bitmap.CheckBit(Object(3)));
  size_t count = 0;
  bitmap.Iterate([&count, object0, object1](Address current) {
    if (count == 0) {
      EXPECT_EQ(object0.address(), current);
    } else if (count == 1) {
      EXPECT_EQ(object1.address(), current);
    }
    count++;
  });
  EXPECT_EQ(2u, count);
}

TEST(ObjectStartBitmapTest, AdjacentObjectsAtEnd) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  const size_t last_entry_index = ObjectStartBitmap::MaxEntries() - 1;
  Object object0(last_entry_index - 1);
  Object object1(last_entry_index);
  bitmap.SetBit(object0);
  bitmap.SetBit(object1);
  EXPECT_FALSE(bitmap.CheckBit(Object(last_entry_index - 2)));
  size_t count = 0;
  bitmap.Iterate([&count, object0, object1](Address current) {
    if (count == 0) {
      EXPECT_EQ(object0.address(), current);
    } else if (count == 1) {
      EXPECT_EQ(object1.address(), current);
    }
    count++;
  });
  EXPECT_EQ(2u, count);
}

TEST(ObjectStartBitmapTest, FindHeaderExact) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object(654);
  bitmap.SetBit(object);
  EXPECT_EQ(object.address(), bitmap.FindHeader(object.address()));
}

TEST(ObjectStartBitmapTest, FindHeaderApproximate) {
  static const size_t kInternalDelta = 37;
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object(654);
  bitmap.SetBit(object);
  EXPECT_EQ(object.address(),
            bitmap.FindHeader(object.address() + kInternalDelta));
}

TEST(ObjectStartBitmapTest, FindHeaderIteratingWholeBitmap) {
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object_to_find(Object(0));
  Address hint_index = Object(ObjectStartBitmap::MaxEntries() - 1);
  bitmap.SetBit(object_to_find);
  EXPECT_EQ(object_to_find.address(), bitmap.FindHeader(hint_index));
}

TEST(ObjectStartBitmapTest, FindHeaderNextCell) {
  // This white box test makes use of the fact that cells are of type uint8_t.
  const size_t kCellSize = sizeof(uint8_t);
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object_to_find(Object(kCellSize - 1));
  Address hint = Object(kCellSize);
  bitmap.SetBit(Object(0));
  bitmap.SetBit(object_to_find);
  EXPECT_EQ(object_to_find.address(), bitmap.FindHeader(hint));
}

TEST(ObjectStartBitmapTest, FindHeaderSameCell) {
  // This white box test makes use of the fact that cells are of type uint8_t.
  const size_t kCellSize = sizeof(uint8_t);
  ObjectStartBitmap bitmap(Object::kBaseOffset);
  Object object_to_find(Object(kCellSize - 1));
  bitmap.SetBit(Object(0));
  bitmap.SetBit(object_to_find);
  EXPECT_EQ(object_to_find.address(),
            bitmap.FindHeader(object_to_find.address()));
}

}  // namespace blink
