From 35eb54f89f8db2a354aa4869d4ad9e581ba16140 Mon Sep 17 00:00:00 2001 From: Chris Tian Date: Sat, 21 Sep 2024 00:44:53 +0000 Subject: [PATCH 1/3] paged memory for uninitialized_memory --- crates/core/executor/src/executor.rs | 6 +++--- crates/core/executor/src/memory.rs | 8 ++++++++ crates/core/executor/src/state.rs | 13 +++++++------ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/crates/core/executor/src/executor.rs b/crates/core/executor/src/executor.rs index 991ba3cb0c..3614e520ae 100644 --- a/crates/core/executor/src/executor.rs +++ b/crates/core/executor/src/executor.rs @@ -383,7 +383,7 @@ impl<'a> Executor<'a> { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { // If addr has a specific value to be initialized with, use that, otherwise 0. - let value = self.state.uninitialized_memory.get(&addr).unwrap_or(&0); + let value = self.state.uninitialized_memory.get(addr).unwrap_or(&0); entry.insert(MemoryRecord { value: *value, shard: 0, timestamp: 0 }) } }; @@ -428,7 +428,7 @@ impl<'a> Executor<'a> { Entry::Occupied(entry) => entry.into_mut(), Entry::Vacant(entry) => { // If addr has a specific value to be initialized with, use that, otherwise 0. - let value = self.state.uninitialized_memory.get(&addr).unwrap_or(&0); + let value = self.state.uninitialized_memory.get(addr).unwrap_or(&0); entry.insert(MemoryRecord { value: *value, shard: 0, timestamp: 0 }) } @@ -1373,7 +1373,7 @@ impl<'a> Executor<'a> { // Program memory is initialized in the MemoryProgram chip and doesn't require any // events, so we only send init events for other memory addresses. if !self.record.program.memory_image.contains_key(&addr) { - let initial_value = self.state.uninitialized_memory.get(&addr).unwrap_or(&0); + let initial_value = self.state.uninitialized_memory.get(addr).unwrap_or(&0); memory_initialize_events.push(MemoryInitializeFinalizeEvent::initialize( addr, *initial_value, diff --git a/crates/core/executor/src/memory.rs b/crates/core/executor/src/memory.rs index 4a1c2c9418..7f7b16bbfb 100644 --- a/crates/core/executor/src/memory.rs +++ b/crates/core/executor/src/memory.rs @@ -185,6 +185,14 @@ impl<'a, V> Entry<'a, V> { Entry::Occupied(entry) => entry.into_mut(), } } + + pub fn and_modify(mut self, f: F) -> Self { + match &mut self { + Entry::Vacant(_) => {} + Entry::Occupied(entry) => f(entry.get_mut()), + } + self + } } /// A vacant entry of `PagedMemory`, for in-place manipulation. diff --git a/crates/core/executor/src/state.rs b/crates/core/executor/src/state.rs index 70dbd08404..d89d9aca5e 100644 --- a/crates/core/executor/src/state.rs +++ b/crates/core/executor/src/state.rs @@ -43,11 +43,12 @@ pub struct ExecutionState { /// Uninitialized memory addresses that have a specific value they should be initialized with. /// `SyscallHintRead` uses this to write hint data into uninitialized memory. - #[serde( - serialize_with = "serialize_hashmap_as_vec", - deserialize_with = "deserialize_hashmap_as_vec" - )] - pub uninitialized_memory: HashMap>, + // #[serde( + // serialize_with = "serialize_hashmap_as_vec", + // deserialize_with = "deserialize_hashmap_as_vec" + // )] + // pub uninitialized_memory: HashMap>, + pub uninitialized_memory: PagedMemory, /// A stream of input values (global to the entire program). pub input_stream: Vec>, @@ -84,7 +85,7 @@ impl ExecutionState { channel: 0, pc: pc_start, memory: PagedMemory::new_preallocated(), - uninitialized_memory: HashMap::default(), + uninitialized_memory: Default::default(), input_stream: Vec::new(), input_stream_ptr: 0, public_values_stream: Vec::new(), From 62d7d74abeb4e33d3f64c17b645e05d849b53892 Mon Sep 17 00:00:00 2001 From: Chris Tian Date: Mon, 23 Sep 2024 15:15:51 -0700 Subject: [PATCH 2/3] cleanup --- crates/core/executor/src/lib.rs | 1 - crates/core/executor/src/state.rs | 9 +-------- crates/core/executor/src/utils.rs | 18 ------------------ 3 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 crates/core/executor/src/utils.rs diff --git a/crates/core/executor/src/lib.rs b/crates/core/executor/src/lib.rs index b6e8ae9c86..472bc7d7c8 100644 --- a/crates/core/executor/src/lib.rs +++ b/crates/core/executor/src/lib.rs @@ -37,7 +37,6 @@ mod report; mod state; pub mod subproof; pub mod syscalls; -mod utils; pub use context::*; pub use executor::*; diff --git a/crates/core/executor/src/state.rs b/crates/core/executor/src/state.rs index d89d9aca5e..c749db9c76 100644 --- a/crates/core/executor/src/state.rs +++ b/crates/core/executor/src/state.rs @@ -4,7 +4,6 @@ use std::{ }; use hashbrown::HashMap; -use nohash_hasher::BuildNoHashHasher; use serde::{Deserialize, Serialize}; use sp1_stark::{baby_bear_poseidon2::BabyBearPoseidon2, ShardProof, StarkVerifyingKey}; @@ -13,7 +12,6 @@ use crate::{ memory::PagedMemory, record::{ExecutionRecord, MemoryAccessRecord}, syscalls::SyscallCode, - utils::{deserialize_hashmap_as_vec, serialize_hashmap_as_vec}, ExecutorMode, }; @@ -43,11 +41,6 @@ pub struct ExecutionState { /// Uninitialized memory addresses that have a specific value they should be initialized with. /// `SyscallHintRead` uses this to write hint data into uninitialized memory. - // #[serde( - // serialize_with = "serialize_hashmap_as_vec", - // deserialize_with = "deserialize_hashmap_as_vec" - // )] - // pub uninitialized_memory: HashMap>, pub uninitialized_memory: PagedMemory, /// A stream of input values (global to the entire program). @@ -85,7 +78,7 @@ impl ExecutionState { channel: 0, pc: pc_start, memory: PagedMemory::new_preallocated(), - uninitialized_memory: Default::default(), + uninitialized_memory: PagedMemory::default(), input_stream: Vec::new(), input_stream_ptr: 0, public_values_stream: Vec::new(), diff --git a/crates/core/executor/src/utils.rs b/crates/core/executor/src/utils.rs deleted file mode 100644 index 2b1448a893..0000000000 --- a/crates/core/executor/src/utils.rs +++ /dev/null @@ -1,18 +0,0 @@ -use hashbrown::HashMap; - -use nohash_hasher::BuildNoHashHasher; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -pub fn serialize_hashmap_as_vec( - map: &HashMap>, - serializer: S, -) -> Result { - Serialize::serialize(&map.iter().collect::>(), serializer) -} - -pub fn deserialize_hashmap_as_vec<'de, V: Deserialize<'de>, D: Deserializer<'de>>( - deserializer: D, -) -> Result>, D::Error> { - let seq: Vec<(u32, V)> = Deserialize::deserialize(deserializer)?; - Ok(seq.into_iter().collect()) -} From faf120fc845e5b3f2c018d375457ed3dccd542e3 Mon Sep 17 00:00:00 2001 From: Chris Tian Date: Tue, 24 Sep 2024 14:12:59 -0700 Subject: [PATCH 3/3] doc --- crates/core/executor/src/memory.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/executor/src/memory.rs b/crates/core/executor/src/memory.rs index 7f7b16bbfb..e6166c1c0c 100644 --- a/crates/core/executor/src/memory.rs +++ b/crates/core/executor/src/memory.rs @@ -186,6 +186,7 @@ impl<'a, V> Entry<'a, V> { } } + /// Provides in-place mutable access to an occupied entry before any potential inserts into the map. pub fn and_modify(mut self, f: F) -> Self { match &mut self { Entry::Vacant(_) => {}