@@ -20,6 +20,7 @@ use fmt;
20
20
use mem;
21
21
use usize;
22
22
use ptr:: { self , NonNull } ;
23
+ use num:: NonZeroUsize ;
23
24
24
25
extern {
25
26
/// An opaque, unsized type. Used for pointers to allocated memory.
@@ -66,7 +67,7 @@ fn size_align<T>() -> (usize, usize) {
66
67
#[ derive( Copy , Clone , Debug , PartialEq , Eq ) ]
67
68
pub struct Layout {
68
69
// size of the requested block of memory, measured in bytes.
69
- size : usize ,
70
+ size_ : usize ,
70
71
71
72
// alignment of the requested block of memory, measured in bytes.
72
73
// we ensure that this is always a power-of-two, because API's
@@ -75,17 +76,12 @@ pub struct Layout {
75
76
//
76
77
// (However, we do not analogously require `align >= sizeof(void*)`,
77
78
// even though that is *also* a requirement of `posix_memalign`.)
78
- align : usize ,
79
+ align_ : NonZeroUsize ,
79
80
}
80
81
81
-
82
- // FIXME: audit default implementations for overflow errors,
83
- // (potentially switching to overflowing_add and
84
- // overflowing_mul as necessary).
85
-
86
82
impl Layout {
87
83
/// Constructs a `Layout` from a given `size` and `align`,
88
- /// or returns `None ` if either of the following conditions
84
+ /// or returns `LayoutErr ` if either of the following conditions
89
85
/// are not met:
90
86
///
91
87
/// * `align` must be a power of two,
@@ -126,23 +122,23 @@ impl Layout {
126
122
///
127
123
/// # Safety
128
124
///
129
- /// This function is unsafe as it does not verify that `align` is
130
- /// a power-of-two nor `size` aligned to `align` fits within the
131
- /// address space (i.e. the `Layout::from_size_align` preconditions).
125
+ /// This function is unsafe as it does not verify the preconditions from
126
+ /// [`Layout::from_size_align`](#method.from_size_align).
132
127
#[ inline]
133
128
pub unsafe fn from_size_align_unchecked ( size : usize , align : usize ) -> Self {
134
- Layout { size : size, align : align }
129
+ Layout { size_ : size, align_ : NonZeroUsize :: new_unchecked ( align) }
135
130
}
136
131
137
132
/// The minimum size in bytes for a memory block of this layout.
138
133
#[ inline]
139
- pub fn size ( & self ) -> usize { self . size }
134
+ pub fn size ( & self ) -> usize { self . size_ }
140
135
141
136
/// The minimum byte alignment for a memory block of this layout.
142
137
#[ inline]
143
- pub fn align ( & self ) -> usize { self . align }
138
+ pub fn align ( & self ) -> usize { self . align_ . get ( ) }
144
139
145
140
/// Constructs a `Layout` suitable for holding a value of type `T`.
141
+ #[ inline]
146
142
pub fn new < T > ( ) -> Self {
147
143
let ( size, align) = size_align :: < T > ( ) ;
148
144
// Note that the align is guaranteed by rustc to be a power of two and
@@ -158,6 +154,7 @@ impl Layout {
158
154
/// Produces layout describing a record that could be used to
159
155
/// allocate backing structure for `T` (which could be a trait
160
156
/// or other unsized type like a slice).
157
+ #[ inline]
161
158
pub fn for_value < T : ?Sized > ( t : & T ) -> Self {
162
159
let ( size, align) = ( mem:: size_of_val ( t) , mem:: align_of_val ( t) ) ;
163
160
// See rationale in `new` for why this us using an unsafe variant below
@@ -181,18 +178,19 @@ impl Layout {
181
178
///
182
179
/// # Panics
183
180
///
184
- /// Panics if the combination of `self.size` and the given `align`
185
- /// violates the conditions listed in `from_size_align`.
181
+ /// Panics if the combination of `self.size()` and the given `align`
182
+ /// violates the conditions listed in
183
+ /// [`Layout::from_size_align`](#method.from_size_align).
186
184
#[ inline]
187
185
pub fn align_to ( & self , align : usize ) -> Self {
188
- Layout :: from_size_align ( self . size , cmp:: max ( self . align , align) ) . unwrap ( )
186
+ Layout :: from_size_align ( self . size ( ) , cmp:: max ( self . align ( ) , align) ) . unwrap ( )
189
187
}
190
188
191
189
/// Returns the amount of padding we must insert after `self`
192
190
/// to ensure that the following address will satisfy `align`
193
191
/// (measured in bytes).
194
192
///
195
- /// E.g. if `self.size` is 9, then `self.padding_needed_for(4)`
193
+ /// E.g. if `self.size() ` is 9, then `self.padding_needed_for(4)`
196
194
/// returns 3, because that is the minimum number of bytes of
197
195
/// padding required to get a 4-aligned address (assuming that the
198
196
/// corresponding memory block starts at a 4-aligned address).
@@ -203,9 +201,12 @@ impl Layout {
203
201
/// Note that the utility of the returned value requires `align`
204
202
/// to be less than or equal to the alignment of the starting
205
203
/// address for the whole allocated block of memory. One way to
206
- /// satisfy this constraint is to ensure `align <= self.align`.
204
+ /// satisfy this constraint is to ensure `align <= self.align() `.
207
205
#[ inline]
208
206
pub fn padding_needed_for ( & self , align : usize ) -> usize {
207
+ // **FIXME**: This function is only called with proper power-of-two
208
+ // alignments. Maybe we should turn this into a real assert!.
209
+ debug_assert ! ( align. is_power_of_two( ) ) ;
209
210
let len = self . size ( ) ;
210
211
211
212
// Rounded up value is:
@@ -227,7 +228,8 @@ impl Layout {
227
228
// size and padding overflow in the above manner should cause
228
229
// the allocator to yield an error anyway.)
229
230
230
- let len_rounded_up = len. wrapping_add ( align) . wrapping_sub ( 1 ) & !align. wrapping_sub ( 1 ) ;
231
+ let len_rounded_up = len. wrapping_add ( align) . wrapping_sub ( 1 )
232
+ & !align. wrapping_sub ( 1 ) ;
231
233
return len_rounded_up. wrapping_sub ( len) ;
232
234
}
233
235
@@ -238,14 +240,14 @@ impl Layout {
238
240
/// layout of the array and `offs` is the distance between the start
239
241
/// of each element in the array.
240
242
///
241
- /// On arithmetic overflow, returns `None `.
243
+ /// On arithmetic overflow, returns `LayoutErr `.
242
244
#[ inline]
243
245
pub fn repeat ( & self , n : usize ) -> Result < ( Self , usize ) , LayoutErr > {
244
- let padded_size = self . size . checked_add ( self . padding_needed_for ( self . align ) )
246
+ let padded_size = self . size ( ) . checked_add ( self . padding_needed_for ( self . align ( ) ) )
245
247
. ok_or ( LayoutErr { private : ( ) } ) ?;
246
248
let alloc_size = padded_size. checked_mul ( n)
247
249
. ok_or ( LayoutErr { private : ( ) } ) ?;
248
- Ok ( ( Layout :: from_size_align ( alloc_size, self . align ) ?, padded_size) )
250
+ Ok ( ( Layout :: from_size_align ( alloc_size, self . align ( ) ) ?, padded_size) )
249
251
}
250
252
251
253
/// Creates a layout describing the record for `self` followed by
@@ -258,16 +260,16 @@ impl Layout {
258
260
/// start of the `next` embedded within the concatenated record
259
261
/// (assuming that the record itself starts at offset 0).
260
262
///
261
- /// On arithmetic overflow, returns `None `.
263
+ /// On arithmetic overflow, returns `LayoutErr `.
262
264
pub fn extend ( & self , next : Self ) -> Result < ( Self , usize ) , LayoutErr > {
263
- let new_align = cmp:: max ( self . align , next. align ) ;
264
- let realigned = Layout :: from_size_align ( self . size , new_align) ?;
265
+ let new_align = cmp:: max ( self . align ( ) , next. align ( ) ) ;
266
+ let realigned = Layout :: from_size_align ( self . size ( ) , new_align) ?;
265
267
266
- let pad = realigned. padding_needed_for ( next. align ) ;
268
+ let pad = realigned. padding_needed_for ( next. align ( ) ) ;
267
269
268
- let offset = self . size . checked_add ( pad)
270
+ let offset = self . size ( ) . checked_add ( pad)
269
271
. ok_or ( LayoutErr { private : ( ) } ) ?;
270
- let new_size = offset. checked_add ( next. size )
272
+ let new_size = offset. checked_add ( next. size ( ) )
271
273
. ok_or ( LayoutErr { private : ( ) } ) ?;
272
274
273
275
let layout = Layout :: from_size_align ( new_size, new_align) ?;
@@ -285,10 +287,10 @@ impl Layout {
285
287
/// guaranteed that all elements in the array will be properly
286
288
/// aligned.
287
289
///
288
- /// On arithmetic overflow, returns `None `.
290
+ /// On arithmetic overflow, returns `LayoutErr `.
289
291
pub fn repeat_packed ( & self , n : usize ) -> Result < Self , LayoutErr > {
290
292
let size = self . size ( ) . checked_mul ( n) . ok_or ( LayoutErr { private : ( ) } ) ?;
291
- Layout :: from_size_align ( size, self . align )
293
+ Layout :: from_size_align ( size, self . align ( ) )
292
294
}
293
295
294
296
/// Creates a layout describing the record for `self` followed by
@@ -305,17 +307,17 @@ impl Layout {
305
307
/// signature out of convenience in matching the signature of
306
308
/// `extend`.)
307
309
///
308
- /// On arithmetic overflow, returns `None `.
310
+ /// On arithmetic overflow, returns `LayoutErr `.
309
311
pub fn extend_packed ( & self , next : Self ) -> Result < ( Self , usize ) , LayoutErr > {
310
312
let new_size = self . size ( ) . checked_add ( next. size ( ) )
311
313
. ok_or ( LayoutErr { private : ( ) } ) ?;
312
- let layout = Layout :: from_size_align ( new_size, self . align ) ?;
314
+ let layout = Layout :: from_size_align ( new_size, self . align ( ) ) ?;
313
315
Ok ( ( layout, self . size ( ) ) )
314
316
}
315
317
316
318
/// Creates a layout describing the record for a `[T; n]`.
317
319
///
318
- /// On arithmetic overflow, returns `None `.
320
+ /// On arithmetic overflow, returns `LayoutErr `.
319
321
pub fn array < T > ( n : usize ) -> Result < Self , LayoutErr > {
320
322
Layout :: new :: < T > ( )
321
323
. repeat ( n)
@@ -834,7 +836,7 @@ pub unsafe trait Alloc {
834
836
layout : Layout ,
835
837
new_size : usize ) -> Result < ( ) , CannotReallocInPlace > {
836
838
let _ = ptr; // this default implementation doesn't care about the actual address.
837
- debug_assert ! ( new_size >= layout. size) ;
839
+ debug_assert ! ( new_size >= layout. size( ) ) ;
838
840
let ( _l, u) = self . usable_size ( & layout) ;
839
841
// _l <= layout.size() [guaranteed by usable_size()]
840
842
// layout.size() <= new_layout.size() [required by this method]
@@ -889,7 +891,7 @@ pub unsafe trait Alloc {
889
891
layout : Layout ,
890
892
new_size : usize ) -> Result < ( ) , CannotReallocInPlace > {
891
893
let _ = ptr; // this default implementation doesn't care about the actual address.
892
- debug_assert ! ( new_size <= layout. size) ;
894
+ debug_assert ! ( new_size <= layout. size( ) ) ;
893
895
let ( l, _u) = self . usable_size ( & layout) ;
894
896
// layout.size() <= _u [guaranteed by usable_size()]
895
897
// new_layout.size() <= layout.size() [required by this method]
0 commit comments