Commit ad4ccfc8 authored by Anton Bikineev's avatar Anton Bikineev Committed by Commit Bot

heap: Add test for write barrier in in-place element construction

This tests generational barriers issued in
HeapAllocator::NotifyNewObject function.

Bug: 1029379
Change-Id: I4d6c38a7095d43500c3a2aa7d3d935dbf7e080c8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2039451
Commit-Queue: Anton Bikineev <bikineev@chromium.org>
Reviewed-by: default avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738975}
parent b922b3a9
......@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/heap/thread_state.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink {
......@@ -195,7 +196,7 @@ TYPED_TEST(MinorGCTestForType, InterGenerationalPointerInCollection) {
// Check that the remembered set is visited.
MinorGCTest::CollectMinor();
EXPECT_EQ(kCollectionSize / 2, MinorGCTest::DestructedObjects());
for (auto& member : *old) {
for (const auto& member : *old) {
if (member) {
EXPECT_TRUE(HeapObjectHeader::FromPayload(member.Get())->IsMarked());
EXPECT_FALSE(HeapObjectHeader::FromPayload(member.Get())->IsFree());
......@@ -207,4 +208,88 @@ TYPED_TEST(MinorGCTestForType, InterGenerationalPointerInCollection) {
EXPECT_EQ(kCollectionSize, MinorGCTest::DestructedObjects());
}
TYPED_TEST(MinorGCTestForType, InterGenerationalPointerInPlaceBarrier) {
using Type = typename TestFixture::Type;
using ValueType = std::pair<WTF::String, Member<Type>>;
using CollectionType = HeapVector<ValueType>;
static constexpr size_t kCollectionSize = 1;
Persistent<CollectionType> old = MakeGarbageCollected<CollectionType>();
old->ReserveInitialCapacity(kCollectionSize);
void* raw_backing = old->data();
EXPECT_FALSE(HeapObjectHeader::FromPayload(raw_backing)->IsMarked());
MinorGCTest::CollectMinor();
EXPECT_TRUE(HeapObjectHeader::FromPayload(raw_backing)->IsMarked());
// Issue barrier (in HeapAllocator::NotifyNewElement).
old->push_back(std::make_pair("test", MakeGarbageCollected<Type>()));
// Check that the remembered set is visited.
MinorGCTest::CollectMinor();
// No objects destructed.
EXPECT_EQ(0u, MinorGCTest::DestructedObjects());
EXPECT_EQ(1u, old->size());
{
Type* member = (*old)[0].second;
EXPECT_TRUE(HeapObjectHeader::FromPayload(member)->IsMarked());
EXPECT_FALSE(HeapObjectHeader::FromPayload(member)->IsFree());
}
old.Release();
MinorGCTest::CollectMajor();
EXPECT_EQ(1u, MinorGCTest::DestructedObjects());
}
TYPED_TEST(MinorGCTestForType,
InterGenerationalPointerNotifyingBunchOfElements) {
using Type = typename TestFixture::Type;
using ValueType = std::pair<int, Member<Type>>;
using CollectionType = HeapVector<ValueType>;
static_assert(WTF::VectorTraits<ValueType>::kCanCopyWithMemcpy,
"Only when copying with memcpy the "
"Allocator::NotifyNewElements is called");
Persistent<CollectionType> old = MakeGarbageCollected<CollectionType>();
old->ReserveInitialCapacity(1);
void* raw_backing = old->data();
EXPECT_FALSE(HeapObjectHeader::FromPayload(raw_backing)->IsMarked());
// Mark old backing.
MinorGCTest::CollectMinor();
EXPECT_TRUE(HeapObjectHeader::FromPayload(raw_backing)->IsMarked());
Persistent<CollectionType> young = MakeGarbageCollected<CollectionType>();
// Add a single element to the young container.
young->push_back(std::make_pair(1, MakeGarbageCollected<Type>()));
// Copy young container and issue barrier in HeapAllocator::NotifyNewElements.
*old = *young;
// Release young container.
young.Release();
// Check that the remembered set is visited.
MinorGCTest::CollectMinor();
// Nothing must be destructed since the old vector backing was revisited.
EXPECT_EQ(0u, MinorGCTest::DestructedObjects());
EXPECT_EQ(1u, old->size());
{
Type* member = (*old)[0].second;
EXPECT_TRUE(HeapObjectHeader::FromPayload(member)->IsMarked());
EXPECT_FALSE(HeapObjectHeader::FromPayload(member)->IsFree());
}
old.Release();
MinorGCTest::CollectMajor();
EXPECT_EQ(1u, MinorGCTest::DestructedObjects());
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment