JITの基礎知識についてのいくつかのリンク


Basic JIT
この文章はJITの1つの基本的な原理を述べて、その他の地方の得たバイナリコードを直接メモリに書き込んで、それから強制的なタイプを通じて関数のポインタに転化します..これでJITコードは走ることができます.
#include  // printf
#include  // memcpy
#include  // mmap, munmap

int main () {
// Hexadecimal x86_64 machine code for: int mul (int a, int b) { return a * b; }
unsigned char code [] = {
  0x55, // push rbp
  0x48, 0x89, 0xe5, // mov rbp, rsp
  0x89, 0x7d, 0xfc, // mov DWORD PTR [rbp-0x4],edi
  0x89, 0x75, 0xf8, // mov DWORD PTR [rbp-0x8],esi
  0x8b, 0x75, 0xfc, // mov esi,DWORD PTR [rbp-04x]
  0x0f, 0xaf, 0x75, 0xf8, // imul esi,DWORD PTR [rbp-0x8]
  0x89, 0xf0, // mov eax,esi
  0x5d, // pop rbp
  0xc3 // ret
};

  // allocate executable memory via sys call
  void* mem = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC,
                   MAP_ANON | MAP_PRIVATE, -1, 0);

  // copy runtime code into allocated memory
  memcpy(mem, code, sizeof(code));

  // typecast allocated memory to a function pointer
  int (*func) () = mem;

  // call function pointer
  printf("%d * %d = %d
", 5, 11, func(5, 11)); // Free up allocated memory munmap(mem, sizeof(code)); }

Brainfuck JIT
動的にコードをコンパイルするためにGNU Lightningが使用する.コードはやや長く、BFコードをアセンブリ書き込みファイル/
BF-JIT
见えない..
Hello, JIT World: The Joy of Simple JITs
本文はMike PollのDynASMを用いてアセンブリを転化し、各プラットフォームに適応した.
まず、非常に簡単な例です(-!簡単だとは思いませんでした)、この例にはBynASMはありません.mmapの方法を使って、一時的にメモリに実行可能な権限があることを許可しました.
#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {
  // Machine code for:
  //   mov eax, 0
  //   ret
  unsigned char code[] = {0xb8, 0x00, 0x00, 0x00, 0x00, 0xc3};

  if (argc < 2) {
    fprintf(stderr, "Usage: jit1 
"); return 1; } // Overwrite immediate value "0" in the instruction // with the user's value. This will make our code: // mov eax, // ret int num = atoi(argv[1]); memcpy(&code[1], &num, 4); // Allocate writable/executable memory. // Note: real programs should not map memory both writable // and executable because it is a security risk. void *mem = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); memcpy(mem, code, sizeof(code)); // The function will return the user's value. int (*func)() = mem; return func(); }

後にBFのJIT例を示して、読めないことを示しています...対応する完全なコードはGitHub上にありますhttps://github.com/haberman/jitdemo
A libjit wrapper for Golang
libjit GNU Cの書いたJITモジュール、教程はほとんど見ることができなくて、とても分かりにくいです.
でもGoのパッケージを見てみるといいと思います.なお、JITがどのように呼び出すかは、以下の例を参照して概ね理解することができる.
Samples https://github.com/eliben/libjit-samples
jit.js - JIT Assembler in javascript
C++のJSパッケージで、中には多くの命令が定義されていて、今は読めません.
How to start JIT-ting
本文は大体いくつかのアセンブリに関する基礎を紹介し、以下のコードの例を示した.ここではesprima解析APIを用いて上のjitを用いる.jsがJITコードを生成するのは、あまり難しくない.
var jit = require('jit.js'),
    esprima = require('esprima'),
    assert = require('assert');

var ast = esprima.parse(process.argv[2]);

// Compile
var fn = jit.compile(function() {
  // This will generate default entry boilerplate
  this.Proc(functon() {
    visit.call(this, ast);

    // The result should be in 'rax' at this point

    // This will generate default exit boilerplate
    this.Return();
  });
});

// Execute
console.log(fn());

function visit(ast) {
  if (ast.type === 'Program')
    visitProgram.call(this, ast);
  else if (ast.type === 'Literal')
    visitLiteral.call(this, ast);
  else if (ast.type === 'UnaryExpression')
    visitUnary.call(this, ast);
  else if (ast.type === 'BinaryExpression')
    visitBinary.call(this, ast);
  else
    throw new Error('Unknown ast node: ' + ast.type);
}

function visitProgram(ast) {
  assert.equal(ast.body.length,
               1,
               'Only one statement programs are supported');
  assert.equal(ast.body[0].type, 'ExpressionStatement');
  visit.call(this, ast.body[0].expression);
}

function visitLiteral(ast) {
  assert.equal(typeof ast.value, 'number');
  assert.equal(ast.value | 0,
               ast.value,
               'Only integer numbers are supported');

  this.mov('rax', ast.value);
}

function visitBinary(ast) {
  // Preserve 'rbx' after leaving the AST node
  this.push('rbx');

  // Visit right side of expresion
  visit.call(this, ast.right);

  // Move it to 'rbx'
  this.mov('rbx', 'rax');

  // Visit left side of expression (the result is in 'rax')
  visit.call(this, ast.left);

  //
  // So, to conclude, we've left side in 'rax' and right in 'rbx'
  //

  // Execute binary operation
  if (ast.operator === '+') {
    this.add('rax', 'rbx');
  } else if (ast.operator === '-') {
    this.sub('rax', 'rbx');
  } else if (ast.operator === '*') {
    // Signed multiplication
    // rax = rax * rbx
    this.imul('rbx');
  } else if (ast.operator === '/') {
    // Preserve 'rdx'
    this.push('rdx');

    // idiv is diving rdx:rax by rbx, therefore we need to clear rdx
    // before running it
    this.xor('rdx', 'rdx');

    // Signed division, rax = rax / rbx
    this.idiv('rbx');

    // Restore 'rdx'
    this.pop('rdx');
  } else if (ast.operator === '%') {
    // Preserve 'rdx'
    this.push('rdx');

    // Prepare to execute idiv
    this.xor('rdx', 'rdx');
    this.idiv('rbx');

    // imul puts remainedr in 'rdx'
    this.mov('rax', 'rdx');

    // Restore 'rdx'
    this.pop('rdx');
  } else {
    throw new Error('Unsupported binary operator: ' + ast.operator);
  }

  // Restore 'rbx'
  this.pop('rbx');

  // The result is in 'rax'
}

function visitUnary(ast) {
  // Visit argument and put result into 'rax'
  visit.call(this, ast.argument);

  if (ast.operator === '-') {
    // Negate argument
    this.neg('rax');
  } else {
    throw new Error('Unsupported unary operator: ' + ast.operator);
  }
}

文章の作者はNodeです.jsのコアメンバーの一人で、彼は別のブログでjit.を話しています.jsの例:
https://blog.indutny.com/5.allocating-numbers
Simple VM JIT with LLVM
簡単な加算がLLVMで動的にコンパイルされた例です.简単じゃない
A Basic Just-In-Time Compiler
How to JIT - an introduction
Building a simple JIT in Rust
ブログのトップページに戻ります.http://blog.tiye.me