Slide 51
Slide 51 text
JIT Compilation
JIT compiler translates byte code to machine code
class Hello
def initialize
@foo = 1
@bar = 2
end
def foo
@foo + @bar
end
end
hi = Hello.new
hi.foo
Source Code Byte Code for "foo"
[:getivar, :@foo, cache]
[:getivar, :@bar, cache]
[:plus]
Machine Code
== BLOCK 1/5, ISEQ RANGE [0,3), 93 bytes ======================
# getinstancevariable
# guard not immediate
0x55a658d0a6dd: test qword ptr [r13 + 0x18], 7
0x55a658d0a6e5: jne 0x55a660d0a0e5
0x55a658d0a6eb: cmp qword ptr [r13 + 0x18], 8
0x55a658d0a6f0: jbe 0x55a660d0a0fe
0x55a658d0a6f6: mov rax, qword ptr [r13 + 0x18]
# guard known class
0x55a658d0a6fa: movabs rcx, 0x7fbb2af48f20
0x55a658d0a704: cmp qword ptr [rax + 8], rcx
0x55a658d0a708: jne 0x55a660d0a117
0x55a658d0a70e: mov rax, qword ptr [r13 + 0x18]
0x55a658d0a712: cmp qword ptr [rax + 0x10], 0
0x55a658d0a717: jbe 0x55a660d0a0cc
# guard embedded getivar
0x55a658d0a71d: test word ptr [rax], 0x2000
0x55a658d0a722: je 0x55a660d0a130
0x55a658d0a728: cmp qword ptr [rax + 0x18], 0x34
0x55a658d0a72d: mov ecx, 8
0x55a658d0a732: cmovne rcx, qword ptr [rax + 0x18]
0x55a658d0a737: mov qword ptr [rbx], rcx
== BLOCK 2/5, ISEQ RANGE [3,6), 0 bytes =======================
== BLOCK 3/5, ISEQ RANGE [3,6), 69 bytes ======================
# getinstancevariable
# regenerate_branch
# getinstancevariable
# regenerate_branch
0x55a658d0a73a: mov rax, qword ptr [r13 + 0x18]
# guard known class
0x55a658d0a73e: movabs rcx, 0x7fbb2af48f20
0x55a658d0a748: cmp qword ptr [rax + 8], rcx
0x55a658d0a74c: jne 0x55a660d0a183
0x55a658d0a752: mov rax, qword ptr [r13 + 0x18]
0x55a658d0a756: cmp qword ptr [rax + 0x10], 1
0x55a658d0a75b: jbe 0x55a660d0a162
# guard embedded getivar
0x55a658d0a761: test word ptr [rax], 0x2000
0x55a658d0a766: je 0x55a660d0a19c
0x55a658d0a76c: cmp qword ptr [rax + 0x20], 0x34
0x55a658d0a771: mov ecx, 8
0x55a658d0a776: cmovne rcx, qword ptr [rax + 0x20]
0x55a658d0a77b: mov qword ptr [rbx + 8], rcx
== BLOCK 4/5, ISEQ RANGE [6,8), 0 bytes =======================
== BLOCK 5/5, ISEQ RANGE [6,9), 86 bytes ======================
# opt_plus
# regenerate_branch
# opt_plus
# guard arg0 fixnum
# regenerate_branch
0x55a658d0a77f: test byte ptr [rbx], 1
0x55a658d0a782: je 0x55a660d0a1ef
# guard arg1 fixnum
0x55a658d0a788: test byte ptr [rbx + 8], 1
0x55a658d0a78c: je 0x55a660d0a208
0x55a658d0a792: mov rax, qword ptr [rbx]
0x55a658d0a795: sub rax, 1
0x55a658d0a799: add rax, qword ptr [rbx + 8]
0x55a658d0a79d: jo 0x55a660d0a1ce
0x55a658d0a7a3: mov qword ptr [rbx], rax
# leave
# RUBY_VM_CHECK_INTS(ec)
0x55a658d0a7a6: mov eax, dword ptr [r12 + 0x24]
0x55a658d0a7ab: not eax
0x55a658d0a7ad: test dword ptr [r12 + 0x20], eax
0x55a658d0a7b2: jne 0x55a660d0a221
# pop stack frame
0x55a658d0a7b8: mov rax, r13
0x55a658d0a7bb: add rax, 0x40
0x55a658d0a7bf: mov r13, rax
Machine Code
== BLOCK 1/5, ISEQ RANGE [0,3), 93 bytes ======================
# getinstancevariable
# guard not immediate
0x55a658d0a6dd: test qword ptr [r13 + 0x18], 7
0x55a658d0a6e5: jne 0x55a660d0a0e5
0x55a658d0a6eb: cmp qword ptr [r13 + 0x18], 8
0x55a658d0a6f0: jbe 0x55a660d0a0fe
0x55a658d0a6f6: mov rax, qword ptr [r13 + 0x18]
# guard known class
0x55a658d0a6fa: movabs rcx, 0x7fbb2af48f20
0x55a658d0a704: cmp qword ptr [rax + 8], rcx
0x55a658d0a708: jne 0x55a660d0a117
0x55a658d0a70e: mov rax, qword ptr [r13 + 0x18]
0x55a658d0a712: cmp qword ptr [rax + 0x10], 0
0x55a658d0a717: jbe 0x55a660d0a0cc
# guard embedded getivar
0x55a658d0a71d: test word ptr [rax], 0x2000
0x55a658d0a722: je 0x55a660d0a130
0x55a658d0a728: cmp qword ptr [rax + 0x18], 0x34
0x55a658d0a72d: mov ecx, 8
0x55a658d0a732: cmovne rcx, qword ptr [rax + 0x18]
0x55a658d0a737: mov qword ptr [rbx], rcx
== BLOCK 2/5, ISEQ RANGE [3,6), 0 bytes =======================
== BLOCK 3/5, ISEQ RANGE [3,6), 69 bytes ======================
# getinstancevariable
# regenerate_branch
# getinstancevariable
# regenerate_branch
0x55a658d0a73a: mov rax, qword ptr [r13 + 0x18]
# guard known class
0x55a658d0a73e: movabs rcx, 0x7fbb2af48f20
0x55a658d0a748: cmp qword ptr [rax + 8], rcx
0x55a658d0a74c: jne 0x55a660d0a183
0x55a658d0a752: mov rax, qword ptr [r13 + 0x18]
0x55a658d0a756: cmp qword ptr [rax + 0x10], 1
0x55a658d0a75b: jbe 0x55a660d0a162
# guard embedded getivar
0x55a658d0a761: test word ptr [rax], 0x2000
0x55a658d0a766: je 0x55a660d0a19c
0x55a658d0a76c: cmp qword ptr [rax + 0x20], 0x34
0x55a658d0a771: mov ecx, 8
0x55a658d0a776: cmovne rcx, qword ptr [rax + 0x20]
0x55a658d0a77b: mov qword ptr [rbx + 8], rcx
== BLOCK 4/5, ISEQ RANGE [6,8), 0 bytes =======================
== BLOCK 5/5, ISEQ RANGE [6,9), 86 bytes ======================
# opt_plus
# regenerate_branch
# opt_plus
# guard arg0 fixnum
# regenerate_branch
0x55a658d0a77f: test byte ptr [rbx], 1
0x55a658d0a782: je 0x55a660d0a1ef
# guard arg1 fixnum
0x55a658d0a788: test byte ptr [rbx + 8], 1
0x55a658d0a78c: je 0x55a660d0a208
0x55a658d0a792: mov rax, qword ptr [rbx]
0x55a658d0a795: sub rax, 1
0x55a658d0a799: add rax, qword ptr [rbx + 8]
0x55a658d0a79d: jo 0x55a660d0a1ce
0x55a658d0a7a3: mov qword ptr [rbx], rax
# leave
# RUBY_VM_CHECK_INTS(ec)
0x55a658d0a7a6: mov eax, dword ptr [r12 + 0x24]
0x55a658d0a7ab: not eax
0x55a658d0a7ad: test dword ptr [r12 + 0x20], eax
0x55a658d0a7b2: jne 0x55a660d0a221
# pop stack frame
0x55a658d0a7b8: mov rax, r13
0x55a658d0a7bb: add rax, 0x40
0x55a658d0a7bf: mov r13, rax
Machine Code
== BLOCK 1/5, ISEQ RANGE [0,3), 93 bytes ======================
# getinstancevariable
# guard not immediate
0x55a658d0a6dd: test qword ptr [r13 + 0x18], 7
0x55a658d0a6e5: jne 0x55a660d0a0e5
0x55a658d0a6eb: cmp qword ptr [r13 + 0x18], 8
0x55a658d0a6f0: jbe 0x55a660d0a0fe
0x55a658d0a6f6: mov rax, qword ptr [r13 + 0x18]
# guard known class
0x55a658d0a6fa: movabs rcx, 0x7fbb2af48f20
0x55a658d0a704: cmp qword ptr [rax + 8], rcx
0x55a658d0a708: jne 0x55a660d0a117
0x55a658d0a70e: mov rax, qword ptr [r13 + 0x18]
0x55a658d0a712: cmp qword ptr [rax + 0x10], 0
0x55a658d0a717: jbe 0x55a660d0a0cc
# guard embedded getivar
0x55a658d0a71d: test word ptr [rax], 0x2000
0x55a658d0a722: je 0x55a660d0a130
0x55a658d0a728: cmp qword ptr [rax + 0x18], 0x34
0x55a658d0a72d: mov ecx, 8
0x55a658d0a732: cmovne rcx, qword ptr [rax + 0x18]
0x55a658d0a737: mov qword ptr [rbx], rcx
== BLOCK 2/5, ISEQ RANGE [3,6), 0 bytes =======================
== BLOCK 3/5, ISEQ RANGE [3,6), 69 bytes ======================
# getinstancevariable
# regenerate_branch
# getinstancevariable
# regenerate_branch
0x55a658d0a73a: mov rax, qword ptr [r13 + 0x18]
# guard known class
0x55a658d0a73e: movabs rcx, 0x7fbb2af48f20
0x55a658d0a748: cmp qword ptr [rax + 8], rcx
0x55a658d0a74c: jne 0x55a660d0a183
0x55a658d0a752: mov rax, qword ptr [r13 + 0x18]
0x55a658d0a756: cmp qword ptr [rax + 0x10], 1
0x55a658d0a75b: jbe 0x55a660d0a162
# guard embedded getivar
0x55a658d0a761: test word ptr [rax], 0x2000
0x55a658d0a766: je 0x55a660d0a19c
0x55a658d0a76c: cmp qword ptr [rax + 0x20], 0x34
0x55a658d0a771: mov ecx, 8
0x55a658d0a776: cmovne rcx, qword ptr [rax + 0x20]
0x55a658d0a77b: mov qword ptr [rbx + 8], rcx
== BLOCK 4/5, ISEQ RANGE [6,8), 0 bytes =======================
== BLOCK 5/5, ISEQ RANGE [6,9), 86 bytes ======================
# opt_plus
# regenerate_branch
# opt_plus
# guard arg0 fixnum
# regenerate_branch
0x55a658d0a77f: test byte ptr [rbx], 1
0x55a658d0a782: je 0x55a660d0a1ef
# guard arg1 fixnum
0x55a658d0a788: test byte ptr [rbx + 8], 1
0x55a658d0a78c: je 0x55a660d0a208
0x55a658d0a792: mov rax, qword ptr [rbx]
0x55a658d0a795: sub rax, 1
0x55a658d0a799: add rax, qword ptr [rbx + 8]
0x55a658d0a79d: jo 0x55a660d0a1ce
0x55a658d0a7a3: mov qword ptr [rbx], rax
# leave
# RUBY_VM_CHECK_INTS(ec)
0x55a658d0a7a6: mov eax, dword ptr [r12 + 0x24]
0x55a658d0a7ab: not eax
0x55a658d0a7ad: test dword ptr [r12 + 0x20], eax
0x55a658d0a7b2: jne 0x55a660d0a221
# pop stack frame
0x55a658d0a7b8: mov rax, r13
0x55a658d0a7bb: add rax, 0x40
0x55a658d0a7bf: mov r13, rax
Machine Code