Slide 1

Slide 1 text

https://github.com/tenderlove/tenderjit TenderJIT Intro Short Intro to TenderJIT

Slide 2

Slide 2 text

Pure Ruby JIT Compiler For Ruby

Slide 3

Slide 3 text

Agenda Why? Machine Types What is JIT? TenderJIT & Code

Slide 4

Slide 4 text

Why?

Slide 5

Slide 5 text

1. I’m not good at JITs

Slide 6

Slide 6 text

2. To See If I Could

Slide 7

Slide 7 text

I ❤ Ruby

Slide 8

Slide 8 text

Is this “real”?

Slide 9

Slide 9 text

Yes. It is Le JIT

Slide 10

Slide 10 text

But is it really “real”?

Slide 11

Slide 11 text

Is this a “real” JIT or a learning project?

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Code Execution How do machines work?

Slide 14

Slide 14 text

Two Machine Types Stack Machines Register Machines

Slide 15

Slide 15 text

Stack Machines

Slide 16

Slide 16 text

Stack Machine 5 + 3 push 5 push 3 plus Source Code Machine Code 5 3 8 Machine Stack

Slide 17

Slide 17 text

YARV is a Stack Machine

Slide 18

Slide 18 text

YARV Instructions $ cat thing.rb 5 + 3 $ ruby --dump=insns thing.rb == disasm: #@thing.rb:1 (1,0)-(1,5)> (catch: FALSE) 0000 putobject 5 ( 1)[Li] 0002 putobject 3 0004 opt_plus [CcCr] 0006 leave

Slide 19

Slide 19 text

Terminology

Slide 20

Slide 20 text

Stack Machine 5 + 3 push 5 push 3 plus Source Code Machine Code 5 3 Machine Stack PC (Program Counter) SP (Stack Pointer)

Slide 21

Slide 21 text

Stack Machine 5 + 3 push 5 push 3 plus Source Code Machine Code 5 3 Machine Stack 0 1 2 … -1 1 0

Slide 22

Slide 22 text

CFP = “Control Frame Pointer”

Slide 23

Slide 23 text

Control Frame Pointer Contains Information About the Current Frame def baz end def bar baz end def foo bar end foo Main Control Frame Pointers foo bar baz

Slide 24

Slide 24 text

Control Frame Pointer Contains Information About the Current Frame def add 5 + 3 end Field Description iseq Instruction Sequence (the method) PC Program Counter (what are we running right now?) SP Stack Pointer (what is on the stack?) opt_plus 3 5

Slide 25

Slide 25 text

EC = “Execution Context”

Slide 26

Slide 26 text

Register Machine (x86, ARM, etc)

Slide 27

Slide 27 text

Register Machine 5 + 3 mov r1, 5 mov r2, 3 add r1, r2 Source Code Machine Code Machine Registers Register Name Value r1 r2 r3 … 5 3 8

Slide 28

Slide 28 text

x86 Instructions int main(int argc, char *argv[]) { int x = 5; int y = 3; return x + y; } 100003fa2: mov dword ptr [rbp - 20], 5 100003fa9: mov dword ptr [rbp - 24], 3 100003fb0: mov eax, dword ptr [rbp - 20] 100003fb3: add eax, dword ptr [rbp - 24] Source Code Machine Code

Slide 29

Slide 29 text

x86 Instructions int main(int argc, char *argv[]) { int x = 5; int y = 3; return x + y; } 100003fa2: mov dword ptr [rbp - 20], 5 100003fa9: mov dword ptr [rbp - 24], 3 100003fb0: mov eax, dword ptr [rbp - 20] 100003fb3: add eax, dword ptr [rbp - 24] Source Code Machine Code

Slide 30

Slide 30 text

x86 Instructions int main(int argc, char *argv[]) { int x = 5; int y = 3; return x + y; } 100003fa2: mov dword ptr [rbp - 20], 5 100003fa9: mov dword ptr [rbp - 24], 3 100003fb0: mov eax, dword ptr [rbp - 20] 100003fb3: add eax, dword ptr [rbp - 24] Source Code Machine Code

Slide 31

Slide 31 text

x86 Instructions int main(int argc, char *argv[]) { int x = 5; int y = 3; return x + y; } 100003fa2: mov dword ptr [rbp - 20], 5 100003fa9: mov dword ptr [rbp - 24], 3 100003fb0: mov eax, dword ptr [rbp - 20] 100003fb3: add eax, dword ptr [rbp - 24] Source Code Machine Code Register “EAX”

Slide 32

Slide 32 text

x86 Instructions int main(int argc, char *argv[]) { int x = 5; int y = 3; return x + y; } 100003fa2: mov dword ptr [rbp - 20], 5 100003fa9: mov dword ptr [rbp - 24], 3 100003fb0: mov eax, dword ptr [rbp - 20] 100003fb3: add eax, dword ptr [rbp - 24] Source Code Machine Code

Slide 33

Slide 33 text

What is a JIT?

Slide 34

Slide 34 text

JIT: Machine Code at Runtime

Slide 35

Slide 35 text

Machine Code in Ruby require "fisk" require "fisk/helpers" # Allocate executable memory jitbuf = Fisk::Helpers.jitbuffer 4096 fisk = Fisk.new # Add 5 and 3 in machine language, and write to the JIT buffer fisk.asm(jitbuf) do mov rax, imm(5) # Store 5 in RAX mov r9, imm(3) # Store 3 in R9 add rax, r9 # Add R9 to RAX ret # Return from this function end # Define an add method define_method :add, &jitbuf.to_function([], Fiddle::TYPE_INT) p add # Call add and print it

Slide 36

Slide 36 text

TenderJIT: Translate YARV to Machine Code

Slide 37

Slide 37 text

Stack Machine to Register Machine