Bug 1339483: Fix tab frame lookup performance issues. r?Mossop draft
authorKris Maglione <maglione.k@gmail.com>
Tue, 14 Feb 2017 13:24:07 -0800
changeset 484134 2134cd25b55b07f683f0dbdc954651d30304c893
parent 483404 6b2fe8524bba18aa3eae8571fbcddea947819985
child 545721 60c43769490c7f332cd2354883eee1dcee652e76
push id45402
push usermaglione.k@gmail.com
push dateTue, 14 Feb 2017 21:25:05 +0000
reviewersMossop
bugs1339483
milestone54.0a1
Bug 1339483: Fix tab frame lookup performance issues. r?Mossop MozReview-Commit-ID: Fvx1J8bpzGg
addon-sdk/source/lib/sdk/remote/child.js
--- a/addon-sdk/source/lib/sdk/remote/child.js
+++ b/addon-sdk/source/lib/sdk/remote/child.js
@@ -127,48 +127,52 @@ function makeFrameEventListener(frame, c
 var FRAME_ID = 0;
 var tabMap = new Map();
 
 const Frame = Class({
   implements: [ Disposable ],
   extends: EventTarget,
   setup: function(contentFrame) {
     // This ID should be unique for this loader across all processes
-    ns(this).id = runtime.processID + ":" + FRAME_ID++;
+    let priv = ns(this);
+
+    priv.id = runtime.processID + ":" + FRAME_ID++;
 
-    ns(this).contentFrame = contentFrame;
-    ns(this).messageManager = contentFrame;
-    ns(this).domListeners = [];
+    priv.contentFrame = contentFrame;
+    priv.messageManager = contentFrame;
+    priv.domListeners = [];
 
     tabMap.set(contentFrame.docShell, this);
 
-    ns(this).messageReceived = messageReceived.bind(this);
-    ns(this).messageManager.addMessageListener('sdk/remote/frame/message', ns(this).messageReceived);
+    priv.messageReceived = messageReceived.bind(this);
+    priv.messageManager.addMessageListener('sdk/remote/frame/message', priv.messageReceived);
 
     this.port = new EventTarget();
     definePort(this, 'sdk/remote/frame/message');
 
-    ns(this).messageManager.sendAsyncMessage('sdk/remote/frame/attach', {
+    priv.messageManager.sendAsyncMessage('sdk/remote/frame/attach', {
       loaderID,
-      frameID: ns(this).id,
+      frameID: priv.id,
       processID: runtime.processID
     });
 
     frames.attachItem(this);
   },
 
   dispose: function() {
+    let priv = ns(this);
+
     emit(this, 'detach', this);
 
-    for (let listener of ns(this).domListeners)
-      ns(this).contentFrame.removeEventListener(...listener.args);
+    for (let listener of priv.domListeners)
+      priv.contentFrame.removeEventListener(...listener.args);
 
-    ns(this).messageManager.removeMessageListener('sdk/remote/frame/message', ns(this).messageReceived);
-    tabMap.delete(ns(this).contentFrame.docShell);
-    ns(this).contentFrame = null;
+    priv.messageManager.removeMessageListener('sdk/remote/frame/message', priv.messageReceived);
+    tabMap.delete(priv.contentFrame.docShell);
+    priv.contentFrame = null;
   },
 
   get content() {
     return ns(this).contentFrame.content;
   },
 
   get isTab() {
     let docShell = ns(this).contentFrame.docShell;
@@ -186,33 +190,37 @@ const Frame = Class({
       // And check we can find a tab for the browser element directly.
       let browser = docShell.chromeEventHandler;
       let tab = require('../tabs/utils').getTabForBrowser(browser);
       return !!tab;
     }
   },
 
   addEventListener: function(...args) {
+    let priv = ns(this);
+
     let listener = listenerFor(...args);
-    if (arrayContainsListener(ns(this).domListeners, listener))
+    if (arrayContainsListener(priv.domListeners, listener))
       return;
 
     listener.registeredCallback = makeFrameEventListener(this, listener.callback);
 
-    ns(this).domListeners.push(listener);
-    ns(this).contentFrame.addEventListener(...listener.args);
+    priv.domListeners.push(listener);
+    priv.contentFrame.addEventListener(...listener.args);
   },
 
   removeEventListener: function(...args) {
-    let listener = getListenerFromArray(ns(this).domListeners, listenerFor(...args));
+    let priv = ns(this);
+
+    let listener = getListenerFromArray(priv.domListeners, listenerFor(...args));
     if (!listener)
       return;
 
-    removeListenerFromArray(ns(this).domListeners, listener);
-    ns(this).contentFrame.removeEventListener(...listener.args);
+    removeListenerFromArray(priv.domListeners, listener);
+    priv.contentFrame.removeEventListener(...listener.args);
   }
 });
 
 const FrameList = Class({
   implements: [ EventParent, Disposable ],
   extends: EventTarget,
   setup: function() {
     EventParent.prototype.initialize.call(this);
@@ -228,22 +236,20 @@ const FrameList = Class({
 
   dispose: function() {
     // The only case where we get destroyed is when the loader is unloaded in
     // which case each frame will clean up its own event listeners.
     ns(this).domListeners = null;
   },
 
   getFrameForWindow: function(window) {
-    for (let frame of this) {
-      if (frame.content == window)
-        return frame;
-    }
+    let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                         .getInterface(Ci.nsIDocShell);
 
-    return null;
+    return tabMap.get(docShell) || null;
   },
 
   addEventListener: function(...args) {
     let listener = listenerFor(...args);
     if (arrayContainsListener(ns(this).domListeners, listener))
       return;
 
     ns(this).domListeners.push(listener);