def call_releasegil_addr_and_move_real_arguments(self): assert not self.asm._is_asmgcc() from rpython.jit.backend.arm.regalloc import CoreRegisterManager with saved_registers(self.mc, CoreRegisterManager.save_around_call_regs): self.mc.BL(self.asm.releasegil_addr) if not we_are_translated(): # for testing: we should not access self.mc.ADD_ri(r.fp.value, r.fp.value, 1) # fp any more
def move_real_result_and_call_reacqgil_addr(self): # save the result we just got assert not self.asm._is_asmgcc() 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) 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 move_real_result_and_call_reacqgil_addr(self, fastgil): # try to reacquire the lock. The registers r5 to r7 are still # valid from before the call: # r5 == &root_stack_top # r6 == fastgil # r7 == previous value of root_stack_top # r8 == our thread ident self.mc.LDREX(r.r3.value, r.r6.value) # load the lock value self.mc.CMP_ri(r.r3.value, 0) # is the lock free? self.mc.STREX(r.r3.value, r.r8.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 move_real_result_and_call_reacqgil_addr(self, fastgil): # try to reacquire the lock. The registers r5 to r7 are still # valid from before the call: # r5 == &root_stack_top # r6 == fastgil # r7 == previous value of root_stack_top self.mc.LDREX(r.r3.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