ASM #1: JVM, Mesin Yang Tidak Nyata


Untuk melakukan bytecode instrumentation melalui library seperti ASM, aku setidaknya harus mengerti bagaimana cara kerja JVM.  Setiap program Java, atau tepatnya class Java, akan dijalankan oleh Java Virtual Machine (JVM).  Mirip seperti mesin asli, JVM juga memiliki struktur-struktur seperti register dan stack.

Masing-masing thread yang dijalankan oleh JVM memiliki sebuah register Program Counter (pc).  Register pc berisi lokasi alamat instruksi yang sedang dikerjakan.  Untuk method native,  nilai register pc tidak didefinisikan.

Setiap thread di JVM juga memiliki Java Virtual Machine Stack yang kegunaannya mirip seperti di program biasa seperti C, seperti menampung nilai variabel lokal dan hasil perhitungan sementara.

Seluruh thread di JVM memiliki memory yang di-share yang disebut heap. Heap adalah lokasi memori yang berisi informasi instance dari sebuah class dan array.  Garbage collector akan bekerja secara otomatis untuk menentukan instance yang tidak dibutuhkan lagi dan membebaskan lokasi memori di heap sehingga memori dapat dipakai ulang.

Setiap kali sebuah method dipanggil, JVM akan membuat sebuah frame di Java Virtual Machine stack untuk thread bersangkutan.  Setelah method selesai dikerjakan, JVM akan memusnahkan frame tersebut.   Di dalam frame terdapat informasi local variables.  Sebuah “slot” local variable dapat mengandung nilai boolean, byte, char, short, int, float, reference, atau returnAddress.  Nilai long atau double memerlukan dua “slot”  local variable.

Setiap “slot” local variable memiliki index berurut mulai dari 0, 1, 2, dst.   Pada saat method mulai dijalankan, local variable 0 akan berisi referensi ke object yang mengandung method tersebut (nilai this dalam program Java).  Local variable 1, 2, dst berisi nilai parameter secara berurut.

Frame juga mengandung apa yang disebut operand stack yang banyak dipakai oleh instruksi JVM untuk menulis dan membaca nilai.  Pada saat frame pertama kali dibuat, operand stack tidak memiliki isi.

Instruksi JVM terdiri atas sebuah byte yang berisi opcode, diikuti oleh operands (jika ada).  Kebanyakan instruksi JVM bekerja pada tipe data tertentu.  Sebagai contoh, instruksi yang diawali dengan huruf i bekerja pada data int, huruf l bekerja pada data long, huruf s bekerja pada data short, huruf b bekerja pada data byte, huruf c bekerja pada data char, huruf f bekerja pada data float, huruf d bekerja pada data double, dan huruf a bekerja pada data reference.  O ya, di bahasa pemograman Java ada tipe data boolean, tapi  JVM tidak mengenal istilah boolean.   JVM akan menganggap boolean sebagai integer.

Instruksi load dan store dipakai untuk mengambil nilai dan menulis nilai ke dalam local variable. Sebagai contoh, iload 1 akan menulis local variable 1 yang bertipe int ke dalam operand stack.  Sebaliknya, istore 1 akan menulis nilai int yang ada di operand stack ke local variable 1.

Contoh instruksi aritmatika yang tersedia seperti iadd (penjumlahan), isub (pengurangan), imul (perkalian), idiv (pembagian),  irem (modulus), ineg (negation), ishl (shift left), ishr (shift right), ior (bitwise OR), iand (bitwise AND), ixor (bitwise XOR), iinc (local variable increment), lcmp (perbandingan).  Sebagai contoh, instruksi iadd akan menjumlahkan dua nilai int yang ada di operand stack (men-pop dua nilai terakhir), kemudian menyimpan hasil penjumlahan ke operand stack (men-push hasil penjumlahan).

JVM juga menyediakan beberapa instruksi untuk konversi, seperti i2l (int to long), i2f (int to float), i2d (int to double), l2f (long to float), l2d (long to double) dan f2d (float to double).

Untuk membuat instance class baru, terdapat instruksi new.  Untuk membuat array baru, tersedia instruksi newarray, anewarray, dan multianewarray.  Untuk meng-akses field dari sebuah object, instruksi berikut dapat dipergunakan: getfield, putfield, getstatic, putstatic.  Beberapa instruksi lain yang berkaitan dengan class: arraylength, instanceof, dan checkcast.

Instruksi berikut dipakai untuk memanipulasi operand stack: pop, pop2, dup, dup2, dup_xl, dup2_xl, dup_x2, dup2_x2, dan swap.

Contoh instruksi yang dipakai untuk control transfer (percabangan), misalnya: ifeq (jika sama dengan), iflt (jika lebih kecil), tableswitch, goto, dan ret.

Untuk memanggil method dari sebuah class, instruksi berikut dapat dipergunakan: invokevirtual, invokeinterface, invokespecial, dan invokestatic.  Untuk keluar dari method, instruksi berikut dapat dipergunakan sesuai dengan tipe kembalian dari method: return, ireturn, lreturn, freturn, dreturn, dan areturn.  Untuk membuat exception, instruksi athrow dapat dipergunakan.

Untuk mendukung sinkronisasi (keyword synchronize di bahasa pemograman Java), JVM menggunakan monitor, dan menyediakan instruksi berikut: monitorenter dan monitorexit.

Perihal Solid Snake
I'm nothing...

Apa komentar Anda?

Please log in using one of these methods to post your comment:

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: