Author: Armin Rigo <[email protected]>
Branch: remove-globals-in-jit
Changeset: r59721:db015e15e91a
Date: 2013-01-05 13:52 +0100
http://bitbucket.org/pypy/pypy/changeset/db015e15e91a/
Log: hg merge default
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
@@ -220,6 +220,7 @@
# get the 'elidable' and 'loopinvariant' flags from the function object
elidable = False
loopinvariant = False
+ call_release_gil_target = llmemory.NULL
if op.opname == "direct_call":
funcobj = get_funcobj(op.args[0].value)
assert getattr(funcobj, 'calling_conv', 'c') == 'c', (
@@ -230,6 +231,10 @@
if loopinvariant:
assert not NON_VOID_ARGS, ("arguments not supported for "
"loop-invariant function!")
+ if getattr(func, "_call_aroundstate_target_", None):
+ call_release_gil_target = func._call_aroundstate_target_
+ call_release_gil_target = llmemory.cast_ptr_to_adr(
+ call_release_gil_target)
# build the extraeffect
random_effects = self.randomeffects_analyzer.analyze(op)
if random_effects:
@@ -253,7 +258,7 @@
#
effectinfo = effectinfo_from_writeanalyze(
self.readwrite_analyzer.analyze(op), self.cpu, extraeffect,
- oopspecindex, can_invalidate)
+ oopspecindex, can_invalidate, call_release_gil_target)
#
assert effectinfo is not None
if elidable or loopinvariant:
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
@@ -1,6 +1,6 @@
from pypy.jit.metainterp.typesystem import deref, fieldType, arrayItem
from pypy.rpython.lltypesystem.rclass import OBJECT
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.ootypesystem import ootype
from pypy.translator.backendopt.graphanalyze import BoolGraphAnalyzer
@@ -87,7 +87,8 @@
write_descrs_fields, write_descrs_arrays,
extraeffect=EF_CAN_RAISE,
oopspecindex=OS_NONE,
- can_invalidate=False):
+ can_invalidate=False,
+ call_release_gil_target=llmemory.NULL):
key = (frozenset_or_none(readonly_descrs_fields),
frozenset_or_none(readonly_descrs_arrays),
frozenset_or_none(write_descrs_fields),
@@ -95,6 +96,8 @@
extraeffect,
oopspecindex,
can_invalidate)
+ if call_release_gil_target:
+ key += (object(),) # don't care about caching in this case
if key in cls._cache:
return cls._cache[key]
if extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
@@ -121,6 +124,7 @@
result.extraeffect = extraeffect
result.can_invalidate = can_invalidate
result.oopspecindex = oopspecindex
+ result.call_release_gil_target = call_release_gil_target
if result.check_can_raise():
assert oopspecindex in cls._OS_CANRAISE
cls._cache[key] = result
@@ -142,6 +146,9 @@
def has_random_effects(self):
return self.extraeffect >= self.EF_RANDOM_EFFECTS
+ def is_call_release_gil(self):
+ return bool(self.call_release_gil_target)
+
def frozenset_or_none(x):
if x is None:
@@ -156,7 +163,8 @@
def effectinfo_from_writeanalyze(effects, cpu,
extraeffect=EffectInfo.EF_CAN_RAISE,
oopspecindex=EffectInfo.OS_NONE,
- can_invalidate=False):
+ can_invalidate=False,
+ call_release_gil_target=llmemory.NULL):
from pypy.translator.backendopt.writeanalyze import top_set
if effects is top_set or extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
readonly_descrs_fields = None
@@ -204,7 +212,8 @@
write_descrs_arrays,
extraeffect,
oopspecindex,
- can_invalidate)
+ can_invalidate,
+ call_release_gil_target)
def consider_struct(TYPE, fieldname):
if fieldType(TYPE, fieldname) is lltype.Void:
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
@@ -1,6 +1,6 @@
import py
from pypy.objspace.flow.model import SpaceOperation, Constant, Variable
-from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.translator.unsimplify import varoftype
from pypy.rlib import jit
from pypy.jit.codewriter.call import CallControl
@@ -192,6 +192,32 @@
[op] = block.operations
call_descr = cc.getcalldescr(op)
assert call_descr.extrainfo.has_random_effects()
+ assert call_descr.extrainfo.is_call_release_gil() is False
+
+def test_call_release_gil():
+ from pypy.jit.backend.llgraph.runner import LLtypeCPU
+
+ T = rffi.CArrayPtr(rffi.TIME_T)
+ external = rffi.llexternal("time", [T], rffi.TIME_T, threadsafe=True)
+
+ # no jit.dont_look_inside in this test
+ def f():
+ return external(lltype.nullptr(T.TO))
+
+ rtyper = support.annotate(f, [])
+ jitdriver_sd = FakeJitDriverSD(rtyper.annotator.translator.graphs[0])
+ cc = CallControl(LLtypeCPU(rtyper), jitdrivers_sd=[jitdriver_sd])
+ res = cc.find_all_graphs(FakePolicy())
+
+ [llext_graph] = [x for x in res if x.func is external]
+ [block, _] = list(llext_graph.iterblocks())
+ [op] = block.operations
+ call_target = op.args[0].value._obj.graph.func._call_aroundstate_target_
+ call_target = llmemory.cast_ptr_to_adr(call_target)
+ call_descr = cc.getcalldescr(op)
+ assert call_descr.extrainfo.has_random_effects()
+ assert call_descr.extrainfo.is_call_release_gil() is True
+ assert call_descr.extrainfo.call_release_gil_target == call_target
def test_random_effects_on_stacklet_switch():
from pypy.jit.backend.llgraph.runner import LLtypeCPU
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
@@ -171,6 +171,7 @@
call_external_function._dont_inline_ = True
call_external_function._annspecialcase_ = 'specialize:ll'
call_external_function._gctransformer_hint_close_stack_ = True
+ call_external_function._call_aroundstate_target_ = funcptr
call_external_function = func_with_new_name(call_external_function,
'ccall_' + name)
# don't inline, as a hack to guarantee that no GC pointer is alive
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit