jump to navigation

CLR Execution Model (Bagian 03) – Eksekusi Sebuah Assembly 11 Juni 2008

Posted by firstyuyu in CLR.
trackback

Sebagaimana disebutkan sebelumnya, managed assembly berisi metadata dan Intermediate Language (IL). IL merupakan bahasa mesin buatan Microsoft yang bersifat CPU-independent. IL mempunyai level yang lebih tinggi daripada kebanyakan bahasa mesin yang lain. IL bisa mengakses dan memanipulasi obyek serta mempunyai instruksi untuk membuat dan menginisialisasi obyek, memanggil virtual method pada obyek, dan memanipulasi elemen array secara langsung. Ia bahkan juga mempunyai instruksi untuk melontarkan dan menangkap exception. Kita bisa menganggap IL sebagai bahasa mesin berorientasi obyek.

Biasanya, developer akan memprogram menggunakan bahasa level tinggi, seperti C#, C++/CLI, atau Visual Basic. Compiler untuk semua bahasa tersebut akan menghasilkan kode IL. Namun, kita juga bisa memprogram langsung menggunakan IL. Microsoft telah menyediakan compilernya, yaitu IL Assembler (ILAsm.exe). Microsoft juga menyediakan IL Disassembler (ILDasm.exe).

Yang harus kita ingat ialah bahasa-bahasa level tinggi biasanya akan cenderung menawarkan sebagian saja dari fitur-fitur yang dimiliki CLR. Namung dengan menggunakan IL, developer bisa mengakses semua fitur yang dimiliki oleh CLR. Karena itu, jika bahasa pemrograman yang kita gunakan kebetulan tidak menawarkan fitur CLR yang kita butuhkan, kita bisa menulis modul yang mengakses fitur CLR tersebut menggunakan IL assembly atau bahasa pemrograman lain yang menawarkan fitur tersebut.

Untuk mengeksekusi sebuah method, maka kode IL method tersebut harus di-compile dahulu menjadi native CPU instruction. Ini merupakan tugas dari JIT (just-in-time) compiler. Gambar 01 menunjukkan bagaimana proses yang terjadi ketika sebuah method pertama kali dieksekusi.

Gambar 01. Eksekusi sebuah method pertama kali (Klik untuk memperbesar)

Tepat sebelum method Main dieksekusi, CLR akan mendeteksi semua tipe data yang dirujuk oleh kode di dalam method Main. Hal ini akan menyebabkan CLR mengalokasikan struktur data internal yang digunakan untuk mengelola akses ke tipe-tipe data yang dirujuk ini. Pada gambar 01 di atas, method Main merujuk ke sebuah tipe data, Console, yang menyebabkan CLR akan mengalokasikan struktur data internal tersebut. Struktur data ini berisi sebuah item untuk setiap method yang didefinisikan oleh kelas Console. Masing-masing item tersebut berisi alamat dimana kode implementasi method tersebut berada.

Ketika method Main pertama kali memanggil WriteLine, maka CLR akan memanggil sebuah komponen internal (sebut saja JITCompiler) untuk meng-compile kode IL dalam method WriteLine menjadi instruksi native CPU. Karena kode IL hanya di-compile pada saat dibutuhkan saja, maka sering disebut just in time compilation.

Ketika komponen JITCompiler dipanggil, ia akan diberitahu method apa yang akan di-compile dan berada di tipe data apa. JITCompiler kemudian akan mencari informasi mengenai method tersebut melalui metadata yang ada di dalam assembly dimana method tersebut didefinisikan. Lalu JITCompiler akan meng-compile kode IL method tersebut menjadi instruksi native CPU. Instruksi native CPU ini akan disimpan pada sebuah blok memori yang dialokasikan secara dinamis oleh CLR.

Setelah itu, JITCompiler akan pergi ke item di dalam struktur data internal milik CLR dimana pointer ke method yang sedang di-compile berada, lalu JITCompiler akan mengganti alamat di dalam item tersebut sehingga alamat di dalam item tersebut sekarang menunjuk ke blok memori hasil kompilasi yang baru saja dilakukan oleh JITCompiler. Akhirnya, blok memori yang berisi instruksi native CPU tadi (yaitu hasil kompilasi kode IL method WriteLine) akan dieksekusi. Setelah selesai dieksekusi, maka alur program akan kembali ke method Main untuk menjalankan statemen berikutnya.

Method Main sekarang memanggil WriteLine untuk kedua kali. Saat ini, kode IL WriteLine telah berada dalam keadaan ter-compile. Karena itu pemanggilan method WriteLine yang kedua kali ini akan langsung menuju ke blok memory hasil kompilasi yang telah dilakukan sebelumnya, melompati proses yang melibatkan JITCompiler. Gambar 02 menunjukkan proses yang terjadi ketika WriteLine dipanggil untuk kedua kalinya.

Gambar 02. Pemanggilan method yang sama untuk kedua kalinya (Klik untuk memperbesar).

Bisa kita lihat di sini, dampak terhadap performa hanya terjadi pertama kali ketika method dipanggil. Pemanggilan-pemanggilan berikutnya pada method yang sama akan dieksekusi dengan sangat cepat (secepat native code) karena proses kompilasi tidak terjadi lagi.

JIT compiler menyimpan hasil kompilasi yang dilakukannya ke dalam memori. Hal ini berarti bahwa hasil kompilasi tersebut akan hilang ketika aplikasi ditutup. Sehingga jika kita menjalankan lagi aplikasi tersebut atau membuka dua aplikasi yang sama namun berada pada proses yang berbeda di sistem operasi, JIT compiler harus melakukan kompilasi lagi terhadap kode IL yang ada.

Untuk kebanyakan aplikasi, penurunan performa yang disebabkan oleh JIT compiler tidaklah signifikan. Bahkan sebagian besar aplikasi cenderung memanggil method yang sama berulang kali. Pada aplikasi seperti ini, penurunan performa hanya terjadi sekali saja pada saat sebuah method dipanggil untuk pertama kalinya.

Iklan

Komentar»

No comments yet — be the first.

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s

%d blogger menyukai ini: