Skip to content

Boehm GC for WebAssembly #4812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 13, 2025
Merged

Boehm GC for WebAssembly #4812

merged 1 commit into from
Jun 13, 2025

Conversation

aykevl
Copy link
Member

@aykevl aykevl commented Mar 17, 2025

See: #4385

This is an incomplete port. Things that need to be resolved are:

  • Boehm GC support #4385 needs to be merged first, and this PR needs to be rebased.
  • We need to have two separate builds of wasi-libc since the MALLOC_IMPL macro is going to be different. I think it's easiest to start doing this build not when creating a TinyGo tarball but when running TinyGo itself (similar to picolibc, musl, etc). This makes it easier to build different variants easily and when needed.

The performance improvements can be large. For example, for the html package some benchmarks are more than 50% faster:

$ benchstat html-precise.txt html-boehm.txt
               │ html-precise.txt │           html-boehm.txt           │
               │      sec/op      │   sec/op     vs base               │
Escape               110.29µ ± 0%   73.62µ ± 3%  -33.25% (p=0.002 n=6)
EscapeNone            48.37µ ± 0%   49.15µ ± 1%   +1.62% (p=0.002 n=6)
Unescape             192.31µ ± 5%   84.53µ ± 3%  -56.04% (p=0.002 n=6)
UnescapeNone          2.638µ ± 1%   2.559µ ± 4%        ~ (p=0.132 n=6)
UnescapeSparse        45.44µ ± 2%   18.55µ ± 1%  -59.17% (p=0.002 n=6)
UnescapeDense        182.55µ ± 1%   79.63µ ± 1%  -56.38% (p=0.002 n=6)
geomean               53.11µ        32.40µ       -39.00%

Pause times should also be reduced quite a bit, likely much more than the performance improvements. I did not test those, though.

If you want to try this PR, you will have to rebuild wasi-libc:

$ rm -rf lib/wasi-libc/sysroot/ lib/wasi-libc/build
$ make wasi-libc

(Also note that only wasip1 is supported right now, other wasm variants should be easy to add in the future).

Copy link

github-actions bot commented Mar 17, 2025

Size difference with the dev branch:

Binary size difference
not the same command!
    tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650
    go: downloading tinygo.org/x/tinyfont v0.3.0
not the same command!
    tinygo build -size short -o ./build/test.hex -target=pico ./examples/tmc5160/main.go
    go: downloading github.com/orsinium-labs/tinymath v1.1.0
not the same command!
    tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/websocket/dial/
    go: downloading golang.org/x/net v0.33.0
not the same command!
    tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/mqttclient/natiu/
    go: downloading github.com/soypat/natiu-mqtt v0.5.1
