diff --git a/libevmjit/GasMeter.cpp b/libevmjit/GasMeter.cpp index 92435ba91..34dff5a69 100644 --- a/libevmjit/GasMeter.cpp +++ b/libevmjit/GasMeter.cpp @@ -125,7 +125,7 @@ void GasMeter::count(Instruction _inst) m_blockCost += getStepCost(_inst); } -void GasMeter::count(llvm::Value* _cost) +void GasMeter::count(llvm::Value* _cost, llvm::Value* _jmpBuf) { if (_cost->getType() == Type::Word) { @@ -136,7 +136,7 @@ void GasMeter::count(llvm::Value* _cost) } assert(_cost->getType() == Type::Gas); - createCall(m_gasCheckFunc, {m_runtimeManager.getGasPtr(), _cost, m_runtimeManager.getJmpBufExt()}); + createCall(m_gasCheckFunc, {m_runtimeManager.getGasPtr(), _cost, _jmpBuf ? _jmpBuf : m_runtimeManager.getJmpBuf()}); } void GasMeter::countExp(llvm::Value* _exponent) @@ -215,10 +215,10 @@ void GasMeter::commitCostBlock() assert(m_blockCost == 0); } -void GasMeter::countMemory(llvm::Value* _additionalMemoryInWords) +void GasMeter::countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf) { static_assert(c_memoryGas == 1, "Memory gas cost has changed. Update GasMeter."); - count(_additionalMemoryInWords); + count(_additionalMemoryInWords, _jmpBuf); } void GasMeter::countCopy(llvm::Value* _copyWords) diff --git a/libevmjit/GasMeter.h b/libevmjit/GasMeter.h index 4056cd64d..550b5474c 100644 --- a/libevmjit/GasMeter.h +++ b/libevmjit/GasMeter.h @@ -20,7 +20,7 @@ public: void count(Instruction _inst); /// Count additional cost - void count(llvm::Value* _cost); + void count(llvm::Value* _cost, llvm::Value* _jmpBuf = nullptr); /// Calculate & count gas cost for SSTORE instruction void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue); @@ -41,7 +41,7 @@ public: void giveBack(llvm::Value* _gas); /// Generate code that checks the cost of additional memory used by program - void countMemory(llvm::Value* _additionalMemoryInWords); + void countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf); /// Count addional gas cost for memory copy void countCopy(llvm::Value* _copyWords); diff --git a/libevmjit/Memory.cpp b/libevmjit/Memory.cpp index 647c5f26a..53a40ffc5 100644 --- a/libevmjit/Memory.cpp +++ b/libevmjit/Memory.cpp @@ -27,7 +27,7 @@ llvm::Function* Memory::getRequireFunc() auto& func = m_require; if (!func) { - llvm::Type* argTypes[] = {Type::RuntimePtr, Type::Word, Type::Word}; + llvm::Type* argTypes[] = {Type::RuntimePtr, Type::Word, Type::Word, Type::BytePtr}; func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "mem.require", getModule()); auto rt = func->arg_begin(); rt->setName("rt"); @@ -35,6 +35,8 @@ llvm::Function* Memory::getRequireFunc() offset->setName("offset"); auto size = offset->getNextNode(); size->setName("size"); + auto jmpBuf = size->getNextNode(); + jmpBuf->setName("jmpBuf"); llvm::Type* resizeArgs[] = {Type::RuntimePtr, Type::WordPtr}; auto resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, resizeArgs, false), llvm::Function::ExternalLinkage, "mem_resize", getModule()); @@ -79,7 +81,7 @@ llvm::Function* Memory::getRequireFunc() sizeRequired = m_builder.CreateMul(wordsRequired, Constant::get(32), "roundedSizeReq"); auto words = m_builder.CreateUDiv(currSize, Constant::get(32), "words"); // size is always 32*k auto newWords = m_builder.CreateSub(wordsRequired, words, "addtionalWords"); - m_gasMeter.countMemory(newWords); + m_gasMeter.countMemory(newWords, jmpBuf); // Resize m_builder.CreateStore(sizeRequired, sizePtr); auto newData = m_builder.CreateCall2(resize, rt, sizePtr, "newData"); @@ -112,8 +114,6 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMet auto index = rt->getNextNode(); index->setName("index"); - auto valueSize = _valueType->getPrimitiveSizeInBits() / 8; - this->require(index, Constant::get(valueSize)); auto ptr = getBytePtr(index); if (isWord) ptr = m_builder.CreateBitCast(ptr, Type::WordPtr, "wordPtr"); @@ -163,16 +163,19 @@ llvm::Function* Memory::getStoreByteFunc() llvm::Value* Memory::loadWord(llvm::Value* _addr) { + require(_addr, Constant::get(Type::Word->getPrimitiveSizeInBits() / 8)); return createCall(getLoadWordFunc(), {getRuntimeManager().getRuntimePtr(), _addr}); } void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word) { + require(_addr, Constant::get(Type::Word->getPrimitiveSizeInBits() / 8)); createCall(getStoreWordFunc(), {getRuntimeManager().getRuntimePtr(), _addr, _word}); } void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word) { + require(_addr, Constant::get(Type::Byte->getPrimitiveSizeInBits() / 8)); auto byte = m_builder.CreateTrunc(_word, Type::Byte, "byte"); createCall(getStoreByteFunc(), {getRuntimeManager().getRuntimePtr(), _addr, byte}); } @@ -204,7 +207,7 @@ void Memory::require(llvm::Value* _offset, llvm::Value* _size) if (!constant->getValue()) return; } - createCall(getRequireFunc(), {getRuntimeManager().getRuntimePtr(), _offset, _size}); + createCall(getRequireFunc(), {getRuntimeManager().getRuntimePtr(), _offset, _size, getRuntimeManager().getJmpBuf()}); } void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx,