core/vm: improve jumpdest lookup (#21123)

This commit is contained in:
Martin Holst Swende 2020-05-25 16:12:48 +02:00 committed by GitHub
parent 25a661e0c2
commit e868adde30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -92,25 +92,28 @@ func (c *Contract) validJumpdest(dest *big.Int) bool {
if OpCode(c.Code[udest]) != JUMPDEST { if OpCode(c.Code[udest]) != JUMPDEST {
return false return false
} }
// Do we have a contract hash already? // Do we have it locally already?
if c.analysis != nil {
return c.analysis.codeSegment(udest)
}
// If we have the code hash (but no analysis), we should look into the
// parent analysis map and see if the analysis has been made previously
if c.CodeHash != (common.Hash{}) { if c.CodeHash != (common.Hash{}) {
// Does parent context have the analysis?
analysis, exist := c.jumpdests[c.CodeHash] analysis, exist := c.jumpdests[c.CodeHash]
if !exist { if !exist {
// Do the analysis and save in parent context // Do the analysis and save in parent context
// We do not need to store it in c.analysis
analysis = codeBitmap(c.Code) analysis = codeBitmap(c.Code)
c.jumpdests[c.CodeHash] = analysis c.jumpdests[c.CodeHash] = analysis
} }
// Also stash it in current contract for faster access
c.analysis = analysis
return analysis.codeSegment(udest) return analysis.codeSegment(udest)
} }
// We don't have the code hash, most likely a piece of initcode not already // We don't have the code hash, most likely a piece of initcode not already
// in state trie. In that case, we do an analysis, and save it locally, so // in state trie. In that case, we do an analysis, and save it locally, so
// we don't have to recalculate it for every JUMP instruction in the execution // we don't have to recalculate it for every JUMP instruction in the execution
// However, we don't save it within the parent context // However, we don't save it within the parent context
if c.analysis == nil {
c.analysis = codeBitmap(c.Code) c.analysis = codeBitmap(c.Code)
}
return c.analysis.codeSegment(udest) return c.analysis.codeSegment(udest)
} }