not the same command!
    tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/mqttclient/paho/
    go: downloading github.com/eclipse/paho.mqtt.golang v1.2.0
 flash                          ram
 before   after   diff          before   after   diff
  16564   16564      0   0.00%    4172    4172      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/adafruit4650
  61844   61844      0   0.00%    6180    6180      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adt7410/main.go
   8840    8840      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/adxl345/main.go
  13572   13572      0   0.00%    6796    6796      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/amg88xx
   9000    9000      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go
  11816   11816      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/apds9960/proximity/main.go
   9264    9264      0   0.00%    4752    4752      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go
   7576    7576      0   0.00%    2320    2320      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go
   8084    8084      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bh1750/main.go
   7452    7452      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/blinkm/main.go
  71124   71124      0   0.00%    3656    3656      0   0.00% tinygo build -size short -o ./build/test.hex -target=pinetime     ./examples/bma42x/main.go
  64556   64556      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmi160/main.go
  27620   27620      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp180/main.go
  64480   64480      0   0.00%    6220    6220      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/bmp280/main.go
  11944   11944      0   0.00%    4812    4812      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bmp388/main.go
   7868    7868      0   0.00%    3352    3352      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/sram/main.go
  22184   22184      0   0.00%    3556    3556      0   0.00% tinygo build -size short -o ./build/test.hex -target=bluepill ./examples/ds1307/time/main.go
  70136   70136      0   0.00%    6368    6368      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/ds3231/main.go
   4628    4628      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/easystepper/main.go
  70328   70328      0   0.00%    6980    6980      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/flash/console/spi
  67088   67088      0   0.00%    9020    9020      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/flash/console/qspi
   7300    7300      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/gc9a01/main.go
  67496   67496      0   0.00%    6360    6360      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/i2c/main.go
  67912   67912      0   0.00%    6504    6504      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/gps/uart/main.go
   7864    7864      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/hcsr04/main.go
   5756    5756      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/customchar/main.go
   5796    5796      0   0.00%    2280    2280      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hd44780/text/main.go
  10420   10420      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/hd44780i2c/main.go
  14700   14700      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/hts221/main.go
  16176   16176      0   0.00%    2364    2364      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go
  10272   10272      0   0.00%    6916    6916      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic
  11060   11060      0   0.00%    4876    4876      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/basic
  29636   29636      0   0.00%   38076   38076      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/pyportal_boing
  10300   10300      0   0.00%    6916    6916      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/scroll
  11140   11140      0   0.00%    4876    4876      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/ili9341/scroll
 263720  263720      0   0.00%   46744   46744      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/slideshow
  11044   11044      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go
  14056   14056      0   0.00%    6580    6580      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go
  26348   26348      0   0.00%    2328    2328      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go
  12368   12368      0   0.00%    4788    4788      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go
  10080   10080      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mag3110/main.go
   9240    9240      0   0.00%    4772    4772      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017/main.go
   9644    9644      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp23017-multiple/main.go
   9488    9488      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp3008/main.go
  69220   69220      0   0.00%    6196    6196      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mcp2515/main.go
  27148   27148      0   0.00%    3640    3640      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/microbitmatrix/main.go
  26964   26964      0   0.00%    5620    5620      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit-v2 ./examples/microbitmatrix/main.go
   7540    7540      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mma8653/main.go
   7448    7448      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/mpu6050/main.go
  75832   75832      0   0.00%    7452    7452      0   0.00% tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/main.go
  12192   12192      0   0.00%    3352    3352      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/pca9685/main.go
   6268    6268      0   0.00%    3292    3292      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go
   4652    4652      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go
  10480   10480      0   0.00%    3328    3328      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/seesaw
   2841    2841      0   0.00%     558     558      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino ./examples/servo
  13764   13764      0   0.00%    3400    3400      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico     ./examples/sgp30
   8216    8216      0   0.00%    6788    6788      0   0.00% tinygo build -size short -o ./build/test.hex -target=pybadge ./examples/shifter/main.go
  58008   58008      0   0.00%    3688    3688      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
  58000   58000      0   0.00%    3696    3696      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht4x/main.go
  58008   58008      0   0.00%    3688    3688      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go
   6044    6044      0   0.00%    2288    2288      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go
   5572    5572      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go
   5900    5900      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1331/main.go
   6808    6808      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7735/main.go
   6704    6704      0   0.00%    2284    2284      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/st7789/main.go
  16784   16784      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/thermistor/main.go
  10124   10124      0   0.00%    4532    4532      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-bluefruit ./examples/tone
  10180   10180      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/tm1637/main.go
  10752   10752      0   0.00%    3340    3340      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/touch/capacitive
   9164    9164      0   0.00%    6780    6780      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/fourwire/main.go
  12576   12576      0   0.00%    6976    6976      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/touch/resistive/pyportal_touchpaint/main.go
  15140   15140      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl53l1x/main.go
  13660   13660      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/vl6180x/main.go
  24780   24780      0   0.00%   13720   13720      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840-sense ./examples/waveshare-epd/epd1in54/main.go
   6532    6532      0   0.00%    2324    2324      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13/main.go
   6168    6168      0   0.00%    2316    2316      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd2in13x/main.go
   6452    6452      0   0.00%    2324    2324      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/waveshare-epd/epd4in2/main.go
  25972   25972      0   0.00%   16412   16412      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/waveshare-epd/epd2in66b/main.go
   6960    6960      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812
   5584    5584      0   0.00%    9538    9538      0   0.00% '-xesppie' is not a recognized feature for this target (ignoring feature)
  63216   63216      0   0.00%    5948    5948      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/is31fl3731/main.go
   1581    1581      0   0.00%     598     598      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino   ./examples/ws2812
   1056    1056      0   0.00%     180     180      0   0.00% tinygo build -size short -o ./build/test.hex -target=digispark ./examples/ws2812
  32096   32096      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/bme280/main.go
  16368   16368      0   0.00%    4724    4724      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/microphone/main.go
  11532   11532      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/buzzer/main.go
  12300   12300      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=trinket-m0 ./examples/veml6070/main.go
   6860    6860      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/simple/main.go
   8776    8776      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l293x/speed/main.go
   6836    6836      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/simple/main.go
   9180    9180      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/l9110x/speed/main.go
   7416    7416      0   0.00%    3324    3324      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-f103rb ./examples/shiftregister/main.go
   6732    6732      0   0.00%    2272    2272      0   0.00% '-xesppie' is not a recognized feature for this target (ignoring feature)
  13276   13276      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis2mdl/main.go
   9884    9884      0   0.00%    4764    4764      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/max72xx/main.go
  76656   76656      0   0.00%    6336    6336      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go
  36388   36388      0   0.00%    3988    3988      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8523/
  71748   71748      0   0.00%    6344    6344      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/alarm/
   7256    7256      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/clkout/
  71292   71292      0   0.00%    6340    6340      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/time/
  71644   71644      0   0.00%    6344    6344      0   0.00% tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/timer/
  12112   12112      0   0.00%    3304    3304      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/qmi8658c/main.go
  10764   10764      0   0.00%    3288    3288      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-rp2040 ./examples/pcf8591/
   8756    8756      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina260/main.go
  12344   12344      0   0.00%    4780    4780      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/ina219/main.go
   9408    9408      0   0.00%    5248    5248      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-l432kc ./examples/aht20/main.go
  74080   74080      0   0.00%   10756   10756      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/sdcard/console/
  62264   62264      0   0.00%    8228    8228      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/i2csoft/adt7410/
  10388   10388      0   0.00%    6788    6788      0   0.00% tinygo build -size short -o ./build/test.elf -target=wioterminal ./examples/axp192/m5stack-core2-blinky/
   8896    8896      0   0.00%    3276    3276      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/xpt2046/main.go
  13220   13220      0   0.00%    4936    4936      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/sx126x/lora_rxtx/
  31208   31208      0   0.00%    4544    4544      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/ssd1289/main.go
  11156   11156      0   0.00%    4252    4252      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/irremote/main.go
  11980   11980      0   0.00%    3324    3324      0   0.00% tinygo build -size short -o ./build/test.hex -target=badger2040 ./examples/uc8151/main.go
  10400   10400      0   0.00%    3356    3356      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/scd4x/main.go
   8028    8028      0   0.00%    4748    4748      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=circuitplay-express ./examples/makeybutton/main.go
   9572    9572      0   0.00%    4764    4764      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ds18b20/main.go
  82956   82956      0   0.00%    6592    6592      0   0.00% tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/lora/lorawan/atcmd/
  15968   15968      0   0.00%    4956    4956      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/as560x/main.go
   9804    9804      0   0.00%    3296    3296      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu6886/main.go
   7840    7840      0   0.00%    4740    4740      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ttp229/main.go
  67284   67284      0   0.00%    4816    4816      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/ndir/main_ndir.go
  62588   62588      0   0.00%    3784    3784      0   0.00% tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ndir/main_ndir.go
  65592   65592      0   0.00%    6252    6252      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/ndir/main_ndir.go
   9256    9256      0   0.00%    3288    3288      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mpu9150/main.go
  11524   11524      0   0.00%    3324    3324      0   0.00% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/sh1106/macropad_spi
   8280    8280      0   0.00%    3760    3760      0   0.00% tinygo build -size short -o ./build/test.hex -target=macropad-rp2040 ./examples/encoders/quadrature-interrupt
  66644   66644      0   0.00%    4784    4784      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/mcp9808/main.go
  30168   30168      0   0.00%    3672    3672      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/tmc2209/main.go
  13112   13112      0   0.00%    3284    3284      0   0.00% tinygo build -size short -o ./build/test.hex -target=pico ./examples/tmc5160/main.go
  12456   12456      0   0.00%    4544    4544      0   0.00% tinygo build -size short -o ./build/test.uf2 -target=nicenano ./examples/sharpmem/main.go
  60768   60768      0   0.00%    5968    5968      0   0.00% tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/max6675/main.go
  86628   86628      0   0.00%    5140    5140      0   0.00% tinygo build -size short -o ./build/test.hex -target=challenger-rp2040 ./examples/net/ntpclient/
 298544  298544      0   0.00%   15908   15908      0   0.00% tinygo build -size short -o ./build/test.hex -target=pyportal -stack-size 8kb ./examples/net/http-get/
 119064  119064      0   0.00%    7828    7828      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-nano33 -stack-size 8kb ./examples/net/tcpclient/
 251032  251032      0   0.00%   12860   12860      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/websocket/dial/
 102536  102536      0   0.00%    9808    9808      0   0.00% tinygo build -size short -o ./build/test.hex -target=metro-m4-airlift -stack-size 8kb ./examples/net/socket/
 339988  339988      0   0.00%   16520   16520      0   0.00% tinygo build -size short -o ./build/test.hex -target=matrixportal-m4 -stack-size 8kb ./examples/net/webstatic/
 111288  111288      0   0.00%    7784    7784      0   0.00% tinygo build -size short -o ./build/test.hex -target=arduino-mkrwifi1010 -stack-size 8kb ./examples/net/tlsclient/
 153776  153776      0   0.00%    6524    6524      0   0.00% tinygo build -size short -o ./build/test.hex -target=nano-rp2040 -stack-size 8kb ./examples/net/mqttclient/natiu/
 116284  116284      0   0.00%   13104   13104      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webclient/
 290240  290240      0   0.00%   19564   19564      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/webserver/
 290544  290544      0   0.00%   20864   20864      0   0.00% tinygo build -size short -o ./build/test.hex -target=wioterminal -stack-size 8kb ./examples/net/mqttclient/paho/
 118132  118132      0   0.00%    9504    9504      0   0.00% tinygo build -size short -o ./build/test.hex -target=elecrow-rp2040 -stack-size 8kb ./examples/net/tlsclient/
 118012  118012      0   0.00%    9544    9544      0   0.00% tinygo build -size short -o ./build/test.hex -target=elecrow-rp2350 -stack-size 8kb ./examples/net/ntpclient/
