Skip to content

Commit 7749cf3

Browse files
Carbocardedomenukk
andauthored
Use static for count class lookup tables (#3453)
* Use static for count class lookup tables This improves performance on fuzzbench with libpng on an m1 mac mini. Before: 98.65k execs/sec After: 115.0k execs/sec * Remove unused enumerate index --------- Co-authored-by: Dominik Maier <[email protected]>
1 parent 5af963c commit 7749cf3

File tree

2 files changed

+16
-35
lines changed

2 files changed

+16
-35
lines changed

crates/libafl/src/executors/sand.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use libafl_bolts::{
1616
use super::{Executor, ExecutorsTuple, ExitKind, HasObservers, HasTimeout};
1717
use crate::{
1818
HasNamedMetadata,
19-
observers::{MapObserver, classify_counts, init_count_class_16},
19+
observers::{MapObserver, classify_counts},
2020
};
2121

2222
/// The execution pattern of the [`SANDExecutor`]. The default value used in our paper is
@@ -75,9 +75,6 @@ where
7575
bitmap_size: usize,
7676
pattern: SANDExecutionPattern,
7777
) -> Self {
78-
if matches!(pattern, SANDExecutionPattern::UniqueTrace) {
79-
init_count_class_16();
80-
}
8178
Self {
8279
executor,
8380
sand_executors: sand_extra_executors,

crates/libafl/src/observers/map/hitcount_map.rs

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,21 @@ static COUNT_CLASS_LOOKUP: [u8; 256] = [
3636
];
3737

3838
/// Hitcounts class lookup for 16-byte values
39-
static mut COUNT_CLASS_LOOKUP_16: Vec<u16> = vec![];
40-
41-
/// Initialize the 16-byte hitcounts map
42-
pub(crate) fn init_count_class_16() {
43-
// # Safety
44-
//
45-
// Calling this from multiple threads may be racey and hence leak 65k mem or even create a broken lookup vec.
46-
// We can live with that.
47-
unsafe {
48-
let count_class_lookup_16 = &raw mut COUNT_CLASS_LOOKUP_16;
49-
let count_class_lookup_16 = &mut *count_class_lookup_16;
50-
51-
if !count_class_lookup_16.is_empty() {
52-
return;
53-
}
54-
55-
*count_class_lookup_16 = vec![0; 65536];
56-
for i in 0..256 {
57-
for j in 0..256 {
58-
count_class_lookup_16[(i << 8) + j] =
59-
(u16::from(COUNT_CLASS_LOOKUP[i]) << 8) | u16::from(COUNT_CLASS_LOOKUP[j]);
60-
}
39+
static COUNT_CLASS_LOOKUP_16: [u16; 256 * 256] = {
40+
let mut seq = [0u16; 256 * 256];
41+
let mut lo_bits = 0;
42+
let mut hi_bits = 0;
43+
while lo_bits < 256 {
44+
while hi_bits < 256 {
45+
seq[hi_bits << 8 | lo_bits] =
46+
(COUNT_CLASS_LOOKUP[hi_bits] as u16) << 8 | COUNT_CLASS_LOOKUP[lo_bits] as u16;
47+
hi_bits += 1;
6148
}
49+
hi_bits = 0;
50+
lo_bits += 1;
6251
}
63-
}
52+
seq
53+
};
6454

6555
/// AFL-style classify counts
6656
#[inline]
@@ -94,14 +84,10 @@ pub(crate) fn classify_counts(map: &mut [u8]) {
9484

9585
let map16 =
9686
unsafe { slice::from_raw_parts_mut(map.as_mut_ptr().add(align_offset) as *mut u16, cnt) };
97-
let count_class_lookup_16 = &raw mut COUNT_CLASS_LOOKUP_16;
9887

99-
// 2022-07: Adding `enumerate` here increases execution speed/register allocation on x86_64.
100-
#[expect(clippy::unused_enumerate_index)]
101-
for (_i, item) in map16[0..cnt].iter_mut().enumerate() {
88+
for item in &mut map16[0..cnt] {
10289
unsafe {
103-
let count_class_lookup_16 = &mut *count_class_lookup_16;
104-
*item = *(*count_class_lookup_16).get_unchecked(*item as usize);
90+
*item = *(COUNT_CLASS_LOOKUP_16).get_unchecked(*item as usize);
10591
}
10692
}
10793
}
@@ -158,7 +144,6 @@ where
158144
impl<M> HitcountsMapObserver<M> {
159145
/// Creates a new [`MapObserver`]
160146
pub fn new(base: M) -> Self {
161-
init_count_class_16();
162147
Self { base }
163148
}
164149
}
@@ -375,7 +360,6 @@ where
375360
impl<M> HitcountsIterableMapObserver<M> {
376361
/// Creates a new [`MapObserver`]
377362
pub fn new(base: M) -> Self {
378-
init_count_class_16();
379363
Self { base }
380364
}
381365
}

0 commit comments

Comments
 (0)