Commits

Armin Rigo committed fd30ac3

(arigo, fijal around)
Finally add the shortcut we were looking for: now calls to external
functions that release the GIL should be turned into just a
CALL_RELEASE_GIL.

Comments (0)

Files changed (3)

pypy/jit/backend/llgraph/runner.py

         return res
 
     def execute_call_release_gil(self, descr, func, *args):
+        if hasattr(descr, '_original_func_'):
+            func = descr._original_func_     # see pyjitpl.py
+            # we want to call the function that does the aroundstate
+            # manipulation here (as a hack, instead of really doing
+            # the aroundstate manipulation ourselves)
+            return self.execute_call_may_force(descr, func, *args)
         call_args = support.cast_call_args_in_order(descr.ARGS, args)
         FUNC = lltype.FuncType(descr.ARGS, descr.RESULT)
         func_to_call = rffi.cast(lltype.Ptr(FUNC), func)

pypy/jit/metainterp/pyjitpl.py

             self.metainterp.vable_and_vrefs_before_residual_call()
             resbox = self.metainterp.execute_and_record_varargs(
                 rop.CALL_MAY_FORCE, allboxes, descr=descr)
+            if effectinfo.is_call_release_gil():
+                self.metainterp.direct_call_release_gil()
             self.metainterp.vrefs_after_residual_call()
             vablebox = None
             if assembler_call:
             if vablebox is not None:
                 self.metainterp.history.record(rop.KEEPALIVE, [vablebox], None)
             self.metainterp.handle_possible_exception()
+            # XXX refactor: direct_libffi_call() is a hack
             if effectinfo.oopspecindex == effectinfo.OS_LIBFFI_CALL:
                 self.metainterp.direct_libffi_call()
             return resbox
                                 [box_resultpos, ConstInt(0), box_result],
                                 None, descr)
 
+    def direct_call_release_gil(self):
+        op = self.history.operations.pop()
+        assert op.opnum == rop.CALL_MAY_FORCE
+        descr = op.getdescr()
+        effectinfo = descr.get_extra_info()
+        realfuncaddr = effectinfo.call_release_gil_target
+        funcbox = ConstInt(heaptracker.adr2int(realfuncaddr))
+        self.history.record(rop.CALL_RELEASE_GIL,
+                            [funcbox] + op.getarglist()[1:],
+                            op.result, descr)
+        if not we_are_translated():       # for llgraph
+            descr._original_func_ = op.getarg(0).value
+
 # ____________________________________________________________
 
 class ChangeFrame(JitException):

pypy/jit/metainterp/test/test_ajit.py

         assert res == 2
         res = self.interp_operations(f, [])
         assert res == 2
+        self.check_operations_history(call_release_gil=1, call_may_force=0)