Browse Source

Always commit cost blocks

[#79942174]
cl-refactor
Paweł Bylica 10 years ago
parent
commit
d5f7de4a2e
  1. 4
      evmcc/Compiler.cpp
  2. 18
      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]); auto inst = static_cast<Instruction>(bytecode[currentPC]);
gasMeter.check(inst); gasMeter.count(inst);
switch (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 (!builder.GetInsertBlock()->getTerminator()) // If block not terminated
{ {
if (basicBlock.end() == bytecode.size()) if (basicBlock.end() == bytecode.size())

18
evmcc/GasMeter.cpp

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

6
evmcc/GasMeter.h

@ -16,7 +16,11 @@ public:
GasMeter(const GasMeter&) = delete; GasMeter(const GasMeter&) = delete;
void operator=(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 /// 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);

Loading…
Cancel
Save