Skip to content

Commit c3ba995

Browse files
committed
Optimized blitting between strings and bigstrings
1 parent 6d62d29 commit c3ba995

File tree

5 files changed

+78
-67
lines changed

5 files changed

+78
-67
lines changed

runtime/wasm/bigarray.wat

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@
6969
(import "bindings" "ta_subarray"
7070
(func $ta_subarray
7171
(param (ref extern)) (param i32) (param i32) (result (ref extern))))
72+
(import "bindings" "ta_blit_from_string"
73+
(func $ta_blit_from_string
74+
(param (ref $string)) (param i32) (param (ref extern)) (param i32)
75+
(param i32)))
76+
(import "bindings" "ta_blit_to_string"
77+
(func $ta_blit_to_string
78+
(param (ref extern)) (param i32) (param (ref $string)) (param i32)
79+
(param i32)))
7280
(import "fail" "caml_bound_error" (func $caml_bound_error))
7381
(import "fail" "caml_raise_out_of_memory" (func $caml_raise_out_of_memory))
7482
(import "fail" "caml_invalid_argument"
@@ -2016,42 +2024,32 @@
20162024
(func $caml_string_of_array (export "caml_string_of_array")
20172025
(param (ref eq)) (result (ref eq))
20182026
;; used to convert a typed array to a string
2019-
(local $a (ref extern)) (local $len i32) (local $i i32)
2027+
(local $a (ref extern)) (local $len i32)
20202028
(local $s (ref $string))
20212029
(local.set $a
20222030
(ref.as_non_null (extern.convert_any (call $unwrap (local.get 0)))))
20232031
(local.set $len (call $ta_length (local.get $a)))
20242032
(local.set $s (array.new $string (i32.const 0) (local.get $len)))
2025-
(loop $loop
2026-
(if (i32.lt_u (local.get $i) (local.get $len))
2027-
(then
2028-
(array.set $string (local.get $s) (local.get $i)
2029-
(call $ta_get_ui8 (local.get $a) (local.get $i)))
2030-
(local.set $i (i32.add (local.get $i) (i32.const 1)))
2031-
(br $loop))))
2033+
(call $ta_blit_to_string
2034+
(local.get $a) (i32.const 0) (local.get $s) (i32.const 0)
2035+
(local.get $len))
20322036
(local.get $s))
20332037

20342038
(export "caml_uint8_array_of_bytes" (func $caml_uint8_array_of_string))
20352039
(func $caml_uint8_array_of_string (export "caml_uint8_array_of_string")
20362040
(param (ref eq)) (result (ref eq))
20372041
;; Convert a string to a typed array
2038-
(local $ta (ref extern)) (local $len i32) (local $i i32)
2042+
(local $ta (ref extern)) (local $len i32)
20392043
(local $s (ref $string))
20402044
(local.set $s (ref.cast (ref $string) (local.get 0)))
20412045
(local.set $len (array.len (local.get $s)))
20422046
(local.set $ta
20432047
(call $ta_create
20442048
(i32.const 3) ;; Uint8Array
20452049
(local.get $len)))
2046-
(loop $loop
2047-
(if (i32.lt_u (local.get $i) (local.get $len))
2048-
(then
2049-
(call $ta_set_ui8
2050-
(local.get $ta)
2051-
(local.get $i)
2052-
(ref.i31 (array.get $string (local.get $s) (local.get $i))))
2053-
(local.set $i (i32.add (local.get $i) (i32.const 1)))
2054-
(br $loop))))
2050+
(call $ta_blit_from_string
2051+
(local.get $s) (i32.const 0) (local.get $ta) (i32.const 0)
2052+
(local.get $len))
20552053
(call $wrap (any.convert_extern (local.get $ta))))
20562054

20572055
(func (export "caml_ba_get_kind") (param (ref eq)) (result i32)
@@ -2082,4 +2080,16 @@
20822080
(local.get $num_dims)
20832081
(local.get $kind)
20842082
(local.get $layout)))
2083+
2084+
(func (export "string_set")
2085+
(param $s externref) (param $i i32) (param $v i32)
2086+
(array.set $string
2087+
(ref.cast (ref null $string) (any.convert_extern (local.get $s)))
2088+
(local.get $i) (local.get $v)))
2089+
2090+
(func (export "string_get")
2091+
(param $s externref) (param $i i32) (result i32)
2092+
(array.get $string
2093+
(ref.cast (ref null $string) (any.convert_extern (local.get $s)))
2094+
(local.get $i)))
20852095
)

runtime/wasm/bigstring.wat

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@
4848
(func $ta_length (param (ref extern)) (result i32)))
4949
(import "bindings" "ta_bytes"
5050
(func $ta_bytes (param anyref) (result anyref)))
51+
(import "bindings" "ta_blit_from_string"
52+
(func $ta_blit_from_string
53+
(param (ref $string)) (param i32) (param (ref extern)) (param i32)
54+
(param i32)))
55+
(import "bindings" "ta_blit_to_string"
56+
(func $ta_blit_to_string
57+
(param (ref extern)) (param i32) (param (ref $string)) (param i32)
58+
(param i32)))
5159
(import "hash" "caml_hash_mix_int"
5260
(func $caml_hash_mix_int (param i32) (param i32) (result i32)))
5361

