| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
Microsoft Visual Studio 12.0 doesn't support it.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Support loading builtin features written in Ruby, which implement
with C builtin functions.
[Feature #16254]
Several features:
(1) Load .rb file at boottime with native binary.
Now, prelude.rb is loaded at boottime. However, this file is contained
into the interpreter as a text format and we need to compile it.
This patch contains a feature to load from binary format.
(2) __builtin_func() in Ruby call func() written in C.
In Ruby file, we can write `__builtin_func()` like method call.
However this is not a method call, but special syntax to call
a function `func()` written in C. C functions should be defined
in a file (same compile unit) which load this .rb file.
Functions (`func` in above example) should be defined with
(a) 1st parameter: rb_execution_context_t *ec
(b) rest parameters (0 to 15).
(c) VALUE return type.
This is very similar requirements for functions used by
rb_define_method(), however `rb_execution_context_t *ec`
is new requirement.
(3) automatic C code generation from .rb files.
tool/mk_builtin_loader.rb creates a C code to load .rb files
needed by miniruby and ruby command. This script is run by
BASERUBY, so *.rb should be written in BASERUBY compatbile
syntax. This script load a .rb file and find all of __builtin_
prefix method calls, and generate a part of C code to export
functions.
tool/mk_builtin_binary.rb creates a C code which contains
binary compiled Ruby files needed by ruby command.
|
| |
|
| |
|
|
|
|
|
| |
`param.flags.ruby2_keywords` is not store/load correctly at to_binary
so restore this flag correctly.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Get rid of these redundant and useless warnings.
```
$ ruby -e 'def bar(a) a; end; def foo(...) bar(...) end; foo({})'
-e:1: warning: The last argument is used as the keyword parameter
-e:1: warning: for `foo' defined here
-e:1: warning: The keyword argument is passed as the last hash parameter
-e:1: warning: for `bar' defined here
```
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
To perform a regular method call, the VM needs two structs,
`rb_call_info` and `rb_call_cache`. At the moment, we allocate these two
structures in separate buffers. In the worst case, the CPU needs to read
4 cache lines to complete a method call. Putting the two structures
together reduces the maximum number of cache line reads to 2.
Combining the structures also saves 8 bytes per call site as the current
layout uses separate two pointers for the call info and the call cache.
This saves about 2 MiB on Discourse.
This change improves the Optcarrot benchmark at least 3%. For more
details, see attached bugs.ruby-lang.org ticket.
Complications:
- A new instruction attribute `comptime_sp_inc` is introduced to
calculate SP increase at compile time without using call caches. At
compile time, a `TS_CALLDATA` operand points to a call info struct, but
at runtime, the same operand points to a call data struct. Instruction
that explicitly define `sp_inc` also need to define `comptime_sp_inc`.
- MJIT code for copying call cache becomes slightly more complicated.
- This changes the bytecode format, which might break existing tools.
[Misc #16258]
|
| |
|
|
|
|
| |
The declarations went out-of-sync in dcfb7f6.
|
| |
|
|
|
|
|
|
|
| |
This changeset basically replaces `ruby_xmalloc(x * y)` into
`ruby_xmalloc2(x, y)`. Some convenient functions are also
provided for instance `rb_xmalloc_mul_add(x, y, z)` which allocates
x * y + z byes.
|
|
|
|
|
|
|
|
|
|
|
|
| |
The parser needs to determine whether a local varaiable is defined or
not in outer scope. For the sake, "base_block" field has kept the outer
block.
However, the whole block was actually unneeded; the parser used only
base_block->iseq.
So, this change lets parser_params have the iseq directly, instead of
the whole block.
|
|
|
|
| |
RUBY_ISEQ_DUMP_DEBUG=to_binary and the attached test case was failing.
Dump the flag to make sure `**nil` can round-trip properly.
|
|
|
|
|
| |
Drop catch table entries used in eliminated block, as well as
call_infos. [Bug #16184]
|
| |
|
| |
|
|
|
|
|
| |
This function is just a synonym for RB_OBJ_WRITTEN, so we can just
directly call that.
|
|
|
|
|
| |
We can mark everything via the instruction objects, so just execute the
write barrier instead of appending to the array
|
|
|
|
|
|
|
| |
`freeze_string` essentially called iseq_add_mark_object_compile_time. I
need to know where all writes occur on the `rb_iseq_t`, so this commit
separates the function calls so we can add write barriers in the right
place.
|
|
|
|
|
|
|
| |
Move the "add mark object" function to the location where we should be
calling RB_OBJ_WRITTEN. I'm going to add verification code next so we
can make sure the objects we're adding to the array are also reachable
from the mark function.
|
|
|
|
|
| |
This commit scans the ISEQ arena for objects that can be marked and
marks them. This should make the mark array unnecessary.
|
| |
|
|
|
|
|
|
| |
We'll scan the secondary arena during GC mark. So, we should only
allocate "markable" instruction linked list nodes out of the secondary
arena.
|
|
|
|
| |
This is so we can configure a new arena later
|
| |
|
|
|
|
| |
[Feature #11297] [Feature #16123]
|
|
|
|
|
|
|
|
|
|
| |
This makes it consistent with calling private attribute assignment
methods, which currently is allowed (e.g. `self.value =`).
Calling a private method in this way can be useful when trying to
assign the return value to a local variable with the same name.
[Feature #11297] [Feature #16123]
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The output of RubyVM::InstructionSequence#to_binary is extremely large.
We have reduced the output of #to_binary by more than 70%.
The execution speed of RubyVM::InstructionSequence.load_from_binary is about 7% slower, but when reading a binary from a file, it may be faster than the master.
Since Bootsnap gem uses #to_binary, this proposal reduces the compilation cache size of Rails projects to about 1/4.
See details: [Feature #16163]
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
RubyVM::InstructionSequence.to_binary generates a bytecode binary
representation. To check compatibility with binary and loading
MRI we prepared major/minor version and compare them at loading
time. However, development version of MRI can change this format
but we can not increment minor version to make them consistent
with Ruby's major/minor versions.
To solve this issue, we introduce new minor version scheme
(binary's minor_version = ruby's minor * 10000 + dev ver)
and we can check incompatibility with older dev version.
|
| |
|
|
|
|
|
| |
and add some comments.
(I confirm that `foo(**{})` allocates no hash object.)
|
|
|
|
|
| |
This is a similar refactoring to 8c908c989077c74eed26e02912b98362e509b8a3,
but the target is compile_hash.
|
| |
|
| |
|
|
|
|
|
| |
NODE_ZLIST case is handled in compile_hash, so iseq_compile_each0
doesn't have to do the same check redundantly.
|
|
|
|
|
|
| |
The length of NODE_LIST chain in NODE_HASH is always even because it
represents key-value pairs. There is no need to check for the
odd-length case.
|
|
|
|
|
| |
The array is just for a temporal buffer to create a hash, not stored in
the final iseq.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The original code looks unnecessarily complicated (to me).
Also, it creates a pre-allocated array only for the prefix of the array.
The new code optimizes not only the prefix but also the subsequence that
is longer than 0x40 elements.
# not optimized
10000000.times { [1+1, 1,2,3,4,...,63] } # 2.12 sec.
# (1+1; push 1; push 2; ...; puts 63; newarray 64; concatarray)
# optimized
10000000.times { [1+1, 1,2,3,4,...,63,64] } # 1.46 sec.
# (1+1; newarray 1; putobject [1,2,3,...,64]; concatarray)
|
|
|
|
| |
The same refactoring as to b601b13c7267889bf394146353c5f2b0eb488278.
|
|
|
|
|
|
| |
"popped" case can be so simple, so this change moves the branch to the
first, instead of scattering `if (popped)` branches to the main part.
Also, the return value "len" is not used. So it returns just 0 or 1.
|
|
|
|
|
|
|
|
|
| |
compile_list was for the compilation of Array literal and Hash literal.
I guess it was originally reasonable to handle them in one function, but
now, compilation of Array is very different from Hash. So the function
was complicated by many branches for Array and Hash.
This change separates the function to two ones for Array and Hash.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
An array literal [1,2,...,301] was compiled to the following iseq:
duparray [1,2,...,300]
putobject [301]
concatarray
The Array literal optimization took every two elements maybe because it
must handle not only Array but also Hash.
Now the optimization takes each element if it is an Array literal. So
the new iseq is: duparray [1,2,...,301].
|
|
|
|
|
|
|
| |
`[{}, {}, {}, ..., {}, *{}]` is wrongly created.
A big array literal is created and concatenated for every 256 elements.
The newarraykwsplat must be emitted only at the last chunk.
|