[pypy-svn] rev 2540 - in pypy/trunk/src/pypy/annotation: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Dec 19 10:54:01 CET 2003
Author: arigo
Date: Fri Dec 19 10:54:00 2003
New Revision: 2540
Modified:
pypy/trunk/src/pypy/annotation/annset.py
pypy/trunk/src/pypy/annotation/test/test_annset.py
Log:
Fixed merge() to deal with immutables-that-are-not-really-changed.
Modified: pypy/trunk/src/pypy/annotation/annset.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/annset.py (original)
+++ pypy/trunk/src/pypy/annotation/annset.py Fri Dec 19 10:54:00 2003
@@ -8,6 +8,10 @@
return False
mostgeneralvalue = MostGeneralValue()
+class ImpossibleValue(Exception):
+ pass
+impossiblevalue = ImpossibleValue()
+
class About:
def __init__(self):
@@ -44,8 +48,8 @@
def leave(self):
self.inblock = None
- def isshared(self, someval1, someval2):
- return self.about[someval1] is self.about[someval2]
+ def isshared(self, val1, val2):
+ return self.about.get(val1, val1) == self.about.get(val2, val2)
def __repr__(self): # debugging
lines = ['===== AnnotationSet =====']
@@ -61,15 +65,15 @@
return '\n'.join(lines)
def get(self, predicate, subject):
- about = self._about(subject)
- result = about.annotations.get(predicate)
- if result:
- answer, dependencies = result
- if self.inblock:
- dependencies[self.inblock] = True
- return answer
- else:
- return mostgeneralvalue
+ if subject is not mostgeneralvalue:
+ about = self._about(subject)
+ result = about.annotations.get(predicate)
+ if result:
+ answer, dependencies = result
+ if self.inblock:
+ dependencies[self.inblock] = True
+ return answer
+ return mostgeneralvalue
def _about(self, somevalue):
try:
@@ -77,6 +81,8 @@
except KeyError:
if somevalue is mostgeneralvalue:
raise ValueError, "Unexpected mostgeneralvalue"
+ if isinstance(somevalue, ImpossibleValue):
+ raise somevalue
about = self.about[somevalue] = About()
about.subjects[somevalue] = True
return about
@@ -100,8 +106,14 @@
def merge(self, oldvalue, newvalue):
"""Update the heap to account for the merging of oldvalue and newvalue.
Return the merged somevalue."""
+ if isinstance(newvalue, ImpossibleValue):
+ return oldvalue
+ if isinstance(oldvalue, ImpossibleValue):
+ return newvalue
if newvalue is mostgeneralvalue or oldvalue is mostgeneralvalue:
return mostgeneralvalue
+ if self.isshared(oldvalue, newvalue):
+ return oldvalue
# build an About set that is the intersection of the two incoming ones
about1 = self._about(oldvalue)
@@ -128,17 +140,24 @@
# modify the annotations about it. If one of them is mutable,
# then we must replace its About set with 'about3'.
invalidatedblocks = {}
- for value, about in [(oldvalue, about1), (newvalue, about2)]:
- if ANN.immutable not in about.annotations:
- # find all annotations that are removed or generalized
- for pred, (someval, deps) in about.annotations.items():
- if (pred not in about3.annotations or
- about3.annotations[pred][0] != someval):
- invalidatedblocks.update(deps)
+ for about in [about1, about2]:
+ # find all annotations that are removed or generalized
+ removedannotations = []
+ for pred, (someval, deps) in about.annotations.items():
+ if (pred in about3.annotations and
+ self.isshared(about3.annotations[pred][0], someval)):
+ continue # unmodified annotation
+ removedannotations.append(deps)
+ # if the existing 'value' is mutable, or if nothing has been
+ # removed, then we identify (by sharing) the 'value' and the
+ # new 'about3'.
+ if not removedannotations or ANN.immutable not in about.annotations:
# patch 'value' to use the new 'about3'.
for sharedvalue in about.subjects: # this includes 'value'
self.about[sharedvalue] = about3
about3.subjects[sharedvalue] = True
+ for deps in removedannotations:
+ invalidatedblocks.update(deps)
if not about3.subjects:
value3 = SomeValue()
Modified: pypy/trunk/src/pypy/annotation/test/test_annset.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/test/test_annset.py (original)
+++ pypy/trunk/src/pypy/annotation/test/test_annset.py Fri Dec 19 10:54:00 2003
@@ -101,38 +101,57 @@
self.assertSameCells(a1, c, c1, c3)
self.assertSameSet(a1, a2)
- def test_merge_immutable1(self):
+ def test_merge_same_immutables(self):
a1 = annset(ANN.len, c1, c2,
ANN.immutable, c1,
ANN.len, c3, c2,
ANN.immutable, c3)
- # (c1) inter (c3) == (some new c)
+ # (c1) inter (c3) == (c1 and c3)
c = a1.merge(c1, c3)
- a2 = annset(ANN.len, c1, c2,
+ self.assertSameCells(a1, c, c1, c3)
+ a2 = annset(ANN.len, c, c2,
+ ANN.immutable, c,
+ links=[c1,c,c3,c])
+ self.assertSameSet(a1, a2)
+
+ def test_merge_generalize_one_immutable(self):
+ a1 = annset(ANN.len, c1, c2,
ANN.immutable, c1,
+ ANN.type, c1, list,
ANN.len, c3, c2,
ANN.immutable, c3,
+ ANN.type, c2, str)
+ # (c1) inter (c3) == (c3)
+ c = a1.merge(c1, c3)
+ self.assertSameCells(a1, c, c3)
+ a2 = annset(ANN.len, c1, c2,
+ ANN.immutable, c1,
+ ANN.type, c1, list,
ANN.len, c, c2,
- ANN.immutable, c)
+ ANN.immutable, c,
+ ANN.type, c2, str,
+ links=[c3,c])
self.assertSameSet(a1, a2)
- def test_merge_immutable2(self):
+ def test_merge_generalize_both_immutables(self):
a1 = annset(ANN.len, c1, c2,
ANN.immutable, c1,
+ ANN.type, c1, list,
ANN.len, c3, c2,
ANN.immutable, c3,
- ANN.type, c1, list,
+ ANN.type, c3, tuple,
ANN.type, c2, str)
- # (c1) inter (c3) == (some new c)
+ # (c1) inter (c3) == (a more general c)
c = a1.merge(c1, c3)
a2 = annset(ANN.len, c1, c2,
ANN.immutable, c1,
+ ANN.type, c1, list,
ANN.len, c3, c2,
ANN.immutable, c3,
- ANN.type, c1, list,
- ANN.type, c2, str,
+ ANN.type, c3, tuple,
ANN.len, c, c2,
- ANN.immutable, c)
+ ANN.immutable, c,
+ ANN.type, c2, str)
self.assertSameSet(a1, a2)
def test_recursive_merge(self):
@@ -151,23 +170,20 @@
c9 = a1.merge(c1, c5)
c10 = a1.get(ANN.tupleitem[2], c9)
c11 = a1.get(ANN.listitems, c10)
+ self.assertSameCells(a1, c1, c5, c9)
self.assertSameCells(a1, c2, c6, c10)
- a2 = annset(ANN.tupleitem[2], c1, c2,
- ANN.immutable, c1,
- ANN.type, c3, int,
- ANN.immutable, c3,
- ANN.tupleitem[2], c5, c6,
- ANN.immutable, c5,
- ANN.type, c7, float,
- ANN.immutable, c7,
-
- ANN.tupleitem[2], c9, c10,
+ a2 = annset(ANN.tupleitem[2], c9, c10,
ANN.immutable, c9,
ANN.type, c10, list,
ANN.listitems, c10, c11,
ANN.immutable, c11,
- links=[c2,c10,c6,c10])
+ # old remaining stuff
+ ANN.type, c3, int,
+ ANN.immutable, c3,
+ ANN.type, c7, float,
+ ANN.immutable, c7,
+ links=[c1,c9, c5,c9, c2,c10, c6,c10])
self.assertSameSet(a1, a2)
def test_settype(self):
More information about the Pypy-commit
mailing list