InstrumentationStrategy

Enum InstrumentationStrategy 

Source
pub enum InstrumentationStrategy {
    ThreeGlobals,
    HostCalls,
}
Expand description

The instrumentation strategy for recording profiling data.

Variants§

§

ThreeGlobals

A low-overhead but imprecise instrumentation strategy that records profiling information in globals.

This strategy adds three globals per indirect call site:

  1. The total number of calls for this call site.
  2. The table index of the last indirect callee.
  3. The number of times the last callee has been called.

A call_indirect then becomes the following sequence:

;; $total_count += 1
global.get $total_count
i64.const 1
i64.add
global.set $total_count

;; if $last_callee != $current_callee {
;;     $last_callee = $current_callee
;;     $last_callee_count = 0
;; }
local.tee $current_callee
global.get $last_callee
i32.eq
i32.eqz
if
    local.get $current_callee
    global.set $last_callee
    i64.const 0
    global.set $last_callee_count
end

;; $last_callee_count += 1
global.get $last_callee_count
i64.const 1
i64.add
global.set $last_callee_count

;; Finally, do the actual indirect call.
local.get $current_callee
call_indirect

When $last_callee_count / $total_count is high enough, then winlining table[$last_callee] is beneficial.

Note that this strategy is imprecise and is easily defeated by the following sequence of calls:

  • Indirect call to f
  • Indirect call to f
  • Indirect call to f
  • … many, many times …
  • Indirect call to f
  • Indirect call to g

In this case, winlining f would be beneficial, but we don’t learn that because the last call to g clears that information away.

However, this instrumentation’s overhead is low enough that it is practical to run the instrumented Wasm programs in many production scenarios.

§

HostCalls

A precise but high-overhead strategy that inserts calls out to the host.

This strategy inserts a call to an imported host function before every call_indirect instruction, letting the host record precise information about the number of indirect calls per call site and which function was the callee.

The imported instrumentation function has the following module, name, and signature:

(import "winliner" "add_indirect_call" (func (param i32 i32)))

Each call_indirect is then transformed into the following sequence:

;; Call out to the host to record the indirect call.
local.tee $current_callee
i32.const 1234 ;; This is the 1234th indirect call site.
call $winliner_add_indirect_call

;; Finally, do the actual indirect call.
local.get $current_callee
call_indirect

When using this strategy, it is your responsibility to provide the host function that this instrumentation inserts calls to, and to build up the profiles using the ProfileBuilder type.

Note that, while this strategy yields precise profiling information, it incurs fairly high overheads, likely making it unacceptable to run the instrumented Wasm programs in production scenarios.

Trait Implementations§

Source§

impl Clone for InstrumentationStrategy

Source§

fn clone(&self) -> InstrumentationStrategy

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl FromStr for InstrumentationStrategy

Source§

type Err = Error

The associated error which can be returned from parsing.
Source§

fn from_str(s: &str) -> Result<Self>

Parses a string s to return a value of this type. Read more
Source§

impl PartialEq for InstrumentationStrategy

Source§

fn eq(&self, other: &InstrumentationStrategy) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for InstrumentationStrategy

Source§

impl Eq for InstrumentationStrategy

Source§

impl StructuralPartialEq for InstrumentationStrategy

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.