Abstract interface for variable-layout memory allocation.
The interface makes no guarantees about its implementation. Consumers of the generic interface must not make any assumptions around allocator behavior, thread safety, or performance.
Public Types | |
| using | Fragmentation = allocator::Fragmentation |
Public Types inherited from pw::Deallocator | |
| using | Capabilities = allocator::Capabilities |
| using | Capability = allocator::Capability |
| using | Layout = allocator::Layout |
Public Member Functions | |
| void * | Allocate (Layout layout) |
| template<typename T , int &... kExplicitGuard, std::enable_if_t<!std::is_array_v< T >, int > = 0, typename... Args> | |
| T * | New (Args &&... args) |
| template<typename T , int &... kExplicitGuard, typename ElementType = std::remove_extent_t<T>, std::enable_if_t< is_bounded_array_v< T >, int > = 0> | |
| ElementType * | New () |
| template<typename T , int &... kExplicitGuard, typename ElementType = std::remove_extent_t<T>, std::enable_if_t< is_unbounded_array_v< T >, int > = 0> | |
| ElementType * | New (size_t count) |
| template<typename T , int &... kExplicitGuard, typename ElementType = std::remove_extent_t<T>, std::enable_if_t< is_unbounded_array_v< T >, int > = 0> | |
| ElementType * | New (size_t count, size_t alignment) |
Constructs an alignment-byte aligned array of count objects. | |
| template<typename T , int &... kExplicitGuard, std::enable_if_t<!std::is_array_v< T >, int > = 0, typename... Args> | |
| UniquePtr< T > | MakeUnique (Args &&... args) |
| template<typename T , std::enable_if_t< is_unbounded_array_v< T >, int > = 0> | |
| UniquePtr< T > | MakeUnique (size_t size) |
| template<typename T , std::enable_if_t< is_unbounded_array_v< T >, int > = 0> | |
| UniquePtr< T > | MakeUnique (size_t size, size_t alignment) |
| template<typename T , std::enable_if_t< is_bounded_array_v< T >, int > = 0> | |
| UniquePtr< T > | MakeUnique () |
| template<typename T , int &... kExplicitGuard, std::enable_if_t<!std::is_array_v< T >, int > = 0, typename... Args> | |
| SharedPtr< T > | MakeShared (Args &&... args) |
| template<typename T , std::enable_if_t< is_unbounded_array_v< T >, int > = 0> | |
| SharedPtr< T > | MakeShared (size_t size) |
| template<typename T , std::enable_if_t< is_unbounded_array_v< T >, int > = 0> | |
| SharedPtr< T > | MakeShared (size_t size, size_t alignment) |
| template<typename T , std::enable_if_t< is_bounded_array_v< T >, int > = 0> | |
| SharedPtr< T > | MakeShared () |
| bool | Resize (void *ptr, size_t new_size) |
| void * | Reallocate (void *ptr, Layout new_layout) |
| size_t | GetAllocated () const |
| std::optional< Fragmentation > | MeasureFragmentation () const |
| Returns fragmentation information for the allocator's memory region. | |
Public Member Functions inherited from pw::Deallocator | |
| constexpr const Capabilities & | capabilities () const |
| constexpr bool | HasCapability (Capability capability) const |
| Returns whether a given capability is enabled for this object. | |
| void | Deallocate (void *ptr) |
| template<typename ElementType > | |
| void | DeleteArray (ElementType *ptr, size_t count) |
| StatusWithSize | GetCapacity () const |
| bool | IsEqual (const Deallocator &other) const |
| template<typename T , int &... kExplicitGuard, std::enable_if_t<!std::is_array_v< T >, int > = 0> | |
| void | Delete (T *ptr) |
| template<typename T , int &... kExplicitGuard, typename ElementType = std::remove_extent_t<T>, std::enable_if_t< is_bounded_array_v< T >, int > = 0> | |
| void | Delete (ElementType *ptr) |
| template<typename T , int &... kExplicitGuard, typename ElementType = std::remove_extent_t<T>, std::enable_if_t< is_unbounded_array_v< T >, int > = 0> | |
| void | Delete (ElementType *ptr, size_t count) |
Protected Member Functions | |
| constexpr | Allocator () noexcept=default |
| TODO(b/326509341): Remove when downstream consumers migrate. | |
| constexpr | Allocator (const Capabilities &capabilities) noexcept |
| virtual void * | DoAllocate (Layout layout)=0 |
| virtual bool | DoResize (void *ptr, size_t new_size) |
| virtual void * | DoReallocate (void *ptr, Layout new_layout) |
| virtual void | DoBeforeReallocate (void *ptr, Layout new_layout) |
| virtual void | DoAfterReallocateCopy (void *ptr, Layout new_layout, void *new_ptr) |
| virtual void | DoAfterReallocateDone (Layout new_layout, void *new_ptr) |
| virtual size_t | DoGetAllocated () const |
| virtual std::optional< Fragmentation > | DoMeasureFragmentation () const |
| Returns fragmentation information for the allocator's memory region. | |
Protected Member Functions inherited from pw::Deallocator | |
| constexpr | Deallocator ()=default |
| TODO(b/326509341): Remove when downstream consumers migrate. | |
| constexpr | Deallocator (const Capabilities &capabilities) |
| Result< Layout > | GetInfo (InfoType info_type, const void *ptr) const |
| Result< Layout > | GetRequestedLayout (const void *ptr) const |
| Result< Layout > | GetUsableLayout (const void *ptr) const |
| Result< Layout > | GetAllocatedLayout (const void *ptr) const |
| bool | Recognizes (const void *ptr) const |
| virtual void | DoDeallocate (void *ptr)=0 |
| virtual Result< Layout > | DoGetInfo (InfoType, const void *) const |
Static Protected Member Functions | |
| static void | BeforeReallocate (Allocator &allocator, void *ptr, Layout new_layout) |
| static void | AfterReallocateCopy (Allocator &allocator, void *ptr, Layout new_layout, void *new_ptr) |
| static void | AfterReallocateDone (Allocator &allocator, Layout new_layout, void *new_ptr) |
Static Protected Member Functions inherited from pw::Deallocator | |
| static Result< Layout > | GetInfo (const Deallocator &deallocator, InfoType info_type, const void *ptr) |
| static Result< Layout > | GetRequestedLayout (const Deallocator &deallocator, const void *ptr) |
| static Result< Layout > | GetUsableLayout (const Deallocator &deallocator, const void *ptr) |
| static Result< Layout > | GetAllocatedLayout (const Deallocator &deallocator, const void *ptr) |
| static bool | Recognizes (const Deallocator &deallocator, const void *ptr) |
Additional Inherited Members | |
Protected Types inherited from pw::Deallocator | |
| enum class | InfoType { kRequestedLayoutOf , kUsableLayoutOf , kAllocatedLayoutOf , kCapacity , kRecognizes } |
Static Protected Attributes inherited from pw::Deallocator | |
| template<typename T > | |
| static constexpr bool | is_bounded_array_v = ::pw::is_bounded_array_v<T> |
| template<typename T > | |
| static constexpr bool | is_unbounded_array_v = ::pw::is_unbounded_array_v<T> |
|
inlinestaticprotected |
Static version of DoAfterReallocateCopy that allows forwarding allocators to call it on wrapped allocators.
|
inlinestaticprotected |
Static version of DoAfterReallocateDone that allows forwarding allocators to call it on wrapped allocators.
|
inline |
Allocates a block of memory with the specified size and alignment.
Returns nullptr if the allocation cannot be made, or the layout has a size of 0.
| [in] | layout | Describes the memory to be allocated. |
|
inlinestaticprotected |
Static version of DoBeforeReallocate that allows forwarding allocators to call it on wrapped allocators.
|
inlineprotectedvirtual |
Called as part of the default implementation of DoReallocate once the data from ptr has been resized or copied to new_ptr.
By default, does nothing. Derived types may implement this method to add additional behavior. If they do, they must call DoAfterReallocateCopy on their base type before performing any other action.
ptr and new_ptr are guaranteed to be non-null, and new_layout.size() is guaranteed to be non-zero.
Reimplemented in pw::allocator::ForwardingAllocator.
|
inlineprotectedvirtual |
Called as part of the default implementation of DoReallocate just before returning.
By default, does nothing. Derived types may implement this method to add additional behavior. If they do, they must call DoAfterReallocateDone on their base type before performing any other action.
new_ptr is guaranteed to be non-null, and new_layout.size() is guaranteed to be non-zero.
Reimplemented in pw::allocator::ForwardingAllocator, and pw::allocator::TrackingAllocator< MetricsType >.
|
protectedpure virtual |
Allocates a block of memory with the specified size and alignment.
Returns nullptr if the allocation cannot be made, or the layout has a size of 0.
| [in] | layout | Describes the memory to be allocated. |
Implemented in pw::multibuf::v1_adapter::internal::ChunkAllocator, pw::allocator::BlockAllocator< BlockType_ >, pw::allocator::BlockAllocator< BucketBlock<> >, pw::allocator::BlockAllocator< BestFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< DlBlock< uintptr_t > >, pw::allocator::BlockAllocator< FirstFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< TlsfBlock< uint32_t > >, pw::allocator::BlockAllocator< WorstFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< BlockType >, pw::allocator::BlockAllocator< pw::allocator::TinyBlock >, pw::allocator::internal::GenericBuddyAllocator, pw::allocator::BumpAllocator, pw::allocator::FallbackAllocator, pw::allocator::test::FaultInjectingAllocator, pw::allocator::ForwardingAllocator, pw::allocator::GuardedAllocator< BlockAllocatorType, LockType >, pw::allocator::LibCAllocator, pw::allocator::NullAllocator, pw::allocator::SynchronizedAllocator< LockType >, pw::allocator::test::AllocatorForTest< kBufferSize, BlockType_, MetricsType_ >, pw::allocator::TrackingAllocator< MetricsType >, and pw::multibuf::v1_adapter::internal::SingleChunkAllocator.
|
inlineprotectedvirtual |
Called at the start of the default implementation of DoReallocate.
By default, does nothing. Derived types may implement this method to add additional behavior. If they do, they must call DoBeforeReallocate on their base type just before returning.
ptr is guaranteed to be non-null, and new_layout.size() is guaranteed to be non-zero.
Reimplemented in pw::allocator::ForwardingAllocator, pw::allocator::test::AllocatorForTest< kBufferSize, BlockType_, MetricsType_ >, and pw::allocator::TrackingAllocator< MetricsType >.
|
inlineprotectedvirtual |
Returns the total bytes that have been allocated by this allocator, or size_t(-1) if this allocator does not track its total allocated bytes.
The default implementation simply returns size_t(-1), indicating that tracking total allocated bytes is not supported.
Reimplemented in pw::allocator::AbstractAllocator, pw::allocator::BlockAllocator< BlockType_ >, pw::allocator::BlockAllocator< BucketBlock<> >, pw::allocator::BlockAllocator< BestFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< DlBlock< uintptr_t > >, pw::allocator::BlockAllocator< FirstFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< TlsfBlock< uint32_t > >, pw::allocator::BlockAllocator< WorstFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< BlockType >, pw::allocator::BlockAllocator< pw::allocator::TinyBlock >, pw::allocator::BumpAllocator, pw::allocator::FallbackAllocator, pw::allocator::ForwardingAllocator, and pw::allocator::SynchronizedAllocator< LockType >.
|
inlineprotectedvirtual |
Returns fragmentation information for the allocator's memory region.
The default implementation simply returns std::nullopt, indicating that tracking memory fragmentation is not supported.
Reimplemented in pw::allocator::AbstractAllocator, pw::allocator::BlockAllocator< BlockType_ >, pw::allocator::BlockAllocator< BucketBlock<> >, pw::allocator::BlockAllocator< BestFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< DlBlock< uintptr_t > >, pw::allocator::BlockAllocator< FirstFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< TlsfBlock< uint32_t > >, pw::allocator::BlockAllocator< WorstFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< BlockType >, pw::allocator::BlockAllocator< pw::allocator::TinyBlock >, pw::allocator::FallbackAllocator, pw::allocator::ForwardingAllocator, pw::allocator::SynchronizedAllocator< LockType >, and pw::allocator::test::AllocatorForTest< kBufferSize, BlockType_, MetricsType_ >.
|
protectedvirtual |
Modifies the size of a previously-allocated block of memory.
Returns pointer to the modified block of memory, or nullptr if the memory could not be modified.
The data stored by the memory being modified must be trivially copyable. If it is not, callers should themselves attempt to Resize, then Allocate, move the data, and Deallocate as needed.
If nullptr is returned, the block of memory is unchanged. In particular, if the new_layout has a size of 0, the given pointer will NOT be deallocated.
TODO(b/331290408): This error condition needs to be better communicated to module users, who may assume the pointer is freed.
Unlike Resize, providing a null pointer will return a new allocation.
If the request can be satisfied using Resize, the alignment parameter may be ignored.
| [in] | ptr | Pointer to previously-allocated memory. |
| [in] | new_layout | Describes the memory to be allocated. |
The default implementation will first try to Resize the data. If that is unsuccessful, it will allocate an entirely new block, copy existing data, and deallocate the given block.
Derived allocators should avoid overiding this method unless absolutely necessary, and instead override the DoBeforeReallocate, DoAfterReallocateCopy, and DoAfterReallocateDone methods below that are called as part of the default implementation. By using the default implementation, the derived types guarantees its own implementations of DoAllocate, DoDeallocate and DoResize will be used for the reallocation. This is especially important for allocators such as ForwardingAllocator that use composition instead of inheritance.
Reimplemented in pw::allocator::test::FaultInjectingAllocator, pw::allocator::LibCAllocator, and pw::allocator::SynchronizedAllocator< LockType >.
|
protectedvirtual |
Modifies the size of an previously-allocated block of memory without copying any data.
Returns true if its size was changed without copying data to a new allocation; otherwise returns false.
In particular, it always returns true if the old_layout.size() equals new_size, and always returns false if the given pointer is null, the old_layout.size() is 0, or the new_size is 0.
| [in] | ptr | Pointer to previously-allocated memory. |
| [in] | new_size | Requested new size for the memory allocation. |
Reimplemented in pw::allocator::AbstractAllocator, pw::allocator::BlockAllocator< BlockType_ >, pw::allocator::BlockAllocator< BucketBlock<> >, pw::allocator::BlockAllocator< BestFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< DlBlock< uintptr_t > >, pw::allocator::BlockAllocator< FirstFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< TlsfBlock< uint32_t > >, pw::allocator::BlockAllocator< WorstFitBlock< uintptr_t > >, pw::allocator::BlockAllocator< BlockType >, pw::allocator::BlockAllocator< pw::allocator::TinyBlock >, pw::allocator::FallbackAllocator, pw::allocator::test::FaultInjectingAllocator, pw::allocator::ForwardingAllocator, pw::allocator::GuardedAllocator< BlockAllocatorType, LockType >, pw::allocator::SynchronizedAllocator< LockType >, pw::allocator::test::AllocatorForTest< kBufferSize, BlockType_, MetricsType_ >, pw::allocator::TrackingAllocator< MetricsType >, and pw::multibuf::v1_adapter::internal::ChunkAllocator.
|
inline |
Returns the total bytes that have been allocated by this allocator, or size_t(-1) if this allocator does not track its total allocated bytes.
|
inline |
|
inline |
|
inline |
|
inline |
Constructs an alignment-byte aligned array of size objects, and wraps it in a SharedPtr
The returned value may contain null if allocating memory for the object fails. Callers must check for null before using the SharedPtr.
| T | An array type. |
| [in] | size | Number of objects to allocate. |
| [in] | alignment | Object alignment. |
|
inline |
|
inline |
Constructs and object of type T from the given args, and wraps it in a UniquePtr
The returned value may contain null if allocating memory for the object fails. Callers must check for null before using the UniquePtr.
| T | A non-array object type, like int. |
| [in] | args | Arguments passed to the object constructor. |
|
inline |
Constructs an array of size objects, and wraps it in a UniquePtr
The returned value may contain null if allocating memory for the object fails. Callers must check for null before using the UniquePtr.
| T | An unbounded array type, like int[]. |
| [in] | size | Number of objects to allocate. |
|
inline |
Constructs an alignment-byte aligned array of size objects and wraps it in a UniquePtr.
The returned value may contain null if allocating memory for the object fails. Callers must check for null before using the UniquePtr.
| T | An unbounded array type, like int[]. |
| [in] | size | Number of objects to allocate. |
| [in] | alignment | Object alignment. |
|
inline |
Constructs an array of objects.
The return value is nullable, as allocating memory for the object may fail. Callers must check for this error before using the resulting pointer.
| T | A bounded array type, like int[3]. |
|
inline |
Constructs an object of type T from the given args.
The return value is nullable, as allocating memory for the object may fail. Callers must check for this error before using the resulting pointer.
| T | A non-array object type, like int. |
| [in] | args | Arguments passed to the object constructor. |
|
inline |
Constructs an array of count objects.
The return value is nullable, as allocating memory for the object may fail. Callers must check for this error before using the resulting pointer.
| T | An unbounded array type, like int[]. |
| [in] | count | Number of objects to allocate. |
|
inline |
Constructs an alignment-byte aligned array of count objects.
The return value is nullable, as allocating memory for the object may fail. Callers must check for this error before using the resulting pointer.
| T | An unbounded array type, like int[]. |
| [in] | count | Number of objects to allocate. |
| [in] | alignment | Alignment to use for the start of the array. |
|
inline |
Modifies the size of a previously-allocated block of memory.
Returns pointer to the modified block of memory, or nullptr if the memory could not be modified.
The data stored by the memory being modified must be trivially copyable. If it is not, callers should themselves attempt to Resize, then Allocate, move the data, and Deallocate as needed.
If nullptr is returned, the block of memory is unchanged. In particular, if the new_layout has a size of 0, the given pointer will NOT be deallocated.
TODO(b/331290408): This error condition needs to be better communicated to module users, who may assume the pointer is freed.
Unlike Resize, providing a null pointer will return a new allocation.
If the request can be satisfied using Resize, the alignment parameter may be ignored.
| [in] | ptr | Pointer to previously-allocated memory. |
| [in] | new_layout | Describes the memory to be allocated. |
|
inline |
Modifies the size of an previously-allocated block of memory without copying any data.
Returns true if its size was changed without copying data to a new allocation; otherwise returns false.
In particular, it always returns true if the old_layout.size() equals new_size, and always returns false if the given pointer is null, the old_layout.size() is 0, or the new_size is 0.
| [in] | ptr | Pointer to previously-allocated memory. |
| [in] | new_size | Requested new size for the memory allocation. |