[pypy-commit] pypy result-in-resops: start cleaning up storing of resops in dictionaries. start with declaring __hash__ illegal

fijal noreply at buildbot.pypy.org
Sat Aug 25 16:51:39 CEST 2012


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: result-in-resops
Changeset: r56851:08c043d9900b
Date: 2012-08-25 16:51 +0200
http://bitbucket.org/pypy/pypy/changeset/08c043d9900b/

Log:	start cleaning up storing of resops in dictionaries. start with
	declaring __hash__ illegal

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
@@ -119,7 +119,7 @@
     part.resume_at_jump_descr = resume_at_jump_descr
     part.operations = ([create_resop(rop.LABEL, None, inputargs,
                                      descr=TargetToken(jitcell_token))] +
-                       [h_ops[i].clone() for i in range(start, len(h_ops))]+
+                       [h_ops[i] for i in range(start, len(h_ops))]+
                        [create_resop(rop.LABEL, None, jumpargs,
                                      descr=jitcell_token)])
 
@@ -476,8 +476,6 @@
     _counters = None    # they get stored in _counters then.
 
     # this class also gets the following attributes stored by resume.py code
-    rd_snapshot = None
-    rd_frame_info_list = None
     rd_numb = lltype.nullptr(NUMBERING)
     rd_consts = None
     rd_virtuals = None
@@ -610,31 +608,11 @@
                                self, inputargs, new_loop.operations,
                                new_loop.original_jitcell_token)
 
-    def copy_all_attributes_into(self, res):
-        # XXX a bit ugly to have to list them all here
-        res.rd_snapshot = self.rd_snapshot
-        res.rd_frame_info_list = self.rd_frame_info_list
-        res.rd_numb = self.rd_numb
-        res.rd_consts = self.rd_consts
-        res.rd_virtuals = self.rd_virtuals
-        res.rd_pendingfields = self.rd_pendingfields
-
-    def _clone_if_mutable(self):
-        res = ResumeGuardDescr()
-        self.copy_all_attributes_into(res)
-        return res
-
 class ResumeGuardNotInvalidated(ResumeGuardDescr):
-    def _clone_if_mutable(self):
-        res = ResumeGuardNotInvalidated()
-        self.copy_all_attributes_into(res)
-        return res
+    pass
 
 class ResumeAtPositionDescr(ResumeGuardDescr):
-    def _clone_if_mutable(self):
-        res = ResumeAtPositionDescr()
-        self.copy_all_attributes_into(res)
-        return res
+    pass
 
 class ResumeGuardForcedDescr(ResumeGuardDescr):
 
@@ -712,12 +690,6 @@
                 assert 0, "not found: %r" % (key,)
         return data
 
-    def _clone_if_mutable(self):
-        res = ResumeGuardForcedDescr(self.metainterp_sd,
-                                     self.jitdriver_sd)
-        self.copy_all_attributes_into(res)
-        return res
-
 
 class AbstractResumeGuardCounters(object):
     # Completely custom algorithm for now: keep 5 pairs (value, counter),
@@ -813,7 +785,7 @@
     # Attempt to use optimize_bridge().  This may return None in case
     # it does not work -- i.e. none of the existing old_loop_tokens match.
     new_trace = create_empty_loop(metainterp)
-    new_trace.inputargs = inputargs = metainterp.history.inputargs[:]
+    new_trace.inputargs = metainterp.history.inputargs[:]
 
     new_trace.operations = metainterp.history.operations
     new_trace.resume_at_jump_descr = resume_at_jump_descr
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -736,12 +736,10 @@
                 if hasattr(op.getdescr(), '_debug_suboperations'):
                     ops = op.getdescr()._debug_suboperations
                     TreeLoop.check_consistency_of_branch(ops, seen.copy())
-                for failarg in op.getfailargs() or []:
+                for failarg in op.get_extra("failargs") or []:
                     if failarg is not None:
                         assert not failarg.is_constant()
                         assert failarg in seen
-            else:
-                assert op.getfailargs() is None
             seen[op] = True
             if op.getopnum() == rop.LABEL:
                 inputargs = op.getarglist()
