Skip to content
Closed
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
5 changes: 3 additions & 2 deletions external-crates/move/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion external-crates/move/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async-trait = "0.1.42"
bcs = "0.1.4"
better_any = "0.1.1"
bitvec = "0.19.4"
bumpalo = "3.16.0"
bumpalo = "3.17.0"
byteorder = "1.4.3"
bytes = "1.0.1"
chrono = "0.4.19"
Expand Down
2 changes: 2 additions & 0 deletions external-crates/move/crates/move-core-types/src/vm_status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ pub enum StatusCode {
MEMORY_LIMIT_EXCEEDED = 4028,
VM_MAX_TYPE_NODES_REACHED = 4029,
VARIANT_TAG_MISMATCH = 4030,
PACKAGE_ARENA_LIMIT_REACHED = 4031,
INTERNER_LIMIT_REACHED = 4032,

// A reserved status to represent an unknown vm status.
// this is std::u64::MAX, but we can't pattern match on that, so put the hardcoded value in
Expand Down
6 changes: 6 additions & 0 deletions external-crates/move/crates/move-vm-config/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ pub struct VMConfig {
/// Maximal nodes which are allowed when converting to layout. This includes the types of
/// fields for struct types.
pub max_type_to_layout_nodes: Option<u64>,
/// Enable or disable bytecode optimization passes while caching bytecode in the Move Runtime.
pub optimize_bytecode: bool,
}

impl Default for VMConfig {
Expand All @@ -55,6 +57,10 @@ impl Default for VMConfig {
binary_config: BinaryConfig::with_extraneous_bytes_check(false),
rethrow_serialization_type_layout_errors: false,
max_type_to_layout_nodes: Some(512),
// FIXME FIXME FIXME
// FEATURE GATE THIS AFTER GAS BLOCKS
// FIXME FIXME FIXME
optimize_bytecode: false,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions external-crates/move/crates/move-vm-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ sha2.workspace = true
sha3.workspace = true
smallvec.workspace = true
tracing.workspace = true
move-abstract-interpreter.workspace = true

# referred to via path for execution versioning
move-bytecode-verifier = { path = "../move-bytecode-verifier" }
Expand Down
25 changes: 21 additions & 4 deletions external-crates/move/crates/move-vm-runtime/src/cache/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#![allow(unsafe_code)]

use move_binary_format::errors::{PartialVMError, PartialVMResult};
use move_core_types::vm_status::StatusCode;

use bumpalo::Bump;

// -------------------------------------------------------------------------------------------------
Expand All @@ -11,13 +14,21 @@ use bumpalo::Bump;

pub struct Arena(Bump);

/// Size of a package arena.
/// This is 10 megabytes, which should be more than enough room for any pacakge on chain.
/// FIXME: Test this limit and validate. See how large packages are in backtesting and double that
/// limit, setting it here.
const ARENA_SIZE: usize = 10_000_000;

// -------------------------------------------------------------------------------------------------
// Impls
// -------------------------------------------------------------------------------------------------

impl Default for Arena {
fn default() -> Self {
Self::new()
let bump = Bump::new();
bump.set_allocation_limit(Some(ARENA_SIZE));
Arena(bump)
}
}

Expand All @@ -30,9 +41,15 @@ impl Arena {
/// threads during this call. This should be fine as the translation step that uses an arena
/// should happen in a thread that holds that arena, with no other contention for allocation
/// into it, and nothing should allocate into a LoadedModule after it is loaded.
pub fn alloc_slice<T>(&self, items: impl ExactSizeIterator<Item = T>) -> *mut [T] {
let slice = self.0.alloc_slice_fill_iter(items);
slice as *mut [T]
pub fn alloc_slice<T>(
&self,
items: impl ExactSizeIterator<Item = T>,
) -> PartialVMResult<*mut [T]> {
if let Ok(slice) = self.0.try_alloc_slice_fill_iter(items) {
Ok(slice)
} else {
Err(PartialVMError::new(StatusCode::PACKAGE_ARENA_LIMIT_REACHED))
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,21 @@ use move_core_types::{
use lasso::{Spur, ThreadedRodeo};

/// A wrapper around a lasso ThreadedRoade with some niceties to make it easier to use in the VM.
#[derive(Debug, Default)]
#[derive(Debug)]
pub struct IdentifierInterner(ThreadedRodeo);

/// Maximum number of identifiers we can ever intern.
/// FIXME: Set to 1 billion, but should be experimentally determined based on actual run data.
const IDENTIFIER_SLOTS: usize = 1_000_000_000;

pub type IdentifierKey = Spur;

impl IdentifierInterner {
pub fn new() -> Self {
let rodeo = ThreadedRodeo::with_capacity(lasso::Capacity::for_strings(IDENTIFIER_SLOTS));
Self(rodeo)
}

/// Resolve a string in the interner or produce an invariant violation (as they should always be
/// there). The `key_type` is used to make a more-informative error message.
pub fn resolve_string(&self, key: &IdentifierKey, key_type: &str) -> PartialVMResult<String> {
Expand Down Expand Up @@ -46,10 +55,8 @@ impl IdentifierInterner {
fn get_or_intern_str(&self, string: &str) -> PartialVMResult<IdentifierKey> {
match self.0.try_get_or_intern(string) {
Ok(result) => Ok(result),
Err(err) => Err(
PartialVMError::new(StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR)
.with_message(format!("Failed to intern string {string}; error: {err:?}.")),
),
Err(err) => Err(PartialVMError::new(StatusCode::INTERNER_LIMIT_REACHED)
.with_message(format!("Failed to intern string {string}; error: {err:?}."))),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
// and publishing packages to the VM.

use crate::{
cache::identifier_interner::IdentifierInterner, jit, natives::functions::NativeFunctions,
shared::types::PackageStorageId, validation::verification,
jit, natives::functions::NativeFunctions, shared::types::PackageStorageId,
validation::verification,
};
use move_vm_config::runtime::VMConfig;
use parking_lot::RwLock;
Expand Down Expand Up @@ -44,7 +44,6 @@ pub struct MoveCache {
pub(crate) natives: Arc<NativeFunctions>,
pub(crate) vm_config: Arc<VMConfig>,
pub(crate) package_cache: Arc<RwLock<PackageCache>>,
pub(crate) string_cache: Arc<IdentifierInterner>,
}

// -------------------------------------------------------------------------------------------------
Expand All @@ -57,7 +56,6 @@ impl MoveCache {
natives,
vm_config,
package_cache: Arc::new(RwLock::new(HashMap::new())),
string_cache: Arc::new(IdentifierInterner::default()),
}
}

Expand Down Expand Up @@ -92,10 +90,6 @@ impl MoveCache {
pub fn package_cache(&self) -> &RwLock<PackageCache> {
&self.package_cache
}

pub fn string_interner(&self) -> &IdentifierInterner {
&self.string_cache
}
}

impl Package {
Expand Down Expand Up @@ -124,13 +118,11 @@ impl Clone for MoveCache {
natives,
vm_config,
package_cache,
string_cache,
} = self;
Self {
natives: natives.clone(),
vm_config: vm_config.clone(),
package_cache: package_cache.clone(),
string_cache: string_cache.clone(),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ pub struct DebugFlags {
pub function_list_sizes: bool,
pub function_resolution: bool,
pub eval_step: bool,
pub optimizer: bool,
}

pub const DEBUG_FLAGS: DebugFlags = DebugFlags {
function_list_sizes: true,
function_resolution: true,
eval_step: true,
function_list_sizes: false,
function_resolution: false,
eval_step: false,
optimizer: true,
};

#[cfg(debug_assertions)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub(crate) const TRACING_ENABLED: bool = true;
pub(crate) const TRACING_ENABLED: bool = false;

#[inline]
pub(crate) fn trace<'a, F: Fn(&mut VMTracer<'a>) -> ()>(tracer: &mut Option<VMTracer<'a>>, op: F) {
pub(crate) fn trace<'a, F: Fn(&mut VMTracer<'a>)>(tracer: &mut Option<VMTracer<'a>>, op: F) {
if TRACING_ENABLED {
if let Some(tracer) = tracer {
op(tracer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ impl<'a> VMTracer<'a> {

/// Snapshot the value at the root of a location. This is used to create the value snapshots
/// for TraceValue references.
#[allow(clippy::only_used_in_recursion)]
fn root_location_snapshot(
&self,
vtables: &VMDispatchTables,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3512,7 +3512,7 @@ impl Container {
})
.collect::<Option<Vec<_>>>()?;

let tag = tag.clone();
let tag = *tag;
let type_ = type_.clone();
let variant_name = variant_name.clone();
let variant = AnnVariant {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1134,9 +1134,9 @@ impl Type {
// Into
// -------------------------------------------------------------------------------------------------

impl Into<Opcodes> for &Bytecode {
fn into(self) -> Opcodes {
match self {
impl From<&Bytecode> for Opcodes {
fn from(val: &Bytecode) -> Self {
match val {
Bytecode::Pop => Opcodes::POP,
Bytecode::Ret => Opcodes::RET,
Bytecode::BrTrue(_) => Opcodes::BR_TRUE,
Expand Down
Loading
Loading