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

38 Коммитов

Автор SHA1 Сообщение Дата
Alan Wu 7e27de2f1e
YJIT: Remove unused branch_t::src_ctx field
No one reads it at the moment and it's heap allocated.
2021-12-15 16:13:23 -05:00
Alan Wu b5b6ab4194
YJIT: Add ability to exit to interpreter from stubs
Previously, YJIT assumed that it's always possible to generate a new
basic block when servicing a stub in branch_stub_hit(). When YJIT is out
of executable memory, for example, this assumption doesn't hold up.

Add handling to branch_stub_hit() for servicing stubs without consuming
more executable memory by adding a code path that exits to the
interpreter at the location the branch stub represents. The new code
path reconstructs interpreter state in branch_stub_hit() and then exits
with a new snippet called `code_for_exit_from_stub` that returns
`Qundef` from the YJIT native stack frame.

As this change adds another place where we regenerate code from
`branch_t`, extract the logic for it into a new function and call it
regenerate_branch(). While we are at it, make the branch shrinking code
path in branch_stub_hit() more explicit.

This new functionality is hard to test without full support for out of
memory conditions. To verify this change, I ran
`RUBY_YJIT_ENABLE=1 make check -j12` with the following patch to stress
test the new code path:

```diff
diff --git a/yjit_core.c b/yjit_core.c
index 4ab63d9806..5788b8c5ed 100644
--- a/yjit_core.c
+++ b/yjit_core.c
@@ -878,8 +878,12 @@ branch_stub_hit(branch_t *branch, const uint32_t target_idx, rb_execution_contex
                 cb_set_write_ptr(cb, branch->end_addr);
             }

+if (rand() < RAND_MAX/2) {
             // Compile the new block version
             p_block = gen_block_version(target, target_ctx, ec);
+}else{
+    p_block = NULL;
+}

             if (!p_block && branch_modified) {
                 // We couldn't generate a new block for the branch, but we modified the branch.
```

We can enable the new test along with other OOM tests once full support
lands.

Other small changes:
 * yjit_utils.c (print_str): Update to work with new native frame shape.
       Follow up for 8fa0ee4d40.
 * yjit_iface.c (rb_yjit_init): Run yjit_init_core() after
       yjit_init_codegen() so `cb` and `ocb` are available.
2021-11-26 18:00:42 -05:00
Alan Wu 13d1ded253 YJIT: Make block invalidation more robust
This commit adds an entry_exit field to block_t for use in
invalidate_block_version(). By patching the start of the block while
invalidating it, invalidate_block_version() can function correctly
while there is no executable memory left for new branch stubs.

This change additionally fixes correctness for situations where we
cannot patch incoming jumps to the invalidated block. In situations
such as Shopify/yjit#226, the address to the start of the block
is saved and used later, possibly after the block is invalidated.

The assume_* family of function now generate block->entry_exit before
remembering blocks for invalidation.

RubyVM::YJIT.simulate_oom! is introduced for testing out of memory
conditions. The test for it is disabled for now because OOM triggers
other failure conditions not addressed by this commit.

