4d52549a6f
Move inlined methods to .h files accordingly, follwing style guide rule: https://google.github.io/styleguide/cppguide.html#Self_contained_Headers Bug: chromium:1056170 Change-Id: Ia6c4f82bd4352d507eece36e540ad0d318e56920 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2273858 Reviewed-by: Anton Bikineev <bikineev@chromium.org> Reviewed-by: Omer Katz <omerkatz@chromium.org> Commit-Queue: Michael Lippautz <mlippautz@chromium.org> Cr-Commit-Position: refs/heads/master@{#68627}
183 lines
5.4 KiB
C++
183 lines
5.4 KiB
C++
// 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/object-start-bitmap.h"
|
|
|
|
#include "include/cppgc/allocation.h"
|
|
#include "src/base/macros.h"
|
|
#include "src/heap/cppgc/globals.h"
|
|
#include "src/heap/cppgc/heap-object-header.h"
|
|
#include "src/heap/cppgc/page-memory.h"
|
|
#include "src/heap/cppgc/raw-heap.h"
|
|
#include "test/unittests/heap/cppgc/tests.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
namespace cppgc {
|
|
namespace internal {
|
|
|
|
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 {
|
|
public:
|
|
static Address kBaseOffset;
|
|
|
|
explicit 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_;
|
|
}
|
|
|
|
HeapObjectHeader* header() const {
|
|
return reinterpret_cast<HeapObjectHeader*>(address());
|
|
}
|
|
|
|
// 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.header(), 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.header(),
|
|
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.header(), 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.header(), 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.header(),
|
|
bitmap.FindHeader(object_to_find.address()));
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace cppgc
|