Age | Commit message (Collapse) | Author |
|
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.
Notes:
Merged: https://github.com/ruby/ruby/pull/5698
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/5558
Merged-By: nobu <[email protected]>
|
|
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/5519
|
|
Previously, the right hand side was always evaluated before the
left hand side for constant assignments. For the following:
```ruby
lhs::C = rhs
```
rhs was evaluated before lhs, which is inconsistant with attribute
assignment (lhs.m = rhs), and apparently also does not conform to
JIS 3017:2013 11.4.2.2.3.
Fix this by changing evaluation order. Previously, the above
compiled to:
```
0000 putself ( 1)[Li]
0001 opt_send_without_block <calldata!mid:rhs, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0003 dup
0004 putself
0005 opt_send_without_block <calldata!mid:lhs, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0007 setconstant :C
0009 leave
```
After this change:
```
0000 putself ( 1)[Li]
0001 opt_send_without_block <calldata!mid:lhs, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0003 putself
0004 opt_send_without_block <calldata!mid:rhs, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0006 swap
0007 topn 1
0009 swap
0010 setconstant :C
0012 leave
```
Note that if expr is not a module/class, then a TypeError is not
raised until after the evaluation of rhs. This is because that
error is raised by setconstant. If we wanted to raise TypeError
before evaluation of rhs, we would have to add a VM instruction
for calling vm_check_if_namespace.
Changing assignment order for single assignments caused problems
in the multiple assignment code, revealing that the issue also
affected multiple assignment. Fix the multiple assignment code
so left-to-right evaluation also works for constant assignments.
Do some refactoring of the multiple assignment code to reduce
duplication after adding support for constants. Rename struct
masgn_attrasgn to masgn_lhs_node, since it now handles both
constants and attributes. Add add_masgn_lhs_node static function
for adding data for lhs attribute and constant setting.
Fixes [Bug #15928]
Notes:
Merged: https://github.com/ruby/ruby/pull/4450
|
|
This `NODE` type was used in pre-YARV implementation, to improve
the performance of assignment to dynamic local variable defined at
the innermost scope. It has no longer any actual difference with
`NODE_DASGN`, except for the node dump.
Notes:
Merged: https://github.com/ruby/ruby/pull/5251
|
|
* Use duparray when possible for argspush
ARGSPUSH is the node we see with a single value pushed to the end of a
splatted array. ARGSCAT is similar, but is used when multiple values are
being concatenated to the list.
Previously only ARGSCAT had an optimization where when all the values
were static it would use duparray instead of newarray to create the
intermediate array.
This commit adds similar behaviour for ARGSPUSH, using duparray instead
of putobject/newarray.
* Replace duparray with putobject before concatarray
When performing duparray/concatarray we know we'll never use the
intermediate array being created by duparray, so we should be able to
use it as a temporary object.
This avoids an extra array allocation for NODE_ARGSPUSH (ex. [*foo, 1])
and NODE_ARGSCAT (ex. [*foo, 1, 2]).
Notes:
Merged-By: jhawthorn <[email protected]>
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/5091
Merged-By: nobu <[email protected]>
|
|
Dumped iseq binary can not have unnamed symbols/IDs, and ID 0 is
stored instead. As `struct rb_id_table` disallows ID 0, also for
the distinction, re-assign a new temporary ID based on the local
variable table index when loading from the binary, as well as the
parser.
Notes:
Merged: https://github.com/ruby/ruby/pull/5157
|
|
The implementation of a local variable tables was represented as `ID*`,
but it was very hacky: the first element is not an ID but the size of
the table, and, the last element is (sometimes) a link to the next local
table only when the id tables are a linked list.
This change converts the hacky implementation to a normal struct.
Notes:
Merged: https://github.com/ruby/ruby/pull/5136
|
|
Introduce new optimized method type
`OPTIMIZED_METHOD_TYPE_STRUCT_AREF/ASET` with index information.
Notes:
Merged: https://github.com/ruby/ruby/pull/5131
|
|
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.
Speedups (using included benchmarks):
:symbol :: 60%
0-9 :: 50%
Class/Module :: 50%
nil/true/false :: 20%
integer :: 10%
[] :: 10%
"" :: 3%
One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.
Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.
This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.
This disables 4 YJIT tests. Those tests should be reenabled after
YJIT optimizes the new objtostring insn.
Implements [Feature #13715]
Co-authored-by: Eric Wong <[email protected]>
Co-authored-by: Alan Wu <[email protected]>
Co-authored-by: Yusuke Endoh <[email protected]>
Co-authored-by: Koichi Sasada <[email protected]>
Notes:
Merged: https://github.com/ruby/ruby/pull/5002
Merged-By: jeremyevans <[email protected]>
|
|
|
|
|
|
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
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/5047
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/5015
|
|
`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
|
|
Since opt_getinlinecache and opt_setinlinecache point to the same cache
struct, there is no need to track the index of the get instruction and
then store it on the cache struct later when processing the set
instruction. Setting it when processing the get instruction works just
as well.
This change reduces our diff.
|
|
|
|
Nobu pointed out that saving the old ci to a local is enough to keep it
reachable.
|
|
This reverts commit 1e0f2e4b09ca9443524acf4b50ffd50a80f330f3.
|
|
The old code didn't keep old_operands[0] reachable while allocating. You
can crash it by requiring erb under GC stress mode.
|
|
Make sure `opt_getinlinecache` is in a block all on its own, and
invalidate it from the interpreter when `opt_setinlinecache`.
It will recompile with a filled cache the second time around.
This lets YJIT runs well when the IC for constant is cold.
|
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
This commit dumps the outer variables table when dumping an iseq to
binary. This fixes a case where Ractors aren't able to tell what outer
variables belong to a lambda after the lambda is loaded via ISeq.load_from_binary
[Bug #18232] [ruby-core:105504]
Notes:
Merged: https://github.com/ruby/ruby/pull/4942
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4925
Merged-By: nobu <[email protected]>
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4821
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4798
|
|
|
|
I was not aware of this because I use clang these days.
Notes:
Merged: https://github.com/ruby/ruby/pull/4815
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4791
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/4795
|