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

975 Коммитов

Автор SHA1 Сообщение Дата
Alan Wu 0a93ea4808 YJIT: Auto fix for clippy::clone_on_copy 2023-11-10 16:55:56 -05:00
Alan Wu b8eb4bd4ce YJIT: Panic with more info when global invalidation patching fails 2023-11-10 11:51:05 -05:00
Alan Wu 38fe710e08 YJIT: Invoke PosMarker callbacks only with solid positions
Previously, PosMarker callbacks ran even when the assembler failed to
assemble its contents due to insufficient space. This was problematic
because when Assembler::compile() failed, the callbacks were given
positions that have no valid code, contrary to general expectation.

For example, we use a PosMarker callback to record VM instruction
boundaries and patch in jumps to exits in case the guest program starts
tracing, however, previously, we could record a location near the end of
the code block, where there is no space to patch in jumps. I suspect
this is the cause of the recent occurrences of rare random failures on
GitHub Actions with the invariants.rs:529 "can rewrite existing code"
message. `--yjit-perf` also uses PosMarker and had a similar issue.

Buffer the list of callbacks to fire, and only fire them when all code
in the assembler are written out successfully. It's more intuitive this
way.
2023-11-10 11:51:05 -05:00
Edwin Garcia 1ee6968855 YJIT: Fix comment typos [ci skip] 2023-11-10 09:47:56 -05:00
Takashi Kokubun 50402db5a7
YJIT: Disable code GC (#8865)
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2023-11-08 10:21:04 -05:00
Jean Boussier d898e8d6f8 Refactor rb_shape_transition_shape_capa out
Right now the `rb_shape_get_next` shape caller need to
first check if there is capacity left, and if not call
`rb_shape_transition_shape_capa` before it can call `rb_shape_get_next`.

And on each of these it needs to checks if we got a TOO_COMPLEX
back.

All this logic is duplicated in the interpreter, YJIT and RJIT.

Instead we can have `rb_shape_get_next` do the capacity transition
when needed. The caller can compare the old and new shapes capacity
to know if resizing is needed. It also can check for TOO_COMPLEX
only once.
2023-11-08 11:02:55 +01:00
Alan Wu 7367336c4e YJIT: Fix assert in OOM scenario
We still need to do `jit.record_boundary_patch_point = false`
when gen_outlined_exit() returns `None` and we return with `?`.
Previously, we tripped the assert at codegen.rs:1042.

Found with `--yjit-exec-mem-size=3` on the lobsters benchmark.

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2023-11-07 18:50:10 -05:00
Alan Wu a1c61f0ae5 YJIT: Use u32 for CodePtr to save 4 bytes each
We've long had a size restriction on the code memory region such that a
u32 could refer to everything. This commit capitalizes on this
restriction by shrinking the size of `CodePtr` to be 4 bytes from 8.

To derive a full raw pointer from a `CodePtr`, one needs a base pointer.
Both `CodeBlock` and `VirtualMemory` can be used for this purpose. The
base pointer is readily available everywhere, except for in the case of
the `jit_return` "branch". Generalize lea_label() to lea_jump_target()
in the IR to delay deriving the `jit_return` address until `compile()`,
when the base pointer is available.

On railsbench, this yields roughly a 1% reduction to `yjit_alloc_size`
(58,397,765 to 57,742,248).
2023-11-07 17:43:43 -05:00
Takashi Kokubun 9877f3ada8
YJIT: Inline basic Ruby methods (#8855)
* YJIT: Inline basic Ruby methods

* YJIT: Fix "InsnOut operand made it past register allocation"

checktype should not generate a useless instruction.
2023-11-07 10:54:33 -05:00
Jean byroot Boussier a294bb844c
YJIT: handle out of shape situation in gen_setinstancevariable (#8857)
If the VM ran out of shape, `rb_shape_transition_shape_capa` might
return `OBJ_TOO_COMPLEX_SHAPE`.

Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
2023-11-07 10:49:36 -05:00
Maxime Chevalier-Boisvert 6e38076b16
YJIT: implement two-step call threshold (#8839)
* YJIT: implement two-step call threshold

Automatically switch call threshold to a larger value for
larger, production-sized apps, while still allowing smaller apps
and command-line programs to start with a lower threshold.

* Update yjit/src/options.rs

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

* Make the new variables constants

* Check that a custom call threshold was not specified

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-11-03 21:07:13 +00:00
Alan Wu 38bdb9d0da YJIT: Delete some dead code and enable lints 2023-11-03 18:47:41 +00:00
Takashi Kokubun ad4f973ecd
YJIT: Always define method codegen table at boot (#8807) 2023-11-02 09:15:48 -07:00
Aaron Patterson dc81432482 updating bindgen 2023-10-24 10:52:06 -07:00
Takashi Kokubun 8a88172fd4
YJIT: Skip printing stats at exit if --yjit-disable (#8727) 2023-10-20 13:12:38 -07:00
Maxime Chevalier-Boisvert 3e65115cef
YJIT: remove unused `--yjit-greedy-versioning` command-line option (#8713) 2023-10-19 19:29:31 +00:00
Alan Wu cdc2a18541 YJIT: Return Option from asm.compile() for has_dropped_bytes()
So that we get a reminder to check CodeBlock::has_dropped_bytes().
Internally, asm.compile() already checks it, and this patch just
propagates it out to the caller with a `#[must_use]`.

Code GC logic moved out one level in entry_stub_hit(), so the body
can freely use `?`
2023-10-19 14:56:35 -04:00
Takashi Kokubun 6beb09c2c9
YJIT: Add RubyVM::YJIT.enable (#8705) 2023-10-19 10:54:35 -07:00
Alan Wu 9d9aa63e82 YJIT: Enable the dead_code lint and delete some dead code 2023-10-19 11:50:36 -04:00
Alan Wu d2b0c9da2e
YJIT: Add a live ISeq counter
It's an estimator for application size and could be used as a
compilation heuristic later.

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-10-18 23:46:35 +00:00
Katherine Oelsner a7032b80af Revert "shape.h: Make attr_index_t uint8_t"
This reverts commit e3afc212ec.
2023-10-18 15:01:13 -07:00
Takashi Kokubun f51b92fe23
YJIT: Add --yjit-perf (#8697)
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
2023-10-18 21:07:03 +00:00
dependabot[bot] 58ee088bb3 Bump rustix from 0.38.2 to 0.38.19 in /yjit/bindgen
Bumps [rustix](https://github.com/bytecodealliance/rustix) from 0.38.2 to 0.38.19.
- [Release notes](https://github.com/bytecodealliance/rustix/releases)
- [Commits](https://github.com/bytecodealliance/rustix/compare/v0.38.2...v0.38.19)

---
updated-dependencies:
- dependency-name: rustix
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 12:34:10 -07:00
Alan Wu 36ee5d8ca8 YJIT: Fix clippy::redundant_locals
> note: `#[deny(clippy::redundant_locals)]` on by default

On Rust 1.73.0.
2023-10-17 18:36:23 -04:00
Alan Wu 2abd061e8b YJIT: Remove call to compile() on empty Assembler 2023-10-17 15:24:55 -04:00
Takashi Kokubun d458b4127f
YJIT: Add a few missing counters for send fallback (#8681) 2023-10-17 11:36:13 -04:00
Alan Wu 1f7234c015 YJIT: Lookup IDs on boot instead of binding to them
Previously, the version-controlled `cruby_bindings.inc.rs` file
contained the build-time artifact `id.h`, which nobu mentioned hinders
the goal of having fewer magic numbers in the repository.

Lookup the IDs YJIT needs on boot. It costs cycles, but it's fine since
YJIT only uses a handful of IDs at the moment. No perceptible
degradation to boot time found in my testing.
2023-10-17 11:30:35 -04:00
Takashi Kokubun 48c6cea330
YJIT: Count cold_iseq_entry by default (#8654) 2023-10-14 21:00:50 -07:00
Takashi Kokubun 5808999d30
YJIT: Fallback opt_getconstant_path for const_missing (#8623)
* YJIT: Fallback opt_getconstant_path for const_missing

* Fix a comment [ci skip]

* Remove a wrapper function
2023-10-13 08:52:23 -07:00
Alan Wu 0bf1749e9f
YJIT: Fix argument clobbering in some block_arg+rest_param calls (#8647)
Previously, for block argument callsites with some specific argument
count and callee local variable count combinations, YJIT ended up
writing over arguments that are supposed to be collected into a rest
parameter array unmodified.

Detect when clobbering would happen and avoid it. Also, place the block
handler after the stack overflow check, since it writes to new stack
space.

Reported-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-10-13 10:41:53 -04:00
Maxime Chevalier-Boisvert b2e1ddffa5
YJIT: port call threshold logic from Rust to C for performance (#8628)
* Port call threshold logic from Rust to C for performance

* Prefix global/field names with yjit_

* Fix linker error

* Fix preprocessor condition for rb_yjit_threshold_hit

* Fix third linker issue

* Exclude yjit_calls_at_interv from RJIT bindgen

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-10-12 10:05:34 -04:00
Jean Boussier e3afc212ec shape.h: Make attr_index_t uint8_t
Given `SHAPE_MAX_NUM_IVS 80`, we transition to TOO_COMPLEX
way before we could overflow a 8bit counter.

This reduce the size of `rb_shape_t` from 32B to 24B.

If we decide to raise `SHAPE_MAX_NUM_IVS` we can always increase
that type again.
2023-10-11 08:33:09 +02:00
Takashi Kokubun 4d0a619f71
YJIT: Allow --yjit-trace-exits on release builds (#8619) 2023-10-10 14:54:19 -07:00
Jean Boussier 5cc44f48c5 Refactor rb_shape_transition_shape_capa to not accept capacity
This way the groth factor is encapsulated, which allows
rb_shape_transition_shape_capa to be smarter about ideal sizes.
2023-10-10 14:47:54 +02:00
Alan Wu 8cb906d706 YJIT: Simplify linker flavor check
By not allowlisting every OS that could have a GNU flavor linker,
it's also a bigger tent
2023-10-05 17:31:54 -04:00
Maxime Chevalier-Boisvert 13bde94a9f
YJIT: shink local types from 8 to 4 bytes (#8597)
* Shink local types from 8 to 4 bytes, context from 21 to 17 bytes

Use repr(packed)

* Add comment about Type being limited to 4 bits
2023-10-05 17:17:33 -04:00
Alan Wu 7d1abd5d31 YJIT: Run bindgen 2023-10-05 17:09:18 -04:00
Alan Wu 07a7c4bdaf YJIT: Remove duplicate cfp->iseq accessor 2023-10-05 16:40:27 -04:00
Alan Wu 41a6e4bdf9 YJIT: Avoid writing return value to memory in `leave`
Previously, at the end of `leave` we did
`*caller_cfp->sp = return_value`, like the interpreter.
With future changes that leaves the SP field uninitialized for C frames,
this will become problematic. For cases like returning from
`rb_funcall()`, the return value was written above the stack and
never read anyway (callers use the copy in the return register).

Leave the return value in a register at the end of `leave` and have the
code at `cfp->jit_return` decide what to do with it. This avoids the
unnecessary memory write mentioned above. For JIT-to-JIT returns, it goes
through `asm.stack_push()` and benefits from register allocation for
stack temporaries.

Mostly flat on benchmarks, with maybe some marginal speed improvements.

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-10-05 15:53:05 -04:00
Nobuyoshi Nakada cf1223348a
Remove unmatch parenthesis
```
yjit/yjit.mk:48: Extraneous text after `ifneq' directive
```
2023-10-06 03:39:33 +09:00
Thomas Hurst fd22d5debb
YJIT: Build on BSD platforms with GNU make (#8591) 2023-10-05 13:23:51 -04:00
Takashi Kokubun f834b1a40d YJIT: Add a comment for YJIT_OPTIONS [ci skip] 2023-10-04 10:28:32 -07:00
Takashi Kokubun 7db6f448ed Use a better variable name for w 2023-10-04 10:25:46 -07:00
Takashi Kokubun 577ff858bc Make the function names consistent 2023-10-04 10:25:46 -07:00
Takashi Kokubun 01c462ce6a YJIT: Move help descriptions to options.rs 2023-10-04 10:25:46 -07:00
Takashi Kokubun 465bc682a2
YJIT: Call mprotect after entry stub failure (#8582)
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-10-03 22:39:45 -07:00
Maxime Chevalier-Boisvert ea491802fa
YJIT: add heuristic to avoid compiling cold ISEQs (#8522)
* YJIT: Add counter to measure how often we compile "cold" ISEQs (#535)

Fix counter name in DEFAULT_COUNTERS

YJIT: add --yjit-cold-threshold, don't compile cold ISEQs

YJIT: increase default cold threshold to 200_000

Remove rb_yjit_call_threshold()

Remove conflict markers

Fix compilation errors

Threshold 1 should compile immediately

Debug deadlock issue with test_ractor

Fix call threshold issue with tests

* Revert exception threshold logic. Document option in yjid.md

* (void) for 0 parameter functions in C99

* Rename iseq_entry_cold => cold_iseq_entry

* Document --yjit-cold-threshold in ruby.c

* Update doc/yjit/yjit.md

Co-authored-by: Jean byroot Boussier <jean.boussier+github@shopify.com>

* Shorten help string to appease test

* Address bug found by Kokubun. Reorder logic.

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Jean byroot Boussier <jean.boussier+github@shopify.com>
2023-10-03 17:45:46 -04:00
Takashi Kokubun 1992aef722
YJIT: Stop spilling temps on jit_prepare_routine_call (#8581)
YJIT: Remove spill_temps from jit_prepare_routine_call
2023-10-03 12:54:24 -04:00
Takashi Kokubun 0b67e3fd3e
YJIT: Chain-guard opt_mult overflow (#8554)
* YJIT: Chain-guard opt_mult overflow

* YJIT: Support regenerating Jo after Mul
2023-09-29 21:55:48 -04:00
Takashi Kokubun 0d4c4b6573
YJIT: Use registers for passing C method arguments (#8538) 2023-09-29 10:08:15 -04:00
Takashi Kokubun a8578fff98
YJIT: Remove obsoleted jit_rb_int_mul (#8539) 2023-09-29 10:01:50 -04:00
Takashi Kokubun 9aeb6e72db
YJIT: Avoid creating a vector in get_temp_regs() (#8446)
* YJIT: Avoid creating a vector in get_temp_regs()

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>

* Remove unused import

---------

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-09-15 21:41:00 -04:00
Alan Wu 7cec7d14c3
YJIT: Fix object movement bug in iseq guard for invokeblock
Since the compile-time iseq used in the guard was not marked and updated
during compaction, a runtime value reusing the address could falsely pass
the guard.

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-15 19:03:48 -04:00
Alan Wu 0996cf5593 YJIT: Fix and enable the unused_imports warning 2023-09-15 16:15:15 -04:00
Takashi Kokubun 982d6503b9
YJIT: Skip Insn::Comment and format! if disasm is disabled (#8441)
* YJIT: Skip Insn::Comment and format!

if disasm is disabled

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>

* YJIT: Get rid of asm.comment

---------

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
2023-09-14 15:49:40 -07:00
Alan Wu 0ba6c603bc YJIT: Remove UTF-8 BOM [ci skip]
/yjit/src/backend/x86_64/mod.rs Is also UTF-8 and it doesn't have the
marker. The standard recommends against it, so remove it.
2023-09-14 18:40:45 -04:00
Alan Wu 1961c5bb76
YJIT: Plug native stack overflow
Previously, TestStack#test_machine_stack_size failed pretty consistently
on ARM64 macOS, with Rust code and part of the interpreter used for
per-instruction fallback (rb_vm_invokeblock() and friends) touching the
stack guard page and crashing with SEGV. I've also seen the same test
fail on x64 Linux, though with a different symptom.
2023-09-14 17:18:45 -04:00
Takashi Kokubun fcc1699162
YJIT: Initialize Vec with capacity for iterators (#8439) 2023-09-14 10:55:00 -07:00
Takashi Kokubun cdc69da9e5
YJIT: Initialize Assembler vectors with capacity (#8437) 2023-09-14 10:10:31 -04:00
Takashi Kokubun b49be2a70f
YJIT: Skip adding past_page_bytes for past pages (#8433)
YJIT: Skip adding past_pages_bytes for past pages
2023-09-13 16:44:23 -04:00
Takashi Kokubun ff329ce428
YJIT: Make yjit_alloc_size available by default (#8426) 2023-09-13 10:48:14 -04:00
Takashi Kokubun 721d21d301
YJIT: Make compile_time_ns a default counter (#8425) 2023-09-13 10:45:40 -04:00
Takashi Kokubun 0ae7f2d1ac
YJIT: Add compilation time counter (#8417)
* YJIT: Add compilation time counter

* YJIT: Use Instant instead
2023-09-12 13:52:40 -04:00
Alan Wu 39ee3e22bd Make Kernel#lambda raise when given non-literal block
Previously, Kernel#lambda returned a non-lambda proc when given a
non-literal block and issued a warning under the `:deprecated` category.
With this change, Kernel#lambda will always return a lambda proc, if it
returns without raising.

Due to interactions with block passing optimizations, we previously had
two separate code paths for detecting whether Kernel#lambda got a
literal block. This change allows us to remove one path, the hack done
with rb_control_frame_t::block_code introduced in 85a337f for supporting
situations where Kernel#lambda returned a non-lambda proc.

[Feature #19777]

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-12 11:25:07 -04:00
Ian Candy 78233e8352
Add `String#getbyte` YJIT implementation (#8397)
* Add getbyte JIT implementation

Adds an implementation for String#getbyte for YJIT, along with a
bootstrap test. This should be helpful for pure Ruby implementations
and to avoid unneeded allocations.

Co-authored-by: John Hawthorn <jhawthorn@github.com>

* Skip the getbyte test for RJIT for now

---------

Co-authored-by: John Hawthorn <jhawthorn@github.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-07 23:15:24 -04:00
Takashi Kokubun 89edce4321
YJIT: Decrease IVAR_MAX_DEPTH to 8 (#8398) 2023-09-07 23:15:08 -04:00
Takashi Kokubun fcdedf7f47
YJIT: Decrease SEND_MAX_DEPTH to 5 (#8390) 2023-09-07 14:22:34 -04:00
Aaron Patterson 0adca625ee
Remove function call for String#bytesize (#8389)
* Remove function call for String#bytesize

String size is stored in a consistent location, so we can eliminate the
function call.

* Update yjit/src/codegen.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-07 09:54:05 -04:00
Alan Wu f1422e4cec YJIT: Different comment when only setting ec->cfp [ci skip] 2023-09-06 15:32:36 -04:00
Takashi Kokubun a334077b7b
YJIT: Make compiled_* stats available by default (#8379)
* YJIT: Make compiled_* stats available by default

* Update comment about default counters [ci skip]

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-09-06 09:29:33 -07:00
Alan Wu 6c4df555fd YJIT: Silence Clippy for bindgen generated code
New Clippy lint in 1.72.0 is breaking our build as GitHub has updated
their image. No point hearing about lints from generated code we don't
manually write.
2023-09-05 14:46:44 -04:00
John Hawthorn 43825fba6e YJIT: Handle getblockparamproxy with ifunc
getblockparamproxy for "ifunc" behaves identically to iseq, in just
pushing rb_block_param_proxy.
2023-08-31 10:46:24 -04:00
Maxime Chevalier-Boisvert e58fed128b
YJIT: shrink Context from 29 to 21 bytes by reducing space used by TempMapping (#8321)
* YJIT: merge tempmapping and temp types into a single-byte encoding

YJIT: refactor to shrink Context by 8 bytes

* Add tests, fix bug in TempMapping::map_to_local()

* Update yjit/src/core.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

* Update yjit/src/core.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

* Fewer transmutes where `as` would suffice. Also repr(u8)

* Update yjit/src/core.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

* Update yjit/src/core.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

* Update yjit/src/core.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-08-30 11:14:51 -04:00
Alan Wu 23c83d172c YJIT: Remove Type::CArray and limit use of Type::CString
These types are essentially claims about what `RBASIC_CLASS(obj)`
returns. The field changes with singleton class creation, but we didn't
consider so previously and elided guards where we actually needed them.

Found running ruby/spec with --yjit-verify-ctx. The assertion interface
makes extensive use of singleton classes.
2023-08-28 17:14:33 -04:00
Alan Wu 5937a0da80 YJIT: Refactor to use Option<BlockHandler> in SpecVal
We pass block around as `Option<BlockHandler>` having SpecVal
match that simplifes code matching for the `None` case.
2023-08-24 17:35:10 -04:00
Alan Wu f61e620c4d YJIT: Move block handler SpecVal variants into BlockHandler
A refactor so that the variants correspond to
branches in vm_caller_setup_arg_block().
2023-08-24 17:35:10 -04:00
Alan Wu b4bc047f2f
YJIT: Implement VM_CALL_ARGS_BLOCKARG with Proc for ISeq calls
Rack uses this. Speculate that the `obj` in `the_call(&obj)`
will be a proc when the compile-time sample is a proc.

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2023-08-23 11:10:52 -04:00
Aaron Patterson 58c1ebb634
Fix guard-heap upgrades (#8264)
* Fix guard-heap upgrades

`getinstancevariable` was generating more heap guards than I thought.
It turns out that the upgrade code has a bug in it.

Given the following Ruby code:

```ruby
class Foo
  def initialize
    @a = 1
    @b = 1
  end

  def foo
    [@a, @b]
  end
end

foo = Foo.new
10.times { foo.foo }

puts RubyVM::YJIT.disasm Foo.instance_method(:foo)
```

Before this commit, the machine code was like this:

```
== BLOCK 1/4, ISEQ RANGE [0,3), 36 bytes ======================
  # Insn: 0000 getinstancevariable (stack_size: 0)
  0x5562fb831023: mov rax, qword ptr [r13 + 0x18]
  # guard object is heap
  0x5562fb831027: test al, 7
  0x5562fb83102a: jne 0x5562fb833080
  0x5562fb831030: test rax, rax
  0x5562fb831033: je 0x5562fb833080
  # guard shape
  0x5562fb831039: cmp dword ptr [rax + 4], 0x18
  0x5562fb83103d: jne 0x5562fb833062
  # reg_temps: 00000000 -> 00000001
  0x5562fb831043: mov rsi, qword ptr [rax + 0x10]

== BLOCK 2/4, ISEQ RANGE [3,6), 0 bytes =======================
== BLOCK 3/4, ISEQ RANGE [3,6), 36 bytes ======================
  # regenerate_branch
  # Insn: 0003 getinstancevariable (stack_size: 1)
  # regenerate_branch
  0x5562fb831047: mov rax, qword ptr [r13 + 0x18]
  # guard object is heap
  0x5562fb83104b: test al, 7
  0x5562fb83104e: jne 0x5562fb8330db
  0x5562fb831054: test rax, rax
  0x5562fb831057: je 0x5562fb8330db
  # guard shape
  0x5562fb83105d: cmp dword ptr [rax + 4], 0x18
  0x5562fb831061: jne 0x5562fb8330ba
  # reg_temps: 00000001 -> 00000011
  0x5562fb831067: mov rdi, qword ptr [rax + 0x18]
```

After this commit, the machine code has fewer guards for `self`:

```
== BLOCK 1/4, ISEQ RANGE [0,3), 36 bytes ======================
  # Insn: 0000 getinstancevariable (stack_size: 0)
  0x55cb5db5f023: mov rax, qword ptr [r13 + 0x18]
  # guard object is heap
  0x55cb5db5f027: test al, 7
  0x55cb5db5f02a: jne 0x55cb5db61080
  0x55cb5db5f030: test rax, rax
  0x55cb5db5f033: je 0x55cb5db61080
  # guard shape
  0x55cb5db5f039: cmp dword ptr [rax + 4], 0x18
  0x55cb5db5f03d: jne 0x55cb5db61062
  # reg_temps: 00000000 -> 00000001
  0x55cb5db5f043: mov rsi, qword ptr [rax + 0x10]

== BLOCK 2/4, ISEQ RANGE [3,6), 0 bytes =======================
== BLOCK 3/4, ISEQ RANGE [3,6), 18 bytes ======================
  # regenerate_branch
  # Insn: 0003 getinstancevariable (stack_size: 1)
  # regenerate_branch
  0x55cb5db5f047: mov rax, qword ptr [r13 + 0x18]
  # guard shape
  0x55cb5db5f04b: cmp dword ptr [rax + 4], 0x18
  0x55cb5db5f04f: jne 0x55cb5db610ba
  # reg_temps: 00000001 -> 00000011
  0x55cb5db5f055: mov rdi, qword ptr [rax + 0x18]
```

Co-Authored-By: Takashi Kokubun <takashikkbn@gmail.com>

* Fix array/string guards as well

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-08-23 10:34:03 -04:00
Alan Wu ff55238913
YJIT: x64: Split mem-to-mem Insn::Store like Insn::Mov
The ARM backend allows for this so let's make x64 consistent.
2023-08-22 18:43:56 -04:00
Alan Wu 817ffa8ec4
YJIT: Remove unnecessary roundtrip conversion 2023-08-21 12:52:34 -04:00
ywenc 3dff315ed3
YJIT: Quiet mode when running with `--yjit-stats` (#8251)
Quiet mode for running with --yjit-stats
2023-08-18 18:27:59 -04:00
Alan Wu 4524aeba2f YJIT: Fix return type of Integer#/ with T_FIXNUM inputs
Issue found by running ruby/spec with `--yjit-verify-ctx`. Thanks!
2023-08-18 12:17:37 -04:00
Maxime Chevalier-Boisvert 314eed8a5e
YJIT: implement fast path for integer multiplication in opt_mult (#8204)
* YJIT: implement fast path for integer multiplication in opt_mult

* Update yjit/src/codegen.rs

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

* Implement mul with overflow checking on arm64

* Fix missing semicolon

* Add arm splitting for lshift, rshift, urshift

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-08-18 10:05:32 -04:00
Alan Wu 5d48825d55 YJIT: Fix String#<< return type
We previously falsely asserted that String#<< always returns a ::String
instance. Issue was discovered on CI with `--yjit-verify-ctx`.

https://github.com/ruby/ruby/actions/runs/5893760435/job/15986002531
2023-08-17 17:17:31 -04:00
Alan Wu 518d5ab5c8 Add note about rb_f_notimplement [ci skip]
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-08-17 17:14:46 -04:00
Alan Wu 9683eb06cf YJIT: Fix Kernel#respond_to? handling of rb_f_notimplement
We should return false for this type of special methods but wasn't
previously. Was reproducible with:

    make test-all TESTS=../test/-ext-/test_notimplement.rb RUN_OPTS='--yjit-call-threshold=1'
2023-08-17 17:14:46 -04:00
Maxime Chevalier-Boisvert 30a5b94517
YJIT: implement side chain fallback for setlocal to avoid exiting (#8227)
* YJIT: implement side chain fallback for setlocal to avoid exiting

* Update yjit/src/codegen.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-08-17 10:11:17 -04:00
Alan Wu 9acc73d7c5
YJIT: Optional parameter rework and bugfix (#8220)
* YJIT: Fix splatting empty array with rest param

* YJIT: Rework optional parameter handling to fix corner case

The old code had a few unintuitive parts. The starting PC of the callee
was set in different places; `num_param`, which one would assume to be
static for a particular callee seemingly tallied to different amounts
depending on the what the caller passed; `opts_filled_with_splat` was
greater than zero even when the opts were not filled by items in the
splat array. Functionally, the bits that lets the callee know which
keyword parameters are unspecified were not passed properly when there
are optional parameters and a rest parameter, and then optional
parameters are all filled.

Make `num_param` non-mut and use parameter information in the callee
iseq as-is. Move local variable nil fill and placing of the rest array
out of `gen_push_frame()` as they are only ever relevant for iseq calls.
Always place the rest array at `lead_num + opt_num` to fix the
previously buggy situation.

* YJIT: Compile splat calls to iseqs with rest params

Test interactions with optional parameters.
2023-08-15 10:08:48 -04:00
Takashi Kokubun 75c9487a98
YJIT: Chain guard classes on instance_of (#8209) 2023-08-14 10:18:19 -04:00
Takashi Kokubun 02e5095108
YJIT: Implement GET_BLOCK_HANDLER() for invokesuper (#8206) 2023-08-11 13:07:16 -07:00
Maxime Chevalier-Boisvert b6c66604d8
YJIT: increase max chain depth for expandarray (#8205) 2023-08-11 14:08:45 -04:00
Maxime Chevalier-Boisvert a8cd18f08d
YJIT: implement codegen for rb_int_lshift (#8201)
* YJIT: implement codegen for rb_int_lshift

* Update yjit/src/asm/x86_64/mod.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-08-11 11:01:16 -04:00
Takashi Kokubun 654b648223
YJIT: Implement checkmatch instruction (#8203) 2023-08-10 23:08:29 -04:00
Takashi Kokubun d7c0fec40b Update an outdated YJIT binding 2023-08-10 17:44:08 -07:00
Maxime Chevalier-Boisvert b5b34c1f84
YJIT: add mul() instruction to backend IR (#8195) 2023-08-10 14:47:03 -04:00
Takashi Kokubun 3ad306b4f0
YJIT: Fallback megamorphic super/yield to dynamic dispatch (#8197)
YJIT: Fallback megamorphic super/yield

to dynamic dispatch
2023-08-10 14:13:21 -04:00
Takashi Kokubun 92cf14b4c5
YJIT: Allow VM_CALL_ARGS_BLOCKARG on invokesuper (#8198) 2023-08-10 08:59:52 -07:00
Takashi Kokubun 1ccd0eae11
YJIT: Chain guard method IDs for respond_to? (#8196) 2023-08-09 14:46:42 -07:00
Takashi Kokubun 493acaf4d4
YJIT: Distinguish exit and fallback reasons for invokesuper/invokeblock (#8194)
YJIT: Distinguish exit and fallback reasons

for invokesuper/invokeblock
2023-08-09 15:34:30 -04:00
Takashi Kokubun d3efce69ea
YJIT: Count throw instructions for each tag (#8188)
* YJIT: Count throw instructions for each tag

* Show % of each throw type
2023-08-09 10:16:15 -07:00
Maxime Chevalier-Boisvert c9b30f9d76
YJIT: implement imul instruction encoding in x86 assembler (#8191) 2023-08-09 13:12:21 -04:00
Kevin Newton a41c617e41
Implement MUL instruction for aarch64 (#8193) 2023-08-09 12:21:53 -04:00
Takashi Kokubun 6acfc50bcc
YJIT: Count all opt_getconstant_path exit reasons (#8187) 2023-08-09 09:54:24 -04:00
Alan Wu 5eef3ce21f
YJIT: Correct name of a counter (#8186) 2023-08-09 09:47:42 -04:00
Takashi Kokubun cd8d20cd1f
YJIT: Compile exception handlers (#8171)
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-08-08 16:06:22 -07:00
Maxime Chevalier-Boisvert 8d7861e3da
YJIT: expand bitwise shift support in x86 assembler (#8174) 2023-08-04 14:57:56 -04:00
Maxime Chevalier-Boisvert fc0b2a8df2
YJIT: guard for array_len >= num in expandarray (#8169)
Avoid generating long dispatch chains for all array lengths seen.
2023-08-04 10:09:43 -04:00
Maxime Chevalier-Boisvert 4f99240b2e
YJIT: add jb (unsigned less-than) instruction to backend (#8168) 2023-08-03 16:14:44 -04:00
Maxime Chevalier-Boisvert 98b4256aa7
YJIT: handle expandarray_rhs_too_small case (#8161)
* YJIT: handle expandarray_rhs_too_small case

YJIT: fix csel bug in x86 backend, add test

Remove commented out lines

Refactor expandarray to use chain guards

Propagate Type::Nil when known

Update yjit/src/codegen.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

* Add missing counter, use get_array_ptr() in expandarray

* Make change suggested by Kokubun to reuse loop

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-08-03 16:09:18 -04:00
Jean byroot Boussier e20f1e443f
YJIT: Fallback setivar if the receiver isn't T_OBJECT (#8160)
Followup: https://github.com/ruby/ruby/pull/8152

If the receiver is a T_MODULE or T_CLASS and has a lot of
ivars, `get_next_shape_internal` will return `NULL`.

Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
2023-08-02 11:33:12 -04:00
Takashi Kokubun 81c198b5cf
YJIT: Distinguish exit and fallback reasons for send (#8159) 2023-08-02 10:19:39 -04:00
Takashi Kokubun 452debba22
YJIT: Fix --yjit-dump-disasm coloring on less(1) (#8158) 2023-08-02 10:16:37 -04:00
Takashi Kokubun d405410e3c
YJIT: Move ROBJECT_OFFSET_* to yjit.c (#8157) 2023-08-02 10:15:29 -04:00
Hiroshi SHIBATA fd782dcd1e
Revert "YJIT: implement `expandarray_rhs_too_small` case (#8153)"
This reverts commit 3b88a0bee8.

  This commit break aarch64 platform and Apple Silicon
2023-08-02 14:25:16 +09:00
Takashi Kokubun 5ff1c00e17
YJIT: Let local yjit-bindgen exit successfully (#8156) 2023-08-01 14:46:14 -07:00
Maxime Chevalier-Boisvert 3b88a0bee8
YJIT: implement `expandarray_rhs_too_small` case (#8153)
* YJIT: handle expandarray_rhs_too_small case

* YJIT: fix csel bug in x86 backend, add test

* Remove commented out lines
2023-08-01 15:58:00 -04:00
Takashi Kokubun 16b91a346f
YJIT: Fallback setivar if the next shape is too complex (#8152) 2023-08-01 11:43:32 -07:00
Takashi Kokubun bde4080b39
YJIT: Drop Copy trait from Context (#8138) 2023-07-29 21:14:04 -04:00
Takashi Kokubun cf0c907bc7
YJIT: Count setivar too-complex exits (#8131) 2023-07-27 19:35:30 -04:00
Maxime Chevalier-Boisvert 5669a28fde
YJIT: implement missing `asm.jg` instruction in backend (#8130)
YJIT: implement missing jg instruction in backend

While trying to implement a specialize integer left shift, I ran
into a problem where we have no way to do a greater-than comparison
at the moment. Surprising we went this far without ever needing it.
2023-07-27 17:47:29 -04:00
Alan Wu 7633299c50 YJIT: getblockparamproxy for when block is a Proc 2023-07-27 15:03:46 -04:00
Alan Wu 34825ed20d Revert "YJIT: Fix naming for a getblockparamproxy counter"
This reverts commit e7804963f09d7df7f6cce44fbb3e37809c9a15cc.
Oops. The counter was for getblockparam, without "proxy", so
it was aptly named.
2023-07-27 15:03:46 -04:00
Takashi Kokubun e5effa4bd0
YJIT: Use dynamic dispatch for megamorphic send (#8125) 2023-07-27 13:09:17 -04:00
Takashi Kokubun 9bdd485972
YJIT: Count the number of dynamic send dispatches (#8122) 2023-07-26 12:59:59 -07:00
Alan Wu 37160be439 YJIT: Fix naming for a getblockparamproxy counter
The rest of the counters are prefixed with `gbpp_` and that's what
`yjit.rb` uses when printing the summary. This counter wasn't included
in the summary.
2023-07-26 13:58:15 -04:00
ywenc 8ca399d640
Implement `opt_aref_with` instruction (#8118)
Implement gen_opt_aref_with

Vm opt_aref_with is available

Test opt_aref_with

Stats for opt_aref_with

Co-authored-by: jhawthorn <jhawthorn@github.com>
2023-07-26 10:38:59 -04:00
Takashi Kokubun cef60e93e6
YJIT: Fallback send instructions to vm_sendish (#8106) 2023-07-24 13:51:46 -07:00
Takashi Kokubun c4ef3d767b
YJIT: Rename exec_instruction to yjit_insns_count (#8102) 2023-07-20 15:54:59 -04:00
Takashi Kokubun a7127745f1 Get rid of obsoleted __bp__ references 2023-07-20 11:55:31 -07:00
Takashi Kokubun b41fc9b9a4
YJIT: Avoid undercounting retired_in_yjit (#8038)
* YJIT: Count the number of failed instructions

* Rename yjit_insns_count to exec_instructions instead

* Hoist out the exec_instruction counter
2023-07-20 13:14:25 -04:00
Alan Wu f302e725e1
Remove __bp__ and speed-up bmethod calls (#8060)
Remove rb_control_frame_t::__bp__ and optimize bmethod calls

This commit removes the __bp__ field from rb_control_frame_t. It was
introduced to help MJIT, but since MJIT was replaced by RJIT, we can use
vm_base_ptr() to compute it from the SP of the previous control frame
instead. Removing the field avoids needing to set it up when pushing new
frames.

Simply removing __bp__ would cause crashes since RJIT and YJIT used a
slightly different stack layout for bmethod calls than the interpreter.
At the moment of the call, the two layouts looked as follows:

                   ┌────────────┐    ┌────────────┐
                   │ frame_base │    │ frame_base │
                   ├────────────┤    ├────────────┤
                   │    ...     │    │    ...     │
                   ├────────────┤    ├────────────┤
                   │    args    │    │    args    │
                   ├────────────┤    └────────────┘<─prev_frame_sp
                   │  receiver  │
    prev_frame_sp─>└────────────┘
                     RJIT & YJIT      interpreter

Essentially, vm_base_ptr() needs to compute the address to frame_base
given prev_frame_sp in the diagrams. The presence of the receiver
created an off-by-one situation.

Make the interpreter use the layout the JITs use for iseq-to-iseq
bmethod calls. Doing so removes unnecessary argument shifting and
vm_exec_core() re-entry from the interpreter, yielding a speed
improvement visible through `benchmark/vm_defined_method.yml`:

     patched:   7578743.1 i/s
      master:   4796596.3 i/s - 1.58x  slower

C-to-iseq bmethod calls now store one more VALUE than before, but that
should have negligible impact on overall performance.

Note that re-entering vm_exec_core() used to be necessary for firing
TracePoint events, but that's no longer the case since
9121e57a5f.

Closes ruby/ruby#6428
2023-07-17 13:57:58 -04:00
Maxime Chevalier-Boisvert d70484f0eb
YJIT: refactoring to allow for fancier call threshold logic (#8078)
* YJIT: refactoring to allow for fancier call threshold logic

* Avoid potentially compiling functions multiple times.

* Update vm.c

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

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-07-17 10:41:18 -04:00
Takashi Kokubun d814722fb8
YJIT: Make ratio_in_yjit always available (#8064) 2023-07-13 18:14:43 -04:00
Peter Zhu 3223181284 Remove RARRAY_CONST_PTR_TRANSIENT
RARRAY_CONST_PTR now does the same things as RARRAY_CONST_PTR_TRANSIENT.
2023-07-13 14:48:14 -04:00
Peter Zhu 1e7b67f733 [Feature #19730] Remove transient heap 2023-07-13 09:27:33 -04:00
Hiroshi SHIBATA 76ef28186f
[DOC] Removed redundant `the` 2023-07-13 20:30:44 +09:00
Matt Valentine-House d426343418 Store object age in a bitmap
Closes [Feature #19729]

Previously 2 bits of the flags on each RVALUE are reserved to store the
number of GC cycles that each object has survived. This commit
introduces a new bit array on the heap page, called age_bits, to store
that information instead.

This patch still reserves one of the age bits in the flags (the old
FL_PROMOTED0 bit, now renamed FL_PROMOTED).

This is set to 0 for young objects and 1 for old objects, and is used as
a performance optimisation for the write barrier. Fetching the age_bits
from the heap page and doing the required math to calculate if the
object was old or not would slow down the write barrier. So we keep this
bit synced in the flags for fast access.
2023-07-13 09:21:36 +01:00
Maxime Chevalier-Boisvert e770006486
YJIT: add counter for untracked gbpp exit reason (#8052) 2023-07-11 10:17:48 -04:00
Takashi Kokubun 48d95de6a6
YJIT: Use registers to pass stack temps to C calls (#7920)
* YJIT: Use registers to pass stack temps to C calls

* YJIT: Update comments in ccall
2023-07-06 15:51:01 -04:00
Maxime Chevalier-Boisvert 2acb44e044
YJIT: add new stats counter for compiled ISEQ entry points (#8032)
* YJIT: add new stats counter for compiled ISEQ entry points

* Update yjit.rb

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-07-06 10:17:03 -04:00
Takashi Kokubun 9c1776e6b0
YJIT: Use --yjit-exec-mem-size=128 by default (#8031) 2023-07-05 14:21:02 -07:00
Takashi Kokubun 6b2abe570f
YJIT: Avoid reloading InsnOut operands (#8021) 2023-07-04 16:02:39 -04:00
Takashi Kokubun a1d4dada6b
YJIT: Break register cycles for C arguments (take 2) (#8018)
* Revert "Revert "YJIT: Break register cycles for C arguments (#7918)""

This reverts commit 78ca085785.

* Use shfited_live_ranges for the last-insn check
2023-07-04 15:57:32 -04:00
Alan Wu 296782ab60
YJIT: Fix autosplat miscomp for blocks with optionals (#8006)
* YJIT: Fix autosplat miscomp for blocks with optionals

When passing an array as the sole argument to `yield`, and the yieldee
takes more than 1 optional parameter, the array is expanded similar
to `*array` splat calls. This is called "autosplat" in
`setup_parameters_complex()`.

Previously, YJIT did not detect this autosplat condition. It passed the
array without expanding it, deviating from interpreter behavior.
Detect this conditon and refuse to compile it.

Fixes: Shopify/yjit#313

* RJIT: Fix autosplat miscomp for blocks with optionals

This is mirrors the same issue as YJIT. See previous commit.
2023-07-04 10:45:29 -04:00
Hiroshi SHIBATA 218f913aa6 Suppressing security alert of atty dependency by env_logger-0.9.0 2023-07-04 10:18:54 -04:00
Nobuyoshi Nakada 512cac3240
Remove taint and untrusted flags (#7958)
* Make TAINT and UNTRUSTED flags zero

These flags do nothing already, and should break nothing.

* Remove TAINT and UNTRUSTED macros same as functions

These macros had been defined to use with `#ifdef`, but should not be
used anymore.
2023-06-19 11:29:24 -04:00
Takashi Kokubun 78ca085785 Revert "YJIT: Break register cycles for C arguments (#7918)"
This reverts commit 888ba29e46.

It caused a CI failure
http://ci.rvm.jp/results/trunk-yjit@ruby-sp2-docker/4598881
and I'm investigating it.
2023-06-12 11:30:25 -07:00
Takashi Kokubun 888ba29e46
YJIT: Break register cycles for C arguments (#7918) 2023-06-12 12:54:06 -04:00
Peter Zhu 441302be1a Remove RHASH_TRANSIENT_FLAG
Hashes are no longer allocated on the transient heap.
2023-06-08 10:42:59 -04:00
Alan Wu 2b54c135ff
YJIT: Avoid identity-based known-class guards for IO objects (#7911)
`IO#reopen` is very special in that it is able to change the class and
singleton class of IO instances. In its presence, it is not correct to
assume that IO instances has a stable class/singleton class and guard
by comparing identity.
2023-06-06 10:21:29 -04:00
Peter Zhu 7577c101ed
Unify length field for embedded and heap strings (#7908)
* Unify length field for embedded and heap strings

The length field is of the same type and position in RString for both
embedded and heap allocated strings, so we can unify it.

* Remove RSTRING_EMBED_LEN
2023-06-06 10:19:20 -04:00
Takashi Kokubun ebe1077330
YJIT: Fix a warning on cargo test (#7909) 2023-06-05 14:58:04 -07:00
Peter Zhu 2543a6573f Implement Struct on VWA
The benchmark results show that this feature has either a positive or
no impact on performance. The memory usage is also mostly unchanged,
except in hexapdf, where there is a decrease in RSS.

--------------  -----------  ----------  ---------  -----------  ----------  ---------  --------------  -------------
bench           master (ms)  stddev (%)  RSS (MiB)  branch (ms)  stddev (%)  RSS (MiB)  branch 1st itr  master/branch
activerecord    70.8         2.2         56.0       71.7         2.2         56.0       0.99            0.99
erubi_rails     20.5         13.6        94.7       20.5         14.3        94.2       0.93            1.00
hexapdf         2541.0       0.7         212.8      2544.4       0.7         203.4      1.00            1.00
liquid-c        65.6         0.3         38.9       65.3         0.3         38.9       1.01            1.01
liquid-compile  63.7         0.3         34.6       61.1         0.2         34.6       1.04            1.04
liquid-render   163.1        0.1         37.1       163.3        0.1         37.1       1.00            1.00
mail            139.3        0.1         50.5       137.0        0.1         50.1       0.99            1.02
psych-load      2065.7       0.1         36.9       2068.2       0.1         37.3       1.00            1.00
railsbench      2034.6       0.5         103.9      2031.9       0.5         103.8      1.02            1.00
ruby-lsp        65.3         3.1         89.8       66.2         3.0         89.7       1.01            0.99
sequel          73.2         1.0         40.3       73.4         1.0         40.3       1.00            1.00
--------------  -----------  ----------  ---------  -----------  ----------  ---------  --------------  -------------
2023-06-05 15:47:16 -04:00
eileencodes 40f090f433 Revert "Revert "Fix cvar caching when class is cloned""
This reverts commit 10621f7cb9.

This was reverted because the gc integrity build started failing. We
have figured out a fix so I'm reopening the PR.

Original commit message:

Fix cvar caching when class is cloned

The class variable cache that was added in
ruby#4544 changed the behavior of class
variables on cloned classes. As reported when a class is cloned AND a
class variable was set, and the class variable was read from the
original class, reading a class variable from the cloned class would
return the value from the original class.

This was happening because the IC (inline cache) is stored on the ISEQ
which is shared between the original and cloned class, therefore they
share the cache too.

To fix this we are now storing the `cref` in the cache so that we can
check if it's equal to the current `cref`. If it's different we don't
want to read from the cache. If it's the same we do. Cloned classes
don't share the same cref with their original class.

This will need to be backported to 3.1 in addition to 3.2 since the bug
exists in both versions.

We also added a marking function which was missing.

Fixes [Bug #19379]

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2023-06-05 11:11:12 -07:00
Takashi Kokubun 4e26ae3cb9
YJIT: Use #[cfg] instead of if cfg! (#7899) 2023-06-02 14:16:52 -07:00
Aaron Patterson 10621f7cb9
Revert "Fix cvar caching when class is cloned"
This reverts commit 77d1b08247.
2023-06-01 14:55:36 -07:00
eileencodes 77d1b08247 Fix cvar caching when class is cloned
The class variable cache that was added in
https://github.com/ruby/ruby/pull/4544 changed the behavior of class
variables on cloned classes. As reported when a class is cloned AND a
class variable was set, and the class variable was read from the
original class, reading a class variable from the cloned class would
return the value from the original class.

This was happening because the IC (inline cache) is stored on the ISEQ
which is shared between the original and cloned class, therefore they
share the cache too.

To fix this we are now storing the `cref` in the cache so that we can
check if it's equal to the current `cref`. If it's different we don't
want to read from the cache. If it's the same we do. Cloned classes
don't share the same cref with their original class.

This will need to be backported to 3.1 in addition to 3.2 since the bug
exists in both versions.

We also added a marking function which was missing.

Fixes [Bug #19379]

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2023-06-01 08:52:48 -07:00
Takashi Kokubun 1f74e25c3b
YJIT: Force showing a backtrace on panic (#7869) 2023-05-30 11:20:02 -04:00
Nobuyoshi Nakada d8da563f9e
Add a newline at EOF [ci skip] 2023-05-24 15:04:07 +09:00
Takashi Kokubun 94a513b08f
YJIT: Enable debug symbols in dev_nodebug (#7822) 2023-05-19 09:05:39 +09:00
Jimmy Miller bd532fe3ae
YJIT: Move exits in gen_send_iseq to functions and use ? (#7725) 2023-05-01 17:01:06 -04:00
Jeremy Evans 99c6d19e50 Generalize cfunc large array splat fix to fix many additional cases raising SystemStackError
Originally, when 2e7bceb34e fixed cfuncs to no
longer use the VM stack for large array splats, it was thought to have fully
fixed Bug #4040, since the issue was fixed for methods defined in Ruby (iseqs)
back in Ruby 2.2.

After additional research, I determined that same issue affects almost all
types of method calls, not just iseq and cfunc calls.  There were two main
types of remaining issues, important cases (where large array splat should
work) and pedantic cases (where large array splat raised SystemStackError
instead of ArgumentError).

Important cases:

```ruby
define_method(:a){|*a|}
a(*1380888.times)

def b(*a); end
send(:b, *1380888.times)

:b.to_proc.call(self, *1380888.times)

def d; yield(*1380888.times) end
d(&method(:b))

def self.method_missing(*a); end
not_a_method(*1380888.times)

```

Pedantic cases:

```ruby
def a; end
a(*1380888.times)
def b(_); end
b(*1380888.times)
def c(_=nil); end
c(*1380888.times)

c = Class.new do
  attr_accessor :a
  alias b a=
end.new
c.a(*1380888.times)
c.b(*1380888.times)

c = Struct.new(:a) do
  alias b a=
end.new
c.a(*1380888.times)
c.b(*1380888.times)
```

This patch fixes all usage of CALLER_SETUP_ARG with splatting a large
number of arguments, and required similar fixes to use a temporary
hidden array in three other cases where the VM would use the VM stack
for handling a large number of arguments.  However, it is possible
there may be additional cases where splatting a large number
of arguments still causes a SystemStackError.

This has a measurable performance impact, as it requires additional
checks for a large number of arguments in many additional cases.

This change is fairly invasive, as there were many different VM
functions that needed to be modified to support this. To avoid
too much API change, I modified struct rb_calling_info to add a
heap_argv member for storing the array, so I would not have to
thread it through many functions.  This struct is always stack
allocated, which helps ensure sure GC doesn't collect it early.

Because of how invasive the changes are, and how rarely large
arrays are actually splatted in Ruby code, the existing test/spec
suites are not great at testing for correct behavior.  To try to
find and fix all issues, I tested this in CI with
VM_ARGC_STACK_MAX to -1, ensuring that a temporary array is used
for all array splat method calls.  This was very helpful in
finding breaking cases, especially ones involving flagged keyword
hashes.

Fixes [Bug #4040]

Co-authored-by: Jimmy Miller <jimmy.miller@shopify.com>
2023-04-25 08:06:16 -07:00
Takashi Kokubun f492e3b4e5
YJIT: Use general definedivar at the end of chains (#7756) 2023-04-24 12:20:52 -07:00
John Hawthorn 072ef7a1aa YJIT: invokesuper: Remove cme mid matching check
This check was introduced to match an assertion in the C YJIT when this
was originally introduced. I don't believe it's necessary for
correctness of the generated code.

Co-authored-by: Adam Hess <HParker@github.com>
Co-authored-by: Daniel Colson <danieljamescolson@gmail.com>
Co-authored-by: Luan Vieira <luanzeba@github.com>
2023-04-20 16:09:16 -07:00
Takashi Kokubun a42c36c0f1
YJIT: Merge lower_stack into the split pass (#7748) 2023-04-20 15:35:27 -07:00
Maxime Chevalier-Boisvert 277098bde2 Fix inaccurate comment 2023-04-20 16:31:34 -04:00
Takashi Kokubun 64a25977ed
YJIT: Merge csel and mov on arm64 (#7747)
* YJIT: Refactor arm64_split with &mut insn

* YJIT: Merge csel and mov on arm64
2023-04-20 13:08:42 -07:00
Takashi Kokubun 995b960c70
YJIT: Avoid splitting mov for small values on arm64 (#7745)
* YJIT: Avoid splitting mov for small values on arm64

* Fix a comment

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

* YJIT: Test the 0xffff boundary

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-04-20 10:05:30 -07:00
Takashi Kokubun d2d0954c16
YJIT: Replace Mov with LoadInto on arm64 (#7744)
* YJIT: Replace Mov with LoadInto on arm64

* YJIT: Add a test for the new pass
2023-04-19 17:25:24 -07:00
Takashi Kokubun 5fc11f306c
YJIT: Tweak asm comments (#7743) 2023-04-19 19:30:43 -04:00
Takashi Kokubun 2531bb0b66
YJIT: Remove Insn::RegTemps (#7741)
* YJIT: Remove Insn::RegTemps

* Update a comment

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-04-19 13:08:35 -07:00
Aaron Patterson b816ea8772 Implement opt_newarray_send in YJIT
This commit implements opt_newarray_send along with min / max / hash for
stack allocated arrays
2023-04-18 17:16:22 -07:00
Aaron Patterson 66938fc703 updating bindgen 2023-04-18 17:16:22 -07:00
John Hawthorn 2dff1d4fda
YJIT: Fix raw sample stack lengths in exit traces (#7728)
yjit-trace-exits appends a synthetic sample for the instruction being
exited, but we didn't increment the size of the stack. Fixing this count
correctly lets us successfully generate a flamegraph from the exits.

I also replaced the line number for instructions with 0, as I don't
think the previous value had meaning.

Co-authored-by: Adam Hess <HParker@github.com>
2023-04-18 10:09:16 -04:00
Jimmy Miller 293913905e
YJIT: Fixes failure reported by rails for opt+splat+rest (#7727) 2023-04-17 17:58:04 -04:00
Takashi Kokubun 5aa3be65f4
YJIT: Spill a caller stack as late as possible (#7726) 2023-04-17 17:57:33 -04:00
Takashi Kokubun 45c6b58768
YJIT: Add a counter to all side exits (#7720) 2023-04-14 19:49:44 -04:00
Alan Wu 0b95cbcbde YJIT: Remove duplicate `asm.spill_temps()`
`jit_prepare_routine_call()` calls it, and there is another call above on line 2302.

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-04-14 18:01:14 -04:00
Alan Wu 31e67a476f YJIT: Fix false object collection when setting ivar
Previously, setinstancevariable could generate code that calls
`rb_ensure_iv_list_size()` without first updating `cfp->sp`. This means
in the event that a GC start from within said routine the top few
objects would not be marked, causing them to be falsly collected.

Call `jit_prepare_routine_call()` first.

[Bug #19601]
2023-04-14 18:01:14 -04:00
Takashi Kokubun 4501fb8b46
YJIT: Introduce Target::SideExit (#7712)
* YJIT: Introduce Target::SideExit

* YJIT: Obviate Insn::SideExitContext

* YJIT: Avoid cloning a Context for each insn
2023-04-14 17:00:10 -04:00
Jimmy Miller d83e59e6b8
YJIT: Change to Option<CodegenStatus> (#7717) 2023-04-14 14:21:29 -04:00
Takashi Kokubun 8286eed20b Allow testing a different version 2023-04-13 17:53:41 -07:00
Jimmy Miller 08413f982c
YJIT: Add support for rest with option and splat args (#7698) 2023-04-13 16:21:02 -07:00
Takashi Kokubun bbe69fba59
YJIT: Use an enum to represent counters (#7701) 2023-04-13 13:54:09 -04:00
Takashi Kokubun 2fcd3ea6d8
YJIT: Move stack_opnd from Context to Assembler (#7700) 2023-04-13 12:20:29 -04:00
Adam Hess 854baee2c9
YJIT: Add a sampling option to exit tracing (#7693)
Add a sampling option to trace exits

Running YJIT with trace exits enabled can make very large metrics files.
This allows us to configure a sample rate to make tracing exits possible
on larger tests. This also updates the documented YJIT options.

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: John Hawthorn <john@hawthorn.email>
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-04-13 10:07:07 -04:00
John Hawthorn 0ce2bdc76d YJIT: Fix missing argc check in known cfuncs
Previously we were missing a compile-time check that the known cfuncs
receive the correct number of arguments.

We noticied this because in particular when using ARGS_SPLAT, which also
wasn't checked, YJIT would crash on code which was otherwise correct
(didn't raise exceptions in the VM).

This still supports vararg (argc == -1) cfuncs. I added an additional
assertion that when we use the specialized codegen for one of these
known functions that the argc are popped off the stack correctly, which
should help ensure they're implemented correctly (previously the crash
was usually observed on a future `leave` insn).

[Bug #19595]
2023-04-12 17:48:34 -07:00
Takashi Kokubun 00bbd31edb
YJIT: Let Assembler own Context (#7691)
* YJIT: Let Assembler own Context

* Update a comment

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-04-12 12:11:44 -07:00
Alan Wu c767e6f0c2 YJIT: Fix build on A64
Typo fix for the last commit (1432b37)
2023-04-11 19:35:30 -04:00
Takashi Kokubun 1432b3768a YJIT: Fix a compilation warning in x86_64
This is used only for arm64's cb.jmp_ptr_bytes().
2023-04-11 14:59:21 -07:00
Takashi Kokubun 7297374c5e
YJIT: Reduce paddings if --yjit-exec-mem-size <= 128 on arm64 (#7671)
* YJIT: Reduce paddings if --yjit-exec-mem-size <= 128

on arm64

* YJIT: Define jmp_ptr_bytes on CodeBlock
2023-04-11 11:02:52 -04:00
Takashi Kokubun 1ff14a855a
YJIT: Avoid using a register for unspecified_bits (#7685)
Fix [Bug #19586]
2023-04-10 16:35:48 -07:00
Nobuyoshi Nakada 08324ab9eb
Include `--no-llvm-bc` option in `NM` macro only if usable 2023-04-08 12:47:27 +09:00
Takashi Kokubun 89bdf6e94c
YJIT: Stack temp register allocation for arm64 (#7659)
* YJIT: Stack temp register allocation for arm64

* Update a comment

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>

* Update comments about assertion

* Update a comment

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-04-06 11:34:58 -04:00
Matt Valentine-House 2a34bcaa10 Update VPATH for socket, & dependencies
The socket extensions rubysocket.h pulls in the "private" include/gc.h,
which now depends on vm_core.h. vm_core.h pulls in id.h

when tool/update-deps generates the dependencies for the makefiles, it
generates the line for id.h to be based on VPATH, which is configured in
the extconf.rb for each of the extensions. By default VPATH does not
include the actual source directory of the current Ruby so the
dependency fails to resolve and linking fails.

We need to append the topdir and top_srcdir to VPATH to have the
dependancy picked up correctly (and I believe we need both of these to
cope with in-tree and out-of-tree builds).

I copied this from the approach taken in
https://github.com/ruby/ruby/blob/master/ext/objspace/extconf.rb#L3
2023-04-06 11:07:16 +01:00
Takashi Kokubun 1587494b0b
YJIT: Add codegen for Integer methods (#7665)
* YJIT: Add codegen for Integer methods

* YJIT: Update dependencies

* YJIT: Fix Integer#[] for argc=2
2023-04-05 13:19:31 -07:00
Takashi Kokubun 615a1bc470
YJIT: Count the number of actually written bytes (#7658) 2023-04-05 10:32:04 -04:00
Alan Wu 3e1e09b2b7 YJIT: Smoke test on Rust 1.58.0
Since warnings might show up on older version but not newer ones.
2023-04-05 09:49:31 -04:00
Alan Wu 8f734cf93e YJIT: Eanble `unsafe_op_in_unsafe_fn` on crate::core
Encourages commenting about soundness of `unsafe` usages.
2023-04-05 09:49:31 -04:00
Alan Wu 929d55c3c7 Revert "YJIT: Suppress unnecessary `unsafe` block (GH-7634)"
This reverts commit 9e678cdbd0.

Without the `unsafe` annotations, the SAFETY comments make less sense.
I want to keep the SAFETY comments.
2023-04-05 09:49:31 -04:00
Peter Zhu 1da2e7fca3
[Feature #19579] Remove !USE_RVARGC code (#7655)
Remove !USE_RVARGC code

[Feature #19579]

The Variable Width Allocation feature was turned on by default in Ruby
3.2. Since then, we haven't received bug reports or backports to the
non-Variable Width Allocation code paths, so we assume that nobody is
using it. We also don't plan on maintaining the non-Variable Width
Allocation code, so we are going to remove it.
2023-04-04 17:30:06 -04:00
Maxime Chevalier-Boisvert d26d3575ca
YJIT: add stats for ratio of versions per block (#7653) 2023-04-04 16:41:52 -04:00
Takashi Kokubun e5de0fe108 Remove an unused counter
I ended up not using it.
2023-04-04 11:09:09 -07:00
Takashi Kokubun 116c0f92ef Resurrect yjit-smoke-test before #7651 2023-04-04 11:07:57 -07:00
Takashi Kokubun b7717fc390
YJIT: Stack temp register allocation (#7651)
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-04-04 10:58:11 -07:00
Takashi Kokubun 38209ffdca
YJIT: Add codegen for Array#<< (#7645) 2023-04-03 14:10:35 -07:00
Takashi Kokubun 1b475fcd10 Remove an unneeded function copy 2023-04-01 23:09:05 -07:00
Takashi Kokubun df1b007fbd Remove unused VM_CALL_BLOCKISEQ flag 2023-04-01 10:22:47 -07:00
Alan Wu 8938f146ab YJIT: Remove unused variable [ci skip] 2023-03-31 15:19:02 -04:00
Nobuyoshi Nakada 9e678cdbd0
YJIT: Suppress unnecessary `unsafe` block (#7634) 2023-03-31 10:15:39 -04:00
Jimmy Miller a8782c454c YJIT: Test more kw and rest cases and change exit name 2023-03-30 18:01:26 -04:00
Takashi Kokubun 9a617c067f
YJIT: Generate side exits as late as possible (#7612)
* YJIT: Generate side exits late as possible

* YJIT: s/for_stack_size/with_stack_size/

* YJIT: s/get_counter/exit_counter/
2023-03-30 14:15:59 -07:00
Alan Wu 1b06422767
YJIT: Leave cfp->pc uninitialized for VM_FRAME_MAGIC_CFUNC
C function frames don't need to use the VM-specific pc field to run
properly. When pushing a control frame from output code, save one
instruction by leaving the field uninitialized.

Fix-up rb_vm_svar_lep(), which is used while setting local variables via
Regexp#=~. Use cfp->iseq as a secondary signal so it can stop assuming
that all CFUNC frames always have zero pc's.
2023-03-29 17:57:52 -04:00
Alan Wu a1a4d77472 YJIT: code_gc(): Assert self is inline to avoid other_cb()
The derived `&mut` from `other_cb()` overlapped with the parameter
`ocb`.

Use `cfg!()` instead of `#[cfg...]` to avoid unused warnings.
2023-03-29 14:53:49 -04:00
Alan Wu cdededf24d YJIT: Take VM lock in RubyVM::YJIT.code_gc
Code GC needs synchronization.
2023-03-29 14:53:49 -04:00
Alan Wu 93b6997103 YJIT: Fix overlapping &mut in Assembler::code_gc()
Making overlapping `&mut`s triggers Undefined Bahavior. This function
previously had them through `cb` and `ocb` aliasing with `self` or live
references in the caller.

To fix the overlap, take `ocb` as a parameter and don't use `get_inline_cb()`
in the body of the function.
2023-03-29 14:53:49 -04:00
Jimmy Miller a8c6ba23a6
YJIT: Rest and keyword (non-supplying) (#7608)
* YJIT: Rest and keyword (non-supplying)

* Update yjit/src/codegen.rs

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-03-29 12:31:41 -04:00
Maxime Chevalier-Boisvert 39a34694a0
YJIT: Add `--yjit-pause` and `RubyVM::YJIT.resume` (#7609)
* YJIT: Add --yjit-pause and RubyVM::YJIT.resume

This allows booting YJIT in a suspended state. We chose to add a new
command line option as opposed to simply allowing YJIT.resume to work
without any command line option because it allows for combining with
YJIT tuning command line options. It also simpifies implementation.

Paired with Kokubun and Maxime.

* Update yjit.rb

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-03-28 15:21:19 -04:00
Takashi Kokubun 2f8a598dc5
YJIT: Stop using the starting_context pattern (#7610) 2023-03-28 11:40:48 -07:00
Jimmy Miller 59c3fac6c4
YJIT: Rest and block_arg support (#7584) 2023-03-24 17:01:59 -04:00
Alan Wu 35e9b5348d
YJIT: Constify EC to avoid an `as` pointer cast (#7591) 2023-03-24 12:36:06 -04:00
Takashi Kokubun b4e438d8aa
YJIT: Save PC on rb_str_concat (#7586)
[Bug #19483]

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
2023-03-23 13:42:49 -07:00
Jimmy Miller 8286544dc5
YJIT: Use starting context for status === CantCompile (#7583) 2023-03-23 13:11:46 -04:00
Ole Friis Østergaard e950781880
Use shape information in YJIT's definedivar implementation (#7579)
* Use shape information in YJIT's definedivar implementation

* Handle complex shape for definedivar
2023-03-23 11:04:30 -04:00
Koichi Sasada c9fd81b860 `vm_call_single_noarg_inline_builtin`
If the iseq only contains `opt_invokebuiltin_delegate_leave` insn and
the builtin-function (bf) is inline-able, the caller doesn't need to
build a method frame.

`vm_call_single_noarg_inline_builtin` is fast path for such cases.
2023-03-23 14:03:12 +09:00
Alan Wu aa54082d70
YJIT: Fix large ISeq rejection (#7576)
We crashed in some edge cases due to the recent change to not compile
encoded iseqs that are larger than `u16::MAX`.

- Match the C signature of rb_yjit_constant_ic_update() and clamp down
  to `IseqIdx` size
- Return failure instead of panicking with `unwrap()` in codegen when
  the iseq is too large

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Noah Gibbs <noah.gibbs@shopify.com>
2023-03-21 14:24:17 -04:00
Jimmy Miller 5de26bc031
YJIT: Fix incorrect exit in splat (#7575)
So by itself, this shouldn't have been a correctness issue, but we
also pop the stack for block_args. Doing stack manipulation like that
and then side-exiting causes issues. So, while this fixes the
immediate failure, we have a bigger issue with block_args popping and
then exiting that we need to deal with.
2023-03-21 12:57:26 -04:00
Peter Zhu 30e7561d1d Revert "YJIT: Rest and block_arg support (#7557)"
This reverts commit 5d0a1ffafa.

This commit is causing sequel in yjit-bench to raise with this stack trace:

```
sequel-5.64.0/lib/sequel/dataset/sql.rb:266:in `literal': wrong argument type Array (expected Proc) (TypeError)
	from sequel-5.64.0/lib/sequel/database/misc.rb:269:in `literal'
	from sequel-5.64.0/lib/sequel/adapters/shared/sqlite.rb:314:in `column_definition_default_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:564:in `block in column_definition_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:564:in `each'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:564:in `column_definition_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:634:in `block in column_list_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:634:in `map'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:634:in `column_list_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:753:in `create_table_sql'
	from sequel-5.64.0/lib/sequel/adapters/shared/sqlite.rb:348:in `create_table_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:702:in `create_table_from_generator'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:203:in `create_table'
	from benchmarks/sequel/benchmark.rb:19:in `<main>'
```
2023-03-21 10:51:35 -04:00
Takashi Kokubun 51834ff2ec
YJIT: Make dev_nodebug closer to dev (#7570) 2023-03-20 13:03:22 -07:00
Maxime Chevalier-Boisvert 44f444478a
YJIT: tag output type as UnknownHeap in `toregexp` (#7562) 2023-03-20 10:16:22 -04:00
Alan Wu b9f411b3a8 YJIT: Simplify using the BITS associated constant
All the integer types have it.
2023-03-17 17:32:06 -04:00
Maxime Chevalier-Boisvert 6ba07df490
YJIT: make type info more specific in gen_fixnum_cmp and gen_opt_mod (#7555) 2023-03-17 16:16:34 -04:00
Alan Wu 7fc796f92a
YJIT: Delete --yjit-global-constant-state (#7559)
It was useful for evaluating 6068da8937
but I think we should remove it now to make the logic around
invalidation more straight forward.
2023-03-17 16:16:17 -04:00
Alan Wu 2a26a5e677 YJIT: Add and use Branch::assert_layout()
This assert would've caught a bug I wrote while developing
ruby/ruby#7443 so I figured it would be good to commit it
as it could be helpful in the future.
2023-03-17 16:15:58 -04:00
Jimmy Miller 5d0a1ffafa
YJIT: Rest and block_arg support (#7557)
* YJIT: Rest and block_arg support

* Update bootstraptest/test_yjit.rb

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-03-17 16:11:30 -04:00
Takashi Kokubun 9fd94d6a0c
YJIT: Support entry for multiple PCs per ISEQ (GH-7535) 2023-03-17 11:53:17 -07:00
Alan Wu 10e4fa3a0f YJIT: Use raw pointers and shared references over `Rc<RefCell<_>>`
`Rc` and `RefCell` both incur runtime space costs.
In addition, `RefCell` has given us some headaches with the
non obvious borrow panics it likes to throw out. The latest
one started with 7fd53eeb46
and is yet to be resolved.

Since we already rely on the GC to properly reclaim memory for `Block`
and `Branch`, we might as well stop paying the overhead of `Rc` and
`RefCell`. The `RefCell` panics go away with this change, too.

On 25 iterations of `railsbench` with a stats build I got
`yjit_alloc_size: 8,386,129 => 7,348,637`, with the new memory size 87.6%
of the status quo. This makes the metadata and machine code size roughly
line up one-to-one.

The general idea here is to use `&` shared references with
[interior mutability][1] with `Cell`, which doesn't take any extra
space. The `noalias` requirement that `&mut` imposes is way too hard to
meet and verify. Imagine replacing places where we would've gotten
`BorrowError` from `RefCell` with Rust/LLVM miscompiling us due to aliasing
violations. With shared references, we don't have to think about subtle
cases like the GC _sometimes_ calling the mark callback while codegen
has an aliasing reference in a stack frame below. We mostly only need to
worry about liveness, with which the GC already helps.

There is now a clean split between blocks and branches that are not yet
fully constructed and ones that are "in-service", so to speak. Working
with `PendingBranch` and `JITState` don't really involve `unsafe` stuff.
This change allows `Branch` and `Block` to not have as many optional
fields as many of them are only optional during compilation. Fields that
change post-compilation are wrapped in `Cell` to facilitate mutation
through shared references.

I do some `unsafe` dances here. I've included just a couple tests to run
with Miri (`cargo +nightly miri test miri`). We can add more Miri tests
if desired.

[1]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html
2023-03-17 09:30:24 -07:00
Jimmy Miller 5825d7d4a1
YJIT: Remove exit for rest and send combo (#7546) 2023-03-16 17:40:36 -04:00
Maxime Chevalier-Boisvert 473009d7cb
YJIT: add stats to keep track of when branch direction is known (#7544)
This measures the impact of changes made by @jhawthorn last year.
2023-03-16 17:24:08 -04:00
Takashi Kokubun 6183180603
YJIT: Eliminate unnecessary mov for trampolines (#7537) 2023-03-15 16:27:36 -07:00
Alan Wu ca10274fe3
YJIT: Use assert_disasm! in an A64 test to avoid unused warning
I kept getting unused warnings for this macro on A64 macOS.
2023-03-15 19:07:49 -04:00
Maxime Chevalier-Boisvert 9a735c776b
YJIT: use u16 for insn_idx instead of u32 (#7534) 2023-03-15 17:55:29 -04:00
Alan Wu de174681f7 YJIT: Assert that we have the VM lock while marking
Somewhat important because having the lock is a key part of the
soundness reasoning for the `unsafe` usage here.
2023-03-15 15:45:20 -04:00
Aaron Patterson 77c8daa2d4
Make EC required on JIT state (#7520)
* Make EC required on JIT state

Lets make EC required on the JITState object so we don't need to
`unwrap` it.

* Minor nitpicks

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-03-15 10:55:07 -04:00
Takashi Kokubun 70ba310212
YJIT: Introduce no_gc attribute (#7511) 2023-03-14 15:38:58 -07:00
Takashi Kokubun 9a43c63d43
YJIT: Implement throw instruction (#7491)
* Break up jit_exec from vm_sendish

* YJIT: Implement throw instruction

* YJIT: Explain what rb_vm_throw does [ci skip]
2023-03-14 13:39:06 -07:00
Takashi Kokubun 76f2031884
YJIT: Allow testing assembler with disasm (#7470)
* YJIT: Allow testing assembler with disasm

* YJIT: Drop new dependencies

* YJIT: Avoid address manipulation

* YJIT: Introduce assert_disasm! macro

* YJIT: Update the comment about assert_disasm
2023-03-14 13:26:05 -04:00
Takashi Kokubun c7822b8dbb
YJIT: Merge add/sub/and/or/xor and mov on x86_64 (#7492) 2023-03-13 16:32:45 -04:00
Jimmy Miller 45127c84d9
YJIT: Handle rest+splat where non-splat < required (#7499) 2023-03-13 11:12:23 -04:00
Takashi Kokubun 83f6eee76c
YJIT: Bump SEND_MAX_DEPTH to 20 (#7469)
* YJIT: Bump SEND_MAX_DEPTH to 20

* Fix a test failure
2023-03-10 17:14:38 -05:00