Commits

Antonio Cuni  committed 9879b1c Merge

merge heads

  • Participants
  • Parent commits 34eca51, d2a47f3

Comments (0)

Files changed (27)

File pypy/doc/config/translation.jit_ffi.txt

-Internal option: enable OptFfiCall in the jit optimizations.

File pypy/jit/codewriter/longlong.py

 
     getfloatstorage = longlong2float.float2longlong
     getrealfloat    = longlong2float.longlong2float
-    gethash         = lambda xll: xll - (xll >> 32)
+    gethash         = lambda xll: rarithmetic.intmask(xll - (xll >> 32))
     is_longlong     = lambda TYPE: (TYPE == lltype.SignedLongLong or
                                     TYPE == lltype.UnsignedLongLong)
 

File pypy/jit/codewriter/test/test_longlong.py

 from pypy.jit.codewriter.jtransform import Transformer, NotSupported
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter.test.test_jtransform import const
+from pypy.jit.codewriter import longlong
 
 
 class FakeRTyper:
         self.rtyper = FakeRTyper()
 
 
+def test_functions():
+    xll = longlong.getfloatstorage(3.5)
+    assert longlong.getrealfloat(xll) == 3.5
+    assert isinstance(longlong.gethash(xll), int)
+
+
 class TestLongLong:
     def setup_class(cls):
         if sys.maxint > 2147483647:

File pypy/jit/metainterp/compile.py

 
 def create_empty_loop(metainterp, name_prefix=''):
     name = metainterp.staticdata.stats.name_for_new_loop()
-    return TreeLoop(name_prefix + name)
+    loop = TreeLoop(name_prefix + name)
+    loop.call_pure_results = metainterp.call_pure_results
+    return loop
+
 
 def make_loop_token(nb_args, jitdriver_sd):
     loop_token = LoopToken()

File pypy/jit/metainterp/history.py

     inputargs = None
     operations = None
     token = None
+    call_pure_results = None
 
     def __init__(self, name):
         self.name = name

File pypy/jit/metainterp/optimizeopt/optimizer.py

         self.posponedop = None
         self.exception_might_have_happened = False
         self.newoperations = []
+        if loop is not None:
+            self.call_pure_results = loop.call_pure_results
 
         self.set_optimizations(optimizations)
 

File pypy/jit/metainterp/optimizeopt/rewrite.py

             self.emit_operation(op)
 
     def optimize_CALL_PURE(self, op):
+        arg_consts = []
         for i in range(op.numargs()):
             arg = op.getarg(i)
-            if self.get_constant_box(arg) is None:
+            const = self.get_constant_box(arg)
+            if const is None:
                 break
+            arg_consts.append(const)
         else:
-            # all constant arguments: constant-fold away
-            self.make_constant(op.result, op.getarg(0))
-            return
+            # all constant arguments: check if we already know the reslut
+            try:
+                result = self.optimizer.call_pure_results[arg_consts]
+            except KeyError:
+                pass
+            else:
+                self.make_constant(op.result, result)
+                return
         # replace CALL_PURE with just CALL
-        args = op.getarglist()[1:]
+        args = op.getarglist()
         self.emit_operation(ResOperation(rop.CALL, args, op.result,
                                          op.getdescr()))
 

File pypy/jit/metainterp/optimizeopt/simplify.py

 
 class OptSimplify(Optimization):
     def optimize_CALL_PURE(self, op):
-        args = op.getarglist()[1:]
+        args = op.getarglist()
         self.emit_operation(ResOperation(rop.CALL, args, op.result,
                                          op.getdescr()))
 

File pypy/jit/metainterp/optimizeopt/string.py

         if not self.enabled:
             self.emit_operation(op)
             return
-            
+
         opnum = op.getopnum()
         for value, func in optimize_ops:
             if opnum == value:

File pypy/jit/metainterp/optimizeutil.py

 
 def args_dict():
     return r_dict(args_eq, args_hash)
+
+def args_dict_box():
+    return r_dict(args_eq, args_hash)

File pypy/jit/metainterp/pyjitpl.py

 from pypy.rlib.objectmodel import specialize
 from pypy.jit.codewriter.jitcode import JitCode, SwitchDictDescr, MissingLiveness
 from pypy.jit.codewriter import heaptracker, longlong
