Skip to content

Commit f55f7f9

Browse files
committed
Fix free logic
1 parent cf6a569 commit f55f7f9

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

src/hole.rs

+29-22
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ impl HoleList {
234234
}
235235
}
236236

237-
#[cfg(test)]
238237
#[allow(dead_code)]
239238
pub(crate) fn debug(&mut self) {
240239
if let Some(cursor) = self.cursor() {
@@ -421,36 +420,44 @@ impl Cursor {
421420
}
422421

423422
fn try_insert_after(&mut self, mut node: NonNull<Hole>) -> Result<(), ()> {
424-
if self.hole < node {
425-
let node_u8 = node.as_ptr().cast::<u8>();
426-
let node_size = unsafe { node.as_ref().size };
427-
let hole_u8 = self.hole.as_ptr().cast::<u8>();
428-
let hole_size = self.current().size;
423+
let node_u8 = node.as_ptr().cast::<u8>();
424+
let node_size = unsafe { node.as_ref().size };
429425

430-
// Does hole overlap node?
431-
assert!(
432-
hole_u8.wrapping_add(hole_size) <= node_u8,
433-
"Freed node aliases existing hole! Bad free?",
434-
);
435-
436-
// If we have a next, does the node overlap next?
437-
if let Some(next) = self.current().next.as_ref() {
426+
// If we have a next, does the node overlap next?
427+
if let Some(next) = self.current().next.as_ref() {
428+
if node < *next {
438429
let node_u8 = node_u8 as *const u8;
439430
assert!(
440431
node_u8.wrapping_add(node_size) <= next.as_ptr().cast::<u8>(),
441432
"Freed node aliases existing hole! Bad free?",
442433
);
434+
} else {
435+
// The new hole isn't between current and next.
436+
return Err(());
443437
}
438+
}
444439

445-
// All good! Let's insert that after.
446-
unsafe {
447-
let maybe_next = self.hole.as_mut().next.replace(node);
448-
node.as_mut().next = maybe_next;
449-
}
450-
Ok(())
451-
} else {
452-
Err(())
440+
// At this point, we either have no "next" pointer, or the hole is
441+
// between current and "next". The following assert can only trigger
442+
// if we've gotten our list out of order.
443+
debug_assert!(self.hole < node, "Hole list out of order?");
444+
445+
let hole_u8 = self.hole.as_ptr().cast::<u8>();
446+
let hole_size = self.current().size;
447+
448+
// Does hole overlap node?
449+
assert!(
450+
hole_u8.wrapping_add(hole_size) <= node_u8,
451+
"Freed node aliases existing hole! Bad free?",
452+
);
453+
454+
// All good! Let's insert that after.
455+
unsafe {
456+
let maybe_next = self.hole.as_mut().next.replace(node);
457+
node.as_mut().next = maybe_next;
453458
}
459+
460+
Ok(())
454461
}
455462

456463
// Merge the current node with up to n following nodes

src/lib.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
)]
66
#![no_std]
77

8-
#[cfg(test)]
98
#[macro_use]
109
extern crate std;
1110

@@ -160,10 +159,14 @@ impl Heap {
160159
pub fn allocate_first_fit(&mut self, layout: Layout) -> Result<NonNull<u8>, ()> {
161160
match self.holes.allocate_first_fit(layout) {
162161
Ok((ptr, aligned_layout)) => {
162+
self.holes.debug();
163163
self.used += aligned_layout.size();
164164
Ok(ptr)
165165
}
166-
Err(err) => Err(err),
166+
Err(err) => {
167+
println!("ERR");
168+
Err(err)
169+
}
167170
}
168171
}
169172

@@ -180,6 +183,7 @@ impl Heap {
180183
/// identical layout. Undefined behavior may occur for invalid arguments.
181184
pub unsafe fn deallocate(&mut self, ptr: NonNull<u8>, layout: Layout) {
182185
self.used -= self.holes.deallocate(ptr, layout).size();
186+
self.holes.debug();
183187
}
184188

185189
/// Returns the bottom address of the heap.

0 commit comments

Comments
 (0)