Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r79020:71fc12ecb018
Date: 2015-08-17 18:15 +0200
http://bitbucket.org/pypy/pypy/changeset/71fc12ecb018/

Log:    Move to C the _write_header() code: it was not guaranteed (but only
        very likely) to occur as the first write. Moreover, this is easier
        to keep the code identical with CPython.

diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py
--- a/rpython/rlib/rvmprof/cintf.py
+++ b/rpython/rlib/rvmprof/cintf.py
@@ -40,9 +40,10 @@
         **eci_kwds))
 
 
-    vmprof_init = rffi.llexternal("vmprof_init", [rffi.INT], rffi.CCHARP,
-                                  compilation_info=eci)
-    vmprof_enable = rffi.llexternal("vmprof_enable", [rffi.LONG], rffi.INT,
+    vmprof_init = rffi.llexternal("vmprof_init",
+                                  [rffi.INT, rffi.DOUBLE, rffi.CCHARP],
+                                  rffi.CCHARP, compilation_info=eci)
+    vmprof_enable = rffi.llexternal("vmprof_enable", [], rffi.INT,
                                     compilation_info=eci,
                                     save_err=rffi.RFFI_SAVE_ERRNO)
     vmprof_disable = rffi.llexternal("vmprof_disable", [], rffi.INT,
diff --git a/rpython/rlib/rvmprof/rvmprof.py b/rpython/rlib/rvmprof/rvmprof.py
--- a/rpython/rlib/rvmprof/rvmprof.py
+++ b/rpython/rlib/rvmprof/rvmprof.py
@@ -102,18 +102,14 @@
         assert fileno >= 0
         if self.is_enabled:
             raise VMProfError("vmprof is already enabled")
-        if not (1e-6 <= interval < 1.0):
-            raise VMProfError("bad value for 'interval'")
-        interval_usec = int(interval * 1000000.0)
 
-        p_error = self.cintf.vmprof_init(fileno)
+        p_error = self.cintf.vmprof_init(fileno, interval, "pypy")
         if p_error:
             raise VMProfError(rffi.charp2str(p_error))
 
         self.fileno = fileno
-        self._write_header(interval_usec)
         self._gather_all_code_objs()
-        res = self.cintf.vmprof_enable(interval_usec)
+        res = self.cintf.vmprof_enable()
         if res < 0:
             raise VMProfError(os.strerror(rposix.get_saved_errno()))
         self.is_enabled = True
@@ -154,19 +150,6 @@
         # a maximum of 8184 bytes.  This should be guaranteed here because:
         assert MAX_CODES + 17 + MAX_FUNC_NAME <= 8184
 
-    def _write_header(self, interval_usec):
-        b = StringBuilder()
-        _write_long_to_string_builder(0, b)
-        _write_long_to_string_builder(3, b)
-        _write_long_to_string_builder(0, b)
-        _write_long_to_string_builder(interval_usec, b)
-        _write_long_to_string_builder(0, b)
-        b.append('\x04') # interp name
-        b.append(chr(len('pypy')))
-        b.append('pypy')
-        buf = b.build()
-        self.cintf.vmprof_write_buf(buf, len(buf))
-
 
 def _write_long_to_string_builder(l, b):
     b.append(chr(l & 0xff))
diff --git a/rpython/rlib/rvmprof/src/rvmprof.h 
b/rpython/rlib/rvmprof/src/rvmprof.h
--- a/rpython/rlib/rvmprof/src/rvmprof.h
+++ b/rpython/rlib/rvmprof/src/rvmprof.h
@@ -1,6 +1,6 @@
 
-RPY_EXTERN char *vmprof_init(int);
+RPY_EXTERN char *vmprof_init(int, double, const char *);
 RPY_EXTERN void vmprof_ignore_signals(int);
-RPY_EXTERN int vmprof_enable(long);
+RPY_EXTERN int vmprof_enable(void);
 RPY_EXTERN int vmprof_disable(void);
 RPY_EXTERN void vmprof_write_buf(char *, long);
diff --git a/rpython/rlib/rvmprof/src/vmprof_main.h 
b/rpython/rlib/rvmprof/src/vmprof_main.h
--- a/rpython/rlib/rvmprof/src/vmprof_main.h
+++ b/rpython/rlib/rvmprof/src/vmprof_main.h
@@ -44,11 +44,17 @@
 static int (*unw_get_proc_info)(unw_cursor_t *, unw_proc_info_t *) = NULL;
 
 static int profile_file = -1;
+static long prepare_interval_usec;
 
+static int opened_profile(const char *interp_name);
 
 RPY_EXTERN
-char *vmprof_init(int fd)
+char *vmprof_init(int fd, double interval, const char *interp_name)
 {
+    if (interval < 1e-6 || interval >= 1.0)
+        return "bad value for 'interval'";
+    prepare_interval_usec = (int)(interval * 1000000.0);
+
     if (!unw_get_reg) {
         void *libhandle;
 
@@ -68,6 +74,10 @@
 
     assert(fd >= 0);
     profile_file = fd;
+    if (opened_profile(interp_name) < 0) {
+        profile_file = -1;
+        return strerror(errno);
+    }
     return NULL;
 
  error:
@@ -108,6 +118,7 @@
 #define MARKER_STACKTRACE '\x01'
 #define MARKER_VIRTUAL_IP '\x02'
 #define MARKER_TRAILER '\x03'
+#define MARKER_INTERP_NAME '\x04'
 
 struct prof_stacktrace_s {
     char padding[sizeof(long) - 1];
@@ -338,11 +349,11 @@
 }
 
 RPY_EXTERN
-int vmprof_enable(long interval_usec)
+int vmprof_enable(void)
 {
     assert(profile_file >= 0);
-    assert(interval_usec > 0);
-    profile_interval_usec = interval_usec;
+    assert(prepare_interval_usec > 0);
+    profile_interval_usec = prepare_interval_usec;
 
     if (install_pthread_atfork_hooks() == -1)
         goto error;
@@ -371,6 +382,27 @@
     return 0;
 }
 
+static int opened_profile(const char *interp_name)
+{
+    struct {
+        long hdr[5];
+        char interp_name[257];
+    } header;
+
+    size_t namelen = strlen(interp_name);
+    assert(namelen <= 255);
+
+    header.hdr[0] = 0;
+    header.hdr[1] = 3;
+    header.hdr[2] = 0;
+    header.hdr[3] = prepare_interval_usec;
+    header.hdr[4] = 0;
+    header.interp_name[0] = MARKER_INTERP_NAME;
+    header.interp_name[1] = namelen;
+    memcpy(&header.interp_name[2], interp_name, namelen);
+    return _write_all(&header, 5 * sizeof(long) + 2 + namelen);
+}
+
 static int close_profile(void)
 {
     char buf[4096];
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to