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