diff --git a/pypy/jit/metainterp/logger.py b/pypy/jit/metainterp/logger.py
--- a/pypy/jit/metainterp/logger.py
+++ b/pypy/jit/metainterp/logger.py
@@ -14,6 +14,7 @@
         self.guard_number = guard_number
 
     def log_loop(self, inputargs, operations, number=0, type=None, ops_offset=None, name=''):
+        return
         if type is None:
             debug_start("jit-log-noopt-loop")
             logops = self._log_operations(inputargs, operations, ops_offset)
@@ -31,6 +32,7 @@
         return logops
 
     def log_bridge(self, inputargs, operations, number=-1, ops_offset=None):
+        return
         if number == -1:
             debug_start("jit-log-noopt-bridge")
             logops = self._log_operations(inputargs, operations, ops_offset)
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
@@ -178,10 +178,27 @@
     pc = 0
     opnum = 0
 
+    extras = None
+    # ResOps are immutable, however someone can store a temporary
+    # extra mutable stuff here, in the extras field. Other fields (including
+    # descr) should be deeply immutable. This replaces various dictionaries
+    # that has been previously used.
+
+    @specialize.arg(1)
+    def get_extra(self, key):
+        return getattr(self, key)
+
+    @specialize.arg(1)
+    def set_extra(self, key, value):
+        setattr(self, key, value)
+
     @classmethod
     def getopnum(cls):
         return cls.opnum
 
+    def __hash__(self):
+        raise Exception("Should not hash resops, use get/set extra instead")
+
     # methods implemented by the arity mixins
     # ---------------------------------------
 
@@ -198,25 +215,12 @@
     def numargs(self):
         raise NotImplementedError
 
-
-    # methods implemented by GuardResOp
-    # ---------------------------------
-
-    def getfailargs(self):
-        return None
-
-    def setfailargs(self, fail_args):
-        raise NotImplementedError
-
     # methods implemented by ResOpWithDescr
     # -------------------------------------
 
     def getdescr(self):
         return None
 
-    def getdescrclone(self):
-        return None
-
     def setdescr(self, descr):
         raise NotImplementedError
 
@@ -418,9 +422,6 @@
     def getdescr(self):
         return self._descr
 
-    def getdescrclone(self):
-        return self._descr.clone_if_mutable()
-
     def setdescr(self, descr):
         # for 'call', 'new', 'getfield_gc'...: the descr is a prebuilt
         # instance provided by the backend holding details about the type
@@ -444,15 +445,25 @@
 
 class GuardResOp(ResOpWithDescr):
 
-    _fail_args = None
+    # gathered during tracing
+    _rd_snapshot = None
+    _rd_frame_info_list = None
 
-    def getfailargs(self):
-        return self._fail_args
+    def get_rd_snapshot(self):
+        return self._rd_snapshot
 
-    def setfailargs(self, fail_args):
-        if self._fail_args is not None:
-            raise Exception("Setting fail args on a resop already constructed!")
-        self._fail_args = fail_args
+    def set_rd_snapshot(self, rd_snapshot):
+        if self._rd_snapshot is not None:
+            raise Exception("rd_snapshot already set")
+        self._rd_snapshot = rd_snapshot
+
+    def get_rd_frame_info_list(self):
+        return self._rd_frame_info_list
+
+    def set_rd_frame_info_list(self, rd_frame_info_list):
+        if self._rd_frame_info_list is not None:
+            raise Exception("rd_frame_info_list already set")
+        self._rd_frame_info_list = rd_frame_info_list
 
 # ============
 # arity mixins
@@ -478,24 +489,12 @@
     def foreach_arg(self, func):
         pass
 
-    def clone(self):
-        r = create_resop_0(self.opnum, self.getresult(), self.getdescrclone())
-        if self.is_guard():
-            r.setfailargs(self.getfailargs())
-        return r
-
     @specialize.arg(1)
     def copy_and_change(self, newopnum, descr=None):
-        r = create_resop_0(newopnum, self.getresult(),
-                           descr or self.getdescrclone())
-        if r.is_guard():
-            r.setfailargs(self.getfailargs())
-            assert self.is_guard()
-        return r
+        return create_resop_0(newopnum, self.getresult(),
+                              descr or self.getdescr())
 
-    def copy_if_modified_by_optimization(self, opt, force_copy=False):
-        if force_copy:
-            return self.clone()
+    def copy_if_modified_by_optimization(self, opt):
         return self
 
 class UnaryOp(object):
@@ -524,29 +523,18 @@
     def foreach_arg(self, func):
         func(self.getopnum(), 0, self._arg0)
 
-    def clone(self):
-        r = create_resop_1(self.opnum, self.getresult(), self._arg0,
-                              self.getdescrclone())
-        if self.is_guard():
-            r.setfailargs(self.getfailargs())
-        return r
-
     @specialize.argtype(1)
-    def copy_if_modified_by_optimization(self, opt, force_copy=False):
+    def copy_if_modified_by_optimization(self, opt):
         new_arg = opt.get_value_replacement(self._arg0)
-        if not force_copy and new_arg is None:
+        if new_arg is None:
             return self
         return create_resop_1(self.opnum, self.getresult(), new_arg,
-                              self.getdescrclone())
+                              self.getdescr())
 
     @specialize.arg(1)
     def copy_and_change(self, newopnum, arg0=None, descr=None):
-        r = create_resop_1(newopnum, self.getresult(), arg0 or self._arg0,
-                           descr or self.getdescrclone())
-        if r.is_guard():
-            r.setfailargs(self.getfailargs())
-            assert self.is_guard()
-        return r
+        return create_resop_1(newopnum, self.getresult(), arg0 or self._arg0,
+                              descr or self.getdescr())
 
 class BinaryOp(object):
     _mixin_ = True
@@ -578,33 +566,22 @@
         func(self.getopnum(), 0, self._arg0)
         func(self.getopnum(), 1, self._arg1)
 
-    def clone(self):
-        r = create_resop_2(self.opnum, self.getresult(), self._arg0, self._arg1,
-                           self.getdescrclone())
-        if self.is_guard():
-            r.setfailargs(self.getfailargs())
-        return r
-
     @specialize.argtype(1)
-    def copy_if_modified_by_optimization(self, opt, force_copy=False):
+    def copy_if_modified_by_optimization(self, opt):
         new_arg0 = opt.get_value_replacement(self._arg0)
         new_arg1 = opt.get_value_replacement(self._arg1)
-        if not force_copy and new_arg0 is None and new_arg1 is None:
+        if new_arg0 is None and new_arg1 is None:
             return self
         return create_resop_2(self.opnum, self.getresult(),
                               new_arg0 or self._arg0,
                               new_arg1 or self._arg1,
-                              self.getdescrclone())
+                              self.getdescr())
 
     @specialize.arg(1)
     def copy_and_change(self, newopnum, arg0=None, arg1=None, descr=None):
-        r = create_resop_2(newopnum, self.getresult(), arg0 or self._arg0,
-                           arg1 or self._arg1,
-                           descr or self.getdescrclone())
-        if r.is_guard():
-            r.setfailargs(self.getfailargs())
-            assert self.is_guard()
-        return r
+        return create_resop_2(newopnum, self.getresult(), arg0 or self._arg0,
+                              arg1 or self._arg1,
+                              descr or self.getdescr())
 
 class TernaryOp(object):
     _mixin_ = True
@@ -640,32 +617,26 @@
         func(self.getopnum(), 1, self._arg1)
         func(self.getopnum(), 2, self._arg2)
 
-    def clone(self):
-        assert not self.is_guard()
-        return create_resop_3(self.opnum, self.getresult(), self._arg0,
-                              self._arg1, self._arg2, self.getdescrclone())
-
     @specialize.argtype(1)
-    def copy_if_modified_by_optimization(self, opt, force_copy=False):
+    def copy_if_modified_by_optimization(self, opt):
         assert not self.is_guard()
         new_arg0 = opt.get_value_replacement(self._arg0)
         new_arg1 = opt.get_value_replacement(self._arg1)
         new_arg2 = opt.get_value_replacement(self._arg2)
-        if (not force_copy and new_arg0 is None and new_arg1 is None and
-            new_arg2 is None):
+        if new_arg0 is None and new_arg1 is None and new_arg2 is None:
             return self
         return create_resop_3(self.opnum, self.getresult(),
                               new_arg0 or self._arg0,
                               new_arg1 or self._arg1,
                               new_arg2 or self._arg2,
-                              self.getdescrclone())
+                              self.getdescr())
 
     @specialize.arg(1)
     def copy_and_change(self, newopnum, arg0=None, arg1=None, arg2=None,
                         descr=None):
         r = create_resop_3(newopnum, self.getresult(), arg0 or self._arg0,
                            arg1 or self._arg1, arg2 or self._arg2,
-                           descr or self.getdescrclone())
+                           descr or self.getdescr())
         assert not r.is_guard()
         return r
 