-from pypy.jit.metainterp.optimizeutil import RetraceLoop
+from pypy.jit.metainterp.optimizeutil import RetraceLoop, args_dict_box, args_dict
 
 # ____________________________________________________________
 
         self.free_frames_list = []
         self.last_exc_value_box = None
         self.retracing_loop_from = None
+        self.call_pure_results = args_dict_box()
 
     def perform_call(self, jitcode, boxes, greenkey=None):
         # causes the metainterp to enter the given subfunction
             return resbox_as_const
         # not all constants (so far): turn CALL into CALL_PURE, which might
         # be either removed later by optimizeopt or turned back into CALL.
-        newop = op.copy_and_change(rop.CALL_PURE, args=[resbox_as_const]+op.getarglist())
+        arg_consts = [a.constbox() for a in op.getarglist()]
+        self.call_pure_results[arg_consts] = resbox_as_const
+        newop = op.copy_and_change(rop.CALL_PURE, args=op.getarglist())
         self.history.operations[-1] = newop
         return resbox
 

File pypy/jit/metainterp/resoperation.py

     #'OOSEND',                     # ootype operation
     #'OOSEND_PURE',                # ootype operation
     'CALL_PURE/*d',             # removed before it's passed to the backend
-                             # CALL_PURE(result, func, arg_1,..,arg_n)
     '_CALL_LAST',
     '_CANRAISE_LAST', # ----- end of can_raise operations -----
 

File pypy/jit/metainterp/simple_optimize.py

-
-""" Simplified optimize.py
-"""
-
-from pypy.jit.metainterp.resoperation import rop, ResOperation
-from pypy.jit.metainterp import resume, compile
-
-EMPTY_VALUES = {}
-
-def transform(op):
-    from pypy.jit.metainterp.history import AbstractDescr
-    # Rename CALL_PURE and CALL_LOOPINVARIANT to CALL.
-    # Simplify the VIRTUAL_REF_* so that they don't show up in the backend.
-    if op.getopnum() == rop.CALL_PURE:
-        op = ResOperation(rop.CALL, op.getarglist()[1:], op.result,
-                          op.getdescr())
-    elif op.getopnum() == rop.CALL_LOOPINVARIANT:
-        op = op.copy_and_change(rop.CALL)
-    elif op.getopnum() == rop.VIRTUAL_REF:
-        op = ResOperation(rop.SAME_AS, [op.getarg(0)], op.result)
-    elif op.getopnum() == rop.VIRTUAL_REF_FINISH:
-        return []
-    return [op]
-
-def optimize_loop(metainterp_sd, old_loops, loop):
-    if old_loops:
-        assert len(old_loops) == 1
-        return old_loops[0]
-    else:
-        # copy loop operations here
-        # we need it since the backend can modify those lists, which make
-        # get_guard_op in compile.py invalid
-        # in fact, x86 modifies this list for moving GCs
-        memo = resume.ResumeDataLoopMemo(metainterp_sd)
-        newoperations = []
-        for op in loop.operations:
-            if op.is_guard():
-                descr = op.getdescr()
-                assert isinstance(descr, compile.ResumeGuardDescr)
-                modifier = resume.ResumeDataVirtualAdder(descr, memo)
-                newboxes = modifier.finish(EMPTY_VALUES)
-                descr.store_final_boxes(op, newboxes)
-            newoperations.extend(transform(op))
-        loop.operations = newoperations
-        jumpop = newoperations[-1]
-        if jumpop.getopnum() == rop.JUMP:
-            jumpop.setdescr(loop.token)
-        return None
-
-def optimize_bridge(metainterp_sd, old_loops, loop, inline_short_preamble,
-                    retraced):
-    optimize_loop(metainterp_sd, [], loop)
-    jumpop = loop.operations[-1]
-    if jumpop.getopnum() == rop.JUMP:
-        jumpop.setdescr(old_loops[0])
-    return old_loops[0]

File pypy/jit/metainterp/test/test_basic.py

 def _get_jitcodes(testself, CPUClass, func, values, type_system,
                   supports_longlong=False, **kwds):
     from pypy.jit.codewriter import support, codewriter
