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 }