aboutsummaryrefslogtreecommitdiffstats
path: root/vm_method.c
Commit message (Collapse)AuthorAgeFilesLines
* make functions static卜部昌平2019-11-191-0/+1
| | | | | | | 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.
* rb_method_basic_definition_p with CC卜部昌平2019-11-051-0/+18
| | | | | | | | | | | | | | | | | | | Noticed that rb_method_basic_definition_p is frequently called. Its callers include vm_caller_setup_args_block(), rb_hash_default_value(), rb_num_neative_int_p(), and a lot more. It seems worth caching the method resolution part. Majority of rb_method_basic_definion_p() usages take fixed class and fixed method id combinations. Calculating ------------------------------------- ours trunk so_matrix 2.379 2.115 i/s - 1.000 times in 0.420409s 0.472879s Comparison: so_matrix ours: 2.4 i/s trunk: 2.1 i/s - 1.12x slower
* Warn for calling public/protected/private/module_function without arguments ↵Jeremy Evans2019-10-161-1/+14
| | | | | | | | | inside method Calling these methods without an argument does not have the desired effect inside a method. Fixes [Bug #13249]
* Allow ruby2_keywords to be used with bmethodsJeremy Evans2019-10-071-9/+37
| | | | | | | | There are libraries that use define_method with argument splats where they would like to pass keywords through the method. To more easily allow such libraries to use ruby2_keywords to handle backwards compatibility, it is necessary for ruby2_keywords to support bmethods.
* Revert https://github.com/ruby/ruby/pull/2486卜部昌平2019-10-031-357/+213
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commits: 10d6a3aca7 8ba48c1b85 fba8627dc1 dd883de5ba 6c6a25feca 167e6b48f1 7cb96d41a5 3207979278 595b3c4fdd 1521f7cf89 c11c5e69ac cf33608203 3632a812c0 f56506be0d 86427a3219 . The reason for the revert is that we observe ABA problem around inline method cache. When a cache misshits, we search for a method entry. And if the entry is identical to what was cached before, we reuse the cache. But the commits we are reverting here introduced situations where a method entry is freed, then the identical memory region is used for another method entry. An inline method cache cannot detect that ABA. Here is a code that reproduce such situation: ```ruby require 'prime' class << Integer alias org_sqrt sqrt def sqrt(n) raise end GC.stress = true Prime.each(7*37){} rescue nil # <- Here we populate CC class << Object.new; end # These adjacent remove-then-alias maneuver # frees a method entry, then immediately # reuses it for another. remove_method :sqrt alias sqrt org_sqrt end Prime.each(7*37).to_a # <- SEGV ```
* rb_method_attr_t::location should be 0 or others.Koichi Sasada2019-09-301-2/+2
| | | | | method_def_location() expects that rb_method_attr_t::location is 0 (Qfalse) or not.
* refactor constify most of rb_method_entry_t卜部昌平2019-09-301-55/+63
| | | | | | | | | | | Now that we have eliminated most destructive operations over the rb_method_entry_t / rb_callable_method_entry_t, let's make them mostly immutabe and mark them const. One exception is rb_export_method(), which destructively modifies visibilities of method entries. I have left that operation as is because I suspect that destructiveness is the nature of that function.
* refactor add rb_method_entry_from_template卜部昌平2019-09-301-34/+58
| | | | | | Tired of rb_method_entry_create(..., rb_method_definition_create( ..., &(rb_method_foo_t) {...})) maneuver. Provide a function that does the thing to reduce copy&paste.
* refactor reduce METHOD_ENTRY_FLAGS_COPY卜部昌平2019-09-301-16/+33
| | | | Make things more immutable.
* refactor delete rb_method_entry_copy卜部昌平2019-09-301-11/+0
| | | | | | The deleted function was to destructively overwrite existing method entries, which is now considered to be a bad idea. Delete it, and assign a newly created method entry instead.
* refactor delete rb_method_definition_set卜部昌平2019-09-301-10/+21
| | | | | Instead of destructively write fields of method entries, create a new entry and let it overwrite its owner.
* refactor rb_method_definition_create take opts卜部昌平2019-09-301-42/+34
| | | | | | | Before this changeset rb_method_definition_create only allocated a memory region and we had to destructively initialize it later. That is not a good design so we change the API to return a complete struct instead.
* refactor split rb_method_definition_set卜部昌平2019-09-301-92/+202
| | | | | | | | | | | Did you know that C functions can return structs? That has been true since the beginning, but not that very useful until C99. Now that we can write compound literals, this feature is much easier to use. By allowing struct-returning functions, some formerly big functions can be split into smaller ones, like this changeset. At least GCC is smart enough to inline the split functions back into one. No performance penalty is observed.
* refactor constify most of rb_method_definition_t卜部昌平2019-09-301-41/+39
| | | | | | Most (if not all) of the fields of rb_method_definition_t are never meant to be modified once after they are stored. Marking them const makes it possible for compilers to warn on unintended modifications.
* refactor delete METHOD_ENTRY_COMPLEMENTED flag卜部昌平2019-09-301-10/+5
| | | | | Because rb_method_definition_t tracks its own complemented_count, we no longer have to check it in rb_method_entry_t side.
* Add Module#ruby2_keywords for passing keywords through regular argument splatsJeremy Evans2019-09-251-0/+79
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This approach uses a flag bit on the final hash object in the regular splat, as opposed to a previous approach that used a VM frame flag. The hash flag approach is less invasive, and handles some cases that the VM frame flag approach does not, such as saving the argument splat array and splatting it later: ruby2_keywords def foo(*args) @args = args bar end def bar baz(*@args) end def baz(*args, **kw) [args, kw] end foo(a:1) #=> [[], {a: 1}] foo({a: 1}, **{}) #=> [[{a: 1}], {}] foo({a: 1}) #=> 2.7: [[], {a: 1}] # and warning foo({a: 1}) #=> 3.0: [[{a: 1}], {}] It doesn't handle some cases that the VM frame flag handles, such as when the final hash object is replaced using Hash#merge, but those cases are probably less common and are unlikely to properly support keyword argument separation. Use ruby2_keywords to handle argument delegation in the delegate library.
* Call rb_vm_call_kw insted of rb_vm_call0 in a few casesJeremy Evans2019-09-201-3/+1
| | | | | | | | | | rb_vm_call_kw handles the tmp buffer for you. Also, change method_missing so it also calls rb_vm_call_kw to handle the kw_splat flag, instead of requiring callers to handle kw_splat flag before calling method_missing. This may fix other cases where method_missing is currently called without the kw_splat being handled.
* Make passing empty keywords to dig pass empty keywords to next dig methodJeremy Evans2019-09-201-5/+7
| | | | | | | | | | | | | | | | If defined in Ruby, dig would be defined as def dig(arg, *rest) end, it would not use keywords. If the last dig argument was an empty hash, it could be treated as keyword arguments by the next dig method. Allow dig to pass along the empty keyword flag if called with an empty keyword, to suppress the previous behavior and force treating the hash as a positional argument and not keywords. Also handle the case where dig calls method_missing, passing the empty keyword flag to that as well. This requires adding rb_check_funcall_with_hook_kw functions, so that dig can specify how arguments are treated. It also adds kw_splat arguments to a couple static functions.
* Add rb_funcall_with_block_kwJeremy Evans2019-09-051-1/+1
| | | | | | | | | | | | | | | | | This is needed for C functions to call methods with keyword arguments. This is a copy of rb_funcall_with_block with an extra argument for the keyword flag. There isn't a clean way to implement this that doesn't involve changing a lot of function signatures, because rb_call doesn't support a way to mark that the call has keyword arguments. So hack this in using a CALL_PUBLIC_KW call_type, which we switch for CALL_PUBLIC later in the call stack. We do need to modify rm_vm_call0 to take an argument for whether keyword arguments are used, since the call_type is no longer available at that point. Use the passed in value to set the appropriate keyword flag in both calling and ci_entry.
* drop-in type check for rb_define_private_method卜部昌平2019-08-291-2/+2
| | | | | | | We can check the function pointer passed to rb_define_private_method like how we do so in rb_define_method. Doing so revealed some problematic usages of rb_obj_dummy. They had to be split according to their arity.
* drop-in type check for rb_define_method卜部昌平2019-08-291-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The rb_define_method function takes a pointer to ANYARGS-ed functions, which in fact varies 18 different prototypes. We still need to preserve ANYARGS for storages but why not check the consistencies if possible. Q&As: Q: Where did the magic number "18" came from in the description above? A: Count the case branch of vm_method.c:call_cfunc_invoker_func(). Note also that the 18 branches has lasted for at least 25 years. See also 200e0ee2fd3c1c006c528874a88f684447215524. Q: What is this __weakref__ thing? A: That is a kind of function overloading mechanism that GCC provides. In this case for instance rb_define_method0 is an alias of rb_define_method, with a strong type. Q: What is this __transparent_union__ thing? A: That is another kind of function overloading mechanism that GCC provides. In this case the attributed function pointer is either VALUE(*)(int,VALUE*,VALUE) or VALUE(*)(int,const VALUE*,VALUE). This is better than void* or ANYARGS because we can reject all other possibilities than the two. Q: What does this rb_define_method macro mean? A: It selects appropriate alias of the rb_define_method function, depending on the arity. Q: Why the prototype change of rb_f_notimplement? A: Function pointer to rb_f_notimplement is special cased in vm_method.c:rb_add_method_cfunc(). That should be handled by the __builtin_choose_expr chain inside of rb_define_method macro expansion. In order to do so, comparison like (func == rb_f_notimplement) is inappropriate for __builtin_choose_expr's expression (which must be a compile-time integer constant but the address of rb_f_notimplement is not fixed until the linker). So instead we are using __builtin_types_compatible_p, and in doing so we need to distinguish rb_f_notimplement from others, by type.
* Ensure non-OPT_GLOBAL_METHOD_CACHE code validNobuyoshi Nakada2019-08-181-4/+3
|
* Ensure VM_DEBUG_VERIFY_METHOD_CACHE code validNobuyoshi Nakada2019-08-181-4/+1
|
* Make attr* methods define public methods if self in caller is not same as ↵Jeremy Evans2019-08-011-1/+3
| | | | | | | | | | | | receiver Previously, attr* methods could be private even if not in the private section of a class/module block. This uses the same approach that ruby started using for define_method in 1fc33199736f316dd71d0c551edbf514528ddde6. Fixes [Bug #4537]
* * expand tabs.svn2019-04-101-2/+2
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67500 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Reverting all commits from r67479 to r67496 because of CI failureskazu2019-04-101-1/+6
| | | | | | | | Because hard to specify commits related to r67479 only. So please commit again. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_method.c: fix a warningnobu2019-04-101-6/+1
| | | | | | | | * vm_method.c (rb_add_method_iseq): use rb_method_iseq_t, as rb_method_definition_set refers, with a cast to suppress a warning. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67494 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Adding `GC.compact` and compacting GC support.tenderlove2019-04-091-1/+1
| | | | | | | | | | | This commit adds the new method `GC.compact` and compacting GC support. Please see this issue for caveats: https://bugs.ruby-lang.org/issues/15626 [Feature #15626] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67479 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* `rb_add_method` is void function.ko12019-04-051-4/+2
| | | | | | | | * method.h (rb_add_method): make it void function because nobody use a return value. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * expand tabs.svn2019-04-051-2/+2
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67443 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* add definemethod/definesmethod insn.ko12019-04-051-31/+4
| | | | | | | | | | | | | | | | | | | | | * insns.def: add definemethod and definesmethod (singleton method) instructions. Old YARV contains these instructions, but it is moved to methods of FrozenCore class because remove number of instructions can improve performance for some techniques (static stack caching and so on). However, we don't employ these technique and it is hard to optimize/analysis definition sequence. So I decide to introduce them (and remove definition methods). `putiseq` insn is also removed. * vm_method.c (rb_scope_visibility_get): renamed to `vm_scope_visibility_get()` and make it accept `ec`. Same for `vm_scope_module_func_check()`. These fixes are result of refactoring `vm_define_method`. * vm_insnhelper.c (rb_vm_get_cref): renamed to `vm_get_cref` because of consistency with other functions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67442 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* [DOC] Fix method references to Method instance methodsnobu2019-03-281-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67355 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* [DOC] fix markups [ci skip]nobu2019-03-281-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67354 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* change `cfunc->invoker` type for opt.ko12019-02-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | * vm_insnhelper.c: change `call_cfunc_*` parameters order and specify a function type for the passed func ptr. This fix reduce the number of asm instructions, such as: # before this patch 0000000000000110 <call_cfunc_0>: 110: 48 89 fa mov %rdi,%rdx 113: 31 c0 xor %eax,%eax 115: 48 89 f7 mov %rsi,%rdi 118: ff e2 jmpq *%rdx 11a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) # after this patch 0000000000000110 <call_cfunc_0>: 110: ff e1 jmpq *%rcx However, this kind of instruction reduction doesn't affect any performance because of great CPU architectures :p git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67122 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Add refinements support to method/instance_method.nobu2019-01-281-0/+6
| | | | | | | | [Fix GH-2034] From: manga_osyo <manga.osyo@gmail.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66935 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Fix styles [ci skip]nobu2019-01-091-1/+2
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66762 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Constified to fix warning at r66442nobu2018-12-181-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * expand tabs.svn2018-12-181-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66443 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Expand cross-recursion to a loopnobu2018-12-181-30/+17
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66442 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Enable refinements on symbol-proc in ruby-level methodsnobu2018-12-181-1/+1
| | | | | | | | | | | | | | * vm_args.c (refine_sym_proc_call): resolve refinements when the proc is invoked, instead of resolving at making the proc, to enable refinements on symbol-proc in ruby-level methods * vm.c (vm_cref_dup): clear cached symbol-procs when duplicating. [Bug #15114] [Fix GH-2039] From: manga_osyo <manga.osyo@gmail.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66439 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Warn redefinitions of some methods on Objectnobu2018-12-061-2/+8
| | | | | | [Bug #5473] [Bug #14670] [Bug #15382] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66262 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Revert "Symbol refinements"mrkn2018-12-041-1/+1
| | | | | | Due to assertion failures when VM_CHECK_MODE >= 2. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66182 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Symbol refinementsmrkn2018-12-041-1/+1
| | | | | | | | | * vm_args.c (refine_sym_proc_call): enalbe accidentally disabled refinements in Symbol#to_proc. [Bug #15114] From: osyo (manga osyo) <manga.osyo@gmail.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66181 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Revert "Symbol refinements"nobu2018-12-031-1/+1
| | | | | | Due to assertion failures when VM_CHECK_MODE >= 2. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Symbol refinementsnobu2018-12-031-1/+1
| | | | | | | | | * vm_args.c (refine_sym_proc_call): enalbe accidentally disabled refinements in Symbol#to_proc. [Bug #15114] From: osyo (manga osyo) <manga.osyo@gmail.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66151 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Revert "Symbol refinements [Bug #15114]"nobu2018-12-031-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66150 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Symbol refinements [Bug #15114]nobu2018-12-031-1/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66149 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * expand tabs.svn2018-11-261-5/+5
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66004 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Support targetting TracePoint [Feature #15289]ko12018-11-261-6/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * vm_trace.c (rb_tracepoint_enable_for_target): support targetting TracePoint. [Feature #15289] Tragetting TracePoint is only enabled on specified method, proc and so on, example: `tp.enable(target: code)`. `code` should be consisted of InstructionSeuqnece (iseq) (RubyVM::InstructionSeuqnece.of(code) should not return nil) If code is a tree of iseq, TracePoint is enabled on all of iseqs in a tree. Enabled tragetting TracePoints can not enabled again with and without target. * vm_core.h (rb_iseq_t): introduce `rb_iseq_t::local_hooks` to store local hooks. `rb_iseq_t::aux::trace_events` is renamed to `global_trace_events` to contrast with `local_hooks`. * vm_core.h (rb_hook_list_t): add `rb_hook_list_t::running` to represent how many Threads/Fibers are used this list. If this field is 0, nobody using this hooks and we can delete it. This is why we can remove code from cont.c. * vm_core.h (rb_vm_t): because of above change, we can eliminate `rb_vm_t::trace_running` field. Also renamed from `rb_vm_t::event_hooks` to `global_hooks`. * vm_core.h, vm.c (ruby_vm_event_enabled_global_flags): renamed from `ruby_vm_event_enabled_flags. * vm_core.h, vm.c (ruby_vm_event_local_num): added to count enabled targetting TracePoints. * vm_core.h, vm_trace.c (rb_exec_event_hooks): accepts hook list. * vm_core.h (rb_vm_global_hooks): added for convinience. * method.h (rb_method_bmethod_t): added to maintain Proc and `rb_hook_list_t` for bmethod (defined by define_method). * prelude.rb (TracePoint#enable): extracet a keyword parameter (because it is easy than writing in C). It calls `TracePoint#__enable` internal method written in C. * vm_insnhelper.c (vm_trace): check also iseq->local_hooks. * vm.c (invoke_bmethod): check def->body.bmethod.hooks. * vm.c (hook_before_rewind): check iseq->local_hooks and def->body.bmethod.hooks before rewind by exception. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66003 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Enable refinements at Object#respond_to?nobu2018-11-221-1/+8
| | | | | | | | [Feature #15327] [Fix GH-2020] From: osyo-manga <manga.osyo@gmail.com> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e