Count additional cost for EXP exponent

This commit is contained in:
Paweł Bylica 2014-12-16 19:13:39 +01:00
parent c2699b32ee
commit 077cf7be5d
3 changed files with 22 additions and 3 deletions

View file

@ -332,9 +332,10 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
case Instruction::EXP:
{
auto left = stack.pop();
auto right = stack.pop();
auto ret = _arith.exp(left, right);
auto base = stack.pop();
auto exponent = stack.pop();
_gasMeter.countExp(exponent);
auto ret = _arith.exp(base, exponent);
stack.push(ret);
break;
}

View file

@ -144,6 +144,21 @@ void GasMeter::count(Instruction _inst)
commitCostBlock();
}
void GasMeter::countExp(llvm::Value* _exponent)
{
// Additional cost is 1 per significant byte of exponent
// lz - leading zeros
// cost = ((256 - lz) + 7) / 8
// OPT: All calculations can be done on 32/64 bits
auto ctlz = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::ctlz, Type::Word);
auto lz = m_builder.CreateCall2(ctlz, _exponent, m_builder.getInt1(false));
auto sigBits = m_builder.CreateSub(Constant::get(256), lz);
auto sigBytes = m_builder.CreateUDiv(m_builder.CreateAdd(sigBits, Constant::get(7)), Constant::get(8));
createCall(m_gasCheckFunc, sigBytes);
}
void GasMeter::countSStore(Ext& _ext, llvm::Value* _index, llvm::Value* _newValue)
{
assert(!m_checkCall); // Everything should've been commited before

View file

@ -23,6 +23,9 @@ public:
/// Calculate & count gas cost for SSTORE instruction
void countSStore(class Ext& _ext, llvm::Value* _index, llvm::Value* _newValue);
/// Calculate & count additional gas cost for EXP instruction
void countExp(llvm::Value* _exponent);
/// Count gas cost of LOG data
void countLogData(llvm::Value* _dataLength);