aboutsummaryrefslogtreecommitdiffstats
path: root/vm_eval.c
Commit message (Collapse)AuthorAgeFilesLines
* Add ISEQ_BODY macroPeter Zhu2022-03-241-4/+4
| | | | | | 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.
* Lazily create singletons on instance_{exec,eval} (#5146)John Hawthorn2021-12-021-37/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Lazily create singletons on instance_{exec,eval} Previously when instance_exec or instance_eval was called on an object, that object would be given a singleton class so that method definitions inside the block would be added to the object rather than its class. This commit aims to improve performance by delaying the creation of the singleton class unless/until one is needed for method definition. Most of the time instance_eval is used without any method definition. This was implemented by adding a flag to the cref indicating that it represents a singleton of the object rather than a class itself. In this case CREF_CLASS returns the object's existing class, but in cases that we are defining a method (either via definemethod or VM_SPECIAL_OBJECT_CBASE which is used for undef and alias). This also happens to fix what I believe is a bug. Previously instance_eval behaved differently with regards to constant access for true/false/nil than for all other objects. I don't think this was intentional. String::Foo = "foo" "".instance_eval("Foo") # => "foo" Integer::Foo = "foo" 123.instance_eval("Foo") # => "foo" TrueClass::Foo = "foo" true.instance_eval("Foo") # NameError: uninitialized constant Foo This also slightly changes the error message when trying to define a method through instance_eval on an object which can't have a singleton class. Before: $ ruby -e '123.instance_eval { def foo; end }' -e:1:in `block in <main>': no class/module to add method (TypeError) After: $ ./ruby -e '123.instance_eval { def foo; end }' -e:1:in `block in <main>': can't define singleton (TypeError) IMO this error is a small improvement on the original and better matches the (both old and new) message when definging a method using `def self.` $ ruby -e '123.instance_eval{ def self.foo; end }' -e:1:in `block in <main>': can't define singleton (TypeError) Co-authored-by: Matthew Draper <matthew@trebex.net> * Remove "under" argument from yield_under * Move CREF_SINGLETON_SET into vm_cref_new * Simplify vm_get_const_base * Fix leaf VM_SPECIAL_OBJECT_CONST_BASE Co-authored-by: Matthew Draper <matthew@trebex.net>
* fix to choose correct callcacheKoichi Sasada2021-11-261-4/+9
| | | | | | | | It should retun general `cc`, not for overloaded (mandatory only) method call cache. This issue is reported by @shugo and @ktou https://twitter.com/shugomaeda/status/1463699797182119936
* Fix setting struct member by public_sendNobuyoshi Nakada2021-11-211-2/+2
|
* optimize `Struct` getter/setterKoichi Sasada2021-11-191-16/+23
| | | | | Introduce new optimized method type `OPTIMIZED_METHOD_TYPE_STRUCT_AREF/ASET` with index information.
* `rb_method_optimized_t` for further extensionKoichi Sasada2021-11-191-2/+2
| | | | | Now `rb_method_optimized_t optimized` field is added to represent optimized method type.
* `Primitive.mandatory_only?` for fast pathKoichi Sasada2021-11-151-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Introduce rb_vm_call_with_refinements to DRY up a few callsJeremy Evans2021-10-011-0/+14
|
* Refactor rb_call_super functionS-H-GAMELINKS2021-09-251-3/+1
|
* Add gvl and fiber assertions to scheduler interface to catch invalid usage.Samuel Williams2021-09-201-0/+2
|
* Extract hook macro for attributesNobuyoshi Nakada2021-09-191-20/+6
|
* include/ruby/internal/intern/vm.h: add doxygen卜部昌平2021-09-101-8/+0
| | | | Must not be a bad idea to improve documents. [ci skip]
* include/ruby/internal/eval.h: add doxygen卜部昌平2021-09-101-58/+1
| | | | Must not be a bad idea to improve documents. [ci skip]
* Support tracing of attr_reader and attr_writerJeremy Evans2021-08-291-2/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | In vm_call_method_each_type, check for c_call and c_return events before dispatching to vm_call_ivar and vm_call_attrset. With this approach, the call cache will still dispatch directly to those functions, so this change will only decrease performance for the first (uncached) call, and even then, the performance decrease is very minimal. This approach requires that we clear the call caches when tracing is enabled or disabled. The approach currently switches all vm_call_ivar and vm_call_attrset call caches to vm_call_general any time tracing is enabled or disabled. So it could theoretically result in a slowdown for code that constantly enables or disables tracing. This approach does not handle targeted tracepoints, but from my testing, c_call and c_return events are not supported for targeted tracepoints, so that shouldn't matter. This includes a benchmark showing the performance decrease is minimal if detectable at all. Fixes [Bug #16383] Fixes [Bug #10470] Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
* [Feature #18045] Remove T_PAYLOADPeter Zhu2021-08-251-1/+0
| | | | | | | This commit removes T_PAYLOAD since the new VWA implementation no longer requires T_PAYLOAD types. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Revert "[Feature #18045] Implement size classes for GC"Peter Zhu2021-08-231-0/+1
| | | | | | This reverts commits 48ff7a9f3e47bffb3e4d067a12ba9b936261caa0 and b2e2cf2dedd104acad8610721db5e4d341f135ef because it is causing crashes in SPARC solaris and i386 debian.
* [Feature #18045] Remove T_PAYLOADPeter Zhu2021-08-231-1/+0
| | | | | | | This commit removes T_PAYLOAD since the new VWA implementation no longer requires T_PAYLOAD types. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Get rid of type-punning pointer casts [Bug #18062]Nobuyoshi Nakada2021-08-111-1/+3
|
* Using RBOOL macroS.H2021-08-021-6/+1
|
* Make RubyVM::AbstractSyntaxTree.of raise for method/proc created in evalJeremy Evans2021-07-291-4/+21
| | | | | | | | | | | This changes Thread::Location::Backtrace#absolute_path to return nil for methods/procs defined in eval. If the realpath of an iseq is nil, that indicates it was defined in eval, in which case you cannot use RubyVM::AbstractSyntaxTree.of. Fixes [Bug #16983] Co-authored-by: Koichi Sasada <ko1@atdot.net>
* Emit deprecatation warnings for rb_iterate()Benoit Daloze2021-07-161-5/+12
| | | | | | * It is obsolete since 1.9, see https://github.com/ruby/ruby/blob/master/doc/extension.rdoc#label-Control+Structure and [Misc #18025]
* Add debug assertion in `rb_funcall*` that the current thread has the gvl.Samuel Williams2021-07-161-0/+4
|
* Refactor rb_block_call functionS.H2021-06-131-8/+3
| | | | rb_block_call and rb_block_call_kw have similar code. So, using rb_block_kw function in rb_block_call function for refactoring.
* Allow newobj_of0 and newobj_slowpath to allocate into multiple heap slotsMatt Valentine-House2021-05-061-0/+1
|
* Removed unnecessary parentheses at `case` [ci skip]Nobuyoshi Nakada2021-02-081-3/+3
|
* use goto intead of recursion on vm_call0_body()Koichi Sasada2021-02-031-1/+16
| | | | | | | | | | | "alias" type method entries can chain another aliased method so that machine stack can be overflow on nested alias chain. http://ci.rvm.jp/results/trunk-repeat20@phosphorus-docker/3344209 This patch fix this issue by use goto instead of recursion if possible. TODO: Essentially, the alias method should not points another aliased method entry. Try to fix it later.
* refactoring rb_method_call_status()Koichi Sasada2021-01-291-29/+26
|
* global call-cache cache table for rb_funcall*Koichi Sasada2021-01-291-69/+219
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Check stack overflow in recursive glob_helper [Bug #17162]Nobuyoshi Nakada2021-01-131-0/+10
|
* [DOC] Fix grammar: "is same as" -> "is the same as"Marcus Stollsteimer2021-01-051-1/+1
|
* Optimize calls to `Kernel#hash` (#3987)Marc-André Lafortune2020-12-251-0/+28
| | | | This avoids recursive checks when the `hash` method of an object isn't specialized.
* Prefer stdbool in vm_execTakashi Kokubun2020-12-211-4/+4
| | | | Make the code a bit modern and consistent with some other places.
* add several debug countersKoichi Sasada2020-12-151-0/+2
| | | | | | | add cc_found_in_ccs (renamed from cc_found_ccs), cc_not_found_in_ccs, call0_public, call0_other debug counters to measure more details. also it contains several modification.
* fix inline method cache sync bugKoichi Sasada2020-12-151-18/+16
| | | | | | | | | `cd` is passed to method call functions to method invocation functions, but `cd` can be manipulated by other ractors simultaneously so it contains thread-safety issue. To solve this issue, this patch stores `ci` and found `cc` to `calling` and stops to pass `cd`.
* use method cache on Object#respond_to?Koichi Sasada2020-12-141-2/+2
| | | | | rb_method_boundp (method_boundp) searches method_entry, but this search did not use pCMC, so change to use it.
* Add description __send__ is saferNARUSE, Yui2020-11-051-2/+4
|
* check isolated Proc more strictlyKoichi Sasada2020-10-291-4/+21
| | | | | Isolated Proc prohibit to access outer local variables, but it was violated by binding and so on, so they should be error.
* Deprecate iterator? methodNobuyoshi Nakada2020-08-311-3/+15
| | | | [Feature #15547] [Fix GH-2071]
* Run method_missing in the same execution contextNobuyoshi Nakada2020-07-061-7/+6
|
* add UNREACHABLE_RETURN卜部昌平2020-06-291-0/+1
| | | | | | 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.
* method_missing: do not goto into a branch卜部昌平2020-06-291-2/+3
| | | | | I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
* rb_method_call_status: do not goto into a branch卜部昌平2020-06-291-2/+3
| | | | | I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
* eliminate C99 compound literals卜部昌平2020-06-091-14/+12
| | | | | Ko1 prefers variables be assgined, instead of bare literals in function arguments.
* rb_vm_call0: on-stack call info卜部昌平2020-06-091-6/+14
| | | | | This changeset reduces the generated binary of rb_vm_call0 from 281 bytes to 211 bytes on my machine. Should reduce GC pressure as well.
* drop varargs.h support卜部昌平2020-05-111-2/+2
| | | | | This header file is simply out of date (for decades since at least 1989). It's the 21st century. Just stop using it.
* Introduce disposable call-cache.Koichi Sasada2020-02-221-24/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* VALUE size packed callinfo (ci).Koichi Sasada2020-02-221-46/+9
| | | | | | | | | | | | | | | | | | | | 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.
* Remove rb_eval_cmdJeremy Evans2020-02-111-7/+0
| | | | | This was related to $SAFE, and was deprecated in 2.7. I missed it earlier when removing the other $SAFE-related code.
* script_compiled event on compile error.Koichi Sasada2020-01-061-6/+8
| | | | | | script_compiled event for TracePoint should not be invoked on compile error (SyntaxError) because it is not "compiled". [Bug #16459]
* Make eval(code, binding) use (eval) as __FILE__ and 1 as __LINE__Jeremy Evans2020-01-031-6/+0
| | | | | | | | | This removes the warning that was added in 3802fb92ff8c83eed3e867db20f72c53932f542d, and switches the behavior so that the eval does not use the binding's __FILE__ and __LINE__ implicitly. Fixes [Bug #4352]