From 1c78064accff1d8837389166cf71587e332b9352 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 9 Feb 2022 15:30:12 +0300 Subject: [PATCH 1/3] optimize mload instruction to not allocate a temporary vector Naked-eye based optimization -- it feels suboptimal to allocate a `Vec` to fetch `[0; u32]`. Running a macro-benchmark in aurora shows that this is about a 1% win, so the compiler probably can't eliminate this vec entirely. --- core/src/eval/misc.rs | 2 +- core/src/memory.rs | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/core/src/eval/misc.rs b/core/src/eval/misc.rs index f3627b722..a44adc8e7 100644 --- a/core/src/eval/misc.rs +++ b/core/src/eval/misc.rs @@ -81,7 +81,7 @@ pub fn mload(state: &mut Machine) -> Control { pop_u256!(state, index); try_or_fail!(state.memory.resize_offset(index, U256::from(32))); let index = as_usize_or_fail!(index); - let value = H256::from_slice(&state.memory.get(index, 32)[..]); + let value = state.memory.get_h256(index); push!(state, value); Control::Continue(1) } diff --git a/core/src/memory.rs b/core/src/memory.rs index 7bb09629b..a23a4fdd4 100644 --- a/core/src/memory.rs +++ b/core/src/memory.rs @@ -2,7 +2,7 @@ use crate::{ExitError, ExitFatal}; use alloc::vec::Vec; use core::cmp::min; use core::ops::{BitAnd, Not}; -use primitive_types::U256; +use primitive_types::{U256, H256}; /// A sequencial memory. It uses Rust's `Vec` for internal /// representation. @@ -96,6 +96,23 @@ impl Memory { ret } + /// Get `H256` from a specific offset in memory. + pub fn get_h256(&self, offset: usize) -> H256 { + let mut ret = [0; 32]; + + #[allow(clippy::needless_range_loop)] + for index in 0..32 { + let position = offset + index; + if position >= self.data.len() { + break; + } + + ret[index] = self.data[position]; + } + + H256(ret) + } + /// Set memory region at given offset. The offset and value is considered /// untrusted. pub fn set( From f6d7cf302ce6bd36f7aebb7d7061f92c63b6a00d Mon Sep 17 00:00:00 2001 From: Michael Birch Date: Thu, 10 Feb 2022 20:26:54 +0100 Subject: [PATCH 2/3] cargo fmt --- core/src/memory.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/memory.rs b/core/src/memory.rs index a23a4fdd4..2f1f96393 100644 --- a/core/src/memory.rs +++ b/core/src/memory.rs @@ -2,7 +2,7 @@ use crate::{ExitError, ExitFatal}; use alloc::vec::Vec; use core::cmp::min; use core::ops::{BitAnd, Not}; -use primitive_types::{U256, H256}; +use primitive_types::{H256, U256}; /// A sequencial memory. It uses Rust's `Vec` for internal /// representation. From 1efd1d11fabad99fe7843d9ebcead627a29dfe51 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 14 Feb 2022 12:45:15 +0300 Subject: [PATCH 3/3] reduce duplication --- core/src/memory.rs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/core/src/memory.rs b/core/src/memory.rs index 2f1f96393..b16648133 100644 --- a/core/src/memory.rs +++ b/core/src/memory.rs @@ -82,35 +82,27 @@ impl Memory { pub fn get(&self, offset: usize, size: usize) -> Vec { let mut ret = Vec::new(); ret.resize(size, 0); - - #[allow(clippy::needless_range_loop)] - for index in 0..size { - let position = offset + index; - if position >= self.data.len() { - break; - } - - ret[index] = self.data[position]; - } - + self.get_to(offset, &mut ret); ret } /// Get `H256` from a specific offset in memory. pub fn get_h256(&self, offset: usize) -> H256 { let mut ret = [0; 32]; + self.get_to(offset, &mut ret); + H256(ret) + } + fn get_to(&self, offset: usize, buf: &mut [u8]) { #[allow(clippy::needless_range_loop)] - for index in 0..32 { + for index in 0..buf.len() { let position = offset + index; if position >= self.data.len() { break; } - ret[index] = self.data[position]; + buf[index] = self.data[position]; } - - H256(ret) } /// Set memory region at given offset. The offset and value is considered