git.delta.rocks / jrsonnet / refs/commits / d710b4fe6639

difftreelog

perf use weak objvalue as cache key

Yaroslav Bolyukin2022-03-21parent: #7efefe2.patch.diff
in: master

4 files changed

modifiedcrates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/Cargo.toml
+++ b/crates/jrsonnet-evaluator/Cargo.toml
@@ -15,9 +15,6 @@
 # Allows library authors to throw custom errors
 anyhow-error = ["anyhow"]
 
-# Unlocks extra features, but works only on unstable
-unstable = []
-
 [dependencies]
 jrsonnet-interner = { path = "../jrsonnet-interner", version = "0.4.2" }
 jrsonnet-parser = { path = "../jrsonnet-parser", version = "0.4.2" }
modifiedcrates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/ctx.rs
+++ b/crates/jrsonnet-evaluator/src/ctx.rs
@@ -133,10 +133,6 @@
 		}
 		Ok(self.extend(new, new_dollar, this, super_obj))
 	}
-	#[cfg(feature = "unstable")]
-	pub fn into_weak(self) -> WeakContext {
-		WeakContext(Rc::downgrade(&self.0))
-	}
 }
 
 impl Default for Context {
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -1,4 +1,3 @@
-#![cfg_attr(feature = "unstable", feature(stmt_expr_attributes))]
 #![warn(clippy::all, clippy::nursery)]
 #![allow(
 	macro_expanded_macro_exports_accessed_by_absolute_paths,
@@ -31,7 +30,7 @@
 pub use evaluate::*;
 use function::{Builtin, TlaArg};
 use gc::{GcHashMap, TraceBox};
-use gcmodule::{Cc, Trace};
+use gcmodule::{Cc, Trace, Weak};
 pub use import::*;
 pub use jrsonnet_interner::IStr;
 use jrsonnet_parser::*;
@@ -653,6 +652,28 @@
 	std::ptr::eq(a, b)
 }
 
+fn weak_raw<T>(a: Weak<T>) -> *const () {
+	unsafe { std::mem::transmute(a) }
+}
+fn weak_ptr_eq<T>(a: Weak<T>, b: Weak<T>) -> bool {
+	std::ptr::eq(weak_raw(a), weak_raw(b))
+}
+
+#[test]
+fn weak_unsafe() {
+	let a = Cc::new(1);
+	let b = Cc::new(2);
+
+	let aw1 = a.clone().downgrade();
+	let aw2 = a.clone().downgrade();
+	let aw3 = a.clone().downgrade();
+
+	let bw = b.clone().downgrade();
+
+	assert!(weak_ptr_eq(aw1, aw2));
+	assert!(!weak_ptr_eq(aw3, bw));
+}
+
 #[cfg(test)]
 pub mod tests {
 	use super::Val;
modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
1use crate::gc::{GcHashMap, GcHashSet, TraceBox};1use crate::gc::{GcHashMap, GcHashSet, TraceBox};
2use crate::operator::evaluate_add_op;2use crate::operator::evaluate_add_op;
3use crate::{cc_ptr_eq, Bindable, LazyBinding, LazyVal, Result, Val};3use crate::{cc_ptr_eq, weak_ptr_eq, weak_raw, Bindable, LazyBinding, LazyVal, Result, Val};
4use gcmodule::{Cc, Trace};4use gcmodule::{Cc, Trace, Weak};
5use jrsonnet_interner::IStr;5use jrsonnet_interner::IStr;
6use jrsonnet_parser::{ExprLocation, Visibility};6use jrsonnet_parser::{ExprLocation, Visibility};
7use rustc_hash::FxHashMap;7use rustc_hash::FxHashMap;
22}22}
2323
24// Field => This24// Field => This
25type CacheKey = (IStr, ObjValue);25type CacheKey = (IStr, WeakObjValue);
26#[derive(Trace)]26#[derive(Trace)]
27#[force_tracking]27#[force_tracking]
28pub struct ObjValueInternals {28pub struct ObjValueInternals {
34 value_cache: RefCell<GcHashMap<CacheKey, Option<Val>>>,34 value_cache: RefCell<GcHashMap<CacheKey, Option<Val>>>,
35}35}
36
37#[derive(Clone, Trace)]
38pub struct WeakObjValue(#[skip_trace] pub(crate) Weak<ObjValueInternals>);
39
40impl PartialEq for WeakObjValue {
41 fn eq(&self, other: &Self) -> bool {
42 weak_ptr_eq(self.0.clone(), other.0.clone())
43 }
44}
45
46impl Eq for WeakObjValue {}
47impl Hash for WeakObjValue {
48 fn hash<H: Hasher>(&self, hasher: &mut H) {
49 hasher.write_usize(weak_raw(self.0.clone()) as usize)
50 }
51}
3652
37#[derive(Clone, Trace)]53#[derive(Clone, Trace)]
38pub struct ObjValue(pub(crate) Cc<ObjValueInternals>);54pub struct ObjValue(pub(crate) Cc<ObjValueInternals>);
50 for (name, member) in self.0.this_entries.iter() {66 for (name, member) in self.0.this_entries.iter() {
51 debug.field(name, member);67 debug.field(name, member);
52 }68 }
53 #[cfg(feature = "unstable")]
54 {
55 debug.finish_non_exhaustive()69 debug.finish_non_exhaustive()
56 }
57 #[cfg(not(feature = "unstable"))]
58 {
59 debug.finish()
60 }
61 }70 }
62}71}
6372
217226
218 fn get_raw(&self, key: IStr, real_this: Option<&Self>) -> Result<Option<Val>> {227 fn get_raw(&self, key: IStr, real_this: Option<&Self>) -> Result<Option<Val>> {
219 let real_this = real_this.unwrap_or(self);228 let real_this = real_this.unwrap_or(self);
220 let cache_key = (key.clone(), real_this.clone());229 let cache_key = (key.clone(), WeakObjValue(real_this.0.downgrade()));
221230
222 if let Some(v) = self.0.value_cache.borrow().get(&cache_key) {231 if let Some(v) = self.0.value_cache.borrow().get(&cache_key) {
223 return Ok(v.clone());232 return Ok(v.clone());