Skip to content

Commit e39b630

Browse files
committed
reduce implementor overhead to zero
1 parent ba7691b commit e39b630

File tree

3 files changed

+175
-105
lines changed

3 files changed

+175
-105
lines changed

libafl/src/feedbacks/map.rs

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,23 @@ use crate::{
3232
pub const MAPFEEDBACK_PREFIX: &str = "mapfeedback_metadata_";
3333

3434
/// A [`MapFeedback`] that implements the AFL algorithm using an [`OrReducer`] combining the bits for the history map and the bit from ``HitcountsMapObserver``.
35-
pub type AflMapFeedback<O, S, T> = MapFeedback<DifferentIsNovel, O, OrReducer, S, T>;
35+
pub type AflMapFeedback<O, S, T, A> = MapFeedback<DifferentIsNovel, O, OrReducer, S, T, A>;
3636

3737
/// A [`MapFeedback`] that strives to maximize the map contents.
38-
pub type MaxMapFeedback<O, S, T> = MapFeedback<DifferentIsNovel, O, MaxReducer, S, T>;
38+
pub type MaxMapFeedback<O, S, T, A> = MapFeedback<DifferentIsNovel, O, MaxReducer, S, T, A>;
3939
/// A [`MapFeedback`] that strives to minimize the map contents.
40-
pub type MinMapFeedback<O, S, T> = MapFeedback<DifferentIsNovel, O, MinReducer, S, T>;
40+
pub type MinMapFeedback<O, S, T, A> = MapFeedback<DifferentIsNovel, O, MinReducer, S, T, A>;
4141

4242
/// A [`MapFeedback`] that always returns `true` for `is_interesting`. Useful for tracing all executions.
43-
pub type AlwaysInterestingMapFeedback<O, S, T> = MapFeedback<AllIsNovel, O, NopReducer, S, T>;
43+
pub type AlwaysInterestingMapFeedback<O, S, T, A> = MapFeedback<AllIsNovel, O, NopReducer, S, T, A>;
4444

4545
/// A [`MapFeedback`] that strives to maximize the map contents,
4646
/// but only, if a value is larger than `pow2` of the previous.
47-
pub type MaxMapPow2Feedback<O, S, T> = MapFeedback<NextPow2IsNovel, O, MaxReducer, S, T>;
47+
pub type MaxMapPow2Feedback<O, S, T, A> = MapFeedback<NextPow2IsNovel, O, MaxReducer, S, T, A>;
4848
/// A [`MapFeedback`] that strives to maximize the map contents,
4949
/// but only, if a value is larger than `pow2` of the previous.
50-
pub type MaxMapOneOrFilledFeedback<O, S, T> = MapFeedback<OneOrFilledIsNovel, O, MaxReducer, S, T>;
50+
pub type MaxMapOneOrFilledFeedback<O, S, T, A> =
51+
MapFeedback<OneOrFilledIsNovel, O, MaxReducer, S, T, A>;
5152

5253
/// A `Reducer` function is used to aggregate values for the novelty search
5354
pub trait Reducer<T>: 'static
@@ -365,7 +366,7 @@ where
365366

366367
/// The most common AFL-like feedback type
367368
#[derive(Clone, Debug)]
368-
pub struct MapFeedback<N, O, R, S, T> {
369+
pub struct MapFeedback<N, O, R, S, T, A> {
369370
/// For tracking, always keep indexes and/or novelties, even if the map isn't considered `interesting`.
370371
always_track: bool,
371372
/// New indexes observed in the last observation
@@ -377,24 +378,26 @@ pub struct MapFeedback<N, O, R, S, T> {
377378
/// Name of the feedback as shown in the `UserStats`
378379
stats_name: String,
379380
/// Phantom Data of Reducer
380-
phantom: PhantomData<(N, O, R, S, T)>,
381+
phantom: PhantomData<(N, O, R, S, T, A)>,
381382
}
382383

383-
impl<N, O, R, S, T> UsesObserver<S> for MapFeedback<N, O, R, S, T>
384+
impl<N, O, R, S, T, A> UsesObserver<S> for MapFeedback<N, O, R, S, T, A>
384385
where
385386
S: UsesInput,
386387
O: Observer<S>,
388+
A: AsRef<O> + Observer<S>,
387389
{
388-
type Observer = O;
390+
type Observer = A;
389391
}
390392

391-
impl<N, O, R, S, T> Feedback<S> for MapFeedback<N, O, R, S, T>
393+
impl<N, O, R, S, T, A> Feedback<S> for MapFeedback<N, O, R, S, T, A>
392394
where
393395
N: IsNovel<T>,
394-
O: MapObserver<Entry = T> + for<'it> AsIter<'it, Item = T> + TrackingHinted,
396+
O: MapObserver<Entry = T> + for<'it> AsIter<'it, Item = T>,
395397
R: Reducer<T>,
396398
S: State + HasNamedMetadata,
397399
T: Default + Copy + Serialize + for<'de> Deserialize<'de> + PartialEq + Debug + 'static,
400+
A: AsRef<O> + TrackingHinted,
398401
{
399402
fn init_state(&mut self, state: &mut S) -> Result<(), Error> {
400403
// Initialize `MapFeedbackMetadata` with an empty vector and add it to the state.
@@ -448,7 +451,10 @@ where
448451
let meta = MapNoveltiesMetadata::new(novelties);
449452
testcase.add_metadata(meta);
450453
}
451-
let observer = observers.match_name::<O>(&self.observer_name).unwrap();
454+
let observer = observers
455+
.match_name::<A>(&self.observer_name)
456+
.unwrap()
457+
.as_ref();
452458
let initial = observer.initial();
453459
let map_state = state
454460
.named_metadata_map_mut()
@@ -460,7 +466,7 @@ where
460466
}
461467

462468
let history_map = map_state.history_map.as_mut_slice();
463-
if O::INDICES {
469+
if A::INDICES {
464470
let mut indices = Vec::new();
465471

466472
for (i, value) in observer
@@ -490,11 +496,12 @@ where
490496

491497
/// Specialize for the common coverage map size, maximization of u8s
492498
#[rustversion::nightly]
493-
impl<O, S> Feedback<S> for MapFeedback<DifferentIsNovel, O, MaxReducer, S, u8>
499+
impl<O, S, A> Feedback<S> for MapFeedback<DifferentIsNovel, O, MaxReducer, S, u8, A>
494500
where
495-
O: MapObserver<Entry = u8> + AsSlice<Entry = u8> + TrackingHinted,
501+
O: MapObserver<Entry = u8> + AsSlice<Entry = u8>,
496502
for<'it> O: AsIter<'it, Item = u8>,
497503
S: State + HasNamedMetadata,
504+
A: AsRef<O> + TrackingHinted,
498505
{
499506
#[allow(clippy::wrong_self_convention)]
500507
#[allow(clippy::needless_range_loop)]
@@ -515,7 +522,10 @@ where
515522

516523
let mut interesting = false;
517524
// TODO Replace with match_name_type when stable
518-
let observer = observers.match_name::<O>(&self.observer_name).unwrap();
525+
let observer = observers
526+
.match_name::<A>(&self.observer_name)
527+
.unwrap()
528+
.as_ref();
519529

520530
let map_state = state
521531
.named_metadata_map_mut()
@@ -632,14 +642,14 @@ where
632642
}
633643
}
634644

635-
impl<N, O, R, S, T> Named for MapFeedback<N, O, R, S, T> {
645+
impl<N, O, R, S, T, A> Named for MapFeedback<N, O, R, S, T, A> {
636646
#[inline]
637647
fn name(&self) -> &str {
638648
self.name.as_str()
639649
}
640650
}
641651

642-
impl<N, O, R, S, T> HasObserverName for MapFeedback<N, O, R, S, T>
652+
impl<N, O, R, S, T, A> HasObserverName for MapFeedback<N, O, R, S, T, A>
643653
where
644654
T: PartialEq + Default + Copy + 'static + Serialize + DeserializeOwned + Debug,
645655
R: Reducer<T>,
@@ -658,20 +668,22 @@ fn create_stats_name(name: &str) -> String {
658668
name.to_lowercase()
659669
}
660670

661-
impl<N, O, R, S, T> MapFeedback<N, O, R, S, T>
671+
impl<N, O, R, S, T, A> MapFeedback<N, O, R, S, T, A>
662672
where
663673
T: PartialEq + Default + Copy + 'static + Serialize + DeserializeOwned + Debug,
664674
R: Reducer<T>,
665-
O: MapObserver<Entry = T> + TrackingHinted,
675+
O: MapObserver<Entry = T>,
666676
for<'it> O: AsIter<'it, Item = T>,
667677
N: IsNovel<T>,
668678
S: UsesInput + HasNamedMetadata,
679+
A: AsRef<O> + TrackingHinted,
669680
{
670681
/// Create new `MapFeedback`
671682
#[must_use]
672-
pub fn new(map_observer: &O) -> Self {
683+
pub fn new(map_observer: &A) -> Self {
684+
let map_observer = map_observer.as_ref();
673685
Self {
674-
novelties: if O::NOVELTIES { Some(vec![]) } else { None },
686+
novelties: if A::NOVELTIES { Some(vec![]) } else { None },
675687
name: MAPFEEDBACK_PREFIX.to_string() + map_observer.name(),
676688
observer_name: map_observer.name().to_string(),
677689
stats_name: create_stats_name(map_observer.name()),
@@ -680,19 +692,6 @@ where
680692
}
681693
}
682694

683-
/// Create new `MapFeedback`
684-
#[must_use]
685-
pub fn with_names(name: &'static str, observer_name: &'static str) -> Self {
686-
Self {
687-
novelties: if O::NOVELTIES { Some(vec![]) } else { None },
688-
name: name.to_string(),
689-
observer_name: observer_name.to_string(),
690-
stats_name: create_stats_name(name),
691-
phantom: PhantomData,
692-
always_track: false,
693-
}
694-
}
695-
696695
/// For tracking, enable `always_track` mode, that also adds `novelties` or `indexes`,
697696
/// even if the map is not novel for this feedback.
698697
/// This is useful in combination with `load_initial_inputs_forced`, or other feedbacks.
@@ -704,9 +703,10 @@ where
704703
/// feedback is needed twice, but with a different history. Using `new()` always results in the
705704
/// same name and therefore also the same history.
706705
#[must_use]
707-
pub fn with_name(name: &'static str, map_observer: &O) -> Self {
706+
pub fn with_name(name: &'static str, map_observer: &A) -> Self {
707+
let map_observer = map_observer.as_ref();
708708
Self {
709-
novelties: if O::NOVELTIES { Some(vec![]) } else { None },
709+
novelties: if A::NOVELTIES { Some(vec![]) } else { None },
710710
name: name.to_string(),
711711
observer_name: map_observer.name().to_string(),
712712
stats_name: create_stats_name(name),

0 commit comments

Comments
 (0)