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:
- The total number of calls for this call site.
- The table index of the last indirect callee.
- 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_indirectWhen $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_indirectWhen 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
impl Clone for InstrumentationStrategy
Source§fn clone(&self) -> InstrumentationStrategy
fn clone(&self) -> InstrumentationStrategy
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl FromStr for InstrumentationStrategy
impl FromStr for InstrumentationStrategy
Source§impl PartialEq for InstrumentationStrategy
impl PartialEq for InstrumentationStrategy
impl Copy for InstrumentationStrategy
impl Eq for InstrumentationStrategy
impl StructuralPartialEq for InstrumentationStrategy
Auto Trait Implementations§
impl Freeze for InstrumentationStrategy
impl RefUnwindSafe for InstrumentationStrategy
impl Send for InstrumentationStrategy
impl Sync for InstrumentationStrategy
impl Unpin for InstrumentationStrategy
impl UnwindSafe for InstrumentationStrategy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.