Skip to content
Open
5 changes: 5 additions & 0 deletions bbq/compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4274,6 +4274,11 @@ func (c *Compiler[_, _]) getOrAddType(ty sema.Type) uint16 {
data := c.typeGen.CompileType(staticType)
index = c.addCompiledType(ty, data)
c.typesInPool[typeID] = index

semaTypeCache := c.Config.GetSemaTypeCache()
if semaTypeCache != nil {
semaTypeCache[typeID] = ty
}
}

return index
Expand Down
5 changes: 5 additions & 0 deletions bbq/compiler/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ import (
"github.com/onflow/cadence/activations"
"github.com/onflow/cadence/bbq/commons"
"github.com/onflow/cadence/common"
"github.com/onflow/cadence/sema"
)

type BuiltinGlobalsProvider func(location common.Location) *activations.Activation[GlobalImport]

type ElaborationResolver func(location common.Location) (*DesugaredElaboration, error)

type GetSemaTypeCache func() map[sema.TypeID]sema.Type

type Config struct {
MemoryGauge common.MemoryGauge
ImportHandler commons.ImportHandler
Expand All @@ -38,4 +41,6 @@ type Config struct {
BuiltinGlobalsProvider BuiltinGlobalsProvider

PeepholeOptimizationsEnabled bool

GetSemaTypeCache GetSemaTypeCache
}
7 changes: 7 additions & 0 deletions bbq/vm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ type Config struct {
StackDepthLimit uint64

debugEnabled bool

GetSemaTypeCache GetSemaTypeCache
}

func NewConfig(storage interpreter.Storage) *Config {
Expand All @@ -85,6 +87,9 @@ func NewConfig(storage interpreter.Storage) *Config {
storage: storage,
StackDepthLimit: math.MaxInt,
Tracer: tracer,
GetSemaTypeCache: func() map[sema.TypeID]sema.Type {
return nil
},
}
}

Expand Down Expand Up @@ -301,6 +306,8 @@ type ContractValueHandler func(

type ElaborationResolver func(location common.Location) (*sema.Elaboration, error)

type GetSemaTypeCache func() map[sema.TypeID]sema.Type

type EntitlementTypeHandlerFunc func(location common.Location, typeID interpreter.TypeID) *sema.EntitlementType

type EntitlementMapTypeHandlerFunc func(location common.Location, typeID interpreter.TypeID) *sema.EntitlementMapType
21 changes: 20 additions & 1 deletion bbq/vm/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
package vm

import (
"fmt"

"github.com/onflow/atree"

"github.com/onflow/cadence/bbq"
Expand All @@ -29,6 +31,9 @@ import (
"github.com/onflow/cadence/sema"
)

var cacheHitCount int = 0
var cacheMissCount int = 0

// Context holds the information about the current execution at any given point of time.
// It consists of:
// - Re-usable configurations (Config).
Expand Down Expand Up @@ -76,7 +81,8 @@ var _ interpreter.InvocationContext = &Context{}

func NewContext(config *Config) *Context {
return &Context{
Config: config,
Config: config,
semaTypeCache: config.GetSemaTypeCache(),
}
}

Expand Down Expand Up @@ -427,6 +433,7 @@ func (c *Context) SemaTypeFromStaticType(staticType interpreter.StaticType) sema
typeID := staticType.ID()
semaType, ok := c.semaTypeCache[typeID]
if ok {
cacheHitCount++
return semaType
}

Expand All @@ -438,6 +445,8 @@ func (c *Context) SemaTypeFromStaticType(staticType interpreter.StaticType) sema
}
c.semaTypeCache[typeID] = semaType

cacheMissCount++

return semaType
}

Expand Down Expand Up @@ -551,3 +560,13 @@ func (c *Context) SemaAccessFromStaticAuthorization(auth interpreter.Authorizati

return semaAccess, nil
}

func (c *Context) GetCacheStatistics() {
fmt.Printf("Cache hit count: %d\n", cacheHitCount)
fmt.Printf("Cache miss count: %d\n", cacheMissCount)
}

func (c *Context) ResetCacheStatistics() {
cacheHitCount = 0
cacheMissCount = 0
}
13 changes: 12 additions & 1 deletion bbq/vm/test/ft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ func compiledFTTransfer(tb testing.TB) {
nonFungibleTokenLocation := common.NewAddressLocation(nil, contractsAddress, "NonFungibleToken")
flowTokenLocation := common.NewAddressLocation(nil, contractsAddress, "FlowToken")

semaTypeCache := make(map[sema.TypeID]sema.Type)

codes := map[common.Location][]byte{
burnerLocation: []byte(contracts.RealBurnerContract),
viewResolverLocation: []byte(contracts.RealViewResolverContract),
Expand Down Expand Up @@ -91,7 +93,10 @@ func compiledFTTransfer(tb testing.TB) {

compilerConfig := &compiler.Config{
LocationHandler: locationHandler,
ImportHandler: importHandler,
GetSemaTypeCache: func() map[sema.TypeID]sema.Type {
return semaTypeCache
},
ImportHandler: importHandler,
ElaborationResolver: func(location common.Location) (*compiler.DesugaredElaboration, error) {
imported, ok := compiledPrograms[location]
if !ok {
Expand Down Expand Up @@ -164,6 +169,10 @@ func compiledFTTransfer(tb testing.TB) {

vmConfig := vm.NewConfig(storage)

// vmConfig.GetSemaTypeCache = func() map[sema.TypeID]sema.Type {
// return semaTypeCache
// }

vmConfig.CapabilityBorrowHandler = func(
context interpreter.BorrowCapabilityControllerContext,
address interpreter.AddressValue,
Expand Down Expand Up @@ -483,6 +492,8 @@ func compiledFTTransfer(tb testing.TB) {
)
}
}

tokenTransferTxVM.Context().GetCacheStatistics()
}

func TestFTTransfer(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion bbq/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@ func checkMemberAccessTargetType(

context := vm.context

// TODO: Avoid sema type conversion.
// TODO: Avoid sema type conversion
accessedSemaType := context.SemaTypeFromStaticType(accessedType)

interpreter.CheckMemberAccessTargetType(
Expand Down
Loading