Commits

Antonio Cuni committed 6b0ffab

make AbstractMethDescr.jitcodes much smaller: instead of storing an entry for
each possible class, we store it only for classes where the method is actually
defined, and then we walk through the superclasses when we need it.

The net result is that the static data is waaay smaller: the exe of
pypy-cli-jit is now 14MB instead of 26MB, and the startup time is 29s instead
of 1m:49s

  • Participants
  • Parent commits 1267691
  • Branches cli-jit

Comments (0)

Files changed (3)

pypy/jit/metainterp/codewriter.py

         assert isinstance(INSTANCE, ootype.Instance)
         TYPES = INSTANCE._all_subclasses()
         for T in TYPES:
-            _, meth = T._lookup(methname)
-            if not getattr(meth, 'abstract', False):
+            TDEF, meth = T._lookup(methname)
+            if TDEF is T and not getattr(meth, 'abstract', False):
                 assert meth.graph
                 if self.is_candidate(meth.graph):
                     jitcode = self.get_jitcode(meth.graph,

pypy/jit/metainterp/history.py

         # jitcodes maps { runtimeClass -> jitcode for runtimeClass.methname }
         self.jitcodes = jitcodes
     def get_jitcode_for_class(self, oocls):
-        return self.jitcodes[oocls]
+        rootcls = ootype.runtimeClass(ootype.ROOT)
+        while oocls is not rootcls:
+            try:
+                return self.jitcodes[oocls]
+            except KeyError:
+                oocls = ootype.getsuperclassof(oocls)
+        assert False, 'we should never get here'
 
 
 class Const(AbstractValue):

pypy/jit/metainterp/test/test_send.py

         res = self.meta_interp(fn, [20], policy=StopAtXPolicy(extern))
         assert res == 21
 
+    def test_call_method_of_base_class(self): 
+        myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'w', 'res'])
+        class Base:
+            def foo(self):
+                return 42
+        class W1(Base):
+            pass
+        class W2(Base):
+            def foo(self):
+                return 43
+        
+        def f(x, y):
+            if x == 0:
+                w = Base()
+            elif x == 1:
+                w = W1()
+            else:
+                w = W2()
+            res = 0
+            while y > 0:
+                myjitdriver.can_enter_jit(x=x, y=y, w=w, res=res)
+                myjitdriver.jit_merge_point(x=x, y=y, w=w, res=res)
+                res = w.foo()
+                y -= 1
+            return res
+        res = self.meta_interp(f, [0, 10])
+        assert res == 42
+        res = self.meta_interp(f, [1, 10])
+        assert res == 42
+        res = self.meta_interp(f, [2, 10])
+        assert res == 43
+       
+
 
 class TestOOtype(SendTests, OOJitMixin):
     pass