[pypy-commit] pypy stacklet: Rename the 'releases_gil' attribute into the longer name

arigo noreply at buildbot.pypy.org
Mon Aug 8 18:08:34 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46380:165a28e7d8ad
Date: 2011-08-08 18:10 +0200
http://bitbucket.org/pypy/pypy/changeset/165a28e7d8ad/

Log:	Rename the 'releases_gil' attribute into the longer name
	'has_random_consequences_on_gc_objects', which describes better the
	intention. Set it to True also for functions with a callback. And
	also allow it to be manually set to True, for libffi's call() and
	for stacklet_new() and stacklet_switch().

diff --git a/pypy/jit/codewriter/call.py b/pypy/jit/codewriter/call.py
--- a/pypy/jit/codewriter/call.py
+++ b/pypy/jit/codewriter/call.py
@@ -6,8 +6,8 @@
 from pypy.jit.codewriter import support
 from pypy.jit.codewriter.jitcode import JitCode
 from pypy.jit.codewriter.effectinfo import (VirtualizableAnalyzer,
-    QuasiImmutAnalyzer, CanReleaseGILAnalyzer, effectinfo_from_writeanalyze,
-    EffectInfo, CallInfoCollection)
+    QuasiImmutAnalyzer, HasRandomConsequencesOnGcObjectsAnalyzer,
+    effectinfo_from_writeanalyze, EffectInfo, CallInfoCollection)
 from pypy.translator.simplify import get_funcobj, get_functype
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.translator.backendopt.canraise import RaiseAnalyzer
@@ -31,7 +31,8 @@
             self.readwrite_analyzer = ReadWriteAnalyzer(translator)
             self.virtualizable_analyzer = VirtualizableAnalyzer(translator)
             self.quasiimmut_analyzer = QuasiImmutAnalyzer(translator)
-            self.canreleasegil_analyzer = CanReleaseGILAnalyzer(translator)
+            self.hasrandomconsequencesongcobject_analyzer = (
+                HasRandomConsequencesOnGcObjectsAnalyzer(translator))
         #
         for index, jd in enumerate(jitdrivers_sd):
             jd.index = index
@@ -219,9 +220,9 @@
                 assert not NON_VOID_ARGS, ("arguments not supported for "
                                            "loop-invariant function!")
         # build the extraeffect
-        can_release_gil = self.canreleasegil_analyzer.analyze(op)
-        # can_release_gil implies can_invalidate
-        can_invalidate = can_release_gil or self.quasiimmut_analyzer.analyze(op)
+        has_random_c = self.hasrandomconsequencesongcobject_analyzer.analyze(op)
+        # has_random_c implies can_invalidate
+        can_invalidate = has_random_c or self.quasiimmut_analyzer.analyze(op)
         if extraeffect is None:
             if self.virtualizable_analyzer.analyze(op):
                 extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
@@ -239,7 +240,7 @@
         #
         effectinfo = effectinfo_from_writeanalyze(
             self.readwrite_analyzer.analyze(op), self.cpu, extraeffect,
-            oopspecindex, can_invalidate, can_release_gil)
+            oopspecindex, can_invalidate, has_random_c)
         #
         if oopspecindex != EffectInfo.OS_NONE:
             assert effectinfo is not None
diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py
--- a/pypy/jit/codewriter/effectinfo.py
+++ b/pypy/jit/codewriter/effectinfo.py
@@ -80,7 +80,8 @@
                 write_descrs_fields, write_descrs_arrays,
                 extraeffect=EF_CAN_RAISE,
                 oopspecindex=OS_NONE,
-                can_invalidate=False, can_release_gil=False):
+                can_invalidate=False,
+                has_random_consequences_on_gc_objects=False):
         key = (frozenset(readonly_descrs_fields),
                frozenset(readonly_descrs_arrays),
                frozenset(write_descrs_fields),
@@ -88,7 +89,7 @@
                extraeffect,
                oopspecindex,
                can_invalidate,
-               can_release_gil)
+               has_random_consequences_on_gc_objects)
         if key in cls._cache:
             return cls._cache[key]
         result = object.__new__(cls)
@@ -104,7 +105,8 @@
             result.write_descrs_arrays = write_descrs_arrays
         result.extraeffect = extraeffect
         result.can_invalidate = can_invalidate
-        result.can_release_gil = can_release_gil
+        result.has_random_consequences_on_gc_objects = (
+            has_random_consequences_on_gc_objects)
         result.oopspecindex = oopspecindex
         cls._cache[key] = result
         return result
@@ -116,13 +118,13 @@
         return self.extraeffect >= self.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
 
     def has_random_effects(self):
-        return self.oopspecindex == self.OS_LIBFFI_CALL or self.can_release_gil
+        return self.has_random_consequences_on_gc_objects
 
 def effectinfo_from_writeanalyze(effects, cpu,
                                  extraeffect=EffectInfo.EF_CAN_RAISE,
                                  oopspecindex=EffectInfo.OS_NONE,
                                  can_invalidate=False,
-                                 can_release_gil=False):
+                                 has_random_consequences_on_gc_objects=False):
     from pypy.translator.backendopt.writeanalyze import top_set
     if effects is top_set:
         return None
@@ -165,7 +167,7 @@
                       extraeffect,
                       oopspecindex,
                       can_invalidate,
-                      can_release_gil)
+                      has_random_consequences_on_gc_objects)
 
 def consider_struct(TYPE, fieldname):
     if fieldType(TYPE, fieldname) is lltype.Void:
@@ -201,12 +203,13 @@
     def analyze_simple_operation(self, op, graphinfo):
         return op.opname == 'jit_force_quasi_immutable'
 
-class CanReleaseGILAnalyzer(BoolGraphAnalyzer):
+class HasRandomConsequencesOnGcObjectsAnalyzer(BoolGraphAnalyzer):
     def analyze_direct_call(self, graph, seen=None):
-        releases_gil = False
         if hasattr(graph, "func") and hasattr(graph.func, "_ptr"):
-            releases_gil = graph.func._ptr._obj.releases_gil
-        return releases_gil or super(CanReleaseGILAnalyzer, self).analyze_direct_call(graph, seen)
+            if graph.func._ptr._obj.has_random_consequences_on_gc_objects:
+                return True
+        return (super(HasRandomConsequencesOnGcObjectsAnalyzer, self)
+                .analyze_direct_call(graph, seen))
 
     def analyze_simple_operation(self, op, graphinfo):
         return False
diff --git a/pypy/jit/codewriter/test/test_call.py b/pypy/jit/codewriter/test/test_call.py
--- a/pypy/jit/codewriter/test/test_call.py
+++ b/pypy/jit/codewriter/test/test_call.py
@@ -191,4 +191,4 @@
     [block, _] = list(f_graph.iterblocks())
     [op] = block.operations
     call_descr = cc.getcalldescr(op)
-    assert call_descr.extrainfo.can_release_gil
\ No newline at end of file
+    assert call_descr.extrainfo.has_random_consequences_on_gc_objects
diff --git a/pypy/rlib/_rffi_stacklet.py b/pypy/rlib/_rffi_stacklet.py
--- a/pypy/rlib/_rffi_stacklet.py
+++ b/pypy/rlib/_rffi_stacklet.py
@@ -13,9 +13,9 @@
     separate_module_sources = ['#include "src/stacklet/stacklet.c"\n'],
 )
 
-def llexternal(name, args, result):
+def llexternal(name, args, result, **kwds):
     return rffi.llexternal(name, args, result, compilation_info=eci,
-                           _nowrapper=True)
+                           _nowrapper=True, **kwds)
 
 # ----- types -----
 
@@ -37,8 +37,9 @@
 deletethread = llexternal('stacklet_deletethread',[thread_handle], lltype.Void)
 
 new = llexternal('stacklet_new', [thread_handle, run_fn, llmemory.Address],
-                 handle)
-switch = llexternal('stacklet_switch', [thread_handle, handle], handle)
+                 handle, has_random_consequences_on_gc_objects=True)
+switch = llexternal('stacklet_switch', [thread_handle, handle], handle,
+                    has_random_consequences_on_gc_objects=True)
 destroy = llexternal('stacklet_destroy', [thread_handle, handle], lltype.Void)
 
 _translate_pointer = llexternal("_stacklet_translate_pointer",
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -303,7 +303,8 @@
 else:
     c_ffi_call_return_type = lltype.Void
 c_ffi_call = external('ffi_call', [FFI_CIFP, rffi.VOIDP, rffi.VOIDP,
-                                   VOIDPP], c_ffi_call_return_type)
+                                   VOIDPP], c_ffi_call_return_type,
+                      has_random_consequences_on_gc_objects=True)
 CALLBACK_TP = rffi.CCallback([FFI_CIFP, rffi.VOIDP, rffi.VOIDPP, rffi.VOIDP],
                              lltype.Void)
 c_ffi_prep_closure = external('ffi_prep_closure', [FFI_CLOSUREP, FFI_CIFP,
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -56,6 +56,7 @@
                sandboxsafe=False, threadsafe='auto',
                _nowrapper=False, calling_conv='c',
                oo_primitive=None, elidable_function=False,
+               has_random_consequences_on_gc_objects='auto',
                macro=None):
     """Build an external function that will invoke the C function 'name'
     with the given 'args' types and 'result' type.
@@ -112,13 +113,19 @@
         # sandboxsafe is a hint for "too-small-ness" (e.g. math functions).
         invoke_around_handlers = not sandboxsafe
 
+    if has_random_consequences_on_gc_objects not in (False, True):
+        has_random_consequences_on_gc_objects = (
+            invoke_around_handlers or   # because it can release the GIL
+            has_callback)               # because the callback can do it
+
     funcptr = lltype.functionptr(ext_type, name, external='C',
                                  compilation_info=compilation_info,
                                  _callable=_callable,
                                  _safe_not_sandboxed=sandboxsafe,
                                  _debugexc=True, # on top of llinterp
                                  canraise=False,
-                                 releases_gil=invoke_around_handlers,
+                                 has_random_consequences_on_gc_objects=
+                                     has_random_consequences_on_gc_objects,
                                  **kwds)
     if isinstance(_callable, ll2ctypes.LL2CtypesCallable):
         _callable.funcptr = funcptr
@@ -1068,4 +1075,4 @@
     [VOIDP, VOIDP, SIZE_T],
     lltype.Void,
     threadsafe=False
-)
\ No newline at end of file
+)


More information about the pypy-commit mailing list