Skip to content

Commit

Permalink
Merge pull request #1546 from onflow/container-length-metering
Browse files Browse the repository at this point in the history
Improve metering of containers
  • Loading branch information
dsainati1 committed Apr 11, 2022
2 parents 903b8c5 + 5d96c72 commit d1c8541
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 128 deletions.
9 changes: 6 additions & 3 deletions runtime/common/memorykind.go
Expand Up @@ -35,9 +35,12 @@ const (
MemoryKindCharacter
MemoryKindMetaType
MemoryKindNumber
MemoryKindArray
MemoryKindDictionary
MemoryKindComposite
MemoryKindArrayBase
MemoryKindArrayLength
MemoryKindDictionaryBase
MemoryKindDictionarySize
MemoryKindCompositeBase
MemoryKindCompositeSize
MemoryKindOptional
MemoryKindNil
MemoryKindVoid
Expand Down
179 changes: 91 additions & 88 deletions runtime/common/memorykind_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 44 additions & 0 deletions runtime/common/metering.go
Expand Up @@ -115,6 +115,50 @@ func NewConstantMemoryUsage(kind MemoryKind) MemoryUsage {
}
}

func NewArrayMemoryUsages(length int) (MemoryUsage, MemoryUsage) {
return MemoryUsage{
Kind: MemoryKindArrayBase,
Amount: 1,
}, MemoryUsage{
Kind: MemoryKindArrayLength,
Amount: uint64(length),
}
}

func NewArrayLengthUsage(length int) MemoryUsage {
return MemoryUsage{
Kind: MemoryKindArrayLength,
Amount: uint64(length),
}
}

func NewDictionaryMemoryUsages(length int) (MemoryUsage, MemoryUsage) {
return MemoryUsage{
Kind: MemoryKindDictionaryBase,
Amount: 1,
}, MemoryUsage{
Kind: MemoryKindDictionarySize,
Amount: uint64(length),
}
}

func NewDictionarySizeUsage(length int) MemoryUsage {
return MemoryUsage{
Kind: MemoryKindDictionarySize,
Amount: uint64(length),
}
}

func NewCompositeMemoryUsages(length int) (MemoryUsage, MemoryUsage) {
return MemoryUsage{
Kind: MemoryKindCompositeBase,
Amount: 1,
}, MemoryUsage{
Kind: MemoryKindCompositeSize,
Amount: uint64(length),
}
}

func NewStringMemoryUsage(length int) MemoryUsage {
return MemoryUsage{
Kind: MemoryKindString,
Expand Down
2 changes: 1 addition & 1 deletion runtime/imported_values_memory_metering_test.go
Expand Up @@ -372,7 +372,7 @@ func TestMemoryMeteringErrors(t *testing.T) {
intf := &testRuntimeInterface{
meterMemory: func(usage common.MemoryUsage) error {
if usage.Kind == common.MemoryKindString ||
usage.Kind == common.MemoryKindArray {
usage.Kind == common.MemoryKindArrayBase {
return testMemoryError{}
}
return nil
Expand Down
5 changes: 4 additions & 1 deletion runtime/interpreter/simplecompositevalue.go
Expand Up @@ -57,7 +57,10 @@ func NewSimpleCompositeValue(
fieldFormatters map[string]func(Value, SeenReferences) string,
stringer func(SeenReferences) string,
) *SimpleCompositeValue {
common.UseConstantMemory(inter, common.MemoryKindComposite)

baseUsage, lengthUsage := common.NewCompositeMemoryUsages(len(fields))
common.UseMemory(inter, baseUsage)
common.UseMemory(inter, lengthUsage)

return &SimpleCompositeValue{
TypeID: typeID,
Expand Down
21 changes: 18 additions & 3 deletions runtime/interpreter/value.go
Expand Up @@ -1356,7 +1356,9 @@ func newArrayValueFromAtreeValue(
staticType ArrayStaticType,
) *ArrayValue {

common.UseMemory(memoryGauge, common.NewConstantMemoryUsage(common.MemoryKindArray))
baseUse, lengthUse := common.NewArrayMemoryUsages(int(array.Count()))
common.UseMemory(memoryGauge, baseUse)
common.UseMemory(memoryGauge, lengthUse)

return &ArrayValue{
Type: staticType,
Expand Down Expand Up @@ -1648,6 +1650,9 @@ func (v *ArrayValue) RecursiveString(seenReferences SeenReferences) string {

func (v *ArrayValue) Append(interpreter *Interpreter, getLocationRange func() LocationRange, element Value) {

// length increases by 1
common.UseMemory(interpreter, common.NewArrayLengthUsage(1))

interpreter.checkContainerMutation(v.Type.ElementType(), element, getLocationRange)

element = element.Transfer(
Expand Down Expand Up @@ -1694,6 +1699,9 @@ func (v *ArrayValue) Insert(interpreter *Interpreter, getLocationRange func() Lo
})
}

// length increases by 1
common.UseMemory(interpreter, common.NewArrayLengthUsage(1))

interpreter.checkContainerMutation(v.Type.ElementType(), element, getLocationRange)

element = element.Transfer(
Expand Down Expand Up @@ -13973,7 +13981,9 @@ func newCompositeValueFromOrderedMap(
typeInfo compositeTypeInfo,
) *CompositeValue {

common.UseMemory(memoryGauge, common.NewConstantMemoryUsage(common.MemoryKindComposite))
baseUse, lengthUse := common.NewCompositeMemoryUsages(int(dict.Count()))
common.UseMemory(memoryGauge, baseUse)
common.UseMemory(memoryGauge, lengthUse)

return &CompositeValue{
dictionary: dict,
Expand Down Expand Up @@ -15067,7 +15077,9 @@ func newDictionaryValueFromOrderedMap(
staticType DictionaryStaticType,
) *DictionaryValue {

common.UseMemory(memoryGauge, common.NewConstantMemoryUsage(common.MemoryKindDictionary))
baseUse, lengthUse := common.NewDictionaryMemoryUsages(int(dict.Count()))
common.UseMemory(memoryGauge, baseUse)
common.UseMemory(memoryGauge, lengthUse)

return &DictionaryValue{
Type: staticType,
Expand Down Expand Up @@ -15562,6 +15574,9 @@ func (v *DictionaryValue) Insert(
keyValue, value Value,
) OptionalValue {

// length increases by 1
common.UseMemory(interpreter, common.NewDictionarySizeUsage(1))

interpreter.checkContainerMutation(v.Type.KeyType, keyValue, getLocationRange)
interpreter.checkContainerMutation(v.Type.ValueType, value, getLocationRange)

Expand Down

0 comments on commit d1c8541

Please sign in to comment.