Author: Armin Rigo <[email protected]>
Branch: effectinfo-cleanup
Changeset: r46386:1eb7497a8982
Date: 2011-08-09 09:16 +0200
http://bitbucket.org/pypy/pypy/changeset/1eb7497a8982/
Log: Clean-up effectinfo: now all calldescrs need to have one, but its
extraeffects can be EF_RANDOM_EFFECTS, in replacement of
effectinfo=None. This is a clean-up because it allows us to build
an effectinfo with both EF_RANDOM_EFFECTS and OS_LIBFFI_CALL.
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
@@ -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,
@@ -220,6 +220,8 @@
"loop-invariant function!")
# build the extraeffect
can_release_gil = self.canreleasegil_analyzer.analyze(op)
+ if can_release_gil:
+ extraeffect = EffectInfo.EF_RANDOM_EFFECTS
# can_release_gil implies can_invalidate
can_invalidate = can_release_gil or
self.quasiimmut_analyzer.analyze(op)
if extraeffect is None:
@@ -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:
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
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit