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);
}
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)
{
@ -136,7 +136,7 @@ void GasMeter::count(llvm::Value* _cost, llvm::Value* _jmpBuf)
}
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)
@ -215,10 +215,10 @@ void GasMeter::commitCostBlock()
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.");
count(_additionalMemoryInWords, _jmpBuf);
count(_additionalMemoryInWords, _jmpBuf, _gasPtr);
}
void GasMeter::countCopy(llvm::Value* _copyWords)

4
evmjit/libevmjit/GasMeter.h

@ -20,7 +20,7 @@ public:
void count(Instruction _inst);
/// 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
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, llvm::Value* _jmpBuf);
void countMemory(llvm::Value* _additionalMemoryInWords, llvm::Value* _jmpBuf, llvm::Value* _gasPtr);
/// Count addional gas cost for memory copy
void countCopy(llvm::Value* _copyWords);

37
evmjit/libevmjit/Memory.cpp

@ -28,18 +28,19 @@ llvm::Function* Memory::getRequireFunc()
auto& func = m_require;
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());
auto rt = func->arg_begin();
rt->setName("rt");
auto offset = rt->getNextNode();
auto mem = &func->getArgumentList().front();
mem->setName("mem");
auto offset = mem->getNextNode();
offset->setName("offset");
auto size = offset->getNextNode();
size->setName("size");
auto jmpBuf = size->getNextNode();
jmpBuf->setName("jmpBuf");
auto mem = jmpBuf->getNextNode();
mem->setName("mem");
auto gas = jmpBuf->getNextNode();
gas->setName("gas");
auto preBB = llvm::BasicBlock::Create(func->getContext(), "Pre", 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");
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");
m_gasMeter.countMemory(newWords, jmpBuf);
m_gasMeter.countMemory(newWords, jmpBuf, gas);
// Resize
auto extendSize = m_builder.CreateTrunc(sizeRequired, Type::Size, "extendSize");
m_memory.extend(mem, extendSize);
@ -93,8 +94,8 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType)
{
auto isWord = _valueType == Type::Word;
llvm::Type* storeArgs[] = {Type::RuntimePtr, Type::Word, _valueType, Array::getType()->getPointerTo()};
llvm::Type* loadArgs[] = {Type::RuntimePtr, Type::Word, Array::getType()->getPointerTo()};
llvm::Type* storeArgs[] = {Array::getType()->getPointerTo(), Type::Word, _valueType};
llvm::Type* loadArgs[] = {Array::getType()->getPointerTo(), Type::Word};
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 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
m_builder.SetInsertPoint(llvm::BasicBlock::Create(func->getContext(), {}, func));
auto rt = func->arg_begin();
rt->setName("rt");
auto index = rt->getNextNode();
auto mem = &func->getArgumentList().front();
mem->setName("mem");
auto index = mem->getNextNode();
index->setName("index");
if (_isStore)
{
auto valueArg = index->getNextNode();
valueArg->setName("value");
auto mem = valueArg->getNextNode();
mem->setName("mem");
auto value = isWord ? Endianness::toBE(m_builder, valueArg) : valueArg;
auto memPtr = m_memory.getPtr(mem, m_builder.CreateTrunc(index, Type::Size));
auto valuePtr = m_builder.CreateBitCast(memPtr, _valueType->getPointerTo(), "valuePtr");
@ -121,8 +120,6 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType)
}
else
{
auto mem = index->getNextNode();
mem->setName("mem");
auto memPtr = m_memory.getPtr(mem, m_builder.CreateTrunc(index, Type::Size));
llvm::Value* ret = m_builder.CreateLoad(memPtr);
ret = Endianness::toNative(m_builder, ret);
@ -160,20 +157,20 @@ 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, getRuntimeManager().getMem()});
return createCall(getLoadWordFunc(), {getRuntimeManager().getMem(), _addr});
}
void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word)
{
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)
{
require(_addr, Constant::get(Type::Byte->getPrimitiveSizeInBits() / 8));
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()
@ -202,7 +199,7 @@ void Memory::require(llvm::Value* _offset, llvm::Value* _size)
if (!constant->getValue())
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,

22
evmjit/libevmjit/RuntimeManager.cpp

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

1
evmjit/libevmjit/RuntimeManager.h

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

Loading…
Cancel
Save