68766 Commits

Author SHA1 Message Date
Maxime Chevalier-Boisvert
d2d564be1d Moved ujit code invalidation test into bootstraptest 2021-10-20 18:19:28 -04:00
Alan Wu
56ce40e8be Only compile iseqs with simple parameters. Enable get_local_wc1 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
e85e0e2fa9 Commit WIP setlocal_WC_1 implementation 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
439e1089b7 Implement opt_le, opt_ge in ujit 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
020f745041 Fix overflow check in ujit 2021-10-20 18:19:28 -04:00
Alan Wu
7f73948c3a Add code side info to --ujit-stats
shopify/ruby#23
2021-10-20 18:19:28 -04:00
Alan Wu
c734405ccd Add stats for number of ujit entry points installed
shopify/ruby#23
2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
6a29131439 Implement Ruby-to-Ruby calls in ujit (opt_send_without_block) 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
27a4443643 Add total exit count to stats 2021-10-20 18:19:28 -04:00
Aaron Patterson
9453267689 add bop to redefinition callback 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
53bd13edf3 Implement opt_and in ujit 2021-10-20 18:19:28 -04:00
Aaron Patterson
863ff14997 Add a callback in to microjit when a BOP is redefined
This commit adds a callback `rb_ujit_bop_redefined` when a basic
operation is redefined.
2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
05c72d40b7 Alan & Max at Tanagra 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
a6d0c61c3c Add percentages to exit op counts in --ujit-stats 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
2e561ff255 Restore interpreter regs in ujit hook. Implement leave bytecode. 2021-10-20 18:19:28 -04:00
Alan Wu
3c7251b41b Tally instructions when taking side exists for --ujit-stats
shopify/ruby#29

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
09479c33f5 Implement block version limit 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
81c57ab9b8 Reduce size of ctx_t 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert
a14015e9b5 Report unknown --ujit-* options 2021-10-20 18:19:28 -04:00
Alan Wu
b7f93e81df Implement --ujit-stats and instructoin counting
VM and ujit instruction counting in debug builds.

shopify/ruby#19
2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
36232a48a6 Set T_FIXNUM type tags in opt_plus, opt_minus 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
c61238a276 Optimize putobject codegen 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
e7909467df Eliminate type checks in opt_lt 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
63e85de33a Fix bug, block added with wrong blockid. 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
b0b1bc1684 Tweak ujit disasm output 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
4f47181be6 Keep track of multiple versions per blockid 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
9def269b47 Fix issue with block address accessor. Print absolute addresses. 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
79d6e9618d Make find_block_version() do list search 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
8a61e848c0 Minor changes to disasm output. Fix GCC warning. 2021-10-20 18:19:27 -04:00
Alan Wu
25234f8a1c Update dependencies 2021-10-20 18:19:27 -04:00
Alan Wu
042c6aab54 Fix cast warning 2021-10-20 18:19:27 -04:00
Alan Wu
f68ddaa54a Declare instead of define data varaibles in header 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
738160db0a Write ctx_diff() function to compate ctx_t objects 2021-10-20 18:19:27 -04:00
Aaron Patterson
7efde1bfb4 conditionally add libcapstone 2021-10-20 18:19:27 -04:00
Aaron Patterson
e427fdff0a Directly link libcapstone for easier development
This lets us use libcapstone directly from miniruby so we don't need a
Ruby Gem to to dev work.

Example usage:

```ruby
def foo(x)
  if x < 1
    "wow"
  else
    "neat"
  end
end

iseq = RubyVM::InstructionSequence.of(method(:foo))
puts UJIT.disasm(iseq)
100.times { foo 1 }
puts UJIT.disasm(iseq)
```

Then in the terminal

```
$ ./miniruby test.rb

== disasm: #<ISeq:foo@test.rb:1 (1,0)-(7,3)> (catch: FALSE)
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0<Arg>
0000 getlocal_WC_0                          x@0                       (   2)[LiCa]
0002 putobject_INT2FIX_1_
0003 opt_lt                                 <calldata!mid:<, argc:1, ARGS_SIMPLE>
0005 branchunless                           10
0007 putstring                              "wow"                     (   3)[Li]
0009 leave                                                            (   7)[Re]
0010 putstring                              "neat"                    (   5)[Li]
0012 leave                                                            (   7)[Re]

== ISEQ RANGE: 10 -> 10 ========================================================
        0x0:    movabs  rax, 0x7fe816e2d1a0
        0xa:    mov     qword ptr [rdi], rax
        0xd:    mov     r8, rax
        0x10:   mov     r9, rax
        0x13:   mov     r11, r12
        0x16:   jmp     qword ptr [rax]
== ISEQ RANGE: 0 -> 7 ==========================================================
        0x0:    mov     rax, qword ptr [rdi + 0x20]
        0x4:    mov     rax, qword ptr [rax - 0x18]
        0x8:    mov     qword ptr [rdx], rax
        0xb:    mov     qword ptr [rdx + 8], 3
        0x13:   movabs  rax, 0x7fe817808200
        0x1d:   test    byte ptr [rax + 0x3e6], 1
        0x24:   jne     0x3ffff7b
        0x2a:   test    byte ptr [rdx], 1
        0x2d:   je      0x3ffff7b
        0x33:   test    byte ptr [rdx + 8], 1
        0x37:   je      0x3ffff7b
        0x3d:   mov     rax, qword ptr [rdx]
        0x40:   cmp     rax, qword ptr [rdx + 8]
        0x44:   movabs  rax, 0
        0x4e:   movabs  rcx, 0x14
        0x58:   cmovl   rax, rcx
        0x5c:   mov     qword ptr [rdx], rax
        0x5f:   test    qword ptr [rdx], -9
        0x66:   jne     0x3ffffd5
```

Make sure to `brew install pkg-config capstone`
2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
dea4db16c0 Add support for multiple versions per block 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
d528cf4fd5 Added comments. Fixed compiler warning. 2021-10-20 18:19:27 -04:00
Aaron Patterson
11512a80fc add a helper script for ujit disasm 2021-10-20 18:19:27 -04:00
Aaron Patterson
d9176d9fca Expose methods for inspecting Micro JIT code blocks
This commit adds a module `UJIT`.  The module allows you to insert the
initial Micro JIT instruction in to an arbitrary iseq like this:

```ruby
def foo(x)
  if x < 1
    "less than one"
  else
    "something else"
  end
end

iseq = RubyVM::InstructionSequence.of(method(:foo))

UJIT.insert(iseq) # Add initial jump
```

After the initial jump is added, we can make Micro JIT do some work:

```ruby
100.times { foo(0) }
```

The `UJIT` module also exposes a method for finding all compiled blocks
for a given iseq, like this:

```ruby
blocks = UJIT.blocks_for(iseq)
```

We can sort the blocks by address and use the Crabstone gem (which is a
wrapper around `capstone`) to disassemble the generated code.

Here is the full code example:

```ruby
def foo(x)
  if x < 1
    "less than one"
  else
    "something else"
  end
end

iseq = RubyVM::InstructionSequence.of(method(:foo))

UJIT.insert(iseq) # Add initial jump

100.times { foo(0) }

blocks = UJIT.blocks_for(iseq)

 # brew install capstone
 # gem install crabstone
require "crabstone"

cs = Crabstone::Disassembler.new(Crabstone::ARCH_X86, Crabstone::MODE_64)

puts iseq.disasm

blocks.sort_by(&:address).reverse.each do |block|
  puts "== ISEQ RANGE: #{block.iseq_start_index} -> #{block.iseq_end_index} ".ljust(80, "=")
  cs.disasm(block.code, 0).each do |i|
    printf(
      "\t0x%<address>x:\t%<instruction>s\t%<details>s\n",
      address: i.address,
      instruction: i.mnemonic,
      details: i.op_str
    )
  end
end
```

Here is the output:

```
$ ./ruby test.rb
== disasm: #<ISeq:foo@test.rb:1 (1,0)-(7,3)> (catch: FALSE)
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] x@0<Arg>
0000 getlocal_WC_0                          x@0                       (   2)[LiCa]
0002 putobject_INT2FIX_1_
0003 opt_lt                                 <calldata!mid:<, argc:1, ARGS_SIMPLE>
0005 branchunless                           10
0007 putstring                              "less than one"           (   3)[Li]
0009 leave                                                            (   7)[Re]
0010 putstring                              "something else"          (   5)[Li]
0012 leave                                                            (   7)[Re]
== ISEQ RANGE: 7 -> 7 ==========================================================
	0x0:	movabs	rax, 0x7fcd014cd518
	0xa:	mov	qword ptr [rdi], rax
	0xd:	mov	r8, rax
	0x10:	mov	r9, rax
	0x13:	mov	r11, r12
	0x16:	jmp	qword ptr [rax]
== ISEQ RANGE: 0 -> 7 ==========================================================
	0x0:	mov	rax, qword ptr [rdi + 0x20]
	0x4:	mov	rax, qword ptr [rax - 0x18]
	0x8:	mov	qword ptr [rdx], rax
	0xb:	mov	qword ptr [rdx + 8], 3
	0x13:	movabs	rax, 0x7fcd0180ac00
	0x1d:	test	byte ptr [rax + 0x3e6], 1
	0x24:	jne	0x3ffe0da
	0x2a:	test	byte ptr [rdx], 1
	0x2d:	je	0x3ffe0da
	0x33:	test	byte ptr [rdx + 8], 1
	0x37:	je	0x3ffe0da
	0x3d:	mov	rax, qword ptr [rdx]
	0x40:	cmp	rax, qword ptr [rdx + 8]
	0x44:	movabs	rax, 0
	0x4e:	movabs	rcx, 0x14
	0x58:	cmovl	rax, rcx
	0x5c:	mov	qword ptr [rdx], rax
	0x5f:	test	qword ptr [rdx], -9
	0x66:	je	0x3ffe111
	0x6c:	jmp	0xffffffffffffffa3
```
2021-10-20 18:19:27 -04:00
Alan Wu
ce233c95db Remove assert that doesn't compile 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
0a42428098 Implement branchif in ujit 2021-10-20 18:19:27 -04:00
Alan Wu
331f662ddb Update dependencies 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
0a6e824ad2 Prototype type-specialization for temp values 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
cf4021ca78 Take VM lock in branch_stub_hit(), fix ractor deadlock. 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
dde69ab5c6 Fix ujit block hash table bug 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
136bf983be Fix bug with ujit code invalidation 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
37ad374607 Added gen_direct_jump() for unary branches 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
187435c117 Complete refactoring to eliminate recursion in ujit's compilation 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
02a9700475 End current block after opt_send_without_block 2021-10-20 18:19:27 -04:00
Maxime Chevalier-Boisvert
79331368b9 Added block end index 2021-10-20 18:19:27 -04:00