diff options
author | Martin Holst Swende <martin@swende.se> | 2018-06-14 17:23:37 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2018-06-14 17:23:37 +0800 |
commit | 947e0afeb3bce9c52548979daddd1e00aa0d7ba8 (patch) | |
tree | ab3e44f8cf74d60e541df07c5ef81ad0ca9797d2 /core/vm/memory.go | |
parent | 1836366ac19e30f157570e61342fae53bc6c8a57 (diff) | |
download | go-tangerine-947e0afeb3bce9c52548979daddd1e00aa0d7ba8.tar go-tangerine-947e0afeb3bce9c52548979daddd1e00aa0d7ba8.tar.gz go-tangerine-947e0afeb3bce9c52548979daddd1e00aa0d7ba8.tar.bz2 go-tangerine-947e0afeb3bce9c52548979daddd1e00aa0d7ba8.tar.lz go-tangerine-947e0afeb3bce9c52548979daddd1e00aa0d7ba8.tar.xz go-tangerine-947e0afeb3bce9c52548979daddd1e00aa0d7ba8.tar.zst go-tangerine-947e0afeb3bce9c52548979daddd1e00aa0d7ba8.zip |
core/vm: optimize MSTORE and SLOAD (#16939)
* vm/test: add tests+benchmarks for mstore
* core/vm: less alloc and copying for mstore
* core/vm: less allocs in sload
* vm: check for errors more correctly
Diffstat (limited to 'core/vm/memory.go')
-rw-r--r-- | core/vm/memory.go | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/core/vm/memory.go b/core/vm/memory.go index d5cc7870b..43f6ff5bf 100644 --- a/core/vm/memory.go +++ b/core/vm/memory.go @@ -16,7 +16,12 @@ package vm -import "fmt" +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common/math" +) // Memory implements a simple memory model for the ethereum virtual machine. type Memory struct { @@ -30,19 +35,32 @@ func NewMemory() *Memory { // Set sets offset + size to value func (m *Memory) Set(offset, size uint64, value []byte) { - // length of store may never be less than offset + size. - // The store should be resized PRIOR to setting the memory - if size > uint64(len(m.store)) { - panic("INVALID memory: store empty") - } - // It's possible the offset is greater than 0 and size equals 0. This is because // the calcMemSize (common.go) could potentially return 0 when size is zero (NO-OP) if size > 0 { + // length of store may never be less than offset + size. + // The store should be resized PRIOR to setting the memory + if offset+size > uint64(len(m.store)) { + panic("invalid memory: store empty") + } copy(m.store[offset:offset+size], value) } } +// Set32 sets the 32 bytes starting at offset to the value of val, left-padded with zeroes to +// 32 bytes. +func (m *Memory) Set32(offset uint64, val *big.Int) { + // length of store may never be less than offset + size. + // The store should be resized PRIOR to setting the memory + if offset+32 > uint64(len(m.store)) { + panic("invalid memory: store empty") + } + // Zero the memory area + copy(m.store[offset:offset+32], []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) + // Fill in relevant bits + math.ReadBits(val, m.store[offset:offset+32]) +} + // Resize resizes the memory to size func (m *Memory) Resize(size uint64) { if uint64(m.Len()) < size { |