[pypy-commit] pypy guard-compatible: Fix an easy and a subtle GC issue

arigo pypy.commits at gmail.com
Sun Jun 19 14:07:44 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: guard-compatible
Changeset: r85228:524da3e89aea
Date: 2016-06-19 19:08 +0100
http://bitbucket.org/pypy/pypy/changeset/524da3e89aea/

Log:	Fix an easy and a subtle GC issue

diff --git a/rpython/jit/backend/llsupport/assembler.py b/rpython/jit/backend/llsupport/assembler.py
--- a/rpython/jit/backend/llsupport/assembler.py
+++ b/rpython/jit/backend/llsupport/assembler.py
@@ -49,7 +49,8 @@
     def compute_gcmap(self, gcmap, failargs, fail_locs, frame_depth):
         # note that regalloc has a very similar compute, but
         # one that does iteration over all bindings, so slightly different,
-        # eh
+        # eh.  Also: for GUARD_COMPATIBLE, the gcmap we receive is not
+        # empty.  Make sure we only add some bits, but don't remove any.
         input_i = 0
         for i in range(len(failargs)):
             arg = failargs[i]
diff --git a/rpython/jit/backend/llsupport/guard_compat.py b/rpython/jit/backend/llsupport/guard_compat.py
--- a/rpython/jit/backend/llsupport/guard_compat.py
+++ b/rpython/jit/backend/llsupport/guard_compat.py
@@ -25,6 +25,7 @@
 def _getofs(name):
     return llmemory.offsetof(BACKEND_CHOICES, name)
 BCFAILDESCR = _getofs('bc_faildescr')
+BCGCTABLETRACER = _getofs('bc_gc_table_tracer')
 BCMOSTRECENT = _getofs('bc_most_recent')
 BCLIST = _getofs('bc_list')
 del _getofs
@@ -46,6 +47,7 @@
 
 def bchoices_trace(gc, obj_addr, callback, arg):
     gc._trace_callback(callback, arg, obj_addr + BCFAILDESCR)
+    gc._trace_callback(callback, arg, obj_addr + BCGCTABLETRACER)
     bchoices_pair(gc, obj_addr + BCMOSTRECENT, callback, arg)
     length = (obj_addr + BCLIST + BCLISTLENGTHOFS).signed[0]
     array_addr = obj_addr + BCLIST + BCLISTITEMSOFS
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
@@ -1937,7 +1937,15 @@
 
     def implement_guard_recovery(self, guard_opnum, faildescr, failargs,
                                  fail_locs, frame_depth):
-        gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE)
+        if guard_opnum == rop.GUARD_COMPATIBLE:
+            # In this case, we might stop at the guard but continue
+            # running anyway.  So we must make sure that the gcmap
+            # ensures that all gcrefs stay alive.
+            gcmap = self._regalloc.get_gcmap()
+        else:
+            # Common case: get an empty gcmap.  It will be filled
+            # with compute_gcmap() in llsupport.assembler.
+            gcmap = allocate_gcmap(self, frame_depth, JITFRAME_FIXED_SIZE)
         faildescrindex = self.get_gcref_from_faildescr(faildescr)
         return GuardToken(self.cpu, gcmap, faildescr, failargs, fail_locs,
                           guard_opnum, frame_depth, faildescrindex)


More information about the pypy-commit mailing list