Changeset 96500 in webkit


Ignore:
Timestamp:
Oct 3, 2011 8:07:00 AM (13 years ago)
Author:
loislo@chromium.org
Message:

Web Inspector: debuggerPresentatioModel.linkifyLocation leaks updateAnchor closure instances.
https://bugs.webkit.org/show_bug.cgi?id=69146

In many places we use linkifyLocation function to produce a link node which updates automatically when the source file is changed on the fly.
Such changes happen when we use pretty print or another operation that changes the source code somehow.
linkifyLocation associates a new instance of updateAnchor closure with the each link node and add the closure to the SourceMappingUpdated event's list.
As the result the node<->closure pairs wouldn't be collected until reset the UI and DebuggerPresentationModel.

Reviewed by Yury Semikhatsky.

Test: inspector/performance/resources/network-append-30-requests.html

  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • inspector/front-end/ConsoleMessage.js:

(WebInspector.ConsoleMessage.prototype._linkifyLocation):

  • inspector/front-end/ConsoleView.js:

(WebInspector.ConsoleView.prototype._consoleCleared):

  • inspector/front-end/DebuggerPresentationModel.js:
  • inspector/front-end/EventListenersSidebarPane.js:

(WebInspector.EventListenersSidebarPane.prototype.update.callback):
(WebInspector.EventListenersSidebarPane.prototype.update):
():

  • inspector/front-end/Linkifier.js: Added.

(WebInspector.Linkifier):
(WebInspector.Linkifier.prototype.linkifyLocation):
(WebInspector.Linkifier.prototype.reset):
(WebInspector.Linkifier.prototype._updateSourceAnchors):
(WebInspector.Linkifier.prototype._updateAnchor):

  • inspector/front-end/NetworkPanel.js:

(WebInspector.NetworkLogView):
(WebInspector.NetworkLogView.prototype._reset):
(WebInspector.NetworkDataGridNode.prototype._refreshInitiatorCell):

  • inspector/front-end/ProfileDataGridTree.js:

(WebInspector.ProfileDataGridNode.prototype.createCell):

  • inspector/front-end/ProfileView.js:

(WebInspector.CPUProfileView):
(WebInspector.CPUProfileView.prototype._resetClicked):

  • inspector/front-end/TimelinePanel.js:

(WebInspector.TimelinePanel):
(WebInspector.TimelinePanel.prototype._linkifyLocation):
(WebInspector.TimelinePanel.prototype._linkifyCallFrame):
(WebInspector.TimelinePanel.prototype._clearPanel):
(WebInspector.TimelinePanel.FormattedRecord):
(WebInspector.TimelinePanel.FormattedRecord.prototype._generatePopupContent):
(WebInspector.TimelinePanel.FormattedRecord.prototype._getRecordDetails):
(WebInspector.TimelinePanel.PopupContentHelper):
(WebInspector.TimelinePanel.PopupContentHelper.prototype._appendLinkRow):
(WebInspector.TimelinePanel.PopupContentHelper.prototype._appendStackTrace):

  • inspector/front-end/WebKit.qrc:
  • inspector/front-end/inspector.html:
  • inspector/front-end/inspector.js:
