Bug 1443983: Part 2 - Remove remaining interpositions. r=mconley
authorKris Maglione <maglione.k@gmail.com>
Wed, 07 Mar 2018 18:10:24 -0800
changeset 459784 a45d6d58a07d2f999b285e9a821822a21bd69ac4
parent 459783 916ad3941bf1b8f06e8806f42ab7e2a3d5e46091
child 459785 f1431c234b4eb10d3c16067465bfc22e8699c1ed
push id8824
push userarchaeopteryx@coole-files.de
push dateMon, 12 Mar 2018 14:54:48 +0000
treeherdermozilla-beta@8d9daab95d68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmconley
bugs1443983
milestone60.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 1443983: Part 2 - Remove remaining interpositions. r=mconley MozReview-Commit-ID: AHwNsBB7OAQ
CLOBBER
browser/app/profile/firefox.js
browser/base/content/tabbrowser.js
browser/installer/package-manifest.in
toolkit/components/addoncompat/Prefetcher.jsm
toolkit/components/addoncompat/RemoteAddonsChild.jsm
toolkit/components/addoncompat/RemoteAddonsParent.jsm
toolkit/components/addoncompat/addoncompat.manifest
toolkit/components/addoncompat/defaultShims.js
toolkit/components/addoncompat/moz.build
toolkit/components/addoncompat/multiprocessShims.js
toolkit/components/moz.build
toolkit/content/browser-child.js
toolkit/modules/RemoteWebProgress.jsm
toolkit/mozapps/extensions/AddonManagerStartup.cpp
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/xre/nsXREDirProvider.cpp
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
 # Are you updating CLOBBER because you think it's needed for your WebIDL
 # changes to stick? As of bug 928195, this shouldn't be necessary! Please
 # don't change CLOBBER for WebIDL changes any more.
 
