diff options
| author | Tobia <tobia.conforto@gruppo4.it> | 2019-04-01 18:16:03 +0900 |
|---|---|---|
| committer | Tobia <tobia.conforto@gruppo4.it> | 2019-04-13 01:24:10 +0900 |
| commit | a4a07e00ced90e076dbadd8b350db527bcc588bd (patch) | |
| tree | 13e55524c00d9acf65a0ef3fe6e0587c617a8480 | |
| parent | eab3eb38df8dca99110b6149b3a15deeb4ef0413 (diff) | |
| download | rust-a4a07e00ced90e076dbadd8b350db527bcc588bd.tar.gz rust-a4a07e00ced90e076dbadd8b350db527bcc588bd.zip | |
Replaced linear token counting macros with optimized implementation
| -rw-r--r-- | src/librustc/hir/map/definitions.rs | 12 | ||||
| -rw-r--r-- | src/libserialize/serialize.rs | 17 |
2 files changed, 22 insertions, 7 deletions
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 1006d813e65..c72edb6cc6d 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -696,9 +696,17 @@ impl DefPathData { } } +/// Evaluates to the number of tokens passed to it. +/// +/// Logarithmic counting: every one or two recursive expansions, the number of +/// tokens to count is divided by two, instead of being reduced by one. +/// Therefore, the recursion depth is the binary logarithm of the number of +/// tokens to count, and the expanded tree is likewise very small. macro_rules! count { - () => (0usize); - ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*)); + () => (0usize); + ($one:tt) => (1usize); + ($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize); + ($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize); } // We define the GlobalMetaDataKind enum with this macro because we want to diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index cf948078b08..d53891828f1 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -723,10 +723,17 @@ macro_rules! peel { ($name:ident, $($other:ident,)*) => (tuple! { $($other,)* }) } -/// Evaluates to the number of identifiers passed to it, for example: `count_idents!(a, b, c) == 3 -macro_rules! count_idents { - () => { 0 }; - ($_i:ident, $($rest:ident,)*) => { 1 + count_idents!($($rest,)*) } +/// Evaluates to the number of tokens passed to it. +/// +/// Logarithmic counting: every one or two recursive expansions, the number of +/// tokens to count is divided by two, instead of being reduced by one. +/// Therefore, the recursion depth is the binary logarithm of the number of +/// tokens to count, and the expanded tree is likewise very small. +macro_rules! count { + () => (0usize); + ($one:tt) => (1usize); + ($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize); + ($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize); } macro_rules! tuple { @@ -735,7 +742,7 @@ macro_rules! tuple { impl<$($name:Decodable),*> Decodable for ($($name,)*) { #[allow(non_snake_case)] fn decode<D: Decoder>(d: &mut D) -> Result<($($name,)*), D::Error> { - let len: usize = count_idents!($($name,)*); + let len: usize = count!($($name)*); d.read_tuple(len, |d| { let mut i = 0; let ret = ($(d.read_tuple_arg({ i+=1; i-1 }, |d| -> Result<$name, D::Error> { |
