mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Place current gas counter value in RuntimeData
This commit is contained in:
parent
097b7ae1eb
commit
b579c70643
7 changed files with 37 additions and 32 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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…
Reference in a new issue