[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