[pypy-commit] pypy default: merge

fijal pypy.commits at gmail.com
Mon Nov 20 10:43:42 EST 2017


Author: fijal
Branch: 
Changeset: r93100:21fd35c44d66
Date: 2017-11-20 16:42 +0100
http://bitbucket.org/pypy/pypy/changeset/21fd35c44d66/

Log:	merge

diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -15,34 +15,10 @@
     typeof, s_ImpossibleValue, SomeInstance, intersection, difference)
 from rpython.annotator.bookkeeper import Bookkeeper
 from rpython.rtyper.normalizecalls import perform_normalizations
-from collections import deque
 
 log = AnsiLogger("annrpython")
 
 
-class ShuffleDict(object):
-    def __init__(self):
-        self._d = {}
-        self.keys = deque()
-
-    def __setitem__(self, k, v):
-        if k in self._d:
-            self._d[k] = v
-        else:
-            self._d[k] = v
-            self.keys.append(k)
-
-    def __getitem__(self, k):
-        return self._d[k]
-
-    def popitem(self):
-        key = self.keys.popleft()
-        item = self._d.pop(key)
-        return (key, item)
-
-    def __nonzero__(self):
-        return bool(self._d)
-
 class RPythonAnnotator(object):
     """Block annotator for RPython.
     See description in doc/translation.txt."""
@@ -57,7 +33,7 @@
             translator = TranslationContext()
             translator.annotator = self
         self.translator = translator
-        self.pendingblocks = ShuffleDict()  # map {block: graph-containing-it}
+        self.genpendingblocks=[{}] # [{block: graph-containing-it}] * generation
         self.annotated = {}      # set of blocks already seen
         self.added_blocks = None # see processblock() below
         self.links_followed = {} # set of links that have ever been followed
@@ -81,7 +57,7 @@
         self.errors = []
 
     def __getstate__(self):
-        attrs = """translator pendingblocks annotated links_followed
+        attrs = """translator genpendingblocks annotated links_followed
         notify bookkeeper frozen policy added_blocks""".split()
         ret = self.__dict__.copy()
         for key, value in ret.items():
@@ -212,19 +188,47 @@
             else:
                 self.mergeinputargs(graph, block, cells)
             if not self.annotated[block]:
-                self.pendingblocks[block] = graph
+                self.schedulependingblock(graph, block)
+
+    def schedulependingblock(self, graph, block):
+        # 'self.genpendingblocks' is a list of dictionaries which is
+        # logically equivalent to just one dictionary.  But we keep a
+        # 'generation' number on each block (=key), and whenever we
+        # process a block, we increase its generation number.  The
+        # block is added to the 'genpendingblocks' indexed by its
+        # generation number.  See complete_pending_blocks() below.
+        generation = getattr(block, 'generation', 0)
+        self.genpendingblocks[generation][block] = graph
 
     def complete_pending_blocks(self):
-        while self.pendingblocks:
-            block, graph = self.pendingblocks.popitem()
-            self.processblock(graph, block)
+        while True:
+            # Find the first of the dictionaries in 'self.genpendingblocks'
+            # which is not empty
+            gen = 0
+            for pendingblocks in self.genpendingblocks:
+                if pendingblocks:
+                    break
+                gen += 1
+            else:
+                return    # all empty => done
+
+            gen += 1   # next generation number
+            if len(self.genpendingblocks) == gen:
+                self.genpendingblocks.append({})
+
+            # Process all blocks at this level
+            # (if any gets re-inserted, it will be into the next level)
+            while pendingblocks:
+                block, graph = pendingblocks.popitem()
+                block.generation = gen
+                self.processblock(graph, block)
 
     def complete(self):
         """Process pending blocks until none is left."""
         while True:
             self.complete_pending_blocks()
             self.policy.no_more_blocks_to_annotate(self)
-            if not self.pendingblocks:
+            if not any(self.genpendingblocks):
                 break   # finished
         # make sure that the return variables of all graphs is annotated
         if self.added_blocks is not None:
@@ -410,7 +414,7 @@
     def reflowpendingblock(self, graph, block):
         assert not self.frozen
         assert graph not in self.fixed_graphs
-        self.pendingblocks[block] = graph
+        self.schedulependingblock(graph, block)
         assert block in self.annotated
         self.annotated[block] = False  # must re-flow
         self.blocked_blocks[block] = (graph, None)
diff --git a/rpython/flowspace/model.py b/rpython/flowspace/model.py
--- a/rpython/flowspace/model.py
+++ b/rpython/flowspace/model.py
@@ -170,7 +170,7 @@
 
 class Block(object):
     __slots__ = """inputargs operations exitswitch
-                exits blockcolor""".split()
+                exits blockcolor generation""".split()
 
     def __init__(self, inputargs):
         self.inputargs = list(inputargs)  # mixed list of variable/const XXX
diff --git a/rpython/rlib/rvmprof/test/test_rvmprof.py b/rpython/rlib/rvmprof/test/test_rvmprof.py
--- a/rpython/rlib/rvmprof/test/test_rvmprof.py
+++ b/rpython/rlib/rvmprof/test/test_rvmprof.py
@@ -164,23 +164,25 @@
 
     @rvmprof.vmprof_execute_code("xcode1", lambda self, code, count: code)
     def main(self, code, count):
+        code = self.MyCode('py:main:3:main')
+        rvmprof.register_code(code, self.MyCode.get_name)
+        code = self.MyCode('py:code:7:native_func')
+        rvmprof.register_code(code, self.MyCode.get_name)
         if count > 0:
             return self.main(code, count-1)
         else:
             return self.native_func(100)
 
     def test(self):
-        # XXX: this test is known to fail since rev a4f077ba651c, but buildbot
-        # never ran it. FIXME.
         from vmprof import read_profile
-        from vmprof.show import PrettyPrinter
+        # from vmprof.show import PrettyPrinter
         assert self.rpy_entry_point(3, 0.5) == 42000
         assert self.tmpfile.check()
-        #
+
         prof = read_profile(self.tmpfilename)
         tree = prof.get_tree()
-        p = PrettyPrinter()
-        p._print_tree(tree)
+        # p = PrettyPrinter()
+        # p._print_tree(tree)
         def walk(tree, symbols):
             symbols.append(tree.name)
             if len(tree.children) == 0:
@@ -189,7 +191,7 @@
                 walk(child, symbols)
         symbols = []
         walk(tree, symbols)
-        not_found = ['n:native_func']
+        not_found = ['py:code:7:native_func']
         for sym in symbols:
             for i,name in enumerate(not_found):
                 if sym.startswith(name):


More information about the pypy-commit mailing list