Commit 03bbead
committed
Free the ABI string buffers on the JS bridge
Every Ruby String crossing to JS is copied into a fresh `xmalloc` buffer by
`rstring_to_abi_string`, and `rb_js_abi_host_string_free` is never called on
it. The canonical ABI leaves the caller owning a lowered string param, and the
generated bindings only pass ptr/len, so those bytes are never reclaimed. wasm
linear memory never shrinks, so the loss is permanent.
Four sites lower a string without freeing: `_rb_js_eval_js`, `_rb_js_obj_aref`,
`_rb_js_obj_aset` and `_rb_js_string_to_js`. Because `_rb_js_obj_call` resolves
its method through `_rb_js_obj_aref`, EVERY `JS::Object#call` leaks the length
of its method name.
Two more leak in the opposite direction. `js-value-to-string` and
`js-value-typeof` have the host allocate through `cabi_realloc` and hand
ownership to the guest, but `_rb_js_obj_to_s` and `_rb_js_obj_typeof` copy the
bytes out with `rb_utf8_str_new` and abandon the buffer. Their siblings
`_rb_js_obj_to_i` and `_rb_js_obj_to_f` already call
`rb_js_abi_host_raw_integer_free` on the same kind of returned payload, so this
brings the two string readers in line with them.
In `_rb_js_eval_js`, `_rb_js_obj_aref` and `_rb_js_obj_aset` the free has to
precede `raise_js_error_if_failure`, which longjmps past anything after it.
`types.h` gains a `rb_js_abi_host_string_free` alias so the component-model
build resolves it to `ext_string_free`; the legacy bindings already declare it.
Both implementations are the same guarded `free`.
Measured on a 60fps canvas application making roughly 1000 crossings per frame:
about 1 MB/s of unreclaimable linear memory before, and flat after. Such an
application dies at 2 GB rather than 4, because the generated glue reads guest
pointers as signed i32, so the first symptom is a confusing
"RangeError: Start offset -2147..." out of `new Uint8Array`.1 parent 3f6e185 commit 03bbead
3 files changed
Lines changed: 39 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
101 | 101 | | |
102 | 102 | | |
103 | 103 | | |
| 104 | + | |
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
| |||
197 | 198 | | |
198 | 199 | | |
199 | 200 | | |
| 201 | + | |
200 | 202 | | |
201 | 203 | | |
202 | 204 | | |
| |||
224 | 226 | | |
225 | 227 | | |
226 | 228 | | |
| 229 | + | |
227 | 230 | | |
228 | 231 | | |
229 | 232 | | |
| |||
346 | 349 | | |
347 | 350 | | |
348 | 351 | | |
349 | | - | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
350 | 355 | | |
351 | 356 | | |
352 | 357 | | |
| |||
366 | 371 | | |
367 | 372 | | |
368 | 373 | | |
369 | | - | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
370 | 377 | | |
371 | 378 | | |
372 | 379 | | |
| |||
494 | 501 | | |
495 | 502 | | |
496 | 503 | | |
497 | | - | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
498 | 508 | | |
499 | 509 | | |
500 | 510 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| 47 | + | |
47 | 48 | | |
48 | 49 | | |
49 | 50 | | |
| |||
Lines changed: 25 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
441 | 441 | | |
442 | 442 | | |
443 | 443 | | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
444 | 469 | | |
0 commit comments