Hakan Ardo avatar Hakan Ardo committed bb28cf1

Be more consistant on not includinging null-valued fields in VirtualState

Comments (0)

Files changed (2)

pypy/jit/metainterp/optimizeopt/virtualstate.py

     def debug_header(self, indent):
         raise NotImplementedError
 
+    def kill_null_fields(self):
+        pass
+
+    def is_null(self):
+        return False
+
 
 class AbstractVirtualStructStateInfo(AbstractVirtualStateInfo):
     def __init__(self, fielddescrs):
-        self.fielddescrs = fielddescrs
+        self.fielddescrs = fielddescrs[:]
 
     def generalization_of(self, other, renum, bad):
         assert self.position != -1
 
     def make_guardable_generalization_of(self, other, value, optimizer):
         if not self._generalization_of(other):
-            raise InvalidLoop
+            raise InvalidLoop('Cant combine virtuals of different classes.')
         assert isinstance(other, AbstractVirtualStructStateInfo)
         assert len(self.fielddescrs) == len(self.fieldstate)
         assert len(other.fielddescrs) == len(other.fieldstate)
         assert isinstance(value, virtualize.AbstractVirtualStructValue)
         if len(self.fielddescrs) != len(other.fielddescrs):
-            raise InvalidLoop
+            raise InvalidLoop('Cant combine virtuals with different numbers of fields.')
         for i in range(len(self.fielddescrs)):
             if other.fielddescrs[i] is not self.fielddescrs[i]:
-                raise InvalidLoop
+                raise InvalidLoop('Cant combine virtuals with different fields.')
             new_field_value = self.fieldstate[i].make_guardable_generalization_of(other.fieldstate[i],
                                                                         value.getfield(self.fielddescrs[i], None),
                                                                         optimizer)
             if new_field_value:
                 value.setfield(self.fielddescrs[i], new_field_value)
-            #FIXME: default value of getfield
 
-
-
+    def kill_null_fields(self):
+        assert len(self.fielddescrs) == len(self.fieldstate)
+        for i in reversed(range(len(self.fielddescrs))):
+            if self.fieldstate[i].is_null():
+                del self.fieldstate[i]
+                del self.fielddescrs[i]
 
     def _generalization_of(self, other):
         raise NotImplementedError
     def debug_header(self, indent):
         debug_print(indent + 'VArrayStructStateInfo(%d):' % self.position)
 
-
 class NotVirtualStateInfo(AbstractVirtualStateInfo):
     def __init__(self, value, is_opaque=False):
         self.is_opaque = is_opaque
         debug_print(indent + mark + 'NotVirtualInfo(%d' % self.position +
                     ', ' + l + ', ' + self.intbound.__repr__() + lb + ')')
 
+    def is_null(self):
+        if self.level == LEVEL_CONSTANT:
+            box = self.constbox
+            assert isinstance(box, Const)
+            return not box.nonnull()
+        return False
+
 class VirtualState(object):
     def __init__(self, state):
         self.state = state
                 self.info[box] = info = value.make_virtual_info(self, None)
                 flds = self.fieldboxes[box]
                 info.fieldstate = [self.state(b) for b in flds]
+                info.kill_null_fields()
             else:
                 self.info[box] = info = self.make_not_virtual(value)
         return info

pypy/jit/metainterp/test/test_ajit.py

         self.check_resops(new_with_vtable=0)
         self.check_retraced_simple_loop(2, int_mul=0)
 
-    def test_nested_loops_boxed(self):
+    def test_nested_loops_boxed_one(self):
         class Int(object):
             def __init__(self, val):
                 self.val = val
                 if op == 'i':
                     i = Int(1)
                 elif op == 'j':
-                    j = Int(1) # FIXME: test with 0 aswell
+                    j = Int(1)
+                elif op == '+':
+                    sa += 3 * i.val + j.val + 5 * c.val
+                elif op == 'a':
+                    i = Int(i.val + 1)
+                elif op == 'b':
+                    j = Int(j.val + 1)
+                elif op == 'J':
+                    if j.val < n:
+                        pc -= 2
+                        myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+                        continue
+                elif op == 'I':
+                    if i.val < n:
+                        pc -= 5
+                        myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+                        continue
+                pc += 1
+            return sa
+        res = self.meta_interp(f, [10])
+        assert res == f(10)
+        self.check_resops(new_with_vtable=0)
+        self.check_retraced_simple_loop(2, getfield_gc=0, int_mul=0)
+
+    def test_nested_loops_boxed_zero(self):
+        class Int(object):
+            def __init__(self, val):
+                self.val = val
+        bytecode = "iajb+JI"
+        def get_printable_location(i):
+            return "%d: %s" % (i, bytecode[i])
+        myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'sa', 'c', 'i', 'j'],
+                                get_printable_location=get_printable_location)
+        def f(n):
+            pc = sa = 0
+            i = j = Int(0)
+            c = Int(n)
+            while pc < len(bytecode):
+                myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i, j=j, c=c)
+                op = bytecode[pc]
+                if op == 'i':
+                    i = Int(0)
+                elif op == 'j':
+                    j = Int(0)
                 elif op == '+':
                     sa += 3 * i.val + j.val + 5 * c.val
                 elif op == 'a':
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.