Author: Hakan Ardo <[email protected]>
Branch: jit-continue_tracing
Changeset: r44342:0a682377607f
Date: 2011-05-16 20:35 +0200
http://bitbucket.org/pypy/pypy/changeset/0a682377607f/
Log: hg merge default
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -127,8 +127,6 @@
SQLITE_FUNCTION = 31
# SQLite C API
-sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double]
-sqlite.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64]
sqlite.sqlite3_value_int.argtypes = [c_void_p]
sqlite.sqlite3_value_int.restype = c_int
@@ -151,7 +149,16 @@
sqlite.sqlite3_value_type.argtypes = [c_void_p]
sqlite.sqlite3_value_type.restype = c_int
+sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int,c_void_p]
+sqlite.sqlite3_bind_blob.restype = c_int
+sqlite.sqlite3_bind_double.argtypes = [c_void_p, c_int, c_double]
+sqlite.sqlite3_bind_double.restype = c_int
sqlite.sqlite3_bind_int.argtypes = [c_void_p, c_int, c_int]
+sqlite.sqlite3_bind_int.restype = c_int
+sqlite.sqlite3_bind_int64.argtypes = [c_void_p, c_int, c_int64]
+sqlite.sqlite3_bind_int64.restype = c_int
+sqlite.sqlite3_bind_null.argtypes = [c_void_p, c_int]
+sqlite.sqlite3_bind_null.restype = c_int
sqlite.sqlite3_bind_parameter_count.argtypes = [c_void_p]
sqlite.sqlite3_bind_parameter_count.restype = c_int
sqlite.sqlite3_bind_parameter_index.argtypes = [c_void_p, c_char_p]
@@ -159,45 +166,69 @@
sqlite.sqlite3_bind_parameter_name.argtypes = [c_void_p, c_int]
sqlite.sqlite3_bind_parameter_name.restype = c_char_p
sqlite.sqlite3_bind_text.argtypes = [c_void_p, c_int, c_char_p, c_int,c_void_p]
-sqlite.sqlite3_bind_blob.argtypes = [c_void_p, c_int, c_void_p, c_int,c_void_p]
-sqlite.sqlite3_bind_blob.restype = c_int
+sqlite.sqlite3_bind_text.restype = c_int
+sqlite.sqlite3_busy_timeout.argtypes = [c_void_p, c_int]
+sqlite.sqlite3_busy_timeout.restype = c_int
sqlite.sqlite3_changes.argtypes = [c_void_p]
sqlite.sqlite3_changes.restype = c_int
sqlite.sqlite3_close.argtypes = [c_void_p]
sqlite.sqlite3_close.restype = c_int
+sqlite.sqlite3_column_blob.argtypes = [c_void_p, c_int]
sqlite.sqlite3_column_blob.restype = c_void_p
+sqlite.sqlite3_column_bytes.argtypes = [c_void_p, c_int]
sqlite.sqlite3_column_bytes.restype = c_int
+sqlite.sqlite3_column_count.argtypes = [c_void_p]
+sqlite.sqlite3_column_count.restype = c_int
+sqlite.sqlite3_column_decltype.argtypes = [c_void_p, c_int]
+sqlite.sqlite3_column_decltype.restype = c_char_p
+sqlite.sqlite3_column_double.argtypes = [c_void_p, c_int]
sqlite.sqlite3_column_double.restype = c_double
+sqlite.sqlite3_column_int64.argtypes = [c_void_p, c_int]
sqlite.sqlite3_column_int64.restype = c_int64
+sqlite.sqlite3_column_name.argtypes = [c_void_p, c_int]
sqlite.sqlite3_column_name.restype = c_char_p
+sqlite.sqlite3_column_text.argtypes = [c_void_p, c_int]
sqlite.sqlite3_column_text.restype = c_char_p
+sqlite.sqlite3_column_type.argtypes = [c_void_p, c_int]
+sqlite.sqlite3_column_type.restype = c_int
sqlite.sqlite3_complete.argtypes = [c_char_p]
sqlite.sqlite3_complete.restype = c_int
sqlite.sqlite3_errcode.restype = c_int
+sqlite.sqlite3_errmsg.argtypes = [c_void_p]
sqlite.sqlite3_errmsg.restype = c_char_p
+sqlite.sqlite3_finalize.argtypes = [c_void_p]
+sqlite.sqlite3_finalize.restype = c_int
sqlite.sqlite3_get_autocommit.argtypes = [c_void_p]
sqlite.sqlite3_get_autocommit.restype = c_int
+sqlite.sqlite3_last_insert_rowid.argtypes = [c_void_p]
+sqlite.sqlite3_last_insert_rowid.restype = c_int64
sqlite.sqlite3_libversion.argtypes = []
sqlite.sqlite3_libversion.restype = c_char_p
sqlite.sqlite3_open.argtypes = [c_char_p, c_void_p]
sqlite.sqlite3_open.restype = c_int
+sqlite.sqlite3_prepare.argtypes = [c_void_p, c_char_p, c_int, c_void_p,
POINTER(c_char_p)]
+sqlite.sqlite3_prepare.restype = c_int
sqlite.sqlite3_prepare_v2.argtypes = [c_void_p, c_char_p, c_int, c_void_p,
POINTER(c_char_p)]
sqlite.sqlite3_prepare_v2.restype = c_int
-sqlite.sqlite3_column_decltype.argtypes = [c_void_p, c_int]
-sqlite.sqlite3_column_decltype.restype = c_char_p
sqlite.sqlite3_step.argtypes = [c_void_p]
sqlite.sqlite3_step.restype = c_int
sqlite.sqlite3_reset.argtypes = [c_void_p]
sqlite.sqlite3_reset.restype = c_int
-sqlite.sqlite3_column_count.argtypes = [c_void_p]
-sqlite.sqlite3_column_count.restype = c_int
+sqlite.sqlite3_total_changes.argtypes = [c_void_p]
+sqlite.sqlite3_total_changes.restype = c_int
sqlite.sqlite3_result_blob.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
+sqlite.sqlite3_result_blob.restype = None
sqlite.sqlite3_result_int64.argtypes = [c_void_p, c_int64]
+sqlite.sqlite3_result_int64.restype = None
sqlite.sqlite3_result_null.argtypes = [c_void_p]
+sqlite.sqlite3_result_null.restype = None
sqlite.sqlite3_result_double.argtypes = [c_void_p, c_double]
+sqlite.sqlite3_result_double.restype = None
sqlite.sqlite3_result_error.argtypes = [c_void_p, c_char_p, c_int]
+sqlite.sqlite3_result_error.restype = None
sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
+sqlite.sqlite3_result_text.restype = None
##########################################
# END Wrapped SQLite C API and constants
diff --git a/pypy/interpreter/executioncontext.py
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -24,6 +24,8 @@
# XXX [fijal] but they're not. is_being_profiled is guarded a bit all
# over the place as well as w_tracefunc
+ _immutable_fields_ = ['profilefunc?', 'w_tracefunc?']
+
def __init__(self, space):
self.space = space
self.topframeref = jit.vref_None
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -768,6 +768,31 @@
funcptr(llmemory.cast_ptr_to_adr(gcref_struct),
llmemory.cast_ptr_to_adr(gcref_newptr))
+ def replace_constptrs_with_getfield_raw(self, cpu, newops, op):
+ # xxx some performance issue here
+ newargs = [None] * op.numargs()
+ needs_copy = False
+ for i in range(op.numargs()):
+ v = op.getarg(i)
+ newargs[i] = v
+ if isinstance(v, ConstPtr) and bool(v.value):
+ addr = self.gcrefs.get_address_of_gcref(v.value)
+ # ^^^even for non-movable objects, to record their presence
+ if rgc.can_move(v.value):
+ box = BoxPtr(v.value)
+ addr = cpu.cast_adr_to_int(addr)
+ newops.append(ResOperation(rop.GETFIELD_RAW,
+ [ConstInt(addr)], box,
+ self.single_gcref_descr))
+ newargs[i] = box
+ needs_copy = True
+ #
+ if needs_copy:
+ return op.copy_and_change(op.getopnum(), args=newargs)
+ else:
+ return op
+
+
def rewrite_assembler(self, cpu, operations):
# Perform two kinds of rewrites in parallel:
#
@@ -790,19 +815,7 @@
if op.getopnum() == rop.DEBUG_MERGE_POINT:
continue
# ---------- replace ConstPtrs with GETFIELD_RAW ----------
- # xxx some performance issue here
- for i in range(op.numargs()):
- v = op.getarg(i)
- if isinstance(v, ConstPtr) and bool(v.value):
- addr = self.gcrefs.get_address_of_gcref(v.value)
- # ^^^even for non-movable objects, to record their presence
- if rgc.can_move(v.value):
- box = BoxPtr(v.value)
- addr = cpu.cast_adr_to_int(addr)
- newops.append(ResOperation(rop.GETFIELD_RAW,
- [ConstInt(addr)], box,
- self.single_gcref_descr))
- op.setarg(i, box)
+ op = self.replace_constptrs_with_getfield_raw(cpu, newops, op)
if op.is_malloc():
last_malloc = op.result
elif op.can_malloc():
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py
b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -6,6 +6,7 @@
from pypy.jit.backend.llsupport.gc import *
from pypy.jit.backend.llsupport import symbolic
from pypy.jit.metainterp.gc import get_description
+from pypy.jit.metainterp.resoperation import get_deep_immutable_oplist
from pypy.jit.tool.oparser import parse
from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
from pypy.jit.metainterp.test.test_optimizeopt import equaloplists
@@ -437,6 +438,7 @@
]
gc_ll_descr = self.gc_ll_descr
gc_ll_descr.gcrefs = MyFakeGCRefList()
+ operations = get_deep_immutable_oplist(operations)
operations = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations)
assert len(operations) == 2
assert operations[0].getopnum() == rop.GETFIELD_RAW
@@ -472,6 +474,7 @@
gc_ll_descr = self.gc_ll_descr
gc_ll_descr.gcrefs = MyFakeGCRefList()
old_can_move = rgc.can_move
+ operations = get_deep_immutable_oplist(operations)
try:
rgc.can_move = lambda s: False
operations = gc_ll_descr.rewrite_assembler(MyFakeCPU(), operations)
@@ -496,6 +499,7 @@
descr=field_descr),
]
gc_ll_descr = self.gc_ll_descr
+ operations = get_deep_immutable_oplist(operations)
operations = gc_ll_descr.rewrite_assembler(self.fake_cpu, operations)
assert len(operations) == 2
#
@@ -520,6 +524,7 @@
descr=array_descr),
]
gc_ll_descr = self.gc_ll_descr
+ operations = get_deep_immutable_oplist(operations)
operations = gc_ll_descr.rewrite_assembler(self.fake_cpu, operations)
assert len(operations) == 2
#
@@ -552,7 +557,8 @@
setfield_gc(p0, p1, descr=xdescr)
jump()
""", namespace=locals())
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
ops.operations)
+ operations = get_deep_immutable_oplist(ops.operations)
+ operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
operations)
equaloplists(operations, expected.operations)
def test_rewrite_assembler_initialization_store_2(self):
@@ -576,7 +582,8 @@
setfield_raw(p0, p1, descr=xdescr)
jump()
""", namespace=locals())
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
ops.operations)
+ operations = get_deep_immutable_oplist(ops.operations)
+ operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
operations)
equaloplists(operations, expected.operations)
def test_rewrite_assembler_initialization_store_3(self):
@@ -594,7 +601,8 @@
setarrayitem_gc(p0, 0, p1, descr=arraydescr)
jump()
""", namespace=locals())
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
ops.operations)
+ operations = get_deep_immutable_oplist(ops.operations)
+ operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
operations)
equaloplists(operations, expected.operations)
class TestFrameworkMiniMark(TestFramework):
diff --git a/pypy/jit/backend/x86/test/test_gc_integration.py
b/pypy/jit/backend/x86/test/test_gc_integration.py
--- a/pypy/jit/backend/x86/test/test_gc_integration.py
+++ b/pypy/jit/backend/x86/test/test_gc_integration.py
@@ -54,7 +54,8 @@
self.gcrefs = GcRefList()
self.gcrefs.initialize()
self.single_gcref_descr = GcPtrFieldDescr('', 0)
-
+
+ replace_constptrs_with_getfield_raw =
GcLLDescr_framework.replace_constptrs_with_getfield_raw.im_func
rewrite_assembler = GcLLDescr_framework.rewrite_assembler.im_func
class TestRegallocDirectGcIntegration(object):
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
@@ -219,11 +219,10 @@
assert not NON_VOID_ARGS, ("arguments not supported for "
"loop-invariant function!")
# build the extraeffect
+ can_invalidate = self.quasiimmut_analyzer.analyze(op)
if extraeffect is None:
if self.virtualizable_analyzer.analyze(op):
extraeffect = EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
- elif self.quasiimmut_analyzer.analyze(op):
- extraeffect = EffectInfo.EF_CAN_INVALIDATE
elif loopinvariant:
extraeffect = EffectInfo.EF_LOOPINVARIANT
elif pure:
@@ -236,12 +235,14 @@
#
effectinfo = effectinfo_from_writeanalyze(
self.readwrite_analyzer.analyze(op), self.cpu, extraeffect,
- oopspecindex)
+ oopspecindex, can_invalidate)
#
if pure or loopinvariant:
assert effectinfo is not None
assert extraeffect != EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
- assert extraeffect != EffectInfo.EF_CAN_INVALIDATE
+ # XXX this should also say assert not can_invalidate, but
+ # it can't because our analyzer is not good enough for now
+ # (and getexecutioncontext() can't really invalidate)
#
return self.cpu.calldescrof(FUNC, tuple(NON_VOID_ARGS), RESULT,
effectinfo)
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
@@ -13,7 +13,6 @@
EF_LOOPINVARIANT = 1 #special: call it only once per loop
EF_CANNOT_RAISE = 2 #a function which cannot raise
EF_CAN_RAISE = 3 #normal function (can raise)
- EF_CAN_INVALIDATE = 4 #can force all GUARD_NOT_INVALIDATED
EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE = 5 #can raise and force virtualizables
# the 'oopspecindex' field is one of the following values:
@@ -79,7 +78,8 @@
def __new__(cls, readonly_descrs_fields,
write_descrs_fields, write_descrs_arrays,
extraeffect=EF_CAN_RAISE,
- oopspecindex=OS_NONE):
+ oopspecindex=OS_NONE,
+ can_invalidate=False):
key = (frozenset(readonly_descrs_fields),
frozenset(write_descrs_fields),
frozenset(write_descrs_arrays),
@@ -97,19 +97,21 @@
result.write_descrs_fields = write_descrs_fields
result.write_descrs_arrays = write_descrs_arrays
result.extraeffect = extraeffect
+ result.can_invalidate = can_invalidate
result.oopspecindex = oopspecindex
cls._cache[key] = result
return result
def check_can_invalidate(self):
- return self.extraeffect >= self.EF_CAN_INVALIDATE
+ return self.can_invalidate
def check_forces_virtual_or_virtualizable(self):
return self.extraeffect >= self.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE
def effectinfo_from_writeanalyze(effects, cpu,
extraeffect=EffectInfo.EF_CAN_RAISE,
- oopspecindex=EffectInfo.OS_NONE):
+ oopspecindex=EffectInfo.OS_NONE,
+ can_invalidate=False):
from pypy.translator.backendopt.writeanalyze import top_set
if effects is top_set:
return None
@@ -147,7 +149,8 @@
write_descrs_fields,
write_descrs_arrays,
extraeffect,
- oopspecindex)
+ oopspecindex,
+ can_invalidate)
def consider_struct(TYPE, fieldname):
if fieldType(TYPE, fieldname) is lltype.Void:
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -7,7 +7,7 @@
from pypy.conftest import option
from pypy.tool.sourcetools import func_with_new_name
-from pypy.jit.metainterp.resoperation import ResOperation, rop
+from pypy.jit.metainterp.resoperation import ResOperation, rop,
get_deep_immutable_oplist
from pypy.jit.metainterp.history import TreeLoop, Box, History, LoopToken
from pypy.jit.metainterp.history import AbstractFailDescr, BoxInt
from pypy.jit.metainterp.history import BoxPtr, BoxObj, BoxFloat, Const
@@ -73,7 +73,7 @@
# test_memgr.py)
if descr is not looptoken:
looptoken.record_jump_to(descr)
- op.setdescr(None) # clear reference, mostly for tests
+ op._descr = None # clear reference, mostly for tests
if not we_are_translated():
op._jumptarget_number = descr.number
# record this looptoken on the QuasiImmut used in the code
@@ -159,10 +159,12 @@
if not we_are_translated():
show_loop(metainterp_sd, loop)
loop.check_consistency()
+
+ operations = get_deep_immutable_oplist(loop.operations)
metainterp_sd.profiler.start_backend()
debug_start("jit-backend")
try:
- ops_offset = metainterp_sd.cpu.compile_loop(loop.inputargs,
loop.operations,
+ ops_offset = metainterp_sd.cpu.compile_loop(loop.inputargs, operations,
loop.token)
finally:
debug_stop("jit-backend")
@@ -190,6 +192,7 @@
show_loop(metainterp_sd)
TreeLoop.check_consistency_of(inputargs, operations)
metainterp_sd.profiler.start_backend()
+ operations = get_deep_immutable_oplist(operations)
debug_start("jit-backend")
try:
ops_offset = metainterp_sd.cpu.compile_bridge(faildescr, inputargs,
operations,
@@ -688,6 +691,7 @@
ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken)
]
operations[1].setfailargs([])
+ operations = get_deep_immutable_oplist(operations)
cpu.compile_loop(inputargs, operations, loop_token, log=False)
if memory_manager is not None: # for tests
memory_manager.keep_loop_alive(loop_token)
diff --git a/pypy/jit/metainterp/resoperation.py
b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -627,13 +627,15 @@
rop.PTR_NE: rop.PTR_NE,
}
+
def get_deep_immutable_oplist(operations):
"""
- When not we_are_translated(), turns ``operations`` into a tuple and
+ When not we_are_translated(), turns ``operations`` into a frozenlist and
monkey-patch its items to make sure they are not mutated.
When we_are_translated(), do nothing and just return the old list.
"""
+ from pypy.tool.frozenlist import frozenlist
if we_are_translated():
return operations
#
@@ -641,7 +643,7 @@
assert False, "operations cannot change at this point"
def setdescr(*args):
assert False, "operations cannot change at this point"
- newops = tuple(operations)
+ newops = frozenlist(operations)
for op in newops:
op.setarg = setarg
op.setdescr = setdescr
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -265,7 +265,7 @@
PARAMETERS = {'threshold': 1000,
'trace_eagerness': 200,
- 'trace_limit': 10000,
+ 'trace_limit': 12000,
'inlining': 0,
'loop_longevity': 1000,
'retrace_limit': 5,
diff --git a/pypy/tool/frozenlist.py b/pypy/tool/frozenlist.py
new file mode 100644
--- /dev/null
+++ b/pypy/tool/frozenlist.py
@@ -0,0 +1,19 @@
+from pypy.tool.sourcetools import func_with_new_name
+
+def forbid(*args):
+ raise TypeError, "cannot mutate a frozenlist"
+
+class frozenlist(list):
+ __setitem__ = func_with_new_name(forbid, '__setitem__')
+ __delitem__ = func_with_new_name(forbid, '__delitem__')
+ __setslice__ = func_with_new_name(forbid, '__setslice__')
+ __delslice__ = func_with_new_name(forbid, '__delslice__')
+ __iadd__ = func_with_new_name(forbid, '__iadd__')
+ __imul__ = func_with_new_name(forbid, '__imul__')
+ append = func_with_new_name(forbid, 'append')
+ insert = func_with_new_name(forbid, 'insert')
+ pop = func_with_new_name(forbid, 'pop')
+ remove = func_with_new_name(forbid, 'remove')
+ reverse = func_with_new_name(forbid, 'reverse')
+ sort = func_with_new_name(forbid, 'sort')
+ extend = func_with_new_name(forbid, 'extend')
diff --git a/pypy/tool/test/test_frozenlist.py
b/pypy/tool/test/test_frozenlist.py
new file mode 100644
--- /dev/null
+++ b/pypy/tool/test/test_frozenlist.py
@@ -0,0 +1,21 @@
+import py
+from pypy.tool.frozenlist import frozenlist
+
+def test_frozenlist():
+ l = frozenlist([1, 2, 3])
+ assert l[0] == 1
+ assert l[:2] == [1, 2]
+ assert l.index(2) == 1
+ py.test.raises(TypeError, "l[0] = 1")
+ py.test.raises(TypeError, "del l[0]")
+ py.test.raises(TypeError, "l[:] = []")
+ py.test.raises(TypeError, "del l[:]")
+ py.test.raises(TypeError, "l += []")
+ py.test.raises(TypeError, "l *= 2")
+ py.test.raises(TypeError, "l.append(1)")
+ py.test.raises(TypeError, "l.insert(0, 0)")
+ py.test.raises(TypeError, "l.pop()")
+ py.test.raises(TypeError, "l.remove(1)")
+ py.test.raises(TypeError, "l.reverse()")
+ py.test.raises(TypeError, "l.sort()")
+ py.test.raises(TypeError, "l.extend([])")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit