From 3727f02bb1e89d7cce9999d53c5a19993521f9db Mon Sep 17 00:00:00 2001 From: Jan Ferdinand Sauer Date: Thu, 6 Jun 2024 17:34:19 +0200 Subject: [PATCH] fix: Initialize vector before calling `.set_len()` The previous use of `.set_len()` did not uphold the safety contract, resulting in undefined behavior. [0, 1] Initializing the spare capacity before setting the length makes the behavior defined. [0] https://users.rust-lang.org/t/58755 [1] https://users.rust-lang.org/t/38248 --- triton-vm/src/table/master_table.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/triton-vm/src/table/master_table.rs b/triton-vm/src/table/master_table.rs index 6d1009e6..ba3a3c0d 100644 --- a/triton-vm/src/table/master_table.rs +++ b/triton-vm/src/table/master_table.rs @@ -1,4 +1,5 @@ use std::borrow::Borrow; +use std::mem::MaybeUninit; use std::ops::Mul; use std::ops::MulAssign; use std::ops::Range; @@ -314,25 +315,24 @@ where if should_cache { profiler!(start "resize"); assert!(extended_trace.capacity() >= num_elements); + extended_trace + .spare_capacity_mut() + .par_iter_mut() + .for_each(|e| *e = MaybeUninit::new(FF::zero())); + unsafe { // Speed up initialization through parallelization. // // SAFETY: // 1. The capacity is sufficiently large – see above `assert!`. // 2. The length is set to equal (or less than) the capacity. - // 3. Each element is over-written before being read in the - // immediately following lines. + // 3. Each element in the spare capacity is initialized. extended_trace.set_len(num_elements); } let mut extended_columns = Array2::from_shape_vec([num_rows, Self::NUM_COLUMNS], extended_trace).unwrap(); profiler!(stop "resize"); - // Speeds up the subsequent parallel iteration. Maybe because of page faults? - profiler!(start "touch memory"); - extended_columns.par_mapv_inplace(|_| FF::zero()); - profiler!(stop "touch memory"); - profiler!(start "evaluation"); Zip::from(extended_columns.axis_iter_mut(Axis(1))) .and(interpolation_polynomials.axis_iter(Axis(0)))