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

322 Коммитов

Автор SHA1 Сообщение Дата
Jemma Issroff a11952dac1 Rename `iv_count` on shapes to `next_iv_index`
`iv_count` is a misleading name because when IVs are unset, the new
shape doesn't decrement this value. `next_iv_count` is an accurate, and
more descriptive name.
2022-10-21 14:57:34 -07:00
Alan Wu 87bb0bee6b
YJIT: Fix page rounding for icache busting
Previously, we found the current page by rounding the current pointer to
the closest smaller page size. This is incorrect because pages are
relative to the start of the address we reserve. For example, if the
starting address is 12KiB modulo the 16KiB page size, once we have more
than 4KiB of code, calculating with the address would incorrectly give
us page 1 when we're actually still on page 0.

Previously, I can reproduce crashes with:

    make btest RUN_OPTS=--yjit-code-page-size=32

on ARM64 macOS, where system page sizes are 16KiB.
2022-10-21 17:06:34 -04:00
Alan Wu 8bbcb75377 YJIT: Read rb_num_t as usize early
This patch makes sure that we're not accidentally reading rb_num_t
instruction arguments as VALUE and accidentally baking them into
code and marking them. Some of these are simply moving the cast earlier,
but some of these avoid potential problems for flag and ID arguments.

Follow-up for 39f7eddec4.
2022-10-21 16:25:41 -04:00
Alan Wu 39f7eddec4 YJIT: Fix gen_expandarray treating argument as VALUE
The expandarray instruction interpreters its arguments as rb_num_t.
YJIT was treating the num argument as a VALUE previously and when
it has a certain bit pattern, it can look like a GC pointer. The
argument is not a pointer, so YJIT crashed when trying to mark those
pointers.

This bug existed previously, but our test suite didn't expose it until
f55212bce9. TestArgf#test_to_io has a
line like:

    a1, a2, a3, a4, a5, a6, a7, a8 = array

Which maps to an expandarray with an argument of 8. Qnil happened to
be defined as 8, which masked the issue.

Fix it by not using the argument as a VALUE.
2022-10-20 18:12:15 -04:00
Alan Wu 2930302244
YJIT: remove some stale comments [ci skip] 2022-10-20 17:17:00 -04:00
Nobuyoshi Nakada 245ad2b38a YJIT: incorporate ruby_special_consts 2022-10-20 15:43:34 -04:00
Nobuyoshi Nakada f55212bce9 Move "special consts" so `Qundef` and `Qnil` differ just 1 bit 2022-10-20 22:05:27 +09:00
Takashi Kokubun b963fb25d2
YJIT: Respect writable_addrs on --yjit-dump-iseq-disasm as well (#6596)
YJIT: Respect writable_addrs on --yjit-dump-iseq-disasm

as well
2022-10-19 20:47:11 -04:00
Takashi Kokubun 0d360ee7ff
YJIT: Skip dumping code for the other cb on --yjit-dump-disasm (#6592)
YJIT: Skip dumping code for the other cb

on --yjit-dump-disasm
2022-10-19 15:36:24 -04:00
Alan Wu 9da0d4ca9d YJIT: fix a #[warn(unused_parens)] 2022-10-19 14:44:58 -04:00
Alan Wu 5ca23caa20
YJIT: fold the "asm_comments" feature into "disasm" (#6591)
Previously, enabling only "disasm" didn't actually build. Since these
two features are closely related and we don't really use one without the
other, let's simplify and merge the two features together.
2022-10-19 14:03:07 -04:00
Jimmy Miller 12c30f215c
Fixes remaining issues and turns back on dead code and unused (#6584) 2022-10-18 16:03:55 -04:00
Jimmy Miller b2ba71df9e
Code clean around unused code for some architectures or features (#6581) 2022-10-18 14:19:41 -04:00
Takashi Kokubun e7166c9bb7
Allow passing a Rust closure to rb_iseq_callback (#6575) 2022-10-18 09:07:11 -07:00
Takashi Kokubun f11765aef0
YJIT: Allow --yjit-dump-disasm to dump into a file (#6552)
* YJIT: Allow --yjit-dump-disasm to dump into a file

* YJIT: Move IO implementation to disasm.rs

* YJIT: More consistent naming
2022-10-17 10:47:22 -07:00
Takashi Kokubun 64c52c4282
YJIT: Interleave inline and outlined code blocks (#6460)
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2022-10-17 10:45:59 -07:00
Takashi Kokubun e7c71c6c92
Make mjit_cont sharable with YJIT (#6556)
* Make mjit_cont sharable with YJIT

* Update dependencies

* Update YJIT binding
2022-10-17 09:27:59 -07:00
Alan Wu ad3d210bea YJIT: call free_block to cleanup block when out of memory
The commented out instance of free_block() is left over from the port.
The addition in gen_single_block() was a place we missed. The new block
is allocated in the same function and could have invariants associated
with it even though there is no space to hold all the code.
2022-10-17 12:11:17 -04:00
Aaron Patterson 1acc1a5c6d YJIT doesn't need rb_obj_ensure_iv_index_mapping
We should make this function static and remove it from YJIT bindings.
2022-10-14 17:14:41 -07:00
Takashi Kokubun 53e0e5e8df
YJIT: Avoid creating payloads for non-JITed ISEQs (#6549)
* YJIT: Count freed ISEQs

* YJIT: Avoid creating payloads for non-JITed ISEQs
2022-10-14 12:45:00 -07:00
Jimmy Miller fb99227ca1
More clippy fixes (#6547) 2022-10-14 13:04:53 -04:00
Jimmy Miller 3c0b4ef1a2
fixes more clippy warnings (#6543)
* fixes more clippy warnings

* Fix x86 c_callable to have doc_strings
2022-10-13 18:20:04 -04:00
Jimmy Miller 93a87f4963
Make op_ext an optional for code clarity (#6542) 2022-10-13 18:17:13 -04:00
Alan Wu 1b0c9d0e3d YJIT: No need to fill to get UDF on ARM64
On ARM64, all zeros is already undefined, so we don't need to do extra
work to fill new memory with undefined instructions.
2022-10-13 14:29:42 -04:00
Jimmy Miller 467992ee35
Implement optimize send in yjit (#6488)
* Implement optimize send in yjit

This successfully makes all our benchmarks exit way less for optimize send reasons.
It makes some benchmarks faster, but not by as much as I'd like. I think this implementation
works, but there are definitely more optimial arrangements. For example, what if we compiled
send to a jump table? That seems like perhaps the most optimal we could do, but not obvious (to me)
how to implement give our current setup.

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>

* Attempt at fixing the issues raised by @XrXr

* fix allowlist

* returns 0 instead of nil when not found

* remove comment about encoding exception

* Fix up c changes

* Update assert

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>

* get rid of unneeded code and fix the flags

* Apply suggestions from code review

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>

* rename and fix typo

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2022-10-11 16:37:05 -04:00
Jemma Issroff 913979bede
Make inline cache reads / writes atomic with object shapes
Prior to this commit, we were reading and writing ivar index and
shape ID in inline caches in two separate instructions when
getting and setting ivars. This meant there was a race condition
with ractors and these caches where one ractor could change
a value in the cache while another was still reading from it.

This commit instead reads and writes shape ID and ivar index to
inline caches atomically so there is no longer a race condition.

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
Co-Authored-By: John Hawthorn <john@hawthorn.email>
2022-10-11 08:40:56 -07: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
Alan Wu 0472effc41
YJIT: add an assert for branch_stub_hit() (#6505)
We set the PC in branch_stub_hit(), which only makes sense if we're
running with the intended iseq for the stub. We ran into an issue caught
by this while tweaking code layout.
2022-10-06 18:42:26 -04:00
Alan Wu 43e87c7e8a
YJIT: fix ARM64 bitmask encoding for 32 bit registers (#6503)
For logical instructions such as AND, there is a constraint that the N
part of the bitmask immediate must be 0. We weren't respecting this
condition previously and were silently emitting undefined instructions.

Check for this condition in the assembler and tweak the backend to
correctly detect whether a number could be encoded as an immediate in a
32 bit logical instruction. Due to the nature of the immediate encoding,
the same numeric value encodes differently depending on the size of
the register the instruction works on.

We currently don't have cases where we use 32 bit immediates but we ran
into this encoding issue during development.
2022-10-06 18:41:38 -04:00
Alan Wu 7293bfe1bf
YJIT: add support for calling bmethods (#6489)
* YJIT: fix a parameter name

* YJIT: add support for calling bmethods

This commit adds support for the VM_METHOD_TYPE_BMETHOD method type in
YJIT. You can get these type of methods from facilities like
Kernel#define_singleton_method and Module#define_method.

Even though the body of these methods are blocks, the parameter setup
for them is exactly the same as VM_METHOD_TYPE_ISEQ, so we can reuse
the same logic in gen_send_iseq(). You can see this from how
vm_call_bmethod() eventually calls setup_parameters_complex() with
arg_setup_method.

Bmethods do need their frame environment to be setup differently. We
handle this by allowing callers of gen_send_iseq() to control the iseq,
the frame flag, and the prev_ep. The `prev_ep` goes into the same
location as the block handler would go into in an iseq method frame.

Co-authored-by: John Hawthorn <john@hawthorn.email>

Co-authored-by: John Hawthorn <john@hawthorn.email>
2022-10-04 22:48:05 -04:00
Jimmy Miller efc7766244
Split cmp operations that aren't 32/64 bit for arm (#6484) 2022-10-03 16:57:27 -04:00
John Hawthorn 70538beaa9 Fix YJIT args for rb_vm_set_ivar_idx
This was broken accidentally with the revert of shapes (it conflicted
with some unrelated cleanup).
2022-09-30 17:26:27 -07:00
John Hawthorn 1143fe340a Fix YJIT build after shapes-revert
An variable had been renamed in between the merge and revert, so the
build was broken. This restores it.
2022-09-30 16:29:10 -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
Jimmy Miller 31461c7e0e
A bunch of clippy auto fixes for yjit (#6476) 2022-09-30 11:14:55 -04: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
Maxime Chevalier-Boisvert a58cbddd57
YJIT: add assertion wrt label names (#6459)
Add assertion wrt label names
2022-09-27 19:27:39 -04:00
Kevin Newton 28433e9aa0
Change IncrCounter lowering on AArch64 (#6455)
* Change IncrCounter lowering on AArch64

Previously we were using LDADDAL which is not available on
Graviton 1 chips. Instead, we're going to use an exclusive
load/store group through the LDAXR/STLXR instructions.

* Update yjit/src/backend/arm64/mod.rs

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2022-09-27 16:58:01 -04: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
Takashi Kokubun 912ea8257a
YJIT: Support Rust 1.58.1 for --yjit-stats on Arm (#6410)
* YJIT: Test Rust 1.58.1 as well on Cirrus

* YJIT: Avoid using a Rust 1.60.0 feature

* YJIT: Use autoconf to detect support

* YJIT: We actually need to run it

for checking it properly

* YJIT: Try cfg!(target_feature = "lse")

* Revert "YJIT: Try cfg!(target_feature = "lse")"

This reverts commit 4e2a9ca9a9c83052c23b5e205c91bdf79e88342e.

* YJIT: Add --features stats only when it works

* Update configure.ac

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2022-09-23 16:17:54 -04:00
Maxime Chevalier-Boisvert 4e40fdbcee
YJIT: add chain guards in `guard_two_fixnums` (#6422)
* Add chain guards in guard_two_fixnums, opt_eq with symbols

* Remove symbol comparison in gen_equality_specialized
2022-09-22 17:47:54 -04:00
John Hawthorn 4b97f1e525
YJIT: Refactor into gen_push_frame (#6412)
This refactors the "push frame" operation common to both gen_send_iseq
and gen_send_cfunc into its own method. This allows that logic to live
in one place.
2022-09-22 17:47:26 -04:00
Maxime Chevalier-Boisvert d3733c2ba5
Guard `--yjit-stats` behind `#[cfg(feature = "stats")]` (#6409)
* Guard --yjit-stats behind #[cfg(feature = "stats")]

* Only ask for --yjit-stats with dev builds on cirrus CI

* Revert "Only ask for --yjit-stats with dev builds on cirrus CI"

This reverts commit cfb5ddfa4b9394ca240447eee02637788435b02a.

* Make it so the --yjit-stats option works for non-release builds

* Revert accidental changes
2022-09-20 19:30:10 -04:00
Alan Wu a8dc49b4d5 YJIT: Support MAKE=bmake for release build
This add support for bmake, which should allow building with
`configure --enable-yjit` for the BSDs. Tested on FreeBSD 13 and
on macOS with `configure MAKE=bmake` on a case-sensitive file system.

It works by including a fragment into the Makefile through the configure
script, similar to common.mk. It uses the always rebuild approach to
keep build system changes minimal.
2022-09-20 14:17:27 -04:00
Takashi Kokubun f8dad616c2
YJIT: Show --yjit-stats of railsbench on CI (#6403)
* YJIT: Show --yjit-stats of railsbench on CI

* YJIT: Use --enable-yjit=dev to see ratio_in_yjit

* YJIT: Show master GitHub URL for quick comparison

* YJIT: Avoid making CI red by a yjit-bench failure
2022-09-20 06:07:28 +09:00
Takashi Kokubun 5883bc7c07
YJIT: Check if the processor supports --yjit-stats (#6401)
* YJIT: Add asm comment for incr_counter

* YJIT: Check if the processor supports --yjit-stats
2022-09-19 16:34:03 +09:00
Jimmy Miller e75d963685
Only exit if ruby2_keywords and splat together (#6395)
Before this change railsbench spent less time in yjit than before splat. This brings it back to parity.
2022-09-19 15:09:38 +09:00
Takashi Kokubun 0ca037b35c
Update bindgen crate (#6397)
to get rid of deprecated indirect dependency, ansi_term
2022-09-18 20:42:57 +09:00
Takashi Kokubun 5b735d0beb
Invalidate i-cache after link_labels (#6388) 2022-09-16 20:44:58 +09:00