@@ -202,47 +210,36 @@
202210
(param $str1 (ref eq)) (param $vpos1 (ref eq))
203211
(param $ba2 (ref eq)) (param $vpos2 (ref eq))
204212
(param $vlen (ref eq)) (result (ref eq))
205-
(local $i i32) (local $pos1 i32) (local $pos2 i32) (local $len i32)
213+
(local $pos1 i32) (local $pos2 i32) (local $len i32)
206214
(local $s1 (ref $string))
207215
(local $d2 (ref extern))
208216
(local.set $s1 (ref.cast (ref $string) (local.get $str1)))
209217
(local.set $pos1 (i31.get_s (ref.cast (ref i31) (local.get $vpos1))))
210218
(local.set $d2 (call $caml_ba_get_data (local.get $ba2)))
211219
(local.set $pos2 (i31.get_s (ref.cast (ref i31) (local.get $vpos2))))
212220
(local.set $len (i31.get_s (ref.cast (ref i31) (local.get $vlen))))
213-
(loop $loop
214-
(if (i32.lt_u (local.get $i) (local.get $len))
215-
(then
216-
(call $ta_set_ui8 (local.get $d2)
217-
(i32.add (local.get $pos2) (local.get $i))
218-
(ref.i31
219-
(array.get_u $string (local.get $s1)
220-
(i32.add (local.get $pos1) (local.get $i)))))
221-
(local.set $i (i32.add (local.get $i) (i32.const 1)))
222-
(br $loop))))
221+
(call $ta_blit_from_string
222+
(local.get $s1) (local.get $pos1)
223+
(local.get $d2) (local.get $pos2)
224+
(local.get $len))
223225
(ref.i31 (i32.const 0)))
224226

225227
(func (export "caml_bigstring_blit_ba_to_bytes")
226228
(param $ba1 (ref eq)) (param $vpos1 (ref eq))
227229
(param $str2 (ref eq)) (param $vpos2 (ref eq))
228230
(param $vlen (ref eq)) (result (ref eq))
229-
(local $i i32) (local $pos1 i32) (local $pos2 i32) (local $len i32)
231+
(local $pos1 i32) (local $pos2 i32) (local $len i32)
230232
(local $d1 (ref extern))
231233
(local $s2 (ref $string))
232234
(local.set $d1 (call $caml_ba_get_data (local.get $ba1)))
233235
(local.set $pos1 (i31.get_s (ref.cast (ref i31) (local.get $vpos1))))
234236
(local.set $s2 (ref.cast (ref $string) (local.get $str2)))
235237
(local.set $pos2 (i31.get_s (ref.cast (ref i31) (local.get $vpos2))))
236238
(local.set $len (i31.get_s (ref.cast (ref i31) (local.get $vlen))))
237-
(loop $loop
238-
(if (i32.lt_u (local.get $i) (local.get $len))
239-
(then
240-
(array.set $string (local.get $s2)
241-
(i32.add (local.get $pos2) (local.get $i))
242-
(call $ta_get_ui8 (local.get $d1)
243-
(i32.add (local.get $pos1) (local.get $i))))
244-
(local.set $i (i32.add (local.get $i) (i32.const 1)))
245-
(br $loop))))
239+
(call $ta_blit_to_string
240+
(local.get $d1) (local.get $pos1)
241+
(local.get $s2) (local.get $pos2)
242+
(local.get $len))
246243
(ref.i31 (i32.const 0)))
247244

248245
(func (export "caml_bigstring_blit_ba_to_ba")

runtime/wasm/deps.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[
22
{
33
"name": "root",
4-
"reaches": ["init", "exn", "mem", "strings"],
4+
"reaches": ["init", "exn", "mem", "strings", "string_get", "string_set"],
55
"root": true
66
},
77
{
@@ -20,6 +20,14 @@
2020
"name": "strings",
2121
"export": "caml_extract_string"
2222
},
23+
{
24+
"name": "string_get",
25+
"export": "string_get"
26+
},
27+
{
28+
"name": "string_set",
29+
"export": "string_set"
30+
},
2331
{
2432
"name": "callback",
2533
"export": "caml_callback"

runtime/wasm/io.wat

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@
5656
(func $ta_set_ui8 (param (ref extern)) (param i32) (param i32))) ;; ZZZ ??
5757
(import "bindings" "ta_get_ui8"
5858
(func $ta_get_ui8 (param (ref extern)) (param i32) (result i32)))
59+
(import "bindings" "ta_blit_from_string"
60+
(func $ta_blit_from_string
61+
(param (ref $string)) (param i32) (param (ref extern)) (param i32)
62+
(param i32)))
63+
(import "bindings" "ta_blit_to_string"
64+
(func $ta_blit_to_string
65+
(param (ref extern)) (param i32) (param (ref $string)) (param i32)
66+
(param i32)))
5967
(import "custom" "custom_compare_id"
6068
(func $custom_compare_id
6169
(param (ref eq)) (param (ref eq)) (param i32) (result i32)))
@@ -330,20 +338,6 @@
330338
(i64.add (local.get $offset) (i64.extend_i32_u (local.get $n))))
331339
(local.get $n))
332340