@@ -692,17 +663,9 @@
         for i, arg in enumerate(self._args):
             func(self.getopnum(), i, arg)
 
-    def clone(self):
-        assert not self.is_guard()
-        return create_resop(self.opnum, self.getresult(), self._args[:],
-                              self.getdescrclone())
-
     @specialize.argtype(1)
-    def copy_if_modified_by_optimization(self, opt, force_copy=False):
-        if force_copy:
-            newargs = []
-        else:
-            newargs = None
+    def copy_if_modified_by_optimization(self, opt):
+        newargs = None
         for i, arg in enumerate(self._args):
             new_arg = opt.get_value_replacement(arg)
             if new_arg is not None:
@@ -717,13 +680,13 @@
         if newargs is None:
             return self
         return create_resop(self.opnum, self.getresult(),
-                            newargs, self.getdescrclone())
+                            newargs, self.getdescr())
 
     @specialize.arg(1)
     def copy_and_change(self, newopnum, newargs=None, descr=None):
         r = create_resop(newopnum, self.getresult(),
                          newargs or self.getarglist(),
-                         descr or self.getdescrclone())
+                         descr or self.getdescr())
         assert not r.is_guard()
         return r
 
diff --git a/pypy/jit/metainterp/test/test_resoperation.py b/pypy/jit/metainterp/test/test_resoperation.py
--- a/pypy/jit/metainterp/test/test_resoperation.py
+++ b/pypy/jit/metainterp/test/test_resoperation.py
@@ -106,40 +106,6 @@
     assert not rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox('a'),
                                   FakeBox('b')).can_malloc()
 
-def test_clone():
-    mydescr = AbstractDescr()
-    op = rop.create_resop_0(rop.rop.GUARD_NO_EXCEPTION, None, descr=mydescr)
-    op.setfailargs([3])
-    op2 = op.clone()
-    assert not op2 is op
-    assert op2.getresult() is None
-    assert op2.getfailargs() is op.getfailargs()
-    op = rop.create_resop_1(rop.rop.INT_IS_ZERO, 1, FakeBox('a'))
-    op2 = op.clone()
-    assert op2 is not op
-    assert op2._arg0 == FakeBox('a')
-    assert op2.getint() == 1
-    op = rop.create_resop_2(rop.rop.INT_ADD, 1, FakeBox('a'), FakeBox('b'))
-    op2 = op.clone()
-    assert op2 is not op
-    assert op2._arg0 == FakeBox('a')
-    assert op2._arg1 == FakeBox('b')
-    assert op2.getint() == 1
-    op = rop.create_resop_3(rop.rop.STRSETITEM, None, FakeBox('a'),
-                            FakeBox('b'), FakeBox('c'))
-    op2 = op.clone()
-    assert op2 is not op
-    assert op2._arg0 == FakeBox('a')
-    assert op2._arg1 == FakeBox('b')
-    assert op2._arg2 == FakeBox('c')
-    assert op2.getresult() is None
-    op = rop.create_resop(rop.rop.CALL_i, 13, [FakeBox('a'), FakeBox('b'),
-                            FakeBox('c')], descr=mydescr)
-    op2 = op.clone()
-    assert op2 is not op
-    assert op2._args == [FakeBox('a'), FakeBox('b'), FakeBox('c')]
-    assert op2.getint() == 13
-
 def test_repr():
     mydescr = FakeDescr()
     op = rop.create_resop_0(rop.rop.GUARD_NO_EXCEPTION, None, descr=mydescr)
@@ -215,3 +181,8 @@
     assert op2.getarglist() == ['a', 'b', 'c']
     op2 = op.copy_and_change(rop.rop.CALL_i, [FakeBox('a')])
     assert op2.getarglist() == ['a']
+
+def test_get_set_extra():
+    op = rop.create_resop_2(rop.rop.INT_ADD, 3, FakeBox("a"), FakeBox("b"))
+    op.set_extra("x", 2)
+    assert op.get_extra("x") == 2


More information about the pypy-commit mailing list