-    from pypy.jit.metainterp import simple_optimize
 
     class FakeJitCell:
         __compiled_merge_points = []
             return self._cell
         _cell = FakeJitCell()
 
-        # pick the optimizer this way
-        optimize_loop = staticmethod(simple_optimize.optimize_loop)
-        optimize_bridge = staticmethod(simple_optimize.optimize_bridge)
-
         trace_limit = sys.maxint
         enable_opts = ALL_OPTS_DICT
 

File pypy/jit/metainterp/test/test_compile.py

         pass
 
 class FakeMetaInterp:
+    call_pure_results = {}
     class jitdriver_sd:
         warmstate = FakeState()
 

File pypy/jit/metainterp/test/test_optimizebasic.py

 from pypy.jit.metainterp import executor, compile, resume, history
 from pypy.jit.metainterp.resoperation import rop, opname, ResOperation
 from pypy.jit.tool.oparser import pure_parse
+from pypy.jit.metainterp.optimizeutil import args_dict
 
 ##class FakeFrame(object):
 ##    parent_resumedata_snapshot = None
         assert equaloplists(optimized.operations,
                             expected.operations, False, remap)
 
-    def optimize_loop(self, ops, optops):
+    def optimize_loop(self, ops, optops, call_pure_results=None):
         loop = self.parse(ops)
         #
         self.loop = loop
+        loop.call_pure_results = args_dict()
+        if call_pure_results is not None:
+            for k, v in call_pure_results.items():
+                loop.call_pure_results[list(k)] = v        
         metainterp_sd = FakeMetaInterpStaticData(self.cpu)
         if hasattr(self, 'vrefinfo'):
             metainterp_sd.virtualref_info = self.vrefinfo
         ops = '''
         [p1, i1]
         setfield_gc(p1, i1, descr=valuedescr)
-        i3 = call_pure(42, p1, descr=plaincalldescr)
+        i3 = call_pure(p1, descr=plaincalldescr)
         setfield_gc(p1, i3, descr=valuedescr)
         jump(p1, i3)
         '''
         # time.  Check that it is either constant-folded (and replaced by
         # the result of the call, recorded as the first arg), or turned into
         # a regular CALL.
+        arg_consts = [ConstInt(i) for i in (123456, 4, 5, 6)]
+        call_pure_results = {tuple(arg_consts): ConstInt(42)}        
         ops = '''
         [i0, i1, i2]
         escape(i1)
         escape(i2)
-        i3 = call_pure(42, 123456, 4, 5, 6, descr=plaincalldescr)
-        i4 = call_pure(43, 123456, 4, i0, 6, descr=plaincalldescr)
+        i3 = call_pure(123456, 4, 5, 6, descr=plaincalldescr)
+        i4 = call_pure(123456, 4, i0, 6, descr=plaincalldescr)
         jump(i0, i3, i4)
         '''
         expected = '''
         i4 = call(123456, 4, i0, 6, descr=plaincalldescr)
         jump(i0, 42, i4)
         '''