Location:
trunk/Source/WebCore
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r96499 r96500  
     12011-10-03  Ilya Tikhonovsky  <loislo@chromium.org>
     2
     3        Web Inspector: debuggerPresentatioModel.linkifyLocation leaks updateAnchor closure instances.
     4        https://bugs.webkit.org/show_bug.cgi?id=69146
     5
     6        In many places we use linkifyLocation function to produce a link node which updates automatically when the source file is changed on the fly.
     7        Such changes happen when we use pretty print or another operation that changes the source code somehow.
     8        linkifyLocation associates a new instance of updateAnchor closure with the each link node and add the closure to the SourceMappingUpdated event's list.
     9        As the result the node<->closure pairs wouldn't be collected until reset the UI and DebuggerPresentationModel.
     10
     11        Reviewed by Yury Semikhatsky.
     12
     13        Test: inspector/performance/resources/network-append-30-requests.html
     14
     15        * WebCore.gypi:
     16        * WebCore.vcproj/WebCore.vcproj:
     17        * inspector/front-end/ConsoleMessage.js:
     18        (WebInspector.ConsoleMessage.prototype._linkifyLocation):
     19        * inspector/front-end/ConsoleView.js:
     20        (WebInspector.ConsoleView.prototype._consoleCleared):
     21        * inspector/front-end/DebuggerPresentationModel.js:
     22        * inspector/front-end/EventListenersSidebarPane.js:
     23        (WebInspector.EventListenersSidebarPane.prototype.update.callback):
     24        (WebInspector.EventListenersSidebarPane.prototype.update):
     25        ():
     26        * inspector/front-end/Linkifier.js: Added.
     27        (WebInspector.Linkifier):
     28        (WebInspector.Linkifier.prototype.linkifyLocation):
     29        (WebInspector.Linkifier.prototype.reset):
     30        (WebInspector.Linkifier.prototype._updateSourceAnchors):
     31        (WebInspector.Linkifier.prototype._updateAnchor):
     32        * inspector/front-end/NetworkPanel.js:
     33        (WebInspector.NetworkLogView):
     34        (WebInspector.NetworkLogView.prototype._reset):
     35        (WebInspector.NetworkDataGridNode.prototype._refreshInitiatorCell):
     36        * inspector/front-end/ProfileDataGridTree.js:
     37        (WebInspector.ProfileDataGridNode.prototype.createCell):
     38        * inspector/front-end/ProfileView.js:
     39        (WebInspector.CPUProfileView):
     40        (WebInspector.CPUProfileView.prototype._resetClicked):
     41        * inspector/front-end/TimelinePanel.js:
     42        (WebInspector.TimelinePanel):
     43        (WebInspector.TimelinePanel.prototype._linkifyLocation):
     44        (WebInspector.TimelinePanel.prototype._linkifyCallFrame):
     45        (WebInspector.TimelinePanel.prototype._clearPanel):
     46        (WebInspector.TimelinePanel.FormattedRecord):
     47        (WebInspector.TimelinePanel.FormattedRecord.prototype._generatePopupContent):
     48        (WebInspector.TimelinePanel.FormattedRecord.prototype._getRecordDetails):
     49        (WebInspector.TimelinePanel.PopupContentHelper):
     50        (WebInspector.TimelinePanel.PopupContentHelper.prototype._appendLinkRow):
     51        (WebInspector.TimelinePanel.PopupContentHelper.prototype._appendStackTrace):
     52        * inspector/front-end/WebKit.qrc:
     53        * inspector/front-end/inspector.html:
     54        * inspector/front-end/inspector.js:
     55
    1562011-10-03  Pavel Feldman  <pfeldman@google.com>
    257
  • trunk/Source/WebCore/WebCore.gypi

    r96398 r96500  
    62356235            'inspector/front-end/DebuggerModel.js',
    62366236            'inspector/front-end/DebuggerPresentationModel.js',
     6237            'inspector/front-end/Linkifier.js',
    62376238            'inspector/front-end/DetailedHeapshotGridNodes.js',
    62386239            'inspector/front-end/DetailedHeapshotView.js',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r96313 r96500  
    6935069350                                </File>
    6935169351                                <File
     69352                                        RelativePath="..\inspector\front-end\Linkifier.js"
     69353                                        >
     69354                                </File>
     69355                                <File
    6935269356                                        RelativePath="..\inspector\front-end\MetricsSidebarPane.js"
    6935369357                                        >
  • trunk/Source/WebCore/inspector/front-end/ConsoleMessage.js

    r96499 r96500  
    195195        lineNumber = lineNumber ? lineNumber - 1 : undefined;
    196196        columnNumber = columnNumber ? columnNumber - 1 : 0;
    197         return WebInspector.debuggerPresentationModel.linkifyLocation(url, lineNumber, columnNumber, "console-message-url");
     197        return WebInspector.ConsoleView.linkifier.linkifyLocation(url, lineNumber, columnNumber, "console-message-url");
    198198    },
    199199
  • trunk/Source/WebCore/inspector/front-end/ConsoleView.js

    r96499 r96500  
    110110    WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
    111111    WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
     112
     113    WebInspector.ConsoleView.linkifier = new WebInspector.Linkifier(WebInspector.debuggerPresentationModel);
    112114}
    113115
     
    329331
    330332        this.dispatchEventToListeners(WebInspector.ConsoleView.Events.ConsoleCleared);
     333
     334        WebInspector.ConsoleView.linkifier.reset();
    331335    },
    332336
  • trunk/Source/WebCore/inspector/front-end/DebuggerPresentationModel.js

    r96097 r96500  
    6767
    6868WebInspector.DebuggerPresentationModel.prototype = {
    69     linkifyLocation: function(sourceURL, lineNumber, columnNumber, classes)
    70     {
    71         var linkText = WebInspector.formatLinkText(sourceURL, lineNumber);
    72         var anchor = WebInspector.linkifyURLAsNode(sourceURL, linkText, classes, false);
    73 
    74         var rawSourceCode = this._rawSourceCodeForScript(sourceURL);
    75         if (!rawSourceCode) {
    76             anchor.setAttribute("preferred_panel", "resources");
    77             anchor.setAttribute("line_number", lineNumber);
    78             return anchor;
    79         }
    80 
    81         function updateAnchor()
    82         {
    83             var uiLocation = rawSourceCode.sourceMapping.rawLocationToUILocation({ lineNumber: lineNumber, columnNumber: columnNumber });
    84             anchor.textContent = WebInspector.formatLinkText(uiLocation.uiSourceCode.url, uiLocation.lineNumber);
    85             anchor.setAttribute("preferred_panel", "scripts");
    86             anchor.uiSourceCode = uiLocation.uiSourceCode;
    87             anchor.lineNumber = uiLocation.lineNumber;
    88         }
    89         if (rawSourceCode.sourceMapping)
    90             updateAnchor.call(this);
    91         rawSourceCode.addEventListener(WebInspector.RawSourceCode.Events.SourceMappingUpdated, updateAnchor, this);
    92         return anchor;
    93     },
    94 
    9569    _parsedScriptSource: function(event)
    9670    {
  • trunk/Source/WebCore/inspector/front-end/EventListenersSidebarPane.js

    r94754 r96500  
    5757
    5858    this.titleElement.appendChild(this.settingsSelectElement);
     59
     60    this._linkifier = new WebInspector.Linkifier(WebInspector.debuggerPresentationModel);
    5961}
    6062
     
    6567    {
    6668        RuntimeAgent.releaseObjectGroup(WebInspector.EventListenersSidebarPane._objectGroupName);
     69        this._linkifier.reset();
     70
    6771        var body = this.bodyElement;
    6872        body.removeChildren();
     
    8589                var section = sectionMap[type];
    8690                if (!section) {
    87                     section = new WebInspector.EventListenersSection(type, node.id);
     91                    section = new WebInspector.EventListenersSection(type, node.id, self._linkifier);
    8892                    sectionMap[type] = section;
    8993                    sectionNames.push(type);
     
    125129WebInspector.EventListenersSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
    126130
    127 WebInspector.EventListenersSection = function(title, nodeId)
     131WebInspector.EventListenersSection = function(title, nodeId, linkifier)
    128132{
    129133    this.eventListeners = [];
    130134    this._nodeId = nodeId;
     135    this._linkifier = linkifier;
    131136    WebInspector.PropertiesSection.call(this, title);
    132137
     
    159164        for (var i = 0; i < length; ++i) {
    160165            var eventListener = filteredEventListeners[i];
    161             var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId);
     166            var eventListenerBar = new WebInspector.EventListenerBar(eventListener, this._nodeId, this._linkifier);
    162167            this.eventBars.appendChild(eventListenerBar.element);
    163168        }
     
    172177WebInspector.EventListenersSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
    173178
    174 WebInspector.EventListenerBar = function(eventListener, nodeId)
     179WebInspector.EventListenerBar = function(eventListener, nodeId, linkifier)
    175180{
    176181    this.eventListener = eventListener;
     
    178183    WebInspector.ObjectPropertiesSection.call(this);
    179184    this._setNodeTitle();
    180     this._setFunctionSubtitle();
     185    this._setFunctionSubtitle(linkifier);
    181186    this.editable = false;
    182187    this.element.className = "event-bar"; /* Changed from "section" */
     
    232237    },
    233238
    234     _setFunctionSubtitle: function()
     239    _setFunctionSubtitle: function(linkifier)
    235240    {
    236241        // Requires that Function.toString() return at least the function's signature.
     
    241246            var lineNumber = this.eventListener.location.lineNumber - 1;
    242247            var columnNumber = 0;
    243             var urlElement = WebInspector.debuggerPresentationModel.linkifyLocation(url, lineNumber, columnNumber);
     248            var urlElement = linkifier.linkifyLocation(url, lineNumber, columnNumber);
    244249            this.subtitleElement.appendChild(urlElement);
    245250        } else {
  • trunk/Source/WebCore/inspector/front-end/NetworkPanel.js

    r96326 r96500  
    5757    this._createStatusbarButtons();
    5858    this._createFilterStatusBarItems();
     59    this._linkifier = new WebInspector.Linkifier(WebInspector.debuggerPresentationModel);
    5960
    6061    WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResourceStarted, this._onResourceStarted, this);
     
    736737        this._mainResourceLoadTime = -1;
    737738        this._mainResourceDOMContentTime = -1;
    738 
     739        this._linkifier.reset();
    739740    },
    740741
     
    20422043                }
    20432044                this._initiatorCell.title = topFrame.url + ":" + topFrame.lineNumber;
    2044                 var urlElement = WebInspector.debuggerPresentationModel.linkifyLocation(topFrame.url, topFrame.lineNumber - 1, 0);
     2045                var urlElement = this._parentView._linkifier.linkifyLocation(topFrame.url, topFrame.lineNumber - 1, 0);
    20452046                this._initiatorCell.appendChild(urlElement);
    20462047                this._appendSubtitle(this._initiatorCell, WebInspector.UIString("Script"));
  • trunk/Source/WebCore/inspector/front-end/ProfileDataGridTree.js

    r95027 r96500  
    9999            // FIXME(62725): profileNode should reference a debugger location.
    100100            var lineNumber = this.profileNode.lineNumber ? this.profileNode.lineNumber - 1 : 0;
    101             var urlElement = WebInspector.debuggerPresentationModel.linkifyLocation(this.profileNode.url, lineNumber, 0, "profile-node-file");
     101            var urlElement = this.profileView._linkifier.linkifyLocation(this.profileNode.url, lineNumber, 0, "profile-node-file");
    102102            urlElement.style.maxWidth = "75%";
    103103            cell.insertBefore(urlElement, cell.firstChild);
  • trunk/Source/WebCore/inspector/front-end/ProfileView.js

    r94754 r96500  
    9797    }
    9898
     99    this._linkifier = new WebInspector.Linkifier(WebInspector.debuggerPresentationModel);
     100
    99101    ProfilerAgent.getProfile(this.profile.typeId, this.profile.uid, profileCallback);
    100102}
     
    486488        this.resetButton.visible = false;
    487489        this.profileDataGridTree.restore();
     490        this._linkiier.reset();
    488491        this.refresh();
    489492        this.refreshVisibleData();
  • trunk/Source/WebCore/inspector/front-end/TimelinePanel.js

    r95794 r96500  
    110110    this._registerShortcuts();
    111111    WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, this._onTimelineEventRecorded, this);
     112    this._linkifier = new WebInspector.Linkifier(WebInspector.debuggerPresentationModel);
    112113}
    113114
     
    117118
    118119WebInspector.TimelinePanel.prototype = {
     120    _linkifyLocation: function(url, lineNumber, columnNumber)
     121    {
     122        // FIXME(62725): stack trace line/column numbers are one-based.
     123        lineNumber = lineNumber ? lineNumber - 1 : lineNumber;
     124        columnNumber = columnNumber ? columnNumber - 1 : 0;
     125        return this._linkifier.linkifyLocation(url, lineNumber, columnNumber, "timeline-details");
     126    },
     127
     128    _linkifyCallFrame: function(callFrame)
     129    {
     130        return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
     131    },
     132
    119133    _createTopPane: function() {
    120134        var topPaneElement = document.createElement("div");
     
    529543        this._closeRecordDetails();
    530544        this._model._reset();
     545        this._linkifier.reset();
    531546    },
    532547
     
    962977WebInspector.TimelinePanel.FormattedRecord = function(record, parentRecord, panel, scriptDetails)
    963978{
     979    this._panel = panel;
    964980    var recordTypes = WebInspector.TimelineAgent.RecordType;
    965981    var style = panel._recordStyles[record.type];
     
    10521068    _generatePopupContent: function(calculator, categories)
    10531069    {
    1054         var contentHelper = new WebInspector.TimelinePanel.PopupContentHelper(this.title);
     1070        var contentHelper = new WebInspector.TimelinePanel.PopupContentHelper(this.title, this._panel);
    10551071
    10561072        if (this._children && this._children.length) {
     
    11371153                return WebInspector.UIString("%s collected", Number.bytesToString(this.data.usedHeapSizeDelta));
    11381154            case WebInspector.TimelineAgent.RecordType.TimerFire:
    1139                 return this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : this.data.timerId;
     1155                return this.scriptName ? this._panel._linkifyLocation(this.scriptName, this.scriptLine, 0) : this.data.timerId;
    11401156            case WebInspector.TimelineAgent.RecordType.FunctionCall:
    1141                 return this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : null;
     1157                return this.scriptName ? this._panel._linkifyLocation(this.scriptName, this.scriptLine, 0) : null;
    11421158            case WebInspector.TimelineAgent.RecordType.FireAnimationFrameEvent:
    1143                 return this.scriptName ? this._linkifyLocation(this.scriptName, this.scriptLine, 0) : this.data.id;
     1159                return this.scriptName ? this._panel._linkifyLocation(this.scriptName, this.scriptLine, 0) : this.data.id;
    11441160            case WebInspector.TimelineAgent.RecordType.EventDispatch:
    11451161                return this.data ? this.data.type : null;
     
    11481164            case WebInspector.TimelineAgent.RecordType.TimerInstall:
    11491165            case WebInspector.TimelineAgent.RecordType.TimerRemove:
    1150                 return this.stackTrace ? this._linkifyCallFrame(this.stackTrace[0]) : this.data.timerId;
     1166                return this.stackTrace ? this._panel._linkifyCallFrame(this.stackTrace[0]) : this.data.timerId;
    11511167            case WebInspector.TimelineAgent.RecordType.RegisterAnimationFrameCallback:
    11521168            case WebInspector.TimelineAgent.RecordType.CancelAnimationFrameCallback:
    1153                 return this.stackTrace ? this._linkifyCallFrame(this.stackTrace[0]) : this.data.id;
     1169                return this.stackTrace ? this._panel._linkifyCallFrame(this.stackTrace[0]) : this.data.id;
    11541170            case WebInspector.TimelineAgent.RecordType.ParseHTML:
    11551171            case WebInspector.TimelineAgent.RecordType.RecalculateStyles:
    1156                 return this.stackTrace ? this._linkifyCallFrame(this.stackTrace[0]) : null;
     1172                return this.stackTrace ? this._panel._linkifyCallFrame(this.stackTrace[0]) : null;
    11571173            case WebInspector.TimelineAgent.RecordType.EvaluateScript:
    1158                 return this.url ? this._linkifyLocation(this.url, this.data.lineNumber, 0) : null;
     1174                return this.url ? this._panel._linkifyLocation(this.url, this.data.lineNumber, 0) : null;
    11591175            case WebInspector.TimelineAgent.RecordType.XHRReadyStateChange:
    11601176            case WebInspector.TimelineAgent.RecordType.XHRLoad:
     
    11721188    },
    11731189
    1174     _linkifyLocation: function(url, lineNumber, columnNumber)
    1175     {
    1176         // FIXME(62725): stack trace line/column numbers are one-based.
    1177         lineNumber = lineNumber ? lineNumber - 1 : lineNumber;
    1178         columnNumber = columnNumber ? columnNumber - 1 : 0;
    1179         return WebInspector.debuggerPresentationModel.linkifyLocation(url, lineNumber, columnNumber, "timeline-details");
    1180     },
    1181 
    1182     _linkifyCallFrame: function(callFrame)
    1183     {
    1184         return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
    1185     },
    1186 
    11871190    _calculateAggregatedStats: function(categories)
    11881191    {
     
    12051208}
    12061209
    1207 WebInspector.TimelinePanel.PopupContentHelper = function(title)
     1210WebInspector.TimelinePanel.PopupContentHelper = function(title, panel)
    12081211{
     1212    this._panel = panel;
    12091213    this._contentTable = document.createElement("table");;
    12101214    var titleCell = this._createCell(WebInspector.UIString("%s - Details", title), "timeline-details-title");
     
    12521256    _appendLinkRow: function(title, scriptName, scriptLine)
    12531257    {
    1254         var link = WebInspector.TimelinePanel.FormattedRecord.prototype._linkifyLocation(scriptName, scriptLine, 0, "timeline-details");
     1258        var link = this._panel._linkifyLocation(scriptName, scriptLine, 0, "timeline-details");
    12551259        this._appendElementRow(title, link);
    12561260    },
     
    12671271            row.appendChild(this._createCell(" @ "));
    12681272            var linkCell = document.createElement("td");
    1269             var urlElement = WebInspector.TimelinePanel.FormattedRecord.prototype._linkifyCallFrame(stackFrame);
     1273            var urlElement = this._panel._linkifyCallFrame(stackFrame);
    12701274            linkCell.appendChild(urlElement);
    12711275            row.appendChild(linkCell);
  • trunk/Source/WebCore/inspector/front-end/WebKit.qrc

    r96313 r96500  
    3737    <file>DebuggerModel.js</file>
    3838    <file>DebuggerPresentationModel.js</file>
     39    <file>Linkifier.js</file>
    3940    <file>DOMAgent.js</file>
    4041    <file>DOMBreakpointsSidebarPane.js</file>
  • trunk/Source/WebCore/inspector/front-end/inspector.html

    r96499 r96500  
    159159    <script type="text/javascript" src="DebuggerModel.js"></script>
    160160    <script type="text/javascript" src="DebuggerPresentationModel.js"></script>
     161    <script type="text/javascript" src="Linkifier.js"></script>
    161162    <script type="text/javascript" src="BreakpointManager.js"></script>
    162163    <script type="text/javascript" src="UISourceCode.js"></script>
  • trunk/Source/WebCore/inspector/front-end/inspector.js

    r96499 r96500  
    510510    this.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._updateErrorAndWarningCounts, this);
    511511
     512    this.debuggerModel = new WebInspector.DebuggerModel();
     513    this.debuggerPresentationModel = new WebInspector.DebuggerPresentationModel();
     514
    512515    this.drawer = new WebInspector.Drawer();
    513516    this.consoleView = new WebInspector.ConsoleView();
     
    522525
    523526    this.cssModel = new WebInspector.CSSStyleModel();
    524     this.debuggerModel = new WebInspector.DebuggerModel();
    525     this.debuggerPresentationModel = new WebInspector.DebuggerPresentationModel();
    526527
    527528    this.searchController = new WebInspector.SearchController();
Note: See TracChangeset for help on using the changeset viewer.