Changeset 84840 in webkit


Ignore:
Timestamp:
Apr 25, 2011 4:41:59 PM (13 years ago)
Author:
weinig@apple.com
Message:

2011-04-25 Sam Weinig <sam@webkit.org>

Reviewed by Adam Roben.

Leaks Viewer throws "Cannot post cyclic structures" in Safari 5
https://bugs.webkit.org/show_bug.cgi?id=56090

Make LeaksViewer work with versions of browsers that don't support message
passing of cyclic structures.

  • BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParser.js: (LeaksParser.this._worker.onmessage): (LeaksParser): (LeaksParser.prototype.addLeaksFile): Use LeaksParserImpl directly if we don't support passing cyclic structures.
  • BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParserImpl.js: Copied from BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParserWorker.js. (LeaksParserImpl): (LeaksParserImpl.prototype.addLeaksFile): (LeaksParserImpl.prototype._incorporateLeaks):
  • BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParserWorker.js: (onmessage): Factor out LeaksParser implementation into LeaksParserImpl.js.
  • BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/Utilities.js: (workersSupportCyclicStructures): Add function to detect if workers support passing cyclic structures.
  • BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/index.html: Add LeaksParserImpl.js include.
Location:
trunk/Tools
Files:
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParser.js

    r80864 r84840  
    2626function LeaksParser(didParseLeaksFileCallback) {
    2727    this._didParseLeaksFileCallback = didParseLeaksFileCallback;
    28     this._worker = new Worker("LeaksParserWorker.js");
     28   
     29    if (workersSupportCyclicStructures()) {
     30        this._worker = new Worker("LeaksParserWorker.js");
    2931
    30     var self = this;
    31     this._worker.onmessage = function(e) {
    32         self._didParseLeaksFileCallback(e.data);
    33     };
     32        var self = this;
     33        this._worker.onmessage = function(e) {
     34            self._didParseLeaksFileCallback(e.data);
     35        };
     36    } else
     37        this._parserImpl = new LeaksParserImpl(this._didParseLeaksFileCallback);
    3438}
    3539
    3640LeaksParser.prototype = {
    3741    addLeaksFile: function(leaksText) {
    38         this._worker.postMessage(leaksText);
     42        if (this._worker)
     43            this._worker.postMessage(leaksText);
     44        else
     45            this._parserImpl.addLeaksFile(leaksText);
    3946    },
    4047};
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParserImpl.js

    r84804 r84840  
    2424 */
    2525
    26 function LeaksParserWorker() {
    27     this.profile = this._createNode("top level");
     26function LeaksParserImpl(didParseLeaksCallback) {
     27    this._didParseLeaksCallback = didParseLeaksCallback;
     28    this._profile = this._createNode("top level");
    2829}
    2930
    30 LeaksParserWorker.prototype = {
     31LeaksParserImpl.prototype = {
    3132    addLeaksFile: function(leaksText) {
    3233        this._incorporateLeaks(this._parseLeaks(leaksText));
     34        this._didParseLeaksCallback(this._profile);
    3335    },
    3436
     
    7981                else {
    8082                    childNode = self._createNode(frame);
    81                     childNode.head = self.profile;
     83                    childNode.head = self._profile;
    8284                    node.childrenByName[frame] = childNode;
    8385                    node.children.push(childNode);
     
    8890                ++childNode.numberOfCalls;
    8991                return childNode;
    90             }, self.profile);
     92            }, self._profile);
    9193        });
    92         self.profile.totalTime = self.profile.children.reduce(function(sum, child) { return sum + child.totalTime; }, 0);
     94        self._profile.totalTime = self._profile.children.reduce(function(sum, child) { return sum + child.totalTime; }, 0);
    9395    },
    9496};
    95 
    96 var parser = new LeaksParserWorker();
    97 
    98 onmessage = function(e) {
    99     parser.addLeaksFile(e.data);
    100     postMessage(parser.profile);
    101 }
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParserWorker.js

    r81448 r84840  
    2424 */
    2525
    26 function LeaksParserWorker() {
    27     this.profile = this._createNode("top level");
    28 }
     26importScripts("LeaksParserImpl.js");
    2927
    30 LeaksParserWorker.prototype = {
    31     addLeaksFile: function(leaksText) {
    32         this._incorporateLeaks(this._parseLeaks(leaksText));
    33     },
    34 
    35     _parseLeaks: function(text) {
    36         var leaks = [];
    37         var currentSize = 0;
    38         text.split("\n").forEach(function(line) {
    39             var match = /^Leak:.*\ssize=(\d+)\s/.exec(line);
    40             if (match) {
    41                 currentSize = parseInt(match[1], 10);
    42                 return;
    43             }
    44             if (!/^\s+Call stack:/.test(line))
    45                 return;
    46 
    47             // The first frame is not really a frame at all ("Call stack: thread 0xNNNNN:"), so we omit it.
    48             leaks.push({ size: currentSize, stack: line.split(" | ").slice(1).map(function(str) { return str.trim(); }) });
    49             currentSize = 0;
    50         });
    51         return leaks;
    52     },
    53 
    54     _createNode: function(functionName) {
    55         return {
    56             functionName: functionName,
    57             selfTime: 0,
    58             totalTime: 0,
    59             averageTime: 0,
    60             numberOfCalls: 0,
    61             children: [],
    62             childrenByName: {},
    63             callUID: functionName,
    64         };
    65     },
    66 
    67     // This function creates a fake "profile" from a set of leak stacks. "selfTime" is the number of
    68     // stacks in which this function was at the top (in theory, only functions like malloc should have a
    69     // non-zero selfTime). "totalTime" is the number of stacks which contain this function (and thus is
    70     // the number of leaks that occurred in or beneath this function).
    71     // FIXME: This is expensive! Can we parallelize it?
    72     _incorporateLeaks: function(leaks) {
    73         var self = this;
    74         leaks.forEach(function(leak) {
    75             leak.stack.reduce(function(node, frame, index, array) {
    76                 var childNode;
    77                 if (frame in node.childrenByName)
    78                     childNode = node.childrenByName[frame];
    79                 else {
    80                     childNode = self._createNode(frame);
    81                     childNode.head = self.profile;
    82                     node.childrenByName[frame] = childNode;
    83                     node.children.push(childNode);
    84                 }
    85                 if (index === array.length - 1)
    86                     childNode.selfTime += leak.size;
    87                 childNode.totalTime += leak.size;
    88                 ++childNode.numberOfCalls;
    89                 return childNode;
    90             }, self.profile);
    91         });
    92         self.profile.totalTime = self.profile.children.reduce(function(sum, child) { return sum + child.totalTime; }, 0);
    93     },
    94 };
    95 
    96 var parser = new LeaksParserWorker();
     28var parser = new LeaksParserImpl(function(profile) {
     29    postMessage(profile);
     30});
    9731
    9832onmessage = function(e) {
    9933    parser.addLeaksFile(e.data);
    100     postMessage(parser.profile);
    10134}
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/Utilities.js

    r82682 r84840  
    4242}
    4343
     44function workersSupportCyclicStructures() {
     45    var worker = new Worker("Utilities.js");
     46    var supportsCyclicStructures = true;
     47
     48    try {
     49        var cyclicStructure = { cycle: null };
     50        cyclicStructure.cycle = cyclicStructure;
     51
     52        worker.postMessage(cyclicStructure);
     53    } catch(e) {
     54        supportsCyclicStructures = false;
     55    }
     56
     57    return supportsCyclicStructures;
     58}
     59
    4460Array.prototype.first = function(predicate) {
    4561    for (var i = 0; i < this.length; ++i) {
  • trunk/Tools/BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/index.html

    r81068 r84840  
    5555    <script src=LeaksLoader.js></script>
    5656    <script src=LeaksParser.js></script>
     57    <script src=LeaksParserImpl.js></script>
    5758    <script src=LeaksViewer.js></script>
    5859    <script src=RecentBuildsLoader.js></script>
  • trunk/Tools/ChangeLog

    r84826 r84840  
     12011-04-25  Sam Weinig  <sam@webkit.org>
     2
     3        Reviewed by Adam Roben.
     4
     5        Leaks Viewer throws "Cannot post cyclic structures" in Safari 5
     6        https://bugs.webkit.org/show_bug.cgi?id=56090
     7
     8        Make LeaksViewer work with versions of browsers that don't support message
     9        passing of cyclic structures.
     10
     11        * BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParser.js:
     12        (LeaksParser.this._worker.onmessage):
     13        (LeaksParser):
     14        (LeaksParser.prototype.addLeaksFile):
     15        Use LeaksParserImpl directly if we don't support passing cyclic structures.
     16
     17        * BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParserImpl.js: Copied from BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParserWorker.js.
     18        (LeaksParserImpl):
     19        (LeaksParserImpl.prototype.addLeaksFile):
     20        (LeaksParserImpl.prototype._incorporateLeaks):
     21        * BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/LeaksParserWorker.js:
     22        (onmessage):
     23        Factor out LeaksParser implementation into LeaksParserImpl.js.
     24
     25        * BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/Utilities.js:
     26        (workersSupportCyclicStructures):
     27        Add function to detect if workers support passing cyclic structures.
     28
     29        * BuildSlaveSupport/build.webkit.org-config/public_html/LeaksViewer/index.html:
     30        Add LeaksParserImpl.js include.
     31
    1322011-04-25  Jeff Miller  <jeffm@apple.com>
    233
Note: See TracChangeset for help on using the changeset viewer.