-        self.optimize_loop(ops, expected)
+        self.optimize_loop(ops, expected, call_pure_results)
 
     def test_vref_nonvirtual_nonescape(self):
         ops = """

File pypy/jit/metainterp/test/test_optimizeopt.py

 from pypy.jit.metainterp.resoperation import rop, opname, ResOperation
 from pypy.jit.tool.oparser import pure_parse
 from pypy.jit.metainterp.test.test_optimizebasic import equaloplists
+from pypy.jit.metainterp.optimizeutil import args_dict
 
 class Fake(object):
     failargs_limit = 1000
         assert equaloplists(optimized.operations,
                             expected.operations, False, remap, text_right)
 
-    def optimize_loop(self, ops, optops, expected_preamble=None):
+    def optimize_loop(self, ops, optops, expected_preamble=None,
+                      call_pure_results=None):
         loop = self.parse(ops)
         if optops != "crash!":
             expected = self.parse(optops)
             expected_preamble = self.parse(expected_preamble)
         #
         self.loop = loop
+        loop.call_pure_results = args_dict()
+        if call_pure_results is not None:
+            for k, v in call_pure_results.items():
+                loop.call_pure_results[list(k)] = v
         loop.preamble = TreeLoop('preamble')
         loop.preamble.inputargs = loop.inputargs
         loop.preamble.token = LoopToken()
         ops = '''
         [p1, i1, i4]
         setfield_gc(p1, i1, descr=valuedescr)
-        i3 = call_pure(42, p1, descr=plaincalldescr)
+        i3 = call_pure(p1, descr=plaincalldescr)
         setfield_gc(p1, i3, descr=valuedescr)
         jump(p1, i4, i3)
         '''
         ops = '''
         [p1, i1, i4]
         setfield_gc(p1, i1, descr=valuedescr)
-        i3 = call_pure(42, p1, descr=plaincalldescr)
+        i3 = call_pure(p1, descr=plaincalldescr)
         setfield_gc(p1, i1, descr=valuedescr)
         jump(p1, i4, i3)
         '''
         # the result of the call, recorded as the first arg), or turned into
         # a regular CALL.
         # XXX can this test be improved with unrolling?
+        arg_consts = [ConstInt(i) for i in (123456, 4, 5, 6)]
+        call_pure_results = {tuple(arg_consts): ConstInt(42)}
         ops = '''
         [i0, i1, i2]
         escape(i1)
         escape(i2)
-        i3 = call_pure(42, 123456, 4, 5, 6, descr=plaincalldescr)
-        i4 = call_pure(43, 123456, 4, i0, 6, descr=plaincalldescr)
+        i3 = call_pure(123456, 4, 5, 6, descr=plaincalldescr)
+        i4 = call_pure(123456, 4, i0, 6, descr=plaincalldescr)
         jump(i0, i3, i4)
         '''
         preamble = '''
         i4 = call(123456, 4, i0, 6, descr=plaincalldescr)
         jump(i0, i4)
         '''
-        self.optimize_loop(ops, expected, preamble)
+        self.optimize_loop(ops, expected, preamble, call_pure_results)
 
     # ----------
 

File pypy/jit/metainterp/test/test_slist.py

         assert res == 2
 
     def test_make_list(self):
-        from pypy.jit.metainterp import simple_optimize
         myjitdriver = JitDriver(greens = [], reds = ['n', 'lst'])
         def f(n):
             lst = None

File pypy/jit/metainterp/test/test_tl.py

     def test_tl_call(self, listops=True, policy=None):
         from pypy.jit.tl.tl import interp
         from pypy.jit.tl.tlopcode import compile
-        from pypy.jit.metainterp import simple_optimize
 
         code = compile('''
               PUSHARG

File pypy/module/_stackless/test/test_composable_coroutine.py

         space = gettestobjspace(usemodules=('_stackless',))
         cls.space = space
 
-        cls.w_generator = space.appexec([], """():
+        cls.w_generator_ = space.appexec([], """():
             import _stackless
 
             generators_costate = _stackless.usercostate()
 
             generator.Yield = Yield
             generator._costate = generators_costate
-            return generator
+            return (generator,)
         """)
 
     def test_simple_costate(self):
         assert result == [co]
 
     def test_generator(self):
-        generator = self.generator
+        generator, = self.generator_
 
         def squares(n):
             for i in range(n):
         """
 
         import _stackless
-        generator = self.generator
+        generator, = self.generator_
 
         # you can see how it fails if we don't have two different costates
         # by setting compute_costate to generator._costate instead

File pypy/module/test_lib_pypy/test_distributed/test_distributed.py

     def setup_class(cls):
         #cls.space = gettestobjspace(**{"objspace.std.withtproxy": True,
         #    "usemodules":("_stackless",)})
-        cls.w_test_env = cls.space.appexec([], """():
+        cls.w_test_env_ = cls.space.appexec([], """():
         from distributed import test_env
-        return test_env
+        return (test_env,)
         """)
         cls.reclimit = sys.getrecursionlimit()
         sys.setrecursionlimit(100000)
         def f(x, y):
             return x + y
         
-        protocol = self.test_env({"f": f})
+        protocol = self.test_env_[0]({"f": f})
         fun = protocol.get_remote("f")
         assert fun(2, 3) == 5
 
         def f(x):
             return x + g()
         
