Skip to content

Commit 9eee011

Browse files
committed
remove unused handle of table0 cache
1 parent ad98c5a commit 9eee011

4 files changed

Lines changed: 49 additions & 10 deletions

File tree

crates/wasmi/src/engine/executor/handler/utils.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,13 +638,14 @@ impl_load_entity_for_inst! {
638638
impl LoadEntity<Table0> for Inst {
639639
type Entity = TableEntity;
640640

641+
#[inline]
641642
fn load(self, _store: &mut StoreInner, _addr: Table0) -> &mut Self::Entity {
642643
// SAFETY: `addr` addresses an entry of this kind by translation invariant.
643-
let Some(entry) = (unsafe { self.as_ptr().get_table0() }) else {
644+
let Some(entity) = (unsafe { self.as_ptr().get_table0() }) else {
644645
unsafe { unreachable_unchecked!("missing table entity for table 0") }
645646
};
646647
// SAFETY: warmed at instantiation; the `_store` borrow scopes the reference.
647-
unsafe { &mut *entry.entity().as_ptr() }
648+
unsafe { &mut *entity.as_ptr() }
648649
}
649650
}
650651

crates/wasmi/src/instance/cache.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55
Handle,
66
Memory,
77
Table,
8+
core::CoreTable,
89
instance::handle::{AnyHandle, HasHandleKind},
910
memory::DataSegment,
1011
store::StoreInner,
@@ -23,7 +24,7 @@ use core::{
2324
///
2425
/// This is the type-erased storage type of an instance's `handles` buffer, which mixes all
2526
/// handle kinds. Access it as a [`HandleAndEntity<T>`] to get at the handle or entity.
26-
#[derive(Debug, Clone)]
27+
#[derive(Debug)]
2728
pub struct AnyHandleAndEntity {
2829
/// The cached entity pointer, warmed up at instantiation.
2930
entity: NonNull<AnyEntity>,
@@ -46,6 +47,41 @@ unsafe impl Send for AnyHandleAndEntity {}
4647
// `&AnyHandleAndEntity` across threads cannot by itself race on entity data.
4748
unsafe impl Sync for AnyHandleAndEntity {}
4849

50+
/// The cached entity pointer of an instance's `(table 0)`.
51+
///
52+
/// # Note
53+
///
54+
/// Unlike [`HandleAndEntity`] this drops the handle: `(table 0)` is only ever resolved to its
55+
/// entity, and halving the field keeps the instance header small.
56+
#[derive(Debug, Copy, Clone)]
57+
#[repr(transparent)]
58+
pub struct Table0Ptr(NonNull<CoreTable>);
59+
60+
// SAFETY: same argument as for `AnyHandleAndEntity`: the pointee is owned by the very
61+
// `StoreInner` that (transitively) owns the instance holding this pointer, so it never
62+
// crosses a thread boundary on its own, and `StableArena` addresses survive a `Store` move.
63+
unsafe impl Send for Table0Ptr {}
64+
65+
// SAFETY: no safe method on `&Table0Ptr` reads or writes the pointee — `get` only hands out a
66+
// raw `NonNull` copy whose dereference is `unsafe` and the caller's contract against the
67+
// owning `Store`.
68+
unsafe impl Sync for Table0Ptr {}
69+
70+
impl Table0Ptr {
71+
/// Creates a new [`Table0Ptr`] from the warmed up `entity` pointer.
72+
pub fn new(entity: NonNull<CoreTable>) -> Self {
73+
Self(entity)
74+
}
75+
76+
/// Returns the cached entity pointer of `self`.
77+
///
78+
/// The returned pointer is only sound to dereference once the cache has been warmed up.
79+
#[inline]
80+
pub fn get(self) -> NonNull<CoreTable> {
81+
self.0
82+
}
83+
}
84+
4985
impl AnyHandleAndEntity {
5086
/// Creates a new [`AnyHandleAndEntity`] from the given `handle`.
5187
///
@@ -92,7 +128,7 @@ impl AnyHandleAndEntity {
92128
/// This is a view on an entry of an instance's `handles` buffer. Its constructors assert the
93129
/// handle kind of the entry — and validate it in debug builds — which is why
94130
/// [`HandleAndEntity::handle`] and [`HandleAndEntity::entity`] are safe and check nothing.
95-
#[derive(Debug, Clone)]
131+
#[derive(Debug)]
96132
#[repr(transparent)]
97133
pub struct HandleAndEntity<T: Handle> {
98134
/// The type-erased entry.

crates/wasmi/src/instance/entity.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use super::{
1010
InstanceEntityBuilder,
1111
InstanceLayout,
1212
MemoryAddr,
13+
Table0Ptr,
1314
TableAddr,
1415
ThinPtr,
1516
};
@@ -21,6 +22,7 @@ use crate::{
2122
Module,
2223
Table,
2324
collections::Map,
25+
core::CoreTable,
2426
memory::DataSegment,
2527
store::StoreInner,
2628
};
@@ -74,7 +76,7 @@ struct InstanceEntityHeader {
7476
state: InstanceState,
7577
exports: Map<Box<str>, Extern>,
7678
layout: InstanceLayout,
77-
table0: Option<HandleAndEntity<Table>>,
79+
table0: Option<Table0Ptr>,
7880
}
7981

8082
/// The byte offset of the `handles` buffer within an [`InstanceEntity`] allocation.
@@ -307,7 +309,7 @@ impl InstanceEntity {
307309
let entry = &self.handles[u32::from(addr) as usize];
308310
// Safety: the `InstanceLayout` only yields addresses of its own group.
309311
let entry = unsafe { entry.typed_ref::<Table>() };
310-
self.header.table0 = Some(entry.clone());
312+
self.header.table0 = Some(Table0Ptr::new(entry.entity()));
311313
}
312314
}
313315

@@ -487,9 +489,9 @@ impl ThinPtr<InstanceEntity> {
487489
unsafe { self.header() }.layout()
488490
}
489491

490-
/// Returns the [`HandleAndEntity`] for `(table 0)` if any.
491-
pub unsafe fn get_table0<'a>(self) -> Option<&'a HandleAndEntity<Table>> {
492-
unsafe { self.header() }.table0.as_ref()
492+
/// Returns the cached entity pointer for `(table 0)` if any.
493+
pub unsafe fn get_table0(self) -> Option<NonNull<CoreTable>> {
494+
unsafe { self.header() }.table0.map(Table0Ptr::get)
493495
}
494496

495497
impl_get_entry! {

crates/wasmi/src/instance/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub(crate) use self::builder::InstanceEntityBuilder;
2-
use self::cache::{AnyHandleAndEntity, HandleAndEntity};
2+
use self::cache::{AnyHandleAndEntity, HandleAndEntity, Table0Ptr};
33
pub use self::{
44
entity::InstanceEntity,
55
exports::{Export, ExportsIter, Extern, ExternType},

0 commit comments

Comments
 (0)