| Կոմպիլյատորի կառուցումը  |
| --- |
| 
Ընդհանուր թեմաներ |
| * Լեքսիկական վերլուծություն
* Շարահյուսական վերլուծություն
* Ծրագրի կատարում
* Կապերի խմբագրիչ
* Դինամիկ կապերի խմբագրիչ
* Ծրագրի բեռնիչ
* Տրանսլյատոր
* Կոմպիլյատոր
* Դեկոմպիլյատոր
* Կրոսս կոմպիլյատոր
* Դինամիկ կոմպիլյացիա
* JIT-կոմպիլյացիա
* AOT-կոմպիլյացիա
* Ինտերպրետատոր
* Run-time գրադարան
* Ծրագրի կատարման ժամանակ
* Կոմպիլյացիայի ժամանակ
* Ելակոդ
* Օբյեկտային կոդ
* Բայթկոդ
* Մեքենայական կոդ
* Միկրոկոդ
* Բացարձակ կոդ
 |
| * դ
* ք
* խ
 |

**JIT-կոմպիլյացիա** (անգլ. just-in-time compilation), **դինամիկ կոմպիլացիան** (անգլ. dynamic translation) ծրագրի կատարման ժամանակ արված կոմպիլյացիա է՝ այլ ոչ թե մինչև ծրագրի կատարումը։ Շատ հաճախ այն բաղկացած է մեքենայական կոդի թարգմանությունից, բայց կարող է վերաբերվել նաև այլ ֆորմատի թարգմանությանը։

 Դինամիկ թարգմանչի հաջորդականությունը
JIT-կոմպիլյացիան մեքենայական կոդը թարգմանելու երկու ավանդական գաղափարների կոմբինացիա է՝ AOT-կոմպիլյացիա և ինտերպրետացիա, և իր մեջ համատեղում է երկուսի որոշ առավելություններ և թերություններ։ Կոպիտ ասած, JIT-կոմպիլյացիան համատեղում է կոմպիլյացված կոդի արագությունը ինտերպրետացիայի ճկունության հետ, ինտերպրետատորի հավելյալ ծախսերի հետ և լրացուցիչ կոմպիլյացիայի ծախսերը (ոչ միայն ինտերպրետացիայի)։ JIT-կոմպիլյացիան դինամիկ կոմպիլյացիայի տեսակ է, այդպիսով JIT-կոմպիլյացիայի տեսությունում կարող է տալ ավելի արագ կատարում քան ստատիկ կոմպիլացիան։ Ինտերպրետացիան և JIT-կոմպիլյացիան հատկապես համապատասխանում են *դինամիկ ծրագրավորման լեզուների* համար, այդ դեպքում runtime համակարգը կարող է կարգավորել *late-bound* տվյալների տիպերը և երաշխավորել կատարման անվտանգությունը։

 Դինամիկ կոպիլյացիայի դասկարգումները

**Իրականցման առանձնահատկությունները**
-------------------------------------

JIT-կոմպիլյացիան կարող է կիրառվել ինչպես ամբողջ ծրագրում, այնպես էլ դրա առանձին մասերում։ Օրինակ տեքստային ձևախիչը (անգլ. text editor) կարող է կոմպիլյացնել ռեգուլյար արտահայտությունները տեքստի ավելի արագ փնտրման համար։ AOT-կոմպիլյացիայի հետ այդպիսի բան անել հնարավոր չէ, քանի որ տվյալները տրամադրում են ծրագրի կատարման ժամանակ, այլ ոչ թե կոմպիլյացիայի ժամանակ։

**Նկարագրություն**
------------------

 Վիիտուալ մեքենայի միջավայրը՝ միջանկյալ ծրագրի բեռնման համար
Լեզուներում, ինչպիսին են Java, PHP, C#,Lua, Perl, GNU CLISP, սկզբնական կոդը թարգմանվում է միջանկյալ նկարագրության (անգլ. intermediate representation )՝ **բայթկոդ** անվանմամբ (անգլ. bytecode)։ Բայթկոդը ինչ-որ կոնկրետ պրեցոսսորի մեքենայական կոդ չի հանդիսանում և կարող է տեղափոխվել համակարգչի տարբեր ճարտարապետություն և իրականացվել նույն ձևով։ Բայթկոդը ինտերպրետացվում է կամ իրականցվում *վիրտուալ մեքենայում* ։ JIT կոպիլյատորը կարդում է բայթկոդի տարբեր բաժիներ (կամ ամբողջը միանգամից՝ հազվադեպ) և կոմպիլյացնում է մեքենայակն կոդի։ Այդ բաժիները կարող են լինել ֆայլեր, ֆունկցիաներ կամ կոդի ցանկացած հատված։ Կոդը կարող է կոմպիլյացված լինել, երբ այն պատրաստվում է կատարվել (այստեղից էլ *"just-in-time"* անունը)։ Մեկ անգամ կոմպիլյացված կոդը կարող է կեշավորվել և հետագայում կրկին օգտագործվել առանց վերակոմպիլյացայի (անգլ. recompile)։

Ի տարբերություն, ավանդական *ինտերպրետացված վիրտուալ մեքենան* (անգլ. interpreted virtual machine) ուղղակի ինտերպրետացնում է բայթկոդ, սովորաբար ավելի ցածր արդյունավետությամբ։ Որոշ ինտերպրետատորներ նույնիսկ ինտերպրետացնում են սկզբնական կոդը, բայթկոդի առանց սկազբանական կոմպիլյացիայի քայլի և նույնիսկ ավելի վատ արդյունավետությամբ։ *Ստատիկ կոմպիլյացված կոդը* (անգլ. Statically compiled code) կամ հարազատ կոդը (անգլ. native code) կոմպիլյացվում է նախքան տեղակայումը։

JIT մեթոդի հիմանակն նպատակը՝ ստատիկ կոմպիլյացիայի արդյունավետությանը հասնելը և գերազանցելն է, այդպիսով պահպանելով դինամիկ կոմպիլյացիայի առավելությունները՝

* Ծանրաքարշ գործողությունների մեծամասնությունը, ինչպիսին է նախնական կոդի վերլուծությունը և հիմնական օպտիմիզացիաները հաճախ մշակվում են կոմպիլյացիայի ժամանակ, մինչև տեղակայումը՝ բայթկոդից մեքենայական կոդի կոմպիլյացիան շատ ավելի արագ է, քան կոմպիլյացիան սկզբնական կոդից։
* Բայթկոդը փոխադրելի է, ի տարբերություն հարազատ կոդի կամ մեքենայական կոդի (անգլ.՝ native code)։

* Միջոցը կարող է հսկել բայթկոդի կատարումը կոմպիլյացիայից հետո, այդ պատճառով այն կարող է գործարկվել ավազամանում ( անգլ.՝ Sandboxing, Ավազամանը համակարգչային անվտանգությունում հատուկ մշակված միջոց է, համակարգչային ծրագրերի անվտանգ կատարման համար)։
* Պետք է նշել նաև որ հարազատ ծրագրերի համար ևս կա այդպիսի հնարավորություն, բայց տվյալ մեթոդի իրականցումը դժվար է։

* Կոմպիլյացիան բայթկոդից մեքենայակն կոդի հեշտ է իրականցնել, քանի որ օպտիմիզացիայի աշխատանքի մեծամասնությունը արդեն արված է եղել կոմպիլյատորի կողմից։

JIT կոդը հիմանականում առաջարկում է ավելի լավ արդյունավետություն քան ինտերպրետատորը։ Դրանից բացի կարող է առաջարկել ավելի լավ արդյունավետություն քան ստատիկ կոմպիլյացիան, քանի որ շատ օպտիմիզացիաներ հնարավոր են միայն ծրագրի կատարման ժամանակ ՝

* Կոմպիլյացիան կարող է իրականցվել անմիջապես նպատակային պրացեսսորի և օպերացիան համակարգի համար, որում գործարկվելու է հավելվածը։ Օրիանակ JIT-ը կարող է օգտագործել վեկտորային *SSE2* պրոցոսսորի ընդլայնում, եթե գտնում է որ այդ պրոցեսսորը աջակցում է այն։ Սակայն մինչ դեռ JIT-ի հիմանակն իրականացում չկա, որտեղ այդ մոտեցումը կօգտագործվի, քանի որ պետք է օպտիմիզացիայի նման մակարդակ ապահովել, համեմատած ստատսիկ կոմպիլյատերի հետ, կպահանհանջվեր կամ ապպահովել բինար ֆայլ յուրաքանչյուր պալտֆորմի տակ, կամ միացնել օպտիմիզատորի մեկ գրադարան յուրաքանչյուր պալտֆորմի տակ։
* Այդ միջոցը կարող է աշխատող ծրագրի մասին հավաքել վիճակագրություն և դուրս բերել օպտիմիզացիաներ հաշվի առնելով այդ ինֆորմացիաները։ Որոշ ստատիկ կոմպիլյատորներ կարող են նաև ընդունել մուտքային ինֆորմացիա։
* Այդ միջոցը կարող է կատարել կոդի գլոբալ օպիմիզացիաներ (օրինակ՝ գրադարանային ֆունկցիաներ ներկառուցումը) առանց կորցնելու դինամիկ կոմպիլյացիայի առավելությունները և առանց հավելյալ ծախսերի՝ բնորոշ ստատիկ կոմպիլյատորին և լինկերին։
* Կեշի ցանկալի օգտագործման համար կոդի ավելի հասարակ վերակառուցում։

**Մեկնարկի հապավումը և օպտիմիզացիաները**
----------------------------------------

JJIT կոմպիլյատորի տիպիկ հապավման պատճառը ծախսերն են բեռնման և բայթկոդի կոմպիլյացիայի վրա։ Ընդհանուր դեպքում, ինչքան լավ և ինչքան մեծ օպտիմիզացիաներ է կատարում JIT-ը, այնքան երկար է ստանում հապաղումը։ Այդ պատճառով JIT կոմպիլյատորը պետք է փոխզիջումներ կատարի գեներացված կոդի որակի և մեկնարկի ժամանակի միջև։ Սակայն, հաճախ ստացվում է այնպես, որ նեղ տեղերը (անգլ. bottleneck) կոմպիլյացիայի գործընթացում ստացվում է ոչ ինքը՝ կոմպիլյացիայի գործընթացը, այլ մուտքային և ելքային հապավումները (ինչպես օրինակ, rt.jar-ը *Java Virtual Machine*-ում *(JVM)* ունի 40ՄԲ չափ, և իրենում մետատվյալների փնտրումը զբաղեցնում է բավականչափ շատ ժամանակ)։

Այլ օպտիմիզացիայի միջոց է կոմպիլյացնել հավելվածի այն հատվածները, որոնք ավելի հաճախ են օգտագործվում։ Այդ մոտեցում է իրականցված է SunMicrosystems ընկերության *PyPy* -ում и *HotSpot Java Virtual Machine* -ում։

  

Երբեմն բավական դժվար է գտնել ճիշտ փոխզիջումներ։ Այդպես, օրինակ *Sun’s Java Virtual Machine-ը* ունի երկու աշխատանքի ռեժիմ՝ կլիենտ և սերվեր (անգլ. client and server) ։ Կլիենտի ռեժիմում կոմպիլյացիայի քանակը և օպտիմիզացիան մինիմալ են ավելի արագ բեռնման համար, մինչդեռ սերվերի ռեժիմում հասնում է մաքսիմալ արդյունավետության, բայց դրա պատճառով մեծանում է բեռնման ժամանակը։  

Եվս մեկ մեթոդ, որը կոչվում է *pre-JIT* , կոդը կոմպիլյացնում է մինչև բեռնելը. տվյալ մեթոդի առավելությունը հանդիսանում է բեռնման ժամանակի արագությունը, մինչդեռ թերությունը հանդիսանում է վատ կոմպիլյացված կոդը *runtime JIT* -ի հետ համեմատած։

**Հուսալիությունը**
-------------------

Քանի որ JIT կոմպիլյացիան բաղկացած է սկզբնական կոդի տվյալներից առաջանում է հուսալության (անվտանգության) հարց։

JIT կոմպիլյացիան իրենում համախմբում է սկզբնական կոդի կամ բայթկոդի կոմպիլյացիան մեքենայական կոդի և դրանց կատարումը։ Որպես կանոն արդյունքը գրվում է հիշողությունում և կատարվում է անմիջապես, չօգտագործելով դիսկ և չկանչելով առանձին ծրագիր։ Ժամանակակաից ճարտարապետությունում հուսալիությունը բարձրացնելու համար կամայական հիշողության հատվածները չեն կարող լինել իրականցված։ Ճիշտ աշխատանքի հաամար հիշողությունը պետք է նշված, որպես կատարվող (NX bit), ավելի մեծ անվտանգության համար ֆլագը պետք է դրված լինի հիշողության մեջ կոդի բեռնումից հետո, իսկ այդ հիշողությունը պետք է հասանելի լինի միայն ընթեցման համար։

Արտաքին հղումներ
----------------

* Free Online Dictionary of Computing entry Արխիվացված 2002-09-05 Wayback Machine
* libJIT
* Mozilla Nanojit Արխիվացված 2012-05-09 Wayback Machine
* SoftWire
* CCG
* Dyninst Արխիվացված 2015-10-17 Wayback Machine
* JatoVM Արխիվացված 2012-08-11 Wayback Machine
* AsmJit
* Xbyak Արխիվացված 2016-01-12 Wayback Machine
* sljit
* Profiling Runtime Generated and Interpreted Code using the VTune Performance Analyzer