Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 11 additions & 16 deletions ceno_emul/src/tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
};
use ceno_rt::WORD_SIZE;
use smallvec::SmallVec;
use std::{collections::BTreeMap, fmt, mem};
use std::{collections::BTreeMap, fmt, mem, sync::Arc};

/// An instruction and its context in an execution trace. That is concrete values of registers and memory.
///
Expand Down Expand Up @@ -88,6 +88,14 @@ pub trait Tracer {

fn new(platform: &Platform) -> Self;

fn with_next_accesses(platform: &Platform, next_accesses: Option<Arc<NextCycleAccess>>) -> Self
where
Self: Sized,
{
let _ = next_accesses;
Self::new(platform)
}

fn advance(&mut self) -> Self::Record;

fn is_busy_loop(&self, record: &Self::Record) -> bool;
Expand Down Expand Up @@ -541,10 +549,6 @@ pub struct FullTracer {

// keep track of each address that the cycle when they were last accessed.
latest_accesses: LatestAccesses,

// keep track of each cycle that accessed addresses in the future with respective future cycles.
// format: [current cycle -> Vec<(WordAddr, Cycle)>]
next_accesses: NextCycleAccess,
}

impl FullTracer {
Expand All @@ -565,7 +569,6 @@ impl FullTracer {
},
platform: platform.clone(),
latest_accesses: LatestAccesses::new(platform),
next_accesses: NextCycleAccess::new(ACCESSED_CHUNK_SIZE),
max_heap_addr_access: ByteAddr::from(platform.heap.start),
max_hint_addr_access: ByteAddr::from(platform.hints.start),
}
Expand Down Expand Up @@ -711,21 +714,13 @@ impl FullTracer {
#[inline(always)]
pub fn track_access(&mut self, addr: WordAddr, subcycle: Cycle) -> Cycle {
let cur_cycle = self.record.cycle + subcycle;
let prev_cycle = self.latest_accesses.track(addr, cur_cycle);
self.next_accesses
.get_or_create(prev_cycle as usize)
.push((addr, cur_cycle));
prev_cycle
self.latest_accesses.track(addr, cur_cycle)
}

pub fn final_accesses(&self) -> &LatestAccesses {
&self.latest_accesses
}

pub fn next_accesses(self) -> NextCycleAccess {
self.next_accesses
}

/// Return the cycle of the pending instruction (after the last completed step).
pub fn cycle(&self) -> Cycle {
self.record.cycle
Expand Down Expand Up @@ -1010,7 +1005,7 @@ impl Tracer for FullTracer {
}

fn into_next_accesses(self) -> NextCycleAccess {
self.next_accesses()
unimplemented!("FullTracer does not record next access metadata")
}

fn cycle(&self) -> Cycle {
Expand Down
12 changes: 10 additions & 2 deletions ceno_emul/src/vm_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
platform::Platform,
rv32im::{Instruction, TrapCause},
syscalls::{SyscallEffects, handle_syscall},
tracer::{Change, FullTracer, Tracer},
tracer::{Change, FullTracer, NextCycleAccess, Tracer},
};
use anyhow::{Result, anyhow};
use std::{iter::from_fn, ops::Deref, sync::Arc};
Expand Down Expand Up @@ -47,6 +47,14 @@ impl<T: Tracer> VMState<T> {
pub const REG_COUNT: usize = VM_REG_COUNT;

pub fn new_with_tracer(platform: Platform, program: Arc<Program>) -> Self {
Self::new_with_tracer_and_next_accesses(platform, program, None)
}

pub fn new_with_tracer_and_next_accesses(
platform: Platform,
program: Arc<Program>,
next_accesses: Option<Arc<NextCycleAccess>>,
) -> Self {
let pc = program.entry;

let mut vm = Self {
Expand All @@ -59,7 +67,7 @@ impl<T: Tracer> VMState<T> {
),
registers: [0; VM_REG_COUNT],
halt_state: None,
tracer: T::new(&platform),
tracer: T::with_next_accesses(&platform, next_accesses),
};

for (&addr, &value) in &program.image {
Expand Down