Sto lavorando su una VM (e su un linguaggio di scripting per questo) che ho intenzione di implementare per JITing. Sto solo lavorando al "plumbing" di esso ora, ma non voglio che il compilatore JIT sia un ripensamento. Tuttavia, mentre comprendo i fondamenti di ciò, sono un po 'confuso su cosa dovrebbe fare esattamente il JIT.
Ci sono due modi in cui posso pensare che sia implementato:
- Traduci il bytecode in "corretto" x86 proprio come farebbe qualsiasi compilatore, eliminando così la parte interprete / VM.
- Traduci il bytecode in x86 che chiama le funzioni VM per dirgli cosa fare eliminando così il passo di decodifica dell'opcode dell'interprete e andando direttamente a chiamare le funzioni interne della VM.
Il primo metodo sarebbe difficile da implementare semplicemente perché richiede conoscenze non solo sulla compilazione di un compilatore completo, ma sulla possibilità di compilare un linguaggio di alto livello che si basa normalmente sulle funzionalità di VM per essere compilato nel codice nativo.
Il secondo metodo sarebbe molto più semplice da implementare visto che non stai compilando il programma, stai solo creando dinamicamente un elenco di chiamate di funzioni C (alla VM interna) con gli operandi corrispondenti con le istruzioni x86 per chiamare il lo stesso ordine che avrebbe altrimenti richiesto a un interprete di "decodificare".
Tuttavia, mentre il secondo sembra chiaramente più sano da implementare, non sono sicuro di quanto (o meno) possa influire sulle prestazioni del programma. In quale direzione dovrei mirare? Qualsiasi pro e contro notevole?