- let base_addr = Self::align_addr(global_state.next_base_addr, alloc.align.bytes());
- global_state.next_base_addr = base_addr + alloc.bytes.len() as u64;
- alloc.extra.intptrcast.base_addr.set(Some(base_addr));
+ // Leave some space to the previous allocation, to give it some chance to be less aligned.
+ let slack = {
+ let mut rng = memory.extra.rng.borrow_mut();
+ // This means that `(global_state.next_base_addr + slack) % 16` is uniformly distributed.
+ rng.gen_range(0, 16)
+ };
+ // From next_base_addr + slack, round up to adjust for alignment.
+ let base_addr = global_state.next_base_addr.checked_add(slack).unwrap();
+ let base_addr = Self::align_addr(base_addr, align.bytes());
+ entry.insert(base_addr);
+ trace!(
+ "Assigning base address {:#x} to allocation {:?} (slack: {}, align: {})",
+ base_addr,
+ id,
+ slack,
+ align.bytes(),
+ );
+
+ // Remember next base address. If this allocation is zero-sized, leave a gap
+ // of at least 1 to avoid two allocations having the same base address.
+ global_state.next_base_addr = base_addr.checked_add(max(size.bytes(), 1)).unwrap();