[pypy-commit] pypy identity-dict-strategy: use an enum instead of a bool to keep track of the comparse_by_identiy status; this way, we can cache also the False case

antocuni noreply at buildbot.pypy.org
Tue Jul 19 18:44:25 CEST 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: identity-dict-strategy
Changeset: r45746:f99a873a003f
Date: 2011-07-19 18:43 +0200
http://bitbucket.org/pypy/pypy/changeset/f99a873a003f/

Log:	use an enum instead of a bool to keep track of the
	comparse_by_identiy status; this way, we can cache also the False
	case

diff --git a/pypy/objspace/std/objecttype.py b/pypy/objspace/std/objecttype.py
--- a/pypy/objspace/std/objecttype.py
+++ b/pypy/objspace/std/objecttype.py
@@ -44,7 +44,7 @@
     if w_oldcls.get_full_instance_layout() == w_newcls.get_full_instance_layout():
         w_obj.setclass(space, w_newcls)
         if space.config.objspace.std.trackcomparebyidentity:
-            if not w_oldcls.overrides_hash_eq_or_cmp and not w_newcls.compares_by_identity():
+            if w_oldcls.compares_by_identity() and not w_newcls.compares_by_identity():
                 space.bump_compares_by_identity_version()
     else:
         raise operationerrfmt(space.w_TypeError,
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -76,6 +76,10 @@
         for i in range(len(self.lookup_where)):
             self.lookup_where[i] = None_None
 
+# possible values of compares_by_identity_status 
+UNKNOWN = 0
+COMPARES_BY_IDENTITY = 1
+OVERRIDES_EQ_CMP_OR_HASH = 2
 
 class W_TypeObject(W_Object):
     from pypy.objspace.std.typetype import type_typedef as typedef
@@ -103,8 +107,7 @@
     uses_object_getattribute = False
 
     # for config.objspace.std.trackcomparebyidentity
-    # (True is a conservative default, fixed during real usage)
-    overrides_hash_eq_or_cmp = True
+    compares_by_identity_status = UNKNOWN
 
     # used to cache the type __new__ function if it comes from a builtin type
     # != 'type', in that case call__Type will also assumes the result
@@ -169,12 +172,12 @@
             # ^^^ conservative default, fixed during real usage
 
         if space.config.objspace.std.trackcomparebyidentity:
-            did_compare_by_identity = not w_self.overrides_hash_eq_or_cmp
-            if did_compare_by_identity and (key is None or
-                                            key == '__eq__' or
-                                            key == '__cmp__' or
-                                            key == '__hash__'):
-                w_self.overrides_hash_eq_or_cmp = True
+            did_compare_by_identity = (
+                w_self.compares_by_identity_status == COMPARES_BY_IDENTITY)
+            if (key is None or key == '__eq__' or
+                key == '__cmp__' or key == '__hash__'):
+                w_self.compares_by_identity_status = UNKNOWN
+                if did_compare_by_identity:
                 w_self.space.bump_compares_by_identity_version()
                 
         if space.config.objspace.std.newshortcut:
@@ -232,16 +235,19 @@
         if not track:
             return False # conservative
         #
-        if not w_self.overrides_hash_eq_or_cmp:
-            return True # fast path
+        if w_self.compares_by_identity_status != UNKNOWN:
+            # fast path
+            return w_self.compares_by_identity_status == COMPARES_BY_IDENTITY
         #
-        # XXX: if the class *does* overrides, we always hit the slow path. Do
-        # we care?
         default_hash = object_hash(w_self.space)
-        w_self.overrides_hash_eq_or_cmp = (w_self.lookup('__eq__') or
+        overrides_eq_cmp_or_hash = (w_self.lookup('__eq__') or
                                            w_self.lookup('__cmp__') or
                                            w_self.lookup('__hash__') is not default_hash)
-        return not w_self.overrides_hash_eq_or_cmp
+        if overrides_eq_cmp_or_hash:
+            w_self.compares_by_identity_status = OVERRIDES_EQ_CMP_OR_HASH
+        else:
+            w_self.compares_by_identity_status = COMPARES_BY_IDENTITY
+        return w_self.compares_by_identity_status == COMPARES_BY_IDENTITY
 
     def ready(w_self):
         for w_base in w_self.bases_w:


More information about the pypy-commit mailing list