diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 7c665fba2f..778ffa9b1f 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -842,7 +842,7 @@ struct State<'a> { /// pending specializations in the same thread. pub needs_specialization: MutSet, - pub all_pending_specializations: MutMap, PendingSpecialization>>, + pub all_pending_specializations: MutMap, PendingSpecialization<'a>>>, pub specializations_in_flight: u32, @@ -3969,6 +3969,7 @@ fn add_def_to_module<'a>( procs.insert_exposed( symbol, layout, + mono_env.arena, mono_env.subs, def.annotation, annotation, @@ -4021,6 +4022,7 @@ fn add_def_to_module<'a>( procs.insert_exposed( symbol, layout, + mono_env.arena, mono_env.subs, def.annotation, annotation, diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index c4a34297e2..ffd6f231ea 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -77,31 +77,35 @@ impl<'a> CapturedSymbols<'a> { } #[derive(Clone, Debug, PartialEq)] -pub struct PendingSpecialization { +pub struct PendingSpecialization<'a> { solved_type: SolvedType, - host_exposed_aliases: MutMap, + host_exposed_aliases: BumpMap<'a, Symbol, SolvedType>, } -impl PendingSpecialization { - pub fn from_var(subs: &Subs, var: Variable) -> Self { +impl<'a> PendingSpecialization<'a> { + pub fn from_var(arena: &'a Bump, subs: &Subs, var: Variable) -> Self { let solved_type = SolvedType::from_var(subs, var); PendingSpecialization { solved_type, - host_exposed_aliases: MutMap::default(), + host_exposed_aliases: BumpMap::new_in(arena), } } pub fn from_var_host_exposed( + arena: &'a Bump, subs: &Subs, var: Variable, - host_exposed_aliases: &MutMap, + exposed: &MutMap, ) -> Self { let solved_type = SolvedType::from_var(subs, var); - let host_exposed_aliases = host_exposed_aliases - .iter() - .map(|(symbol, variable)| (*symbol, SolvedType::from_var(subs, *variable))) - .collect(); + let mut host_exposed_aliases = BumpMap::with_capacity_in(exposed.len(), arena); + + host_exposed_aliases.extend( + exposed + .iter() + .map(|(symbol, variable)| (*symbol, SolvedType::from_var(subs, *variable))), + ); PendingSpecialization { solved_type, @@ -275,7 +279,8 @@ pub struct Procs<'a> { pub partial_procs: MutMap>, pub imported_module_thunks: MutSet, pub module_thunks: MutSet, - pub pending_specializations: Option, PendingSpecialization>>>, + pub pending_specializations: + Option, PendingSpecialization<'a>>>>, pub specialized: MutMap<(Symbol, Layout<'a>), InProgressProc<'a>>, pub call_by_pointer_wrappers: MutMap, pub runtime_errors: MutMap, @@ -502,7 +507,7 @@ impl<'a> Procs<'a> { // Changing it to use .entry() would necessarily make it incorrect. #[allow(clippy::map_entry)] if !already_specialized { - let pending = PendingSpecialization::from_var(env.subs, annotation); + let pending = PendingSpecialization::from_var(env.arena, env.subs, annotation); let partial_proc; if let Some(existing) = self.partial_procs.get(&symbol) { @@ -576,6 +581,7 @@ impl<'a> Procs<'a> { &mut self, name: Symbol, layout: Layout<'a>, + arena: &'a Bump, subs: &Subs, opt_annotation: Option, fn_var: Variable, @@ -590,8 +596,9 @@ impl<'a> Procs<'a> { // We're done with that tuple, so move layout back out to avoid cloning it. let (name, layout) = tuple; let pending = match opt_annotation { - None => PendingSpecialization::from_var(subs, fn_var), + None => PendingSpecialization::from_var(arena, subs, fn_var), Some(annotation) => PendingSpecialization::from_var_host_exposed( + arena, subs, fn_var, &annotation.introduced_variables.host_exposed_aliases, @@ -634,7 +641,7 @@ impl<'a> Procs<'a> { // We're done with that tuple, so move layout back out to avoid cloning it. let (name, layout) = tuple; - let pending = PendingSpecialization::from_var(env.subs, fn_var); + let pending = PendingSpecialization::from_var(env.arena, env.subs, fn_var); // This should only be called when pending_specializations is Some. // Otherwise, it's being called in the wrong pass! @@ -674,10 +681,10 @@ impl<'a> Procs<'a> { } fn add_pending<'a>( - pending_specializations: &mut MutMap, PendingSpecialization>>, + pending_specializations: &mut MutMap, PendingSpecialization<'a>>>, symbol: Symbol, layout: Layout<'a>, - pending: PendingSpecialization, + pending: PendingSpecialization<'a>, ) { let all_pending = pending_specializations .entry(symbol) @@ -1662,7 +1669,7 @@ pub fn specialize_all<'a>( name, layout_cache, solved_type, - MutMap::default(), + BumpMap::new_in(env.arena), partial_proc, ) { Ok((proc, layout)) => { @@ -2335,7 +2342,7 @@ fn specialize_solved_type<'a>( proc_name: Symbol, layout_cache: &mut LayoutCache<'a>, solved_type: SolvedType, - host_exposed_aliases: MutMap, + host_exposed_aliases: BumpMap, partial_proc: PartialProc<'a>, ) -> Result<(Proc<'a>, Layout<'a>), SpecializeFailure<'a>> { // add the specializations that other modules require of us @@ -6089,7 +6096,7 @@ fn call_by_name<'a>( let iter = loc_args.into_iter().rev().zip(field_symbols.iter().rev()); assign_to_symbols(env, procs, layout_cache, iter, result) } else { - let pending = PendingSpecialization::from_var(env.subs, fn_var); + let pending = PendingSpecialization::from_var(env.arena, env.subs, fn_var); // When requested (that is, when procs.pending_specializations is `Some`), // store a pending specialization rather than specializing immediately.