4 poin oleh GN⁺ 2023-11-04 | 1 komentar | Bagikan ke WhatsApp
  • 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/free di 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-opt dan 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
    • Contoh utamanya adalah Pyodide untuk Python dan Blazor untuk C#
    • Blazor mendukung kompilasi AOT maupun JIT
  • 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/free jika melakukan alokasi yang bermakna
    • dlmalloc berukuran 6K, dan emmalloc yang mengutamakan ukuran pun melebihi 1K
  • Karena WasmGC membuat VM mengelola memori secara otomatis, tidak perlu memasukkan GC atau malloc/free ke dalam Wasm
    • Pada benchmark fannkuch di artikel WasmGC sebelumnya, WasmGC berukuran 2.3K, sedangkan C/Rust 6.1–9.6K

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/free pada 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 $Node dan field $next yang 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

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 10 ke field, lalu mengembalikannya secara logis dapat direduksi menjadi return 10
    • Pada WasmMVP, alokasi berubah menjadi panggilan malloc, dan karena malloc adalah 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
  • WasmGC juga menyediakan function pointer eksplisit ref.func, pemanggilan melaluinya call_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
  • 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
  • Optimisasi GC baru Binaryen dan cara penggunaannya dirangkum dalam dokumentasi Binaryen
  • Saat mengukur performa Java dari output J2Wasm, wasm-opt meningkatkan 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.test lolos pemeriksaan tipe tertentu, maka ref.cast ke tipe yang sama seharusnya berhasil
    • Pada pola seperti downcast setelah instanceof di Java, cast dapat dihilangkan
  • 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 $Node dan cara pembuatan memakai struct.new
  • Wiki Binaryen membahas cara compiler menghasilkan kode WasmGC yang mudah dioptimalkan

1 komentar

 
GN⁺ 2023-11-04
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

    • https://github.com/cretz/asmble berjalan dengan baik, tetapi sebagian besar merupakan proyek yang dibuat untuk bersenang-senang dan kini praktis tidak lagi dipelihara
      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
    • GraalVM dapat menjalankan berkas eksekusi WASM: https://www.graalvm.org/latest/reference-manual/wasm/
    • Ini berarti mengikuti jejak CLR dengan terlambat 22 tahun
      “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...
    • Kalau mau sedikit lebih teliti, JVM adalah konsep yang lebih besar daripada garbage collector[^1]. Namun memang benar JVM telah menjadi arena eksperimen garbage collection
      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
    • Secara ketat, thread menyediakan konkurensi, bukan selalu paralelisme. Jadi menyebutnya paralelisme sejati terdengar aneh
      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/

    • Ini benar-benar kemajuan besar
      Semoga lebih banyak kode bisa dikompilasi berkat tipe Memory{T} yang baru
  • Terasa 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

    • LLVM bukan mesin virtual, tetapi WASM adalah mesin virtual
      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...
    • Saya datang untuk menanyakan hal serupa
      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
    • Jika melihat sesuatu seperti wasmtime, pada dasarnya Anda bisa membuat program native dengan plugin yang sangat aman dan mendukung banyak bahasa. Dengan cara yang sama, ini juga berjalan di browser sambil mempertahankan model keamanan dasar
      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
    • Daripada “WASM adalah LLVM baru”, ini lebih dekat ke WASM adalah JVM baru
    • Ini lebih dekat ke “wasm adalah Emscripten baru”. Sebuah standar yang jauh lebih diformalkan di seluruh browser
      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

    • Kurva untuk membuat browser sendiri bukan sekadar terlalu curam, tetapi secara harfiah mustahil. Membuat keseluruhan sistem operasi jauh lebih mudah daripada membuat browser
    • Bahkan Google dan Apple tidak memulai dari nol; mereka memakai WebKit, yaitu KHTML dari KDE
    • Membuat Linux sendiri juga mustahil, tetapi orang-orang tidak banyak mengeluh soal itu. Mereka juga tidak menyalahkan Android karena tidak mudah dibuat sendiri
      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
    • Memang benar, tetapi pekerjaan ini menjadi dasar untuk runtime alternatif yang lebih sederhana dan bisa dijalankan tanpa keseluruhan engine browser. Pikirkan Node atau Deno yang bergantung pada V8
    • Banyak hal modern sudah mencapai titik ini. Kita tidak bisa membuat mobil sendiri, dan secara praktis hampir mustahil membangun rumah sepenuhnya dari nol sendiri. Terlalu banyak keahlian khusus seperti kode bangunan yang diperlukan
  • 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

    • Mungkin butuh waktu sampai WasmGC benar-benar layak dipakai di .NET. Menurut diskusi, versi pertama WasmGC belum punya cara yang baik untuk menangani beberapa skenario khusus .NET, dan skenario-skenario itu diklasifikasikan sebagai “post-post-mvp” [0]
      Tentu saja yang mengkhawatirkan adalah, kalau fitur itu hanya dibutuhkan oleh .NET, insentif untuk menambahkannya tidak besar. Pada titik itu, fitur semacam include yang 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
    • Tim Wasm Chrome mengompilasi benchmark Fannkuch, yang mengalokasikan struktur data saat berjalan, dari C, Rust, dan Java. Biner C dan Rust berukuran 6,1K hingga 9,6K tergantung flag compiler, sedangkan versi Java jauh lebih kecil, yaitu 2,3K
      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 penasaran bagaimana Compose Multiplatform bekerja di web. Apakah caranya menggambar ke Canvas seperti Flutter
      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
    • Setiap kali mencobanya, antusiasme saya patah karena kekacauan Gradle
  • 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

    • WasmGC tidak mendukung interior pointer sehingga Go sulit mendapat manfaat darinya. Setidaknya sulit tanpa pendekatan buruk seperti fat pointer
  • 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

    • Dari sudut pandang praktis untuk sedikit menghemat ruang, ini bisa masuk akal. Namun dari sudut pandang desain, karena ini bukan “fitur minimum yang esensial” yang memungkinkan sesuatu yang sebelumnya tidak bisa dilakukan, menetapkannya sebagai bagian dari standar hanya akan membuatnya membengkak tanpa alasan
      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
    • Kesulitan pendekatan itu adalah perilaku library alokasi harus terstandardisasi dan deterministik
      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
    • Ini terdengar seperti arah yang cerdas. Tambahkan alloc dan fungsi terkait sebagai fungsi runtime agar kode tradisional bisa memanggilnya, dan biarkan GC apa pun dibangun di atasnya
  • Saya 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

    • Yang berbeda kali ini adalah WASM membalik urutan waktu dari cara yang dulu dicoba Sun JVM dan Microsoft CLR
      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
    • Sulit mengatakan JVM dan CLR dirancang untuk mendukung banyak bahasa. JVM memiliki bahasa tuan rumah bernama Java, dan bahasa lain yang ingin berjalan di JVM menanggung beban yang makin besar semakin jauh mereka dari sistem tipe Java
      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 i31ref
      Karena hal-hal ini, Wasm GC lebih umum dibanding upaya-upaya yang disebutkan di atas, justru karena levelnya lebih rendah
    • Dukungan WASM-GC sengaja dijaga sesederhana mungkin. Lihat https://github.com/WebAssembly/gc/blob/main/proposals/gc/MVP...
      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
    • Menurut saya yang berbeda adalah pentingnya proyek ini
      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
    • Yang dilakukan wasm berbeda dari upaya-upaya sebelumnya. Fitur GC tidak disediakan demi interoperabilitas dengan bahasa lain atau untuk berbagi sumber daya pengembangan antar-implementasi runtime bahasa
      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

    • Tulisan yang menarik
      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