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.
Alexis Sellier committed ago 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;