Skip to content

Commit 9b01ca8

Browse files
committed
add missing _excess methods to Alloc
1 parent 8f39dba commit 9b01ca8

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

src/libcore/alloc.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,28 @@ pub unsafe trait Alloc {
794794
.map(|p| Excess(p, usable_size.1))
795795
}
796796

797+
/// Behaves like `alloc`, but also ensures that the contents are set to zero
798+
/// before being returned. For some `layout` inputs, like arrays, this may
799+
/// include extra storage usable for additional data.
800+
///
801+
/// # Safety
802+
///
803+
/// This function is unsafe for the same reasons that `alloc` is.
804+
///
805+
/// # Errors
806+
///
807+
/// Returning `Err` indicates that either memory is exhausted or
808+
/// `layout` does not meet allocator's size or alignment
809+
/// constraints, just as in `alloc`.
810+
///
811+
/// Clients wishing to abort computation in response to an
812+
/// allocation error are encouraged to call the allocator's `oom`
813+
/// method, rather than directly invoking `panic!` or similar.
814+
unsafe fn alloc_zeroed_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
815+
let usable_size = self.usable_size(&layout);
816+
self.alloc_zeroed(layout).map(|p| Excess(p, usable_size.1))
817+
}
818+
797819
/// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
798820
///
799821
/// If this returns `Ok`, then the allocator has asserted that the
@@ -845,6 +867,60 @@ pub unsafe trait Alloc {
845867
}
846868
}
847869

870+
/// Attempts to extend the allocation referenced by `ptr` to fit `new_size`.
871+
/// For some `layout` inputs, like arrays, this may include extra storage
872+
/// usable for additional data.
873+
///
874+
/// If this returns `Ok`, then the allocator has asserted that the
875+
/// memory block referenced by `ptr` now fits `new_size`, and thus can
876+
/// be used to carry data of a layout of that size and same alignment as
877+
/// `layout`. (The allocator is allowed to
878+
/// expend effort to accomplish this, such as extending the memory block to
879+
/// include successor blocks, or virtual memory tricks.)
880+
///
881+
/// Regardless of what this method returns, ownership of the
882+
/// memory block referenced by `ptr` has not been transferred, and
883+
/// the contents of the memory block are unaltered.
884+
///
885+
/// # Safety
886+
///
887+
/// This function is unsafe because undefined behavior can result
888+
/// if the caller does not ensure all of the following:
889+
///
890+
/// * `ptr` must be currently allocated via this allocator,
891+
///
892+
/// * `layout` must *fit* the `ptr` (see above); note the
893+
/// `new_size` argument need not fit it,
894+
///
895+
/// * `new_size` must not be less than `layout.size()`,
896+
///
897+
/// # Errors
898+
///
899+
/// Returns `Err(CannotReallocInPlace)` when the allocator is
900+
/// unable to assert that the memory block referenced by `ptr`
901+
/// could fit `layout`.
902+
///
903+
/// Note that one cannot pass `CannotReallocInPlace` to the `oom`
904+
/// method; clients are expected either to be able to recover from
905+
/// `grow_in_place` failures without aborting, or to fall back on
906+
/// another reallocation method before resorting to an abort.
907+
unsafe fn grow_in_place_excess(&mut self,
908+
ptr: NonNull<Opaque>,
909+
layout: Layout,
910+
new_size: usize) -> Result<Excess, CannotReallocInPlace> {
911+
let _ = ptr; // this default implementation doesn't care about the actual address.
912+
debug_assert!(new_size >= layout.size);
913+
let (_l, u) = self.usable_size(&layout);
914+
// _l <= layout.size() [guaranteed by usable_size()]
915+
// layout.size() <= new_layout.size() [required by this method]
916+
if new_size <= u {
917+
return Ok(Excess(ptr, u));
918+
} else {
919+
return Err(CannotReallocInPlace);
920+
}
921+
}
922+
923+
848924
/// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
849925
///
850926
/// If this returns `Ok`, then the allocator has asserted that the
@@ -900,6 +976,62 @@ pub unsafe trait Alloc {
900976
}
901977
}
902978

979+
/// Attempts to shrink the allocation referenced by `ptr` to fit `new_size`.
980+
/// For some `layout` inputs, like arrays, this may include extra storage
981+
/// usable for additional data.
982+
///
983+
/// If this returns `Ok`, then the allocator has asserted that the
984+
/// memory block referenced by `ptr` now fits `new_size`, and
985+
/// thus can only be used to carry data of that smaller
986+
/// layout. (The allocator is allowed to take advantage of this,
987+
/// carving off portions of the block for reuse elsewhere.) The
988+
/// truncated contents of the block within the smaller layout are
989+
/// unaltered, and ownership of block has not been transferred.
990+
///
991+
/// If this returns `Err`, then the memory block is considered to
992+
/// still represent the original (larger) `layout`. None of the
993+
/// block has been carved off for reuse elsewhere, ownership of
994+
/// the memory block has not been transferred, and the contents of
995+
/// the memory block are unaltered.
996+
///
997+
/// # Safety
998+
///
999+
/// This function is unsafe because undefined behavior can result
1000+
/// if the caller does not ensure all of the following:
1001+
///
1002+
/// * `ptr` must be currently allocated via this allocator,
1003+
///
1004+
/// * `layout` must *fit* the `ptr` (see above); note the
1005+
/// `new_size` argument need not fit it,
1006+
///
1007+
/// * `new_size` must not be greater than `layout.size()`
1008+
/// (and must be greater than zero),
1009+
///
1010+
/// # Errors
1011+
///
1012+
/// Returns `Err(CannotReallocInPlace)` when the allocator is
1013+
/// unable to assert that the memory block referenced by `ptr`
1014+
/// could fit `layout`.
1015+
///
1016+
/// Note that one cannot pass `CannotReallocInPlace` to the `oom`
1017+
/// method; clients are expected either to be able to recover from
1018+
/// `shrink_in_place` failures without aborting, or to fall back
1019+
/// on another reallocation method before resorting to an abort.
1020+
unsafe fn shrink_in_place_excess(&mut self,
1021+
ptr: NonNull<Opaque>,
1022+
layout: Layout,
1023+
new_size: usize) -> Result<Excess, CannotReallocInPlace> {
1024+
let _ = ptr; // this default implementation doesn't care about the actual address.
1025+
debug_assert!(new_size <= layout.size);
1026+
let (l, u) = self.usable_size(&layout);
1027+
// layout.size() <= _u [guaranteed by usable_size()]
1028+
// new_layout.size() <= layout.size() [required by this method]
1029+
if l <= new_size {
1030+
return Ok(Excess(ptr, u));
1031+
} else {
1032+
return Err(CannotReallocInPlace);
1033+
}
1034+
}
9031035

9041036
// == COMMON USAGE PATTERNS ==
9051037
// alloc_one, dealloc_one, alloc_array, realloc_array. dealloc_array

0 commit comments

Comments
 (0)