Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.

Commit 6942f39

Browse files
committed
Optimized memory usage
1 parent 2819508 commit 6942f39

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

ethcore/src/evm/interpreter/memory.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
use util::U256;
1818
use evm::ReturnData;
19-
use std::cmp::min;
19+
20+
const MAX_RETURN_WASTE_BYTES: usize = 16384;
2021

2122
pub trait Memory {
2223
/// Retrieve current size of the memory
@@ -39,7 +40,7 @@ pub trait Memory {
3940
fn writeable_slice(&mut self, offset: U256, size: U256) -> &mut[u8];
4041
fn dump(&self);
4142
/// Convert memory into return data.
42-
fn into_return_data(self, offset: usize, size: usize) -> ReturnData;
43+
fn into_return_data(self, offset: U256, size: U256) -> ReturnData;
4344
}
4445

4546
/// Checks whether offset and size is valid memory range
@@ -114,10 +115,18 @@ impl Memory for Vec<u8> {
114115
}
115116
}
116117

117-
fn into_return_data(self, offset: usize, size: usize) -> ReturnData {
118-
let offset = min(offset, self.len());
119-
let size = min(size, self.len() - offset);
120-
ReturnData::new(self, offset, size)
118+
fn into_return_data(mut self, offset: U256, size: U256) -> ReturnData {
119+
let offset = offset.low_u64() as usize;
120+
let size = size.low_u64() as usize;
121+
if !is_valid_range(offset, size) {
122+
return ReturnData::empty()
123+
}
124+
if self.len() - size > MAX_RETURN_WASTE_BYTES {
125+
let mem = self.drain(offset..).take(size).collect();
126+
ReturnData::new(mem, 0, size)
127+
} else {
128+
ReturnData::new(self, offset, size)
129+
}
121130
}
122131
}
123132

ethcore/src/evm/interpreter/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ impl<Cost: CostType> evm::Evm for Interpreter<Cost> {
170170
let mem = mem::replace(&mut self.mem, Vec::new());
171171
return Ok(GasLeft::NeedsReturn {
172172
gas_left: gas.as_u256(),
173-
data: mem.into_return_data(usize::from_u256(init_off)?, usize::from_u256(init_size)?),
173+
data: mem.into_return_data(init_off, init_size),
174174
apply_state: apply
175175
});
176176
},
@@ -499,6 +499,9 @@ impl<Cost: CostType> Interpreter<Cost> {
499499
instructions::CODESIZE => {
500500
stack.push(U256::from(code.len()));
501501
},
502+
instructions::RETURNDATASIZE => {
503+
stack.push(U256::from(self.return_data.len()))
504+
},
502505
instructions::EXTCODESIZE => {
503506
let address = u256_to_address(&stack.pop_back());
504507
let len = ext.extcodesize(&address)?;

0 commit comments

Comments
 (0)