[gjs/gbsneto/fix-profiler-js60] profiler: Concat entry.label() and entry.dynamicString()



commit 0c9067dfc429e9a4b2b15d2851fb405d8f20ad0f
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Sep 7 22:13:19 2018 -0300

    profiler: Concat entry.label() and entry.dynamicString()
    
    In MozJS 60, only using entry.label() is not enough to give
    meaningful Sysprof entries, since it might be an empty string
    in various cases. This gives many empty entries in Sysprof,
    making the profiler not as useful.
    
    As per upstream MozJS, in version 60, the final string is a
    combination of entry.label() and entry.dynamicString(). In [1],
    however, the dynamic string is conditionally added depending
    on a privacy toggle - which is not really the case with GJS
    since enabling the profiler isn't possible without a large
    control over the software stack, and opting in.
    
    Thus, use entry.dynamicLabel() as an additional source of
    information when saving the profiling labels, with enough
    care to not allocate new strings while there.
    
    [1] https://hg.mozilla.org/releases/mozilla-esr60/rev/768e500ad190

 gjs/profiler.cpp | 43 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 41 insertions(+), 2 deletions(-)
---
diff --git a/gjs/profiler.cpp b/gjs/profiler.cpp
index 27864fc3..a3b25873 100644
--- a/gjs/profiler.cpp
+++ b/gjs/profiler.cpp
@@ -304,15 +304,54 @@ gjs_profiler_sigprof(int        signum,
     for (uint32_t ix = 0; ix < depth; ix++) {
         js::ProfileEntry& entry = self->stack.entries[ix];
         const char *label = entry.label();
+        const char *dynamic_string = entry.dynamicString();
         uint32_t flipped = depth - 1 - ix;
+        size_t label_length = strlen(label);
+
+        /*
+         * 512 is an arbitrarily large size, very likely to be enough to
+         * hold the final string.
+         */
+        char final_string[512] = { 0, };
+        size_t available_length = sizeof (final_string);
+        size_t position = 0;
+
+        if (label_length > 0) {
+            /* Start copying the label to the final string */
+            memcpy(final_string, label, label_length);
+            available_length -= label_length;
+            position += label_length;
+
+            /*
+             * Add a space in between the label and the dynamic string,
+             * If there is one.
+             */
+            if (dynamic_string) {
+                memcpy(final_string + label_length, " ", 1);
+                available_length -=  1;
+                position += 1;
+            }
+        }
+
+        /* Now append the dynamic string at the end of the final string.
+         * The string is cut in case it doesn't fit the remaining space.
+         */
+        if (dynamic_string) {
+            size_t dynamic_string_length = strlen(dynamic_string);
+
+            if (dynamic_string_length > 0) {
+                size_t remaining_length = MIN (available_length - 1, dynamic_string_length);
+                memcpy(final_string + position, dynamic_string, remaining_length);
+            }
+        }
 
         /*
          * GeckoProfiler will put "js::RunScript" on the stack, but it has
          * a stack address of "this", which is not terribly useful since
          * everything will show up as [stack] when building callgraphs.
          */
-        if (label)
-            addrs[flipped] = sp_capture_writer_add_jitmap(self->capture, label);
+        if (final_string[0] != '\0')
+            addrs[flipped] = sp_capture_writer_add_jitmap(self->capture, final_string);
         else
             addrs[flipped] = SpCaptureAddress(entry.stackAddress());
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]