// Actual wasm code execution -- this is run on the target thread
// in the thread pool.
Actual wasm code execution -- this is run on the target thread
in the thread pool.
Actual wasm code execution -- this is run on the target thread in the thread pool .
fn run(
        &self,
        exec_input: SandboxExecInput,
        mut wasm_memory: Memory,
        mut stable_memory: Memory,
        total_timer: std::time::Instant,
    ) {
        let run_timer = std::time::Instant::now();
        let system_state_accessor =
            SystemStateAccessorRPC::new(self.exec_id, self.sandbox_manager.controller.clone());
        let subnet_available_memory = exec_input
            .execution_parameters
            .subnet_available_memory
            .clone();
        let (
            WasmExecutionOutput {
                wasm_result,
                num_instructions_left,
                instance_stats,
            },
            deltas,
            instance_or_system_api,
        ) = ic_embedders::wasm_executor::process(
            exec_input.func_ref,
            exec_input.api_type,
            exec_input.canister_current_memory_usage,
            exec_input.execution_parameters,
            exec_input.static_system_state,
            system_state_accessor,
            &self.canister_wasm.compilate,
            &self.canister_wasm.embedder,
            &mut wasm_memory,
            &mut stable_memory,
            &exec_input.globals,
            no_op_logger(),
        );
        match wasm_result {
            Ok(_) => {
                let state_modifications = deltas.map(
                    |(
                        DirtyPageIndices {
                            wasm_memory_delta,
                            stable_memory_delta,
                        },
                        globals,
                    )| {
                        let system_state_changes = match instance_or_system_api {
                            // Here we use `store_data_mut` instead of
                            // `into_store_data` because the later will drop the
                            // wasmtime Instance which can be an expensive
                            // operation. Mutating the store instead allows us
                            // to delay the drop until after the execution
                            // completed message is sent back to the main
                            // process.
                            Ok(mut instance) => instance
                                .store_data_mut()
                                .system_api
                                .take_system_state_changes(),
                            Err(system_api) => system_api.release_system_state_accessor().1,
                        };
                        StateModifications::new(
                            globals,
                            &wasm_memory,
                            &stable_memory,
                            &wasm_memory_delta,
                            &stable_memory_delta,
                            subnet_available_memory.get(),
                            system_state_changes,
                        )
                    },
                );
                if state_modifications.is_some() {
                    self.sandbox_manager
                        .add_memory(exec_input.next_wasm_memory_id, wasm_memory);
                    self.sandbox_manager
                        .add_memory(exec_input.next_stable_memory_id, stable_memory);
                }
                let wasm_output = WasmExecutionOutput {
                    wasm_result,
                    num_instructions_left,
                    instance_stats,
                };
                self.sandbox_manager.controller.execution_finished(
                    protocol::ctlsvc::ExecutionFinishedRequest {
                        exec_id: self.exec_id,
                        exec_output: SandboxExecOutput {
                            wasm: wasm_output,
                            state: state_modifications,
                            execute_total_duration: total_timer.elapsed(),
                            execute_run_duration: run_timer.elapsed(),
                        },
                    },
                );
            }
            Err(err) => {
                let wasm_output = WasmExecutionOutput {
                    wasm_result: Err(err),
                    num_instructions_left,
                    instance_stats,
                };
                self.sandbox_manager.controller.execution_finished(
                    protocol::ctlsvc::ExecutionFinishedRequest {
                        exec_id: self.exec_id,
                        exec_output: SandboxExecOutput {
                            wasm: wasm_output,
                            state: None,
                            execute_total_duration: total_timer.elapsed(),
                            execute_run_duration: run_timer.elapsed(),
                        },
                    },
                );
            }
        }
    }
fn run ( & self , exec_input : SandboxExecInput , mut wasm_memory : Memory , mut stable_memory : Memory , total_timer : std :: time :: Instant , ) { let run_timer = std :: time :: Instant :: now ( ) ; let system_state_accessor = SystemStateAccessorRPC :: new ( self . exec_id , self . sandbox_manager . controller . clone ( ) ) ; let subnet_available_memory = exec_input . execution_parameters . subnet_available_memory . clone ( ) ; let ( WasmExecutionOutput { wasm_result , num_instructions_left , instance_stats , } , deltas , instance_or_system_api , ) = ic_embedders :: wasm_executor :: process ( exec_input . func_ref , exec_input . api_type , exec_input . canister_current_memory_usage , exec_input . execution_parameters , exec_input . static_system_state , system_state_accessor , & self . canister_wasm . compilate , & self . canister_wasm . embedder , & mut wasm_memory , & mut stable_memory , & exec_input . globals , no_op_logger ( ) , ) ; match wasm_result { Ok ( _ ) => { let state_modifications = deltas . map ( | ( DirtyPageIndices { wasm_memory_delta , stable_memory_delta , } , globals , ) | { let system_state_changes = match instance_or_system_api { // Here we use `store_data_mut` instead of // `into_store_data` because the later will drop the // wasmtime Instance which can be an expensive // operation. Mutating the store instead allows us // to delay the drop until after the execution // completed message is sent back to the main // process. Ok ( mut instance ) => instance . store_data_mut ( ) . system_api . take_system_state_changes ( ) , Err ( system_api ) => system_api . release_system_state_accessor ( ) . 1 , } ; StateModifications :: new ( globals , & wasm_memory , & stable_memory , & wasm_memory_delta , & stable_memory_delta , subnet_available_memory . get ( ) , system_state_changes , ) } , ) ; if state_modifications . is_some ( ) { self . sandbox_manager . add_memory ( exec_input . next_wasm_memory_id , wasm_memory ) ; self . sandbox_manager . add_memory ( exec_input . next_stable_memory_id , stable_memory ) ; } let wasm_output = WasmExecutionOutput { wasm_result , num_instructions_left , instance_stats , } ; self . sandbox_manager . controller . execution_finished ( protocol :: ctlsvc :: ExecutionFinishedRequest { exec_id : self . exec_id , exec_output : SandboxExecOutput { wasm : wasm_output , state : state_modifications , execute_total_duration : total_timer . elapsed ( ) , execute_run_duration : run_timer . elapsed ( ) , } , } , ) ; } Err ( err ) => { let wasm_output = WasmExecutionOutput { wasm_result : Err ( err ) , num_instructions_left , instance_stats , } ; self . sandbox_manager . controller . execution_finished ( protocol :: ctlsvc :: ExecutionFinishedRequest { exec_id : self . exec_id , exec_output : SandboxExecOutput { wasm : wasm_output , state : None , execute_total_duration : total_timer . elapsed ( ) , execute_run_duration : run_timer . elapsed ( ) , } , } , ) ; } } }
Actual wasm code execution -- this is run on the target thread
in the thread pool.
Actual wasm code execution -- this is run on the target thread in the thread pool .
&self
exec_input
SandboxExecInput
wasm_memory
Memory
stable_memory
Memory
total_timer
std::time::Instant