[pypy-commit] pypy arm-backend-2: implement call_release_gil
bivab
noreply at buildbot.pypy.org
Wed Jul 13 14:53:16 CEST 2011
Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r45549:37b0e249c32f
Date: 2011-07-13 14:53 +0200
http://bitbucket.org/pypy/pypy/changeset/37b0e249c32f/
Log: implement call_release_gil
diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -121,11 +121,34 @@
ll_new_unicode)
if gc_ll_descr.get_malloc_slowpath_addr is not None:
self._build_malloc_slowpath()
+ if gc_ll_descr.gcrootmap:
+ self._build_release_gil(gc_ll_descr.gcrootmap)
self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
self._exit_code_addr = self._gen_exit_path()
self._leave_jitted_hook_save_exc = self._gen_leave_jitted_hook_code(True)
self._leave_jitted_hook = self._gen_leave_jitted_hook_code(False)
+ @staticmethod
+ def _release_gil_shadowstack():
+ before = rffi.aroundstate.before
+ if before:
+ before()
+
+ @staticmethod
+ def _reacquire_gil_shadowstack():
+ after = rffi.aroundstate.after
+ if after:
+ after()
+ _NOARG_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
+ def _build_release_gil(self, gcrootmap):
+ assert gcrootmap.is_shadow_stack
+ releasegil_func = llhelper(self._NOARG_FUNC,
+ self._release_gil_shadowstack)
+ reacqgil_func = llhelper(self._NOARG_FUNC,
+ self._reacquire_gil_shadowstack)
+ self.releasegil_addr = self.cpu.cast_ptr_to_int(releasegil_func)
+ self.reacqgil_addr = self.cpu.cast_ptr_to_int(reacqgil_func)
+
def setup_failure_recovery(self):
@rgc.no_collect
@@ -758,6 +781,8 @@
opnum = operations[i + 1].getopnum()
assert opnum == rop.GUARD_OVERFLOW or opnum == rop.GUARD_NO_OVERFLOW
return True
+ if num == rop.CALL_RELEASE_GIL:
+ return True
return False
diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -474,7 +474,7 @@
# the following is supposed to be the slow path, so whenever possible
# we choose the most compact encoding over the most efficient one.
- with saved_registers(self.mc, r.caller_resp, regalloc=regalloc):
+ with saved_registers(self.mc, r.caller_resp):
if N == 2:
callargs = [r.r0, r.r1]
else:
@@ -950,6 +950,35 @@
self._emit_guard(guard_op, arglocs, c.GE)
return fcond
+ emit_guard_call_release_gil = emit_guard_call_may_force
+
+ def call_release_gil(self, gcrootmap, save_registers):
+ # First, we need to save away the registers listed in
+ # 'save_registers' that are not callee-save. XXX We assume that
+ # the floating point registers won't be modified.
+ import pdb; pdb.set_trace()
+ regs_to_save = []
+ for reg in self._regalloc.rm.save_around_call_regs:
+ if reg in save_registers:
+ regs_to_save.append(reg)
+ assert gcrootmap.is_shadow_stack
+ with saved_registers(self.mc, regs_to_save):
+ self._emit_call(-1, self.releasegil_addr, [], regalloc, fcond)
+
+ def call_reacquire_gil(self, gcrootmap, save_loc):
+ # save the previous result into the stack temporarily.
+ # XXX like with call_release_gil(), we assume that we don't need
+ # to save vfp regs in this case.
+ regs_to_save = []
+ if isinstance(save_loc, RegLoc) and not save_loc.is_vfp_reg():
+ regs_to_save.append(save_loc)
+ # call the reopenstack() function (also reacquiring the GIL)
+ if len(regs_to_save) == 1:
+ regs_to_save.append(r.ip) # for alingment
+ assert gcrootmap.is_shadow_stack
+ with saved_registers(self.mc, regs_to_save):
+ self._emit_call(-1, self.reacqgil_addr, [], regalloc, fcond)
+
def write_new_force_index(self):
# for shadowstack only: get a new, unused force_index number and
# write it to FORCE_INDEX_OFS. Used to record the call shape
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -998,6 +998,23 @@
self.possibly_free_vars(guard_op.getfailargs())
return locs
+ def prepare_guard_call_release_gil(self, op, guard_op, fcond):
+ # first, close the stack in the sense of the asmgcc GC root tracker
+ gcrootmap = self.cpu.gc_ll_descr.gcrootmap
+ if gcrootmap:
+ self.assembler.call_release_gil(gcrootmap, arglocs)
+ # do the call
+ faildescr = guard_op.getdescr()
+ fail_index = self.cpu.get_fail_descr_number(faildescr)
+ args = [imm(rffi.cast(lltype.Signed, op.getarg(0).getint()))]
+ self.assembler.emit_op_call(op, args, self, fcond, fail_index)
+ # then reopen the stack
+ if gcrootmap:
+ self.call_reacquire_gil(gcrootmap, r.r0)
+ locs = self._prepare_guard(guard_op)
+ self.possibly_free_vars(guard_op.getfailargs())
+ return locs
+
def prepare_guard_call_assembler(self, op, guard_op, fcond):
descr = op.getdescr()
assert isinstance(descr, LoopToken)
More information about the pypy-commit
mailing list