pub struct HotFn<A, M, F>where
F: HotFunction<A, M>,{ /* private fields */ }Expand description
A hot-reloadable function: HotFn::call runs the newest version the jump table maps.
Implementations§
Source§impl<A, M, F: HotFunction<A, M>> HotFn<A, M, F>
impl<A, M, F: HotFunction<A, M>> HotFn<A, M, F>
Sourcepub const fn current(f: F) -> HotFn<A, M, F>
pub const fn current(f: F) -> HotFn<A, M, F>
Wrap f, keyed on its call_it monomorphisation. Sound for any FnMut: a fn item, a
closure of any size, or a function pointer (which then dispatches as one call_it shared
by every pointer of that type; use HotFn::from_fn_ptr to key on the pointer itself).
Sourcepub fn from_fn_ptr(f: F) -> HotFn<A, M, F>where
F: FnPointer<A, M>,
pub fn from_fn_ptr(f: F) -> HotFn<A, M, F>where
F: FnPointer<A, M>,
Wrap the function pointer f, keyed on its own value: the jump table maps the pointed-to
function’s address to its patched version. F must be a non-higher-ranked
fn(A, ..) -> R of up to nine arguments (FnPointer); wrap anything else with
HotFn::current.
Sourcepub fn call(&mut self, args: A) -> F::Return
pub fn call(&mut self, args: A) -> F::Return
Call the function with args.
In a debug build this is one jump-table lookup (see HotFn::try_call): the patched
version runs when the installed table maps this function’s key, else the original. No
stale-call detection, no retry; panics propagate untouched. A release build calls the
function directly and never reads the table.
Sourcepub fn ptr_address(&self) -> HotFnPtr
pub fn ptr_address(&self) -> HotFnPtr
The address a call would currently reach: the jump table’s mapping for this function’s key
when one is installed and maps it, else the key itself. The key is the call_it address,
or for HotFn::from_fn_ptr the pointer’s value. A release build never reads the table
and always reports the key.
A runtime that memoizes state across patches can compare it between patches: an unchanged address means the state “above” the function is still valid. Tracking it over time is the caller’s job.
Sourcepub fn try_call(&mut self, args: A) -> Result<F::Return, Infallible>
pub fn try_call(&mut self, args: A) -> Result<F::Return, Infallible>
Call the function with args through one jump-table lookup.
Debug builds only: the key (the call_it address, or for HotFn::from_fn_ptr the
pointer’s value, with the aarch64 Android pointer tag stripped) is looked up in the
installed table; a hit calls the patched address, a miss or an empty table calls the
original, and the outcome is recorded for last_call_fell_through /
fall_through_count / missed_keys; a hit is counted by seam_hits. A release build
calls the function directly.
Never fails: the Result keeps subsecond’s call shape, and the error type is
Infallible.
Sourcepub unsafe fn try_call_with_ptr(
&mut self,
ptr: HotFnPtr,
args: A,
) -> Result<F::Return, Infallible>
pub unsafe fn try_call_with_ptr( &mut self, ptr: HotFnPtr, args: A, ) -> Result<F::Return, Infallible>
Call the function at ptr directly, bypassing the jump table.
ptr is consulted on every call, in every build profile (release included): the table is
never read and no fall-through is recorded.
§Safety
For a HotFn::current value, ptr must be this monomorphisation’s call_it (signature
fn(&mut F, A) -> F::Return) or its patched equivalent. For a HotFn::from_fn_ptr
value, ptr must be a function of type F: the pointer’s own target or its patched
equivalent. Either way the argument and return layouts (for HotFn::current, F’s own
layout too: a closure’s captures) must not have changed since ptr was taken.
HotFn::ptr_address on a HotFn built the same way returns such an address.