333-
(func $copy_from_buffer
334-
(param $buf (ref extern)) (param $curr i32)
335-
(param $s (ref $string)) (param $pos i32) (param $len i32)
336-
(local $i i32)
337-
(loop $loop
338-
(if (i32.lt_u (local.get $i) (local.get $len))
339-
(then
340-
(array.set $string (local.get $s)
341-
(i32.add (local.get $pos) (local.get $i))
342-
(call $ta_get_ui8 (local.get $buf)
343-
(i32.add (local.get $curr) (local.get $i))))
344-
(local.set $i (i32.add (local.get $i) (i32.const 1)))
345-
(br $loop)))))
346-
347341
(func $caml_refill (param $ch (ref $channel)) (result i32)
348342
(local $n i32)
349343
(local $buf (ref extern))
@@ -374,7 +368,7 @@
374368
(then
375369
(if (i32.gt_u (local.get $len) (local.get $avail))
376370
(then (local.set $len (local.get $avail))))
377-
(call $copy_from_buffer
371+
(call $ta_blit_to_string
378372
(struct.get $channel $buffer (local.get $ch))
379373
(struct.get $channel $curr (local.get $ch))
380374
(local.get $s) (local.get $pos)
@@ -389,7 +383,7 @@
389383
(struct.set $channel $max (local.get $ch) (local.get $nread))
390384
(if (i32.gt_u (local.get $len) (local.get $nread))
391385
(then (local.set $len (local.get $nread))))
392-
(call $copy_from_buffer
386+
(call $ta_blit_to_string
393387
(struct.get $channel $buffer (local.get $ch))
394388
(i32.const 0)
395389
(local.get $s) (local.get $pos)
@@ -445,7 +439,7 @@
445439
(local.set $curr (i32.const 0))
446440
(if (i32.gt_u (local.get $len) (local.get $nread))
447441
(then (local.set $len (local.get $nread))))))))
448-
(call $copy_from_buffer
442+
(call $ta_blit_to_string
449443
(local.get $buf) (local.get $curr)
450444
(local.get $s) (local.get $pos) (local.get $len))
451445
(struct.set $channel $curr (local.get $ch)
@@ -730,23 +724,17 @@
730724
(func $caml_putblock
731725
(param $ch (ref $channel)) (param $s (ref $string)) (param $pos i32)
732726
(param $len i32) (result i32)
733-
(local $free i32) (local $curr i32) (local $i i32)
727+
(local $free i32) (local $curr i32)
734728
(local $buf (ref extern))
735729
(local.set $curr (struct.get $channel $curr (local.get $ch)))
736730
(local.set $free
737731
(i32.sub (struct.get $channel $size (local.get $ch)) (local.get $curr)))
738732
(if (i32.ge_u (local.get $len) (local.get $free))
739733
(then (local.set $len (local.get $free))))
740734
(local.set $buf (struct.get $channel $buffer (local.get $ch)))
741-
(loop $loop
742-
(if (i32.lt_u (local.get $i) (local.get $len))
743-
(then
744-
(call $ta_set_ui8 (local.get $buf)
745-
(i32.add (local.get $curr) (local.get $i))
746-
(array.get_u $string (local.get $s)
747-
(i32.add (local.get $pos) (local.get $i))))
748-
(local.set $i (i32.add (local.get $i) (i32.const 1)))
749-
(br $loop))))
735+
(call $ta_blit_from_string
736+
(local.get $s) (local.get $pos)
737+
(local.get $buf) (local.get $curr) (local.get $len))
750738
(struct.set $channel $curr (local.get $ch)
751739
(i32.add (local.get $curr) (local.get $len)))
752740
(if (i32.ge_u (local.get $len) (local.get $free))

runtime/wasm/runtime.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,12 @@
222222
ta_copy: (ta, t, s, n) => ta.copyWithin(t, s, n),
223223
ta_bytes: (a) =>
224224
new Uint8Array(a.buffer, a.byteOffset, a.length * a.BYTES_PER_ELEMENT),
225+
ta_blit_from_string: (s, p1, a, p2, l) => {
226+
for (let i = 0; i < l; i++) a[p2 + i] = string_get(s, p1 + i);
227+
},
228+
ta_blit_to_string: (a, p1, s, p2, l) => {
229+
for (let i = 0; i < l; i++) string_set(s, p2 + i, a[p1 + i]);
230+
},
225231
wrap_callback: (f) =>
226232
function () {
227233
var n = arguments.length;
@@ -537,6 +543,8 @@
537543
caml_handle_uncaught_exception,
538544
caml_buffer,
539545
caml_extract_string,
546+
string_get,
547+
string_set,
540548
_initialize,
541549
} = wasmModule.instance.exports;
542550

0 commit comments

Comments
 (0)