Browse Source

Remove Runtime pointer from memory helper functions

cl-refactor
Paweł Bylica 10 years ago
parent
commit
5a14c942fa
  1. 8
      evmjit/libevmjit/GasMeter.cpp
  2. 4
      evmjit/libevmjit/GasMeter.h
  3. 37
      evmjit/libevmjit/Memory.cpp
  4. 22
      evmjit/libevmjit/RuntimeManager.cpp
  5. 1
      evmjit/libevmjit/RuntimeManager.h

8
evmjit/libevmjit/GasMeter.cpp

@ -125,7 +125,7 @@ void GasMeter::count(Instruction _inst)
m_blockCost += getStepCost(_inst); m_blockCost += getStepCost(_inst);
} }
void GasMeter::count(llvm::Value* _cost, llvm::Value* _jmpBuf) void GasMeter::count(llvm::Value* _cost, llvm::Value* _jmpBuf, llvm::Value* _gasPtr)
{ {
if (_cost->getType() == Type::Word) if (_cost->getType() == Type::Word)
{ {
@ -136,7 +136,7 @@ void GasMeter::count(llvm::Value* _cost, llvm::Value* _jmpBuf)
} }
assert(_cost->getType() == Type::Gas); assert(_cost->getType() == Type::Gas);
createCall(m_gasCheckFunc, {m_runtimeManager.getGasPtr(), _cost, _jmpBuf ? _jmpBuf : m_runtimeManager.getJmpBuf()}); createCall(m_gasCheckFunc, {_gasPtr ? _gasPtr : m_runtimeManager.getGasPtr(), _cost, _jmpBuf ? _jmpBuf : m_runtimeManager.getJmpBuf()});
} }
void GasMeter::countExp(llvm::Value* _exponent) void GasMeter::countExp(llvm::Value* _exponent)
@ -215,10 +215,10 @@ void GasMeter::commitCostBlock()
assert(m_blockCost == 0); assert(m_blockCost == 0);
} }
void GasMeter::countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf) void GasMeter::countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf, llvm::Value* _gasPtr)
{ {
static_assert(c_memoryGas == 1, "Memory gas cost has changed. Update GasMeter."); static_assert(c_memoryGas == 1, "Memory gas cost has changed. Update GasMeter.");
count(_additionalMemoryInWords, _jmpBuf); count(_additionalMemoryInWords, _jmpBuf, _gasPtr);
} }
void GasMeter::countCopy(llvm::Value* _copyWords) void GasMeter::countCopy(llvm::Value* _copyWords)

4
evmjit/libevmjit/GasMeter.h

@ -20,7 +20,7 @@ public:
void count(Instruction _inst); void count(Instruction _inst);
/// Count additional cost /// Count additional cost
void count(llvm::Value* _cost, llvm::Value* _jmpBuf = nullptr); void count(llvm::Value* _cost, llvm::Value* _jmpBuf = nullptr, llvm::Value* _gasPtr = nullptr);
/// Calculate & count gas cost for SSTORE instruction /// Calculate & count gas cost for SSTORE instruction
void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue); void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue);
@ -41,7 +41,7 @@ public:
void giveBack(llvm::Value* _gas); void giveBack(llvm::Value* _gas);
/// Generate code that checks the cost of additional memory used by program /// Generate code that checks the cost of additional memory used by program
void countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf); void countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf, llvm::Value* _gasPtr);
/// Count addional gas cost for memory copy /// Count addional gas cost for memory copy
void countCopy(llvm::Value* _copyWords); void countCopy(llvm::Value* _copyWords);

37
evmjit/libevmjit/Memory.cpp