Fixes Shopify/yjit#226
2021-11-22 18:23:28 -05:00
Maxime Chevalier-Boisvert 2421527d6e
YJIT code pages refactoring for code GC (#5073)
* New code page allocation logic

* Fix leaked globals

* Fix leaked symbols, yjit asm tests

* Make COUNTED_EXIT take a jit argument, so we can eliminate global ocb

* Remove extra whitespace

* Change block start_pos/end_pos to be pointers instead of uint32_t

* Change branch end_pos and start_pos to end_addr, start_addr
2021-11-04 16:05:41 -04:00
Nobuyoshi Nakada a202408180
Fix typos 2021-11-02 19:17:37 +09:00
Alan Wu f6da559d5b Put YJIT into a single compilation unit
For upstreaming, we want functions we export either prefixed with "rb_"
or made static. Historically we haven't been following this rule, so we
were "leaking" a lot of symbols as `make leak-globals` would tell us.

This change unifies everything YJIT into a single compilation unit,
yjit.o, and makes everything unprefixed static to pass `make leak-globals`.
This manual "unified build" setup is similar to that of vm.o.

Having everything in one compilation unit allows static functions to
be visible across YJIT files and removes the need for declarations in
headers in some cases. Unnecessary declarations were removed.

Other changes of note:
  - switched to MJIT_SYMBOL_EXPORT_BEGIN which indicates stuff as being
    off limits for native extensions
  - the first include of each YJIT file is change to be "internal.h"
  - undefined MAP_STACK before explicitly redefining it since it
    collide's with a definition in system headers. Consider renaming?
2021-10-20 18:19:42 -04:00
Noah Gibbs be06112d48 Fix changes from rebase 2021-10-20 18:19:42 -04:00
Maxime Chevalier-Boisvert f1eb48cb23 Step 2 to remove the global cb/ocb objects. 2021-10-20 18:19:41 -04:00
John Hawthorn fbde1d9bee Store block callee_cme in darray
This allows a block version to have dependencies on multiple CMEs.
2021-10-20 18:19:39 -04:00
John Hawthorn 8fa0ee4d40 Use callee-saved regs for REG_SP, REG_EP, REG_CFP 2021-10-20 18:19:39 -04:00
John Hawthorn 48dca3348a Move yjit_type_of_value into yjit_core.c 2021-10-20 18:19:38 -04:00
John Hawthorn d78ea4abec Implement verify_ctx for debugging 2021-10-20 18:19:38 -04:00
John Hawthorn 6c80150d40 Introduce ctx_{get,set}_opnd_mapping 2021-10-20 18:19:38 -04:00
John Hawthorn 4ea69e5c0b Rename to ctx_upgrade_opnd_type 2021-10-20 18:19:38 -04:00
Aaron Patterson 84a1e04e58 Change register definitions to match the entry point calling convention
The JIT entry point passes the CFP as RSI and the EC as RDI.  Lets match
that so we don't have to shuffle registers around.
2021-10-20 18:19:38 -04:00
Maxime Chevalier-Boisvert 350b686a2c First pass at code page GC object. 2021-10-20 18:19:37 -04:00
John Hawthorn 9e0a56fb24 Add FLONUM detection 2021-10-20 18:19:37 -04:00
John Hawthorn dfc5e5e35b Support guards against symbols and integers
This adds guards
2021-10-20 18:19:37 -04:00
John Hawthorn ea33b0a9ba Add concatstrings to yjit codegen (#58)
* Add ETYPE_TRUE and ETYPE_FALSE

* Implement checktype

* Implement concatstrings

* Update deps
2021-10-20 18:19:35 -04:00
John Hawthorn 764740c661 Merge pull request #50 from jhawthorn/detect_type
Detect types from putobject and getinlinecache
2021-10-20 18:19:35 -04:00
Alan Wu 7eef8f09c0 Implement getblockparamproxy
* Implement getblockparamproxy

* Parallel runner: wait for timeout thread to terminate after killing

Or else the leak cheaker could sees the thread as running and cause test
failures in test-tool.

* Add a comment, use jne

* Comment about where 0x3 comes from
2021-10-20 18:19:35 -04:00
Maxime Chevalier-Boisvert 0cc73ca2a9 Malloc branch entries (#112)
* Malloc branch entries

* Add ASM comment for stack overflow check

* WIP

* Fix branch GC code. Add rb_darray_remove_unordered().

* Fix block end_pos after branch rewriting. Remove dst_patched bits.
2021-10-20 18:19:33 -04:00
Maxime Chevalier-Boisvert 6164274c76 Re-enable local type tracking, until first call 2021-10-20 18:19:33 -04:00
Maxime Chevalier-Boisvert 7ee3636f61 Remove unnamed enums because MSVC sux 2021-10-20 18:19:33 -04:00
Maxime Chevalier-Boisvert f6e3f75c2b Introduce concept of YJIT instruction operands 2021-10-20 18:19:33 -04:00
Alan Wu b626dd7211 YJIT: Fancier opt_getinlinecache
Make sure `opt_getinlinecache` is in a block all on its own, and
invalidate it from the interpreter when `opt_setinlinecache`.
It will recompile with a filled cache the second time around.
This lets YJIT runs well when the IC for constant is cold.
2021-10-20 18:19:33 -04:00
Maxime Chevalier-Boisvert 42af04efee Add flag bits to avoid compiling stubs multiple times.
Fixes bug involving ractors and branch stubs.
2021-10-20 18:19:33 -04:00
Maxime Chevalier-Boisvert cbbae12a96 Keep track of local types in the context 2021-10-20 18:19:33 -04:00
Maxime Chevalier-Boisvert e98d2c5ec8 Add ctcx_stack_push_local() 2021-10-20 18:19:33 -04:00
Alan Wu 21a6345023 YJIT: adjust branch shape properly when target already exists
The old code decides branch->shape based on the write position of the
native code block, which is unsound in case the block already exists
and no new code is written to the write position.

Make this decision with the start address of the target block instead.
Also handle when the branch becomes smaller after patching.
2021-10-20 18:19:32 -04:00
Maxime Chevalier-Boisvert c299112fd7 use ctx_stack_push_self() 2021-10-20 18:19:32 -04:00
Maxime Chevalier-Boisvert aee44e4f2b Part 1 of improved type tracking logic 2021-10-20 18:19:32 -04:00
Maxime Chevalier-Boisvert e47dd8bb88 WIP 2021-10-20 18:19:32 -04:00
Maxime Chevalier-Boisvert c5f3126428 Commit WIP 2021-10-20 18:19:32 -04:00
Maxime Chevalier-Boisvert ac1aa84c1a First sketch at temp type mapping 2021-10-20 18:19:32 -04:00
Alan Wu ec1cbbb07d Get rid of dependency on rb_call_cache 2021-10-20 18:19:32 -04:00
Alan Wu f505446d1f Yjit: rename context struct 2021-10-20 18:19:32 -04:00
Jose Narvaez 4e2eb7695e Yet Another Ruby JIT!
Renaming uJIT to YJIT. AKA s/ujit/yjit/g.
2021-10-20 18:19:31 -04:00