-Merge day clobber
+Bug 1443983: Removing addoncompat.manifest requires clobber.
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1548,20 +1548,16 @@ pref("browser.tabs.remote.warmup.unloadD
 
 // For the about:tabcrashed page
 pref("browser.tabs.crashReporting.sendReport", true);
 pref("browser.tabs.crashReporting.includeURL", false);
 pref("browser.tabs.crashReporting.requestEmail", false);
 pref("browser.tabs.crashReporting.emailMe", false);
 pref("browser.tabs.crashReporting.email", "");
 
-// Enable e10s add-on interposition by default.
-pref("extensions.interposition.enabled", true);
-pref("extensions.interposition.prefetching", true);
-
 // But don't allow non-MPC extensions by default on Nightly
 #if defined(NIGHTLY_BUILD)
 pref("extensions.allow-non-mpc-extensions", false);
 #endif
 
 pref("extensions.legacy.enabled", false);
 
 // How often to check for CPOW timeouts. CPOWs are only timed out by
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -2,18 +2,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* eslint-env mozilla/browser-window */
 
 window._gBrowser = {
   init() {
-    this.requiresAddonInterpositions = true;
-
     ChromeUtils.defineModuleGetter(this, "AsyncTabSwitcher",
       "resource:///modules/AsyncTabSwitcher.jsm");
 
     XPCOMUtils.defineLazyServiceGetters(this, {
       _unifiedComplete: ["@mozilla.org/autocomplete/search;1?name=unifiedcomplete", "mozIPlacesAutoComplete"],
       serializationHelper: ["@mozilla.org/network/serialization-helper;1", "nsISerializationHelper"],
       mURIFixup: ["@mozilla.org/docshell/urifixup;1", "nsIURIFixup"],
     });
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -419,19 +419,16 @@
 @RESPATH@/components/nsBlocklistServiceContent.js
 #ifdef MOZ_UPDATER
 @RESPATH@/components/nsUpdateService.manifest
 @RESPATH@/components/nsUpdateService.js
 @RESPATH@/components/nsUpdateServiceStub.js
 #endif
 @RESPATH@/components/nsUpdateTimerManager.manifest
 @RESPATH@/components/nsUpdateTimerManager.js
-@RESPATH@/components/addoncompat.manifest
-@RESPATH@/components/multiprocessShims.js
-@RESPATH@/components/defaultShims.js
 @RESPATH@/components/utils.manifest
 @RESPATH@/components/simpleServices.js
 @RESPATH@/components/pluginGlue.manifest
 @RESPATH@/components/ProcessSingleton.manifest
 @RESPATH@/components/MainProcessSingleton.js
 @RESPATH@/components/ContentProcessSingleton.js
 @RESPATH@/browser/components/nsSessionStore.manifest
 @RESPATH@/browser/components/nsSessionStartup.js
deleted file mode 100644
--- a/toolkit/components/addoncompat/Prefetcher.jsm
+++ /dev/null
@@ -1,536 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-var EXPORTED_SYMBOLS = ["Prefetcher"];
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-// Rules are defined at the bottom of this file.
-var PrefetcherRules = {};
-
-/*
- * When events that trigger in the content process are forwarded to
- * add-ons in the chrome process, we expect the add-ons to send a lot
- * of CPOWs to query content nodes while processing the events. To
- * speed this up, the prefetching system anticipates which properties
- * will be read and reads them ahead of time. The prefetched
- * properties are passed to the chrome process along with each
- * event. A typical scenario might work like this:
- *
- * 1. "load" event fires in content
- * 2. Content process prefetches:
- *      event.target.defaultView = <win 1>
- *      <win 1>.location = <location obj>
- *      event.target.getElementsByTagName("form") = [<elt 1>, <elt 2>]
- *      <elt 1>.id = "login-form"
- *      <elt 2>.id = "subscribe-form"
- * 3. Content process forwards "load" event to add-on along with
- *    prefetched data
- * 4. Add-on reads:
- *      event.target.defaultView (already prefetched)
- *      event.target.getElementsByTagName("form") (already prefetched)
- *      <elt 1>.id (already prefetched)
- *      <elt 1>.className (not prefetched; CPOW must be sent)
- *
- * The amount of data to prefetch is determined based on the add-on ID
- * and the event type. The specific data to select is determined using
- * a set of Datalog-like rules (http://en.wikipedia.org/wiki/Datalog).
- *
- * Rules operate on a series of "tables" like in a database. Each
- * table contains a set of content-process objects. When an event
- * handler runs, it seeds some initial tables with objects of
- * interest. For example, the Event table might start out containing
- * the event that fired.
- *
- * Objects are added to tables using a set of rules of the form "if X
- * is in table A, then add F(X) to table B", where F(X) is typically a
- * property access or a method call. The most common functions F are:
- *
- * PropertyOp(destTable, sourceTable, property):
- *   For each object X in sourceTable, add X.property to destTable.
- * MethodOp(destTable, sourceTable, method, args):
- *   For each object X in sourceTable, add X.method(args) to destTable.
- * CollectionOp(destTable, sourceTable):
- *   For each object X in sourceTable, add X[i] to destTable for
- *   all i from 0 to X.length - 1.
- *
- * To generate the prefetching in the example above, the following
- * rules would work:
- *
- * 1. PropertyOp("EventTarget", "Event", "target")
- * 2. PropertyOp("Window", "EventTarget", "defaultView")
- * 3. MethodOp("FormCollection", "EventTarget", "getElementsByTagName", "form")
- * 4. CollectionOp("Form", "FormCollection")
- * 5. PropertyOp(null, "Form", "id")
- *
- * Rules are written at the bottom of this file.
- *
- * When a rule runs, it will usually generate some cache entries that
- * will be passed to the chrome process. For example, when PropertyOp
- * prefetches obj.prop and gets the value X, it caches the value of
- * obj and X. When the chrome process receives this data, it creates a
- * two-level map [obj -> [prop -> X]]. When the add-on accesses a
- * property on obj, the add-on shim code consults this map to see if
- * the property has already been cached.
- */
-
-const PREF_PREFETCHING_ENABLED = "extensions.interposition.prefetching";
-
-function isPrimitive(v) {
-  if (!v)
-    return true;
-  let type = typeof(v);
-  return type !== "object" && type !== "function";
-}
-
-function objAddr(obj) {
-/*
-  if (!isPrimitive(obj)) {
-    return String(obj) + "[" + Cu.getJSTestingFunctions().objectAddress(obj) + "]";
-  }
-  return String(obj);
-*/
-}
-
-function log(/* ...args*/) {
-/*
-  for (let arg of args) {
-    dump(arg);
-    dump(" ");
-  }
-  dump("\n");
-*/
-}
-
-function logPrefetch(/* kind, value1, component, value2*/) {
-/*
-  log("prefetching", kind, objAddr(value1) + "." + component, "=", objAddr(value2));
-*/
-}
-
-/*
- * All the Op classes (representing Datalog rules) have the same interface:
- *   outputTable: Table that objects generated by the rule are added to.
- *     Note that this can be null.
- *   inputTable: Table that the rule draws objects from.
- *   addObject(database, obj): Called when an object is added to inputTable.
- *     This code should take care of adding objects to outputTable.
- *     Data to be cached should be stored by calling database.cache.
- *   makeCacheEntry(item, cache):
- *     Called by the chrome process to create the two-level map of
- *     prefetched objects. |item| holds the cached data
- *     generated by the content process. |cache| is the map to be
- *     generated.
- */
-
-function PropertyOp(outputTable, inputTable, prop) {
-  this.outputTable = outputTable;
-  this.inputTable = inputTable;
-  this.prop = prop;
-}
-
-PropertyOp.prototype.addObject = function(database, obj) {
-  let has = false, propValue;
-  try {
-    if (this.prop in obj) {
-      has = true;
-      propValue = obj[this.prop];
-    }
-  } catch (e) {
-    // Don't cache anything if an exception is thrown.
-    return;
-  }
-
-  logPrefetch("prop", obj, this.prop, propValue);
-  database.cache(this.index, obj, has, propValue);
-  if (has && !isPrimitive(propValue) && this.outputTable) {
-    database.add(this.outputTable, propValue);
-  }
-};
-
-PropertyOp.prototype.makeCacheEntry = function(item, cache) {
-  let [, obj, , propValue] = item;
-
-  let desc = { configurable: false, enumerable: true, writable: false, value: propValue };
-
-  if (!cache.has(obj)) {
-    cache.set(obj, new Map());
-  }
-  let propMap = cache.get(obj);
-  propMap.set(this.prop, desc);
-};
-
-function MethodOp(outputTable, inputTable, method, ...args) {
-  this.outputTable = outputTable;
-  this.inputTable = inputTable;
-  this.method = method;
-  this.args = args;
-}
-
-MethodOp.prototype.addObject = function(database, obj) {
-  let result;
-  try {
-    result = obj[this.method].apply(obj, this.args);
-  } catch (e) {
-    // Don't cache anything if an exception is thrown.
-    return;
-  }
-
-  logPrefetch("method", obj, this.method + "(" + this.args + ")", result);
-  database.cache(this.index, obj, result);
-  if (!isPrimitive(result) && this.outputTable) {
-    database.add(this.outputTable, result);
-  }
-};
-
-MethodOp.prototype.makeCacheEntry = function(item, cache) {
-  let [, obj, result] = item;
-
-  if (!cache.has(obj)) {
-    cache.set(obj, new Map());
-  }
-  let propMap = cache.get(obj);
-  let fallback = propMap.get(this.method);
-
-  let method = this.method;
-  let selfArgs = this.args;
-  let methodImpl = function(...args) {
-    if (args.length == selfArgs.length && args.every((v, i) => v === selfArgs[i])) {
-      return result;
-    }
-
-    if (fallback) {
-      return fallback.value(...args);
-    }
-    return obj[method](...args);
-  };
-
-  let desc = { configurable: false, enumerable: true, writable: false, value: methodImpl };
-  propMap.set(this.method, desc);
-};
-
-function CollectionOp(outputTable, inputTable) {
-  this.outputTable = outputTable;
-  this.inputTable = inputTable;
-}
-
-CollectionOp.prototype.addObject = function(database, obj) {
-  let elements = [];
-  try {
-    let len = obj.length;
-    for (let i = 0; i < len; i++) {
-      logPrefetch("index", obj, i, obj[i]);
-      elements.push(obj[i]);
-    }
-  } catch (e) {
-    // Don't cache anything if an exception is thrown.
-    return;
-  }
-
-  database.cache(this.index, obj, ...elements);
-  for (let i = 0; i < elements.length; i++) {
-    if (!isPrimitive(elements[i]) && this.outputTable) {
-      database.add(this.outputTable, elements[i]);
-    }
-  }
-};
-
-CollectionOp.prototype.makeCacheEntry = function(item, cache) {
-  let [, obj, ...elements] = item;
-
-  if (!cache.has(obj)) {
-    cache.set(obj, new Map());
-  }
-  let propMap = cache.get(obj);
-
-  let lenDesc = { configurable: false, enumerable: true, writable: false, value: elements.length };
-  propMap.set("length", lenDesc);
-
-  for (let i = 0; i < elements.length; i++) {
-    let desc = { configurable: false, enumerable: true, writable: false, value: elements[i] };
-    propMap.set(i, desc);
-  }
-};
-
-function CopyOp(outputTable, inputTable) {
-  this.outputTable = outputTable;
-  this.inputTable = inputTable;
-}
-
-CopyOp.prototype.addObject = function(database, obj) {
-  database.add(this.outputTable, obj);
-};
-
-function Database(trigger, addons) {
-  // Create a map of rules that apply to this specific trigger and set
-  // of add-ons. The rules are indexed based on their inputTable.
-  this.rules = new Map();
-  for (let addon of addons) {
-    let addonRules = PrefetcherRules[addon] || {};
-    let triggerRules = addonRules[trigger] || [];
-    for (let rule of triggerRules) {
-      let inTable = rule.inputTable;
-      if (!this.rules.has(inTable)) {
-        this.rules.set(inTable, new Set());
-      }
-      let set = this.rules.get(inTable);
-      set.add(rule);
-    }
-  }
-
-  // this.tables maps table names to sets of objects contained in them.
-  this.tables = new Map();
-
-  // todo is a worklist of items added to tables that have not had
-  // rules run on them yet.
-  this.todo = [];
-
-  // Cached data to be sent to the chrome process.
-  this.cached = [];
-}
-
-Database.prototype = {
-  // Add an object to a table.
-  add(table, obj) {
-    if (!this.tables.has(table)) {
-      this.tables.set(table, new Set());
-    }
-    let tableSet = this.tables.get(table);
-    if (tableSet.has(obj)) {
-      return;
-    }
-    tableSet.add(obj);
-
-    this.todo.push([table, obj]);
-  },
-
-  cache(...args) {
-    this.cached.push(args);
-  },
-
-  // Run a fixed-point iteration that adds objects to table based on
-  // this.rules until there are no more objects to add.
-  process() {
-    while (this.todo.length) {
-      let [table, obj] = this.todo.pop();
-      let rules = this.rules.get(table);
-      if (!rules) {
-        continue;
-      }
-      for (let rule of rules) {
-        rule.addObject(this, obj);
-      }
-    }
-  },
-};
-
-var Prefetcher = {
-  init() {
-    // Give an index to each rule and store it in this.ruleMap based
-    // on the index. The index is used to serialize and deserialize
-    // data from content to chrome.
-    let counter = 0;
-    this.ruleMap = new Map();
-    for (let addon in PrefetcherRules) {
-      for (let trigger in PrefetcherRules[addon]) {
-        for (let rule of PrefetcherRules[addon][trigger]) {
-          rule.index = counter++;
-          this.ruleMap.set(rule.index, rule);
-        }
-      }
-    }
-
-    this.prefetchingEnabled = Services.prefs.getBoolPref(PREF_PREFETCHING_ENABLED, false);
-    Services.prefs.addObserver(PREF_PREFETCHING_ENABLED, this);
-    Services.obs.addObserver(this, "xpcom-shutdown");
-  },
-
-  observe(subject, topic, data) {
-    if (topic == "xpcom-shutdown") {
-      Services.prefs.removeObserver(PREF_PREFETCHING_ENABLED, this);
-      Services.obs.removeObserver(this, "xpcom-shutdown");
-    } else if (topic == PREF_PREFETCHING_ENABLED) {
-      this.prefetchingEnabled = Services.prefs.getBoolPref(PREF_PREFETCHING_ENABLED, false);
-    }
-  },
-
-  // Called when an event occurs in the content process. The event is
-  // described by the trigger string. |addons| is a list of addons
-  // that have listeners installed for the event. |args| is
-  // event-specific data (such as the event object).
-  prefetch(trigger, addons, args) {
-    if (!this.prefetchingEnabled) {
-      return [[], []];
-    }
-
-    let db = new Database(trigger, addons);
-    for (let table in args) {
-      log("root", table, "=", objAddr(args[table]));
-      db.add(table, args[table]);
-    }
-
-    // Prefetch objects and add them to tables.
-    db.process();
-
-    // Data passed to sendAsyncMessage must be split into a JSON
-    // portion and a CPOW portion. This code splits apart db.cached
-    // into these two pieces. Any object in db.cache is added to an
-    // array of CPOWs and replaced with {cpow: <index in array>}.
-    let cpowIndexes = new Map();
-    let prefetched = [];
-    let cpows = [];
-    for (let item of db.cached) {
-      item = item.map((elt) => {
-        if (!isPrimitive(elt)) {
-          if (!cpowIndexes.has(elt)) {
-            let index = cpows.length;
-            cpows.push(elt);
-            cpowIndexes.set(elt, index);
-          }
-          return {cpow: cpowIndexes.get(elt)};
-        }
-        return elt;
-      });
-
-      prefetched.push(item);
-    }
-
-    return [prefetched, cpows];
-  },
-
-  cache: null,
-
-  // Generate a two-level mapping based on cached data received from
-  // the content process.
-  generateCache(prefetched, cpows) {
-    let cache = new Map();
-    for (let item of prefetched) {
-      // Replace anything of the form {cpow: <index>} with the actual
-      // object in |cpows|.
-      item = item.map((elt) => {
-        if (!isPrimitive(elt)) {
-          return cpows[elt.cpow];
-        }
-        return elt;
-      });
-
-      let index = item[0];
-      let op = this.ruleMap.get(index);
-      op.makeCacheEntry(item, cache);
-    }
-    return cache;
-  },
-
-  // Run |func|, using the prefetched data in |prefetched| and |cpows|
-  // as a cache.
-  withPrefetching(prefetched, cpows, func) {
-    if (!this.prefetchingEnabled) {
-      return func();
-    }
-
-    this.cache = this.generateCache(prefetched, cpows);
-
-    try {
-      log("Prefetching on");
-      return func();
-    } finally {
-      // After we return from this event handler, the content process
-      // is free to continue executing, so we invalidate our cache.
-      log("Prefetching off");
-      this.cache = null;
-    }
-  },
-
-  // Called by shim code in the chrome process to check if target.prop
-  // is cached.
-  lookupInCache(addon, target, prop) {
-    if (!this.cache || !Cu.isCrossProcessWrapper(target)) {
-      return null;
-    }
-
-    let propMap = this.cache.get(target);
-    if (!propMap) {
-      return null;
-    }
-
-    return propMap.get(prop);
-  },
-};
-
-var AdblockId = "{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}";
-var AdblockRules = {
-  "ContentPolicy.shouldLoad": [
-    new MethodOp("Node", "InitNode", "QueryInterface", Ci.nsISupports),
-    new PropertyOp("Document", "Node", "ownerDocument"),
-    new PropertyOp("Window", "Node", "defaultView"),
-    new PropertyOp("Window", "Document", "defaultView"),
-    new PropertyOp("TopWindow", "Window", "top"),
-    new PropertyOp("WindowLocation", "Window", "location"),
-    new PropertyOp(null, "WindowLocation", "href"),
-    new PropertyOp("Window", "Window", "parent"),
-    new PropertyOp(null, "Window", "name"),
-    new PropertyOp("Document", "Window", "document"),
-    new PropertyOp("TopDocumentElement", "Document", "documentElement"),
-    new MethodOp(null, "TopDocumentElement", "getAttribute", "data-adblockkey"),
-  ]
-};
-PrefetcherRules[AdblockId] = AdblockRules;
-
-var LastpassId = "support@lastpass.com";
-var LastpassRules = {
-  "EventTarget.handleEvent": [
-    new PropertyOp("EventTarget", "Event", "target"),
-    new PropertyOp("EventOriginalTarget", "Event", "originalTarget"),
-    new PropertyOp("Window", "EventOriginalTarget", "defaultView"),
-
-    new CopyOp("Frame", "Window"),
-    new PropertyOp("FrameCollection", "Window", "frames"),
-    new CollectionOp("Frame", "FrameCollection"),
-    new PropertyOp("FrameCollection", "Frame", "frames"),
-    new PropertyOp("FrameDocument", "Frame", "document"),
-    new PropertyOp(null, "Frame", "window"),
-    new PropertyOp(null, "FrameDocument", "defaultView"),
-
-    new PropertyOp("FrameDocumentLocation", "FrameDocument", "location"),
-    new PropertyOp(null, "FrameDocumentLocation", "href"),
-    new PropertyOp("FrameLocation", "Frame", "location"),
-    new PropertyOp(null, "FrameLocation", "href"),
-
-    new MethodOp("FormCollection", "FrameDocument", "getElementsByTagName", "form"),
-    new MethodOp("FormCollection", "FrameDocument", "getElementsByTagName", "FORM"),
-    new CollectionOp("Form", "FormCollection"),
-    new PropertyOp("FormElementCollection", "Form", "elements"),
-    new CollectionOp("FormElement", "FormElementCollection"),
-    new PropertyOp("Style", "Form", "style"),
-
-    new PropertyOp(null, "FormElement", "type"),
-    new PropertyOp(null, "FormElement", "name"),
-    new PropertyOp(null, "FormElement", "value"),
-    new PropertyOp(null, "FormElement", "tagName"),
-    new PropertyOp(null, "FormElement", "id"),
-    new PropertyOp("Style", "FormElement", "style"),
-
-    new PropertyOp(null, "Style", "visibility"),
-
-    new MethodOp("MetaElementsCollection", "EventOriginalTarget", "getElementsByTagName", "meta"),
-    new CollectionOp("MetaElement", "MetaElementsCollection"),
-    new PropertyOp(null, "MetaElement", "httpEquiv"),
-
-    new MethodOp("InputElementCollection", "FrameDocument", "getElementsByTagName", "input"),
-    new MethodOp("InputElementCollection", "FrameDocument", "getElementsByTagName", "INPUT"),
-    new CollectionOp("InputElement", "InputElementCollection"),
-    new PropertyOp(null, "InputElement", "type"),
-    new PropertyOp(null, "InputElement", "name"),
-    new PropertyOp(null, "InputElement", "tagName"),
-    new PropertyOp(null, "InputElement", "form"),
-
-    new PropertyOp("BodyElement", "FrameDocument", "body"),
-    new PropertyOp("BodyInnerText", "BodyElement", "innerText"),
-
-    new PropertyOp("DocumentFormCollection", "FrameDocument", "forms"),
-    new CollectionOp("DocumentForm", "DocumentFormCollection"),
-  ]
-};
-PrefetcherRules[LastpassId] = LastpassRules;
deleted file mode 100644
--- a/toolkit/components/addoncompat/RemoteAddonsChild.jsm
+++ /dev/null
@@ -1,167 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-var EXPORTED_SYMBOLS = ["RemoteAddonsChild"];
-
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-// Similar to Python. Returns dict[key] if it exists. Otherwise,
-// sets dict[key] to default_ and returns default_.
-function setDefault(dict, key, default_) {
-  if (key in dict) {
-    return dict[key];
-  }
-  dict[key] = default_;
-  return default_;
-}
-
-// This code keeps track of a set of paths of the form [component_1,
-// ..., component_n]. The components can be strings or booleans. The
-// child is notified whenever a path is added or removed, and new
-// children can request the current set of paths. The purpose is to
-// keep track of all the observers and events that the child should
-// monitor for the parent.
-//
-// In the child, clients can watch for changes to all paths that start
-// with a given component.
-var NotificationTracker = {
-  init() {
-    let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
-               .getService(Ci.nsISyncMessageSender);
-    cpmm.addMessageListener("Addons:ChangeNotification", this);
-    this._paths = cpmm.initialProcessData.remoteAddonsNotificationPaths;
-    this._registered = new Map();
-    this._watchers = {};
-  },
-
-  receiveMessage(msg) {
-    let path = msg.data.path;
-    let count = msg.data.count;
-
-    let tracked = this._paths;
-    for (let component of path) {
-      tracked = setDefault(tracked, component, {});
-    }
-
-    tracked._count = count;
-
-    if (this._watchers[path[0]]) {
-      for (let watcher of this._watchers[path[0]]) {
-        this.runCallback(watcher, path, count);
-      }
-    }
-  },
-
-  runCallback(watcher, path, count) {
-    let pathString = path.join("/");
-    let registeredSet = this._registered.get(watcher);
-    let registered = registeredSet.has(pathString);
-    if (count && !registered) {
-      watcher.track(path, true);
-      registeredSet.add(pathString);
-    } else if (!count && registered) {
-      watcher.track(path, false);
-      registeredSet.delete(pathString);
-    }
-  },
-
-  findPaths(prefix) {
-    if (!this._paths) {
-      return [];
-    }
-
-    let tracked = this._paths;
-    for (let component of prefix) {
-      tracked = setDefault(tracked, component, {});
-    }
-
-    let result = [];
-    let enumerate = (tracked, curPath) => {
-      for (let component in tracked) {
-        if (component == "_count") {
-          result.push([curPath, tracked._count]);
-        } else {
-          let path = curPath.slice();
-          if (component === "true") {
-            component = true;
-          } else if (component === "false") {
-            component = false;
-          }
-          path.push(component);
-          enumerate(tracked[component], path);
-        }
-      }
-    };
-    enumerate(tracked, prefix);
-
-    return result;
-  },
-
-  findSuffixes(prefix) {
-    let paths = this.findPaths(prefix);
-    return paths.map(([path, count]) => path[path.length - 1]);
-  },
-
-  watch(component1, watcher) {
-    setDefault(this._watchers, component1, []).push(watcher);
-    this._registered.set(watcher, new Set());
-
-    let paths = this.findPaths([component1]);
-    for (let [path, count] of paths) {
-      this.runCallback(watcher, path, count);
-    }
-  },
-
-  unwatch(component1, watcher) {
-    let watchers = this._watchers[component1];
-    let index = watchers.lastIndexOf(watcher);
-    if (index > -1) {
-      watchers.splice(index, 1);
-    }
-
-    this._registered.delete(watcher);
-  },
-
-  getCount(component1) {
-    return this.findPaths([component1]).length;
-  },
-};
-
-
-var RemoteAddonsChild = {
-  _ready: false,
-
-  makeReady() {
-  },
-
-  init(global) {
-
-    if (!this._ready) {
-      if (!Services.cpmm.initialProcessData.remoteAddonsParentInitted) {
-        return null;
-      }
-
-      this.makeReady();
-      this._ready = true;
-    }
-
-    global.sendAsyncMessage("Addons:RegisterGlobal", {}, {global});
-
-    return [];
-  },
-
-  uninit(perTabShims) {
-    for (let shim of perTabShims) {
-      try {
-        shim.uninit();
-      } catch (e) {
-        Cu.reportError(e);
-      }
-    }
-  },
-
-  get useSyncWebProgress() {
-    return NotificationTracker.getCount("web-progress") > 0;
-  },
-};
deleted file mode 100644
--- a/toolkit/components/addoncompat/RemoteAddonsParent.jsm
+++ /dev/null
@@ -1,168 +0,0 @@
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-var EXPORTED_SYMBOLS = ["RemoteAddonsParent"];
-
-ChromeUtils.import("resource://gre/modules/RemoteWebProgress.jsm");
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-Cu.permitCPOWsInScope(this);
-
-// Similar to Python. Returns dict[key] if it exists. Otherwise,
-// sets dict[key] to default_ and returns default_.
-function setDefault(dict, key, default_) {
-  if (key in dict) {
-    return dict[key];
-  }
-  dict[key] = default_;
-  return default_;
-}
-
-// This code keeps track of a set of paths of the form [component_1,
-// ..., component_n]. The components can be strings or booleans. The
-// child is notified whenever a path is added or removed, and new
-// children can request the current set of paths. The purpose is to
-// keep track of all the observers and events that the child should
-// monitor for the parent.
-var NotificationTracker = {
-  // _paths is a multi-level dictionary. Let's add paths [A, B] and
-  // [A, C]. Then _paths will look like this:
-  //   { 'A': { 'B': { '_count': 1 }, 'C': { '_count': 1 } } }
-  // Each component in a path will be a key in some dictionary. At the
-  // end, the _count property keeps track of how many instances of the
-  // given path are present in _paths.
-  _paths: {},
-
-  init() {
-    let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-               .getService(Ci.nsIMessageBroadcaster);
-    ppmm.initialProcessData.remoteAddonsNotificationPaths = this._paths;
-  },
-
-  add(path) {
-    let tracked = this._paths;
-    for (let component of path) {
-      tracked = setDefault(tracked, component, {});
-    }
-    let count = tracked._count || 0;
-    count++;
-    tracked._count = count;
-
-    let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-               .getService(Ci.nsIMessageBroadcaster);
-    ppmm.broadcastAsyncMessage("Addons:ChangeNotification", {path, count});
-  },
-
-  remove(path) {
-    let tracked = this._paths;
-    for (let component of path) {
-      tracked = setDefault(tracked, component, {});
-    }
-    tracked._count--;
-
-    let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
-               .getService(Ci.nsIMessageBroadcaster);
-    ppmm.broadcastAsyncMessage("Addons:ChangeNotification", {path, count: tracked._count});
-  },
-};
-NotificationTracker.init();
-
-// An interposition is an object with three properties: methods,
-// getters, and setters. See multiprocessShims.js for an explanation
-// of how these are used. The constructor here just allows one
-// interposition to inherit members from another.
-function Interposition(name, base) {
-  this.name = name;
-  if (base) {
-    this.methods = Object.create(base.methods);
-    this.getters = Object.create(base.getters);
-    this.setters = Object.create(base.setters);
-  } else {
-    this.methods = Object.create(null);
-    this.getters = Object.create(null);
-    this.setters = Object.create(null);
-  }
-}
-
-var TabBrowserElementInterposition = new Interposition("TabBrowserElementInterposition");
-
-// This function returns a wrapper around an
-// nsIWebProgressListener. When the wrapper is invoked, it calls the
-// real listener but passes CPOWs for the nsIWebProgress and
-// nsIRequest arguments.
-var progressListeners = {global: new WeakMap(), tabs: new WeakMap()};
-function wrapProgressListener(kind, listener) {
-  if (progressListeners[kind].has(listener)) {
-    return progressListeners[kind].get(listener);
-  }
-
-  let ListenerHandler = {
-    get(target, name) {
-      if (name.startsWith("on")) {
-        return function(...args) {
-          listener[name].apply(listener, RemoteWebProgressManager.argumentsForAddonListener(kind, args));
-        };
-      }
-
-      return listener[name];
-    }
-  };
-  let listenerProxy = new Proxy(listener, ListenerHandler);
-
-  progressListeners[kind].set(listener, listenerProxy);
-  return listenerProxy;
-}
-
-TabBrowserElementInterposition.methods.addProgressListener = function(addon, target, listener) {
-  if (!target.ownerGlobal.gMultiProcessBrowser) {
-    return target.addProgressListener(listener);
-  }
-
-  NotificationTracker.add(["web-progress", addon]);
-  return target.addProgressListener(wrapProgressListener("global", listener));
-};
-
-TabBrowserElementInterposition.methods.removeProgressListener = function(addon, target, listener) {
-  if (!target.ownerGlobal.gMultiProcessBrowser) {
-    return target.removeProgressListener(listener);
-  }
-
-  NotificationTracker.remove(["web-progress", addon]);
-  return target.removeProgressListener(wrapProgressListener("global", listener));
-};
-
-var RemoteAddonsParent = {
-  init() {
-    let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager);
-    mm.addMessageListener("Addons:RegisterGlobal", this);
-
-    Services.ppmm.initialProcessData.remoteAddonsParentInitted = true;
-
-    Services.ppmm.loadProcessScript("data:,new " + function() {
-      ChromeUtils.import("resource://gre/modules/RemoteAddonsChild.jsm");
-    }, true);
-
-    this.globalToBrowser = new WeakMap();
-    this.browserToGlobal = new WeakMap();
-  },
-
-  getInterfaceInterpositions() {
-    return {};
-  },
-
-  getTaggedInterpositions() {
-    return {
-      TabBrowserElement: TabBrowserElementInterposition,
-    };
-  },
-
-  receiveMessage(msg) {
-    switch (msg.name) {
-    case "Addons:RegisterGlobal":
-      this.browserToGlobal.set(msg.target, msg.objects.global);
-      this.globalToBrowser.set(msg.objects.global, msg.target);
-      break;
-    }
-  }
-};
deleted file mode 100644
--- a/toolkit/components/addoncompat/addoncompat.manifest
+++ /dev/null
@@ -1,4 +0,0 @@
-component {1363d5f0-d95e-11e3-9c1a-0800200c9a66} multiprocessShims.js
-contract @mozilla.org/addons/multiprocess-shims;1 {1363d5f0-d95e-11e3-9c1a-0800200c9a66}
-component {50bc93ce-602a-4bef-bf3a-61fc749c4caf} defaultShims.js
-contract @mozilla.org/addons/default-addon-shims;1 {50bc93ce-602a-4bef-bf3a-61fc749c4caf}
deleted file mode 100644
--- a/toolkit/components/addoncompat/defaultShims.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-/**
- * Using multiprocessShims is optional, and if an add-on is e10s compatible it should not
- * use it. But in some cases we still want to use the interposition service for various
- * features so we have a default shim service.
- */
-
-function DefaultInterpositionService() {
-}
-
-DefaultInterpositionService.prototype = {
-  classID: Components.ID("{50bc93ce-602a-4bef-bf3a-61fc749c4caf}"),
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]),
-
-  getWhitelist() {
-    return [];
-  },
-
-  interposeProperty(addon, target, iid, prop) {
-    return null;
-  },
-
-  interposeCall(addonId, originalFunc, originalThis, args) {
-    args.splice(0, 0, addonId);
-    return originalFunc.apply(originalThis, args);
-  },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([DefaultInterpositionService]);
deleted file mode 100644
--- a/toolkit/components/addoncompat/moz.build
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-with Files('**'):
-    BUG_COMPONENT = ('Firefox', 'Extension Compatibility')
-
-EXTRA_COMPONENTS += [
-    'addoncompat.manifest',
-    'defaultShims.js',
-    'multiprocessShims.js',
-]
-
-EXTRA_JS_MODULES += [
-    'Prefetcher.jsm',
-    'RemoteAddonsChild.jsm',
-    'RemoteAddonsParent.jsm',
-]
deleted file mode 100644
--- a/toolkit/components/addoncompat/multiprocessShims.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-ChromeUtils.defineModuleGetter(this, "Prefetcher",
-                               "resource://gre/modules/Prefetcher.jsm");
-ChromeUtils.defineModuleGetter(this, "RemoteAddonsParent",
-                               "resource://gre/modules/RemoteAddonsParent.jsm");
-
-/**
- * This service overlays the API that the browser exposes to
- * add-ons. The overlay tries to make a multiprocess browser appear as
- * much as possible like a single process browser. An overlay can
- * replace methods, getters, and setters of arbitrary browser objects.
- *
- * Most of the actual replacement code is implemented in
- * RemoteAddonsParent. The code in this service simply decides how to
- * replace code. For a given type of object (say, an
- * nsIObserverService) the code in RemoteAddonsParent can register a
- * set of replacement methods. This set is called an
- * "interposition". The service keeps track of all the different
- * interpositions. Whenever a method is called on some part of the
- * browser API, this service gets a chance to replace it. To do so, it
- * consults its map based on the type of object. If an interposition
- * is found, the given method is looked up on it and called
- * instead. If no method (or no interposition) is found, then the
- * original target method is called as normal.
- *
- * For each method call, we need to determine the type of the target
- * object.  If the object is an old-style XPConnect wrapped native,
- * then the type is simply the interface that the method was called on
- * (Ci.nsIObserverService, say). For all other objects (WebIDL
- * objects, CPOWs, and normal JS objects), the type is determined by
- * calling getObjectTag.
- *
- * The interpositions defined in RemoteAddonsParent have three
- * properties: methods, getters, and setters. When accessing a
- * property, we first consult methods. If nothing is found, then we
- * consult getters or setters, depending on whether the access is a
- * get or a set.
- *
- * The methods in |methods| are functions that will be called whenever
- * the given method is called on the target object. They are passed
- * the same parameters as the original function except for two
- * additional ones at the beginning: the add-on ID and the original
- * target object that the method was called on. Additionally, the
- * value of |this| is set to the original target object.
- *
- * The values in |getters| and |setters| should also be
- * functions. They are called immediately when the given property is
- * accessed. The functions in |getters| take two parameters: the
- * add-on ID and the original target object. The functions in
- * |setters| take those arguments plus the value that the property is
- * being set to.
- */
-
-function AddonInterpositionService() {
-  Prefetcher.init();
-  RemoteAddonsParent.init();
-
-  // These maps keep track of the interpositions for all different
-  // kinds of objects.
-  this._interfaceInterpositions = RemoteAddonsParent.getInterfaceInterpositions();
-  this._taggedInterpositions = RemoteAddonsParent.getTaggedInterpositions();
-
-  let wl = [];
-  for (let v in this._interfaceInterpositions) {
-    let interp = this._interfaceInterpositions[v];
-    wl.push(...Object.getOwnPropertyNames(interp.methods));
-    wl.push(...Object.getOwnPropertyNames(interp.getters));
-    wl.push(...Object.getOwnPropertyNames(interp.setters));
-  }
-
-  for (let v in this._taggedInterpositions) {
-    let interp = this._taggedInterpositions[v];
-    wl.push(...Object.getOwnPropertyNames(interp.methods));
-    wl.push(...Object.getOwnPropertyNames(interp.getters));
-    wl.push(...Object.getOwnPropertyNames(interp.setters));
-  }
-
-  let nameSet = new Set();
-  wl = wl.filter(function(item) {
-    if (nameSet.has(item))
-      return true;
-
-    nameSet.add(item);
-    return true;
-  });
-
-  this._whitelist = wl;
-}
-
-AddonInterpositionService.prototype = {
-  classID: Components.ID("{1363d5f0-d95e-11e3-9c1a-0800200c9a66}"),
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAddonInterposition, Ci.nsISupportsWeakReference]),
-
-  getWhitelist() {
-    return this._whitelist;
-  },
-
-  // When the interface is not known for a method call, this code
-  // determines the type of the target object.
-  getObjectTag(target) {
-    if (Cu.isCrossProcessWrapper(target)) {
-      return Cu.getCrossProcessWrapperTag(target);
-    }
-
-    if (target.ownerGlobal && target === target.ownerGlobal.gBrowser) {
-      return "TabBrowserElement";
-    }
-
-    return "generic";
-  },
-
-  interposeProperty(addon, target, iid, prop) {
-    let interp;
-    if (iid) {
-      interp = this._interfaceInterpositions[iid];
-    } else {
-      try {
-        interp = this._taggedInterpositions[this.getObjectTag(target)];
-      } catch (e) {
-        Cu.reportError(new Components.Exception("Failed to interpose object", e.result, Components.stack.caller));
-      }
-    }
-
-    if (!interp) {
-      return Prefetcher.lookupInCache(addon, target, prop);
-    }
-
-    let desc = { configurable: false, enumerable: true };
-
-    if ("methods" in interp && prop in interp.methods) {
-      desc.writable = false;
-      desc.value = function(...args) {
-        return interp.methods[prop](addon, target, ...args);
-      };
-
-      return desc;
-    } else if ("getters" in interp && prop in interp.getters) {
-      desc.get = function() { return interp.getters[prop](addon, target); };
-
-      if ("setters" in interp && prop in interp.setters) {
-        desc.set = function(v) { return interp.setters[prop](addon, target, v); };
-      }
-
-      return desc;
-    }
-
-    return Prefetcher.lookupInCache(addon, target, prop);
-  },
-
-  interposeCall(addonId, originalFunc, originalThis, args) {
-    args.splice(0, 0, addonId);
-    return originalFunc.apply(originalThis, args);
-  },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AddonInterpositionService]);
--- a/toolkit/components/moz.build
+++ b/toolkit/components/moz.build
@@ -11,17 +11,16 @@ with Files('**'):
 if CONFIG['MOZ_ENABLE_XREMOTE']:
     DIRS += ['remote']
 
 DIRS += [
     'aboutcache',
     'aboutcheckerboard',
     'aboutmemory',
     'aboutperformance',
-    'addoncompat',
     'alerts',
     'apppicker',
     'asyncshutdown',
     'backgroundhangmonitor',
     'browser',
     'cloudstorage',
     'commandlines',
     'contentprefs',
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* eslint-env mozilla/frame-script */
 
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 ChromeUtils.import("resource://gre/modules/BrowserUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/RemoteAddonsChild.jsm");
 ChromeUtils.import("resource://gre/modules/Timer.jsm");
 
 ChromeUtils.defineModuleGetter(this, "PageThumbUtils",
   "resource://gre/modules/PageThumbUtils.jsm");
 
 ChromeUtils.defineModuleGetter(this, "Utils",
   "resource://gre/modules/sessionstore/Utils.jsm");
 
@@ -110,21 +109,17 @@ var WebProgressListener = {
       // DOMWindow is not necessarily the content-window with subframes.
       DOMWindow: domWindow,
       webProgress: aWebProgress,
       request: aRequest,
     };
   },
 
   _send(name, data, objects) {
-    if (RemoteAddonsChild.useSyncWebProgress) {
-      sendRpcMessage(name, data, objects);
-    } else {
-      sendAsyncMessage(name, data, objects);
-    }
+    sendAsyncMessage(name, data, objects);
   },
 
   onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
     let json = this._setupJSON(aWebProgress, aRequest, aStateFlags);
     let objects = this._setupObjects(aWebProgress, aRequest);
 
     json.stateFlags = aStateFlags;
     json.status = aStatus;
@@ -600,25 +595,16 @@ addMessageListener("Browser:CreateAboutB
   if (!content.document || content.document.documentURI != "about:blank") {
     throw new Error("Can't create a content viewer unless on about:blank");
   }
   let principal = aMessage.data;
   principal = BrowserUtils.principalWithMatchingOA(principal, content.document.nodePrincipal);
   docShell.createAboutBlankContentViewer(principal);
 });
 
-// The AddonsChild needs to be rooted so that it stays alive as long as
-// the tab.
-var AddonsChild = RemoteAddonsChild.init(this);
-if (AddonsChild) {
-  addEventListener("unload", () => {
-    RemoteAddonsChild.uninit(AddonsChild);
-  });
-}
-
 addMessageListener("InPermitUnload", msg => {
   let inPermitUnload = docShell.contentViewer && docShell.contentViewer.inPermitUnload;
   sendAsyncMessage("InPermitUnload", {id: msg.data.id, inPermitUnload});
 });
 
 addMessageListener("PermitUnload", msg => {
   sendAsyncMessage("PermitUnload", {id: msg.data.id, kind: "start"});
 
--- a/toolkit/modules/RemoteWebProgress.jsm
+++ b/toolkit/modules/RemoteWebProgress.jsm
@@ -67,45 +67,16 @@ RemoteWebProgress.prototype = {
 
 function RemoteWebProgressManager(aBrowser) {
   this._topLevelWebProgress = new RemoteWebProgress(this, true);
   this._progressListeners = [];
 
   this.swapBrowser(aBrowser);
 }
 
-RemoteWebProgressManager.argumentsForAddonListener = function(kind, args) {
-  function checkType(arg, typ) {
-    if (!arg) {
-      return false;
-    }
-    return (arg instanceof typ) ||
-      (arg instanceof Ci.nsISupports && arg.wrappedJSObject instanceof typ);
-  }
-
-  // Arguments for a tabs listener are shifted over one since the
-  // <browser> element is passed as the first argument.
-  let webProgressIndex = 0;
-  let requestIndex = 1;
-  if (kind == "tabs") {
-    webProgressIndex = 1;
-    requestIndex = 2;
-  }
-
-  if (checkType(args[webProgressIndex], RemoteWebProgress)) {
-    args[webProgressIndex] = args[webProgressIndex].wrappedJSObject._webProgressCPOW;
-  }
-
-  if (checkType(args[requestIndex], RemoteWebProgressRequest)) {
-    args[requestIndex] = args[requestIndex].wrappedJSObject._requestCPOW;
-  }
-
-  return args;
-};
-
 RemoteWebProgressManager.prototype = {
   swapBrowser(aBrowser) {
     if (this._messageManager) {
       this._messageManager.removeMessageListener("Content:StateChange", this);
       this._messageManager.removeMessageListener("Content:LocationChange", this);
       this._messageManager.removeMessageListener("Content:SecurityChange", this);
       this._messageManager.removeMessageListener("Content:StatusChange", this);
       this._messageManager.removeMessageListener("Content:ProgressChange", this);
--- a/toolkit/mozapps/extensions/AddonManagerStartup.cpp
+++ b/toolkit/mozapps/extensions/AddonManagerStartup.cpp
@@ -23,17 +23,16 @@
 #include "mozilla/Unused.h"
 #include "mozilla/ErrorResult.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsAppRunner.h"
 #include "nsContentUtils.h"
 #include "nsChromeRegistry.h"
-#include "nsIAddonInterposition.h"
 #include "nsIDOMWindowUtils.h" // for nsIJSRAIIHelper
 #include "nsIFileURL.h"
 #include "nsIIOService.h"
 #include "nsIJARProtocolHandler.h"
 #include "nsIJARURI.h"
 #include "nsIStringEnumerator.h"
 #include "nsIZipReader.h"
 #include "nsJSUtils.h"
@@ -506,33 +505,16 @@ InstallLocation::InstallLocation(JSConte
   mAddonsIter.emplace(cx, mAddonsObj, this);
 }
 
 
 /*****************************************************************************
  * XPC interfacing
  *****************************************************************************/
 
-static void
-EnableShimsAndCPOWs(const nsAString& addonId, bool enableShims)
-{
-  NS_ConvertUTF16toUTF8 id(addonId);
-
-  if (enableShims) {
-    nsCOMPtr<nsIAddonInterposition> interposition =
-      do_GetService("@mozilla.org/addons/multiprocess-shims;1");
-
-    if (!interposition || !xpc::SetAddonInterposition(id, interposition)) {
-      return;
-    }
-  }
-
-  Unused << xpc::AllowCPOWsInAddon(id, true);
-}
-
 Result<Ok, nsresult>
 AddonManagerStartup::AddInstallLocation(Addon& addon)
 {
   nsCOMPtr<nsIFile> file;
   MOZ_TRY_VAR(file, addon.FullPath());
 
   nsString path;
   MOZ_TRY(file->GetPath(path));
@@ -608,30 +590,29 @@ AddonManagerStartup::InitializeExtension
   NS_ENSURE_TRUE(locations.isObject(), NS_ERROR_INVALID_ARG);
 
   mInitialized = true;
 
   if (!Preferences::GetBool("extensions.defaultProviders.enabled", true)) {
     return NS_OK;
   }
 
-  bool enableInterpositions = Preferences::GetBool("extensions.interposition.enabled", false);
-
   JS::RootedObject locs(cx, &locations.toObject());
   for (auto e1 : PropertyIter(cx, locs)) {
     InstallLocation loc(e1);
 
     for (auto e2 : loc.Addons()) {
       Addon addon(e2);
 
       if (addon.Enabled() && !addon.Bootstrapped()) {
         Unused << AddInstallLocation(addon);
 
         if (addon.ShimsEnabled()) {
-          EnableShimsAndCPOWs(addon.Id(), enableInterpositions);
+          NS_ConvertUTF16toUTF8 id(addon.Id());
+          Unused << xpc::AllowCPOWsInAddon(id, true);
         }
       }
     }
   }
 
   return NS_OK;
 }
 
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -80,17 +80,16 @@ const PREF_XPI_FILE_WHITELISTED       = 
 // xpinstall.signatures.required only supported in dev builds
 const PREF_XPI_SIGNATURES_REQUIRED    = "xpinstall.signatures.required";
 const PREF_XPI_SIGNATURES_DEV_ROOT    = "xpinstall.signatures.dev-root";
 const PREF_XPI_PERMISSIONS_BRANCH     = "xpinstall.";
 const PREF_INSTALL_REQUIRESECUREORIGIN = "extensions.install.requireSecureOrigin";
 const PREF_INSTALL_DISTRO_ADDONS      = "extensions.installDistroAddons";
 const PREF_BRANCH_INSTALLED_ADDON     = "extensions.installedDistroAddon.";
 const PREF_DISTRO_ADDONS_PERMS        = "extensions.distroAddons.promptForPermissions";
-const PREF_INTERPOSITION_ENABLED      = "extensions.interposition.enabled";
 const PREF_SYSTEM_ADDON_SET           = "extensions.systemAddonSet";
 const PREF_SYSTEM_ADDON_UPDATE_URL    = "extensions.systemAddon.update.url";
 const PREF_ALLOW_LEGACY               = "extensions.legacy.enabled";
 const PREF_ALLOW_NON_MPC              = "extensions.allow-non-mpc-extensions";
 
 const PREF_EM_MIN_COMPAT_APP_VERSION      = "extensions.minCompatibleAppVersion";
 const PREF_EM_MIN_COMPAT_PLATFORM_VERSION = "extensions.minCompatiblePlatformVersion";
 
@@ -4227,21 +4226,16 @@ var XPIProvider = {
 
     let activeAddon = this.activeAddons.get(aId);
 
     logger.debug("Loading bootstrap scope from " + aFile.path);
 
     let principal = Cc["@mozilla.org/systemprincipal;1"].
                     createInstance(Ci.nsIPrincipal);
     if (!aMultiprocessCompatible) {
-      if (Services.prefs.getBoolPref(PREF_INTERPOSITION_ENABLED, false)) {
-        let interposition = Cc["@mozilla.org/addons/multiprocess-shims;1"].
-          getService(Ci.nsIAddonInterposition);
-        Cu.setAddonInterposition(aId, interposition);
-      }
       Cu.allowCPOWsInAddon(aId, true);
     }
 
     if (!aFile.exists()) {
       activeAddon.bootstrapScope =
         new Cu.Sandbox(principal, { sandboxName: aFile.path,
                                     addonId: aId,
                                     wantGlobalProperties: ["ChromeUtils"],
@@ -4295,19 +4289,16 @@ var XPIProvider = {
   /**
    * Unloads a bootstrap scope by dropping all references to it and then
    * updating the list of active add-ons with the crash reporter.
    *
    * @param  aId
    *         The add-on's ID
    */
   unloadBootstrapScope(aId) {
-    // In case the add-on was not multiprocess-compatible, deregister
-    // any interpositions for it.
-    Cu.setAddonInterposition(aId, null);
     Cu.allowCPOWsInAddon(aId, false);
 
     this.activeAddons.delete(aId);
     this.addAddonsToCrashReporter();
 
     // Notify the BrowserToolboxProcess that an addon has been unloaded.
     let wrappedJSObject = { id: aId, options: { global: null }};
     Services.obs.notifyObservers({ wrappedJSObject }, "toolbox-update-addon-options");
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -6,17 +6,16 @@
 #include "nsAppRunner.h"
 #include "nsToolkitCompsCID.h"
 #include "nsXREDirProvider.h"
 #include "mozilla/AddonManagerStartup.h"
 
 #include "jsapi.h"
 #include "xpcpublic.h"
 
-#include "nsIAddonInterposition.h"
 #include "nsIAppStartup.h"
 #include "nsIDirectoryEnumerator.h"
 #include "nsIFile.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIToolkitChromeRegistry.h"
 #include "nsIToolkitProfileService.h"