github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/meter/memory_meter.go (about)

     1  package meter
     2  
     3  import (
     4  	"math"
     5  
     6  	"github.com/onflow/cadence/runtime/common"
     7  
     8  	"github.com/onflow/flow-go/fvm/errors"
     9  )
    10  
    11  var (
    12  	// DefaultMemoryWeights are currently hard-coded here. In the future we might like to
    13  	// define this in a contract similar to the computation weights
    14  	DefaultMemoryWeights = ExecutionMemoryWeights{
    15  
    16  		// Values
    17  
    18  		common.MemoryKindAddressValue:   32,
    19  		common.MemoryKindStringValue:    138,
    20  		common.MemoryKindCharacterValue: 24,
    21  		common.MemoryKindNumberValue:    8,
    22  		// weights for these values include the cost of the Go struct itself (first number)
    23  		// as well as the overhead for creation of the underlying atree (second number)
    24  		common.MemoryKindArrayValueBase:                   57 + 48,
    25  		common.MemoryKindDictionaryValueBase:              33 + 96,
    26  		common.MemoryKindCompositeValueBase:               233 + 96,
    27  		common.MemoryKindSimpleCompositeValue:             73,
    28  		common.MemoryKindSimpleCompositeValueBase:         89,
    29  		common.MemoryKindOptionalValue:                    41,
    30  		common.MemoryKindTypeValue:                        17,
    31  		common.MemoryKindPathValue:                        24,
    32  		common.MemoryKindCapabilityValue:                  1, // TODO: update with proper weight
    33  		common.MemoryKindStorageCapabilityControllerValue: 32,
    34  		common.MemoryKindAccountCapabilityControllerValue: 32,
    35  		common.MemoryKindPublishedValue:                   1,
    36  		common.MemoryKindStorageReferenceValue:            41,
    37  		common.MemoryKindEphemeralReferenceValue:          41,
    38  		common.MemoryKindInterpretedFunctionValue:         128,
    39  		common.MemoryKindHostFunctionValue:                41,
    40  		common.MemoryKindBoundFunctionValue:               25,
    41  		common.MemoryKindBigInt:                           50,
    42  		common.MemoryKindVoidExpression:                   1,
    43  
    44  		// Atree
    45  
    46  		common.MemoryKindAtreeArrayDataSlab:          80,
    47  		common.MemoryKindAtreeArrayMetaDataSlab:      1024,
    48  		common.MemoryKindAtreeArrayElementOverhead:   16,
    49  		common.MemoryKindAtreeMapDataSlab:            144,
    50  		common.MemoryKindAtreeMapMetaDataSlab:        1024,
    51  		common.MemoryKindAtreeMapElementOverhead:     64,
    52  		common.MemoryKindAtreeMapPreAllocatedElement: 24,
    53  		common.MemoryKindAtreeEncodedSlab:            1536,
    54  
    55  		// Static Types
    56  
    57  		common.MemoryKindPrimitiveStaticType:     8,
    58  		common.MemoryKindCompositeStaticType:     17,
    59  		common.MemoryKindInterfaceStaticType:     17,
    60  		common.MemoryKindVariableSizedStaticType: 17,
    61  		common.MemoryKindConstantSizedStaticType: 25,
    62  		common.MemoryKindDictionaryStaticType:    33,
    63  		common.MemoryKindOptionalStaticType:      17,
    64  		common.MemoryKindIntersectionStaticType:  41,
    65  		common.MemoryKindReferenceStaticType:     41,
    66  		common.MemoryKindCapabilityStaticType:    17,
    67  		common.MemoryKindFunctionStaticType:      9,
    68  
    69  		// Cadence Values
    70  
    71  		common.MemoryKindCadenceVoidValue:           1,
    72  		common.MemoryKindCadenceOptionalValue:       17,
    73  		common.MemoryKindCadenceBoolValue:           8,
    74  		common.MemoryKindCadenceStringValue:         16,
    75  		common.MemoryKindCadenceCharacterValue:      16,
    76  		common.MemoryKindCadenceAddressValue:        8,
    77  		common.MemoryKindCadenceIntValue:            50,
    78  		common.MemoryKindCadenceNumberValue:         1,
    79  		common.MemoryKindCadenceArrayValueBase:      41,
    80  		common.MemoryKindCadenceArrayValueLength:    16,
    81  		common.MemoryKindCadenceDictionaryValue:     41,
    82  		common.MemoryKindCadenceKeyValuePair:        33,
    83  		common.MemoryKindCadenceStructValueBase:     33,
    84  		common.MemoryKindCadenceStructValueSize:     16,
    85  		common.MemoryKindCadenceResourceValueBase:   33,
    86  		common.MemoryKindCadenceResourceValueSize:   16,
    87  		common.MemoryKindCadenceEventValueBase:      33,
    88  		common.MemoryKindCadenceEventValueSize:      16,
    89  		common.MemoryKindCadenceContractValueBase:   33,
    90  		common.MemoryKindCadenceContractValueSize:   16,
    91  		common.MemoryKindCadenceEnumValueBase:       33,
    92  		common.MemoryKindCadenceEnumValueSize:       16,
    93  		common.MemoryKindCadencePathValue:           33,
    94  		common.MemoryKindCadenceTypeValue:           17,
    95  		common.MemoryKindCadenceCapabilityValue:     1, // TODO: update with proper weight
    96  		common.MemoryKindCadenceFunctionValue:       1,
    97  		common.MemoryKindCadenceAttachmentValueBase: 33,
    98  		common.MemoryKindCadenceAttachmentValueSize: 16,
    99  
   100  		// Cadence Types
   101  
   102  		common.MemoryKindCadenceTypeParameter:            17,
   103  		common.MemoryKindCadenceOptionalType:             17,
   104  		common.MemoryKindCadenceVariableSizedArrayType:   17,
   105  		common.MemoryKindCadenceConstantSizedArrayType:   25,
   106  		common.MemoryKindCadenceDictionaryType:           33,
   107  		common.MemoryKindCadenceField:                    33,
   108  		common.MemoryKindCadenceParameter:                49,
   109  		common.MemoryKindCadenceStructType:               81,
   110  		common.MemoryKindCadenceResourceType:             81,
   111  		common.MemoryKindCadenceEventType:                81,
   112  		common.MemoryKindCadenceContractType:             81,
   113  		common.MemoryKindCadenceStructInterfaceType:      81,
   114  		common.MemoryKindCadenceResourceInterfaceType:    81,
   115  		common.MemoryKindCadenceContractInterfaceType:    81,
   116  		common.MemoryKindCadenceFunctionType:             41,
   117  		common.MemoryKindCadenceReferenceType:            25,
   118  		common.MemoryKindCadenceIntersectionType:         57,
   119  		common.MemoryKindCadenceDeprecatedRestrictedType: 57,
   120  		common.MemoryKindCadenceCapabilityType:           17,
   121  		common.MemoryKindCadenceEnumType:                 97,
   122  		common.MemoryKindCadenceAttachmentType:           81,
   123  
   124  		// Misc
   125  
   126  		common.MemoryKindRawString:         9,
   127  		common.MemoryKindAddressLocation:   18,
   128  		common.MemoryKindBytes:             24,
   129  		common.MemoryKindVariable:          18,
   130  		common.MemoryKindCompositeTypeInfo: 41,
   131  		common.MemoryKindCompositeField:    33,
   132  		common.MemoryKindInvocation:        89,
   133  		common.MemoryKindStorageMap:        58,
   134  		common.MemoryKindStorageKey:        41,
   135  
   136  		// Tokens
   137  
   138  		common.MemoryKindErrorToken: 41,
   139  		common.MemoryKindTypeToken:  25,
   140  		common.MemoryKindSpaceToken: 50,
   141  
   142  		// AST nodes
   143  
   144  		common.MemoryKindProgram:           220,
   145  		common.MemoryKindIdentifier:        17,
   146  		common.MemoryKindArgument:          49,
   147  		common.MemoryKindBlock:             25,
   148  		common.MemoryKindFunctionBlock:     25,
   149  		common.MemoryKindParameter:         25,
   150  		common.MemoryKindParameterList:     59,
   151  		common.MemoryKindTypeParameter:     9,
   152  		common.MemoryKindTypeParameterList: 59,
   153  		common.MemoryKindTransfer:          1,
   154  		common.MemoryKindMembers:           276,
   155  		common.MemoryKindTypeAnnotation:    25,
   156  		common.MemoryKindDictionaryEntry:   33,
   157  
   158  		common.MemoryKindFunctionDeclaration:           49,
   159  		common.MemoryKindCompositeDeclaration:          65,
   160  		common.MemoryKindInterfaceDeclaration:          41,
   161  		common.MemoryKindEnumCaseDeclaration:           25,
   162  		common.MemoryKindFieldDeclaration:              41,
   163  		common.MemoryKindTransactionDeclaration:        81,
   164  		common.MemoryKindImportDeclaration:             41,
   165  		common.MemoryKindVariableDeclaration:           97,
   166  		common.MemoryKindSpecialFunctionDeclaration:    17,
   167  		common.MemoryKindPragmaDeclaration:             17,
   168  		common.MemoryKindAttachmentDeclaration:         70,
   169  		common.MemoryKindEntitlementDeclaration:        33,
   170  		common.MemoryKindEntitlementMappingElement:     17,
   171  		common.MemoryKindEntitlementMappingDeclaration: 57,
   172  
   173  		common.MemoryKindAssignmentStatement: 41,
   174  		common.MemoryKindBreakStatement:      1,
   175  		common.MemoryKindContinueStatement:   1,
   176  		common.MemoryKindEmitStatement:       9,
   177  		common.MemoryKindExpressionStatement: 17,
   178  		common.MemoryKindForStatement:        33,
   179  		common.MemoryKindIfStatement:         33,
   180  		common.MemoryKindReturnStatement:     17,
   181  		common.MemoryKindSwapStatement:       33,
   182  		common.MemoryKindSwitchStatement:     41,
   183  		common.MemoryKindWhileStatement:      25,
   184  		common.MemoryKindRemoveStatement:     33,
   185  
   186  		common.MemoryKindBooleanExpression:     9,
   187  		common.MemoryKindNilExpression:         1,
   188  		common.MemoryKindStringExpression:      17,
   189  		common.MemoryKindIntegerExpression:     33,
   190  		common.MemoryKindFixedPointExpression:  49,
   191  		common.MemoryKindArrayExpression:       25,
   192  		common.MemoryKindDictionaryExpression:  25,
   193  		common.MemoryKindIdentifierExpression:  1,
   194  		common.MemoryKindInvocationExpression:  49,
   195  		common.MemoryKindMemberExpression:      25,
   196  		common.MemoryKindIndexExpression:       33,
   197  		common.MemoryKindConditionalExpression: 49,
   198  		common.MemoryKindUnaryExpression:       25,
   199  		common.MemoryKindBinaryExpression:      41,
   200  		common.MemoryKindFunctionExpression:    25,
   201  		common.MemoryKindCastingExpression:     41,
   202  		common.MemoryKindCreateExpression:      9,
   203  		common.MemoryKindDestroyExpression:     17,
   204  		common.MemoryKindReferenceExpression:   33,
   205  		common.MemoryKindForceExpression:       17,
   206  		common.MemoryKindPathExpression:        1,
   207  		common.MemoryKindAttachExpression:      33,
   208  
   209  		common.MemoryKindConstantSizedType: 25,
   210  		common.MemoryKindDictionaryType:    33,
   211  		common.MemoryKindFunctionType:      33,
   212  		common.MemoryKindInstantiationType: 41,
   213  		common.MemoryKindNominalType:       25,
   214  		common.MemoryKindOptionalType:      17,
   215  		common.MemoryKindReferenceType:     25,
   216  		common.MemoryKindIntersectionType:  41,
   217  		common.MemoryKindVariableSizedType: 17,
   218  
   219  		common.MemoryKindPosition:          25,
   220  		common.MemoryKindRange:             1,
   221  		common.MemoryKindActivation:        128,
   222  		common.MemoryKindActivationEntries: 256,
   223  		common.MemoryKindElaboration:       501,
   224  
   225  		// sema types
   226  		common.MemoryKindVariableSizedSemaType:       51,
   227  		common.MemoryKindConstantSizedSemaType:       59,
   228  		common.MemoryKindDictionarySemaType:          67,
   229  		common.MemoryKindOptionalSemaType:            17,
   230  		common.MemoryKindIntersectionSemaType:        75,
   231  		common.MemoryKindReferenceSemaType:           25,
   232  		common.MemoryKindCapabilitySemaType:          51,
   233  		common.MemoryKindEntitlementSemaType:         49,
   234  		common.MemoryKindEntitlementMapSemaType:      73,
   235  		common.MemoryKindEntitlementRelationSemaType: 73,
   236  
   237  		// ordered-map
   238  		common.MemoryKindOrderedMap:          17,
   239  		common.MemoryKindOrderedMapEntryList: 50,
   240  		common.MemoryKindOrderedMapEntry:     64,
   241  
   242  		// Entitlement access
   243  		common.MemoryKindEntitlementSetStaticAccess:  17,
   244  		common.MemoryKindEntitlementMapStaticAccess:  17,
   245  		common.MemoryKindCadenceEntitlementSetAccess: 33,
   246  		common.MemoryKindCadenceEntitlementMapAccess: 17,
   247  
   248  		// InclusiveRange
   249  		common.MemoryKindInclusiveRangeStaticType:   17,
   250  		common.MemoryKindCadenceInclusiveRangeValue: 81,
   251  		common.MemoryKindCadenceInclusiveRangeType:  33,
   252  		common.MemoryKindInclusiveRangeSemaType:     17,
   253  	}
   254  )
   255  
   256  func _() {
   257  	// A compiler error signifies that we have not accounted for all memory kinds
   258  	var x [1]struct{}
   259  	_ = x[int(common.MemoryKindLast)-len(DefaultMemoryWeights)-1]
   260  }
   261  
   262  type ExecutionMemoryWeights map[common.MemoryKind]uint64
   263  type MeteredMemoryIntensities map[common.MemoryKind]uint
   264  
   265  type MemoryMeterParameters struct {
   266  	memoryLimit   uint64
   267  	memoryWeights ExecutionMemoryWeights
   268  }
   269  
   270  func DefaultMemoryParameters() MemoryMeterParameters {
   271  	return MemoryMeterParameters{
   272  		memoryLimit:   math.MaxUint64,
   273  		memoryWeights: DefaultMemoryWeights,
   274  	}
   275  }
   276  
   277  func (params MemoryMeterParameters) MemoryWeights() ExecutionMemoryWeights {
   278  	return params.memoryWeights
   279  }
   280  
   281  // TotalMemoryLimit returns the total memory limit
   282  func (params MemoryMeterParameters) TotalMemoryLimit() uint64 {
   283  	return params.memoryLimit
   284  }
   285  
   286  func (params MeterParameters) WithMemoryLimit(limit uint64) MeterParameters {
   287  	newParams := params
   288  	newParams.memoryLimit = limit
   289  	return newParams
   290  }
   291  
   292  func (params MeterParameters) WithMemoryWeights(
   293  	weights ExecutionMemoryWeights,
   294  ) MeterParameters {
   295  	newParams := params
   296  	newParams.memoryWeights = weights
   297  	return newParams
   298  }
   299  
   300  type MemoryMeter struct {
   301  	params MemoryMeterParameters
   302  
   303  	memoryIntensities MeteredMemoryIntensities
   304  	memoryEstimate    uint64
   305  }
   306  
   307  // MemoryIntensities returns all the measured memory intensities
   308  func (m *MemoryMeter) MemoryIntensities() MeteredMemoryIntensities {
   309  	return m.memoryIntensities
   310  }
   311  
   312  // NewMemoryMeter constructs a new Meter
   313  func NewMemoryMeter(params MemoryMeterParameters) MemoryMeter {
   314  	m := MemoryMeter{
   315  		params:            params,
   316  		memoryIntensities: make(MeteredMemoryIntensities),
   317  	}
   318  
   319  	return m
   320  }
   321  
   322  // MeterMemory captures memory usage and returns an error if it goes beyond the limit
   323  func (m *MemoryMeter) MeterMemory(kind common.MemoryKind, intensity uint) error {
   324  	m.memoryIntensities[kind] += intensity
   325  	w, ok := m.params.memoryWeights[kind]
   326  	if !ok {
   327  		return nil
   328  	}
   329  	m.memoryEstimate += w * uint64(intensity)
   330  	if m.memoryEstimate > m.params.memoryLimit {
   331  		return errors.NewMemoryLimitExceededError(m.params.TotalMemoryLimit())
   332  	}
   333  	return nil
   334  }
   335  
   336  // TotalMemoryEstimate returns the total memory used
   337  func (m *MemoryMeter) TotalMemoryEstimate() uint64 {
   338  	return m.memoryEstimate
   339  }
   340  
   341  // Merge merges the input meter into the current meter and checks for the limits
   342  func (m *MemoryMeter) Merge(child MemoryMeter) {
   343  	m.memoryEstimate = m.memoryEstimate + child.TotalMemoryEstimate()
   344  
   345  	for key, intensity := range child.memoryIntensities {
   346  		m.memoryIntensities[key] += intensity
   347  	}
   348  }