to adopt strict shareable rule.
* (basically) shareable objects only refer shareable objects
* (exception) shareable objects can refere unshareable objects
but should not leak reference to unshareable objects to Ruby world
* `RB_OBJ_SET_SHAREABLE(obj)` makes obj shareable.
All of reachable objects from `obj` should be shareable.
* `RB_OBJ_SET_FROZEN_SHAREABLE(obj)` same as above
but freeze `obj` before making it shareable.
Also `rb_gc_verify_shareable(obj)` is introduced to check
the `obj` does not violate shareable rule (an shareable object
only refers shareable objects) strictly.
The rule has some exceptions (some shareable objects can refer to
unshareable objects, such as a Ractor object (which is a shareable
object) can refer to the Ractor local objects.
To handle such case, `check_shareable` flag is also introduced.
`STRICT_VERIFY_SHAREABLE` macro is also introduced to verify
the strict shareable rule at `SET_SHAREABLE`.
https://github.com/Shopify/ruby/issues/649
Class vars are a bit more involved than ivars, since we need to get the
class from the cref, so this calls out to `rb_vm_getclassvariable` and
`rb_vm_setclassvariable` like YJIT.
When RUBYOPT is invalid, it raises an error which causes moreswitches
to leak memory. It can be seen when building with LSAN enabled:
$ RUBY_FREE_AT_EXIT=1 RUBYOPT=f ruby
ruby: invalid option -f (-h will show valid options) (RuntimeError)
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x618cef8efa23 in malloc (miniruby+0x64a23)
#1 0x618cefa0e8d8 in rb_gc_impl_malloc gc/default/default.c:8182:5
#2 0x618cef9f7f01 in ruby_xmalloc2_body gc.c:5182:12
#3 0x618cef9f7eac in ruby_xmalloc2 gc.c:5176:34
#4 0x618cefb547b2 in moreswitches ruby.c:919:18
#5 0x618cefb526fe in process_options ruby.c:2350:9
#6 0x618cefb524ac in ruby_process_options ruby.c:3202:12
#7 0x618cef9dc11f in ruby_options eval.c:119:16
#8 0x618cef8f2fb5 in rb_main main.c:42:26
#9 0x618cef8f2f59 in main main.c:62:12
Previously, when the output register and the base register are the same
in `out = Lea(Mem(out, disp))`, we did
out = disp
out = out + out
Which wasn't the desired `out = out + disp`.
Fixes a SEGV with `--zjit-call-threshold=2` in
`bootstraptest/test_yjit.rb`.
This one has been on my mind for a while now.
Currently, there are only tests against the latest syntax version.
This changes the snapshot structure as follows:
* Snapshots at their current location are tested against all syntax versions
* Snapshots inside a version folder like "3.3" are tested against all versions starting from that version
* Snapshots inside a version folder like "3.3-4.2" are tested against all versions in the given range.
This makes sure that as new syntax is added, older versions still work as expected.
I also added a few tests for now valid syntax that should be invalid in older versions (and the other way around as well)
These tests run really fast. So even though it does 3x the work for these, I am still able to run the whole test suite in just 11 seconds.
https://github.com/ruby/prism/commit/5191b1aa68
The st_insert in RCLASS_SET_NAMESPACE_CLASSEXT may overwrite an existing
rb_classext_t, causing it to leak memory. This commit changes it to use
st_update to free the existing one before overwriting it.
```
/src/jit.c:19:5: error: ISO C restricts enumerator values to range of 'int' (4294967295 is too large) [-Werror,-Wpedantic]
19 | RB_INVALID_SHAPE_ID = INVALID_SHAPE_ID,
| ^ ~~~~~~~~~~~~~~~~
```
This guide is for those that want to contribute to ruby but don't
understand where they need to use locks or other concurrency mechanisms.
It teaches them how to use these locks safely and what is prohibited in
certain circumstances.