use granular hierarchical locks in offset_table.rs

This commit is contained in:
Mark Thom
2025-06-24 21:58:40 -07:00
committed by Mark Thom
parent 2844b5a958
commit 762b63e1f4
18 changed files with 233 additions and 333 deletions

View File

@@ -1389,8 +1389,8 @@ impl MachineState {
self.interms.push(Number::Fixnum(n));
}
(HeapCellValueTag::F64Offset, offset) => {
let fl = self.arena.f64_tbl.lookup(offset);
self.interms.push(Number::Float(*fl));
let fl = self.arena.f64_tbl.get_entry(offset);
self.interms.push(Number::Float(fl));
}
(HeapCellValueTag::Cons, ptr) => {
match_untyped_arena_ptr!(ptr,

View File

@@ -1328,17 +1328,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let index_ptr = LS::machine_st(&mut self.payload)
.arena
.code_index_tbl
.lookup(code_idx.into());
.get_entry(code_idx.into());
print_overwrite_warning(
&predicates.compilation_target,
*index_ptr,
index_ptr,
key,
settings.is_dynamic(),
);
drop(index_ptr);
let index_ptr = if settings.is_dynamic() {
IndexPtr::dynamic_index(code_ptr)
} else {
@@ -2231,10 +2229,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
if let Some(filename) = self.listing_src_file_name() {
if let Some(ref mut module) = self.wam_prelude.indices.modules.get_mut(&filename) {
let index_ptr = *LS::machine_st(&mut self.payload)
let index_ptr = LS::machine_st(&mut self.payload)
.arena
.code_index_tbl
.lookup_mut(offset.into());
.get_entry(offset.into());
let offset = *module.code_dir.entry(key).or_insert(offset);

View File

@@ -547,8 +547,8 @@ impl Machine {
// Find the boundaries of the current predicate
self.indices.code_dir.sort_by(|_, a, _, b| {
let a = *self.machine_st.arena.code_index_tbl.lookup((*a).into());
let b = *self.machine_st.arena.code_index_tbl.lookup((*b).into());
let a = self.machine_st.arena.code_index_tbl.get_entry((*a).into());
let b = self.machine_st.arena.code_index_tbl.get_entry((*b).into());
a.cmp(&b)
});
@@ -557,8 +557,11 @@ impl Machine {
.indices
.code_dir
.binary_search_by_key(&p, |_, x| -> usize {
self.machine_st.arena.code_index_tbl.lookup((*x).into()).p()
as usize
self.machine_st
.arena
.code_index_tbl
.get_entry((*x).into())
.p() as usize
})
.unwrap_or_else(|x| x - 1);
@@ -570,7 +573,7 @@ impl Machine {
self.machine_st
.arena
.code_index_tbl
.lookup((*idx.1).into())
.get_entry((*idx.1).into())
.p() as usize
})
.unwrap();
@@ -585,7 +588,7 @@ impl Machine {
self.machine_st
.arena
.code_index_tbl
.lookup((*idx.1).into())
.get_entry((*idx.1).into())
.p() as usize
})
.unwrap_or(self.code.len());
@@ -2696,7 +2699,7 @@ impl Machine {
}
}
&Instruction::CallNamed(arity, name, idx) => {
let idx = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into());
try_or_throw!(self.machine_st, self.try_call(name, arity, idx));
@@ -2707,7 +2710,7 @@ impl Machine {
}
}
&Instruction::ExecuteNamed(arity, name, idx) => {
let idx = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into());
try_or_throw!(self.machine_st, self.try_execute(name, arity, idx));
@@ -2718,7 +2721,7 @@ impl Machine {
}
}
&Instruction::DefaultCallNamed(arity, name, idx) => {
let idx = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into());
try_or_throw!(self.machine_st, self.try_call(name, arity, idx));
@@ -2727,7 +2730,7 @@ impl Machine {
}
}
&Instruction::DefaultExecuteNamed(arity, name, idx) => {
let idx = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
let idx = self.machine_st.arena.code_index_tbl.get_entry(idx.into());
try_or_throw!(self.machine_st, self.try_execute(name, arity, idx));

View File

@@ -278,7 +278,7 @@ impl Term {
}
}
(HeapCellValueTag::F64Offset, offset) => {
let f = *machine.machine_st.arena.f64_tbl.lookup(offset);
let f = machine.machine_st.arena.f64_tbl.get_entry(offset);
term_stack.push(Term::Float(f.into()));
}
(HeapCellValueTag::Fixnum, n) => {
@@ -602,7 +602,7 @@ impl Machine {
self.machine_st
.arena
.code_index_tbl
.lookup(offset.into())
.get_entry(offset.into())
.p() as usize
})
.expect("couldn't get code index");

View File

@@ -22,33 +22,30 @@ pub(super) fn set_code_index<'a, LS: LoadState<'a>>(
code_idx: CodeIndex,
code_ptr: IndexPtr,
) {
let mut code_idx_ptr = LS::machine_st(payload)
.arena
.code_index_tbl
.lookup_mut(code_idx.into());
let record = match compilation_target {
CompilationTarget::User => {
if IndexPtrTag::Undefined == code_idx_ptr.tag() {
code_idx_ptr.set(code_ptr);
RetractionRecord::AddedUserPredicate(key)
} else {
let replaced = code_idx_ptr.replace(code_ptr);
RetractionRecord::ReplacedUserPredicate(key, replaced)
let record = LS::machine_st(payload).arena.code_index_tbl.with_entry_mut(
code_idx.into(),
|code_idx_ptr| match compilation_target {
CompilationTarget::User => {
if IndexPtrTag::Undefined == code_idx_ptr.tag() {
*code_idx_ptr = code_ptr;
RetractionRecord::AddedUserPredicate(key)
} else {
let replaced = mem::replace(code_idx_ptr, code_ptr);
RetractionRecord::ReplacedUserPredicate(key, replaced)
}
}
}
CompilationTarget::Module(ref module_name) => {
if IndexPtrTag::Undefined == code_idx_ptr.tag() {
code_idx_ptr.set(code_ptr);
RetractionRecord::AddedModulePredicate(*module_name, key)
} else {
let replaced = code_idx_ptr.replace(code_ptr);
RetractionRecord::ReplacedModulePredicate(*module_name, key, replaced)
CompilationTarget::Module(ref module_name) => {
if IndexPtrTag::Undefined == code_idx_ptr.tag() {
*code_idx_ptr = code_ptr;
RetractionRecord::AddedModulePredicate(*module_name, key)
} else {
let replaced = mem::replace(code_idx_ptr, code_ptr);
RetractionRecord::ReplacedModulePredicate(*module_name, key, replaced)
}
}
}
};
},
);
drop(code_idx_ptr);
payload.retraction_info.push_record(record);
}
@@ -145,7 +142,7 @@ pub(super) fn import_module_exports<'a, LS: LoadState<'a>>(
.entry(key)
.or_insert_with(|| CodeIndex::default(code_idx_tbl));
let src_code_index_ptr = *code_idx_tbl.lookup(src_code_index.into());
let src_code_index_ptr = code_idx_tbl.get_entry(src_code_index.into());
set_code_index::<LS>(
payload,
@@ -158,7 +155,7 @@ pub(super) fn import_module_exports<'a, LS: LoadState<'a>>(
if LS::machine_st(payload)
.arena
.code_index_tbl
.lookup(src_code_index.into())
.get_entry(src_code_index.into())
.is_dynamic_undefined()
{
code_dir.insert(key, src_code_index);
@@ -205,7 +202,7 @@ fn import_module_exports_into_module<'a, LS: LoadState<'a>>(
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
let src_code_ptr = code_index_tbl.get_entry(src_code_index.into());
let target_code_index = *code_dir
.entry(key)
.or_insert_with(|| CodeIndex::default(code_index_tbl));
@@ -259,7 +256,7 @@ fn import_qualified_module_exports<'a, LS: LoadState<'a>>(
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
let src_code_ptr = code_index_tbl.get_entry(src_code_index.into());
let target_code_index =
*wam_prelude.indices.code_dir.entry(key).or_insert_with(|| {
CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
@@ -320,7 +317,7 @@ fn import_qualified_module_exports_into_module<'a, LS: LoadState<'a>>(
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
let code_index_tbl = &mut LS::machine_st(payload).arena.code_index_tbl;
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
let src_code_ptr = code_index_tbl.get_entry(src_code_index.into());
let target_code_index = *code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), code_index_tbl));
@@ -505,10 +502,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
let code_index_tbl = &mut LS::machine_st(&mut self.payload).arena.code_index_tbl;
let code_ptr = code_index_tbl.lookup((*code_index).into());
let code_ptr = code_index_tbl.get_entry((*code_index).into());
if !code_ptr.is_undefined() && !code_ptr.is_dynamic_undefined() {
drop(code_ptr);
let old_index_ptr = code_index.replace(code_index_tbl, IndexPtr::undefined());
self.payload.retraction_info.push_record(
@@ -557,13 +553,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
(Some(module_code_idx), Some(target_code_idx)) => {
let code_index_tbl =
&mut LS::machine_st(payload).arena.code_index_tbl;
let module_code_ptr = code_index_tbl.lookup(module_code_idx.into());
let target_code_ptr = code_index_tbl.lookup(target_code_idx.into());
let module_code_ptr =
code_index_tbl.get_entry(module_code_idx.into());
let target_code_ptr =
code_index_tbl.get_entry(target_code_idx.into());
if module_code_ptr == target_code_ptr {
drop(module_code_ptr);
drop(target_code_ptr);
let old_index_ptr = target_code_idx
.replace(code_index_tbl, IndexPtr::undefined());
payload

View File

@@ -1225,11 +1225,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let code_idx_ptr = LS::machine_st(&mut self.payload)
.arena
.code_index_tbl
.lookup_mut(offset.into());
.get_entry(offset.into());
if code_idx_ptr.is_undefined() {
drop(code_idx_ptr);
set_code_index::<LS>(
&mut self.payload,
&compilation_target,
@@ -2015,8 +2013,7 @@ impl Machine {
.machine_st
.arena
.code_index_tbl
.lookup(offset.into())
.tag()
.with_entry(offset.into(), |idx| idx.tag())
})
.unwrap_or(IndexPtrTag::DynamicUndefined);
@@ -2162,16 +2159,14 @@ impl Machine {
let offset = loader.get_or_insert_code_index(key, compilation_target);
let mut code_idx = loader
loader
.payload
.machine_st
.arena
.code_index_tbl
.lookup_mut(offset.into());
code_idx.set(IndexPtr::undefined());
drop(code_idx);
.with_entry_mut(offset.into(), |code_idx| {
*code_idx = IndexPtr::undefined();
});
loader.payload.compilation_target = clause_clause_compilation_target;

View File

@@ -186,12 +186,12 @@ impl CodeIndex {
#[inline(always)]
pub(crate) fn set(&self, code_index_tbl: &mut CodeIndexTable, value: IndexPtr) {
code_index_tbl.lookup_mut(self.0).set(value);
code_index_tbl.with_entry_mut(self.0, |idx| *idx = value);
}
#[inline(always)]
pub(crate) fn replace(&self, code_index_tbl: &mut CodeIndexTable, value: IndexPtr) -> IndexPtr {
code_index_tbl.lookup_mut(self.0).replace(value)
code_index_tbl.with_entry_mut(self.0, |idx| std::mem::replace(idx, value))
}
}

View File

@@ -412,8 +412,8 @@ impl MachineState {
let v1 = cell_as_f64_offset!(v1);
let v2 = cell_as_f64_offset!(v2);
let v1 = self.arena.f64_tbl.lookup(v1);
let v2 = self.arena.f64_tbl.lookup(v2);
let v1 = self.arena.f64_tbl.get_entry(v1);
let v2 = self.arena.f64_tbl.get_entry(v2);
if v1 != v2 {
self.pdl.clear();

View File

@@ -253,7 +253,11 @@ impl Machine {
) -> std::process::ExitCode {
if let Some(module) = self.indices.modules.get(&module_name) {
if let Some(code_idx) = module.code_dir.get(&key) {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
let index_ptr = self
.machine_st
.arena
.code_index_tbl
.get_entry(code_idx.into());
let p = index_ptr.local().unwrap();
// Leave a halting choice point to backtrack to in case the predicate fails or throws.
@@ -327,7 +331,11 @@ impl Machine {
if let Some(module) = self.indices.modules.get(&atom!("$atts")) {
if let Some(code_idx) = module.code_dir.get(&(atom!("driver"), 2)) {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
let index_ptr = self
.machine_st
.arena
.code_index_tbl
.get_entry(code_idx.into());
self.machine_st.attr_var_init.verify_attrs_loc = index_ptr.local().unwrap();
}
}
@@ -350,7 +358,7 @@ impl Machine {
CodeIndex::new(IndexPtr::undefined(), code_index_tbl)
});
let src_code_ptr = *code_index_tbl.lookup(src_code_index.into());
let src_code_ptr = code_index_tbl.get_entry(src_code_index.into());
target_code_index.set(code_index_tbl, src_code_ptr);
}
None => {
@@ -1045,14 +1053,14 @@ impl Machine {
if module_name == atom!("user") {
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
let index_ptr = self.machine_st.arena.code_index_tbl.get_entry(idx.into());
self.try_call(name, arity, index_ptr)
} else {
Err(self.machine_st.throw_undefined_error(name, arity))
}
} else if let Some(module) = self.indices.modules.get(&module_name) {
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
let index_ptr = self.machine_st.arena.code_index_tbl.get_entry(idx.into());
self.try_call(name, arity, index_ptr)
} else {
self.undefined_procedure(name, arity)
@@ -1076,15 +1084,23 @@ impl Machine {
let (name, arity) = key;
if module_name == atom!("user") {
if let Some(idx) = self.indices.code_dir.get(&(name, arity)).cloned() {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
if let Some(offset) = self.indices.code_dir.get(&(name, arity)).cloned() {
let index_ptr = self
.machine_st
.arena
.code_index_tbl
.get_entry(offset.into());
self.try_execute(name, arity, index_ptr)
} else {
self.undefined_procedure(name, arity)
}
} else if let Some(module) = self.indices.modules.get(&module_name) {
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(idx.into());
if let Some(offset) = module.code_dir.get(&(name, arity)).cloned() {
let index_ptr = self
.machine_st
.arena
.code_index_tbl
.get_entry(offset.into());
self.try_execute(name, arity, index_ptr)
} else {
self.undefined_procedure(name, arity)
@@ -1131,7 +1147,7 @@ impl Machine {
self.machine_st
.arena
.code_index_tbl
.lookup(code_idx.into())
.get_entry(code_idx.into())
.local()
})
.unwrap();
@@ -1142,7 +1158,7 @@ impl Machine {
self.machine_st
.arena
.code_index_tbl
.lookup(code_idx.into())
.get_entry(code_idx.into())
.local()
})
.unwrap();

View File

@@ -1246,7 +1246,7 @@ impl Machine {
self.machine_st
.arena
.code_index_tbl
.lookup(idx.into())
.get_entry(idx.into())
.local()
})
.unwrap();
@@ -1477,7 +1477,11 @@ impl Machine {
};
if let Some(code_idx) = index_cell_opt {
let index_ptr = *self.machine_st.arena.code_index_tbl.lookup(code_idx.into());
let index_ptr = self
.machine_st
.arena
.code_index_tbl
.get_entry(code_idx.into());
if !index_ptr.is_undefined() {
load_registers(&mut self.machine_st, goal, goal_arity);
@@ -6005,7 +6009,7 @@ impl Machine {
self.machine_st
.arena
.code_index_tbl
.lookup(idx.into())
.get_entry(idx.into())
.local()
.is_some()
})
@@ -6030,10 +6034,10 @@ impl Machine {
arity,
module_name,
)
.map(|idx| *self.machine_st
.map(|idx| self.machine_st
.arena
.code_index_tbl
.lookup(idx.into()))
.get_entry(idx.into()))
.unwrap_or(IndexPtr::dynamic_undefined());
!matches!(index.tag(), IndexPtrTag::DynamicUndefined | IndexPtrTag::Undefined)
@@ -6050,10 +6054,10 @@ impl Machine {
0,
module_name,
)
.map(|idx| *self.machine_st
.map(|idx| self.machine_st
.arena
.code_index_tbl
.lookup(idx.into()))
.get_entry(idx.into()))
.unwrap_or(IndexPtr::dynamic_undefined());
!matches!(index.tag(), IndexPtrTag::DynamicUndefined)
@@ -7480,7 +7484,7 @@ impl Machine {
self.machine_st
.arena
.code_index_tbl
.lookup(first_idx.into())
.get_entry(first_idx.into())
.local()
});

View File

@@ -289,10 +289,10 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
(HeapCellValueTag::F64Offset, f2) => {
let machine_st = self.deref_mut();
let f1 = *machine_st.arena.f64_tbl.lookup(f1);
let f2 = *machine_st.arena.f64_tbl.lookup(f2.into());
let f1 = machine_st.arena.f64_tbl.get_entry(f1);
let f2 = machine_st.arena.f64_tbl.get_entry(f2.into());
self.fail = *f1 != *f2;
self.fail = f1 != f2;
}
_ => {
self.fail = true;