From d5f7de4a2ea45f78b614857182aed22a4442aa38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 13 Oct 2014 12:50:23 +0200 Subject: [PATCH] Always commit cost blocks [#79942174] --- evmcc/Compiler.cpp | 4 +++- evmcc/GasMeter.cpp | 18 +++++++++++++----- evmcc/GasMeter.h | 6 +++++- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/evmcc/Compiler.cpp b/evmcc/Compiler.cpp index e532ce9f5..1fc4ef6a1 100644 --- a/evmcc/Compiler.cpp +++ b/evmcc/Compiler.cpp @@ -213,7 +213,7 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) { auto inst = static_cast(bytecode[currentPC]); - gasMeter.check(inst); + gasMeter.count(inst); switch (inst) { @@ -819,6 +819,8 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) } } + gasMeter.commitCostBlock(); + if (!builder.GetInsertBlock()->getTerminator()) // If block not terminated { if (basicBlock.end() == bytecode.size()) diff --git a/evmcc/GasMeter.cpp b/evmcc/GasMeter.cpp index fd68b9d40..7ba822e4a 100644 --- a/evmcc/GasMeter.cpp +++ b/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)) - { - m_checkCall->setArgOperand(0, m_builder.getIntN(256, m_blockCost)); // Update block cost in gas check call + 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) diff --git a/evmcc/GasMeter.h b/evmcc/GasMeter.h index 73f0d6e1c..38f780ca5 100644 --- a/evmcc/GasMeter.h +++ b/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);