-        protocol = self.test_env({"f":f})
+        protocol = self.test_env_[0]({"f":f})
         fun = protocol.get_remote("f")
         assert fun(8) == 16
     
     def test_remote_dict(self):
         #skip("Land of infinite recursion")
         d = {'a':3}
-        protocol = self.test_env({'d':d})
+        protocol = self.test_env_[0]({'d':d})
         xd = protocol.get_remote('d')
         #assert d['a'] == xd['a']
         assert d.keys() == xd.keys()
                 return self.x + 8
         a = A(3)
         
-        protocol = self.test_env({'a':a})
+        protocol = self.test_env_[0]({'a':a})
         xa = protocol.get_remote("a")
         assert xa.x == 3
         assert len(xa) == 11
         
         a = A()
         
-        protocol = self.test_env({'a':a})
+        protocol = self.test_env_[0]({'a':a})
         xa = protocol.get_remote('a')
         assert xa.__class__.__doc__ == 'xxx'
         assert xa.meth(x) == 4
                 return [1,2,3]
         
         a = A()
-        protocol = self.test_env({'a': a})
+        protocol = self.test_env_[0]({'a': a})
         xa = protocol.get_remote('a')
         xa.meth(B())
         assert xa.perform() == 4
         #skip("Land of infinite recursion")
         import sys
         f = sys._getframe()
-        protocol = self.test_env({'f':f})
+        protocol = self.test_env_[0]({'f':f})
         xf = protocol.get_remote('f')
         assert f.f_globals.keys() == xf.f_globals.keys()
         assert f.f_locals.keys() == xf.f_locals.keys()
         def raising():
             1/0
         
-        protocol = self.test_env({'raising':raising})
+        protocol = self.test_env_[0]({'raising':raising})
         xr = protocol.get_remote('raising')
         try:
             xr()
                 return cls.z
 
         a = A()
-        protocol = self.test_env({'a':a})
+        protocol = self.test_env_[0]({'a':a})
         xa = protocol.get_remote("a")
         res = xa.x()
         assert res == 8
                 assert type(self) is tp
 
         a = A()
-        protocol = self.test_env({'a':a, 'A':A})
+        protocol = self.test_env_[0]({'a':a, 'A':A})
         xa = protocol.get_remote('a')
         xA = protocol.get_remote('A')
         xa.m(xA)
             def x(self):
                 return self.y
 
-        protocol = self.test_env({'C':C})
+        protocol = self.test_env_[0]({'C':C})
         xC = protocol.get_remote('C')
         xc = xC(3)
         res = xc.x()
         skip("Fix me some day maybe")
         import sys
 
-        protocol = self.test_env({'sys':sys})
+        protocol = self.test_env_[0]({'sys':sys})
         s = protocol.get_remote('sys')
         l = dir(s)
         assert l
 
     def test_remote_file_access(self):
         skip("Descriptor logic seems broken")
-        protocol = self.test_env({'f':open})
+        protocol = self.test_env_[0]({'f':open})
         xf = protocol.get_remote('f')
         data = xf('/etc/passwd').read()
         assert data
 
         x = X()
 
-        protocol = self.test_env({'x':x})
+        protocol = self.test_env_[0]({'x':x})
         xx = protocol.get_remote('x')
         assert xx.x == 3
     
             pass
 
         y = Y()
-        protocol = self.test_env({'y':y, 'X':X})
+        protocol = self.test_env_[0]({'y':y, 'X':X})
         xy = protocol.get_remote('y')
         xX = protocol.get_remote('X')
         assert isinstance(xy, xX)
 
     def test_key_error(self):
         from distributed import ObjectNotFound
-        protocol = self.test_env({})
+        protocol = self.test_env_[0]({})
         raises(ObjectNotFound, "protocol.get_remote('x')")
 
     def test_list_items(self):
-        protocol = self.test_env({'x':3, 'y':8})
+        protocol = self.test_env_[0]({'x':3, 'y':8})
         assert sorted(protocol.remote_keys()) == ['x', 'y']
 

File pypy/objspace/std/objecttype.py

     return w_obj
 
 def descr__init__(space, w_obj, __args__):
+    # don't allow arguments unless __new__ is overridden
     w_type = space.type(w_obj)
     w_parent_new, _ = w_type.lookup_where('__new__')
