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

ruby-changes:68672

From: Alan <ko1@a...>
Date: Thu, 21 Oct 2021 08:12:17 +0900 (JST)
Subject: [ruby-changes:68672] c2cb6a6fd3 (master): MicroJIT: Read pointer to call cache from call data

https://git.ruby-lang.org/ruby.git/commit/?id=c2cb6a6fd3

From c2cb6a6fd38eea3ce91d3370a62aaf6ba15e410a Mon Sep 17 00:00:00 2001
From: Alan Wu <XrXr@u...>
Date: Wed, 21 Oct 2020 18:15:43 -0400
Subject: MicroJIT: Read pointer to call cache from call data

The call cache changes when the call site becomes polymophic and can
result in the generated code falsely assuming cd->cc->cme is not NULL.

Here is a crasher:

    def body(thing)
      thing.strip
    end

    str = ""
    10.times { body(str) }
    body(0) rescue p 'not found'
    body(str)
---
 ujit_compile.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/ujit_compile.c b/ujit_compile.c
index 4dd2c988b1..7beab133c0 100644
--- a/ujit_compile.c
+++ b/ujit_compile.c
@@ -563,12 +563,14 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L563
     // Pointer to the klass field of the receiver &(recv->klass)
     x86opnd_t klass_opnd = mem_opnd(64, REG0, offsetof(struct RBasic, klass));
 
-    // FIXME: currently assuming that cc->klass doesn't change
-    // Ideally we would like the GC to update the klass pointer
-    //
-    // Check if we have a cache hit
-    mov(cb, REG1, const_ptr_opnd((void*)cd->cc->klass));
-    cmp(cb, REG1, klass_opnd);
+    // Load the call cache into REG1
+    mov(cb, REG1, const_ptr_opnd(cd));
+    x86opnd_t ptr_to_cc = member_opnd(REG1, struct rb_call_data, cc);
+    mov(cb, REG1, ptr_to_cc);
+
+    // Check the class of the receiver against the call cache
+    mov(cb, REG0, klass_opnd);
+    cmp(cb, REG0, mem_opnd(64, REG1, offsetof(struct rb_callcache, klass)));
     jne_ptr(cb, side_exit);
 
     // NOTE: there *has to be* a way to optimize the entry invalidated check
@@ -577,9 +579,6 @@ gen_opt_send_without_block(codeblock_t* cb, codeblock_t* ocb, ctx_t* ctx) https://github.com/ruby/ruby/blob/trunk/ujit_compile.c#L579
     // Check that the method entry is not invalidated
     // cd->cc->cme->flags
     // #define METHOD_ENTRY_INVALIDATED(me) ((me)->flags & IMEMO_FL_USER5)
-    mov(cb, REG1, const_ptr_opnd(cd));
-    x86opnd_t ptr_to_cc = member_opnd(REG1, struct rb_call_data, cc);
-    mov(cb, REG1, ptr_to_cc);
     x86opnd_t ptr_to_cme_ = mem_opnd(64, REG1, offsetof(struct rb_callcache, cme_));
     mov(cb, REG1, ptr_to_cme_);
     x86opnd_t flags_opnd = mem_opnd(64, REG1, offsetof(rb_callable_method_entry_t, flags));
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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