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:
Ayaz Hafiz 2022-08-31 12:03:30 -05:00
parent 9d170be5c7
commit c5466810a4
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
19 changed files with 177 additions and 86 deletions

View file

@ -84,9 +84,9 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
/// Size of the return value is statically determined from its Rust type
/// The `transform` callback takes the app's memory and the returned value
/// _main_fn_name is always the same and we don't use it here
fn call_function<Return, F>(&mut self, _main_fn_name: &str, transform: F) -> Expr<'a>
fn call_function<Return, F>(&mut self, _main_fn_name: &str, mut transform: F) -> Expr<'a>
where
F: Fn(&'a Self::Memory, Return) -> Expr<'a>,
F: FnMut(&'a Self::Memory, Return) -> Expr<'a>,
Self::Memory: 'a,
{
let result: Return = unsafe {
@ -100,7 +100,7 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
fn call_function_returns_roc_list<F>(&mut self, main_fn_name: &str, transform: F) -> Expr<'a>
where
F: Fn(&'a Self::Memory, (usize, usize, usize)) -> Expr<'a>,
F: FnMut(&'a Self::Memory, (usize, usize, usize)) -> Expr<'a>,
Self::Memory: 'a,
{
self.call_function(main_fn_name, transform)
@ -127,10 +127,10 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
&mut self,
_main_fn_name: &str,
_ret_bytes: usize,
transform: F,
mut transform: F,
) -> T
where
F: Fn(&'a Self::Memory, usize) -> T,
F: FnMut(&'a Self::Memory, usize) -> T,
Self::Memory: 'a,
{
transform(self.memory, self.offset)

View file

@ -1,9 +1,10 @@
#[cfg(not(windows))]
use {
roc_intern::GlobalInterner,
roc_module::symbol::Interns,
roc_mono::{
ir::ProcLayout,
layout::{CapturesNiche, LayoutCache},
layout::{CapturesNiche, Layout, LayoutCache},
},
roc_parse::ast::Expr,
roc_repl_eval::{
@ -12,6 +13,7 @@ use {
},
roc_target::TargetInfo,
roc_types::subs::{Subs, Variable},
std::sync::Arc,
};
#[cfg(not(windows))]
@ -29,6 +31,7 @@ pub fn get_values<'a>(
arena: &'a bumpalo::Bump,
subs: &Subs,
interns: &'a Interns,
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
start: *const u8,
start_offset: usize,
variables: &[Variable],
@ -53,7 +56,8 @@ pub fn get_values<'a>(
let content = subs.get_content_without_compacting(variable);
let mut layout_cache = LayoutCache::new(target_info);
// TODO: pass layout_cache to jit_to_ast directly
let mut layout_cache = LayoutCache::new(layout_interner.fork(), target_info);
let layout = layout_cache.from_var(arena, variable, subs).unwrap();
let proc_layout = ProcLayout {
@ -70,6 +74,7 @@ pub fn get_values<'a>(
content,
subs,
interns,
layout_interner.fork(),
target_info,
)?
};
@ -132,7 +137,7 @@ mod test {
let interns = loaded.interns.clone();
let (lib, expects) = expect_mono_module_to_dylib(
let (lib, expects, layout_interner) = expect_mono_module_to_dylib(
arena,
target.clone(),
loaded,
@ -160,6 +165,7 @@ mod test {
RenderTarget::ColorTerminal,
arena,
interns,
&layout_interner.into_global(),
&lib,
&mut expectations,
expects,

View file

@ -1,4 +1,4 @@
use std::os::unix::process::parent_id;
use std::{os::unix::process::parent_id, sync::Arc};
use bumpalo::collections::Vec as BumpVec;
use bumpalo::Bump;
@ -10,9 +10,10 @@ use roc_gen_llvm::{
run_roc::RocCallResult,
run_roc_dylib,
};
use roc_intern::{GlobalInterner, SingleThreadedInterner};
use roc_load::{EntryPoint, Expectations, MonomorphizedModule};
use roc_module::symbol::{Interns, ModuleId, Symbol};
use roc_mono::ir::OptLevel;
use roc_mono::{ir::OptLevel, layout::Layout};
use roc_region::all::Region;
use roc_reporting::{error::expect::Renderer, report::RenderTarget};
use roc_target::TargetInfo;
@ -80,11 +81,12 @@ impl<'a> ExpectMemory<'a> {
}
#[allow(clippy::too_many_arguments)]
pub fn run_expects<W: std::io::Write>(
pub fn run_expects<'a, W: std::io::Write>(
writer: &mut W,
render_target: RenderTarget,
arena: &Bump,
interns: &Interns,
arena: &'a Bump,
interns: &'a Interns,
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
lib: &libloading::Library,
expectations: &mut VecMap<ModuleId, Expectations>,
expects: ExpectFunctions<'_>,
@ -97,6 +99,7 @@ pub fn run_expects<W: std::io::Write>(
render_target,
arena,
interns,
layout_interner,
lib,
expectations,
expects,
@ -105,11 +108,12 @@ pub fn run_expects<W: std::io::Write>(
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn run_expects_with_memory<W: std::io::Write>(
pub(crate) fn run_expects_with_memory<'a, W: std::io::Write>(
writer: &mut W,
render_target: RenderTarget,
arena: &Bump,
interns: &Interns,
arena: &'a Bump,
interns: &'a Interns,
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
lib: &libloading::Library,
expectations: &mut VecMap<ModuleId, Expectations>,
expects: ExpectFunctions<'_>,
@ -124,6 +128,7 @@ pub(crate) fn run_expects_with_memory<W: std::io::Write>(
render_target,
arena,
interns,
layout_interner,
lib,
expectations,
memory,
@ -144,6 +149,7 @@ pub(crate) fn run_expects_with_memory<W: std::io::Write>(
render_target,
arena,
interns,
layout_interner,
lib,
expectations,
memory,
@ -160,11 +166,12 @@ pub(crate) fn run_expects_with_memory<W: std::io::Write>(
}
#[allow(clippy::too_many_arguments)]
fn run_expect_pure<W: std::io::Write>(
fn run_expect_pure<'a, W: std::io::Write>(
writer: &mut W,
render_target: RenderTarget,
arena: &Bump,
interns: &Interns,
arena: &'a Bump,
interns: &'a Interns,
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
lib: &libloading::Library,
expectations: &mut VecMap<ModuleId, Expectations>,
shared_memory: &mut ExpectMemory,
@ -201,6 +208,7 @@ fn run_expect_pure<W: std::io::Write>(
Some(expect),
expectations,
interns,
layout_interner,
shared_memory_ptr,
offset,
)?;
@ -216,11 +224,12 @@ fn run_expect_pure<W: std::io::Write>(
}
#[allow(clippy::too_many_arguments)]
fn run_expect_fx<W: std::io::Write>(
fn run_expect_fx<'a, W: std::io::Write>(
writer: &mut W,
render_target: RenderTarget,
arena: &Bump,
interns: &Interns,
arena: &'a Bump,
interns: &'a Interns,
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
lib: &libloading::Library,
expectations: &mut VecMap<ModuleId, Expectations>,
parent_memory: &mut ExpectMemory,
@ -299,6 +308,7 @@ fn run_expect_fx<W: std::io::Write>(
None,
expectations,
interns,
layout_interner,
parent_memory.ptr,
ExpectSequence::START_OFFSET,
)?;
@ -313,11 +323,12 @@ fn run_expect_fx<W: std::io::Write>(
}
}
pub fn roc_dev_expect(
pub fn roc_dev_expect<'a>(
writer: &mut impl std::io::Write,
arena: &Bump,
arena: &'a Bump,
expectations: &mut VecMap<ModuleId, Expectations>,
interns: &Interns,
interns: &'a Interns,
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
shared_ptr: *mut u8,
) -> std::io::Result<usize> {
let frame = ExpectFrame::at_offset(shared_ptr, ExpectSequence::START_OFFSET);
@ -343,6 +354,7 @@ pub fn roc_dev_expect(
None,
expectations,
interns,
layout_interner,
shared_ptr,
ExpectSequence::START_OFFSET,
)
@ -356,6 +368,7 @@ fn render_expect_failure<'a>(
expect: Option<ToplevelExpect>,
expectations: &mut VecMap<ModuleId, Expectations>,
interns: &'a Interns,
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
start: *const u8,
offset: usize,
) -> std::io::Result<usize> {
@ -383,6 +396,7 @@ fn render_expect_failure<'a>(
arena,
subs,
interns,
layout_interner,
start,
frame.start_offset,
&variables,
@ -473,7 +487,14 @@ pub fn expect_mono_module_to_dylib<'a>(
loaded: MonomorphizedModule<'a>,
opt_level: OptLevel,
mode: LlvmBackendMode,
) -> Result<(libloading::Library, ExpectFunctions<'a>), libloading::Error> {
) -> Result<
(
libloading::Library,
ExpectFunctions<'a>,
SingleThreadedInterner<'a, Layout<'a>>,
),
libloading::Error,
> {
let target_info = TargetInfo::from(&target);
let MonomorphizedModule {
@ -481,6 +502,7 @@ pub fn expect_mono_module_to_dylib<'a>(
procedures,
entry_point,
interns,
layout_interner,
..
} = loaded;
@ -590,5 +612,5 @@ pub fn expect_mono_module_to_dylib<'a>(
);
}
llvm_module_to_dylib(env.module, &target, opt_level).map(|lib| (lib, expects))
llvm_module_to_dylib(env.module, &target, opt_level).map(|lib| (lib, expects, layout_interner))
}