mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Move external specializations storage subs into its own struct
This commit is contained in:
parent
882d589d5f
commit
53e1551cd1
3 changed files with 39 additions and 72 deletions
|
@ -22,6 +22,8 @@ use roc_unify::unify::{Env, Mode, Unified};
|
||||||
pub use roc_solve::ability::Resolved;
|
pub use roc_solve::ability::Resolved;
|
||||||
pub use roc_types::subs::instantiate_rigids;
|
pub use roc_types::subs::instantiate_rigids;
|
||||||
|
|
||||||
|
pub mod storage;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UnificationFailed;
|
pub struct UnificationFailed;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ use roc_derive::SharedDerivedModule;
|
||||||
use roc_error_macros::{internal_error, todo_abilities};
|
use roc_error_macros::{internal_error, todo_abilities};
|
||||||
use roc_exhaustive::{Ctor, CtorName, RenderAs, TagId};
|
use roc_exhaustive::{Ctor, CtorName, RenderAs, TagId};
|
||||||
use roc_intern::Interner;
|
use roc_intern::Interner;
|
||||||
|
use roc_late_solve::storage::{ExternalModuleStorage, ExternalModuleStorageSnapshot};
|
||||||
use roc_late_solve::{resolve_ability_specialization, AbilitiesView, Resolved, UnificationFailed};
|
use roc_late_solve::{resolve_ability_specialization, AbilitiesView, Resolved, UnificationFailed};
|
||||||
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
use roc_module::ident::{ForeignSymbol, Lowercase, TagName};
|
||||||
use roc_module::low_level::LowLevel;
|
use roc_module::low_level::LowLevel;
|
||||||
|
@ -32,8 +33,8 @@ use roc_region::all::{Loc, Region};
|
||||||
use roc_std::RocDec;
|
use roc_std::RocDec;
|
||||||
use roc_target::TargetInfo;
|
use roc_target::TargetInfo;
|
||||||
use roc_types::subs::{
|
use roc_types::subs::{
|
||||||
instantiate_rigids, Content, ExhaustiveMark, FlatType, RedundantMark, StorageSnapshot,
|
instantiate_rigids, Content, ExhaustiveMark, FlatType, RedundantMark, StorageSubs, Subs,
|
||||||
StorageSubs, Subs, Variable, VariableSubsSlice,
|
Variable, VariableSubsSlice,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder};
|
use ven_pretty::{BoxAllocator, DocAllocator, DocBuilder};
|
||||||
|
@ -557,14 +558,15 @@ impl<'a> HostSpecializations<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specializations of this module's symbols that other modules need
|
/// Specializations of this module's symbols that other modules need.
|
||||||
|
/// One struct represents one pair of modules, e.g. what module A wants of module B.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ExternalSpecializations<'a> {
|
pub struct ExternalSpecializations<'a> {
|
||||||
/// Not a bumpalo vec because bumpalo is not thread safe
|
/// Not a bumpalo vec because bumpalo is not thread safe
|
||||||
/// Separate array so we can search for membership quickly
|
/// Separate array so we can search for membership quickly
|
||||||
/// If it's a value and not a lambda, the value is recorded as LambdaName::no_niche.
|
/// If it's a value and not a lambda, the value is recorded as LambdaName::no_niche.
|
||||||
pub symbol_or_lambda: std::vec::Vec<LambdaName<'a>>,
|
pub symbol_or_lambda: std::vec::Vec<LambdaName<'a>>,
|
||||||
storage_subs: StorageSubs,
|
storage: ExternalModuleStorage,
|
||||||
/// For each symbol, what types to specialize it for, points into the storage_subs
|
/// For each symbol, what types to specialize it for, points into the storage_subs
|
||||||
types_to_specialize: std::vec::Vec<std::vec::Vec<Variable>>,
|
types_to_specialize: std::vec::Vec<std::vec::Vec<Variable>>,
|
||||||
}
|
}
|
||||||
|
@ -579,7 +581,7 @@ impl<'a> ExternalSpecializations<'a> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
symbol_or_lambda: std::vec::Vec::new(),
|
symbol_or_lambda: std::vec::Vec::new(),
|
||||||
storage_subs: StorageSubs::new(Subs::default()),
|
storage: ExternalModuleStorage::new(Subs::default()),
|
||||||
types_to_specialize: std::vec::Vec::new(),
|
types_to_specialize: std::vec::Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -590,7 +592,7 @@ impl<'a> ExternalSpecializations<'a> {
|
||||||
env_subs: &mut Subs,
|
env_subs: &mut Subs,
|
||||||
variable: Variable,
|
variable: Variable,
|
||||||
) {
|
) {
|
||||||
let stored_variable = self.storage_subs.extend_with_variable(env_subs, variable);
|
let stored_variable = self.storage.extend_with_variable(env_subs, variable);
|
||||||
roc_tracing::debug!(original = ?variable, stored = ?stored_variable, "stored needed external");
|
roc_tracing::debug!(original = ?variable, stored = ?stored_variable, "stored needed external");
|
||||||
|
|
||||||
match self
|
match self
|
||||||
|
@ -616,27 +618,27 @@ impl<'a> ExternalSpecializations<'a> {
|
||||||
impl Iterator<Item = (LambdaName<'a>, std::vec::Vec<Variable>)>,
|
impl Iterator<Item = (LambdaName<'a>, std::vec::Vec<Variable>)>,
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
self.storage_subs,
|
self.storage.into_storage_subs(),
|
||||||
self.symbol_or_lambda
|
self.symbol_or_lambda
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(self.types_to_specialize.into_iter()),
|
.zip(self.types_to_specialize.into_iter()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot_cache(&mut self) -> StorageSnapshot {
|
fn snapshot_cache(&mut self) -> ExternalModuleStorageSnapshot {
|
||||||
self.storage_subs.snapshot_cache()
|
self.storage.snapshot_cache()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rollback_cache(&mut self, snapshot: StorageSnapshot) {
|
fn rollback_cache(&mut self, snapshot: ExternalModuleStorageSnapshot) {
|
||||||
self.storage_subs.rollback_cache(snapshot)
|
self.storage.rollback_cache(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invalidate_cache(&mut self, changed_variables: &[Variable]) {
|
fn invalidate_cache(&mut self, changed_variables: &[Variable]) {
|
||||||
self.storage_subs.invalidate_cache(changed_variables)
|
self.storage.invalidate_cache(changed_variables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invalidate_whole_cache(&mut self) {
|
fn invalidate_whole_cache(&mut self) {
|
||||||
self.storage_subs.invalidate_whole_cache()
|
self.storage.invalidate_whole_cache()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +686,7 @@ impl<'a> Suspended<'a> {
|
||||||
self.symbol_or_lambdas.push(symbol_or_lambda);
|
self.symbol_or_lambdas.push(symbol_or_lambda);
|
||||||
self.layouts.push(proc_layout);
|
self.layouts.push(proc_layout);
|
||||||
|
|
||||||
let variable = self.store.extend_with_variable(subs, variable);
|
let variable = self.store.import_variable_from(subs, variable).variable;
|
||||||
|
|
||||||
self.variables.push(variable);
|
self.variables.push(variable);
|
||||||
}
|
}
|
||||||
|
@ -3114,7 +3116,7 @@ fn generate_runtime_error_function<'a>(
|
||||||
struct TypeStateSnapshot {
|
struct TypeStateSnapshot {
|
||||||
subs_snapshot: roc_types::subs::SubsSnapshot,
|
subs_snapshot: roc_types::subs::SubsSnapshot,
|
||||||
layout_snapshot: crate::layout::CacheSnapshot,
|
layout_snapshot: crate::layout::CacheSnapshot,
|
||||||
external_storage_snapshot: VecMap<ModuleId, StorageSnapshot>,
|
external_storage_snapshot: VecMap<ModuleId, ExternalModuleStorageSnapshot>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Takes a snapshot of the type state. Snapshots should be taken before new specializations, and
|
/// Takes a snapshot of the type state. Snapshots should be taken before new specializations, and
|
||||||
|
|
|
@ -3996,32 +3996,9 @@ pub struct ExposedTypesStorageSubs {
|
||||||
pub stored_ability_member_vars: VecMap<Variable, Variable>,
|
pub stored_ability_member_vars: VecMap<Variable, Variable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
struct VariableMapCache(Vec<FnvMap<Variable, Variable>>);
|
|
||||||
|
|
||||||
impl VariableMapCache {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self(vec![Default::default()])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get(&self, v: &Variable) -> Option<&Variable> {
|
|
||||||
self.0.iter().rev().find_map(|cache| cache.get(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn insert(&mut self, key: Variable, value: Variable) -> Option<Variable> {
|
|
||||||
self.0.last_mut().unwrap().insert(key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct StorageSubs {
|
pub struct StorageSubs {
|
||||||
subs: Subs,
|
subs: Subs,
|
||||||
/// Variable they expose -> variable we record into storage
|
|
||||||
variable_mapping_cache: VariableMapCache,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct StorageSnapshot {
|
|
||||||
mapping_cache_len: usize,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
@ -4037,12 +4014,26 @@ struct StorageSubsOffsets {
|
||||||
problems: u32,
|
problems: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct VariableMapCache(pub Vec<FnvMap<Variable, Variable>>);
|
||||||
|
|
||||||
|
impl VariableMapCache {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self(vec![Default::default()])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get(&self, v: &Variable) -> Option<&Variable> {
|
||||||
|
self.0.iter().rev().find_map(|cache| cache.get(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert(&mut self, key: Variable, value: Variable) -> Option<Variable> {
|
||||||
|
self.0.last_mut().unwrap().insert(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl StorageSubs {
|
impl StorageSubs {
|
||||||
pub fn new(subs: Subs) -> Self {
|
pub fn new(subs: Subs) -> Self {
|
||||||
Self {
|
Self { subs }
|
||||||
subs,
|
|
||||||
variable_mapping_cache: VariableMapCache::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fresh_unnamed_flex_var(&mut self) -> Variable {
|
pub fn fresh_unnamed_flex_var(&mut self) -> Variable {
|
||||||
|
@ -4059,41 +4050,13 @@ impl StorageSubs {
|
||||||
|
|
||||||
pub fn extend_with_variable(&mut self, source: &Subs, variable: Variable) -> Variable {
|
pub fn extend_with_variable(&mut self, source: &Subs, variable: Variable) -> Variable {
|
||||||
storage_copy_var_to(
|
storage_copy_var_to(
|
||||||
&mut self.variable_mapping_cache,
|
&mut VariableMapCache::new(),
|
||||||
source,
|
source,
|
||||||
&mut self.subs,
|
&mut self.subs,
|
||||||
variable,
|
variable,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalidate_cache(&mut self, changed_variables: &[Variable]) {
|
|
||||||
for var in changed_variables {
|
|
||||||
for cache in self.variable_mapping_cache.0.iter_mut().rev() {
|
|
||||||
cache.remove(var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn invalidate_whole_cache(&mut self) {
|
|
||||||
debug_assert_eq!(self.variable_mapping_cache.0.len(), 1);
|
|
||||||
self.variable_mapping_cache.0.last_mut().unwrap().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn snapshot_cache(&mut self) -> StorageSnapshot {
|
|
||||||
self.variable_mapping_cache.0.push(Default::default());
|
|
||||||
StorageSnapshot {
|
|
||||||
mapping_cache_len: self.variable_mapping_cache.0.len(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rollback_cache(&mut self, snapshot: StorageSnapshot) {
|
|
||||||
debug_assert_eq!(
|
|
||||||
self.variable_mapping_cache.0.len(),
|
|
||||||
snapshot.mapping_cache_len
|
|
||||||
);
|
|
||||||
self.variable_mapping_cache.0.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn import_variable_from(&mut self, source: &Subs, variable: Variable) -> CopiedImport {
|
pub fn import_variable_from(&mut self, source: &Subs, variable: Variable) -> CopiedImport {
|
||||||
copy_import_to(source, &mut self.subs, false, variable, Rank::import())
|
copy_import_to(source, &mut self.subs, false, variable, Rank::import())
|
||||||
}
|
}
|
||||||
|
@ -4384,7 +4347,7 @@ fn put_scratchpad(scratchpad: bumpalo::Bump) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn storage_copy_var_to(
|
pub fn storage_copy_var_to(
|
||||||
copy_table: &mut VariableMapCache,
|
copy_table: &mut VariableMapCache,
|
||||||
source: &Subs,
|
source: &Subs,
|
||||||
target: &mut Subs,
|
target: &mut Subs,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue