summaryrefslogtreecommitdiff
path: root/misc
Commit message (Collapse)AuthorAgeFilesLines
* LLDB: Fix T_ARRAY inspect [ci skip]Nobuyoshi Nakada2023-04-101-2/+2
|
* gdb: Fix a command exampleTakashi Kokubun2023-04-011-1/+1
| | | | | It was actually harder to type `cfp + 1`. `cfp 1` also works and is more useful.
* gdb: Fix specvalTakashi Kokubun2023-04-011-3/+4
| | | | | Somehow my gdb stopped recognizing VM_BLOCK_HANDLER_NONE (macro) today. Just changing it to a safer code.
* gdb: Don't dump params and locals for C framesTakashi Kokubun2023-04-011-11/+12
|
* gdb: Visualize register positions on the leftTakashi Kokubun2023-03-311-1/+14
|
* gdb: Always show actual values in cfpTakashi Kokubun2023-03-311-5/+7
|
* gdb: Show params and locals in cfpTakashi Kokubun2023-03-311-1/+12
|
* gdb: Dump env data in cfp commandTakashi Kokubun2023-03-311-3/+72
|
* Put misc/gdb.py [experimental]Takashi Kokubun2023-03-311-0/+33
| | | | | | | | | | | | | | | | | | | | | | | | This works like: ``` (gdb) cfp CFP (count=3, addr=0x7ffff73fef50): $1 = {pc = 0x555556bf7818, sp = 0x7ffff72ff078, iseq = 0x7ffff2603270, self = 140737344619296, ep = 0x7ffff72ff058, block_code = 0x0, __bp__ = 0x7ffff72ff060, jit_return = 0x555558c2b000} Stack (size=3): [0] FIXNUM: 1 [1] T_STRING: "" bytesize:0 (embed) encoding:1 coderange:7bit $2 = (struct RString *) 0x7ffff249ea80 [2] [PROMOTED] T_OBJECT: $3 = {flags = 21474844769, klass = 140737344040416} $4 = {0x24, 0x24, 0x24} (gdb) cfp + 1 CFP (count=3, addr=0x7ffff73fef90): $5 = {pc = 0x5555567a78f8, sp = 0x7ffff72ff040, iseq = 0x7ffff26032d0, self = 140737344619296, ep = 0x7ffff72ff038, block_code = 0x0, __bp__ = 0x7ffff72ff040, jit_return = 0x555558c2b000} Stack (size=0): ```
* [ci skip] LLDB: Fix rp for arraysMatt Valentine-House2023-03-301-3/+3
|
* Fix missing receiver [ci sip]Nobuyoshi Nakada2023-03-311-1/+1
|
* [ci skip] Move rb_id2str into new LLDB formatMatt Valentine-House2023-03-212-1/+50
|
* * remove trailing spaces. [ci skip]git2023-03-172-11/+11
|
* [ci skip] Move rp helper to new LLDB formatMatt Valentine-House2023-03-177-16/+455
| | | | | For now, the old function still exists as `old_rp`, in order to debug issues with this command.
* [lldb] Add a print_flags command (#7358)Matt Valentine-House2023-02-222-3/+33
|
* Tell VSCode to debug test.rb by default [ci-skip]Matt Valentine-House2023-02-101-1/+1
|
* Put example VSCode configs in misc/.vscode [ci skip]Takashi Kokubun2023-02-034-0/+33
| | | | | | | | | | They are needed very often but it's hard to remember. I thought it'd be useful to just copy that to /.vscode and edit that. Usage: cp -r misc/.vscode .vscode Don't symlink it because you'd edit it but not want to commit it.
* Ivar copy needs to happen _before_ setting the shapeAaron Patterson2022-11-011-2/+2
| | | | | | | | When we copy instance variables, it is possible for the GC to be kicked off. The GC looks at the shape to determine what slots to mark inside the object. If the shape is set too soon, the GC could think that there are more instance variables on the object than there actually are at that moment.
* Revert "Revert "This commit implements the Object Shapes technique in CRuby.""Jemma Issroff2022-10-111-0/+1
| | | | This reverts commit 9a6803c90b817f70389cae10d60b50ad752da48f.
* Revert "This commit implements the Object Shapes technique in CRuby."Aaron Patterson2022-09-301-1/+0
| | | | This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
* This commit implements the Object Shapes technique in CRuby.Jemma Issroff2022-09-281-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Object Shapes is used for accessing instance variables and representing the "frozenness" of objects. Object instances have a "shape" and the shape represents some attributes of the object (currently which instance variables are set and the "frozenness"). Shapes form a tree data structure, and when a new instance variable is set on an object, that object "transitions" to a new shape in the shape tree. Each shape has an ID that is used for caching. The shape structure is independent of class, so objects of different types can have the same shape. For example: ```ruby class Foo def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end class Bar def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end foo = Foo.new # `foo` has shape id 2 bar = Bar.new # `bar` has shape id 2 ``` Both `foo` and `bar` instances have the same shape because they both set instance variables of the same name in the same order. This technique can help to improve inline cache hits as well as generate more efficient machine code in JIT compilers. This commit also adds some methods for debugging shapes on objects. See `RubyVM::Shape` for more details. For more context on Object Shapes, see [Feature: #18776] Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
* Revert this until we can figure out WB issues or remove shapes from GCAaron Patterson2022-09-261-5/+1
| | | | | | | | | | Revert "* expand tabs. [ci skip]" This reverts commit 830b5b5c351c5c6efa5ad461ae4ec5085e5f0275. Revert "This commit implements the Object Shapes technique in CRuby." This reverts commit 9ddfd2ca004d1952be79cf1b84c52c79a55978f4.
* This commit implements the Object Shapes technique in CRuby.Jemma Issroff2022-09-261-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Object Shapes is used for accessing instance variables and representing the "frozenness" of objects. Object instances have a "shape" and the shape represents some attributes of the object (currently which instance variables are set and the "frozenness"). Shapes form a tree data structure, and when a new instance variable is set on an object, that object "transitions" to a new shape in the shape tree. Each shape has an ID that is used for caching. The shape structure is independent of class, so objects of different types can have the same shape. For example: ```ruby class Foo def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end class Bar def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end foo = Foo.new # `foo` has shape id 2 bar = Bar.new # `bar` has shape id 2 ``` Both `foo` and `bar` instances have the same shape because they both set instance variables of the same name in the same order. This technique can help to improve inline cache hits as well as generate more efficient machine code in JIT compilers. This commit also adds some methods for debugging shapes on objects. See `RubyVM::Shape` for more details. For more context on Object Shapes, see [Feature: #18776] Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
* Write interface instead of interfactKaíque Kandy Koga2022-08-191-1/+1
|
* * remove trailing spaces. [ci skip]git2022-08-191-3/+3
|
* [ci skip][Feature #18910][lldb] Dedup lldb_initMatt Valentine-House2022-08-182-28/+31
| | | | by moving it fully into RbBaseCommand
* [ci-skip][Feature #18910][lldb] New directory structureMatt Valentine-House2022-08-186-6/+11
| | | | | Push the newly refactored lldb files into a sub-directory so that we're not cluttering up the misc directory
* [ci-skip][Feature #18910][lldb] Port rclass_ext to new LLDB FrameworkMatt Valentine-House2022-08-182-19/+14
|
* [ci-skip][Feature #18910][lldb] Port heap_page command to new LLDB frameworkMatt Valentine-House2022-08-182-14/+26
|
* [ci-skip][Feature #18910][lldb] Provide class framework for lldb commandsMatt Valentine-House2022-08-184-5/+121
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `lldb_cruby.py` manages lldb custom commands using functions. The file is a large list of Python functions, and an init handler to map some of the Python functions into the debugger, to enable execution of custom logic during a debugging session. Since LLDB 3.7 (September 2015) there has also been support for using python classes rather than bare functions, as long as those classes implement a specific interface. This PR Introduces some more defined structure to the LLDB helper functions by switching from the function based implementation to the class based one, and providing an auto-loading mechanism by which new functions can be loaded. The intention behind this change is to make working with the LLDB helpers easier, by reducing code duplication, providing a consistent structure and a clearer API for developers. The current function based approach has some advantages and disadvantages Advantages: - Adding new code is easy. - All the code is self contained and searchable. Disadvantages: - No visible organisation of the file contents. This means - Hard to tell which functions are utility functions and which are available to you in a debugging session - Lots of code duplication within lldb functions - Large files quickly become intimidating to work with - for example, `lldb_disasm.py` was implemented as a seperate Python module because it was easier to start with a clean slate than add significant amounts of code to `lldb_cruby.py` This PR attempts, to fix the disadvantages of the current approach and maintain, or enhance, the benefits. The new structure of a command looks like this; ``` class TestCommand(RbBaseCommand): # program is the keyword the user will type in lldb to execute this command program = "test" # help_string will be displayed in lldb when the user uses the help functions help_string = "This is a test command to show how to implement lldb commands" # call is where our command logic will be implemented def call(self, debugger, command, exe_ctx, result): pass ``` If the command fulfils the following criteria it will then be auto-loaded when an lldb session is started: - The package file must exist inside the `commands` directory and the filename must end in `_command.py` - The package must implement a class whose name ends in `Command` - The class inherits from `RbBaseCommand` or at minimum a class that shares the same interface as `RbBaseCommand` (at minimum this means defining `__init__` and `__call__`, and using `__call__` to call `call` which is defined in the subclasses). - The class must have a class variable `package` that is a String. This is the name of the command you'll call in the `lldb` debugger.
* Get the insns_address_table from the vm_exec_core module table...Matt Valentine-House2022-07-141-2/+11
|
* fix lldb scripts on older lldb pythonAaron Patterson2022-07-061-1/+3
|
* Add T_STRUCT to lldb inspect helperJemma Issroff2022-06-211-0/+4
|
* [ci skip][lldb] Fix array length representation with USING_RVARGCMatt Valentine-House2022-06-171-2/+2
| | | | | | | | | | | | This commit makes `rp` report the correct array length in lldb. When USING_RVARGC is set we use 7 bits of the flags to store the array len rather than the usual 2, so they need to be part of the mask when calculating the length in lldb. When calculating whether rvargc is enabled I've used the same approach that's used by `GC.using_rvargc?` which is to detect whether there is more than one size pool in the current objspace.
* [ci skip] [lldb] Ensure rbbt has loaded the globalsMatt Valentine-House2022-06-151-0/+2
| | | | | | | | | rb_backtrace relies on the existend of RUBY_T_MASK. This is set up by the global loading code in lldb_init() rb_backtrace does not call lldb_init previously, and therefore would only work if called after another lldb function that _did_ load the globals.
* [ci skip] Print the rb_classext_t for a class, using an offsetMatt Valentine-House2022-06-151-0/+19
| | | | | | Now that classes are using VWA, the RCLASS_PTR uses an offset to get the rb_classext_t object. Doing this all the time in lldb is boring. So script lldb to do it for us
* Add imemo types to global namespace in lldb helpersJemma Issroff2022-06-151-0/+6
|
* Add more information to lldb dump_page helperJemma Issroff2022-05-271-2/+6
|
* Update lldb helper for iseq disassembly to use correct var nameJemma Issroff2022-05-041-1/+1
|
* Rust YJITAlan Wu2022-04-272-453/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In December 2021, we opened an [issue] to solicit feedback regarding the porting of the YJIT codebase from C99 to Rust. There were some reservations, but this project was given the go ahead by Ruby core developers and Matz. Since then, we have successfully completed the port of YJIT to Rust. The new Rust version of YJIT has reached parity with the C version, in that it passes all the CRuby tests, is able to run all of the YJIT benchmarks, and performs similarly to the C version (because it works the same way and largely generates the same machine code). We've even incorporated some design improvements, such as a more fine-grained constant invalidation mechanism which we expect will make a big difference in Ruby on Rails applications. Because we want to be careful, YJIT is guarded behind a configure option: ```shell ./configure --enable-yjit # Build YJIT in release mode ./configure --enable-yjit=dev # Build YJIT in dev/debug mode ``` By default, YJIT does not get compiled and cargo/rustc is not required. If YJIT is built in dev mode, then `cargo` is used to fetch development dependencies, but when building in release, `cargo` is not required, only `rustc`. At the moment YJIT requires Rust 1.60.0 or newer. The YJIT command-line options remain mostly unchanged, and more details about the build process are documented in `doc/yjit/yjit.md`. The CI tests have been updated and do not take any more resources than before. The development history of the Rust port is available at the following commit for interested parties: https://github.com/Shopify/ruby/commit/1fd9573d8b4b65219f1c2407f30a0a60e537f8be Our hope is that Rust YJIT will be compiled and included as a part of system packages and compiled binaries of the Ruby 3.2 release. We do not anticipate any major problems as Rust is well supported on every platform which YJIT supports, but to make sure that this process works smoothly, we would like to reach out to those who take care of building systems packages before the 3.2 release is shipped and resolve any issues that may come up. [issue]: https://bugs.ruby-lang.org/issues/18481 Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Co-authored-by: Noah Gibbs <the.codefolio.guy@gmail.com> Co-authored-by: Kevin Newton <kddnewton@gmail.com>
* Make heap page sizes 64KiB by defaultPeter Zhu2022-04-041-4/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit dde164e968e382d50b07ad4559468885cbff33ef decoupled incremental marking from page sizes. This commit changes Ruby heap page sizes to 64KiB. Doing so will have several benefits: 1. We can use compaction on systems with 64KiB system page sizes (e.g. PowerPC). 2. Larger page sizes will allow Variable Width Allocation to increase slot sizes and embed larger objects. 3. Since commit 002fa2859962f22de8afdbeece04966ea57b7da9, macOS has 64 KiB pages. Making page sizes 64 KiB will bring these systems to parity. I have attached some bechmark results below. Discourse: On Discourse, we saw much better p99 performance (e.g. for "categories" it went from 214ms on master to 134ms on branch, for "home" it went from 265ms to 251ms). We don’t see much change in p60, p75, and p90 performance. We also see a slight decrease in memory usage by 1.04x. Branch RSS: 354.9MB Master RSS: 368.2MB railsbench: On rails bench, we don’t see a big change in RPS or p99 performance. We don’t see a big difference in memory usage. Branch RPS: 826.27 Master RPS: 824.85 Branch p99: 1.67 Master p99: 1.72 Branch RSS: 88.72MB Master RSS: 88.48MB liquid: We don’t see a significant change in liquid performance. Branch parse & render: 28.653 I/s Master parse & render: 28.563 i/s
* Fix up global name references in misc/lldb_disasm.pyAaron Patterson2022-04-011-4/+4
| | | | | Some of the symbols had changed names and the script was no longer finding them.
* Treat TS_ICVARC cache as separate from TS_IVC cacheJemma Issroff2022-02-021-0/+2
|
* [lldb] Handle MacOS 64Kb heap pages in the lldb helpersMatt Valentine-House2022-01-261-1/+6
|
* lldb_cruby.py: support RVARGC on T_CLASS [ci skip]Nobuyoshi Nakada2022-01-171-0/+3
|
* Update lldb_cruby.py for VWA stringsPeter Zhu2022-01-061-2/+1
|
* YJIT: Bounds check every byte in the assemblerAlan Wu2021-12-032-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Previously, YJIT assumed that basic blocks never consume more than 1 KiB of memory. This assumption does not hold for long Ruby methods such as the one in the following: ```ruby eval(<<RUBY) def set_local_a_lot #{'_=0;'*0x40000} end RUBY set_local_a_lot ``` For low `--yjit-exec-mem-size` values, one basic block could exhaust the entire buffer. Introduce a new field `codeblock_t::dropped_bytes` that the assembler sets whenever it runs out of space. Check this field in gen_single_block() to respond to out of memory situations and other error conditions. This design avoids making the control flow graph of existing code generation functions more complex. Use POSIX shell in misc/test_yjit_asm.sh since bash is expanding `0%/*/*` differently. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Mark JIT code as writeable / executable depending on the situationAaron Patterson2021-12-011-1/+1
| | | | | | | | | | | | | | | | Some platforms don't want memory to be marked as writeable and executable at the same time. When we write to the code block, we calculate the OS page that the buffer position maps to. Then we call `mprotect` to allow writes on that particular page. As an optimization, we cache the "last written" aligned page which allows us to amortize the cost of the `mprotect` call. In other words, sequential writes to the same page will only call `mprotect` on the page once. When we're done writing, we call `mprotect` on the entire JIT buffer. This means we don't need to keep track of which pages were marked as writeable, we let the OS take care of that. Co-authored-by: John Hawthorn <john@hawthorn.email>
* YJIT: use shorter encoding for mov(r64,imm) when unambiguous (#5081)Alan Wu2021-11-051-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | | * YJIT: use shorter encoding for mov(r64,imm) when unambiguous Previously, for small constants such as `mov(RAX, imm_opnd(Qundef))`, we emit an instruction with an 8-byte immediate. This form commonly gets the `movabs` mnemonic. In 64-bit mode, 32-bit operands get zero extended to 64-bit to fill the register, so when the immediate is small enough, we can save 4 bytes by using the `mov` variant that takes a 32-bit immediate and does a zero extension. Not implement with this change, there is an imm32 variant of `mov` that does sign extension we could use. When the constant is negative, we fallback to the `movabs` form. In railsbench, this change yields roughly a 12% code size reduction for the outlined block. Co-authored-by: Jemma Issroff <jemmaissroff@gmail.com> * [ci skip] comment edit. Please squash. Co-authored-by: Jemma Issroff <jemmaissroff@gmail.com>
* YJIT code pages refactoring for code GC (#5073)Maxime Chevalier-Boisvert2021-11-041-4/+0
| | | | | | | | | | | | | | | * New code page allocation logic * Fix leaked globals * Fix leaked symbols, yjit asm tests * Make COUNTED_EXIT take a jit argument, so we can eliminate global ocb * Remove extra whitespace * Change block start_pos/end_pos to be pointers instead of uint32_t * Change branch end_pos and start_pos to end_addr, start_addr