Browse Source

Place current gas counter value in RuntimeData

cl-refactor
Paweł Bylica 10 years ago
parent
commit
fcf5400c3a
  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.
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<llvm::Module> 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<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());
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;
}

2
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();

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);
// 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;

21
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");
}
}
}
}

8
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;
};
}

25
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);
}
}
}
}

3
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;

Loading…
Cancel
Save