Skip to content

Commit 353ed87

Browse files
authored
Minor invoke optimizations (#256)
* 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
1 parent 9e4d501 commit 353ed87

2 files changed

Lines changed: 78 additions & 72 deletions

File tree

packages/wasm/src/runtime/imports.rs

Lines changed: 75 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
1414
let context = FunctionEnv::new(store, state);
1515

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

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

3838
memory_view
39-
.write(method_ptr.try_into().unwrap(), &mutable_state.method)
39+
.write(method_ptr, &mutable_state.method)
4040
.unwrap();
4141
memory_view
42-
.write(args_ptr.try_into().unwrap(), &mutable_state.args)
42+
.write(args_ptr, &mutable_state.args)
4343
.unwrap();
4444
Ok(vec![])
4545
};
@@ -54,12 +54,12 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
5454
let mut mutable_state = mutable_context.data().lock().unwrap();
5555
let memory = mutable_state.memory.as_ref().unwrap();
5656
let memory_view = memory.view(&mutable_context);
57-
let offset = values[0].unwrap_i32() as u32;
58-
let length = values[1].unwrap_i32() as u32;
57+
let offset = values[0].unwrap_i32() as u64;
58+
let length = values[1].unwrap_i32() as usize;
5959

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

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

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

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

118118
let mutable_context = context.as_mut();
119119
let state = mutable_context.data().lock().unwrap();
120120
let memory = state.memory.as_ref().unwrap();
121121
let memory_view = memory.view(&mutable_context);
122122

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

126126
memory_view
127-
.read(msg_offset.try_into().unwrap(), &mut msg_buffer)
127+
.read(msg_offset, &mut msg_buffer)
128128
.unwrap();
129129
memory_view
130-
.read(file_offset.try_into().unwrap(), &mut file_buffer)
130+
.read(file_offset, &mut file_buffer)
131131
.unwrap();
132132

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

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

163163
let async_context = Arc::new(Mutex::new(context));
164164
let mut context = async_context.lock().unwrap();
165165
let mutable_context = context.as_mut();
166166
let mut state = mutable_context.data().lock().unwrap();
167167

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

173173
memory
174174
.view(&mutable_context)
175-
.read(uri_ptr.try_into().unwrap(), &mut uri_buffer)
175+
.read(uri_ptr, &mut uri_buffer)
176176
.unwrap();
177177
memory
178178
.view(&mutable_context)
179-
.read(method_ptr.try_into().unwrap(), &mut method_buffer)
179+
.read(method_ptr, &mut method_buffer)
180180
.unwrap();
181181
memory
182182
.view(&mutable_context)
183-
.read(args_ptr.try_into().unwrap(), &mut args_buffer)
183+
.read(args_ptr, &mut args_buffer)
184184
.unwrap();
185185

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

243-
let pointer = values[0].unwrap_i32() as u32;
243+
let pointer = values[0].unwrap_i32() as u64;
244244

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

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

293-
let pointer = values[0].unwrap_i32() as u32;
293+
let pointer = values[0].unwrap_i32() as u64;
294294

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

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

