v8 12.4.254 (node 22.4.1)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
allocation.h
Go to the documentation of this file.
1// Copyright 2020 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef INCLUDE_CPPGC_ALLOCATION_H_
6#define INCLUDE_CPPGC_ALLOCATION_H_
7
8#include <atomic>
9#include <cstddef>
10#include <cstdint>
11#include <new>
12#include <type_traits>
13#include <utility>
14
15#include "cppgc/custom-space.h"
18#include "cppgc/type-traits.h"
19#include "v8config.h" // NOLINT(build/include_directory)
20
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)))
27#endif // __has_attribute(assume_aligned)
28#endif // defined(__has_attribute)
29
30#if !defined(CPPGC_DEFAULT_ALIGNED)
31#define CPPGC_DEFAULT_ALIGNED
32#endif
33
34#if !defined(CPPGC_DOUBLE_WORD_ALIGNED)
35#define CPPGC_DOUBLE_WORD_ALIGNED
36#endif
37
38namespace cppgc {
39
43class AllocationHandle;
44
45namespace internal {
46
47// Similar to C++17 std::align_val_t;
48enum class AlignVal : size_t {};
49
51 protected:
52 static inline void MarkObjectAsFullyConstructed(const void* payload) {
53 // See api_constants for an explanation of the constants.
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) -
58 api_constants::kFullyConstructedBitFieldOffsetFromPayload)));
59 // It's safe to split use load+store here (instead of a read-modify-write
60 // operation), since it's guaranteed that this 16-bit bitfield is only
61 // modified by a single thread. This is cheaper in terms of code bloat (on
62 // ARM) and performance.
63 uint16_t value = atomic_mutable_bitfield->load(std::memory_order_relaxed);
64 value |= api_constants::kFullyConstructedBitMask;
65 atomic_mutable_bitfield->store(value, std::memory_order_release);
66 }
67
68 // Dispatch based on compile-time information.
69 //
70 // Default implementation is for a custom space with >`kDefaultAlignment` byte
71 // alignment.
72 template <typename GCInfoType, typename CustomSpace, size_t alignment>
73 struct AllocationDispatcher final {
74 static void* Invoke(AllocationHandle& handle, size_t size) {
75 static_assert(std::is_base_of<CustomSpaceBase, CustomSpace>::value,
76 "Custom space must inherit from CustomSpaceBase.");
77 static_assert(
78 !CustomSpace::kSupportsCompaction,
79 "Custom spaces that support compaction do not support allocating "
80 "objects with non-default (i.e. word-sized) alignment.");
81 return MakeGarbageCollectedTraitInternal::Allocate(
82 handle, size, static_cast<AlignVal>(alignment),
83 internal::GCInfoTrait<GCInfoType>::Index(), CustomSpace::kSpaceIndex);
84 }
85 };
86
87 // Fast path for regular allocations for the default space with
88 // `kDefaultAlignment` byte alignment.
89 template <typename GCInfoType>
90 struct AllocationDispatcher<GCInfoType, void,
91 api_constants::kDefaultAlignment>
92 final {
93 static void* Invoke(AllocationHandle& handle, size_t size) {
94 return MakeGarbageCollectedTraitInternal::Allocate(
95 handle, size, internal::GCInfoTrait<GCInfoType>::Index());
96 }
97 };
98
99 // Default space with >`kDefaultAlignment` byte alignment.
100 template <typename GCInfoType, size_t alignment>
101 struct AllocationDispatcher<GCInfoType, void, alignment> final {
102 static void* Invoke(AllocationHandle& handle, size_t size) {
103 return MakeGarbageCollectedTraitInternal::Allocate(
104 handle, size, static_cast<AlignVal>(alignment),
105 internal::GCInfoTrait<GCInfoType>::Index());
106 }
107 };
108
109 // Custom space with `kDefaultAlignment` byte alignment.
110 template <typename GCInfoType, typename CustomSpace>
112 api_constants::kDefaultAlignment>
113 final {
114 static void* Invoke(AllocationHandle& handle, size_t size) {
115 static_assert(std::is_base_of<CustomSpaceBase, CustomSpace>::value,
116 "Custom space must inherit from CustomSpaceBase.");
117 return MakeGarbageCollectedTraitInternal::Allocate(
118 handle, size, internal::GCInfoTrait<GCInfoType>::Index(),
119 CustomSpace::kSpaceIndex);
120 }
121 };
122
123 private:
124 static void* CPPGC_DEFAULT_ALIGNED Allocate(cppgc::AllocationHandle&, size_t,
126 static void* CPPGC_DOUBLE_WORD_ALIGNED Allocate(cppgc::AllocationHandle&,
127 size_t, AlignVal,
129 static void* CPPGC_DEFAULT_ALIGNED Allocate(cppgc::AllocationHandle&, size_t,
131 static void* CPPGC_DOUBLE_WORD_ALIGNED Allocate(cppgc::AllocationHandle&,
132 size_t, AlignVal, GCInfoIndex,
134
135 friend class HeapObjectHeader;
136};
137
138} // namespace internal
139
147template <typename T>
150 private:
152 "T needs to be a garbage collected object");
153 static_assert(!IsGarbageCollectedWithMixinTypeV<T> ||
154 sizeof(T) <=
155 internal::api_constants::kLargeObjectSizeThreshold,
156 "GarbageCollectedMixin may not be a large object");
157
158 protected:
167 V8_INLINE static void* Allocate(AllocationHandle& handle, size_t size) {
168 static_assert(
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 =
173 alignof(T) < internal::api_constants::kDefaultAlignment
174 ? internal::api_constants::kDefaultAlignment
175 : alignof(T);
176 static_assert(
177 kWantedAlignment <= internal::api_constants::kMaxSupportedAlignment,
178 "Requested alignment larger than alignof(std::max_align_t) bytes. "
179 "Please file a bug to possibly get this restriction lifted.");
182 T, typename T::ParentMostGarbageCollectedType>::ResultType,
183 typename SpaceTrait<T>::Space, kWantedAlignment>::Invoke(handle, size);
184 }
185
192 V8_INLINE static void MarkObjectAsFullyConstructed(const void* payload) {
194 payload);
195 }
196};
197
221 constexpr explicit AdditionalBytes(size_t bytes) : value(bytes) {}
222 const size_t value;
223};
224
235template <typename T>
237 public:
238 template <typename... Args>
239 static T* Call(AllocationHandle& handle, Args&&... args) {
240 void* memory =
242 T* object = ::new (memory) T(std::forward<Args>(args)...);
244 return object;
245 }
246
247 template <typename... Args>
248 static T* Call(AllocationHandle& handle, AdditionalBytes additional_bytes,
249 Args&&... args) {
251 handle, sizeof(T) + additional_bytes.value);
252 T* object = ::new (memory) T(std::forward<Args>(args)...);
254 return object;
255 }
256};
257
264template <typename T, typename = void>
266 static void Call(T*) {}
267};
268
277template <typename T, typename... Args>
278V8_INLINE T* MakeGarbageCollected(AllocationHandle& handle, Args&&... args) {
279 T* object =
280 MakeGarbageCollectedTrait<T>::Call(handle, std::forward<Args>(args)...);
282 return object;
283}
284
295template <typename T, typename... Args>
296V8_INLINE T* MakeGarbageCollected(AllocationHandle& handle,
297 AdditionalBytes additional_bytes,
298 Args&&... args) {
299 T* object = MakeGarbageCollectedTrait<T>::Call(handle, additional_bytes,
300 std::forward<Args>(args)...);
302 return object;
303}
304
305} // namespace cppgc
306
307#undef CPPGC_DEFAULT_ALIGNED
308#undef CPPGC_DOUBLE_WORD_ALIGNED
309
310#endif // INCLUDE_CPPGC_ALLOCATION_H_
#define CPPGC_DEFAULT_ALIGNED
Definition allocation.h:31
#define CPPGC_DOUBLE_WORD_ALIGNED
Definition allocation.h:35
static V8_INLINE void MarkObjectAsFullyConstructed(const void *payload)
Definition allocation.h:192
static V8_INLINE void * Allocate(AllocationHandle &handle, size_t size)
Definition allocation.h:167
static T * Call(AllocationHandle &handle, AdditionalBytes additional_bytes, Args &&... args)
Definition allocation.h:248
static T * Call(AllocationHandle &handle, Args &&... args)
Definition allocation.h:239
static void MarkObjectAsFullyConstructed(const void *payload)
Definition allocation.h:52
uint16_t GCInfoIndex
Definition gc-info.h:21
V8_INLINE T * MakeGarbageCollected(AllocationHandle &handle, Args &&... args)
Definition allocation.h:278
constexpr AdditionalBytes(size_t bytes)
Definition allocation.h:221
Definition allocation.h:265
static void Call(T *)
Definition allocation.h:266
static void * Invoke(AllocationHandle &handle, size_t size)
Definition allocation.h:74
#define V8_EXPORT
Definition v8config.h:753
#define V8_INLINE
Definition v8config.h:477