Upgrade to Pro — share decks privately, control downloads, hide ads and more …

HexDevs 2021

HexDevs 2021

Slides from my session on HexDevs with TenderJIT

Aaron Patterson

October 11, 2021
Tweet

More Decks by Aaron Patterson

Other Decks in Technology

Transcript

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

    View Slide

  2. Pure Ruby JIT Compiler


    For Ruby

    View Slide

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

    View Slide

  4. Why?

    View Slide

  5. 1. I’m not good at JITs

    View Slide

  6. 2. To See If I Could

    View Slide

  7. I ❤ Ruby

    View Slide

  8. Is this “real”?

    View Slide

  9. Yes. It is Le JIT

    View Slide

  10. But is it really “real”?

    View Slide

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

    View Slide

  12. View Slide

  13. Code Execution
    How do machines work?

    View Slide

  14. Two Machine Types
    Stack Machines
    Register Machines

    View Slide

  15. Stack Machines

    View Slide

  16. Stack Machine
    5 + 3 push 5


    push 3


    plus
    Source Code Machine Code
    5
    3
    8
    Machine Stack

    View Slide

  17. YARV is a Stack Machine

    View Slide

  18. 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

    View Slide

  19. Terminology

    View Slide

  20. Stack Machine
    5 + 3 push 5


    push 3


    plus
    Source Code Machine Code
    5
    3
    Machine Stack
    PC


    (Program
    Counter) SP


    (Stack Pointer)

    View Slide

  21. Stack Machine
    5 + 3 push 5


    push 3


    plus
    Source Code Machine Code
    5
    3
    Machine Stack
    0


    1


    2



    -1
    1
    0

    View Slide

  22. CFP = “Control Frame Pointer”

    View Slide

  23. 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

    View Slide

  24. 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

    View Slide

  25. EC = “Execution Context”

    View Slide

  26. Register Machine (x86, ARM, etc)

    View Slide

  27. 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

    View Slide

  28. 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

    View Slide

  29. 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

    View Slide

  30. 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

    View Slide

  31. 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”

    View Slide

  32. 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

    View Slide

  33. What is a JIT?

    View Slide

  34. JIT: Machine Code at Runtime

    View Slide

  35. 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

    View Slide

  36. TenderJIT:


    Translate YARV to Machine Code

    View Slide

  37. Stack Machine to


    Register Machine

    View Slide