mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 08:11:12 +00:00
pick the single-threaded load when target-family=wasm
This commit is contained in:
parent
180be06772
commit
45217b8074
4 changed files with 91 additions and 128 deletions
23
cli_utils/Cargo.lock
generated
23
cli_utils/Cargo.lock
generated
|
@ -2771,6 +2771,7 @@ dependencies = [
|
|||
"roc_types",
|
||||
"roc_unify",
|
||||
"ven_pretty",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2879,6 +2880,7 @@ dependencies = [
|
|||
"roc_reporting",
|
||||
"roc_target",
|
||||
"roc_types",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2911,6 +2913,7 @@ dependencies = [
|
|||
"roc_region",
|
||||
"roc_types",
|
||||
"roc_unify",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3558,9 +3561,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
|
||||
checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
|
@ -3568,9 +3571,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
|
||||
checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
|
@ -3595,9 +3598,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
|
||||
checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
@ -3605,9 +3608,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
|
||||
checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -3618,9 +3621,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.78"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
|
||||
checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2"
|
||||
|
||||
[[package]]
|
||||
name = "wayland-client"
|
||||
|
|
|
@ -45,19 +45,6 @@ use std::path::{Path, PathBuf};
|
|||
use std::str::from_utf8_unchecked;
|
||||
use std::sync::Arc;
|
||||
use std::{env, fs};
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn log(s: &str);
|
||||
}
|
||||
|
||||
// In-browser debugging
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! console_log {
|
||||
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
|
||||
}
|
||||
|
||||
use crate::work::{Dependencies, Phase};
|
||||
|
||||
|
@ -611,6 +598,43 @@ struct State<'a> {
|
|||
pub layout_caches: std::vec::Vec<LayoutCache<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> State<'a> {
|
||||
fn new(
|
||||
root_id: ModuleId,
|
||||
target_info: TargetInfo,
|
||||
goal_phase: Phase,
|
||||
stdlib: &'a StdLib,
|
||||
exposed_types: SubsByModule,
|
||||
arc_modules: Arc<Mutex<PackageModuleIds<'a>>>,
|
||||
ident_ids_by_module: Arc<Mutex<MutMap<ModuleId, IdentIds>>>,
|
||||
) -> Self {
|
||||
let arc_shorthands = Arc::new(Mutex::new(MutMap::default()));
|
||||
|
||||
Self {
|
||||
root_id,
|
||||
target_info,
|
||||
platform_data: None,
|
||||
goal_phase,
|
||||
stdlib,
|
||||
output_path: None,
|
||||
platform_path: PlatformPath::NotSpecified,
|
||||
module_cache: ModuleCache::default(),
|
||||
dependencies: Dependencies::default(),
|
||||
procedures: MutMap::default(),
|
||||
exposed_to_host: ExposedToHost::default(),
|
||||
exposed_types,
|
||||
arc_modules,
|
||||
arc_shorthands,
|
||||
constrained_ident_ids: IdentIds::exposed_builtins(0),
|
||||
ident_ids_by_module,
|
||||
declarations_by_id: MutMap::default(),
|
||||
exposed_symbols_by_module: MutMap::default(),
|
||||
timings: MutMap::default(),
|
||||
layout_caches: std::vec::Vec::with_capacity(num_cpus::get()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ModuleTiming {
|
||||
pub read_roc_file: Duration,
|
||||
|
@ -845,8 +869,6 @@ pub fn load_and_monomorphize_from_str<'a>(
|
|||
) -> Result<MonomorphizedModule<'a>, LoadingProblem<'a>> {
|
||||
use LoadResult::*;
|
||||
|
||||
console_log!("load_and_monomorphize_from_str");
|
||||
|
||||
let load_start = LoadStart::from_str(arena, filename, src)?;
|
||||
|
||||
match load(
|
||||
|
@ -1005,7 +1027,6 @@ enum LoadResult<'a> {
|
|||
#[allow(clippy::too_many_arguments)]
|
||||
fn load<'a>(
|
||||
arena: &'a Bump,
|
||||
//filename: PathBuf,
|
||||
load_start: LoadStart<'a>,
|
||||
stdlib: &'a StdLib,
|
||||
src_dir: &Path,
|
||||
|
@ -1013,8 +1034,42 @@ fn load<'a>(
|
|||
goal_phase: Phase,
|
||||
target_info: TargetInfo,
|
||||
) -> Result<LoadResult<'a>, LoadingProblem<'a>> {
|
||||
console_log!("load start");
|
||||
// When compiling to wasm, we cannot spawn extra threads
|
||||
// so we have a single-threaded implementation
|
||||
if cfg!(target_family = "wasm") {
|
||||
load_single_threaded(
|
||||
arena,
|
||||
load_start,
|
||||
stdlib,
|
||||
src_dir,
|
||||
exposed_types,
|
||||
goal_phase,
|
||||
target_info,
|
||||
)
|
||||
} else {
|
||||
load_multi_threaded(
|
||||
arena,
|
||||
load_start,
|
||||
stdlib,
|
||||
src_dir,
|
||||
exposed_types,
|
||||
goal_phase,
|
||||
target_info,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Load using only a single thread; used when compiling to webassembly
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn load_single_threaded<'a>(
|
||||
arena: &'a Bump,
|
||||
load_start: LoadStart<'a>,
|
||||
stdlib: &'a StdLib,
|
||||
src_dir: &Path,
|
||||
exposed_types: SubsByModule,
|
||||
goal_phase: Phase,
|
||||
target_info: TargetInfo,
|
||||
) -> Result<LoadResult<'a>, LoadingProblem<'a>> {
|
||||
let LoadStart {
|
||||
arc_modules,
|
||||
ident_ids_by_module,
|
||||
|
@ -1022,59 +1077,34 @@ fn load<'a>(
|
|||
root_msg,
|
||||
} = load_start;
|
||||
|
||||
let arc_shorthands = Arc::new(Mutex::new(MutMap::default()));
|
||||
|
||||
let (msg_tx, msg_rx) = bounded(1024);
|
||||
|
||||
console_log!("before msg_tx.send");
|
||||
|
||||
msg_tx
|
||||
.send(root_msg)
|
||||
.map_err(|_| LoadingProblem::MsgChannelDied)?;
|
||||
|
||||
console_log!("after msg_tx.send");
|
||||
|
||||
let mut state = State {
|
||||
let mut state = State::new(
|
||||
root_id,
|
||||
target_info,
|
||||
platform_data: None,
|
||||
goal_phase,
|
||||
stdlib,
|
||||
output_path: None,
|
||||
platform_path: PlatformPath::NotSpecified,
|
||||
module_cache: ModuleCache::default(),
|
||||
dependencies: Dependencies::default(),
|
||||
procedures: MutMap::default(),
|
||||
exposed_to_host: ExposedToHost::default(),
|
||||
exposed_types,
|
||||
arc_modules,
|
||||
arc_shorthands,
|
||||
constrained_ident_ids: IdentIds::exposed_builtins(0),
|
||||
ident_ids_by_module,
|
||||
declarations_by_id: MutMap::default(),
|
||||
exposed_symbols_by_module: MutMap::default(),
|
||||
timings: MutMap::default(),
|
||||
layout_caches: std::vec::Vec::with_capacity(num_cpus::get()),
|
||||
};
|
||||
);
|
||||
|
||||
// We'll add tasks to this, and then worker threads will take tasks from it.
|
||||
let injector = Injector::new();
|
||||
|
||||
console_log!("after injector");
|
||||
|
||||
let (worker_msg_tx, worker_msg_rx) = bounded(1024);
|
||||
let worker_listener = worker_msg_tx;
|
||||
let worker_listeners = arena.alloc([worker_listener]);
|
||||
|
||||
console_log!("before Worker lifo");
|
||||
|
||||
let worker = Worker::new_lifo();
|
||||
let stealer = worker.stealer();
|
||||
let stealers = &[stealer];
|
||||
|
||||
console_log!("before loop");
|
||||
loop {
|
||||
console_log!("inside loop");
|
||||
match state_thread_step(arena, state, worker_listeners, &injector, &msg_tx, &msg_rx) {
|
||||
Ok(ControlFlow::Break(done)) => return Ok(done),
|
||||
Ok(ControlFlow::Continue(new_state)) => {
|
||||
|
@ -1082,7 +1112,6 @@ fn load<'a>(
|
|||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
console_log!("after match");
|
||||
|
||||
let control_flow = worker_task_step(
|
||||
arena,
|
||||
|
@ -1095,8 +1124,6 @@ fn load<'a>(
|
|||
target_info,
|
||||
);
|
||||
|
||||
console_log!("control flow {:?}", control_flow);
|
||||
|
||||
match control_flow {
|
||||
Ok(ControlFlow::Break(())) => panic!("the worker should not break!"),
|
||||
Ok(ControlFlow::Continue(())) => {
|
||||
|
@ -1193,7 +1220,7 @@ fn state_thread_step<'a>(
|
|||
to_parse_problem_report(problem, module_ids, constrained_ident_ids);
|
||||
return Err(LoadingProblem::FormattedReport(buf));
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1206,9 +1233,8 @@ fn state_thread_step<'a>(
|
|||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn load_multithreaded<'a>(
|
||||
fn load_multi_threaded<'a>(
|
||||
arena: &'a Bump,
|
||||
//filename: PathBuf,
|
||||
load_start: LoadStart<'a>,
|
||||
stdlib: &'a StdLib,
|
||||
src_dir: &Path,
|
||||
|
@ -1223,8 +1249,6 @@ fn load_multithreaded<'a>(
|
|||
root_msg,
|
||||
} = load_start;
|
||||
|
||||
let arc_shorthands = Arc::new(Mutex::new(MutMap::default()));
|
||||
|
||||
let (msg_tx, msg_rx) = bounded(1024);
|
||||
msg_tx
|
||||
.send(root_msg)
|
||||
|
@ -1317,28 +1341,15 @@ fn load_multithreaded<'a>(
|
|||
res_join_handle.unwrap();
|
||||
}
|
||||
|
||||
let mut state = State {
|
||||
let mut state = State::new(
|
||||
root_id,
|
||||
target_info,
|
||||
platform_data: None,
|
||||
goal_phase,
|
||||
stdlib,
|
||||
output_path: None,
|
||||
platform_path: PlatformPath::NotSpecified,
|
||||
module_cache: ModuleCache::default(),
|
||||
dependencies: Dependencies::default(),
|
||||
procedures: MutMap::default(),
|
||||
exposed_to_host: ExposedToHost::default(),
|
||||
exposed_types,
|
||||
arc_modules,
|
||||
arc_shorthands,
|
||||
constrained_ident_ids: IdentIds::exposed_builtins(0),
|
||||
ident_ids_by_module,
|
||||
declarations_by_id: MutMap::default(),
|
||||
exposed_symbols_by_module: MutMap::default(),
|
||||
timings: MutMap::default(),
|
||||
layout_caches: std::vec::Vec::with_capacity(num_cpus::get()),
|
||||
};
|
||||
);
|
||||
|
||||
// We've now distributed one worker queue to each thread.
|
||||
// There should be no queues left to distribute!
|
||||
|
@ -1486,9 +1497,7 @@ fn worker_task_step<'a>(
|
|||
src_dir: &Path,
|
||||
target_info: TargetInfo,
|
||||
) -> Result<ControlFlow<(), ()>, LoadingProblem<'a>> {
|
||||
console_log!("worker_task_step");
|
||||
let recv = worker_msg_rx.try_recv();
|
||||
console_log!("recv {:?}", &recv);
|
||||
match recv {
|
||||
Ok(msg) => {
|
||||
match msg {
|
||||
|
@ -1510,10 +1519,8 @@ fn worker_task_step<'a>(
|
|||
// added. In that case, do nothing, and keep waiting
|
||||
// until we receive a Shutdown message.
|
||||
if let Some(task) = find_task(&worker, injector, stealers) {
|
||||
console_log!("found Some task {:?}", task);
|
||||
let result =
|
||||
run_task(task, worker_arena, src_dir, msg_tx.clone(), target_info);
|
||||
console_log!("run_task result {:?}", &result);
|
||||
|
||||
match result {
|
||||
Ok(()) => {}
|
||||
|
@ -1533,7 +1540,6 @@ fn worker_task_step<'a>(
|
|||
}
|
||||
}
|
||||
}
|
||||
console_log!("after if let Some(task)");
|
||||
|
||||
Ok(ControlFlow::Continue(()))
|
||||
}
|
||||
|
@ -3168,15 +3174,12 @@ fn run_solve<'a>(
|
|||
dep_idents: MutMap<ModuleId, IdentIds>,
|
||||
unused_imports: MutMap<ModuleId, Region>,
|
||||
) -> Msg<'a> {
|
||||
|
||||
console_log!("run_solve");
|
||||
// We have more constraining work to do now, so we'll add it to our timings.
|
||||
let constrain_start = SystemTime::now();
|
||||
|
||||
// Finish constraining the module by wrapping the existing Constraint
|
||||
// in the ones we just computed. We can do this off the main thread.
|
||||
let constraint = constrain_imports(imported_symbols, constraint, &mut var_store);
|
||||
console_log!("after constrain_imports");
|
||||
|
||||
let constrain_end = SystemTime::now();
|
||||
|
||||
|
@ -3196,16 +3199,12 @@ fn run_solve<'a>(
|
|||
let (solved_subs, solved_env, problems) =
|
||||
roc_solve::module::run_solve(aliases, rigid_variables, constraint, var_store);
|
||||
|
||||
console_log!("after run_solve");
|
||||
|
||||
let mut exposed_vars_by_symbol: MutMap<Symbol, Variable> = solved_env.vars_by_symbol.clone();
|
||||
exposed_vars_by_symbol.retain(|k, _| exposed_symbols.contains(k));
|
||||
|
||||
let solved_types =
|
||||
roc_solve::module::make_solved_types(&solved_env, &solved_subs, &exposed_vars_by_symbol);
|
||||
|
||||
console_log!("after make_solved_types");
|
||||
|
||||
let solved_module = SolvedModule {
|
||||
exposed_vars_by_symbol,
|
||||
exposed_symbols: exposed_symbols.into_iter().collect::<Vec<_>>(),
|
||||
|
@ -3221,8 +3220,6 @@ fn run_solve<'a>(
|
|||
module_timing.constrain += constrain_elapsed;
|
||||
module_timing.solve = solve_end.duration_since(constrain_end).unwrap();
|
||||
|
||||
console_log!("creating Msg::SolvedTypes");
|
||||
|
||||
// Send the subs to the main thread for processing,
|
||||
Msg::SolvedTypes {
|
||||
module_id,
|
||||
|
|
|
@ -7,20 +7,6 @@ use roc_types::solved_types::{Solved, SolvedType};
|
|||
use roc_types::subs::{Subs, VarStore, Variable};
|
||||
use roc_types::types::Alias;
|
||||
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn log(s: &str);
|
||||
}
|
||||
|
||||
// In-browser debugging
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! console_log {
|
||||
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SolvedModule {
|
||||
pub solved_types: MutMap<Symbol, SolvedType>,
|
||||
|
@ -36,20 +22,16 @@ pub fn run_solve(
|
|||
constraint: Constraint,
|
||||
var_store: VarStore,
|
||||
) -> (Solved<Subs>, solve::Env, Vec<solve::TypeError>) {
|
||||
console_log!("run_solve");
|
||||
|
||||
let env = solve::Env {
|
||||
vars_by_symbol: MutMap::default(),
|
||||
aliases,
|
||||
};
|
||||
|
||||
let mut subs = Subs::new_from_varstore(var_store);
|
||||
console_log!("after new_from_varstore");
|
||||
|
||||
for (var, name) in rigid_variables {
|
||||
subs.rigid_var(var, name);
|
||||
}
|
||||
console_log!("after rigid_var");
|
||||
|
||||
// Now that the module is parsed, canonicalized, and constrained,
|
||||
// we need to type check it.
|
||||
|
@ -57,7 +39,6 @@ pub fn run_solve(
|
|||
|
||||
// Run the solver to populate Subs.
|
||||
let (solved_subs, solved_env) = solve::run(&env, &mut problems, subs, &constraint);
|
||||
console_log!("after solve::run");
|
||||
|
||||
(solved_subs, solved_env, problems)
|
||||
}
|
||||
|
|
|
@ -15,22 +15,6 @@ use roc_types::types::{gather_fields_unsorted_iter, Alias, Category, ErrorType,
|
|||
use roc_unify::unify::{unify, Mode, Unified::*};
|
||||
use std::collections::hash_map::Entry;
|
||||
|
||||
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn log(s: &str);
|
||||
}
|
||||
|
||||
// In-browser debugging
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! console_log {
|
||||
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
|
||||
}
|
||||
|
||||
|
||||
// Type checking system adapted from Elm by Evan Czaplicki, BSD-3-Clause Licensed
|
||||
// https://github.com/elm/compiler
|
||||
// Thank you, Evan!
|
||||
|
@ -171,7 +155,6 @@ pub fn run_in_place(
|
|||
subs: &mut Subs,
|
||||
constraint: &Constraint,
|
||||
) -> Env {
|
||||
console_log!("run_in_place");
|
||||
let mut pools = Pools::default();
|
||||
let state = State {
|
||||
env: env.clone(),
|
||||
|
@ -203,7 +186,6 @@ fn solve(
|
|||
subs: &mut Subs,
|
||||
constraint: &Constraint,
|
||||
) -> State {
|
||||
console_log!("solve constraint {:?}", constraint);
|
||||
match constraint {
|
||||
True => state,
|
||||
SaveTheEnvironment => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue