From f952dc61d108bef116657aa39f0ae043054e9bf5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 31 Jul 2021 18:25:45 +0300 Subject: [PATCH] internal: add API to check what are the max limits in practice --- crates/hir_expand/src/db.rs | 4 +++- crates/limit/Cargo.toml | 4 +++- crates/limit/src/lib.rs | 31 +++++++++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 7c83fcd639..ee64564430 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs @@ -22,7 +22,9 @@ use crate::{ /// /// If an invocation produces more tokens than this limit, it will not be stored in the database and /// an error will be emitted. -const TOKEN_LIMIT: Limit = Limit::new(524288); +/// +/// Actual max for `analysis-stats .` at some point: 30672. +static TOKEN_LIMIT: Limit = Limit::new(524_288); #[derive(Debug, Clone, Eq, PartialEq)] pub enum TokenExpander { diff --git a/crates/limit/Cargo.toml b/crates/limit/Cargo.toml index 7676f3644b..cb3ccbd73c 100644 --- a/crates/limit/Cargo.toml +++ b/crates/limit/Cargo.toml @@ -6,4 +6,6 @@ license = "MIT OR Apache-2.0" authors = ["rust-analyzer developers"] edition = "2018" -[dependencies] +[features] +tracking = [] +default = ["tracking"] diff --git a/crates/limit/src/lib.rs b/crates/limit/src/lib.rs index 8c96c748db..ace7ef7239 100644 --- a/crates/limit/src/lib.rs +++ b/crates/limit/src/lib.rs @@ -1,15 +1,26 @@ //! limit defines a struct to enforce limits. +use std::sync::atomic::AtomicUsize; + /// Represents a struct used to enforce a numerical limit. pub struct Limit { upper_bound: usize, + #[allow(unused)] + max: AtomicUsize, } impl Limit { /// Creates a new limit. #[inline] pub const fn new(upper_bound: usize) -> Self { - Self { upper_bound } + Self { upper_bound, max: AtomicUsize::new(0) } + } + + /// Creates a new limit. + #[inline] + #[cfg(feature = "tracking")] + pub const fn new_tracking(upper_bound: usize) -> Self { + Self { upper_bound, max: AtomicUsize::new(1) } } /// Gets the underlying numeric limit. @@ -21,10 +32,26 @@ impl Limit { /// Checks whether the given value is below the limit. /// Returns `Ok` when `other` is below `self`, and `Err` otherwise. #[inline] - pub const fn check(&self, other: usize) -> Result<(), ()> { + pub fn check(&self, other: usize) -> Result<(), ()> { if other > self.upper_bound { Err(()) } else { + #[cfg(feature = "tracking")] + loop { + use std::sync::atomic::Ordering; + let old_max = self.max.load(Ordering::Relaxed); + if other <= old_max || old_max == 0 { + break; + } + if self + .max + .compare_exchange(old_max, other, Ordering::Relaxed, Ordering::Relaxed) + .is_ok() + { + eprintln!("new max: {}", other); + } + } + Ok(()) } }