Skip to content

Commit

Permalink
YJIT: No need to fill to get UDF on ARM64
Browse files Browse the repository at this point in the history
On ARM64, all zeros is already undefined, so we don't need to do extra
work to fill new memory with undefined instructions.
  • Loading branch information
XrXr committed Oct 12, 2022
1 parent 166140a commit ad0c8a6
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions yjit/src/virtualmem.rs
Expand Up @@ -141,10 +141,16 @@ impl<A: Allocator> VirtualMemory<A> {
if !alloc.mark_writable(mapped_region_end.cast(), alloc_size_u32) {
return Err(FailedPageMapping);
}
// Fill new memory with PUSH DS (0x1E) so that executing uninitialized memory
// will fault with #UD in 64-bit mode. On Linux it becomes SIGILL and use the
// usual Ruby crash reporter.
std::slice::from_raw_parts_mut(mapped_region_end, alloc_size).fill(0x1E);
if cfg!(target_arch = "x86_64") {
// Fill new memory with PUSH DS (0x1E) so that executing uninitialized memory
// will fault with #UD in 64-bit mode. On Linux it becomes SIGILL and use the
// usual Ruby crash reporter.
std::slice::from_raw_parts_mut(mapped_region_end, alloc_size).fill(0x1E);
} else if cfg!(target_arch = "aarch64") {
// In aarch64, all zeros encodes UDF, so it's already what we want.
} else {
unreachable!("unknown arch");
}
}
self.mapped_region_bytes = self.mapped_region_bytes + alloc_size;

Expand Down Expand Up @@ -313,6 +319,8 @@ pub mod tests {
let mut virt = new_dummy_virt_mem();

virt.write_byte(virt.start_ptr(), 1).unwrap();

#[cfg(target_arch = "x86_64")]
assert!(
virt.allocator.memory[..PAGE_SIZE].iter().all(|&byte| byte != 0),
"Entire page should be initialized",
Expand Down

0 comments on commit ad0c8a6

Please sign in to comment.