Don't clone when finding binding parents

Cloning bindings when traversing their ancestors is expensive when done
often enough. Using references is an easy way to work around this, at
the cost of requiring two methods: Binding::find_parent() and
Binding::find_parent_mut().
parent baf6d686
Pipeline #158405789 passed with stages
in 70 minutes and 54 seconds
......@@ -8,6 +8,22 @@ use crate::immix::copy_object::CopyObject;
use crate::object_pointer::{ObjectPointer, ObjectPointerPointer};
use std::cell::UnsafeCell;
macro_rules! find_parent {
($self: expr, $depth: expr, $method: ident) => {{
let mut found = $self.parent.$method();
for _ in 0..$depth {
if let Some(binding) = found {
found = binding.parent.$method();
} else {
return None;
}
}
found
}};
}
pub struct Binding {
/// The local variables in the current binding.
///
......@@ -65,20 +81,16 @@ impl Binding {
self.parent.clone()
}
/// Tries to find a parent binding while limiting the amount of bindings to
/// traverse.
pub fn find_parent(&self, depth: usize) -> Option<RcBinding> {
let mut found = self.parent();
for _ in 0..depth {
if let Some(unwrapped) = found {
found = unwrapped.parent();
} else {
return None;
}
}
/// Returns an immutable reference to the parent binding, `depth` steps up
/// from the current binding.
pub fn find_parent(&self, depth: usize) -> Option<&RcBinding> {
find_parent!(self, depth, as_ref)
}
found
/// Returns a mutable reference to the parent binding, `depth` steps up from
/// the current binding.
pub fn find_parent_mut(&mut self, depth: usize) -> Option<&mut RcBinding> {
find_parent!(self, depth, as_mut)
}
/// Returns an immutable reference to this binding's local variables.
......
......@@ -124,7 +124,7 @@ pub fn set_parent_local(
depth: usize,
value: ObjectPointer,
) -> Result<(), String> {
if let Some(mut binding) = process.context_mut().binding.find_parent(depth)
if let Some(binding) = process.context_mut().binding.find_parent_mut(depth)
{
binding.set_local(local, value);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment