Bosh sahifa Wiki Bytecode

Bytecode

Bytecodesource code bilan fizik protsessor machine code’i orasidagi oraliq instruction formati. U odatda virtual mashina, interpreter yoki JIT compiler tomonidan bajariladi.

Bytecode ma’lum CPU modeliga emas, runtime belgilagan virtual instruction setga mo‘ljallanadi. Shu sababli bir xil bytecode turli operatsion tizim va protsessorlarda tegishli runtime mavjud bo‘lsa ishlashi mumkin.

Yaratilish jarayoni

Oddiy pipeline:

Source code
→ Compiler
→ Bytecode
→ Virtual machine
→ Machine instruction

Bytecode compile vaqtida yaratiladi. Runtime uni:

  • interpretatsiya qiladi;
  • JIT orqali native kodga aylantiradi;
  • AOT orqali oldindan compile qiladi;
  • aralash usulda bajaradi.

Virtual instruction set

Bytecode o‘z instructionlariga ega.

Misollar:

  • constant yuklash;
  • local variable olish;
  • arithmetic;
  • method chaqirish;
  • object yaratish;
  • branch;
  • return;
  • exception;
  • type check.

Instructionlar ko‘pincha bir yoki bir nechta baytdan iborat bo‘ladi. “Bytecode” nomi shundan kelgan, ammo har instruction aynan bir bayt bo‘lishi shart emas.

Stack-based bytecode

Ko‘p virtual mashina operand stackdan foydalanadi.

Misol:

push 2
push 3
add
return

add stackdagi ikki qiymatni oladi va natijani qayta stackka qo‘yadi.

Stack-based format ixcham va compiler uchun sodda.

Register-based bytecode

Boshqa virtual mashina virtual registerlardan foydalanadi.

Misol:

load r1, 2
load r2, 3
add r3, r1, r2
return r3

Instruction uzunroq bo‘lishi mumkin, ammo kamroq instruction talab qilishi ehtimoli bor.

Platform mustaqilligi

Machine code x86-64, ARM64 yoki boshqa architecture uchun alohida yaratiladi.

Bytecode esa runtime specificationga bog‘liq.

Masalan, bir bytecode fayl:

  • Linux x86-64;
  • Windows x86-64;
  • ARM64

runtime’larida ishlashi mumkin.

Platformaga xos native library yoki system API ishlatilsa, to‘liq mustaqillik cheklanadi.

Metadata

Bytecode fayli faqat instructionlardan iborat bo‘lmasligi mumkin.

Unda:

  • class;
  • method;
  • type;
  • constant pool;
  • symbol;
  • annotation;
  • debug line;
  • dependency;
  • exception table;
  • version

saqlanadi.

Runtime verification va reflection shu metadata’dan foydalanadi.

Constant pool

String, class nomi, method reference va literal qiymatlar umumiy jadvalda saqlanishi mumkin.

Instruction constant pool indeksiga murojaat qiladi.

Bu formatni ixchamlashtiradi va linkingni runtime’ga qoldiradi.

Verification

Managed runtime bytecode’ni bajarishdan oldin tekshirishi mumkin.

Tekshiruvlar:

Bu xotira xavfsizligi va runtime barqarorligini oshiradi.

Verification zararli kodni to‘liq xavfsiz qilmaydi, ammo noto‘g‘ri formatni rad etadi.

Interpreter

Interpreter bytecode instructionlarini ketma-ket o‘qib bajaradi.

Afzalliklari:

  • tez startup;
  • sodda implementatsiya;
  • kam qo‘shimcha memory;
  • profiling ma’lumoti yig‘ish.

Kamchiligi — har instruction uchun decode va dispatch overhead.

JIT compilation

JIT tez-tez ishlatiladigan bytecode qismlarini native machine code’ga aylantiradi.

Runtime haqiqiy type va branch profilidan foydalanib chuqur optimization bajarishi mumkin.

Sovuq kod interpreterda qolishi, issiq kod JIT qilinishi mumkin.

AOT compilation

Bytecode install yoki build vaqtida native code’ga aylantirilishi mumkin.

Bu startupni tezlashtiradi va JIT talabini kamaytiradi.

Runtime metadata, garbage collection va dynamic linking baribir saqlanishi mumkin.

Bytecode cache

Interpreted til source code’ni parse qilish xarajatini kamaytirish uchun bytecode cache yaratishi mumkin.

Cache:

bilan bog‘liq.

Eski runtime bytecode cache’ni o‘qimasligi va source’dan qayta yaratishi mumkin.

Version

Bytecode format runtime versiyasiga bog‘liq.

Yangi compiler:

  • yangi opcode;
  • yangi metadata;
  • boshqa constant format

yaratishi mumkin.

Eski runtime bunday faylni rad etadi.

Backward yoki forward compatibility specification bilan belgilanadi.

Obfuscation

Bytecode machine code’dan yuqori darajali metadata saqlashi mumkin. Shu sababli decompile qilish osonroq bo‘lishi mumkin.

Obfuscator:

  • symbol nomlarini o‘zgartiradi;
  • control flow’ni murakkablashtiradi;
  • metadata’ni kamaytiradi;
  • stringni yashiradi.

Obfuscation maxfiy algoritmni mutlaq himoya qilmaydi.

Decompilation

Bytecode’dan source’ga o‘xshash kod tiklanishi mumkin.

Ammo:

  • asl variable nomi;
  • comment;
  • formatting;
  • ayrim generic ma’lumot;
  • compiler transformatsiyasi

yo‘qolgan bo‘lishi mumkin.

Decompiled kod asl source bilan aynan bir xil emas.

Sandbox

Virtual machine bytecode instructionlari va APIlarini nazorat qilishi mumkin.

Sandbox:

kirishini cheklaydi.

Faqat bytecode formatining o‘zi sandbox bermaydi; runtime policy zarur.

Debugging

Bytecode fayl source line mapping saqlasa, debugger source qatorini ko‘rsatadi.

Breakpoint runtime instruction yoki method bilan bog‘lanadi.

Optimization sabab bajarilish tartibi source’dan farq qilishi mumkin.

Performance tahlili

Bytecode darajasida:

tahlil qilinadi.

Biroq real performance JIT hosil qilgan machine code va runtime profilingga ham bog‘liq.

Diagnostika

Bytecode muammosida:

tekshiriladi.

“Unsupported class version” kabi xato compiler va runtime versiyasi mos emasligini bildiradi.

Bytecode va umumiy IR

Har intermediate representation bytecode emas. Compiler ichki SSA yoki graph ko‘rinishidagi IR’dan optimization uchun foydalanishi mumkin, ammo u tarqatish formati bo‘lmasligi mumkin. Bytecode odatda saqlash, yuklash va virtual mashinada bajarish uchun barqarorroq formatga ega.

Bog‘liq tushunchalar

Virtual machine, Interpreter, JIT, AOT, Compiler, Machine code, Runtime, Opcode, Verification, Decompiler