ruby-changes:68634
From: Maxime <ko1@a...>
Date: Thu, 21 Oct 2021 08:11:17 +0900 (JST)
Subject: [ruby-changes:68634] 7c9fdb5dc9 (master): Check receiver type and klass in MicroJIT
https://git.ruby-lang.org/ruby.git/commit/?id=7c9fdb5dc9 From 7c9fdb5dc9cb1431f16e67d206971db3e27f9e82 Mon Sep 17 00:00:00 2001 From: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@s...> Date: Fri, 16 Oct 2020 14:46:46 -0400 Subject: Check receiver type and klass in MicroJIT --- ujit_compile.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/ujit_compile.c b/ujit_compile.c index c731a29654..e25a400804 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -520,6 +520,7 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L520 return false; } + //printf("call to C function \"%s\", argc: %lu\n", rb_id2name(mid), argc); // Things we need to do at run-time: // - Check that the cached klass matches @@ -530,6 +531,34 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L531 // - Call the C function // - Remove the frame + // Create a size-exit to fall back to the interpreter + uint8_t* side_exit = ujit_side_exit(ocb, ctx, ctx->pc); + + // Points to the receiver operand on the stack + x86opnd_t recv = ctx_stack_opnd(ctx, argc); + mov(cb, RCX, recv); + + //print_str(cb, rb_id2name(mid)); + //print_ptr(cb, RCX); + + // TODO: guard_is_object() helper function? + // Check that the receiver is an object + cmp(cb, RCX, imm_opnd(0)); + je_ptr(cb, side_exit); + test(cb, RCX, imm_opnd(RUBY_IMMEDIATE_MASK | RUBY_Qnil)); + jnz_ptr(cb, side_exit); + + // Pointer to the klass field of the receiver &(recv->klass) + x86opnd_t klass_opnd = mem_opnd(64, RCX, offsetof(struct RBasic, klass)); + + // IDEA: Aaron suggested we could possibly treat a changed + // class pointer as a cache miss + // Check if we have a cache hit + mov(cb, RAX, const_ptr_opnd((void*)cd->cc->klass)); + cmp(cb, RAX, klass_opnd); + jne_ptr(cb, side_exit); + //print_str(cb, "cache klass hit"); + @@ -539,7 +568,22 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L568 - return false; + + + + + + + + + + + + + + + jmp_ptr(cb, side_exit); + return true; /* // Create a size-exit to fall back to the interpreter -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/