diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index 339f73959..ddfe2497e 100644 --- a/libevmjit/Compiler.cpp +++ b/libevmjit/Compiler.cpp @@ -178,7 +178,7 @@ std::unique_ptr Compiler::compile(bytesConstRef bytecode) // Init runtime structures. RuntimeManager runtimeManager(m_builder); - GasMeter gasMeter(m_builder); + GasMeter gasMeter(m_builder, runtimeManager); Memory memory(m_builder, gasMeter); Ext ext(m_builder); Stack stack(m_builder); @@ -191,7 +191,7 @@ std::unique_ptr Compiler::compile(bytesConstRef bytecode) auto iterCopy = basicBlockPairIt; ++iterCopy; auto nextBasicBlock = (iterCopy != basicBlocks.end()) ? iterCopy->second.llvm() : nullptr; - compileBasicBlock(basicBlock, bytecode, memory, ext, gasMeter, nextBasicBlock); + compileBasicBlock(basicBlock, bytecode, runtimeManager, memory, ext, gasMeter, nextBasicBlock); } // Code for special blocks: @@ -272,7 +272,7 @@ std::unique_ptr Compiler::compile(bytesConstRef bytecode) } -void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, Memory& memory, Ext& ext, GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock) +void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, RuntimeManager& _runtimeManager, Memory& memory, Ext& ext, GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock) { m_builder.SetInsertPoint(basicBlock.llvm()); auto& stack = basicBlock.localStack(); @@ -680,7 +680,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, case Instruction::GAS: { - stack.push(gasMeter.getGas()); + stack.push(_runtimeManager.getGas()); break; } diff --git a/libevmjit/Compiler.h b/libevmjit/Compiler.h index afd5aef72..d543b9b1d 100644 --- a/libevmjit/Compiler.h +++ b/libevmjit/Compiler.h @@ -31,7 +31,7 @@ private: void createBasicBlocks(bytesConstRef bytecode); - void compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, class Memory& memory, class Ext& ext, class GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock); + void compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, class RuntimeManager& _runtimeManager, class Memory& memory, class Ext& ext, class GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock); void removeDeadBlocks(); diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index e537d0517..5d5af553e 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -115,7 +115,7 @@ int ExecutionEngine::run(std::unique_ptr _module, u256& _gas, ExtV returnCode = static_cast(r); // Return remaining gas - _gas = returnCode == ReturnCode::OutOfGas ? 0 : Runtime::getGas(); + _gas = returnCode == ReturnCode::OutOfGas ? 0 : runtime.getGas(); std::cout << "Max stack size: " << Stack::maxStackSize << std::endl; diff --git a/libevmjit/GasMeter.cpp b/libevmjit/GasMeter.cpp index 6eb8eb6eb..317b204fc 100644 --- a/libevmjit/GasMeter.cpp +++ b/libevmjit/GasMeter.cpp @@ -10,6 +10,7 @@ #include "Type.h" #include "Ext.h" +#include "Runtime.h" namespace dev { @@ -79,12 +80,11 @@ bool isCostBlockEnd(Instruction _inst) } -GasMeter::GasMeter(llvm::IRBuilder<>& _builder) : - CompilerHelper(_builder) +GasMeter::GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager) : + CompilerHelper(_builder), + m_runtimeManager(_runtimeManager) { auto module = getModule(); - m_gas = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas"); - m_gas->setUnnamedAddr(true); // Address is not important m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", module); InsertPointGuard guard(m_builder); @@ -96,7 +96,7 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder) : m_builder.SetInsertPoint(checkBB); llvm::Value* cost = m_gasCheckFunc->arg_begin(); cost->setName("cost"); - llvm::Value* gas = m_builder.CreateLoad(m_gas, "gas"); + auto gas = m_runtimeManager.getGas(); auto isOutOfGas = m_builder.CreateICmpUGT(cost, gas, "isOutOfGas"); m_builder.CreateCondBr(isOutOfGas, outOfGasBB, updateBB); @@ -111,7 +111,7 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder) : m_builder.SetInsertPoint(updateBB); gas = m_builder.CreateSub(gas, cost); - m_builder.CreateStore(gas, m_gas); + m_runtimeManager.setGas(gas); m_builder.CreateRetVoid(); } @@ -153,9 +153,7 @@ void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValu void GasMeter::giveBack(llvm::Value* _gas) { - llvm::Value* gasCounter = m_builder.CreateLoad(m_gas, "gas"); - gasCounter = m_builder.CreateAdd(gasCounter, _gas); - m_builder.CreateStore(gasCounter, m_gas); + m_runtimeManager.setGas(m_builder.CreateAdd(m_runtimeManager.getGas(), _gas)); } void GasMeter::commitCostBlock(llvm::Value* _additionalCost) @@ -191,11 +189,6 @@ void GasMeter::checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilde _builder.CreateCall(m_gasCheckFunc, cost); } -llvm::Value* GasMeter::getGas() -{ - return m_builder.CreateLoad(m_gas, "gas"); -} - } } } diff --git a/libevmjit/GasMeter.h b/libevmjit/GasMeter.h index 521e7080a..82007fc00 100644 --- a/libevmjit/GasMeter.h +++ b/libevmjit/GasMeter.h @@ -11,11 +11,12 @@ namespace eth { namespace jit { +class RuntimeManager; class GasMeter : public CompilerHelper { public: - GasMeter(llvm::IRBuilder<>& _builder); + GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager); /// Count step cost of instruction void count(Instruction _inst); @@ -33,16 +34,15 @@ public: /// Generate code that checks the cost of additional memory used by program void checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder); - llvm::Value* getGas(); - private: /// Cumulative gas cost of a block of instructions /// @TODO Handle overflow uint64_t m_blockCost = 0; llvm::CallInst* m_checkCall = nullptr; - llvm::GlobalVariable* m_gas; llvm::Function* m_gasCheckFunc; + + RuntimeManager& m_runtimeManager; }; } diff --git a/libevmjit/Runtime.cpp b/libevmjit/Runtime.cpp index 4d800535c..e37729e5b 100644 --- a/libevmjit/Runtime.cpp +++ b/libevmjit/Runtime.cpp @@ -31,17 +31,12 @@ llvm::StructType* RuntimeData::getType() static Runtime* g_runtime; -extern "C" -{ -EXPORT i256 gas; -} - Runtime::Runtime(u256 _gas, ExtVMFace& _ext): m_ext(_ext) { assert(!g_runtime); g_runtime = this; - gas = eth2llvm(_gas); + m_data.gas = eth2llvm(_gas); } Runtime::~Runtime() @@ -66,7 +61,7 @@ ExtVMFace& Runtime::getExt() u256 Runtime::getGas() { - return llvm2eth(gas); + return llvm2eth(m_data.gas); } @@ -81,6 +76,22 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_bui m_builder.CreateStore(dataPtr, m_dataPtr); } +llvm::Value* RuntimeManager::getGas() +{ + //auto gasPtr = m_builder.CreateConstGEP2_64(m_dataPtr, 0, 0); + auto rt = m_builder.CreateLoad(m_dataPtr); + auto gasPtr = m_builder.CreateStructGEP(rt, 0); + return m_builder.CreateLoad(gasPtr, "gas"); +} + +void RuntimeManager::setGas(llvm::Value* _gas) +{ + //auto gasPtr = m_builder.CreateStructGEP(m_dataPtr, 0); + auto rt = m_builder.CreateLoad(m_dataPtr); + auto gasPtr = m_builder.CreateStructGEP(rt, 0); + m_builder.CreateStore(_gas, gasPtr); +} + } } } diff --git a/libevmjit/Runtime.h b/libevmjit/Runtime.h index d9984966e..418555c04 100644 --- a/libevmjit/Runtime.h +++ b/libevmjit/Runtime.h @@ -46,7 +46,7 @@ public: static StackImpl& getStack(); static MemoryImpl& getMemory(); static ExtVMFace& getExt(); - static u256 getGas(); + u256 getGas(); private: @@ -63,6 +63,7 @@ public: RuntimeManager(llvm::IRBuilder<>& _builder); llvm::Value* getGas(); + void setGas(llvm::Value* _gas); private: llvm::GlobalVariable* m_dataPtr;