Skip to content

Commit 7cca404

Browse files
committed
Consider regions that lead to very small back paddings as unsuitable
If the resulting back padding is too small to be stored as a hole, we treat the hole as unsuitable for the allocation. This way, we avoid unrecoverable leaks of that back padding, which can add up over time and fragment the heap.
1 parent 9e5878a commit 7cca404

File tree

1 file changed

+24
-24
lines changed

1 file changed

+24
-24
lines changed

src/hole.rs

+24-24
Original file line numberDiff line numberDiff line change
@@ -120,31 +120,31 @@ impl Cursor {
120120
alloc_ptr = aligned_addr;
121121
alloc_size = required_size;
122122

123-
// Okay, time to move onto the back padding. Here, we are opportunistic -
124-
// if it fits, we sits. Otherwise we just skip adding the back padding, and
125-
// sort of assume that the allocation is actually a bit larger than it
126-
// actually needs to be.
127-
//
128-
// NOTE: Because we always use `HoleList::align_layout`, the size of
129-
// the new allocation is always "rounded up" to cover any partial gaps that
130-
// would have occurred. For this reason, we DON'T need to "round up"
131-
// to account for an unaligned hole spot.
132-
let hole_layout = Layout::new::<Hole>();
133-
let back_padding_start = align_up(allocation_end, hole_layout.align());
134-
let back_padding_end = back_padding_start.wrapping_add(hole_layout.size());
135-
136-
// Will the proposed new back padding actually fit in the old hole slot?
137-
back_padding = if back_padding_end <= hole_end {
138-
// Yes, it does! Place a back padding node
139-
Some(HoleInfo {
140-
addr: back_padding_start,
141-
size: (hole_end as usize) - (back_padding_start as usize),
142-
})
143-
} else {
144-
// No, it does not. We are now pretending the allocation now
145-
// holds the extra 0..size_of::<Hole>() bytes that are not
146-
// big enough to hold what SHOULD be back_padding
123+
// Okay, time to move onto the back padding.
124+
let back_padding_size = hole_end as usize - allocation_end as usize;
125+
back_padding = if back_padding_size == 0 {
147126
None
127+
} else {
128+
// NOTE: Because we always use `HoleList::align_layout`, the size of
129+
// the new allocation is always "rounded up" to cover any partial gaps that
130+
// would have occurred. For this reason, we DON'T need to "round up"
131+
// to account for an unaligned hole spot.
132+
let hole_layout = Layout::new::<Hole>();
133+
let back_padding_start = align_up(allocation_end, hole_layout.align());
134+
let back_padding_end = back_padding_start.wrapping_add(hole_layout.size());
135+
136+
// Will the proposed new back padding actually fit in the old hole slot?
137+
if back_padding_end <= hole_end {
138+
// Yes, it does! Place a back padding node
139+
Some(HoleInfo {
140+
addr: back_padding_start,
141+
size: back_padding_size,
142+
})
143+
} else {
144+
// No, it does not. We don't want to leak any heap bytes, so we
145+
// consider this hole unsuitable for the requested allocation.
146+
return Err(self);
147+
}
148148
};
149149
}
150150

0 commit comments

Comments
 (0)