- Saat memindahkan bahasa GC seperti Java, Kotlin, Dart, Python, dan C# ke WebAssembly, WasmGC tidak mengompilasi ulang VM yang sudah ada, melainkan memanfaatkan struktur, array, dan sistem tipe GC milik Wasm sendiri
- Porting WasmMVP tradisional memudahkan penggunaan ulang VM dan optimisasi yang sudah ada, tetapi memiliki biaya karena harus membawa GC atau
malloc/freedi dalam linear memory, serta keterbatasan terkait referensi stack, referensi siklik, dan fragmentasi - Dengan WasmGC, VM mengelola objek dan memori secara langsung sehingga ukuran binary bisa diperkecil; pada benchmark
fannkuch, ukurannya 2.3K, lebih kecil daripada C/Rust yang 6.1–9.6K - Karena WasmGC adalah intermediate representation pada level yang lebih tinggi, optimisasi Binaryen
wasm-optdan runtime V8 menjadi penting; ada contoh peningkatan rata-rata 1.9× pada benchmark Java dan sekitar 30% pada Google Sheets Calc Engine - Standardisasi dan dukungan browser sudah berjalan, tetapi karena ini bukan cara mengompilasi VM lama apa adanya, diperlukan pekerjaan toolchain baru untuk menurunkan struktur bahasa ke primitive WasmGC
Dua Cara Memindahkan Bahasa GC ke Wasm
- Porting WebAssembly untuk bahasa GC secara garis besar terbagi menjadi dua jalur
- Porting tradisional: mengompilasi VM bahasa yang sudah ada ke WasmMVP, WebAssembly Minimum Viable Product yang dirilis pada 2017
- Porting WasmGC: mengompilasi bahasa ke struktur GC Wasm yang didefinisikan dalam proposal GC
- Porting tradisional lebih mirip model memindahkan bahasa ke arsitektur CPU baru: berbagi parser VM, dukungan library, GC, dan optimizer, lalu hanya menambahkan backend baru
- Porting WasmGC lebih mirip memindahkan bahasa bukan ke arsitektur baru, melainkan ke VM baru
- Seperti J2CL yang mengompilasi Java ke JavaScript, objek bahasa direpresentasikan sebagai objek VM target dan dikelola oleh GC milik VM target
- WasmGC menargetkan level yang lebih rendah daripada JavaScript VM, JVM, dan CLR, tetapi lebih tinggi daripada WasmMVP karena menyediakan struktur dan array yang dikelola VM, serta relasi tipe
Kelebihan dan Batasan Porting WasmMVP Tradisional
- Kelebihan terbesar porting tradisional adalah kemampuan menggunakan ulang hampir seluruh kode VM, implementasi bahasa, dan optimisasi yang sudah ada
- Hasil WasmMVP menggunakan struktur dasar WasmMVP seperti linear memory, table, dan function
- Wasm sering dijalankan di dalam VM yang sudah memiliki GC, seperti browser, Node.js, workerd, Deno, dan Bun
- Di lingkungan ini, menyertakan implementasi GC di binary Wasm menyebabkan peningkatan ukuran yang tidak perlu
- Bahasa yang memakai linear memory seperti C, C++, dan Rust juga harus menyertakan kode
malloc/freejika melakukan alokasi yang bermakna dlmallocberukuran 6K, danemmallocyang mengutamakan ukuran pun melebihi 1K
- Karena WasmGC membuat VM mengelola memori secara otomatis, tidak perlu memasukkan GC atau
malloc/freeke dalam Wasm- Pada benchmark
fannkuchdi artikel WasmGC sebelumnya, WasmGC berukuran 2.3K, sedangkan C/Rust 6.1–9.6K
- Pada benchmark
Pengumpulan Siklik, Referensi Stack, dan Fragmentasi
- Di browser, Wasm sering berinteraksi dengan JavaScript dan Web API, tetapi dengan WasmMVP dan reference types saja, pengumpulan siklik yang halus pada tautan dua arah antara Wasm dan JS sulit dilakukan
- Tautan objek JS hanya bisa ditempatkan di table Wasm
- Tautan dari JS kembali ke Wasm dapat merujuk seluruh instance Wasm seolah-olah satu objek besar
- WasmGC mendefinisikan objek Wasm yang dikenali VM, sehingga referensi yang tepat dapat dibuat antara Wasm dan JavaScript
- Bahasa GC juga harus mengenali referensi di stack, seperti variabel lokal dalam scope pemanggilan
- Pada porting tradisional, program tidak dapat memeriksa stack-nya sendiri karena sandboxing Wasm
- Alternatifnya adalah memakai shadow stack atau menjalankan GC hanya saat tidak ada referensi di stack, misalnya di antara turn event loop JavaScript
- Dukungan stack scanning Wasm di masa depan dapat membantu porting tradisional
- Saat ini, cara yang otomatis menangani referensi stack tanpa overhead adalah WasmGC
malloc/freepada linear memory WasmMVP dapat menimbulkan fragmentasi memori pada program yang berjalan lama- Meskipun total memori yang tidak terpakai mencukupi, alokasi besar bisa gagal jika tidak ada blok besar yang berurutan
- Fragmentasi membuat modul Wasm lebih sering memperbesar memori, yang dapat berujung pada overhead dan error out-of-memory
- WasmGC dapat menghindari fragmentasi karena VM bisa memindahkan objek untuk mengompaksi GC heap
Developer Tools dan Semantik Bahasa
- Dalam porting WasmMVP tradisional, objek ditempatkan sebagai byte dalam linear memory, sehingga developer tools sulit melihat informasi tipe level tinggi
- Pada WasmGC, VM mengelola objek GC, sehingga integrasi tools menjadi lebih mudah
- Di tab Memory Chrome DevTools, heap snapshot program WasmGC dapat dilihat
- Pada contoh linked list, terlihat nama tipe
$Nodedan field$nextyang merujuk objek berikutnya - Informasi heap snapshot umum seperti jumlah objek, shallow size, dan retained size juga disediakan
- Debugger Chrome DevTools juga bekerja pada objek WasmGC
- Porting tradisional mengompilasi ulang VM yang sudah ada, sehingga lebih mudah mendapatkan semantik bahasa yang diharapkan apa adanya
- Porting WasmGC harus merepresentasikan struktur bahasa dengan tipe GC baru, yaitu structure dan array, sehingga kompromi semantik mungkin diperlukan demi efisiensi
- Field structure WasmGC memiliki indeks dan tipe tetap, sehingga bahasa yang ingin mengakses field secara lebih dinamis dapat mengalami kesulitan
- Saat ini WasmGC tidak memiliki interior pointer, dan batasan seperti ini diharapkan membaik seiring waktu
- Pilihan semantik juga ada pada contoh lain yang mengompilasi ke VM target
- Perilaku angka dart2js berbeda dari Dart VM
- String IronPython berperilaku seperti string C#
- Sebaliknya, dart2wasm bekerja tanpa kompromi semantik angka karena Wasm dapat merepresentasikan tipe angka yang dibutuhkan Dart secara efisien
Pekerjaan Toolchain yang Diperlukan untuk Porting WasmGC
- Porting WasmGC bukan sekadar mengompilasi ulang VM yang sudah ada
- Sebagian kode yang tidak terintegrasi langsung dengan runtime GC, seperti logika parser atau optimisasi AOT, dapat digunakan ulang
- Secara umum, diperlukan banyak kode baru untuk menurunkan struktur bahasa menjadi structure dan array WasmGC
- VM seperti Lua VM yang ditulis dalam C dapat dikompilasi ke Wasm dalam hitungan menit, tetapi porting WasmGC untuk Lua harus menentukan dan mengimplementasikan bagaimana struktur Lua direpresentasikan dalam batasan sistem tipe WasmGC
- Kekurangan besar porting WasmGC adalah upaya toolchain
- Kondisi idealnya adalah sistem tipe WasmGC mendukung semua bahasa secara efisien, dan tiap bahasa mengimplementasikan port WasmGC
- Fitur tambahan sistem tipe WasmGC di masa depan dapat membantu bagian pertama
- Berbagi pekerjaan toolchain umum dapat mengurangi beban bagian kedua
Mengapa WasmGC Bisa Dioptimalkan Lebih Baik
- WasmGC adalah intermediate representation pada level yang lebih tinggi daripada WasmMVP, sehingga ruang optimisasinya besar
- Dalam fungsi contoh, kode yang mengalokasikan objek GC dua kali, menyimpan
10ke field, lalu mengembalikannya secara logis dapat direduksi menjadireturn 10- Pada WasmMVP, alokasi berubah menjadi panggilan
malloc, dan karenamallocadalah fungsi kompleks dengan side effect pada linear memory, optimizer sulit yakin bahwa alokasi kedua tidak mengubah field objek pertama - Pada WasmGC, alokasi direpresentasikan sebagai instruksi
struct.new, dan karena dapat disimpulkan sebagai operasi VM, referensi dan nilai field dapat dilacak
- Pada WasmMVP, alokasi berubah menjadi panggilan
- WasmGC juga menyediakan function pointer eksplisit
ref.func, pemanggilan melaluinyacall_ref, serta tipe field structure dan array - Alasan WasmMVP dapat mencapai kecepatan mendekati native biasanya karena compiler optimisasi yang kuat seperti LLVM melakukan sebagian besar optimisasi sebelum menghasilkan Wasm
- LLVM tidak mendukung WasmGC, dan banyak bahasa GC juga tidak memakai LLVM, sehingga WasmGC membutuhkan model optimisasi yang berbeda
Optimisasi Binaryen dan wasm-opt
- WasmGC memungkinkan optimisasi tujuan umum dilakukan setelah diturunkan ke Wasm, sehingga toolchain berbagai bahasa dapat berbagi optimizer Wasm-to-Wasm yang sama
- Tim V8 berinvestasi pada dukungan WasmGC di Binaryen, proyek optimisasi toolchain WebAssembly
- Setiap toolchain dapat memakai Binaryen melalui tool command-line
wasm-opt
- Setiap toolchain dapat memakai Binaryen melalui tool command-line
- Binaryen sudah memiliki optimisasi untuk WasmMVP seperti inlining, constant propagation, dan dead code elimination, dan sebagian besar juga berlaku untuk WasmGC
- Optimisasi utama yang ditambahkan untuk WasmGC adalah sebagai berikut
- Escape analysis: memindahkan alokasi heap ke lokal
- Devirtualization: mengubah indirect call menjadi direct call
- Dead code elimination global yang lebih kuat
- Whole-program type-aware content flow analysis, GUFA
- Cast optimizations: menghapus cast redundan dan memindahkan posisi cast
- Type pruning
- Type merging
- Penyempurnaan tipe untuk local, global, field, dan signature
- Optimisasi GC baru Binaryen dan cara penggunaannya dirangkum dalam dokumentasi Binaryen
- Saat mengukur performa Java dari output J2Wasm,
wasm-optmeningkatkan kecepatan di setiap benchmark dan rata-rata menjadi 1.9× lebih cepat
Optimisasi WasmGC di V8
- Bahasa GC memiliki model performa yang berbeda dari bahasa seperti C, C++, dan Rust yang sangat bergantung pada inlining saat compile time
- Bahasa GC seperti Java dan Dart biasanya membuat VM melakukan inlining dan optimisasi saat runtime
- Di Java, semua panggilan pada awalnya dimulai sebagai indirect call
- Class turunan dapat meng-override fungsi parent, dan hal yang sama berlaku saat child dipanggil melalui referensi bertipe parent
- Toolchain mendapat manfaat jika mengubah indirect call menjadi direct call, tetapi dalam kode Java nyata ada banyak jalur yang sulit disimpulkan secara statis sebagai direct call
- V8 mengimplementasikan speculative inlining untuk WasmGC
- Mengamati indirect call saat runtime
- Jika call site tertentu menunjukkan perilaku sederhana, misalnya hanya sedikit target panggilan, V8 melakukan inlining dengan guard check
- Google Sheets Calc Engine adalah codebase Java yang menghitung formula spreadsheet, dan sebelumnya dikompilasi ke JavaScript dengan J2CL
- Tim V8 bekerja sama dengan Sheets dan J2CL untuk mem-porting kode ini ke WasmGC
- Pada kode ini, speculative inlining memberikan dampak terbesar di antara optimisasi tunggal yang diimplementasikan V8 untuk WasmGC
- Peningkatan kecepatan sekitar 30%, lebih besar daripada gabungan peningkatan dari semua optimisasi lain yang terukur
- Optimisasi WasmGC lain di V8 mencakup load elimination, type-based optimizations, branch elimination, constant folding, escape analysis, common subexpression elimination, dan lainnya
- Informasi tipe WasmGC juga digunakan untuk optimisasi runtime
- Jika
ref.testlolos pemeriksaan tipe tertentu, makaref.castke tipe yang sama seharusnya berhasil - Pada pola seperti downcast setelah
instanceofdi Java, cast dapat dihilangkan
- Jika
- Pada WasmMVP, pemisahan peran antara toolchain dan optimisasi VM relatif jelas, tetapi pada WasmGC, karakteristik bahasa GC dan kemungkinan optimisasi representasi WasmGC dapat membuat optimisasi toolchain dan VM lebih saling tumpang tindih
Status Saat Ini dan Titik Awal
- WasmGC telah mencapai phase 4 di W3C dan menjadi standar yang lengkap serta final
- Chrome 119 menyertakan dukungan WasmGC
- Firefox 120 diperkirakan akan dirilis dengan dukungan WasmGC pada akhir bulan yang sama
- Dalam demo Flutter, Dart yang dikompilasi dengan WasmGC menjalankan logika aplikasi termasuk widget, layout, dan animasi
- Toolchain yang mendukung WasmGC adalah sebagai berikut
- Source code contoh kecil di bagian developer tools adalah contoh program WasmGC “hello world” yang ditulis tangan
- Anda dapat melihat definisi tipe
$Nodedan cara pembuatan memakaistruct.new
- Anda dapat melihat definisi tipe
- Wiki Binaryen membahas cara compiler menghasilkan kode WasmGC yang mudah dioptimalkan
- GC Implementation - Lowering Tips
- Pass dan flag Binaryen yang digunakan oleh toolchain Java, Dart, dan Kotlin juga dapat dijadikan referensi
1 komentar
Opini Hacker News
WASM tampak seperti contoh thin waist, dan jika ditambah garbage collector, strukturnya menjadi N+M, bukan N×M. Artinya, kita bisa menuju N bahasa + M mesin virtual + G garbage collector, dan V8 sudah memiliki garbage collector yang matang
Saya penasaran apakah ada alat untuk berpindah dari WASM ke JVM, dan ternyata ada satu di GitHub. Saya belum mencobanya langsung; saya mencarinya karena JVM juga memiliki garbage collector yang matang dan paralel
Saya tidak menyangka WASMGC akan muncul secepat ini, jadi sekarang saya juga menantikan WASM Threads untuk paralelisme sejati, bukan hanya paralelisme input/output
Jika ada peluang untuk menyelesaikan async, paralelisme, dan garbage collection secara efektif, WASM akan menjadi lebih kuat dan mungkin tidak menjadi sumber kebingungan atau kesulitan bagi pengembang. Menurut saya WASI juga penting karena ini adalah kesempatan untuk mendefinisikan API yang setabil POSIX
1: https://www.oilshell.org/blog/2022/02/diagrams.html
2: https://github.com/cretz/asmble
Semoga ide dan penjelasan tentang bagaimana representasi perantara WASM dipetakan ke bytecode JVM dapat membantu orang yang membuat implementasi yang lebih resmi. Saat ini tidak ada rencana untuk dukungan WASM GC
“Lebih dari 20 perusahaan alat pemrograman menyediakan sekitar 26 bahasa pemrograman di .NET, termasuk C++, Perl, Python, Java, COBOL, RPG, dan Haskell”
Sumber: https://news.microsoft.com/2001/10/22/massive-industry-and-d...
Bukan karena dunia akademik secara khusus lebih berani terhadap JVM, melainkan karena program JVM digunakan luas dan sering dipakai dengan cara yang menekan satu teknik garbage collection tertentu
[^1]: https://www.baeldung.com/jvm-garbage-collectors. Azul JVM juga memiliki garbage collector lain yang terpisah. Ini hanya yang saya ketahui, dan kemungkinan cukup banyak yang terlewat
Sepertinya itu dikatakan sebagai perbandingan dengan coroutine, tetapi coroutine bersifat sekuensial. Walaupun urutan eksekusinya bisa arbitrer, kita dapat bergantung pada fakta bahwa ia tidak berjalan secara bersamaan
Jika wasm mengadopsi thread, rasanya itu akan menjadi satu lagi situasi “Worse is Better” yang disayangkan. Thread termasuk salah satu model konkurensi terburuk yang pernah kita rancang. Tentu saja, kecuali hal-hal seperti concurrent COMEFROM
Alat Julia WASM dapat membuat aplikasi yang mendukung atau membutuhkan fitur ini. Misalnya, ada contoh mengompilasi ODE solver ke WASM di https://tshort.github.io/WebAssemblyCompiler.jl/stable/examp...
Agar langsung berjalan, diperlukan Chrome v119, karena versi ini adalah yang pertama mengaktifkan dukungan garbage collection. Ada detail lebih lanjut di halaman depan WASM compiler https://tshort.github.io/WebAssemblyCompiler.jl/stable/
Semoga lebih banyak kode bisa dikompilasi berkat tipe
Memory{T}yang baruTerasa seperti “wasm adalah LLVM baru”. Penasaran apakah ada orang lain yang merasakan hal serupa
Saya mengerti apa yang ingin dilakukan dan sudah melihat demo yang menunjukkan kekuatannya, tetapi sebagian besar masih sangat level rendah secara teknis dan sering kali menjadi cukup merepotkan untuk dipakai sungguhan
Saya penasaran kapan kira-kira ini dianggap siap diadopsi lebih luas sampai layak dipilih sebagai target alih-alih cara yang ada sekarang
Karena namanya, sering muncul kesalahpahaman umum: LLVM pada awalnya memang dimaksudkan sebagai mesin virtual, tetapi pada praktiknya tidak pernah demikian dan sekarang pun bukan. Kalimat pertama di beranda situsnya juga menjelaskan hal ini: https://llvm.org/
Pada dasarnya, ini adalah sekumpulan pustaka C++ yang mengimplementasikan representasi antara yang berubah seiring waktu, dan merupakan alat untuk membantu menulis compiler
Sekitar 10 tahun lalu Google punya proyek yang menargetkan ranah mirip WASM, dan sepertinya mereka mengalami kesalahpahaman ini. Mereka menganggap LLVM sebagai mesin virtual. Mungkin sesuatu seperti PNaCl
Ini agak mirip dengan LuaJIT yang membekukan Lua pada Lua 5.1. Lua bukan standar, tetapi untuk implementasi ulang, orang bisa membekukan versi tertentu. Namun pendekatan itu punya masalah yang jelas: pihak yang mengimplementasikan ulang tidak tahu semua bug yang ikut mereka bekukan dalam waktu
Ada kalanya “kompromi” WASM membuat saya mengernyit, tetapi satu hal yang tidak bisa diragukan adalah bahwa WASM memang benar-benar mesin virtual
Saya menonton presentasi WASM GC, dan para pembuatnya berbicara jujur tentang kompromi yang diambil. Misalnya, pada awalnya diperlukan runtime cast, dan overhead yang diukur berada pada tingkat yang masuk akal. Sikap seperti ini justru memberi kepercayaan
https://old.reddit.com/r/ProgrammingLanguages/comments/17crk...
Jujur, saya tidak terlalu paham wasm. Tidak jelas masalah apa tepatnya yang sedang kita coba selesaikan
Saya penasaran apakah tujuannya adalah menulis aplikasi dalam bahasa selain JavaScript atau kode yang ditranspilasi ke JavaScript. Saya juga tidak tahu apakah itu mencakup bagian yang berinteraksi dengan lapisan tampilan DOM di browser. Sejauh pemahaman saya, tampaknya hal itu sebenarnya tidak bisa dilakukan; kalau benar, saya juga penasaran apakah tujuannya adalah menjalankan aplikasi di kanvas khusus di dalam DOM seperti Flash. Jika demikian, saya tidak tahu seberapa besar ceruk itu
Di thread lain ada juga pembicaraan tentang penggunaan wasm di Cloudflare Workers. Mungkin karena itu berjalan melalui interpreter JavaScript. Namun jika orang ingin menulis Cloudflare Workers dengan runtime apa pun, rasanya Cloudflare bisa saja menambahkan dukungan runtime lain. Mereka seharusnya punya kemampuan untuk itu
Atau saya penasaran apakah, selain keterkaitannya dengan ekosistem JavaScript, wasm sebagai bytecode memiliki hal yang secara unik hebat
Rasanya saya melewatkan materi pengantar yang menjelaskan mengapa teknologi ini menarik, tetapi agak malu menanyakannya pada titik ini
LLVM tidak menyediakan “sandbox keamanan yang mudah secara bawaan” tanpa banyak coding. wasmer memang punya backend LLVM, tetapi secara pribadi menurut saya inilah pembeda terbesar WASM
Arahnya memang menuju hal seperti LLVM, tetapi masih jauh dari sana
Betapapun hebatnya dan betapapun banyak kemungkinan yang dibukanya, saya terus terpikir bahwa browser saat ini sangat kompleks dan hambatan masuk untuk membuatnya sendiri hampir terlalu curam
Saya tidak paham mengapa platform hipermedia paling sukses dan paling mudah diakses di dunia harus mudah diimplementasikan. Wajar saja sistem online paling sukses di dunia itu kompleks dan kaya fitur. Itulah sebabnya kita memakainya, dan itulah sebabnya ia menang
Mengesankan bahwa ini akhirnya dibuat dan dirilis. Rencana untuk memasukkan GC ke WASM sudah terdengar selama bertahun-tahun, dan saya tidak yakin apakah itu benar-benar akan terjadi
Saya penasaran seberapa besar ini akan membantu bahasa-bahasa yang menargetkan WASM dan mengalami masalah ukuran biner yang membengkak karena harus menyertakan runtime. Seingat saya, Blazor bahkan untuk hello world saja membutuhkan sekitar 1MB, dan saya tidak tahu apakah WasmGC akan membantu dalam hal ini
Tentu saja yang mengkhawatirkan adalah, kalau fitur itu hanya dibutuhkan oleh .NET, insentif untuk menambahkannya tidak besar. Pada titik itu, fitur semacam
includeyang memungkinkan versi GC tertentu di-cache lalu dimuat oleh assembly WASM lain mungkin akan lebih berguna, meskipun menimbulkan rasa sakit tersendiri[0] - https://github.com/WebAssembly/gc/issues/77
C dan Rust memang tidak menyertakan garbage collector, tetapi tetap harus membundel malloc/free untuk manajemen memori. Alasan Java lebih kecil di sini adalah karena tidak perlu membundel kode manajemen memori sama sekali
https://developer.chrome.com/blog/wasmgc/
Untuk Blazor, ini mungkin hanya membantu di sisi GC. Seingat saya, Blazor harus mengirimkan seluruh runtime dotnet bersama aplikasinya
Dukungan wasm baru di Kotlin cukup menjanjikan. Ada versi eksperimental Compose Multiplatform yang bisa menargetkan browser, dan ini rencananya akan menggunakan WASM
Compose Multiplatform pada dasarnya adalah Google Jetpack Compose untuk Android yang ditambah dukungan platform lain
Per beberapa hari lalu, dukungan iOS masih alpha dan direncanakan masuk beta tahun depan. Dukungan Android dan desktop sekarang sudah stabil. Jika semuanya stabil, pada praktiknya kita bisa menulis aplikasi UI yang berjalan di platform mana pun
Compiler wasm akan dirilis bersama rilis mayor Kotlin berikutnya, yaitu Kotlin 2.0, yang mencakup compiler baru k2. Kemungkinan sekitar awal tahun depan. k2 saat ini tersedia dalam beta dan bisa diaktifkan di Kotlin 1.9.x
Kelebihan ekosistem Kotlin Multiplatform adalah sudah ada banyak library yang berjalan di berbagai platform. Jadi compiler wasm juga kemungkinan akan cepat menjadi bagian dari ekosistem itu dan mewarisi library-library yang bagus. Secara umum, cukup ubah konfigurasi build agar menargetkan ekosistem tersebut, lalu implementasikan perilaku spesifik platform yang masih kurang
Hal lain yang juga menarik di area ini adalah memakai dan menghubungkan library yang ditulis dalam bahasa berbeda. Misalnya, banyak bagian spesifik platform kemungkinan besar akan bergantung pada library C atau Rust yang sudah ada. Dalam banyak kasus, bisa saja itu library yang sama dengan yang dipakai Kotlin Native
Saya juga penasaran apakah widget yang sama dipakai di desktop, web, iOS, dan Android. Saya paham bahwa di Android itu native. Di platform lain, saya tidak tahu apakah ia meniru gaya yang berbeda. Pertanyaan utamanya adalah bagaimana feel aplikasi Compose Multiplatform di platform non-Android
Misalnya, Dart di web menurut saya terasa sangat tersendat-sendat, begitu juga Electron di desktop. Dart di desktop cukup oke, tetapi aplikasi-aplikasinya umumnya punya tombol dan margin yang besar, sehingga terasa seperti aplikasi Android yang berjalan di emulator, bukan aplikasi native sungguhan
Saya juga penasaran apakah Kotlin layak direkomendasikan sebagai bahasa untuk proyek baru
Saya penasaran apakah ada yang bisa menjelaskan mengapa tulisan blog ini dan pengumuman Chrome tidak menyebut Go
Go juga memakai garbage collection, jadi ini memberi kesan bahwa Go tidak bisa mendapatkan manfaat dari perubahan ini
Saya penasaran apakah masuk akal jika runtime mengekspos library alokasi bawaan yang bisa digunakan oleh C/C++/Rust
Program bisa memilih library itu alih-alih membundel library alokasinya sendiri
Primitive Wasm GC dirancang untuk mendapatkan peningkatan terbesar dengan tambahan sekecil mungkin. Begitu pula ketika primitive lain seperti SIMD ditambahkan, karena itu adalah “primitive yang kira-kira minimal” untuk mencapai kemampuan tersebut. Di sini yang dibutuhkan adalah building block sekecil mungkin
Namun API allocator memori seperti malloc/free bukanlah fitur minimum. Allocator memori pada praktiknya adalah kumpulan kebijakan dan keputusan desain, lalu algoritmenya mengikuti dari sana. Building block dasar di ranah itu adalah “potongan memori linear yang dimiliki allocator”, dan itu adalah memori linear yang sudah dimiliki WASM sejak hari pertama
Masuk akal jika runtime individual menyediakannya. Misalnya dengan meneruskan sebagian memori linear ke wasm import bawaan dan membiarkan allocator yang diimplementasikan runtime menanganinya. Namun saya rasa kemungkinannya sangat kecil untuk distandarkan. Selain itu, sebagian besar tooling untuk bahasa Wasm tanpa GC disesuaikan dengan cara mem-porting codebase yang ada beserta allocator-nya. Pada akhirnya, ini berarti ada lebih banyak kode yang harus dipelihara untuk implementasi sekali pakai, sehingga mungkin tidak sepadan dengan upayanya
Jika tidak deterministik, perbedaan perilaku program bisa menjadi penting. Misalnya, jika sebuah browser memasukkan allocator “pintar” yang lebih baik dalam menggunakan ulang memori, program yang kehabisan memori di browser lain karena fragmentasi memori linear bisa berhasil di browser tersebut. Secara historis, browser telah berupaya keras menstandardisasi perilaku untuk menghindari perbedaan seperti ini
Menstandardisasi perilaku implementasi malloc/free juga rumit karena beberapa alasan. Pertama, kompleksitasnya besar, seperti bagaimana menangani free list, ukuran chunk apa yang digunakan, dan sebagainya. Itu terlalu banyak untuk dimasukkan ke spesifikasi. Kedua, jika perilaku tertentu distandardisasi, perilaku itu tidak bisa diperbaiki, padahal ide malloc/free yang lebih baik masih terus bermunculan
Karena alasan-alasan ini, saya skeptis bahwa hal ini akan masuk ke spesifikasi wasm
Sebaliknya, GC menghindari masalah-masalah ini. Karena nilai pointer tidak dapat diamati, tidak ada yang perlu dispesifikasikan
allocdan fungsi terkait sebagai fungsi runtime agar kode tradisional bisa memanggilnya, dan biarkan GC apa pun dibangun di atasnyaSaya agak skeptis terhadap arah ini. Ini sangat meningkatkan kompleksitas WebAssembly
Garbage collector adalah abstraksi yang bocor. Ada yang mendukung pointer internal, ada yang tidak. Ada yang mendukung pekerjaan paralel yang berbagi memori, ada yang tidak. Ada yang membutuhkan kompresi sehingga C FFI menjadi lebih sulit, ada yang tidak. Ada yang harus terintegrasi erat dengan mekanisme yang dipakai untuk green process/thread dan stack yang dapat diperluas, ada yang tidak
Jika melihat bahasa seperti Erlang, JavaScript, Python, dan Go, pilihan di tingkat bahasa sampai taraf tertentu tercermin dalam garbage collector
Gagasan mesin virtual serbaguna/umum yang mendukung banyak bahasa sudah beberapa kali dicoba lewat JVM, CLR, Parrot, dan sebagainya, tetapi keberhasilannya terbatas. Saya penasaran apa yang berbeda kali ini
JVM/CLR terlebih dahulu membuat mesin virtual, spesifikasi instruksi bahasa perantara, dan runtime, lalu menyebarkannya seluas mungkin dengan harapan diadopsi secara universal di sisi klien. Dengan kata lain, mereka berharap “VM bahasa perantara” begitu menarik sehingga menyebar ke seluruh industri. Harapan ini hanya sebagian terbukti benar. JVM/CLR menyebar di desktop dan server, tetapi di browser web Java Applet dan Microsoft Silverlight gagal, dan di platform mobile juga tidak diadopsi secara luas
WASM urutannya sebaliknya. Ia berangkat mundur dari sesuatu yang sudah tersebar dan diadopsi di seluruh industri, yaitu JavaScript, lalu membuat “mesin virtual, spesifikasi instruksi bahasa perantara, dan runtime”
Dari sudut pandang ini, apa yang disebut “bahasa mainan” JavaScript adalah kuda Troya selama 20 tahun agar lebih dulu tersebar luas di semua klien. Kini industri pada dasarnya berkata, “Ada yang sadar bahwa kita sudah punya JavaScript sebagai runtime universal di server+desktop+browser+mobile? Mari buat runtime bahasa perantara agar cepat”
Ada juga beberapa masalah teknis. Sun JVM tidak memiliki pointer mentah sehingga sulit menjadi target berkinerja baik bagi bahasa berbasis pointer seperti C/C++, dan MS CLR tidak bisa dipakai di macOS. CLR minimal di Silverlight adalah pengecualian. Namun dibandingkan keterbatasan teknis ini, urutan waktu bagaimana JavaScript tersebar seperti kuda Troya yang tidak berbahaya memberikan penjelasan yang lebih kuat
Wasm berada pada level yang lebih rendah dibanding sebagian besar format bytecode di atas. Itu tetap benar meski mencakup Wasm GC yang menambahkan struct dan array bertipe statis, serta proposal function-references yang membawa fungsi bertipe. Wasm GC juga memiliki dukungan eksplisit untuk pointer bertag
i31refKarena hal-hal ini, Wasm GC lebih umum dibanding upaya-upaya yang disebutkan di atas, justru karena levelnya lebih rendah
Membuat VM “serbaguna” atau “umum” yang mendukung banyak bahasa secara setara dan mulus bukanlah tujuan eksplisit WASM-GC. Posisinya adalah bahwa tiap implementasi mungkin membutuhkan hack dan semantik khususnya sendiri di atas dukungan dasar yang disediakan WASM, dan itu tidak masalah karena FFI serta interoperabilitas antarbahasa dipandang sebagai persoalan yang sepenuhnya terpisah
Garbage collection JavaScript akan terus ada, dan tampaknya menjadi yang paling mengakar kuat di antara contoh-contoh yang disebutkan
Dalam banyak kasus, sekalipun lebih inferior, bahasa serta aplikasi/library lain harus menyesuaikan diri dengannya
wasm menyediakan fitur GC agar bahasa runtime managed memory dapat menargetkan lingkungan wasm tanpa menderita akibat keterbatasan model memori yang restriktif, dan sebagai manfaat sampingan untuk mengurangi ukuran bundle
wasm kemungkinan dapat mendukung parameter GC yang lebih dapat disesuaikan agar lebih cocok dengan karakteristik bahasa tamu. Selain itu, tidak seperti runtime bahasa tujuan umum yang menjadi pembanding, para implementor bahasa sama sekali tidak punya opsi untuk membuat runtime khusus mereka sendiri
Beberapa kekhawatiran tentang kelayakan WASM GC saat ini dibahas di sini. Terjemahan Google bahasa Inggris:
https://habr-com.translate.goog/ru/articles/757182/?_x_tr_sl...
Artikel asli:
https://habr.com/ru/articles/757182/
Ini adalah tulisan dari pembuat TeaVM, yang selama 10 tahun mengerjakan cara menjalankan Java dan kode JVM secara efisien di browser. https://teavm.org/
Konversi Java-to-JavaScript TeaVM yang ada saat ini menggunakan JS GC milik browser dan tetap berkinerja baik. Akan menarik untuk melihat apakah WASM GC menjadi lebih matang dan bisa lebih cepat dari itu
Sebagai catatan tentang masalah-masalah yang dibahas dalam tulisan itu, masalah perlunya shadow stack manual sudah diselesaikan di WasmGC. Seperti yang disebutkan di tautan, caranya sama seperti berjalan di JS
Ketiadaan try-catch sudah diselesaikan oleh proposal penanganan exception Wasm yang telah dirilis di browser: https://github.com/WebAssembly/exception-handling/blob/main/...
Pemeriksaan null juga sebagian besar diselesaikan oleh WasmGC. Spesifikasi mendefinisikan tipe lokal yang tidak bisa null, dan VM dapat mengoptimalkannya menggunakan sinyal seperti teknik yang disebutkan dalam tulisan. Misalnya, Wizard melakukannya seperti itu
Inisialisasi class adalah masalah yang sulit, seperti disebutkan dalam tulisan. J2Wasm dan Binaryen sedang berupaya mengoptimalkannya dengan analisis statis di tingkat toolchain. PR yang baru-baru ini saya tulis membuat kemajuan ke arah ini: https://github.com/WebAssembly/binaryen/pull/6061
Overhead vtable yang disebutkan dalam tulisan bisa menjadi masalah. Namun, saya belum tahu pengukuran yang bagus. Ada beberapa ide solusi post-MVP untuk method dispatch, tetapi belum ada yang konkret
Mengenai pemeriksaan null dan trap, pernah ada diskusi tentang varian instruksi GC yang melempar exception alih-alih trap. Namun, berdasarkan pengukuran, saat ini itu belum tampak sebagai masalah besar, jadi prioritasnya rendah
Penulis benar bahwa stack walking, sinyal, dan kontrol memori adalah area penting
Secara keseluruhan, berkat WasmGC dan penanganan exception, Java yang dihasilkan J2Wasm saat ini berada dalam posisi yang cukup baik. Biasanya lebih cepat daripada J2CL yang mengompilasi Java ke JavaScript. Meski begitu, jelas masih ada ruang untuk perbaikan