510 Commits

Author SHA1 Message Date
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 ceebc7fc98d
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 84ab77ba592.  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 fac2498e0299f13dffe4f09a7dd7657fb49bf643 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 81739ad4fdfcc86a769056fec352f27c686fba1b.
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 e042e8460bb9a63c05f938d51e8c7c5345a6f3a4.
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 ac69849e49982ea83036c04c5d5f7245e3956a49.
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