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

807 Коммитов

Автор SHA1 Сообщение Дата
Takashi Kokubun bd91c5127f
YJIT: Add stats option to RubyVM::YJIT.enable (#9297) 2023-12-19 11:47:27 -08:00
Takashi Kokubun b266890dab
YJIT: Add --yjit-disable to help and reorder it (#9230) 2023-12-13 13:29:37 -08:00
Alan Wu d4bbee7475
YJIT: Fix off-by-one in Kernel#send type handling (#9212)
Previously, if the method ID argument happens to be on one below the top
of the stack, we didn't overwrite the type of the stack slot, which
leaves an incorrect type for the stack slot. The included script tripped
asserts both with and without --yjit-verify-ctx.
2023-12-12 22:10:14 +00:00
Alan Wu 9cb0ad863c YJIT: Fix missing arity check for splat calls to methods with optionals
Previously, for splat callsites that land in methods with optional
parameters, we didn't reject the case where the caller supplies too many
arguments. Accepting those calls previously caused YJIT to construct
corrupted control frames, which leads to crashes if the callee uses
certain stack walking methods such as Kernel#raise and String#gsub (for
setting up the frame-local `$~`).

Example crash in a debug build:

    Assertion Failed: ../vm_core.h:1375:VM_ENV_FLAGS:FIXNUM_P(flags)
2023-12-11 19:21:08 -05:00
Alan Wu 4755309474 YJIT: Rename helper function and correct counter name
Counter::guard_send_iseq_has_rest_and_splat_not_equal was using
jump-if-lesser-than, so wasn't checking for equality. Rename function
because moving is destructive in Rust, which is confusing for this function
which doesn't modify the array.
2023-12-11 19:21:08 -05:00
Jeremy Evans a950f23078 Ensure f(**kw, &block) calls kw.to_hash before block.to_proc
Previously, block.to_proc was called first, by vm_caller_setup_arg_block.
kw.to_hash was called later inside CALLER_SETUP_ARG or setup_parameters_complex.

This adds a splatkw instruction that is inserted before sends with
ARGS_BLOCKARG and KW_SPLAT and without KW_SPLAT_MUT. This is not needed in the
KW_SPLAT_MUT case, because then you know the value is a hash, and you don't
need to call to_hash on it.

The splatkw instruction checks whether the second to top block is a hash,
and if not, replaces it with the value of calling to_hash on it (using
rb_to_hash_type).  As it is always before a send with ARGS_BLOCKARG and
KW_SPLAT, second to top is the keyword splat, and top is the passed block.
2023-12-09 13:15:47 -08:00
Takashi Kokubun ac5fd58700
YJIT: Fix on-stack ISEQ comparison for auto_compact (#9164) 2023-12-07 22:53:05 +00:00
Alan Wu 9d9865d9bc YJIT: Add some object validity assertions
We've seen quite a few compaction bugs lately, and these assertions
should give clearer symptoms. We only call class_of() on
objects that the Ruby code can see.
2023-12-06 16:42:53 -05:00
Takashi Kokubun a439fc2f17
YJIT: Avoid register allocation conflict with a higher stack_idx (#9143)
YJIT: Avoid register allocation conflict

with a higher stack_idx
2023-12-06 15:19:43 -05:00
Alan Wu a063969ec1 YJIT: Assert code pages are not partially in-bounds
Helps understand page switching
2023-12-05 13:20:06 -05:00
Alan Wu 695e5c179e YJIT: Simplify code page switching logic, remove an assert
We have received a report of `assert!( !cb.has_dropped_bytes())` in
set_page() failing. The only explanation for this seems to be memory
allocation failing in write_byte(). The if condition implies that
`current_write_pos < dst_pos < mem_size`, which rules out failing to
encode the relative jump. The has_capacity() assert above not tripping
implies that we were in a place in the page where write_byte() did
attempt to write the byte and potentially made a syscall in the process.

Remove the assert, since memory allocation could fail. Also, return
failure if the destination is outside of the code region to detect that
out-of-memory situation quicker.
2023-12-05 13:20:06 -05:00
Alan Wu b5a62eb9ab
YJIT: Mark and update stubs in invalidated blocks (#9104)
Like in the example given in delayed_deallocation(), stubs can be hit
even if the block housing it is invalidated. Mark them so we don't
work with invalidate ISeqs when hitting these stubs.
2023-12-04 10:13:40 -05:00
Takashi Kokubun ba1cdadfc8
YJIT: Cancel on-stack jit_return on invalidation (#9086)
* YJIT: Cancel on-stack jit_return on invalidation

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

* Use RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P

---------

Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
2023-11-30 21:35:55 -05:00
Maxime Chevalier-Boisvert 73e6d8a0d0
YJIT: optimized codegen for `rb_ary_length()` (#9085)
YJIT: optimized codegen for rb_ary_length()
2023-11-30 17:14:53 -05:00
Takashi Kokubun d048bae96b
YJIT: Bump ec->cfp after setting cfp->jit_return (#9072) 2023-11-30 11:23:25 -05:00
Maxime Chevalier-Boisvert 8d1138c1cf
YJIT: edit `yjit.md` and bring it up to date (#9068)
Also make various minor edits to improve readability.
2023-11-29 18:09:55 -05:00
Maxime Chevalier-Boisvert ea3e17e430
YJIT: fix bug in top cfunc logging in `--yjit-stats` (#9056)
YJIT: correctly handle case where there are no cfunc calls

Fix bug in top cfunc logging in `--yjit-stats`
2023-11-28 22:27:11 +00:00
Maxime Chevalier-Boisvert 6310522a9a
YJIT: reduce default exec-mem-size to 64MiB (#9054) 2023-11-28 20:04:33 +00:00
Takashi Kokubun 476a231e7e
YJIT: Assert no patch overlap on pos_marker (#9048) 2023-11-28 10:41:14 -05:00
Maxime Chevalier-Boisvert 7f50c70574
YJIT: add top C function call counts to `--yjit-stats` (#9047)
* YJIT: gather call counts for individual cfuncs

Co-authored by Takashi Kokubun
2023-11-27 22:49:53 +00:00
Maxime Chevalier-Boisvert f05d586cc9
YJIT: record `num_send_cfunc` stat (#9022)
* YJIT: record num_send_cfunc stat

Also report num_send_known_cfunc as percentage of num_send_cfunc

* Rename num_send_known_cfunc => num_send_cfunc_inline

Name seems more descriptive of what we do with out custom codegen
2023-11-23 15:33:43 -05:00
Takashi Kokubun 440b59db10
YJIT: Apply patches ignoring page_end_reserve (#9015) 2023-11-23 10:53:12 -05:00
Takashi Kokubun 95369ac0a3
YJIT: Fix jmp_ptr_bytes on x86_64 (#9016) 2023-11-23 10:50:42 -05:00
Takashi Kokubun 926bfc3bc0
YJIT: Avoid a register spill on arm64 (#9014) 2023-11-22 15:13:32 -08:00
Takashi Kokubun 95d4a52b3a
YJIT: Skip dump-disasm if it fails to create a file (#8968) 2023-11-21 10:28:45 -05:00
Aaron Patterson 6fce8c7980 Don't try compacting ivars on Classes that are "too complex"
Too complex classes use a hash table to store ivs, and should always pin
their IVs.  We shouldn't touch those classes in compaction.
2023-11-20 16:09:48 -08:00
Takashi Kokubun fa547cd702
YJIT: Print a disasm path to stderr (#8967)
YJIT: Print a perf map path to stderr
2023-11-20 14:51:54 -08:00
Maxime Chevalier-Boisvert f9628fb4be
YJIT: make --yjit-max-versions=N option undocumented (#8962)
Not useful for the vast majority of end users to change
this option.
2023-11-20 21:26:18 +00:00
Maxime Chevalier-Boisvert c552a5f7b0
YJIT: shrink `Context` down to 15 bytes (#8911)
* WIP context refactoring

* Refactor to remove Context.temp_mapping
2023-11-13 17:14:24 -05:00
Alan Wu f5fa90fe0b YJIT: Fix `clippy::useless_vec` in a test 2023-11-10 16:55:56 -05:00
Alan Wu 8dfbfa15f6 YJIT: Take cargo --fix for unnecessary calls to into() 2023-11-10 16:55:56 -05:00
Alan Wu 408d5886cf YJIT: Auto fix for clippy::unnecessary_cast 2023-11-10 16:55:56 -05:00
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