@@ -9,7 +9,8 @@ use core::{
9
9
hash:: { BuildHasher , Hasher } ,
10
10
iter:: Flatten ,
11
11
marker:: PhantomData ,
12
- slice:: { from_raw_parts, Iter , IterMut } ,
12
+ mem:: size_of,
13
+ slice:: { self , Iter , IterMut } ,
13
14
} ;
14
15
15
16
use ahash:: RandomState ;
@@ -72,9 +73,9 @@ fn init_count_class_16() {
72
73
fn hash_slice < T > ( slice : & [ T ] ) -> u64 {
73
74
let mut hasher = RandomState :: with_seeds ( 0 , 0 , 0 , 0 ) . build_hasher ( ) ;
74
75
let ptr = slice. as_ptr ( ) as * const u8 ;
75
- let map_size = slice. len ( ) / core :: mem :: size_of :: < T > ( ) ;
76
+ let map_size = slice. len ( ) / size_of :: < T > ( ) ;
76
77
unsafe {
77
- hasher. write ( from_raw_parts ( ptr, map_size) ) ;
78
+ hasher. write ( slice :: from_raw_parts ( ptr, map_size) ) ;
78
79
}
79
80
hasher. finish ( )
80
81
}
@@ -1234,7 +1235,23 @@ where
1234
1235
exit_kind : & ExitKind ,
1235
1236
) -> Result < ( ) , Error > {
1236
1237
let map = self . as_mut_slice ( ) ;
1237
- let len = map. len ( ) ;
1238
+ let mut len = map. len ( ) ;
1239
+ let align_offset = map. as_ptr ( ) . align_offset ( size_of :: < u16 > ( ) ) ;
1240
+
1241
+ // if len == 1, the next branch will already do this lookup
1242
+ if len > 1 && align_offset != 0 {
1243
+ debug_assert_eq ! (
1244
+ align_offset, 1 ,
1245
+ "Aligning u8 to u16 should always be offset of 1?"
1246
+ ) ;
1247
+ unsafe {
1248
+ * map. get_unchecked_mut ( 0 ) =
1249
+ * COUNT_CLASS_LOOKUP . get_unchecked ( * map. get_unchecked ( 0 ) as usize ) ;
1250
+ }
1251
+ len -= 1 ;
1252
+ }
1253
+
1254
+ // Fix the last element
1238
1255
if ( len & 1 ) != 0 {
1239
1256
unsafe {
1240
1257
* map. get_unchecked_mut ( len - 1 ) =
@@ -1243,13 +1260,17 @@ where
1243
1260
}
1244
1261
1245
1262
let cnt = len / 2 ;
1246
- let map16 = unsafe { core:: slice:: from_raw_parts_mut ( map. as_mut_ptr ( ) as * mut u16 , cnt) } ;
1263
+
1264
+ let map16 = unsafe {
1265
+ slice:: from_raw_parts_mut ( map. as_mut_ptr ( ) . add ( align_offset) as * mut u16 , cnt)
1266
+ } ;
1247
1267
// 2022-07: Adding `enumerate` here increases execution speed/register allocation on x86_64.
1248
1268
for ( _i, item) in map16[ 0 ..cnt] . iter_mut ( ) . enumerate ( ) {
1249
1269
unsafe {
1250
1270
* item = * COUNT_CLASS_LOOKUP_16 . get_unchecked ( * item as usize ) ;
1251
1271
}
1252
1272
}
1273
+
1253
1274
self . base . post_exec ( state, input, exit_kind)
1254
1275
}
1255
1276
}
@@ -1776,9 +1797,9 @@ where
1776
1797
for map in & self . maps {
1777
1798
let slice = map. as_slice ( ) ;
1778
1799
let ptr = slice. as_ptr ( ) as * const u8 ;
1779
- let map_size = slice. len ( ) / core :: mem :: size_of :: < T > ( ) ;
1800
+ let map_size = slice. len ( ) / size_of :: < T > ( ) ;
1780
1801
unsafe {
1781
- hasher. write ( from_raw_parts ( ptr, map_size) ) ;
1802
+ hasher. write ( slice :: from_raw_parts ( ptr, map_size) ) ;
1782
1803
}
1783
1804
}
1784
1805
hasher. finish ( )
0 commit comments