[pypy-svn] r67802 - in pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp: . test

pedronis at codespeak.net pedronis at codespeak.net
Sat Sep 19 20:34:02 CEST 2009


Author: pedronis
Date: Sat Sep 19 20:34:00 2009
New Revision: 67802

Modified:
   pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/resume.py
   pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/test/test_resume.py
Log:
the code, additional tests in test_resume.py

move the frame walking logic into resume.py, makes it easier to reorganize how exactly the information is walked



Modified: pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/pyjitpl.py	Sat Sep 19 20:34:00 2009
@@ -118,6 +118,7 @@
 class MIFrame(object):
     exception_box = None
     exc_value_box = None
+    parent_resumedata = None # for resume.py operation
 
     def __init__(self, metainterp, jitcode):
         assert isinstance(jitcode, codewriter.JitCode)
@@ -975,13 +976,9 @@
             return
         saved_pc = self.pc
         self.pc = pc
-        resumebuilder = resume.ResumeDataBuilder()
+        resumebuilder = resume.ResumeDataBuilder.make(metainterp.framestack)
         if metainterp.staticdata.virtualizable_info is not None:
             resumebuilder.generate_boxes(metainterp.virtualizable_boxes)
-        for frame in metainterp.framestack:
-            resumebuilder.generate_frame_info(frame.jitcode, frame.pc,
-                                              frame.exception_target)
-            resumebuilder.generate_boxes(frame.env)
         if box is not None:
             moreargs = [box] + extraargs
         else:
@@ -1717,6 +1714,12 @@
             self._debug_history.append(['guard_failure', None, None])
         vinfo = self.staticdata.virtualizable_info
         resumereader = resume.ResumeDataReader(resumedescr, newboxes, self)
+        self.framestack = []
+        while resumereader.has_more_frame_infos():
+            jitcode, pc, exception_target = resumereader.consume_frame_info()
+            env = resumereader.consume_boxes()
+            f = self.newframe(jitcode)
+            f.setup_resume_at_op(pc, exception_target, env)
         if vinfo is not None:
             self.virtualizable_boxes = resumereader.consume_boxes()
             # just jumped away from assembler (case 4 in the comment in
@@ -1726,13 +1729,6 @@
             virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
             assert not virtualizable.vable_rti
             self.synchronize_virtualizable()
-            #
-        self.framestack = []
-        while resumereader.has_more_frame_infos():
-            jitcode, pc, exception_target = resumereader.consume_frame_info()
-            env = resumereader.consume_boxes()
-            f = self.newframe(jitcode)
-            f.setup_resume_at_op(pc, exception_target, env)
 
     def check_synchronized_virtualizable(self):
         if not we_are_translated():

Modified: pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/resume.py	(original)
+++ pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/resume.py	Sat Sep 19 20:34:00 2009
@@ -12,16 +12,26 @@
 
 debug = False
 
-
+# xxx we would like more "chaining" instead of copying
 class ResumeDataBuilder(object):
 
-    def __init__(self):
-        self.memo = {}
-        self.liveboxes = []
-        self.consts = []
-        self.nums = []
-        self.frame_infos = []
-
+    def __init__(self, _other=None):
+        if _other is None:
+            self.memo = {}
+            self.liveboxes = []
+            self.consts = []
+            self.nums = []
+            self.frame_infos = []
+        else:
+            self.memo = _other.memo.copy()
+            self.liveboxes = _other.liveboxes[:]
+            self.consts = _other.consts[:]
+            self.nums = _other.nums[:]
+            self.frame_infos = _other.frame_infos[:]
+
+    def clone(self):
+        return ResumeDataBuilder(self)
+        
     def generate_boxes(self, boxes):
         for box in boxes:
             assert box is not None
@@ -41,6 +51,32 @@
     def generate_frame_info(self, *frame_info):
         self.frame_infos.append(frame_info)
 
+    def _add_level(self, frame):
+        self.generate_frame_info(frame.jitcode, frame.pc,
+                                    frame.exception_target)
+        self.generate_boxes(frame.env)        
+
+    @staticmethod
+    def _get_fresh_parent_resumedata(framestack, n):
+        target = framestack[n]
+        if target.parent_resumedata is not None:
+            return target.parent_resumedata.clone()
+        if n == 0:
+            parent_resumedata = ResumeDataBuilder()
+        else:
+            parent_resumedata = ResumeDataBuilder._get_fresh_parent_resumedata(framestack, n-1)
+            parent_resumedata._add_level(framestack[n-1])
+        target.parent_resumedata = parent_resumedata
+        return parent_resumedata.clone()
+
+    @staticmethod
+    def make(framestack):
+        n = len(framestack)-1
+        top = framestack[-1]
+        builder = ResumeDataBuilder._get_fresh_parent_resumedata(framestack, n)
+        builder._add_level(top)
+        return builder
+         
     def finish(self, storage):
         storage.rd_frame_infos = self.frame_infos[:]
         storage.rd_nums = self.nums[:]

Modified: pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/test/test_resume.py
==============================================================================
--- pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/test/test_resume.py	(original)
+++ pypy/branch/get_fresh_parent_resumedata/pypy/jit/metainterp/test/test_resume.py	Sat Sep 19 20:34:00 2009
@@ -57,6 +57,111 @@
     assert not reader.has_more_frame_infos()
 
 
+class FakeFrame(object):
+    parent_resumedata = None
+
+    def __init__(self, code, pc, exc_target, *boxes):
+        self.jitcode = code
+        self.pc = pc
+        self.exception_target = exc_target
+        self.env = list(boxes)
+
+def test_ResumeDataBuilder_clone():
+    b1, b2, b3 = [BoxInt(), BoxPtr(), BoxInt()]
+    c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)]
+    rd = ResumeDataBuilder()
+    rd.generate_boxes([b1, c1, b2])
+    rd.generate_frame_info(('code1', 2, -1))
+
+    rd1 = rd.clone()
+    assert rd1.liveboxes == rd.liveboxes
+    assert rd1.memo == rd.memo
+    assert rd1.consts == rd.consts
+    assert rd1.nums == rd.nums
+    assert rd1.frame_infos == rd.frame_infos
+
+    assert rd1 is not rd
+    assert rd1.liveboxes is not rd.liveboxes
+    assert rd1.memo is not rd.memo
+    assert rd1.consts is not rd.consts
+    assert rd1.nums is not rd.nums
+    assert rd1.frame_infos is not rd.frame_infos
+
+
+def test_ResumeDataBuilder_make():
+    b1, b2, b3 = [BoxInt(), BoxPtr(), BoxInt()]
+    c1, c2, c3 = [ConstInt(1), ConstInt(2), ConstInt(3)]    
+    fs = [FakeFrame("code0", 0, -1, b1, c1, b2)]
+    rd = ResumeDataBuilder.make(fs)
+    assert rd.liveboxes == [b1, b2]
+    assert rd.consts == [c1]
+    assert rd.nums == [0, -2, 1, -1]
+    assert rd.frame_infos == [('code0', 0, -1)]
+
+    assert fs[0].parent_resumedata is not None
+    prd = fs[0].parent_resumedata
+    assert prd.nums == []
+
+    assert rd is not prd
+    
+    fs = [FakeFrame("code0", 0, -1, b1, c1, b2),
+          FakeFrame("code1", 3, 7, b3, c2, b1),
+          FakeFrame("code2", 9, -1, c3, b2)]
+    rd = ResumeDataBuilder.make(fs)
+    assert rd.liveboxes == [b1, b2, b3]
+    assert rd.consts == [c1, c2, c3]
+    assert rd.nums == [0, -2, 1, -1,
+                       2, -3, 0, -1,
+                       -4, 1, -1]
+                       
+    assert rd.frame_infos == [('code0', 0, -1),
+                              ('code1', 3, 7),
+                              ('code2', 9, -1)]
+
+    assert fs[0].parent_resumedata is not None
+    assert fs[1].parent_resumedata is not None
+    assert fs[2].parent_resumedata is not None
+
+    prd = fs[0].parent_resumedata
+    assert prd.nums == []
+
+    prd = fs[1].parent_resumedata
+    assert prd.nums == [0, -2, 1, -1]
+    
+    prd = fs[2].parent_resumedata
+    assert prd.nums == [0, -2, 1, -1,
+                       2, -3, 0, -1]
+
+    rds = (rd, fs[0].parent_resumedata, fs[1].parent_resumedata,
+               fs[2].parent_resumedata)
+    for i in range(len(rds)):
+        for j in range(i+1, len(rds)):
+            assert rds[i] is not rds[j]
+
+    fs[2].env = [b2, b3]
+    fs[2].pc = 15
+    rd = ResumeDataBuilder.make(fs)
+    assert rd.liveboxes == [b1, b2, b3]
+    assert rd.consts == [c1, c2]
+    assert rd.nums == [0, -2, 1, -1,
+                       2, -3, 0, -1,
+                       1, 2, -1]
+                       
+    assert rd.frame_infos == [('code0', 0, -1),
+                              ('code1', 3, 7),
+                              ('code2', 15, -1)]
+
+    assert fs[2].parent_resumedata is prd
+
+    rds = (rd, fs[0].parent_resumedata, fs[1].parent_resumedata,
+               fs[2].parent_resumedata)
+    for i in range(len(rds)):
+        for j in range(i+1, len(rds)):
+            assert rds[i] is not rds[j]    
+
+
+# ____________________________________________________________
+
 class MyMetaInterp:
     def __init__(self, cpu):
         self.cpu = cpu



More information about the Pypy-commit mailing list