Skip to content

Commit 6d62d29

Browse files
committed
Bigstring: add JavaScript functions to access 2 or 4 bytes at once
Calling a JavaScript function is costly. This reduces the number of calls to a JavaScript function that we need to make to get or set a 16-bit or 32-bit integer.
1 parent 38abfd5 commit 6d62d29

File tree

3 files changed

+39
-117
lines changed

3 files changed

+39
-117
lines changed

runtime/wasm/bigarray.wat

Lines changed: 23 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
(func $ta_get_i8 (param (ref extern)) (param i32) (result i32)))
3939
(import "bindings" "ta_get_ui8"
4040
(func $ta_get_ui8 (param (ref extern)) (param i32) (result i32)))
41+
(import "bindings" "ta_get32_ui8"
42+
(func $ta_get32_ui8 (param (ref extern)) (param i32) (result i32)))
43+
(import "bindings" "ta_get16_ui8"
44+
(func $ta_get16_ui8 (param (ref extern)) (param i32) (result i32)))
4145
(import "bindings" "ta_set_f64"
4246
(func $ta_set_f64 (param (ref extern)) (param i32) (param f64)))
4347
(import "bindings" "ta_set_f32"
@@ -52,6 +56,10 @@
5256
(func $ta_set_i8 (param (ref extern)) (param i32) (param (ref i31))))
5357
(import "bindings" "ta_set_ui8"
5458
(func $ta_set_ui8 (param (ref extern)) (param i32) (param (ref i31))))
59+
(import "bindings" "ta_set16_ui8"
60+
(func $ta_set16_ui8 (param (ref extern)) (param i32) (param (ref i31))))
61+
(import "bindings" "ta_set32_ui8"
62+
(func $ta_set32_ui8 (param (ref extern)) (param i32) (param i32)))
5563
(import "bindings" "ta_fill"
5664
(func $ta_fill_int (param (ref extern)) (param i32)))
5765
(import "bindings" "ta_fill"
@@ -268,19 +276,7 @@
268276
(local.set $h
269277
(call $caml_hash_mix_int
270278
(local.get $h)
271-
(i32.or
272-
(i32.or
273-
(call $ta_get_ui8 (local.get $data) (local.get $i))
274-
(i32.shl (call $ta_get_ui8 (local.get $data)
275-
(i32.add (local.get $i) (i32.const 1)))
276-
(i32.const 8)))
277-
(i32.or
278-
(i32.shl (call $ta_get_ui8 (local.get $data)
279-
(i32.add (local.get $i) (i32.const 2)))
280-
(i32.const 16))
281-
(i32.shl (call $ta_get_ui8 (local.get $data)
282-
(i32.add (local.get $i) (i32.const 3)))
283-
(i32.const 24))))))
279+
(call $ta_get32_ui8 (local.get $data) (local.get $i))))
284280
(local.set $i (i32.add (local.get $i) (i32.const 4)))
285281
(br $loop))))
286282
(local.set $w (i32.const 0))
@@ -1912,11 +1908,7 @@
19121908
(struct.get $bigarray $ba_dim (local.get $ba))
19131909
(i32.const 0)))
19141910
(then (call $caml_bound_error)))
1915-
(ref.i31 (i32.or
1916-
(call $ta_get_ui8 (local.get $data) (local.get $p))
1917-
(i32.shl (call $ta_get_ui8 (local.get $data)
1918-
(i32.add (local.get $p) (i32.const 1)))
1919-
(i32.const 8)))))
1911+
(ref.i31 (call $ta_get16_ui8 (local.get $data) (local.get $p))))
19201912

19211913
(func (export "caml_ba_uint8_get32")
19221914
(param $vba (ref eq)) (param $i (ref eq)) (result i32)
@@ -1933,19 +1925,7 @@
19331925
(struct.get $bigarray $ba_dim (local.get $ba))
19341926
(i32.const 0)))
19351927
(then (call $caml_bound_error)))
1936-
(i32.or
1937-
(i32.or
1938-
(call $ta_get_ui8 (local.get $data) (local.get $p))
1939-
(i32.shl (call $ta_get_ui8 (local.get $data)
1940-
(i32.add (local.get $p) (i32.const 1)))
1941-
(i32.const 8)))
1942-
(i32.or
1943-
(i32.shl (call $ta_get_ui8 (local.get $data)
1944-
(i32.add (local.get $p) (i32.const 2)))
1945-
(i32.const 16))
1946-
(i32.shl (call $ta_get_ui8 (local.get $data)
1947-
(i32.add (local.get $p) (i32.const 3)))
1948-
(i32.const 24)))))
1928+
(return_call $ta_get32_ui8 (local.get $data) (local.get $p)))
19491929

