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