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

644 Коммитов

Автор SHA1 Сообщение Дата
Nobuyoshi Nakada 1e3fa634f7
Explicitly cast to uint32_t and suppress warnings by VC
```
../src/variable.c(1440): warning C4244: 'initializing': conversion from 'double' to 'uint32_t', possible loss of data
242
../src/variable.c(1470): warning C4244: 'initializing': conversion from 'double' to 'uint32_t', possible loss of data
243
```

TODO: check for `newsize` overflow
2022-10-16 00:26:51 +09:00
Aaron Patterson 1acc1a5c6d YJIT doesn't need rb_obj_ensure_iv_index_mapping
We should make this function static and remove it from YJIT bindings.
2022-10-14 17:14:41 -07: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
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
git 414f1066b1 * expand tabs. [ci skip]
Tabs were expanded because the file did not have any tab indentation in unedited lines.
Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook.
2022-09-29 00:27:12 +09: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
git 830b5b5c35 * expand tabs. [ci skip]
Tabs were expanded because the file did not have any tab indentation in unedited lines.
Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook.
2022-09-27 01:21:58 +09: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
S-H-GAMELINKS f095361758 Repalce to NIL_P macro 2022-08-19 09:47:43 +09:00
Takashi Kokubun 5b21e94beb Expand tabs [ci skip]
[Misc #18891]
2022-07-21 09:42:04 -07:00
Peter Zhu 7424ea184f Implement Objects on VWA
This commit implements Objects on Variable Width Allocation. This allows
Objects with more ivars to be embedded (i.e. contents directly follow the
object header) which improves performance through better cache locality.
2022-07-15 09:21:07 -04:00
Nobuyoshi Nakada 2361a1a53e
Get rid of a nasal demon
On platforms not having `typeof`, `ccan_container_off_var()` macro
subtracts the pointer variable from the member address pointed by that
variable.
2022-06-23 16:42:57 +09:00
Jean Boussier eca31d24d6 [Bug #18813] Warn when autoload has to lookup in parent namespace
This is a verbose mode only warning.
2022-06-18 14:49:02 +02:00
Jeremy Evans c85d1cda86 Fix Module#const_source_location for autoload constants with direct requires
If an autoload exists for a constant, but the path for the autoload
was required, const_source_location would return [false, 0] instead
of the actual file and line. This fixes it by setting the appropriate
file and line in rb_const_set, and saving the file and line in
const_tbl_update before they get reset by current_autoload_data.

Fixes [Bug #18624]
2022-06-06 11:12:55 -07:00
Samuel Williams 946e3bbdc2 Simplify the autoload require logic. 2022-05-26 14:20:59 +12:00
Samuel Williams d875445e8a Fix GC race condition in autoload. 2022-05-26 00:17:30 +12:00
Samuel Williams 9a8fc4e04c Tidy up redundant returns. 2022-05-25 15:24:24 +12:00
Samuel Williams 42bcc629fb Retain reference to blocking fibers. 2022-05-25 15:24:24 +12:00
Nobuyoshi Nakada 72fc3b1bbb
Fold too long lines, etc [ci skip] 2022-05-19 16:46:08 +09:00
Nobuyoshi Nakada a72529182d
Suppress unused-function [ci skip] 2022-05-19 16:46:08 +09:00
Samuel Williams 11af23ee92
Move feature deletion from GC mark to `autoload_delete`. (#5912) 2022-05-17 23:44:14 +12:00
Samuel Williams 60d45b2ee8
Restore implicit relationship between `autoload_const` and `autoload_data` during GC. (#5911) 2022-05-17 19:12:36 +12:00
Nobuyoshi Nakada 8a907da0f6
Suppress an unused-but-set-variable warning [ci skip] 2022-05-17 13:55:56 +09:00
Samuel Williams f626998c4f
Delete autoload data from global features after autoload has completed. (#5910)
* Update naming of critical section assertions macros.

* Improved locking for autoload.
2022-05-17 00:50:02 +12:00
Samuel Williams 32de6097b2
Fix various autoload race conditions. (#5898)
* Add RUBY_VM_CRITICAL_SECTION for detecting unexpected context switch.

* Prevent race between GC mark and autoload setup.

* Protect race on autoload state.

* Avoid potential race condition when allocating `autoload_featuremap`.

* Add NEWS entry for autoload fixes.
2022-05-15 16:07:12 +12:00
Samuel Williams fd6cef79f5
Use a proper mutex for autoloading features. (#5788)
Object#autoload implements a custom per-thread "mutex" for blocking
threads waiting on autoloading a feature. This causes problems when used
with the fiber scheduler. We swap the implementation to use a Ruby mutex
which is fiber aware.
2022-05-08 10:22:58 +12:00
Koichi Sasada c77a31df5e call `const_added` after `autoload`
When calling `const_added` while process in `autoload`, it can
cause synchronization issue because of a thread swithcing.

http://ci.rvm.jp/logfiles/brlog.trunk.20220407-152213#L489

```
1)
Module#autoload (concurrently) raises a LoadError in each thread if the file does not exist ERROR
NameError: uninitialized constant ModuleSpecs::Autoload::FileDoesNotExist

            ModuleSpecs::Autoload::FileDoesNotExist
                                 ^^^^^^^^^^^^^^^^^^
/tmp/ruby/v3/src/trunk/spec/ruby/core/module/autoload_spec.rb:965:in `block (5 levels) in <top (required)>'
```
2022-04-08 21:30:32 +09: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 42a0bed351
Prefix ccan headers (#4568)
* Prefixed ccan headers

* Remove unprefixed names in ccan/build_assert

* Remove unprefixed names in ccan/check_type

* Remove unprefixed names in ccan/container_of

* Remove unprefixed names in ccan/list

Co-authored-by: Samuel Williams <samuel.williams@oriontransfer.co.nz>
2022-03-30 20:36:31 +13: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
Jean Boussier 82539a3d13 variable.c: Fix incorrect identation in `const_added` 2022-01-14 16:22:57 +01:00
Jean Boussier 8d05047d72 Add a Module#const_added callback
[Feature #17881]

Works similarly to `method_added` but for constants.

```ruby
Foo::BAR = 42 # call Foo.const_added(:FOO)
class Foo::Baz; end # call Foo.const_added(:Baz)
Foo.autoload(:Something, "path") # call Foo.const_added(:Something)
```
2022-01-14 11:30:07 +01:00
Kazuhiro NISHIYAMA 04f07713d1
Fix typos [ci skip] 2021-12-25 10:33:49 +09:00
Koichi Sasada 397a509b6d prohibit load by `autoload` on non-main Ractor
fix [Bug #18120]
2021-12-15 02:33:17 +09:00
Koichi Sasada acb23454e5 allow to access ivars of classes/modules
if an ivar of a class/module refer to a shareable object, this ivar
can be read from non-main Ractors.
2021-10-23 01:32:55 +09:00
Alan Wu b74d6563a6 Extract yjit_force_iv_index and make it work when object is frozen
In an effort to simplify the logic YJIT generates for accessing instance
variable, YJIT ensures that a given name-to-index mapping exists at
compile time. In the case that the mapping doesn't exist, it was created
by using rb_ivar_set() with Qundef on the sample object we see at
compile time. This hack isn't fine if the sample object happens to be
frozen, in which case YJIT would raise a FrozenError unexpectedly.

To deal with this, make a new function that only reserves the mapping
but doesn't touch the object. This is rb_obj_ensure_iv_index_mapping().
This new function superceeds the functionality of rb_iv_index_tbl_lookup()
so it was removed.

Reported by and includes a test case from John Hawthorn <john@hawthorn.email>

Fixes: GH-282
2021-10-20 18:19:43 -04:00
Jeremy Evans 08759edea8
Remove autoload for constant if the autoload fails
Previously, if an autoload failed (the file was loaded, but the
constant was not defined by the autoloaded file). Ruby will try
to autoload again if you delete the autoloaded file from
$LOADED_FEATURES.  With this change, the autoload and the
constant itself are removed as soon as it fails.

To handle cases where multiple threads are autoloading, when
deleting an autoload, handle the case where another thread
already deleted it.

Fixes [Bug #15790]
2021-10-08 14:54:26 -07:00
S-H-GAMELINKS 323e7a6744 Merge if statement 2021-10-07 19:18:46 +13:00
Samuel Williams 9151ed2fb2 Return fstrings from `build_const_pathname`.
It's possible for `build_const_pathname` to be called when `rb_cString` is
still NULL. There is a fix-up step when `rb_cString` is initialized, but
it only applies to `fstring` instances.
2021-09-25 18:19:20 +12:00
S.H b8c3a84bdd
Refactor and Using RBOOL macro 2021-09-15 08:11:05 +09:00
Alan Wu 3dd3ea092a Use Module#ancestors order in recursive constant lookup
Before this commit, const_get with inherit=true and constant lookup
expressions searched the ancestors of the starting point in an order
different from `starting_point.ancestors`.

Items in the ancestry list introduced through prepend were searched
after searching the module they were prepended into. This oddity allowed
for situations where constant lookups gave different results even though
`starting_point.ancestors` is the same.

Do the lookup in the same order as `starting_point.ancestors` by
skipping classes and modules that have an origin iclass. The origin
iclass is in the super chain after the prepended modules.

Note that just like before this commit, the starting point of the
constant lookup is always the first item that we search, regardless of
the presence of any prepended modules.

[Bug #17887]
2021-06-30 10:49:27 +09:00
Nobuyoshi Nakada def7b3ee09
Get rid of pointer casting 2021-06-23 10:55:23 +09:00
Nobuyoshi Nakada 0700ee0e94
Refactor class variable cache functions
Extracted repeated code as update_classvariable_cache.  When cvc
table is not set in getclassvariable, an empty table was created
but it has no id and would cause [BUG], so made the code same as
setclassvariable.
2021-06-23 10:55:22 +09:00
eileencodes b91b3bc771 Add a cache for class variables
Redo of 34a2acdac788602c14bf05fb616215187badd504 and
931138b00696419945dc03e10f033b1f53cd50f3 which were reverted.

GitHub PR #4340.

This change implements a cache for class variables. Previously there was
no cache for cvars. Cvar access is slow due to needing to travel all the
way up th ancestor tree before returning the cvar value. The deeper the
ancestor tree the slower cvar access will be.

The benefits of the cache are more visible with a higher number of
included modules due to the way Ruby looks up class variables. The
benchmark here includes 26 modules and shows with the cache, this branch
is 6.5x faster when accessing class variables.

```
compare-ruby: ruby 3.1.0dev (2021-03-15T06:22:34Z master 9e5105c) [x86_64-darwin19]
built-ruby: ruby 3.1.0dev (2021-03-15T12:12:44Z add-cache-for-clas.. c6be009) [x86_64-darwin19]

|         |compare-ruby|built-ruby|
|:--------|-----------:|---------:|
|vm_cvar  |      5.681M|   36.980M|
|         |           -|     6.51x|
```

Benchmark.ips calling `ActiveRecord::Base.logger` from within a Rails
application. ActiveRecord::Base.logger has 71 ancestors. The more
ancestors a tree has, the more clear the speed increase. IE if Base had
only one ancestor we'd see no improvement. This benchmark is run on a
vanilla Rails application.

Benchmark code:

```ruby
require "benchmark/ips"
require_relative "config/environment"

Benchmark.ips do |x|
  x.report "logger" do
    ActiveRecord::Base.logger
  end
end
```

Ruby 3.0 master / Rails 6.1:

```
Warming up --------------------------------------
              logger   155.251k i/100ms
Calculating -------------------------------------
```

Ruby 3.0 with cvar cache /  Rails 6.1:

```
Warming up --------------------------------------
              logger     1.546M i/100ms
Calculating -------------------------------------
              logger     14.857M (± 4.8%) i/s -     74.198M in   5.006202s
```

Lastly we ran a benchmark to demonstate the difference between master
and our cache when the number of modules increases. This benchmark
measures 1 ancestor, 30 ancestors, and 100 ancestors.

Ruby 3.0 master:

```
Warming up --------------------------------------
            1 module     1.231M i/100ms
          30 modules   432.020k i/100ms
         100 modules   145.399k i/100ms
Calculating -------------------------------------
            1 module     12.210M (± 2.1%) i/s -     61.553M in   5.043400s
          30 modules      4.354M (± 2.7%) i/s -     22.033M in   5.063839s
         100 modules      1.434M (± 2.9%) i/s -      7.270M in   5.072531s

Comparison:
            1 module: 12209958.3 i/s
          30 modules:  4354217.8 i/s - 2.80x  (± 0.00) slower
         100 modules:  1434447.3 i/s - 8.51x  (± 0.00) slower
```

Ruby 3.0 with cvar cache:

```
Warming up --------------------------------------
            1 module     1.641M i/100ms
          30 modules     1.655M i/100ms
         100 modules     1.620M i/100ms
Calculating -------------------------------------
            1 module     16.279M (± 3.8%) i/s -     82.038M in   5.046923s
          30 modules     15.891M (± 3.9%) i/s -     79.459M in   5.007958s
         100 modules     16.087M (± 3.6%) i/s -     81.005M in   5.041931s

Comparison:
            1 module: 16279458.0 i/s
         100 modules: 16087484.6 i/s - same-ish: difference falls within error
          30 modules: 15891406.2 i/s - same-ish: difference falls within error
```

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2021-06-18 10:02:44 -07:00
Nobuyoshi Nakada e4f891ce8d
Adjust styles [ci skip]
* --braces-after-func-def-line
* --dont-cuddle-else
* --procnames-start-lines
* --space-after-for
* --space-after-if
* --space-after-while
2021-06-17 10:13:40 +09:00
S.H a2cf0607b0
Refactor rb_class_path_cached function (#4485) 2021-06-01 00:34:56 -07:00
S.H 1055b37ef5
Refactor rb_define_class_variable function (#4492) 2021-06-01 00:32:24 -07:00
Aaron Patterson 07f055bb13
Revert "Filling cache values on cvar write"
This reverts commit 08de37f9fa.
This reverts commit e8ae922b62.
2021-05-11 13:31:00 -07:00
eileencodes 08de37f9fa Filling cache values on cvar write
Instead of on read. Once it's in the inline cache we never have to make
one again. We want to eventually put the value into the cache, and the
best opportunity to do that is when you write the value.
2021-05-11 12:04:27 -07:00
eileencodes e8ae922b62 Add a cache for class variables
This change implements a cache for class variables. Previously there was
no cache for cvars. Cvar access is slow due to needing to travel all the
way up th ancestor tree before returning the cvar value. The deeper the
ancestor tree the slower cvar access will be.

The benefits of the cache are more visible with a higher number of
included modules due to the way Ruby looks up class variables. The
benchmark here includes 26 modules and shows with the cache, this branch
is 6.5x faster when accessing class variables.

```
compare-ruby: ruby 3.1.0dev (2021-03-15T06:22:34Z master 9e5105ca45) [x86_64-darwin19]
built-ruby: ruby 3.1.0dev (2021-03-15T12:12:44Z add-cache-for-clas.. c6be0093ae) [x86_64-darwin19]

|         |compare-ruby|built-ruby|
|:--------|-----------:|---------:|
|vm_cvar  |      5.681M|   36.980M|
|         |           -|     6.51x|
```

Benchmark.ips calling `ActiveRecord::Base.logger` from within a Rails
application. ActiveRecord::Base.logger has 71 ancestors. The more
ancestors a tree has, the more clear the speed increase. IE if Base had
only one ancestor we'd see no improvement. This benchmark is run on a
vanilla Rails application.

Benchmark code:

```ruby
require "benchmark/ips"
require_relative "config/environment"

Benchmark.ips do |x|
  x.report "logger" do
    ActiveRecord::Base.logger
  end
end
```

Ruby 3.0 master / Rails 6.1:

```
Warming up --------------------------------------
              logger   155.251k i/100ms
Calculating -------------------------------------
```

Ruby 3.0 with cvar cache /  Rails 6.1:

```
Warming up --------------------------------------
              logger     1.546M i/100ms
Calculating -------------------------------------
              logger     14.857M (± 4.8%) i/s -     74.198M in   5.006202s
```

Lastly we ran a benchmark to demonstate the difference between master
and our cache when the number of modules increases. This benchmark
measures 1 ancestor, 30 ancestors, and 100 ancestors.

Ruby 3.0 master:

```
Warming up --------------------------------------
            1 module     1.231M i/100ms
          30 modules   432.020k i/100ms
         100 modules   145.399k i/100ms
Calculating -------------------------------------
            1 module     12.210M (± 2.1%) i/s -     61.553M in   5.043400s
          30 modules      4.354M (± 2.7%) i/s -     22.033M in   5.063839s
         100 modules      1.434M (± 2.9%) i/s -      7.270M in   5.072531s

Comparison:
            1 module: 12209958.3 i/s
          30 modules:  4354217.8 i/s - 2.80x  (± 0.00) slower
         100 modules:  1434447.3 i/s - 8.51x  (± 0.00) slower
```

Ruby 3.0 with cvar cache:

```
Warming up --------------------------------------
            1 module     1.641M i/100ms
          30 modules     1.655M i/100ms
         100 modules     1.620M i/100ms
Calculating -------------------------------------
            1 module     16.279M (± 3.8%) i/s -     82.038M in   5.046923s
          30 modules     15.891M (± 3.9%) i/s -     79.459M in   5.007958s
         100 modules     16.087M (± 3.6%) i/s -     81.005M in   5.041931s

Comparison:
            1 module: 16279458.0 i/s
         100 modules: 16087484.6 i/s - same-ish: difference falls within error
          30 modules: 15891406.2 i/s - same-ish: difference falls within error
```

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2021-05-11 12:04:27 -07:00
eileencodes 23a48d8fe6 Refactor `rb_class_ivar_set`
In every caller of `rb_class_ivar_set` it checks for the `RCLASS_IV_TBL`
and then creates it if it doesn't exist. Instead of repeating this in
every caller, this can be done once in `rb_class_ivar_set`.
2021-03-10 09:39:18 -08:00
Aaron Patterson 33d6e92e0c
Revert "Don't pin `val` passed in to `rb_define_const`."
I think this is breaking something

This reverts commit 1be84e53d7.
2021-02-03 12:48:37 -08:00
Aaron Patterson 1be84e53d7 Don't pin `val` passed in to `rb_define_const`.
The caller should be responsible for holding a pinned reference (if they
need that)
2021-02-03 09:35:15 -08:00
Nobuyoshi Nakada 565aeb81e0 Skip freezing check on setting temporary class path [Bug #17563]
Co-authored-by: ryannevell (Ryan Nevell) <ryan.nevell@gmail.com>
2021-01-20 19:24:16 +09:00
Gannon McGibbon 9e0075a3d9 Replace "iff" with "if and only if"
iff means if and only if, but readers without that knowledge might
assume this to be a spelling mistake. To me, this seems like
exclusionary language that is unnecessary. Simply using "if and only if"
instead should suffice.
2021-01-19 12:06:45 -08:00
Koichi Sasada dca6752fec Introduce Ractor::IsolationError
Ractor has several restrictions to keep each ractor being isolated
and some operation such as `CONST="foo"` in non-main ractor raises
an exception. This kind of operation raises an error but there is
confusion (some code raises RuntimeError and some code raises
NameError).

To make clear we introduce Ractor::IsolationError which is raised
when the isolation between ractors is violated.
2020-12-21 22:29:05 +09:00
Koichi Sasada f70b894b88 sync RCLASS_CONST_TBL()
RCLASS_CONST_TBL() is shared resource so we need to sync with
other ractors.
2020-12-20 11:46:13 +09:00
Jeremy Evans 05313c914b Use category: :deprecated in warnings that are related to deprecation
Also document that both :deprecated and :experimental are supported
:category option values.

The locations where warnings were marked as deprecation warnings
was previously reviewed by shyouhei.

Comment a couple locations where deprecation warnings should probably
be used but are not currently used because deprecation warning
enablement has not occurred at the time they are called
(RUBY_FREE_MIN, RUBY_HEAP_MIN_SLOTS, -K).

Add assert_deprecated_warn to test assertions.  Use this to simplify
some tests, and fix failing tests after marking some warnings with
deprecated category.
2020-12-18 09:54:11 -08:00
Koichi Sasada 5499651ee7 tuning ivar set
* make rb_init_iv_list() simple
* introduce vm_setivar_slowpath() for cache miss cases

../clean/miniruby is 647ee6f091.

Calculating -------------------------------------
                      ./miniruby  ../clean/miniruby  ../ruby_2_7/miniruby
         vm_ivar_init     7.388M             6.814M                5.771M i/s -     30.000M times in 4.060420s 4.402534s 5.198781s
vm_ivar_init_subclass     2.158M             2.147M                1.974M i/s -      3.000M times in 1.390328s 1.397587s 1.519951s
          vm_ivar_set   128.607M            97.931M              140.668M i/s -     30.000M times in 0.233269s 0.306338s 0.213268s
              vm_ivar   144.315M           151.722M              117.734M i/s -     30.000M times in 0.207879s 0.197730s 0.254811s

Comparison:
                      vm_ivar_init
           ./miniruby:   7388398.8 i/s
    ../clean/miniruby:   6814257.1 i/s - 1.08x  slower
 ../ruby_2_7/miniruby:   5770583.9 i/s - 1.28x  slower

             vm_ivar_init_subclass
           ./miniruby:   2157763.6 i/s
    ../clean/miniruby:   2146557.0 i/s - 1.01x  slower
 ../ruby_2_7/miniruby:   1973747.9 i/s - 1.09x  slower

                       vm_ivar_set
 ../ruby_2_7/miniruby: 140668063.8 i/s
           ./miniruby: 128606912.1 i/s - 1.09x  slower
    ../clean/miniruby:  97931027.8 i/s - 1.44x  slower

                           vm_ivar
    ../clean/miniruby: 151722121.9 i/s
           ./miniruby: 144314526.5 i/s - 1.05x  slower
 ../ruby_2_7/miniruby: 117734305.5 i/s - 1.29x  slower
2020-12-16 13:06:13 +09:00
Koichi Sasada d741c77b5f fix ivar with shareable objects issue
Instance variables of sharable objects are accessible only from
main ractor, so we need to check it correctly.
2020-12-12 06:19:18 +09:00
Jeremy Evans 01b7d5acc7 Remove the uninitialized instance variable verbose mode warning
This speeds up all instance variable access, even when not in
verbose mode.  Uninitialized instance variable warnings were
rarely helpful, and resulted in slower code if you wanted to
avoid warnings when run in verbose mode.

Implements [Feature #17055]
2020-12-10 10:16:05 -08:00
Koichi Sasada 5e3259ea74 fix public interface
To make some kind of Ractor related extensions, some functions
should be exposed.

* include/ruby/thread_native.h
  * rb_native_mutex_*
  * rb_native_cond_*
* include/ruby/ractor.h
  * RB_OBJ_SHAREABLE_P(obj)
  * rb_ractor_shareable_p(obj)
  * rb_ractor_std*()
  * rb_cRactor

and rm ractor_pub.h
and rename srcdir/ractor.h to srcdir/ractor_core.h
    (to avoid conflict with include/ruby/ractor.h)
2020-11-18 03:52:41 +09:00
Koichi Sasada b557c5768c refactoring.
iv_index_tbl_newsize() usually returns iv_index_tbl->num_entries
because ivup->iv_extended is usually false.
2020-11-10 10:44:45 +09:00
Aaron Patterson eb229994e5 eagerly initialize ivar table when index is small enough
When the inline cache is written, the iv table will contain an entry for
the instance variable.  If we get an inline cache hit, then we know the
iv table must contain a value for the index written to the inline cache.

If the index in the inline cache is larger than the list on the object,
but *smaller* than the iv index table on the class, then we can just
eagerly allocate the iv list to be the same size as the iv index table.

This avoids duplicate work of checking frozen as well as looking up the
index for the particular instance variable name.
2020-11-09 09:44:16 -08:00
Aaron Patterson 70680feeea Simplify setting instance variables
Since T_OBJECT objects come to life as embedded objects, that means that
ROBJECT_NUMIV will always return a _minimum_ of ROBJECT_EMBED_LEN_MAX.
If ivup.index is *greater* than ROBJECT_NUMIV, then we know that the
object *must not* be an embedded object. Thus we can skip the
ROBJECT_EMBED_LEN_MAX check as well as initializing internals of
embedded objects.
2020-11-04 14:40:50 -08:00
Koichi Sasada db7a3b63ba suppport Ractor.send(move: true) for more deta
This patch allows to move more data types.
2020-11-02 01:37:28 +09:00
Jeremy Evans ff2276ef8c Fix bootstrap-test error in previous commit 2020-10-25 15:56:10 -07:00
Koichi Sasada 0c0d0752f1 allow to access ivars of frozen shareable objects
Accessing a shareable object is prohibitted because it can cause
race condition, but if the shareable object is frozen, there is no
problem to access ivars.
2020-10-22 00:43:44 +09:00
Koichi Sasada 631eaa8510 check main-ractor or not first
On non-multi-ractor-mode, the cost of rb_ractor_main_p() is low
so check it first.
2020-10-21 23:52:11 +09:00
Koichi Sasada f6661f5085 sync RClass::ext::iv_index_tbl
iv_index_tbl manages instance variable indexes (ID -> index).
This data structure should be synchronized with other ractors
so introduce some VM locks.

This patch also introduced atomic ivar cache used by
set/getinlinecache instructions. To make updating ivar cache (IVC),
we changed iv_index_tbl data structure to manage (ID -> entry)
and an entry points serial and index. IVC points to this entry so
that cache update becomes atomically.
2020-10-17 08:18:04 +09:00
Koichi Sasada fad97f1f96 sync generic_ivtbl
generic_ivtbl is a process global table to maintain instance variables
for non T_OBJECT/T_CLASS/... objects. So we need to protect them
for multi-Ractor exection.

Hint: we can make them Ractor local for unshareable objects, but
      now it is premature optimization.
2020-10-14 16:36:55 +09:00
Koichi Sasada 79df14c04b Introduce Ractor mechanism for parallel execution
This commit introduces Ractor mechanism to run Ruby program in
parallel. See doc/ractor.md for more details about Ractor.
See ticket [Feature #17100] to see the implementation details
and discussions.

[Feature #17100]

This commit does not complete the implementation. You can find
many bugs on using Ractor. Also the specification will be changed
so that this feature is experimental. You will see a warning when
you make the first Ractor with `Ractor.new`.

I hope this feature can help programmers from thread-safety issues.
2020-09-03 21:11:06 +09:00
Alan Wu 7b9ef66747 Don't call to_s in const_set
Follow up for 5e16857315. Calling a method
in the middle of const_set adds a way that it would fail. It also makes
it inconsistent with declaring a constant using `::`, which doesn't call
`to_s`.
2020-09-03 16:49:45 +09:00
Marc-Andre Lafortune 5e16857315 Fix constant names set using const_set on a singleton class
Fixes [Bug #14895]
2020-09-02 00:05:14 -04:00
卜部昌平 6649677eb9 ROBJECT_IV_INDEX_TBL: convert into an inline function
Former ROBJECT_IV_INDEX_TBL macro included RCLASS_IV_INDEX_TBL, which is
not disclosed to extension libraies.  The macro was kind of broken.  Why
not just deprecate it, and convert the internal use into an inline
function.
2020-08-19 14:30:57 +09:00
Nobuyoshi Nakada b52a501ca7
Ensure the shortcut cached in the class
As well as the other places using RCLASS_IV_INDEX_TBL.
`IO#reopen` seems the only case that the class of an object can be
changed.
2020-08-17 22:57:40 +09:00
Alan Wu c987be2552 Improve docs for Module#remove_class_variable [ci skip] 2020-08-02 12:56:06 -04:00
Nobuyoshi Nakada d2bf6133f6
Remove trailing spaces [ci skip] 2020-07-20 13:34:16 +09:00
Koichi Sasada a0f12a0258
Use ID instead of GENTRY for gvars. (#3278)
Use ID instead of GENTRY for gvars.

Global variables are compiled into GENTRY (a pointer to struct
rb_global_entry). This patch replace this GENTRY to ID and
make the code simple.

We need to search GENTRY from ID every time (st_lookup), so
additional overhead will be introduced.
However, the performance of accessing global variables is not
important now a day and this simplicity helps Ractor development.
2020-07-03 16:56:44 +09:00
卜部昌平 de3e931df7 add UNREACHABLE_RETURN
Not every compilers understand that rb_raise does not return.  When a
function does not end with a return statement, such compilers can issue
warnings.  We would better tell them about reachabilities.
2020-06-29 11:05:41 +09:00
卜部昌平 b95b249784 rb_mod_remove_cvar: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平 1e9d58391c rb_copy_generic_ivar: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平 fc45a061b9 generic_ivar_update: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平 421db59c9e rb_path_to_class: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
Jeremy Evans 95dc9c07f3 Raise RuntimeError for class variable overtaken in nonverbose mode
900e83b501 changed from a warning
to an error in this case, but the warning was only issued in
verbose mode, and therefore the error was only raised in verbose
mode.  That was not intentional, verbose mode should only change
whether warnings are emitted, not other behavior.  This issues
the RuntimeError in all cases.

This change broke a couple tests, as the tests actually issued
the warning and therefore now raise an error.  This wasn't caught
earlier as test_variable suppressed the warning in this case,
effectively setting $VERBOSE = false around the code that warned.
basictest isn't run in verbose mode and therefore didn't expose
the issue previously. Fix these tests.

Fixes [Bug #14541]
2020-06-18 08:21:29 -07:00
Alan Wu e100fcbdd1 Prohibit setting class variable on frozen module through inheritance
Setting class varibles goes through the ancestor list which can
contain iclasses. Iclasses share a lot of information with the
module they are made from, but not the frozen status.

Check the frozen status of the module instead of the iclass.
2020-06-11 14:46:08 -04:00
卜部昌平 9e41a75255 sed -i 's|ruby/impl|ruby/internal|'
To fix build failures.
2020-05-11 09:24:08 +09:00
卜部昌平 d7f4d732c1 sed -i s|ruby/3|ruby/impl|g
This shall fix compile errors.
2020-05-11 09:24:08 +09:00
Aaron Patterson ff4f9cf95d
Allow global variables to move
This patch allows global variables that have been assigned in Ruby to
move.  I added a new function for the GC to call that will update
global references and introduced a new callback in the global variable
struct for updating references.

Only pure Ruby global variables are supported right now, other
references will be pinned.
2020-05-07 11:42:39 -07:00
Jeremy Evans 900e83b501 Turn class variable warnings into exceptions
This changes the following warnings:

* warning: class variable access from toplevel
* warning: class variable @foo of D is overtaken by C

into RuntimeErrors.  Handle defined?(@@foo) at toplevel
by returning nil instead of raising an exception (the previous
behavior warned before returning nil when defined? was used).

Refactor the specs to avoid the warnings even in older versions.
The specs were checking for the warnings, but the purpose of
the related specs as evidenced from their description is to
test for behavior, not for warnings.

Fixes [Bug #14541]
2020-04-10 00:29:05 -07:00
Nobuyoshi Nakada e474c189da
Suppress -Wswitch warnings 2020-04-08 15:13:37 +09:00
卜部昌平 9e6e39c351
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
2020-04-08 13:28:13 +09:00
Nobuyoshi Nakada 927308108c
Fix source location of autoloaded constant [Bug #16764] 2020-04-07 21:35:28 +09:00
Nobuyoshi Nakada ce60821387
Removed unnecessary cast 2020-04-07 20:20:34 +09:00
Nobuyoshi Nakada 52cdf400ef
Workaround of instance variable on hidden object
Since 9d9aea7fe5, generic instance
variables need `iv_index_tbl` in the object's class.  As hidden
objects, however, have no class, access to the variables causes a
segfault.  Get rid of that segfault by raising an exception, for
the time being.
2020-02-12 15:05:29 +09:00
Nobuyoshi Nakada d83d61c98b
Removed unused variable
`generic_iv_tbl_compat` has not been utilized since 14d61a94ff.
2020-02-11 11:08:02 +09:00
Aaron Patterson 18e7f9000d
Use `rb_gc_mark` when marking globals
I think global references should either be 0 or valid heap pointers.
`rb_gc_mark_maybe` checks to see if the pointer is a valid heap pointer,
but I believe we already know they are valid addresses
2020-01-30 08:23:07 -08:00