Commit 346b7937 authored by Omer Katz's avatar Omer Katz Committed by Commit Bot

cppgc: Support allocation with additional bytes

Bug: chromium:1056170
Change-Id: I548f27d29250f0e5ca01c8ec30cc2a85eee92f52
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2488681
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70675}
parent 7cd040a1
......@@ -112,6 +112,15 @@ class MakeGarbageCollectedTraitBase
}
};
/**
* struct used specify to MakeGarbageCollected how many bytes should be
* appended to the allocated object.
*/
struct AdditionalBytes {
explicit AdditionalBytes(size_t bytes) : value(bytes) {}
const size_t value;
};
/**
* Default trait class that specifies how to construct an object of type T.
* Advanced users may override how an object is constructed using the utilities
......@@ -139,6 +148,22 @@ class MakeGarbageCollectedTrait : public MakeGarbageCollectedTraitBase<T> {
MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed(object);
return object;
}
template <typename... Args>
static T* Call(AllocationHandle& handle, AdditionalBytes additional_bytes,
Args&&... args) {
static_assert(internal::IsGarbageCollectedType<T>::value,
"T needs to be a garbage collected object");
static_assert(
!internal::IsGarbageCollectedMixinType<T>::value ||
sizeof(T) <= internal::api_constants::kLargeObjectSizeThreshold,
"GarbageCollectedMixin may not be a large object");
void* memory = MakeGarbageCollectedTraitBase<T>::Allocate(
handle, sizeof(T) + additional_bytes.value);
T* object = ::new (memory) T(std::forward<Args>(args)...);
MakeGarbageCollectedTraitBase<T>::MarkObjectAsFullyConstructed(object);
return object;
}
};
/**
......@@ -168,6 +193,25 @@ T* MakeGarbageCollected(AllocationHandle& handle, Args&&... args) {
return object;
}
/**
* Constructs a managed object of type T where T transitively inherits from
* GarbageCollected. Created objects will have additional bytes appended to
* it. Allocated memory would suffice for `sizeof(T) + additional_bytes`.
*
* \param additional_bytes Denotes how many bytes to append to T.
* \param args List of arguments with which an instance of T will be
* constructed.
* \returns an instance of type T.
*/
template <typename T, typename... Args>
T* MakeGarbageCollected(AllocationHandle& handle,
AdditionalBytes additional_bytes, Args&&... args) {
T* object = MakeGarbageCollectedTrait<T>::Call(handle, additional_bytes,
std::forward<Args>(args)...);
PostConstructionCallbackTrait<T>::Call(object);
return object;
}
} // namespace cppgc
#endif // INCLUDE_CPPGC_ALLOCATION_H_
......@@ -117,5 +117,41 @@ TEST_F(GCHeapTest, ObjectPayloadSize) {
EXPECT_LE(expected_size, Heap::From(GetHeap())->ObjectPayloadSize());
}
TEST_F(GCHeapTest, AllocateWithAdditionalBytes) {
static constexpr size_t kBaseSize = sizeof(HeapObjectHeader) + sizeof(Foo);
static constexpr size_t kAdditionalBytes = 10u * kAllocationGranularity;
{
Foo* object = MakeGarbageCollected<Foo>(GetAllocationHandle());
EXPECT_LE(kBaseSize, HeapObjectHeader::FromPayload(object).GetSize());
}
{
Foo* object = MakeGarbageCollected<Foo>(GetAllocationHandle(),
AdditionalBytes(kAdditionalBytes));
EXPECT_LE(kBaseSize + kAdditionalBytes,
HeapObjectHeader::FromPayload(object).GetSize());
}
{
Foo* object = MakeGarbageCollected<Foo>(
GetAllocationHandle(),
AdditionalBytes(kAdditionalBytes * kAdditionalBytes));
EXPECT_LE(kBaseSize + kAdditionalBytes * kAdditionalBytes,
HeapObjectHeader::FromPayload(object).GetSize());
}
}
TEST_F(GCHeapTest, AllocatedSizeDependOnAdditionalBytes) {
static constexpr size_t kAdditionalBytes = 10u * kAllocationGranularity;
Foo* object = MakeGarbageCollected<Foo>(GetAllocationHandle());
Foo* object_with_bytes = MakeGarbageCollected<Foo>(
GetAllocationHandle(), AdditionalBytes(kAdditionalBytes));
Foo* object_with_more_bytes = MakeGarbageCollected<Foo>(
GetAllocationHandle(),
AdditionalBytes(kAdditionalBytes * kAdditionalBytes));
EXPECT_LT(HeapObjectHeader::FromPayload(object).GetSize(),
HeapObjectHeader::FromPayload(object_with_bytes).GetSize());
EXPECT_LT(HeapObjectHeader::FromPayload(object_with_bytes).GetSize(),
HeapObjectHeader::FromPayload(object_with_more_bytes).GetSize());
}
} // namespace internal
} // namespace cppgc
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