34 uintptr_t current_begin_;
35 uintptr_t current_end_;
39 constexpr static int64_t large_buffer_threshold = 4096;
42#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE
43 int64_t user_requested_size_ = 0;
44 int64_t owned_allocation_size_ = 0;
55 for (
void *
ptr : owned_buffers_) {
56 allocator_.deallocate(
ptr);
72 const uintptr_t alignment_mask = alignment - 1;
73 const uintptr_t potential_allocation_begin = (current_begin_ + alignment_mask) &
75 const uintptr_t potential_allocation_end = potential_allocation_begin +
size;
77 if (potential_allocation_end <= current_end_) {
78#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE
79 user_requested_size_ +=
size;
81 current_begin_ = potential_allocation_end;
82 return reinterpret_cast<void *
>(potential_allocation_begin);
84 if (
size <= large_buffer_threshold) {
85 this->allocate_new_buffer(
size + alignment, alignment);
86 return this->
allocate(size, alignment);
88#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE
89 user_requested_size_ +=
size;
91 return this->allocator_large_buffer(
size, alignment);
101 return static_cast<T *
>(this->
allocate(
sizeof(
T),
alignof(
T)));
137 void *buffer = this->
allocate(
sizeof(
T),
alignof(
T));
138 T *value =
new (buffer)
T(std::forward<Args>(args)...);
147 template<
typename T,
typename... Args>
152 new (&
array[
i])
T(std::forward<Args>(args)...);
177 char *buffer =
static_cast<char *
>(this->
allocate(alloc_size, 1));
178 str.copy_unsafe(buffer);
186 void *pointer_buffer = this->
allocate(element_amount *
sizeof(
void *),
alignof(
void *));
187 void *elements_buffer = this->
allocate(element_amount * element_size, element_alignment);
190 void *next_element_buffer = elements_buffer;
192 pointers[
i] = next_element_buffer;
193 next_element_buffer =
POINTER_OFFSET(next_element_buffer, element_size);
199 template<
typename T,
typename... Args>
203 n,
sizeof(
T),
alignof(
T));
207 new (
static_cast<void *
>(pointers[
i]))
T(std::forward<Args>(args)...);
220 current_begin_ = uintptr_t(buffer);
221 current_end_ = current_begin_ +
size;
224 template<
size_t Size,
size_t Alignment>
242 const void *free_after)
246 if (original_allocation_size <= large_buffer_threshold) {
247 const int64_t new_begin = uintptr_t(free_after);
252 const int64_t freed_bytes_num = current_begin_ - new_begin;
253 if (freed_bytes_num > 0) {
254 current_begin_ = new_begin;
257 current_begin_ = new_begin;
271 owned_buffers_.extend(other.owned_buffers_);
272#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE
273 user_requested_size_ += other.user_requested_size_;
274 owned_allocation_size_ += other.owned_allocation_size_;
276 other.owned_buffers_.
clear();
277 std::destroy_at(&other);
282 void allocate_new_buffer(
int64_t min_allocation_size,
int64_t min_alignment)
287 int64_t size_in_bytes = min_allocation_size;
288 if (size_in_bytes <= large_buffer_threshold) {
290 const int grow_size = 1 << std::min<int>(owned_buffers_.
size() + 6, 20);
291 size_in_bytes = std::min(large_buffer_threshold,
292 std::max<int64_t>(size_in_bytes, grow_size));
295 void *buffer = this->allocated_owned(size_in_bytes, min_alignment);
296 current_begin_ = uintptr_t(buffer);
297 current_end_ = current_begin_ + size_in_bytes;
302 return this->allocated_owned(
size, alignment);
307 void *buffer = allocator_.allocate(
size, alignment, __func__);
308 owned_buffers_.append(buffer);
309#ifdef BLI_DEBUG_LINEAR_ALLOCATOR_SIZE
310 owned_allocation_size_ +=
size;
#define POINTER_OFFSET(v, ofs)
#define BLI_NO_UNIQUE_ADDRESS
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
destruct_ptr< T > construct(Args &&...args)
void provide_buffer(void *buffer, const int64_t size)
MutableSpan< T > allocate_array(int64_t size)
StringRefNull copy_string(StringRef str)
void * allocate(const int64_t size, const int64_t alignment)
void provide_buffer(AlignedBuffer< Size, Alignment > &aligned_buffer)
MutableSpan< T > construct_array(int64_t size, Args &&...args)
void free_end_of_previous_allocation(const int64_t original_allocation_size, const void *free_after)
Span< T * > construct_elements_and_pointer_array(int64_t n, Args &&...args)
MutableSpan< T > construct_array_copy(Span< T > src)
void * allocate_array(const CPPType &type, const int64_t size)
void transfer_ownership_from(LinearAllocator<> &other)
void * allocate(const CPPType &type)
MutableSpan< void * > allocate_elements_and_pointer_array(int64_t element_amount, int64_t element_size, int64_t element_alignment)
constexpr MutableSpan< NewT > cast() const
constexpr T * data() const
NonCopyable(const NonCopyable &other)=delete
NonMovable(NonMovable &&other)=delete
constexpr const T * data() const
constexpr int64_t size() const
constexpr bool is_empty() const
std::unique_ptr< T, DestructValueAtAddress< T > > destruct_ptr
void uninitialized_copy_n(const T *src, int64_t n, T *dst)