mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 15:59:20 +03:00
commit
7b885f2e7c
@ -29,6 +29,7 @@ pub type SendMap<K, V> = im::hashmap::HashMap<K, V, BuildHasher>;
|
||||
pub type SendSet<K> = im::hashset::HashSet<K, BuildHasher>;
|
||||
|
||||
pub type BumpMap<'a, K, V> = hashbrown::HashMap<K, V, BuildHasher, hashbrown::BumpWrapper<'a>>;
|
||||
pub type BumpSet<'a, K> = hashbrown::HashSet<K, BuildHasher, hashbrown::BumpWrapper<'a>>;
|
||||
|
||||
pub trait BumpMapDefault<'a> {
|
||||
fn new_in(arena: &'a bumpalo::Bump) -> Self;
|
||||
@ -50,6 +51,20 @@ impl<'a, K, V> BumpMapDefault<'a> for BumpMap<'a, K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K> BumpMapDefault<'a> for BumpSet<'a, K> {
|
||||
fn new_in(arena: &'a bumpalo::Bump) -> Self {
|
||||
hashbrown::HashSet::with_hasher_in(default_hasher(), hashbrown::BumpWrapper(arena))
|
||||
}
|
||||
|
||||
fn with_capacity_in(capacity: usize, arena: &'a bumpalo::Bump) -> Self {
|
||||
hashbrown::HashSet::with_capacity_and_hasher_in(
|
||||
capacity,
|
||||
default_hasher(),
|
||||
hashbrown::BumpWrapper(arena),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arena_join<'a, I>(arena: &'a Bump, strings: &mut I, join_str: &str) -> String<'a>
|
||||
where
|
||||
I: Iterator<Item = &'a str>,
|
||||
|
@ -8,7 +8,7 @@ use roc_builtins::std::StdLib;
|
||||
use roc_can::constraint::Constraint;
|
||||
use roc_can::def::{Declaration, Def};
|
||||
use roc_can::module::{canonicalize_module_defs, Module};
|
||||
use roc_collections::all::{default_hasher, MutMap, MutSet};
|
||||
use roc_collections::all::{default_hasher, BumpMap, BumpMapDefault, BumpSet, MutMap, MutSet};
|
||||
use roc_constrain::module::{
|
||||
constrain_imports, pre_constrain_imports, ConstrainableImports, Import,
|
||||
};
|
||||
@ -355,7 +355,7 @@ struct ModuleCache<'a> {
|
||||
constrained: MutMap<ModuleId, ConstrainedModule>,
|
||||
typechecked: MutMap<ModuleId, TypeCheckedModule<'a>>,
|
||||
found_specializations: MutMap<ModuleId, FoundSpecializationsModule<'a>>,
|
||||
external_specializations_requested: MutMap<ModuleId, ExternalSpecializations>,
|
||||
external_specializations_requested: MutMap<ModuleId, ExternalSpecializations<'a>>,
|
||||
|
||||
/// Various information
|
||||
imports: MutMap<ModuleId, MutSet<ModuleId>>,
|
||||
@ -369,7 +369,12 @@ struct ModuleCache<'a> {
|
||||
header_sources: MutMap<ModuleId, (PathBuf, &'a str)>,
|
||||
}
|
||||
|
||||
fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) -> Vec<BuildTask<'a>> {
|
||||
fn start_phase<'a>(
|
||||
module_id: ModuleId,
|
||||
phase: Phase,
|
||||
arena: &'a Bump,
|
||||
state: &mut State<'a>,
|
||||
) -> Vec<BuildTask<'a>> {
|
||||
// we blindly assume all dependencies are met
|
||||
|
||||
match state
|
||||
@ -391,7 +396,7 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
|
||||
.dependencies
|
||||
.notify(module_id, phase)
|
||||
.into_iter()
|
||||
.map(|(module_id, phase)| start_phase(module_id, phase, state))
|
||||
.map(|(module_id, phase)| start_phase(module_id, phase, arena, state))
|
||||
.flatten()
|
||||
.collect();
|
||||
}
|
||||
@ -545,7 +550,7 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
|
||||
ident_ids,
|
||||
} = typechecked;
|
||||
|
||||
let mut imported_module_thunks = MutSet::default();
|
||||
let mut imported_module_thunks = BumpSet::new_in(arena);
|
||||
|
||||
if let Some(imports) = state.module_cache.imports.get(&module_id) {
|
||||
for imported in imports.iter() {
|
||||
@ -579,7 +584,7 @@ fn start_phase<'a>(module_id: ModuleId, phase: Phase, state: &mut State<'a>) ->
|
||||
.module_cache
|
||||
.external_specializations_requested
|
||||
.remove(&module_id)
|
||||
.unwrap_or_default();
|
||||
.unwrap_or_else(|| ExternalSpecializations::new_in(arena));
|
||||
|
||||
let FoundSpecializationsModule {
|
||||
module_id,
|
||||
@ -769,7 +774,7 @@ enum Msg<'a> {
|
||||
module_id: ModuleId,
|
||||
ident_ids: IdentIds,
|
||||
layout_cache: LayoutCache<'a>,
|
||||
external_specializations_requested: MutMap<ModuleId, ExternalSpecializations>,
|
||||
external_specializations_requested: BumpMap<'a, ModuleId, ExternalSpecializations<'a>>,
|
||||
procedures: MutMap<(Symbol, Layout<'a>), Proc<'a>>,
|
||||
problems: Vec<roc_mono::ir::MonoProblem>,
|
||||
module_timing: ModuleTiming,
|
||||
@ -971,7 +976,7 @@ enum BuildTask<'a> {
|
||||
module_timing: ModuleTiming,
|
||||
layout_cache: LayoutCache<'a>,
|
||||
solved_subs: Solved<Subs>,
|
||||
imported_module_thunks: MutSet<Symbol>,
|
||||
imported_module_thunks: BumpSet<'a, Symbol>,
|
||||
module_id: ModuleId,
|
||||
ident_ids: IdentIds,
|
||||
decls: Vec<Declaration>,
|
||||
@ -983,7 +988,7 @@ enum BuildTask<'a> {
|
||||
subs: Subs,
|
||||
procs: Procs<'a>,
|
||||
layout_cache: LayoutCache<'a>,
|
||||
specializations_we_must_make: ExternalSpecializations,
|
||||
specializations_we_must_make: ExternalSpecializations<'a>,
|
||||
module_timing: ModuleTiming,
|
||||
},
|
||||
}
|
||||
@ -1464,7 +1469,7 @@ where
|
||||
all_pending_specializations: MutMap::default(),
|
||||
specializations_in_flight: 0,
|
||||
layout_caches: std::vec::Vec::with_capacity(num_cpus::get()),
|
||||
procs: Procs::default(),
|
||||
procs: Procs::new_in(arena),
|
||||
};
|
||||
|
||||
// We've now distributed one worker queue to each thread.
|
||||
@ -1603,13 +1608,14 @@ where
|
||||
}
|
||||
|
||||
fn start_tasks<'a>(
|
||||
work: MutSet<(ModuleId, Phase)>,
|
||||
arena: &'a Bump,
|
||||
state: &mut State<'a>,
|
||||
work: MutSet<(ModuleId, Phase)>,
|
||||
injector: &Injector<BuildTask<'a>>,
|
||||
worker_listeners: &'a [Sender<WorkerMsg>],
|
||||
) -> Result<(), LoadingProblem<'a>> {
|
||||
for (module_id, phase) in work {
|
||||
for task in start_phase(module_id, phase, state) {
|
||||
for task in start_phase(module_id, phase, arena, state) {
|
||||
enqueue_task(&injector, worker_listeners, task)?
|
||||
}
|
||||
}
|
||||
@ -1731,11 +1737,11 @@ fn update<'a>(
|
||||
|
||||
state.module_cache.headers.insert(header.module_id, header);
|
||||
|
||||
start_tasks(work, &mut state, &injector, worker_listeners)?;
|
||||
start_tasks(arena, &mut state, work, &injector, worker_listeners)?;
|
||||
|
||||
let work = state.dependencies.notify(home, Phase::LoadHeader);
|
||||
|
||||
start_tasks(work, &mut state, &injector, worker_listeners)?;
|
||||
start_tasks(arena, &mut state, work, &injector, worker_listeners)?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
@ -1768,7 +1774,7 @@ fn update<'a>(
|
||||
|
||||
let work = state.dependencies.notify(module_id, Phase::Parse);
|
||||
|
||||
start_tasks(work, &mut state, &injector, worker_listeners)?;
|
||||
start_tasks(arena, &mut state, work, &injector, worker_listeners)?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
@ -1803,7 +1809,7 @@ fn update<'a>(
|
||||
.dependencies
|
||||
.notify(module_id, Phase::CanonicalizeAndConstrain);
|
||||
|
||||
start_tasks(work, &mut state, &injector, worker_listeners)?;
|
||||
start_tasks(arena, &mut state, work, &injector, worker_listeners)?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
@ -1854,7 +1860,7 @@ fn update<'a>(
|
||||
.notify(module_id, Phase::CanonicalizeAndConstrain),
|
||||
);
|
||||
|
||||
start_tasks(work, &mut state, &injector, worker_listeners)?;
|
||||
start_tasks(arena, &mut state, work, &injector, worker_listeners)?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
@ -1956,7 +1962,7 @@ fn update<'a>(
|
||||
state.constrained_ident_ids.insert(module_id, ident_ids);
|
||||
}
|
||||
|
||||
start_tasks(work, &mut state, &injector, worker_listeners)?;
|
||||
start_tasks(arena, &mut state, work, &injector, worker_listeners)?;
|
||||
}
|
||||
|
||||
Ok(state)
|
||||
@ -2011,7 +2017,7 @@ fn update<'a>(
|
||||
.dependencies
|
||||
.notify(module_id, Phase::FindSpecializations);
|
||||
|
||||
start_tasks(work, &mut state, &injector, worker_listeners)?;
|
||||
start_tasks(arena, &mut state, work, &injector, worker_listeners)?;
|
||||
|
||||
Ok(state)
|
||||
}
|
||||
@ -2057,7 +2063,7 @@ fn update<'a>(
|
||||
.external_specializations_requested
|
||||
.entry(module_id)
|
||||
{
|
||||
Vacant(entry) => entry.insert(ExternalSpecializations::default()),
|
||||
Vacant(entry) => entry.insert(ExternalSpecializations::new_in(arena)),
|
||||
Occupied(entry) => entry.into_mut(),
|
||||
};
|
||||
|
||||
@ -2097,14 +2103,14 @@ fn update<'a>(
|
||||
.external_specializations_requested
|
||||
.entry(module_id)
|
||||
{
|
||||
Vacant(entry) => entry.insert(ExternalSpecializations::default()),
|
||||
Vacant(entry) => entry.insert(ExternalSpecializations::new_in(arena)),
|
||||
Occupied(entry) => entry.into_mut(),
|
||||
};
|
||||
|
||||
existing.extend(requested);
|
||||
}
|
||||
|
||||
start_tasks(work, &mut state, &injector, worker_listeners)?;
|
||||
start_tasks(arena, &mut state, work, &injector, worker_listeners)?;
|
||||
}
|
||||
|
||||
Ok(state)
|
||||
@ -3776,7 +3782,7 @@ fn make_specializations<'a>(
|
||||
mut subs: Subs,
|
||||
mut procs: Procs<'a>,
|
||||
mut layout_cache: LayoutCache<'a>,
|
||||
specializations_we_must_make: ExternalSpecializations,
|
||||
specializations_we_must_make: ExternalSpecializations<'a>,
|
||||
mut module_timing: ModuleTiming,
|
||||
ptr_bytes: u32,
|
||||
) -> Msg<'a> {
|
||||
@ -3825,7 +3831,7 @@ fn make_specializations<'a>(
|
||||
fn build_pending_specializations<'a>(
|
||||
arena: &'a Bump,
|
||||
solved_subs: Solved<Subs>,
|
||||
imported_module_thunks: MutSet<Symbol>,
|
||||
imported_module_thunks: BumpSet<'a, Symbol>,
|
||||
home: ModuleId,
|
||||
mut ident_ids: IdentIds,
|
||||
decls: Vec<Declaration>,
|
||||
@ -3836,7 +3842,7 @@ fn build_pending_specializations<'a>(
|
||||
exposed_to_host: MutMap<Symbol, Variable>,
|
||||
) -> Msg<'a> {
|
||||
let find_specializations_start = SystemTime::now();
|
||||
let mut procs = Procs::default();
|
||||
let mut procs = Procs::new_in(arena);
|
||||
|
||||
debug_assert!(procs.imported_module_thunks.is_empty());
|
||||
procs.imported_module_thunks = imported_module_thunks;
|
||||
|
@ -6,7 +6,7 @@ use crate::layout::{
|
||||
};
|
||||
use bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
use roc_collections::all::{default_hasher, BumpMap, BumpMapDefault, MutMap, MutSet};
|
||||
use roc_collections::all::{default_hasher, BumpMap, BumpMapDefault, BumpSet, MutMap, MutSet};
|
||||
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{IdentIds, ModuleId, Symbol};
|
||||
@ -55,12 +55,6 @@ pub struct PartialProc<'a> {
|
||||
pub is_self_recursive: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Default)]
|
||||
pub struct HostExposedVariables {
|
||||
rigids: MutMap<Lowercase, Variable>,
|
||||
aliases: MutMap<Symbol, Variable>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum CapturedSymbols<'a> {
|
||||
None,
|
||||
@ -243,14 +237,20 @@ impl<'a> Proc<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct ExternalSpecializations {
|
||||
pub specs: MutMap<Symbol, MutSet<SolvedType>>,
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ExternalSpecializations<'a> {
|
||||
pub specs: BumpMap<'a, Symbol, MutSet<SolvedType>>,
|
||||
}
|
||||
|
||||
impl ExternalSpecializations {
|
||||
impl<'a> ExternalSpecializations<'a> {
|
||||
pub fn new_in(arena: &'a Bump) -> Self {
|
||||
Self {
|
||||
specs: BumpMap::new_in(arena),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, symbol: Symbol, typ: SolvedType) {
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use hashbrown::hash_map::Entry::{Occupied, Vacant};
|
||||
|
||||
let existing = match self.specs.entry(symbol) {
|
||||
Vacant(entry) => entry.insert(MutSet::default()),
|
||||
@ -261,7 +261,7 @@ impl ExternalSpecializations {
|
||||
}
|
||||
|
||||
pub fn extend(&mut self, other: Self) {
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use hashbrown::hash_map::Entry::{Occupied, Vacant};
|
||||
|
||||
for (symbol, solved_types) in other.specs {
|
||||
let existing = match self.specs.entry(symbol) {
|
||||
@ -276,30 +276,30 @@ impl ExternalSpecializations {
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Procs<'a> {
|
||||
pub partial_procs: MutMap<Symbol, PartialProc<'a>>,
|
||||
pub imported_module_thunks: MutSet<Symbol>,
|
||||
pub module_thunks: MutSet<Symbol>,
|
||||
pub partial_procs: BumpMap<'a, Symbol, PartialProc<'a>>,
|
||||
pub imported_module_thunks: BumpSet<'a, Symbol>,
|
||||
pub module_thunks: BumpSet<'a, Symbol>,
|
||||
pub pending_specializations:
|
||||
Option<MutMap<Symbol, MutMap<Layout<'a>, PendingSpecialization<'a>>>>,
|
||||
pub specialized: MutMap<(Symbol, Layout<'a>), InProgressProc<'a>>,
|
||||
pub call_by_pointer_wrappers: MutMap<Symbol, Symbol>,
|
||||
pub runtime_errors: MutMap<Symbol, &'a str>,
|
||||
pub externals_others_need: ExternalSpecializations,
|
||||
pub externals_we_need: MutMap<ModuleId, ExternalSpecializations>,
|
||||
Option<BumpMap<'a, Symbol, MutMap<Layout<'a>, PendingSpecialization<'a>>>>,
|
||||
pub specialized: BumpMap<'a, (Symbol, Layout<'a>), InProgressProc<'a>>,
|
||||
pub runtime_errors: BumpMap<'a, Symbol, &'a str>,
|
||||
pub call_by_pointer_wrappers: BumpMap<'a, Symbol, Symbol>,
|
||||
pub externals_others_need: ExternalSpecializations<'a>,
|
||||
pub externals_we_need: BumpMap<'a, ModuleId, ExternalSpecializations<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Default for Procs<'a> {
|
||||
fn default() -> Self {
|
||||
impl<'a> Procs<'a> {
|
||||
pub fn new_in(arena: &'a Bump) -> Self {
|
||||
Self {
|
||||
partial_procs: MutMap::default(),
|
||||
imported_module_thunks: MutSet::default(),
|
||||
module_thunks: MutSet::default(),
|
||||
pending_specializations: Some(MutMap::default()),
|
||||
specialized: MutMap::default(),
|
||||
runtime_errors: MutMap::default(),
|
||||
call_by_pointer_wrappers: MutMap::default(),
|
||||
externals_we_need: MutMap::default(),
|
||||
externals_others_need: ExternalSpecializations::default(),
|
||||
partial_procs: BumpMap::new_in(arena),
|
||||
imported_module_thunks: BumpSet::new_in(arena),
|
||||
module_thunks: BumpSet::new_in(arena),
|
||||
pending_specializations: Some(BumpMap::new_in(arena)),
|
||||
specialized: BumpMap::new_in(arena),
|
||||
runtime_errors: BumpMap::new_in(arena),
|
||||
call_by_pointer_wrappers: BumpMap::new_in(arena),
|
||||
externals_we_need: BumpMap::new_in(arena),
|
||||
externals_others_need: ExternalSpecializations::new_in(arena),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -681,7 +681,11 @@ impl<'a> Procs<'a> {
|
||||
}
|
||||
|
||||
fn add_pending<'a>(
|
||||
pending_specializations: &mut MutMap<Symbol, MutMap<Layout<'a>, PendingSpecialization<'a>>>,
|
||||
pending_specializations: &mut BumpMap<
|
||||
'a,
|
||||
Symbol,
|
||||
MutMap<Layout<'a>, PendingSpecialization<'a>>,
|
||||
>,
|
||||
symbol: Symbol,
|
||||
layout: Layout<'a>,
|
||||
pending: PendingSpecialization<'a>,
|
||||
@ -1688,7 +1692,9 @@ pub fn specialize_all<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
let mut pending_specializations = procs.pending_specializations.unwrap_or_default();
|
||||
let mut pending_specializations = procs
|
||||
.pending_specializations
|
||||
.unwrap_or_else(|| BumpMap::new_in(env.arena));
|
||||
|
||||
// When calling from_can, pending_specializations should be unavailable.
|
||||
// This must be a single pass, and we must not add any more entries to it!
|
||||
@ -5948,10 +5954,10 @@ fn add_needed_external<'a>(
|
||||
name: Symbol,
|
||||
) {
|
||||
// call of a function that is not in this module
|
||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||
use hashbrown::hash_map::Entry::{Occupied, Vacant};
|
||||
|
||||
let existing = match procs.externals_we_need.entry(name.module_id()) {
|
||||
Vacant(entry) => entry.insert(ExternalSpecializations::default()),
|
||||
Vacant(entry) => entry.insert(ExternalSpecializations::new_in(env.arena)),
|
||||
Occupied(entry) => entry.into_mut(),
|
||||
};
|
||||
|
||||
|
@ -84,7 +84,7 @@ mod test_reporting {
|
||||
let arena = Bump::new();
|
||||
|
||||
// Compile and add all the Procs before adding main
|
||||
let mut procs = Procs::default();
|
||||
let mut procs = Procs::new_in(&arena);
|
||||
let mut ident_ids = interns.all_ident_ids.remove(&home).unwrap();
|
||||
|
||||
// Populate Procs and Subs, and get the low-level Expr from the canonical Expr
|
||||
|
Loading…
Reference in New Issue
Block a user