[pypy-svn] r69218 - in pypy/trunk/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Thu Nov 12 13:04:24 CET 2009


Author: arigo
Date: Thu Nov 12 13:04:24 2009
New Revision: 69218

Modified:
   pypy/trunk/pypy/jit/metainterp/codewriter.py
   pypy/trunk/pypy/jit/metainterp/logger.py
   pypy/trunk/pypy/jit/metainterp/pyjitpl.py
   pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py
   pypy/trunk/pypy/jit/metainterp/test/test_logger.py
   pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py
Log:
Merge the branch 'jit-log-class-func':  a list that maps the address of
functions and classes to their name, for the logger.


Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/codewriter.py	Thu Nov 12 13:04:24 2009
@@ -65,6 +65,8 @@
         self.counter = 0
         self.class_sizes = []
         self._class_sizes_seen = {}
+        self.list_of_addr2name = []
+        self._functions_addr_seen = {}
 
         # set later with .start()
         self.metainterp_sd = None
@@ -172,7 +174,9 @@
         portal_code = self.make_portal_bytecode(portal_graph)
 
         self.metainterp_sd.info_from_codewriter(portal_code, leave_code,
-                                                self.class_sizes)
+                                                self.class_sizes,
+                                                self.list_of_addr2name,
+                                                portal_runner_ptr)
 
     def _start(self, metainterp_sd, portal_runner_ptr):
         self.metainterp_sd = metainterp_sd
@@ -306,6 +310,8 @@
         methdescr.setup(jitcodes)
 
     def getcalldescr(self, v_func, args, result, consider_effects_of=None):
+        if isinstance(v_func, Constant):
+            self.register_known_function(v_func.value)
         non_void_args = [x for x in args if x.concretetype is not lltype.Void]
         NON_VOID_ARGS = [x.concretetype for x in non_void_args]
         RESULT = result.concretetype
@@ -330,6 +336,8 @@
             self._class_sizes_seen[key] = True
             sizedescr = self.cpu.sizeof(STRUCT)
             self.class_sizes.append((vtable, sizedescr))
+            vtable_addr = llmemory.cast_ptr_to_adr(vtable)
+            self.list_of_addr2name.append((vtable_addr, STRUCT.__name__))
 
     def register_known_ooclass(self, cls, CLASS):
         # ootype only
@@ -338,6 +346,16 @@
             typedescr = self.cpu.typedescrof(CLASS)
             self.class_sizes.append((cls, typedescr))
 
+    def register_known_function(self, func):
+        if self.rtyper.type_system.name == 'lltypesystem':
+            try:
+                obj = func._obj
+            except lltype.DelayedPointer:   # probably ll_portal_runner
+                return
+            if obj not in self._functions_addr_seen:
+                self._functions_addr_seen[obj] = True
+                func_addr = llmemory.cast_ptr_to_adr(func)
+                self.list_of_addr2name.append((func_addr, obj._name))
 
 
 class BytecodeMaker(object):

Modified: pypy/trunk/pypy/jit/metainterp/logger.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/logger.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/logger.py	Thu Nov 12 13:04:24 2009
@@ -7,9 +7,10 @@
 
 class Logger(object):
 
-    def __init__(self, ts, guard_number=False):
-        self.ts = ts
-        self.guard_number=guard_number
+    def __init__(self, metainterp_sd, guard_number=False):
+        self.metainterp_sd = metainterp_sd
+        self.ts = metainterp_sd.cpu.ts
+        self.guard_number = guard_number
 
     def log_loop(self, inputargs, operations, number=0, type=None):
         if type is None:
@@ -57,7 +58,11 @@
         elif isinstance(arg, BoxFloat):
             return 'f' + str(mv)
         elif isinstance(arg, self.ts.ConstAddr):
-            return 'ConstClass(cls' + str(mv) + ')'
+            addr = arg.getaddr(self.metainterp_sd.cpu)
+            name = self.metainterp_sd.get_name_from_address(addr)
+            if not name:
+                name = 'cls' + str(mv)
+            return 'ConstClass(' + name + ')'
         else:
             return '?'
 

Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py	Thu Nov 12 13:04:24 2009
@@ -996,8 +996,8 @@
         self.cpu = cpu
         self.stats = stats
         self.options = options
