summaryrefslogtreecommitdiff
path: root/iseq.c
AgeCommit message (Collapse)Author
2021-12-01Rework tracing for blocks running as methodsAlan Wu
The main impetus for this change is to fix [Bug #13392]. Previously, we fired the "return" TracePoint event after popping the stack frame for the block running as method (BMETHOD). This gave undesirable source location outputs as the return event normally fires right before the frame going away. The iseq for each block can run both as a block and as a method. To accommodate that, this commit makes vm_trace() fire call/return events for instructions that have b_call/b_return events attached when the iseq is running as a BMETHOD. The logic for rewriting to "trace_*" instruction is tweaked so that when the user listens to call/return events, instructions with b_call/b_return become trace variants. To continue to provide the return value for non-local returns done using the "return" or "break" keyword inside BMETHODs, the stack unwinding code is tweaked. b_return events now provide the same return value as return events for these non-local cases. A pre-existing test deemed not providing a return value for these b_return events as a limitation. This commit removes the checks for call/return TracePoint events that happen when calling into BMETHODs when no TracePoints are active. Technically, migrating just the return event is enough to fix the bug, but migrating both call and return removes our reliance on `VM_FRAME_FLAG_FINISH` and re-entering the interpreter when the caller is already in the interpreter. Notes: Merged: https://github.com/ruby/ruby/pull/4637
2021-11-17add `VM_CALLCACHE_ON_STACK`Koichi Sasada
check if iseq refers to on stack CC (it shouldn't). Notes: Merged: https://github.com/ruby/ruby/pull/5122
2021-11-15`Primitive.mandatory_only?` for fast pathKoichi Sasada
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. Notes: Merged: https://github.com/ruby/ruby/pull/5112
2021-10-29need to mark script_linesKoichi Sasada
Notes: Merged: https://github.com/ruby/ruby/pull/5048
2021-10-21freeze (make shareable) script_linesKoichi Sasada
Notes: Merged: https://github.com/ruby/ruby/pull/4913
2021-10-21`RubyVM.keep_script_lines`Koichi Sasada
`RubyVM.keep_script_lines` enables to keep script lines for each ISeq and AST. This feature is for debugger/REPL support. ```ruby RubyVM.keep_script_lines = true RubyVM::keep_script_lines = true eval("def foo = nil\ndef bar = nil") pp RubyVM::InstructionSequence.of(method(:foo)).script_lines ``` Notes: Merged: https://github.com/ruby/ruby/pull/4913
2021-10-20Cleanup iseq.c minimize diff with upstreamAlan Wu
Most of these are vestiges of our old setup where we hack into the interpreter loop.
2021-10-20TracePoint supportAlan Wu
This change fixes some cases where YJIT fails to fire tracing events. Most of the situations YJIT did not handle correctly involves enabling tracing while running inside generated code. A new operation to invalidate all generated code is added, which uses patching to make generated code exit at the next VM instruction boundary. A new routine called `jit_prepare_routine_call()` is introduced to facilitate this and should be used when generating code that could allocate, or could otherwise use `RB_VM_LOCK_ENTER()`. The `c_return` event is fired in the middle of an instruction as opposed to at an instruction boundary, so it requires special handling. C method call return points are patched to go to a fucntion which does everything the interpreter does, including firing the `c_return` event. The generated code for C method calls normally does not fire the event. Invalided code should not change after patching so the exits are not clobbered. A new variable is introduced to track the region of code that should not change.
2021-10-20Clear JIT code when tracepoints get enabledAaron Patterson
Clear out any JIT code on iseqs when tracepoints get enabled. We can't handle tracepoints right now, so we'll just try to recompile later.
2021-10-20Yet Another Ruby JIT!Jose Narvaez
Renaming uJIT to YJIT. AKA s/ujit/yjit/g.
2021-10-20Should fix builds without mjit supportAlan Wu
2021-10-20Tie lifetime of uJIT blocks to iseqsAlan Wu
* Tie lifetime of uJIT blocks to iseqs Blocks weren't being freed when iseqs are collected. * Add rb_dary. Use it for method dependency table * Keep track of blocks per iseq Remove global version_tbl * Block version bookkeeping fix * dary -> darray * free ujit_blocks * comment about size of ujit_blocks
2021-10-20Restore interpreter regs in ujit hook. Implement leave bytecode.Maxime Chevalier-Boisvert
2021-10-20Add to the MicroJIT scraper an example that passes ecAlan Wu
2021-10-20MicroJIT: Don't compile trace instructionsAlan Wu
2021-10-20Small build fixesAlan Wu
2021-10-20Try to fix Windows buildAlan Wu
2021-10-20Avoid triggering GC while translating threaded codeAlan Wu
2021-10-20Remove PC argument from ujit instructionsMaxime Chevalier-Boisvert
2021-10-20Removed native_pop_code, ported call with labelMaxime Chevalier-Boisvert
2021-10-20Generate multiple copies of native code for `pop`Alan Wu
Insert generated addresses into st_table for mapping native code addresses back to info about VM instructions. Export `encoded_insn_data` to do this. Also some style fixes.
2021-10-20Reimplement Alan's pop instruction with the new assemblerMaxime Chevalier-Boisvert
2021-10-20Added sub instruction, 32-bit registers, more testsMaxime Chevalier-Boisvert
2021-10-20Yeah, this actually works!Alan Wu
2021-10-20Add example handler for ujit and scrape it from vm.oAlan Wu
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