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

@ -3,6 +3,8 @@ use const_format::concatcp;
use inkwell::context::Context;
use libloading::Library;
use roc_gen_llvm::llvm::build::LlvmBackendMode;
use roc_intern::SingleThreadedInterner;
use roc_mono::layout::Layout;
use roc_types::subs::Subs;
use rustyline::highlight::{Highlighter, PromptInfo};
use rustyline::validate::{self, ValidationContext, ValidationResult, Validator};
@ -132,9 +134,9 @@ impl<'a> ReplApp<'a> for CliApp {
/// Run user code that returns a type with a `Builtin` layout
/// Size of the return value is statically determined from its Rust type
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,
{
run_jit_function!(self.lib, main_fn_name, Return, |v| transform(&CliMemory, v))
@ -145,10 +147,10 @@ impl<'a> ReplApp<'a> for CliApp {
&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,
{
run_jit_function_dynamic_type!(self.lib, main_fn_name, ret_bytes, |v| transform(
@ -204,9 +206,17 @@ impl ReplAppMemory for CliMemory {
pub fn mono_module_to_dylib<'a>(
arena: &'a Bump,
target: Triple,
loaded: MonomorphizedModule,
loaded: MonomorphizedModule<'a>,
opt_level: OptLevel,
) -> Result<(libloading::Library, &'a str, Subs), libloading::Error> {
) -> Result<
(
libloading::Library,
&'a str,
Subs,
SingleThreadedInterner<'a, Layout<'a>>,
),
libloading::Error,
> {
let target_info = TargetInfo::from(&target);
let MonomorphizedModule {
@ -214,6 +224,7 @@ pub fn mono_module_to_dylib<'a>(
entry_point,
interns,
subs,
layout_interner,
..
} = loaded;
@ -291,7 +302,8 @@ pub fn mono_module_to_dylib<'a>(
);
}
llvm_module_to_dylib(env.module, &target, opt_level).map(|lib| (lib, main_fn_name, subs))
llvm_module_to_dylib(env.module, &target, opt_level)
.map(|lib| (lib, main_fn_name, subs, layout_interner))
}
fn gen_and_eval_llvm<'a>(
@ -336,7 +348,7 @@ fn gen_and_eval_llvm<'a>(
let interns = loaded.interns.clone();
let (lib, main_fn_name, subs) =
let (lib, main_fn_name, subs, layout_interner) =
mono_module_to_dylib(&arena, target, loaded, opt_level).expect("we produce a valid Dylib");
let mut app = CliApp { lib };
@ -349,6 +361,7 @@ fn gen_and_eval_llvm<'a>(
&content,
&subs,
&interns,
layout_interner.into_global().fork(),
target_info,
);