Add msize

This commit is contained in:
wborgeaud 2022-10-20 19:23:01 +02:00
parent 71ed3c43ac
commit 9982d79999
5 changed files with 57 additions and 30 deletions

View File

@ -393,3 +393,21 @@
%mstore_kernel_general_2
// stack: (empty)
%endmacro
%macro mload_main
// stack: offset
DUP1
// stack: offset, offset
%update_msize
// stack: offset
%mload_current(@SEGMENT_MAIN_MEMORY)
%endmacro
%macro mstore_main
// stack: offset, value
DUP1
// stack: offset, offset, value
%update_msize
// stack: offset, value
%mstore_current(@SEGMENT_MAIN_MEMORY)
%endmacro

View File

@ -45,3 +45,23 @@
%macro callvalue
%mload_context_metadata(@CTX_METADATA_CALL_VALUE)
%endmacro
%macro msize
%mload_context_metadata(@CTX_METADATA_MSIZE)
%endmacro
%macro update_msize
// stack: offset
%add_const(32)
// stack: 32 + offset
%div_const(32)
// stack: (offset+32)/32 = ceil_div_usize(offset+1, 32)
%mul_const(32)
// stack: ceil_div_usize(offset+1, 32)*32
%msize
// stack: current_msize, ceil_div_usize(offset+1, 32) * 32
%max
// stack: new_msize
%mstore_context_metadata(@CTX_METADATA_MSIZE)
%endmacro

View File

@ -23,7 +23,7 @@ pub(crate) enum ContextMetadata {
/// Pointer to the initial version of the state trie, at the creation of this context. Used when
/// we need to revert a context.
StateTrieCheckpointPointer = 9,
/// Size of active memory.
/// Size of the active main memory.
MSize = 10,
}

View File

@ -10,6 +10,7 @@ use plonky2_util::ceil_div_usize;
use crate::cpu::kernel::aggregator::KERNEL;
use crate::cpu::kernel::assembler::Kernel;
use crate::cpu::kernel::constants::context_metadata::ContextMetadata;
use crate::cpu::kernel::constants::global_metadata::GlobalMetadata;
use crate::cpu::kernel::constants::txn_fields::NormalizedTxnField;
use crate::generation::memory::{MemoryContextState, MemorySegmentState};
@ -46,9 +47,7 @@ impl InterpreterMemory {
mem
}
}
impl InterpreterMemory {
fn mload_general(&mut self, context: usize, segment: Segment, offset: usize) -> U256 {
let value = self.context_memory[context].segments[segment as usize].get(offset);
assert!(
@ -67,6 +66,16 @@ impl InterpreterMemory {
);
self.context_memory[context].segments[segment as usize].set(offset, value)
}
fn update_msize(&mut self, context: usize, offset: usize) {
let current_msize = self.context_memory[context].segments
[Segment::ContextMetadata as usize]
.get(ContextMetadata::MSize as usize);
let msize = ceil_div_usize(offset + 1, 32) * 32;
let new_msize = current_msize.max(msize.into());
self.context_memory[context].segments[Segment::ContextMetadata as usize]
.set(ContextMetadata::MSize as usize, new_msize)
}
}
pub struct Interpreter<'a> {
@ -502,6 +511,8 @@ impl<'a> Interpreter<'a> {
fn run_keccak_general(&mut self) {
let context = self.pop().as_usize();
let segment = Segment::all()[self.pop().as_usize()];
// Not strictly needed but here to avoid surprises with MSIZE.
assert_ne!(segment, Segment::MainMemory, "Call KECCAK256 instead.");
let offset = self.pop().as_usize();
let size = self.pop().as_usize();
let bytes = (offset..offset + size)
@ -582,7 +593,8 @@ impl<'a> Interpreter<'a> {
fn run_msize(&mut self) {
self.push(U256::from(
self.memory.context_memory[self.context].segments[Segment::MainMemory as usize].msize,
self.memory.context_memory[self.context].segments[Segment::ContextMetadata as usize]
.get(ContextMetadata::MSize as usize),
))
}

View File

@ -23,34 +23,19 @@ impl Default for MemoryState {
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Default, Debug)]
pub(crate) struct MemoryContextState {
/// The content of each memory segment.
pub segments: [MemorySegmentState; Segment::COUNT],
}
impl Default for MemoryContextState {
fn default() -> Self {
Self {
segments: Segment::all().map(|segment| MemorySegmentState {
content: vec![],
segment,
msize: 0,
}),
}
}
}
#[derive(Clone, Debug)]
#[derive(Clone, Default, Debug)]
pub(crate) struct MemorySegmentState {
pub content: Vec<U256>,
pub segment: Segment,
pub msize: usize,
}
impl MemorySegmentState {
pub(crate) fn get(&mut self, virtual_addr: usize) -> U256 {
self.update_msize(virtual_addr);
pub(crate) fn get(&self, virtual_addr: usize) -> U256 {
self.content
.get(virtual_addr)
.copied()
@ -58,17 +43,9 @@ impl MemorySegmentState {
}
pub(crate) fn set(&mut self, virtual_addr: usize, value: U256) {
assert_eq!(value >> self.segment.bit_range(), U256::zero());
self.update_msize(virtual_addr);
if virtual_addr >= self.content.len() {
self.content.resize(virtual_addr + 1, U256::zero());
}
self.content[virtual_addr] = value;
}
fn update_msize(&mut self, virtual_addr: usize) {
let word_size = 256 / self.segment.bit_range();
let new_msize = ceil_div_usize(virtual_addr + 1, word_size) * 32;
self.msize = self.msize.max(new_msize);
}
}