diff options
| author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2020-11-09 16:54:29 -0500 |
|---|---|---|
| committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:26 -0400 |
| commit | 1cd4c8b294acd2b4d34c2c830ee2b541a87a0e6f (patch) | |
| tree | 09acbc2c875e45ce3313541d39f2925f08873ec7 | |
| parent | 64072dd3a6a321b674255f44632f2c34ac196507 (diff) | |
Deoptimize on side-exit
| -rw-r--r-- | ujit_compile.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/ujit_compile.c b/ujit_compile.c index 20592ba54a..064e93152d 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -113,7 +113,7 @@ struct compiled_region_array { const rb_iseq_t *iseq; size_t start_idx; uint8_t *code; - }data[]; + } data[]; }; // Add an element to a region array, or allocate a new region array. @@ -346,14 +346,25 @@ ujit_side_exit(codeblock_t* cb, ctx_t* ctx, VALUE* exit_pc) { uint8_t* code_ptr = cb_get_ptr(cb, cb->write_pos); + // Table mapping opcodes to interpreter handlers + const void * const *table = rb_vm_get_insns_address_table(); + + // Write back the old instruction at the entry PC + // To deotimize the code block this instruction belongs to + VALUE* entry_pc = &ctx->iseq->body->iseq_encoded[ctx->start_idx]; + int entry_opcode = opcode_at_pc(ctx->iseq, entry_pc); + void* entry_instr = (void*)table[entry_opcode]; + mov(cb, RAX, const_ptr_opnd(entry_pc)); + mov(cb, RCX, const_ptr_opnd(entry_instr)); + mov(cb, mem_opnd(64, RAX, 0), RCX); + // Write back the old instruction at the exit PC // Otherwise the interpreter may jump right back to the // JITted code we're trying to exit - const void * const *table = rb_vm_get_insns_address_table(); - int opcode = opcode_at_pc(ctx->iseq, exit_pc); - void* old_instr = (void*)table[opcode]; + int exit_opcode = opcode_at_pc(ctx->iseq, exit_pc); + void* exit_instr = (void*)table[exit_opcode]; mov(cb, RAX, const_ptr_opnd(exit_pc)); - mov(cb, RCX, const_ptr_opnd(old_instr)); + mov(cb, RCX, const_ptr_opnd(exit_instr)); mov(cb, mem_opnd(64, RAX, 0), RCX); // Generate the code to exit to the interpreters |
