On non RUBY_DEBUG builds, assert() compiles to nothing and the compiler
warns about uninitialized variables in those code paths. Replace
those asserts with rb_bug() to fix the warnings and do the assert in
all builds. Since yjit_asm_tests.c compiles outside of Ruby, it needed
a distinct version of rb_bug().
Also put YJIT_STATS check for function delcaration that is only defined
in YJIT_STATS builds.
This script is an lldb helper that just loops through all the comments
stored and prints out the comment along with the address corresponding
to the comment.
For example, I'm crashing in JIT code at address 0x0000000110000168.
Using the `lc` helper I can see that it's probably crashing inside the
exit back to the interpreter
```
(lldb) bt 5
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x22220021)
frame #0: 0x0000000110000168
* frame #1: 0x00000001002b5ff5 miniruby`invoke_block_from_c_bh [inlined] invoke_block(ec=0x0000000100e05350, iseq=0x0000000100c1ff10, self=0x0000000100c76cc0, captured=<unavailable>, cref=0x0000000000000000, type=<unavailable>, opt_pc=<unavailable>) at vm.c:1268:12
frame #2: 0x00000001002b5f7d miniruby`invoke_block_from_c_bh [inlined] invoke_iseq_block_from_c(ec=<unavailable>, captured=<unavailable>, self=0x0000000100c76cc0, argc=2, argv=<unavailable>, kw_splat=0, passed_block_handler=0x0000000000000000, cref=0x0000000000000000, is_lambda=<unavailable>, me=0x0000000000000000) at vm.c:1340
frame #3: 0x00000001002b5e14 miniruby`invoke_block_from_c_bh(ec=<unavailable>, block_handler=<unavailable>, argc=<unavailable>, argv=<unavailable>, kw_splat=0, passed_block_handler=0x0000000000000000, cref=0x0000000000000000, is_lambda=<unavailable>, force_blockarg=0) at vm.c:1358
frame #4: 0x000000010029860b miniruby`rb_yield_values(n=<unavailable>) at vm_eval.c:0
(lldb) lc
0x11000006d "putobject_INT2FIX_1_"
0x110000083 "leave"
0x110000087 "check for interrupts"
0x110000087 "RUBY_VM_CHECK_INTS(ec)"
0x110000098 "check for finish frame"
0x1100000ed "getlocal_WC_0"
0x110000107 "getlocal_WC_1"
0x11000012a "opt_send_without_block"
0x110000139 "opt_send_without_block"
0x11000013c "exit to interpreter"
```
This commits implements size classes in the GC for the Variable Width
Allocation feature. Unless `USE_RVARGC` compile flag is set, only a
single size class is created, maintaining current behaviour. See the
redmine ticket for more details.
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
This commit removes T_PAYLOAD since the new VWA implementation no longer
requires T_PAYLOAD types.
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
This commits implements size classes in the GC for the Variable Width
Allocation feature. Unless `USE_RVARGC` compile flag is set, only a
single size class is created, maintaining current behaviour. See the
redmine ticket for more details.
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
This commit removes T_PAYLOAD since the new VWA implementation no longer
requires T_PAYLOAD types.
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
rather than having to do this in a two step process:
1. heap_page obj
2. dump_page $2 (or whatever lldb variable heap_page set)
we can now just
dump_page_rvalue obj
Update the lldb script so it can mostly recover a Ruby stack trace from
a core file. It's still missing line numbers and dealing with CFUNCs,
but you use it like this:
```
(lldb) rbbt ec
rb_control_frame_t TYPE
0x7f6fd6555fa0 EVAL ./bootstraptest/runner.rb error!!
0x7f6fd6555f68 METHOD ./bootstraptest/runner.rb main
0x7f6fd6555f30 METHOD ./bootstraptest/runner.rb in_temporary_working_directory
0x7f6fd6555ef8 METHOD /home/aaron/git/ruby/lib/tmpdir.rb mktmpdir
0x7f6fd6555ec0 BLOCK ./bootstraptest/runner.rb block in in_temporary_working_directory
0x7f6fd6555e88 CFUNC
0x7f6fd6555e50 BLOCK ./bootstraptest/runner.rb block (2 levels) in in_temporary_working_directory
0x7f6fd6555e18 BLOCK ./bootstraptest/runner.rb block in main
0x7f6fd6555de0 METHOD ./bootstraptest/runner.rb exec_test
0x7f6fd6555da8 CFUNC
0x7f6fd6555d70 BLOCK ./bootstraptest/runner.rb block in exec_test
0x7f6fd6555d38 CFUNC
0x7f6fd6555d00 TOP /home/aaron/git/ruby/bootstraptest/test_insns.rb error!!
0x7f6fd6555cc8 CFUNC
0x7f6fd6555c90 BLOCK /home/aaron/git/ruby/bootstraptest/test_insns.rb block in <top (required)>
0x7f6fd6555c58 METHOD ./bootstraptest/runner.rb assert_equal
0x7f6fd6555c20 METHOD ./bootstraptest/runner.rb assert_check
0x7f6fd6555be8 METHOD ./bootstraptest/runner.rb show_progress
0x7f6fd6555bb0 METHOD ./bootstraptest/runner.rb with_stderr
0x7f6fd6555b78 BLOCK ./bootstraptest/runner.rb block in show_progress
0x7f6fd6555b40 BLOCK ./bootstraptest/runner.rb block in assert_check
0x7f6fd6555b08 METHOD ./bootstraptest/runner.rb get_result_string
0x7f6fd6555ad0 METHOD ./bootstraptest/runner.rb make_srcfile
0x7f6fd6555a98 CFUNC
0x7f6fd6555a60 BLOCK ./bootstraptest/runner.rb block in make_srcfile
```
Getting the main execution context is difficult (it is stored in a
thread local) so for now you must supply an ec and this will make a
backtrace
This fixes the lldb disassembler script so that it doesn't need a live
process when disassembling rb_iseq_t. I also added the PC to the output
so you can tell what the VM is executing when it crashed.
For example:
```
(lldb) rbdisasm ec->cfp->iseq
PC IDX insn_name(operands)
0x56039f0a1720 0000 nop
0x56039f0a1728 0001 getlocal_WC_1( 5 )
0x56039f0a1738 0003 branchunless( 7 )
0x56039f0a1748 0005 getlocal_WC_0( 3 )
0x56039f0a1758 0007 putstring( (VALUE)0x56039f0c7eb8 )
0x56039f0a1768 0009 opt_send_without_block( (struct rb_call_data *)0x56039f09f140 )
0x56039f0a1778 0011 pop
0x56039f0a1780 0012 getglobal( ID: 0x7fd7 )
0x56039f0a1790 0014 branchunless( 7 )
0x56039f0a17a0 0016 getlocal_WC_0( 3 )
0x56039f0a17b0 0018 putstring( (VALUE)0x56039f0c7e90 )
0x56039f0a17c0 0020 opt_send_without_block( (struct rb_call_data *)0x56039f09f150 )
0x56039f0a17d0 0022 pop
0x56039f0a17d8 0023 getlocal_WC_0( 3 )
0x56039f0a17e8 0025 putobject( (VALUE)0x56039f0c7e68 )
0x56039f0a17f8 0027 getlocal_WC_1( 6 )
0x56039f0a1808 0029 dup
0x56039f0a1810 0030 checktype( 5 )
0x56039f0a1820 0032 branchif( 4 )
0x56039f0a1830 0034 dup
0x56039f0a1838 0035 opt_send_without_block( (struct rb_call_data *)0x56039f09f160 )
0x56039f0a1848 0037 tostring
0x56039f0a1850 0038 putobject( (VALUE)0x56039f0c7e40 )
0x56039f0a1860 0040 concatstrings( 3 )
0x56039f0a1870 0042 opt_send_without_block( (struct rb_call_data *)0x56039f09f170 )
0x56039f0a1880 0044 nop
0x56039f0a1888 0045 leave
(lldb) p ec->cfp->pc
(const VALUE *) $146 = 0x000056039f0a1848
```
Here we can see the VM is currently executing `opt_send_without_block`
(because the PC is one ahead of the current instruction)
I need to disassemble instruction sequences while debugging, so I wrote
this.
Usage is like this:
```
(lldb) p iseq
(rb_iseq_t *) $147 = 0x0000000101068400
(lldb) rbdisasm iseq
0000 putspecialobject( 3 )
0002 putnil
0003 defineclass( ID: 0x560b, (rb_iseq_t *)0x1010681d0, 2 )
0007 pop
0008 putspecialobject( 3 )
0010 putnil
0011 defineclass( ID: 0x56eb, (rb_iseq_t *)0x101063b58, 2 )
0015 leave
```
Also thanks a ton to @kivikakk helping me figure out how to navigate LLDB's Python 😆