[pypy-commit] pypy arm64: start working on call_release_gil
fijal
pypy.commits at gmail.com
Tue Jun 25 07:33:37 EDT 2019
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: arm64
Changeset: r96859:dc101f8cce32
Date: 2019-06-25 11:32 +0000
http://bitbucket.org/pypy/pypy/changeset/dc101f8cce32/
Log: start working on call_release_gil
diff --git a/rpython/jit/backend/aarch64/callbuilder.py b/rpython/jit/backend/aarch64/callbuilder.py
--- a/rpython/jit/backend/aarch64/callbuilder.py
+++ b/rpython/jit/backend/aarch64/callbuilder.py
@@ -149,7 +149,55 @@
xxx
def move_real_result_and_call_reacqgil_addr(self, fastgil):
- xxx
+ # try to reacquire the lock.
+ # XXX r5 == &root_stack_top
+ # r6 == fastgil
+ # XXX r7 == previous value of root_stack_top
+ self.mc.gen_load_int(r.ip1.value, fastgil)
+ self.mc.LDREX(r.x0.value, r.r6.value) # load the lock value
+ self.mc.MOV_ri(r.ip.value, 1)
+ self.mc.CMP_ri(r.r3.value, 0) # is the lock free?
+ self.mc.STREX(r.r3.value, r.ip.value, r.r6.value, c=c.EQ)
+ # try to claim the lock
+ self.mc.CMP_ri(r.r3.value, 0, cond=c.EQ) # did this succeed?
+ if self.asm.cpu.cpuinfo.arch_version >= 7:
+ self.mc.DMB()
+ # the success of the lock acquisition is defined by
+ # 'EQ is true', or equivalently by 'r3 == 0'.
+ #
+ if self.asm.cpu.gc_ll_descr.gcrootmap:
+ # When doing a call_release_gil with shadowstack, there
+ # is the risk that the 'rpy_fastgil' was free but the
+ # current shadowstack can be the one of a different
+ # thread. So here we check if the shadowstack pointer
+ # is still the same as before we released the GIL (saved
+ # in 'r7'), and if not, we fall back to 'reacqgil_addr'.
+ self.mc.LDR_ri(r.ip.value, r.r5.value, cond=c.EQ)
+ self.mc.CMP_rr(r.ip.value, r.r7.value, cond=c.EQ)
+ b1_location = self.mc.currpos()
+ self.mc.BKPT() # BEQ below
+ # there are two cases here: either EQ was false from
+ # the beginning, or EQ was true at first but the CMP
+ # made it false. In the second case we need to
+ # release the fastgil here. We know which case it is
+ # by checking again r3.
+ self.mc.CMP_ri(r.r3.value, 0)
+ self.mc.STR_ri(r.r3.value, r.r6.value, cond=c.EQ)
+ else:
+ b1_location = self.mc.currpos()
+ self.mc.BKPT() # BEQ below
+ #
+ # save the result we just got
+ gpr_to_save, vfp_to_save = self.get_result_locs()
+ with saved_registers(self.mc, gpr_to_save, vfp_to_save):
+ self.mc.BL(self.asm.reacqgil_addr)
+
+ # replace b1_location with B(here, c.EQ)
+ pmc = OverwritingBuilder(self.mc, b1_location, WORD)
+ pmc.B_offs(self.mc.currpos(), c.EQ)
+
+ if not we_are_translated(): # for testing: now we can accesss
+ self.mc.SUB_ri(r.fp.value, r.fp.value, 1) # fp again
def get_result_locs(self):
if self.resloc is None:
More information about the pypy-commit
mailing list