[pypy-commit] pypy stacklet: hg merge effectinfo-cleanup
arigo
noreply at buildbot.pypy.org
Tue Aug 9 09:31:58 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46390:52932c87607d
Date: 2011-08-09 09:33 +0200
http://bitbucket.org/pypy/pypy/changeset/52932c87607d/
Log: hg merge effectinfo-cleanup
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -312,7 +312,7 @@
token = history.getkind(getattr(S, fieldname))
return self.getdescr(ofs, token[0], name=fieldname)
- def calldescrof(self, FUNC, ARGS, RESULT, extrainfo=None):
+ def calldescrof(self, FUNC, ARGS, RESULT, extrainfo):
arg_types = []
for ARG in ARGS:
token = history.getkind(ARG)
@@ -326,7 +326,7 @@
return self.getdescr(0, token[0], extrainfo=extrainfo,
arg_types=''.join(arg_types))
- def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo=None):
+ def calldescrof_dynamic(self, ffi_args, ffi_result, extrainfo):
from pypy.jit.backend.llsupport.ffisupport import get_ffi_type_kind
from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind
arg_types = []
@@ -522,7 +522,7 @@
return FieldDescr.new(T1, fieldname)
@staticmethod
- def calldescrof(FUNC, ARGS, RESULT, extrainfo=None):
+ def calldescrof(FUNC, ARGS, RESULT, extrainfo):
return StaticMethDescr.new(FUNC, ARGS, RESULT, extrainfo)
@staticmethod
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -9,6 +9,7 @@
ConstObj, BoxFloat, ConstFloat)
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.metainterp.typesystem import deref
+from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.tool.oparser import parse
from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rffi, rclass
from pypy.rpython.ootypesystem import ootype
@@ -445,7 +446,8 @@
return chr(ord(c) + 1)
FPTR = self.Ptr(self.FuncType([lltype.Char], lltype.Char))
func_ptr = llhelper(FPTR, func)
- calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char)
+ calldescr = cpu.calldescrof(deref(FPTR), (lltype.Char,), lltype.Char,
+ EffectInfo.MOST_GENERAL)
x = cpu.bh_call_i(self.get_funcbox(cpu, func_ptr).value,
calldescr, [ord('A')], None, None)
assert x == ord('B')
@@ -458,7 +460,8 @@
lltype.Float))
func_ptr = llhelper(FPTR, func)
FTP = deref(FPTR)
- calldescr = cpu.calldescrof(FTP, FTP.ARGS, FTP.RESULT)
+ calldescr = cpu.calldescrof(FTP, FTP.ARGS, FTP.RESULT,
+ EffectInfo.MOST_GENERAL)
x = cpu.bh_call_f(self.get_funcbox(cpu, func_ptr).value,
calldescr,
[42], None, [longlong.getfloatstorage(3.5)])
@@ -486,13 +489,15 @@
FUNC = deref(FPTR)
funcbox = self.get_funcbox(cpu, func_ptr)
# first, try it with the "normal" calldescr
- calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
res = self.execute_operation(rop.CALL,
[funcbox, BoxInt(num), BoxInt(num)],
'int', descr=calldescr)
assert res.value == 2 * num
# then, try it with the dynamic calldescr
- dyn_calldescr = cpu.calldescrof_dynamic([ffi_type, ffi_type], ffi_type)
+ dyn_calldescr = cpu.calldescrof_dynamic([ffi_type, ffi_type], ffi_type,
+ EffectInfo.MOST_GENERAL)
res = self.execute_operation(rop.CALL,
[funcbox, BoxInt(num), BoxInt(num)],
'int', descr=dyn_calldescr)
@@ -507,7 +512,8 @@
FUNC = self.FuncType([F] * 7 + [I] * 2 + [F] * 3, F)
FPTR = self.Ptr(FUNC)
func_ptr = llhelper(FPTR, func)
- calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
funcbox = self.get_funcbox(cpu, func_ptr)
args = ([boxfloat(.1) for i in range(7)] +
[BoxInt(1), BoxInt(2), boxfloat(.2), boxfloat(.3),
@@ -529,7 +535,8 @@
FUNC = self.FuncType([lltype.Signed]*16, lltype.Signed)
FPTR = self.Ptr(FUNC)
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
func_ptr = llhelper(FPTR, func)
args = range(16)
funcbox = self.get_funcbox(self.cpu, func_ptr)
@@ -552,7 +559,8 @@
FPTR = self.Ptr(self.FuncType([TP] * nb_args, TP))
func_ptr = llhelper(FPTR, func_ints)
FUNC = deref(FPTR)
- calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
funcbox = self.get_funcbox(cpu, func_ptr)
args = [280-24*i for i in range(nb_args)]
res = self.execute_operation(rop.CALL,
@@ -566,7 +574,8 @@
FUNC = self.FuncType([lltype.Float, lltype.Float], lltype.Float)
FPTR = self.Ptr(FUNC)
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
func_ptr = llhelper(FPTR, func)
funcbox = self.get_funcbox(self.cpu, func_ptr)
res = self.execute_operation(rop.CALL, [funcbox, constfloat(1.5),
@@ -1589,7 +1598,8 @@
'''
FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
fptr = llhelper(FPTR, func)
- calldescr = self.cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT)
+ calldescr = self.cpu.calldescrof(FPTR.TO, FPTR.TO.ARGS, FPTR.TO.RESULT,
+ EffectInfo.MOST_GENERAL)
xtp = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
xtp.subclassrange_min = 1
@@ -1807,7 +1817,8 @@
FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Void)
func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force)
funcbox = self.get_funcbox(self.cpu, func_ptr).constbox()
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
cpu = self.cpu
i0 = BoxInt()
i1 = BoxInt()
@@ -1850,7 +1861,8 @@
FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Signed)
func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force)
funcbox = self.get_funcbox(self.cpu, func_ptr).constbox()
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
cpu = self.cpu
i0 = BoxInt()
i1 = BoxInt()
@@ -1895,7 +1907,8 @@
FUNC = self.FuncType([lltype.Signed, lltype.Signed], lltype.Float)
func_ptr = llhelper(lltype.Ptr(FUNC), maybe_force)
funcbox = self.get_funcbox(self.cpu, func_ptr).constbox()
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
cpu = self.cpu
i0 = BoxInt()
i1 = BoxInt()
@@ -1941,7 +1954,8 @@
cpu = self.cpu
func_adr = llmemory.cast_ptr_to_adr(c_tolower.funcsym)
funcbox = ConstInt(heaptracker.adr2int(func_adr))
- calldescr = cpu.calldescrof_dynamic([types.uchar], types.sint)
+ calldescr = cpu.calldescrof_dynamic([types.uchar], types.sint,
+ EffectInfo.MOST_GENERAL)
i1 = BoxInt()
i2 = BoxInt()
tok = BoxInt()
@@ -1997,7 +2011,8 @@
funcbox = ConstInt(heaptracker.adr2int(func_adr))
calldescr = cpu.calldescrof_dynamic([types.pointer, types_size_t,
types_size_t, types.pointer],
- types.void)
+ types.void,
+ EffectInfo.MOST_GENERAL)
i0 = BoxInt()
i1 = BoxInt()
i2 = BoxInt()
@@ -2292,7 +2307,8 @@
ARGS = [lltype.Signed] * 10
RES = lltype.Signed
FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
- lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES)
+ lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
+ EffectInfo.MOST_GENERAL)
for i in range(10):
self.cpu.set_future_value_int(i, i+1)
res = self.cpu.execute_token(looptoken)
@@ -2332,7 +2348,8 @@
ARGS = [lltype.Float, lltype.Float]
RES = lltype.Float
FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
- lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES)
+ lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
+ EffectInfo.MOST_GENERAL)
ops = '''
[f0, f1]
@@ -2422,7 +2439,8 @@
ARGS = [lltype.Float, lltype.Float]
RES = lltype.Float
FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
- lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES)
+ lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
+ EffectInfo.MOST_GENERAL)
ops = '''
[f0, f1]
@@ -2634,7 +2652,8 @@
#
FUNC = self.FuncType([lltype.Signed], RESTYPE)
FPTR = self.Ptr(FUNC)
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
x = self.cpu.bh_call_i(self.get_funcbox(self.cpu, f).value,
calldescr, [value], None, None)
assert x == expected, (
@@ -2667,7 +2686,8 @@
#
FUNC = self.FuncType([lltype.Signed], RESTYPE)
FPTR = self.Ptr(FUNC)
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
funcbox = self.get_funcbox(self.cpu, f)
res = self.execute_operation(rop.CALL, [funcbox, BoxInt(value)],
'int', descr=calldescr)
@@ -2701,7 +2721,8 @@
#
FUNC = self.FuncType([lltype.SignedLongLong], lltype.SignedLongLong)
FPTR = self.Ptr(FUNC)
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
x = self.cpu.bh_call_f(self.get_funcbox(self.cpu, f).value,
calldescr, None, None, [value])
assert x == expected
@@ -2728,7 +2749,8 @@
#
FUNC = self.FuncType([lltype.SignedLongLong], lltype.SignedLongLong)
FPTR = self.Ptr(FUNC)
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
funcbox = self.get_funcbox(self.cpu, f)
res = self.execute_operation(rop.CALL, [funcbox, BoxFloat(value)],
'float', descr=calldescr)
@@ -2756,7 +2778,8 @@
#
FUNC = self.FuncType([lltype.SingleFloat], lltype.SingleFloat)
FPTR = self.Ptr(FUNC)
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
ivalue = longlong.singlefloat2int(value)
iexpected = longlong.singlefloat2int(expected)
x = self.cpu.bh_call_i(self.get_funcbox(self.cpu, f).value,
@@ -2785,7 +2808,8 @@
#
FUNC = self.FuncType([lltype.SingleFloat], lltype.SingleFloat)
FPTR = self.Ptr(FUNC)
- calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ calldescr = self.cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
funcbox = self.get_funcbox(self.cpu, f)
ivalue = longlong.singlefloat2int(value)
iexpected = longlong.singlefloat2int(expected)
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -843,8 +843,8 @@
def consider_call(self, op):
effectinfo = op.getdescr().get_extra_info()
- if effectinfo is not None:
- oopspecindex = effectinfo.oopspecindex
+ oopspecindex = effectinfo.oopspecindex
+ if oopspecindex != EffectInfo.OS_NONE:
if IS_X86_32:
# support for some of the llong operations,
# which only exist on x86-32
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,7 +6,7 @@
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,
+ QuasiImmutAnalyzer, RandomEffectsAnalyzer, effectinfo_from_writeanalyze,
EffectInfo, CallInfoCollection)
from pypy.translator.simplify import get_funcobj, get_functype
from pypy.rpython.lltypesystem import lltype, llmemory
@@ -31,7 +31,7 @@
self.readwrite_analyzer = ReadWriteAnalyzer(translator)
self.virtualizable_analyzer = VirtualizableAnalyzer(translator)
self.quasiimmut_analyzer = QuasiImmutAnalyzer(translator)
- self.canreleasegil_analyzer = CanReleaseGILAnalyzer(translator)
+ self.randomeffects_analyzer = RandomEffectsAnalyzer(translator)
#
for index, jd in enumerate(jitdrivers_sd):
jd.index = index
@@ -187,7 +187,7 @@
fnaddr = llmemory.cast_ptr_to_adr(fnptr)
NON_VOID_ARGS = [ARG for ARG in FUNC.ARGS if ARG is not lltype.Void]
calldescr = self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS),
- FUNC.RESULT)
+ FUNC.RESULT, EffectInfo.MOST_GENERAL)
return (fnaddr, calldescr)
def getcalldescr(self, op, oopspecindex=EffectInfo.OS_NONE,
@@ -219,9 +219,11 @@
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)
+ random_effects = self.randomeffects_analyzer.analyze(op)
+ if random_effects:
+ extraeffect = EffectInfo.EF_RANDOM_EFFECTS
+ # random_effects implies can_invalidate
+ can_invalidate = random_effects or self.quasiimmut_analyzer.analyze(op)
if extraeffect is None:
if self.virtualizable_analyzer.analyze(op):
extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
@@ -239,12 +241,10 @@
#
effectinfo = effectinfo_from_writeanalyze(
self.readwrite_analyzer.analyze(op), self.cpu, extraeffect,
- oopspecindex, can_invalidate, can_release_gil)
+ oopspecindex, can_invalidate)
#
- if oopspecindex != EffectInfo.OS_NONE:
- assert effectinfo is not None
+ assert effectinfo is not None
if elidable or loopinvariant:
- assert effectinfo is not None
assert extraeffect != EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
# XXX this should also say assert not can_invalidate, but
# it can't because our analyzer is not good enough for now
@@ -264,8 +264,7 @@
def calldescr_canraise(self, calldescr):
effectinfo = calldescr.get_extra_info()
- return (effectinfo is None or
- effectinfo.extraeffect > EffectInfo.EF_CANNOT_RAISE)
+ return effectinfo.check_can_raise()
def jitdriver_sd_from_portal_graph(self, graph):
for jd in self.jitdrivers_sd:
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
@@ -15,6 +15,7 @@
EF_ELIDABLE_CAN_RAISE = 3 #elidable function (but can raise)
EF_CAN_RAISE = 4 #normal function (can raise)
EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE = 5 #can raise and force virtualizables
+ EF_RANDOM_EFFECTS = 6 #can do whatever
# the 'oopspecindex' field is one of the following values:
OS_NONE = 0 # normal case, no oopspec
@@ -80,17 +81,26 @@
write_descrs_fields, write_descrs_arrays,
extraeffect=EF_CAN_RAISE,
oopspecindex=OS_NONE,
- can_invalidate=False, can_release_gil=False):
- key = (frozenset(readonly_descrs_fields),
- frozenset(readonly_descrs_arrays),
- frozenset(write_descrs_fields),
- frozenset(write_descrs_arrays),
+ can_invalidate=False):
+ key = (frozenset_or_none(readonly_descrs_fields),
+ frozenset_or_none(readonly_descrs_arrays),
+ frozenset_or_none(write_descrs_fields),
+ frozenset_or_none(write_descrs_arrays),
extraeffect,
oopspecindex,
- can_invalidate,
- can_release_gil)
+ can_invalidate)
if key in cls._cache:
return cls._cache[key]
+ if extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
+ assert readonly_descrs_fields is None
+ assert readonly_descrs_arrays is None
+ assert write_descrs_fields is None
+ assert write_descrs_arrays is None
+ else:
+ assert readonly_descrs_fields is not None
+ assert readonly_descrs_arrays is not None
+ assert write_descrs_fields is not None
+ assert write_descrs_arrays is not None
result = object.__new__(cls)
result.readonly_descrs_fields = readonly_descrs_fields
result.readonly_descrs_arrays = readonly_descrs_arrays
@@ -104,11 +114,13 @@
result.write_descrs_arrays = write_descrs_arrays
result.extraeffect = extraeffect
result.can_invalidate = can_invalidate
- result.can_release_gil = can_release_gil
result.oopspecindex = oopspecindex
cls._cache[key] = result
return result
+ def check_can_raise(self):
+ return self.extraeffect > self.EF_CANNOT_RAISE
+
def check_can_invalidate(self):
return self.can_invalidate
@@ -116,56 +128,71 @@
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.extraeffect >= self.EF_RANDOM_EFFECTS
+
+
+def frozenset_or_none(x):
+ if x is None:
+ return None
+ return frozenset(x)
+
+EffectInfo.MOST_GENERAL = EffectInfo(None, None, None, None,
+ EffectInfo.EF_RANDOM_EFFECTS,
+ can_invalidate=True)
+
def effectinfo_from_writeanalyze(effects, cpu,
extraeffect=EffectInfo.EF_CAN_RAISE,
oopspecindex=EffectInfo.OS_NONE,
- can_invalidate=False,
- can_release_gil=False):
+ can_invalidate=False):
from pypy.translator.backendopt.writeanalyze import top_set
- if effects is top_set:
- return None
- readonly_descrs_fields = []
- readonly_descrs_arrays = []
- write_descrs_fields = []
- write_descrs_arrays = []
+ if effects is top_set or extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
+ readonly_descrs_fields = None
+ readonly_descrs_arrays = None
+ write_descrs_fields = None
+ write_descrs_arrays = None
+ extraeffect = EffectInfo.EF_RANDOM_EFFECTS
+ else:
+ readonly_descrs_fields = []
+ readonly_descrs_arrays = []
+ write_descrs_fields = []
+ write_descrs_arrays = []
- def add_struct(descrs_fields, (_, T, fieldname)):
- T = deref(T)
- if consider_struct(T, fieldname):
- descr = cpu.fielddescrof(T, fieldname)
- descrs_fields.append(descr)
+ def add_struct(descrs_fields, (_, T, fieldname)):
+ T = deref(T)
+ if consider_struct(T, fieldname):
+ descr = cpu.fielddescrof(T, fieldname)
+ descrs_fields.append(descr)
- def add_array(descrs_arrays, (_, T)):
- ARRAY = deref(T)
- if consider_array(ARRAY):
- descr = cpu.arraydescrof(ARRAY)
- descrs_arrays.append(descr)
+ def add_array(descrs_arrays, (_, T)):
+ ARRAY = deref(T)
+ if consider_array(ARRAY):
+ descr = cpu.arraydescrof(ARRAY)
+ descrs_arrays.append(descr)
- for tup in effects:
- if tup[0] == "struct":
- add_struct(write_descrs_fields, tup)
- elif tup[0] == "readstruct":
- tupw = ("struct",) + tup[1:]
- if tupw not in effects:
- add_struct(readonly_descrs_fields, tup)
- elif tup[0] == "array":
- add_array(write_descrs_arrays, tup)
- elif tup[0] == "readarray":
- tupw = ("array",) + tup[1:]
- if tupw not in effects:
- add_array(readonly_descrs_arrays, tup)
- else:
- assert 0
+ for tup in effects:
+ if tup[0] == "struct":
+ add_struct(write_descrs_fields, tup)
+ elif tup[0] == "readstruct":
+ tupw = ("struct",) + tup[1:]
+ if tupw not in effects:
+ add_struct(readonly_descrs_fields, tup)
+ elif tup[0] == "array":
+ add_array(write_descrs_arrays, tup)
+ elif tup[0] == "readarray":
+ tupw = ("array",) + tup[1:]
+ if tupw not in effects:
+ add_array(readonly_descrs_arrays, tup)
+ else:
+ assert 0
+ #
return EffectInfo(readonly_descrs_fields,
readonly_descrs_arrays,
write_descrs_fields,
write_descrs_arrays,
extraeffect,
oopspecindex,
- can_invalidate,
- can_release_gil)
+ can_invalidate)
def consider_struct(TYPE, fieldname):
if fieldType(TYPE, fieldname) is lltype.Void:
@@ -201,12 +228,13 @@
def analyze_simple_operation(self, op, graphinfo):
return op.opname == 'jit_force_quasi_immutable'
-class CanReleaseGILAnalyzer(BoolGraphAnalyzer):
+class RandomEffectsAnalyzer(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.random_effects_on_gcobjs:
+ return True
+ return super(RandomEffectsAnalyzer, self).analyze_direct_call(graph,
+ seen)
def analyze_simple_operation(self, op, graphinfo):
return False
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -1399,7 +1399,7 @@
extraeffect = EffectInfo.EF_CANNOT_RAISE
elif oopspec_name.startswith('libffi_call_'):
oopspecindex = EffectInfo.OS_LIBFFI_CALL
- extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
+ extraeffect = EffectInfo.EF_RANDOM_EFFECTS
else:
assert False, 'unsupported oopspec: %s' % oopspec_name
return self._handle_oopspec_call(op, args, oopspecindex, extraeffect)
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_effects()
diff --git a/pypy/jit/codewriter/test/test_codewriter.py b/pypy/jit/codewriter/test/test_codewriter.py
--- a/pypy/jit/codewriter/test/test_codewriter.py
+++ b/pypy/jit/codewriter/test/test_codewriter.py
@@ -5,7 +5,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
class FakeCallDescr(AbstractDescr):
- def __init__(self, FUNC, ARGS, RESULT, effectinfo=None):
+ def __init__(self, FUNC, ARGS, RESULT, effectinfo):
self.FUNC = FUNC
self.ARGS = ARGS
self.RESULT = RESULT
diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py
--- a/pypy/jit/codewriter/test/test_flatten.py
+++ b/pypy/jit/codewriter/test/test_flatten.py
@@ -50,7 +50,7 @@
def __init__(self, rtyper):
rtyper._builtin_func_for_spec_cache = FakeDict()
self.rtyper = rtyper
- def calldescrof(self, FUNC, ARGS, RESULT):
+ def calldescrof(self, FUNC, ARGS, RESULT, effectinfo):
return FakeDescr()
def fielddescrof(self, STRUCT, name):
return FakeDescr()
diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py b/pypy/jit/metainterp/optimizeopt/fficall.py
--- a/pypy/jit/metainterp/optimizeopt/fficall.py
+++ b/pypy/jit/metainterp/optimizeopt/fficall.py
@@ -19,7 +19,8 @@
self.funcval = funcval
self.opargs = []
argtypes, restype = self._get_signature(funcval)
- self.descr = cpu.calldescrof_dynamic(argtypes, restype)
+ self.descr = cpu.calldescrof_dynamic(argtypes, restype,
+ EffectInfo.MOST_GENERAL)
# ^^^ may be None if unsupported
self.prepare_op = prepare_op
self.delayed_ops = []
@@ -196,9 +197,7 @@
def _get_oopspec(self, op):
effectinfo = op.getdescr().get_extra_info()
- if effectinfo is not None:
- return effectinfo.oopspecindex
- return EffectInfo.OS_NONE
+ return effectinfo.oopspecindex
def _get_funcval(self, op):
return self.getvalue(op.getarg(1))
diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -194,31 +194,33 @@
opnum == rop.CALL_RELEASE_GIL or
opnum == rop.CALL_ASSEMBLER):
if opnum == rop.CALL_ASSEMBLER:
- effectinfo = None
+ self._seen_guard_not_invalidated = False
else:
effectinfo = op.getdescr().get_extra_info()
- if effectinfo is None or effectinfo.check_can_invalidate():
- self._seen_guard_not_invalidated = False
- if effectinfo is not None and not effectinfo.has_random_effects():
- # XXX we can get the wrong complexity here, if the lists
- # XXX stored on effectinfo are large
- for fielddescr in effectinfo.readonly_descrs_fields:
- self.force_lazy_setfield(fielddescr)
- for arraydescr in effectinfo.readonly_descrs_arrays:
- self.force_lazy_setarrayitem(arraydescr)
- for fielddescr in effectinfo.write_descrs_fields:
- self.force_lazy_setfield(fielddescr, can_cache=False)
- for arraydescr in effectinfo.write_descrs_arrays:
- self.force_lazy_setarrayitem(arraydescr, can_cache=False)
- if effectinfo.check_forces_virtual_or_virtualizable():
- vrefinfo = self.optimizer.metainterp_sd.virtualref_info
- self.force_lazy_setfield(vrefinfo.descr_forced)
- # ^^^ we only need to force this field; the other fields
- # of virtualref_info and virtualizable_info are not gcptrs.
- return
+ if effectinfo.check_can_invalidate():
+ self._seen_guard_not_invalidated = False
+ if not effectinfo.has_random_effects():
+ self.force_from_effectinfo(effectinfo)
+ return
self.force_all_lazy_setfields_and_arrayitems()
self.clean_caches()
+ def force_from_effectinfo(self, effectinfo):
+ # XXX we can get the wrong complexity here, if the lists
+ # XXX stored on effectinfo are large
+ for fielddescr in effectinfo.readonly_descrs_fields:
+ self.force_lazy_setfield(fielddescr)
+ for arraydescr in effectinfo.readonly_descrs_arrays:
+ self.force_lazy_setarrayitem(arraydescr)
+ for fielddescr in effectinfo.write_descrs_fields:
+ self.force_lazy_setfield(fielddescr, can_cache=False)
+ for arraydescr in effectinfo.write_descrs_arrays:
+ self.force_lazy_setarrayitem(arraydescr, can_cache=False)
+ if effectinfo.check_forces_virtual_or_virtualizable():
+ vrefinfo = self.optimizer.metainterp_sd.virtualref_info
+ self.force_lazy_setfield(vrefinfo.descr_forced)
+ # ^^^ we only need to force this field; the other fields
+ # of virtualref_info and virtualizable_info are not gcptrs.
def turned_constant(self, value):
assert value.is_constant()
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -424,11 +424,10 @@
# specifically the given oopspec call. For non-oopspec calls,
# oopspecindex is just zero.
effectinfo = op.getdescr().get_extra_info()
- if effectinfo is not None:
- oopspecindex = effectinfo.oopspecindex
- if oopspecindex == EffectInfo.OS_ARRAYCOPY:
- if self._optimize_CALL_ARRAYCOPY(op):
- return
+ oopspecindex = effectinfo.oopspecindex
+ if oopspecindex == EffectInfo.OS_ARRAYCOPY:
+ if self._optimize_CALL_ARRAYCOPY(op):
+ return
self.emit_operation(op)
def _optimize_CALL_ARRAYCOPY(self, op):
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizefficall.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizefficall.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizefficall.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizefficall.py
@@ -51,14 +51,18 @@
restype=types.sint)
#
def calldescr(cpu, FUNC, oopspecindex, extraeffect=None):
- einfo = EffectInfo([], [], [], [], oopspecindex=oopspecindex,
+ if extraeffect == EffectInfo.EF_RANDOM_EFFECTS:
+ f = None # means "can force all" really
+ else:
+ f = []
+ einfo = EffectInfo(f, f, f, f, oopspecindex=oopspecindex,
extraeffect=extraeffect)
return cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, einfo)
#
libffi_prepare = calldescr(cpu, FUNC, EffectInfo.OS_LIBFFI_PREPARE)
libffi_push_arg = calldescr(cpu, FUNC, EffectInfo.OS_LIBFFI_PUSH_ARG)
libffi_call = calldescr(cpu, FUNC, EffectInfo.OS_LIBFFI_CALL,
- EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE)
+ EffectInfo.EF_RANDOM_EFFECTS)
namespace = namespace.__dict__
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_util.py b/pypy/jit/metainterp/optimizeopt/test/test_util.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_util.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_util.py
@@ -164,7 +164,8 @@
onedescr = cpu.fielddescrof(U, 'one')
FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
- plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ plaincalldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
+ EffectInfo.MOST_GENERAL)
nonwritedescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
EffectInfo([], [], [], []))
writeadescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT,
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -545,12 +545,11 @@
return True
elif opnum == rop.CALL:
effectinfo = descr.get_extra_info()
- if effectinfo is not None:
- ef = effectinfo.extraeffect
- if ef == EffectInfo.EF_LOOPINVARIANT or \
- ef == EffectInfo.EF_ELIDABLE_CANNOT_RAISE or \
- ef == EffectInfo.EF_ELIDABLE_CAN_RAISE:
- return True
+ ef = effectinfo.extraeffect
+ if ef == EffectInfo.EF_LOOPINVARIANT or \
+ ef == EffectInfo.EF_ELIDABLE_CANNOT_RAISE or \
+ ef == EffectInfo.EF_ELIDABLE_CAN_RAISE:
+ return True
return False
def update(self, op):
@@ -579,7 +578,7 @@
return
if opnum == rop.CALL:
effectinfo = descr.get_extra_info()
- if effectinfo is not None:
+ if not effectinfo.has_random_effects():
for fielddescr in effectinfo.write_descrs_fields:
self.unsafe_getitem[fielddescr] = True
for arraydescr in effectinfo.write_descrs_arrays:
diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py
--- a/pypy/jit/metainterp/optimizeopt/vstring.py
+++ b/pypy/jit/metainterp/optimizeopt/vstring.py
@@ -456,8 +456,8 @@
# specifically the given oopspec call. For non-oopspec calls,
# oopspecindex is just zero.
effectinfo = op.getdescr().get_extra_info()
- if effectinfo is not None:
- oopspecindex = effectinfo.oopspecindex
+ oopspecindex = effectinfo.oopspecindex
+ if oopspecindex != EffectInfo.OS_NONE:
for value, meth in opt_call_oopspec_ops:
if oopspecindex == value: # a match with the OS_STR_xxx
if meth(self, op, mode_string):
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1257,10 +1257,8 @@
assert i == len(allboxes)
#
effectinfo = descr.get_extra_info()
- if (effectinfo is None or
- effectinfo.extraeffect ==
- effectinfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE or
- assembler_call):
+ if (assembler_call or
+ effectinfo.check_forces_virtual_or_virtualizable()):
# residual calls require attention to keep virtualizables in-sync
self.metainterp.clear_exception()
self.metainterp.vable_and_vrefs_before_residual_call()
@@ -1692,12 +1690,11 @@
return
if opnum == rop.CALL:
effectinfo = descr.get_extra_info()
- if effectinfo is not None:
- ef = effectinfo.extraeffect
- if ef == effectinfo.EF_LOOPINVARIANT or \
- ef == effectinfo.EF_ELIDABLE_CANNOT_RAISE or \
- ef == effectinfo.EF_ELIDABLE_CAN_RAISE:
- return
+ ef = effectinfo.extraeffect
+ if ef == effectinfo.EF_LOOPINVARIANT or \
+ ef == effectinfo.EF_ELIDABLE_CANNOT_RAISE or \
+ ef == effectinfo.EF_ELIDABLE_CAN_RAISE:
+ return
if self.heap_cache:
self.heap_cache.clear()
if self.heap_array_cache:
diff --git a/pypy/jit/metainterp/test/test_compile.py b/pypy/jit/metainterp/test/test_compile.py
--- a/pypy/jit/metainterp/test/test_compile.py
+++ b/pypy/jit/metainterp/test/test_compile.py
@@ -190,7 +190,7 @@
class FakeJitDriverSD:
portal_runner_ptr = llhelper(lltype.Ptr(FUNC), ll_portal_runner)
portal_runner_adr = llmemory.cast_ptr_to_adr(portal_runner_ptr)
- portal_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ portal_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT, None)
portal_finishtoken = compile.DoneWithThisFrameDescrInt()
num_red_args = 2
result_type = INT
diff --git a/pypy/jit/metainterp/test/test_string.py b/pypy/jit/metainterp/test/test_string.py
--- a/pypy/jit/metainterp/test/test_string.py
+++ b/pypy/jit/metainterp/test/test_string.py
@@ -1,5 +1,6 @@
import py
from pypy.rlib.jit import JitDriver, dont_look_inside, we_are_jitted
+from pypy.rlib.debug import debug_print
from pypy.jit.codewriter.policy import StopAtXPolicy
from pypy.rpython.ootypesystem import ootype
from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
@@ -364,7 +365,8 @@
jitdriver = JitDriver(greens = ['g'], reds = ['m'])
@dont_look_inside
def escape(x):
- print str(x)
+ # a plain "print" would call os.write() and release the gil
+ debug_print(str(x))
def f(g, m):
g = str(g)
while m >= 0:
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -745,7 +745,8 @@
jd.portal_calldescr = self.cpu.calldescrof(
jd._PTR_PORTAL_FUNCTYPE.TO,
jd._PTR_PORTAL_FUNCTYPE.TO.ARGS,
- jd._PTR_PORTAL_FUNCTYPE.TO.RESULT)
+ jd._PTR_PORTAL_FUNCTYPE.TO.RESULT,
+ None)
vinfo = jd.virtualizable_info
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,7 +56,7 @@
sandboxsafe=False, threadsafe='auto',
_nowrapper=False, calling_conv='c',
oo_primitive=None, elidable_function=False,
- macro=None):
+ macro=None, random_effects_on_gcobjs='auto'):
"""Build an external function that will invoke the C function 'name'
with the given 'args' types and 'result' type.
@@ -112,13 +112,19 @@
# sandboxsafe is a hint for "too-small-ness" (e.g. math functions).
invoke_around_handlers = not sandboxsafe
+ if random_effects_on_gcobjs not in (False, True):
+ random_effects_on_gcobjs = (
+ 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,
+ random_effects_on_gcobjs=
+ random_effects_on_gcobjs,
**kwds)
if isinstance(_callable, ll2ctypes.LL2CtypesCallable):
_callable.funcptr = funcptr
@@ -1068,4 +1074,4 @@
[VOIDP, VOIDP, SIZE_T],
lltype.Void,
threadsafe=False
-)
\ No newline at end of file
+)
diff --git a/pypy/tool/gdb_pypy.py b/pypy/tool/gdb_pypy.py
--- a/pypy/tool/gdb_pypy.py
+++ b/pypy/tool/gdb_pypy.py
@@ -65,7 +65,7 @@
"""
prog2typeids = {}
-
+
def __init__(self, gdb=None):
# dependency injection, for tests
if gdb is None:
@@ -137,7 +137,7 @@
val" and see the nice string, and "p *val" to see the underyling struct
fields
"""
-
+
def __init__(self, val):
self.val = val
@@ -172,7 +172,8 @@
@classmethod
def lookup(cls, val, gdb=None):
t = val.type
- if is_ptr(t, gdb) and re.match(r'pypy_list\d*', t.target().tag):
+ if (is_ptr(t, gdb) and t.target().tag is not None and
+ re.match(r'pypy_list\d*', t.target().tag)):
return cls(val)
return None
diff --git a/pypy/tool/test/test_gdb_pypy.py b/pypy/tool/test/test_gdb_pypy.py
--- a/pypy/tool/test/test_gdb_pypy.py
+++ b/pypy/tool/test/test_gdb_pypy.py
@@ -29,7 +29,7 @@
class Struct(object):
code = FakeGdb.TYPE_CODE_STRUCT
-
+
def __init__(self, fieldnames, tag):
self._fields = [Field(name=name) for name in fieldnames]
self.tag = tag
@@ -178,3 +178,6 @@
mylist.type.target().tag = 'pypy_list1234'
printer = gdb_pypy.RPyListPrinter.lookup(mylist, FakeGdb)
assert printer.to_string() == 'r[40, 41, 42] (len=3, alloc=5)'
+
+ mylist.type.target().tag = None
+ assert gdb_pypy.RPyListPrinter.lookup(mylist, FakeGdb) is None
\ No newline at end of file
More information about the pypy-commit
mailing list