AOT — dastur kodi bajarilishidan oldin target platforma uchun machine code yoki boshqa yakuniy formatga compile qilinadigan usul. Uning to‘liq nomi Ahead-Of-Time Compilation hisoblanadi.
AOT compile odatda build, package yoki install jarayonida bajariladi. Runtime ishga tushganda asosiy kodni qayta compile qilishga ehtiyoj kamayadi.
Asosiy jarayon
Source yoki bytecode
→ AOT compiler
→ Native artifact
→ Loader
→ Execution
Artifact ma’lum:
- CPU architecture;
- operating system;
- ABI;
- runtime;
- library version
uchun yaratiladi.
Native artifact
AOT natijasi:
bo‘lishi mumkin.
Machine code target protsessor instruction setiga bog‘langan.
x86-64 artifact ARM64da to‘g‘ridan-to‘g‘ri ishlamaydi.
Startup
JIT tizim runtime’da code compilation bilan shug‘ullanadi.
AOTda kod oldindan tayyor bo‘lgani sabab:
Serverless function, CLI va mobil ilovada bu muhim.
Runtime hajmi
AOT ilova to‘liq self-contained bo‘lishi mumkin.
U kerakli runtime va library qismlarini artifact ichiga qo‘shadi.
Afzalligi — hostga runtime o‘rnatish shart emas.
Kamchiligi — binary hajmi kattalashishi mumkin.
Static linking
AOT bilan static linking keng qo‘llanadi.
Library code executable ichiga qo‘shiladi.
Afzalliklari:
- deployment sodda;
- dynamic library topilmasligi kamayadi;
- aniq dependency versiyasi.
Kamchiliklari:
- binary katta;
- library patch uchun applicationni qayta build qilish;
- ayrim litsenziya va plugin cheklovlari.
Dynamic linking
AOT artifact dynamic librarylarga ham tayanishi mumkin.
Bu holatda:
muhim bo‘lib qoladi.
AOT dynamic dependency muammosini avtomatik yo‘q qilmaydi.
Optimization
AOT compiler butun program yoki module’ni ko‘rib optimization bajarishi mumkin.
Misollar:
- constant folding;
- dead code elimination;
- inlining;
- loop optimization;
- vectorization;
- link-time optimization;
- escape analysis.
Runtime’dagi aniq type va branch profili bo‘lmasa, ba’zi spekulyativ optimizatsiya cheklanadi.
Link-Time Optimization
Compiler object fayllarni alohida yakuniy machine code deb qabul qilmasdan, link bosqichida umumiy intermediate representation bilan ishlaydi.
Bu module chegarasidan o‘tuvchi:
- inlining;
- dead code elimination;
- constant propagation
imkonini beradi.
LTO build vaqtini va memory sarfini oshiradi.
Profile-Guided Optimization
Dastur representative workload bilan ishga tushiriladi va profil yig‘iladi.
Keyingi AOT build:
uchun shu ma’lumotdan foydalanadi.
Profil real production workloadga o‘xshamasa natija yomonlashishi mumkin.
Tree shaking
Managed yoki dynamic ekotizim AOT build’da ishlatilmagan kodni olib tashlashga urinadi.
Static call graph aniq bo‘lsa binary kichrayadi.
Reflection, dynamic loading va string orqali class topish static analysisni qiyinlashtiradi.
Kerakli type metadata explicit saqlanishi mumkin.
Reflection
AOT compiler runtime’da qaysi type yoki method reflection orqali ishlatilishini oldindan bilmasligi mumkin.
Natija:
- metadata olib tashlanadi;
- dynamic constructor topilmaydi;
- serializer xato beradi.
Configuration, annotation yoki source generator kerakli metadata’ni saqlaydi.
Dynamic code generation
Ayrim runtime:
ga tayanadi.
Qat’iy AOT muhitda executable memory yaratish taqiqlanishi mumkin.
Library AOT-compatible alternativ yo‘lga ega bo‘lishi kerak.
Cross-compilation
AOT compiler hostdan boshqa target uchun artifact yaratishi mumkin.
Masalan:
Linux x86-64 host
→ ARM64 embedded target
Buning uchun:
kerak.
Deterministik build
AOT artifact bir xil source va toolchain uchun takroriy yaratilishi mumkin.
Deterministik build:
- timestampni boshqaradi;
- pathni normalizatsiya qiladi;
- dependencyni pin qiladi;
- archive tartibini saqlaydi.
Bu supply-chain verification uchun muhim.
Build vaqti
AOT optimization buildni sekinlashtirishi mumkin.
Katta loyiha:
ishlatadi.
Developer debug build tez, release AOT build esa chuqur optimizatsiyali bo‘lishi mumkin.
Debugging
Optimized AOT code’da:
sabab source-level debug murakkab.
Debug symbol alohida faylda saqlanishi mumkin.
Production binary’dan symbol olib tashlanib, crash serverda symbolication qilinadi.
Security
AOT runtime’da writable-executable memory ehtiyojini kamaytiradi.
Bu W^X siyosatini soddalashtiradi.
Biroq native code memory corruption xavfiga ega bo‘lishi mumkin.
- stack protector;
- control-flow protection;
- PIE;
- RELRO;
- fortify
qo‘llanadi.
JIT bilan birga
Ba’zi runtime standart library yoki asosiy methodlarni AOT compile qiladi, qolganini JITga qoldiradi.
Bu:
- tez startup;
- dynamic optimization;
- kichik initial compilation
muvozanatini beradi.
Diagnostika
AOT muammosida:
- target architecture;
- ABI;
- linker;
- sysroot;
- reflection metadata;
- dynamic feature;
- static library;
- debug symbol;
- optimization;
- build cache;
- runtime dependency
tekshiriladi.
Development runtime’da ishlagan code AOTda dynamic xususiyat sabab ishlamasligi mumkin.
Binary hajmi
AOT compiler generic specialization, static linking va runtime metadata sabab katta binary yaratishi mumkin. Dead code elimination, symbol stripping va split debug info hajmni kamaytiradi. Kichik binary disk, download va instruction cache uchun foydali, ammo kerakli reflection metadata tasodifan olib tashlanmasligi kerak.
Bog‘liq tushunchalar
Ahead-Of-Time Compilation, JIT, Compiler, Native code, Static linking, LTO, PGO, Cross-compilation, Reflection, Toolchain