Wasmtime 47.0.0 iznāca 20. jūlijā un ieslēdza divus WebAssembly priekšlikumus pēc noklusējuma: atkritumu savākšanu (Wasm GC) un izņēmumu apstrādi. Vēl iepriekšējā versijā abiem vajadzēja atsevišķu karogu konfigurācijā. Tagad jebkurš modulis, kas nonāk izpildlaikā, drīkst definēt savas struktūras un masīvus, izmest izņēmumu un to noķert.
Bytecode Alliance izstrādātājs Niks Ficdžeralds jaunumu apraksta kā vairāku gadu inženierdarba noslēgumu. Apjomu var nomērīt. Tikai izņēmumu atbalsts Cranelift kompilatorā prasīja 37 izmaiņu pieprasījumus un aptuveni 16 000 jaunu koda rindu.
Savācējs kopē objektus starp divām kaudzes pusēm
Wasmtime izmanto Čeinija tipa pusattēlu kopējošo savācēju. Kaudze ir sadalīta divās pusēs. Kad viena piepildās, savācējs pārceļ dzīvos objektus uz otru pusi un visu atlikušo atmet vienā gājienā. Atbrīvošana tāpēc maksā vienādi neatkarīgi no mirušo objektu skaita. Cena ir atmiņa. Pusattēlu shēma prasa turēt rezervē tukšu kaudzes pusi, kas pēc izmēra atbilst lietotajai.
Netipiskākā izvēle ir atsauču formāts. Wasmtime objektus adresē nevis ar procesora rādītāju, bet ar 32 bitu indeksu GC kaudzes lineārajā atmiņā. Indekss ir divreiz mazāks par rādītāju uz 64 bitu mašīnas. Izpildlaiks to var pārbaudīt pirms lietošanas, jo ārpus kaudzes robežām šāds indekss vienkārši nav derīgs.
Ātrums pagaidām nav galvenais mērķis.
Līdz šim inženierdarbs gājis savācēja pareizībai, mazāk tā veiktspējai, raksta Ficdžeralds.
Izvēle daļēji izriet no tā, kam Wasmtime paredzēts. Tas retāk darbina vienu ilgdzīvojošu procesu un biežāk rada daudz mazu, īslaicīgu instanču, kuras nomirst, pirms savācējs paspētu sākt otro ciklu.
Izņēmumi maksā tikai tad, kad tos izmet
Otrs priekšlikums aizstāj pašdarinātas izsaukumu konvencijas ar parastiem throw un try/catch konstruktiem. Kriss Falins, kas šo daļu būvēja, apraksta Cranelift jauno instrukciju try_call. Apdarinātājs tajā ir parasts pamatbloks, nevis īpašs gadījums. Izmešana notiek tikai caur izpildlaika libcall izsaukumiem, tāpēc kompilatoram nav jāizseko izmešanas vietas visā starpkodā. Kompilators tāpēc nepārbauda kļūdas kodu pēc katra izsaukuma. Informāciju par to, kur meklēt apdarinātāju, glabā blakustabulas un tās nolasa tikai brīdī, kad izņēmums patiešām lido.
Cena tomēr ir. Katrs try_call izsaukums uzskata par sabojātiem visus reģistrus, tāpēc kompilatoram dzīvās vērtības jāizmet uz steka. Izņēmuma objekts exnref ir GC objekts, tāpēc izņēmumus nevarēja pabeigt pirms savācēja. Tagiem ir atsevišķa identitāte katrā moduļa instancē, tāpēc steka rāmī jāglabā instances rādītājs, ko atritinātājs salīdzina, meklējot pareizo apdarinātāju.
Falins atzīst, ka darba apjomu sākumā novērtējis divreiz par zemu. Vainīgas bija tieši šīs saiknes ar savācēju un ar robežu starp resursdatoru un viesa kodu.
Pārlūki to prata jau kopš 2023. gada
Wasm GC pārlūkos nav jaunums. Chrome 119 to ieslēdza 2023. gada oktobrī, Firefox 120 mēnesi vēlāk, Safari 18.2 2024. gada decembrī. Kotlin rīkkopa uz jaunāko WasmGC priekšlikuma versiju pārgāja 1.9.20 laidienā. Dart kompilē Flutter lietotnes uz to pašu formātu.
Sekas bija praktiskas. Valodas ar atkritumu savākšanu, kas kompilējas uz Wasm GC, reāli darbojās tikai pārlūkā. Serverī vai malas izpildlaikā tās vai nu vispār nestartēja, vai arī vilka līdzi pašas savu savācēju. Tādā gadījumā kompilators to iepakoja modulī un moduļa izmērs pieauga. Wasmtime 47 šo plaisu aizver aptuveni divarpus gadus pēc Chrome.
Abas funkcijas nav atsevišķi eksperimenti. Tās ietilpst WebAssembly 3.0 standartā, ko darba grupa pabeidza 2025. gada septembrī kopā ar 64 bitu adresēšanu, vairākām atmiņām un asteszvaniem. Izpildlaikam, kas grib teikt, ka atbalsta pašreizējo standartu, savācējs un izņēmumi vairs nav izvēles jautājums.
Kas vēl ir 47. versijā
Laidiens izmet wasi-threads un wasi-common atbalstu saskaņā ar agrāk pieņemtu RFC. Cranelift iemācījās kompakto atritināšanas formātu Mach-O platformās. Engine ieguva atspoguļošanas API, ar ko var nolasīt lielāko daļu Config iestatījumu. Fiber atbalsts arhitektūrām bez dzimtā atbalsta tagad pieejams kā Cargo funkcija. Jaunais Accessor::poll_ready_for_concurrent_call ļauj noteikt pretspiedienu paralēlos izsaukumos. cwasm failos saruka .wasmtime sadaļas ar slazdu un adrešu kartēm. RISC-V pusē pievienots Zvbb paplašinājums.
Divu izmesto moduļu dēļ atjaunināšana nebūs pilnīgi bezsāpīga. Kas savu iegulto Wasmtime vēl būvē uz wasi-common, tam jāpāriet uz jaunākajām WASI saskarnēm, jo vecais slānis kopš šī laidiena vairs netiek piegādāts.
Labojumu sarakstā ir viena vieta, kas tieši saistīta ar jaunajām funkcijām. Nenoķerts wasm izņēmums, kas izlien cauri komponentes robežai, tagad pārvēršas slazdā, nevis aizceļo tālāk. Divu dienu laikā sekoja arī divi ielāpu laidieni. Versija 47.0.1 saremontēja wasmtime-cli publicēšanu crates.io reģistrā, bet 47.0.2 salaboja asinhroni piegādātos write-closed notikumus un izsaukumu āķus, kas izmanto yield.
Nākamie punkti Ficdžeralda sarakstā ir aliasu analīzes optimizācijas savācējam un GC sasaiste ar komponenšu modeli.
Komentāri
Šim rakstam vēl nav komentāru. Esi pirmais, kurš dalās ar savu viedokli.