[pypy-commit] pypy guard-compatible: Fix for guard_compatible_3

arigo pypy.commits at gmail.com
Sun May 22 16:07:30 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: guard-compatible
Changeset: r84592:c1979bc4a504
Date: 2016-05-22 22:08 +0200
http://bitbucket.org/pypy/pypy/changeset/c1979bc4a504/

Log:	Fix for guard_compatible_3

diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -742,12 +742,12 @@
         # the field in question to point (initially) to the recovery stub
         clt = self.current_clt
         for tok in self.pending_guard_tokens:
+            addr = rawstart + tok.pos_jump_offset
+            tok.faildescr.adr_jump_offset = addr
             if tok.guard_compatible():
                 guard_compat.patch_guard_compatible(tok, rawstart,
                                                     self.gc_table_addr)
                 continue
-            addr = rawstart + tok.pos_jump_offset
-            tok.faildescr.adr_jump_offset = addr
             descr = tok.faildescr
             if descr.loop_version():
                 continue # patch them later
@@ -857,7 +857,12 @@
 
     def patch_jump_for_descr(self, faildescr, adr_new_target):
         if isinstance(faildescr, guard_compat.GuardCompatibleDescr):
-            xxxxxxxxxx
+            # We must not patch the failure recovery stub of a
+            # GUARD_COMPATIBLE.  Instead, the new bridge just compiled
+            # is not attached, but will be later returned by a call to
+            # find_compatible().  Here, we must only invalidate the
+            # cache in the guard's bchoices.
+            guard_compat.invalidate_cache(faildescr)
             return
         adr_jump_offset = faildescr.adr_jump_offset
         assert adr_jump_offset != 0
diff --git a/rpython/jit/backend/x86/guard_compat.py b/rpython/jit/backend/x86/guard_compat.py
--- a/rpython/jit/backend/x86/guard_compat.py
+++ b/rpython/jit/backend/x86/guard_compat.py
@@ -308,6 +308,14 @@
     # bchoices.bc_list[0].asmaddr: patch_guard_compatible()
     return bchoices
 
+def descr_to_bchoices(descr):
+    assert isinstance(descr, GuardCompatibleDescr)
+    # ---no GC operation---
+    bchoices = llop.raw_load(lltype.Signed, descr._backend_choices_addr, 0)
+    bchoices = rffi.cast(lltype.Ptr(BACKEND_CHOICES), bchoices)
+    # ---no GC operation end---
+    return bchoices
+
 def patch_guard_compatible(guard_token, rawstart, gc_table_addr):
     # go to the address in the gctable, number 'bindex'
     bindex = guard_token.guard_compat_bindex
@@ -323,10 +331,8 @@
     guard_compat_descr._backend_choices_addr = choices_addr
     guard_compat_descr._backend_sequel_label = sequel_label
     guard_compat_descr._backend_failure_recovery = failure_recovery
-    # ---no GC operation---
-    bchoices = llop.raw_load(lltype.Signed, choices_addr, 0)
-    bchoices = rffi.cast(lltype.Ptr(BACKEND_CHOICES), bchoices)
-    # ---no GC operation end---
+    #
+    bchoices = descr_to_bchoices(guard_compat_descr)
     assert len(bchoices.bc_list) == 1
     assert (cast_gcref_to_instance(GuardCompatibleDescr, bchoices.bc_faildescr)
             is guard_compat_descr)
@@ -339,8 +345,9 @@
     llop.raw_store(lltype.Void, gcref_base, _real_number(pair_ofs), r_uint(-1))
     llop.raw_store(lltype.Void, gcref_base, _real_number(pair_ofs), r_uint(-1))
 
-def invalidate_cache(bchoices):
+def invalidate_cache(faildescr):
     """Write -1 inside bchoices.bc_most_recent.gcref."""
+    bchoices = descr_to_bchoices(faildescr)
     invalidate_pair(bchoices, BCMOSTRECENT)
 
 


More information about the pypy-commit mailing list