about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSparrowLii <liyuan179@huawei.com>2022-09-13 15:35:44 +0800
committerSparrowLii <liyuan179@huawei.com>2022-09-14 08:49:12 +0800
commitbfc4f2e189dd1929086b31a7502a2b39e4797770 (patch)
treeb0bbacc854a881e896ef206ee12a9d6ae851f8d3
parent1a3ecbdb6a4c9eeced6e9a7ece9f5733548d531b (diff)
downloadrust-bfc4f2e189dd1929086b31a7502a2b39e4797770.tar.gz
rust-bfc4f2e189dd1929086b31a7502a2b39e4797770.zip
add debug assertion for max `attr_id`
-rw-r--r--compiler/rustc_ast/src/attr/mod.rs25
1 files changed, 24 insertions, 1 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 67affb622f8..990f4f8f132 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -19,6 +19,10 @@ use rustc_span::Span;
 
 use std::cell::Cell;
 use std::iter;
+#[cfg(debug_assertions)]
+use std::ops::BitXor;
+#[cfg(debug_assertions)]
+use std::sync::atomic::{AtomicU32, Ordering};
 
 pub struct MarkedAttrs(GrowableBitSet<AttrId>);
 
@@ -350,17 +354,36 @@ pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem {
 
 pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>);
 
+#[cfg(debug_assertions)]
+static MAX_ATTR_ID: AtomicU32 = AtomicU32::new(u32::MAX);
+
 impl AttrIdGenerator {
     pub fn new() -> Self {
         // We use `(index as u32).reverse_bits()` to initialize the
         // starting value of AttrId in each worker thread.
         // The `index` is the index of the worker thread.
         // This ensures that the AttrId generated in each thread is unique.
-        AttrIdGenerator(WorkerLocal::new(|index| Cell::new((index as u32).reverse_bits())))
+        AttrIdGenerator(WorkerLocal::new(|index| {
+            let index: u32 = index.try_into().unwrap();
+
+            #[cfg(debug_assertions)]
+            {
+                let max_id = ((index + 1).next_power_of_two() - 1).bitxor(u32::MAX).reverse_bits();
+                MAX_ATTR_ID.fetch_min(max_id, Ordering::Release);
+            }
+
+            Cell::new(index.reverse_bits())
+        }))
     }
 
     pub fn mk_attr_id(&self) -> AttrId {
         let id = self.0.get();
+
+        // Ensure the assigned attr_id does not overlap the bits
+        // representing the number of threads.
+        #[cfg(debug_assertions)]
+        assert!(id <= MAX_ATTR_ID.load(Ordering::Acquire));
+
         self.0.set(id + 1);
         AttrId::from_u32(id)
     }