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

528 Коммитов

Автор SHA1 Сообщение Дата
Kevin Newton 8ee4a82e8c
RubyVM.stat constant cache metrics (#5766)
Before the new constant cache behavior, caches were invalidated by a
single global variable. You could inspect the value of this variable
with RubyVM.stat(:global_constant_state). This was mostly useful to
verify the behavior of the VM or to test constant loading like in Rails.

With the new constant cache behavior, we introduced
RubyVM.stat(:constant_cache) which returned a hash with symbol keys and
integer values that represented the number of live constant caches
associated with the given symbol. Additionally, we removed the old
RubyVM.stat(:global_constant_state).

This was proven to be not very useful, so it doesn't help you diagnose
constant loading issues. So, instead we added the global constant state
back into the RubyVM output. However, that number can be misleading as
now when you invalidate something like `Foo::Bar::Baz` you're actually
invalidating 3 different lists of inline caches.

This commit attempts to get the best of both worlds. We remove
RubyVM.stat(:global_constant_state) like we did originally, as it
doesn't have the same semantic meaning and it could be confusing going
forward. Instead we add RubyVM.stat(:constant_cache_invalidations) and
RubyVM.stat(:constant_cache_misses). These two metrics should provide
enough information to diagnose any constant loading issues, as well as
provide a replacement for the old global constant state.
2022-04-05 16:37:00 -04:00
Kevin Newton 42000664be Bring back RubyVM.stat(:global_constant_state)
This was removed as part of [Feature #18589]. But some applications were relying on this behavior. So bringing this back to make it better for backward compatibility going forward.
2022-04-04 20:41:05 +02: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
Jeremy Evans 0c6e24d102 Fix visibility of alias of zsuper methods
This was broken by 71c746379d.

Fixes [Bug #18600]
2022-03-10 08:35:26 -08:00
Yuta Saito 2b5097b890 vm_method.c: avoid signature mismatch in rb_f_notimplement call
`rb_f_notimplement` has a similar signature with arity=-1, but it has an
extra marker argument to distinguish it from other methods in
compile-time type check in rb_define_method.
This trick is introduced to override a given arity to be -1 since
9ef51b0b89

However, the trailing extra argument introduces a signature mismatch
between caller and callee expectation.
This patch adds rb_f_notimplement_internal, which has canonical arity=-1
signature, and makes rb_define_method family to inserts a method entry
with rb_f_notimplement_internal instead of rb_f_notimplement.
2022-03-02 17:13:40 +09:00
Nobuyoshi Nakada e89d80702b Fix memory leak at the same named alias [Bug #18516]
When aliasing a method to the same name method, set a separate bit
flag on that method definition, instead of the reference count
increment.  Although this kind of alias has no actual effect at
runtime, is used as the hack to suppress the method re-definition
warning.
2022-01-27 15:46:08 +09:00
Nobuyoshi Nakada 069cca6f74
Negative RBOOL usage 2022-01-01 17:02:04 +09:00
Koichi Sasada ca032d5eea undef `rb_vm_lookup_overloaded_cme()`
Some callable method entries (cme) can be a key of `overloaded_cme_table`
and the keys should be pinned because the table is numtable (VALUE is a key).
Before the patch GC checks the cme is in `overloaded_cme_table` by looking up
the table, but it needs VM locking.

It works well in normal GC marking because it is protected by the VM lock,
but it doesn't work on `rb_objspace_reachable_objects_from` because it doesn't
use VM lock.

Now, the number of target cmes are small enough, I decide to pin down
all possible cmes instead of using looking up the table.
2021-12-23 16:49:49 +09:00
Koichi Sasada ad450c9fe5 make `overloaded_cme_table` truly weak key map
`overloaded_cme_table` keeps cme -> monly_cme pairs to manage
corresponding `monly_cme` for `cme`. The lifetime of the `monly_cme`
should be longer than `monly_cme`, but the previous patch losts the
reference to the living `monly_cme`.

Now `overloaded_cme_table` values are always root (keys are only weak
reference), it means `monly_cme` does not freed until corresponding
`cme` is invalidated.

To make managing easy, move `overloaded_cme_table` to `rb_vm_t`.
2021-12-21 15:21:30 +09:00
Koichi Sasada df48db987d `mandatory_only_cme` should not be in `def`
`def` (`rb_method_definition_t`) is shared by multiple callable
method entries (cme, `rb_callable_method_entry_t`).

There are two issues:

* old -> young reference: `cme1->def->mandatory_only_cme = monly_cme`
  if `cme1` is young and `monly_cme` is young, there is no problem.
  Howevr, another old `cme2` can refer `def`, in this case, old `cme2`
  points young `monly_cme` and it violates gengc assumption.
* cme can have different `defined_class` but `monly_cme` only has
  one `defined_class`. It does not make sense and `monly_cme`
  should be created for a cme (not `def`).

To solve these issues, this patch allocates `monly_cme` per `cme`.
`cme` does not have another room to store a pointer to the `monly_cme`,
so this patch introduces `overloaded_cme_table`, which is weak key map
`[cme] -> [monly_cme]`.

`def::body::iseqptr::monly_cme` is deleted.

The first issue is reported by Alan Wu.
2021-12-21 11:03:09 +09:00
Koichi Sasada 82ea287018 optimize `Struct` getter/setter
Introduce new optimized method type
`OPTIMIZED_METHOD_TYPE_STRUCT_AREF/ASET` with index information.
2021-11-19 08:32:39 +09:00
Koichi Sasada be71c95b88 `rb_method_optimized_t` for further extension
Now `rb_method_optimized_t optimized` field is added to represent
optimized method type.
2021-11-19 08:32:39 +09:00
Jeremy Evans ab737b1919 Update documentation for Module#{private,public,protected,module_function}
Also, update NEWS for this change and the Kernel#load change.
2021-11-18 10:51:14 -08:00
Jeremy Evans 75ecbda438 Make Module#{public,private,protected,module_function} return arguments
Previously, each of these methods returned self, but it is
more useful to return arguments, to allow for simpler method
decorators, such as:

```ruby
cached private def foo; some_long_calculation; end
```

Where cached sets up caching for the method.

For each of these methods, the following behavior is used:

1) No arguments returns nil
2) Single argument is returned
3) Multiple arguments are returned as an array

The single argument case is really the case we are trying to
optimize for, for the same reason that def was changed to return
a symbol for the method.

Idea and initial patch from Herwin Quarantainenet.

Implements [Feature #12495]
2021-11-18 09:47:40 -08:00
Peter Zhu c400165afa Fix crash when clearing method cache for builtin method
Builtin methods do not always have their mandatory_only_cme created (it
is only created when called with only mandatory parameters), so it could
be null. If we try to clear the cme, it will crash because it is null.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2021-11-17 09:02:57 -05:00
Koichi Sasada b1b73936c1 `Primitive.mandatory_only?` for fast path
Compare with the C methods, A built-in methods written in Ruby is
slower if only mandatory parameters are given because it needs to
check the argumens and fill default values for optional and keyword
parameters (C methods can check the number of parameters with `argc`,
so there are no overhead). Passing mandatory arguments are common
(optional arguments are exceptional, in many cases) so it is important
to provide the fast path for such common cases.

`Primitive.mandatory_only?` is a special builtin function used with
`if` expression like that:

```ruby
  def self.at(time, subsec = false, unit = :microsecond, in: nil)
    if Primitive.mandatory_only?
      Primitive.time_s_at1(time)
    else
      Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
    end
  end
```

and it makes two ISeq,

```
  def self.at(time, subsec = false, unit = :microsecond, in: nil)
    Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
  end

  def self.at(time)
    Primitive.time_s_at1(time)
  end
```

and (2) is pointed by (1). Note that `Primitive.mandatory_only?`
should be used only in a condition of an `if` statement and the
`if` statement should be equal to the methdo body (you can not
put any expression before and after the `if` statement).

A method entry with `mandatory_only?` (`Time.at` on the above case)
is marked as `iseq_overload`. When the method will be dispatch only
with mandatory arguments (`Time.at(0)` for example), make another
method entry with ISeq (2) as mandatory only method entry and it
will be cached in an inline method cache.

The idea is similar discussed in https://bugs.ruby-lang.org/issues/16254
but it only checks mandatory parameters or more, because many cases
only mandatory parameters are given. If we find other cases (optional
or keyword parameters are used frequently and it hurts performance),
we can extend the feature.
2021-11-15 15:58:56 +09:00
Aaron Patterson 0d63600e4f Partial revert of ceebc7fc98
I'm looking through the places where YJIT needs notifications.  It looks
like these changes to gc.c and vm_callinfo.h have become unnecessary
since 84ab77ba59.  This commit just makes the diff against upstream
smaller, but otherwise shouldn't change any behavior.
2021-10-20 18:19:36 -04:00
Alan Wu ec1cbbb07d Get rid of dependency on rb_call_cache 2021-10-20 18:19:32 -04:00
Jose Narvaez 4e2eb7695e Yet Another Ruby JIT!
Renaming uJIT to YJIT. AKA s/ujit/yjit/g.
2021-10-20 18:19:31 -04:00
Aaron Patterson ab5760307b add a callback for when method cache changes 2021-10-20 18:19:28 -04:00
Maxime Chevalier-Boisvert e4c65ec49c Refactor uJIT code into more files for readability 2021-10-20 18:19:26 -04:00
Alan Wu c378c7a7cb MicroJIT: generate less code for CFUNCs
Added UJIT_CHECK_MODE. Set to 1 to double check method dispatch in
generated code.

It's surprising to me that we need to watch both cc and cme. There might
be opportunities to simplify there.
2021-10-20 18:19:26 -04:00
Jeremy Evans e8d6076fbd Fix typo in static function name 2021-10-01 08:12:46 -09:00
Nobuyoshi Nakada a0a8f2abf5 Get rid of type-punning pointer casts [Bug #18062] 2021-08-11 12:07:44 +09:00
S.H 378e8cdad6
Using RBOOL macro 2021-08-02 12:06:44 +09:00
Jeremy Evans 693ce6af0a Update documentation for ruby2_keywords
Point out that the method should be used for backwards compatibility
with code prior to Ruby 3.0 instead of Ruby 2.7.  It's still needed
in Ruby 2.7. It isn't needed in Ruby 3.0, as the methods using it
could switch to delegating both positional and keyword arguments.

Add a link to the www.ruby-lang.org web page that goes into detail
describing when and how ruby2_keywords should be used.
2021-07-29 08:10:20 -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
Takashi Kokubun e1b03b0c2b
Enable VM_ASSERT in --jit CIs (#4543) 2021-06-01 00:15:51 -07:00
Alan Wu 636d4f7eb9 Avoid setting the visibility of refinement method entries
Since refinement search is always performed, these entries should always
be public. The method entry that the refinement search returns decides
the visibility.

Fixes [Bug #17822]
2021-05-21 12:12:31 -04: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
Nobuyoshi Nakada 0bbab1e515
Protoized old pre-ANSI K&R style declarations and definitions 2021-05-07 00:04:36 +09:00
Jeremy Evans 4b36a597f4 Fix setting method visibility for a refinement without an origin class
If a class has been refined but does not have an origin class,
there is a single method entry marked with VM_METHOD_TYPE_REFINED,
but it contains the original method entry.  If the original method
entry is present, we shouldn't skip the method when searching even
when skipping refined methods.

Fixes [Bug #17519]
2021-04-23 16:31:18 -07:00
Jeremy Evans 58660e9434 Skip refined method when exporting methods with changed visibility
Previously, attempting to change the visibility of a method in a
singleton class for a class/module that is prepended to and refined
would raise a NoMethodError.

Fixes [Bug #17519]
2021-03-16 12:10:11 -07:00
Koichi Sasada 9c769575bf invalidate negative cache any time.
negative cache on a class which does not have subclasses was not
invalidated, but it should be invalidated because other classes
can cache this negative cache.
[Bug #17553]
2021-02-19 16:54:31 +09:00
Jeremy Evans 49d3830f44 Fix documentation for Module#ruby2_keywords
It returns nil, not self.

Fixes [Bug #17560]
2021-02-09 14:47:36 -08:00
Nobuyoshi Nakada 71c746379d Make alias for aliased original method
Chaining aliased methods increases searching cost linearly.
2021-02-03 19:59:35 +09:00
Nobuyoshi Nakada ea47a9506a
Adjusted indent [ci skip] 2021-02-03 13:42:03 +09: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
Koichi Sasada 1ecda21366 global call-cache cache table for rb_funcall*
rb_funcall* (rb_funcall(), rb_funcallv(), ...) functions invokes
Ruby's method with given receiver. Ruby 2.7 introduced inline method
cache with static memory area. However, Ruby 3.0 reimplemented the
method cache data structures and the inline cache was removed.

Without inline cache, rb_funcall* searched methods everytime.
Most of cases per-Class Method Cache (pCMC) will be helped but
pCMC requires VM-wide locking and it hurts performance on
multi-Ractor execution, especially all Ractors calls methods
with rb_funcall*.

This patch introduced Global Call-Cache Cache Table (gccct) for
rb_funcall*. Call-Cache was introduced from Ruby 3.0 to manage
method cache entry atomically and gccct enables method-caching
without VM-wide locking. This table solves the performance issue
on multi-ractor execution.
[Bug #17497]

Ruby-level method invocation does not use gccct because it has
inline-method-cache and the table size is limited. Basically
rb_funcall* is not used frequently, so 1023 entries can be enough.
We will revisit the table size if it is not enough.
2021-01-29 16:22:12 +09:00
Nobuyoshi Nakada 8dfae85adb
Warn the defined location as deprecation as well as the main message
[Bug #17575]
2021-01-23 19:58:39 +09:00
Nobuyoshi Nakada eeacdcb9a0 Fixed premature return
After setting ruby2_keywords for bmethod, the rest of arguments
had been ignored. [Bug #17558]
2021-01-19 17:59:37 +09:00
Alan Wu e812b36205 Fix typo: invaldate -> invalidate 2021-01-18 14:02:19 -05:00
Aaron Patterson 0ed71b37fa Don't try to clear cache on garbage objects
Method cache can be cleared during lazy sweeping.  An object that will
be collected during lazy sweep *should not* have it's method cache
cleared.  Soon-to-be-collected objects can be in an inconsistent state and
this can lead to a crash.  This patch just leaves early if the object is
going to be collected.

Fixes [Bug #17536]

Co-Authored-By: John Hawthorn <john@hawthorn.email>
Co-Authored-By: Alan Wu <XrXr@users.noreply.github.com>
2021-01-15 15:23:16 -08:00
Koichi Sasada f4ce78d5c1 delete negative cache from the table correctly
negative cache entry should be removed from
vm->negative_cme_table even if the redefined class has no
subclasses.
2021-01-14 09:06:39 +09:00
Nobuyoshi Nakada 85b5d4c8bf Revert "[Bug #11213] let defined?(super) call respond_to_missing?"
This reverts commit fac2498e02 for
now, due to [Bug #17509], the breakage in the case `super` is
called in `respond_to?`.
2021-01-13 18:11:46 +09:00
Marcus Stollsteimer 0a867315e8 [DOC] Fix typos in vm_method.c 2020-12-26 22:50:55 +01:00
Yusuke Endoh 3a81daaf8d Module#public_class_method also accepts a symbol array as an argument
I'm unsure if this is intentional, but add a document anyway.
[Feature #17314]
2020-12-24 00:15:29 +09:00
Koichi Sasada 02d9524cda separate rb_ractor_pub from rb_ractor_t
separate some fields from rb_ractor_t to rb_ractor_pub and put it
at the beggining of rb_ractor_t and declare it in vm_core.h so
vm_core.h can access rb_ractor_pub fields.

Now rb_ec_ractor_hooks() is a complete inline function and no
MJIT related issue.
2020-12-22 00:03:00 +09:00
Radosław Bułat eb8ea336d3 Feature 17314: allow to pass array to public, protected and private methods 2020-12-19 18:19:49 +09:00
Radosław Bułat 51bcd50915 Feature 17314: alias_method returns symbol 2020-12-19 12:23:58 +09:00
Koichi Sasada 04d62e6f62 fix method cache debug tool 2020-12-19 04:33:04 +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
Yusuke Endoh 982443e6e3 Revert "Better cooperation between public/protected/private with attr* and alias_method"
This reverts commit 81739ad4fd.
2020-12-18 16:08:55 +09:00
Yusuke Endoh c4e50b58d1 Revert "Added missing tests for public, private, protected and alias_method"
This reverts commit e042e8460b.
2020-12-18 16:08:24 +09:00
Nobuyoshi Nakada e042e8460b
Added missing tests for public, private, protected and alias_method 2020-12-18 12:59:01 +09:00
Radosław Bułat 81739ad4fd Better cooperation between public/protected/private with attr* and alias_method 2020-12-17 12:46:02 -05:00
Koichi Sasada c37ba2c547 add ccs_not_found debug counter
ccs_not_found to count not found in ccs table.
2020-12-14 18:17:35 +09:00
Koichi Sasada 53edb27bac use method cache on Object#respond_to?
rb_method_boundp (method_boundp) searches method_entry, but this
search did not use pCMC, so change to use it.
2020-12-14 15:28:09 +09:00
Koichi Sasada a8aa169b8f add cc_invalidate_negative debug counter
counts for invalidating negative cache.
2020-12-14 11:57:46 +09:00
Koichi Sasada 967040ba59 Introduce negative method cache
pCMC doesn't have negative method cache so this patch  implements it.
2020-12-14 11:57:46 +09:00
Koichi Sasada 182fb73c40 rb_ext_ractor_safe() to declare ractor-safe ext
C extensions can violate the ractor-safety, so only ractor-safe
C extensions (C methods) can run on non-main ractors.
rb_ext_ractor_safe(true) declares that the successive
defined methods are ractor-safe. Otherwiwze, defined methods
checked they are invoked in main ractor and raise an error
if invoked at non-main ractors.

[Feature #17307]
2020-12-01 15:44:18 +09:00
Nobuyoshi Nakada fac2498e02 [Bug #11213] let defined?(super) call respond_to_missing? 2020-11-20 16:04:45 +09:00
Alan Wu c56fdaecc4 Revert assert for debugging on CI
This reverts commit ac69849e49.
The bug seems to have been fixed.
2020-10-26 16:44:15 -04:00
Stefan Stüben 8c2e5bbf58 Don't redefine #rb_intern over and over again 2020-10-21 12:45:18 +09:00
Aaron Patterson b9488accf9 Fix ASAN support when invalidating CCs
Again, this code is walking the heap.  Empty slots can be poisoned, so
we need to unpoison before checking the type
2020-09-28 08:20:23 -07:00
Koichi Sasada caaa36b4e6 prohibi method call by defined_method in other racotrs
We can not call a non-isolated Proc in multiple ractors.
2020-09-25 20:37:38 +09:00
Koichi Sasada ea78960ee5 sync callable_method_entry()
callable_method_entry() read/write method table structures so that
this function should be synchronized between Ractors.
2020-09-10 18:44:02 +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
Alan Wu ac69849e49 Enable an assert on all configs for debugging
I'm trying to get a better understanding for rare crashes that happen on
ci:
 - http://ci.rvm.jp/results/trunk_clang_10@silicon-docker/3101898
 - http://ci.rvm.jp/results/trunk-test@ruby-sky1/2777695

Looking at the stack trace it looks like a type confusion possibly
induced by heap corruption. I'm hoping to verify this theory.
2020-08-01 23:05:19 -04:00
Nobuyoshi Nakada d637208abd
Fixed a typo 2020-07-19 23:13:21 +09:00
Nobuyoshi Nakada 1351374bd1
Split visibility cases 2020-06-30 19:12:05 +09:00
Jeremy Evans b6d6b89615 Allow refining a frozen class
Doing so modifies the class's method table, but not in a way that should
be detectable from Ruby, so it may be safe to avoid checking if the
class is frozen.

Fixes [Bug #11669]
2020-06-18 08:22:40 -07:00
Nobuyoshi Nakada 184f78314e Properly resolve refinements in defined? on private call [Bug #16932] 2020-06-04 02:12:57 +09:00
Nobuyoshi Nakada 8340c773e5 Properly resolve refinements in defined? on method call [Bug #16932] 2020-06-04 02:12:57 +09: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
Nobuyoshi Nakada 74c8aaef7d
Just call search_method_protect [Bug #16669] 2020-04-23 10:24:49 +09:00
Koichi Sasada 8119bcbfc0 rb_method_entry() returns valid me.
search_method() can return invalid method, but vm_defined() checks
it as valid method entry. This is why defined?(foo) if foo is undef'ed.
To solve this problem, check invalidation and return NULL.
[Bug #16669]
https://twitter.com/kamipo/status/1252881930103558144

Tests will be merged by nobu soon.
2020-04-23 02:21:38 +09:00
Nobuyoshi Nakada e474c189da
Suppress -Wswitch warnings 2020-04-08 15:13:37 +09:00
Jeremy Evans adecd43197
Merge pull request #2721 from jeremyevans/method-inspect-chain-alias-11188
Correctly show defined class for aliases of aliases
2020-03-22 09:30:20 -07:00
Koichi Sasada 2943ff9d44 fix bug on method cache invalidation.
To invalidate cached method entry, existing method entry (ment)
is marked as invalidated and replace with copied ment. However,
complemented method entry (method entries in Module) should not
be set to Module's m_tbl.
[Bug #16669]
2020-03-11 02:50:44 +09:00
卜部昌平 aa44b29030 suppress uninitialized variable warnings
Starting GCC 7, warnings about uninitialized variables are issued around
them.  Such warnings could be false positives (all versions of clang do
not warn), but adding initializers there could never be bad things.
2020-03-04 12:30:42 +09:00
卜部昌平 f12b9a3338 %p is for void *
See also
35eb12c063
6f5eb28507
687308cf0d
b6a2d63eb3
2020-03-04 12:30:42 +09: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
Koichi Sasada f2286925f0 VALUE size packed callinfo (ci).
Now, rb_call_info contains how to call the method with tuple of
(mid, orig_argc, flags, kwarg). Most of cases, kwarg == NULL and
mid+argc+flags only requires 64bits. So this patch packed
rb_call_info to VALUE (1 word) on such cases. If we can not
represent it in VALUE, then use imemo_callinfo which contains
conventional callinfo (rb_callinfo, renamed from rb_call_info).

iseq->body->ci_kw_size is removed because all of callinfo is VALUE
size (packed ci or a pointer to imemo_callinfo).

To access ci information, we need to use these functions:
vm_ci_mid(ci), _flag(ci), _argc(ci), _kwarg(ci).

struct rb_call_info_kw_arg is renamed to rb_callinfo_kwarg.

rb_funcallv_with_cc() and rb_method_basic_definition_p_with_cc()
is temporary removed because cd->ci should be marked.
2020-02-22 09:58:59 +09:00
卜部昌平 6788c375b1 suppress clang warnings
Starting clang 11, casts between pointer and (narrower-than-pointer) int
are now warned.  However all such thing in our repository are guaranteed
safe.  Let's suppress the warnings.
2020-02-20 11:46:54 +09:00
卜部昌平 97d75639a9 VALUE is narrower than rb_serial_t
VALUE and rb_serial_t do not agree with their width.  We have to be
consistent.  Assigning an rb_serial_t value to a VALUE variable is
practically a problem on a ILP32 environment.
2020-01-21 14:21:15 +09:00
Nobuyoshi Nakada 34bc15c86b
Check Module#ruby2_keywords arity
It is considered a mistake, because calling this method with no
arguments has no effect.
2020-01-02 10:41:24 +09:00
卜部昌平 f054f11a38 per-method serial number
Methods and their definitions can be allocated/deallocated on-the-fly.
One pathological situation is when a method is deallocated then another
one is allocated immediately after that.  Address of those old/new method
entries/definitions can be the same then, depending on underlying
malloc/free implementation.

So pointer comparison is insufficient.  We have to check the contents.
To do so we introduce def->method_serial, which is an integer unique to
that specific method definition.

PS: Note that method_serial being uintptr_t rather than rb_serial_t is
intentional.  This is because rb_serial_t can be bigger than a pointer
on a 32bit system (rb_serial_t is at least 64bit).  In order to preserve
old packing of struct rb_call_cache, rb_serial_t is inappropriate.
2019-12-18 12:52:28 +09:00
John Hawthorn 254477248c Skip optimized method check for most method IDs
Previously every time a method was defined on a module, we would
recursively walk all subclasses to see if the module was included in a
class which the VM optimizes for (such as Integer#+).

For most method definitions we can tell immediately that this won't be
the case based on the method's name. To do this we just keep a hash with
method IDs of optimized methods and if our new method isn't in that list
we don't need to check subclasses at all.
2019-12-17 09:19:00 -08:00
John Hawthorn 9245462499 Replace debug test with assertion
It's a Ruby bug if this ever happens check it as an assertion instead of
paying the cost of the check every time.
2019-12-17 09:19:00 -08:00
John Hawthorn a01d22b8c1 Check type with BUILTIN_TYPE in method cache clear
We know that this is a heap-allocated object (a CLASS, MODULE, or
ICLASS) so we don't need to check if it is an immediate value. This
should be very slightly faster.
2019-12-17 09:19:00 -08:00
John Hawthorn 8e56d3a6ab Define PREV_CLASS_SERIAL
Avoids genereating a "throwaway" sentinel class serial. There wasn't any
read harm in doing so (we're at no risk of exhaustion and there'd be no
measurable performance impact), but if feels cleaner that all class
serials actually end up assigned and used (especially now that we won't
overwrite them in a single method definition).
2019-12-17 09:19:00 -08:00
John Hawthorn d7a50a5cc6 Avoid revisiting seen nodes clearing method cache
rb_clear_method_cache_by_class calls rb_class_clear_method_cache
recursively on subclasses, where it will bump the class serial and clear
some other data (callable_m_tbl, and some mjit data).

Previously this could end up taking a long time to clear all the classes
if the module was included a few levels deep and especially if there
were multiple paths to it in the dependency tree (ie. a class includes
two modules which both include the same other module) as we end up
revisiting class/iclass/module objects multiple times.

This commit avoids revisiting the same object, by short circuiting when
revisit the same object. We can check this efficiently by comparing the
class serial of each object we visit with the next class serial at the
start. We know that any objects with a higher class serial have already
been visited.
2019-12-17 09:19:00 -08:00
Yusuke Endoh 3a87826d0c vm_method.c: add top-level ruby2_keywords
This is a top-level version of Module#ruby2_keywords.
It can be used for functions (top-level methods) that delegates
arguments.  [Feature #16364]
2019-11-29 16:51:13 +09:00
Jeremy Evans f9debf3437 Update documentation for ruby2_keywords [ci skip] 2019-11-27 15:13:35 -08:00
卜部昌平 0e8219f591 make functions static
These functions are used from within a compilation unit so we can
make them static, for better binary size.  This changeset reduces
the size of generated ruby binary from 26,590,128 bytes to
26,584,472 bytes on my macihne.
2019-11-19 12:36:19 +09:00