mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-17 02:10:46 +00:00
core/vm: avoid map lookups for accessing jumpdest analysis (#21411)
This commit is contained in:
parent
a020259bb5
commit
4e832ee6f0
1 changed files with 15 additions and 4 deletions
|
|
@ -93,16 +93,25 @@ func (c *Contract) validJumpdest(dest *uint256.Int) bool {
|
||||||
if OpCode(c.Code[udest]) != JUMPDEST {
|
if OpCode(c.Code[udest]) != JUMPDEST {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// Do we have it locally already?
|
return c.isCode(udest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// isCode returns true if the provided PC location is an actual opcode, as
|
||||||
|
// opposed to a data-segment following a PUSHN operation.
|
||||||
|
func (c *Contract) isCode(udest uint64) bool {
|
||||||
|
// Do we already have an analysis laying around?
|
||||||
if c.analysis != nil {
|
if c.analysis != nil {
|
||||||
return c.analysis.codeSegment(udest)
|
return c.analysis.codeSegment(udest)
|
||||||
}
|
}
|
||||||
// If we have the code hash (but no analysis), we should look into the
|
// Do we have a contract hash already?
|
||||||
// parent analysis map and see if the analysis has been made previously
|
// If we do have a hash, that means it's a 'regular' contract. For regular
|
||||||
|
// contracts ( not temporary initcode), we store the analysis in a map
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +123,9 @@ func (c *Contract) validJumpdest(dest *uint256.Int) bool {
|
||||||
// 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
|
||||||
c.analysis = codeBitmap(c.Code)
|
if c.analysis == nil {
|
||||||
|
c.analysis = codeBitmap(c.Code)
|
||||||
|
}
|
||||||
return c.analysis.codeSegment(udest)
|
return c.analysis.codeSegment(udest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue