Browse Source

Place current gas counter value in RuntimeData

cl-refactor
Paweł Bylica 10 years ago
parent
commit
b579c70643
  1. 8
      libevmjit/Compiler.cpp
  2. 2
      libevmjit/Compiler.h
  3. 2
      libevmjit/ExecutionEngine.cpp
  4. 21
      libevmjit/GasMeter.cpp
  5. 8
      libevmjit/GasMeter.h
  6. 25
      libevmjit/Runtime.cpp
  7. 3
      libevmjit/Runtime.h

8
libevmjit/Compiler.cpp

@ -178,7 +178,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytesConstRef bytecode)
// Init runtime structures. // Init runtime structures.
RuntimeManager runtimeManager(m_builder); RuntimeManager runtimeManager(m_builder);
GasMeter gasMeter(m_builder); GasMeter gasMeter(m_builder, runtimeManager);
Memory memory(m_builder, gasMeter); Memory memory(m_builder, gasMeter);
Ext ext(m_builder); Ext ext(m_builder);
Stack stack(m_builder); Stack stack(m_builder);
@ -191,7 +191,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytesConstRef bytecode)
auto iterCopy = basicBlockPairIt; auto iterCopy = basicBlockPairIt;
++iterCopy; ++iterCopy;
auto nextBasicBlock = (iterCopy != basicBlocks.end()) ? iterCopy->second.llvm() : nullptr; 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: // Code for special blocks:
@ -272,7 +272,7 @@ std::unique_ptr<llvm::Module> 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()); m_builder.SetInsertPoint(basicBlock.llvm());
auto& stack = basicBlock.localStack(); auto& stack = basicBlock.localStack();
@ -680,7 +680,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
case Instruction::GAS: case Instruction::GAS:
{ {
stack.push(gasMeter.getGas()); stack.push(_runtimeManager.getGas());
break; break;
} }

2
libevmjit/Compiler.h

@ -31,7 +31,7 @@ private:
void createBasicBlocks(bytesConstRef bytecode); 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(); void removeDeadBlocks();

2
libevmjit/ExecutionEngine.cpp

@ -115,7 +115,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, u256& _gas, ExtV
returnCode = static_cast<ReturnCode>(r); returnCode = static_cast<ReturnCode>(r);
// Return remaining gas // 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; std::cout << "Max stack size: " << Stack::maxStackSize << std::endl;

21
libevmjit/GasMeter.cpp

@ -10,6 +10,7 @@
#include "Type.h" #include "Type.h"
#include "Ext.h" #include "Ext.h"
#include "Runtime.h"
namespace dev namespace dev
{ {
@ -79,12 +80,11 @@ bool isCostBlockEnd(Instruction _inst)
} }
GasMeter::GasMeter(llvm::IRBuilder<>& _builder) : GasMeter::GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager) :
CompilerHelper(_builder) CompilerHelper(_builder),
m_runtimeManager(_runtimeManager)
{ {
auto module = getModule(); 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); m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", module);
InsertPointGuard guard(m_builder); InsertPointGuard guard(m_builder);
@ -96,7 +96,7 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder) :
m_builder.SetInsertPoint(checkBB); m_builder.SetInsertPoint(checkBB);
llvm::Value* cost = m_gasCheckFunc->arg_begin(); llvm::Value* cost = m_gasCheckFunc->arg_begin();
cost->setName("cost"); 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"); auto isOutOfGas = m_builder.CreateICmpUGT(cost, gas, "isOutOfGas");
m_builder.CreateCondBr(isOutOfGas, outOfGasBB, updateBB); m_builder.CreateCondBr(isOutOfGas, outOfGasBB, updateBB);
@ -111,7 +111,7 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder) :
m_builder.SetInsertPoint(updateBB); m_builder.SetInsertPoint(updateBB);
gas = m_builder.CreateSub(gas, cost); gas = m_builder.CreateSub(gas, cost);
m_builder.CreateStore(gas, m_gas); m_runtimeManager.setGas(gas);
m_builder.CreateRetVoid(); m_builder.CreateRetVoid();
} }
@ -153,9 +153,7 @@ void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValu
void GasMeter::giveBack(llvm::Value* _gas) void GasMeter::giveBack(llvm::Value* _gas)
{ {
llvm::Value* gasCounter = m_builder.CreateLoad(m_gas, "gas"); m_runtimeManager.setGas(m_builder.CreateAdd(m_runtimeManager.getGas(), _gas));
gasCounter = m_builder.CreateAdd(gasCounter, _gas);
m_builder.CreateStore(gasCounter, m_gas);
} }
void GasMeter::commitCostBlock(llvm::Value* _additionalCost) void GasMeter::commitCostBlock(llvm::Value* _additionalCost)
@ -191,11 +189,6 @@ void GasMeter::checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilde
_builder.CreateCall(m_gasCheckFunc, cost); _builder.CreateCall(m_gasCheckFunc, cost);
} }
llvm::Value* GasMeter::getGas()
{
return m_builder.CreateLoad(m_gas, "gas");
}
} }
} }
} }

