5 #ifndef INCLUDE_CPPGC_ALLOCATION_H_
6 #define INCLUDE_CPPGC_ALLOCATION_H_
12 #include <type_traits>
15 #include "cppgc/custom-space.h"
16 #include "cppgc/internal/api-constants.h"
17 #include "cppgc/internal/gc-info.h"
18 #include "cppgc/type-traits.h"
21 #if defined(__has_attribute
)
22 #if __has_attribute
(assume_aligned)
23 #define CPPGC_DEFAULT_ALIGNED
24 __attribute__((assume_aligned(api_constants::kDefaultAlignment)))
25 #define CPPGC_DOUBLE_WORD_ALIGNED
26 __attribute__((assume_aligned(2
* api_constants::kDefaultAlignment)))
31 #define CPPGC_DEFAULT_ALIGNED
35 #define CPPGC_DOUBLE_WORD_ALIGNED
43 class AllocationHandle;
54 std::atomic<uint16_t>* atomic_mutable_bitfield =
55 reinterpret_cast<std::atomic<uint16_t>*>(
56 const_cast<uint16_t*>(
reinterpret_cast<
const uint16_t*>(
57 reinterpret_cast<
const uint8_t*>(payload) -
63 uint16_t value = atomic_mutable_bitfield->load(std::memory_order_relaxed);
65 atomic_mutable_bitfield->store(value, std::memory_order_release);
72 template <
typename GCInfoType,
typename CustomSpace, size_t alignment>
73 struct AllocationDispatcher
final {
74 static void*
Invoke(AllocationHandle& handle, size_t size) {
76 "Custom space must inherit from CustomSpaceBase.");
78 !CustomSpace::kSupportsCompaction,
79 "Custom spaces that support compaction do not support allocating "
80 "objects with non-default (i.e. word-sized) alignment.");
82 handle, size,
static_cast<
AlignVal>(alignment),
83 internal::GCInfoTrait<GCInfoType>::Index(), CustomSpace::kSpaceIndex);
89 template <
typename GCInfoType>
90 struct AllocationDispatcher<GCInfoType,
void,
93 static void*
Invoke(AllocationHandle& handle, size_t size) {
95 handle, size,
internal::GCInfoTrait<GCInfoType>::Index());
100 template <
typename GCInfoType, size_t alignment>
101 struct AllocationDispatcher<GCInfoType,
void, alignment>
final {
102 static void*
Invoke(AllocationHandle& handle, size_t size) {
104 handle, size,
static_cast<
AlignVal>(alignment),
105 internal::GCInfoTrait<GCInfoType>::Index());
110 template <
typename GCInfoType,
typename CustomSpace>
111 struct AllocationDispatcher<GCInfoType, CustomSpace,
114 static void*
Invoke(AllocationHandle& handle, size_t size) {
116 "Custom space must inherit from CustomSpaceBase.");
118 handle, size,
internal::GCInfoTrait<GCInfoType>::Index(),
119 CustomSpace::kSpaceIndex);
135 friend class HeapObjectHeader;
147 template <
typename T>
152 "T needs to be a garbage collected object");
153 static_assert(!IsGarbageCollectedWithMixinTypeV<T> ||
156 "GarbageCollectedMixin may not be a large object");
169 std::is_base_of<
typename T::ParentMostGarbageCollectedType, T>::value,
170 "U of GarbageCollected<U> must be a base of T. Check "
171 "GarbageCollected<T> base class inheritance.");
172 static constexpr size_t kWantedAlignment =
178 "Requested alignment larger than alignof(std::max_align_t) bytes. "
179 "Please file a bug to possibly get this restriction lifted.");
180 return AllocationDispatcher<
182 T,
typename T::ParentMostGarbageCollectedType>::ResultType,
183 typename SpaceTrait<T>::Space, kWantedAlignment>::Invoke(handle, size);
235 template <
typename T>
238 template <
typename... Args>
239 static T*
Call(AllocationHandle& handle, Args&&... args) {
242 T* object = ::
new (memory) T(std::forward<Args>(args)...);
247 template <
typename... Args>
251 handle,
sizeof(T) + additional_bytes
.value);
252 T* object = ::
new (memory) T(std::forward<Args>(args)...);
264 template <
typename T,
typename =
void>
277 template <
typename T,
typename... Args>
295 template <
typename T,
typename... Args>
300 std::forward<Args>(args)...);
307 #undef CPPGC_DEFAULT_ALIGNED
308 #undef CPPGC_DOUBLE_WORD_ALIGNED