| Age | Commit message (Collapse) | Author |
|
Fix unused_mut Rust warnings
Rust version 1.71.0 and up issue these warnings. On GitHub CI, the
warnings were previously seen in -DYJIT_FORCE_ENABLE runs.
|
|
Stubs we generate for invalidation don't necessarily co-locate with the
code that jump to the stub. Since we rely on co-location to keep stubs
alive as they are in the outlined code block, it used to be possible for
code GC inside branch_stub_hit() to free the stub that's its direct
caller, leading us to return to freed code after.
Stubs used to look like:
```
mov arg0, branch_ptr
mov arg1, target_idx
mov arg2, ec
call branch_stub_hit
jmp return_reg
```
Since the call and the jump after the call is the same for all stubs, we
can extract them and use a static trampoline for them. That makes
branch_stub_hit() always return to static code. Stubs now look like:
```
mov arg0, branch_ptr
mov arg1, target_idx
jmp trampoline
```
Where the trampoline is:
```
mov arg2, ec
call branch_stub_hit
jmp return_reg
```
Code GC can now free stubs without problems since we'll always return
to the trampoline, which we generate once on boot and lives forever.
This might save a small bit of memory due to factoring out the static
part of stubs, but it's probably minor.
[Bug #19234]
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
Previously we essentially never freed block even after invalidation.
Their reference count never reached zero for a couple of reasons:
1. `Branch::block` formed a cycle with the block holding the branch
2. Strong count on a branch that has ever contained a stub never
reached 0 because we increment the `.clone()` call for
`BranchRef::into_raw()` didn't have a matching decrement.
It's not safe to immediately deallocate blocks during
invalidation since `branch_stub_hit()` can end up
running with a branch pointer from an invalidated branch.
To plug the leaks, we wait until code GC or global invalidation and
deallocate the blocks for iseqs that are definitely not running.
Notes:
Merged: https://github.com/ruby/ruby/pull/6833
|
|
Rename InsnOpnd => YARVOpnd
Make it more clear this refers to YARV insn/vm operands rather
than backend IR, x86 or ARM insn operands.
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
We frequently make branches that only have one target but we used to
always allocate space for two branch targets. This patch moves all the
information a branch target has into a struct and refer to them using
Option<Box<BranchTarget>>, this way when the second branch target is not
present it only takes 8 bytes.
Retained heap size on railsbench went from 16.17 MiB to 14.57 MiB, a
ratio of about 1.1.
Notes:
Merged: https://github.com/ruby/ruby/pull/6799
|
|
YJIT: Skip padding jumps to side exits
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
* YJIT: Stop wrapping CmePtr with CmeDependency
* YJIT: Fix an outdated comment [ci skip]
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
We switch to a new page when we detect dropped_bytes flipping from false
to true. Previously, when we patch code for invalidation during code gc,
we start with the flag being set to true, so we failed to apply patches
that straddle pages. We would write out jumps half way and then stop,
which left the code corrupted.
Reset the flag before patching so we patch across pages properly.
Notes:
Merged: https://github.com/ruby/ruby/pull/6686
|
|
* YJIT: Fix a wrong type reference
* YJIT: Just remove CapturedSelfOpnd for now
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
* YJIT: Support invokeblock
* Update yjit/src/backend/arm64/mod.rs
* Update yjit/src/codegen.rs
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
Co-Authored-By: Alan Wu <alansi.xingwu@shopify.com>
Co-Authored-By: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
While experimenting I found that it's easy to change Context and forget
to also change the copying operation in limit_block_versions(). Add an
assert to make sure we substitute a compatible generic context when
limiting the number of versions.
Notes:
Merged: https://github.com/ruby/ruby/pull/6656
|
|
Context::new() is the same as Context::default() and
Context::new_with_stack_size() was only used in tests.
Notes:
Merged: https://github.com/ruby/ruby/pull/6656
|
|
Co-authored-by: John Hawthorn <john@hawthorn.email>
Co-authored-by: John Hawthorn <john@hawthorn.email>
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
when it fails to allocate a new page.
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
YJIT: Respect writable_addrs on --yjit-dump-iseq-disasm
as well
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
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.
Notes:
Merged: https://github.com/ruby/ruby/pull/6551
|
|
* YJIT: Count freed ISEQs
* YJIT: Avoid creating payloads for non-JITed ISEQs
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
* fixes more clippy warnings
* Fix x86 c_callable to have doc_strings
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
* 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>
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
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.
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/6350
|
|
* Let --yjit-dump-disasm=all dump ocb code as well
* Use an enum instead
* Add a None Option to DumpDisasm (#444)
* Add a None Option to DumpDisasm
* Update yjit/src/asm/mod.rs
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
* Fix a build failure
* Use only a single name
* Only None will be a disabled case
* Fix cargo test
* Fix --yjit-dump-disasm=all to print outlined cb
Co-authored-by: Jimmy Miller <jimmyhmiller@gmail.com>
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
(https://github.com/Shopify/ruby/pull/430)
* Add --yjit-dump-disasm to dump every compiled code
* Just use get_option
* Carve out disasm_from_addr
* Avoid push_str with format!
* Share the logic through asm.compile
* This seems to negatively impact the compilation speed
Notes:
Merged: https://github.com/ruby/ruby/pull/6289
|
|
* Fix a bus error on regenerate_branch
* Fix pad_size
Notes:
Merged: https://github.com/ruby/ruby/pull/6289
|
|
(https://github.com/Shopify/ruby/pull/402)
|
|
(https://github.com/Shopify/ruby/pull/359)
|
|
* Move allocation into Assembler::pos_marker
We wanted to do this to begin with but didn't because we were confused
about the lifetime parameter. It's actually talking about the lifetime
of the references that the closure captures. Since all of our usages
capture no references (they use `move`), it's fine to put a `+ 'static`
here.
* Use optional token syntax for calling convention macro
* Explicitly request C ABI on ARM
It looks like the Rust calling convention for functions are the same as
the C ABI for now and it's unlikely to change, but it's easy for us to
be explicit here. I also tried saying `extern "aapcs"` but that
unfortunately doesn't work.
|
|
(https://github.com/Shopify/ruby/pull/333)
* Refactor defer_compilation to use PosMarker
* Port gen_direct_jump() to use PosMarker
* Port gen_branch, branchunless
* Port over gen_jump()
* Port over branchif and branchnil
* Fix use od record_boundary_patch_point in jump_to_next_insn
|
|
* Implement PosMarker instruction
* Implement PosMarker in the arm backend
* Make bindgen run only for clang image
* Fix if-else in cirrus CI file
* Add missing semicolon
* Try removing trailing semicolon
* Try to fix shell/YAML syntax
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
|
|
* Fix compile errors on arm on the CI
* Fix typo
|
|
|
|
|
|
|
|
|
|
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/6278
|
|
* YJIT: Add known_* helpers for Type
This adds a few helpers to Type which all return Options representing
what is known, from a Ruby perspective, about the type.
This includes:
* known_class_of: If known, the class represented by this type
* known_value_type: If known, the T_ value type
* known_exact_value: If known, the exact VALUE represented by this type
(currently this is only available for true/false/nil)
* known_truthy: If known, whether or not this value evaluates as true
(not false or nil)
The goal of this is to abstract away the specifics of the mappings
between types wherever possible from the codegen. For example previously
by introducing Type::CString as a more specific version of
Type::TString, uses of Type::TString in codegen needed to be updated to
check either case. Now by using known_value_type, at least in theory we
can introduce new types with minimal (if any) codegen changes.
I think rust's Option type allows us to represent this uncertainty
fairly well, and should help avoid mistakes, and the matching using this
turned out pretty cleanly.
* YJIT: Use known_value_type for checktype
* YJIT: Use known_value_type for T_STRING check
* YJIT: Use known_class_of in guard_known_klass
* YJIT: Use known truthyness in jit_rb_obj_not
* YJIT: Rename known_class_of => known_class
Notes:
Merged-By: maximecb <maximecb@ruby-lang.org>
|