-        self.logger_noopt = Logger(cpu.ts)
-        self.logger_ops = Logger(cpu.ts, guard_number=True)
+        self.logger_noopt = Logger(self)
+        self.logger_ops = Logger(self, guard_number=True)
 
         RESULT = portal_graph.getreturnvar().concretetype
         self.result_type = history.getkind(RESULT)
@@ -1022,15 +1022,21 @@
 
         self.portal_code = None
         self.leave_code = None
-        self._class_sizes = None        
+        self._class_sizes = None
+        self._addr2name_keys = []
+        self._addr2name_values = []
 
     def _freeze_(self):
         return True
 
-    def info_from_codewriter(self, portal_code, leave_code, class_sizes):
+    def info_from_codewriter(self, portal_code, leave_code, class_sizes,
+                             list_of_addr2name, portal_runner_ptr):
         self.portal_code = portal_code
         self.leave_code = leave_code
         self._class_sizes = class_sizes
+        self._addr2name_keys   = [key   for key, value in list_of_addr2name]
+        self._addr2name_values = [value for key, value in list_of_addr2name]
+        self._portal_runner_ptr = portal_runner_ptr
 
     def finish_setup(self, optimizer=None):
         warmrunnerdesc = self.warmrunnerdesc
@@ -1063,6 +1069,28 @@
             class_sizes[vtable] = sizedescr
         self.cpu.set_class_sizes(class_sizes)
 
+    def get_name_from_address(self, addr):
+        # for debugging only
+        if we_are_translated():
+            d = self.globaldata.addr2name
+            if d is None:
+                # Build the dictionary at run-time.  This is needed
+                # because the keys are function/class addresses, so they
+                # can change from run to run.
+                k = llmemory.cast_ptr_to_adr(self._portal_runner_ptr)
+                d = {k: 'recursive call'}
+                keys = self._addr2name_keys
+                values = self._addr2name_values
+                for i in range(len(keys)):
+                    d[keys[i]] = values[i]
+                self.globaldata.addr2name = d
+            return d.get(addr, '')
+        else:
+            for i in range(len(self._addr2name_keys)):
+                if addr == self._addr2name_keys[i]:
+                    return self._addr2name_values[i]
+            return ''
+
     def bytecode_for_address(self, fnaddress):
         if we_are_translated():
             d = self.globaldata.indirectcall_dict
@@ -1115,6 +1143,7 @@
     def __init__(self, staticdata, prebuilt_fail_descr_list):
         self.initialized = False
         self.indirectcall_dict = None
+        self.addr2name = None
         self.fail_descr_list = prebuilt_fail_descr_list[:]
         self.loopnumbering = 0
         #

Modified: pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py	Thu Nov 12 13:04:24 2009
@@ -121,12 +121,14 @@
             supports_floats = False
             def fielddescrof(self, STRUCT, fieldname):
                 return ('fielddescr', STRUCT, fieldname)
-            def calldescrof(self, FUNC, NON_VOID_ARGS, RESULT):
+            def calldescrof(self, FUNC, NON_VOID_ARGS, RESULT, stuff=None):
                 return ('calldescr', FUNC, NON_VOID_ARGS, RESULT)
             def typedescrof(self, CLASS):
                 return ('typedescr', CLASS)
             def methdescrof(self, CLASS, methname):
                 return FakeMethDescr(CLASS, methname)
+            def sizeof(self, STRUCT):
+                return ('sizeof', STRUCT)
 
         if type_system == 'lltype':
             FakeCPU.ts = typesystem.llhelper
@@ -366,6 +368,24 @@
         assert jitcode._source.count('oononnull') == 2
         assert jitcode._source.count('ooisnull') == 2
 
+    def test_list_of_addr2name(self):
+        class A1:
+            def g(self):
+                self.x = 123
+                return 5
+        def f():
+            a = A1()
+            a.y = a.g()
+            return a
+        graphs = self.make_graphs(f, [])
+        cw = CodeWriter(self.rtyper)
+        cw.candidate_graphs = [graphs[0]]
+        cw._start(self.metainterp_sd, None)
+        jitcode = cw.make_one_bytecode((graphs[0], None), False)
+        assert len(cw.list_of_addr2name) == 2
+        assert cw.list_of_addr2name[0][1].endswith('.A1')
+        assert cw.list_of_addr2name[1][1] == 'A1.g'
+
 class ImmutableFieldsTests:
 
     def test_fields(self):

