[pypy-svn] r21560 - in pypy/dist/pypy/rpython: lltypesystem test

arigo at codespeak.net arigo at codespeak.net
Sat Dec 24 11:24:14 CET 2005


Author: arigo
Date: Sat Dec 24 11:24:08 2005
New Revision: 21560

Modified:
   pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py
   pypy/dist/pypy/rpython/lltypesystem/rclass.py
   pypy/dist/pypy/rpython/test/test_rclass.py
Log:
Minor optimization in the rtyper for isinstance() on classes with
no subclasses.


Modified: pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py	Sat Dec 24 11:24:08 2005
@@ -30,10 +30,15 @@
 
     v_obj, v_cls = hop.inputargs(instance_repr, class_repr)
     if isinstance(v_cls, Constant):
-        minid = hop.inputconst(lltype.Signed, v_cls.value.subclassrange_min)
-        maxid = hop.inputconst(lltype.Signed, v_cls.value.subclassrange_max)
-        return hop.gendirectcall(rclass.ll_isinstance_const, v_obj, minid,
-                                 maxid)
+        cls = v_cls.value
+        if cls.subclassrange_max == cls.subclassrange_min + 1:
+            # a class with no subclass
+            return hop.gendirectcall(rclass.ll_isinstance_exact, v_obj, v_cls)
+        else:
+            minid = hop.inputconst(lltype.Signed, cls.subclassrange_min)
+            maxid = hop.inputconst(lltype.Signed, cls.subclassrange_max)
+            return hop.gendirectcall(rclass.ll_isinstance_const, v_obj, minid,
+                                     maxid)
     else:
         return hop.gendirectcall(rclass.ll_isinstance, v_obj, v_cls)
 

Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rclass.py	Sat Dec 24 11:24:08 2005
@@ -260,9 +260,15 @@
         class_repr = get_type_repr(self.rtyper)
         v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
         if isinstance(v_cls2, Constant):
-            minid = hop.inputconst(Signed, v_cls2.value.subclassrange_min)
-            maxid = hop.inputconst(Signed, v_cls2.value.subclassrange_max)
-            return hop.gendirectcall(ll_issubclass_const, v_cls1, minid, maxid)
+            cls2 = v_cls2.value
+            if cls2.subclassrange_max == cls2.subclassrange_min + 1:
+                # a class with no subclass
+                return hop.genop('ptr_eq', [v_cls1, v_cls2], resulttype=Bool)
+            else:
+                minid = hop.inputconst(Signed, cls2.subclassrange_min)
+                maxid = hop.inputconst(Signed, cls2.subclassrange_max)
+                return hop.gendirectcall(ll_issubclass_const, v_cls1, minid,
+                                         maxid)
         else:
             v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr)
             return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2)
@@ -632,6 +638,12 @@
         return False
     return ll_issubclass_const(obj.typeptr, minid, maxid)
 
+def ll_isinstance_exact(obj, cls):
+    if not obj:
+        return False
+    obj_cls = obj.typeptr
+    return obj_cls == cls
+
 def ll_runtime_type_info(obj):
     return obj.typeptr.rtti
 

Modified: pypy/dist/pypy/rpython/test/test_rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rclass.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rclass.py	Sat Dec 24 11:24:08 2005
@@ -148,7 +148,9 @@
     assert res == 246
 
 def test_issubclass_type():
-    class A:
+    class Abstract:
+        pass
+    class A(Abstract):
         pass
     class B(A):
         pass



More information about the Pypy-commit mailing list