Author: Armin Rigo <[email protected]>
Branch: jit-constptr-2
Changeset: r83456:7262e1468002
Date: 2016-03-31 13:36 +0100
http://bitbucket.org/pypy/pypy/changeset/7262e1468002/

Log:    (fijal, arigo)

        Creating and freeing gcreftracers

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
@@ -17,3 +17,21 @@
         gc._trace_callback(callback, arg, addr + i * WORD)
         i += 1
 lambda_gcrefs_trace = lambda: gcrefs_trace
+
+def make_gcref_tracer(array_base_addr, gcrefs):
+    # careful about the order here: the allocation of the GCREFTRACER
+    # can trigger a GC.  So we must write the gcrefs into the raw
+    # array only afterwards...
+    tr = lltype.malloc(GCREFTRACER)
+    tr.array_base_addr = array_base_addr
+    tr.array_length = 0    # incremented as we populate the array_base_addr
+    i = 0
+    length = len(gcrefs)
+    while i < length:
+        p = rffi.cast(rffi.SIGNEDP, array_base_addr + i * WORD)
+        # --no GC from here--
+        p[0] = rffi.cast(lltype.Signed, gcrefs[i])
+        tr.array_length += 1
+        # --no GC until here--
+        i += 1
+    return tr
diff --git a/rpython/jit/backend/llsupport/llmodel.py 
b/rpython/jit/backend/llsupport/llmodel.py
--- a/rpython/jit/backend/llsupport/llmodel.py
+++ b/rpython/jit/backend/llsupport/llmodel.py
@@ -246,6 +246,13 @@
 
     def free_loop_and_bridges(self, compiled_loop_token):
         AbstractCPU.free_loop_and_bridges(self, compiled_loop_token)
+        # turn off all gcreftracers
+        tracers = compiled_loop_token.asmmemmgr_gcreftracers
+        if tracers is not None:
+            compiled_loop_token.asmmemmgr_gcreftracers = None
+            for tracer in tracers:
+                tracer.array_length = 0
+        # then free all blocks of code and raw data
         blocks = compiled_loop_token.asmmemmgr_blocks
         if blocks is not None:
             compiled_loop_token.asmmemmgr_blocks = None
diff --git a/rpython/jit/backend/llsupport/test/test_gcreftracer.py 
b/rpython/jit/backend/llsupport/test/test_gcreftracer.py
--- a/rpython/jit/backend/llsupport/test/test_gcreftracer.py
+++ b/rpython/jit/backend/llsupport/test/test_gcreftracer.py
@@ -1,5 +1,6 @@
 from rpython.rtyper.lltypesystem import lltype, llmemory, rffi
 from rpython.jit.backend.llsupport.gcreftracer import GCREFTRACER, gcrefs_trace
+from rpython.jit.backend.llsupport.gcreftracer import make_gcref_tracer
 
 
 class FakeGC:
@@ -26,3 +27,14 @@
     for i in range(3):
         assert gc.called[i] == rffi.cast(llmemory.Address, base + i * WORD)
     lltype.free(a, flavor='raw')
+
+def test_make_gcref_tracer():
+    a = lltype.malloc(rffi.CArray(lltype.Signed), 3, flavor='raw')
+    base = rffi.cast(lltype.Signed, a)
+    tr = make_gcref_tracer(base, [123, 456, 789])
+    assert a[0] == 123
+    assert a[1] == 456
+    assert a[2] == 789
+    assert tr.array_base_addr == base
+    assert tr.array_length == 3
+    lltype.free(a, flavor='raw')
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -285,7 +285,7 @@
 
 class CompiledLoopToken(object):
     asmmemmgr_blocks = None
-    asmmemmgr_gcroots = 0
+    asmmemmgr_gcreftracers = None
 
     def __init__(self, cpu, number):
         cpu.tracker.total_compiled_loops += 1
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to