Граф коммитов

769 Коммитов

Автор SHA1 Сообщение Дата
Takashi Kokubun 63d96ccbcd Invalidate everything on GC.compact 2023-03-05 23:28:59 -08:00
John Bampton 2f7270c681
Fix spelling (#7389) 2023-02-27 09:56:06 -08:00
Matt Valentine-House 72aba64fff Merge gc.h and internal/gc.h
[Feature #19425]
2023-02-09 10:32:29 -05:00
Peter Zhu 861d70e383 Rename iseq_mark_and_update to iseq_mark_and_move
The new name is more consistent.
2023-02-08 12:43:25 -05:00
Samuel Williams 1b06cd3f09
Pass through `line_offset` argument correctly (but it was always 0). (#7177) 2023-01-27 14:49:26 +13:00
Samuel Williams 2c93c55401
Ensure main file has default coverage if required. (#7169)
* Extract common code for coverage setup.
2023-01-22 10:51:59 +13:00
Peter Zhu 056e7a0154 Make all of the references of iseq movable 2023-01-20 08:51:39 -05:00
Peter Zhu 9af84c95d7 Combine code paths for marking cc
This commit avoids a separate code path for marking and moving the
callcache of the iseq.
2023-01-19 11:23:35 -05:00
Peter Zhu 41bf2354e3 Add rb_gc_mark_and_move and implement on iseq
This commit adds rb_gc_mark_and_move which takes a pointer to an object
and marks it during marking phase and updates references during compaction.
This allows for marking and reference updating to be combined into a
single function, which reduces code duplication and prevents bugs if
marking and reference updating goes out of sync.

This commit also implements rb_gc_mark_and_move on iseq as an example.
2023-01-19 11:23:35 -05:00
Peter Zhu dcc676a86e ci in iseq can only be object or null
It looks like rb_callinfo in iseq can only be either a Ruby object or
null, since it cannot be allocated on the stack.
2023-01-19 09:47:21 -05:00
Jemma Issroff 40a9964b89 Set max_iv_count (used for object shapes) based on inline caches
With this change, we're storing the iv name on an inline cache on
setinstancevariable instructions. This allows us to check the inline
cache to count instance variables set in initialize and give us an
estimate of iv capacity for an object.

For the purpose of estimating the number of instance variables required
for an object, we're assuming that all initialize methods will call
`super`.

This change allows us to estimate the number of instance variables
required without disassembling instruction sequences.

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
2022-12-06 13:43:42 -08:00
Peter Zhu d90835aeb5 Fix crash when RGENGC_CHECK_MODE=2
Commit dba61f4 fixes a crash when GC'ing a iseq that failed to compile.
However, if we turn on RGENGC_CHECK_MODE then rb_iseq_memsize crashes
since it cannot handle an iseq without is_entries.
2022-12-04 15:23:09 -05:00
Aaron Patterson dba61f487c return early if there is no is_entries buffer
If there is a compilation error, is_entries may not be allocated, but
ic_size could be greater than 0.  If we don't have a buffer to iterate
over, just return early.  Otherwise GC could segv

[Bug #19173]
2022-12-03 13:03:51 -06:00
Nobuyoshi Nakada f28e79caaa
Use consistent style [ci skip] 2022-12-02 23:46:21 +09:00
Aaron Patterson aedf682bfa
Free the IV table after estimation
We need to make sure the name table is freed otherwise we have a memory
leak.
2022-11-22 13:54:30 -08:00
Jemma Issroff 9c5e3671eb
Increment max_iv_count on class based on number of set_iv in initialize (#6788)
We can loosely predict the number of ivar sets on a class based on the
number of iv set instructions in the initialize method. This should give
us a more accurate estimate to use for initial size pool allocation,
which should in turn give us more cache hits.
2022-11-22 15:28:14 -05:00
S-H-GAMELINKS 1f4f6c9832 Using UNDEF_P macro 2022-11-16 18:58:33 +09:00
Koichi Sasada e35c528d72 push dummy frame for loading process
This patch pushes dummy frames when loading code for the
profiling purpose.

The following methods push a dummy frame:
* `Kernel#require`
* `Kernel#load`
* `RubyVM::InstructionSequence.compile_file`
* `RubyVM::InstructionSequence.load_from_binary`

https://bugs.ruby-lang.org/issues/18559
2022-10-20 17:38:28 +09:00
Jemma Issroff ad63b668e2
Revert "Revert "This commit implements the Object Shapes technique in CRuby.""
This reverts commit 9a6803c90b.
2022-10-11 08:40:56 -07:00
Aaron Patterson 9a6803c90b
Revert "This commit implements the Object Shapes technique in CRuby."
This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
2022-09-30 16:01:50 -07:00
Samuel Williams 9dd902b831
Add `eval: true/false` flag to `Coverage.setup`. 2022-09-29 09:44:14 +13:00
Jemma Issroff d594a5a8bd
This commit implements the Object Shapes technique in CRuby.
Object Shapes is used for accessing instance variables and representing the
"frozenness" of objects.  Object instances have a "shape" and the shape
represents some attributes of the object (currently which instance variables are
set and the "frozenness").  Shapes form a tree data structure, and when a new
instance variable is set on an object, that object "transitions" to a new shape
in the shape tree.  Each shape has an ID that is used for caching. The shape
structure is independent of class, so objects of different types can have the
same shape.

For example:

```ruby
class Foo
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

class Bar
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

foo = Foo.new # `foo` has shape id 2
bar = Bar.new # `bar` has shape id 2
```

Both `foo` and `bar` instances have the same shape because they both set
instance variables of the same name in the same order.

This technique can help to improve inline cache hits as well as generate more
efficient machine code in JIT compilers.

This commit also adds some methods for debugging shapes on objects.  See
`RubyVM::Shape` for more details.

For more context on Object Shapes, see [Feature: #18776]

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com>
Co-Authored-By: John Hawthorn <john@hawthorn.email>
2022-09-28 08:26:21 -07:00
Aaron Patterson 06abfa5be6
Revert this until we can figure out WB issues or remove shapes from GC
Revert "* expand tabs. [ci skip]"

This reverts commit 830b5b5c35.

Revert "This commit implements the Object Shapes technique in CRuby."

This reverts commit 9ddfd2ca00.
2022-09-26 16:10:11 -07:00
Jemma Issroff 9ddfd2ca00 This commit implements the Object Shapes technique in CRuby.
Object Shapes is used for accessing instance variables and representing the
"frozenness" of objects.  Object instances have a "shape" and the shape
represents some attributes of the object (currently which instance variables are
set and the "frozenness").  Shapes form a tree data structure, and when a new
instance variable is set on an object, that object "transitions" to a new shape
in the shape tree.  Each shape has an ID that is used for caching. The shape
structure is independent of class, so objects of different types can have the
same shape.

For example:

```ruby
class Foo
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

class Bar
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

foo = Foo.new # `foo` has shape id 2
bar = Bar.new # `bar` has shape id 2
```

Both `foo` and `bar` instances have the same shape because they both set
instance variables of the same name in the same order.

This technique can help to improve inline cache hits as well as generate more
efficient machine code in JIT compilers.

This commit also adds some methods for debugging shapes on objects.  See
`RubyVM::Shape` for more details.

For more context on Object Shapes, see [Feature: #18776]

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com>
Co-Authored-By: John Hawthorn <john@hawthorn.email>
2022-09-26 09:21:30 -07:00
Samuel Williams 22af2e9084 Rework vm_core to use `int first_lineno` struct member. 2022-09-26 00:41:16 +13:00
Samuel Williams 75cf29f60d Rework `first_lineno` to be `int`. 2022-09-26 00:41:16 +13:00
Samuel Williams 09ea4f3a9f Extract common code for coverage setup. 2022-09-25 20:35:47 +13:00
Samuel Williams 9434a7333c Enable coverage for eval. 2022-09-22 22:19:12 +12:00
John Hawthorn 1cc97412cd Remove rb_iseq_each 2022-09-01 15:20:49 -07:00
John Hawthorn 679ef34586 New constant caching insn: opt_getconstant_path
Previously YARV bytecode implemented constant caching by having a pair
of instructions, opt_getinlinecache and opt_setinlinecache, wrapping a
series of getconstant calls (with putobject providing supporting
arguments).

This commit replaces that pattern with a new instruction,
opt_getconstant_path, handling both getting/setting the inline cache and
fetching the constant on a cache miss.

This is implemented by storing the full constant path as a
null-terminated array of IDs inside of the IC structure. idNULL is used
to signal an absolute constant reference.

    $ ./miniruby --dump=insns -e '::Foo::Bar::Baz'
    == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,13)> (catch: FALSE)
    0000 opt_getconstant_path                   <ic:0 ::Foo::Bar::Baz>      (   1)[Li]
    0002 leave

The motivation for this is that we had increasingly found the need to
disassemble the instructions between the opt_getinlinecache and
opt_setinlinecache in order to determine the constant we are fetching,
or otherwise store metadata.

This disassembly was done:
* In opt_setinlinecache, to register the IC against the constant names
  it is using for granular invalidation.
* In rb_iseq_free, to unregister the IC from the invalidation table.
* In YJIT to find the position of a opt_getinlinecache instruction to
  invalidate it when the cache is populated
* In YJIT to register the constant names being used for invalidation.

With this change we no longe need disassemly for these (in fact
rb_iseq_each is now unused), as the list of constant names being
referenced is held in the IC. This should also make it possible to make
more optimizations in the future.

This may also reduce the size of iseqs, as previously each segment
required 32 bytes (on 64-bit platforms) for each constant segment. This
implementation only stores one ID per-segment.

There should be no significant performance change between this and the
previous implementation. Previously opt_getinlinecache was a "leaf"
instruction, but it included a jump (almost always to a separate cache
line). Now opt_getconstant_path is a non-leaf (it may
raise/autoload/call const_missing) but it does not jump. These seem to
even out.
2022-09-01 15:20:49 -07:00
Takashi Kokubun d6f21b308b
Convert catch_except_t to stdbool
catch_excep_t is a field that exists for MJIT. In the process of
rewriting MJIT in Ruby, I added API to convert 1/0 of _Bool to
true/false, and it seemed confusing and hard to maintain if you
don't use _Bool for *_p fields.
2022-08-25 23:00:19 -07:00
Nobuyoshi Nakada ee864beb7c
Simplify around `USE_YJIT` macro (#6240)
* Simplify around `USE_YJIT` macro

- Use `USE_YJIT` macro only instead of `YJIT_BUILD`.
- An intermediate macro `YJIT_SUPPORTED_P` is no longer used.

* Bail out if YJIT is enabled on unsupported platforms
2022-08-15 13:05:12 -04:00
Peter Zhu efb91ff19b Rename rb_ary_tmp_new to rb_ary_hidden_new
rb_ary_tmp_new suggests that the array is temporary in some way, but
that's not true, it just creates an array that's hidden and not on the
transient heap. This commit renames it to rb_ary_hidden_new.
2022-07-26 09:12:09 -04:00
Yusuke Endoh 8f7e188822 Add "rb_" prefixes to toplevel enum definitions
... as per ko1's request.
2022-07-22 23:10:24 +09:00
Takashi Kokubun 5b21e94beb Expand tabs [ci skip]
[Misc #18891]
2022-07-21 09:42:04 -07:00
Jemma Issroff 85ea46730d Separate TS_IVC and TS_ICVARC in is_entries buffers
This allows us to treat cvar caches differently than ivar caches.
2022-07-18 14:06:30 -07:00
Nobuyoshi Nakada 7bab788309
Simplify BLSR code
And suppress unary minus operator to unsigned type warnings by VC.
2022-07-08 15:59:25 +09:00
Aaron Patterson 3cf2c2e4a1 Remove ISEQ_MARKABLE_ISEQ flag
We don't need this flag anymore.  We have all the info we need via the
bitmap and the is_entries list.
2022-07-07 11:56:25 -07:00
Aaron Patterson cfc8d7eaec Use iseq bitmap when updating references
This allows us to delete the disassembly code path for reference
updating.
2022-06-29 17:07:42 -07:00
Aaron Patterson 8d157bc806 Move function to `static inline` so we don't have leaked globals
This function shouldn't leak and is only needed during instruction
assembly
2022-06-29 16:21:48 -07:00
Aaron Patterson e3ab525f69 Fix ISeq dump / load in array cases
We need to dump relative offsets for inline storage entries so that
loading iseqs as an array works as well.  This commit also has some
minor refactoring to make computing relative ISE information easier.

This should fix the iseq dump / load as array tests we're seeing fail in
CI.

Co-Authored-By: John Hawthorn <john@hawthorn.email>
2022-06-29 16:21:48 -07:00
Jean Boussier d7cc380666 iseq.c: Use ntz_intptr for faster bitmap scan 2022-06-25 00:05:00 +02:00
Aaron Patterson 0b58059f15 Free bitmap buffer if it's not used
If the iseqs don't have any objects in them that need marking, then
immediately free the bitmap buffer
2022-06-23 16:52:00 -07:00
Aaron Patterson 8d63a04703 Flatten bitmap when there is only one element
We can avoid allocating a bitmap when the number of elements in the iseq
is fewer than the size of an iseq_bits_t
2022-06-23 16:52:00 -07:00
Aaron Patterson e23540e566 Speed up ISeq by marking via bitmaps and IC rearranging
This commit adds a bitfield to the iseq body that stores offsets inside
the iseq buffer that contain values we need to mark.  We can use this
bitfield to mark objects instead of disassembling the instructions.

This commit also groups inline storage entries and adds a counter for
each entry.  This allows us to iterate and mark each entry without
disassembling instructions

Since we have a bitfield and grouped inline caches, we can mark all
VALUE objects associated with instructions without actually
disassembling the instructions at mark time.

[Feature #18875] [ruby-core:109042]
2022-06-23 14:01:46 -07:00
Nobuyoshi Nakada 7f05f7378d
Reuse an interned string
Repeating to intern the same string is just redundant, as interned
strings for the same content are always the same object until it gets
collected.
2022-06-17 23:27:16 +09:00
Alan Wu f90549cd38 Rust YJIT
In December 2021, we opened an [issue] to solicit feedback regarding the
porting of the YJIT codebase from C99 to Rust. There were some
reservations, but this project was given the go ahead by Ruby core
developers and Matz. Since then, we have successfully completed the port
of YJIT to Rust.

The new Rust version of YJIT has reached parity with the C version, in
that it passes all the CRuby tests, is able to run all of the YJIT
benchmarks, and performs similarly to the C version (because it works
the same way and largely generates the same machine code). We've even
incorporated some design improvements, such as a more fine-grained
constant invalidation mechanism which we expect will make a big
difference in Ruby on Rails applications.

Because we want to be careful, YJIT is guarded behind a configure
option:

```shell
./configure --enable-yjit # Build YJIT in release mode
./configure --enable-yjit=dev # Build YJIT in dev/debug mode
```

By default, YJIT does not get compiled and cargo/rustc is not required.
If YJIT is built in dev mode, then `cargo` is used to fetch development
dependencies, but when building in release, `cargo` is not required,
only `rustc`. At the moment YJIT requires Rust 1.60.0 or newer.

The YJIT command-line options remain mostly unchanged, and more details
about the build process are documented in `doc/yjit/yjit.md`.

The CI tests have been updated and do not take any more resources than
before.

The development history of the Rust port is available at the following
commit for interested parties:
1fd9573d8b

Our hope is that Rust YJIT will be compiled and included as a part of
system packages and compiled binaries of the Ruby 3.2 release. We do not
anticipate any major problems as Rust is well supported on every
platform which YJIT supports, but to make sure that this process works
smoothly, we would like to reach out to those who take care of building
systems packages before the 3.2 release is shipped and resolve any
issues that may come up.

[issue]: https://bugs.ruby-lang.org/issues/18481

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Noah Gibbs <the.codefolio.guy@gmail.com>
Co-authored-by: Kevin Newton <kddnewton@gmail.com>
2022-04-27 11:00:22 -04:00
Nobuyoshi Nakada 010d92e93d
Adjust indent [ci skip] 2022-04-02 14:54:37 +09:00
Kevin Newton 6068da8937 Finer-grained constant cache invalidation (take 2)
This commit reintroduces finer-grained constant cache invalidation.
After 8008fb7 got merged, it was causing issues on token-threaded
builds (such as on Windows).

The issue was that when you're iterating through instruction sequences
and using the translator functions to get back the instruction structs,
you're either using `rb_vm_insn_null_translator` or
`rb_vm_insn_addr2insn2` depending if it's a direct-threading build.
`rb_vm_insn_addr2insn2` does some normalization to always return to
you the non-trace version of whatever instruction you're looking at.
`rb_vm_insn_null_translator` does not do that normalization.

This means that when you're looping through the instructions if you're
trying to do an opcode comparison, it can change depending on the type
of threading that you're using. This can be very confusing. So, this
commit creates a new translator function
`rb_vm_insn_normalizing_translator` to always return the non-trace
version so that opcode comparisons don't have to worry about different
configurations.

[Feature #18589]
2022-04-01 14:48:22 -04:00
Nobuyoshi Nakada 69967ee64e
Revert "Finer-grained inline constant cache invalidation"
This reverts commits for [Feature #18589]:
* 8008fb7352
  "Update formatting per feedback"
* 8f6eaca2e1
  "Delete ID from constant cache table if it becomes empty on ISEQ free"
* 629908586b
  "Finer-grained inline constant cache invalidation"

MSWin builds on AppVeyor have been crashing since the merger.
2022-03-25 20:29:09 +09:00
Kevin Newton 8f6eaca2e1 Delete ID from constant cache table if it becomes empty on ISEQ free
Co-authored-by: John Hawthorn <john@hawthorn.email>
2022-03-24 09:14:38 -07:00
Kevin Newton 629908586b Finer-grained inline constant cache invalidation
Current behavior - caches depend on a global counter. All constant mutations cause caches to be invalidated.

```ruby
class A
  B = 1
end

def foo
  A::B # inline cache depends on global counter
end

foo # populate inline cache
foo # hit inline cache

C = 1 # global counter increments, all caches are invalidated

foo # misses inline cache due to `C = 1`
```

Proposed behavior - caches depend on name components. Only constant mutations with corresponding names will invalidate the cache.

```ruby
class A
  B = 1
end

def foo
  A::B # inline cache depends constants named "A" and "B"
end

foo # populate inline cache
foo # hit inline cache

C = 1 # caches that depend on the name "C" are invalidated

foo # hits inline cache because IC only depends on "A" and "B"
```

Examples of breaking the new cache:

```ruby
module C
  # Breaks `foo` cache because "A" constant is set and the cache in foo depends
  # on "A" and "B"
  class A; end
end

B = 1
```

We expect the new cache scheme to be invalidated less often because names aren't frequently reused. With the cache being invalidated less, we can rely on its stability more to keep our constant references fast and reduce the need to throw away generated code in YJIT.
2022-03-24 09:14:38 -07:00
Peter Zhu 5f10bd634f Add ISEQ_BODY macro
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.
2022-03-24 10:03:51 -04:00
Nobuyoshi Nakada 8f3a36fb6e
Fix indents [ci skip] 2022-02-03 11:21:41 +09:00
Jemma Issroff 2913a2f5cf Treat TS_ICVARC cache as separate from TS_IVC cache 2022-02-02 09:20:34 -08:00
Koichi Sasada 6bef1ac628 `rb_iseq_update_references()` cares `script_lines`
and it fixes compaction issue:
http://rubyci.s3.amazonaws.com/freebsd12/ruby-master/log/20211218T203001Z.fail.html.gz
2021-12-19 06:15:22 +09:00
Koichi Sasada dd29ba0764 `iseq_type_sym()` -> `iseq_type_id()`
`iseq_type_sym()` returns `ID` (surprisingly!) so rename it
to `iseq_type_id()`.
2021-12-19 05:35:16 +09:00
Koichi Sasada 89a02d8932 add `rb_iseq_type()` to return iseq type in Symbol
It is shorthand `ISeq#to_a[9]`.
2021-12-19 05:16:29 +09:00
Koichi Sasada 2e6e2fd9da fix local TP memory leak
It free `rb_hook_list_t` itself if needed. To recognize the
need, this patch introduced `rb_hook_list_t::is_local` flag.

This patch is succession of https://github.com/ruby/ruby/pull/4652
2021-12-15 02:31:58 +09:00
Yusuke Endoh 8613c0c675 Introduce an option "--dump=insns_without_opt" for debugging purposes 2021-12-13 10:29:08 +09:00
Alan Wu 9121e57a5f Rework tracing for blocks running as methods
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.
2021-12-01 17:42:33 -05:00
Koichi Sasada 7ec1fc37f4 add `VM_CALLCACHE_ON_STACK`
check if iseq refers to on stack CC (it shouldn't).
2021-11-17 22:21:42 +09:00
Koichi Sasada b1b73936c1 `Primitive.mandatory_only?` for fast path
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.
2021-11-15 15:58:56 +09:00
Koichi Sasada cbf2078a25 need to mark script_lines 2021-10-29 02:00:06 +09:00
Koichi Sasada 7185c00fcc freeze (make shareable) script_lines 2021-10-21 16:17:39 +09:00
Koichi Sasada c7550537f1 `RubyVM.keep_script_lines`
`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
```
2021-10-21 16:17:39 +09:00
Alan Wu 506c037a16 Cleanup iseq.c minimize diff with upstream
Most of these are vestiges of our old setup where we hack into the
interpreter loop.
2021-10-20 18:19:42 -04:00
Alan Wu bd876c243a TracePoint support
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-20 18:19:39 -04:00
Aaron Patterson 71cef74432 Clear JIT code when tracepoints get enabled
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-20 18:19:38 -04:00
Jose Narvaez 4e2eb7695e Yet Another Ruby JIT!
Renaming uJIT to YJIT. AKA s/ujit/yjit/g.
2021-10-20 18:19:31 -04:00
Alan Wu 03af6ad995 Should fix builds without mjit support 2021-10-20 18:19:29 -04:00
Alan Wu c02517bacb Tie lifetime of uJIT blocks to iseqs
* 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-20 18:19:29 -04:00
Maxime Chevalier-Boisvert 2e561ff255 Restore interpreter regs in ujit hook. Implement leave bytecode. 2021-10-20 18:19:28 -04:00
Alan Wu 11c1daea17 Add to the MicroJIT scraper an example that passes ec 2021-10-20 18:19:25 -04:00
Alan Wu 93f6ac39f2 MicroJIT: Don't compile trace instructions 2021-10-20 18:19:25 -04:00
Alan Wu 040cfdb139 Small build fixes 2021-10-20 18:19:24 -04:00
Alan Wu 7d1546ece5 Try to fix Windows build 2021-10-20 18:19:24 -04:00
Alan Wu 265c5ca8b1 Avoid triggering GC while translating threaded code 2021-10-20 18:19:23 -04:00
Maxime Chevalier-Boisvert 3739588811 Remove PC argument from ujit instructions 2021-10-20 18:19:23 -04:00
Maxime Chevalier-Boisvert 26fecc7236 Removed native_pop_code, ported call with label 2021-10-20 18:19:23 -04:00
Alan Wu 4929ba0a5c Generate multiple copies of native code for `pop`
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-20 18:19:23 -04:00
Maxime Chevalier-Boisvert 251531bdf0 Reimplement Alan's pop instruction with the new assembler 2021-10-20 18:19:23 -04:00
Maxime Chevalier-Boisvert efcaa49a7b Added sub instruction, 32-bit registers, more tests 2021-10-20 18:19:23 -04:00
Alan Wu 16c5ce863c Yeah, this actually works! 2021-10-20 18:19:22 -04:00
Alan Wu cec197696f Add example handler for ujit and scrape it from vm.o 2021-10-20 18:19:22 -04:00
S.H dc9112cf10
Using NIL_P macro instead of `== Qnil` 2021-10-03 22:34:45 +09:00
S-H-GAMELINKS bdd6d8746f Replace RBOOL macro 2021-09-05 23:01:27 +09:00
Jeremy Evans 2d98593bf5 Support tracing of attr_reader and attr_writer
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>
2021-08-29 07:23:39 -07:00
Nobuyoshi Nakada 4c3140d60f
Add keyrest to ruby2_keywords parameters [Bug #18011] 2021-08-03 10:56:50 +09:00
Jeremy Evans 64ac984129 Make RubyVM::AbstractSyntaxTree.of raise for method/proc created in eval
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>
2021-07-29 13:51:03 -07:00
Yusuke Endoh 68e1dc5172 iseq.c: Make ast_line_count return 0 when syntax error occurred
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-26 00:15:16 +09:00
Yusuke Endoh 0a36cab1b5 Enable USE_ISEQ_NODE_ID by default
... which is formally called EXPERIMENTAL_ISEQ_NODE_ID.

See also ff69ef27b0.

https://bugs.ruby-lang.org/issues/17930
2021-06-18 03:35:38 +09:00
Yusuke Endoh dfba87cd62 Make it possible to get AST::Node from Thread::Backtrace::Location
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.
2021-06-18 03:35:38 +09:00
Yusuke Endoh fb01411ae8 node.h: Reduce struct size to fit with Ruby object size (five VALUEs)
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.
2021-06-18 02:34:27 +09:00
Takashi Kokubun 070caf54d2
Refactor rb_vm_insn_addr2insn calls
It's been a way too much amount of ifdefs.
2021-06-02 01:16:50 -07:00
Yusuke Endoh ff69ef27b0 compile.c: Pass node instead of nd_line(node) to ADD_INSN* functions
... 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>
2021-05-07 17:02:15 +09:00
Aaron Patterson 8359821870 Use rb_fstring for "defined" strings.
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)
2021-03-17 10:55:37 -07:00
Aaron Patterson 17bf478de1 Store strings for `defined` in the iseqs
We can know the string used for "defined" calls at compile time, then
store the string in the instruction sequences
2021-03-17 10:55:37 -07:00
Koichi Sasada 954d6c7432 remove invalidated cc
if cc is invalidated, cc should be released from iseq.
2021-01-06 14:57:48 +09:00
Koichi Sasada e7fc353f04 enable constant cache on ractors
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.
2021-01-05 02:27:58 +09:00
Jeremy Evans 4a5c42db88 Make RubyVM::InstructionSequence.compile_file use same encoding as load
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]
2020-11-19 07:12:50 +09:00
Koichi Sasada 084e7e31b2 remain enabled and line specified trace points
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]
2020-11-17 07:33:38 +09:00
Nobuyoshi Nakada 799253dc46
strip trailing spaces [ci skip] 2020-10-30 12:26:59 +09:00
Koichi Sasada 07c03bc309 check isolated Proc more strictly
Isolated Proc prohibit to access outer local variables, but it was
violated by binding and so on, so they should be error.
2020-10-29 23:42:55 +09:00
Nobuyoshi Nakada 081cc4eb28
Dump FrozenCore specially 2020-10-20 23:52:19 +09:00
Koichi Sasada f6661f5085 sync RClass::ext::iv_index_tbl
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.
2020-10-17 08:18:04 +09:00
Alan Wu 1d8b689b9e Remove unused field in rb_iseq_constant_body
This was introduced in 191ce5344e
and has been unused since beae6cbf0f
2020-07-23 01:17:59 -04:00
Koichi Sasada a0f12a0258
Use ID instead of GENTRY for gvars. (#3278)
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.
2020-07-03 16:56:44 +09:00
Koichi Sasada 8070cb56db
fix return event and opt_invokebuiltin_delegate_leave (#3256)
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.
2020-06-26 10:21:56 +09:00
Takashi Kokubun 737da8d383
Add another missing cast 2020-06-23 23:57:26 -07:00
Takashi Kokubun 6ecef1199e
Add missing cast 2020-06-23 23:50:31 -07:00
Takashi Kokubun 3e02cd518f
Trace :return of builtin methods
using opt_invokebuiltin_delegate_leave insn.

Since Ruby 2.7, :return of methods using builtin have not been traced properly.
2020-06-23 23:42:38 -07:00
Koichi Sasada b06d7c5521
ISeq created with callback is special, translation cannot be applied 2020-06-17 08:18:45 +09:00
卜部昌平 77293cef91 vm_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.
2020-06-09 09:52:46 +09:00
卜部昌平 9e41a75255 sed -i 's|ruby/impl|ruby/internal|'
To fix build failures.
2020-05-11 09:24:08 +09:00
卜部昌平 d7f4d732c1 sed -i s|ruby/3|ruby/impl|g
This shall fix compile errors.
2020-05-11 09:24:08 +09:00
Nobuyoshi Nakada 69b3e0ac59 Create succ_index_table as a part of `iseq_setup`
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`.
2020-04-15 16:06:48 +09:00
Nobuyoshi Nakada f9822d1738
Shrink diassembled result string 2020-04-15 12:17:45 +09:00
Nobuyoshi Nakada e474c189da
Suppress -Wswitch warnings 2020-04-08 15:13:37 +09:00
卜部昌平 9e6e39c351
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
2020-04-08 13:28:13 +09:00
Jeremy Evans d2c41b1bff Reduce allocations for keyword argument hashes
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
2020-03-17 12:09:43 -07:00
Takashi Kokubun 8562bfd150
Move code to mark jit_unit's cc_entries to mjit.c 2020-03-12 22:21:32 -07:00
Takashi Kokubun da4b97a0e3
Pin and inline cme in JIT-ed method calls
```
$ 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-11 00:59:34 -07:00
Takashi Kokubun 9511b4c8fa
Optimize away call data refs in JIT-ed method calls
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-03-10 23:29:50 -07:00
Takashi Kokubun 33b78b89ac
Eliminate unnecessary mjit_iseq_cc_entries calls
just in case.
2020-02-26 00:34:02 -08:00
Takashi Kokubun 69f377a3d6
Internalize rb_mjit_unit definition again
Fixed a TODO in b9007b6c54
2020-02-26 00:27:29 -08:00
Koichi Sasada 84d1a99a3f should be initialize jit_unit->cc_entries.
GC can invoke just after allocation of jit_unit->cc_entries so
it should be zero-cleared.
2020-02-25 13:37:52 +09:00
Koichi Sasada f744d80106 check USE_MJIT
iseq->body->jit_unit is not available if USE_MJIT==0 .
2020-02-22 11:54:19 +09:00
Koichi Sasada b9007b6c54 Introduce disposable call-cache.
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.
2020-02-22 09:58:59 +09:00
Koichi Sasada f2286925f0 VALUE size packed callinfo (ci).
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.
2020-02-22 09:58:59 +09:00
卜部昌平 b223a78a71 this 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.
2020-02-06 11:46:51 +09:00
0x005c 461db352c2 Rename RUBY_MARK_NO_PIN_UNLESS_NULL to RUBY_MARK_MOVABLE_UNLESS_NULL 2020-01-23 00:11:03 +13:00
卜部昌平 5e22f873ed decouple 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).
2019-12-26 20:45:12 +09:00
Nobuyoshi Nakada db16629008
Fixed misspellings
Fixed misspellings reported at [Bug #16437], only in ruby and rubyspec.
2019-12-20 09:32:42 +09:00
Yusuke Endoh 60c53ff6ee vm_core.h (iseq_unique_id): prefer uintptr_t instead of unsigned long
It produced a warning about type cast in LLP64 (i.e., windows).
2019-12-10 17:12:21 +09:00
Yusuke Endoh 156fb72d70 vm_args.c (rb_warn_check): Use iseq_unique_id instead of its pointer
(This is the second try of 036bc1da6c6c9b0fa9b7f5968d897a9554dd770e.)

If iseq is GC'ed, the pointer of iseq may be reused, which may hide a
deprecation warning of keyword argument change.

http://ci.rvm.jp/results/trunk-test1@phosphorus-docker/2474221

```
1) Failure:
TestKeywordArguments#test_explicit_super_kwsplat [/tmp/ruby/v2/src/trunk-test1/test/ruby/test_keyword.rb:549]:
--- expected
+++ actual
@@ -1 +1 @@
-/The keyword argument is passed as the last hash parameter.* for `m'/m
+""
```

This change ad-hocly adds iseq_unique_id for each iseq, and use it
instead of iseq pointer.  This covers the case where caller is GC'ed.
Still, the case where callee is GC'ed, is not covered.

But anyway, it is very rare that iseq is GC'ed.  Even when it occurs, it
just hides some warnings.  It's no big deal.
2019-12-09 15:22:48 +09:00
Yusuke Endoh 3cdb37d9db Revert "vm_args.c (rb_warn_check): Use iseq_unique_id instead of its pointer"
This reverts commit 036bc1da6c.

This caused a failure on iseq_binary mode.
http://ci.rvm.jp/results/trunk-iseq_binary@silicon-docker/2474587

Numbering iseqs is not trivial due to dump/load.
2019-12-09 13:49:24 +09:00
Yusuke Endoh 036bc1da6c vm_args.c (rb_warn_check): Use iseq_unique_id instead of its pointer
If iseq is GC'ed, the pointer of iseq may be reused, which may hide a
deprecation warning of keyword argument change.

http://ci.rvm.jp/results/trunk-test1@phosphorus-docker/2474221

```
  1) Failure:
TestKeywordArguments#test_explicit_super_kwsplat [/tmp/ruby/v2/src/trunk-test1/test/ruby/test_keyword.rb:549]:
--- expected
+++ actual
@@ -1 +1 @@
-/The keyword argument is passed as the last hash parameter.* for `m'/m
+""
```

This change ad-hocly adds iseq_unique_id for each iseq, and use it
instead of iseq pointer.  This covers the case where caller is GC'ed.
Still, the case where callee is GC'ed, is not covered.

But anyway, it is very rare that iseq is GC'ed.  Even when it occurs, it
just hides some warnings.  It's no big deal.
2019-12-09 12:04:58 +09:00
Aaron Patterson 2c8d186c6e
Introduce an "Inline IVAR cache" struct
This commit introduces an "inline ivar cache" struct.  The reason we
need this is so compaction can differentiate from an ivar cache and a
regular inline cache.  Regular inline caches contain references to
`VALUE` and ivar caches just contain references to the ivar index.  With
this new struct we can easily update references for inline caches (but
not inline var caches as they just contain an int)
2019-12-05 13:37:02 -08:00
卜部昌平 0e8219f591 make functions static
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.
2019-11-19 12:36:19 +09:00
Samuel Williams 78e266da1d
Clarify documentation for `InstructionSequence#compile`.
We incorrectly assumed that the `file` argument should be the file name and
caused https://github.com/scoutapp/scout_apm_ruby/issues/307 because
exception backtrace did not contain correct path. This documentation
clarifies the role of the different arguments and provides extra
examples.
2019-11-19 11:40:00 +09:00
Jeremy Evans c5c05460ac Warn on access/modify of $SAFE, and remove effects of modifying $SAFE
This removes the security features added by $SAFE = 1, and warns for access
or modification of $SAFE from Ruby-level, as well as warning when calling
all public C functions related to $SAFE.

This modifies some internal functions that took a safe level argument
to no longer take the argument.

rb_require_safe now warns, rb_require_string has been added as a
version that takes a VALUE and does not warn.

One public C function that still takes a safe level argument and that
this doesn't warn for is rb_eval_cmd.  We may want to consider
adding an alternative method that does not take a safe level argument,
and warn for rb_eval_cmd.
2019-11-18 01:00:25 +02:00
卜部昌平 c9ffe751d1 delete unused functions
Looking at the list of symbols inside of libruby-static.a, I found
hundreds of functions that are defined, but used from nowhere.

There can be reasons for each of them (e.g. some functions are
specific to some platform, some are useful when debugging, etc).
However it seems the functions deleted here exist for no reason.

This changeset reduces the size of ruby binary from 26,671,456
bytes to 26,592,864 bytes on my machine.
2019-11-14 20:35:48 +09:00
Dylan Thacker-Smith ac112f2b5d Avoid top-level search for nested constant reference from nil in defined?
Fixes [Bug #16332]

Constant access was changed to no longer allow top-level constant access
through `nil`, but `defined?` wasn't changed at the same time to stay
consistent.

Use a separate defined type to distinguish between a constant
referenced from the current lexical scope and one referenced from
another namespace.
2019-11-13 15:36:58 +09:00
Takashi Kokubun 5c168c7e7f
Support RB_BUILTIN in ISeq#to_a 2019-11-09 21:40:38 -08:00
Nobuyoshi Nakada 0ad0a8ff58
builtin.h must be included *AFTER* vm_core.h 2019-11-08 14:26:21 +09:00
Koichi Sasada 46acd0075d support builtin features with Ruby and C.
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.
2019-11-08 09:09:29 +09:00
Lourens Naudé 4480d68931 Right size the compile option hash 2019-10-29 11:31:15 +09:00
Aaron Patterson bbf3de22b6
Pin labels during disassembly
We need to ensure that labels are pinned while disassembling.  If the
compactor runs during disassembly, references to these labels could go
bad, so this commit just ensures that the labels can't move until we're
done.
2019-10-28 12:15:05 -07:00
Alan Wu 89e7997622 Combine call info and cache to speed up method invocation
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]
2019-10-24 18:03:42 +09:00