Skip to content

Commit

Permalink
Minor invoke optimizations (#256)
Browse files Browse the repository at this point in the history
* No need to create new string

* Msgpack should export a const NILL = 192u8

* Cast when possible

* Avoid wasting time clearing buffers + better casts

* Revert "Msgpack should export a const NILL = 192u8"

This reverts commit 7e5c497.

* Note to self: remember to enable my code analyzer

* And disable auto-linter

* Fix read not writing anything to the buffer
  • Loading branch information
MarcGuiselin authored Dec 19, 2023
1 parent 9e4d501 commit 353ed87
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 72 deletions.
144 changes: 75 additions & 69 deletions packages/wasm/src/runtime/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let context = FunctionEnv::new(store, state);

let invoke_args = move |mut context: FunctionEnvMut<Arc<Mutex<State>>>, values: &[Value]| {
let method_ptr = values[0].unwrap_i32() as u32;
let args_ptr = values[1].unwrap_i32() as u32;
let method_ptr = values[0].unwrap_i32() as u64;
let args_ptr = values[1].unwrap_i32() as u64;

let mutable_context = context.as_mut();
let mutable_state = mutable_context.data().lock().unwrap();
Expand All @@ -36,10 +36,10 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let memory_view = memory.view(&mutable_context);

memory_view
.write(method_ptr.try_into().unwrap(), &mutable_state.method)
.write(method_ptr, &mutable_state.method)
.unwrap();
memory_view
.write(args_ptr.try_into().unwrap(), &mutable_state.args)
.write(args_ptr, &mutable_state.args)
.unwrap();
Ok(vec![])
};
Expand All @@ -54,12 +54,12 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let mut mutable_state = mutable_context.data().lock().unwrap();
let memory = mutable_state.memory.as_ref().unwrap();
let memory_view = memory.view(&mutable_context);
let offset = values[0].unwrap_i32() as u32;
let length = values[1].unwrap_i32() as u32;
let offset = values[0].unwrap_i32() as u64;
let length = values[1].unwrap_i32() as usize;

let mut buffer: Vec<u8> = vec![0; length as usize];
let mut buffer: Vec<u8> = empty_buffer(length);
memory_view
.read(offset.try_into().unwrap(), &mut buffer)
.read(offset, &mut buffer)
.map_err(|e| RuntimeError::new(e.to_string()))?;
mutable_state.invoke.result = Some(buffer);
Ok(vec![])
Expand All @@ -77,12 +77,12 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let mut mutable_state = mutable_context.data().lock().unwrap();
let memory = mutable_state.memory.as_ref().unwrap();
let memory_view = memory.view(&mutable_context);
let offset = values[0].unwrap_i32() as u32;
let length = values[1].unwrap_i32() as u32;
let offset = values[0].unwrap_i32() as u64;
let length = values[1].unwrap_i32() as usize;

let mut buffer: Vec<u8> = vec![0; length as usize];
let mut buffer: Vec<u8> = empty_buffer(length);
memory_view
.read(offset.try_into().unwrap(), &mut buffer)
.read(offset, &mut buffer)
.map_err(|e| RuntimeError::new(e.to_string()))?;

let invoke_error = String::from_utf8(buffer)
Expand All @@ -108,26 +108,26 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
);

let abort = move |mut context: FunctionEnvMut<Arc<Mutex<State>>>, values: &[Value]| {
let msg_offset = values[0].unwrap_i32() as u32;
let msg_length = values[1].unwrap_i32() as u32;
let file_offset = values[2].unwrap_i32() as u32;
let file_length = values[3].unwrap_i32() as u32;
let line = values[4].unwrap_i32() as u32;
let column = values[5].unwrap_i32() as u32;
let msg_offset = values[0].unwrap_i32() as u64;
let msg_length = values[1].unwrap_i32() as usize;
let file_offset = values[2].unwrap_i32() as u64;
let file_length = values[3].unwrap_i32() as usize;
let line = values[4].unwrap_i32() as u64;
let column = values[5].unwrap_i32() as usize;

let mutable_context = context.as_mut();
let state = mutable_context.data().lock().unwrap();
let memory = state.memory.as_ref().unwrap();
let memory_view = memory.view(&mutable_context);

let mut msg_buffer: Vec<u8> = vec![0; msg_length as usize];
let mut file_buffer: Vec<u8> = vec![0; file_length as usize];
let mut msg_buffer: Vec<u8> = empty_buffer(msg_length);
let mut file_buffer: Vec<u8> = empty_buffer(file_length);

memory_view
.read(msg_offset.try_into().unwrap(), &mut msg_buffer)
.read(msg_offset, &mut msg_buffer)
.unwrap();
memory_view
.read(file_offset.try_into().unwrap(), &mut file_buffer)
.read(file_offset, &mut file_buffer)
.unwrap();

let msg = String::from_utf8(msg_buffer).unwrap();
Expand All @@ -153,34 +153,34 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
);

