diff --git a/Cargo.lock b/Cargo.lock index aca639d79a..a373df043a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2076,6 +2076,16 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "memmap" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6585fd95e7bb50d6cc31e20d4cf9afb4e2ba16c5846fc76793f11218da9c475b" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "memmap2" version = "0.1.0" @@ -3677,6 +3687,7 @@ dependencies = [ "crossbeam", "indoc", "maplit", + "memmap", "morphic_lib", "num_cpus", "parking_lot", diff --git a/compiler/load/Cargo.toml b/compiler/load/Cargo.toml index 3945650771..afb62d8b77 100644 --- a/compiler/load/Cargo.toml +++ b/compiler/load/Cargo.toml @@ -27,6 +27,7 @@ bumpalo = { version = "3.8.0", features = ["collections"] } parking_lot = "0.11.2" crossbeam = "0.8.1" num_cpus = "1.13.0" +memmap = "0.7.0" [dev-dependencies] tempfile = "3.2.0" diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 76586c333c..5eeb735622 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -4475,29 +4475,67 @@ fn run_solve<'a>( solve_aliases.insert(*name, alias.clone()); } - let (solved_subs, solved_env, problems) = roc_solve::module::run_solve( - &constraints, - actual_constraint, - rigid_variables, - subs, - solve_aliases, - ); + let (solved_subs, exposed_vars_by_symbol, problems) = if module_id.is_builtin() { + use memmap::MmapOptions; + use std::fs::File; - let solved_subs = if true { - solved_subs + // let file = File::open(&format!("cached_subs/{:?}.dat", module_id)).unwrap(); + // let mmap = unsafe { MmapOptions::new().map(&file).unwrap() }; + + let mmap = std::fs::read(&format!("cached_subs/{:?}.dat", module_id)).unwrap(); + println!("started {:?}", module_id); + let (subs, vars_by_symbol) = Subs::deserialize(&mmap); + println!("deserialized"); + let solved_subs = Solved(subs); + + let exposed_vars_by_symbol: Vec<_> = vars_by_symbol + .into_iter() + .filter(|(k, _)| exposed_symbols.contains(k)) + .collect(); + + (solved_subs, exposed_vars_by_symbol, vec![]) } else { - let mut serialized = Vec::new(); - solved_subs.inner().serialize(&mut serialized).unwrap(); - let subs = Subs::deserialize(&serialized); + let (solved_subs, solved_env, problems) = roc_solve::module::run_solve( + &constraints, + actual_constraint, + rigid_variables, + subs, + solve_aliases, + ); - Solved(subs) + if module_id.is_builtin() { + let mut f = std::fs::File::create(&format!("cached_subs/{:?}.dat", module_id)).unwrap(); + let vars_by_symbol: Vec<(Symbol, Variable)> = solved_env.vars_by_symbol().collect(); + solved_subs + .inner() + .serialize(&vars_by_symbol, &mut f) + .unwrap(); + } + + let solved_subs = if true { + solved_subs + } else { + let vars_by_symbol: Vec<(Symbol, Variable)> = solved_env.vars_by_symbol().collect(); + let mut serialized = Vec::new(); + solved_subs + .inner() + .serialize(&vars_by_symbol, &mut serialized) + .unwrap(); + let (subs, vbs) = Subs::deserialize(&serialized); + + dbg!(vbs); + + Solved(subs) + }; + + let exposed_vars_by_symbol: Vec<_> = solved_env + .vars_by_symbol() + .filter(|(k, _)| exposed_symbols.contains(k)) + .collect(); + + (solved_subs, exposed_vars_by_symbol, problems) }; - let exposed_vars_by_symbol: Vec<_> = solved_env - .vars_by_symbol() - .filter(|(k, _)| exposed_symbols.contains(k)) - .collect(); - let mut solved_subs = solved_subs; let (storage_subs, stored_vars_by_symbol) = roc_solve::module::exposed_types_storage_subs(&mut solved_subs, &exposed_vars_by_symbol); diff --git a/compiler/types/src/subs.rs b/compiler/types/src/subs.rs index ff77bc0683..e9e4aac075 100644 --- a/compiler/types/src/subs.rs +++ b/compiler/types/src/subs.rs @@ -69,10 +69,11 @@ struct SubsHeader { field_names: usize, record_fields: usize, variable_slices: usize, + vars_by_symbol: usize, } impl SubsHeader { - fn from_subs(subs: &Subs) -> Self { + fn from_subs(subs: &Subs, vars_by_symbol: usize) -> Self { // TODO what do we do with problems? they should // be reported and then removed from Subs I think debug_assert!(subs.problems.is_empty()); @@ -84,6 +85,7 @@ impl SubsHeader { field_names: subs.field_names.len(), record_fields: subs.record_fields.len(), variable_slices: subs.variable_slices.len(), + vars_by_symbol, } } @@ -108,10 +110,14 @@ fn round_to_multiple_of(value: usize, base: usize) -> usize { } impl Subs { - pub fn serialize(&self, writer: &mut impl std::io::Write) -> std::io::Result { + pub fn serialize( + &self, + vars_by_symbol: &[(Symbol, Variable)], + writer: &mut impl std::io::Write, + ) -> std::io::Result { let mut written = 0; - let header = SubsHeader::from_subs(self).to_array(); + let header = SubsHeader::from_subs(self, vars_by_symbol.len()).to_array(); written += header.len(); writer.write_all(&header)?; @@ -122,6 +128,7 @@ impl Subs { written = Self::serialize_field_names(&self.field_names, writer, written)?; written = Self::serialize_slice(&self.record_fields, writer, written)?; written = Self::serialize_slice(&self.variable_slices, writer, written)?; + written = Self::serialize_slice(vars_by_symbol, writer, written)?; Ok(written) } @@ -195,7 +202,7 @@ impl Subs { Ok(written + padding_bytes + bytes_slice.len()) } - pub fn deserialize(bytes: &[u8]) -> Self { + pub fn deserialize(bytes: &[u8]) -> (Self, Vec<(Symbol, Variable)>) { use std::convert::TryInto; let mut offset = 0; @@ -205,14 +212,21 @@ impl Subs { let (utable, offset) = Self::deserialize_unification_table(bytes, header.utable, offset); + println!("utable"); + let (variables, offset) = Self::deserialize_slice(bytes, header.variables, offset); let (tag_names, offset) = Self::deserialize_slice(bytes, header.tag_names, offset); let (field_names, offset) = Self::deserialize_field_names(bytes, header.field_names, offset); + println!("field names"); let (record_fields, offset) = Self::deserialize_slice(bytes, header.record_fields, offset); - let (variable_slices, _) = Self::deserialize_slice(bytes, header.variable_slices, offset); + let (variable_slices, offset) = + Self::deserialize_slice(bytes, header.variable_slices, offset); + let (vars_by_symbol, _) = Self::deserialize_slice(bytes, header.vars_by_symbol, offset); + println!("all"); + let x = vars_by_symbol.to_vec(); - Self { + let subs = Self { utable, variables: variables.to_vec(), tag_names: tag_names.to_vec(), @@ -221,7 +235,10 @@ impl Subs { variable_slices: variable_slices.to_vec(), tag_name_cache: Default::default(), problems: Default::default(), - } + }; + println!("to_vec"); + + (subs, x) } fn deserialize_unification_table(