v8 12.4.254 (node 22.4.1)
V8 is Google's open source JavaScript engine
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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