理解解释器中的JIT机制

原始代码

long add4(long num) {
  return num + 4;
}

JIT代码

0x48, 0x89, 0xf8,                   // mov %rdi, %rax
0x48, 0x83, 0xc0, 0x04,             // add $4, %rax
0xc3                                // ret

执行JIT代码

由于操作系统无法在用户态中执行堆中的数据,所以使用内存映射技术。

简而言之就是将用户空间的一段内存区域映射到内核空间,映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映到用户空间。

#include 
#include 
#include 
#include 


void* alloc_executable_memory(size_t size) {
        void* ptr = mmap(0, size,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        if (ptr == (void*)-1) {
                perror("mmap");
                return NULL;
        }
        return ptr;
}

void emit_code_into_memory(unsigned char* m) {
        unsigned char code[] = {
                0x48, 0x89, 0xf8,                   // mov %rdi, %rax
                0x48, 0x83, 0xc0, 0x04,             // add $4, %rax
                0xc3                                // ret
        };
        memcpy(m, code, sizeof(code));
}

const size_t SIZE = 1024;
typedef long (*JittedFunc)(long);

// Allocates RWX memory directly.
void run_from_rwx() {
        void* m = alloc_executable_memory(SIZE);
        emit_code_into_memory(m);

        JittedFunc func = m;
        int result = func(2);
        printf("result = %d\n", result);
}

int main()
{
        run_from_rwx();
        return 0;
}

你可能感兴趣的:(Operating,System)