8
libevmjit/GasMeter.h

@ -11,11 +11,12 @@ namespace eth
{ {
namespace jit namespace jit
{ {
class RuntimeManager;
class GasMeter : public CompilerHelper class GasMeter : public CompilerHelper
{ {
public: public:
GasMeter(llvm::IRBuilder<>& _builder); GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager);
/// Count step cost of instruction /// Count step cost of instruction
void count(Instruction _inst); void count(Instruction _inst);
@ -33,16 +34,15 @@ public:
/// 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 checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder); void checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder);
llvm::Value* getGas();
private: private:
/// Cumulative gas cost of a block of instructions /// Cumulative gas cost of a block of instructions
/// @TODO Handle overflow /// @TODO Handle overflow
uint64_t m_blockCost = 0; uint64_t m_blockCost = 0;
llvm::CallInst* m_checkCall = nullptr; llvm::CallInst* m_checkCall = nullptr;
llvm::GlobalVariable* m_gas;
llvm::Function* m_gasCheckFunc; llvm::Function* m_gasCheckFunc;
RuntimeManager& m_runtimeManager;
}; };
} }

25
libevmjit/Runtime.cpp

@ -31,17 +31,12 @@ llvm::StructType* RuntimeData::getType()
static Runtime* g_runtime; static Runtime* g_runtime;
extern "C"
{
EXPORT i256 gas;
}
Runtime::Runtime(u256 _gas, ExtVMFace& _ext): Runtime::Runtime(u256 _gas, ExtVMFace& _ext):
m_ext(_ext) m_ext(_ext)
{ {
assert(!g_runtime); assert(!g_runtime);
g_runtime = this; g_runtime = this;
gas = eth2llvm(_gas); m_data.gas = eth2llvm(_gas);
} }
Runtime::~Runtime() Runtime::~Runtime()
@ -66,7 +61,7 @@ ExtVMFace& Runtime::getExt()
u256 Runtime::getGas() 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); 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);
}
} }
} }
} }

3
libevmjit/Runtime.h

@ -46,7 +46,7 @@ public:
static StackImpl& getStack(); static StackImpl& getStack();
static MemoryImpl& getMemory(); static MemoryImpl& getMemory();
static ExtVMFace& getExt(); static ExtVMFace& getExt();
static u256 getGas(); u256 getGas();
private: private:
@ -63,6 +63,7 @@ public:
RuntimeManager(llvm::IRBuilder<>& _builder); RuntimeManager(llvm::IRBuilder<>& _builder);
llvm::Value* getGas(); llvm::Value* getGas();
void setGas(llvm::Value* _gas);
private: private:
llvm::GlobalVariable* m_dataPtr; llvm::GlobalVariable* m_dataPtr;

Loading…
Cancel
Save