19501930
(func (export "caml_ba_uint8_get64")
19511931
(param $vba (ref eq)) (param $i (ref eq)) (result i64)
@@ -1963,42 +1943,12 @@
19631943
(i32.const 0)))
19641944
(then (call $caml_bound_error)))
19651945
(i64.or
1966-
(i64.or
1967-
(i64.or
1968-
(i64.extend_i32_u
1969-
(call $ta_get_ui8 (local.get $data) (local.get $p)))
1970-
(i64.shl (i64.extend_i32_u
1971-
(call $ta_get_ui8 (local.get $data)
1972-
(i32.add (local.get $p) (i32.const 1))))
1973-
(i64.const 8)))
1974-
(i64.or
1975-
(i64.shl (i64.extend_i32_u
1976-
(call $ta_get_ui8 (local.get $data)
1977-
(i32.add (local.get $p) (i32.const 2))))
1978-
(i64.const 16))
1979-
(i64.shl (i64.extend_i32_u
1980-
(call $ta_get_ui8 (local.get $data)
1981-
(i32.add (local.get $p) (i32.const 3))))
1982-
(i64.const 24))))
1983-
(i64.or
1984-
(i64.or
1985-
(i64.shl (i64.extend_i32_u
1986-
(call $ta_get_ui8 (local.get $data)
1987-
(i32.add (local.get $p) (i32.const 4))))
1988-
(i64.const 32))
1989-
(i64.shl (i64.extend_i32_u
1990-
(call $ta_get_ui8 (local.get $data)
1991-
(i32.add (local.get $p) (i32.const 5))))
1992-
(i64.const 40)))
1993-
(i64.or
1994-
(i64.shl (i64.extend_i32_u
1995-
(call $ta_get_ui8 (local.get $data)
1996-
(i32.add (local.get $p) (i32.const 6))))
1997-
(i64.const 48))
1998-
(i64.shl (i64.extend_i32_u
1999-
(call $ta_get_ui8 (local.get $data)
2000-
(i32.add (local.get $p) (i32.const 7))))
2001-
(i64.const 56))))))
1946+
(i64.extend_i32_u
1947+
(call $ta_get32_ui8 (local.get $data) (local.get $p)))
1948+
(i64.shl (i64.extend_i32_u
1949+
(call $ta_get32_ui8 (local.get $data)
1950+
(i32.add (local.get $p) (i32.const 4))))
1951+
(i64.const 32))))
20021952

20031953
(func (export "caml_ba_uint8_set16")
20041954
(param $vba (ref eq)) (param $i (ref eq)) (param $v (ref eq))
@@ -2017,10 +1967,7 @@
20171967
(struct.get $bigarray $ba_dim (local.get $ba))
20181968
(i32.const 0)))
20191969
(then (call $caml_bound_error)))
2020-
(call $ta_set_ui8 (local.get $data) (local.get $p) (local.get $d))
2021-
(call $ta_set_ui8 (local.get $data)
2022-
(i32.add (local.get $p) (i32.const 1))
2023-
(ref.i31 (i32.shr_u (i31.get_s (local.get $d)) (i32.const 8))))
1970+
(call $ta_set16_ui8 (local.get $data) (local.get $p) (local.get $d))
20241971
(ref.i31 (i32.const 0)))
20251972

20261973
(func (export "caml_ba_uint8_set32")
@@ -2039,17 +1986,7 @@
20391986
(struct.get $bigarray $ba_dim (local.get $ba))
20401987
(i32.const 0)))
20411988
(then (call $caml_bound_error)))
2042-
(call $ta_set_ui8 (local.get $data) (local.get $p)
2043-
(ref.i31 (local.get $d)))
2044-
(call $ta_set_ui8 (local.get $data)
2045-
(i32.add (local.get $p) (i32.const 1))
2046-
(ref.i31 (i32.shr_u (local.get $d) (i32.const 8))))
2047-
(call $ta_set_ui8 (local.get $data)
2048-
(i32.add (local.get $p) (i32.const 2))
2049-
(ref.i31 (i32.shr_u (local.get $d) (i32.const 16))))
2050-
(call $ta_set_ui8 (local.get $data)
2051-
(i32.add (local.get $p) (i32.const 3))
2052-
(ref.i31 (i32.shr_u (local.get $d) (i32.const 24))))
1989+
(call $ta_set32_ui8 (local.get $data) (local.get $p) (local.get $d))
20531990
(ref.i31 (i32.const 0)))
20541991