Modified: pypy/trunk/pypy/jit/metainterp/test/test_logger.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_logger.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_logger.py	Thu Nov 12 13:04:24 2009
@@ -34,6 +34,14 @@
 class TestLogger(object):
     ts = llhelper
 
+    def make_metainterp_sd(self):
+        class FakeMetaInterpSd:
+            class cpu:
+                ts = self.ts
+            def get_name_from_address(self, addr):
+                return 'Name'
+        return FakeMetaInterpSd()
+
     def reparse(self, inp, namespace=None, check_equal=True):
         """ parse loop once, then log it and parse again.
         Checks that we get the same thing.
@@ -41,7 +49,7 @@
         if namespace is None:
             namespace = {}
         loop = pure_parse(inp, namespace=namespace)
-        logger = Logger(self.ts)
+        logger = Logger(self.make_metainterp_sd())
         output = logger.log_loop(loop, namespace)
         oloop = pure_parse(output, namespace=namespace)
         if check_equal:
@@ -99,7 +107,7 @@
         jump(i0, descr=target)
         '''
         loop = pure_parse(inp, namespace=namespace)
-        logger = Logger(self.ts)
+        logger = Logger(self.make_metainterp_sd())
         output = logger.log_loop(loop)
         assert output.splitlines()[-1] == "jump(i0, descr=<Loop3>)"
         pure_parse(output)
@@ -111,7 +119,7 @@
         guard_true(i0, descr=fdescr) [i0]
         '''
         loop = pure_parse(inp, namespace=namespace)
-        logger = Logger(self.ts, guard_number=True)
+        logger = Logger(self.make_metainterp_sd(), guard_number=True)
         output = logger.log_loop(loop)
         assert output.splitlines()[-1] == "guard_true(i0, descr=<Guard4>) [i0]"
         pure_parse(output)
@@ -119,18 +127,34 @@
         def boom():
             raise Exception
         namespace['fdescr'].get_index = boom
-        logger = Logger(self.ts, guard_number=False)
+        logger = Logger(self.make_metainterp_sd(), guard_number=False)
         output = logger.log_loop(loop)
         assert output.splitlines()[-1].startswith("guard_true(i0, descr=<")
 
+    def test_class_name(self):
+        from pypy.rpython.lltypesystem import lltype
+        AbcVTable = lltype.Struct('AbcVTable')
+        abcvtable = lltype.malloc(AbcVTable, immortal=True)
+        namespace = {'Name': abcvtable}
+        inp = '''
+        [i0]
+        p = new_with_vtable(ConstClass(Name))
+        '''
+        loop = pure_parse(inp, namespace=namespace)
+        logger = Logger(self.make_metainterp_sd())
+        output = logger.log_loop(loop)
+        assert output.splitlines()[-1].endswith(
+            " = new_with_vtable(ConstClass(Name))")
+        pure_parse(output, namespace=namespace)
+
     def test_intro_loop(self):
-        bare_logger = logger.Logger(self.ts)
+        bare_logger = logger.Logger(self.make_metainterp_sd())
         output = capturing(bare_logger.log_loop, [], [], 1, "foo")
         assert output.splitlines()[0] == "# Loop 1 : foo with 0 ops"
         pure_parse(output)
 
     def test_intro_bridge(self):
-        bare_logger = logger.Logger(self.ts)
+        bare_logger = logger.Logger(self.make_metainterp_sd())
         output = capturing(bare_logger.log_bridge, [], [], 3)
         assert output.splitlines()[0] == "# bridge out of Guard 3 with 0 ops"
         pure_parse(output)

Modified: pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py	Thu Nov 12 13:04:24 2009
@@ -142,3 +142,14 @@
     assert equaloplists(metainterp.history.operations, [
         ResOperation(rop.SAME_AS, [b2], boxes[1]),
         ])
+
+def test_get_name_from_address():
+    class FakeMetaInterpSd(pyjitpl.MetaInterpStaticData):
+        def __init__(self):
+            pass
+    metainterp_sd = FakeMetaInterpSd()
+    metainterp_sd.info_from_codewriter(None, None, None,
+                                       [(123, "a"), (456, "b")])
+    assert metainterp_sd.get_name_from_address(123) == 'a'
+    assert metainterp_sd.get_name_from_address(456) == 'b'
+    assert metainterp_sd.get_name_from_address(789) == ''



More information about the Pypy-commit mailing list