let subinvoke = move |context: FunctionEnvMut<Arc<Mutex<State>>>, values: &[Value]| {
let uri_ptr = values[0].unwrap_i32() as u32;
let uri_len = values[1].unwrap_i32() as u32;
let method_ptr = values[2].unwrap_i32() as u32;
let method_len = values[3].unwrap_i32() as u32;
let args_ptr = values[4].unwrap_i32() as u32;
let args_len = values[5].unwrap_i32() as u32;
let uri_ptr = values[0].unwrap_i32() as u64;
let uri_len = values[1].unwrap_i32() as usize;
let method_ptr = values[2].unwrap_i32() as u64;
let method_len = values[3].unwrap_i32() as usize;
let args_ptr = values[4].unwrap_i32() as u64;
let args_len = values[5].unwrap_i32() as usize;

let async_context = Arc::new(Mutex::new(context));
let mut context = async_context.lock().unwrap();
let mutable_context = context.as_mut();
let mut state = mutable_context.data().lock().unwrap();

let memory = state.memory.as_ref().unwrap();
let mut uri_buffer: Vec<u8> = vec![0; uri_len as usize];
let mut method_buffer: Vec<u8> = vec![0; method_len as usize];
let mut args_buffer: Vec<u8> = vec![0; args_len as usize];
let mut uri_buffer: Vec<u8> = empty_buffer(uri_len);
let mut method_buffer: Vec<u8> = empty_buffer(method_len);
let mut args_buffer: Vec<u8> = empty_buffer(args_len);

memory
.view(&mutable_context)
.read(uri_ptr.try_into().unwrap(), &mut uri_buffer)
.read(uri_ptr, &mut uri_buffer)
.unwrap();
memory
.view(&mutable_context)
.read(method_ptr.try_into().unwrap(), &mut method_buffer)
.read(method_ptr, &mut method_buffer)
.unwrap();
memory
.view(&mutable_context)
.read(args_ptr.try_into().unwrap(), &mut args_buffer)
.read(args_ptr, &mut args_buffer)
.unwrap();

let uri = String::from_utf8(uri_buffer).unwrap();
Expand Down Expand Up @@ -240,7 +240,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let mutable_state = mutable_context.data().lock().unwrap();
let memory = mutable_state.memory.as_ref().unwrap();

let pointer = values[0].unwrap_i32() as u32;
let pointer = values[0].unwrap_i32() as u64;

let result = mutable_state.subinvoke.result.as_ref()
.ok_or(RuntimeError::new(
Expand All @@ -249,7 +249,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

memory
.view(&mutable_context)
.write(pointer as u64, result)
.write(pointer, result)
.map(|_| vec![])
.map_err(|e| RuntimeError::new(e.to_string()))
};
Expand Down Expand Up @@ -290,7 +290,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let mutable_state = mutable_context.data().lock().unwrap();
let memory = mutable_state.memory.as_ref().unwrap();

let pointer = values[0].unwrap_i32() as u32;
let pointer = values[0].unwrap_i32() as u64;

let subinvoke_error = mutable_state.subinvoke.error.as_ref()
.ok_or(RuntimeError::new(
Expand All @@ -299,7 +299,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

memory
.view(&mutable_context)
.write(pointer as u64, subinvoke_error.as_bytes())
.write(pointer, subinvoke_error.as_bytes())
.map(|_| vec![])
.map_err(|e| RuntimeError::new(e.to_string()))
};
Expand All @@ -323,41 +323,41 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

let subinvoke_implementation = move |context: FunctionEnvMut<Arc<Mutex<State>>>,
values: &[Value]| {
let interface_ptr = values[0].unwrap_i32() as u32;
let interface_len = values[1].unwrap_i32() as u32;
let impl_uri_ptr = values[2].unwrap_i32() as u32;
let impl_uri_len = values[3].unwrap_i32() as u32;
let method_ptr = values[4].unwrap_i32() as u32;
let method_len = values[5].unwrap_i32() as u32;
let args_ptr = values[6].unwrap_i32() as u32;
let args_len = values[7].unwrap_i32() as u32;
let interface_ptr = values[0].unwrap_i32() as u64;
let interface_len = values[1].unwrap_i32() as usize;
let impl_uri_ptr = values[2].unwrap_i32() as u64;
let impl_uri_len = values[3].unwrap_i32() as usize;
let method_ptr = values[4].unwrap_i32() as u64;
let method_len = values[5].unwrap_i32() as usize;
let args_ptr = values[6].unwrap_i32() as u64;
let args_len = values[7].unwrap_i32() as usize;

let async_context = Arc::new(Mutex::new(context));
let mut context = async_context.lock().unwrap();
let mutable_context = context.as_mut();
let mut state = mutable_context.data().lock().unwrap();

let mut interface_buffer = vec![0; interface_len.try_into().unwrap()];
let mut impl_uri_buffer = vec![0; impl_uri_len.try_into().unwrap()];
let mut method_buffer = vec![0; method_len.try_into().unwrap()];
let mut args_buffer = vec![0; args_len.try_into().unwrap()];
let mut interface_buffer = empty_buffer(interface_len);
let mut impl_uri_buffer = empty_buffer(impl_uri_len);
let mut method_buffer = empty_buffer(method_len);
let mut args_buffer = empty_buffer(args_len);

let memory = state.memory.as_ref().unwrap();
memory
.view(&mutable_context)
.read(interface_ptr.try_into().unwrap(), &mut interface_buffer)
.read(interface_ptr, &mut interface_buffer)
.unwrap();
memory
.view(&mutable_context)
.read(impl_uri_ptr.try_into().unwrap(), &mut impl_uri_buffer)
.read(impl_uri_ptr, &mut impl_uri_buffer)
.unwrap();
memory
.view(&mutable_context)
.read(method_ptr.try_into().unwrap(), &mut method_buffer)
.read(method_ptr, &mut method_buffer)
.unwrap();
memory
.view(&mutable_context)
.read(args_ptr.try_into().unwrap(), &mut args_buffer)
.read(args_ptr, &mut args_buffer)
.unwrap();

let interface = String::from_utf8(interface_buffer).unwrap();
Expand Down Expand Up @@ -440,7 +440,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let mutable_context = context.as_mut();
let mutable_state = mutable_context.data().lock().unwrap();
let memory = mutable_state.memory.as_ref().unwrap();
let pointer = values[0].unwrap_i32() as u32;
let pointer = values[0].unwrap_i32() as u64;

let implementation = mutable_state.subinvoke_implementation.as_ref()
.ok_or(RuntimeError::new(
Expand All @@ -454,7 +454,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

memory
.view(&mutable_context)
.write(pointer.try_into().unwrap(), implementation_result)
.write(pointer, implementation_result)
.map(|_| vec![])
.map_err(|e| RuntimeError::new(e.to_string()))
};
Expand Down Expand Up @@ -500,7 +500,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let mutable_context = context.as_mut();
let mutable_state = mutable_context.data().lock().unwrap();
let memory = mutable_state.memory.as_ref().unwrap();
let pointer = values[0].unwrap_i32() as u32;
let pointer = values[0].unwrap_i32() as u64;

let implementation = mutable_state.subinvoke_implementation.as_ref()
.ok_or(RuntimeError::new(
Expand All @@ -514,7 +514,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

memory
.view(&mutable_context)
.write(pointer.try_into().unwrap(), implementation_error.as_bytes())
.write(pointer, implementation_error.as_bytes())
.map(|_| vec![])
.map_err(|e| RuntimeError::new(e.to_string()))
};
Expand All @@ -531,8 +531,8 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

let get_implementations = move |context: FunctionEnvMut<Arc<Mutex<State>>>,
values: &[Value]| {
let pointer = values[0].unwrap_i32() as u32;
let length = values[1].unwrap_i32() as u32;
let pointer = values[0].unwrap_i32() as u64;
let length = values[1].unwrap_i32() as usize;

let async_context = Arc::new(Mutex::new(context));

Expand All @@ -541,10 +541,10 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let mut state = mutable_context.data().lock().unwrap();

let memory = state.memory.as_ref().unwrap();
let mut uri_bytes = vec![0; length as usize];
let mut uri_bytes = empty_buffer(length);
memory
.view(&mutable_context)
.read(pointer.try_into().unwrap(), &mut uri_bytes)
.read(pointer, &mut uri_bytes)
.unwrap();
let uri = String::from_utf8(uri_bytes).unwrap();
let result = state.invoker.get_implementations(&uri.try_into().unwrap());
Expand Down Expand Up @@ -602,7 +602,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

let get_implementation_result = move |mut context: FunctionEnvMut<Arc<Mutex<State>>>,
values: &[Value]| {
let pointer = values[0].unwrap_i32() as u32;
let pointer = values[0].unwrap_i32() as u64;

let mutable_context = context.as_mut();
let state = mutable_context.data().lock().unwrap();
Expand All @@ -615,7 +615,7 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

memory
.view(&mutable_context)
.write(pointer.try_into().unwrap(), result)
.write(pointer, result)
.map(|_| vec![])
.map_err(|e| {
RuntimeError::new(format!(
Expand All @@ -635,15 +635,15 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
let load_env_signature = FunctionType::new(vec![Type::I32], vec![]);

let load_env = move |mut context: FunctionEnvMut<Arc<Mutex<State>>>, values: &[Value]| {
let pointer = values[0].unwrap_i32() as u32;
let pointer = values[0].unwrap_i32() as u64;

let mutable_context = context.as_mut();
let state = mutable_context.data().lock().unwrap();
let memory = state.memory.as_ref().unwrap();

memory
.view(&mutable_context)
.write(pointer.try_into().unwrap(), &state.env.to_vec())
.write(pointer, &state.env.to_vec())
.map_err(|e| RuntimeError::new(format!("__wrap_load_env: failed to write to memory: {}", e)))?;

Ok(vec![])
Expand All @@ -653,17 +653,17 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>

let debug_log_signature = FunctionType::new(vec![Type::I32, Type::I32], vec![]);
let debug_log = move |mut context: FunctionEnvMut<Arc<Mutex<State>>>, values: &[Value]| {
let msg_offset = values[0].unwrap_i32() as u32;
let msg_offset = values[0].unwrap_i32() as u64;
let msg_length = values[1].unwrap_i32() as u32;
let mut msg_buffer: Vec<u8> = vec![0; msg_length as usize];
let mut msg_buffer: Vec<u8> = empty_buffer(msg_length as usize);

let mutable_context = context.as_mut();
let state = mutable_context.data().lock().unwrap();
let memory = state.memory.as_ref().unwrap();
let memory_view = memory.view(&mutable_context);

memory_view
.read(msg_offset.try_into().unwrap(), &mut msg_buffer)
.read(msg_offset, &mut msg_buffer)
.unwrap();
let msg = String::from_utf8(msg_buffer).unwrap();
println!("{}", format!("__wrap_debug_log: {msg}"));
Expand Down Expand Up @@ -699,3 +699,9 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
}
}
}

fn empty_buffer(size: usize) -> Vec<u8> {
let mut empty: Vec<u8> = Vec::with_capacity(size);
unsafe { empty.set_len(size); }
empty
}
6 changes: 3 additions & 3 deletions packages/wasm/src/wasm_wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ impl Wrapper for WasmWrapper {
};

let params = &[
Value::I32(method.to_string().len().try_into().unwrap()),
Value::I32(args.len().try_into().unwrap()),
Value::I32(env.len().try_into().unwrap()),
Value::I32(method.len() as _),
Value::I32(args.len() as _),
Value::I32(env.len() as _),
];

let state = Arc::new(Mutex::new(State::new(
Expand Down

0 comments on commit 353ed87

Please sign in to comment.