summaryrefslogtreecommitdiff
path: root/iseq.c
AgeCommit message (Collapse)Author
2021-10-03Using NIL_P macro instead of `== Qnil`S.H
Notes: Merged: https://github.com/ruby/ruby/pull/4925 Merged-By: nobu <nobu@ruby-lang.org>
2021-09-05Replace RBOOL macroS-H-GAMELINKS
Notes: Merged: https://github.com/ruby/ruby/pull/4791
2021-08-29Support tracing of attr_reader and attr_writerJeremy Evans
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> Notes: Merged: https://github.com/ruby/ruby/pull/4767
2021-08-03Add keyrest to ruby2_keywords parameters [Bug #18011]Nobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/4705
2021-07-29Make RubyVM::AbstractSyntaxTree.of raise for method/proc created in evalJeremy Evans
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> Notes: Merged: https://github.com/ruby/ruby/pull/4519
2021-06-26iseq.c: Make ast_line_count return 0 when syntax error occurredYusuke Endoh
This broke coverage CI ``` 1) Failure: TestRequire#test_load_syntax_error [/home/runner/work/actions/actions/ruby/test/ruby/test_require.rb:228]: Exception(SyntaxError) with message matches to /unexpected/. [SyntaxError] exception expected, not #<TypeError: no implicit conversion of false into Integer>. ``` https://github.com/ruby/actions/runs/2914743968?check_suite_focus=true
2021-06-18Enable USE_ISEQ_NODE_ID by defaultYusuke Endoh
... which is formally called EXPERIMENTAL_ISEQ_NODE_ID. See also ff69ef27b06eed1ba750e7d9cab8322f351ed245. https://bugs.ruby-lang.org/issues/17930 Notes: Merged: https://github.com/ruby/ruby/pull/4558
2021-06-18Make it possible to get AST::Node from Thread::Backtrace::LocationYusuke Endoh
RubyVM::AST.of(Thread::Backtrace::Location) returns a node that corresponds to the location. Typically, the node is a method call, but not always. This change also includes iseq's dump/load support of node_ids for each instructions. Notes: Merged: https://github.com/ruby/ruby/pull/4558
2021-06-18node.h: Reduce struct size to fit with Ruby object size (five VALUEs)Yusuke Endoh
by merging `rb_ast_body_t#line_count` and `#script_lines`. Fortunately `line_count == RARRAY_LEN(script_lines)` was always satisfied. When script_lines is saved, it has an array of lines, and when not saved, it has a Fixnum that represents the old line_count. Notes: Merged: https://github.com/ruby/ruby/pull/4581
2021-06-02Refactor rb_vm_insn_addr2insn callsTakashi Kokubun
It's been a way too much amount of ifdefs.
2021-05-07compile.c: Pass node instead of nd_line(node) to ADD_INSN* functionsYusuke Endoh
... then, new_insn_core extracts nd_line(node). Also, if a macro "EXPERIMENTAL_ISEQ_NODE_ID" is defined, this changeset keeps nd_node_id(node) for each instruction. This is intended for TypeProf to identify what AST::Node corresponds to each instruction. This patch is originally authored by @yui-knk for showing which column a NoMethodError occurred. https://github.com/ruby/ruby/compare/master...yui-knk:feature/node_id Co-Authored-By: Yuichiro Kaneko <yui-knk@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/4470
2021-03-17Use rb_fstring for "defined" strings.Aaron Patterson
We can take advantage of fstrings to de-duplicate the defined strings. This means we don't need to keep the list of defined strings on the VM (or register them as mark objects) Notes: Merged: https://github.com/ruby/ruby/pull/4279
2021-03-17Store strings for `defined` in the iseqsAaron Patterson
We can know the string used for "defined" calls at compile time, then store the string in the instruction sequences Notes: Merged: https://github.com/ruby/ruby/pull/4279
2021-01-06remove invalidated ccKoichi Sasada
if cc is invalidated, cc should be released from iseq. Notes: Merged: https://github.com/ruby/ruby/pull/4030
2021-01-05enable constant cache on ractorsKoichi Sasada
constant cache `IC` is accessed by non-atomic manner and there are thread-safety issues, so Ruby 3.0 disables to use const cache on non-main ractors. This patch enables it by introducing `imemo_constcache` and allocates it by every re-fill of const cache like `imemo_callcache`. [Bug #17510] Now `IC` only has one entry `IC::entry` and it points to `iseq_inline_constant_cache_entry`, managed by T_IMEMO object. `IC` is atomic data structure so `rb_mjit_before_vm_ic_update()` and `rb_mjit_after_vm_ic_update()` is not needed. Notes: Merged: https://github.com/ruby/ruby/pull/4022
2020-11-19Make RubyVM::InstructionSequence.compile_file use same encoding as loadJeremy Evans
This switches the internal function from rb_parser_compile_file_path to rb_parser_load_file, which is the same internal method that Kernel#load uses. Fixes [Bug #17308] Notes: Merged: https://github.com/ruby/ruby/pull/3788
2020-11-17remain enabled and line specified trace pointsKoichi Sasada
If two or more tracepoints enabled with the same target and with different target lines, the only last line is activated. This patch fixes this issue by remaining existing trace instructions. [Bug #17302] Notes: Merged: https://github.com/ruby/ruby/pull/3770
2020-10-30strip trailing spaces [ci skip]Nobuyoshi Nakada
2020-10-29check isolated Proc more strictlyKoichi Sasada
Isolated Proc prohibit to access outer local variables, but it was violated by binding and so on, so they should be error. Notes: Merged: https://github.com/ruby/ruby/pull/3721
2020-10-20Dump FrozenCore speciallyNobuyoshi Nakada
2020-10-17sync RClass::ext::iv_index_tblKoichi Sasada
iv_index_tbl manages instance variable indexes (ID -> index). This data structure should be synchronized with other ractors so introduce some VM locks. This patch also introduced atomic ivar cache used by set/getinlinecache instructions. To make updating ivar cache (IVC), we changed iv_index_tbl data structure to manage (ID -> entry) and an entry points serial and index. IVC points to this entry so that cache update becomes atomically. Notes: Merged: https://github.com/ruby/ruby/pull/3662
2020-07-23Remove unused field in rb_iseq_constant_bodyAlan Wu
This was introduced in 191ce5344ec42c91571f8f47c85be9138262b1c7 and has been unused since beae6cbf0fd8b6619e5212552de98022d4c4d4d4 Notes: Merged: https://github.com/ruby/ruby/pull/3353
2020-07-03Use ID instead of GENTRY for gvars. (#3278)Koichi Sasada
Use ID instead of GENTRY for gvars. Global variables are compiled into GENTRY (a pointer to struct rb_global_entry). This patch replace this GENTRY to ID and make the code simple. We need to search GENTRY from ID every time (st_lookup), so additional overhead will be introduced. However, the performance of accessing global variables is not important now a day and this simplicity helps Ractor development. Notes: Merged-By: ko1 <ko1@atdot.net>
2020-06-26fix return event and opt_invokebuiltin_delegate_leave (#3256)Koichi Sasada
If :return event is specified for a opt_invokebuiltin_delegate_leave and leave combination, the instructions should be opt_invokebuiltin_delegate trace_return instructions. To make it, opt_invokebuiltin_delegate_leave instruction will be changed to opt_invokebuiltin_delegate even if it is not an event target instruction. Notes: Merged-By: ko1 <ko1@atdot.net>
2020-06-23Add another missing castTakashi Kokubun
2020-06-23Add missing castTakashi Kokubun
2020-06-23Trace :return of builtin methodsTakashi Kokubun
using opt_invokebuiltin_delegate_leave insn. Since Ruby 2.7, :return of methods using builtin have not been traced properly.
2020-06-17ISeq created with callback is special, translation cannot be appliedKoichi Sasada
2020-06-09vm_ci_markable: added卜部昌平
CIs are created on-the-fly, which increases GC pressure. However they include no references to other objects, and those on-the-fly CIs tend to be short lived. Why not skip allocation of them. In doing so we need to add a flag denotes the CI object does not reside inside of objspace. Notes: Merged: https://github.com/ruby/ruby/pull/3179
2020-05-11sed -i 's|ruby/impl|ruby/internal|'卜部昌平
To fix build failures. Notes: Merged: https://github.com/ruby/ruby/pull/3079
2020-05-11sed -i s|ruby/3|ruby/impl|g卜部昌平
This shall fix compile errors. Notes: Merged: https://github.com/ruby/ruby/pull/3079
2020-04-15Create succ_index_table as a part of `iseq_setup`Nobuyoshi Nakada
With compiling `CPDEBUG >= 2`, `rb_iseq_disasm` segfaults if this table has not been created. Also `ibf_load_iseq_each` calls `rb_iseq_insns_info_encode_positions`. Notes: Merged: https://github.com/ruby/ruby/pull/3033
2020-04-15Shrink diassembled result stringNobuyoshi Nakada
2020-04-08Suppress -Wswitch warningsNobuyoshi Nakada
2020-04-08Merge pull request #2991 from shyouhei/ruby.h卜部昌平
Split ruby.h Notes: Merged-By: shyouhei <shyouhei@ruby-lang.org>
2020-03-17Reduce allocations for keyword argument hashesJeremy Evans
Previously, passing a keyword splat to a method always allocated a hash on the caller side, and accepting arbitrary keywords in a method allocated a separate hash on the callee side. Passing explicit keywords to a method that accepted a keyword splat did not allocate a hash on the caller side, but resulted in two hashes allocated on the callee side. This commit makes passing a single keyword splat to a method not allocate a hash on the caller side. Passing multiple keyword splats or a mix of explicit keywords and a keyword splat still generates a hash on the caller side. On the callee side, if arbitrary keywords are not accepted, it does not allocate a hash. If arbitrary keywords are accepted, it will allocate a hash, but this commit uses a callinfo flag to indicate whether the caller already allocated a hash, and if so, the callee can use the passed hash without duplicating it. So this commit should make it so that a maximum of a single hash is allocated during method calls. To set the callinfo flag appropriately, method call argument compilation checks if only a single keyword splat is given. If only one keyword splat is given, the VM_CALL_KW_SPLAT_MUT callinfo flag is not set, since in that case the keyword splat is passed directly and not mutable. If more than one splat is used, a new hash needs to be generated on the caller side, and in that case the callinfo flag is set, indicating the keyword splat is mutable by the callee. In compile_hash, used for both hash and keyword argument compilation, if compiling keyword arguments and only a single keyword splat is used, pass the argument directly. On the caller side, in vm_args.c, the callinfo flag needs to be recognized and handled. Because the keyword splat argument may not be a hash, it needs to be converted to a hash first if not. Then, unless the callinfo flag is set, the hash needs to be duplicated. The temporary copy of the callinfo flag, kw_flag, is updated if a hash was duplicated, to prevent the need to duplicate it again. If we are converting to a hash or duplicating a hash, we need to update the argument array, which can including duplicating the positional splat array if one was passed. CALLER_SETUP_ARG and a couple other places needs to be modified to handle similar issues for other types of calls. This includes fairly comprehensive tests for different ways keywords are handled internally, checking that you get equal results but that keyword splats on the caller side result in distinct objects for keyword rest parameters. Included are benchmarks for keyword argument calls. Brief results when compiled without optimization: def kw(a: 1) a end def kws(**kw) kw end h = {a: 1} kw(a: 1) # about same kw(**h) # 2.37x faster kws(a: 1) # 1.30x faster kws(**h) # 2.19x faster kw(a: 1, **h) # 1.03x slower kw(**h, **h) # about same kws(a: 1, **h) # 1.16x faster kws(**h, **h) # 1.14x faster Notes: Merged: https://github.com/ruby/ruby/pull/2945
2020-03-12Move code to mark jit_unit's cc_entries to mjit.cTakashi Kokubun
2020-03-11Pin and inline cme in JIT-ed method callsTakashi Kokubun
``` $ benchmark-driver benchmark.yml -v --rbenv 'before --jit;after --jit' --repeat-count=12 --output=all before --jit: ruby 2.8.0dev (2020-03-11T07:43:12Z master e89ebdcb87) +JIT [x86_64-linux] after --jit: ruby 2.8.0dev (2020-03-11T07:54:18Z master 143776a0da) +JIT [x86_64-linux] Calculating ------------------------------------- before --jit after --jit Optcarrot Lan_Master.nes 73.86976729561439 77.20184819316513 fps 74.46997176460742 78.43493030231805 77.59686308754307 78.55714131655935 78.53693921126656 79.08984255596820 80.10158944910573 79.17751731838183 80.12254974411167 79.60853122429181 80.28678655204945 79.74674066871896 80.38690681095379 79.90624544440300 80.79223498756919 80.57881084206193 80.82857188422419 80.70677614429169 81.06447745878245 81.03868541295149 81.21620802278490 82.16354660940607 ```
2020-03-10Optimize away call data refs in JIT-ed method callsTakashi Kokubun
According to ko1, `cd->cc != cc` was for GC.compact guard. As we pin cc by rb_gc_mark(), we don't need the check. ``` $ benchmark-driver benchmark.yml -v --rbenv 'before --jit;after --jit' --repeat-count=12 --output=all before --jit: ruby 2.8.0dev (2020-03-11T05:36:48Z master da6948753e) +JIT [x86_64-linux] after --jit: ruby 2.8.0dev (2020-03-11T06:26:34Z master 36b20b8b4a) +JIT [x86_64-linux] Calculating ------------------------------------- before --jit after --jit Optcarrot Lan_Master.nes 74.03480698689405 71.63404803273507 fps 74.15085286586992 73.43923328104295 75.51738277744781 75.75465268365384 76.24922600109410 76.74071607861318 76.45513422802325 77.47521029238116 76.86617230739330 78.14759496269018 77.71509137131933 79.14051571125866 77.72839157096146 79.35884822673313 78.25218904561633 79.92538876408051 78.72521071333249 79.98075556706726 78.79950460165091 80.51747831497875 79.43884960720381 80.97973166525254 ```
2020-02-26Eliminate unnecessary mjit_iseq_cc_entries callsTakashi Kokubun
just in case.
2020-02-26Internalize rb_mjit_unit definition againTakashi Kokubun
Fixed a TODO in b9007b6c548f91e88fd3f2ffa23de740431fa969
2020-02-25should be initialize jit_unit->cc_entries.Koichi Sasada
GC can invoke just after allocation of jit_unit->cc_entries so it should be zero-cleared.
2020-02-22check USE_MJITKoichi Sasada
iseq->body->jit_unit is not available if USE_MJIT==0 .
2020-02-22Introduce disposable call-cache.Koichi Sasada
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. Notes: Merged: https://github.com/ruby/ruby/pull/2888
2020-02-22VALUE size packed callinfo (ci).Koichi Sasada
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. Notes: Merged: https://github.com/ruby/ruby/pull/2888
2020-02-06this ternary operator is an undefined behaviour卜部昌平
Let me quote ISO/IEC 9899:2018 section 6.5.15: > Constraints > > The first operand shall have scalar type. > One of the following shall hold for the second and third operands: > — both operands have arithmetic type; > — both operands have the same structure or union type; > — both operands have void type; (snip) Here, `*option` is a const struct rb_compile_option_struct. OTOH `COMPILE_OPTION_DEFAULT` is a struct rb_compile_option_struct, without const. These two are _not_ the "same structure or union type". Hence the expression renders undefined behaviour. COMPILE_OPTION_DEFAULT is not a const because `RubyVM::InstructionSequence.compile_option=` touches its internals on-the-fly. There is no way to meet the constraints quoted above. Using ternary operator here was a mistake at the first place. Let's just replace it with a normal `if` statement. Notes: Merged: https://github.com/ruby/ruby/pull/2885
2020-01-23Rename RUBY_MARK_NO_PIN_UNLESS_NULL to RUBY_MARK_MOVABLE_UNLESS_NULL0x005c
Notes: Merged: https://github.com/ruby/ruby/pull/2823
2019-12-26decouple 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). Notes: Merged: https://github.com/ruby/ruby/pull/2711
2019-12-20Fixed misspellingsNobuyoshi Nakada
Fixed misspellings reported at [Bug #16437], only in ruby and rubyspec.
2019-12-10vm_core.h (iseq_unique_id): prefer uintptr_t instead of unsigned longYusuke Endoh
It produced a warning about type cast in LLP64 (i.e., windows).