Граф коммитов

1077 Коммитов

Автор SHA1 Сообщение Дата
Jemma Issroff 9c5e3671eb
Increment max_iv_count on class based on number of set_iv in initialize (#6788)
We can loosely predict the number of ivar sets on a class based on the
number of iv set instructions in the initialize method. This should give
us a more accurate estimate to use for initial size pool allocation,
which should in turn give us more cache hits.
2022-11-22 15:28:14 -05:00
Peter Zhu 648927d71b Refactor obj_ivar_set and vm_setivar
obj_ivar_set and vm_setivar_slowpath is essentially doing the same thing,
but the code is duplicated and not quite implemented in the same way,
which could cause bugs. This commit refactors vm_setivar_slowpath to use
obj_ivar_set.
2022-11-21 09:58:53 -05:00
S-H-GAMELINKS 1f4f6c9832 Using UNDEF_P macro 2022-11-16 18:58:33 +09:00
Jemma Issroff c726c48a3d Remove numiv from RObject
Since object shapes store the capacity of an object, we no longer
need the numiv field on RObjects. This gives us one extra slot which
we can use to give embedded objects one more instance variable (for a
total of 3 ivs). This commit removes the concept of numiv from RObject.
2022-11-10 10:11:34 -05:00
Jemma Issroff 5246f4027e Transition shape when object's capacity changes
This commit adds a `capacity` field to shapes, and adds shape
transitions whenever an object's capacity changes. Objects which are
allocated out of a bigger size pool will also make a transition from the
root shape to the shape with the correct capacity for their size pool
when they are allocated.

This commit will allow us to remove numiv from objects completely, and
will also mean we can guarantee that if two objects share shapes, their
IVs are in the same positions (an embedded and extended object cannot
share shapes). This will enable us to implement ivar sets in YJIT using
object shapes.

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
2022-11-10 10:11:34 -05:00
John Hawthorn 02f1554224
Implement object shapes for T_CLASS and T_MODULE (#6637)
* Avoid RCLASS_IV_TBL in marshal.c
* Avoid RCLASS_IV_TBL for class names
* Avoid RCLASS_IV_TBL for autoload
* Avoid RCLASS_IV_TBL for class variables
* Avoid copying RCLASS_IV_TBL onto ICLASSes
* Use object shapes for Class and Module IVs
2022-10-31 14:05:37 -07:00
Koichi Sasada e35c528d72 push dummy frame for loading process
This patch pushes dummy frames when loading code for the
profiling purpose.

The following methods push a dummy frame:
* `Kernel#require`
* `Kernel#load`
* `RubyVM::InstructionSequence.compile_file`
* `RubyVM::InstructionSequence.load_from_binary`

https://bugs.ruby-lang.org/issues/18559
2022-10-20 17:38:28 +09:00
Aaron Patterson f0654b1027 More precisely iterate over Object instance variables
Shapes provides us with an (almost) exact count of instance variables.
We only need to check for Qundef when an IV has been "undefined"
Prefer to use ROBJECT_IV_COUNT when iterating IVs
2022-10-15 10:44:10 -07:00
Nobuyoshi Nakada b55e3b842a Initialize shape attr index also in non-markable CC 2022-10-12 09:14:55 -07:00
Nobuyoshi Nakada 70bc8cc6c2
Adjust indents [ci skip] 2022-10-12 22:22:04 +09:00
Yusuke Endoh 7a9f865a1d Do not read cached_id from callcache on stack
The inline cache is initialized by vm_cc_attr_index_set only when
vm_cc_markable(cc). However, vm_getivar attempted to read the cache
even if the cc is not vm_cc_markable.

This caused a condition that depends on uninitialized value.
Here is an output of valgrind:

```
==10483== Conditional jump or move depends on uninitialised value(s)
==10483==    at 0x4C1D60: vm_getivar (vm_insnhelper.c:1171)
==10483==    by 0x4C1D60: vm_call_ivar (vm_insnhelper.c:3257)
==10483==    by 0x4E8E48: vm_call_symbol (vm_insnhelper.c:3481)
==10483==    by 0x4EAD8C: vm_sendish (vm_insnhelper.c:5035)
==10483==    by 0x4C62B2: vm_exec_core (insns.def:820)
==10483==    by 0x4DD519: rb_vm_exec (vm.c:0)
==10483==    by 0x4F00B3: invoke_block (vm.c:1417)
==10483==    by 0x4F00B3: invoke_iseq_block_from_c (vm.c:1473)
==10483==    by 0x4F00B3: invoke_block_from_c_bh (vm.c:1491)
==10483==    by 0x4D42B6: rb_yield (vm_eval.c:0)
==10483==    by 0x259128: rb_ary_each (array.c:2733)
==10483==    by 0x4E8730: vm_call_cfunc_with_frame (vm_insnhelper.c:3227)
==10483==    by 0x4EAD8C: vm_sendish (vm_insnhelper.c:5035)
==10483==    by 0x4C6254: vm_exec_core (insns.def:801)
==10483==    by 0x4DD519: rb_vm_exec (vm.c:0)
==10483==
```

In fact, the CI on FreeBSD 12 started failing since ad63b668e2.

```
gmake[1]: Entering directory '/usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby'
/usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:924:in `complete': undefined method `complete' for nil:NilClass (NoMethodError)
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1816:in `block in visit'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1815:in `reverse_each'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1815:in `visit'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1847:in `block in complete'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1846:in `catch'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1846:in `complete'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1640:in `block in parse_in_order'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1632:in `catch'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1632:in `parse_in_order'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1626:in `order!'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1732:in `permute!'
	from /usr/home/chkbuild/chkbuild/tmp/build/20221011T163003Z/ruby/lib/optparse.rb:1757:in `parse!'
	from ./ext/extmk.rb:359:in `parse_args'
	from ./ext/extmk.rb:396:in `<main>'
```

This change adds a guard to read the cache only when vm_cc_markable(cc).
It might be better to initialize the cache as INVALID_SHAPE_ID when the
cc is not vm_cc_markable.
2022-10-12 20:28:24 +09:00
Jemma Issroff 913979bede
Make inline cache reads / writes atomic with object shapes
Prior to this commit, we were reading and writing ivar index and
shape ID in inline caches in two separate instructions when
getting and setting ivars. This meant there was a race condition
with ractors and these caches where one ractor could change
a value in the cache while another was still reading from it.

This commit instead reads and writes shape ID and ivar index to
inline caches atomically so there is no longer a race condition.

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
Co-Authored-By: John Hawthorn <john@hawthorn.email>
2022-10-11 08:40:56 -07:00
Jemma Issroff ad63b668e2
Revert "Revert "This commit implements the Object Shapes technique in CRuby.""
This reverts commit 9a6803c90b.
2022-10-11 08:40:56 -07:00
Nobuyoshi Nakada 56f2fd3bc9
Use the dedicated function to check arity 2022-10-01 16:24:36 +09:00
Nobuyoshi Nakada 27adf5321e
Add macros for assertions 2022-10-01 15:58:47 +09:00
Aaron Patterson 9a6803c90b
Revert "This commit implements the Object Shapes technique in CRuby."
This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
2022-09-30 16:01:50 -07:00
Jemma Issroff 850cfb021e Only assert ractor_shareable is consistent on ivar_set for T_OBJECT
Before d594a5a8bd, we were only
asserting that the value on an ivar_get was ractor_sharable if the
object was a T_OBJECT and also ractor shareable. We should still
be doing this check only if the object is a T_OBJECT and ractor
shareable
2022-09-30 12:41:12 -07:00
Jemma Issroff d594a5a8bd
This commit implements the Object Shapes technique in CRuby.
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>
2022-09-28 08:26:21 -07:00
Aaron Patterson 06abfa5be6
Revert this until we can figure out WB issues or remove shapes from GC
Revert "* expand tabs. [ci skip]"

This reverts commit 830b5b5c35.

Revert "This commit implements the Object Shapes technique in CRuby."

This reverts commit 9ddfd2ca00.
2022-09-26 16:10:11 -07:00
Jemma Issroff 9ddfd2ca00 This commit implements the Object Shapes technique in CRuby.
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>
2022-09-26 09:21:30 -07:00
卜部昌平 4e64edb6cd vm_method_cfunc_is: get rid of ANYARGS
ANYARGS-ed function prototypes are basically prohibited in C23.
Use __attribute__((__transparent_union__)) instead.
2022-09-21 11:44:09 +09:00
卜部昌平 8a577cbc63 cref_replace_with_duplicated_cref_each_frame: returns a pointer
Why use FALSE here?
2022-09-21 11:44:09 +09:00
卜部昌平 06cb030516 vm_insnhelper.c: add casts
Why they have not been at the first place?  Siblings have proper casts.
2022-09-21 11:44:09 +09:00
Jean Boussier b7fa78b0f3 vm_objtostring: skip method lookup for T_STRING receivers
We don't need it, and in string interpolation context
that's the common case.
2022-09-08 15:02:21 +02:00
John Hawthorn 679ef34586 New constant caching insn: opt_getconstant_path
Previously YARV bytecode implemented constant caching by having a pair
of instructions, opt_getinlinecache and opt_setinlinecache, wrapping a
series of getconstant calls (with putobject providing supporting
arguments).

This commit replaces that pattern with a new instruction,
opt_getconstant_path, handling both getting/setting the inline cache and
fetching the constant on a cache miss.

This is implemented by storing the full constant path as a
null-terminated array of IDs inside of the IC structure. idNULL is used
to signal an absolute constant reference.

    $ ./miniruby --dump=insns -e '::Foo::Bar::Baz'
    == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,13)> (catch: FALSE)
    0000 opt_getconstant_path                   <ic:0 ::Foo::Bar::Baz>      (   1)[Li]
    0002 leave

The motivation for this is that we had increasingly found the need to
disassemble the instructions between the opt_getinlinecache and
opt_setinlinecache in order to determine the constant we are fetching,
or otherwise store metadata.

This disassembly was done:
* In opt_setinlinecache, to register the IC against the constant names
  it is using for granular invalidation.
* In rb_iseq_free, to unregister the IC from the invalidation table.
* In YJIT to find the position of a opt_getinlinecache instruction to
  invalidate it when the cache is populated
* In YJIT to register the constant names being used for invalidation.

With this change we no longe need disassemly for these (in fact
rb_iseq_each is now unused), as the list of constant names being
referenced is held in the IC. This should also make it possible to make
more optimizations in the future.

This may also reduce the size of iseqs, as previously each segment
required 32 bytes (on 64-bit platforms) for each constant segment. This
implementation only stores one ID per-segment.

There should be no significant performance change between this and the
previous implementation. Previously opt_getinlinecache was a "leaf"
instruction, but it included a jump (almost always to a separate cache
line). Now opt_getconstant_path is a non-leaf (it may
raise/autoload/call const_missing) but it does not jump. These seem to
even out.
2022-09-01 15:20:49 -07:00
Maple Ong 5a76a15a0f
YJIT: Implement concatarray in yjit (https://github.com/Shopify/ruby/pull/405)
* Create code generation func

* Make rb_vm_concat_array available to use in Rust

* Map opcode to code gen func

* Implement code gen for concatarray

* Add test for concatarray

* Use new asm backend

* Add comment to C func wrapper
2022-08-29 08:47:11 -07:00
Jean Boussier b2d0f78869 Fix private methods reported as protected when called via Symbol#to_proc
Ref: bfa6a8ddc8
Ref: [Bug #18826]
2022-08-25 17:49:50 +02:00
Takashi Kokubun 485019c2bd
Rename mjit_exec to jit_exec (#6262)
* Rename mjit_exec to jit_exec

* Rename mjit_exec_slowpath to mjit_check_iseq

* Remove mjit_exec references from comments
2022-08-19 23:57:17 -07:00
S-H-GAMELINKS f095361758 Repalce to NIL_P macro 2022-08-19 09:47:43 +09:00
Jeremy Evans bfa6a8ddc8
Only allow procs created by Symbol#to_proc to call public methods
Fixes [Bug #18826]

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2022-08-10 13:02:19 -07:00
John Hawthorn 70b60d24b9 Fix inconsistency with opt_aref_with
opt_aref_with is an optimized instruction for accessing a Hash using a
non-frozen string key (ie. from a file without frozen_string_literal).
It attempts to avoid allocating the string, and instead silently using a
frozen string (hash string keys are always fstrings).

Because this is just an optimization, it should be invisible to the
user. However, previously this optimization was could be seen via hashes
with default procs.

For example, previously:

    h = Hash.new { |h, k| k.frozen? }
    str = "foo"
    h[str]   # false
    h["foo"] # true when optimizations enabled

This commit checks that the Hash doesn't have a default proc when using
opt_aref_with.
2022-08-04 14:48:47 -07:00
Nobuyoshi Nakada f42230ff22
Adjust styles [ci skip] 2022-07-27 18:42:27 +09:00
Takashi Kokubun 5b21e94beb Expand tabs [ci skip]
[Misc #18891]
2022-07-21 09:42:04 -07:00
Jeremy Evans 12ac8971a3 Do not have class/module keywords look up ancestors of Object
Fixes case where Object includes a module that defines a constant,
then using class/module keyword to define the same constant on
Object itself.

Implements [Feature #18832]
2022-07-21 08:28:05 -07:00
Jemma Issroff ecff334995 Extract vm_ic_entry API to mimic vm_cc behavior 2022-07-18 12:44:01 -07:00
Jean Boussier 906f7cb3e7 vm_opt_ltlt: call rb_str_buf_append directly if RHS is a String
`rb_str_concat` does a lot of type checking we can easily bypass.

```

|               |compare-ruby|built-ruby|
|:--------------|-----------:|---------:|
|string_concat  |    362.007k|  398.965k|
|               |           -|     1.10x|
```
2022-07-06 17:25:58 +02:00
Nobuyoshi Nakada c617495f8e
Fix empty call cache check for debug counter 2022-07-03 00:05:53 +09:00
Dave Schwantes b6f6fc6e87
YJIT: Refactor gen_opt_mod (#6078)
Refactor gen_opt_mod in YJIT
2022-06-30 10:26:46 -04:00
John Hawthorn 9312f4bf62 Allow method caching of protected FCALLs 2022-06-21 18:33:51 -07:00
John Hawthorn a580dd7737 Don't check protected method ancestry on fcall
If we are making an FCALL, we know we are calling a method on self. This
is the same check made for private method visibility, so it should also
guarantee we can call a protected method.
2022-06-21 18:33:51 -07:00
John Hawthorn ae163cae6b Allow calling protected methods from refinements
Previously protected methods on refinements could never be called
because they were seen as being "defined" on the hidden refinement
ICLASS.

This commit updates calling refined protected methods so that they are
considered to be defined on the original class (the one being refined).

This ended up using the same behaviour that was used to check whether a
call to super was allowed, so I extracted that into a method.

[Bug #18806]
2022-06-16 13:24:48 -07:00
Alan Wu a687756284 Fix use-after-free with interacting TracePoints
`vm_trace_hook()` runs global hooks before running local hooks.
Previously, we read the local hook list before running the global hooks
which led to use-after-free when a global hook frees the local hook
list. A global hook can do this by disabling a local TracePoint, for
example.

Delay local hook list loading until after running the global hooks.

Issue discovered by Jeremy Evans in GH-5862.

[Bug #18730]
2022-05-30 13:54:22 -04:00
Jemma Issroff 80ad0e751f Remove unnecessary module flag, add module assertions to other module flags 2022-05-23 11:04:34 -07:00
Alan Wu f90549cd38 Rust YJIT
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:
1fd9573d8b

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>
2022-04-27 11:00:22 -04:00
Koichi Sasada 798e21637f sync `vm->constant_cache`
On multi-ractors, `vm->constant_cache` (and so on) can be accessed
in parallel so we need to synchronize the accesses to them.

http://rubyci.s3.amazonaws.com/centos7/ruby-master/log/20220407T213003Z.log.html.gz#btest
2022-04-08 13:31:28 +09:00
Alan Wu 16e08d53a0 Fix strict aliasing issue
`rb_id_table_lookup()` writes to a `VALUE`, which is definitely a distinct
type from `st_table *`. With LTO, the compiler is allowed by N1256
§6.5p7 to remove the output parameter write via type-based alias
analysis.

See also: a0a8f2abf5
2022-04-07 12:49:28 -04:00
Kevin Newton 6068da8937 Finer-grained constant cache invalidation (take 2)
This commit reintroduces finer-grained constant cache invalidation.
After 8008fb7 got merged, it was causing issues on token-threaded
builds (such as on Windows).

The issue was that when you're iterating through instruction sequences
and using the translator functions to get back the instruction structs,
you're either using `rb_vm_insn_null_translator` or
`rb_vm_insn_addr2insn2` depending if it's a direct-threading build.
`rb_vm_insn_addr2insn2` does some normalization to always return to
you the non-trace version of whatever instruction you're looking at.
`rb_vm_insn_null_translator` does not do that normalization.

This means that when you're looping through the instructions if you're
trying to do an opcode comparison, it can change depending on the type
of threading that you're using. This can be very confusing. So, this
commit creates a new translator function
`rb_vm_insn_normalizing_translator` to always return the non-trace
version so that opcode comparisons don't have to worry about different
configurations.

[Feature #18589]
2022-04-01 14:48:22 -04:00
Nobuyoshi Nakada 69967ee64e
Revert "Finer-grained inline constant cache invalidation"
This reverts commits for [Feature #18589]:
* 8008fb7352
  "Update formatting per feedback"
* 8f6eaca2e1
  "Delete ID from constant cache table if it becomes empty on ISEQ free"
* 629908586b
  "Finer-grained inline constant cache invalidation"

MSWin builds on AppVeyor have been crashing since the merger.
2022-03-25 20:29:09 +09:00
Kevin Newton 629908586b Finer-grained inline constant cache invalidation
Current behavior - caches depend on a global counter. All constant mutations cause caches to be invalidated.

```ruby
class A
  B = 1
end

def foo
  A::B # inline cache depends on global counter
end

foo # populate inline cache
foo # hit inline cache

C = 1 # global counter increments, all caches are invalidated

foo # misses inline cache due to `C = 1`
```

Proposed behavior - caches depend on name components. Only constant mutations with corresponding names will invalidate the cache.

```ruby
class A
  B = 1
end

def foo
  A::B # inline cache depends constants named "A" and "B"
end

foo # populate inline cache
foo # hit inline cache

C = 1 # caches that depend on the name "C" are invalidated

foo # hits inline cache because IC only depends on "A" and "B"
```

Examples of breaking the new cache:

```ruby
module C
  # Breaks `foo` cache because "A" constant is set and the cache in foo depends
  # on "A" and "B"
  class A; end
end

B = 1
```

We expect the new cache scheme to be invalidated less often because names aren't frequently reused. With the cache being invalidated less, we can rely on its stability more to keep our constant references fast and reduce the need to throw away generated code in YJIT.
2022-03-24 09:14:38 -07:00
Peter Zhu 5f10bd634f Add ISEQ_BODY macro
Use ISEQ_BODY macro to get the rb_iseq_constant_body of the ISeq. Using
this macro will make it easier for us to change the allocation strategy
of rb_iseq_constant_body when using Variable Width Allocation.
2022-03-24 10:03:51 -04:00