Author: Armin Rigo <ar...@tunes.org>
Branch: guard-compatible
Changeset: r84631:9b21c3eba3b5
Date: 2016-05-23 19:05 +0200
http://bitbucket.org/pypy/pypy/changeset/9b21c3eba3b5/

Log:    Pass around the "tracer" object for the GC table, in order to be
        able to call gc_writebarrier() on it when we change the GC table.

diff --git a/rpython/jit/backend/llsupport/gcreftracer.py 
b/rpython/jit/backend/llsupport/gcreftracer.py
--- a/rpython/jit/backend/llsupport/gcreftracer.py
+++ b/rpython/jit/backend/llsupport/gcreftracer.py
@@ -40,10 +40,14 @@
     # --no GC until here--
     return tr
 
+A = lltype.GcArray(llmemory.GCREF)
+
 def make_boehm_tracer(array_base_addr, gcrefs):
-    # copy the addresses, but return 'gcrefs' as the object that must be
-    # kept alive
+    # copy the addresses, but return 'gcrefs' as a low-level array
+    # object that must be kept alive
+    agcrefs = lltype.malloc(A, len(gcrefs))
     for i in range(len(gcrefs)):
         p = rffi.cast(rffi.SIGNEDP, array_base_addr + i * WORD)
         p[0] = rffi.cast(lltype.Signed, gcrefs[i])
-    return gcrefs
+        agcrefs[i] = gcrefs[i]
+    return agcrefs
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
@@ -721,6 +721,7 @@
         gcreftracers = self.get_asmmemmgr_gcreftracers(looptoken)
         gcreftracers.append(tracer)    # keepalive
         self.teardown_gcrefs_list()
+        self.gc_table_tracer = tracer
 
     def write_pending_failure_recoveries(self, regalloc):
         # for each pending guard, generate the code of the recovery stub
@@ -746,7 +747,8 @@
             tok.faildescr.adr_jump_offset = addr
             if tok.guard_compatible():
                 guard_compat.patch_guard_compatible(tok, rawstart,
-                                                    self.gc_table_addr)
+                                                    self.gc_table_addr,
+                                                    self.gc_table_tracer)
                 continue
             descr = tok.faildescr
             if descr.loop_version():
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
@@ -46,6 +46,7 @@
 # with the following fields:
 #
 #     - bc_faildescr: a copy of the faildescr of that guard
+#     - bc_gc_table_tracer: only for a gc_writebarrier()
 #     - bc_most_recent: 1 pair (gcref, asmaddr)
 #     - bc_list: N pairs (gcref, asmaddr) sorted according to gcref
 #
@@ -180,6 +181,7 @@
                              ('asmaddr', lltype.Signed))
 BACKEND_CHOICES = lltype.GcStruct('BACKEND_CHOICES',
                         ('bc_faildescr', llmemory.GCREF),
+                        ('bc_gc_table_tracer', llmemory.GCREF),
                         ('bc_most_recent', PAIR),
                         ('bc_list', lltype.Array(PAIR)))
 
@@ -273,6 +275,7 @@
                 choices_addr = descr._backend_choices_addr  # GC table
                 bchoices_int = rffi.cast(lltype.Signed, bchoices)
                 llop.raw_store(lltype.Void, choices_addr, 0, bchoices_int)
+                llop.gc_writebarrier(lltype.Void, bchoices.bc_gc_table_tracer)
                 # ---no GC operation end---
             bchoices.bc_most_recent.gcref = gcref_to_unsigned(new_gcref)
             bchoices.bc_most_recent.asmaddr = result
@@ -298,6 +301,7 @@
         new_bchoices = lltype.malloc(BACKEND_CHOICES, length * 2 + 1)
         # --- no GC below: it would mess up the order of bc_list ---
         new_bchoices.bc_faildescr = bchoices.bc_faildescr
+        new_bchoices.bc_gc_table_tracer = bchoices.bc_gc_table_tracer
         new_bchoices.bc_most_recent.gcref = bchoices.bc_most_recent.gcref
         new_bchoices.bc_most_recent.asmaddr = bchoices.bc_most_recent.asmaddr
         i = 0
@@ -328,11 +332,13 @@
 def initial_bchoices(guard_compat_descr, initial_gcref):
     bchoices = lltype.malloc(BACKEND_CHOICES, 1)
     bchoices.bc_faildescr = cast_instance_to_gcref(guard_compat_descr)
+    bchoices.bc_gc_table_tracer = lltype.nullptr(llmemory.GCREF.TO)   # (*)
     bchoices.bc_most_recent.gcref = gcref_to_unsigned(initial_gcref)
-    bchoices.bc_most_recent.asmaddr = -43  # patch_guard_compatible()
+    bchoices.bc_most_recent.asmaddr = -43  # (*)
     bchoices.bc_list[0].gcref = gcref_to_unsigned(initial_gcref)
-    bchoices.bc_list[0].asmaddr = -43  # patch_guard_compatible()
+    bchoices.bc_list[0].asmaddr = -43  # (*)
     llop.gc_writebarrier(lltype.Void, bchoices)
+    # entries with (*) are fixed in patch_guard_compatible()
     return bchoices
 
 def descr_to_bchoices(descr):
@@ -343,7 +349,8 @@
     # ---no GC operation end---
     return bchoices
 
-def patch_guard_compatible(guard_token, rawstart, gc_table_addr):
+def patch_guard_compatible(guard_token, rawstart, gc_table_addr,
+                           gc_table_tracer):
     # go to the address in the gctable, number 'bindex'
     bindex = guard_token.guard_compat_bindex
     choices_addr = gc_table_addr + WORD * bindex
@@ -364,6 +371,8 @@
     assert len(bchoices.bc_list) == 1
     assert (cast_gcref_to_instance(GuardCompatibleDescr, bchoices.bc_faildescr)
             is guard_compat_descr)
+    bchoices.bc_gc_table_tracer = lltype.cast_opaque_ptr(llmemory.GCREF,
+                                                         gc_table_tracer)
     bchoices.bc_most_recent.asmaddr = sequel_label
     bchoices.bc_list[0].asmaddr = sequel_label
 
diff --git a/rpython/jit/backend/x86/test/test_compatible.py 
b/rpython/jit/backend/x86/test/test_compatible.py
--- a/rpython/jit/backend/x86/test/test_compatible.py
+++ b/rpython/jit/backend/x86/test/test_compatible.py
@@ -127,7 +127,8 @@
         faildescr = guard_compat_descr
     guard_token = FakeGuardToken()
 
-    patch_guard_compatible(guard_token, rawstart, rawstart)
+    patch_guard_compatible(guard_token, rawstart, rawstart,
+                           lltype.nullptr(llmemory.GCREF.TO))
 
     # ---- ready ----
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to