-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactoring interpreter and paranoid mode, introducing traits to allo… (
#15350) * Refactoring interpreter and paranoid mode, introducing traits to allow generic interpreter as well as compile time switch for the runtime type checks (formerly called paranoid mode) * lint * addressing comments * addressed other * missed null->no * missed null->no
- Loading branch information
Showing
7 changed files
with
1,019 additions
and
927 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
195 changes: 195 additions & 0 deletions
195
third_party/move/move-vm/runtime/src/frame_type_cache.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
// Copyright © Aptos Foundation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
use crate::loader::Resolver; | ||
use move_binary_format::{ | ||
errors::*, | ||
file_format::{ | ||
FieldInstantiationIndex, SignatureIndex, StructDefInstantiationIndex, | ||
StructVariantInstantiationIndex, VariantFieldInstantiationIndex, | ||
}, | ||
}; | ||
use move_core_types::gas_algebra::NumTypeNodes; | ||
use move_vm_types::loaded_data::runtime_types::Type; | ||
use std::collections::BTreeMap; | ||
|
||
#[derive(Default)] | ||
pub(crate) struct FrameTypeCache { | ||
struct_field_type_instantiation: | ||
BTreeMap<StructDefInstantiationIndex, Vec<(Type, NumTypeNodes)>>, | ||
struct_variant_field_type_instantiation: | ||
BTreeMap<StructVariantInstantiationIndex, Vec<(Type, NumTypeNodes)>>, | ||
struct_def_instantiation_type: BTreeMap<StructDefInstantiationIndex, (Type, NumTypeNodes)>, | ||
struct_variant_instantiation_type: | ||
BTreeMap<StructVariantInstantiationIndex, (Type, NumTypeNodes)>, | ||
/// For a given field instantiation, the: | ||
/// ((Type of the field, size of the field type) and (Type of its defining struct, | ||
/// size of its defining struct) | ||
field_instantiation: | ||
BTreeMap<FieldInstantiationIndex, ((Type, NumTypeNodes), (Type, NumTypeNodes))>, | ||
/// Same as above, bot for variant field instantiations | ||
variant_field_instantiation: | ||
BTreeMap<VariantFieldInstantiationIndex, ((Type, NumTypeNodes), (Type, NumTypeNodes))>, | ||
single_sig_token_type: BTreeMap<SignatureIndex, (Type, NumTypeNodes)>, | ||
} | ||
|
||
impl FrameTypeCache { | ||
#[inline(always)] | ||
fn get_or<K: Copy + Ord + Eq, V, F>( | ||
map: &mut BTreeMap<K, V>, | ||
idx: K, | ||
ty_func: F, | ||
) -> PartialVMResult<&V> | ||
where | ||
F: FnOnce(K) -> PartialVMResult<V>, | ||
{ | ||
match map.entry(idx) { | ||
std::collections::btree_map::Entry::Occupied(entry) => Ok(entry.into_mut()), | ||
std::collections::btree_map::Entry::Vacant(entry) => { | ||
let v = ty_func(idx)?; | ||
Ok(entry.insert(v)) | ||
}, | ||
} | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn get_field_type_and_struct_type( | ||
&mut self, | ||
idx: FieldInstantiationIndex, | ||
resolver: &Resolver, | ||
ty_args: &[Type], | ||
) -> PartialVMResult<((&Type, NumTypeNodes), (&Type, NumTypeNodes))> { | ||
let ((field_ty, field_ty_count), (struct_ty, struct_ty_count)) = | ||
Self::get_or(&mut self.field_instantiation, idx, |idx| { | ||
let struct_type = resolver.field_instantiation_to_struct(idx, ty_args)?; | ||
let struct_ty_count = NumTypeNodes::new(struct_type.num_nodes() as u64); | ||
let field_ty = resolver.get_generic_field_ty(idx, ty_args)?; | ||
let field_ty_count = NumTypeNodes::new(field_ty.num_nodes() as u64); | ||
Ok(((field_ty, field_ty_count), (struct_type, struct_ty_count))) | ||
})?; | ||
Ok(((field_ty, *field_ty_count), (struct_ty, *struct_ty_count))) | ||
} | ||
|
||
pub(crate) fn get_variant_field_type_and_struct_type( | ||
&mut self, | ||
idx: VariantFieldInstantiationIndex, | ||
resolver: &Resolver, | ||
ty_args: &[Type], | ||
) -> PartialVMResult<((&Type, NumTypeNodes), (&Type, NumTypeNodes))> { | ||
let ((field_ty, field_ty_count), (struct_ty, struct_ty_count)) = | ||
Self::get_or(&mut self.variant_field_instantiation, idx, |idx| { | ||
let info = resolver.variant_field_instantiation_info_at(idx); | ||
let struct_type = resolver.create_struct_instantiation_ty( | ||
&info.definition_struct_type, | ||
&info.instantiation, | ||
ty_args, | ||
)?; | ||
let struct_ty_count = NumTypeNodes::new(struct_type.num_nodes() as u64); | ||
let field_ty = resolver.instantiate_ty( | ||
&info.uninstantiated_field_ty, | ||
ty_args, | ||
&info.instantiation, | ||
)?; | ||
let field_ty_count = NumTypeNodes::new(field_ty.num_nodes() as u64); | ||
Ok(((field_ty, field_ty_count), (struct_type, struct_ty_count))) | ||
})?; | ||
Ok(((field_ty, *field_ty_count), (struct_ty, *struct_ty_count))) | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn get_struct_type( | ||
&mut self, | ||
idx: StructDefInstantiationIndex, | ||
resolver: &Resolver, | ||
ty_args: &[Type], | ||
) -> PartialVMResult<(&Type, NumTypeNodes)> { | ||
let (ty, ty_count) = Self::get_or(&mut self.struct_def_instantiation_type, idx, |idx| { | ||
let ty = resolver.get_generic_struct_ty(idx, ty_args)?; | ||
let ty_count = NumTypeNodes::new(ty.num_nodes() as u64); | ||
Ok((ty, ty_count)) | ||
})?; | ||
Ok((ty, *ty_count)) | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn get_struct_variant_type( | ||
&mut self, | ||
idx: StructVariantInstantiationIndex, | ||
resolver: &Resolver, | ||
ty_args: &[Type], | ||
) -> PartialVMResult<(&Type, NumTypeNodes)> { | ||
let (ty, ty_count) = | ||
Self::get_or(&mut self.struct_variant_instantiation_type, idx, |idx| { | ||
let info = resolver.get_struct_variant_instantiation_at(idx); | ||
let ty = resolver.create_struct_instantiation_ty( | ||
&info.definition_struct_type, | ||
&info.instantiation, | ||
ty_args, | ||
)?; | ||
let ty_count = NumTypeNodes::new(ty.num_nodes() as u64); | ||
Ok((ty, ty_count)) | ||
})?; | ||
Ok((ty, *ty_count)) | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn get_struct_fields_types( | ||
&mut self, | ||
idx: StructDefInstantiationIndex, | ||
resolver: &Resolver, | ||
ty_args: &[Type], | ||
) -> PartialVMResult<&[(Type, NumTypeNodes)]> { | ||
Ok(Self::get_or( | ||
&mut self.struct_field_type_instantiation, | ||
idx, | ||
|idx| { | ||
Ok(resolver | ||
.instantiate_generic_struct_fields(idx, ty_args)? | ||
.into_iter() | ||
.map(|ty| { | ||
let num_nodes = NumTypeNodes::new(ty.num_nodes() as u64); | ||
(ty, num_nodes) | ||
}) | ||
.collect::<Vec<_>>()) | ||
}, | ||
)?) | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn get_struct_variant_fields_types( | ||
&mut self, | ||
idx: StructVariantInstantiationIndex, | ||
resolver: &Resolver, | ||
ty_args: &[Type], | ||
) -> PartialVMResult<&[(Type, NumTypeNodes)]> { | ||
Ok(Self::get_or( | ||
&mut self.struct_variant_field_type_instantiation, | ||
idx, | ||
|idx| { | ||
Ok(resolver | ||
.instantiate_generic_struct_variant_fields(idx, ty_args)? | ||
.into_iter() | ||
.map(|ty| { | ||
let num_nodes = NumTypeNodes::new(ty.num_nodes() as u64); | ||
(ty, num_nodes) | ||
}) | ||
.collect::<Vec<_>>()) | ||
}, | ||
)?) | ||
} | ||
|
||
#[inline(always)] | ||
pub(crate) fn get_signature_index_type( | ||
&mut self, | ||
idx: SignatureIndex, | ||
resolver: &Resolver, | ||
ty_args: &[Type], | ||
) -> PartialVMResult<(&Type, NumTypeNodes)> { | ||
let (ty, ty_count) = Self::get_or(&mut self.single_sig_token_type, idx, |idx| { | ||
let ty = resolver.instantiate_single_type(idx, ty_args)?; | ||
let ty_count = NumTypeNodes::new(ty.num_nodes() as u64); | ||
Ok((ty, ty_count)) | ||
})?; | ||
Ok((ty, *ty_count)) | ||
} | ||
} |
Oops, something went wrong.