-    w_parent_init, _ = w_type.lookup_where('__init__')
-    try:
-        __args__.fixedunpack(0)
-    except ValueError:
-        if w_parent_new is not space.w_object and w_parent_init is not space.w_object:
-            space.warn("object.__init__() takes no parameters", space.w_DeprecationWarning)
-        elif w_parent_new is space.w_object or w_parent_init is not space.w_object:
+    if w_parent_new is space.w_object:
+        try:
+            __args__.fixedunpack(0)
+        except ValueError:
             raise OperationError(space.w_TypeError,
-                space.wrap("object.__init__() takes no parameters")
-            )
-
+                space.wrap("object.__init__() takes no parameters"))
 
 
 @gateway.unwrap_spec(proto=int)

File pypy/objspace/std/test/test_obj.py

             def __init__(self):
                 super(B, self).__init__(a=3)
 
-        with warnings.catch_warnings(record=True) as log:
-            warnings.simplefilter("always", DeprecationWarning)
-            B()
-        assert len(log) == 1
-        assert log[0].message.args == ("object.__init__() takes no parameters",)
-        assert type(log[0].message) is DeprecationWarning
+        #-- pypy doesn't raise the DeprecationWarning
+        #with warnings.catch_warnings(record=True) as log:
+        #    warnings.simplefilter("always", DeprecationWarning)
+        #    B()
+        #assert len(log) == 1
+        #assert log[0].message.args == ("object.__init__() takes no parameters",)
+        #assert type(log[0].message) is DeprecationWarning

File pypy/rlib/rerased.py

         bk = self.rtyper.annotator.bookkeeper
         s_obj = value._identity.get_input_annotation(bk)
         r_obj = self.rtyper.getrepr(s_obj)
+        if r_obj.lowleveltype is lltype.Void:
+            return lltype.nullptr(self.lowleveltype.TO)
         v = r_obj.convert_const(value._x)
         return lltype.cast_opaque_ptr(self.lowleveltype, v)

File pypy/rlib/test/test_rerased.py

     x = interpret(f, [])
     assert x == 16 + 42 + 1
 
+def test_prebuilt_erased_in_instance():
+    erase_empty, unerase_empty = new_erasing_pair("empty")
+    class FakeList(object):
+        pass
+
+    x1 = X()
+    x1.foobar = 42
+    l1 = FakeList()
+    l1.storage = eraseX(x1)
+    l2 = FakeList()
+    l2.storage = erase_empty(None)
+
+    def f():
+        #assert is_integer(e1)
+        #assert not is_integer(e2)
+        x1.foobar += 1
+        x2 = uneraseX(l1.storage).foobar + (unerase_empty(l2.storage) is None)
+        return x2
+    x = interpret(f, [])
+    assert x == 43 + True
+
+
 def test_overflow():
     def f(i):
         try:

File pypy/rpython/lltypesystem/opimpl.py

     assert isinstance(y, int)
     return x | y
 
+def op_int_xor(x, y):
+    # used in computing hashes
+    if isinstance(x, AddressAsInt): x = llmemory.cast_adr_to_int(x.adr)
+    if isinstance(y, AddressAsInt): y = llmemory.cast_adr_to_int(y.adr)
+    assert isinstance(x, int)
+    assert isinstance(y, int)
+    return x ^ y
+
 def op_int_mul(x, y):
     assert isinstance(x, (int, llmemory.AddressOffset))
     assert isinstance(y, (int, llmemory.AddressOffset))

File pypy/tool/jitlogparser/parser.py

     # factory method
     TraceForOpcode = TraceForOpcode
 
-    def __init__(self, chunks, path, storage, inputargs):
+    def __init__(self, chunks, path, storage, inputargs=''):
         self.path = path
         self.inputargs = inputargs
         self.chunks = chunks
                 if bc.inline_level is not None and bc.inline_level + 1 != len(stack):
                     if bc.inline_level < len(stack):
                         last = stack.pop()
-                        stack[-1].append(cls(last, getpath(stack), storage, inputargs))
+                        stack[-1].append(cls(last, getpath(stack), storage))
                     else:
                         stack.append([])
             stack[-1].append(bc)