Browse Source

Always commit cost blocks

[#79942174]
cl-refactor
Paweł Bylica 10 years ago
parent
commit
d5f7de4a2e
  1. 4
      evmcc/Compiler.cpp
  2. 12
      evmcc/GasMeter.cpp
  3. 6
      evmcc/GasMeter.h

4
evmcc/Compiler.cpp

@ -213,7 +213,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
{
auto inst = static_cast<Instruction>(bytecode[currentPC]);
gasMeter.check(inst);
gasMeter.count(inst);
switch (inst)
{
@ -819,6 +819,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
}
}
gasMeter.commitCostBlock();
if (!builder.GetInsertBlock()->getTerminator()) // If block not terminated
{
if (basicBlock.end() == bytecode.size())

12
evmcc/GasMeter.cpp

@ -97,22 +97,30 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module):
m_builder.SetInsertPoint(bb, pt);
}
void GasMeter::check(Instruction _inst)
void GasMeter::count(Instruction _inst)
{
if (!m_checkCall)
{
// Create gas check call with mocked block cost at begining of current cost-block
m_checkCall = m_builder.CreateCall(m_gasCheckFunc, m_builder.getIntN(256, 0));
m_checkCall = m_builder.CreateCall(m_gasCheckFunc, llvm::UndefValue::get(Type::i256));
}
m_blockCost += getStepCost(_inst);
if (isCostBlockEnd(_inst))
commitCostBlock();
}
void GasMeter::commitCostBlock()
{
// If any uncommited block
if (m_checkCall)
{
m_checkCall->setArgOperand(0, m_builder.getIntN(256, m_blockCost)); // Update block cost in gas check call
m_checkCall = nullptr; // End cost-block
m_blockCost = 0;
}
assert(m_blockCost == 0);
}
void GasMeter::checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder)

6
evmcc/GasMeter.h

@ -16,7 +16,11 @@ public:
GasMeter(const GasMeter&) = delete;
void operator=(GasMeter) = delete;
void check(dev::eth::Instruction _inst);
/// Count step cost of instruction
void count(dev::eth::Instruction _inst);
/// Finalize cost block by checking gas needed for the block before the block
void commitCostBlock();
/// Generate code that checks the cost of additional memory used by program
void checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder);

Loading…
Cancel
Save