16.2 IJVM xotira modeli
Endi siz IJVM arxitekturasini ko'rib chiqishga o'tishingiz mumkin.
U 4,294,967,296 bayt (4 GB) yoki 1,073,741,824 so'zlarning har birida 4
baytni o'z ichiga olgan xotiradan iborat. Ko'pgina yo'riqnoma
arxitekturalaridan farqli o'laroq, Java Virtual Machine qo'llanmada
ko'rinadigan xotiraga kirishni amalga oshirmaydi, ammo ko'rsatgich
bazasini tashkil etuvchi bir nechta yashirin manzillarga ega. IJVM
buyruqlari faqat ushbu ko'rsatkichlar orqali xotiraga kirish huquqiga ega.
Xotiraning quyidagi joylari aniqlanadi:
Barqarorliklar to'plami. IJVM dasturidan yozib bo'lmaydigan bu
joy, eslab o'tilishi mumkin bo'lgan boshqa xotiraga yo'naltiriladigan
doimiy, satr va ko'rsatgichlardan iborat. Ushbu maydon dastur xotiraga
yuklangan paytda yuklanadi va undan keyin o'zgarmaydi. Yashirin CPP
registri mavjud (Constant Pool Pointer - konstantalar to'plamiga
ko'rsatgich), unda konstantalar to'plamining birinchi so'zining manzili
mavjud.
Mahalliy o'zgaruvchan ramka. Ushbu maydon protsedurani
bajarish paytida o'zgaruvchilarni saqlash uchun mo'ljallangan. Yuqorida
aytib o'tilganidek, u mahalliy o'zgaruvchan freym deb nomlanadi. Ushbu
blokning boshida chaqirilayotgan protseduraning parametrlari (yoki
dalillar) mavjud. Mahalliy o'zgaruvchan ramka alohida ajratilgan
operand stackini o'z ichiga olmaydi. Unumdorligi sababli biz operand
stackini mahalliy o'zgaruvchan freymning tepasida joylashtirdik.
Birinchi freym o'zgaruvchisining manzilini o'z ichiga olgan yashirin
registr mavjud. Biz ushbu registrni LV (mahalliy o'zgaruvchan) deb
nomlaymiz. Chaqirilayotgan protseduraning parametrlari mahalliy
o'zgaruvchan freym boshida saqlanadi.
Operand suyakka. Operand stakti Java kompilyatori tomonidan
oldindan hisoblab chiqilgan ma'lum hajmdan oshmasligi kerak. Operand
stack maydoni 1-rasmda ko'rsatilgandek to'g'ridan-to'g'ri mahalliy
o'zgaruvchan ramkaning ustida joylashgan. 4.9. Bunday holda, operand
stack qulay ravishda mahalliy o'zgaruvchan freymning bir qismi
hisoblanadi. Qanday bo'lmasin, stakning eng yuqori so'zining manzilini
o'z ichiga olgan virtual registr mavjud. Shuni esda tutingki, CPP va LV
registrlaridan farqli o'laroq, ushbu ko'rsatgich protsedurani bajarish
paytida o'zgaradi, chunki operandlar stakandan chiqarilib, ochiladi.
Jarayon doirasi. Va nihoyat, dasturni o'z ichiga olgan xotira
maydoni mavjud. Yashirin registrda navbatdagi chaqiriladigan buyruq
manzili mavjud. Ushbu ko'rsatgich Program Counter (PC) deb
nomlanadi. Xotiraning boshqa sohalaridan farqli o'laroq, protsedura
maydoni baytlarning qatoridir.
Ko'rsatkichlar haqida bir fikr qilish kerak. CPP, LV va SP
registrlari so'zlarning baytlariga emas, balki so'zlarga ishora qiladi va
ma'lum miqdordagi so'zlardan kelib chiqadi. Masalan, LV, LV + 1 va
LV + 2 qiymatlari mahalliy o'zgaruvchan freymning birinchi uchta
so'zlarini, LV, LV + 4 va LV + 8 esa bir-biridan to'rtta (16 bayt)
masofada joylashgan so'zlarni anglatadi.
Bunga javoban, kompyuter registri bayt manzillarini o'z ichiga
oladi va uni o'zgartirish so'zlar bilan emas, balki baytlar sonining
ko'payishini anglatadi. Kompyuterning registr xotirasiga kirish boshqa
registr xotiradan kirishdan farq qiladi, shuning uchun Mic-1 kompyuter
uchun maxsus xotira portiga ega. Uning hajmi faqat bitta baytga teng.
Kompyuterni bittaga ko'paytirish va o'qish bilan o'qish keyingi baytni
chaqiradi. Va agar siz SPni bir martaga ko'paytirsangiz va uni o'qib
chiqsangiz, bu keyingi so'zni chaqiradi.
16.3 IJVM buyruqlar to'plami
IJVM buyruqlari to'plami jadvalda keltirilgan. 4.2. Har bir
ko'rsatma opcode va ba'zan operanddan iborat (masalan, manzilni
almashtirish yoki doimiy). Birinchi ustunda hex-dagi buyruq kodi
mavjud. Ikkinchi ustunda montaj tili mnemonik berilgan. Uchinchi
ustunda buyruqning maqsadi tasvirlangan.
4.2-jadval. IJVM buyruqlari to'plami. Bayt, const va varnum
operandlarining hajmi 1 baytni tashkil qiladi. Disp, indeks va ofset
operandlarining hajmi 2 baytni tashkil qiladi
Ba'zi buyruqlar turli manbalardagi so'zlarni suyakka surib chiqaradi.
Ushbu manbalar doimiy kontsentratsiyalar (LDC_W), mahalliy
o'zgaruvchan kadr (ILOAD) va buyruqning o'zi (BIPUSH) bo'lishi
mumkin. O'zgaruvchini stakandan tashqariga chiqarish mumkin va
mahalliy o'zgaruvchan kadrda saqlash mumkin (ISTORE). Stekning
yuqori ikki so'zida ikkita arifmetik operatsiyalar (IADD va ISUB) va
ikkita mantiqiy operatsiyalar (IAND va IOR) bajarilishi mumkin. Har
qanday arifmetik yoki mantiqiy amallarni bajarayotganda, ikkita so'z
stakandan chiqariladi va natija suyakka qaytariladi. 4 ta filial ko'rsatmasi
mavjud: bitta shartsiz dallanishga (GOTO) va yana uchta shartli
dallanishga (IFEQ, IFLT va IF_ICMPEQ). Ushbu buyruqlarning
barchasi shaxsiy kompyuter qiymatini buyruqdagi opkoddan keyin
joylashgan ofset hajmiga o'zgartiradi. Ofset operandining uzunligi 16 bit.
U opkod manziliga qo'shiladi. Shuningdek, suyakka (SWAP) yuqori ikki
so'zni almashtirish, yuqori so'zni (DUP) nusxalash va yuqori so'zni (POP)
olib tashlash buyruqlari mavjud.
Ba'zi buyruqlar murakkab bo'lib, ular tez-tez ishlatiladigan versiyalar
uchun qisqacha belgi qo'yishga imkon beradi. Buning uchun JVM
ishlatadigan barcha mexanizmlardan ikkitasini IJVM ga kiritdik. Bir
holatda, biz an'anaviy shaklni foydasiga qisqartirilgan shaklni qoldirdik.
Boshqa holda, biz keyingi buyruqni o'zgartirish uchun WIDE prefiks
buyrug'idan qanday foydalanish mumkinligini ko'rsatamiz.
Va
nihoyat,
boshqa
protsedurani
chaqirish
buyrug'i
(INVOKEVIRTUAL) va amaldagi protseduradan chiqish va (IRETURN)
protseduraga qaytish buyrug'i mavjud. Mexanizmning murakkabligi
tufayli biz ta'rifni biroz soddalashtirdik. Cheklash shundaki, Java tilidan
farqli o'laroq, bizning misolimizda protsedura faqat uning ichida
joylashgan protsedurani chaqira oladi. Ushbu cheklov Java tilining
mohiyatiga zid bo'lsa-da, protsedurani dinamik joylashtirmasdan, sodda
mexanizmni taqdim etishga imkon beradi. (Agar siz ob'ektga
yo'naltirilgan dasturlash bilan tanishmasangiz, ushbu taklifni e'tiborsiz
qoldirishingiz mumkin. Biz Java-ni oddiy Java-ga C yoki Paskal kabi
ob'ektga yo'naltirilgan dasturni o'zgartirdik.)
JVM-dan tashqari barcha kompyuterlarda chaqiriladigan protsedura
manzili to'g'ridan-to'g'ri CALL buyrug'i bilan belgilanadi, shuning uchun
bizning yondashuvimiz bundan mustasno emas.
Protsedurani chaqirish mexanizmi quyidagicha. Birinchidan,
qo'ng'iroq qiluvchi stackga chaqirilishi kerak bo'lgan narsaga
ko'rsatgichni itaradi. Shaklda 4.10 va bu ko'rsatkich OBJREF belgilar
bilan belgilanadi. Keyin qo'ng'iroq qiluvchi protsedura parametrlarini
suyakka suradi (ushbu misolda, ular 1-variant, 2-variant va 3-variant).
Shundan so'ng INVOKEVIRTUAL buyrug'i bajariladi.
INVOKEVIRTUAL buyrug'i konstantalar to'plamidagi pozitsiyani
aniqlaydigan ofsetni o'z ichiga oladi. Ushbu pozitsiya protsedura
zonasida saqlanadigan chaqiriladigan protseduraning boshlang'ich
manzilini o'z ichiga oladi. Jarayon sohasidagi dastlabki 4 bayt maxsus
ma'lumotlarni o'z ichiga oladi. Dastlabki 2 bayt bu protsedura uchun
parametrlar sonini ko'rsatadigan 16 bitli butun sondir (parametrlarning
o'zlari ilgari suyakka quyilgan). Bunday holda, OBJREF ko'rsatkichi 0 -
parametr deb hisoblanadi. Ushbu 16 bitli butun son SP qiymati bilan
birga OBJREF manzilini beradi. E'tibor bering, LV registri birinchi
haqiqiy parametr emas, balki OBJREFga ishora qiladi. LV ko'rsatgan
narsani tanlash biroz o'ziga xosdir.
Jarayon sohasidagi keyingi 2 bayt, chaqirilayotgan protsedura uchun
mahalliy o'zgaruvchan maydon hajmini belgilaydigan yana 16 bitli
butun sonni bildiradi. Gap shundaki, ushbu protsedura uchun yangi
parametrlar mavjud bo'lib, ular mahalliy parametrlarning hoshiyasida
joylashgan bo'lib, buning uchun bu raqam kerak. Va nihoyat, protsedura
sohasidagi beshinchi bayt birinchi bajariladigan operatsiya kodini o'z
ichiga oladi.
Keling, protsedurani chaqirishdan oldin nima sodir bo'lishini ko'rib
chiqaylik (4.10-rasmga ham qarang). Ochiq kodni bajargan imzo
qo'yilmagan ikkita bayt doimiy jadvalni indekslash uchun ishlatiladi
(birinchi bayt eng muhim). Buyruq yangi o'zgaruvchan freymning
bazaviy adresini xisoblaydi. Buning uchun parametrlar soni stack
markeridan chiqariladi va LV OBJREF ga o'rnatiladi. OBJREF eski
kompyuter qiymati joylashgan uyaning manzilini saqlaydi. Ushbu
manzil LV registridagi manzil bilan mahalliy o'zgaruvchilar (parametrlar
+ mahalliy o'zgaruvchilar) ning o'lchamlarini yig'ish yo'li bilan
hisoblanadi. Eski shaxsiy kompyuter qiymatini saqlash uchun darhol
yuqorida eski LV qiymati saqlanishi kerak bo'lgan manzil joylashgan.
Yangi nomlangan protsedura uchun stack ushbu manzilning tepasida
boshlanadi. SP eski LV qiymatiga ishora qiladi, uning manzili
zaxiradagi birinchi bo'sh katakchadan pastda joylashgan. Eslatib o'tamiz,
SP har doim suyakka ustki so'zni ko'rsatadi. Agar suyakka bo'sh bo'lsa,
unda SP to'g'ridan-to'g'ri suyakka ostidagi manzilga ishora qiladi.
Bizning raqamlarimizda stack har doim pastdan yuqoriga, sahifaning
yuqori qismidagi yuqori manzillarga qarab to'ldiriladi.
Va nihoyat, INVOKEVIRTUAL-ni bajarish uchun kompyuter registri
protsedura kod maydonida beshinchi baytni ko'rsatishi kerak.
IRETURN buyrug'i INVOKEVIRTUAL buyrug'ining teskarisidir
(4.11-rasm). Bu protsedura tomonidan ishlatiladigan xotirani bo'shatadi,
shuningdek stakani avvalgi holatiga qaytaradi, bundan tashqari, birinchi
navbatda OBJREF va barcha parametrlar stakandan chiqariladi;
ikkinchidan, qaytarilgan qiymat OBJREF parametri ishlatilgan stekga
suriladi. Oldingi holatni tiklash uchun IRETURN buyrug'i kompyuter va
LV ko'rsatkichlarining oldingi qiymatlarini qaytarishi kerak. Buning
uchun u bog'lovchi ko'rsatgichga ishora qiladi (bu LVning joriy qiymati
bilan belgilanadigan so'z). Dastlab OBJREF parametri joylashgan joyda
INVOKEVIRTUAL buyrug'i eski kompyuter qiymatini o'z ichiga olgan
manzilni saqlab qo'ydi. Ushbu so'z, shuningdek, yuqoridagi so'z, mos
ravishda PC va LV eski qiymatlarini tiklash uchun olinadi. Qaytish
qiymati, tugatish protsedurasining eng yuqori qismida saqlangan,
OBJREF parametri dastlab joylashgan joyga ko'chiriladi, shundan so'ng
SP ushbu manzilga yo'naltirila boshlaydi. Va keyin nazorat darhol
INVOKEVIRTUALni kuzatib boradigan jamoaga beriladi.
Hozirgacha bizning mashinamizda I / O buyruqlari yo'q edi. Biz ularni
tanishtirmoqchi emasmiz. Bizning misolimizda, Java virtual
mashinasida bo'lgani kabi, ular kerak emas va kirish / chiqish jarayonlari
hech qachon JVM tavsifida esga olinmaydi. I / O mexanizmlari
bo'lmagan mashina yanada ishonchli ekanligiga ishoniladi. (O'qish va
yozish JVMda maxsus protseduralarni chaqirish orqali amalga
oshiriladi.)
Anjir. 4.11. IRETURN (a) buyrug'ini bajarishdan oldin xotira, (b)
buyrug'ini bajargandan so'ng xotira.
16.4 IJVM tuzish
Endi Java ning IJVM bilan nima aloqasi borligini ko'rib chiqamiz.
Ro'yxat 4.1, Java dasturining oz qismini ko'rsatadi. Java kompilyatori
ushbu dasturni Listing 4.2 da ko'rsatilgan IJVM assambleyasi dasturiga
o'zgartirishi kerak edi. Ro'yxatning chap tomonidagi 1-15 qator
raqamlari, shuningdek, (//) qo'shaloq chiziqlardan keyin izohlar
dasturning o'zi emas. Ular tushunarli bo'lishi va shunchaki tushunishni
osonlashtirish uchun berilgan. Java assembler Listing 4.3-da ko'rsatilgan
ikkiliklarga tarjima qiladi. (Aslida, Java kompilyatori oraliq yig'ilishsiz
darhol ikkilik hosil qiladi.) Ushbu misolda, i mahalliy o'zgaruvchi 1, j
mahalliy o'zgaruvchiga 2, k esa mahalliy o'zgaruvchiga 3.
Ro'yxatlash 4.1. Java dasturining parchasi
i = j + k;
agar (I == 3)
k = 0;
yana
j = j - 1;
Ro'yxat 4.2. IJVM uchun Java assambleyasi dasturi
Ro'yxat 4.3. IJVM uchun o'n oltilik dastur
Tuzilgan dastur oddiy. Birinchidan, j va k ustunlar ustiga tashlanadi,
qo'shiladi va natija i ichida saqlanadi. Keyin i va doimiy 3 ustunga
suriladi va taqqoslanadi. Agar ular teng bo'lsa, u holda L1 ga shartli
bo'lim tuziladi, bu erda k 0 qiymatini oladi. Agar ular teng bo'lmasa,
dasturning bir qismi IF_ICMPEQ ko'rsatmasidan keyin bajariladi.
Shundan so'ng, L2 ga o'tish amalga oshiriladi, bu erda qolgan va keyin
qismlar birlashtiriladi.
Listing 4.2-da dastur uchun operand stack 4-2-rasmda keltirilgan. 4.12.
Dastur ishlashni boshlashdan oldin, 0 raqami ustidagi gorizontal
chiziqda ko'rsatilgandek, stack bo'sh. Dastlabki ko'rsatmalardan so'ng,
ILOAD j stakanda suriladi (rasmdagi 1 raqamidan yuqori to'rtburchak).
1 raqami birinchi buyruq bajarilganligini anglatadi. Ikkinchi ILOAD
bajarilgandan
so'ng,
2
raqamining
ustidagi
to'rtburchakda
ko'rsatilganidek, stakanda allaqachon ikkita so'z bor. IADD buyrug'idan
so'ng stakanda faqat bitta so'z qoladi, bu j + k yig'indisidir. Yuqoridagi
so'z suyakdan chiqarilib, i ichida saqlanganida, stack yana bo'sh qoladi.
5-buyruq (ILOAD) if bayonotini boshlaydi. Ushbu buyruq i suyakka
itarib yuboradi. Keyin doimiy 3 keladi (6-buyruqda). Taqqoslashdan
so'ng stack yana bo'shab qoladi (7). 8-buyruq - bu boshqa parchaning
boshlanishi. Bu L2 yorlig'iga o'tish amalga oshirilganda, 12-
buyruqgacha davom etadi.
Откомпилированная программа проста. Сначала j и k
помещаются в стек, складываются, а результат сохраняется в i .
Затем i и константа 3 помещаются в стек и сравниваются. Если они
равны, то совершается условный переход к L1, где k получает
значение 0. Если они не равны, то выполняется часть программы
после команды IF_ICMPEQ . После этого осуществляется переход к
L2 , где объединяются части else и then.
Стек операндов для программы, приведенной в листинге 4.2,
изображен на рис. 4.12. До начала выполнения программы стек
пуст, что показано горизонтальной чертой над цифрой 0. После
выполнения первой команды ILOAD j помещается в стек
(прямоугольник над цифрой 1 на рисунке). Цифра 1 означает, что
выполнена первая команда. После выполнения второй команды
ILOAD в стеке оказываются уже два слова, как показано в
прямоугольнике над цифрой 2. После выполнения команды IADD в
стеке остается только одно слово, которое представляет собой
сумму j + k . Когда верхнее слово выталкивается из стека и
сохраняется в i , стек снова становится пустым.
Команда 5 ( ILOAD ) начинает оператор if . Эта команда
помещает i в стек. Затем идет константа 3 (в команде 6). После
сравнения стек снова становится пустым (7). Команда 8 является
началом фрагмента else . Он продолжается вплоть до команды 12,
когда совершается переход к метке L2 .
Рис. 4.12. Состояние стека после выполнения каждой команды
в программе, приведенной в листинге 4.2
Вопросы
1.
Что такое стек
2.
Разъясните модель памяти IJVM
3.
Перечислите набор IJVM-команд
4.
Расскажите процесс компиляции IJVM
5.
Принцип конвейерной обработки
Do'stlaringiz bilan baham: |