324324
let subinvoke_implementation = move |context: FunctionEnvMut<Arc<Mutex<State>>>,
325325
values: &[Value]| {
326-
let interface_ptr = values[0].unwrap_i32() as u32;
327-
let interface_len = values[1].unwrap_i32() as u32;
328-
let impl_uri_ptr = values[2].unwrap_i32() as u32;
329-
let impl_uri_len = values[3].unwrap_i32() as u32;
330-
let method_ptr = values[4].unwrap_i32() as u32;
331-
let method_len = values[5].unwrap_i32() as u32;
332-
let args_ptr = values[6].unwrap_i32() as u32;
333-
let args_len = values[7].unwrap_i32() as u32;
326+
let interface_ptr = values[0].unwrap_i32() as u64;
327+
let interface_len = values[1].unwrap_i32() as usize;
328+
let impl_uri_ptr = values[2].unwrap_i32() as u64;
329+
let impl_uri_len = values[3].unwrap_i32() as usize;
330+
let method_ptr = values[4].unwrap_i32() as u64;
331+
let method_len = values[5].unwrap_i32() as usize;
332+
let args_ptr = values[6].unwrap_i32() as u64;
333+
let args_len = values[7].unwrap_i32() as usize;
334334

335335
let async_context = Arc::new(Mutex::new(context));
336336
let mut context = async_context.lock().unwrap();
337337
let mutable_context = context.as_mut();
338338
let mut state = mutable_context.data().lock().unwrap();
339339

340-
let mut interface_buffer = vec![0; interface_len.try_into().unwrap()];
341-
let mut impl_uri_buffer = vec![0; impl_uri_len.try_into().unwrap()];
342-
let mut method_buffer = vec![0; method_len.try_into().unwrap()];
343-
let mut args_buffer = vec![0; args_len.try_into().unwrap()];
340+
let mut interface_buffer = empty_buffer(interface_len);
341+
let mut impl_uri_buffer = empty_buffer(impl_uri_len);
342+
let mut method_buffer = empty_buffer(method_len);
343+
let mut args_buffer = empty_buffer(args_len);
344344

345345
let memory = state.memory.as_ref().unwrap();
346346
memory
347347
.view(&mutable_context)
348-
.read(interface_ptr.try_into().unwrap(), &mut interface_buffer)
348+
.read(interface_ptr, &mut interface_buffer)
349349
.unwrap();
350350
memory
351351
.view(&mutable_context)
352-
.read(impl_uri_ptr.try_into().unwrap(), &mut impl_uri_buffer)
352+
.read(impl_uri_ptr, &mut impl_uri_buffer)
353353
.unwrap();
354354
memory
355355
.view(&mutable_context)
356-
.read(method_ptr.try_into().unwrap(), &mut method_buffer)
356+
.read(method_ptr, &mut method_buffer)
357357
.unwrap();
358358
memory
359359
.view(&mutable_context)
360-
.read(args_ptr.try_into().unwrap(), &mut args_buffer)
360+
.read(args_ptr, &mut args_buffer)
361361
.unwrap();
362362

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

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

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

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

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

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

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

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

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

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

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

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

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

640640
let mutable_context = context.as_mut();
641641
let state = mutable_context.data().lock().unwrap();
642642
let memory = state.memory.as_ref().unwrap();
643643

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

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

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

660660
let mutable_context = context.as_mut();
661661
let state = mutable_context.data().lock().unwrap();
662662
let memory = state.memory.as_ref().unwrap();
663663
let memory_view = memory.view(&mutable_context);
664664

665665
memory_view
666-
.read(msg_offset.try_into().unwrap(), &mut msg_buffer)
666+
.read(msg_offset, &mut msg_buffer)
667667
.unwrap();
668668
let msg = String::from_utf8(msg_buffer).unwrap();
669669
println!("{}", format!("__wrap_debug_log: {msg}"));
@@ -699,3 +699,9 @@ pub fn create_imports(memory: Memory, store: &mut Store, state: Arc<Mutex<State>
699699
}
700700
}
701701
}
702+
703+
fn empty_buffer(size: usize) -> Vec<u8> {
704+
let mut empty: Vec<u8> = Vec::with_capacity(size);
705+
unsafe { empty.set_len(size); }
706+
empty
707+
}

packages/wasm/src/wasm_wrapper.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ impl Wrapper for WasmWrapper {
8181
};
8282

8383
let params = &[
84-
Value::I32(method.to_string().len().try_into().unwrap()),
85-
Value::I32(args.len().try_into().unwrap()),
86-
Value::I32(env.len().try_into().unwrap()),
84+
Value::I32(method.len() as _),
85+
Value::I32(args.len() as _),
86+
Value::I32(env.len() as _),
8787
];
8888

8989
let state = Arc::new(Mutex::new(State::new(

0 commit comments

Comments
 (0)