[−][src]Trait object_alloc::ObjectAlloc
Allocators which allocate objects of a particular type.
ObjectAlloc
s provide an interface which is slightly different than the interface provided by
a standard allocator. By definition, they are only capable of allocating objects of a
particular type. Additionally, memory returned from a call to alloc
is guaranteed to already
be a valid, initialized instance of T
. ObjectAlloc
s may differ in how much flexibility they
provide in specifying how allocated objects are initialized, and ObjectAlloc
s obtained using
unsafe
constructors are allowed to break these initialization rules, allocating uninitialized
or invalid objects.
These differences allow ObjectAlloc
s to provide significant performance improvements over
general-purpose allocators. First, only having to allocate objects of a particular size and
alignment allows them to make optimizations that are not available to general-purpose
allocators. Second, since alloc
is required to return already-constructed objects, clients
don't have to initialize allocated objects. This, coupled with an object-caching scheme for
dealloc
'd objects, allows many calls to allloc
to avoid initialization altogether.
Dropping
When an ObjectAlloc
that allocates initialized objects is dropped, all cached T
objects
that have not yet been dropped are dropped. The order in which they are dropped is undefined.
Use in unsafe code
Unsafe code may rely on the fact that objects allocated by an ObjectAlloc
are initialized.
Because of this, it must not be possible for safe code to construct an ObjectAlloc
that
doesn't properly initialize objects, or else safe code could construct such an ObjectAlloc
,
pass it to a safe API that uses unsafe code under the hood (and that relies on the
initialization behavior of ObjectAlloc
s), and thus cause memory unsafety.
It is acceptable for implementors to provide constructors that produce ObjectAlloc
s that do
not abide by the initialization requirements, but these constructors must be unsafe
so that
they cannot be called from safe code.
Required methods
unsafe fn alloc(&mut self) -> Option<NonNull<T>>
Allocates an object of type T
.
If this ObjectAlloc
was obtained using a safe constructor (as opposed to an unsafe
one), then the memory pointed to by the returned raw pointer is guaranteed to be a valid,
initialized instance of T
. In particular, the returned object will be in one of the
following two states:
- The result of a call to whatever initialization function was used to configure this
ObjectAlloc
- The same state as a
T
which was previously returned via a call todealloc
On the other hand, if this ObjectAlloc
was obtained using an unsafe
constructor, then
alloc
may return uninitialized or invalid instances of T
- the exact behavior should
be documented in the constructor.
The memory returned by alloc
is guaranteed to be aligned according to the requirements of
T
(that is, according to core::mem::align_of::<T>()
).
unsafe fn dealloc(&mut self, x: NonNull<T>)
Deallocates an object previously returned by alloc
.
If x
was not obtained through a call to alloc
, or if x
has already been dealloc
'd,
the behavior of dealloc
is undefined.
It is valid for x
to be cached and used to serve future calls to alloc
. The only
guarantee that is made is that if this ObjectAlloc
allocates initialized objects (unsafe
constructors are allowed to produce ObjectAlloc
s that do not allocate initialized
objects), then x
will be dropped at some point during the ObjectAlloc
's lifetime. This
may happen during this call to dealloc
, when the ObjectAlloc
itself is dropped, or some
time in between.
Provided methods
fn oom(&mut self) -> !
Allocator-specific method for signalling an out-of-memory condition.
oom
aborts the thread or process, optionally performing cleanup or logging diagnostic
information before panicking or aborting.
oom
is meant to be used by clients which are unable to cope with an unsatisfied
allocation request, and wish to abandon computation rather than attempt to recover locally.
The allocator likely has more insight into why the request failed, and thus can likely
print more informative diagnostic information than the client could.
Implementations of the oom
method are discouraged from infinitely regressing in nested
calls to oom
. In practice this means implementors should eschew allocating, especially
from self
(directly or indirectly).
Implementions of alloc
are discouraged from panicking (or aborting) in the event of
memory exhaustion; instead they should return an error and let the client decide whether to
invoke this oom
method in response.