From 4f26fab1e98a8a3e5dcb472dd3fc73a549149ffe Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sun, 10 Jun 2018 22:33:50 +0200 Subject: [PATCH] core/vm: less alloc and copying for mstore --- core/vm/instructions.go | 2 +- core/vm/memory.go | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 3a67e1865f..69a04ffc8f 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -556,7 +556,7 @@ func opMload(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *St func opMstore(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { // pop value of the stack mStart, val := stack.pop(), stack.pop() - memory.Set(mStart.Uint64(), 32, math.PaddedBigBytes(val, 32)) + memory.Set32(mStart.Uint64(), val) evm.interpreter.intPool.put(mStart, val) return nil, nil diff --git a/core/vm/memory.go b/core/vm/memory.go index d5cc7870bc..a3530419d9 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 { @@ -43,6 +48,20 @@ func (m *Memory) Set(offset, size uint64, value []byte) { } } +// 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 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 {