@ -28,18 +28,19 @@ llvm::Function* Memory::getRequireFunc()
auto& func = m_require; auto& func = m_require;
if (!func) if (!func)
{ {
llvm::Type* argTypes[] = {Type::RuntimePtr, Type::Word, Type::Word, Type::BytePtr, Array::getType()->getPointerTo()}; llvm::Type* argTypes[] = {Array::getType()->getPointerTo(), Type::Word, Type::Word, Type::BytePtr, Type::GasPtr};
func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "mem.require", getModule()); 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"); auto mem = &func->getArgumentList().front();
auto offset = rt->getNextNode(); mem->setName("mem");
auto offset = mem->getNextNode();
offset->setName("offset"); offset->setName("offset");
auto size = offset->getNextNode(); auto size = offset->getNextNode();
size->setName("size"); size->setName("size");
auto jmpBuf = size->getNextNode(); auto jmpBuf = size->getNextNode();
jmpBuf->setName("jmpBuf"); jmpBuf->setName("jmpBuf");
auto mem = jmpBuf->getNextNode(); auto gas = jmpBuf->getNextNode();
mem->setName("mem"); gas->setName("gas");
auto preBB = llvm::BasicBlock::Create(func->getContext(), "Pre", func); auto preBB = llvm::BasicBlock::Create(func->getContext(), "Pre", func);
auto checkBB = llvm::BasicBlock::Create(func->getContext(), "Check", func); auto checkBB = llvm::BasicBlock::Create(func->getContext(), "Check", func);
@ -76,7 +77,7 @@ llvm::Function* Memory::getRequireFunc()
sizeRequired = m_builder.CreateMul(wordsRequired, Constant::get(32), "roundedSizeReq"); sizeRequired = m_builder.CreateMul(wordsRequired, Constant::get(32), "roundedSizeReq");
auto words = m_builder.CreateUDiv(currSize, m_builder.getInt64(32), "words"); // size is always 32*k auto words = m_builder.CreateUDiv(currSize, m_builder.getInt64(32), "words"); // size is always 32*k
auto newWords = m_builder.CreateSub(wordsRequired, m_builder.CreateZExt(words, Type::Word), "addtionalWords"); auto newWords = m_builder.CreateSub(wordsRequired, m_builder.CreateZExt(words, Type::Word), "addtionalWords");
m_gasMeter.countMemory(newWords, jmpBuf); m_gasMeter.countMemory(newWords, jmpBuf, gas);
// Resize // Resize
auto extendSize = m_builder.CreateTrunc(sizeRequired, Type::Size, "extendSize"); auto extendSize = m_builder.CreateTrunc(sizeRequired, Type::Size, "extendSize");
m_memory.extend(mem, extendSize); m_memory.extend(mem, extendSize);
@ -93,8 +94,8 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType)
{ {
auto isWord = _valueType == Type::Word; auto isWord = _valueType == Type::Word;
llvm::Type* storeArgs[] = {Type::RuntimePtr, Type::Word, _valueType, Array::getType()->getPointerTo()}; llvm::Type* storeArgs[] = {Array::getType()->getPointerTo(), Type::Word, _valueType};
llvm::Type* loadArgs[] = {Type::RuntimePtr, Type::Word, Array::getType()->getPointerTo()}; llvm::Type* loadArgs[] = {Array::getType()->getPointerTo(), Type::Word};
auto name = _isStore ? isWord ? "mstore" : "mstore8" : "mload"; auto name = _isStore ? isWord ? "mstore" : "mstore8" : "mload";
auto funcType = _isStore ? llvm::FunctionType::get(Type::Void, storeArgs, false) : llvm::FunctionType::get(Type::Word, loadArgs, false); auto funcType = _isStore ? llvm::FunctionType::get(Type::Void, storeArgs, false) : llvm::FunctionType::get(Type::Word, loadArgs, false);
auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, getModule()); auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, getModule());
@ -102,17 +103,15 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType)
InsertPointGuard guard(m_builder); // Restores insert point at function exit InsertPointGuard guard(m_builder); // Restores insert point at function exit
m_builder.SetInsertPoint(llvm::BasicBlock::Create(func->getContext(), {}, func)); m_builder.SetInsertPoint(llvm::BasicBlock::Create(func->getContext(), {}, func));
auto rt = func->arg_begin(); auto mem = &func->getArgumentList().front();
rt->setName("rt"); mem->setName("mem");
auto index = rt->getNextNode(); auto index = mem->getNextNode();
index->setName("index"); index->setName("index");
if (_isStore) if (_isStore)
{ {
auto valueArg = index->getNextNode(); auto valueArg = index->getNextNode();
valueArg->setName("value"); valueArg->setName("value");
auto mem = valueArg->getNextNode();
mem->setName("mem");
auto value = isWord ? Endianness::toBE(m_builder, valueArg) : valueArg; auto value = isWord ? Endianness::toBE(m_builder, valueArg) : valueArg;
auto memPtr = m_memory.getPtr(mem, m_builder.CreateTrunc(index, Type::Size)); auto memPtr = m_memory.getPtr(mem, m_builder.CreateTrunc(index, Type::Size));
auto valuePtr = m_builder.CreateBitCast(memPtr, _valueType->getPointerTo(), "valuePtr"); auto valuePtr = m_builder.CreateBitCast(memPtr, _valueType->getPointerTo(), "valuePtr");
@ -121,8 +120,6 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType)
} }
else else
{ {
auto mem = index->getNextNode();
mem->setName("mem");
auto memPtr = m_memory.getPtr(mem, m_builder.CreateTrunc(index, Type::Size)); auto memPtr = m_memory.getPtr(mem, m_builder.CreateTrunc(index, Type::Size));
llvm::Value* ret = m_builder.CreateLoad(memPtr); llvm::Value* ret = m_builder.CreateLoad(memPtr);
ret = Endianness::toNative(m_builder, ret); ret = Endianness::toNative(m_builder, ret);
@ -160,20 +157,20 @@ llvm::Function* Memory::getStoreByteFunc()
llvm::Value* Memory::loadWord(llvm::Value* _addr) llvm::Value* Memory::loadWord(llvm::Value* _addr)
{ {
require(_addr, Constant::get(Type::Word->getPrimitiveSizeInBits() / 8)); require(_addr, Constant::get(Type::Word->getPrimitiveSizeInBits() / 8));
return createCall(getLoadWordFunc(), {getRuntimeManager().getRuntimePtr(), _addr, getRuntimeManager().getMem()}); return createCall(getLoadWordFunc(), {getRuntimeManager().getMem(), _addr});
} }
void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word) void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word)
{ {
require(_addr, Constant::get(Type::Word->getPrimitiveSizeInBits() / 8)); require(_addr, Constant::get(Type::Word->getPrimitiveSizeInBits() / 8));
createCall(getStoreWordFunc(), {getRuntimeManager().getRuntimePtr(), _addr, _word, getRuntimeManager().getMem()}); createCall(getStoreWordFunc(), {getRuntimeManager().getMem(), _addr, _word});
} }
void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word) void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word)
{ {
require(_addr, Constant::get(Type::Byte->getPrimitiveSizeInBits() / 8)); require(_addr, Constant::get(Type::Byte->getPrimitiveSizeInBits() / 8));
auto byte = m_builder.CreateTrunc(_word, Type::Byte, "byte"); auto byte = m_builder.CreateTrunc(_word, Type::Byte, "byte");
createCall(getStoreByteFunc(), {getRuntimeManager().getRuntimePtr(), _addr, byte, getRuntimeManager().getMem()}); createCall(getStoreByteFunc(), {getRuntimeManager().getMem(), _addr, byte});
} }
llvm::Value* Memory::getData() llvm::Value* Memory::getData()
@ -202,7 +199,7 @@ void Memory::require(llvm::Value* _offset, llvm::Value* _size)
if (!constant->getValue()) if (!constant->getValue())
return; return;
} }
createCall(getRequireFunc(), {getRuntimeManager().getRuntimePtr(), _offset, _size, getRuntimeManager().getJmpBuf(), getRuntimeManager().getMem()}); createCall(getRequireFunc(), {getRuntimeManager().getMem(), _offset, _size, getRuntimeManager().getJmpBuf(), getRuntimeManager().getGasPtr()});
} }
void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx, void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx,

