more inlined

This commit is contained in:
Dominik Maier 2020-12-11 08:51:19 +01:00
parent ffdaaa8fcc
commit c7856a1feb
7 changed files with 81 additions and 0 deletions

View File

@ -33,11 +33,13 @@ where
R: Rand,
{
/// Returns the number of elements
#[inline]
fn count(&self) -> usize {
self.entries().len()
}
/// Add an entry to the corpus and return its index
#[inline]
fn add(&mut self, testcase: Testcase<I>) -> usize {
self.entries_mut().push(RefCell::new(testcase));
self.entries().len() - 1
@ -56,11 +58,13 @@ where
}
/// Get by id
#[inline]
fn get(&self, idx: usize) -> &RefCell<Testcase<I>> {
&self.entries()[idx]
}
/// Removes an entry from the corpus, returning it if it was present.
#[inline]
fn remove(&mut self, entry: &Testcase<I>) -> Option<Testcase<I>> {
match self
.entries()
@ -73,6 +77,7 @@ where
}
/// Gets a random entry
#[inline]
fn random_entry(&self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
if self.count() == 0 {
Err(AflError::Empty("No entries in corpus".to_owned()))
@ -142,6 +147,7 @@ where
R: Rand,
{
/// Gets the next entry
#[inline]
fn next(&mut self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
if self.count() == 0 {
Err(AflError::Empty("No entries in corpus".to_owned()))
@ -154,6 +160,7 @@ where
}
/// Returns the testacase we currently use
#[inline]
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize) {
(self.get(self.pos), self.pos)
}
@ -192,9 +199,11 @@ where
I: Input,
R: Rand,
{
#[inline]
fn entries(&self) -> &[RefCell<Testcase<I>>] {
&self.entries
}
#[inline]
fn entries_mut(&mut self) -> &mut Vec<RefCell<Testcase<I>>> {
&mut self.entries
}
@ -221,11 +230,13 @@ where
self.entries.len() - 1
}
#[inline]
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize) {
(self.get(self.pos), self.pos)
}
/// Gets the next entry
#[inline]
fn next(&mut self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
if self.count() == 0 {
Err(AflError::Empty("No entries in corpus".to_owned()))
@ -275,9 +286,11 @@ where
I: Input,
R: Rand,
{
#[inline]
fn entries(&self) -> &[RefCell<Testcase<I>>] {
self.corpus.entries()
}
#[inline]
fn entries_mut(&mut self) -> &mut Vec<RefCell<Testcase<I>>> {
self.corpus.entries_mut()
}
@ -290,30 +303,36 @@ where
R: Rand,
{
/// Returns the number of elements
#[inline]
fn count(&self) -> usize {
self.corpus.count()
}
#[inline]
fn add(&mut self, entry: Testcase<I>) -> usize {
self.corpus.add(entry)
}
/// Removes an entry from the corpus, returning it if it was present.
#[inline]
fn remove(&mut self, entry: &Testcase<I>) -> Option<Testcase<I>> {
self.corpus.remove(entry)
}
/// Gets a random entry
#[inline]
fn random_entry(&self, rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
self.corpus.random_entry(rand)
}
/// Returns the testacase we currently use
#[inline]
fn current_testcase(&self) -> (&RefCell<Testcase<I>>, usize) {
(self.get(self.pos - 1), self.pos - 1)
}
/// Gets the next entry
#[inline]
fn next(&mut self, _rand: &mut R) -> Result<(&RefCell<Testcase<I>>, usize), AflError> {
self.pos += 1;
if self.corpus.count() == 0 {
@ -343,10 +362,12 @@ where
}
}
#[inline]
pub fn cycles(&self) -> u64 {
self.cycles
}
#[inline]
pub fn pos(&self) -> usize {
self.pos
}

View File

@ -84,49 +84,67 @@ where
}
/// Get the input, if any
#[inline]
pub fn input(&self) -> &Option<I> {
&self.input
}
/// Get the input, if any (mutable)
#[inline]
pub fn input_mut(&mut self) -> &mut Option<I> {
&mut self.input
}
/// Set the input
#[inline]
pub fn set_input(&mut self, input: I) {
self.input = Some(input);
}
/// Get the filename, if any
#[inline]
pub fn filename(&self) -> &Option<String> {
&self.filename
}
/// Get the filename, if any (mutable)
#[inline]
pub fn filename_mut(&mut self) -> &mut Option<String> {
&mut self.filename
}
/// Set the filename
#[inline]
pub fn set_filename(&mut self, filename: String) {
self.filename = Some(filename);
}
/// Get the fitness
#[inline]
pub fn fitness(&self) -> u32 {
self.fitness
}
/// Get the fitness (mutable)
#[inline]
pub fn fitness_mut(&mut self) -> &mut u32 {
&mut self.fitness
}
/// Set the fitness
#[inline]
pub fn set_fitness(&mut self, fitness: u32) {
self.fitness = fitness;
}
/// Get all the metadatas into an HashMap (mutable)
#[inline]
pub fn metadatas(&mut self) -> &mut SerdeAnyMap {
&mut self.metadatas
}
/// Add a metadata
#[inline]
pub fn add_metadata<TM>(&mut self, meta: TM)
where
TM: TestcaseMetadata + 'static,
@ -135,6 +153,7 @@ where
}
/// Create a new Testcase instace given an input
#[inline]
pub fn new<T>(input: T) -> Self
where
T: Into<I>,
@ -148,6 +167,7 @@ where
}
/// Create a new Testcase instace given an input and a filename
#[inline]
pub fn with_filename(input: I, filename: String) -> Self {
Testcase {
input: Some(input),
@ -157,6 +177,7 @@ where
}
}
#[inline]
pub fn default() -> Self {
Testcase {
input: None,

View File

@ -44,22 +44,27 @@ where
R: Rand,
{
/// Get executions
#[inline]
pub fn executions(&self) -> usize {
self.executions
}
/// Set executions
#[inline]
pub fn set_executions(&mut self, executions: usize) {
self.executions = executions
}
#[inline]
pub fn start_time(&self) -> u64 {
self.start_time
}
#[inline]
pub fn set_start_time(&mut self, ms: u64) {
self.start_time = ms
}
#[inline]
pub fn executions_over_seconds(&self) -> u64 {
let elapsed = current_milliseconds() - self.start_time();
if elapsed == 0 {
@ -74,31 +79,37 @@ where
}
/// Get all the metadatas into an HashMap
#[inline]
pub fn metadatas(&self) -> &HashMap<&'static str, Box<dyn StateMetadata>> {
&self.metadatas
}
/// Get all the metadatas into an HashMap (mutable)
#[inline]
pub fn metadatas_mut(&mut self) -> &mut HashMap<&'static str, Box<dyn StateMetadata>> {
&mut self.metadatas
}
/// Add a metadata
#[inline]
pub fn add_metadata(&mut self, meta: Box<dyn StateMetadata>) {
self.metadatas_mut().insert(meta.name(), meta);
}
/// Returns vector of feebacks
#[inline]
pub fn feedbacks(&self) -> &[Box<dyn Feedback<I>>] {
&self.feedbacks
}
/// Returns vector of feebacks (mutable)
#[inline]
pub fn feedbacks_mut(&mut self) -> &mut Vec<Box<dyn Feedback<I>>> {
&mut self.feedbacks
}
/// Adds a feedback
#[inline]
pub fn add_feedback(&mut self, feedback: Box<dyn Feedback<I>>) {
self.feedbacks_mut().push(feedback);
}
@ -124,6 +135,7 @@ where
}
/// Resets all current feedbacks
#[inline]
pub fn discard_input(&mut self, input: &I) -> Result<(), AflError> {
// TODO: This could probably be automatic in the feedback somehow?
for feedback in self.feedbacks_mut() {
@ -133,6 +145,7 @@ where
}
/// Creates a new testcase, appending the metadata from each feedback
#[inline]
pub fn input_to_testcase(&mut self, input: I, fitness: u32) -> Result<Testcase<I>, AflError> {
let mut testcase = Testcase::new(input);
testcase.set_fitness(fitness);
@ -144,6 +157,7 @@ where
}
/// Create a testcase from this input, if it's intersting
#[inline]
pub fn testcase_if_interesting(
&mut self,
input: I,
@ -158,6 +172,7 @@ where
}
/// Adds this input to the corpus, if it's intersting
#[inline]
pub fn add_if_interesting<C>(
&mut self,
corpus: &mut C,

View File

@ -164,6 +164,7 @@ impl LlmpMsg {
}
/// Gets the buffer from this message as slice, with the corrent length.
#[inline]
pub fn as_slice(&self, map: &LlmpSharedMap) -> Result<&[u8], AflError> {
unsafe {
if self.in_map(map) {
@ -175,6 +176,7 @@ impl LlmpMsg {
}
/// Returns true, if the pointer is, indeed, in the page of this shared map.
#[inline]
pub fn in_map(&self, map: &LlmpSharedMap) -> bool {
unsafe {
let buf_ptr = self.buf.as_ptr();
@ -286,6 +288,7 @@ unsafe fn shmem2page(afl_shmem: &AflShmem) -> *mut LlmpPage {
}
/// Return, if a msg is contained in the current page
#[inline]
unsafe fn llmp_msg_in_page(page: *mut LlmpPage, msg: *mut LlmpMsg) -> bool {
/* DBG("llmp_msg_in_page %p within %p-%p\n", msg, page, page + page->size_total); */
return (page as *mut u8) < msg as *mut u8
@ -506,6 +509,7 @@ impl LlmpSender {
/// Commit the message last allocated by alloc_next to the queue.
/// After commiting, the msg shall no longer be altered!
/// It will be read by the consuming threads (broker->clients or client->broker)
#[inline(never)] // Not inlined to make cpu-level reodering (hopefully?) improbable
unsafe fn send(&mut self, msg: *mut LlmpMsg) -> Result<(), AflError> {
if self.last_msg_sent == msg {
panic!("Message sent twice!");
@ -720,6 +724,7 @@ impl LlmpReceiver {
}
/// Returns the next message, tag, buf, if avaliable, else None
#[inline]
pub fn recv_buf(&mut self) -> Result<Option<(u32, &[u8])>, AflError> {
unsafe {
Ok(match self.recv()? {
@ -730,6 +735,7 @@ impl LlmpReceiver {
}
/// Returns the next message, tag, buf, looping until it becomes available
#[inline]
pub fn recv_buf_blocking(&mut self) -> Result<(u32, &[u8]), AflError> {
unsafe {
let msg = self.recv_blocking()?;
@ -827,6 +833,7 @@ impl LlmpBroker {
}
/// broker broadcast to its own page for all others to read */
#[inline]
unsafe fn handle_new_msgs(&mut self, client_id: u32) -> Result<(), AflError> {
let mut next_id = self.llmp_clients.len() as u32;
@ -885,6 +892,7 @@ impl LlmpBroker {
/// The broker walks all pages and looks for changes, then broadcasts them on
/// its own shared page, once.
#[inline]
pub fn once(&mut self) -> Result<(), AflError> {
compiler_fence(Ordering::SeqCst);
for i in 0..self.llmp_clients.len() {
@ -1070,28 +1078,33 @@ impl LlmpClient {
/// A client receives a broadcast message.
/// Returns null if no message is availiable
#[inline]
pub unsafe fn recv(&mut self) -> Result<Option<*mut LlmpMsg>, AflError> {
self.llmp_in.recv()
}
/// A client blocks/spins until the next message gets posted to the page,
/// then returns that message.
#[inline]
pub unsafe fn recv_blocking(&mut self) -> Result<*mut LlmpMsg, AflError> {
self.llmp_in.recv_blocking()
}
/// The current page could have changed in recv (EOP)
/// Alloc the next message, internally handling end of page by allocating a new one.
#[inline]
pub unsafe fn alloc_next(&mut self, buf_len: usize) -> Result<*mut LlmpMsg, AflError> {
self.llmp_out.alloc_next(buf_len)
}
/// Returns the next message, tag, buf, if avaliable, else None
#[inline]
pub fn recv_buf(&mut self) -> Result<Option<(u32, &[u8])>, AflError> {
self.llmp_in.recv_buf()
}
/// Receives a buf from the broker, looping until a messages becomes avaliable
#[inline]
pub fn recv_buf_blocking(&mut self) -> Result<(u32, &[u8]), AflError> {
self.llmp_in.recv_buf_blocking()
}

View File

@ -27,11 +27,13 @@ where
fn is_interesting(&mut self, input: &I, observers: &NamedSerdeAnyMap) -> Result<u32, AflError>;
/// Append to the testcase the generated metadata in case of a new corpus item
#[inline]
fn append_metadata(&mut self, _testcase: &mut Testcase<I>) -> Result<(), AflError> {
Ok(())
}
/// Discard the stored metadata in case that the testcase is not added to the corpus
#[inline]
fn discard_metadata(&mut self, _input: &I) -> Result<(), AflError> {
Ok(())
}

View File

@ -14,6 +14,7 @@ where
R: Rand,
{
/// Compute the number of iterations used to apply stacked mutations
#[inline]
fn iterations(&mut self, rand: &mut R, _input: &I) -> u64 {
1 << (1 + rand.below(6))
}
@ -113,9 +114,12 @@ where
I: Input,
R: Rand,
{
#[inline]
fn max_size(&self) -> usize {
self.max_size
}
#[inline]
fn set_max_size(&mut self, max_size: usize) {
self.max_size = max_size;
}

View File

@ -13,12 +13,16 @@ use crate::AflError;
/// Observers observe different information about the target.
/// They can then be used by various sorts of feedback.
pub trait Observer: SerdeAny + 'static {
/// The testcase finished execution, calculate any changes.
#[inline]
fn flush(&mut self) -> Result<(), AflError> {
Ok(())
}
fn reset(&mut self) -> Result<(), AflError>;
#[inline]
fn post_exec(&mut self) -> Result<(), AflError> {
Ok(())
}
@ -49,6 +53,7 @@ where
fn set_initial(&mut self, initial: T);
/// Reset the map
#[inline]
fn reset_map(&mut self) -> Result<(), AflError> {
// Normal memset, see https://rust.godbolt.org/z/Trs5hv
let initial = self.initial();