perf(lang): Intern generic dependencies once
5d2b63a3d309728f250e50d3f3d7476aa52928f308e467b18db9be212959f170
Let generic specialization interning enforce the dependency depth limit and return the canonical callee. This avoids a second specialization search when closure discovers a new callee.
1 parent
067b5f48
lib/std/lang/resolver.rad
+9 -22
| 4107 | 4107 | depth: u16, |
|
| 4108 | 4108 | ) -> *GenericFnSpecialization throws (ResolveError) { |
|
| 4109 | 4109 | if let existing = findGenericFnSpecialization(self, templateSym, args) { |
|
| 4110 | 4110 | return existing; |
|
| 4111 | 4111 | } |
|
| 4112 | + | if depth > MAX_GENERIC_SPECIALIZATION_DEPTH { |
|
| 4113 | + | throw emitError(self, site, ErrorKind::GenericSpecializationChain); |
|
| 4114 | + | } |
|
| 4112 | 4115 | if self.genericSpecializationCount >= MAX_GENERIC_SPECIALIZATIONS { |
|
| 4113 | 4116 | throw emitError(self, site, ErrorKind::GenericSpecializationLimit); |
|
| 4114 | 4117 | } |
|
| 4115 | 4118 | set self.genericSpecializationCount += 1; |
|
| 4116 | 4119 | let template = genericTemplateFor(self, templateSym) |
| 4304 | 4307 | ErrorKind::GenericBoundUnsatisfied(bound.name), |
|
| 4305 | 4308 | ); |
|
| 4306 | 4309 | } |
|
| 4307 | 4310 | } |
|
| 4308 | 4311 | } |
|
| 4309 | - | let mut callee = findGenericFnSpecialization( |
|
| 4310 | - | self, dependency.callee, &concreteArgs[..] |
|
| 4312 | + | let concreteCallee = try internGenericFnSpecialization( |
|
| 4313 | + | self, |
|
| 4314 | + | dependency.callee, |
|
| 4315 | + | &concreteArgs[..], |
|
| 4316 | + | dependency.site, |
|
| 4317 | + | specialization.depth + 1, |
|
| 4311 | 4318 | ); |
|
| 4312 | - | if callee == nil { |
|
| 4313 | - | if specialization.depth >= MAX_GENERIC_SPECIALIZATION_DEPTH { |
|
| 4314 | - | throw emitError( |
|
| 4315 | - | self, |
|
| 4316 | - | dependency.site, |
|
| 4317 | - | ErrorKind::GenericSpecializationChain, |
|
| 4318 | - | ); |
|
| 4319 | - | } |
|
| 4320 | - | set callee = try internGenericFnSpecialization( |
|
| 4321 | - | self, |
|
| 4322 | - | dependency.callee, |
|
| 4323 | - | &concreteArgs[..], |
|
| 4324 | - | dependency.site, |
|
| 4325 | - | specialization.depth + 1, |
|
| 4326 | - | ); |
|
| 4327 | - | } |
|
| 4328 | - | let concreteCallee = callee |
|
| 4329 | - | else throw emitError( |
|
| 4330 | - | self, dependency.site, ErrorKind::Internal |
|
| 4331 | - | ); |
|
| 4332 | 4319 | let resolution = try! alloc::alloc( |
|
| 4333 | 4320 | &mut self.arena, |
|
| 4334 | 4321 | @sizeOf(GenericFnDependencyResolution), |
|
| 4335 | 4322 | @alignOf(GenericFnDependencyResolution), |
|
| 4336 | 4323 | ) as *mut GenericFnDependencyResolution; |