mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 21:39:07 +00:00
Add LayoutInterner to LayoutCache
Adds a thread-local interner of layouts to LayoutCache, and updates all references appropriately. This is a bit suboptimal for single-threaded workloads that will look at creating layout caches again, like the REPL, but I think that's okay for now - since the global interner will be uncontested for those workloads, it should still be plenty fast to access the interner, even behind a lock.
This commit is contained in:
parent
9d170be5c7
commit
c5466810a4
19 changed files with 177 additions and 86 deletions
|
@ -10,8 +10,8 @@ use roc_module::ident::TagName;
|
|||
use roc_module::symbol::{Interns, ModuleId, Symbol};
|
||||
use roc_mono::ir::ProcLayout;
|
||||
use roc_mono::layout::{
|
||||
self, union_sorted_tags_pub, Builtin, Layout, LayoutCache, UnionLayout, UnionVariant,
|
||||
WrappedVariant,
|
||||
self, union_sorted_tags_pub, Builtin, Layout, LayoutCache, LayoutInterner, UnionLayout,
|
||||
UnionVariant, WrappedVariant,
|
||||
};
|
||||
use roc_parse::ast::{AssignedField, Collection, Expr, StrLiteral};
|
||||
use roc_region::all::{Loc, Region};
|
||||
|
@ -26,6 +26,7 @@ struct Env<'a, 'env> {
|
|||
subs: &'env Subs,
|
||||
target_info: TargetInfo,
|
||||
interns: &'a Interns,
|
||||
layout_cache: LayoutCache<'a>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -50,13 +51,15 @@ pub fn jit_to_ast<'a, A: ReplApp<'a>>(
|
|||
content: &Content,
|
||||
subs: &Subs,
|
||||
interns: &'a Interns,
|
||||
layout_interner: LayoutInterner<'a>,
|
||||
target_info: TargetInfo,
|
||||
) -> Result<Expr<'a>, ToAstProblem> {
|
||||
let env = Env {
|
||||
let mut env = Env {
|
||||
arena,
|
||||
subs,
|
||||
target_info,
|
||||
interns,
|
||||
layout_cache: LayoutCache::new(layout_interner, target_info),
|
||||
};
|
||||
|
||||
match layout {
|
||||
|
@ -66,7 +69,7 @@ pub fn jit_to_ast<'a, A: ReplApp<'a>>(
|
|||
captures_niche: _,
|
||||
} => {
|
||||
// this is a thunk
|
||||
jit_to_ast_help(&env, app, main_fn_name, &result, content)
|
||||
jit_to_ast_help(&mut env, app, main_fn_name, &result, content)
|
||||
}
|
||||
_ => Err(ToAstProblem::FunctionLayout),
|
||||
}
|
||||
|
@ -186,7 +189,7 @@ fn unroll_recursion_var<'env>(env: &Env<'_, 'env>, mut content: &'env Content) -
|
|||
}
|
||||
|
||||
fn get_tags_vars_and_variant<'a>(
|
||||
env: &Env<'a, '_>,
|
||||
env: &mut Env<'a, '_>,
|
||||
tags: &UnionTags,
|
||||
opt_rec_var: Option<Variable>,
|
||||
) -> (MutMap<TagName, std::vec::Vec<Variable>>, UnionVariant<'a>) {
|
||||
|
@ -198,9 +201,12 @@ fn get_tags_vars_and_variant<'a>(
|
|||
let vars_of_tag: MutMap<_, _> = tags_vec.iter().cloned().collect();
|
||||
|
||||
let union_variant = {
|
||||
let mut cache = LayoutCache::new(env.target_info);
|
||||
let mut layout_env =
|
||||
layout::Env::from_components(&mut cache, env.subs, env.arena, env.target_info);
|
||||
let mut layout_env = layout::Env::from_components(
|
||||
&mut env.layout_cache,
|
||||
env.subs,
|
||||
env.arena,
|
||||
env.target_info,
|
||||
);
|
||||
union_sorted_tags_pub(&mut layout_env, tags_vec, opt_rec_var)
|
||||
};
|
||||
|
||||
|
@ -208,7 +214,7 @@ fn get_tags_vars_and_variant<'a>(
|
|||
}
|
||||
|
||||
fn expr_of_tag<'a, 'env, M: ReplAppMemory>(
|
||||
env: &Env<'a, 'env>,
|
||||
env: &mut Env<'a, 'env>,
|
||||
mem: &'a M,
|
||||
data_addr: usize,
|
||||
tag_name: &TagName,
|
||||
|
@ -279,7 +285,7 @@ const OPAQUE_FUNCTION: Expr = Expr::Var {
|
|||
};
|
||||
|
||||
fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
||||
env: &Env<'a, '_>,
|
||||
env: &mut Env<'a, '_>,
|
||||
app: &mut A,
|
||||
main_fn_name: &str,
|
||||
layout: &Layout<'a>,
|
||||
|
@ -358,6 +364,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
|||
))
|
||||
}
|
||||
Layout::Struct { field_layouts, .. } => {
|
||||
let target_info = env.target_info;
|
||||
let struct_addr_to_ast = |mem: &'a A::Memory, addr: usize| match raw_content {
|
||||
Content::Structure(FlatType::Record(fields, _)) => {
|
||||
Ok(struct_to_ast(env, mem, addr, *fields))
|
||||
|
@ -406,7 +413,7 @@ fn jit_to_ast_help<'a, A: ReplApp<'a>>(
|
|||
let fields = [Layout::u64(), *layout];
|
||||
let layout = Layout::struct_no_name_order(&fields);
|
||||
|
||||
let result_stack_size = layout.stack_size(env.target_info);
|
||||
let result_stack_size = layout.stack_size(target_info);
|
||||
|
||||
app.call_function_dynamic_size(
|
||||
main_fn_name,
|
||||
|
@ -489,7 +496,7 @@ enum WhenRecursive<'a> {
|
|||
}
|
||||
|
||||
fn addr_to_ast<'a, M: ReplAppMemory>(
|
||||
env: &Env<'a, '_>,
|
||||
env: &mut Env<'a, '_>,
|
||||
mem: &'a M,
|
||||
addr: usize,
|
||||
layout: &Layout<'a>,
|
||||
|
@ -601,7 +608,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
// It's possible to hit a recursive pointer before the full type layout; just
|
||||
// figure out the actual recursive structure layout at this point.
|
||||
let content = env.subs.get_content_without_compacting(*structure);
|
||||
let union_layout = LayoutCache::new(env.target_info)
|
||||
let union_layout = env.layout_cache
|
||||
.from_var(env.arena, *structure, env.subs)
|
||||
.expect("no layout for structure");
|
||||
debug_assert!(matches!(union_layout, Layout::Union(..)));
|
||||
|
@ -833,7 +840,7 @@ fn addr_to_ast<'a, M: ReplAppMemory>(
|
|||
}
|
||||
|
||||
fn list_to_ast<'a, M: ReplAppMemory>(
|
||||
env: &Env<'a, '_>,
|
||||
env: &mut Env<'a, '_>,
|
||||
mem: &'a M,
|
||||
addr: usize,
|
||||
len: usize,
|
||||
|
@ -889,7 +896,7 @@ fn list_to_ast<'a, M: ReplAppMemory>(
|
|||
}
|
||||
|
||||
fn single_tag_union_to_ast<'a, 'env, M: ReplAppMemory>(
|
||||
env: &Env<'a, 'env>,
|
||||
env: &mut Env<'a, 'env>,
|
||||
mem: &'a M,
|
||||
addr: usize,
|
||||
field_layouts: &'a [Layout<'a>],
|
||||
|
@ -916,7 +923,7 @@ fn single_tag_union_to_ast<'a, 'env, M: ReplAppMemory>(
|
|||
}
|
||||
|
||||
fn sequence_of_expr<'a, 'env, I, M: ReplAppMemory>(
|
||||
env: &Env<'a, 'env>,
|
||||
env: &mut Env<'a, 'env>,
|
||||
mem: &'a M,
|
||||
addr: usize,
|
||||
sequence: I,
|
||||
|
@ -948,7 +955,7 @@ where
|
|||
}
|
||||
|
||||
fn struct_to_ast<'a, 'env, M: ReplAppMemory>(
|
||||
env: &Env<'a, 'env>,
|
||||
env: &mut Env<'a, 'env>,
|
||||
mem: &'a M,
|
||||
addr: usize,
|
||||
record_fields: RecordFields,
|
||||
|
@ -956,7 +963,6 @@ fn struct_to_ast<'a, 'env, M: ReplAppMemory>(
|
|||
let arena = env.arena;
|
||||
let subs = env.subs;
|
||||
let mut output = Vec::with_capacity_in(record_fields.len(), arena);
|
||||
let mut layout_cache = LayoutCache::new(env.target_info);
|
||||
|
||||
if record_fields.len() == 1 {
|
||||
// this is a 1-field wrapper record around another record or 1-tag tag union
|
||||
|
@ -966,7 +972,8 @@ fn struct_to_ast<'a, 'env, M: ReplAppMemory>(
|
|||
.unwrap();
|
||||
|
||||
let inner_content = env.subs.get_content_without_compacting(field.into_inner());
|
||||
let field_layout = layout_cache
|
||||
let field_layout = env
|
||||
.layout_cache
|
||||
.from_var(arena, field.into_inner(), env.subs)
|
||||
.unwrap();
|
||||
let inner_layouts = arena.alloc([field_layout]);
|
||||
|
@ -1005,7 +1012,8 @@ fn struct_to_ast<'a, 'env, M: ReplAppMemory>(
|
|||
// the type.
|
||||
for (label, field) in record_fields.sorted_iterator(subs, Variable::EMPTY_RECORD) {
|
||||
let content = subs.get_content_without_compacting(field.into_inner());
|
||||
let field_layout = layout_cache
|
||||
let field_layout = env
|
||||
.layout_cache
|
||||
.from_var(arena, field.into_inner(), env.subs)
|
||||
.unwrap();
|
||||
|
||||
|
@ -1148,7 +1156,7 @@ fn bool_to_ast<'a, M: ReplAppMemory>(
|
|||
}
|
||||
|
||||
fn byte_to_ast<'a, M: ReplAppMemory>(
|
||||
env: &Env<'a, '_>,
|
||||
env: &mut Env<'a, '_>,
|
||||
mem: &M,
|
||||
value: u8,
|
||||
content: &Content,
|
||||
|
@ -1201,9 +1209,8 @@ fn byte_to_ast<'a, M: ReplAppMemory>(
|
|||
.collect();
|
||||
|
||||
let union_variant = {
|
||||
let mut cache = LayoutCache::new(env.target_info);
|
||||
let mut layout_env = layout::Env::from_components(
|
||||
&mut cache,
|
||||
&mut env.layout_cache,
|
||||
env.subs,
|
||||
env.arena,
|
||||
env.target_info,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue