Bug 1443983: Part 2 - Remove remaining interpositions. r?mconley draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 07 Mar 2018 18:10:24 -0800
changeset 764703 059d7a6e76c7503d3e21ca449a8ac19981833456
parent 764702 3ce5cfda782db70e80f0530a48ce54f343bd42ba
child 764704 442f3bef52f4a186dd878dc2c7dde4620441af54
push id101827
push usermaglione.k@gmail.com
push dateThu, 08 Mar 2018 02:14:42 +0000
reviewersmconley
bugs1443983
milestone60.0a1
Bug 1443983: Part 2 - Remove remaining interpositions. r?mconley MozReview-Commit-ID: AHwNsBB7OAQ
CLOBBER
browser/base/content/tabbrowser.js
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/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/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"],
     });
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/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"
@@ -507,29 +506,19 @@ InstallLocation::InstallLocation(JSConte
 }
 
 
 /*****************************************************************************
  * XPC interfacing
  *****************************************************************************/
 
 static void
-EnableShimsAndCPOWs(const nsAString& addonId, bool enableShims)
+EnableShimsAndCPOWs(const nsAString& addonId)
 {
   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());
@@ -608,30 +597,28 @@ 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);
+          EnableShimsAndCPOWs(addon.Id());
         }
       }
     }
   }
 
   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"],
--- 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"