5703198 5703198      0   0.00%  857222  857222      0   0.00%

@deadprogram
Copy link
Member

@aykevl you can now rebase this PR against dev now that #4385 was merged. Thanks!

@aykevl
Copy link
Member Author

aykevl commented Mar 18, 2025

A few more changes are needed to make this PR ready, it needs more than just rebasing. I'm working on it!

@aykevl aykevl marked this pull request as ready for review April 9, 2025 14:39
@aykevl
Copy link
Member Author

aykevl commented Apr 9, 2025

Should be ready now.
The Boehm GC is disabled by default, it can be used with -gc=boehm.

@aykevl aykevl changed the title WIP: Boehm GC for WebAssembly Boehm GC for WebAssembly Apr 9, 2025
@aykevl
Copy link
Member Author

aykevl commented Apr 9, 2025

The main drawback right now is that it will often output messages like the following:

GC Warning: Repeated allocation of very large block (appr. size 68 KiB):
        May lead to memory leak and poor performance

I think the only reasonable fix is to just disable output entirely (see ivmai/bdwgc#721) or disable it using GC_set_warn_proc since using GC_malloc_ignore_off_page is not safe with Go (inner pointers are allowed, even far into an object, so GC_malloc_ignore_off_page is unsafe even if it would probably work for most programs in practice).

@deadprogram
Copy link
Member

@aykevl now that ivmai/bdwgc@6d10870 was merged, I think that this PR can proceed?

@deadprogram
Copy link
Member

@aykevl reminder about this PR 😺

@aykevl
Copy link
Member Author

aykevl commented May 23, 2025

Updated the PR.

  • rebased on dev
  • added GC_DISABLE_SNPRINTF=1 on WebAssembly to avoid linking in printf related functions (saves ~18kB of binary size)
  • disabled warnings on WebAssembly since they happen frequently and there's not much we can do about them.

@deadprogram
Copy link
Member

@aykevl
Copy link
Member Author

aykevl commented May 23, 2025

@deadprogram I think it's more likely to be a flaky test. I don't see how this PR should affect windows/386.

@aykevl
Copy link
Member Author

aykevl commented May 23, 2025

@deadprogram actually, you might be right. The Boehm GC is also used on Windows, and this PR updates the bdwgc library.

@aykevl
Copy link
Member Author

aykevl commented May 30, 2025

I can reproduce this issue in my Windows VM (running on ARM!).

@aykevl
Copy link
Member Author

aykevl commented May 30, 2025

I think it's related to ivmai/bdwgc#736. Probably our bug and not one in bdwgc, but asking to be sure.

EDIT: might not be the actual GOOS=386 issue here.

@aykevl
Copy link
Member Author

aykevl commented Jun 2, 2025

Oh it is actually ivmai/bdwgc@e8aedf6 that is causing this issue on Windows.

@aykevl
Copy link
Member Author

aykevl commented Jun 2, 2025

Pushed a workaround to disable bdwgc on Windows/386 for now. I don't think that's a big loss, I think having bdwgc on WASIp1 is much more important.

@deadprogram
Copy link
Member

@aykevl
Copy link
Member Author

aykevl commented Jun 2, 2025

Should be fixed now.

@deadprogram
Copy link
Member

@aykevl
Copy link
Member Author

aykevl commented Jun 2, 2025

I can't reproduce this issue locally. Trying to re-run the tests to see whether it's a flaky one.

@deadprogram
Copy link
Member

I can't reproduce this issue locally. Trying to re-run the tests to see whether it's a flaky one.

That time it failed on yet a different test. I restarted one more time...

@deadprogram
Copy link
Member

It fails on a different test each time, looking like some kind of race? In any case, still fails eventually on some test or another. 😿

@deadprogram
Copy link
Member

Passing all tests in the last run. Whatever race condition is happening, I do not think it is related to this PR.

Copy link
Member

@deadprogram deadprogram left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my point of view, this PR appears ready to merge now.

Anyone have any further feedback before I do so?

@aykevl
Copy link
Member Author

aykevl commented Jun 11, 2025

I'm not so sure about that. I think you just managed to avoid a somewhat rare crash this time, but the bug is still there.

@deadprogram
Copy link
Member

I'm not so sure about that. I think you just managed to avoid a somewhat rare crash this time, but the bug is still there.

@aykevl I don't think that is specific to this PR, do you?

@deadprogram deadprogram added this to the 0.38.0 milestone Jun 12, 2025
This adds support for `-gc=boehm` on `-target=wasip1` and `-target=wasm`
(in a browser or NodeJS). Notably it does *not* add Boehm GC support for
`-target=wasip2`, since that target doesn't have a real libc.
@aykevl
Copy link
Member Author

aykevl commented Jun 13, 2025

I don't think that is specific to this PR, do you?

I think it is, since we were also hitting issues on windows/386. I think the windows/386 issues and the flaky builds are related.

Currently trying to reproduce it on my system.

@aykevl
Copy link
Member Author

aykevl commented Jun 13, 2025

Changed to use the bdwgc commit just before ivmai/bdwgc@e8aedf6 which I think introduced the Windows issues (GOARCH=386 at least, but I also suspect it is causing the flaky CI issue). See ivmai/bdwgc#736 (comment) for details. This does mean we lose some of the recent size improvements, but fixing these issues will need a bit more time. To at least have (opt-in) bdwgc support in wasm for this release (even if it grows the binary more than needed) is better than having nothing.

Also, this brings back bdwgc support in GOARCH=386, which isn't super useful but a nice side effect I guess.

@deadprogram
Copy link
Member

To at least have (opt-in) bdwgc support in wasm for this release (even if it grows the binary more than needed) is better than having nothing.

Agreed!

@aykevl
Copy link
Member Author

aykevl commented Jun 13, 2025

And all tests pass in the first CI run, this gives me some confidence I was right about that one bdwgc commit being a problem.

@deadprogram
Copy link
Member

Thanks for working on this @aykevl and the various needed fixes along the way. Now merging.

@deadprogram deadprogram merged commit c08b2df into dev Jun 13, 2025
33 of 35 checks passed
@deadprogram deadprogram deleted the bdwgc-wasip1 branch June 13, 2025 12:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants