An allocator that can "frame" its allocation with a leading prefix type, a trailing suffix type, or both.
At least one of Prefix and Suffix must be a type other than void, since in that case there is no need for a frame.
In addition to the template parameter types, each allocation will include up to three additional size_t fields.
void. When present, this field is located just before the usable memory.void, or at the start of the frame.void, or just before the usable memory.The frame offset and data offset locations may match, i.e. the field just after the prefix is right before the suffix offset or usable memory. In this case, only one offset is stored as both the frame and data offset.
Thus assuming sizeof(size_t) == 4, requesting a 64-byte allocation with a 16-byte alignment from a FramingAllocator<uint32_t, uint16_t> might result in an allocation that looks like:
Alternatively, if the selected memory for the same allocation happens to start at 0x...04, the prefix offsets will be combined:
Let's drop the suffix for simplicity. If we make a similar allocation from a FramingAllocator<uint32_t, void> that happens to start at 0x...0C, we get the worst case scenario for padding to maintain alignment:
Finally, requesting a 64-byte allocation with a 16-byte alignment from a suffix-only FramingAllocator<void, uint16_t> might result in an allocation that looks like:
Suffix and the allocated data both have an alignment of alignof(size_t) or less.| Prefix | A default constructible and trivially copyable type to place before each allocation, or void. alignof(Prefix) must be at most alignof(size_t). |
| Suffix | A default constructible and trivially copyable type to place after each allocation, or void. |
| ErrorHandler | Used to report frame validation errors. |
Protected Types | |
| using | Base = internal::BaseFramingAllocator< ErrorHandler > |
Protected Types inherited from pw::Deallocator | |
| enum class | InfoType { kRequestedLayoutOf , kUsableLayoutOf , kAllocatedLayoutOf , kCapacity , kRecognizes } |
Protected Member Functions | |
| constexpr | FramingAllocator (pw::Allocator &allocator) |
| void * | DoAllocate (Layout layout) override |
| void | DoDeallocate (void *ptr) override |
| bool | DoResize (void *ptr, size_t new_size) override |
| bool | DoBeforeReallocate (void *ptr, Layout new_layout) override |
| void | DoAfterReallocateCopy (void *ptr, Layout new_layout, void *new_ptr) override |
| Result< Layout > | DoGetInfo (Deallocator::InfoType info_type, const void *ptr) const override |
| void * | GetFrame (void *data) const |
| const void * | GetFrame (const void *data) const |
| Prefix * | GetPrefix (void *data) const |
| const Prefix * | GetPrefix (const void *data) const |
| void * | GetData (void *frame) const |
| const void * | GetData (const void *data) const |
| Suffix * | GetSuffix (void *data) const |
| const Suffix * | GetSuffix (const void *data) const |
Protected Member Functions inherited from pw::allocator::internal::BaseFramingAllocator< ErrorHandler > | |
| constexpr | BaseFramingAllocator (Allocator &allocator) |
| ByteSpan | AllocateFrame (Layout prefix, Layout data, Layout suffix) |
| bool | ResizeFrame (void *data, size_t new_size, Layout suffix, void *tmp_suffix) |
| Result< Layout > | GetFrameInfo (InfoType info_type, const void *data, Layout suffix) const |
| Result< size_t > | GetFrameSize (const void *frame) const |
Protected Member Functions inherited from pw::allocator::ForwardingAllocator | |
| constexpr | ForwardingAllocator (const Capabilities &capabilities) noexcept |
| constexpr | ForwardingAllocator (pw::Allocator &allocator) noexcept |
| constexpr void | Init (pw::Allocator &allocator) |
| constexpr pw::Allocator & | allocator () |
| constexpr const pw::Allocator & | allocator () const |
| void * | DoAllocate (Layout layout) override |
| void | DoDeallocate (void *ptr) override |
| bool | DoResize (void *ptr, size_t new_size) override |
| bool | DoBeforeReallocate (void *ptr, Layout new_layout) override |
| void | DoAfterReallocateCopy (void *ptr, Layout new_layout, void *new_ptr) override |
| void | DoAfterReallocateDone (Layout new_layout, void *new_ptr) override |
| size_t | DoGetAllocated () const override |
| std::optional< Fragmentation > | DoMeasureFragmentation () const override |
| Returns fragmentation information for the allocator's memory region. | |
| Result< Layout > | DoGetInfo (InfoType info_type, const void *ptr) const override |
Protected Member Functions inherited from pw::Allocator | |
| 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 bool | 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 |
Additional Inherited Members | |
Public Types inherited from pw::Allocator | |
| 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 inherited from pw::Allocator | |
| 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) |
| template<typename ElementType > | |
| void | Destroy (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) |
Static Protected Member Functions inherited from pw::allocator::internal::BaseFramingAllocator< ErrorHandler > | |
| static constexpr size_t | Distance (const void *start, const void *end) |
| Returns the distance between two pointers in bytes. | |
| static void | UpdateOffsets (void *frame, void *data, void *suffix) |
| static void * | GetFrame (void *data, bool has_suffix, bool checked=true) |
| static const void * | GetFrame (const void *data, bool has_suffix, bool checked=true) |
| static void * | GetData (void *frame, Result< size_t > frame_size, Layout prefix) |
| static const void * | GetData (const void *frame, Result< size_t > frame_size, Layout prefix) |
| static void * | GetSuffix (void *data, size_t data_size, Layout suffix) |
| static const void * | GetSuffix (const void *data, size_t data_size, Layout suffix) |
Static Protected Member Functions inherited from pw::Allocator | |
| static bool | 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) |
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> |
|
overrideprotectedvirtual |
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 from pw::allocator::ForwardingAllocator.
Reimplemented in pw::allocator::internal::BasicGuardedAllocator< internal::DefaultGuardErrorHandler >.
|
overrideprotectedvirtual |
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. |
Reimplemented from pw::allocator::ForwardingAllocator.
Reimplemented in pw::allocator::internal::BasicGuardedAllocator< internal::DefaultGuardErrorHandler >.
|
overrideprotectedvirtual |
Called at the start of the default implementation of DoReallocate.
By default, returns true. Derived types may implement this method to add additional behavior. If they do, they must return false or the value returned by DoBeforeReallocate. If false is returned, the reallocation fails and returns null.
ptr is guaranteed to be non-null, and new_layout.size() is guaranteed to be non-zero.
Reimplemented from pw::allocator::ForwardingAllocator.
Reimplemented in pw::allocator::internal::BasicGuardedAllocator< internal::DefaultGuardErrorHandler >.
|
overrideprotectedvirtual |
Releases a previously-allocated block of memory.
The given pointer must have been previously provided by this memory resource; otherwise the behavior is undefined.
| [in] | ptr | Pointer to previously-allocated memory. |
Reimplemented from pw::allocator::ForwardingAllocator.
Reimplemented in pw::allocator::internal::BasicGuardedAllocator< internal::DefaultGuardErrorHandler >.
|
inlineoverrideprotectedvirtual |
Returns deallocator-specific information about allocations.
Deallocators may support any number of InfoTypes. See that type for what each supported type returns. For unsupported types, this method returns UNIMPLEMENTED.
Reimplemented from pw::allocator::ForwardingAllocator.
|
overrideprotectedvirtual |
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 from pw::allocator::ForwardingAllocator.
Reimplemented in pw::allocator::internal::BasicGuardedAllocator< internal::DefaultGuardErrorHandler >.
|
protected |
Returns a data pointer from a frame pointer.
|
protected |
Returns the frame pointer from a data pointer, that is, return a pointer to memory holding the prefix, usable memory, and suffix from a pointer to the usable memory.
|
protected |
Returns a pointer to prefix.
It is an error to call this method if the prefix type is void.
|
protected |
Returns a pointer to the suffix.
It is an error to call this method if the suffix type is void.