20551992
(func (export "caml_ba_uint8_set64")
@@ -2068,29 +2005,11 @@
20682005
(struct.get $bigarray $ba_dim (local.get $ba))
20692006
(i32.const 0)))
20702007
(then (call $caml_bound_error)))
2071-
(call $ta_set_ui8 (local.get $data) (local.get $p)
2072-
(ref.i31 (i32.wrap_i64 (local.get $d))))
2073-
(call $ta_set_ui8 (local.get $data)
2074-
(i32.add (local.get $p) (i32.const 1))
2075-
(ref.i31 (i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 8)))))
2076-
(call $ta_set_ui8 (local.get $data)
2077-
(i32.add (local.get $p) (i32.const 2))
2078-
(ref.i31 (i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 16)))))
2079-
(call $ta_set_ui8 (local.get $data)
2080-
(i32.add (local.get $p) (i32.const 3))
2081-
(ref.i31 (i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 24)))))
2082-
(call $ta_set_ui8 (local.get $data)
2008+
(call $ta_set32_ui8 (local.get $data) (local.get $p)
2009+
(i32.wrap_i64 (local.get $d)))
2010+
(call $ta_set32_ui8 (local.get $data)
20832011
(i32.add (local.get $p) (i32.const 4))
2084-
(ref.i31 (i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 32)))))
2085-
(call $ta_set_ui8 (local.get $data)
2086-
(i32.add (local.get $p) (i32.const 5))
2087-
(ref.i31 (i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 40)))))
2088-
(call $ta_set_ui8 (local.get $data)
2089-
(i32.add (local.get $p) (i32.const 6))
2090-
(ref.i31 (i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 48)))))
2091-
(call $ta_set_ui8 (local.get $data)
2092-
(i32.add (local.get $p) (i32.const 7))
2093-
(ref.i31 (i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 56)))))
2012+
(i32.wrap_i64 (i64.shr_u (local.get $d) (i64.const 32))))
20942013
(ref.i31 (i32.const 0)))
20952014

20962015
(export "caml_bytes_of_array" (func $caml_string_of_array))

runtime/wasm/bigstring.wat

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
(func $ta_create (param i32) (param anyref) (result anyref)))
3636
(import "bindings" "ta_get_ui8"
3737
(func $ta_get_ui8 (param (ref extern)) (param i32) (result i32)))
38+
(import "bindings" "ta_get32_ui8"
39+
(func $ta_get32_ui8 (param (ref extern)) (param i32) (result i32)))
3840
(import "bindings" "ta_set_ui8"
3941
(func $ta_set_ui8 (param (ref extern)) (param i32) (param (ref i31))))
4042
(import "bindings" "ta_subarray"
@@ -63,19 +65,7 @@
6365
(local.set $h
6466
(call $caml_hash_mix_int
6567
(local.get $h)
66-
(i32.or
67-
(i32.or
68-
(call $ta_get_ui8 (local.get $data) (local.get $i))
69-
(i32.shl (call $ta_get_ui8 (local.get $data)
70-
(i32.add (local.get $i) (i32.const 1)))
71-
(i32.const 8)))
72-
(i32.or
73-
(i32.shl (call $ta_get_ui8 (local.get $data)
74-
(i32.add (local.get $i) (i32.const 2)))
75-
(i32.const 16))
76-
(i32.shl (call $ta_get_ui8 (local.get $data)
77-
(i32.add (local.get $i) (i32.const 3)))
78-
(i32.const 24))))))
68+
(call $ta_get32_ui8 (local.get $data) (local.get $i))))
7969
(local.set $i (i32.add (local.get $i) (i32.const 4)))
8070
(br $loop))))
8171
(local.set $w (i32.const 0))

runtime/wasm/runtime.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,26 @@
194194
ta_get_ui16: (a, i) => a[i],
195195
ta_get_i8: (a, i) => a[i],
196196
ta_get_ui8: (a, i) => a[i],
197+
ta_get16_ui8: (a, i) => a[i] | (a[i + 1] << 8),
198+
ta_get32_ui8: (a, i) =>
199+
a[i] | (a[i + 1] << 8) | (a[i + 2] << 16) | (a[i + 3] << 24),
197200
ta_set_f64: (a, i, v) => (a[i] = v),
198201
ta_set_f32: (a, i, v) => (a[i] = v),
199202
ta_set_i32: (a, i, v) => (a[i] = v),
200203
ta_set_i16: (a, i, v) => (a[i] = v),
201204
ta_set_ui16: (a, i, v) => (a[i] = v),
202205
ta_set_i8: (a, i, v) => (a[i] = v),
203206
ta_set_ui8: (a, i, v) => (a[i] = v),
207+
ta_set16_ui8: (a, i, v) => {
208+
a[i] = v;
209+
a[i + 1] = v >> 8;
210+
},
211+
ta_set32_ui8: (a, i, v) => {
212+
a[i] = v;
213+
a[i + 1] = v >> 8;
214+
a[i + 2] = v >> 16;
215+
a[i + 3] = v >> 24;
216+
},
204217
ta_fill: (a, v) => a.fill(v),
205218
ta_blit: (s, d) => d.set(s),
206219
ta_subarray: (a, i, j) => a.subarray(i, j),

0 commit comments

Comments
 (0)