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

545 Коммитов

Автор SHA1 Сообщение Дата
Jeremy Evans 24b53b1f3a Remove unneeded line 2022-01-06 08:03:33 -08:00
Jeremy Evans a79c59472d Allow include before calling Module#initialize
This is to allow Module subclasses that include modules before
calling super in the subclass's initialize.

Remove rb_module_check_initializable from Module#initialize.
Module#initialize only calls module_exec if a block is passed,
it doesn't have other issues that would cause problems if
called multiple times or with an already initialized module.

Move initialization of super to Module#allocate, though I'm not
sure it is required there.  However, it's needed to be removed
from Module#initialize for this to work.

Fixes [Bug #18292]
2022-01-06 08:03:33 -08:00
Nobuyoshi Nakada da43c8822c
Remove useless code [Bug #18185]
RMODULE_SUPER is initialized to 0, as the uninitialized module
flag is used since b929af430c.
2022-01-06 10:26:19 +09:00
zverok 34deea3b42 Add docs for Refinement class 2021-12-24 10:31:04 +09:00
Nobuyoshi Nakada 9902398d86
Split too long line
I don't have a display enough for 170 columns, and it is hard to
use small fonts for my eyes. :(
2021-12-22 14:27:33 +09:00
Jeremy Evans 3bd5f27f73 Remove Class#descendants 2021-12-20 11:02:15 -08:00
Peter Zhu 9aded89f40 Speed up Ractors for Variable Width Allocation
This commit adds a Ractor cache for every size pool. Previously, all VWA
allocated objects used the slowpath and locked the VM.

On a micro-benchmark that benchmarks String allocation:

VWA turned off:
  29.196591   0.889709  30.086300 (  9.434059)

VWA before this commit:
  29.279486  41.477869  70.757355 ( 12.527379)

VWA after this commit:
  16.782903   0.557117  17.340020 (  4.255603)
2021-11-23 10:51:27 -05:00
Jean Boussier c0c2b31a35 Add Class#subclasses
Implements [Feature #18273]

Returns an array containing the receiver's direct subclasses without
singleton classes.
2021-11-23 10:50:44 +01:00
Matt Valentine-House b680b632e5 Make RCLASS_EXT(c)->subclasses a doubly linked list
Updating RCLASS_PARENT_SUBCLASSES and RCLASS_MODULE_SUBCLASSES while
compacting can trigger the read barrier. This commit makes
RCLASS_SUBCLASSES a doubly linked list with a dedicated head object so
that we can add and remove entries from the list without having to touch
an object in the Ruby heap
2021-11-22 09:11:04 -05:00
Matt Valentine-House a9a94540d6 Remove RCLASS(obj)->ptr when RVARGC is enabled
With RVARGC we always store the rb_classext_t in the same slot as the
RClass struct that refers to it. So we don't need to store the pointer
or access through the pointer anymore and can switch the RCLASS_EXT
macro to use an offset
2021-11-11 13:47:45 -05:00
Yusuke Endoh e8086e275b gc.h: move rb_objspace_garbage_object_p to internal/gc.h
... to allow class.c to use the function
2021-11-10 10:08:30 +09:00
Yusuke Endoh 5c892da7d7 class.c: descendants must not cause GC until the result array is created
Follow up of 428227472f. The previous fix
uses `rb_ary_new_from_values` to create the result array, but it may
trigger the GC.

This second try is to create the result array by `rb_ary_new_capa`
before the second iteration, and assume that `rb_ary_push` does not
trigger GC. This assumption is very fragile, so should be improved in
future.

[Bug #18282] [Feature #14394]
2021-11-10 10:08:30 +09:00
Yusuke Endoh 3628616dd1 Remove a redundant condition 2021-11-09 16:11:10 +09:00
Yusuke Endoh 64007fc57f class.c (Class#descendants): Ingore subclasses created after estimation
It is theoretically possible if a finalizer creates a subclass.
2021-11-09 16:11:10 +09:00
Yusuke Endoh 037da50666 class.c: Use ALLOC_N instead of ALLOCA_N 2021-11-09 16:11:10 +09:00
Yusuke Endoh 428227472f class.c: calculate the length of Class.descendants in advance
GC must not be triggered during callback of rb_class_foreach_subclass.
To prevent GC, we can not use rb_ary_push. Instead, this changeset calls
rb_class_foreach_subclass twice: first counts the subclasses, then
allocates a buffer (which may cause GC and reduce subclasses, but not
increase), and finally stores the subclasses to the buffer.

[Bug #18282] [Feature #14394]
2021-11-09 16:11:10 +09:00
Jeremy Evans 717ab0bb2e
Add Class#descendants
Doesn't include receiver or singleton classes.

Implements [Feature #14394]

Co-authored-by: fatkodima <fatkodima123@gmail.com>
Co-authored-by: Benoit Daloze <eregontp@gmail.com>
2021-10-26 12:35:21 -07:00
Shugo Maeda 37395ffa05
Make the metaclass of Refinement explicitly
Otherwise, singleton methods of Module are not inherited unless
Refinement.singleton_class is called.
2021-10-26 19:36:52 +09:00
Peter Zhu 6374be5a81 [Feature #18239] Refactor RVARGC alloc functions
The allocation functions no longer assume that one RVALUE needs to be
allocated.
2021-10-25 13:26:23 -04:00
Shugo Maeda 6606597109
Deprecate include/prepend in refinements and add Refinement#import_methods instead
Refinement#import_methods imports methods from modules.
Unlike Module#include, it copies methods and adds them into the refinement,
so the refinement is activated in the imported methods.

[Bug #17429] [ruby-core:101639]
2021-10-21 16:31:54 +09:00
Nobuyoshi Nakada b929af430c Use the flag for uninitialized module [Bug #18185]
Make `Module#ancestors` not to include `BasicObject`.
2021-09-24 08:29:00 +09:00
Nobuyoshi Nakada 65285bf673 Consider modified modules initialized [Bug #18185] 2021-09-24 08:29:00 +09:00
Nobuyoshi Nakada 2e3d43e577 Allow to include uninitialized modules [Bug #18177]
The module that is about to be included is considered initialized.
2021-09-20 15:23:00 +09:00
Nobuyoshi Nakada c0a892a7f0
Fix a typo [Bug #17048] 2021-09-19 22:39:18 +09:00
Nobuyoshi Nakada 178ee1e801
Already initialized modules cannot be replaced [Bug #17048] 2021-09-17 11:14:04 +09:00
卜部昌平 fbe1fcd82d include/ruby/internal/intern/class.h: add doxygen
Must not be a bad idea to improve documents. [ci skip]
2021-09-10 20:00:06 +09:00
卜部昌平 00ff6b68e4 include/ruby/internal/method.h: add doxygen
Must not be a bad idea to improve documents. [ci skip]

In fact many functions declared in the header file are already
documented more or less.  They were just copy & pasted, with applying
some style updates.
2021-09-10 20:00:06 +09:00
卜部昌平 9ba9dbf168 include/ruby/internal/module.h: add doxygen
Must not be a bad idea to improve documents. [ci skip]

In fact many functions declared in the header file are already
documented more or less.  They were just copy & pasted, with applying
some style updates.
2021-09-10 20:00:06 +09:00
卜部昌平 1f66d8a77b include/ruby/internal/newobj.h: add doxygen
Must not be a bad idea to improve documents. [ci skip]
2021-09-10 20:00:06 +09:00
Nobuyoshi Nakada 10ebf87428
Assert not to be UNDEF visibility
Any defined methods, bound to any classes/modules and not being
UNDEFINED_METHOD_ENTRY_P, should not be METHOD_VISI_UNDEF.
2021-09-01 19:28:54 +09:00
Peter Zhu 62bc4a9420 [Feature #18045] Implement size classes for GC
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>
2021-08-25 09:28:21 -04:00
Peter Zhu eddd369e73 Revert "[Feature #18045] Implement size classes for GC"
This reverts commits 48ff7a9f3e
and b2e2cf2ded because it is causing
crashes in SPARC solaris and i386 debian.
2021-08-23 10:54:53 -04:00
Peter Zhu b2e2cf2ded [Feature #18045] Implement size classes for GC
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>
2021-08-23 09:15:42 -04:00
Nobuyoshi Nakada b32987a3d7
Simplify repeated member access macros 2021-08-20 14:04:07 +09:00
Shugo Maeda 754adbee91
Module#ancestors should not return superclasses of refinements
[ruby-core:86949] [Bug #14744]

Reported by Eregon (Benoit Daloze).  Thanks!
2021-08-20 10:42:01 +09:00
Nobuyoshi Nakada 6963f8f743
Remove old warning aged nearly 8 years 2021-08-19 17:44:48 +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
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
Alan Wu 39a2ba5cc5
Method cache: fix refinement entry handling
To invalidate some callable method entries, we replace the entry in the
class. Most types of method entries are on the method table of the
origin class, but refinement entries without an orig_me are housed in
the method table of the class itself. They are there because refinements
take priority over prepended methods.

By unconditionally inserting a copy of the refinement entry into the
origin class, clearing the method cache created situations where there
are refinement entry duplicates in the lookup chain, leading to infinite
loops and other problems.

Update the replacement logic to use the right class that houses the
method entry. Also, be more selective about cache invalidation when
moving refinement entries for prepend. This avoids calling
clear_method_cache_by_id_in_class() before refinement entries are in the
place it expects.

[Bug #17806]
2021-05-11 12:05:06 -04:00
Matt Valentine-House d1bd4e233c Store rb_classext_t next to RClass slots on the heap 2021-05-06 09:18:17 -04:00
S.H 54bfa0570d
Add ins_methods_type_i function 2021-03-21 06:57:30 +09: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
Alan Wu 58e8220605 Check for cyclic prepend before making origin
It's important to only make the origin when the prepend goes
through, as the precense of the origin informs whether to do an
origin backfill.

This plus 2d877327e fix [Bug #17590].
2021-02-22 17:57:47 -05:00
Jeremy Evans 2d877327e1 Make a cyclic prepend not modify ancestors for the receiver
Check for cyclic prepend before making any changes.  This requires
scanning the module ancestor chain twice, but in general modules
do not have large numbers of ancestors.
2021-02-11 07:45:52 -08:00
Matt Valentine-House e0f999a2ed Add RCLASS_SUBCLASSES Macro 2021-02-01 08:42:54 -08:00
Matt Valentine-House 7341b01465 Add RCLASS_ALLOCATOR Macro 2021-02-01 08:42:54 -08:00
Matt Valentine-House 6edd425674 Add PARENT_MODULE_SUBCLASSES Macro 2021-02-01 08:42:54 -08:00
Matt Valentine-House 49950266be Add RCLASS_PARENT_SUBMODULES Macro 2021-02-01 08:42:54 -08:00
Alan Wu 216e6605a4 Add compaction notes for class/module creation C APIs 2021-01-26 16:24:01 -08:00
Alan Wu 646131448e Make rb_define_module_id_under() pin existing modules
Just like rb_define_class_id_under(). Also makes
rb_define_module_under() consistent with rb_define_class_under() in the
same regard.
2021-01-26 16:24:01 -08:00
Jeremy Evans e09094546a Make Module#prepend affect ancestor chain even if argument already included in receiver
Previously, if a class included a module and then prepended the
same module, the prepend had no effect.  This changes the behavior
so that the prepend has an effect unless the module is already
prepended the receiver.

While here, rename the origin_seen variable in include_modules_at,
since it is misleading. The variable tracks whether c has been seen,
not whether the origin of klass has been.

Fixes [Bug #17423]
2021-01-14 20:43:30 -08:00
Koichi Sasada 520dcbd600 reset cache before iterating
cee02d754d resets pCMC and `me`
will be a invalidated and continuing the invalidated `me`,
it will break the data structure. This patch tris to clear
all methods of specified class before manipulating the `me`s.
[Issue #17417]
2020-12-22 06:09:30 +09:00
Nobuyoshi Nakada fb8f011422
Fixed indefinite articles before "Integer" [ci skip] 2020-12-21 01:19:55 +09:00
Koichi Sasada cee02d754d fix refinements/prepend bug
replaced method entry should be invalidated.
[Bug #17386]
2020-12-19 04:33:04 +09:00
Alan Wu e0944bde91 Prefer rb_module_new() over rb_define_module_id()
rb_define_module_id() doesn't do anything with its parameter so
it's a bit confusing.
2020-11-25 17:05:06 -05:00
Jeremy Evans 08686e71d5 Do not allow Module#include to insert modules before the origin in the lookup chain
Module#include should only be able to insert modules after the origin,
otherwise it ends up working like Module#prepend.

This fixes the case where one of the modules in the included module
chain is included in a module that is already prepended to the receiver.

Fixes [Bug #7844]
2020-11-20 15:26:43 -08:00
Alan Wu ebb96fa880 Fix singleton class cloning
Before this commit, `clone` gave different results depending on whether the original object
had an attached singleton class or not.

Consider the following setup:
```
class Foo; end
Foo.singleton_class.define_method(:foo) {}

obj = Foo.new

obj.singleton_class if $call_singleton

clone = obj.clone
```

When `$call_singleton = false`, neither `obj.singleton_class.singleton_class` nor
`clone.singleton_class.singleton_class` own any methods.

However, when `$call_singleton = true`, `clone.singleton_class.singleton_class` would own a copy of
`foo` from `Foo.singleton_class`, even though `obj.singleton_class.singleton_class` does not.

The latter case is unexpected and results in a visibly different clone, depending on if the original object
had an attached class or not.

Co-authored-by: Ufuk Kayserilioglu <ufuk.kayserilioglu@shopify.com>
2020-11-16 17:41:17 -05:00
Alan Wu 7826210541 Use rb_attr_get() for hidden ivar
rb_ivar_get() can issue an uninitialized ivar warning. We never want to
issue warnings about hidden ivars as they are not actionable for users.
2020-11-13 11:46:08 -05:00
Jeremy Evans ce9beb9d20 Improve error message when subclassing non-Class
Fixes [Bug #14726]
2020-11-13 07:06:13 -08:00
Alan Wu 6778ba48fd Fix excessive GC rooting
rb_vm_add_root_module() is enough to make sure the object become a GC
root.
2020-11-09 16:08:36 -05:00
Alan Wu 6817f4c6b1 rb_vm_add_root_module(): Remove unused parameter 2020-11-09 16:08:36 -05:00
卜部昌平 5ca44076f4 include/ruby/backward/2/rmodule.h: deprecate
Only one function in only one file uses contents of this public header.
That is not a wise idea.  Let's just free the header's soul.
2020-08-27 16:42:06 +09:00
Alan Wu 264e4cd04f Remove write barrier exemption for T_ICLASS
Before this commit, iclasses were "shady", or not protected by write
barriers. Because of that, the GC needs to spend more time marking these
objects than otherwise.

Applications that make heavy use of modules should see reduction in GC
time as they have a significant number of live iclasses on the heap.

 - Put logic for iclass method table ownership into a function
 - Remove calls to WB_UNPROTECT and insert write barriers for iclasses

This commit relies on the following invariant: for any non oirigin
iclass `I`, `RCLASS_M_TBL(I) == RCLASS_M_TBL(RBasic(I)->klass)`. This
invariant did not hold prior to 98286e9 for classes and modules that
have prepended modules.

[Feature #16984]
2020-08-17 17:17:47 -04:00
Nobuyoshi Nakada 28cd254b49
Set cloned flag after checked if copiable 2020-07-30 02:28:46 +09:00
Alan Wu 37e6c83609 Lazily insert origins on prepend to save memory
98286e9850 made it so that
`Module#include` allocates an origin iclass on each use. Since `include`
is widely used, the extra allocation can contribute significantly to
memory usage.

Instead of always allocating in anticipation of prepend, this change
takes a different approach. The new setup inserts a origin iclass into
the super chains of all the children of the module when prepend happens
for the first time.

rb_ensure_origin is made static again since now that adding an origin
now means walking over all usages, we want to limit the number of places
where we do it.
2020-07-22 19:01:28 -04:00
卜部昌平 3a3728e4b3 singleton_class_of: 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
卜部昌平 86e3d63772 SPECIAL_SINGLETON: no longer used
This macro does not improve any readability and/or runtime performance.
2020-06-29 11:05:41 +09:00
Jeremy Evans 41582d5866 Make Module#prepend affect the iclasses of the module
3556a834a2 added support for
Module#include to affect the iclasses of the module.  It didn't add
support for Module#prepend because there were bugs in the object model
and GC at the time that prevented it.  Those problems have been
addressed in ad729a1d11 and
98286e9850, and now adding support for
it is straightforward and does not break any tests or specs.

Fixes [Bug #9573]
2020-06-18 08:18:31 -07:00
Alan Wu 4dba8b4027
Assert iclass property and remove dead code
Iclass objects are never made from other iclass objects.
2020-06-16 17:45:45 -04:00
Jeremy Evans 98286e9850 Ensure origins for all included, prepended, and refined modules
This fixes various issues when a module is included in or prepended
to a module or class, and then refined, or refined and then included
or prepended to a module or class.

Implement by renaming ensure_origin to rb_ensure_origin, making it
non-static, and calling it when refining a module.

Fix Module#initialize_copy to handle origins correctly.  Previously,
Module#initialize_copy did not handle origins correctly.  For example,
this code:

```ruby
module B; end
class A
  def b; 2 end
  prepend B
end
a = A.dup.new
class A
  def b; 1 end
end
p a.b
```

Printed 1 instead of 2.  This is because the super chain for
a.singleton_class was:

```
a.singleton_class
A.dup
B(iclass)
B(iclass origin)
A(origin) # not A.dup(origin)
```

The B iclasses would not be modified, so the includer entry would be
still be set to A and not A.dup.

This modifies things so that if the class/module has an origin,
all iclasses between the class/module and the origin are duplicated
and have the correct includer entry set, and the correct origin
is created.

This requires other changes to make sure all tests still pass:

* rb_undef_methods_from doesn't automatically handle classes with
  origins, so pass it the origin for Comparable when undefing
  methods in Complex. This fixed a failure in the Complex tests.

* When adding a method, the method cache was not cleared
  correctly if klass has an origin.  Clear the method cache for
  the klass before switching to the origin of klass.  This fixed
  failures in the autoload tests related to overridding require,
  without breaking the optimization tests.  Also clear the method
  cache for both the module and origin when removing a method.

* Module#include? is fixed to skip origin iclasses.

* Refinements are fixed to use the origin class of the module that
  has an origin.

* RCLASS_REFINED_BY_ANY is removed as it was only used in a single
  place and is no longer needed.

* Marshal#dump is fixed to skip iclass origins.

* rb_method_entry_make is fixed to handled overridden optimized
  methods for modules that have origins.

Fixes [Bug #16852]
2020-06-03 09:50:37 -07:00
Jeremy Evans ad729a1d11 Fix origin iclass pointer for modules
If a module has an origin, and that module is included in another
module or class, previously the iclass created for the module had
an origin pointer to the module's origin instead of the iclass's
origin.

Setting the origin pointer correctly requires using a stack, since
the origin iclass is not created until after the iclass itself.
Use a hidden ruby array to implement that stack.

Correctly assigning the origin pointers in the iclass caused a
use-after-free in GC.  If a module with an origin is included
in a class, the iclass shares a method table with the module
and the iclass origin shares a method table with module origin.

Mark iclass origin with a flag that notes that even though the
iclass is an origin, it shares a method table, so the method table
should not be garbage collected.  The shared method table will be
garbage collected when the module origin is garbage collected.
I've tested that this does not introduce a memory leak.

This change caused a VM assertion failure, which was traced to callable
method entries using the incorrect defined_class.  Update
rb_vm_check_redefinition_opt_method and find_defined_class_by_owner
to treat iclass origins different than class origins to avoid this
issue.

This also includes a fix for Module#included_modules to skip
iclasses with origins.

Fixes [Bug #16736]
2020-05-22 20:31:23 -07:00
Jeremy Evans 8d798e7c53 Revert "Fix origin iclass pointer for modules"
This reverts commit c745a60634.

This triggers a VM assertion.  Reverting until the issue can be
debugged.
2020-05-22 07:54:34 -07:00
Jeremy Evans c745a60634 Fix origin iclass pointer for modules
If a module has an origin, and that module is included in another
module or class, previously the iclass created for the module had
an origin pointer to the module's origin instead of the iclass's
origin.

Setting the origin pointer correctly requires using a stack, since
the origin iclass is not created until after the iclass itself.
Use a hidden ruby array to implement that stack.

Correctly assigning the origin pointers in the iclass caused a
use-after-free in GC.  If a module with an origin is included
in a class, the iclass shares a method table with the module
and the iclass origin shares a method table with module origin.

Mark iclass origin with a flag that notes that even though the
iclass is an origin, it shares a method table, so the method table
should not be garbage collected.  The shared method table will be
garbage collected when the module origin is garbage collected.
I've tested that this does not introduce a memory leak.

This also includes a fix for Module#included_modules to skip
iclasses with origins.

Fixes [Bug #16736]
2020-05-22 07:36:52 -07:00
Nobuyoshi Nakada ba7f4bb0af
Synchronized non-inline version rb_scan_args with the inline version 2020-05-21 13:31:36 +09: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
Nobuyoshi Nakada 4c8e3f1241
Make rb_scan_args implementations same
between rb_scan_args_set and rb_scan_args_assign +
rb_scan_args_result.
2020-04-12 23:29:22 +09: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
Jeremy Evans 3556a834a2 Make Module#include affect the iclasses of the module
When calling Module#include, if the receiver is a module,
walk the subclasses list and include the argument module in each
iclass.

This does not affect Module#prepend, as fixing that is significantly
more involved.

Fixes [Bug #9573]
2020-02-27 11:03:13 -08:00
Koichi Sasada b9007b6c54 Introduce disposable call-cache.
This patch contains several ideas:

(1) Disposable inline method cache (IMC) for race-free inline method cache
    * Making call-cache (CC) as a RVALUE (GC target object) and allocate new
      CC on cache miss.
    * This technique allows race-free access from parallel processing
      elements like RCU.
(2) Introduce per-Class method cache (pCMC)
    * Instead of fixed-size global method cache (GMC), pCMC allows flexible
      cache size.
    * Caching CCs reduces CC allocation and allow sharing CC's fast-path
      between same call-info (CI) call-sites.
(3) Invalidate an inline method cache by invalidating corresponding method
    entries (MEs)
    * Instead of using class serials, we set "invalidated" flag for method
      entry itself to represent cache invalidation.
    * Compare with using class serials, the impact of method modification
      (add/overwrite/delete) is small.
    * Updating class serials invalidate all method caches of the class and
      sub-classes.
    * Proposed approach only invalidate the method cache of only one ME.

See [Feature #16614] for more details.
2020-02-22 09:58:59 +09:00
Nobuyoshi Nakada 9bc815aa5f
Hoisted out `rb_scan_args_result` 2020-02-14 15:56:37 +09:00
Nobuyoshi Nakada 0ab7f2f222
Make `rb_scan_args_kw` inline too 2020-02-03 13:07:34 +09:00
Nobuyoshi Nakada 48c851f868
Moved runtime assignemnts
Separate assignemnts of dynamically given runtime values in
`rb_scan_args_assign` from parsing statically given format in
`rb_scan_args_parse`.
2020-02-03 12:48:41 +09:00
Nobuyoshi Nakada 9a446fd7ba
`struct rb_scan_args_t::vargs` is never used 2020-02-03 08:44:51 +09:00
Nobuyoshi Nakada fae537259d
Removed no longer used variable `last_hash`
1. By substituting `n_var` with its initializer, `0 < n_var` is
   equivalent to `argc > argi + n_trail`.
2. As `argi` is non-negative, so `argi + n_trail >= n_trail`, and
   the above expression is equivalent to `argc > n_trail`.
3. Therefore, `f_last` is always false, and `last_hash` is no
   longer used.
2020-02-02 23:09:25 +09:00
Marc-Andre Lafortune 8ab11096ef Clarify documentation for Module#included_modules and Module#included?
[DOC] [ci skip] [Bug #8841]
2020-01-16 13:31:25 -06:00
Kazuhiro NISHIYAMA c7af1e432a
Remove unused tmp_buffer in class.c
ref 44a164c26f and beae6cbf0f
2020-01-05 12:26:48 +09:00
Kazuhiro NISHIYAMA 787c6d591a
Remove unused last_idx in class.c
ref c7f01d889b and beae6cbf0f
2020-01-05 12:26:37 +09:00
Kazuhiro NISHIYAMA 170f4dbb9b
Fix unused warnings
http://ci.rvm.jp/results/trunk_gcc7@silicon-docker/2539622
```
/tmp/ruby/v2/src/trunk_gcc7/class.c: In function 'rb_scan_args_parse':
/tmp/ruby/v2/src/trunk_gcc7/class.c:1971:12: warning: unused variable 'tmp_buffer' [-Wunused-variable]
     VALUE *tmp_buffer = arg->tmp_buffer;
            ^~~~~~~~~~
```
```
In file included from /tmp/ruby/v2/src/trunk_gcc7/vm_insnhelper.c:1895:0,
                 from /tmp/ruby/v2/src/trunk_gcc7/vm.c:349:
/tmp/ruby/v2/src/trunk_gcc7/vm_args.c:212:1: warning: 'args_stored_kw_argv_to_hash' defined but not used [-Wunused-function]
 args_stored_kw_argv_to_hash(struct args_info *args)
 ^~~~~~~~~~~~~~~~~~~~~~~~~~~
```
2020-01-03 14:53:25 +09:00
Jeremy Evans beae6cbf0f Fully separate positional arguments and keyword arguments
This removes the warnings added in 2.7, and changes the behavior
so that a final positional hash is not treated as keywords or
vice-versa.

To handle the arg_setup_block splat case correctly with keyword
arguments, we need to check if we are taking a keyword hash.
That case didn't have a test, but it affects real-world code,
so add a test for it.

This removes rb_empty_keyword_given_p() and related code, as
that is not needed in Ruby 3.  The empty keyword case is the
same as the no keyword case in Ruby 3.

This changes rb_scan_args to implement keyword argument
separation for C functions when the : character is used.
For backwards compatibility, it returns a duped hash.
This is a bad idea for performance, but not duping the hash
breaks at least Enumerator::ArithmeticSequence#inspect.

Instead of having RB_PASS_CALLED_KEYWORDS be a number,
simplify the code by just making it be rb_keyword_given_p().
2020-01-02 18:40:45 -08:00
卜部昌平 5e22f873ed decouple internal.h headers
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead.  This would significantly
speed up incremental builds.

We take the following inclusion order in this changeset:

1.  "ruby/config.h", where _GNU_SOURCE is defined (must be the very
    first thing among everything).
2.  RUBY_EXTCONF_H if any.
3.  Standard C headers, sorted alphabetically.
4.  Other system headers, maybe guarded by #ifdef
5.  Everything else, sorted alphabetically.

Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
2019-12-26 20:45:12 +09:00
Marc-Andre Lafortune 819b604037 Reword keyword arguments warning messages to convey these are deprecation warnings 2019-12-23 16:47:33 -05:00
Yusuke Endoh f7aee58498 vm_args.c: rephrase the warning message of keyword argument separation
(old)
test.rb:4: warning: The last argument is used as the keyword parameter
test.rb:1: warning: for `foo' defined here; maybe ** should be added to the call?

(new)
test.rb:4: warning: The last argument is used as keyword parameters; maybe ** should be added to the call
test.rb:1: warning: The called method `foo' is defined here
2019-12-20 19:41:15 +09:00
Jeremy Evans 55b7ba3686 Make super in instance_eval in method in module raise TypeError
This makes behavior the same as super in instance_eval in method
in class.  The reason this wasn't implemented before is that
there is a check to determine if the self in the current context
is of the expected class, and a module itself can be included
in multiple classes, so it doesn't have an expected class.

Implementing this requires giving iclasses knowledge of which
class created them, so that super call in the module method
knows the expected class for super calls.  This reference
is called includer, and should only be set for iclasses.

Note that the approach Ruby uses in this check is not robust. If
you instance_eval another object of the same class and call super,
instead of an TypeError, you get super called with the
instance_eval receiver instead of the method receiver.  Truly
fixing super would require keeping a reference to the super object
(method receiver) in each frame where scope has changed, and using
that instead of current self when calling super.

Fixes [Bug #11636]
2019-12-12 15:50:19 +09:00
Nobuyoshi Nakada 2fa3b4565a
Merged common statements [Bug #16242] 2019-11-28 21:31:53 +09:00
Nobuyoshi Nakada f0a5a07fa5
Removed unused variable [Bug #16242] 2019-11-28 19:57:43 +09:00
Jeremy Evans a0579f3606 Make prepending a refined module after inclusion not break refinements
After the previous commit, this was still broken. The reason it
was broken is that a refined module that hasn't been prepended to
yet keeps the refined methods in the module's method table. When
prepending, the module's method table is moved to the origin
iclass, and then the refined methods are moved from the method
table to a new method table in the module itself.

Unfortunately, that means that if a class has included the module,
prepending breaks the refinements, because when the methods are
moved from the origin iclass method table to the module method
table, they are removed from the method table from the iclass
created when the module was included earlier.

Fix this by always creating an origin class when including a
module that has any refinements, even if the refinements are
not currently used.  I wasn't sure the best way to do that.
The approach I choose was to use an object flag. The flag is
set on the module when Module#refine is called, and if the
flag is present when the module is included in another module
or class, an origin iclass is created for the module.

Fixes [Bug #13446]
2019-11-28 19:57:04 +09:00