22
evmjit/libevmjit/RuntimeManager.cpp

@ -5,6 +5,7 @@
#include "preprocessor/llvm_includes_end.h" #include "preprocessor/llvm_includes_end.h"
#include "Stack.h" #include "Stack.h"
#include "Utils.h"
namespace dev namespace dev
{ {
@ -99,6 +100,8 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, llvm::Value* _jmpBuf
assert(m_dataPtr->getType() == Type::RuntimeDataPtr); assert(m_dataPtr->getType() == Type::RuntimeDataPtr);
m_gasPtr = m_builder.CreateStructGEP(m_dataPtr, 0, "gas"); m_gasPtr = m_builder.CreateStructGEP(m_dataPtr, 0, "gas");
assert(m_gasPtr->getType() == Type::Gas->getPointerTo()); assert(m_gasPtr->getType() == Type::Gas->getPointerTo());
m_memPtr = m_builder.CreateStructGEP(rtPtr, 4, "mem");
assert(m_memPtr->getType() == Array::getType()->getPointerTo());
m_envPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(rtPtr, 1), "env"); m_envPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(rtPtr, 1), "env");
assert(m_envPtr->getType() == Type::EnvPtr); assert(m_envPtr->getType() == Type::EnvPtr);
} }
@ -123,14 +126,6 @@ llvm::Value* RuntimeManager::getDataPtr()
return dataPtr; return dataPtr;
} }
llvm::Value* RuntimeManager::getMem()
{
auto rtPtr = getRuntimePtr();
auto memPtr = m_builder.CreateStructGEP(rtPtr, 4, "mem");
assert(memPtr->getType() == Array::getType()->getPointerTo());
return memPtr;
}
llvm::Value* RuntimeManager::getEnvPtr() llvm::Value* RuntimeManager::getEnvPtr()
{ {
assert(getMainFunction()); // Available only in main function assert(getMainFunction()); // Available only in main function
@ -238,11 +233,14 @@ llvm::Value* RuntimeManager::getGas()
llvm::Value* RuntimeManager::getGasPtr() llvm::Value* RuntimeManager::getGasPtr()
{ {
if (getMainFunction()) assert(getMainFunction());
return m_gasPtr; return m_gasPtr;
}
// TODO: eliminated this case llvm::Value* RuntimeManager::getMem()
return getPtr(RuntimeData::Gas); {
assert(getMainFunction());
return m_memPtr;
} }
void RuntimeManager::setGas(llvm::Value* _gas) void RuntimeManager::setGas(llvm::Value* _gas)

1
evmjit/libevmjit/RuntimeManager.h

@ -55,6 +55,7 @@ private:
llvm::Value* const m_jmpBuf; llvm::Value* const m_jmpBuf;
llvm::Value* m_dataPtr = nullptr; llvm::Value* m_dataPtr = nullptr;
llvm::Value* m_gasPtr = nullptr; llvm::Value* m_gasPtr = nullptr;
llvm::Value* m_memPtr = nullptr;
llvm::Value* m_envPtr = nullptr; llvm::Value* m_envPtr = nullptr;
code_iterator m_codeBegin = {}; code_iterator m_codeBegin = {};

Loading…
Cancel
Save