[pypy-commit] pypy vmprof: Somewhat controversial strategy - store info about code objects in a tempfile().

fijal noreply at buildbot.pypy.org
Mon Feb 16 12:45:52 CET 2015


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: vmprof
Changeset: r75917:ef83e90448b8
Date: 2015-02-16 13:41 +0200
http://bitbucket.org/pypy/pypy/changeset/ef83e90448b8/

Log:	Somewhat controversial strategy - store info about code objects in a
	tempfile(). Let's see how it goes

diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -38,8 +38,8 @@
     "_csv", "cppyy", "_pypyjson"
 ])
 
-if sys.platform.startswith('linux') and sys.maxint > 2147483647:
-    working_modules.add('_vmprof')
+#if sys.platform.startswith('linux') and sys.maxint > 2147483647:
+#    working_modules.add('_vmprof')
 
 translation_modules = default_modules.copy()
 translation_modules.update([
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1,15 +1,14 @@
-import sys
+import sys, os
 
 from rpython.rlib.cache import Cache
 from rpython.tool.uid import HUGEVAL_BYTES
-from rpython.rlib import jit, types
+from rpython.rlib import jit, types, rfile
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.objectmodel import (we_are_translated, newlist_hint,
      compute_unique_id, specialize)
 from rpython.rlib.signature import signature
 from rpython.rlib.rarithmetic import r_uint, SHRT_MIN, SHRT_MAX, \
     INT_MIN, INT_MAX, UINT_MAX, USHRT_MAX
-from rpython.rlib.rweaklist import RWeakListMixin
 
 from pypy.interpreter.executioncontext import (ExecutionContext, ActionFlag,
     UserDelAction)
@@ -367,10 +366,6 @@
 
 # ____________________________________________________________
 
-class CodeObjWeakList(RWeakListMixin):
-    def __init__(self):
-        self.initialize()
-
 class ObjSpace(object):
     """Base class for the interpreter-level implementations of object spaces.
     http://pypy.readthedocs.org/en/latest/objspace.html"""
@@ -394,7 +389,6 @@
         self.check_signal_action = None   # changed by the signal module
         self.user_del_action = UserDelAction(self)
         self._code_of_sys_exc_info = None
-        self.all_code_objs = CodeObjWeakList()
 
         # can be overridden to a subclass
         self.initialize()
@@ -672,16 +666,31 @@
             assert ec is not None
             return ec
 
+    def _open_code_info_file(self):
+        ec = self.getexecutioncontext()
+        try:
+            ec.code_info_file = os.tmpfile()
+        except:
+            ec.code_info_file_present = False # we failed to open it
+
     def register_code_object(self, pycode):
-        callback = self.getexecutioncontext().register_code_callback
-        if callback is not None:
-            callback(self, pycode)
-        self.all_code_objs.add_handle(pycode)
-
-    def set_code_callback(self, callback):
         ec = self.getexecutioncontext()
-        ec.register_code_callback = callback
-        
+        if ec.code_info_file is None:
+            self._open_code_info_file()
+        if not ec.code_info_file_present:
+            return
+        try:
+            rfile.write_int(ec.code_info_file, pycode._unique_id)
+            s = pycode._get_full_name()
+            rfile.write_int(ec.code_info_file, len(s))
+            ec.code_info_file.write(s)
+        except OSError:
+            ec.code_info_file_present = False
+            try:
+                ec.code_info_file.close()
+            except:
+                pass # can fail, ignore
+    
     def _freeze_(self):
         return True
 
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -33,7 +33,9 @@
         self.profilefunc = None
         self.w_profilefuncarg = None
         self.thread_disappeared = False   # might be set to True after os.fork()
-        self.register_code_callback = None
+        self.code_info_file = None
+        self.code_info_file_present = True
+
         if sys.maxint == 2147483647:
             self._code_unique_id = 0 # XXX this is wrong, it won't work on 32bit
         else:
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -70,6 +70,7 @@
         'debug_stop'                : 'interp_debug.debug_stop',
         'debug_print_once'          : 'interp_debug.debug_print_once',
         'debug_flush'               : 'interp_debug.debug_flush',
+        'all_code_info'             : 'interp_magic.all_code_info',
         'builtinify'                : 'interp_magic.builtinify',
         'lookup_special'            : 'interp_magic.lookup_special',
         'do_what_I_mean'            : 'interp_magic.do_what_I_mean',
diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -130,3 +130,15 @@
 def locals_to_fast(space, w_frame):
     assert isinstance(w_frame, PyFrame)
     w_frame.locals2fast()
+
+def all_code_info(space):
+    ec = space.getexecutioncontext()
+    if not ec.code_info_file_present or ec.code_info_file is None:
+        raise OperationError(space.w_RuntimeError, space.wrap(
+            "Info file not present, error writing it"))
+    ec.code_info_file.flush()
+    ec.code_info_file.seek(0, 0)
+    try:
+        return space.wrap(ec.code_info_file.read())
+    finally:
+        ec.code_info_file.seek(2, 0)
diff --git a/pypy/module/__pypy__/test/test_special.py b/pypy/module/__pypy__/test/test_special.py
--- a/pypy/module/__pypy__/test/test_special.py
+++ b/pypy/module/__pypy__/test/test_special.py
@@ -83,6 +83,13 @@
         s = set([2, 3, 4])
         assert strategy(s) == "IntegerSetStrategy"
 
+    def test_code_info_file(self):
+        from __pypy__ import all_code_info
+
+        assert len(all_code_info()) > 0 # eh, what else?
+        exec """def function_of_a_relatively_unique_name():
+            pass"""
+        assert 'function_of_a_relatively_unique_name' in all_code_info()
 
 class AppTestJitFeatures(object):
     spaceconfig = {"translation.jit": True}
diff --git a/pypy/module/_vmprof/interp_vmprof.py b/pypy/module/_vmprof/interp_vmprof.py
--- a/pypy/module/_vmprof/interp_vmprof.py
+++ b/pypy/module/_vmprof/interp_vmprof.py
@@ -138,6 +138,7 @@
         self.fileno = -1
 
     def enable(self, space, fileno, period):
+        xxx
         if self.is_enabled:
             raise oefmt(space.w_ValueError, "_vmprof already enabled")
         self.fileno = fileno
diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -3,7 +3,7 @@
 python builtin open()
 """
 
-import os, stat, errno
+import os, stat, errno, sys
 from rpython.rlib import rposix
 from rpython.rlib.objectmodel import enforceargs
 from rpython.rlib.rarithmetic import intmask
@@ -221,6 +221,22 @@
     return stdin, stdout, stderr
 
 
+def write_int(f, l):
+    if sys.maxint == 2147483647:
+        f.write(chr(l & 0xff) +
+                chr((l >> 8) & 0xff) +
+                chr((l >> 16) & 0xff) +
+                chr((l >> 24) & 0xff))
+    else:
+        f.write(chr(l & 0xff) + 
+                chr((l >> 8) & 0xff) +
+                chr((l >> 16) & 0xff) +
+                chr((l >> 24) & 0xff) +
+                chr((l >> 32) & 0xff) +
+                chr((l >> 40) & 0xff) +
+                chr((l >> 48) & 0xff) +
+                chr((l >> 56) & 0xff))
+
 class RFile(object):
     _setbuf = lltype.nullptr(rffi.CCHARP.TO)
     _univ_newline = False


More information about the pypy-commit mailing list