mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 04:06:44 +00:00
parent
7494fdba7a
commit
fb87a0b2ab
3 changed files with 19 additions and 8 deletions
|
|
@ -784,6 +784,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
auto outOff = stack.pop();
|
auto outOff = stack.pop();
|
||||||
auto outSize = stack.pop();
|
auto outSize = stack.pop();
|
||||||
|
|
||||||
|
gasMeter.commitCostBlock(gas);
|
||||||
auto ret = ext.call(gas, receiveAddress, value, inOff, inSize, outOff, outSize);
|
auto ret = ext.call(gas, receiveAddress, value, inOff, inSize, outOff, outSize);
|
||||||
stack.push(ret);
|
stack.push(ret);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,9 @@ bool isCostBlockEnd(Instruction _inst)
|
||||||
{
|
{
|
||||||
// Basic block terminators like STOP are not needed on the list
|
// Basic block terminators like STOP are not needed on the list
|
||||||
// as cost will be commited at the end of basic block
|
// as cost will be commited at the end of basic block
|
||||||
|
|
||||||
|
// CALL & CALLCODE are commited manually
|
||||||
|
|
||||||
switch (_inst)
|
switch (_inst)
|
||||||
{
|
{
|
||||||
case Instruction::CALLDATACOPY:
|
case Instruction::CALLDATACOPY:
|
||||||
|
|
@ -63,8 +66,6 @@ bool isCostBlockEnd(Instruction _inst)
|
||||||
case Instruction::SSTORE:
|
case Instruction::SSTORE:
|
||||||
case Instruction::GAS:
|
case Instruction::GAS:
|
||||||
case Instruction::CREATE:
|
case Instruction::CREATE:
|
||||||
case Instruction::CALL:
|
|
||||||
case Instruction::CALLCODE:
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -107,16 +108,24 @@ void GasMeter::count(Instruction _inst)
|
||||||
commitCostBlock();
|
commitCostBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GasMeter::commitCostBlock()
|
void GasMeter::commitCostBlock(llvm::Value* _additionalCost)
|
||||||
{
|
{
|
||||||
|
assert(!_additionalCost || m_checkCall); // _additionalCost => m_checkCall; Must be inside cost-block
|
||||||
|
|
||||||
// If any uncommited block
|
// If any uncommited block
|
||||||
if (m_checkCall)
|
if (m_checkCall)
|
||||||
{
|
{
|
||||||
if (m_blockCost > 0) // If any cost
|
if (m_blockCost == 0 && !_additionalCost) // Do not check 0
|
||||||
m_checkCall->setArgOperand(0, Constant::get(m_blockCost)); // Update block cost in gas check call
|
{
|
||||||
else
|
|
||||||
m_checkCall->eraseFromParent(); // Remove the gas check call
|
m_checkCall->eraseFromParent(); // Remove the gas check call
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Value* cost = Constant::get(m_blockCost);
|
||||||
|
if (_additionalCost)
|
||||||
|
cost = m_builder.CreateAdd(cost, _additionalCost);
|
||||||
|
|
||||||
|
m_checkCall->setArgOperand(0, cost); // 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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,9 @@ public:
|
||||||
/// Count step cost of instruction
|
/// Count step cost of instruction
|
||||||
void count(dev::eth::Instruction _inst);
|
void count(dev::eth::Instruction _inst);
|
||||||
|
|
||||||
/// Finalize cost block by checking gas needed for the block before the block
|
/// Finalize cost-block by checking gas needed for the block before the block
|
||||||
void commitCostBlock();
|
/// @param _additionalCost adds additional cost to cost-block before commit
|
||||||
|
void commitCostBlock(llvm::Value* _additionalCost = nullptr);
|
||||||
|
|
||||||
/// 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…
Reference in a new issue