Skip to content

Commit

Permalink
Optimize calldataload. Some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
rakita committed Aug 11, 2022
1 parent b19acaa commit eef29f6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 77 deletions.
27 changes: 14 additions & 13 deletions crates/revm/src/instructions/system.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::cmp::min;

use crate::{gas, interpreter::Interpreter, Return, Spec, SpecId::*, KECCAK_EMPTY};
use primitive_types::{H256, U256};

Expand Down Expand Up @@ -64,19 +66,18 @@ pub fn codecopy(interp: &mut Interpreter) -> Return {
pub fn calldataload(interp: &mut Interpreter) -> Return {
// gas!(interp, gas::VERYLOW);
pop!(interp, index);
let mut load = [0u8; 32];
#[allow(clippy::needless_range_loop)]
for i in 0..32 {
if let Some(p) = index.checked_add(U256::from(i)) {
if p <= U256::from(usize::MAX) {
let p = p.as_usize();
if p < interp.contract.input.len() {
load[i] = interp.contract.input[p];
}
}
}
}
push_h256!(interp, H256::from(load));
let index = as_usize_saturated!(index);

let load = if index < interp.contract.input.len() {
let mut load = H256::zero();
let have_bytes = min(interp.contract.input.len() - index, 32);
load.0[..have_bytes].copy_from_slice(&interp.contract.input[index..index + have_bytes]);
load
} else {
H256::zero()
};

push_h256!(interp, load);
Return::Continue
}

Expand Down
43 changes: 21 additions & 22 deletions crates/revm/src/interpreter/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl Bytecode {
/// Create new checked bytecode
///
/// # Safety
/// Bytecode need to end with STOP (0x00) opcode as checked bytecode assumes that
/// Bytecode need to end with STOP (0x00) opcode as checked bytecode assumes
/// that it is safe to iterate over bytecode without checking lengths
pub unsafe fn new_checked(bytecode: Bytes, len: usize, hash: Option<H256>) -> Self {
let hash = match hash {
Expand All @@ -93,7 +93,8 @@ impl Bytecode {
///
/// # Safety
/// Same as new_checked, bytecode needs to end with STOP (0x00) opcode as checked bytecode assumes
/// that it is safe to iterate over bytecode without checking length
/// that it is safe to iterate over bytecode without checking length.
/// And that ValidJumpAddress is valid.
pub unsafe fn new_analysed(
bytecode: Bytes,
len: usize,
Expand All @@ -120,6 +121,10 @@ impl Bytecode {
self.hash
}

pub fn state(&self) -> &BytecodeState {
&self.state
}

pub fn is_empty(&self) -> bool {
match self.state {
BytecodeState::Raw => self.bytecode.is_empty(),
Expand Down Expand Up @@ -206,8 +211,8 @@ impl Bytecode {

// first gas block
while index < code.len() {
let opcode = unsafe { *code.get_unchecked(index) };
let info = unsafe { opcode_gas.get_unchecked(opcode as usize) };
let opcode = *code.get(index).unwrap();
let info = opcode_gas.get(opcode as usize).unwrap();
analysis.first_gas_block += info.get_gas();

index += if info.is_push() {
Expand All @@ -219,30 +224,25 @@ impl Bytecode {
if info.is_gas_block_end() {
block_start = index - 1;
if info.is_jump() {
unsafe {
jumps.get_unchecked_mut(block_start).set_is_jump();
}
jumps.get_mut(block_start).unwrap().set_is_jump();
}
break;
}
}

while index < code.len() {
let opcode = unsafe { *code.get_unchecked(index) };
let info = unsafe { opcode_gas.get_unchecked(opcode as usize) };
let opcode = *code.get(index).unwrap();
let info = opcode_gas.get(opcode as usize).unwrap();
gas_in_block += info.get_gas();

if info.is_gas_block_end() {
if info.is_jump() {
unsafe {
jumps.get_unchecked_mut(index).set_is_jump();
}
}
unsafe {
jumps
.get_unchecked_mut(block_start)
.set_gas_block(gas_in_block);
jumps.get_mut(index).unwrap().set_is_jump();
}
jumps
.get_mut(block_start)
.unwrap()
.set_gas_block(gas_in_block);
block_start = index;
gas_in_block = 0;
index += 1;
Expand All @@ -255,11 +255,10 @@ impl Bytecode {
}
}
if gas_in_block != 0 {
unsafe {
jumps
.get_unchecked_mut(block_start)
.set_gas_block(gas_in_block);
}
jumps
.get_mut(block_start)
.unwrap()
.set_gas_block(gas_in_block);
}
analysis
}
Expand Down
32 changes: 1 addition & 31 deletions crates/revm/src/interpreter/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ impl AnalysisData {
pub fn none() -> Self {
AnalysisData {
is_jump_and_gas_block: 0,
//gas_block: 0,
}
}

Expand Down Expand Up @@ -176,33 +175,4 @@ mod tests {
assert!(jump.is_jump());
assert_eq!(jump.gas_block(), 350);
}
}

/*
#[cfg(test)]
mod tests {
use std::time::Instant;
use super::*;
use crate::LondonSpec;
#[test]
pub fn analyze() {
let bytes = hex::decode("3dcd25e7dac7413679ca4b860b371699db4a3c06cc8086e35490de6810b5510e792551b0049bc91b54aec6a82b00a85f998982b99dac982fb6f7acf67032fe9f23491f6c29a96be377f44ece4b89ab835bb2d36e387533e9b36e1c47b85c09175488dec63aca38f96d78cf8e468b54486b83c1d8db5931b5579a56bd1aa05d6526251556bfabac7c244c41e6a78f581aded59e297f6af196279d246b99a8670b5edddb646ed751417b70f1066f19dfea1c06e91e0beeb3a2511603d32092a0189f820ea97eb234a42ed8b513144971c4166e48b209d74b1d85e79f93094e901376e964bc2a8141f189f13edc69c97467a09b43c19140df1399a4740c6dfcced5b3d3d08abd97b3c71cfd1c2b95dd4b8ce7951bf9e17bdf35e0fd706e89551a1e7b79cfeedf3037eb1e99537da2c65f3acd7c3c1f47343f536566cd4976002870267f87d1b5066e158fb794185a0ec8a786bca89412bab10a167ba4e2087e37b7c7d4ab98f6c86abc59135bbb07d5c19f028724031be46e69fc1215fe5a8743f8ffb57294989cc3fa6dd9d38a2317ba6de811b9d135ea03b4ab5a2fd034454d2a0a59ec85deb5b05bcf3b6408e0a1d2d6a8b259510b49e2ea7479b9770f42fef2805a4a7cfea63714e0fd00929e293648ee5a57df894ab7cb46e331d120ba83c9e51ccab2c1ec8afe2809e0c3184c607e57045f95062abd78b1974192f542b12300000000000000").unwrap();
let mut t = Vec::new();
for _ in 0..40 {
let time = Instant::now();
for _ in 0..30_000 {
let t = Contract::analyze::<LondonSpec>(&bytes);
}
t.push(time.elapsed());
}
t.sort();
for i in t {
println!("Elapsed: {:?}", i);
}
}
}
*/
}
17 changes: 6 additions & 11 deletions crates/revm/src/interpreter/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl Memory {
/// The caller is responsible for checking the offset and value
#[inline(always)]
pub unsafe fn set_byte(&mut self, index: usize, byte: u8) {
*self.data.get_unchecked_mut(index) = byte;
*self.data.get_mut(index).unwrap() = byte;
}

#[inline(always)]
Expand All @@ -85,11 +85,8 @@ impl Memory {
pub fn set_data(&mut self, memory_offset: usize, data_offset: usize, len: usize, data: &[u8]) {
if data_offset >= data.len() {
// nulify all memory slots
for i in memory_offset..memory_offset + len {
// Safety: Memory is assumed to be valid. And it is commented where that assumption is made
unsafe {
*self.data.get_unchecked_mut(i) = 0;
}
for i in &mut self.data[memory_offset..memory_offset + len] {
*i = 0;
}
return;
}
Expand All @@ -98,11 +95,9 @@ impl Memory {
self.data[memory_offset..memory_data_end].copy_from_slice(&data[data_offset..data_end]);

// nulify rest of memory slots
for i in memory_data_end..memory_offset + len {
// Safety: Memory is assumed to be valid. And it is commented where that assumption is made
unsafe {
*self.data.get_unchecked_mut(i) = 0;
}
// Safety: Memory is assumed to be valid. And it is commented where that assumption is made
for i in &mut self.data[memory_data_end..memory_offset + len] {
*i = 0;
}
}
}
Expand Down

0 comments on commit eef29f6

Please sign in to comment.