- YJIT dan ZJIT adalah arsitektur compiler JIT yang mengubah kode Ruby menjadi bahasa mesin untuk meningkatkan kecepatan eksekusi di Ruby 3.x
- YJIT menghitung jumlah pemanggilan setiap fungsi atau blok dan ketika mencapai ambang tertentu, kode tersebut diubah menjadi bahasa mesin
- Kode yang telah dikonversi disimpan dalam blok YJIT, dan setiap blok mengubah beberapa instruksi YARV menjadi instruksi bahasa mesin ARM64 yang sesuai
- Menggunakan Branch Stub untuk mengamati tipe data aktual saat runtime dan secara selektif menghasilkan instruksi bahasa mesin yang sesuai
- Struktur ini adalah mekanisme inti untuk sekaligus mencapai peningkatan performa eksekusi Ruby dan efisiensi penanganan tipe dinamis
Chapter 4: Mengompilasi Ruby ke Bahasa Mesin
Interpreting vs. Compiling Ruby Code
- Tidak ada rincian lebih lanjut di teks asli
Counting Method and Block Calls
- YJIT melacak jumlah pemanggilan fungsi dan blok dalam program untuk mengidentifikasi kode hotspot
- Menyimpan nilai jit_entry dan jit_entry_calls di samping setiap urutan instruksi YARV untuk fungsi atau blok
jit_entry pada awalnya bernilai null, lalu nanti menyimpan pointer ke kode mesin yang dihasilkan YJIT
jit_entry_calls bertambah 1 setiap kali dipanggil
- Ketika jumlah pemanggilan mencapai ambang tertentu, YJIT mengompilasi kode tersebut ke bahasa mesin
- Ambang default Ruby 3.5 adalah 30 kali untuk program kecil dan 120 kali untuk aplikasi berskala besar
- Dapat diubah saat eksekusi dengan opsi
--yjit-call-threshold
- Dengan cara ini, YJIT hanya mengubah kode yang sering dijalankan menjadi bahasa mesin untuk menciptakan jalur eksekusi yang efisien
YJIT Blocks
- YJIT menyimpan instruksi bahasa mesin yang dihasilkan dalam blok YJIT
- Blok YJIT berbeda dari blok Ruby, dan merepresentasikan sebagian rentang instruksi YARV
- Setiap fungsi atau blok Ruby terdiri dari beberapa blok YJIT
- Dalam program contoh, YJIT mulai mengompilasi saat blok dijalankan untuk ke-30 kalinya
- Mengubah instruksi YARV pertama
getlocal_WC_1 ke bahasa mesin dan membuat blok YJIT baru
- Setelah itu mengompilasi instruksi
getlocal_WC_0 tambahan dan memasukkannya ke blok yang sama
- Menurut Figure 4-8, YJIT menghasilkan instruksi ARM64 untuk memuat nilai ke register x1 dan x9 pada prosesor M1
getlocal_WC_1 menyimpan variabel lokal dari stack frame sebelumnya, sedangkan getlocal_WC_0 menyimpan variabel dari stack saat ini ke stack
- Instruksi bahasa mesin yang dihasilkan menjalankan perilaku yang sama
YJIT Branch Stubs
- Saat YJIT mengompilasi instruksi
opt_plus, muncul masalah karena tipe operand tidak diketahui
- Instruksi bahasa mesin yang dibutuhkan berbeda tergantung pada tipe seperti integer, string, atau floating point
- Contoh: penjumlahan integer menggunakan instruksi
adds, sedangkan penjumlahan floating point memerlukan instruksi lain
- Untuk menyelesaikannya, YJIT menggunakan pendekatan observasi saat runtime alih-alih analisis awal
- Saat program berjalan, ia memeriksa tipe nilai yang benar-benar diteruskan lalu menghasilkan bahasa mesin yang sesuai
- Untuk perilaku ini digunakan Branch Stub
- Ketika cabang (branch) baru belum memiliki blok yang terhubung, ia sementara dihubungkan ke stub
- Setelah tipe aktual diketahui, stub tersebut diganti dengan blok yang sesuai
ZJIT (hanya disebutkan)
- Daftar isi mencakup bagian terkait ZJIT, tetapi tidak ada penjelasan rinci di isi utama
Ringkasan
- YJIT adalah compiler JIT untuk meningkatkan efisiensi eksekusi bahasa bertipe dinamis di Ruby 3.5
- Pemicu kompilasi berbasis jumlah pemanggilan, struktur blok YJIT, dan pemeriksaan tipe saat runtime melalui Branch Stub adalah inti utamanya
- Mengubah kode menjadi instruksi bahasa mesin nyata pada arsitektur ARM64 untuk meningkatkan kecepatan eksekusi kode Ruby
- ZJIT disebut sebagai JIT generasi berikutnya, tetapi tidak ada rincian lebih lanjut di isi utama
Belum ada komentar.