Bug 1259850 - Handle D4 destructors, r=terrence
authorSteve Fink <sfink@mozilla.com>
Fri, 25 Mar 2016 11:44:21 -0700
changeset 340810 c5817a915a31c3292be95f870eefc53ef0c6fe28
parent 340809 d4246cb8c2bab1050b4c4fe3281dd0b68c9b5810
child 340811 8d85ed16c20e633fb14c17d37ac739750424ec2e
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs1259850
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1259850 - Handle D4 destructors, r=terrence MozReview-Commit-ID: 1hArAcAxvZV
js/src/devtools/rootAnalysis/computeCallgraph.js
--- a/js/src/devtools/rootAnalysis/computeCallgraph.js
+++ b/js/src/devtools/rootAnalysis/computeCallgraph.js
@@ -367,17 +367,17 @@ function process(functionName, functionB
     var markerPos = functionName.indexOf(internalMarker);
     if (markerPos > 0) {
         var inChargeXTor = functionName.replace(internalMarker, "");
         print("D " + memo(inChargeXTor) + " " + memo(functionName));
 
         // Bug 1056410: Oh joy. GCC does something even funkier internally,
         // where it generates calls to ~Foo() but a body for ~Foo(int32) even
         // though it uses the same mangled name for both. So we need to add a
-        // synthetic edge from the former to the latter.
+        // synthetic edge from ~Foo() -> ~Foo(int32).
         //
         // inChargeXTor will have the (int32).
         if (functionName.indexOf("::~") > 0) {
             var calledDestructor = inChargeXTor.replace("(int32)", "()");
             print("D " + memo(calledDestructor) + " " + memo(inChargeXTor));
         }
     }
 
@@ -385,41 +385,47 @@ function process(functionName, functionB
     // different kinds of constructors/destructors are:
     // C1	# complete object constructor
     // C2	# base object constructor
     // C3	# complete object allocating constructor
     // D0	# deleting destructor
     // D1	# complete object destructor
     // D2	# base object destructor
     //
-    // In actual practice, I have observed a C4 constructor generated by gcc
+    // In actual practice, I have observed C4 and D4 xtors generated by gcc
     // 4.9.3 (but not 4.7.3). The gcc source code says:
     //
     //   /* This is the old-style "[unified]" constructor.
     //      In some cases, we may emit this function and call
     //      it from the clones in order to share code and save space.  */
     //
     // Unfortunately, that "call... from the clones" does not seem to appear in
-    // the CFG we get from GCC. So if we see a C4 constructor, inject an edge
-    // to it from C1, C2, and C3. (Note that C3 isn't even used in current GCC,
-    // but add the edge anyway just in case.)
-    if (functionName.indexOf("C4E") != -1) {
+    // the CFG we get from GCC. So if we see a C4 constructor or D4 destructor,
+    // inject an edge to it from C1, C2, and C3 (or D1, D2, and D3). (Note that
+    // C3 isn't even used in current GCC, but add the edge anyway just in
+    // case.)
+    if (functionName.indexOf("C4E") != -1 || functionName.indexOf("D4Ev") != -1) {
         var [ mangled, unmangled ] = splitFunction(functionName);
         // E terminates the method name (and precedes the method parameters).
-        if (mangled.indexOf("C4E") != -1) {
-            // If "C4E" shows up in the mangled name for another reason, this
-            // will create bogus edges in the callgraph. But that shouldn't
-            // matter too much, and is somewhat difficult to avoid, so we will
-            // live with it.
-            var C1 = mangled.replace("C4E", "C1E");
-            var C2 = mangled.replace("C4E", "C2E");
-            var C3 = mangled.replace("C4E", "C3E");
-            print("D " + memo(C1) + " " + memo(mangled));
-            print("D " + memo(C2) + " " + memo(mangled));
-            print("D " + memo(C3) + " " + memo(mangled));
+        // If eg "C4E" shows up in the mangled name for another reason, this
+        // will create bogus edges in the callgraph. But will affect little and
+        // is somewhat difficult to avoid, so we will live with it.
+        for (let [synthetic, variant] of [['C4E', 'C1E'],
+                                          ['C4E', 'C2E'],
+                                          ['C4E', 'C3E'],
+                                          ['D4Ev', 'D1Ev'],
+                                          ['D4Ev', 'D2Ev'],
+                                          ['D4Ev', 'D3Ev']])
+        {
+            if (mangled.indexOf(synthetic) == -1)
+                continue;
+
+            let variant_mangled = mangled.replace(synthetic, variant);
+            let variant_full = variant_mangled + "$" + unmangled;
+            print("D " + memo(variant_full) + " " + memo(functionName));
         }
     }
 }
 
 for (var nameIndex = minStream; nameIndex <= maxStream; nameIndex++) {
     var name = xdb.read_key(nameIndex);
     var data = xdb.read_entry(name);
     process(name.readString(), JSON.parse(data.readString()));