[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]