Author: Armin Rigo <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit