[pypy-commit] pypy interp-opt: record types while stepping through a single pycode object

plan_rich pypy.commits at gmail.com
Thu Oct 20 04:31:19 EDT 2016


Author: Richard Plangger <planrichi at gmail.com>
Branch: interp-opt
Changeset: r87887:16b382207424
Date: 2016-10-20 10:28 +0200
http://bitbucket.org/pypy/pypy/changeset/16b382207424/

Log:	record types while stepping through a single pycode object

diff --git a/pypy/interpreter/optimizer/test/test_basic_func_opt.py b/pypy/interpreter/optimizer/test/test_basic_func_opt.py
--- a/pypy/interpreter/optimizer/test/test_basic_func_opt.py
+++ b/pypy/interpreter/optimizer/test/test_basic_func_opt.py
@@ -2,17 +2,47 @@
 from pypy.interpreter import gateway, module, error
 from pypy.interpreter.optimizer import optimize
 
-class TestBytecode(object):
+class BytecodeHelper(object):
     def __init__(self, pycode):
         self.pycode = pycode
 
     def has(self, opcode):
         return True # XXX
 
+    def iterate_records(self):
+        for record in self.pycode.recorded:
+            yield record
+
 class TestVersioning:
+    def coderecord(self, source, functionname, args):
+        space = self.space
+
+        source = str(py.code.Source(source).strip()) + '\n'
+
+        w = space.wrap
+        w_code = space.builtin.call('compile', 
+                w(source), w('<string>'), w('exec'), w(0), w(0))
+
+        tempmodule = module.Module(space, w("__temp__"))
+        w_glob = tempmodule.w_dict
+        space.setitem(w_glob, w("__builtins__"), space.builtin)
+
+        code = space.unwrap(w_code)
+        code.exec_code(space, w_glob, w_glob)
+
+        w_args = [w(a) for a in args]
+        w_func = space.getitem(w_glob, w(functionname))
+        fcode = space.unwrap(space.getattr(w_func, w('__code__')))
+        fcode.start_type_recording()
+        try:
+            w_a = space.call_function(w_func, *w_args)
+        except error.OperationError as e:
+            #e.print_detailed_traceback(space)
+            return '<<<%s>>>' % e.errorstr(space)
+        a = space.unwrap(w_a)
+        return a, BytecodeHelper(fcode)
+
     def codetest(self, source, functionname, args):
-        """Compile and run the given code string, and then call its function
-        named by 'functionname' with arguments 'args'."""
         space = self.space
 
         source = str(py.code.Source(source).strip()) + '\n'
@@ -47,14 +77,38 @@
             return '<<<%s>>>' % e.errorstr(space)
         a = space.unwrap(w_a)
         b = space.unwrap(w_b)
-        return a, TestBytecode(fcode), b, TestBytecode(opt_fcode)
+        return a, BytecodeHelper(fcode), b, BytecodeHelper(opt_fcode)
+
+    def recorded(self, code, gathered):
+        needed = sorted(gathered[:], lambda x: (x[0],x[1]))
+        it = iter(needed)
+        cur = next(it)
+        import pdb; pdb.set_trace()
+        for i,stackpos,typeinfo in code.iterate_records():
+            # for the current byte code consume each entry in
+            # gathered
+            while True:
+                j = cur[0]
+                if i == j:
+                    if stackpos == cur[1] and typeinfo == cur[2]:
+                        # match! move the iterator one step forward
+                        try:
+                            cur = next(it)
+                        except StopIteration:
+                            # matched them all!
+                            return True
+                    continue
+                break
+
+        return False
 
     def test_record_types(self):
-        code = self.coderecord("""
+        a, acode = self.coderecord("""
         def f(v):
             return v + 1.0
         """, 'f', [1.0])
-        assert self.recorded(code, [
+        assert a == 2.0
+        assert self.recorded(acode, [
                 (0, 1, 'FLOAT')
             ])
 
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -96,10 +96,10 @@
         self._initialize()
         self._init_ready()
         self.new_code_hook()
-        self.record = None
+        self.recorded = None
 
     def start_type_recording(self):
-        self.record = []
+        self.recorded = []
 
     def frame_stores_global(self, w_globals):
         if self.w_globals is None:
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -312,6 +312,10 @@
         w_object = self.locals_cells_stack_w[depth]
         self.locals_cells_stack_w[depth] = None
         self.valuestackdepth = depth
+        #
+        if not jit.we_are_jitted() and self.pycode.recorded is not None:
+            self.pycode.recorded.append((self.last_instr, depth+1, type(w_object)))
+        #
         return w_object
 
 


More information about the pypy-commit mailing list