[pypy-svn] r61870 - in pypy/branch/pyjitpl5/pypy/jit/metainterp: . test

fijal at codespeak.net fijal at codespeak.net
Sat Feb 14 12:08:53 CET 2009


Author: fijal
Date: Sat Feb 14 12:08:52 2009
New Revision: 61870

Modified:
   pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py
   pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py
Log:
support for virtual lists. There are still two quirks, but I'll address
them later


Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/optimize.py	Sat Feb 14 12:08:52 2009
@@ -9,7 +9,8 @@
                                           NotSpecNode,
                                           DelayedSpecNode,
                                           SpecNodeWithBox,
-                                          DelayedListSpecNode)
+                                          DelayedListSpecNode,
+                                          VirtualListSpecNode)
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.jit.metainterp.codewriter import ListDescr
 
@@ -46,13 +47,25 @@
             virtual = instnode.virtual
             virtualized = instnode.virtualized
         if virtual:
-            alloc_offset = len(self.allocations)
-            self.allocations.append(instnode.cls.source.getint())
+            if isinstance(instnode.cls.source, ListDescr):
+                ld = instnode.cls.source
+                assert isinstance(ld, ListDescr)
+                alloc_offset = len(self.list_allocations)
+                malloc_func = ld.malloc_func
+                # XXX grab from somewhere the list length
+                self.list_allocations.append((malloc_func, 13))
+            else:
+                alloc_offset = len(self.allocations)
+                self.allocations.append(instnode.cls.source.getint())
             res = alloc_offset
             memo[box] = res
             for ofs, node in instnode.curfields.items():
                 num = self.deal_with_box(node.source, nodes, liveboxes, memo)
-                self.setfields.append((alloc_offset, ofs, num))
+                if isinstance(instnode.cls.source, ListDescr):
+                    ld = instnode.cls.source
+                    self.setitems.append((ld.setfunc, alloc_offset, ofs, num))
+                else:
+                    self.setfields.append((alloc_offset, ofs, num))
         elif virtualized:
             res = ~len(liveboxes)
             memo[box] = res
@@ -116,8 +129,6 @@
                 return NotSpecNode()
             return FixedClassSpecNode(known_class)
         if not other.escaped:
-            # XXX write a spec node
-            assert not isinstance(known_class, ListDescr)
             fields = []
             lst = other.curfields.items()
             lst.sort()
@@ -128,6 +139,8 @@
                     self.origfields[ofs] = InstanceNode(node.source.clonebox())
                     specnode = NotSpecNode()
                 fields.append((ofs, specnode))
+            if isinstance(known_class, ListDescr):
+                return VirtualListSpecNode(known_class, fields)
             return VirtualInstanceSpecNode(known_class, fields)
         if not other.virtualized and self.expanded_fields:
             fields = []
@@ -634,6 +647,7 @@
 
 def rebuild_boxes_from_guard_failure(guard_op, history, boxes_from_frame):
     allocated_boxes = []
+    allocated_lists = []
     storage = guard_op.storage_info
     for vtable in storage.allocations:
         sizebox = ConstInt(type_cache.class_size[vtable])
@@ -642,6 +656,12 @@
                                                [sizebox, vtablebox],
                                                'ptr', False)
         allocated_boxes.append(instbox)
+    for malloc_func, lgt in storage.list_allocations:
+        sizebox = ConstInt(lgt)
+        [listbox] = history.execute_and_record('newlist',
+                                        [malloc_func, sizebox],
+                                               'ptr', False)
+        allocated_lists.append(listbox)
     for index_in_alloc, ofs, index_in_arglist in storage.setfields:
         fieldbox = box_from_index(allocated_boxes, boxes_from_frame,
                                   index_in_arglist)
@@ -653,7 +673,7 @@
     for setfunc, index_in_alloc, ofs, index_in_arglist in storage.setitems:
         itembox = box_from_index(allocated_boxes, boxes_from_frame,
                                  index_in_arglist)
-        box = box_from_index(allocated_boxes, boxes_from_frame,
+        box = box_from_index(allocated_lists, boxes_from_frame,
                              index_in_alloc)
         history.execute_and_record('setitem',
                                    [setfunc, box, ConstInt(ofs), itembox],
@@ -663,6 +683,7 @@
         if index < 0:
             newboxes.append(boxes_from_frame[~index])
         else:
+            # XXX allocated_boxes vs allocated_lists
             newboxes.append(allocated_boxes[index])
 
     return newboxes

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/specnode.py	Sat Feb 14 12:08:52 2009
@@ -193,14 +193,33 @@
             return False
         return SpecNodeWithFields.equals(self, other)
 
-class VirtualInstanceSpecNode(SpecNodeWithFields):
+class VirtualSpecNode(SpecNodeWithFields):
 
     def mutate_nodes(self, instnode):
         SpecNodeWithFields.mutate_nodes(self, instnode)
         instnode.virtual = True
 
+class VirtualInstanceSpecNode(VirtualSpecNode):
+
     def equals(self, other):
         if not isinstance(other, VirtualInstanceSpecNode):
             return False
         return SpecNodeWithFields.equals(self, other)
 
+class VirtualListSpecNode(VirtualSpecNode):
+
+    def equals(self, other):
+        if not isinstance(other, VirtualListSpecNode):
+            return False
+        return SpecNodeWithFields.equals(self, other)
+    
+    def extract_runtime_data(self, cpu, valuebox, resultlist):
+        from pypy.jit.metainterp.codewriter import ListDescr
+        
+        for ofs, subspecnode in self.fields:
+            cls = self.known_class
+            assert isinstance(cls, ListDescr)
+            fieldbox = cpu.execute_operation('getitem',
+                                    [cls.getfunc, valuebox, ConstInt(ofs)],
+                                             cls.tp)
+            subspecnode.extract_runtime_data(cpu, fieldbox, resultlist)

Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py	(original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_vlist.py	Sat Feb 14 12:08:52 2009
@@ -25,6 +25,22 @@
         self.check_loops(int_sub=1)
         self.check_all_virtualized()
 
+    def test_list_pass_around(self):
+        jitdriver = JitDriver(greens = [], reds = ['n', 'l'])
+        def f(n):
+            l = [3]
+            while n > 0:
+                jitdriver.can_enter_jit(n=n, l=l)
+                jitdriver.jit_merge_point(n=n, l=l)
+                x = l[0]
+                l = [x + 1]
+                n -= 1
+            return l[0]
+        
+        res = self.meta_interp(f, [10])
+        assert res == f(10)
+        self.check_all_virtualized()
+
     def test_append_pop(self):
         py.test.skip("XXX")
         def f(n):



More information about the Pypy-commit mailing list