Merge m-c to m-i.
authorMs2ger <ms2ger@gmail.com>
Mon, 09 Apr 2012 09:32:28 +0200
changeset 94551 e0c118cd4f86cde23b457ae9d2b7b25b979bbb6d
parent 94494 22521568cf79dc1059a266bb5835266161c46dc3 (current diff)
parent 94550 2b364a0ca1da908db47d92dba3edf378f6ecc8a2 (diff)
child 94552 cdd4141ec53b1ef60225e8587ae0d1b9ee9d7518
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.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
Merge m-c to m-i.
config/rules.mk.orig
js/src/config/rules.mk.orig
toolkit/components/places/tests/queries/test_redirectsMode.js
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -502,17 +502,17 @@ function HistoryMenu(aPopupShowingEvent)
   // views definitions, and we don't need them there.
   // Defining the prototype inheritance in the prototype itself would cause
   // browser.js to halt on "PlacesMenu is not defined" error.
   this.__proto__.__proto__ = PlacesMenu.prototype;
   XPCOMUtils.defineLazyServiceGetter(this, "_ss",
                                      "@mozilla.org/browser/sessionstore;1",
                                      "nsISessionStore");
   PlacesMenu.call(this, aPopupShowingEvent,
-                  "place:redirectsMode=2&sort=4&maxResults=15");
+                  "place:sort=4&maxResults=15");
 }
 
 HistoryMenu.prototype = {
   toggleRecentlyClosedTabs: function HM_toggleRecentlyClosedTabs() {
     // enable/disable the Recently Closed Tabs sub menu
     var undoMenu = this._rootElt.getElementsByClassName("recentlyClosedTabsMenu")[0];
 
     // no restorable tabs, so disable menu
--- a/browser/components/certerror/content/aboutCertError.css
+++ b/browser/components/certerror/content/aboutCertError.css
@@ -42,11 +42,13 @@
 /* Logical CSS rules belong here, but presentation & theming rules
    should live in the CSS of the appropriate theme */
 
 #technicalContentText {
   overflow: auto;
   white-space: pre-wrap;
 }
 
+.expander[hidden],
+.expander[hidden] + *,
 .expander[collapsed] + * {
   display: none;
 }
--- a/browser/components/certerror/content/aboutCertError.xhtml
+++ b/browser/components/certerror/content/aboutCertError.xhtml
@@ -121,20 +121,18 @@
         if (getCSSClass() == "expertBadCert") {
           toggle('technicalContent');
           toggle('expertContent');
         }
 
         // Disallow overrides if this is a Strict-Transport-Security
         // host and the cert is bad (STS Spec section 7.3) or if the
         // certerror is in a frame (bug 633691).
-        if (getCSSClass() == "badStsCert" || window != top) {
-          var ec = document.getElementById('expertContent');
-          ec.parentNode.removeChild(ec);
-        }
+        if (getCSSClass() == "badStsCert" || window != top)
+          document.getElementById("expertContent").setAttribute("hidden", "true");
         
         var tech = document.getElementById("technicalContentText");
         if (tech)
           tech.textContent = getDescription();
         
         addDomainErrorLink();
       }
       
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1347,17 +1347,17 @@ BrowserGlue.prototype = {
   ensurePlacesDefaultQueriesInitialized:
   function BG_ensurePlacesDefaultQueriesInitialized() {
     // This is actual version of the smart bookmarks, must be increased every
     // time smart bookmarks change.
     // When adding a new smart bookmark below, its newInVersion property must
     // be set to the version it has been added in, we will compare its value
     // to users' smartBookmarksVersion and add new smart bookmarks without
     // recreating old deleted ones.
-    const SMART_BOOKMARKS_VERSION = 3;
+    const SMART_BOOKMARKS_VERSION = 4;
     const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
     const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
 
     // TODO bug 399268: should this be a pref?
     const MAX_RESULTS = 10;
 
     // Get current smart bookmarks version.  If not set, create them.
     let smartBookmarksCurrentVersion = 0;
@@ -1375,19 +1375,17 @@ BrowserGlue.prototype = {
       runBatched: function BG_EPDQI_runBatched() {
         let menuIndex = 0;
         let toolbarIndex = 0;
         let bundle = Services.strings.createBundle("chrome://browser/locale/places/places.properties");
 
         let smartBookmarks = {
           MostVisited: {
             title: bundle.GetStringFromName("mostVisitedTitle"),
-            uri: NetUtil.newURI("place:redirectsMode=" +
-                                Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET +
-                                "&sort=" +
+            uri: NetUtil.newURI("place:sort=" +
                                 Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
                                 "&maxResults=" + MAX_RESULTS),
             parent: PlacesUtils.toolbarFolderId,
             position: toolbarIndex++,
             newInVersion: 1
           },
           RecentlyBookmarked: {
             title: bundle.GetStringFromName("recentlyBookmarkedTitle"),
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -728,16 +728,18 @@ PlacesViewBase.prototype = {
     if ("_isRTL" in this)
       return this._isRTL;
 
     return this._isRTL = document.defaultView
                                  .getComputedStyle(this.viewElt, "")
                                  .direction == "rtl";
   },
 
+  get ownerWindow() window,
+
   /**
    * Adds an "Open All in Tabs" menuitem to the bottom of the popup.
    * @param aPopup
    *        a Places popup.
    */
   _mayAddCommandsItems: function PVB__mayAddCommandsItems(aPopup) {
     // The command items are never added to the root popup.
     if (aPopup == this._rootElt)
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -331,17 +331,17 @@ var PlacesOrganizer = {
         // Open associated uri in the browser.
         PlacesOrganizer.openSelectedNode(aEvent);
       }
       else if (middleClick &&
                PlacesUtils.nodeIsContainer(selectedNode)) {
         // The command execution function will take care of seeing if the
         // selection is a folder or a different container type, and will
         // load its contents in tabs.
-        PlacesUIUtils.openContainerNodeInTabs(selectedNode, aEvent);
+        PlacesUIUtils.openContainerNodeInTabs(selectedNode, aEvent, currentView);
       }
     }
   },
 
   /**
    * Handle focus changes on the trees.
    * When moving focus between panes we should update the details pane contents.
    * @param   aEvent
@@ -358,17 +358,17 @@ var PlacesOrganizer = {
     if (aContainer.itemId != -1)
       this._places.selectItems([aContainer.itemId]);
     else if (PlacesUtils.nodeIsQuery(aContainer))
       this._places.selectPlaceURI(aContainer.uri);
   },
 
   openSelectedNode: function PO_openSelectedNode(aEvent) {
     PlacesUIUtils.openNodeWithEvent(this._content.selectedNode, aEvent,
-                                    this._content.treeBoxObject.view);
+                                    this._content);
   },
 
   /**
    * Returns the options associated with the query currently loaded in the
    * main places pane.
    */
   getCurrentOptions: function PO_getCurrentOptions() {
     return PlacesUtils.asQuery(this._content.result.root).queryOptions;
--- a/browser/components/places/content/sidebarUtils.js
+++ b/browser/components/places/content/sidebarUtils.js
@@ -81,25 +81,25 @@ var SidebarUtils = {
 
     if (aEvent.button == 0 && isContainer && !openInTabs) {
       tbo.view.toggleOpenState(row.value);
       return;
     }
     else if (!mouseInGutter && openInTabs &&
             aEvent.originalTarget.localName == "treechildren") {
       tbo.view.selection.select(row.value);
-      PlacesUIUtils.openContainerNodeInTabs(aTree.selectedNode, aEvent, tbo.view);
+      PlacesUIUtils.openContainerNodeInTabs(aTree.selectedNode, aEvent, aTree);
     }
     else if (!mouseInGutter && !isContainer &&
              aEvent.originalTarget.localName == "treechildren") {
       // Clear all other selection since we're loading a link now. We must
       // do this *before* attempting to load the link since openURL uses
       // selection as an indication of which link to load.
       tbo.view.selection.select(row.value);
-      PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent, tbo.view);
+      PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent, aTree);
     }
   },
 
   handleTreeKeyPress: function SU_handleTreeKeyPress(aEvent) {
     // XXX Bug 627901: Post Fx4, this method should take a tree parameter.
     let node = aEvent.target.selectedNode;
     if (node) {
       let view = PlacesUIUtils.getViewForNode(node);
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -694,16 +694,20 @@
         ]]></body>
       </method>
 
       <method name="destroyContextMenu">
         <parameter name="aPopup"/>
           this._contextMenuShown = false;
         <body/>
       </method>
+
+      <property name="ownerWindow"
+                readonly="true"
+                onget="return window;"/>
     </implementation>
     <handlers>
       <handler event="focus"><![CDATA[
         this._cachedInsertionPoint = undefined;
 
         // See select handler. We need the sidebar's places commandset to be
         // updated as well
         document.commandDispatcher.updateCommands("focus");
--- a/browser/components/places/src/PlacesUIUtils.jsm
+++ b/browser/components/places/src/PlacesUIUtils.jsm
@@ -372,22 +372,16 @@ var PlacesUIUtils = {
    *        Whether the dialog is allowed to resize.  Do not pass this for new
    *        callers since it's deprecated.  It'll be removed in future releases.
    *
    * @see documentation at the top of bookmarkProperties.js
    * @return true if any transaction has been performed, false otherwise.
    */
   showBookmarkDialog:
   function PUIU_showBookmarkDialog(aInfo, aParentWindow, aResizable) {
-    // This is a compatibility shim for add-ons.  It will warn in the Error
-    // Console when used.
-    if (!aParentWindow) {
-      aParentWindow = this._getWindow(null);
-    }
-
     // Preserve size attributes differently based on the fact the dialog has
     // a folder picker or not.  If the picker is visible, the dialog should
     // be resizable since it may not show enough content for the folders
     // hierarchy.
     let hasFolderPicker = !("hiddenRows" in aInfo) ||
                           aInfo.hiddenRows.indexOf("folderPicker") == -1;
     let resizable = aResizable !== undefined ? aResizable : hasFolderPicker;
     // Use a different chrome url, since this allows to persist different sizes,
@@ -616,64 +610,29 @@ var PlacesUIUtils = {
 
     var loadInBackground = where == "tabshifted" ? true : false;
     // For consistency, we want all the bookmarks to open in new tabs, instead
     // of having one of them replace the currently focused tab.  Hence we call
     // loadTabs with aReplace set to false.
     browserWindow.gBrowser.loadTabs(urls, loadInBackground, false);
   },
 
-  /**
-   * Helper method for methods which are forced to take a view/window
-   * parameter as an optional parameter.  It will be removed post Fx4.
-   */
-  _getWindow: function PUIU__getWindow(aView) {
-    if (aView) {
-      // Pratically, this is the case for places trees.
-      if (aView instanceof Components.interfaces.nsIDOMNode)
-        return aView.ownerDocument.defaultView;
-
-      return Cu.getGlobalForObject(aView);
-    }
-
-    let caller = arguments.callee.caller;
-
-    // If a view wasn't expected, the method should have got a window.
-    if (aView === null) {
-      Components.utils.reportError("The api has changed. A window should be " +
-                                   "passed to " + caller.name + ".  Not " +
-                                   "passing a window will throw in a future " +
-                                   "release.");
-    }
-    else {
-      Components.utils.reportError("The api has changed. A places view " +
-                                   "should be passed to " + caller.name + ". " +
-                                   "Not passing a view will throw in a future " +
-                                   "release.");
-    }
-
-    // This could certainly break in some edge cases (like bug 562998), but
-    // that's the best we should do for those extreme backwards-compatibility cases.
-    let topBrowserWin = this._getTopBrowserWin();
-    return topBrowserWin ? topBrowserWin : focusManager.focusedWindow;
-  },
-
   openContainerNodeInTabs:
   function PUIU_openContainerInTabs(aNode, aEvent, aView) {
-    let window = this._getWindow(aView);
+    let window = aView.ownerWindow;
 
     let urlsToOpen = PlacesUtils.getURLsForContainerNode(aNode);
     if (!this._confirmOpenInTabs(urlsToOpen.length, window))
       return;
 
     this._openTabset(urlsToOpen, aEvent, window);
   },
 
   openURINodesInTabs: function PUIU_openURINodesInTabs(aNodes, aEvent, aView) {
-    let window = this._getWindow(aView);
+    let window = aView.ownerWindow;
 
     let urlsToOpen = [];
     for (var i=0; i < aNodes.length; i++) {
       // Skip over separators and folders.
       if (PlacesUtils.nodeIsURI(aNodes[i]))
         urlsToOpen.push({uri: aNodes[i].uri, isBookmark: PlacesUtils.nodeIsBookmark(aNodes[i])});
     }
     this._openTabset(urlsToOpen, aEvent, window);
@@ -688,27 +647,27 @@ var PlacesUIUtils = {
    * @param   aEvent
    *          The DOM mouse/key event with modifier keys set that track the
    *          user's preferred destination window or tab.
    * @param   aView
    *          The controller associated with aNode.
    */
   openNodeWithEvent:
   function PUIU_openNodeWithEvent(aNode, aEvent, aView) {
-    let window = this._getWindow(aView);
+    let window = aView.ownerWindow;
     this._openNodeIn(aNode, window.whereToOpenLink(aEvent), window);
   },
 
   /**
    * Loads the node's URL in the appropriate tab or window or as a
    * web panel.
    * see also openUILinkIn
    */
   openNodeIn: function PUIU_openNodeIn(aNode, aWhere, aView) {
-    let window = this._getWindow(aView);
+    let window = aView.ownerWindow;
     this._openNodeIn(aNode, aWhere, window);
   },
 
   _openNodeIn: function PUIU_openNodeIn(aNode, aWhere, aWindow) {
     if (aNode && PlacesUtils.nodeIsURI(aNode) &&
         this.checkURLSecurity(aNode, aWindow)) {
       let isBookmark = PlacesUtils.nodeIsBookmark(aNode);
 
--- a/browser/components/places/tests/unit/head_bookmarks.js
+++ b/browser/components/places/tests/unit/head_bookmarks.js
@@ -97,15 +97,15 @@ let (XULAppInfo = {
 
 
 const FILENAME_BOOKMARKS_HTML = "bookmarks.html";
 let (backup_date = new Date().toLocaleFormat("%Y-%m-%d")) {
   const FILENAME_BOOKMARKS_JSON = "bookmarks-" + backup_date + ".json";
 }
 
 // Smart bookmarks constants.
-const SMART_BOOKMARKS_VERSION = 3;
+const SMART_BOOKMARKS_VERSION = 4;
 const SMART_BOOKMARKS_ON_TOOLBAR = 1;
 const SMART_BOOKMARKS_ON_MENU = 3; // Takes in count the additional separator.
 
 // Default bookmarks constants.
 const DEFAULT_BOOKMARKS_ON_TOOLBAR = 1;
 const DEFAULT_BOOKMARKS_ON_MENU = 1;
--- a/browser/config/mozconfigs/linux32/nightly
+++ b/browser/config/mozconfigs/linux32/nightly
@@ -6,16 +6,21 @@ ac_add_options --enable-signmar
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 . $topsrcdir/build/unix/mozconfig.linux
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
+# This will overwrite the default of stripping everything and keep the symbol table.
+# This is useful for profiling and debugging and only increases the package size
+# by 2 MBs.
+STRIP_FLAGS="--strip-debug"
+
 # PGO
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/config/mozconfigs/linux64/nightly
+++ b/browser/config/mozconfigs/linux64/nightly
@@ -6,16 +6,21 @@ ac_add_options --enable-signmar
 # Nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 . $topsrcdir/build/unix/mozconfig.linux
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
+# This will overwrite the default of stripping everything and keep the symbol table.
+# This is useful for profiling and debugging and only increases the package size
+# by 2 MBs.
+STRIP_FLAGS="--strip-debug"
+
 # PGO
 mk_add_options PROFILE_GEN_SCRIPT='$(PYTHON) @MOZ_OBJDIR@/_profile/pgo/profileserver.py 10'
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/browser/modules/NewTabUtils.jsm
+++ b/browser/modules/NewTabUtils.jsm
@@ -427,19 +427,16 @@ let PlacesProvider = {
    */
   getLinks: function PlacesProvider_getLinks(aCallback) {
     let options = PlacesUtils.history.getNewQueryOptions();
     options.maxResults = HISTORY_RESULTS_LIMIT;
 
     // Sort by frecency, descending.
     options.sortingMode = Ci.nsINavHistoryQueryOptions.SORT_BY_FRECENCY_DESCENDING
 
-    // We don't want source redirects for this query.
-    options.redirectsMode = Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET;
-
     let links = [];
 
     let callback = {
       handleResult: function (aResultSet) {
         let row;
 
         while (row = aResultSet.getNextRow()) {
           let url = row.getResultByIndex(1);
--- a/browser/modules/WindowsJumpLists.jsm
+++ b/browser/modules/WindowsJumpLists.jsm
@@ -472,18 +472,16 @@ var WinTaskbarJumpList =
    * Nav history helpers
    */
 
   _getHistoryResults:
   function WTBLJL__getHistoryResults(aSortingMode, aLimit, aCallback, aScope) {
     var options = PlacesUtils.history.getNewQueryOptions();
     options.maxResults = aLimit;
     options.sortingMode = aSortingMode;
-    // We don't want source redirects for these queries.
-    options.redirectsMode = Ci.nsINavHistoryQueryOptions.REDIRECTS_MODE_TARGET;
     var query = PlacesUtils.history.getNewQuery();
 
     // Return the pending statement to the caller, to allow cancelation.
     return PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
                               .asyncExecuteLegacyQueries([query], 1, options, {
       handleResult: function (aResultSet) {
         for (let row; (row = aResultSet.getNextRow());) {
           try {
--- a/client.mk
+++ b/client.mk
@@ -289,23 +289,25 @@ EXTRA_CONFIG_DEPS := \
 	$(NULL)
 
 $(CONFIGURES): %: %.in $(EXTRA_CONFIG_DEPS)
 	@$(PYTHON) $(TOPSRCDIR)/js/src/config/check-sync-dirs.py $(TOPSRCDIR)/js/src/build $(TOPSRCDIR)/build
 	@echo Generating $@ using autoconf
 	cd $(@D); $(AUTOCONF)
 
 CONFIG_STATUS_DEPS := \
-	$(wildcard $(CONFIGURES)) \
-	$(TOPSRCDIR)/allmakefiles.sh \
-	$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
-	$(wildcard $(TOPSRCDIR)/config/milestone.txt) \
-	$(wildcard $(TOPSRCDIR)/js/src/config/milestone.txt) \
-	$(wildcard $(TOPSRCDIR)/browser/config/version.txt) \
-	$(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
+	$(wildcard \
+        $(CONFIGURES) \
+        $(TOPSRCDIR)/allmakefiles.sh \
+        $(TOPSRCDIR)/nsprpub/configure \
+        $(TOPSRCDIR)/config/milestone.txt \
+        $(TOPSRCDIR)/js/src/config/milestone.txt \
+        $(TOPSRCDIR)/browser/config/version.txt \
+        $(TOPSRCDIR)/*/confvars.sh \
+	) \
 	$(NULL)
 
 CONFIGURE_ENV_ARGS += \
   MAKE="$(MAKE)" \
   $(NULL)
 
 # configure uses the program name to determine @srcdir@. Calling it without
 #   $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -226,16 +226,17 @@ MOZ_COMPONENT_NSPR_LIBS=@MOZ_COMPONENT_N
 MOZ_FIX_LINK_PATHS=@MOZ_FIX_LINK_PATHS@
 
 XPCOM_FROZEN_LDOPTS=@XPCOM_FROZEN_LDOPTS@
 XPCOM_LIBS=@XPCOM_LIBS@
 LIBXUL_LIBS=@LIBXUL_LIBS@
 
 ENABLE_STRIP	= @ENABLE_STRIP@
 PKG_SKIP_STRIP	= @PKG_SKIP_STRIP@
+STRIP_FLAGS = @STRIP_FLAGS@
 
 MOZ_POST_DSO_LIB_COMMAND = @MOZ_POST_DSO_LIB_COMMAND@
 MOZ_POST_PROGRAM_COMMAND = @MOZ_POST_PROGRAM_COMMAND@
 
 MOZ_BUILD_ROOT             = @MOZ_BUILD_ROOT@
 
 MOZ_XUL                    = @MOZ_XUL@
 
--- a/config/config.mk
+++ b/config/config.mk
@@ -832,8 +832,13 @@ endif
 
 ifdef GNU_CC
 EXPAND_LIBNAME = $(addprefix -l,$(1))
 else
 EXPAND_LIBNAME = $(foreach lib,$(1),$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 endif
 EXPAND_LIBNAME_PATH = $(foreach lib,$(1),$(2)/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 EXPAND_MOZLIBNAME = $(foreach lib,$(1),$(DIST)/lib/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
+
+# Include internal ply only if needed
+ifndef MOZ_SYSTEM_PLY
+PLY_INCLUDE = -I$(topsrcdir)/other-licenses/ply
+endif
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -1439,29 +1439,29 @@ XPIDL_DEPS = \
 xpidl-preqs = \
   $(call mkdir_deps,$(XPIDL_GEN_DIR)) \
   $(call mkdir_deps,$(MDDEPDIR)) \
   $(NULL)
 
 $(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
 	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
-	  -I$(topsrcdir)/other-licenses/ply \
+	  $(PLY_INCLUDE) \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
 
 ifndef NO_GEN_XPT
 # generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
 # into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
 $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
 	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
-	  -I$(topsrcdir)/other-licenses/ply \
+	  $(PLY_INCLUDE) \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
 	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 
 # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
 ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
 $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS)) $(GLOBAL_DEPS)
 	$(XPIDL_LINK) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS))
deleted file mode 100644
--- a/config/rules.mk.orig
+++ /dev/null
@@ -1,2035 +0,0 @@
-# -*- makefile -*-
-# vim:set ts=8 sw=8 sts=8 noet:
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#  Chase Phillips <chase@mozilla.org>
-#  Benjamin Smedberg <benjamin@smedbergs.us>
-#  Jeff Walden <jwalden+code@mit.edu>
-#  Joey Armstrong <joey@mozilla.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of the GNU General Public License Version 2 or later (the "GPL"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-ifndef topsrcdir
-$(error topsrcdir was not set))
-endif
-
-ifndef MOZILLA_DIR
-MOZILLA_DIR = $(topsrcdir)
-endif
-
-ifndef INCLUDED_CONFIG_MK
-include $(topsrcdir)/config/config.mk
-endif
-
-ifndef INCLUDED_VERSION_MK
-include $(topsrcdir)/config/version.mk
-endif
-
-ifdef SDK_XPIDLSRCS
-XPIDLSRCS += $(SDK_XPIDLSRCS)
-endif
-ifdef SDK_HEADERS
-EXPORTS += $(SDK_HEADERS)
-endif
-
-REPORT_BUILD = @echo $(notdir $<)
-
-ifeq ($(OS_ARCH),OS2)
-EXEC			=
-else
-EXEC			= exec
-endif
-
-# Don't copy xulrunner files at install time, when using system xulrunner
-ifdef SYSTEM_LIBXUL
-  SKIP_COPY_XULRUNNER=1
-endif
-
-# ELOG prints out failed command when building silently (gmake -s).
-ifneq (,$(findstring s, $(filter-out --%, $(MAKEFLAGS))))
-  ELOG := $(EXEC) sh $(BUILD_TOOLS)/print-failed-commands.sh
-else
-  ELOG :=
-endif
-
-_VPATH_SRCS = $(abspath $<)
-
-# Add $(DIST)/lib to VPATH so that -lfoo dependencies are followed
-VPATH += $(DIST)/lib
-ifdef LIBXUL_SDK
-VPATH += $(LIBXUL_SDK)/lib
-endif
-
-ifdef EXTRA_DSO_LIBS
-EXTRA_DSO_LIBS	:= $(call EXPAND_MOZLIBNAME,$(EXTRA_DSO_LIBS))
-endif
-
-################################################################################
-# Testing frameworks support
-################################################################################
-
-testxpcobjdir = $(DEPTH)/_tests/xpcshell
-
-ifdef ENABLE_TESTS
-
-# Add test directories to the regular directories list. TEST_DIRS should
-# arguably have the same status as TOOL_DIRS and other *_DIRS variables. It is
-# coded this way until Makefiles stop using the "ifdef ENABLE_TESTS; DIRS +="
-# convention.
-#
-# The current developer workflow expects tests to be updated when processing
-# the default target. If we ever change this implementation, the behavior
-# should be preserved or the change should be widely communicated. A
-# consequence of not processing test dir targets during the default target is
-# that changes to tests may not be updated and code could assume to pass
-# locally against non-current test code.
-DIRS += $(TEST_DIRS)
-
-ifdef XPCSHELL_TESTS
-ifndef relativesrcdir
-$(error Must define relativesrcdir when defining XPCSHELL_TESTS.)
-endif
-
-define _INSTALL_TESTS
-$(DIR_INSTALL) $(wildcard $(srcdir)/$(dir)/*) $(testxpcobjdir)/$(relativesrcdir)/$(dir)
-
-endef # do not remove the blank line!
-
-SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
-
-libs::
-	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
-ifndef NO_XPCSHELL_MANIFEST_CHECK
-	$(PYTHON) $(MOZILLA_DIR)/build/xpccheck.py \
-	  $(topsrcdir) \
-	  $(topsrcdir)/testing/xpcshell/xpcshell.ini \
-	  $(addprefix $(MOZILLA_DIR)/$(relativesrcdir)/,$(XPCSHELL_TESTS))
-endif
-
-testxpcsrcdir = $(topsrcdir)/testing/xpcshell
-
-# Execute all tests in the $(XPCSHELL_TESTS) directories.
-# See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
-xpcshell-tests:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --tests-root-dir=$(testxpcobjdir) \
-	  --xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
-	  --xunit-suite-name=xpcshell \
-	  $(EXTRA_TEST_ARGS) \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-xpcshell-tests-remote: DM_TRANS?=adb
-xpcshell-tests-remote:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  -I$(topsrcdir)/build/mobile \
-	  $(topsrcdir)/testing/xpcshell/remotexpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  $(EXTRA_TEST_ARGS) \
-	  --dm_trans=$(DM_TRANS) \
-	  --deviceIP=${TEST_DEVICE} \
-	  --objdir=$(DEPTH) \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-# Execute a single test, specified in $(SOLO_FILE), but don't automatically
-# start the test. Instead, present the xpcshell prompt so the user can
-# attach a debugger and then start the test.
-check-interactive:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --interactive \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-# Execute a single test, specified in $(SOLO_FILE)
-check-one:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --verbose \
-	  $(EXTRA_TEST_ARGS) \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-check-one-remote: DM_TRANS?=adb
-check-one-remote:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  -I$(topsrcdir)/build/mobile \
-	  $(testxpcsrcdir)/remotexpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --verbose \
-	  $(EXTRA_TEST_ARGS) \
-	  --dm_trans=$(DM_TRANS) \
-	  --deviceIP=${TEST_DEVICE} \
-	  --objdir=$(DEPTH) \
-          --noSetup \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-endif # XPCSHELL_TESTS
-
-ifdef CPP_UNIT_TESTS
-
-# Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
-# through TestHarness.h, by modifying the list of includes and the libs against
-# which stuff links.
-CPPSRCS += $(CPP_UNIT_TESTS)
-SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX))
-INCLUDES += -I$(DIST)/include/testing
-LIBS += $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS) $(MOZ_JS_LIBS)
-
-# ...and run them the usual way
-check::
-	@$(EXIT_ON_ERROR) \
-	  for f in $(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)); do \
-	    XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \
-	  done
-
-endif # CPP_UNIT_TESTS
-
-.PHONY: check xpcshell-tests check-interactive check-one
-
-endif # ENABLE_TESTS
-
-
-#
-# Library rules
-#
-# If FORCE_STATIC_LIB is set, build a static library.
-# Otherwise, build a shared library.
-#
-
-ifndef LIBRARY
-ifdef STATIC_LIBRARY_NAME
-REAL_LIBRARY		:= $(LIB_PREFIX)$(STATIC_LIBRARY_NAME).$(LIB_SUFFIX)
-# Only build actual library if it is installed in DIST/lib or SDK
-ifeq (,$(SDK_LIBRARY)$(DIST_INSTALL)$(NO_EXPAND_LIBS))
-LIBRARY			:= $(REAL_LIBRARY).$(LIBS_DESC_SUFFIX)
-else
-LIBRARY			:= $(REAL_LIBRARY) $(REAL_LIBRARY).$(LIBS_DESC_SUFFIX)
-endif
-endif # STATIC_LIBRARY_NAME
-endif # LIBRARY
-
-ifndef HOST_LIBRARY
-ifdef HOST_LIBRARY_NAME
-HOST_LIBRARY		:= $(LIB_PREFIX)$(HOST_LIBRARY_NAME).$(LIB_SUFFIX)
-endif
-endif
-
-ifdef LIBRARY
-ifdef FORCE_SHARED_LIB
-ifdef MKSHLIB
-
-ifdef LIB_IS_C_ONLY
-MKSHLIB			= $(MKCSHLIB)
-endif
-
-ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
-IMPORT_LIBRARY		:= $(LIB_PREFIX)$(SHARED_LIBRARY_NAME).$(IMPORT_LIB_SUFFIX)
-endif
-
-ifeq (OS2,$(OS_ARCH))
-ifdef SHORT_LIBNAME
-SHARED_LIBRARY_NAME	:= $(SHORT_LIBNAME)
-endif
-endif
-
-ifdef MAKE_FRAMEWORK
-SHARED_LIBRARY		:= $(SHARED_LIBRARY_NAME)
-else
-SHARED_LIBRARY		:= $(DLL_PREFIX)$(SHARED_LIBRARY_NAME)$(DLL_SUFFIX)
-endif
-
-ifeq ($(OS_ARCH),OS2)
-DEF_FILE		:= $(SHARED_LIBRARY:.dll=.def)
-endif
-
-EMBED_MANIFEST_AT=2
-
-endif # MKSHLIB
-endif # FORCE_SHARED_LIB
-endif # LIBRARY
-
-ifdef FORCE_STATIC_LIB
-ifndef FORCE_SHARED_LIB
-SHARED_LIBRARY		:= $(NULL)
-DEF_FILE		:= $(NULL)
-IMPORT_LIBRARY		:= $(NULL)
-endif
-endif
-
-ifdef FORCE_SHARED_LIB
-ifndef FORCE_STATIC_LIB
-LIBRARY := $(NULL)
-endif
-endif
-
-ifdef JAVA_LIBRARY_NAME
-JAVA_LIBRARY := $(JAVA_LIBRARY_NAME).jar
-endif
-
-ifeq ($(OS_ARCH),WINNT)
-ifndef GNU_CC
-
-#
-# Unless we're building SIMPLE_PROGRAMS, all C++ files share a PDB file per
-# directory. For parallel builds, this PDB file is shared and locked by
-# MSPDBSRV.EXE, starting with MSVC8 SP1. If you're using MSVC 7.1 or MSVC8
-# without SP1, don't do parallel builds.
-#
-# The final PDB for libraries and programs is created by the linker and uses
-# a different name from the single PDB file created by the compiler. See
-# bug 462740.
-#
-
-ifdef SIMPLE_PROGRAMS
-COMPILE_PDBFILE = $(basename $(@F)).pdb
-else
-COMPILE_PDBFILE = generated.pdb
-endif
-
-LINK_PDBFILE = $(basename $(@F)).pdb
-ifdef MOZ_DEBUG
-CODFILE=$(basename $(@F)).cod
-endif
-
-ifdef MOZ_MAPINFO
-ifdef SHARED_LIBRARY_NAME
-MAPFILE=$(SHARED_LIBRARY_NAME).map
-else
-MAPFILE=$(basename $(@F)).map
-endif # SHARED_LIBRARY_NAME
-endif # MOZ_MAPINFO
-
-ifdef DEFFILE
-OS_LDFLAGS += -DEF:$(call normalizepath,$(DEFFILE))
-EXTRA_DEPS += $(DEFFILE)
-endif
-
-ifdef MAPFILE
-OS_LDFLAGS += -MAP:$(MAPFILE)
-endif
-
-else #!GNU_CC
-
-ifdef DEFFILE
-OS_LDFLAGS += $(call normalizepath,$(DEFFILE))
-EXTRA_DEPS += $(DEFFILE)
-endif
-
-endif # !GNU_CC
-
-endif # WINNT
-
-ifeq ($(SOLARIS_SUNPRO_CXX),1)
-ifeq (86,$(findstring 86,$(OS_TEST)))
-OS_LDFLAGS += -M $(topsrcdir)/config/solaris_ia32.map
-endif # x86
-endif # Solaris Sun Studio C++
-
-ifeq ($(HOST_OS_ARCH),WINNT)
-HOST_PDBFILE=$(basename $(@F)).pdb
-endif
-
-# Don't build SIMPLE_PROGRAMS during the MOZ_PROFILE_GENERATE pass
-ifdef MOZ_PROFILE_GENERATE
-SIMPLE_PROGRAMS :=
-endif
-
-ifndef TARGETS
-TARGETS			= $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
-endif
-
-ifndef OBJS
-_OBJS			= \
-	$(JRI_STUB_CFILES) \
-	$(addsuffix .$(OBJ_SUFFIX), $(JMC_GEN)) \
-	$(CSRCS:.c=.$(OBJ_SUFFIX)) \
-	$(SSRCS:.S=.$(OBJ_SUFFIX)) \
-	$(patsubst %.cc,%.$(OBJ_SUFFIX),$(CPPSRCS:.cpp=.$(OBJ_SUFFIX))) \
-	$(CMSRCS:.m=.$(OBJ_SUFFIX)) \
-	$(CMMSRCS:.mm=.$(OBJ_SUFFIX)) \
-	$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))
-OBJS	= $(strip $(_OBJS))
-endif
-
-ifndef HOST_OBJS
-_HOST_OBJS		= \
-        $(addprefix host_,$(HOST_CSRCS:.c=.$(OBJ_SUFFIX))) \
-	$(addprefix host_,$(patsubst %.cc,%.$(OBJ_SUFFIX),$(HOST_CPPSRCS:.cpp=.$(OBJ_SUFFIX)))) \
-	$(addprefix host_,$(HOST_CMSRCS:.m=.$(OBJ_SUFFIX))) \
-	$(addprefix host_,$(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX)))
-HOST_OBJS = $(strip $(_HOST_OBJS))
-endif
-
-LIBOBJS			:= $(addprefix \", $(OBJS))
-LIBOBJS			:= $(addsuffix \", $(LIBOBJS))
-
-ifndef MOZ_AUTO_DEPS
-ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
-MDDEPFILES		= $(addprefix $(MDDEPDIR)/,$(OBJS:.$(OBJ_SUFFIX)=.pp))
-ifndef NO_GEN_XPT
-MDDEPFILES		+= $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp))
-endif
-endif
-endif
-
-ALL_TRASH = \
-	$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
-	$(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \
-	$(OBJS:.$(OBJ_SUFFIX)=.i) $(OBJS:.$(OBJ_SUFFIX)=.i_o) \
-	$(HOST_PROGOBJS) $(HOST_OBJS) $(IMPORT_LIBRARY) $(DEF_FILE)\
-	$(EXE_DEF_FILE) so_locations _gen _stubs $(wildcard *.res) $(wildcard *.RES) \
-	$(wildcard *.pdb) $(CODFILE) $(MAPFILE) $(IMPORT_LIBRARY) \
-	$(SHARED_LIBRARY:$(DLL_SUFFIX)=.exp) $(wildcard *.ilk) \
-	$(PROGRAM:$(BIN_SUFFIX)=.exp) $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.exp) \
-	$(PROGRAM:$(BIN_SUFFIX)=.lib) $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.lib) \
-	$(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.$(OBJ_SUFFIX)) \
-	$(wildcard gts_tmp_*) $(LIBRARY:%.a=.%.timestamp)
-ALL_TRASH_DIRS = \
-	$(GARBAGE_DIRS) /no-such-file
-
-ifdef QTDIR
-GARBAGE                 += $(MOCSRCS)
-GARBAGE                 += $(RCCSRCS)
-endif
-
-ifdef SIMPLE_PROGRAMS
-GARBAGE			+= $(SIMPLE_PROGRAMS:%=%.$(OBJ_SUFFIX))
-endif
-
-ifdef HOST_SIMPLE_PROGRAMS
-GARBAGE			+= $(HOST_SIMPLE_PROGRAMS:%=%.$(OBJ_SUFFIX))
-endif
-
-#
-# the Solaris WorkShop template repository cache.  it occasionally can get
-# out of sync, so targets like clobber should kill it.
-#
-ifeq ($(SOLARIS_SUNPRO_CXX),1)
-GARBAGE_DIRS += SunWS_cache
-endif
-
-XPIDL_GEN_DIR		= _xpidlgen
-
-ifdef MOZ_UPDATE_XTERM
-# Its good not to have a newline at the end of the titlebar string because it
-# makes the make -s output easier to read.  Echo -n does not work on all
-# platforms, but we can trick sed into doing it.
-UPDATE_TITLE = sed -e "s!Y!$(1) in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2)!" $(MOZILLA_DIR)/config/xterm.str;
-endif
-
-define SUBMAKE # $(call SUBMAKE,target,directory)
-+@$(UPDATE_TITLE)
-+$(MAKE) $(if $(2),-C $(2)) $(1)
-
-endef # The extra line is important here! don't delete it
-
-ifneq (,$(strip $(DIRS)))
-LOOP_OVER_DIRS = \
-  $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir)))
-endif
-
-# we only use this for the makefiles target and other stuff that doesn't matter
-ifneq (,$(strip $(PARALLEL_DIRS)))
-LOOP_OVER_PARALLEL_DIRS = \
-  $(foreach dir,$(PARALLEL_DIRS),$(call SUBMAKE,$@,$(dir)))
-endif
-
-ifneq (,$(strip $(STATIC_DIRS)))
-LOOP_OVER_STATIC_DIRS = \
-  $(foreach dir,$(STATIC_DIRS),$(call SUBMAKE,$@,$(dir)))
-endif
-
-ifneq (,$(strip $(TOOL_DIRS)))
-LOOP_OVER_TOOL_DIRS = \
-  $(foreach dir,$(TOOL_DIRS),$(call SUBMAKE,$@,$(dir)))
-endif
-
-#
-# Now we can differentiate between objects used to build a library, and
-# objects used to build an executable in the same directory.
-#
-ifndef PROGOBJS
-PROGOBJS		= $(OBJS)
-endif
-
-ifndef HOST_PROGOBJS
-HOST_PROGOBJS		= $(HOST_OBJS)
-endif
-
-# MAKE_DIRS: List of directories to build while looping over directories.
-# A Makefile that needs $(MDDEPDIR) created but doesn't set any of these
-# variables we know to check can just set NEED_MDDEPDIR explicitly.
-ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS)$(NEED_MDDEPDIR))
-MAKE_DIRS		+= $(CURDIR)/$(MDDEPDIR)
-GARBAGE_DIRS		+= $(MDDEPDIR)
-endif
-
-#
-# Tags: emacs (etags), vi (ctags)
-# TAG_PROGRAM := ctags -L -
-#
-TAG_PROGRAM		= xargs etags -a
-
-#
-# Turn on C++ linking if we have any .cpp or .mm files
-# (moved this from config.mk so that config.mk can be included
-#  before the CPPSRCS are defined)
-#
-ifneq ($(CPPSRCS)$(CMMSRCS),)
-CPP_PROG_LINK		= 1
-endif
-ifneq ($(HOST_CPPSRCS)$(HOST_CMMSRCS),)
-HOST_CPP_PROG_LINK	= 1
-endif
-
-#
-# This will strip out symbols that the component should not be
-# exporting from the .dynsym section.
-#
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS += $(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
-endif # IS_COMPONENT
-
-#
-# Enforce the requirement that MODULE_NAME must be set
-# for components in static builds
-#
-ifdef IS_COMPONENT
-ifdef EXPORT_LIBRARY
-ifndef FORCE_SHARED_LIB
-ifndef MODULE_NAME
-$(error MODULE_NAME is required for components which may be used in static builds)
-endif
-endif
-endif
-endif
-
-#
-# MacOS X specific stuff
-#
-
-ifeq ($(OS_ARCH),Darwin)
-ifdef SHARED_LIBRARY
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS	+= -bundle
-else
-EXTRA_DSO_LDOPTS	+= -dynamiclib -install_name @executable_path/$(SHARED_LIBRARY) -compatibility_version 1 -current_version 1 -single_module
-endif
-endif
-endif
-
-#
-# On NetBSD a.out systems, use -Bsymbolic.  This fixes what would otherwise be
-# fatal symbol name clashes between components.
-#
-ifeq ($(OS_ARCH),NetBSD)
-ifeq ($(DLL_SUFFIX),.so.1.0)
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic
-endif
-endif
-endif
-
-ifeq ($(OS_ARCH),FreeBSD)
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic
-endif
-endif
-
-ifeq ($(OS_ARCH),NetBSD)
-ifneq (,$(filter arc cobalt hpcmips mipsco newsmips pmax sgimips,$(OS_TEST)))
-ifeq ($(MODULE),layout)
-OS_CFLAGS += -Wa,-xgot
-OS_CXXFLAGS += -Wa,-xgot
-endif
-endif
-endif
-
-#
-# HP-UXBeOS specific section: for COMPONENTS only, add -Bsymbolic flag
-# which uses internal symbols first
-#
-ifeq ($(OS_ARCH),HP-UX)
-ifdef IS_COMPONENT
-ifeq ($(GNU_CC)$(GNU_CXX),)
-EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic
-ifneq ($(HAS_EXTRAEXPORTS),1)
-MKSHLIB  += -Wl,+eNSGetModule -Wl,+eerrno
-MKCSHLIB += +eNSGetModule +eerrno
-ifneq ($(OS_TEST),ia64)
-MKSHLIB  += -Wl,+e_shlInit
-MKCSHLIB += +e_shlInit
-endif # !ia64
-endif # !HAS_EXTRAEXPORTS
-endif # non-gnu compilers
-endif # IS_COMPONENT
-endif # HP-UX
-
-ifeq ($(OS_ARCH),AIX)
-ifdef IS_COMPONENT
-ifneq ($(HAS_EXTRAEXPORTS),1)
-MKSHLIB += -bE:$(MOZILLA_DIR)/build/unix/aix.exp -bnoexpall
-MKCSHLIB += -bE:$(MOZILLA_DIR)/build/unix/aix.exp -bnoexpall
-endif # HAS_EXTRAEXPORTS
-endif # IS_COMPONENT
-endif # AIX
-
-#
-# OSF1: add -B symbolic flag for components
-#
-ifeq ($(OS_ARCH),OSF1)
-ifdef IS_COMPONENT
-ifeq ($(GNU_CC)$(GNU_CXX),)
-EXTRA_DSO_LDOPTS += -B symbolic
-endif
-endif
-endif
-
-#
-# Linux: add -Bsymbolic flag for components
-#
-ifeq ($(OS_ARCH),Linux)
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic
-endif
-endif
-
-#
-# GNU doesn't have path length limitation
-#
-
-ifeq ($(OS_ARCH),GNU)
-OS_CPPFLAGS += -DPATH_MAX=1024 -DMAXPATHLEN=1024
-endif
-
-#
-# MINGW32
-#
-ifeq ($(OS_ARCH),WINNT)
-ifdef GNU_CC
-ifndef IS_COMPONENT
-DSO_LDOPTS += -Wl,--out-implib -Wl,$(IMPORT_LIBRARY)
-endif
-endif
-endif
-
-ifeq ($(USE_TVFS),1)
-IFLAGS1 = -rb
-IFLAGS2 = -rb
-else
-IFLAGS1 = -m 644
-IFLAGS2 = -m 755
-endif
-
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-OUTOPTION = -Fo# eol
-else
-OUTOPTION = -o # eol
-endif # WINNT && !GNU_CC
-
-ifneq (,$(filter ml%,$(AS)))
-ASOUTOPTION = -Fo# eol
-else
-ASOUTOPTION = -o # eol
-endif
-
-ifeq (,$(CROSS_COMPILE))
-HOST_OUTOPTION = $(OUTOPTION)
-else
-HOST_OUTOPTION = -o # eol
-endif
-################################################################################
-
-# SUBMAKEFILES: List of Makefiles for next level down.
-#   This is used to update or create the Makefiles before invoking them.
-SUBMAKEFILES += $(addsuffix /Makefile, $(DIRS) $(TOOL_DIRS) $(PARALLEL_DIRS))
-
-# The root makefile doesn't want to do a plain export/libs, because
-# of the tiers and because of libxul. Suppress the default rules in favor
-# of something else. Makefiles which use this var *must* provide a sensible
-# default rule before including rules.mk
-ifndef SUPPRESS_DEFAULT_RULES
-ifdef TIERS
-default all alldep::
-	$(foreach tier,$(TIERS),$(call SUBMAKE,tier_$(tier)))
-else
-
-default all::
-ifneq (,$(strip $(STATIC_DIRS)))
-	$(foreach dir,$(STATIC_DIRS),$(call SUBMAKE,,$(dir)))
-endif
-	$(MAKE) export
-	$(MAKE) libs
-	$(MAKE) tools
-
-# Do depend as well
-alldep::
-	$(MAKE) export
-	$(MAKE) depend
-	$(MAKE) libs
-	$(MAKE) tools
-
-endif # TIERS
-endif # SUPPRESS_DEFAULT_RULES
-
-ifeq ($(filter s,$(MAKEFLAGS)),)
-ECHO := echo
-QUIET :=
-else
-ECHO := true
-QUIET := -q
-endif
-
-MAKE_TIER_SUBMAKEFILES = +$(if $(tier_$*_dirs),$(MAKE) $(addsuffix /Makefile,$(tier_$*_dirs)))
-
-$(foreach tier,$(TIERS),tier_$(tier))::
-	@$(ECHO) "$@: $($@_staticdirs) $($@_dirs)"
-	$(foreach dir,$($@_staticdirs),$(call SUBMAKE,,$(dir)))
-	$(MAKE) export_$@
-	$(MAKE) libs_$@
-	$(MAKE) tools_$@
-
-# Do everything from scratch
-everything::
-	$(MAKE) clean
-	$(MAKE) alldep
-
-# Add dummy depend target for tinderboxes
-depend::
-
-# Target to only regenerate makefiles
-makefiles: $(SUBMAKEFILES)
-ifneq (,$(DIRS)$(TOOL_DIRS)$(PARALLEL_DIRS))
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-endif
-
-include $(topsrcdir)/config/makefiles/target_export.mk
-include $(topsrcdir)/config/makefiles/target_tools.mk
-
-#
-# Rule to create list of libraries for final link
-#
-export::
-ifdef LIBRARY_NAME
-ifdef EXPORT_LIBRARY
-ifdef IS_COMPONENT
-else # !IS_COMPONENT
-	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
-endif # IS_COMPONENT
-endif # EXPORT_LIBRARY
-endif # LIBRARY_NAME
-
-ifneq (,$(filter-out %.$(LIB_SUFFIX),$(SHARED_LIBRARY_LIBS)))
-$(error SHARED_LIBRARY_LIBS must contain .$(LIB_SUFFIX) files only)
-endif
-
-# Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
-DO_EXPAND_LIBS = $(foreach f,$(1),$(if $(filter %.$(LIB_SUFFIX),$(f)),$(if $(wildcard $(f).$(LIBS_DESC_SUFFIX)),$(f).$(LIBS_DESC_SUFFIX),$(if $(wildcard $(f)),$(f)))))
-LIBS_DEPS = $(call DO_EXPAND_LIBS,$(filter %.$(LIB_SUFFIX),$(LIBS) $(if $(PROGRAM)$(SIMPLE_PROGRAMS),$(MOZ_GLUE_PROGRAM_LDFLAGS))))
-SHARED_LIBRARY_LIBS_DEPS = $(call DO_EXPAND_LIBS,$(SHARED_LIBRARY_LIBS))
-HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
-DSO_LDOPTS_DEPS = $(call DO_EXPAND_LIBS,$(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS)))
-
-# Dependencies which, if modified, should cause everything to rebuild
-GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
-
-##############################################
-include $(topsrcdir)/config/makefiles/target_libs.mk
-
-##############################################
-ifndef NO_PROFILE_GUIDED_OPTIMIZE
-ifdef MOZ_PROFILE_USE
-ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
-# When building with PGO, we have to make sure to re-link
-# in the MOZ_PROFILE_USE phase if we linked in the
-# MOZ_PROFILE_GENERATE phase. We'll touch this pgo.relink
-# file in the link rule in the GENERATE phase to indicate
-# that we need a relink.
-ifdef SHARED_LIBRARY
-$(SHARED_LIBRARY): pgo.relink
-endif
-ifdef PROGRAM
-$(PROGRAM): pgo.relink
-endif
-
-# In the second pass, we need to merge the pgc files into the pgd file.
-# The compiler would do this for us automatically if they were in the right
-# place, but they're in dist/bin.
-ifneq (,$(SHARED_LIBRARY)$(PROGRAM))
-export::
-ifdef PROGRAM
-	$(PYTHON) $(topsrcdir)/build/win32/pgomerge.py \
-	  $(PROGRAM:$(BIN_SUFFIX)=) $(DIST)/bin
-endif
-ifdef SHARED_LIBRARY
-	$(PYTHON) $(topsrcdir)/build/win32/pgomerge.py \
-	  $(SHARED_LIBRARY_NAME) $(DIST)/bin
-endif
-endif # SHARED_LIBRARY || PROGRAM
-endif # WINNT_
-endif # MOZ_PROFILE_USE
-ifdef MOZ_PROFILE_GENERATE
-# Clean up profiling data during PROFILE_GENERATE phase
-export::
-ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
-	$(foreach pgd,$(wildcard *.pgd),pgomgr -clear $(pgd);)
-else
-ifdef GNU_CC
-	-$(RM) *.gcda
-endif
-endif
-endif
-
-ifneq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE))
-ifdef GNU_CC
-# Force rebuilding libraries and programs in both passes because each
-# pass uses different object files.
-$(PROGRAM) $(SHARED_LIBRARY) $(LIBRARY): FORCE
-endif
-endif
-
-endif # NO_PROFILE_GUIDED_OPTIMIZE
-
-##############################################
-
-stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_TARGET_VERSION)
-host_stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_HOST_VERSION)
-
-checkout:
-	$(MAKE) -C $(topsrcdir) -f client.mk checkout
-
-clean clobber realclean clobber_all:: $(SUBMAKEFILES)
-	-$(RM) $(ALL_TRASH)
-	-$(RM) -r $(ALL_TRASH_DIRS)
-	$(foreach dir,$(PARALLEL_DIRS) $(DIRS) $(STATIC_DIRS) $(TOOL_DIRS),-$(call SUBMAKE,$@,$(dir)))
-
-distclean:: $(SUBMAKEFILES)
-	$(foreach dir,$(PARALLEL_DIRS) $(DIRS) $(STATIC_DIRS) $(TOOL_DIRS),-$(call SUBMAKE,$@,$(dir)))
-	-$(RM) -r $(ALL_TRASH_DIRS)
-	-$(RM) $(ALL_TRASH)  \
-	Makefile .HSancillary \
-	$(wildcard *.$(OBJ_SUFFIX)) $(wildcard *.ho) $(wildcard host_*.o*) \
-	$(wildcard *.$(LIB_SUFFIX)) $(wildcard *$(DLL_SUFFIX)) \
-	$(wildcard *.$(IMPORT_LIB_SUFFIX))
-ifeq ($(OS_ARCH),OS2)
-	-$(RM) $(PROGRAM:.exe=.map)
-endif
-
-alltags:
-	$(RM) TAGS
-	find $(topsrcdir) -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' -o -name '*.idl' \) -print | $(TAG_PROGRAM)
-
-#
-# PROGRAM = Foo
-# creates OBJS, links with LIBS to create Foo
-#
-$(PROGRAM): $(PROGOBJS) $(LIBS_DEPS) $(EXTRA_DEPS) $(EXE_DEF_FILE) $(RESFILE) $(GLOBAL_DEPS)
-	@$(RM) $@.manifest
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(EXPAND_LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
-ifdef MSMANIFEST_TOOL
-	@if test -f $@.manifest; then \
-		if test -f "$(srcdir)/$@.manifest"; then \
-			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
-			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		else \
-			echo "Embedding manifest from $@.manifest"; \
-			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		fi; \
-	elif test -f "$(srcdir)/$@.manifest"; then \
-		echo "Embedding manifest from $(srcdir)/$@.manifest"; \
-		mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" -OUTPUTRESOURCE:$@\;1; \
-	fi
-endif	# MSVC with manifest tool
-ifdef MOZ_PROFILE_GENERATE
-# touch it a few seconds into the future to work around FAT's
-# 2-second granularity
-	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
-endif
-else # !WINNT || GNU_CC
-ifeq ($(CPP_PROG_LINK),1)
-	$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE)
-	@$(call CHECK_STDCXX,$@)
-else # ! CPP_PROG_LINK
-	$(EXPAND_CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE)
-endif # CPP_PROG_LINK
-endif # WINNT && !GNU_CC
-
-ifdef ENABLE_STRIP
-	$(STRIP) $@
-endif
-ifdef MOZ_POST_PROGRAM_COMMAND
-	$(MOZ_POST_PROGRAM_COMMAND) $@
-endif
-
-$(HOST_PROGRAM): $(HOST_PROGOBJS) $(HOST_LIBS_DEPS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
-ifeq (_WINNT,$(GNU_CC)_$(HOST_OS_ARCH))
-	$(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $(HOST_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-ifdef MSMANIFEST_TOOL
-	@if test -f $@.manifest; then \
-		if test -f "$(srcdir)/$@.manifest"; then \
-			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
-			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		else \
-			echo "Embedding manifest from $@.manifest"; \
-			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		fi; \
-	elif test -f "$(srcdir)/$@.manifest"; then \
-		echo "Embedding manifest from $(srcdir)/$@.manifest"; \
-		mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" -OUTPUTRESOURCE:$@\;1; \
-	fi
-endif	# MSVC with manifest tool
-else
-ifeq ($(HOST_CPP_PROG_LINK),1)
-	$(HOST_CXX) -o $@ $(HOST_CXXFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-else
-	$(HOST_CC) -o $@ $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-endif # HOST_CPP_PROG_LINK
-endif
-
-#
-# This is an attempt to support generation of multiple binaries
-# in one directory, it assumes everything to compile Foo is in
-# Foo.o (from either Foo.c or Foo.cpp).
-#
-# SIMPLE_PROGRAMS = Foo Bar
-# creates Foo.o Bar.o, links with LIBS to create Foo, Bar.
-#
-$(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(EXPAND_LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
-ifdef MSMANIFEST_TOOL
-	@if test -f $@.manifest; then \
-		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		rm -f $@.manifest; \
-	fi
-endif	# MSVC with manifest tool
-else
-ifeq ($(CPP_PROG_LINK),1)
-	$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
-	@$(call CHECK_STDCXX,$@)
-else
-	$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
-endif # CPP_PROG_LINK
-endif # WINNT && !GNU_CC
-
-ifdef ENABLE_STRIP
-	$(STRIP) $@
-endif
-ifdef MOZ_POST_PROGRAM_COMMAND
-	$(MOZ_POST_PROGRAM_COMMAND) $@
-endif
-
-$(HOST_SIMPLE_PROGRAMS): host_%$(HOST_BIN_SUFFIX): host_%.$(OBJ_SUFFIX) $(HOST_LIBS_DEPS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
-ifeq (WINNT_,$(HOST_OS_ARCH)_$(GNU_CC))
-	$(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-else
-ifneq (,$(HOST_CPPSRCS)$(USE_HOST_CXX))
-	$(HOST_CXX) $(HOST_OUTOPTION)$@ $(HOST_CXXFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-else
-	$(HOST_CC) $(HOST_OUTOPTION)$@ $(HOST_CFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-endif
-endif
-
-#
-# Purify target.  Solaris/sparc only to start.
-# Purify does not recognize "egcs" or "c++" so we go with
-# "gcc" and "g++" for now.
-#
-pure:	$(PROGRAM)
-ifeq ($(CPP_PROG_LINK),1)
-	$(PURIFY) $(CCC) -o $^.pure $(CXXFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
-else
-	$(PURIFY) $(CC) -o $^.pure $(CFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
-endif
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS2) $^.pure $(FINAL_TARGET)
-endif
-
-quantify: $(PROGRAM)
-ifeq ($(CPP_PROG_LINK),1)
-	$(QUANTIFY) $(CCC) -o $^.quantify $(CXXFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
-else
-	$(QUANTIFY) $(CC) -o $^.quantify $(CFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
-endif
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS2) $^.quantify $(FINAL_TARGET)
-endif
-
-ifdef DTRACE_PROBE_OBJ
-EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
-OBJS += $(DTRACE_PROBE_OBJ)
-endif
-
-$(filter %.$(LIB_SUFFIX),$(LIBRARY)): $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
-	$(RM) $(LIBRARY)
-	$(EXPAND_AR) $(AR_FLAGS) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS)
-	$(RANLIB) $@
-
-$(filter-out %.$(LIB_SUFFIX),$(LIBRARY)): $(filter %.$(LIB_SUFFIX),$(LIBRARY)) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
-# When we only build a library descriptor, blow out any existing library
-	$(if $(filter %.$(LIB_SUFFIX),$(LIBRARY)),,$(RM) $(REAL_LIBRARY) $(EXPORT_LIBRARY:%=%/$(REAL_LIBRARY)))
-	$(EXPAND_LIBS_GEN) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS) > $@
-
-ifeq ($(OS_ARCH),WINNT)
-$(IMPORT_LIBRARY): $(SHARED_LIBRARY)
-endif
-
-ifeq ($(OS_ARCH),OS2)
-$(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
-	$(RM) $@
-	echo LIBRARY $(SHARED_LIBRARY_NAME) INITINSTANCE TERMINSTANCE > $@
-	echo PROTMODE >> $@
-	echo CODE    LOADONCALL MOVEABLE DISCARDABLE >> $@
-	echo DATA    PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@
-	echo EXPORTS >> $@
-
-	$(ADD_TO_DEF_FILE)
-
-$(IMPORT_LIBRARY): $(SHARED_LIBRARY)
-	$(RM) $@
-	$(IMPLIB) $@ $^
-	$(RANLIB) $@
-endif # OS/2
-
-$(HOST_LIBRARY): $(HOST_OBJS) Makefile
-	$(RM) $@
-	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
-	$(HOST_RANLIB) $@
-
-ifdef HAVE_DTRACE
-ifndef XP_MACOSX
-ifdef DTRACE_PROBE_OBJ
-ifndef DTRACE_LIB_DEPENDENT
-NON_DTRACE_OBJS := $(filter-out $(DTRACE_PROBE_OBJ),$(OBJS))
-$(DTRACE_PROBE_OBJ): $(NON_DTRACE_OBJS)
-	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(NON_DTRACE_OBJS)
-endif
-endif
-endif
-endif
-
-# On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
-# so instead of deleting .o files after repacking them into a dylib, we make
-# symlinks back to the originals. The symlinks are a no-op for stabs debugging,
-# so no need to conditionalize on OS version or debugging format.
-
-$(SHARED_LIBRARY): $(OBJS) $(LOBJS) $(DEF_FILE) $(RESFILE) $(SHARED_LIBRARY_LIBS_DEPS) $(LIBRARY) $(EXTRA_DEPS) $(DSO_LDOPTS_DEPS) $(GLOBAL_DEPS)
-ifndef INCREMENTAL_LINKER
-	$(RM) $@
-endif
-ifdef DTRACE_LIB_DEPENDENT
-ifndef XP_MACOSX
-	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
-endif
-	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
-	@$(RM) $(DTRACE_PROBE_OBJ)
-else # ! DTRACE_LIB_DEPENDENT
-	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
-endif # DTRACE_LIB_DEPENDENT
-	@$(call CHECK_STDCXX,$@)
-
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-ifdef MSMANIFEST_TOOL
-ifdef EMBED_MANIFEST_AT
-	@if test -f $@.manifest; then \
-		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;$(EMBED_MANIFEST_AT); \
-		rm -f $@.manifest; \
-	fi
-endif   # EMBED_MANIFEST_AT
-endif	# MSVC with manifest tool
-ifdef MOZ_PROFILE_GENERATE
-	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
-endif
-endif	# WINNT && !GCC
-	@$(RM) foodummyfilefoo $(DELETE_AFTER_LINK)
-	chmod +x $@
-ifdef ENABLE_STRIP
-	$(STRIP) $@
-endif
-ifdef MOZ_POST_DSO_LIB_COMMAND
-	$(MOZ_POST_DSO_LIB_COMMAND) $@
-endif
-
-ifdef MOZ_AUTO_DEPS
-ifdef COMPILER_DEPEND
-ifeq ($(SOLARIS_SUNPRO_CC),1)
-_MDDEPFILE = $(MDDEPDIR)/$(@F).pp
-
-define MAKE_DEPS_AUTO_CC
-if test -d $(@D); then \
-	echo "Building deps for $< using Sun Studio cc"; \
-	$(CC) $(COMPILE_CFLAGS) -xM  $< >$(_MDDEPFILE) ; \
-fi
-endef
-define MAKE_DEPS_AUTO_CXX
-if test -d $(@D); then \
-	echo "Building deps for $< using Sun Studio CC"; \
-	$(CXX) $(COMPILE_CXXFLAGS) -xM $< >$(_MDDEPFILE) ; \
-fi
-endef
-endif # Sun Studio on Solaris
-else # COMPILER_DEPEND
-#
-# Generate dependencies on the fly
-#
-_MDDEPFILE = $(MDDEPDIR)/$(@F).pp
-
-define MAKE_DEPS_AUTO
-if test -d $(@D); then \
-	echo "Building deps for $<"; \
-	$(MKDEPEND) -o'.$(OBJ_SUFFIX)' -f- $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(INCLUDES) $< 2>/dev/null | sed -e "s|^[^ ]*/||" > $(_MDDEPFILE) ; \
-fi
-endef
-
-MAKE_DEPS_AUTO_CC = $(MAKE_DEPS_AUTO)
-MAKE_DEPS_AUTO_CXX = $(MAKE_DEPS_AUTO)
-
-endif # COMPILER_DEPEND
-
-endif # MOZ_AUTO_DEPS
-
-# Rules for building native targets must come first because of the host_ prefix
-host_%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-host_%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-host_%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-host_%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-host_%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-%:: %.c $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CC)
-	$(ELOG) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTOPTION)$@ $(_VPATH_SRCS)
-
-%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CC)
-	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
-
-# DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs:
-# 'moc' only knows about #defines it gets on the command line (-D...), not in
-# included headers like mozilla-config.h
-moc_%.cpp: %.h $(GLOBAL_DEPS)
-	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
-
-moc_%.cc: %.cc $(GLOBAL_DEPS)
-	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
-
-qrc_%.cpp: %.qrc $(GLOBAL_DEPS)
-	$(ELOG) $(RCC) -name $* $< $(OUTOPTION)$@
-
-ifdef ASFILES
-# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
-# a '-c' flag.
-%.$(OBJ_SUFFIX): %.$(ASM_SUFFIX) $(GLOBAL_DEPS)
-	$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
-endif
-
-%.$(OBJ_SUFFIX): %.S $(GLOBAL_DEPS)
-	$(AS) -o $@ $(ASFLAGS) -c $<
-
-%:: %.cpp $(GLOBAL_DEPS)
-	@$(MAKE_DEPS_AUTO_CXX)
-	$(CCC) $(OUTOPTION)$@ $(CXXFLAGS) $(_VPATH_SRCS) $(LDFLAGS)
-
-#
-# Please keep the next two rules in sync.
-#
-%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CXX)
-	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-
-%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CXX)
-ifdef STRICT_CPLUSPLUS_SUFFIX
-	echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > t_$*.cc
-	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) t_$*.cc
-	$(RM) t_$*.cc
-else
-	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-endif #STRICT_CPLUSPLUS_SUFFIX
-
-$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CXX)
-	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
-
-$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CC)
-	$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
-
-%.s: %.cpp
-	$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-
-%.s: %.cc
-	$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-
-%.s: %.c
-	$(CC) -S $(COMPILE_CFLAGS) $(_VPATH_SRCS)
-
-%.i: %.cpp
-	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) > $*.i
-
-%.i: %.cc
-	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) > $*.i
-
-%.i: %.c
-	$(CC) -C -E $(COMPILE_CFLAGS) $(_VPATH_SRCS) > $*.i
-
-%.i: %.mm
-	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS) > $*.i
-
-%.res: %.rc
-	@echo Creating Resource file: $@
-ifeq ($(OS_ARCH),OS2)
-	$(RC) $(RCFLAGS:-D%=-d %) -i $(subst /,\,$(srcdir)) -r $< $@
-else
-ifdef GNU_CC
-	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $(_VPATH_SRCS)
-else
-	$(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $(_VPATH_SRCS)
-endif
-endif
-
-# need 3 separate lines for OS/2
-%:: %.pl
-	$(RM) $@
-	cp $< $@
-	chmod +x $@
-
-%:: %.sh
-	$(RM) $@
-	cp $< $@
-	chmod +x $@
-
-# Cancel these implicit rules
-#
-%: %,v
-
-%: RCS/%,v
-
-%: s.%
-
-%: SCCS/s.%
-
-###############################################################################
-# Java rules
-###############################################################################
-ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
-SEP := ;
-else
-SEP := :
-endif
-
-EMPTY :=
-SPACE := $(EMPTY) $(EMPTY)
-
-# MSYS has its own special path form, but javac expects the source and class
-# paths to be in the DOS form (i.e. e:/builds/...).  This function does the
-# appropriate conversion on Windows, but is a noop on other systems.
-ifeq ($(HOST_OS_ARCH),WINNT)
-#  We use 'pwd -W' to get DOS form of the path.  However, since the given path
-#  could be a file or a non-existent path, we cannot call 'pwd -W' directly
-#  on the path.  Instead, we extract the root path (i.e. "c:/"), call 'pwd -W'
-#  on it, then merge with the rest of the path.
-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
-non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|")
-normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1)))
-else
-normalizepath = $(1)
-endif
-
-_srcdir = $(call normalizepath,$(srcdir))
-ifdef JAVA_SOURCEPATH
-SP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_SOURCEPATH))))
-_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)$(SEP)$(SP)"
-else
-_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)"
-endif
-
-ifdef JAVA_CLASSPATH
-CP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_CLASSPATH))))
-_JAVA_CLASSPATH = ".$(SEP)$(CP)"
-else
-_JAVA_CLASSPATH = .
-endif
-
-_JAVA_DIR = _java
-$(_JAVA_DIR)::
-	$(NSINSTALL) -D $@
-
-$(_JAVA_DIR)/%.class: %.java $(GLOBAL_DEPS) $(_JAVA_DIR)
-	$(JAVAC) $(JAVAC_FLAGS) -classpath $(_JAVA_CLASSPATH) \
-			-sourcepath $(_JAVA_SOURCEPATH) -d $(_JAVA_DIR) $(_VPATH_SRCS)
-
-$(JAVA_LIBRARY): $(addprefix $(_JAVA_DIR)/,$(JAVA_SRCS:.java=.class)) $(GLOBAL_DEPS)
-	$(JAR) cf $@ -C $(_JAVA_DIR) .
-
-GARBAGE_DIRS += $(_JAVA_DIR)
-
-###############################################################################
-# Update Makefiles
-###############################################################################
-
-# Note: Passing depth to make-makefile is optional.
-#       It saves the script some work, though.
-Makefile: Makefile.in
-	@$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH)
-
-ifdef SUBMAKEFILES
-# VPATH does not work on some machines in this case, so add $(srcdir)
-$(SUBMAKEFILES): % : $(srcdir)/%.in
-	$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH) $@
-endif
-
-ifdef AUTOUPDATE_CONFIGURE
-$(topsrcdir)/configure: $(topsrcdir)/configure.in
-	(cd $(topsrcdir) && $(AUTOCONF)) && (cd $(DEPTH) && ./config.status --recheck)
-endif
-
-$(DEPTH)/config/autoconf.mk: $(topsrcdir)/config/autoconf.mk.in
-	cd $(DEPTH) && CONFIG_HEADERS= CONFIG_FILES=config/autoconf.mk ./config.status
-
-###############################################################################
-# Bunch of things that extend the 'export' rule (in order):
-###############################################################################
-
-################################################################################
-# Copy each element of EXPORTS to $(DIST)/include
-
-ifneq ($(XPI_NAME),)
-$(FINAL_TARGET):
-	$(NSINSTALL) -D $@
-
-export:: $(FINAL_TARGET)
-endif
-
-ifndef NO_DIST_INSTALL
-ifneq (,$(EXPORTS))
-export:: $(EXPORTS)
-	$(INSTALL) $(IFLAGS1) $^ $(DIST)/include
-endif
-endif # NO_DIST_INSTALL
-
-define EXPORT_NAMESPACE_RULE
-ifndef NO_DIST_INSTALL
-export:: $(EXPORTS_$(namespace))
-	$(INSTALL) $(IFLAGS1) $$^ $(DIST)/include/$(namespace)
-endif # NO_DIST_INSTALL
-endef
-
-$(foreach namespace,$(EXPORTS_NAMESPACES),$(eval $(EXPORT_NAMESPACE_RULE)))
-
-################################################################################
-# Copy each element of PREF_JS_EXPORTS
-
-ifdef GRE_MODULE
-PREF_DIR = greprefs
-else
-ifneq (,$(XPI_NAME)$(LIBXUL_SDK))
-PREF_DIR = defaults/preferences
-else
-PREF_DIR = defaults/pref
-endif
-endif
-
-ifneq ($(PREF_JS_EXPORTS),)
-# on win32, pref files need CRLF line endings... see bug 206029
-ifeq (WINNT,$(OS_ARCH))
-PREF_PPFLAGS = --line-endings=crlf
-endif
-
-ifndef NO_DIST_INSTALL
-$(FINAL_TARGET)/$(PREF_DIR):
-	$(NSINSTALL) -D $@
-
-libs:: $(FINAL_TARGET)/$(PREF_DIR)
-libs:: $(PREF_JS_EXPORTS)
-	$(EXIT_ON_ERROR)  \
-	for i in $^; do \
-	  dest=$(FINAL_TARGET)/$(PREF_DIR)/`basename $$i`; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
-	done
-endif
-endif
-
-################################################################################
-# Copy each element of AUTOCFG_JS_EXPORTS to $(FINAL_TARGET)/defaults/autoconfig
-
-ifneq ($(AUTOCFG_JS_EXPORTS),)
-$(FINAL_TARGET)/defaults/autoconfig::
-	$(NSINSTALL) -D $@
-
-ifndef NO_DIST_INSTALL
-export:: $(AUTOCFG_JS_EXPORTS) $(FINAL_TARGET)/defaults/autoconfig
-	$(INSTALL) $(IFLAGS1) $^
-endif
-
-endif
-################################################################################
-# Export the elements of $(XPIDLSRCS)
-# generating .h and .xpt files and moving them to the appropriate places.
-
-ifneq ($(XPIDLSRCS),)
-
-export:: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS))
-
-ifndef XPIDL_MODULE
-XPIDL_MODULE		= $(MODULE)
-endif
-
-ifeq ($(XPIDL_MODULE),) # we need $(XPIDL_MODULE) to make $(XPIDL_MODULE).xpt
-export:: FORCE
-	@echo
-	@echo "*** Error processing XPIDLSRCS:"
-	@echo "Please define MODULE or XPIDL_MODULE when defining XPIDLSRCS,"
-	@echo "so we have a module name to use when creating MODULE.xpt."
-	@echo; sleep 2; false
-endif
-
-# generate .h files from into $(XPIDL_GEN_DIR), then export to $(DIST)/include;
-# warn against overriding existing .h file.
-$(XPIDL_GEN_DIR)/.done:
-	$(MKDIR) -p $(XPIDL_GEN_DIR)
-	@$(TOUCH) $@
-
-# don't depend on $(XPIDL_GEN_DIR), because the modification date changes
-# with any addition to the directory, regenerating all .h files -> everything.
-
-XPIDL_DEPS = \
-  $(topsrcdir)/xpcom/idl-parser/header.py \
-  $(topsrcdir)/xpcom/idl-parser/typelib.py \
-  $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-  $(NULL)
-
-$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
-	$(REPORT_BUILD)
-	$(PYTHON_PATH) \
-	  -I$(topsrcdir)/other-licenses/ply \
-	  -I$(topsrcdir)/xpcom/idl-parser \
-	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
-	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
-	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
-
-ifndef NO_GEN_XPT
-# generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
-# into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
-$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
-	$(REPORT_BUILD)
-	$(PYTHON_PATH) \
-	  -I$(topsrcdir)/other-licenses/ply \
-	  -I$(topsrcdir)/xpcom/idl-parser \
-	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
-	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
-
-# no need to link together if XPIDLSRCS contains only XPIDL_MODULE
-ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
-$(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS)) $(GLOBAL_DEPS)
-	$(XPIDL_LINK) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS))
-endif # XPIDL_MODULE.xpt != XPIDLSRCS
-
-libs:: $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS1) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(FINAL_TARGET)/components
-ifndef NO_INTERFACES_MANIFEST
-	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/interfaces.manifest "interfaces $(XPIDL_MODULE).xpt"
-	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/interfaces.manifest"
-endif
-endif
-
-endif # NO_GEN_XPT
-
-GARBAGE_DIRS		+= $(XPIDL_GEN_DIR)
-
-endif # XPIDLSRCS
-
-ifneq ($(XPIDLSRCS),)
-# export .idl files to $(IDL_DIR)
-ifndef NO_DIST_INSTALL
-export:: $(XPIDLSRCS) $(IDL_DIR)
-	$(INSTALL) $(IFLAGS1) $^
-
-export:: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS)) $(DIST)/include
-	$(INSTALL) $(IFLAGS1) $^
-endif # NO_DIST_INSTALL
-
-endif # XPIDLSRCS
-
-
-
-# General rules for exporting idl files.
-$(IDL_DIR):
-	$(NSINSTALL) -D $@
-
-export-idl:: $(SUBMAKEFILES) $(MAKE_DIRS)
-
-ifneq ($(XPIDLSRCS),)
-ifndef NO_DIST_INSTALL
-export-idl:: $(XPIDLSRCS) $(IDL_DIR)
-	$(INSTALL) $(IFLAGS1) $^
-endif
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-################################################################################
-# Copy each element of EXTRA_COMPONENTS to $(FINAL_TARGET)/components
-ifneq (,$(filter %.js,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS)))
-ifeq (,$(filter %.manifest,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS)))
-ifndef NO_JS_MANIFEST
-$(error .js component without matching .manifest. See https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_2.0)
-endif
-endif
-endif
-
-ifdef EXTRA_COMPONENTS
-libs:: $(EXTRA_COMPONENTS)
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/components
-endif
-
-endif
-
-ifdef EXTRA_PP_COMPONENTS
-libs:: $(EXTRA_PP_COMPONENTS)
-ifndef NO_DIST_INSTALL
-	$(EXIT_ON_ERROR) \
-	$(NSINSTALL) -D $(FINAL_TARGET)/components; \
-	for i in $^; do \
-	  fname=`basename $$i`; \
-	  dest=$(FINAL_TARGET)/components/$${fname}; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
-	done
-endif
-endif
-
-EXTRA_MANIFESTS = $(filter %.manifest,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS))
-ifneq (,$(EXTRA_MANIFESTS))
-libs::
-	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest $(patsubst %,"manifest components/%",$(notdir $(EXTRA_MANIFESTS)))
-endif
-
-################################################################################
-# Copy each element of EXTRA_JS_MODULES to $(FINAL_TARGET)/modules
-ifdef EXTRA_JS_MODULES
-libs:: $(EXTRA_JS_MODULES)
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/modules
-endif
-
-endif
-
-ifdef EXTRA_PP_JS_MODULES
-libs:: $(EXTRA_PP_JS_MODULES)
-ifndef NO_DIST_INSTALL
-	$(EXIT_ON_ERROR) \
-	$(NSINSTALL) -D $(FINAL_TARGET)/modules; \
-	for i in $^; do \
-	  dest=$(FINAL_TARGET)/modules/`basename $$i`; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
-	done
-endif
-
-endif
-
-################################################################################
-# SDK
-
-ifneq (,$(SDK_LIBRARY))
-$(SDK_LIB_DIR)::
-	$(NSINSTALL) -D $@
-
-ifndef NO_DIST_INSTALL
-libs:: $(SDK_LIBRARY) $(SDK_LIB_DIR)
-	$(INSTALL) $(IFLAGS2) $^
-endif
-
-endif # SDK_LIBRARY
-
-ifneq (,$(strip $(SDK_BINARY)))
-$(SDK_BIN_DIR)::
-	$(NSINSTALL) -D $@
-
-ifndef NO_DIST_INSTALL
-libs:: $(SDK_BINARY) $(SDK_BIN_DIR)
-	$(INSTALL) $(IFLAGS2) $^
-endif
-
-endif # SDK_BINARY
-
-################################################################################
-# CHROME PACKAGING
-
-JAR_MANIFEST := $(srcdir)/jar.mn
-
-chrome::
-	$(MAKE) realchrome
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-$(FINAL_TARGET)/chrome:
-	$(NSINSTALL) -D $@
-
-ifneq (,$(wildcard $(JAR_MANIFEST)))
-ifndef NO_DIST_INSTALL
-libs realchrome:: $(CHROME_DEPS) $(FINAL_TARGET)/chrome
-	$(PYTHON) $(MOZILLA_DIR)/config/JarMaker.py \
-	  $(QUIET) -j $(FINAL_TARGET)/chrome \
-	  $(MAKE_JARS_FLAGS) $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
-	  $(JAR_MANIFEST)
-endif
-endif
-
-ifneq ($(DIST_FILES),)
-$(DIST)/bin:
-	$(NSINSTALL) -D $@
-
-libs:: $(DIST)/bin
-libs:: $(DIST_FILES)
-	@$(EXIT_ON_ERROR) \
-	for f in $^; do \
-	  dest=$(FINAL_TARGET)/`basename $$f`; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \
-	    $(XULAPP_DEFINES) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
-	    $$f > $$dest; \
-	done
-endif
-
-ifneq ($(DIST_CHROME_FILES),)
-libs:: $(DIST_CHROME_FILES)
-	@$(EXIT_ON_ERROR) \
-	for f in $^; do \
-	  dest=$(FINAL_TARGET)/chrome/`basename $$f`; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \
-	    $(XULAPP_DEFINES) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
-	    $$f > $$dest; \
-	done
-endif
-
-ifneq ($(XPI_PKGNAME),)
-libs realchrome::
-ifdef STRIP_XPI
-ifndef MOZ_DEBUG
-	@echo "Stripping $(XPI_PKGNAME) package directory..."
-	@echo $(FINAL_TARGET)
-	@cd $(FINAL_TARGET) && find . ! -type d \
-			! -name "*.js" \
-			! -name "*.xpt" \
-			! -name "*.gif" \
-			! -name "*.jpg" \
-			! -name "*.png" \
-			! -name "*.xpm" \
-			! -name "*.txt" \
-			! -name "*.rdf" \
-			! -name "*.sh" \
-			! -name "*.properties" \
-			! -name "*.dtd" \
-			! -name "*.html" \
-			! -name "*.xul" \
-			! -name "*.css" \
-			! -name "*.xml" \
-			! -name "*.jar" \
-			! -name "*.dat" \
-			! -name "*.tbl" \
-			! -name "*.src" \
-			! -name "*.reg" \
-			$(PLATFORM_EXCLUDE_LIST) \
-			-exec $(STRIP) $(STRIP_FLAGS) {} >/dev/null 2>&1 \;
-endif
-endif
-	@echo "Packaging $(XPI_PKGNAME).xpi..."
-	cd $(FINAL_TARGET) && $(ZIP) -qr ../$(XPI_PKGNAME).xpi *
-endif
-
-ifdef INSTALL_EXTENSION_ID
-ifndef XPI_NAME
-$(error XPI_NAME must be set for INSTALL_EXTENSION_ID)
-endif
-
-libs::
-	$(RM) -r "$(DIST)/bin/extensions/$(INSTALL_EXTENSION_ID)"
-	$(NSINSTALL) -D "$(DIST)/bin/extensions/$(INSTALL_EXTENSION_ID)"
-	cd $(FINAL_TARGET) && tar $(TAR_CREATE_FLAGS) - . | (cd "../../bin/extensions/$(INSTALL_EXTENSION_ID)" && tar -xf -)
-
-endif
-
-ifneq (,$(filter flat symlink,$(MOZ_CHROME_FILE_FORMAT)))
-_JAR_REGCHROME_DISABLE_JAR=1
-else
-_JAR_REGCHROME_DISABLE_JAR=0
-endif
-
-REGCHROME = $(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/add-chrome.pl \
-	$(if $(filter gtk2,$(MOZ_WIDGET_TOOLKIT)),-x) \
-	$(if $(CROSS_COMPILE),-o $(OS_ARCH)) $(FINAL_TARGET)/chrome/installed-chrome.txt \
-	$(_JAR_REGCHROME_DISABLE_JAR)
-
-REGCHROME_INSTALL = $(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/add-chrome.pl \
-	$(if $(filter gtk2,$(MOZ_WIDGET_TOOLKIT)),-x) \
-	$(if $(CROSS_COMPILE),-o $(OS_ARCH)) $(DESTDIR)$(mozappdir)/chrome/installed-chrome.txt \
-	$(_JAR_REGCHROME_DISABLE_JAR)
-
-
-#############################################################################
-# Dependency system
-#############################################################################
-ifdef COMPILER_DEPEND
-depend::
-	@echo "$(MAKE): No need to run depend target.\
-			Using compiler-based depend." 1>&2
-ifeq ($(GNU_CC)$(GNU_CXX),)
-# Non-GNU compilers
-	@echo "`echo '$(MAKE):'|sed 's/./ /g'`"\
-	'(Compiler-based depend was turned on by "--enable-md".)' 1>&2
-else
-# GNU compilers
-	@space="`echo '$(MAKE): '|sed 's/./ /g'`";\
-	echo "$$space"'Since you are using a GNU compiler,\
-		it is on by default.' 1>&2; \
-	echo "$$space"'To turn it off, pass --disable-md to configure.' 1>&2
-endif
-
-else # ! COMPILER_DEPEND
-
-ifndef MOZ_AUTO_DEPS
-
-define MAKE_DEPS_NOAUTO
-	$(MKDEPEND) -w1024 -o'.$(OBJ_SUFFIX)' -f- $(DEFINES) $(ACDEFINES) $(INCLUDES) $< 2>/dev/null | sed -e "s|^[^ ]*/||" > $@
-endef
-
-$(MDDEPDIR)/%.pp: %.c
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_NOAUTO)
-
-$(MDDEPDIR)/%.pp: %.cpp
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_NOAUTO)
-
-$(MDDEPDIR)/%.pp: %.s
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_NOAUTO)
-
-ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
-depend:: $(SUBMAKEFILES) $(MAKE_DIRS) $(MDDEPFILES)
-else
-depend:: $(SUBMAKEFILES)
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-dependclean:: $(SUBMAKEFILES)
-	$(RM) $(MDDEPFILES)
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-endif # MOZ_AUTO_DEPS
-
-endif # COMPILER_DEPEND
-
-
-#############################################################################
-# MDDEPDIR is the subdirectory where all the dependency files are placed.
-#   This uses a make rule (instead of a macro) to support parallel
-#   builds (-jN). If this were done in the LOOP_OVER_DIRS macro, two
-#   processes could simultaneously try to create the same directory.
-#
-#   We use $(CURDIR) in the rule's target to ensure that we don't find
-#   a dependency directory in the source tree via VPATH (perhaps from
-#   a previous build in the source tree) and thus neglect to create a
-#   dependency directory in the object directory, where we really need
-#   it.
-
-$(CURDIR)/$(MDDEPDIR):
-	$(MKDIR) -p $@
-
-ifneq (,$(filter-out all chrome default export realchrome tools clean clobber clobber_all distclean realclean,$(MAKECMDGOALS)))
-ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
-MDDEPEND_FILES		:= $(strip $(wildcard $(MDDEPDIR)/*.pp))
-
-ifneq (,$(MDDEPEND_FILES))
-# The script mddepend.pl checks the dependencies and writes to stdout
-# one rule to force out-of-date objects. For example,
-#   foo.o boo.o: FORCE
-# The script has an advantage over including the *.pp files directly
-# because it handles the case when header files are removed from the build.
-# 'make' would complain that there is no way to build missing headers.
-ALL_PP_RESULTS = $(shell $(PERL) $(BUILD_TOOLS)/mddepend.pl - $(MDDEPEND_FILES))
-$(eval $(ALL_PP_RESULTS))
-endif
-
-endif
-endif
-#############################################################################
-
--include $(topsrcdir)/$(MOZ_BUILD_APP)/app-rules.mk
--include $(MY_RULES)
-
-#
-# Generate Emacs tags in a file named TAGS if ETAGS was set in $(MY_CONFIG)
-# or in $(MY_RULES)
-#
-ifdef ETAGS
-ifneq ($(CSRCS)$(CPPSRCS)$(HEADERS),)
-all:: TAGS
-TAGS:: $(CSRCS) $(CPPSRCS) $(HEADERS)
-	$(ETAGS) $(CSRCS) $(CPPSRCS) $(HEADERS)
-endif
-endif
-
-################################################################################
-# Special gmake rules.
-################################################################################
-
-
-#
-# Disallow parallel builds with MSVC < 8
-#
-ifneq (,$(filter 1200 1300 1310,$(_MSC_VER)))
-.NOTPARALLEL:
-endif
-
-#
-# Re-define the list of default suffixes, so gmake won't have to churn through
-# hundreds of built-in suffix rules for stuff we don't need.
-#
-.SUFFIXES:
-
-#
-# Fake targets.  Always run these rules, even if a file/directory with that
-# name already exists.
-#
-.PHONY: all alltags boot checkout chrome realchrome clean clobber clobber_all export install libs makefiles realclean run_apprunner tools $(DIRS) $(TOOL_DIRS) FORCE
-
-# Used as a dependency to force targets to rebuild
-FORCE:
-
-# Delete target if error occurs when building target
-.DELETE_ON_ERROR:
-
-# Properly set LIBPATTERNS for the platform
-.LIBPATTERNS = $(if $(IMPORT_LIB_SUFFIX),$(LIB_PREFIX)%.$(IMPORT_LIB_SUFFIX)) $(LIB_PREFIX)%.$(LIB_SUFFIX) $(DLL_PREFIX)%$(DLL_SUFFIX)
-
-tags: TAGS
-
-TAGS: $(SUBMAKEFILES) $(CSRCS) $(CPPSRCS) $(wildcard *.h)
-	-etags $(CSRCS) $(CPPSRCS) $(wildcard *.h)
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-
-echo-variable-%:
-	@echo "$($*)"
-
-echo-tiers:
-	@echo $(TIERS)
-
-echo-tier-dirs:
-	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
-
-echo-dirs:
-	@echo $(DIRS)
-
-echo-module:
-	@echo $(MODULE)
-
-echo-depth-path:
-	@$(topsrcdir)/build/unix/print-depth-path.sh
-
-echo-module-name:
-	@$(topsrcdir)/build/package/rpm/print-module-name.sh
-
-echo-module-filelist:
-	@$(topsrcdir)/build/package/rpm/print-module-filelist.sh
-
-showtargs:
-ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY),$(TARGETS)))
-	@echo --------------------------------------------------------------------------------
-	@echo "PROGRAM             = $(PROGRAM)"
-	@echo "SIMPLE_PROGRAMS     = $(SIMPLE_PROGRAMS)"
-	@echo "LIBRARY             = $(LIBRARY)"
-	@echo "SHARED_LIBRARY      = $(SHARED_LIBRARY)"
-	@echo "SHARED_LIBRARY_LIBS = $(SHARED_LIBRARY_LIBS)"
-	@echo "LIBS                = $(LIBS)"
-	@echo "DEF_FILE            = $(DEF_FILE)"
-	@echo "IMPORT_LIBRARY      = $(IMPORT_LIBRARY)"
-	@echo "STATIC_LIBS         = $(STATIC_LIBS)"
-	@echo "SHARED_LIBS         = $(SHARED_LIBS)"
-	@echo "EXTRA_DSO_LIBS      = $(EXTRA_DSO_LIBS)"
-	@echo "EXTRA_DSO_LDOPTS    = $(EXTRA_DSO_LDOPTS)"
-	@echo "DEPENDENT_LIBS      = $(DEPENDENT_LIBS)"
-	@echo --------------------------------------------------------------------------------
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-
-showbuild:
-	@echo "MOZ_BUILD_ROOT     = $(MOZ_BUILD_ROOT)"
-	@echo "MOZ_WIDGET_TOOLKIT = $(MOZ_WIDGET_TOOLKIT)"
-	@echo "CC                 = $(CC)"
-	@echo "CXX                = $(CXX)"
-	@echo "CCC                = $(CCC)"
-	@echo "CPP                = $(CPP)"
-	@echo "LD                 = $(LD)"
-	@echo "AR                 = $(AR)"
-	@echo "IMPLIB             = $(IMPLIB)"
-	@echo "FILTER             = $(FILTER)"
-	@echo "MKSHLIB            = $(MKSHLIB)"
-	@echo "MKCSHLIB           = $(MKCSHLIB)"
-	@echo "RC                 = $(RC)"
-	@echo "MC                 = $(MC)"
-	@echo "CFLAGS             = $(CFLAGS)"
-	@echo "OS_CFLAGS          = $(OS_CFLAGS)"
-	@echo "COMPILE_CFLAGS     = $(COMPILE_CFLAGS)"
-	@echo "CXXFLAGS           = $(CXXFLAGS)"
-	@echo "OS_CXXFLAGS        = $(OS_CXXFLAGS)"
-	@echo "COMPILE_CXXFLAGS   = $(COMPILE_CXXFLAGS)"
-	@echo "COMPILE_CMFLAGS    = $(COMPILE_CMFLAGS)"
-	@echo "COMPILE_CMMFLAGS   = $(COMPILE_CMMFLAGS)"
-	@echo "LDFLAGS            = $(LDFLAGS)"
-	@echo "OS_LDFLAGS         = $(OS_LDFLAGS)"
-	@echo "DSO_LDOPTS         = $(DSO_LDOPTS)"
-	@echo "OS_INCLUDES        = $(OS_INCLUDES)"
-	@echo "OS_LIBS            = $(OS_LIBS)"
-	@echo "EXTRA_LIBS         = $(EXTRA_LIBS)"
-	@echo "BIN_FLAGS          = $(BIN_FLAGS)"
-	@echo "INCLUDES           = $(INCLUDES)"
-	@echo "DEFINES            = $(DEFINES)"
-	@echo "ACDEFINES          = $(ACDEFINES)"
-	@echo "BIN_SUFFIX         = $(BIN_SUFFIX)"
-	@echo "LIB_SUFFIX         = $(LIB_SUFFIX)"
-	@echo "DLL_SUFFIX         = $(DLL_SUFFIX)"
-	@echo "IMPORT_LIB_SUFFIX  = $(IMPORT_LIB_SUFFIX)"
-	@echo "INSTALL            = $(INSTALL)"
-	@echo "VPATH              = $(VPATH)"
-
-showhost:
-	@echo "HOST_CC            = $(HOST_CC)"
-	@echo "HOST_CXX           = $(HOST_CXX)"
-	@echo "HOST_CFLAGS        = $(HOST_CFLAGS)"
-	@echo "HOST_LDFLAGS       = $(HOST_LDFLAGS)"
-	@echo "HOST_LIBS          = $(HOST_LIBS)"
-	@echo "HOST_EXTRA_LIBS    = $(HOST_EXTRA_LIBS)"
-	@echo "HOST_EXTRA_DEPS    = $(HOST_EXTRA_DEPS)"
-	@echo "HOST_PROGRAM       = $(HOST_PROGRAM)"
-	@echo "HOST_OBJS          = $(HOST_OBJS)"
-	@echo "HOST_PROGOBJS      = $(HOST_PROGOBJS)"
-	@echo "HOST_LIBRARY       = $(HOST_LIBRARY)"
-
-showbuildmods::
-	@echo "Module dirs	= $(BUILD_MODULE_DIRS)"
-
-documentation:
-	@cd $(DEPTH)
-	$(DOXYGEN) $(DEPTH)/config/doxygen.cfg
-
-ifdef ENABLE_TESTS
-check:: $(SUBMAKEFILES) $(MAKE_DIRS)
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-endif
-
-
-FREEZE_VARIABLES = \
-  CSRCS \
-  CPPSRCS \
-  EXPORTS \
-  XPIDLSRCS \
-  DIRS \
-  LIBRARY \
-  MODULE \
-  SHORT_LIBNAME \
-  TIERS \
-  EXTRA_COMPONENTS \
-  EXTRA_PP_COMPONENTS \
-  $(NULL)
-
-$(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
-
-CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
-  $(if $(subst $($(var)_FROZEN),,'$($(var))'),$(error Makefile variable '$(var)' changed value after including rules.mk. Was $($(var)_FROZEN), now $($(var)).)))
-
-libs export libs::
-	$(CHECK_FROZEN_VARIABLES)
-
-default all::
-	if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
--- a/configure.in
+++ b/configure.in
@@ -8398,16 +8398,17 @@ AC_SUBST(MOZ_D3DX9_CAB)
 AC_SUBST(MOZ_D3DCOMPILER_CAB)
 AC_SUBST(MOZ_D3DX9_DLL)
 AC_SUBST(MOZ_D3DCOMPILER_DLL)
 
 AC_SUBST(MOZ_ANDROID_HISTORY)
 AC_SUBST(MOZ_WEBSMS_BACKEND)
 AC_SUBST(ENABLE_STRIP)
 AC_SUBST(PKG_SKIP_STRIP)
+AC_SUBST(STRIP_FLAGS)
 AC_SUBST(USE_ELF_DYNSTR_GC)
 AC_SUBST(USE_ELF_HACK)
 AC_SUBST(INCREMENTAL_LINKER)
 AC_SUBST(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
 AC_SUBST(MOZ_COMPONENT_NSPR_LIBS)
 
 AC_SUBST(MOZ_FIX_LINK_PATHS)
 AC_SUBST(XPCOM_LIBS)
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -130,16 +130,17 @@
 #include "nsHtml5Module.h"
 #include "prprf.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/Preferences.h"
 #include "nsMimeTypes.h"
 #include "nsIRequest.h"
 #include "nsHtml5TreeOpExecutor.h"
 #include "nsHtml5Parser.h"
+#include "nsIDOMJSWindow.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #define NS_MAX_DOCUMENT_WRITE_DEPTH 20
 
 #include "prmem.h"
 #include "prtime.h"
@@ -1321,19 +1322,20 @@ nsHTMLDocument::Open(const nsAString& aC
                "XOW should have caught this!");
 
   // When called with 3 or more arguments, document.open() calls window.open().
   if (aOptionalArgCount > 2) {
     nsCOMPtr<nsIDOMWindow> window = GetWindowInternal();
     if (!window) {
       return NS_OK;
     }
+    nsCOMPtr<nsIDOMJSWindow> win = do_QueryInterface(window);
     nsCOMPtr<nsIDOMWindow> newWindow;
-    nsresult rv = window->Open(aContentTypeOrUrl, aReplaceOrName, aFeatures,
-                               getter_AddRefs(newWindow));
+    nsresult rv = win->OpenJS(aContentTypeOrUrl, aReplaceOrName, aFeatures,
+                              getter_AddRefs(newWindow));
     *aReturn = newWindow.forget().get();
     return rv;
   }
 
   if (!IsHTML() || mDisableDocWrite) {
     // No calling document.open() on XHTML
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
--- a/content/html/document/test/Makefile.in
+++ b/content/html/document/test/Makefile.in
@@ -102,16 +102,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug499092.html \
 		bug499092.xml \
 		bug499092.html \
 		test_bug512367.html \
 		test_bug571981.html \
 		test_bug677495.html \
 		test_bug677495-1.html \
 		test_bug742261.html \
+		test_bug741266.html \
 		$(NULL)
 
 ifneq (mobile,$(MOZ_BUILD_APP))
 _BROWSER_TEST_FILES = \
 		browser_bug592641.js \
 		bug592641_img.jpg \
 		$(NULL)
 endif
new file mode 100644
--- /dev/null
+++ b/content/html/document/test/test_bug741266.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=741266
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 741266</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=741266">Mozilla Bug 741266</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 741266 **/
+var w = window.open("", "", "width=100,height=100");
+is(w.innerHeight, 100, "Popup height should be 100 when opened with window.open");
+// XXXbz On at least some platforms, the innerWidth is off by the scrollbar
+// width for some reason.  So just make sure it's the same for both popups.
+var width = w.innerWidth;
+w.close();
+w = document.open("", "", "width=100,height=100");
+is(w.innerHeight, 100, "Popup height should be 100 when opened with document.open");
+is(w.innerWidth, width, "Popup width should be the same when opened with document.open");
+w.close();
+</script>
+</pre>
+</body>
+</html>
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -395,17 +395,17 @@ nsXBLStreamListener::HandleEvent(nsIDOME
 
     // Remove ourselves from the set of pending docs.
     nsBindingManager *bindingManager = doc->BindingManager();
     nsIURI* documentURI = bindingDocument->GetDocumentURI();
     bindingManager->RemoveLoadingDocListener(documentURI);
 
     if (!bindingDocument->GetRootElement()) {
       // FIXME: How about an error console warning?
-      NS_WARNING("*** XBL doc with no root element! Something went horribly wrong! ***");
+      NS_WARNING("XBL doc with no root element - this usually shouldn't happen");
       return NS_ERROR_FAILURE;
     }
 
     // Put our doc info in the doc table.
     nsBindingManager *xblDocBindingManager = bindingDocument->BindingManager();
     nsRefPtr<nsXBLDocumentInfo> info =
       xblDocBindingManager->GetXBLDocumentInfo(documentURI);
     xblDocBindingManager->RemoveXBLDocumentInfo(info); // Break the self-imposed cycle.
--- a/dom/bindings/Makefile.in
+++ b/dom/bindings/Makefile.in
@@ -1,11 +1,11 @@
 # 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/.
+# 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/.
 
 DEPTH            = ../..
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 MODULE           = dom
 LIBRARY_NAME     = dombindings_s
@@ -70,28 +70,30 @@ bindinggen_dependencies := \
   Codegen.py \
   ParserResults.pkl \
   $(GLOBAL_DEPS) \
   $(NULL)
 
 $(binding_header_files): %Binding.h: $(bindinggen_dependencies) \
                                      $(webidl_base)/%.webidl \
                                      $(NULL)
-	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-    -I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
-    $(srcdir)/BindingGen.py $(ACCESSOR_OPT) header $(srcdir)/Bindings.conf $*Binding \
-    $(webidl_base)/$*.webidl
+	$(PYTHON_PATH) \
+	  $(PLY_INCLUDE) -I$(srcdir)/parser \
+    	  $(srcdir)/BindingGen.py $(ACCESSOR_OPT) header \
+	  $(srcdir)/Bindings.conf $*Binding \
+	  $(webidl_base)/$*.webidl
 
 $(binding_cpp_files): %Binding.cpp: $(bindinggen_dependencies) \
                                     $(webidl_base)/%.webidl \
                                     $(NULL)
-	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-    -I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
-    $(srcdir)/BindingGen.py $(ACCESSOR_OPT) cpp $(srcdir)/Bindings.conf $*Binding \
-    $(webidl_base)/$*.webidl
+	$(PYTHON_PATH) \
+	  $(PLY_INCLUDE) -I$(srcdir)/parser \
+	  $(srcdir)/BindingGen.py $(ACCESSOR_OPT) cpp \
+	  $(srcdir)/Bindings.conf $*Binding \
+	  $(webidl_base)/$*.webidl
 
 $(globalgen_targets): ParserResults.pkl
 
 CACHE_DIR = _cache
 
 globalgen_dependencies := \
   GlobalGen.py \
   Bindings.conf \
@@ -103,17 +105,17 @@ globalgen_dependencies := \
 
 $(CACHE_DIR)/.done:
 	$(MKDIR) -p $(CACHE_DIR)
 	@$(TOUCH) $@
 
 ParserResults.pkl: $(globalgen_dependencies) \
                    $(addprefix $(webidl_base)/, $(webidl_files))
 	$(PYTHON) $(topsrcdir)/config/pythonpath.py \
-    -I$(topsrcdir)/other-licenses/ply -I$(srcdir)/parser \
+    $(PLY_INCLUDE) -I$(srcdir)/parser \
     $(srcdir)/GlobalGen.py $(ACCESSOR_OPT) $(srcdir)/Bindings.conf $(webidl_base) \
     --cachedir=$(CACHE_DIR) \
     $(webidl_files)
 
 GARBAGE += \
   $(binding_header_files) \
   $(binding_cpp_files) \
   $(globalgen_targets) \
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -588,16 +588,34 @@ const PDU_ST_3_SC_SPECIFIC_END   = 0x7F;
 
 // User Data max length in septets
 const PDU_MAX_USER_DATA_7BIT = 160;
 // User Data max length in octets
 const PDU_MAX_USER_DATA_8BIT = 140;
 // User Data max length in chars
 const PDU_MAX_USER_DATA_UCS2 = 70;
 
+// PID - Protocol Indicator
+const PDU_PID_DEFAULT                      = 0x00;
+const PDU_PID_TELEMATIC_INTERWORKING       = 0x20;
+const PDU_PID_SHORT_MESSAGE_TYPE_0         = 0x40;
+const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_1 = 0x41;
+const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_2 = 0x42;
+const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_3 = 0x43;
+const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_4 = 0x44;
+const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_5 = 0x45;
+const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_6 = 0x46;
+const PDU_PID_REPLACE_SHORT_MESSAGE_TYPE_7 = 0x47;
+const PDU_PID_ENHANDED_MESSAGE_SERVICE     = 0x5E;
+const PDU_PID_RETURN_CALL_MESSAGE          = 0x5F
+const PDU_PID_ANSI_136_R_DATA              = 0x7C;
+const PDU_PID_ME_DATA_DOWNLOAD             = 0x7D;
+const PDU_PID_ME_DEPERSONALIZATION         = 0x7E;
+const PDU_PID_USIM_DATA_DOWNLOAD           = 0x7F;
+
 // DCS - Data Coding Scheme
 const PDU_DCS_MSG_CODING_7BITS_ALPHABET = 0x00;
 const PDU_DCS_MSG_CODING_8BITS_ALPHABET = 0x04;
 const PDU_DCS_MSG_CODING_16BITS_ALPHABET= 0x08;
 const PDU_DCS_MSG_CLASS_ME_SPECIFIC     = 0xF1;
 const PDU_DCS_MSG_CLASS_SIM_SPECIFIC    = 0xF2;
 const PDU_DCS_MSG_CLASS_TE_SPECIFIC     = 0xF3;
 
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -1513,16 +1513,23 @@ let RIL = {
    * @return A failure cause defined in 3GPP 23.040 clause 9.2.3.22.
    */
   _processSmsDeliver: function _processSmsDeliver(length) {
     let message = this._processReceivedSms(length);
     if (!message) {
       return PDU_FCS_UNSPECIFIED;
     }
 
+    if (message.epid == PDU_PID_SHORT_MESSAGE_TYPE_0) {
+      // `A short message type 0 indicates that the ME must acknowledge receipt
+      // of the short message but shall discard its contents.` ~ 3GPP TS 23.040
+      // 9.2.3.9
+      return PDU_FCS_OK;
+    }
+
     if (message.header && (message.header.segmentMaxSeq > 1)) {
       message = this._processReceivedSmsSegment(message);
     } else {
       message.fullBody = message.body;
     }
 
     if (message) {
       message.type = "sms-received";
@@ -2228,17 +2235,17 @@ RIL[REQUEST_CDMA_SET_BROADCAST_SMS_CONFI
 RIL[REQUEST_CDMA_SMS_BROADCAST_ACTIVATION] = null;
 RIL[REQUEST_CDMA_SUBSCRIPTION] = null;
 RIL[REQUEST_CDMA_WRITE_SMS_TO_RUIM] = null;
 RIL[REQUEST_CDMA_DELETE_SMS_ON_RUIM] = null;
 RIL[REQUEST_DEVICE_IDENTITY] = null;
 RIL[REQUEST_EXIT_EMERGENCY_CALLBACK_MODE] = null;
 RIL[REQUEST_GET_SMSC_ADDRESS] = function REQUEST_GET_SMSC_ADDRESS(length, options) {
   if (options.rilRequestError) {
-    if (options.body) {
+    if (options.type == "sendSMS") {
       this.sendDOMMessage({
         type: "sms-send-failed",
         envelopeId: options.envelopeId,
         error: options.rilRequestError,
       });
     }
     return;
   }
@@ -2924,38 +2931,64 @@ let GsmPDUHelper = {
     if ((toa >> 4) == (PDU_TOA_INTERNATIONAL >> 4)) {
       addr = '+' + addr;
     }
 
     return addr;
   },
 
   /**
+   * Read TP-Protocol-Indicator(TP-PID).
+   *
+   * @param msg
+   *        message object for output.
+   *
+   * @see 3GPP TS 23.040 9.2.3.9
+   */
+  readProtocolIndicator: function readProtocolIndicator(msg) {
+    // `The MS shall interpret reserved, obsolete, or unsupported values as the
+    // value 00000000 but shall store them exactly as received.`
+    msg.pid = this.readHexOctet();
+
+    msg.epid = msg.pid;
+    switch (msg.epid & 0xC0) {
+      case 0x40:
+        // Bit 7..0 = 01xxxxxx
+        switch (msg.epid) {
+          case PDU_PID_SHORT_MESSAGE_TYPE_0:
+            return;
+        }
+        break;
+    }
+    msg.epid = PDU_PID_DEFAULT;
+  },
+
+  /**
    * Read GSM TP-Service-Centre-Time-Stamp(TP-SCTS).
    *
    * @see 3GPP TS 23.040 9.2.3.11
    */
   readTimestamp: function readTimestamp() {
     let year   = this.readSwappedNibbleBCD(1) + PDU_TIMESTAMP_YEAR_OFFSET;
     let month  = this.readSwappedNibbleBCD(1) - 1;
     let day    = this.readSwappedNibbleBCD(1);
     let hour   = this.readSwappedNibbleBCD(1);
     let minute = this.readSwappedNibbleBCD(1);
     let second = this.readSwappedNibbleBCD(1);
     let timestamp = Date.UTC(year, month, day, hour, minute, second);
 
     // If the most significant bit of the least significant nibble is 1,
-    // the timezone offset is negative (fourth bit from the right => 0x08).
+    // the timezone offset is negative (fourth bit from the right => 0x08):
+    //   localtime = UTC + tzOffset
+    // therefore
+    //   UTC = localtime - tzOffset
     let tzOctet = this.readHexOctet();
     let tzOffset = this.octetToBCD(tzOctet & ~0x08) * 15 * 60 * 1000;
-    if (tzOctet & 0x08) {
-      timestamp -= tzOffset;
-    } else {
-      timestamp += tzOffset;
-    }
+    tzOffset = (tzOctet & 0x08) ? -tzOffset : tzOffset;
+    timestamp -= tzOffset;
 
     return timestamp;
   },
 
   /**
    * User data can be 7 bit (default alphabet) data, 8 bit data, or 16 bit
    * (UCS2) data.
    *
@@ -3069,17 +3102,17 @@ let GsmPDUHelper = {
 
     // `If the TP-UDL bit is set to "1" but the TP-DCS bit is set to "0" then
     // the receiving entity shall for TP-DCS assume a value of 0x00, i.e. the
     // 7bit default alphabet.` ~ 3GPP 23.040 9.2.3.27
     msg.dcs = 0;
 
     // TP-Protocol-Identifier
     if (pi & PDU_PI_PROTOCOL_IDENTIFIER) {
-      msg.pid = this.readHexOctet();
+      this.readProtocolIndicator(msg);
     }
     // TP-Data-Coding-Scheme
     if (pi & PDU_PI_DATA_CODING_SCHEME) {
       msg.dcs = this.readHexOctet();
     }
     // TP-User-Data-Length
     if (pi & PDU_PI_USER_DATA_LENGTH) {
       let userDataLength = this.readHexOctet();
@@ -3101,16 +3134,17 @@ let GsmPDUHelper = {
       // M:Mandatory, O:Optional, X:Unavailable
       //                  D  DR S  SR ST C
       SMSC:      null, // M  M  M  M  M  M
       mti:       null, // M  M  M  M  M  M
       udhi:      null, // M  M  X  M  M  M
       sender:    null, // M  X  X  X  X  X
       recipient: null, // X  X  M  X  M  M
       pid:       null, // M  O  M  O  O  M
+      epid:      null, // M  O  M  O  O  M
       dcs:       null, // M  O  M  O  O  X
       body:      null, // M  O  M  O  O  O
       timestamp: null, // M  X  X  X  X  X
       status:    null, // X  X  X  X  M  X
       scts:      null, // X  X  X  M  M  X
       dt:        null, // X  X  X  X  M  X
     };
 
@@ -3152,17 +3186,17 @@ let GsmPDUHelper = {
    * @param msg
    *        message object for output.
    */
   readDeliverMessage: function readDeliverMessage(msg) {
     // - Sender Address info -
     let senderAddressLength = this.readHexOctet();
     msg.sender = this.readAddress(senderAddressLength);
     // - TP-Protocolo-Identifier -
-    msg.pid = this.readHexOctet();
+    this.readProtocolIndicator(msg);
     // - TP-Data-Coding-Scheme -
     msg.dcs = this.readHexOctet();
     // - TP-Service-Center-Time-Stamp -
     msg.timestamp = this.readTimestamp();
     // - TP-User-Data-Length -
     let userDataLength = this.readHexOctet();
 
     // - TP-User-Data -
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -2797,18 +2797,17 @@ WorkerPrivate::OperationCallback(JSConte
     // Run all control events now.
     mayContinue = ProcessAllControlRunnables();
 
     if (!mayContinue || !mSuspended) {
       break;
     }
 
     // Clean up before suspending.
-    JS_FlushCaches(aCx);
-    JS_GC(aCx);
+    JS_GC(JS_GetRuntime(aCx));
 
     while ((mayContinue = MayContinueRunning())) {
       MutexAutoLock lock(mMutex);
       if (!mControlQueue.IsEmpty()) {
         break;
       }
 
       mCondVar.Wait(PR_MillisecondsToInterval(RemainingRunTimeMS()));
@@ -3886,22 +3885,23 @@ WorkerPrivate::UpdateGCZealInternal(JSCo
 #endif
 
 void
 WorkerPrivate::GarbageCollectInternal(JSContext* aCx, bool aShrinking,
                                       bool aCollectChildren)
 {
   AssertIsOnWorkerThread();
 
-  js::PrepareForFullGC(JS_GetRuntime(aCx));
+  JSRuntime *rt = JS_GetRuntime(aCx);
+  js::PrepareForFullGC(rt);
   if (aShrinking) {
-    js::ShrinkingGC(aCx, js::gcreason::DOM_WORKER);
+    js::ShrinkingGC(rt, js::gcreason::DOM_WORKER);
   }
   else {
-    js::GCForReason(aCx, js::gcreason::DOM_WORKER);
+    js::GCForReason(rt, js::gcreason::DOM_WORKER);
   }
 
   if (aCollectChildren) {
     for (PRUint32 index = 0; index < mChildWorkers.Length(); index++) {
       mChildWorkers[index]->GarbageCollect(aCx, aShrinking);
     }
   }
 }
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -1841,17 +1841,17 @@ public class GeckoAppShell
         GeckoNetworkManager.getInstance().enableNotifications();
     }
 
     public static void disableNetworkNotifications() {
         GeckoNetworkManager.getInstance().disableNotifications();
     }
 
     // This is only used in Native Fennec.
-    public static void setPreventPanning(final boolean aPreventPanning) { }
+    public static void notifyDefaultPrevented(boolean defaultPrevented) { }
 
     public static short getScreenOrientation() {
         return GeckoScreenOrientationListener.getInstance().getScreenOrientation();
     }
 
     public static void enableScreenOrientationNotifications() {
         GeckoScreenOrientationListener.getInstance().enableNotifications();
     }
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -102,16 +102,17 @@ static const char *sExtensionNames[] = {
     "GL_EXT_texture_filter_anisotropic",
     "GL_EXT_framebuffer_blit",
     "GL_ANGLE_framebuffer_blit",
     "GL_EXT_framebuffer_multisample",
     "GL_ANGLE_framebuffer_multisample",
     "GL_OES_rgb8_rgba8",
     "GL_ARB_robustness",
     "GL_EXT_robustness",
+    "GL_ARB_sync",
     NULL
 };
 
 /*
  * XXX - we should really know the ARB/EXT variants of these
  * instead of only handling the symbol if it's exposed directly.
  */
 
@@ -445,16 +446,42 @@ GLContext::InitWithPrefix(const char *pr
             if (!LoadSymbols(&auxSymbols[0], trygl, prefix)) {
                 NS_ERROR("GL supports framebuffer_multisample without supplying glRenderbufferStorageMultisample");
 
                 MarkExtensionUnsupported(ANGLE_framebuffer_multisample);
                 MarkExtensionUnsupported(EXT_framebuffer_multisample);
                 mSymbols.fRenderbufferStorageMultisample = nsnull;
             }
         }
+
+        if (IsExtensionSupported(ARB_sync)) {
+            SymLoadStruct syncSymbols[] = {
+                { (PRFuncPtr*) &mSymbols.fFenceSync,      { "FenceSync",      nsnull } },
+                { (PRFuncPtr*) &mSymbols.fIsSync,         { "IsSync",         nsnull } },
+                { (PRFuncPtr*) &mSymbols.fDeleteSync,     { "DeleteSync",     nsnull } },
+                { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "ClientWaitSync", nsnull } },
+                { (PRFuncPtr*) &mSymbols.fWaitSync,       { "WaitSync",       nsnull } },
+                { (PRFuncPtr*) &mSymbols.fGetInteger64v,  { "GetInteger64v",  nsnull } },
+                { (PRFuncPtr*) &mSymbols.fGetSynciv,      { "GetSynciv",      nsnull } },
+                { nsnull, { nsnull } },
+            };
+
+            if (!LoadSymbols(&syncSymbols[0], trygl, prefix)) {
+                NS_ERROR("GL supports ARB_sync without supplying its functions.");
+
+                MarkExtensionUnsupported(ARB_sync);
+                mSymbols.fFenceSync = nsnull;
+                mSymbols.fIsSync = nsnull;
+                mSymbols.fDeleteSync = nsnull;
+                mSymbols.fClientWaitSync = nsnull;
+                mSymbols.fWaitSync = nsnull;
+                mSymbols.fGetInteger64v = nsnull;
+                mSymbols.fGetSynciv = nsnull;
+            }
+        }
        
         // Load developer symbols, don't fail if we can't find them.
         SymLoadStruct auxSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nsnull } },
                 { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nsnull } },
                 { nsnull, { nsnull } },
         };
         LoadSymbols(&auxSymbols[0], trygl, prefix);
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -1495,16 +1495,17 @@ public:
         EXT_texture_filter_anisotropic,
         EXT_framebuffer_blit,
         ANGLE_framebuffer_blit,
         EXT_framebuffer_multisample,
         ANGLE_framebuffer_multisample,
         OES_rgb8_rgba8,
         ARB_robustness,
         EXT_robustness,
+        ARB_sync,
         Extensions_Max
     };
 
     bool IsExtensionSupported(GLExtensions aKnownExtension) {
         return mAvailableExtensions[aKnownExtension];
     }
 
     void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
@@ -2893,16 +2894,61 @@ public:
 
      GLenum GLAPIENTRY fGetGraphicsResetStatus() {
          BEFORE_GL_CALL;
          GLenum ret = mHasRobustness ? mSymbols.fGetGraphicsResetStatus() : 0;
          AFTER_GL_CALL;
          return ret;
      }
 
+     GLsync GLAPIENTRY fFenceSync(GLenum condition, GLbitfield flags) {
+         BEFORE_GL_CALL;
+         GLsync ret = mSymbols.fFenceSync(condition, flags);
+         AFTER_GL_CALL;
+         return ret;
+     }
+
+     realGLboolean GLAPIENTRY fIsSync(GLsync sync) {
+         BEFORE_GL_CALL;
+         realGLboolean ret = mSymbols.fIsSync(sync);
+         AFTER_GL_CALL;
+         return ret;
+     }
+
+     void GLAPIENTRY fDeleteSync(GLsync sync) {
+         BEFORE_GL_CALL;
+         mSymbols.fDeleteSync(sync);
+         AFTER_GL_CALL;
+     }
+
+     GLenum GLAPIENTRY fClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
+         BEFORE_GL_CALL;
+         GLenum ret = mSymbols.fClientWaitSync(sync, flags, timeout);
+         AFTER_GL_CALL;
+         return ret;
+     }
+
+     void GLAPIENTRY fWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) {
+         BEFORE_GL_CALL;
+         mSymbols.fWaitSync(sync, flags, timeout);
+         AFTER_GL_CALL;
+     }
+
+     void GLAPIENTRY fGetInteger64v(GLenum pname, GLint64 *params) {
+         BEFORE_GL_CALL;
+         mSymbols.fGetInteger64v(pname, params);
+         AFTER_GL_CALL;
+     }
+
+     void GLAPIENTRY fGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
+         BEFORE_GL_CALL;
+         mSymbols.fGetSynciv(sync, pname, bufSize, length, values);
+         AFTER_GL_CALL;
+     }
+
 #ifdef DEBUG
     void THEBES_API CreatedProgram(GLContext *aOrigin, GLuint aName);
     void THEBES_API CreatedShader(GLContext *aOrigin, GLuint aName);
     void THEBES_API CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void THEBES_API CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void THEBES_API CreatedFramebuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void THEBES_API CreatedRenderbuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void THEBES_API DeletedProgram(GLContext *aOrigin, GLuint aName);
--- a/gfx/gl/GLContextSymbols.h
+++ b/gfx/gl/GLContextSymbols.h
@@ -35,16 +35,18 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef GLCONTEXTSYMBOLS_H_
 #define GLCONTEXTSYMBOLS_H_
 
+#include "GLDefs.h"
+
 /*
  * This file should only be included by GLContext.h, and should be
  * autogenerated in the future.
  */
 
 #ifndef GLAPIENTRY
 #ifdef XP_WIN
 #define GLAPIENTRY __stdcall
@@ -376,14 +378,32 @@ struct GLContextSymbols
 
     typedef void* (GLAPIENTRY * PFNGLMAPBUFFER) (GLenum target, GLenum access);
     PFNGLMAPBUFFER fMapBuffer;
     typedef realGLboolean (GLAPIENTRY * PFNGLUNMAPBUFFER) (GLenum target);
     PFNGLUNMAPBUFFER fUnmapBuffer;
 
     typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUS) (void);
     PFNGLGETGRAPHICSRESETSTATUS fGetGraphicsResetStatus;
+
+    /*
+     * ARB_sync extension
+     */
+    typedef GLsync (GLAPIENTRY * PFNGLFENCESYNC) (GLenum condition, GLbitfield flags);
+    PFNGLFENCESYNC fFenceSync;
+    typedef realGLboolean (GLAPIENTRY * PFNGLISSYNC) (GLsync sync);
+    PFNGLISSYNC fIsSync;
+    typedef void (GLAPIENTRY * PFNGLDELETESYNC) (GLsync sync);
+    PFNGLDELETESYNC fDeleteSync;
+    typedef GLenum (GLAPIENTRY * PFNGLCLIENTWAITSYNC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+    PFNGLCLIENTWAITSYNC fClientWaitSync;
+    typedef void (GLAPIENTRY * PFNGLWAITSYNC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+    PFNGLWAITSYNC fWaitSync;
+    typedef void (GLAPIENTRY * PFNGLGETINTEGER64V) (GLenum pname, GLint64 *params);
+    PFNGLGETINTEGER64V fGetInteger64v;
+    typedef void (GLAPIENTRY * PFNGLGETSYNCIV) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+    PFNGLGETSYNCIV fGetSynciv;
 };
 
 }
 }
 
 #endif /* GLCONTEXTSYMBOLS_H_ */
--- a/gfx/gl/GLDefs.h
+++ b/gfx/gl/GLDefs.h
@@ -32,17 +32,16 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #if !defined(LOCALGL_H_)
-
 #define LOCALGL_H_
 
 #if !defined(__gltypes_h_) && !defined(__gl_h_)
 #define __gltypes_h_
 #define __gl_h_
 
 #include <stddef.h>
 
@@ -67,16 +66,24 @@ typedef void GLvoid;
 typedef char GLchar;
 #ifndef __gl2_h_
 typedef ptrdiff_t GLsizeiptr;
 typedef ptrdiff_t GLintptr;
 #endif
 
 #endif /* #if !defined(__gltypes_h_) && !defined(__gl_h_) */
 
+#include "mozilla/StandardInteger.h"
+
+// ARB_sync
+typedef struct __GLsync *GLsync;
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+
+
 #ifndef GLAPIENTRY
 # ifdef WIN32
 #  define GLAPIENTRY APIENTRY
 #  define GLAPI
 # else
 #  define GLAPIENTRY
 #  define GLAPI
 # endif
@@ -3027,16 +3034,33 @@ typedef ptrdiff_t GLintptr;
 #define LOCAL_GL_SUN_vertex 1
 #define LOCAL_GL_WIN_phong_shading 1
 #define LOCAL_GL_PHONG_WIN 0x80EA
 #define LOCAL_GL_PHONG_HINT_WIN 0x80EB
 #define LOCAL_GL_WIN_specular_fog 1
 #define LOCAL_GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
 #define LOCAL_GL_WIN_swap_hint 1
 
+// ARB_sync
+#define LOCAL_GL_MAX_SERVER_WAIT_TIMEOUT          0x9111
+#define LOCAL_GL_OBJECT_TYPE                      0x9112
+#define LOCAL_GL_SYNC_CONDITION                   0x9113
+#define LOCAL_GL_SYNC_STATUS                      0x9114
+#define LOCAL_GL_SYNC_FLAGS                       0x9115
+#define LOCAL_GL_SYNC_FENCE                       0x9116
+#define LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE       0x9117
+#define LOCAL_GL_UNSIGNALED                       0x9118
+#define LOCAL_GL_SIGNALED                         0x9119
+#define LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT          0x00000001
+#define LOCAL_GL_TIMEOUT_IGNORED                  0xFFFFFFFFFFFFFFFFull
+#define LOCAL_GL_ALREADY_SIGNALED                 0x911A
+#define LOCAL_GL_TIMEOUT_EXPIRED                  0x911B
+#define LOCAL_GL_CONDITION_SATISFIED              0x911C
+#define LOCAL_GL_WAIT_FAILED                      0x911D
+
 #define LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS       0x8DFB
 #define LOCAL_GL_MAX_VARYING_VECTORS              0x8DFC
 #define LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS     0x8DFD
 #define LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE   0x8B9A
 #define LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B
 #define LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS    0x9125
 #define LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS     0x9122
 
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -370,94 +370,88 @@ gfxDWriteFontEntry::GetFontTable(PRUint3
 
 nsresult
 gfxDWriteFontEntry::ReadCMAP()
 {
     HRESULT hr;
     nsresult rv;
 
     // attempt this once, if errors occur leave a blank cmap
-    if (mCmapInitialized)
+    if (mCharacterMap) {
         return NS_OK;
-    mCmapInitialized = true;
+    }
+
+    nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
 
     // if loading via GDI, just use GetFontTable
     if (mFont && gfxDWriteFontList::PlatformFontList()->UseGDIFontTableAccess()) {
-        const PRUint32 kCmapTag = TRUETYPE_TAG('c','m','a','p');
-        AutoFallibleTArray<PRUint8,16384> buffer;
+        PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
+        nsresult rv;
+
+        AutoFallibleTArray<PRUint8,16384> cmap;
+        rv = GetFontTable(kCMAP, cmap);
+
+        bool unicodeFont = false, symbolFont = false; // currently ignored
 
-        if (GetFontTable(kCmapTag, buffer) != NS_OK)
-            return NS_ERROR_FAILURE;
-        PRUint8 *cmap = buffer.Elements();
+        if (NS_SUCCEEDED(rv)) {
+            rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
+                                        *charmap, mUVSOffset,
+                                        unicodeFont, symbolFont);
+        }
+    } else {
+        // loading using dwrite, don't use GetFontTable to avoid copy
+        nsRefPtr<IDWriteFontFace> fontFace;
+        rv = CreateFontFace(getter_AddRefs(fontFace));
 
-        bool          unicodeFont = false, symbolFont = false;
-        rv = gfxFontUtils::ReadCMAP(cmap, buffer.Length(),
-                                    mCharacterMap, mUVSOffset,
-                                    unicodeFont, symbolFont);
-#ifdef PR_LOGGING
-        LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
-                      NS_ConvertUTF16toUTF8(mName).get(),
-                      mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
-        if (LOG_CMAPDATA_ENABLED()) {
-            char prefix[256];
-            sprintf(prefix, "(cmapdata) name: %.220s",
-                    NS_ConvertUTF16toUTF8(mName).get());
-            mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
+        if (NS_SUCCEEDED(rv)) {
+            const PRUint32 kCmapTag = DWRITE_MAKE_OPENTYPE_TAG('c', 'm', 'a', 'p');
+            PRUint8 *tableData;
+            PRUint32 len;
+            void *tableContext = NULL;
+            BOOL exists;
+            hr = fontFace->TryGetFontTable(kCmapTag, (const void**)&tableData,
+                                           &len, &tableContext, &exists);
+
+            if (SUCCEEDED(hr)) {
+                bool isSymbol = fontFace->IsSymbolFont();
+                bool isUnicode = true;
+                if (exists) {
+                    rv = gfxFontUtils::ReadCMAP(tableData, len, *charmap,
+                                                mUVSOffset, isUnicode,
+                                                isSymbol);
+                }
+                fontFace->ReleaseFontTable(tableContext);
+            } else {
+                rv = NS_ERROR_FAILURE;
+            }
         }
-#endif
-        mHasCmapTable = NS_SUCCEEDED(rv);
-        return rv;
     }
 
-    // loading using dwrite, don't use GetFontTable to avoid copy
-    nsRefPtr<IDWriteFontFace> fontFace;
-    rv = CreateFontFace(getter_AddRefs(fontFace));
-
-    if (NS_FAILED(rv)) {
-        return rv;
+    mHasCmapTable = NS_SUCCEEDED(rv);
+    if (mHasCmapTable) {
+        gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
+        mCharacterMap = pfl->FindCharMap(charmap);
+    } else {
+        // if error occurred, initialize to null cmap
+        mCharacterMap = new gfxCharacterMap();
     }
 
-    PRUint8 *tableData;
-    PRUint32 len;
-    void *tableContext = NULL;
-    BOOL exists;
-    hr = fontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('c', 'm', 'a', 'p'),
-                                   (const void**)&tableData,
-                                   &len,
-                                   &tableContext,
-                                   &exists);
-    if (FAILED(hr)) {
-        return NS_ERROR_FAILURE;
-    }
-
-    bool isSymbol = fontFace->IsSymbolFont();
-    bool isUnicode = true;
-    if (exists) {
-        rv = gfxFontUtils::ReadCMAP(tableData,
-                                    len,
-                                    mCharacterMap,
-                                    mUVSOffset,
-                                    isUnicode,
-                                    isSymbol);
-    }
-    fontFace->ReleaseFontTable(tableContext);
-
 #ifdef PR_LOGGING
-    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
+    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
                   NS_ConvertUTF16toUTF8(mName).get(),
-                  mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
+                  charmap->SizeOfIncludingThis(moz_malloc_size_of),
+                  charmap->mHash, mCharacterMap == charmap ? " new" : ""));
     if (LOG_CMAPDATA_ENABLED()) {
         char prefix[256];
         sprintf(prefix, "(cmapdata) name: %.220s",
                 NS_ConvertUTF16toUTF8(mName).get());
-        mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
+        charmap->Dump(prefix, eGfxLog_cmapdata);
     }
 #endif
 
-    mHasCmapTable = NS_SUCCEEDED(rv);
     return rv;
 }
 
 gfxFont *
 gfxDWriteFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle,
                                        bool aNeedsBold)
 {
     return new gfxDWriteFont(this, aFontStyle, aNeedsBold);
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -338,35 +338,41 @@ FT2FontEntry::CairoFontFace()
                                       userFontData, FTFontDestroyFunc);
     }
     return mFontFace;
 }
 
 nsresult
 FT2FontEntry::ReadCMAP()
 {
-    if (mCmapInitialized) {
+    if (mCharacterMap) {
         return NS_OK;
     }
 
-    // attempt this once, if errors occur leave a blank cmap
-    mCmapInitialized = true;
+    nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
 
     AutoFallibleTArray<PRUint8,16384> buffer;
     nsresult rv = GetFontTable(TTAG_cmap, buffer);
     
     if (NS_SUCCEEDED(rv)) {
         bool unicodeFont;
         bool symbolFont;
         rv = gfxFontUtils::ReadCMAP(buffer.Elements(), buffer.Length(),
-                                    mCharacterMap, mUVSOffset,
+                                    *charmap, mUVSOffset,
                                     unicodeFont, symbolFont);
     }
 
     mHasCmapTable = NS_SUCCEEDED(rv);
+    if (mHasCmapTable) {
+        gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
+        mCharacterMap = pfl->FindCharMap(charmap);
+    } else {
+        // if error occurred, initialize to null cmap
+        mCharacterMap = new gfxCharacterMap();
+    }
     return rv;
 }
 
 nsresult
 FT2FontEntry::GetFontTable(PRUint32 aTableTag,
                            FallibleTArray<PRUint8>& aBuffer)
 {
     // Ensure existence of mFTFace
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -98,40 +98,52 @@ static PRUint32 gFontCount = 0;
 static PRUint32 gGlyphExtentsCount = 0;
 static PRUint32 gGlyphExtentsWidthsTotalSize = 0;
 static PRUint32 gGlyphExtentsSetupEagerSimple = 0;
 static PRUint32 gGlyphExtentsSetupEagerTight = 0;
 static PRUint32 gGlyphExtentsSetupLazyTight = 0;
 static PRUint32 gGlyphExtentsSetupFallBackToTight = 0;
 #endif
 
+void
+gfxCharacterMap::NotifyReleased()
+{
+    gfxPlatformFontList *fontlist = gfxPlatformFontList::PlatformFontList();
+    if (mShared) {
+        fontlist->RemoveCmap(this);
+    }
+    delete this;
+}
+
 gfxFontEntry::~gfxFontEntry() 
 {
     delete mUserFontData;
 }
 
 bool gfxFontEntry::IsSymbolFont() 
 {
     return mSymbolFont;
 }
 
 bool gfxFontEntry::TestCharacterMap(PRUint32 aCh)
 {
-    if (!mCmapInitialized) {
+    if (!mCharacterMap) {
         ReadCMAP();
-    }
-    return mCharacterMap.test(aCh);
+        NS_ASSERTION(mCharacterMap, "failed to initialize character map");
+    }
+    return mCharacterMap->test(aCh);
 }
 
 nsresult gfxFontEntry::InitializeUVSMap()
 {
     // mUVSOffset will not be initialized
     // until cmap is initialized.
-    if (!mCmapInitialized) {
+    if (!mCharacterMap) {
         ReadCMAP();
+        NS_ASSERTION(mCharacterMap, "failed to initialize character map");
     }
 
     if (!mUVSOffset) {
         return NS_ERROR_FAILURE;
     }
 
     if (!mUVSData) {
         const PRUint32 kCmapTag = TRUETYPE_TAG('c','m','a','p');
@@ -165,17 +177,18 @@ PRUint16 gfxFontEntry::GetUVSGlyph(PRUin
         return gfxFontUtils::MapUVSToGlyphFormat14(mUVSData, aCh, aVS);
     }
 
     return 0;
 }
 
 nsresult gfxFontEntry::ReadCMAP()
 {
-    mCmapInitialized = true;
+    NS_ASSERTION(false, "using default no-op implementation of ReadCMAP");
+    mCharacterMap = new gfxCharacterMap();
     return NS_OK;
 }
 
 nsString gfxFontEntry::FamilyName() const
 {
     NS_ASSERTION(mFamily, "orphaned font entry");
     if (mFamily) {
         return mFamily->Name();
@@ -428,17 +441,22 @@ gfxFontEntry::FontTableHashEntry::SizeOf
     return 0;
 }
 
 void
 gfxFontEntry::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                   FontListSizes*    aSizes) const
 {
     aSizes->mFontListSize += mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
-    aSizes->mCharMapsSize += mCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
+
+    // cmaps are shared so only non-shared cmaps are included here
+    if (mCharacterMap && mCharacterMap->mBuildOnTheFly) {
+        aSizes->mCharMapsSize +=
+            mCharacterMap->SizeOfIncludingThis(aMallocSizeOf);
+    }
     aSizes->mFontTableCacheSize +=
         mFontTableCache.SizeOfExcludingThis(
             FontTableHashEntry::SizeOfEntryExcludingThis,
             aMallocSizeOf, aSizes);
 }
 
 void
 gfxFontEntry::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
@@ -765,17 +783,17 @@ CalcStyleMatch(gfxFontEntry *aFontEntry,
     return rank;
 }
 
 #define RANK_MATCHED_CMAP   20
 
 void
 gfxFontFamily::FindFontForChar(GlobalFontMatch *aMatchData)
 {
-    if (mCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
+    if (mFamilyCharacterMapInitialized && !TestCharacterMap(aMatchData->mCh)) {
         // none of the faces in the family support the required char,
         // so bail out immediately
         return;
     }
 
     bool needsBold;
     gfxFontStyle normal;
     gfxFontEntry *fe = FindFontForStyle(
@@ -1023,17 +1041,18 @@ gfxFontFamily::FindFont(const nsAString&
 }
 
 void
 gfxFontFamily::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                    FontListSizes*    aSizes) const
 {
     aSizes->mFontListSize +=
         mName.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
-    aSizes->mCharMapsSize += mCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
+    aSizes->mCharMapsSize +=
+        mFamilyCharacterMap.SizeOfExcludingThis(aMallocSizeOf);
 
     aSizes->mFontListSize +=
         mAvailableFonts.SizeOfExcludingThis(aMallocSizeOf);
     for (PRUint32 i = 0; i < mAvailableFonts.Length(); ++i) {
         gfxFontEntry *fe = mAvailableFonts[i];
         if (fe) {
             fe->SizeOfIncludingThis(aMallocSizeOf, aSizes);
         }
@@ -3642,17 +3661,19 @@ gfxFontGroup::FindFontForChar(PRUint32 a
         nsRefPtr<gfxFont> font = GetFontAt(i);
         if (font->HasCharacter(aCh)) {
             *aMatchType = gfxTextRange::kFontGroup;
             return font.forget();
         }
 
         // check other faces of the family
         gfxFontFamily *family = font->GetFontEntry()->Family();
-        if (family && family->TestCharacterMap(aCh)) {
+        if (family && !font->GetFontEntry()->mIsProxy &&
+            family->TestCharacterMap(aCh))
+        {
             GlobalFontMatch matchData(aCh, aRunScript, &mStyle);
             family->SearchAllFontsForChar(&matchData);
             gfxFontEntry *fe = matchData.mBestMatch;
             if (fe) {
                 bool needsBold =
                     font->GetStyle()->weight >= 600 && !fe->IsBold();
                 selectedFont =
                     fe->FindOrMakeFont(font->GetStyle(), needsBold);
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -193,16 +193,66 @@ struct THEBES_API gfxFontStyle {
     }
 
     static void ParseFontFeatureSettings(const nsString& aFeatureString,
                                          nsTArray<gfxFontFeature>& aFeatures);
 
     static PRUint32 ParseFontLanguageOverride(const nsString& aLangTag);
 };
 
+class gfxCharacterMap : public gfxSparseBitSet {
+public:
+    nsrefcnt AddRef() {
+        NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
+        ++mRefCnt;
+        NS_LOG_ADDREF(this, mRefCnt, "gfxCharacterMap", sizeof(*this));
+        return mRefCnt;
+    }
+
+    nsrefcnt Release() {
+        NS_PRECONDITION(0 != mRefCnt, "dup release");
+        --mRefCnt;
+        NS_LOG_RELEASE(this, mRefCnt, "gfxCharacterMap");
+        if (mRefCnt == 0) {
+            NotifyReleased();
+            // |this| has been deleted.
+            return 0;
+        }
+        return mRefCnt;
+    }
+
+    gfxCharacterMap() :
+        mHash(0), mBuildOnTheFly(false), mShared(false)
+    { }
+
+    void CalcHash() { mHash = GetChecksum(); }
+
+    size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
+        return gfxSparseBitSet::SizeOfExcludingThis(aMallocSizeOf);
+    }
+
+    // hash of the cmap bitvector
+    PRUint32 mHash;
+
+    // if cmap is built on the fly it's never shared
+    bool mBuildOnTheFly;
+
+    // cmap is shared globally
+    bool mShared;
+
+protected:
+    void NotifyReleased();
+
+    nsAutoRefCnt mRefCnt;
+
+private:
+    gfxCharacterMap(const gfxCharacterMap&);
+    gfxCharacterMap& operator=(const gfxCharacterMap&);
+};
+
 class gfxFontEntry {
 public:
     NS_INLINE_DECL_REFCOUNTING(gfxFontEntry)
 
     gfxFontEntry(const nsAString& aName, gfxFontFamily *aFamily = nsnull,
                  bool aIsStandardFace = false) : 
         mName(aName), mItalic(false), mFixedPitch(false),
         mIsProxy(false), mIsValid(true), 
@@ -211,17 +261,16 @@ public:
         mSymbolFont(false),
         mIgnoreGDEF(false),
         mIgnoreGSUB(false),
         mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
 #ifdef MOZ_GRAPHITE
         mCheckedForGraphiteTables(false),
 #endif
         mHasCmapTable(false),
-        mCmapInitialized(false),
         mUVSOffset(0), mUVSData(nsnull),
         mUserFontData(nsnull),
         mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
         mFamily(aFamily)
     { }
 
     virtual ~gfxFontEntry();
 
@@ -254,26 +303,27 @@ public:
             CheckForGraphiteTables();
             mCheckedForGraphiteTables = true;
         }
         return mHasGraphiteTables;
     }
 #endif
 
     inline bool HasCmapTable() {
-        if (!mCmapInitialized) {
+        if (!mCharacterMap) {
             ReadCMAP();
+            NS_ASSERTION(mCharacterMap, "failed to initialize character map");
         }
         return mHasCmapTable;
     }
 
     inline bool HasCharacter(PRUint32 ch) {
-        if (mCharacterMap.test(ch))
+        if (mCharacterMap && mCharacterMap->test(ch)) {
             return true;
-
+        }
         return TestCharacterMap(ch);
     }
 
     virtual bool SkipDuringSystemFallback() { return false; }
     virtual bool TestCharacterMap(PRUint32 aCh);
     nsresult InitializeUVSMap();
     PRUint16 GetUVSGlyph(PRUint32 aCh, PRUint32 aVS);
     virtual nsresult ReadCMAP();
@@ -339,18 +389,17 @@ public:
     PRUint16         mWeight;
     PRInt16          mStretch;
 
 #ifdef MOZ_GRAPHITE
     bool             mHasGraphiteTables;
     bool             mCheckedForGraphiteTables;
 #endif
     bool             mHasCmapTable;
-    bool             mCmapInitialized;
-    gfxSparseBitSet  mCharacterMap;
+    nsRefPtr<gfxCharacterMap> mCharacterMap;
     PRUint32         mUVSOffset;
     nsAutoArrayPtr<PRUint8> mUVSData;
     gfxUserFontData* mUserFontData;
 
     nsTArray<gfxFontFeature> mFeatureSettings;
     PRUint32         mLanguageOverride;
 
 protected:
@@ -370,17 +419,16 @@ protected:
         mSymbolFont(false),
         mIgnoreGDEF(false),
         mIgnoreGSUB(false),
         mWeight(500), mStretch(NS_FONT_STRETCH_NORMAL),
 #ifdef MOZ_GRAPHITE
         mCheckedForGraphiteTables(false),
 #endif
         mHasCmapTable(false),
-        mCmapInitialized(false),
         mUVSOffset(0), mUVSData(nsnull),
         mUserFontData(nsnull),
         mLanguageOverride(NO_FONT_LANGUAGE_OVERRIDE),
         mFamily(nsnull)
     { }
 
     virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold) {
         NS_NOTREACHED("oops, somebody didn't override CreateFontInstance");
@@ -524,17 +572,17 @@ public:
     gfxFontFamily(const nsAString& aName) :
         mName(aName),
         mOtherFamilyNamesInitialized(false),
         mHasOtherFamilyNames(false),
         mFaceNamesInitialized(false),
         mHasStyles(false),
         mIsSimpleFamily(false),
         mIsBadUnderlineFamily(false),
-        mCharacterMapInitialized(false)
+        mFamilyCharacterMapInitialized(false)
         { }
 
     virtual ~gfxFontFamily() {
         // clear Family pointers in our faces; the font entries might stay
         // alive due to cached font objects, but they can no longer refer
         // to their families.
         PRUint32 i = mAvailableFonts.Length();
         while (i) {
@@ -602,36 +650,37 @@ public:
     // search for a specific face using the Postscript name
     gfxFontEntry* FindFont(const nsAString& aPostscriptName);
 
     // read in cmaps for all the faces
     void ReadAllCMAPs() {
         PRUint32 i, numFonts = mAvailableFonts.Length();
         for (i = 0; i < numFonts; i++) {
             gfxFontEntry *fe = mAvailableFonts[i];
-            if (!fe) {
+            // don't try to load cmaps for downloadable fonts not yet loaded
+            if (!fe || fe->mIsProxy) {
                 continue;
             }
             fe->ReadCMAP();
-            mCharacterMap.Union(fe->mCharacterMap);
+            mFamilyCharacterMap.Union(*(fe->mCharacterMap));
         }
-        mCharacterMap.Compact();
-        mCharacterMapInitialized = true;
+        mFamilyCharacterMap.Compact();
+        mFamilyCharacterMapInitialized = true;
     }
 
     bool TestCharacterMap(PRUint32 aCh) {
-        if (!mCharacterMapInitialized) {
+        if (!mFamilyCharacterMapInitialized) {
             ReadAllCMAPs();
         }
-        return mCharacterMap.test(aCh);
+        return mFamilyCharacterMap.test(aCh);
     }
 
     void ResetCharacterMap() {
-        mCharacterMap.reset();
-        mCharacterMapInitialized = false;
+        mFamilyCharacterMap.reset();
+        mFamilyCharacterMapInitialized = false;
     }
 
     // mark this family as being in the "bad" underline offset blacklist
     void SetBadUnderlineFamily() {
         mIsBadUnderlineFamily = true;
         if (mHasStyles) {
             SetBadUnderlineFonts();
         }
@@ -670,24 +719,24 @@ protected:
             if (mAvailableFonts[i]) {
                 mAvailableFonts[i]->mIsBadUnderlineFont = true;
             }
         }
     }
 
     nsString mName;
     nsTArray<nsRefPtr<gfxFontEntry> >  mAvailableFonts;
-    gfxSparseBitSet mCharacterMap;
-    bool mOtherFamilyNamesInitialized;
-    bool mHasOtherFamilyNames;
-    bool mFaceNamesInitialized;
-    bool mHasStyles;
-    bool mIsSimpleFamily;
-    bool mIsBadUnderlineFamily;
-    bool mCharacterMapInitialized;
+    gfxSparseBitSet mFamilyCharacterMap;
+    bool mOtherFamilyNamesInitialized : 1;
+    bool mHasOtherFamilyNames : 1;
+    bool mFaceNamesInitialized : 1;
+    bool mHasStyles : 1;
+    bool mIsSimpleFamily : 1;
+    bool mIsBadUnderlineFamily : 1;
+    bool mFamilyCharacterMapInitialized : 1;
 
     enum {
         // for "simple" families, the faces are stored in mAvailableFonts
         // with fixed positions:
         kRegularFaceIndex    = 0,
         kBoldFaceIndex       = 1,
         kItalicFaceIndex     = 2,
         kBoldItalicFaceIndex = 3,
--- a/gfx/thebes/gfxFontUtils.h
+++ b/gfx/thebes/gfxFontUtils.h
@@ -53,16 +53,18 @@
 #include "nsCOMPtr.h"
 #include "nsIRunnable.h"
 #include "nsThreadUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsIStreamBufferAccess.h"
 
+#include "zlib.h"
+
 /* Bug 341128 - w32api defines min/max which causes problems with <bitset> */
 #ifdef __MINGW32__
 #undef min
 #undef max
 #endif
 
 class gfxSparseBitSet {
 private:
@@ -82,16 +84,38 @@ public:
         PRUint32 len = aBitset.mBlocks.Length();
         mBlocks.AppendElements(len);
         for (PRUint32 i = 0; i < len; ++i) {
             Block *block = aBitset.mBlocks[i];
             if (block)
                 mBlocks[i] = new Block(*block);
         }
     }
+
+    bool Equals(const gfxSparseBitSet *aOther) const {
+        if (mBlocks.Length() != aOther->mBlocks.Length()) {
+            return false;
+        }
+        size_t n = mBlocks.Length();
+        for (size_t i = 0; i < n; ++i) {
+            const Block *b1 = mBlocks[i];
+            const Block *b2 = aOther->mBlocks[i];
+            if (!b1 != !b2) {
+                return false;
+            }
+            if (!b1) {
+                continue;
+            }
+            if (memcmp(&b1->mBits, &b2->mBits, BLOCK_SIZE) != 0) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     bool test(PRUint32 aIndex) const {
         NS_ASSERTION(mBlocks.DebugGetHeader(), "mHdr is null, this is bad");
         PRUint32 blockIndex = aIndex/BLOCK_SIZE_BITS;
         if (blockIndex >= mBlocks.Length())
             return false;
         Block *block = mBlocks[blockIndex];
         if (!block)
             return false;
@@ -316,16 +340,28 @@ public:
             }
         }
     }
 
     void Compact() {
         mBlocks.Compact();
     }
 
+    PRUint32 GetChecksum() const {
+        PRUint32 check = adler32(0, Z_NULL, 0);
+        for (PRUint32 i = 0; i < mBlocks.Length(); i++) {
+            if (mBlocks[i]) {
+                const Block *block = mBlocks[i];
+                check = adler32(check, (PRUint8*) (&i), 4);
+                check = adler32(check, (PRUint8*) block, sizeof(Block));
+            }
+        }
+        return check;
+    }
+
 private:
     nsTArray< nsAutoPtr<Block> > mBlocks;
 };
 
 #define TRUETYPE_TAG(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
 
 namespace mozilla {
 
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -196,70 +196,89 @@ FontTypeToOutPrecision(PRUint8 fontType)
 
 GDIFontEntry::GDIFontEntry(const nsAString& aFaceName,
                            gfxWindowsFontType aFontType,
                            bool aItalic, PRUint16 aWeight, PRInt16 aStretch,
                            gfxUserFontData *aUserFontData)
     : gfxFontEntry(aFaceName),
       mWindowsFamily(0), mWindowsPitch(0),
       mFontType(aFontType),
-      mForceGDI(false), mUnknownCMAP(false),
+      mForceGDI(false),
       mCharset(), mUnicodeRanges()
 {
     mUserFontData = aUserFontData;
     mItalic = aItalic;
     mWeight = aWeight;
     mStretch = aStretch;
     if (IsType1())
         mForceGDI = true;
     mIsUserFont = aUserFontData != nsnull;
 
     InitLogFont(aFaceName, aFontType);
 }
 
 nsresult
 GDIFontEntry::ReadCMAP()
 {
+    // attempt this once, if errors occur leave a blank cmap
+    if (mCharacterMap) {
+        return NS_OK;
+    }
+
     // skip non-SFNT fonts completely
     if (mFontType != GFX_FONT_TYPE_PS_OPENTYPE && 
         mFontType != GFX_FONT_TYPE_TT_OPENTYPE &&
         mFontType != GFX_FONT_TYPE_TRUETYPE) 
     {
+        mCharacterMap = new gfxCharacterMap();
         return NS_ERROR_FAILURE;
     }
 
-    // attempt this once, if errors occur leave a blank cmap
-    if (mCmapInitialized)
-        return NS_OK;
-    mCmapInitialized = true;
+    nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
+
+    PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
+    nsresult rv;
+
+    AutoFallibleTArray<PRUint8,16384> cmap;
+    rv = GetFontTable(kCMAP, cmap);
+
+    bool unicodeFont = false, symbolFont = false; // currently ignored
 
-    const PRUint32 kCmapTag = TRUETYPE_TAG('c','m','a','p');
-    AutoFallibleTArray<PRUint8,16384> buffer;
-    if (GetFontTable(kCmapTag, buffer) != NS_OK)
-        return NS_ERROR_FAILURE;
-    PRUint8 *cmap = buffer.Elements();
+    if (NS_SUCCEEDED(rv)) {
+        rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
+                                    *charmap, mUVSOffset,
+                                    unicodeFont, symbolFont);
+    }
+    mSymbolFont = symbolFont;
 
-    bool          unicodeFont = false, symbolFont = false;
-    nsresult rv = gfxFontUtils::ReadCMAP(cmap, buffer.Length(),
-                                         mCharacterMap, mUVSOffset,
-                                         unicodeFont, symbolFont);
-    mSymbolFont = symbolFont;
     mHasCmapTable = NS_SUCCEEDED(rv);
+    if (mHasCmapTable) {
+        gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
+        mCharacterMap = pfl->FindCharMap(charmap);
+    } else {
+        // if error occurred, initialize to null cmap
+        mCharacterMap = new gfxCharacterMap();
+        // For fonts where we failed to read the character map,
+        // we can take a slow path to look up glyphs character by character
+        mCharacterMap->mBuildOnTheFly = true;
+    }
 
 #ifdef PR_LOGGING
-    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
+    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
                   NS_ConvertUTF16toUTF8(mName).get(),
-                  mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
+                  charmap->SizeOfIncludingThis(moz_malloc_size_of),
+                  charmap->mHash, mCharacterMap == charmap ? " new" : ""));
     if (LOG_CMAPDATA_ENABLED()) {
         char prefix[256];
         sprintf(prefix, "(cmapdata) name: %.220s",
                 NS_ConvertUTF16toUTF8(mName).get());
-        mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
+        charmap->Dump(prefix, eGfxLog_cmapdata);
     }
 #endif
+
     return rv;
 }
 
 bool
 GDIFontEntry::IsSymbolFont()
 {
     // initialize cmap first
     HasCmapTable();
@@ -341,23 +360,22 @@ GDIFontEntry::FillLogFont(LOGFONTW *aLog
 }
 
 #define MISSING_GLYPH 0x1F // glyph index returned for missing characters
                            // on WinXP with .fon fonts, but not Type1 (.pfb)
 
 bool 
 GDIFontEntry::TestCharacterMap(PRUint32 aCh)
 {
-    if (ReadCMAP() != NS_OK) {
-        // For fonts where we failed to read the character map,
-        // we can take a slow path to look up glyphs character by character
-        mUnknownCMAP = true;
+    if (!mCharacterMap) {
+        nsresult rv = ReadCMAP();
+        NS_ASSERTION(mCharacterMap, "failed to initialize a character map");
     }
 
-    if (mUnknownCMAP) {
+    if (mCharacterMap->mBuildOnTheFly) {
         if (aCh > 0xFFFF)
             return false;
 
         // previous code was using the group style
         gfxFontStyle fakeStyle;  
         if (mItalic)
             fakeStyle.style = NS_FONT_STYLE_ITALIC;
         fakeStyle.weight = mWeight * 100;
@@ -399,22 +417,22 @@ GDIFontEntry::TestCharacterMap(PRUint32 
             if (rv == S_OK)
                 hasGlyph = true;
         }
 
         SelectObject(dc, oldFont);
         ReleaseDC(NULL, dc);
 
         if (hasGlyph) {
-            mCharacterMap.set(aCh);
+            mCharacterMap->set(aCh);
             return true;
         }
     } else {
         // font had a cmap so simply check that
-        return mCharacterMap.test(aCh);
+        return mCharacterMap->test(aCh);
     }
 
     return false;
 }
 
 void
 GDIFontEntry::InitLogFont(const nsAString& aName,
                           gfxWindowsFontType aFontType)
--- a/gfx/thebes/gfxGDIFontList.h
+++ b/gfx/thebes/gfxGDIFontList.h
@@ -288,17 +288,16 @@ public:
     static GDIFontEntry* LoadLocalFont(const gfxProxyFontEntry &aProxyEntry,
                                        const nsAString& aFullname);
 
     PRUint8 mWindowsFamily;
     PRUint8 mWindowsPitch;
 
     gfxWindowsFontType mFontType;
     bool mForceGDI    : 1;
-    bool mUnknownCMAP : 1;
 
     gfxSparseBitSet mCharset;
     gfxSparseBitSet mUnicodeRanges;
 
 protected:
     friend class gfxWindowsFont;
 
     GDIFontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType,
--- a/gfx/thebes/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/gfxMacPlatformFontList.mm
@@ -184,103 +184,108 @@ const ScriptRange gScriptsThatRequireSha
     // Thai seems to be "renderable" without AAT morphing tables
     // xxx - Lao, Khmer?
 };
 
 nsresult
 MacOSFontEntry::ReadCMAP()
 {
     // attempt this once, if errors occur leave a blank cmap
-    if (mCmapInitialized) {
+    if (mCharacterMap) {
         return NS_OK;
     }
-    mCmapInitialized = true;
-
-    PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
-
-    AutoFallibleTArray<PRUint8,16384> cmap;
-    if (GetFontTable(kCMAP, cmap) != NS_OK) {
-        return NS_ERROR_FAILURE;
-    }
 
-    bool          unicodeFont, symbolFont; // currently ignored
-    nsresult rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
-                                         mCharacterMap, mUVSOffset,
-                                         unicodeFont, symbolFont);
-    if (NS_FAILED(rv)) {
-        mCharacterMap.reset();
-        return rv;
-    }
-    mHasCmapTable = true;
+    nsRefPtr<gfxCharacterMap> charmap = new gfxCharacterMap();
+
+    PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
+    nsresult rv;
 
-    CGFontRef fontRef = GetFontRef();
-    if (!fontRef) {
-        return NS_ERROR_FAILURE;
+    AutoFallibleTArray<PRUint8,16384> cmap;
+    rv = GetFontTable(kCMAP, cmap);
+
+    bool unicodeFont = false, symbolFont = false; // currently ignored
+
+    if (NS_SUCCEEDED(rv)) {
+        rv = gfxFontUtils::ReadCMAP(cmap.Elements(), cmap.Length(),
+                                    *charmap, mUVSOffset,
+                                    unicodeFont, symbolFont);
     }
 
-    // for layout support, check for the presence of mort/morx and/or
-    // opentype layout tables
-    bool hasAATLayout = HasFontTable(TRUETYPE_TAG('m','o','r','x')) ||
-                          HasFontTable(TRUETYPE_TAG('m','o','r','t'));
-    bool hasGSUB = HasFontTable(TRUETYPE_TAG('G','S','U','B'));
-    bool hasGPOS = HasFontTable(TRUETYPE_TAG('G','P','O','S'));
-
-    if (hasAATLayout && !(hasGSUB || hasGPOS)) {
-        mRequiresAAT = true; // prefer CoreText if font has no OTL tables
-    }
+    if (NS_SUCCEEDED(rv)) {
+        // for layout support, check for the presence of mort/morx and/or
+        // opentype layout tables
+        bool hasAATLayout = HasFontTable(TRUETYPE_TAG('m','o','r','x')) ||
+                              HasFontTable(TRUETYPE_TAG('m','o','r','t'));
+        bool hasGSUB = HasFontTable(TRUETYPE_TAG('G','S','U','B'));
+        bool hasGPOS = HasFontTable(TRUETYPE_TAG('G','P','O','S'));
 
-    PRUint32 numScripts =
-        sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
+        if (hasAATLayout && !(hasGSUB || hasGPOS)) {
+            mRequiresAAT = true; // prefer CoreText if font has no OTL tables
+        }
+
+        PRUint32 numScripts =
+            sizeof(gScriptsThatRequireShaping) / sizeof(ScriptRange);
 
-    for (PRUint32 s = 0; s < numScripts; s++) {
-        eComplexScript  whichScript = gScriptsThatRequireShaping[s].script;
+        for (PRUint32 s = 0; s < numScripts; s++) {
+            eComplexScript  whichScript = gScriptsThatRequireShaping[s].script;
 
-        // check to see if the cmap includes complex script codepoints
-        if (mCharacterMap.TestRange(gScriptsThatRequireShaping[s].rangeStart,
-                                    gScriptsThatRequireShaping[s].rangeEnd)) {
-            bool omitRange = true;
+            // check to see if the cmap includes complex script codepoints
+            if (charmap->TestRange(gScriptsThatRequireShaping[s].rangeStart,
+                                   gScriptsThatRequireShaping[s].rangeEnd)) {
+                bool omitRange = true;
 
-            if (hasAATLayout) {
-                omitRange = false;
-                // prefer CoreText for Apple's complex-script fonts,
-                // even if they also have some OpenType tables
-                // (e.g. Geeza Pro Bold on 10.6; see bug 614903)
-                mRequiresAAT = true;
-            } else if (whichScript == eComplexScriptArabic) {
-                // special-case for Arabic:
-                // even if there's no morph table, CoreText can shape Arabic
-                // using OpenType layout; or if it's a downloaded font,
-                // assume the site knows what it's doing (as harfbuzz will
-                // be able to shape even though the font itself lacks tables
-                // stripped during sanitization).
-                // We check for GSUB here, as GPOS alone would not be ok
-                // for Arabic shaping.
-                if (hasGSUB || (mIsUserFont && !mIsLocalUserFont)) {
-                    // TODO: to be really thorough, we could check that the
-                    // GSUB table actually supports the 'arab' script tag.
+                if (hasAATLayout) {
                     omitRange = false;
+                    // prefer CoreText for Apple's complex-script fonts,
+                    // even if they also have some OpenType tables
+                    // (e.g. Geeza Pro Bold on 10.6; see bug 614903)
+                    mRequiresAAT = true;
+                } else if (whichScript == eComplexScriptArabic) {
+                    // special-case for Arabic:
+                    // even if there's no morph table, CoreText can shape Arabic
+                    // using OpenType layout; or if it's a downloaded font,
+                    // assume the site knows what it's doing (as harfbuzz will
+                    // be able to shape even though the font itself lacks tables
+                    // stripped during sanitization).
+                    // We check for GSUB here, as GPOS alone would not be ok
+                    // for Arabic shaping.
+                    if (hasGSUB || (mIsUserFont && !mIsLocalUserFont)) {
+                        // TODO: to be really thorough, we could check that the
+                        // GSUB table actually supports the 'arab' script tag.
+                        omitRange = false;
+                    }
                 }
-            }
 
-            if (omitRange) {
-                mCharacterMap.ClearRange(gScriptsThatRequireShaping[s].rangeStart,
-                                         gScriptsThatRequireShaping[s].rangeEnd);
+                if (omitRange) {
+                    charmap->ClearRange(gScriptsThatRequireShaping[s].rangeStart,
+                                        gScriptsThatRequireShaping[s].rangeEnd);
+                }
             }
         }
     }
 
+    mHasCmapTable = NS_SUCCEEDED(rv);
+    if (mHasCmapTable) {
+        gfxPlatformFontList *pfl = gfxPlatformFontList::PlatformFontList();
+        mCharacterMap = pfl->FindCharMap(charmap);
+    } else {
+        // if error occurred, initialize to null cmap
+        mCharacterMap = new gfxCharacterMap();
+    }
+
 #ifdef PR_LOGGING
-    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d\n",
+    LOG_FONTLIST(("(fontlist-cmap) name: %s, size: %d hash: %8.8x%s\n",
                   NS_ConvertUTF16toUTF8(mName).get(),
-                  mCharacterMap.SizeOfExcludingThis(moz_malloc_size_of)));
+                  charmap->SizeOfIncludingThis(moz_malloc_size_of),
+                  charmap->mHash, mCharacterMap == charmap ? " new" : ""));
     if (LOG_CMAPDATA_ENABLED()) {
         char prefix[256];
         sprintf(prefix, "(cmapdata) name: %.220s",
                 NS_ConvertUTF16toUTF8(mName).get());
-        mCharacterMap.Dump(prefix, eGfxLog_cmapdata);
+        charmap->Dump(prefix, eGfxLog_cmapdata);
     }
 #endif
 
     return rv;
 }
 
 gfxFont*
 MacOSFontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, bool aNeedsBold)
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -208,20 +208,23 @@ gfxPlatformFontList::gfxPlatformFontList
     LoadBadUnderlineList();
 
     // pref changes notification setup
     NS_ASSERTION(!gFontListPrefObserver,
                  "There has been font list pref observer already");
     gFontListPrefObserver = new gfxFontListPrefObserver();
     NS_ADDREF(gFontListPrefObserver);
     Preferences::AddStrongObservers(gFontListPrefObserver, kObservedPrefs);
+
+    mSharedCmaps.Init(16);
 }
 
 gfxPlatformFontList::~gfxPlatformFontList()
 {
+    mSharedCmaps.Clear();
     NS_ASSERTION(gFontListPrefObserver, "There is no font list pref observer");
     Preferences::RemoveObservers(gFontListPrefObserver, kObservedPrefs);
     NS_RELEASE(gFontListPrefObserver);
 }
 
 nsresult
 gfxPlatformFontList::InitFontList()
 {
@@ -709,16 +712,51 @@ gfxPlatformFontList::AddPostscriptName(g
 bool
 gfxPlatformFontList::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
 {
     aFamilyName.Truncate();
     ResolveFontName(aFontName, aFamilyName);
     return !aFamilyName.IsEmpty();
 }
 
+gfxCharacterMap*
+gfxPlatformFontList::FindCharMap(gfxCharacterMap *aCmap)
+{
+    aCmap->CalcHash();
+    gfxCharacterMap *cmap = AddCmap(aCmap);
+    cmap->mShared = true;
+    return cmap;
+}
+
+// add a cmap to the shared cmap set
+gfxCharacterMap*
+gfxPlatformFontList::AddCmap(const gfxCharacterMap* aCharMap)
+{
+    CharMapHashKey *found =
+        mSharedCmaps.PutEntry(const_cast<gfxCharacterMap*>(aCharMap));
+    return found->GetKey();
+}
+
+// remove the cmap from the shared cmap set
+void
+gfxPlatformFontList::RemoveCmap(const gfxCharacterMap* aCharMap)
+{
+    // skip lookups during teardown
+    if (mSharedCmaps.Count() == 0) {
+        return;
+    }
+
+    // cmap needs to match the entry *and* be the same ptr before removing
+    CharMapHashKey *found =
+        mSharedCmaps.GetEntry(const_cast<gfxCharacterMap*>(aCharMap));
+    if (found && found->GetKey() == aCharMap) {
+        mSharedCmaps.RemoveEntry(const_cast<gfxCharacterMap*>(aCharMap));
+    }
+}
+
 void 
 gfxPlatformFontList::InitLoader()
 {
     GetFontFamilyList(mFontFamiliesToLoad);
     mStartIndex = 0;
     mNumFamilies = mFontFamiliesToLoad.Length();
 }
 
@@ -825,16 +863,31 @@ SizeOfPrefFontEntryExcludingThis
 static size_t
 SizeOfStringEntryExcludingThis(nsStringHashKey*  aHashEntry,
                                nsMallocSizeOfFun aMallocSizeOf,
                                void*             aUserArg)
 {
     return aHashEntry->GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
 }
 
+static size_t
+SizeOfSharedCmapExcludingThis(CharMapHashKey*   aHashEntry,
+                              nsMallocSizeOfFun aMallocSizeOf,
+                              void*             aUserArg)
+{
+    FontListSizes *sizes = static_cast<FontListSizes*>(aUserArg);
+
+    PRUint32 size = aHashEntry->GetKey()->SizeOfIncludingThis(aMallocSizeOf);
+    sizes->mCharMapsSize += size;
+
+    // we return zero here because the measurements have been added directly
+    // to the relevant fields of the FontListSizes record
+    return 0;
+}
+
 void
 gfxPlatformFontList::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                          FontListSizes*    aSizes) const
 {
     aSizes->mFontListSize +=
         mFontFamilies.SizeOfExcludingThis(SizeOfFamilyEntryExcludingThis,
                                           aMallocSizeOf, aSizes);
 
@@ -860,16 +913,20 @@ gfxPlatformFontList::SizeOfExcludingThis
 
     aSizes->mFontListSize +=
         mPrefFonts.SizeOfExcludingThis(SizeOfPrefFontEntryExcludingThis,
                                        aMallocSizeOf);
 
     aSizes->mFontListSize +=
         mBadUnderlineFamilyNames.SizeOfExcludingThis(SizeOfStringEntryExcludingThis,
                                                      aMallocSizeOf);
+
+    aSizes->mFontListSize +=
+        mSharedCmaps.SizeOfExcludingThis(SizeOfSharedCmapExcludingThis,
+                                         aMallocSizeOf, aSizes);
 }
 
 void
 gfxPlatformFontList::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                          FontListSizes*    aSizes) const
 {
     aSizes->mFontListSize += aMallocSizeOf(this);
     SizeOfExcludingThis(aMallocSizeOf, aSizes);
--- a/gfx/thebes/gfxPlatformFontList.h
+++ b/gfx/thebes/gfxPlatformFontList.h
@@ -45,16 +45,63 @@
 
 #include "gfxFontUtils.h"
 #include "gfxFont.h"
 #include "gfxPlatform.h"
 
 #include "nsIMemoryReporter.h"
 #include "mozilla/FunctionTimer.h"
 
+class CharMapHashKey : public PLDHashEntryHdr
+{
+public:
+    typedef gfxCharacterMap* KeyType;
+    typedef const gfxCharacterMap* KeyTypePointer;
+
+    CharMapHashKey(const gfxCharacterMap *aCharMap) :
+        mCharMap(const_cast<gfxCharacterMap*>(aCharMap))
+    {
+        MOZ_COUNT_CTOR(CharMapHashKey);
+    }
+    CharMapHashKey(const CharMapHashKey& toCopy) :
+        mCharMap(toCopy.mCharMap)
+    {
+        MOZ_COUNT_CTOR(CharMapHashKey);
+    }
+    ~CharMapHashKey()
+    {
+        MOZ_COUNT_DTOR(CharMapHashKey);
+    }
+
+    gfxCharacterMap* GetKey() const { return mCharMap; }
+
+    bool KeyEquals(const gfxCharacterMap *aCharMap) const {
+        NS_ASSERTION(!aCharMap->mBuildOnTheFly && !mCharMap->mBuildOnTheFly,
+                     "custom cmap used in shared cmap hashtable");
+        // cmaps built on the fly never match
+        if (aCharMap->mHash != mCharMap->mHash)
+        {
+            return false;
+        }
+        return mCharMap->Equals(aCharMap);
+    }
+
+    static const gfxCharacterMap* KeyToPointer(gfxCharacterMap *aCharMap) {
+        return aCharMap;
+    }
+    static PLDHashNumber HashKey(const gfxCharacterMap *aCharMap) {
+        return aCharMap->mHash;
+    }
+
+    enum { ALLOW_MEMMOVE = true };
+
+protected:
+    gfxCharacterMap *mCharMap;
+};
+
 // gfxPlatformFontList is an abstract class for the global font list on the system;
 // concrete subclasses for each platform implement the actual interface to the system fonts.
 // This class exists because we cannot rely on the platform font-finding APIs to behave
 // in sensible/similar ways, particularly with rich, complex OpenType families,
 // so we do our own font family/style management here instead.
 
 // Much of this is based on the old gfxQuartzFontCache, but adapted for use on all platforms.
 
@@ -150,16 +197,26 @@ public:
     // (platforms may override, eg Mac)
     virtual bool GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
 
     virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                      FontListSizes*    aSizes) const;
     virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
                                      FontListSizes*    aSizes) const;
 
+    // search for existing cmap that matches the input
+    // return the input if no match is found
+    gfxCharacterMap* FindCharMap(gfxCharacterMap *aCmap);
+
+    // add a cmap to the shared cmap set
+    gfxCharacterMap* AddCmap(const gfxCharacterMap *aCharMap);
+
+    // remove the cmap from the shared cmap set
+    void RemoveCmap(const gfxCharacterMap *aCharMap);
+
 protected:
     class MemoryReporter
         : public nsIMemoryMultiReporter
     {
     public:
         NS_DECL_ISUPPORTS
         NS_DECL_NSIMEMORYMULTIREPORTER
     };
@@ -259,16 +316,20 @@ protected:
     gfxSparseBitSet mCodepointsWithNoFonts;
 
     // the family to use for U+FFFD fallback, to avoid expensive search every time
     // on pages with lots of problems
     nsString mReplacementCharFallbackFamily;
 
     nsTHashtable<nsStringHashKey> mBadUnderlineFamilyNames;
 
+    // character map data shared across families
+    // contains weak ptrs to cmaps shared by font entry objects
+    nsTHashtable<CharMapHashKey> mSharedCmaps;
+
     // data used as part of the font cmap loading process
     nsTArray<nsRefPtr<gfxFontFamily> > mFontFamiliesToLoad;
     PRUint32 mStartIndex;
     PRUint32 mIncrement;
     PRUint32 mNumFamilies;
 };
 
 #endif /* GFXPLATFORMFONTLIST_H_ */
--- a/ipc/ipdl/Makefile.in
+++ b/ipc/ipdl/Makefile.in
@@ -110,19 +110,19 @@ LOCAL_INCLUDES += -I$(DEPTH)/ipc/ipdl/_i
 include $(topsrcdir)/config/config.mk
 include $(topsrcdir)/ipc/chromium/chromium-config.mk
 include $(topsrcdir)/config/rules.mk
 
 
 # NB: the IPDL compiler manages .ipdl-->.h/.cpp dependencies itself,
 # which is why we don't have explicit .h/.cpp targets here
 export:: $(ALL_IPDLSRCS)
-	$(PYTHON) $(topsrcdir)/config/pythonpath.py	\
-	  -I$(topsrcdir)/other-licenses/ply		\
-	  $(srcdir)/ipdl.py				\
-	  --outheaders-dir=_ipdlheaders			\
-	  --outcpp-dir=.				\
-	  $(IPDLDIRS:%=-I$(topsrcdir)/%)		\
+	$(PYTHON_PATH) \
+	  $(PLY_INCLUDE) \
+	  $(srcdir)/ipdl.py \
+	  --outheaders-dir=_ipdlheaders \
+	  --outcpp-dir=. \
+	  $(IPDLDIRS:%=-I$(topsrcdir)/%) \
 	  $^
 
 # We #include some things in the dom/plugins/ directory that rely on
 # toolkit libraries.
 CXXFLAGS    += $(TK_CFLAGS)
--- a/ipc/ipdl/test/ipdl/Makefile.in
+++ b/ipc/ipdl/test/ipdl/Makefile.in
@@ -44,12 +44,12 @@ include $(topsrcdir)/config/rules.mk
 
 OKTESTS := $(wildcard $(srcdir)/ok/*.ipdl)
 ERRORTESTS := $(wildcard $(srcdir)/error/*.ipdl)
 
 check::
 	@$(PYTHON) $(srcdir)/runtests.py  \
 		$(srcdir)/ok $(srcdir)/error  \
 		$(PYTHON) $(topsrcdir)/config/pythonpath.py  \
-		-I$(topsrcdir)/other-licenses/ply  \
+		$(PLY_INCLUDE)  \
 		$(topsrcdir)/ipc/ipdl/ipdl.py  \
 		OKTESTS $(OKTESTS)  \
 		ERRORTESTS $(ERRORTESTS)
--- a/ipc/ril/Ril.cpp
+++ b/ipc/ril/Ril.cpp
@@ -273,16 +273,25 @@ RilClient::OnFileCanReadWithoutBlocking(
     //     If so, break;
 
     MOZ_ASSERT(fd == mSocket.mFd);
     while (true) {
         if (!mIncoming) {
             mIncoming = new RilRawData();
             ssize_t ret = read(fd, mIncoming->mData, RilRawData::MAX_DATA_SIZE);
             if (ret <= 0) {
+                if (ret == -1) {
+                    if (errno == EINTR) {
+                        continue; // retry system call when interrupted
+                    }
+                    else if (errno == EAGAIN || errno == EWOULDBLOCK) {
+                        return; // no data available: return and re-poll
+                    }
+                    // else fall through to error handling on other errno's
+                }
                 LOG("Cannot read from network, error %d\n", ret);
                 // At this point, assume that we can't actually access
                 // the socket anymore, and start a reconnect loop.
                 mIncoming.forget();
                 mReadWatcher.StopWatchingFileDescriptor();
                 mWriteWatcher.StopWatchingFileDescriptor();
                 close(mSocket.mFd);
                 RilReconnectTask::Enqueue();
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -404,19 +404,19 @@ DumpXPC(JSContext *cx,
     return JS_TRUE;
 }
 
 static JSBool
 GC(JSContext *cx,
    unsigned argc,
    jsval *vp)
 {
-    JS_GC(cx);
+    JSRuntime *rt = JS_GetRuntime(cx);
+    JS_GC(rt);
 #ifdef JS_GCMETER
-    JSRuntime *rt = JS_GetRuntime(cx);
     js_DumpGCStats(rt, stdout);
 #endif
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return JS_TRUE;
 }
 
 #ifdef JS_GC_ZEAL
 static JSBool
@@ -1049,26 +1049,25 @@ XPCShellEnvironment::~XPCShellEnvironmen
         JS_BeginRequest(mCx);
 
         JSObject* global = GetGlobalObject();
         if (global) {
             JS_ClearScope(mCx, global);
         }
         mGlobalHolder.Release();
 
-        JS_GC(mCx);
+        JSRuntime *rt = JS_GetRuntime(mCx);
+        JS_GC(rt);
 
         mCxStack = nsnull;
 
         if (mJSPrincipals) {
-            JS_DropPrincipals(JS_GetRuntime(mCx), mJSPrincipals);
+            JS_DropPrincipals(rt, mJSPrincipals);
         }
 
-        JSRuntime* rt = gOldContextCallback ? JS_GetRuntime(mCx) : NULL;
-
         JS_EndRequest(mCx);
         JS_DestroyContext(mCx);
 
         if (gOldContextCallback) {
             NS_ASSERTION(rt, "Should never be null!");
             JS_SetContextCallback(rt, gOldContextCallback);
             gOldContextCallback = NULL;
         }
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -2812,18 +2812,18 @@ jsdService::EnumerateScripts (jsdIScript
 
     return rv;
 }
 
 NS_IMETHODIMP
 jsdService::GC (void)
 {
     ASSERT_VALID_CONTEXT;
-    JSContext *cx = JSD_GetDefaultJSContext (mCx);
-    JS_GC(cx);
+    JSRuntime *rt = JSD_GetJSRuntime (mCx);
+    JS_GC(rt);
     return NS_OK;
 }
     
 NS_IMETHODIMP
 jsdService::DumpHeap(const nsACString &fileName)
 {
     ASSERT_VALID_CONTEXT;
 #ifndef DEBUG
--- a/js/jsd/jsdebug.c
+++ b/js/jsd/jsdebug.c
@@ -93,16 +93,23 @@ JSD_GetMinorVersion(void)
 
 JSD_PUBLIC_API(JSContext*)
 JSD_GetDefaultJSContext(JSDContext* jsdc)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     return jsdc->dumbContext;
 }
 
+JSD_PUBLIC_API(JSRuntime*)
+JSD_GetJSRuntime(JSDContext* jsdc)
+{
+    JSD_ASSERT_VALID_CONTEXT(jsdc);
+    return jsdc->jsrt;
+}
+
 JSD_PUBLIC_API(void)
 JSD_SetUserCallbacks(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user)
 {
     jsd_SetUserCallbacks(jsrt, callbacks, user);
 }
 
 JSD_PUBLIC_API(void)
 JSD_JSContextInUse(JSDContext* jsdc, JSContext* context)
--- a/js/jsd/jsdebug.h
+++ b/js/jsd/jsdebug.h
@@ -184,16 +184,22 @@ JSD_GetMinorVersion(void);
 
 /*
 * Returns a 'dumb' JSContext that can be used for utility purposes as needed
 */
 extern JSD_PUBLIC_API(JSContext*)
 JSD_GetDefaultJSContext(JSDContext* jsdc);
 
 /*
+* Returns a JSRuntime this context is associated with
+*/
+extern JSD_PUBLIC_API(JSRuntime*)
+JSD_GetJSRuntime(JSDContext* jsdc);
+
+/*
 * Set the private data for this context, returns previous value
 */
 extern JSD_PUBLIC_API(void *)
 JSD_SetContextPrivate(JSDContext *jsdc, void *data);
 
 /*
 * Get the private data for this context
 */
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -281,17 +281,17 @@ MapObject::construct(JSContext *cx, unsi
 #define ARG0_KEY(cx, args, key)                                               \
     HashableValue key;                                                        \
     if (args.length() > 0 && !key.setValue(cx, args[0]))                      \
         return false
 
 JSBool
 MapObject::size(JSContext *cx, unsigned argc, Value *vp)
 {
-    THIS_MAP(get, cx, argc, vp, args, map);
+    THIS_MAP(size, cx, argc, vp, args, map);
     JS_STATIC_ASSERT(sizeof map.count() <= sizeof(uint32_t));
     args.rval().setNumber(map.count());
     return true;
 }
 
 JSBool
 MapObject::get(JSContext *cx, unsigned argc, Value *vp)
 {
@@ -450,17 +450,17 @@ SetObject::construct(JSContext *cx, unsi
 }
 
 #define THIS_SET(native, cx, argc, vp, args, set)                             \
     UNPACK_THIS(SetObject, native, cx, argc, vp, args, set)
 
 JSBool
 SetObject::size(JSContext *cx, unsigned argc, Value *vp)
 {
-    THIS_SET(has, cx, argc, vp, args, set);
+    THIS_SET(size, cx, argc, vp, args, set);
     JS_STATIC_ASSERT(sizeof set.count() <= sizeof(uint32_t));
     args.rval().setNumber(set.count());
     return true;
 }
 
 JSBool
 SetObject::has(JSContext *cx, unsigned argc, Value *vp)
 {
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -42,17 +42,17 @@ GC(JSContext *cx, unsigned argc, jsval *
 #ifndef JS_MORE_DETERMINISTIC
     size_t preBytes = cx->runtime->gcBytes;
 #endif
 
     if (compartment)
         PrepareForDebugGC(cx->runtime);
     else
         PrepareForFullGC(cx->runtime);
-    GCForReason(cx, gcreason::API);
+    GCForReason(cx->runtime, gcreason::API);
 
     char buf[256] = { '\0' };
 #ifndef JS_MORE_DETERMINISTIC
     JS_snprintf(buf, sizeof(buf), "before %lu, after %lu\n",
                 (unsigned long)preBytes, (unsigned long)cx->runtime->gcBytes);
 #endif
     JSString *str = JS_NewStringCopyZ(cx, buf);
     if (!str)
@@ -229,17 +229,17 @@ SelectForGC(JSContext *cx, unsigned argc
 
 static JSBool
 VerifyBarriers(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (argc) {
         ReportUsageError(cx, &JS_CALLEE(cx, vp).toObject(), "Too many arguments");
         return JS_FALSE;
     }
-    gc::VerifyBarriers(cx);
+    gc::VerifyBarriers(cx->runtime);
     *vp = JSVAL_VOID;
     return JS_TRUE;
 }
 
 static JSBool
 GCSlice(JSContext *cx, unsigned argc, jsval *vp)
 {
     bool limit = true;
@@ -252,17 +252,17 @@ GCSlice(JSContext *cx, unsigned argc, js
 
     if (argc == 1) {
         if (!JS_ValueToECMAUint32(cx, vp[2], &budget))
             return false;
     } else {
         limit = false;
     }
 
-    GCDebugSlice(cx, limit, budget);
+    GCDebugSlice(cx->runtime, limit, budget);
     *vp = JSVAL_VOID;
     return JS_TRUE;
 }
 
 static JSBool
 DeterministicGC(JSContext *cx, unsigned argc, jsval *vp)
 {
     if (argc != 1) {
@@ -464,17 +464,16 @@ FinalizeCount(JSContext *cx, unsigned ar
     return true;
 }
 
 JSBool
 MJitCodeStats(JSContext *cx, unsigned argc, jsval *vp)
 {
 #ifdef JS_METHODJIT
     JSRuntime *rt = cx->runtime;
-    AutoLockGC lock(rt);
     size_t n = 0;
     for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c) {
         n += (*c)->sizeOfMjitCode();
     }
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(n));
 #else
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
 #endif
@@ -494,17 +493,17 @@ MJitChunkLimit(JSContext *cx, unsigned a
         return JS_FALSE;
 
 #ifdef JS_METHODJIT
     mjit::SetChunkLimit((uint32_t) t);
 #endif
 
     // Clear out analysis information which might refer to code compiled with
     // the previous chunk limit.
-    JS_GC(cx);
+    JS_GC(cx->runtime);
 
     vp->setUndefined();
     return true;
 }
 
 static JSBool
 Terminate(JSContext *cx, unsigned arg, jsval *vp)
 {
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -832,8 +832,13 @@ endif
 
 ifdef GNU_CC
 EXPAND_LIBNAME = $(addprefix -l,$(1))
 else
 EXPAND_LIBNAME = $(foreach lib,$(1),$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 endif
 EXPAND_LIBNAME_PATH = $(foreach lib,$(1),$(2)/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
 EXPAND_MOZLIBNAME = $(foreach lib,$(1),$(DIST)/lib/$(LIB_PREFIX)$(lib).$(LIB_SUFFIX))
+
+# Include internal ply only if needed
+ifndef MOZ_SYSTEM_PLY
+PLY_INCLUDE = -I$(topsrcdir)/other-licenses/ply
+endif
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -1439,29 +1439,29 @@ XPIDL_DEPS = \
 xpidl-preqs = \
   $(call mkdir_deps,$(XPIDL_GEN_DIR)) \
   $(call mkdir_deps,$(MDDEPDIR)) \
   $(NULL)
 
 $(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
 	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
-	  -I$(topsrcdir)/other-licenses/ply \
+	  $(PLY_INCLUDE) \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
 	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
 
 ifndef NO_GEN_XPT
 # generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
 # into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
 $(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
 	$(REPORT_BUILD)
 	$(PYTHON_PATH) \
-	  -I$(topsrcdir)/other-licenses/ply \
+	  $(PLY_INCLUDE) \
 	  -I$(topsrcdir)/xpcom/idl-parser \
 	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
 	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
 
 # no need to link together if XPIDLSRCS contains only XPIDL_MODULE
 ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
 $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS)) $(GLOBAL_DEPS)
 	$(XPIDL_LINK) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS))
deleted file mode 100644
--- a/js/src/config/rules.mk.orig
+++ /dev/null
@@ -1,2035 +0,0 @@
-# -*- makefile -*-
-# vim:set ts=8 sw=8 sts=8 noet:
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 1998
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#  Chase Phillips <chase@mozilla.org>
-#  Benjamin Smedberg <benjamin@smedbergs.us>
-#  Jeff Walden <jwalden+code@mit.edu>
-#  Joey Armstrong <joey@mozilla.com>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of the GNU General Public License Version 2 or later (the "GPL"),
-# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-ifndef topsrcdir
-$(error topsrcdir was not set))
-endif
-
-ifndef MOZILLA_DIR
-MOZILLA_DIR = $(topsrcdir)
-endif
-
-ifndef INCLUDED_CONFIG_MK
-include $(topsrcdir)/config/config.mk
-endif
-
-ifndef INCLUDED_VERSION_MK
-include $(topsrcdir)/config/version.mk
-endif
-
-ifdef SDK_XPIDLSRCS
-XPIDLSRCS += $(SDK_XPIDLSRCS)
-endif
-ifdef SDK_HEADERS
-EXPORTS += $(SDK_HEADERS)
-endif
-
-REPORT_BUILD = @echo $(notdir $<)
-
-ifeq ($(OS_ARCH),OS2)
-EXEC			=
-else
-EXEC			= exec
-endif
-
-# Don't copy xulrunner files at install time, when using system xulrunner
-ifdef SYSTEM_LIBXUL
-  SKIP_COPY_XULRUNNER=1
-endif
-
-# ELOG prints out failed command when building silently (gmake -s).
-ifneq (,$(findstring s, $(filter-out --%, $(MAKEFLAGS))))
-  ELOG := $(EXEC) sh $(BUILD_TOOLS)/print-failed-commands.sh
-else
-  ELOG :=
-endif
-
-_VPATH_SRCS = $(abspath $<)
-
-# Add $(DIST)/lib to VPATH so that -lfoo dependencies are followed
-VPATH += $(DIST)/lib
-ifdef LIBXUL_SDK
-VPATH += $(LIBXUL_SDK)/lib
-endif
-
-ifdef EXTRA_DSO_LIBS
-EXTRA_DSO_LIBS	:= $(call EXPAND_MOZLIBNAME,$(EXTRA_DSO_LIBS))
-endif
-
-################################################################################
-# Testing frameworks support
-################################################################################
-
-testxpcobjdir = $(DEPTH)/_tests/xpcshell
-
-ifdef ENABLE_TESTS
-
-# Add test directories to the regular directories list. TEST_DIRS should
-# arguably have the same status as TOOL_DIRS and other *_DIRS variables. It is
-# coded this way until Makefiles stop using the "ifdef ENABLE_TESTS; DIRS +="
-# convention.
-#
-# The current developer workflow expects tests to be updated when processing
-# the default target. If we ever change this implementation, the behavior
-# should be preserved or the change should be widely communicated. A
-# consequence of not processing test dir targets during the default target is
-# that changes to tests may not be updated and code could assume to pass
-# locally against non-current test code.
-DIRS += $(TEST_DIRS)
-
-ifdef XPCSHELL_TESTS
-ifndef relativesrcdir
-$(error Must define relativesrcdir when defining XPCSHELL_TESTS.)
-endif
-
-define _INSTALL_TESTS
-$(DIR_INSTALL) $(wildcard $(srcdir)/$(dir)/*) $(testxpcobjdir)/$(relativesrcdir)/$(dir)
-
-endef # do not remove the blank line!
-
-SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
-
-libs::
-	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
-ifndef NO_XPCSHELL_MANIFEST_CHECK
-	$(PYTHON) $(MOZILLA_DIR)/build/xpccheck.py \
-	  $(topsrcdir) \
-	  $(topsrcdir)/testing/xpcshell/xpcshell.ini \
-	  $(addprefix $(MOZILLA_DIR)/$(relativesrcdir)/,$(XPCSHELL_TESTS))
-endif
-
-testxpcsrcdir = $(topsrcdir)/testing/xpcshell
-
-# Execute all tests in the $(XPCSHELL_TESTS) directories.
-# See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
-xpcshell-tests:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --tests-root-dir=$(testxpcobjdir) \
-	  --xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
-	  --xunit-suite-name=xpcshell \
-	  $(EXTRA_TEST_ARGS) \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-xpcshell-tests-remote: DM_TRANS?=adb
-xpcshell-tests-remote:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  -I$(topsrcdir)/build/mobile \
-	  $(topsrcdir)/testing/xpcshell/remotexpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  $(EXTRA_TEST_ARGS) \
-	  --dm_trans=$(DM_TRANS) \
-	  --deviceIP=${TEST_DEVICE} \
-	  --objdir=$(DEPTH) \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-# Execute a single test, specified in $(SOLO_FILE), but don't automatically
-# start the test. Instead, present the xpcshell prompt so the user can
-# attach a debugger and then start the test.
-check-interactive:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --interactive \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-# Execute a single test, specified in $(SOLO_FILE)
-check-one:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  $(testxpcsrcdir)/runxpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --verbose \
-	  $(EXTRA_TEST_ARGS) \
-	  $(LIBXUL_DIST)/bin/xpcshell \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-
-check-one-remote: DM_TRANS?=adb
-check-one-remote:
-	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-	  -I$(topsrcdir)/build \
-	  -I$(topsrcdir)/build/mobile \
-	  $(testxpcsrcdir)/remotexpcshelltests.py \
-	  --symbols-path=$(DIST)/crashreporter-symbols \
-	  --build-info-json=$(DEPTH)/mozinfo.json \
-	  --test-path=$(SOLO_FILE) \
-	  --profile-name=$(MOZ_APP_NAME) \
-	  --verbose \
-	  $(EXTRA_TEST_ARGS) \
-	  --dm_trans=$(DM_TRANS) \
-	  --deviceIP=${TEST_DEVICE} \
-	  --objdir=$(DEPTH) \
-          --noSetup \
-	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
-endif # XPCSHELL_TESTS
-
-ifdef CPP_UNIT_TESTS
-
-# Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
-# through TestHarness.h, by modifying the list of includes and the libs against
-# which stuff links.
-CPPSRCS += $(CPP_UNIT_TESTS)
-SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX))
-INCLUDES += -I$(DIST)/include/testing
-LIBS += $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS) $(MOZ_JS_LIBS)
-
-# ...and run them the usual way
-check::
-	@$(EXIT_ON_ERROR) \
-	  for f in $(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)); do \
-	    XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \
-	  done
-
-endif # CPP_UNIT_TESTS
-
-.PHONY: check xpcshell-tests check-interactive check-one
-
-endif # ENABLE_TESTS
-
-
-#
-# Library rules
-#
-# If FORCE_STATIC_LIB is set, build a static library.
-# Otherwise, build a shared library.
-#
-
-ifndef LIBRARY
-ifdef STATIC_LIBRARY_NAME
-REAL_LIBRARY		:= $(LIB_PREFIX)$(STATIC_LIBRARY_NAME).$(LIB_SUFFIX)
-# Only build actual library if it is installed in DIST/lib or SDK
-ifeq (,$(SDK_LIBRARY)$(DIST_INSTALL)$(NO_EXPAND_LIBS))
-LIBRARY			:= $(REAL_LIBRARY).$(LIBS_DESC_SUFFIX)
-else
-LIBRARY			:= $(REAL_LIBRARY) $(REAL_LIBRARY).$(LIBS_DESC_SUFFIX)
-endif
-endif # STATIC_LIBRARY_NAME
-endif # LIBRARY
-
-ifndef HOST_LIBRARY
-ifdef HOST_LIBRARY_NAME
-HOST_LIBRARY		:= $(LIB_PREFIX)$(HOST_LIBRARY_NAME).$(LIB_SUFFIX)
-endif
-endif
-
-ifdef LIBRARY
-ifdef FORCE_SHARED_LIB
-ifdef MKSHLIB
-
-ifdef LIB_IS_C_ONLY
-MKSHLIB			= $(MKCSHLIB)
-endif
-
-ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
-IMPORT_LIBRARY		:= $(LIB_PREFIX)$(SHARED_LIBRARY_NAME).$(IMPORT_LIB_SUFFIX)
-endif
-
-ifeq (OS2,$(OS_ARCH))
-ifdef SHORT_LIBNAME
-SHARED_LIBRARY_NAME	:= $(SHORT_LIBNAME)
-endif
-endif
-
-ifdef MAKE_FRAMEWORK
-SHARED_LIBRARY		:= $(SHARED_LIBRARY_NAME)
-else
-SHARED_LIBRARY		:= $(DLL_PREFIX)$(SHARED_LIBRARY_NAME)$(DLL_SUFFIX)
-endif
-
-ifeq ($(OS_ARCH),OS2)
-DEF_FILE		:= $(SHARED_LIBRARY:.dll=.def)
-endif
-
-EMBED_MANIFEST_AT=2
-
-endif # MKSHLIB
-endif # FORCE_SHARED_LIB
-endif # LIBRARY
-
-ifdef FORCE_STATIC_LIB
-ifndef FORCE_SHARED_LIB
-SHARED_LIBRARY		:= $(NULL)
-DEF_FILE		:= $(NULL)
-IMPORT_LIBRARY		:= $(NULL)
-endif
-endif
-
-ifdef FORCE_SHARED_LIB
-ifndef FORCE_STATIC_LIB
-LIBRARY := $(NULL)
-endif
-endif
-
-ifdef JAVA_LIBRARY_NAME
-JAVA_LIBRARY := $(JAVA_LIBRARY_NAME).jar
-endif
-
-ifeq ($(OS_ARCH),WINNT)
-ifndef GNU_CC
-
-#
-# Unless we're building SIMPLE_PROGRAMS, all C++ files share a PDB file per
-# directory. For parallel builds, this PDB file is shared and locked by
-# MSPDBSRV.EXE, starting with MSVC8 SP1. If you're using MSVC 7.1 or MSVC8
-# without SP1, don't do parallel builds.
-#
-# The final PDB for libraries and programs is created by the linker and uses
-# a different name from the single PDB file created by the compiler. See
-# bug 462740.
-#
-
-ifdef SIMPLE_PROGRAMS
-COMPILE_PDBFILE = $(basename $(@F)).pdb
-else
-COMPILE_PDBFILE = generated.pdb
-endif
-
-LINK_PDBFILE = $(basename $(@F)).pdb
-ifdef MOZ_DEBUG
-CODFILE=$(basename $(@F)).cod
-endif
-
-ifdef MOZ_MAPINFO
-ifdef SHARED_LIBRARY_NAME
-MAPFILE=$(SHARED_LIBRARY_NAME).map
-else
-MAPFILE=$(basename $(@F)).map
-endif # SHARED_LIBRARY_NAME
-endif # MOZ_MAPINFO
-
-ifdef DEFFILE
-OS_LDFLAGS += -DEF:$(call normalizepath,$(DEFFILE))
-EXTRA_DEPS += $(DEFFILE)
-endif
-
-ifdef MAPFILE
-OS_LDFLAGS += -MAP:$(MAPFILE)
-endif
-
-else #!GNU_CC
-
-ifdef DEFFILE
-OS_LDFLAGS += $(call normalizepath,$(DEFFILE))
-EXTRA_DEPS += $(DEFFILE)
-endif
-
-endif # !GNU_CC
-
-endif # WINNT
-
-ifeq ($(SOLARIS_SUNPRO_CXX),1)
-ifeq (86,$(findstring 86,$(OS_TEST)))
-OS_LDFLAGS += -M $(topsrcdir)/config/solaris_ia32.map
-endif # x86
-endif # Solaris Sun Studio C++
-
-ifeq ($(HOST_OS_ARCH),WINNT)
-HOST_PDBFILE=$(basename $(@F)).pdb
-endif
-
-# Don't build SIMPLE_PROGRAMS during the MOZ_PROFILE_GENERATE pass
-ifdef MOZ_PROFILE_GENERATE
-SIMPLE_PROGRAMS :=
-endif
-
-ifndef TARGETS
-TARGETS			= $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(JAVA_LIBRARY)
-endif
-
-ifndef OBJS
-_OBJS			= \
-	$(JRI_STUB_CFILES) \
-	$(addsuffix .$(OBJ_SUFFIX), $(JMC_GEN)) \
-	$(CSRCS:.c=.$(OBJ_SUFFIX)) \
-	$(SSRCS:.S=.$(OBJ_SUFFIX)) \
-	$(patsubst %.cc,%.$(OBJ_SUFFIX),$(CPPSRCS:.cpp=.$(OBJ_SUFFIX))) \
-	$(CMSRCS:.m=.$(OBJ_SUFFIX)) \
-	$(CMMSRCS:.mm=.$(OBJ_SUFFIX)) \
-	$(ASFILES:.$(ASM_SUFFIX)=.$(OBJ_SUFFIX))
-OBJS	= $(strip $(_OBJS))
-endif
-
-ifndef HOST_OBJS
-_HOST_OBJS		= \
-        $(addprefix host_,$(HOST_CSRCS:.c=.$(OBJ_SUFFIX))) \
-	$(addprefix host_,$(patsubst %.cc,%.$(OBJ_SUFFIX),$(HOST_CPPSRCS:.cpp=.$(OBJ_SUFFIX)))) \
-	$(addprefix host_,$(HOST_CMSRCS:.m=.$(OBJ_SUFFIX))) \
-	$(addprefix host_,$(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX)))
-HOST_OBJS = $(strip $(_HOST_OBJS))
-endif
-
-LIBOBJS			:= $(addprefix \", $(OBJS))
-LIBOBJS			:= $(addsuffix \", $(LIBOBJS))
-
-ifndef MOZ_AUTO_DEPS
-ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
-MDDEPFILES		= $(addprefix $(MDDEPDIR)/,$(OBJS:.$(OBJ_SUFFIX)=.pp))
-ifndef NO_GEN_XPT
-MDDEPFILES		+= $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp))
-endif
-endif
-endif
-
-ALL_TRASH = \
-	$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
-	$(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \
-	$(OBJS:.$(OBJ_SUFFIX)=.i) $(OBJS:.$(OBJ_SUFFIX)=.i_o) \
-	$(HOST_PROGOBJS) $(HOST_OBJS) $(IMPORT_LIBRARY) $(DEF_FILE)\
-	$(EXE_DEF_FILE) so_locations _gen _stubs $(wildcard *.res) $(wildcard *.RES) \
-	$(wildcard *.pdb) $(CODFILE) $(MAPFILE) $(IMPORT_LIBRARY) \
-	$(SHARED_LIBRARY:$(DLL_SUFFIX)=.exp) $(wildcard *.ilk) \
-	$(PROGRAM:$(BIN_SUFFIX)=.exp) $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.exp) \
-	$(PROGRAM:$(BIN_SUFFIX)=.lib) $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.lib) \
-	$(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.$(OBJ_SUFFIX)) \
-	$(wildcard gts_tmp_*) $(LIBRARY:%.a=.%.timestamp)
-ALL_TRASH_DIRS = \
-	$(GARBAGE_DIRS) /no-such-file
-
-ifdef QTDIR
-GARBAGE                 += $(MOCSRCS)
-GARBAGE                 += $(RCCSRCS)
-endif
-
-ifdef SIMPLE_PROGRAMS
-GARBAGE			+= $(SIMPLE_PROGRAMS:%=%.$(OBJ_SUFFIX))
-endif
-
-ifdef HOST_SIMPLE_PROGRAMS
-GARBAGE			+= $(HOST_SIMPLE_PROGRAMS:%=%.$(OBJ_SUFFIX))
-endif
-
-#
-# the Solaris WorkShop template repository cache.  it occasionally can get
-# out of sync, so targets like clobber should kill it.
-#
-ifeq ($(SOLARIS_SUNPRO_CXX),1)
-GARBAGE_DIRS += SunWS_cache
-endif
-
-XPIDL_GEN_DIR		= _xpidlgen
-
-ifdef MOZ_UPDATE_XTERM
-# Its good not to have a newline at the end of the titlebar string because it
-# makes the make -s output easier to read.  Echo -n does not work on all
-# platforms, but we can trick sed into doing it.
-UPDATE_TITLE = sed -e "s!Y!$(1) in $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2)!" $(MOZILLA_DIR)/config/xterm.str;
-endif
-
-define SUBMAKE # $(call SUBMAKE,target,directory)
-+@$(UPDATE_TITLE)
-+$(MAKE) $(if $(2),-C $(2)) $(1)
-
-endef # The extra line is important here! don't delete it
-
-ifneq (,$(strip $(DIRS)))
-LOOP_OVER_DIRS = \
-  $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir)))
-endif
-
-# we only use this for the makefiles target and other stuff that doesn't matter
-ifneq (,$(strip $(PARALLEL_DIRS)))
-LOOP_OVER_PARALLEL_DIRS = \
-  $(foreach dir,$(PARALLEL_DIRS),$(call SUBMAKE,$@,$(dir)))
-endif
-
-ifneq (,$(strip $(STATIC_DIRS)))
-LOOP_OVER_STATIC_DIRS = \
-  $(foreach dir,$(STATIC_DIRS),$(call SUBMAKE,$@,$(dir)))
-endif
-
-ifneq (,$(strip $(TOOL_DIRS)))
-LOOP_OVER_TOOL_DIRS = \
-  $(foreach dir,$(TOOL_DIRS),$(call SUBMAKE,$@,$(dir)))
-endif
-
-#
-# Now we can differentiate between objects used to build a library, and
-# objects used to build an executable in the same directory.
-#
-ifndef PROGOBJS
-PROGOBJS		= $(OBJS)
-endif
-
-ifndef HOST_PROGOBJS
-HOST_PROGOBJS		= $(HOST_OBJS)
-endif
-
-# MAKE_DIRS: List of directories to build while looping over directories.
-# A Makefile that needs $(MDDEPDIR) created but doesn't set any of these
-# variables we know to check can just set NEED_MDDEPDIR explicitly.
-ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS)$(NEED_MDDEPDIR))
-MAKE_DIRS		+= $(CURDIR)/$(MDDEPDIR)
-GARBAGE_DIRS		+= $(MDDEPDIR)
-endif
-
-#
-# Tags: emacs (etags), vi (ctags)
-# TAG_PROGRAM := ctags -L -
-#
-TAG_PROGRAM		= xargs etags -a
-
-#
-# Turn on C++ linking if we have any .cpp or .mm files
-# (moved this from config.mk so that config.mk can be included
-#  before the CPPSRCS are defined)
-#
-ifneq ($(CPPSRCS)$(CMMSRCS),)
-CPP_PROG_LINK		= 1
-endif
-ifneq ($(HOST_CPPSRCS)$(HOST_CMMSRCS),)
-HOST_CPP_PROG_LINK	= 1
-endif
-
-#
-# This will strip out symbols that the component should not be
-# exporting from the .dynsym section.
-#
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS += $(MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS)
-endif # IS_COMPONENT
-
-#
-# Enforce the requirement that MODULE_NAME must be set
-# for components in static builds
-#
-ifdef IS_COMPONENT
-ifdef EXPORT_LIBRARY
-ifndef FORCE_SHARED_LIB
-ifndef MODULE_NAME
-$(error MODULE_NAME is required for components which may be used in static builds)
-endif
-endif
-endif
-endif
-
-#
-# MacOS X specific stuff
-#
-
-ifeq ($(OS_ARCH),Darwin)
-ifdef SHARED_LIBRARY
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS	+= -bundle
-else
-EXTRA_DSO_LDOPTS	+= -dynamiclib -install_name @executable_path/$(SHARED_LIBRARY) -compatibility_version 1 -current_version 1 -single_module
-endif
-endif
-endif
-
-#
-# On NetBSD a.out systems, use -Bsymbolic.  This fixes what would otherwise be
-# fatal symbol name clashes between components.
-#
-ifeq ($(OS_ARCH),NetBSD)
-ifeq ($(DLL_SUFFIX),.so.1.0)
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic
-endif
-endif
-endif
-
-ifeq ($(OS_ARCH),FreeBSD)
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic
-endif
-endif
-
-ifeq ($(OS_ARCH),NetBSD)
-ifneq (,$(filter arc cobalt hpcmips mipsco newsmips pmax sgimips,$(OS_TEST)))
-ifeq ($(MODULE),layout)
-OS_CFLAGS += -Wa,-xgot
-OS_CXXFLAGS += -Wa,-xgot
-endif
-endif
-endif
-
-#
-# HP-UXBeOS specific section: for COMPONENTS only, add -Bsymbolic flag
-# which uses internal symbols first
-#
-ifeq ($(OS_ARCH),HP-UX)
-ifdef IS_COMPONENT
-ifeq ($(GNU_CC)$(GNU_CXX),)
-EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic
-ifneq ($(HAS_EXTRAEXPORTS),1)
-MKSHLIB  += -Wl,+eNSGetModule -Wl,+eerrno
-MKCSHLIB += +eNSGetModule +eerrno
-ifneq ($(OS_TEST),ia64)
-MKSHLIB  += -Wl,+e_shlInit
-MKCSHLIB += +e_shlInit
-endif # !ia64
-endif # !HAS_EXTRAEXPORTS
-endif # non-gnu compilers
-endif # IS_COMPONENT
-endif # HP-UX
-
-ifeq ($(OS_ARCH),AIX)
-ifdef IS_COMPONENT
-ifneq ($(HAS_EXTRAEXPORTS),1)
-MKSHLIB += -bE:$(MOZILLA_DIR)/build/unix/aix.exp -bnoexpall
-MKCSHLIB += -bE:$(MOZILLA_DIR)/build/unix/aix.exp -bnoexpall
-endif # HAS_EXTRAEXPORTS
-endif # IS_COMPONENT
-endif # AIX
-
-#
-# OSF1: add -B symbolic flag for components
-#
-ifeq ($(OS_ARCH),OSF1)
-ifdef IS_COMPONENT
-ifeq ($(GNU_CC)$(GNU_CXX),)
-EXTRA_DSO_LDOPTS += -B symbolic
-endif
-endif
-endif
-
-#
-# Linux: add -Bsymbolic flag for components
-#
-ifeq ($(OS_ARCH),Linux)
-ifdef IS_COMPONENT
-EXTRA_DSO_LDOPTS += -Wl,-Bsymbolic
-endif
-endif
-
-#
-# GNU doesn't have path length limitation
-#
-
-ifeq ($(OS_ARCH),GNU)
-OS_CPPFLAGS += -DPATH_MAX=1024 -DMAXPATHLEN=1024
-endif
-
-#
-# MINGW32
-#
-ifeq ($(OS_ARCH),WINNT)
-ifdef GNU_CC
-ifndef IS_COMPONENT
-DSO_LDOPTS += -Wl,--out-implib -Wl,$(IMPORT_LIBRARY)
-endif
-endif
-endif
-
-ifeq ($(USE_TVFS),1)
-IFLAGS1 = -rb
-IFLAGS2 = -rb
-else
-IFLAGS1 = -m 644
-IFLAGS2 = -m 755
-endif
-
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-OUTOPTION = -Fo# eol
-else
-OUTOPTION = -o # eol
-endif # WINNT && !GNU_CC
-
-ifneq (,$(filter ml%,$(AS)))
-ASOUTOPTION = -Fo# eol
-else
-ASOUTOPTION = -o # eol
-endif
-
-ifeq (,$(CROSS_COMPILE))
-HOST_OUTOPTION = $(OUTOPTION)
-else
-HOST_OUTOPTION = -o # eol
-endif
-################################################################################
-
-# SUBMAKEFILES: List of Makefiles for next level down.
-#   This is used to update or create the Makefiles before invoking them.
-SUBMAKEFILES += $(addsuffix /Makefile, $(DIRS) $(TOOL_DIRS) $(PARALLEL_DIRS))
-
-# The root makefile doesn't want to do a plain export/libs, because
-# of the tiers and because of libxul. Suppress the default rules in favor
-# of something else. Makefiles which use this var *must* provide a sensible
-# default rule before including rules.mk
-ifndef SUPPRESS_DEFAULT_RULES
-ifdef TIERS
-default all alldep::
-	$(foreach tier,$(TIERS),$(call SUBMAKE,tier_$(tier)))
-else
-
-default all::
-ifneq (,$(strip $(STATIC_DIRS)))
-	$(foreach dir,$(STATIC_DIRS),$(call SUBMAKE,,$(dir)))
-endif
-	$(MAKE) export
-	$(MAKE) libs
-	$(MAKE) tools
-
-# Do depend as well
-alldep::
-	$(MAKE) export
-	$(MAKE) depend
-	$(MAKE) libs
-	$(MAKE) tools
-
-endif # TIERS
-endif # SUPPRESS_DEFAULT_RULES
-
-ifeq ($(filter s,$(MAKEFLAGS)),)
-ECHO := echo
-QUIET :=
-else
-ECHO := true
-QUIET := -q
-endif
-
-MAKE_TIER_SUBMAKEFILES = +$(if $(tier_$*_dirs),$(MAKE) $(addsuffix /Makefile,$(tier_$*_dirs)))
-
-$(foreach tier,$(TIERS),tier_$(tier))::
-	@$(ECHO) "$@: $($@_staticdirs) $($@_dirs)"
-	$(foreach dir,$($@_staticdirs),$(call SUBMAKE,,$(dir)))
-	$(MAKE) export_$@
-	$(MAKE) libs_$@
-	$(MAKE) tools_$@
-
-# Do everything from scratch
-everything::
-	$(MAKE) clean
-	$(MAKE) alldep
-
-# Add dummy depend target for tinderboxes
-depend::
-
-# Target to only regenerate makefiles
-makefiles: $(SUBMAKEFILES)
-ifneq (,$(DIRS)$(TOOL_DIRS)$(PARALLEL_DIRS))
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-endif
-
-include $(topsrcdir)/config/makefiles/target_export.mk
-include $(topsrcdir)/config/makefiles/target_tools.mk
-
-#
-# Rule to create list of libraries for final link
-#
-export::
-ifdef LIBRARY_NAME
-ifdef EXPORT_LIBRARY
-ifdef IS_COMPONENT
-else # !IS_COMPONENT
-	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
-endif # IS_COMPONENT
-endif # EXPORT_LIBRARY
-endif # LIBRARY_NAME
-
-ifneq (,$(filter-out %.$(LIB_SUFFIX),$(SHARED_LIBRARY_LIBS)))
-$(error SHARED_LIBRARY_LIBS must contain .$(LIB_SUFFIX) files only)
-endif
-
-# Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
-DO_EXPAND_LIBS = $(foreach f,$(1),$(if $(filter %.$(LIB_SUFFIX),$(f)),$(if $(wildcard $(f).$(LIBS_DESC_SUFFIX)),$(f).$(LIBS_DESC_SUFFIX),$(if $(wildcard $(f)),$(f)))))
-LIBS_DEPS = $(call DO_EXPAND_LIBS,$(filter %.$(LIB_SUFFIX),$(LIBS) $(if $(PROGRAM)$(SIMPLE_PROGRAMS),$(MOZ_GLUE_PROGRAM_LDFLAGS))))
-SHARED_LIBRARY_LIBS_DEPS = $(call DO_EXPAND_LIBS,$(SHARED_LIBRARY_LIBS))
-HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
-DSO_LDOPTS_DEPS = $(call DO_EXPAND_LIBS,$(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS)))
-
-# Dependencies which, if modified, should cause everything to rebuild
-GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
-
-##############################################
-include $(topsrcdir)/config/makefiles/target_libs.mk
-
-##############################################
-ifndef NO_PROFILE_GUIDED_OPTIMIZE
-ifdef MOZ_PROFILE_USE
-ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
-# When building with PGO, we have to make sure to re-link
-# in the MOZ_PROFILE_USE phase if we linked in the
-# MOZ_PROFILE_GENERATE phase. We'll touch this pgo.relink
-# file in the link rule in the GENERATE phase to indicate
-# that we need a relink.
-ifdef SHARED_LIBRARY
-$(SHARED_LIBRARY): pgo.relink
-endif
-ifdef PROGRAM
-$(PROGRAM): pgo.relink
-endif
-
-# In the second pass, we need to merge the pgc files into the pgd file.
-# The compiler would do this for us automatically if they were in the right
-# place, but they're in dist/bin.
-ifneq (,$(SHARED_LIBRARY)$(PROGRAM))
-export::
-ifdef PROGRAM
-	$(PYTHON) $(topsrcdir)/build/win32/pgomerge.py \
-	  $(PROGRAM:$(BIN_SUFFIX)=) $(DIST)/bin
-endif
-ifdef SHARED_LIBRARY
-	$(PYTHON) $(topsrcdir)/build/win32/pgomerge.py \
-	  $(SHARED_LIBRARY_NAME) $(DIST)/bin
-endif
-endif # SHARED_LIBRARY || PROGRAM
-endif # WINNT_
-endif # MOZ_PROFILE_USE
-ifdef MOZ_PROFILE_GENERATE
-# Clean up profiling data during PROFILE_GENERATE phase
-export::
-ifeq ($(OS_ARCH)_$(GNU_CC), WINNT_)
-	$(foreach pgd,$(wildcard *.pgd),pgomgr -clear $(pgd);)
-else
-ifdef GNU_CC
-	-$(RM) *.gcda
-endif
-endif
-endif
-
-ifneq (,$(MOZ_PROFILE_GENERATE)$(MOZ_PROFILE_USE))
-ifdef GNU_CC
-# Force rebuilding libraries and programs in both passes because each
-# pass uses different object files.
-$(PROGRAM) $(SHARED_LIBRARY) $(LIBRARY): FORCE
-endif
-endif
-
-endif # NO_PROFILE_GUIDED_OPTIMIZE
-
-##############################################
-
-stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_TARGET_VERSION)
-host_stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_HOST_VERSION)
-
-checkout:
-	$(MAKE) -C $(topsrcdir) -f client.mk checkout
-
-clean clobber realclean clobber_all:: $(SUBMAKEFILES)
-	-$(RM) $(ALL_TRASH)
-	-$(RM) -r $(ALL_TRASH_DIRS)
-	$(foreach dir,$(PARALLEL_DIRS) $(DIRS) $(STATIC_DIRS) $(TOOL_DIRS),-$(call SUBMAKE,$@,$(dir)))
-
-distclean:: $(SUBMAKEFILES)
-	$(foreach dir,$(PARALLEL_DIRS) $(DIRS) $(STATIC_DIRS) $(TOOL_DIRS),-$(call SUBMAKE,$@,$(dir)))
-	-$(RM) -r $(ALL_TRASH_DIRS)
-	-$(RM) $(ALL_TRASH)  \
-	Makefile .HSancillary \
-	$(wildcard *.$(OBJ_SUFFIX)) $(wildcard *.ho) $(wildcard host_*.o*) \
-	$(wildcard *.$(LIB_SUFFIX)) $(wildcard *$(DLL_SUFFIX)) \
-	$(wildcard *.$(IMPORT_LIB_SUFFIX))
-ifeq ($(OS_ARCH),OS2)
-	-$(RM) $(PROGRAM:.exe=.map)
-endif
-
-alltags:
-	$(RM) TAGS
-	find $(topsrcdir) -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' -o -name '*.idl' \) -print | $(TAG_PROGRAM)
-
-#
-# PROGRAM = Foo
-# creates OBJS, links with LIBS to create Foo
-#
-$(PROGRAM): $(PROGOBJS) $(LIBS_DEPS) $(EXTRA_DEPS) $(EXE_DEF_FILE) $(RESFILE) $(GLOBAL_DEPS)
-	@$(RM) $@.manifest
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(EXPAND_LD) -NOLOGO -OUT:$@ -PDB:$(LINK_PDBFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(PROGOBJS) $(RESFILE) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
-ifdef MSMANIFEST_TOOL
-	@if test -f $@.manifest; then \
-		if test -f "$(srcdir)/$@.manifest"; then \
-			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
-			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		else \
-			echo "Embedding manifest from $@.manifest"; \
-			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		fi; \
-	elif test -f "$(srcdir)/$@.manifest"; then \
-		echo "Embedding manifest from $(srcdir)/$@.manifest"; \
-		mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" -OUTPUTRESOURCE:$@\;1; \
-	fi
-endif	# MSVC with manifest tool
-ifdef MOZ_PROFILE_GENERATE
-# touch it a few seconds into the future to work around FAT's
-# 2-second granularity
-	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
-endif
-else # !WINNT || GNU_CC
-ifeq ($(CPP_PROG_LINK),1)
-	$(EXPAND_CCC) -o $@ $(CXXFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE)
-	@$(call CHECK_STDCXX,$@)
-else # ! CPP_PROG_LINK
-	$(EXPAND_CC) -o $@ $(CFLAGS) $(PROGOBJS) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS) $(EXE_DEF_FILE)
-endif # CPP_PROG_LINK
-endif # WINNT && !GNU_CC
-
-ifdef ENABLE_STRIP
-	$(STRIP) $@
-endif
-ifdef MOZ_POST_PROGRAM_COMMAND
-	$(MOZ_POST_PROGRAM_COMMAND) $@
-endif
-
-$(HOST_PROGRAM): $(HOST_PROGOBJS) $(HOST_LIBS_DEPS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
-ifeq (_WINNT,$(GNU_CC)_$(HOST_OS_ARCH))
-	$(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $(HOST_OBJS) $(WIN32_EXE_LDFLAGS) $(HOST_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-ifdef MSMANIFEST_TOOL
-	@if test -f $@.manifest; then \
-		if test -f "$(srcdir)/$@.manifest"; then \
-			echo "Embedding manifest from $(srcdir)/$@.manifest and $@.manifest"; \
-			mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		else \
-			echo "Embedding manifest from $@.manifest"; \
-			mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		fi; \
-	elif test -f "$(srcdir)/$@.manifest"; then \
-		echo "Embedding manifest from $(srcdir)/$@.manifest"; \
-		mt.exe -NOLOGO -MANIFEST "$(win_srcdir)/$@.manifest" -OUTPUTRESOURCE:$@\;1; \
-	fi
-endif	# MSVC with manifest tool
-else
-ifeq ($(HOST_CPP_PROG_LINK),1)
-	$(HOST_CXX) -o $@ $(HOST_CXXFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-else
-	$(HOST_CC) -o $@ $(HOST_CFLAGS) $(HOST_LDFLAGS) $(HOST_PROGOBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-endif # HOST_CPP_PROG_LINK
-endif
-
-#
-# This is an attempt to support generation of multiple binaries
-# in one directory, it assumes everything to compile Foo is in
-# Foo.o (from either Foo.c or Foo.cpp).
-#
-# SIMPLE_PROGRAMS = Foo Bar
-# creates Foo.o Bar.o, links with LIBS to create Foo, Bar.
-#
-$(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-	$(EXPAND_LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
-ifdef MSMANIFEST_TOOL
-	@if test -f $@.manifest; then \
-		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
-		rm -f $@.manifest; \
-	fi
-endif	# MSVC with manifest tool
-else
-ifeq ($(CPP_PROG_LINK),1)
-	$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
-	@$(call CHECK_STDCXX,$@)
-else
-	$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
-endif # CPP_PROG_LINK
-endif # WINNT && !GNU_CC
-
-ifdef ENABLE_STRIP
-	$(STRIP) $@
-endif
-ifdef MOZ_POST_PROGRAM_COMMAND
-	$(MOZ_POST_PROGRAM_COMMAND) $@
-endif
-
-$(HOST_SIMPLE_PROGRAMS): host_%$(HOST_BIN_SUFFIX): host_%.$(OBJ_SUFFIX) $(HOST_LIBS_DEPS) $(HOST_EXTRA_DEPS) $(GLOBAL_DEPS)
-ifeq (WINNT_,$(HOST_OS_ARCH)_$(GNU_CC))
-	$(HOST_LD) -NOLOGO -OUT:$@ -PDB:$(HOST_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-else
-ifneq (,$(HOST_CPPSRCS)$(USE_HOST_CXX))
-	$(HOST_CXX) $(HOST_OUTOPTION)$@ $(HOST_CXXFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-else
-	$(HOST_CC) $(HOST_OUTOPTION)$@ $(HOST_CFLAGS) $(INCLUDES) $< $(HOST_LIBS) $(HOST_EXTRA_LIBS)
-endif
-endif
-
-#
-# Purify target.  Solaris/sparc only to start.
-# Purify does not recognize "egcs" or "c++" so we go with
-# "gcc" and "g++" for now.
-#
-pure:	$(PROGRAM)
-ifeq ($(CPP_PROG_LINK),1)
-	$(PURIFY) $(CCC) -o $^.pure $(CXXFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
-else
-	$(PURIFY) $(CC) -o $^.pure $(CFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
-endif
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS2) $^.pure $(FINAL_TARGET)
-endif
-
-quantify: $(PROGRAM)
-ifeq ($(CPP_PROG_LINK),1)
-	$(QUANTIFY) $(CCC) -o $^.quantify $(CXXFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
-else
-	$(QUANTIFY) $(CC) -o $^.quantify $(CFLAGS) $(PROGOBJS) $(LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS)
-endif
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS2) $^.quantify $(FINAL_TARGET)
-endif
-
-ifdef DTRACE_PROBE_OBJ
-EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
-OBJS += $(DTRACE_PROBE_OBJ)
-endif
-
-$(filter %.$(LIB_SUFFIX),$(LIBRARY)): $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
-	$(RM) $(LIBRARY)
-	$(EXPAND_AR) $(AR_FLAGS) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS)
-	$(RANLIB) $@
-
-$(filter-out %.$(LIB_SUFFIX),$(LIBRARY)): $(filter %.$(LIB_SUFFIX),$(LIBRARY)) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
-# When we only build a library descriptor, blow out any existing library
-	$(if $(filter %.$(LIB_SUFFIX),$(LIBRARY)),,$(RM) $(REAL_LIBRARY) $(EXPORT_LIBRARY:%=%/$(REAL_LIBRARY)))
-	$(EXPAND_LIBS_GEN) $(OBJS) $(LOBJS) $(SHARED_LIBRARY_LIBS) > $@
-
-ifeq ($(OS_ARCH),WINNT)
-$(IMPORT_LIBRARY): $(SHARED_LIBRARY)
-endif
-
-ifeq ($(OS_ARCH),OS2)
-$(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
-	$(RM) $@
-	echo LIBRARY $(SHARED_LIBRARY_NAME) INITINSTANCE TERMINSTANCE > $@
-	echo PROTMODE >> $@
-	echo CODE    LOADONCALL MOVEABLE DISCARDABLE >> $@
-	echo DATA    PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@
-	echo EXPORTS >> $@
-
-	$(ADD_TO_DEF_FILE)
-
-$(IMPORT_LIBRARY): $(SHARED_LIBRARY)
-	$(RM) $@
-	$(IMPLIB) $@ $^
-	$(RANLIB) $@
-endif # OS/2
-
-$(HOST_LIBRARY): $(HOST_OBJS) Makefile
-	$(RM) $@
-	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
-	$(HOST_RANLIB) $@
-
-ifdef HAVE_DTRACE
-ifndef XP_MACOSX
-ifdef DTRACE_PROBE_OBJ
-ifndef DTRACE_LIB_DEPENDENT
-NON_DTRACE_OBJS := $(filter-out $(DTRACE_PROBE_OBJ),$(OBJS))
-$(DTRACE_PROBE_OBJ): $(NON_DTRACE_OBJS)
-	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(NON_DTRACE_OBJS)
-endif
-endif
-endif
-endif
-
-# On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
-# so instead of deleting .o files after repacking them into a dylib, we make
-# symlinks back to the originals. The symlinks are a no-op for stabs debugging,
-# so no need to conditionalize on OS version or debugging format.
-
-$(SHARED_LIBRARY): $(OBJS) $(LOBJS) $(DEF_FILE) $(RESFILE) $(SHARED_LIBRARY_LIBS_DEPS) $(LIBRARY) $(EXTRA_DEPS) $(DSO_LDOPTS_DEPS) $(GLOBAL_DEPS)
-ifndef INCREMENTAL_LINKER
-	$(RM) $@
-endif
-ifdef DTRACE_LIB_DEPENDENT
-ifndef XP_MACOSX
-	dtrace -G -C -s $(MOZILLA_DTRACE_SRC) -o  $(DTRACE_PROBE_OBJ) $(shell $(EXPAND_LIBS) $(MOZILLA_PROBE_LIBS))
-endif
-	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(MOZILLA_PROBE_LIBS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
-	@$(RM) $(DTRACE_PROBE_OBJ)
-else # ! DTRACE_LIB_DEPENDENT
-	$(EXPAND_MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(WRAP_LDFLAGS) $(SHARED_LIBRARY_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
-endif # DTRACE_LIB_DEPENDENT
-	@$(call CHECK_STDCXX,$@)
-
-ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
-ifdef MSMANIFEST_TOOL
-ifdef EMBED_MANIFEST_AT
-	@if test -f $@.manifest; then \
-		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;$(EMBED_MANIFEST_AT); \
-		rm -f $@.manifest; \
-	fi
-endif   # EMBED_MANIFEST_AT
-endif	# MSVC with manifest tool
-ifdef MOZ_PROFILE_GENERATE
-	touch -t `date +%Y%m%d%H%M.%S -d "now+5seconds"` pgo.relink
-endif
-endif	# WINNT && !GCC
-	@$(RM) foodummyfilefoo $(DELETE_AFTER_LINK)
-	chmod +x $@
-ifdef ENABLE_STRIP
-	$(STRIP) $@
-endif
-ifdef MOZ_POST_DSO_LIB_COMMAND
-	$(MOZ_POST_DSO_LIB_COMMAND) $@
-endif
-
-ifdef MOZ_AUTO_DEPS
-ifdef COMPILER_DEPEND
-ifeq ($(SOLARIS_SUNPRO_CC),1)
-_MDDEPFILE = $(MDDEPDIR)/$(@F).pp
-
-define MAKE_DEPS_AUTO_CC
-if test -d $(@D); then \
-	echo "Building deps for $< using Sun Studio cc"; \
-	$(CC) $(COMPILE_CFLAGS) -xM  $< >$(_MDDEPFILE) ; \
-fi
-endef
-define MAKE_DEPS_AUTO_CXX
-if test -d $(@D); then \
-	echo "Building deps for $< using Sun Studio CC"; \
-	$(CXX) $(COMPILE_CXXFLAGS) -xM $< >$(_MDDEPFILE) ; \
-fi
-endef
-endif # Sun Studio on Solaris
-else # COMPILER_DEPEND
-#
-# Generate dependencies on the fly
-#
-_MDDEPFILE = $(MDDEPDIR)/$(@F).pp
-
-define MAKE_DEPS_AUTO
-if test -d $(@D); then \
-	echo "Building deps for $<"; \
-	$(MKDEPEND) -o'.$(OBJ_SUFFIX)' -f- $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(INCLUDES) $< 2>/dev/null | sed -e "s|^[^ ]*/||" > $(_MDDEPFILE) ; \
-fi
-endef
-
-MAKE_DEPS_AUTO_CC = $(MAKE_DEPS_AUTO)
-MAKE_DEPS_AUTO_CXX = $(MAKE_DEPS_AUTO)
-
-endif # COMPILER_DEPEND
-
-endif # MOZ_AUTO_DEPS
-
-# Rules for building native targets must come first because of the host_ prefix
-host_%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-host_%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-host_%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-host_%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CC) $(HOST_OUTOPTION)$@ -c $(HOST_CFLAGS) $(HOST_CMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-host_%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
-
-%:: %.c $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CC)
-	$(ELOG) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTOPTION)$@ $(_VPATH_SRCS)
-
-%.$(OBJ_SUFFIX): %.c $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CC)
-	$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
-
-# DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs:
-# 'moc' only knows about #defines it gets on the command line (-D...), not in
-# included headers like mozilla-config.h
-moc_%.cpp: %.h $(GLOBAL_DEPS)
-	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
-
-moc_%.cc: %.cc $(GLOBAL_DEPS)
-	$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
-
-qrc_%.cpp: %.qrc $(GLOBAL_DEPS)
-	$(ELOG) $(RCC) -name $* $< $(OUTOPTION)$@
-
-ifdef ASFILES
-# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
-# a '-c' flag.
-%.$(OBJ_SUFFIX): %.$(ASM_SUFFIX) $(GLOBAL_DEPS)
-	$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
-endif
-
-%.$(OBJ_SUFFIX): %.S $(GLOBAL_DEPS)
-	$(AS) -o $@ $(ASFLAGS) -c $<
-
-%:: %.cpp $(GLOBAL_DEPS)
-	@$(MAKE_DEPS_AUTO_CXX)
-	$(CCC) $(OUTOPTION)$@ $(CXXFLAGS) $(_VPATH_SRCS) $(LDFLAGS)
-
-#
-# Please keep the next two rules in sync.
-#
-%.$(OBJ_SUFFIX): %.cc $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CXX)
-	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-
-%.$(OBJ_SUFFIX): %.cpp $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CXX)
-ifdef STRICT_CPLUSPLUS_SUFFIX
-	echo "#line 1 \"$*.cpp\"" | cat - $*.cpp > t_$*.cc
-	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) t_$*.cc
-	$(RM) t_$*.cc
-else
-	$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-endif #STRICT_CPLUSPLUS_SUFFIX
-
-$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CXX)
-	$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
-
-$(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m $(GLOBAL_DEPS)
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_AUTO_CC)
-	$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
-
-%.s: %.cpp
-	$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-
-%.s: %.cc
-	$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
-
-%.s: %.c
-	$(CC) -S $(COMPILE_CFLAGS) $(_VPATH_SRCS)
-
-%.i: %.cpp
-	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) > $*.i
-
-%.i: %.cc
-	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) > $*.i
-
-%.i: %.c
-	$(CC) -C -E $(COMPILE_CFLAGS) $(_VPATH_SRCS) > $*.i
-
-%.i: %.mm
-	$(CCC) -C -E $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS) > $*.i
-
-%.res: %.rc
-	@echo Creating Resource file: $@
-ifeq ($(OS_ARCH),OS2)
-	$(RC) $(RCFLAGS:-D%=-d %) -i $(subst /,\,$(srcdir)) -r $< $@
-else
-ifdef GNU_CC
-	$(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $(_VPATH_SRCS)
-else
-	$(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $(_VPATH_SRCS)
-endif
-endif
-
-# need 3 separate lines for OS/2
-%:: %.pl
-	$(RM) $@
-	cp $< $@
-	chmod +x $@
-
-%:: %.sh
-	$(RM) $@
-	cp $< $@
-	chmod +x $@
-
-# Cancel these implicit rules
-#
-%: %,v
-
-%: RCS/%,v
-
-%: s.%
-
-%: SCCS/s.%
-
-###############################################################################
-# Java rules
-###############################################################################
-ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
-SEP := ;
-else
-SEP := :
-endif
-
-EMPTY :=
-SPACE := $(EMPTY) $(EMPTY)
-
-# MSYS has its own special path form, but javac expects the source and class
-# paths to be in the DOS form (i.e. e:/builds/...).  This function does the
-# appropriate conversion on Windows, but is a noop on other systems.
-ifeq ($(HOST_OS_ARCH),WINNT)
-#  We use 'pwd -W' to get DOS form of the path.  However, since the given path
-#  could be a file or a non-existent path, we cannot call 'pwd -W' directly
-#  on the path.  Instead, we extract the root path (i.e. "c:/"), call 'pwd -W'
-#  on it, then merge with the rest of the path.
-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
-non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|")
-normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1)))
-else
-normalizepath = $(1)
-endif
-
-_srcdir = $(call normalizepath,$(srcdir))
-ifdef JAVA_SOURCEPATH
-SP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_SOURCEPATH))))
-_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)$(SEP)$(SP)"
-else
-_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)"
-endif
-
-ifdef JAVA_CLASSPATH
-CP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_CLASSPATH))))
-_JAVA_CLASSPATH = ".$(SEP)$(CP)"
-else
-_JAVA_CLASSPATH = .
-endif
-
-_JAVA_DIR = _java
-$(_JAVA_DIR)::
-	$(NSINSTALL) -D $@
-
-$(_JAVA_DIR)/%.class: %.java $(GLOBAL_DEPS) $(_JAVA_DIR)
-	$(JAVAC) $(JAVAC_FLAGS) -classpath $(_JAVA_CLASSPATH) \
-			-sourcepath $(_JAVA_SOURCEPATH) -d $(_JAVA_DIR) $(_VPATH_SRCS)
-
-$(JAVA_LIBRARY): $(addprefix $(_JAVA_DIR)/,$(JAVA_SRCS:.java=.class)) $(GLOBAL_DEPS)
-	$(JAR) cf $@ -C $(_JAVA_DIR) .
-
-GARBAGE_DIRS += $(_JAVA_DIR)
-
-###############################################################################
-# Update Makefiles
-###############################################################################
-
-# Note: Passing depth to make-makefile is optional.
-#       It saves the script some work, though.
-Makefile: Makefile.in
-	@$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH)
-
-ifdef SUBMAKEFILES
-# VPATH does not work on some machines in this case, so add $(srcdir)
-$(SUBMAKEFILES): % : $(srcdir)/%.in
-	$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH) $@
-endif
-
-ifdef AUTOUPDATE_CONFIGURE
-$(topsrcdir)/configure: $(topsrcdir)/configure.in
-	(cd $(topsrcdir) && $(AUTOCONF)) && (cd $(DEPTH) && ./config.status --recheck)
-endif
-
-$(DEPTH)/config/autoconf.mk: $(topsrcdir)/config/autoconf.mk.in
-	cd $(DEPTH) && CONFIG_HEADERS= CONFIG_FILES=config/autoconf.mk ./config.status
-
-###############################################################################
-# Bunch of things that extend the 'export' rule (in order):
-###############################################################################
-
-################################################################################
-# Copy each element of EXPORTS to $(DIST)/include
-
-ifneq ($(XPI_NAME),)
-$(FINAL_TARGET):
-	$(NSINSTALL) -D $@
-
-export:: $(FINAL_TARGET)
-endif
-
-ifndef NO_DIST_INSTALL
-ifneq (,$(EXPORTS))
-export:: $(EXPORTS)
-	$(INSTALL) $(IFLAGS1) $^ $(DIST)/include
-endif
-endif # NO_DIST_INSTALL
-
-define EXPORT_NAMESPACE_RULE
-ifndef NO_DIST_INSTALL
-export:: $(EXPORTS_$(namespace))
-	$(INSTALL) $(IFLAGS1) $$^ $(DIST)/include/$(namespace)
-endif # NO_DIST_INSTALL
-endef
-
-$(foreach namespace,$(EXPORTS_NAMESPACES),$(eval $(EXPORT_NAMESPACE_RULE)))
-
-################################################################################
-# Copy each element of PREF_JS_EXPORTS
-
-ifdef GRE_MODULE
-PREF_DIR = greprefs
-else
-ifneq (,$(XPI_NAME)$(LIBXUL_SDK))
-PREF_DIR = defaults/preferences
-else
-PREF_DIR = defaults/pref
-endif
-endif
-
-ifneq ($(PREF_JS_EXPORTS),)
-# on win32, pref files need CRLF line endings... see bug 206029
-ifeq (WINNT,$(OS_ARCH))
-PREF_PPFLAGS = --line-endings=crlf
-endif
-
-ifndef NO_DIST_INSTALL
-$(FINAL_TARGET)/$(PREF_DIR):
-	$(NSINSTALL) -D $@
-
-libs:: $(FINAL_TARGET)/$(PREF_DIR)
-libs:: $(PREF_JS_EXPORTS)
-	$(EXIT_ON_ERROR)  \
-	for i in $^; do \
-	  dest=$(FINAL_TARGET)/$(PREF_DIR)/`basename $$i`; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
-	done
-endif
-endif
-
-################################################################################
-# Copy each element of AUTOCFG_JS_EXPORTS to $(FINAL_TARGET)/defaults/autoconfig
-
-ifneq ($(AUTOCFG_JS_EXPORTS),)
-$(FINAL_TARGET)/defaults/autoconfig::
-	$(NSINSTALL) -D $@
-
-ifndef NO_DIST_INSTALL
-export:: $(AUTOCFG_JS_EXPORTS) $(FINAL_TARGET)/defaults/autoconfig
-	$(INSTALL) $(IFLAGS1) $^
-endif
-
-endif
-################################################################################
-# Export the elements of $(XPIDLSRCS)
-# generating .h and .xpt files and moving them to the appropriate places.
-
-ifneq ($(XPIDLSRCS),)
-
-export:: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS))
-
-ifndef XPIDL_MODULE
-XPIDL_MODULE		= $(MODULE)
-endif
-
-ifeq ($(XPIDL_MODULE),) # we need $(XPIDL_MODULE) to make $(XPIDL_MODULE).xpt
-export:: FORCE
-	@echo
-	@echo "*** Error processing XPIDLSRCS:"
-	@echo "Please define MODULE or XPIDL_MODULE when defining XPIDLSRCS,"
-	@echo "so we have a module name to use when creating MODULE.xpt."
-	@echo; sleep 2; false
-endif
-
-# generate .h files from into $(XPIDL_GEN_DIR), then export to $(DIST)/include;
-# warn against overriding existing .h file.
-$(XPIDL_GEN_DIR)/.done:
-	$(MKDIR) -p $(XPIDL_GEN_DIR)
-	@$(TOUCH) $@
-
-# don't depend on $(XPIDL_GEN_DIR), because the modification date changes
-# with any addition to the directory, regenerating all .h files -> everything.
-
-XPIDL_DEPS = \
-  $(topsrcdir)/xpcom/idl-parser/header.py \
-  $(topsrcdir)/xpcom/idl-parser/typelib.py \
-  $(topsrcdir)/xpcom/idl-parser/xpidl.py \
-  $(NULL)
-
-$(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
-	$(REPORT_BUILD)
-	$(PYTHON_PATH) \
-	  -I$(topsrcdir)/other-licenses/ply \
-	  -I$(topsrcdir)/xpcom/idl-parser \
-	  $(topsrcdir)/xpcom/idl-parser/header.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
-	@if test -n "$(findstring $*.h, $(EXPORTS))"; \
-	  then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
-
-ifndef NO_GEN_XPT
-# generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
-# into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
-$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(XPIDL_GEN_DIR)/.done
-	$(REPORT_BUILD)
-	$(PYTHON_PATH) \
-	  -I$(topsrcdir)/other-licenses/ply \
-	  -I$(topsrcdir)/xpcom/idl-parser \
-	  -I$(topsrcdir)/xpcom/typelib/xpt/tools \
-	  $(topsrcdir)/xpcom/idl-parser/typelib.py --cachedir=$(DEPTH)/xpcom/idl-parser $(XPIDL_FLAGS) $(_VPATH_SRCS) -d $(MDDEPDIR)/$(@F).pp -o $@
-
-# no need to link together if XPIDLSRCS contains only XPIDL_MODULE
-ifneq ($(XPIDL_MODULE).idl,$(strip $(XPIDLSRCS)))
-$(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS)) $(GLOBAL_DEPS)
-	$(XPIDL_LINK) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.xpt,$(XPIDLSRCS))
-endif # XPIDL_MODULE.xpt != XPIDLSRCS
-
-libs:: $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS1) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(FINAL_TARGET)/components
-ifndef NO_INTERFACES_MANIFEST
-	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/interfaces.manifest "interfaces $(XPIDL_MODULE).xpt"
-	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/interfaces.manifest"
-endif
-endif
-
-endif # NO_GEN_XPT
-
-GARBAGE_DIRS		+= $(XPIDL_GEN_DIR)
-
-endif # XPIDLSRCS
-
-ifneq ($(XPIDLSRCS),)
-# export .idl files to $(IDL_DIR)
-ifndef NO_DIST_INSTALL
-export:: $(XPIDLSRCS) $(IDL_DIR)
-	$(INSTALL) $(IFLAGS1) $^
-
-export:: $(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS)) $(DIST)/include
-	$(INSTALL) $(IFLAGS1) $^
-endif # NO_DIST_INSTALL
-
-endif # XPIDLSRCS
-
-
-
-# General rules for exporting idl files.
-$(IDL_DIR):
-	$(NSINSTALL) -D $@
-
-export-idl:: $(SUBMAKEFILES) $(MAKE_DIRS)
-
-ifneq ($(XPIDLSRCS),)
-ifndef NO_DIST_INSTALL
-export-idl:: $(XPIDLSRCS) $(IDL_DIR)
-	$(INSTALL) $(IFLAGS1) $^
-endif
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-################################################################################
-# Copy each element of EXTRA_COMPONENTS to $(FINAL_TARGET)/components
-ifneq (,$(filter %.js,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS)))
-ifeq (,$(filter %.manifest,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS)))
-ifndef NO_JS_MANIFEST
-$(error .js component without matching .manifest. See https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_2.0)
-endif
-endif
-endif
-
-ifdef EXTRA_COMPONENTS
-libs:: $(EXTRA_COMPONENTS)
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/components
-endif
-
-endif
-
-ifdef EXTRA_PP_COMPONENTS
-libs:: $(EXTRA_PP_COMPONENTS)
-ifndef NO_DIST_INSTALL
-	$(EXIT_ON_ERROR) \
-	$(NSINSTALL) -D $(FINAL_TARGET)/components; \
-	for i in $^; do \
-	  fname=`basename $$i`; \
-	  dest=$(FINAL_TARGET)/components/$${fname}; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
-	done
-endif
-endif
-
-EXTRA_MANIFESTS = $(filter %.manifest,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS))
-ifneq (,$(EXTRA_MANIFESTS))
-libs::
-	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest $(patsubst %,"manifest components/%",$(notdir $(EXTRA_MANIFESTS)))
-endif
-
-################################################################################
-# Copy each element of EXTRA_JS_MODULES to $(FINAL_TARGET)/modules
-ifdef EXTRA_JS_MODULES
-libs:: $(EXTRA_JS_MODULES)
-ifndef NO_DIST_INSTALL
-	$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/modules
-endif
-
-endif
-
-ifdef EXTRA_PP_JS_MODULES
-libs:: $(EXTRA_PP_JS_MODULES)
-ifndef NO_DIST_INSTALL
-	$(EXIT_ON_ERROR) \
-	$(NSINSTALL) -D $(FINAL_TARGET)/modules; \
-	for i in $^; do \
-	  dest=$(FINAL_TARGET)/modules/`basename $$i`; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
-	done
-endif
-
-endif
-
-################################################################################
-# SDK
-
-ifneq (,$(SDK_LIBRARY))
-$(SDK_LIB_DIR)::
-	$(NSINSTALL) -D $@
-
-ifndef NO_DIST_INSTALL
-libs:: $(SDK_LIBRARY) $(SDK_LIB_DIR)
-	$(INSTALL) $(IFLAGS2) $^
-endif
-
-endif # SDK_LIBRARY
-
-ifneq (,$(strip $(SDK_BINARY)))
-$(SDK_BIN_DIR)::
-	$(NSINSTALL) -D $@
-
-ifndef NO_DIST_INSTALL
-libs:: $(SDK_BINARY) $(SDK_BIN_DIR)
-	$(INSTALL) $(IFLAGS2) $^
-endif
-
-endif # SDK_BINARY
-
-################################################################################
-# CHROME PACKAGING
-
-JAR_MANIFEST := $(srcdir)/jar.mn
-
-chrome::
-	$(MAKE) realchrome
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-$(FINAL_TARGET)/chrome:
-	$(NSINSTALL) -D $@
-
-ifneq (,$(wildcard $(JAR_MANIFEST)))
-ifndef NO_DIST_INSTALL
-libs realchrome:: $(CHROME_DEPS) $(FINAL_TARGET)/chrome
-	$(PYTHON) $(MOZILLA_DIR)/config/JarMaker.py \
-	  $(QUIET) -j $(FINAL_TARGET)/chrome \
-	  $(MAKE_JARS_FLAGS) $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
-	  $(JAR_MANIFEST)
-endif
-endif
-
-ifneq ($(DIST_FILES),)
-$(DIST)/bin:
-	$(NSINSTALL) -D $@
-
-libs:: $(DIST)/bin
-libs:: $(DIST_FILES)
-	@$(EXIT_ON_ERROR) \
-	for f in $^; do \
-	  dest=$(FINAL_TARGET)/`basename $$f`; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \
-	    $(XULAPP_DEFINES) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
-	    $$f > $$dest; \
-	done
-endif
-
-ifneq ($(DIST_CHROME_FILES),)
-libs:: $(DIST_CHROME_FILES)
-	@$(EXIT_ON_ERROR) \
-	for f in $^; do \
-	  dest=$(FINAL_TARGET)/chrome/`basename $$f`; \
-	  $(RM) -f $$dest; \
-	  $(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \
-	    $(XULAPP_DEFINES) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
-	    $$f > $$dest; \
-	done
-endif
-
-ifneq ($(XPI_PKGNAME),)
-libs realchrome::
-ifdef STRIP_XPI
-ifndef MOZ_DEBUG
-	@echo "Stripping $(XPI_PKGNAME) package directory..."
-	@echo $(FINAL_TARGET)
-	@cd $(FINAL_TARGET) && find . ! -type d \
-			! -name "*.js" \
-			! -name "*.xpt" \
-			! -name "*.gif" \
-			! -name "*.jpg" \
-			! -name "*.png" \
-			! -name "*.xpm" \
-			! -name "*.txt" \
-			! -name "*.rdf" \
-			! -name "*.sh" \
-			! -name "*.properties" \
-			! -name "*.dtd" \
-			! -name "*.html" \
-			! -name "*.xul" \
-			! -name "*.css" \
-			! -name "*.xml" \
-			! -name "*.jar" \
-			! -name "*.dat" \
-			! -name "*.tbl" \
-			! -name "*.src" \
-			! -name "*.reg" \
-			$(PLATFORM_EXCLUDE_LIST) \
-			-exec $(STRIP) $(STRIP_FLAGS) {} >/dev/null 2>&1 \;
-endif
-endif
-	@echo "Packaging $(XPI_PKGNAME).xpi..."
-	cd $(FINAL_TARGET) && $(ZIP) -qr ../$(XPI_PKGNAME).xpi *
-endif
-
-ifdef INSTALL_EXTENSION_ID
-ifndef XPI_NAME
-$(error XPI_NAME must be set for INSTALL_EXTENSION_ID)
-endif
-
-libs::
-	$(RM) -r "$(DIST)/bin/extensions/$(INSTALL_EXTENSION_ID)"
-	$(NSINSTALL) -D "$(DIST)/bin/extensions/$(INSTALL_EXTENSION_ID)"
-	cd $(FINAL_TARGET) && tar $(TAR_CREATE_FLAGS) - . | (cd "../../bin/extensions/$(INSTALL_EXTENSION_ID)" && tar -xf -)
-
-endif
-
-ifneq (,$(filter flat symlink,$(MOZ_CHROME_FILE_FORMAT)))
-_JAR_REGCHROME_DISABLE_JAR=1
-else
-_JAR_REGCHROME_DISABLE_JAR=0
-endif
-
-REGCHROME = $(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/add-chrome.pl \
-	$(if $(filter gtk2,$(MOZ_WIDGET_TOOLKIT)),-x) \
-	$(if $(CROSS_COMPILE),-o $(OS_ARCH)) $(FINAL_TARGET)/chrome/installed-chrome.txt \
-	$(_JAR_REGCHROME_DISABLE_JAR)
-
-REGCHROME_INSTALL = $(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/add-chrome.pl \
-	$(if $(filter gtk2,$(MOZ_WIDGET_TOOLKIT)),-x) \
-	$(if $(CROSS_COMPILE),-o $(OS_ARCH)) $(DESTDIR)$(mozappdir)/chrome/installed-chrome.txt \
-	$(_JAR_REGCHROME_DISABLE_JAR)
-
-
-#############################################################################
-# Dependency system
-#############################################################################
-ifdef COMPILER_DEPEND
-depend::
-	@echo "$(MAKE): No need to run depend target.\
-			Using compiler-based depend." 1>&2
-ifeq ($(GNU_CC)$(GNU_CXX),)
-# Non-GNU compilers
-	@echo "`echo '$(MAKE):'|sed 's/./ /g'`"\
-	'(Compiler-based depend was turned on by "--enable-md".)' 1>&2
-else
-# GNU compilers
-	@space="`echo '$(MAKE): '|sed 's/./ /g'`";\
-	echo "$$space"'Since you are using a GNU compiler,\
-		it is on by default.' 1>&2; \
-	echo "$$space"'To turn it off, pass --disable-md to configure.' 1>&2
-endif
-
-else # ! COMPILER_DEPEND
-
-ifndef MOZ_AUTO_DEPS
-
-define MAKE_DEPS_NOAUTO
-	$(MKDEPEND) -w1024 -o'.$(OBJ_SUFFIX)' -f- $(DEFINES) $(ACDEFINES) $(INCLUDES) $< 2>/dev/null | sed -e "s|^[^ ]*/||" > $@
-endef
-
-$(MDDEPDIR)/%.pp: %.c
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_NOAUTO)
-
-$(MDDEPDIR)/%.pp: %.cpp
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_NOAUTO)
-
-$(MDDEPDIR)/%.pp: %.s
-	$(REPORT_BUILD)
-	@$(MAKE_DEPS_NOAUTO)
-
-ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
-depend:: $(SUBMAKEFILES) $(MAKE_DIRS) $(MDDEPFILES)
-else
-depend:: $(SUBMAKEFILES)
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-dependclean:: $(SUBMAKEFILES)
-	$(RM) $(MDDEPFILES)
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-
-endif # MOZ_AUTO_DEPS
-
-endif # COMPILER_DEPEND
-
-
-#############################################################################
-# MDDEPDIR is the subdirectory where all the dependency files are placed.
-#   This uses a make rule (instead of a macro) to support parallel
-#   builds (-jN). If this were done in the LOOP_OVER_DIRS macro, two
-#   processes could simultaneously try to create the same directory.
-#
-#   We use $(CURDIR) in the rule's target to ensure that we don't find
-#   a dependency directory in the source tree via VPATH (perhaps from
-#   a previous build in the source tree) and thus neglect to create a
-#   dependency directory in the object directory, where we really need
-#   it.
-
-$(CURDIR)/$(MDDEPDIR):
-	$(MKDIR) -p $@
-
-ifneq (,$(filter-out all chrome default export realchrome tools clean clobber clobber_all distclean realclean,$(MAKECMDGOALS)))
-ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
-MDDEPEND_FILES		:= $(strip $(wildcard $(MDDEPDIR)/*.pp))
-
-ifneq (,$(MDDEPEND_FILES))
-# The script mddepend.pl checks the dependencies and writes to stdout
-# one rule to force out-of-date objects. For example,
-#   foo.o boo.o: FORCE
-# The script has an advantage over including the *.pp files directly
-# because it handles the case when header files are removed from the build.
-# 'make' would complain that there is no way to build missing headers.
-ALL_PP_RESULTS = $(shell $(PERL) $(BUILD_TOOLS)/mddepend.pl - $(MDDEPEND_FILES))
-$(eval $(ALL_PP_RESULTS))
-endif
-
-endif
-endif
-#############################################################################
-
--include $(topsrcdir)/$(MOZ_BUILD_APP)/app-rules.mk
--include $(MY_RULES)
-
-#
-# Generate Emacs tags in a file named TAGS if ETAGS was set in $(MY_CONFIG)
-# or in $(MY_RULES)
-#
-ifdef ETAGS
-ifneq ($(CSRCS)$(CPPSRCS)$(HEADERS),)
-all:: TAGS
-TAGS:: $(CSRCS) $(CPPSRCS) $(HEADERS)
-	$(ETAGS) $(CSRCS) $(CPPSRCS) $(HEADERS)
-endif
-endif
-
-################################################################################
-# Special gmake rules.
-################################################################################
-
-
-#
-# Disallow parallel builds with MSVC < 8
-#
-ifneq (,$(filter 1200 1300 1310,$(_MSC_VER)))
-.NOTPARALLEL:
-endif
-
-#
-# Re-define the list of default suffixes, so gmake won't have to churn through
-# hundreds of built-in suffix rules for stuff we don't need.
-#
-.SUFFIXES:
-
-#
-# Fake targets.  Always run these rules, even if a file/directory with that
-# name already exists.
-#
-.PHONY: all alltags boot checkout chrome realchrome clean clobber clobber_all export install libs makefiles realclean run_apprunner tools $(DIRS) $(TOOL_DIRS) FORCE
-
-# Used as a dependency to force targets to rebuild
-FORCE:
-
-# Delete target if error occurs when building target
-.DELETE_ON_ERROR:
-
-# Properly set LIBPATTERNS for the platform
-.LIBPATTERNS = $(if $(IMPORT_LIB_SUFFIX),$(LIB_PREFIX)%.$(IMPORT_LIB_SUFFIX)) $(LIB_PREFIX)%.$(LIB_SUFFIX) $(DLL_PREFIX)%$(DLL_SUFFIX)
-
-tags: TAGS
-
-TAGS: $(SUBMAKEFILES) $(CSRCS) $(CPPSRCS) $(wildcard *.h)
-	-etags $(CSRCS) $(CPPSRCS) $(wildcard *.h)
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-
-echo-variable-%:
-	@echo "$($*)"
-
-echo-tiers:
-	@echo $(TIERS)
-
-echo-tier-dirs:
-	@$(foreach tier,$(TIERS),echo '$(tier):'; echo '  dirs: $(tier_$(tier)_dirs)'; echo '  staticdirs: $(tier_$(tier)_staticdirs)'; )
-
-echo-dirs:
-	@echo $(DIRS)
-
-echo-module:
-	@echo $(MODULE)
-
-echo-depth-path:
-	@$(topsrcdir)/build/unix/print-depth-path.sh
-
-echo-module-name:
-	@$(topsrcdir)/build/package/rpm/print-module-name.sh
-
-echo-module-filelist:
-	@$(topsrcdir)/build/package/rpm/print-module-filelist.sh
-
-showtargs:
-ifneq (,$(filter $(PROGRAM) $(HOST_PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY),$(TARGETS)))
-	@echo --------------------------------------------------------------------------------
-	@echo "PROGRAM             = $(PROGRAM)"
-	@echo "SIMPLE_PROGRAMS     = $(SIMPLE_PROGRAMS)"
-	@echo "LIBRARY             = $(LIBRARY)"
-	@echo "SHARED_LIBRARY      = $(SHARED_LIBRARY)"
-	@echo "SHARED_LIBRARY_LIBS = $(SHARED_LIBRARY_LIBS)"
-	@echo "LIBS                = $(LIBS)"
-	@echo "DEF_FILE            = $(DEF_FILE)"
-	@echo "IMPORT_LIBRARY      = $(IMPORT_LIBRARY)"
-	@echo "STATIC_LIBS         = $(STATIC_LIBS)"
-	@echo "SHARED_LIBS         = $(SHARED_LIBS)"
-	@echo "EXTRA_DSO_LIBS      = $(EXTRA_DSO_LIBS)"
-	@echo "EXTRA_DSO_LDOPTS    = $(EXTRA_DSO_LDOPTS)"
-	@echo "DEPENDENT_LIBS      = $(DEPENDENT_LIBS)"
-	@echo --------------------------------------------------------------------------------
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-
-showbuild:
-	@echo "MOZ_BUILD_ROOT     = $(MOZ_BUILD_ROOT)"
-	@echo "MOZ_WIDGET_TOOLKIT = $(MOZ_WIDGET_TOOLKIT)"
-	@echo "CC                 = $(CC)"
-	@echo "CXX                = $(CXX)"
-	@echo "CCC                = $(CCC)"
-	@echo "CPP                = $(CPP)"
-	@echo "LD                 = $(LD)"
-	@echo "AR                 = $(AR)"
-	@echo "IMPLIB             = $(IMPLIB)"
-	@echo "FILTER             = $(FILTER)"
-	@echo "MKSHLIB            = $(MKSHLIB)"
-	@echo "MKCSHLIB           = $(MKCSHLIB)"
-	@echo "RC                 = $(RC)"
-	@echo "MC                 = $(MC)"
-	@echo "CFLAGS             = $(CFLAGS)"
-	@echo "OS_CFLAGS          = $(OS_CFLAGS)"
-	@echo "COMPILE_CFLAGS     = $(COMPILE_CFLAGS)"
-	@echo "CXXFLAGS           = $(CXXFLAGS)"
-	@echo "OS_CXXFLAGS        = $(OS_CXXFLAGS)"
-	@echo "COMPILE_CXXFLAGS   = $(COMPILE_CXXFLAGS)"
-	@echo "COMPILE_CMFLAGS    = $(COMPILE_CMFLAGS)"
-	@echo "COMPILE_CMMFLAGS   = $(COMPILE_CMMFLAGS)"
-	@echo "LDFLAGS            = $(LDFLAGS)"
-	@echo "OS_LDFLAGS         = $(OS_LDFLAGS)"
-	@echo "DSO_LDOPTS         = $(DSO_LDOPTS)"
-	@echo "OS_INCLUDES        = $(OS_INCLUDES)"
-	@echo "OS_LIBS            = $(OS_LIBS)"
-	@echo "EXTRA_LIBS         = $(EXTRA_LIBS)"
-	@echo "BIN_FLAGS          = $(BIN_FLAGS)"
-	@echo "INCLUDES           = $(INCLUDES)"
-	@echo "DEFINES            = $(DEFINES)"
-	@echo "ACDEFINES          = $(ACDEFINES)"
-	@echo "BIN_SUFFIX         = $(BIN_SUFFIX)"
-	@echo "LIB_SUFFIX         = $(LIB_SUFFIX)"
-	@echo "DLL_SUFFIX         = $(DLL_SUFFIX)"
-	@echo "IMPORT_LIB_SUFFIX  = $(IMPORT_LIB_SUFFIX)"
-	@echo "INSTALL            = $(INSTALL)"
-	@echo "VPATH              = $(VPATH)"
-
-showhost:
-	@echo "HOST_CC            = $(HOST_CC)"
-	@echo "HOST_CXX           = $(HOST_CXX)"
-	@echo "HOST_CFLAGS        = $(HOST_CFLAGS)"
-	@echo "HOST_LDFLAGS       = $(HOST_LDFLAGS)"
-	@echo "HOST_LIBS          = $(HOST_LIBS)"
-	@echo "HOST_EXTRA_LIBS    = $(HOST_EXTRA_LIBS)"
-	@echo "HOST_EXTRA_DEPS    = $(HOST_EXTRA_DEPS)"
-	@echo "HOST_PROGRAM       = $(HOST_PROGRAM)"
-	@echo "HOST_OBJS          = $(HOST_OBJS)"
-	@echo "HOST_PROGOBJS      = $(HOST_PROGOBJS)"
-	@echo "HOST_LIBRARY       = $(HOST_LIBRARY)"
-
-showbuildmods::
-	@echo "Module dirs	= $(BUILD_MODULE_DIRS)"
-
-documentation:
-	@cd $(DEPTH)
-	$(DOXYGEN) $(DEPTH)/config/doxygen.cfg
-
-ifdef ENABLE_TESTS
-check:: $(SUBMAKEFILES) $(MAKE_DIRS)
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-	$(LOOP_OVER_TOOL_DIRS)
-endif
-
-
-FREEZE_VARIABLES = \
-  CSRCS \
-  CPPSRCS \
-  EXPORTS \
-  XPIDLSRCS \
-  DIRS \
-  LIBRARY \
-  MODULE \
-  SHORT_LIBNAME \
-  TIERS \
-  EXTRA_COMPONENTS \
-  EXTRA_PP_COMPONENTS \
-  $(NULL)
-
-$(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
-
-CHECK_FROZEN_VARIABLES = $(foreach var,$(FREEZE_VARIABLES), \
-  $(if $(subst $($(var)_FROZEN),,'$($(var))'),$(error Makefile variable '$(var)' changed value after including rules.mk. Was $($(var)_FROZEN), now $($(var)).)))
-
-libs export libs::
-	$(CHECK_FROZEN_VARIABLES)
-
-default all::
-	if test -d $(DIST)/bin ; then touch $(DIST)/bin/.purgecaches ; fi
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/collections/bug-743101.js
@@ -0,0 +1,5 @@
+load(libdir + "asserts.js");
+
+var g = newGlobal('new-compartment');
+assertThrowsInstanceOf(function () { Map.prototype.size.apply(g, []); }, g.TypeError);
+assertThrowsInstanceOf(function () { Set.prototype.size.apply(g, []); }, g.TypeError);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-01.js
@@ -0,0 +1,14 @@
+// Environment.prototype.getVariable does not see variables bound in enclosing scopes.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+dbg.onDebuggerStatement = function (frame) {
+    assertEq(frame.environment.getVariable("x"), 13);
+    assertEq(frame.environment.getVariable("k"), undefined);
+    assertEq(frame.environment.find("k").getVariable("k"), 3);
+    hits++;
+};
+g.eval("var k = 3; function f(x) { debugger; }");
+g.f(13);
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-02.js
@@ -0,0 +1,16 @@
+// getVariable works in function scopes.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+dbg.onDebuggerStatement = function (frame) {
+    assertEq(frame.environment.getVariable("a"), 1);
+    assertEq(frame.environment.getVariable("b"), 2);
+    assertEq(frame.environment.getVariable("c"), 3);
+    assertEq(frame.environment.getVariable("d"), 4);
+    assertEq(frame.environment.getVariable("e"), 5);
+    hits++;
+};
+g.eval("function f(a, [b, c]) { var d = c + 1; let e = d + 1; debugger; }");
+g.f(1, [2, 3]);
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-03.js
@@ -0,0 +1,22 @@
+// getVariable sees bindings in let-block scopes.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var log = '';
+dbg.onDebuggerStatement = function (frame) {
+    log += frame.environment.getVariable("x");
+};
+g.eval("function f() {\n" +
+       "    let x = 'a';\n" +
+       "    debugger;\n" +
+       "    for (let x = 0; x < 2; x++)\n" + 
+       "        if (x === 0)\n" +
+       "            debugger;\n" +
+       "        else {\n" +
+       "            let x = 'b'; debugger;\n" +
+       "        }\n" +
+       "}\n");
+g.f();
+g.eval("let (x = 'c') { debugger; }");
+g.eval("{ let x = 'd'; debugger; }");
+assertEq(log, 'a0bcd');
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-04.js
@@ -0,0 +1,12 @@
+// getVariable sees variables in function scopes added by non-strict direct eval.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var v;
+dbg.onDebuggerStatement = function (frame) {
+    v = frame.environment.getVariable("x");
+};
+
+g.eval("function f(s) { eval(s); debugger; }");
+g.f("var x = 'Q';");
+assertEq(v, 'Q');
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-05.js
@@ -0,0 +1,10 @@
+// getVariable sees global variables.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var log = '';
+dbg.onDebuggerStatement = function (frame) {
+    log += frame.environment.getVariable("x") + frame.environment.getVariable("y");
+};
+g.eval("var x = 'a'; this.y = 'b'; debugger;");
+assertEq(log, 'ab');
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-06.js
@@ -0,0 +1,12 @@
+// getVariable sees properties inherited from the global object's prototype chain.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var log = '';
+dbg.onDebuggerStatement = function (frame) {
+    log += frame.environment.getVariable("x") + frame.environment.getVariable("y");
+};
+g.eval("Object.getPrototypeOf(this).x = 'a';\n" +
+       "Object.prototype.y = 'b';\n" +
+       "debugger;\n");
+assertEq(log, 'ab');
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-07.js
@@ -0,0 +1,10 @@
+// getVariable can get properties from with-block scopes.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var v;
+dbg.onDebuggerStatement = function (frame) {
+    v = frame.environment.getVariable("x");
+};
+g.eval("var x = 1; { let x = 2; with ({x: 3}) { debugger; } }");
+assertEq(v, 3);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-08.js
@@ -0,0 +1,10 @@
+// getVariable sees properties inherited from a with-object's prototype chain.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var v;
+dbg.onDebuggerStatement = function (frame) {
+    v = frame.environment.getVariable("x");
+};
+g.eval("var x = 1; { let x = 2; with (Object.create({x: 3})) { debugger; } }");
+assertEq(v, 3);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-09.js
@@ -0,0 +1,13 @@
+// getVariable works on ancestors of frame.environment.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var log = '';
+dbg.onDebuggerStatement = function (frame) {
+    for (var env = frame.environment; env; env = env.parent) {
+        if (env.find("x") === env)
+            log += env.getVariable("x");
+    }
+};
+g.eval("var x = 1; { let x = 2; with (Object.create({x: 3})) { debugger; } }");
+assertEq(log, "321");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-10.js
@@ -0,0 +1,27 @@
+// getVariable works on a heavyweight environment after control leaves its scope.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var envs = [];
+dbg.onDebuggerStatement = function (frame) {
+    envs.push(frame.environment);
+};
+g.eval("var f;\n" +
+       "for (var x = 0; x < 3; x++) {\n" +
+       "    (function (x) {\n" +
+       "        for (var y = 0; y < 3; y++) {\n" +
+       "            (function (z) {\n" +
+       "                eval(z); // force heavyweight\n" +
+       "                debugger;\n" +
+       "            })(x + y);\n" +
+       "        }\n" +
+       "    })(x);\n" +
+       "}");
+
+var i = 0;
+for (var x = 0; x < 3; x++) {
+    for (var y = 0; y < 3; y++) {
+        var e = envs[i++];
+        assertEq(e.getVariable("z"), x + y);
+    }
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-11.js
@@ -0,0 +1,15 @@
+// The value returned by getVariable can be a Debugger.Object.
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+var hits = 0;
+dbg.onDebuggerStatement = function (frame) {
+    var a = frame.environment.getVariable('Math');
+    assertEq(a instanceof Debugger.Object, true);
+    var b = gw.getOwnPropertyDescriptor('Math').value;
+    assertEq(a, b);
+    hits++;
+};
+g.eval("debugger;");
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-getVariable-WouldRun.js
@@ -0,0 +1,17 @@
+// getVariable that would trigger a getter does not crash or explode.
+// It should throw WouldRunDebuggee, but that isn't implemented yet.
+
+load(libdir + "asserts.js");
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+dbg.onDebuggerStatement = function (frame) {
+    assertThrowsInstanceOf(function () {
+        frame.environment.getVariable("x");
+    }, Error);
+    hits++;
+};
+g.eval("Object.defineProperty(this, 'x', {get: function () { throw new Error('fail'); }});\n" +
+       "debugger;");
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-01.js
@@ -0,0 +1,9 @@
+// Environment.prototype.setVariable can set global variables.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+    frame.environment.setVariable("x", 2);
+};
+g.eval("var x = 1; debugger;");
+assertEq(g.x, 2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-02.js
@@ -0,0 +1,10 @@
+// The argument to setVariable can be a Debugger.Object.
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+dbg.onDebuggerStatement = function (frame) {
+    frame.environment.setVariable("x", gw);
+};
+g.eval("var x = 1; debugger;");
+assertEq(g.x, g);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-03.js
@@ -0,0 +1,16 @@
+// setVariable cannot create new global variables.
+// (Other kinds of environment are tested in Environment-variables.js.)
+
+load(libdir + "asserts.js");
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger(g);
+var hits = 0;
+dbg.onDebuggerStatement = function (frame) {
+    assertThrowsInstanceOf(function () { frame.environment.setVariable("x", 7); }, TypeError);
+    hits++;
+};
+g.eval("debugger");
+assertEq("x" in g, false);
+assertEq(hits, 1);
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-04.js
@@ -0,0 +1,10 @@
+// setVariable can set variables and arguments in functions.
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+    frame.environment.setVariable("a", 100);
+    frame.environment.setVariable("b", 200);
+};
+g.eval("function f(a) { var b = a + 1; debugger; return a + b; }");
+assertEq(g.f(1), 300);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-05.js
@@ -0,0 +1,14 @@
+// setVariable can change the types of variables and arguments in functions.
+
+var g = newGlobal('new-compartment');
+g.eval("function f(a) { var b = a + 1; debugger; return a + b; }");
+for (var i = 0; i < 20; i++)
+    assertEq(g.f(i), 2 * i + 1);
+
+var dbg = new Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+    frame.environment.setVariable("a", "xyz");
+    frame.environment.setVariable("b", "zy");
+};
+for (var i = 0; i < 10; i++)
+    assertEq(g.f(i), "xyzzy");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-06.js
@@ -0,0 +1,9 @@
+// setVariable on an argument works as expected with non-strict 'arguments'.
+
+var g = newGlobal('new-compartment');
+g.eval("function f(a) { debugger; return arguments[0]; }");
+var dbg = new Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+    frame.environment.setVariable("a", 2);
+};
+assertEq(g.f(1), 2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-07.js
@@ -0,0 +1,15 @@
+// setVariable works on let-bindings.
+
+var g = newGlobal('new-compartment');
+function test(code, val) {
+    g.eval("function f() { " + code + " }");
+    var dbg = new Debugger(g);
+    dbg.onDebuggerStatement = function (frame) {
+        frame.environment.setVariable("a", val);
+    };
+    assertEq(g.f(), val);
+}
+
+test("let a = 1; debugger; return a;", "xyzzy");
+test("{ let a = 1; debugger; return a; }", "plugh");
+test("let (a = 1) { debugger; return a; }", "wcgr");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-08.js
@@ -0,0 +1,29 @@
+// setVariable throws if no binding exists.
+
+load(libdir + "asserts.js");
+
+function test(code) {
+    var g = newGlobal('new-compartment');
+    var dbg = new Debugger(g);
+    var hits = 0;
+    dbg.onDebuggerStatement = function (frame) {
+        var env = frame.older.environment;
+        assertThrowsInstanceOf(function () { env.setVariable("y", 2); }, Error);
+        hits++;
+    };
+    g.eval("var y = 0; function d() { debugger; }");
+
+    assertEq(g.eval(code), 0);
+
+    assertEq(g.y, 0);
+    assertEq(hits, 1);
+}
+
+// local scope of non-heavyweight function
+test("function f() { var x = 1; d(); return y; }  f();");
+
+// block scope
+test("function h(x) { if (x) { let x = 1; d(); return y; } }  h(3);");
+
+// strict eval scope
+test("'use strict'; eval('d(); y;');");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-10.js
@@ -0,0 +1,32 @@
+// setVariable works on non-innermost environments.
+
+// (The debuggee code here is a bit convoluted to defeat optimizations that
+// could make obj.b a null closure or obj.i a flat closure--that is, a function
+// that gets a frozen copy of i instead of a reference to the runtime
+// environment that contains it. setVariable does not currently detect this
+// flat closure case.)
+
+var g = newGlobal('new-compartment');
+g.eval("function d() { debugger; }\n" +
+       "var i = 'FAIL';\n" +
+       "function a() {\n" +
+       "    var obj = {b: function (i) { d(obj); return i; },\n" +
+       "               i: function () { return i; }};\n" +
+       "    var i = 'FAIL2';\n" +
+       "    return obj;\n" +
+       "}\n");
+
+var dbg = Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+    var x = 0;
+    for (var env = frame.older.environment; env; env = env.parent) {
+        if (env.getVariable("i") !== undefined)
+            env.setVariable("i", x++);
+    }
+};
+
+var obj = g.a();
+var r = obj.b('FAIL3');
+assertEq(r, 0);
+assertEq(obj.i(), 1);
+assertEq(g.i, 2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-11.js
@@ -0,0 +1,16 @@
+// setVariable cannot modify the binding for a FunctionExpression's name.
+
+load(libdir + "asserts.js");
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+var hits = 0;
+dbg.onDebuggerStatement = function (frame) {
+    var env = frame.environment.find("f");
+    assertEq(env.getVariable("f"), frame.callee);
+    assertThrowsInstanceOf(function () { env.setVariable("f", 0) }, TypeError);
+    assertThrowsInstanceOf(function () { env.setVariable("f", frame.callee) }, TypeError);
+    hits++;
+};
+g.eval("(function f() { debugger; })();");
+assertEq(hits, 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-12.js
@@ -0,0 +1,21 @@
+// setVariable can create a new property on a with block's bindings object, if
+// it is shadowing an existing property on the prototype chain.
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger(g);
+dbg.onDebuggerStatement = function (frame) {
+    var env = frame.environment.find("x");
+    env.setVariable("x", 2);
+};
+g.eval("var obj1 = {x: 1}, obj2 = Object.create(obj1), z; with (obj2) { debugger; z = x; }");
+assertEq(g.obj1.x, 1);
+assertEq(g.obj2.x, 2);
+assertEq(g.z, 2);
+
+// The property created by setVariable is like the one created by ordinary
+// assignment in a with-block.
+var desc = Object.getOwnPropertyDescriptor(g.obj2, "x");
+assertEq(desc.configurable, true);
+assertEq(desc.enumerable, true);
+assertEq(desc.writable, true);
+assertEq(desc.value, 2);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-setVariable-WouldRun.js
@@ -0,0 +1,22 @@
+// setVariable triggering a setter doesn't crash or explode.
+// It should throw WouldRunDebuggee, but that isn't implemented yet.
+
+function test(code) {
+    var g = newGlobal('new-compartment');
+    g.eval("function d() { debugger; }");
+    var dbg = Debugger(g);
+    var hits = 0;
+    dbg.onDebuggerStatement = function (frame) {
+        var env = frame.environment.find("x");
+        try {
+            env.setVariable("x", 0);
+        } catch (exc) {
+        }
+        hits++;
+    };
+    g.eval(code);
+}
+
+test("Object.defineProperty(this, 'x', {set: function (v) {}}); d();");
+test("Object.defineProperty(Object.prototype, 'x', {set: function (v) {}}); d();");
+test("with ({set x(v) {}}) eval(d());");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Environment-variables.js
@@ -0,0 +1,92 @@
+// Comprehensive test of get/setVariable on many kinds of environments and
+// bindings.
+
+load(libdir + "asserts.js");
+
+var cases = [
+    // global bindings and bindings on the global prototype chain
+    "x = VAL; @@",
+    "var x = VAL; @@",
+    "Object.prototype.x = VAL; @@",
+
+    // let, catch, and comprehension bindings
+    "let x = VAL; @@",
+    "{ let x = VAL; @@ }",
+    "let (x = VAL) { @@ }",
+    "try { throw VAL; } catch (x) { @@ }",
+    "try { throw VAL; } catch (x) { @@ }",
+    "for (let x of [VAL]) { @@ }",
+    "for each (let x in [VAL]) { @@ }",
+    "switch (0) { default: let x = VAL; @@ }",
+    "[function () { @@ }() for (x of [VAL])];",
+    // "((function () { @@ })() for (x of [VAL])).next();",  // bug 709367
+
+    // arguments
+    "function f(x) { @@ } f(VAL);",
+    "function f([w, x]) { @@ } f([0, VAL]);",
+    "function f({v: x}) { @@ } f({v: VAL});",
+    "function f([w, {v: x}]) { @@ } f([0, {v: VAL}]);",
+
+    // bindings in functions
+    "function f() { var x = VAL; @@ } f();",
+    "function f() { let x = VAL; @@ } f();",
+    "function f([x]) { let x = VAL; @@ } f(['fail']);",
+    "function f(x) { { let x = VAL; @@ } } f('fail');",
+    "function f() { function x() {} x = VAL; @@ } f();",
+
+    // dynamic bindings
+    "function f(s) { eval(s); @@ } f('var x = VAL');",
+    "function f(s) { let (x = 'fail') { eval(s); } x = VAL; @@ } f('var x;');",
+    "var x = VAL; function f(s) { eval('var x = 0;'); eval(s); @@ } f('delete x;');",
+    "function f(obj) { with (obj) { @@ } } f({x: VAL});",
+    "function f(obj) { with (obj) { @@ } } f(Object.create({x: VAL}));",
+    "function f(b) { if (b) { function x(){} } x = VAL; @@ } f(1);",
+];
+
+var nextval = 1000;
+
+function test(code, debugStmts, followupStmts) {
+    var val = nextval++;
+    var hits = 0;
+
+    var g = newGlobal('new-compartment');
+    g.eval("function debugMe() { var x = 'wrong-x'; debugger; }");
+    g.capture = null;
+
+    var dbg = Debugger(g);
+    dbg.onDebuggerStatement = function (frame) {
+        if (frame.callee !== null && frame.callee.name == 'debugMe')
+            frame = frame.older;
+        var env = frame.environment.find("x");
+        assertEq(env.getVariable("x"), val)
+        assertEq(env.setVariable("x", 'ok'), undefined);
+        assertEq(env.getVariable("x"), 'ok');
+
+        // setVariable cannot create new variables.
+        assertThrowsInstanceOf(function () { env.setVariable("newVar", 0); }, TypeError);
+        hits++;
+    };
+
+    code = code.replace("@@", debugStmts);
+    if (followupStmts !== undefined)
+        code += " " + followupStmts;
+    code = code.replace(/VAL/g, uneval(val));
+    g.eval(code);
+    assertEq(hits, 1);
+}
+
+for (var s of cases) {
+    // Test triggering the debugger right in the scope in which x is bound.
+    test(s, "debugger; assertEq(x, 'ok');");
+
+    // Test calling a function that triggers the debugger.
+    test(s, "debugMe(); assertEq(x, 'ok');");
+
+    // Test triggering the debugger from a scope nested in x's scope.
+    test(s, "let (y = 'irrelevant') { (function (z) { let (zz = y) { debugger; }})(); } assertEq(x, 'ok');"),
+
+    // Test closing over the variable and triggering the debugger later, after
+    // leaving the variable's scope.
+    test(s, "capture = {dbg: function () { debugger; }, get x() { return x; }};",
+            "assertEq(capture.x, VAL); capture.dbg(); assertEq(capture.x, 'ok');");
+}
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -372,8 +372,10 @@ MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH
 MSG_DEF(JSMSG_DEBUG_NOT_SCRIPT_FRAME, 286, 0, JSEXN_ERR, "stack frame is not running JavaScript code")
 MSG_DEF(JSMSG_CANT_WATCH_PROP,        287, 0, JSEXN_TYPEERR, "properties whose names are objects can't be watched")
 MSG_DEF(JSMSG_CSP_BLOCKED_EVAL,       288, 0, JSEXN_ERR, "call to eval() blocked by CSP")
 MSG_DEF(JSMSG_DEBUG_NO_SCOPE_OBJECT,  289, 0, JSEXN_TYPEERR, "declarative Environments don't have binding objects")
 MSG_DEF(JSMSG_EMPTY_CONSEQUENT,       290, 0, JSEXN_SYNTAXERR, "mistyped ; after conditional?")
 MSG_DEF(JSMSG_NOT_ITERABLE,           291, 1, JSEXN_TYPEERR, "{0} is not iterable")
 MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL, 292, 0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'url' property")
 MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 293, 0, JSEXN_TYPEERR, "findScripts query object has 'innermost' property without both 'url' and 'line' properties")
+MSG_DEF(JSMSG_DEBUG_VARIABLE_NOT_FOUND, 294, 0, JSEXN_TYPEERR, "variable not found in environment")
+
--- a/js/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -33,17 +33,17 @@ wrap(JSContext *cx, JSObject *toWrap, JS
     if (!JS_WrapObject(cx, &wrapper))
         return NULL;
     return wrapper;
 }
 
 static JSObject *
 PreWrap(JSContext *cx, JSObject *scope, JSObject *obj, unsigned flags)
 {
-    JS_GC(cx);
+    JS_GC(JS_GetRuntime(cx));
     return obj;
 }
 
 static JSObject *
 Wrap(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, unsigned flags)
 {
     return js::Wrapper::New(cx, obj, proto, parent, &js::CrossCompartmentWrapper::singleton);
 }
--- a/js/src/jsapi-tests/testConservativeGC.cpp
+++ b/js/src/jsapi-tests/testConservativeGC.cpp
@@ -24,24 +24,24 @@ BEGIN_TEST(testConservativeGC)
 
     EVAL("String(Math.sqrt(3));", &tmp);
     CHECK(JSVAL_IS_STRING(tmp));
     JSString *str2 = JSVAL_TO_STRING(tmp);
     JSString str2Copy = *str2;
 
     tmp = JSVAL_NULL;
 
-    JS_GC(cx);
+    JS_GC(rt);
 
     EVAL("var a = [];\n"
          "for (var i = 0; i != 10000; ++i) {\n"
          "a.push(i + 0.1, [1, 2], String(Math.sqrt(i)), {a: i});\n"
          "}", &tmp);
 
-    JS_GC(cx);
+    JS_GC(rt);
 
     checkObjectFields((JSObject *)objCopy, JSVAL_TO_OBJECT(v2));
     CHECK(!memcmp(&strCopy, JSVAL_TO_STRING(v3), sizeof(strCopy)));
 
     checkObjectFields((JSObject *)obj2Copy, obj2);
     CHECK(!memcmp(&str2Copy, str2, sizeof(str2Copy)));
 
     return true;
@@ -64,15 +64,15 @@ BEGIN_TEST(testDerivedValues)
   static const jschar expected[] = { 'o', 'n', 'c', 'e' };
   const jschar *ch = JS_GetStringCharsZ(cx, str);
   str = NULL;
 
   /* Do a lot of allocation and collection. */
   for (int i = 0; i < 3; i++) {
     for (int j = 0; j < 1000; j++)
       JS_NewStringCopyZ(cx, "as I pondered weak and weary");
-    JS_GC(cx);
+    JS_GC(rt);
   }
 
   CHECK(!memcmp(ch, expected, sizeof(expected)));
   return true;
 }
 END_TEST(testDerivedValues)
--- a/js/src/jsapi-tests/testExternalStrings.cpp
+++ b/js/src/jsapi-tests/testExternalStrings.cpp
@@ -34,17 +34,17 @@ BEGIN_TEST(testExternalStrings)
     for (unsigned i = 0; i < N; ++i) {
         CHECK(JS_NewExternalString(cx, arr, arrlen, &finalizer1));
         CHECK(JS_NewExternalString(cx, arr, arrlen, &finalizer2));
     }
 
     // clear that newborn root
     JS_NewUCStringCopyN(cx, arr, arrlen);
 
-    JS_GC(cx);
+    JS_GC(rt);
 
     // a generous fudge factor to account for strings rooted by conservative gc
     const unsigned epsilon = 10;
 
     CHECK((N - finalized1) < epsilon);
     CHECK((N - finalized2) < epsilon);
 
     return true;
--- a/js/src/jsapi-tests/testGCOutOfMemory.cpp
+++ b/js/src/jsapi-tests/testGCOutOfMemory.cpp
@@ -32,17 +32,17 @@ BEGIN_TEST(testGCOutOfMemory)
         "})();";
     JSBool ok = JS_EvaluateScript(cx, global, source, strlen(source), "", 1,
                                   root.addr());
 
     /* Check that we get OOM. */
     CHECK(!ok);
     CHECK(!JS_IsExceptionPending(cx));
     CHECK_EQUAL(errorCount, 1);
-    JS_GC(cx);
+    JS_GC(rt);
     EVAL("(function() {"
          "    var array = [];"
          "    for (var i = max >> 2; i != 0;) {"
          "        --i;"
          "        array.push({});"
          "    }"
          "})();", root.addr());
     CHECK_EQUAL(errorCount, 1);
--- a/js/src/jsapi-tests/testIntern.cpp
+++ b/js/src/jsapi-tests/testIntern.cpp
@@ -31,13 +31,13 @@ FinalizeCallback(JSFreeOp *fop, JSFinali
 }
 
 BEGIN_TEST(testInternAcrossGC)
 {
     sw.str = JS_InternString(cx, "wrapped chars that another test shouldn't be using");
     sw.strOk = false;
     CHECK(sw.str);
     JS_SetFinalizeCallback(rt, FinalizeCallback);
-    JS_GC(cx);
+    JS_GC(rt);
     CHECK(sw.strOk);
     return true;
 }
 END_TEST(testInternAcrossGC)
--- a/js/src/jsapi-tests/testScriptObject.cpp
+++ b/js/src/jsapi-tests/testScriptObject.cpp
@@ -14,17 +14,17 @@ struct ScriptObjectFixture : public JSAP
         for (int i = 0; i < code_size; i++)
             uc_code[i] = code[i];
     }
 
     bool tryScript(JSScript *script)
     {
         CHECK(script);
 
-        JS_GC(cx);
+        JS_GC(rt);
 
         /* After a garbage collection, the script should still work. */
         jsval result;
         CHECK(JS_ExecuteScript(cx, global, script, &result));
 
         return true;
     }
 };
--- a/js/src/jsapi-tests/testTrap.cpp
+++ b/js/src/jsapi-tests/testTrap.cpp
@@ -6,17 +6,17 @@
 #include "jsdbgapi.h"
 
 static int emptyTrapCallCount = 0;
 
 static JSTrapStatus
 EmptyTrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
                  jsval closure)
 {
-    JS_GC(cx);
+    JS_GC(JS_GetRuntime(cx));
     if (JSVAL_IS_STRING(closure))
         ++emptyTrapCallCount;
     return JSTRAP_CONTINUE;
 }
 
 BEGIN_TEST(testTrap_gc)
 {
     static const char source[] =
@@ -54,25 +54,25 @@ BEGIN_TEST(testTrap_gc)
         jsbytecode *line6 = JS_LineNumberToPC(cx, script, 5);
         CHECK(line2);
 
         trapClosure = JS_NewStringCopyZ(cx, trapClosureText);
         CHECK(trapClosure);
         JS_SetTrap(cx, script, line2, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
         JS_SetTrap(cx, script, line6, EmptyTrapHandler, STRING_TO_JSVAL(trapClosure));
 
-        JS_GC(cx);
+        JS_GC(rt);
 
         CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
     }
 
     // execute
     CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
     CHECK_EQUAL(emptyTrapCallCount, 11);
 
-    JS_GC(cx);
+    JS_GC(rt);
 
     CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
 
     return true;
 }
 END_TEST(testTrap_gc)
 
--- a/js/src/jsapi-tests/testXDR.cpp
+++ b/js/src/jsapi-tests/testXDR.cpp
@@ -197,17 +197,17 @@ BEGIN_TEST(testXDR_bug506491)
     script = FreezeThaw(cx, script);
     CHECK(script);
 
     // execute
     jsvalRoot v2(cx);
     CHECK(JS_ExecuteScript(cx, global, script, v2.addr()));
 
     // try to break the Block object that is the parent of f
-    JS_GC(cx);
+    JS_GC(rt);
 
     // confirm
     EVAL("f() === 'ok';\n", v2.addr());
     jsvalRoot trueval(cx, JSVAL_TRUE);
     CHECK_SAME(v2, trueval);
     return true;
 }
 END_TEST(testXDR_bug506491)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1132,35 +1132,29 @@ JS_SetContextCallback(JSRuntime *rt, JSC
     old = rt->cxCallback;
     rt->cxCallback = cxCallback;
     return old;
 }
 
 JS_PUBLIC_API(JSContext *)
 JS_NewContext(JSRuntime *rt, size_t stackChunkSize)
 {
-    return js_NewContext(rt, stackChunkSize);
+    return NewContext(rt, stackChunkSize);
 }
 
 JS_PUBLIC_API(void)
 JS_DestroyContext(JSContext *cx)
 {
-    js_DestroyContext(cx, JSDCM_FORCE_GC);
+    DestroyContext(cx, DCM_FORCE_GC);
 }
 
 JS_PUBLIC_API(void)
 JS_DestroyContextNoGC(JSContext *cx)
 {
-    js_DestroyContext(cx, JSDCM_NO_GC);
-}
-
-JS_PUBLIC_API(void)
-JS_DestroyContextMaybeGC(JSContext *cx)
-{
-    js_DestroyContext(cx, JSDCM_MAYBE_GC);
+    DestroyContext(cx, DCM_NO_GC);
 }
 
 JS_PUBLIC_API(void *)
 JS_GetContextPrivate(JSContext *cx)
 {
     return cx->data;
 }
 
@@ -2855,21 +2849,21 @@ JS_DumpHeap(JSRuntime *rt, FILE *fp, voi
 
 extern JS_PUBLIC_API(JSBool)
 JS_IsGCMarkingTracer(JSTracer *trc)
 {
     return IS_GC_MARKING_TRACER(trc);
 }
 
 JS_PUBLIC_API(void)
-JS_GC(JSContext *cx)
-{
-    AssertNoGC(cx);
-    PrepareForFullGC(cx->runtime);
-    GC(cx, GC_NORMAL, gcreason::API);
+JS_GC(JSRuntime *rt)
+{
+    AssertNoGC(rt);
+    PrepareForFullGC(rt);
+    GC(rt, GC_NORMAL, gcreason::API);
 }
 
 JS_PUBLIC_API(void)
 JS_MaybeGC(JSContext *cx)
 {
     MaybeGC(cx);
 }
 
@@ -2956,21 +2950,16 @@ JS_SetGCParameterForThread(JSContext *cx
 
 JS_PUBLIC_API(uint32_t)
 JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key)
 {
     JS_ASSERT(key == JSGC_MAX_CODE_CACHE_BYTES);
     return 0;
 }
 
-JS_PUBLIC_API(void)
-JS_FlushCaches(JSContext *cx)
-{
-}
-
 JS_PUBLIC_API(JSString *)
 JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
                      const JSStringFinalizer *fin)
 {
     AssertNoGC(cx);
     CHECK_REQUEST(cx);
     JSString *s = JSExternalString::new_(cx, chars, length, fin);
     Probes::createString(cx, s, length);
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2563,19 +2563,16 @@ extern JS_PUBLIC_API(JSContext *)
 JS_NewContext(JSRuntime *rt, size_t stackChunkSize);
 
 extern JS_PUBLIC_API(void)
 JS_DestroyContext(JSContext *cx);
 
 extern JS_PUBLIC_API(void)
 JS_DestroyContextNoGC(JSContext *cx);
 
-extern JS_PUBLIC_API(void)
-JS_DestroyContextMaybeGC(JSContext *cx);
-
 extern JS_PUBLIC_API(void *)
 JS_GetContextPrivate(JSContext *cx);
 
 extern JS_PUBLIC_API(void)
 JS_SetContextPrivate(JSContext *cx, void *data);
 
 extern JS_PUBLIC_API(void *)
 JS_GetSecondContextPrivate(JSContext *cx);
@@ -3153,22 +3150,16 @@ JS_DumpNamedRoots(JSRuntime *rt,
  * The root is pointed at by rp; if the root is unnamed, name is null; data is
  * supplied from the third parameter to JS_MapGCRoots.
  *
  * The map function should return JS_MAP_GCROOT_REMOVE to cause the currently
  * enumerated root to be removed.  To stop enumeration, set JS_MAP_GCROOT_STOP
  * in the return value.  To keep on mapping, return JS_MAP_GCROOT_NEXT.  These
  * constants are flags; you can OR them together.
  *
- * This function acquires and releases rt's GC lock around the mapping of the
- * roots table, so the map function should run to completion in as few cycles
- * as possible.  Of course, map cannot call JS_GC, JS_MaybeGC, JS_BeginRequest,
- * or any JS API entry point that acquires locks, without double-tripping or
- * deadlocking on the GC lock.
- *
  * The JSGCRootType parameter indicates whether rp is a pointer to a Value
  * (which is obtained by '(Value *)rp') or a pointer to a GC-thing pointer
  * (which is obtained by '(void **)rp').
  *
  * JS_MapGCRoots returns the count of roots that were successfully mapped.
  */
 #define JS_MAP_GCROOT_NEXT      0       /* continue mapping entries */
 #define JS_MAP_GCROOT_STOP      1       /* stop mapping entries */
@@ -3255,16 +3246,19 @@ typedef void
 
 struct JSTracer {
     JSRuntime           *runtime;
     JSTraceCallback     callback;
     JSTraceNamePrinter  debugPrinter;
     const void          *debugPrintArg;
     size_t              debugPrintIndex;
     JSBool              eagerlyTraceWeakMaps;
+#ifdef DEBUG
+    void                *realLocation;
+#endif
 };
 
 /*
  * The method to call on each reference to a traceable thing stored in a
  * particular JSObject or other runtime structure. With DEBUG defined the
  * caller before calling JS_CallTracer must initialize JSTracer fields
  * describing the reference using the macros below.
  */
@@ -3296,16 +3290,32 @@ JS_CallTracer(JSTracer *trc, void *thing
     JS_END_MACRO
 #else
 # define JS_SET_TRACING_DETAILS(trc, printer, arg, index)                     \
     JS_BEGIN_MACRO                                                            \
     JS_END_MACRO
 #endif
 
 /*
+ * Sets the real location for a marked reference, when passing the address
+ * directly is not feasable.
+ */
+#ifdef DEBUG
+# define JS_SET_TRACING_LOCATION(trc, location)                               \
+    JS_BEGIN_MACRO                                                            \
+        (trc)->realLocation = (location);                                     \
+    JS_END_MACRO
+#else
+# define JS_SET_TRACING_LOCATION(trc, location)                               \
+    JS_BEGIN_MACRO                                                            \
+    JS_END_MACRO
+#endif
+
+
+/*
  * Convenience macro to describe the argument of JS_CallTracer using C string
  * and index.
  */
 # define JS_SET_TRACING_INDEX(trc, name, index)                               \
     JS_SET_TRACING_DETAILS(trc, NULL, name, index)
 
 /*
  * Convenience macro to describe the argument of JS_CallTracer using C string.
@@ -3390,20 +3400,20 @@ JS_DumpHeap(JSRuntime *rt, FILE *fp, voi
             void *thingToFind, size_t maxDepth, void *thingToIgnore);
 
 #endif
 
 /*
  * Garbage collector API.
  */
 extern JS_PUBLIC_API(void)
-JS_GC(JSContext *cx);
+JS_GC(JSRuntime *rt);
 
 extern JS_PUBLIC_API(void)
-JS_CompartmentGC(JSContext *cx, JSCompartment *comp);
+JS_CompartmentGC(JSRuntime *rt, JSCompartment *comp);
 
 extern JS_PUBLIC_API(void)
 JS_MaybeGC(JSContext *cx);
 
 extern JS_PUBLIC_API(void)
 JS_SetGCCallback(JSRuntime *rt, JSGCCallback cb);
 
 extern JS_PUBLIC_API(void)
@@ -3469,25 +3479,16 @@ JS_GetGCParameter(JSRuntime *rt, JSGCPar
 
 extern JS_PUBLIC_API(void)
 JS_SetGCParameterForThread(JSContext *cx, JSGCParamKey key, uint32_t value);
 
 extern JS_PUBLIC_API(uint32_t)
 JS_GetGCParameterForThread(JSContext *cx, JSGCParamKey key);
 
 /*
- * Flush the code cache for the current thread. The operation might be
- * delayed if the cache cannot be flushed currently because native
- * code is currently executing.
- */
-
-extern JS_PUBLIC_API(void)
-JS_FlushCaches(JSContext *cx);
-
-/*
  * Create a new JSString whose chars member refers to external memory, i.e.,
  * memory requiring application-specific finalization.
  */
 extern JS_PUBLIC_API(JSString *)
 JS_NewExternalString(JSContext *cx, const jschar *chars, size_t length,
                      const JSStringFinalizer *fin);
 
 /*
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -497,42 +497,42 @@ js_DumpAtoms(JSContext *cx, FILE *fp)
 #endif
 #define TEMP_SIZE_LIMIT_LOG2    (TEMP_SIZE_START_LOG2 + NUM_TEMP_FREELISTS)
 
 #define TEMP_SIZE_START         JS_BIT(TEMP_SIZE_START_LOG2)
 #define TEMP_SIZE_LIMIT         JS_BIT(TEMP_SIZE_LIMIT_LOG2)
 
 JS_STATIC_ASSERT(TEMP_SIZE_START >= sizeof(JSHashTable));
 
+namespace js {
+
 void
-js_InitAtomMap(JSContext *cx, AtomIndexMap *indices, JSAtom **atoms)
+InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtrAtom *atoms)
 {
     if (indices->isMap()) {
         typedef AtomIndexMap::WordMap WordMap;
         const WordMap &wm = indices->asMap();
         for (WordMap::Range r = wm.all(); !r.empty(); r.popFront()) {
             JSAtom *atom = r.front().key;
             jsatomid index = r.front().value;
             JS_ASSERT(index < indices->count());
-            atoms[index] = atom;
+            atoms[index].init(atom);
         }
     } else {
         for (const AtomIndexMap::InlineElem *it = indices->asInline(), *end = indices->inlineEnd();
              it != end; ++it) {
             JSAtom *atom = it->key;
             if (!atom)
                 continue;
             JS_ASSERT(it->value < indices->count());
-            atoms[it->value] = atom;
+            atoms[it->value].init(atom);
         }
     }
 }
 
-namespace js {
-
 bool
 IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp)
 {
     JS_ASSERT(index > JSID_INT_MAX);
 
     jschar buf[UINT32_CHAR_BUFFER_LENGTH];
     RangedPtr<jschar> end(ArrayEnd(buf), buf, ArrayEnd(buf));
     RangedPtr<jschar> start = BackfillIndexInCharBuffer(index, end);
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -465,25 +465,25 @@ js_ValueToStringId(JSContext *cx, const 
 
 inline bool
 js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
                          jsid *idp);
 inline bool
 js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
                          jsid *idp, js::Value *vp);
 
+namespace js {
+
 /*
  * For all unmapped atoms recorded in al, add a mapping from the atom's index
  * to its address. map->length must already be set to the number of atoms in
  * the list and map->vector must point to pre-allocated memory.
  */
 extern void
-js_InitAtomMap(JSContext *cx, js::AtomIndexMap *indices, JSAtom **atoms);
-
-namespace js {
+InitAtomMap(JSContext *cx, AtomIndexMap *indices, HeapPtrAtom *atoms);
 
 template<XDRMode mode>
 bool
 XDRAtom(XDRState<mode> *xdr, JSAtom **atomp);
 
 } /* namespace js */
 
 #endif /* jsatom_h___ */
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -164,17 +164,17 @@ JSRuntime::createBumpPointerAllocator(JS
 
 JSScript *
 js_GetCurrentScript(JSContext *cx)
 {
     return cx->hasfp() ? cx->fp()->maybeScript() : NULL;
 }
 
 JSContext *
-js_NewContext(JSRuntime *rt, size_t stackChunkSize)
+js::NewContext(JSRuntime *rt, size_t stackChunkSize)
 {
     JS_AbortIfWrongThread(rt);
 
     JSContext *cx = OffTheBooks::new_<JSContext>(rt);
     if (!cx)
         return NULL;
 
     JS_ASSERT(cx->findVersion() == JSVERSION_DEFAULT);
@@ -193,112 +193,94 @@ js_NewContext(JSRuntime *rt, size_t stac
 
     js_InitRandom(cx);
 
     /*
      * If cx is the first context on this runtime, initialize well-known atoms,
      * keywords, numbers, and strings.  If one of these steps should fail, the
      * runtime will be left in a partially initialized state, with zeroes and
      * nulls stored in the default-initialized remainder of the struct.  We'll
-     * clean the runtime up under js_DestroyContext, because cx will be "last"
+     * clean the runtime up under DestroyContext, because cx will be "last"
      * as well as "first".
      */
     if (first) {
 #ifdef JS_THREADSAFE
         JS_BeginRequest(cx);
 #endif
         bool ok = rt->staticStrings.init(cx);
         if (ok)
             ok = InitCommonAtoms(cx);
 
 #ifdef JS_THREADSAFE
         JS_EndRequest(cx);
 #endif
         if (!ok) {
-            js_DestroyContext(cx, JSDCM_NEW_FAILED);
+            DestroyContext(cx, DCM_NEW_FAILED);
             return NULL;
         }
     }
 
     JSContextCallback cxCallback = rt->cxCallback;
     if (cxCallback && !cxCallback(cx, JSCONTEXT_NEW)) {
-        js_DestroyContext(cx, JSDCM_NEW_FAILED);
+        DestroyContext(cx, DCM_NEW_FAILED);
         return NULL;
     }
 
     return cx;
 }
 
 void
-js_DestroyContext(JSContext *cx, JSDestroyContextMode mode)
+js::DestroyContext(JSContext *cx, DestroyContextMode mode)
 {
     JSRuntime *rt = cx->runtime;
     JS_AbortIfWrongThread(rt);
 
     JS_ASSERT(!cx->enumerators);
 
 #ifdef JS_THREADSAFE
     JS_ASSERT(cx->outstandingRequests == 0);
 #endif
 
-    if (mode != JSDCM_NEW_FAILED) {
+    if (mode != DCM_NEW_FAILED) {
         if (JSContextCallback cxCallback = rt->cxCallback) {
             /*
              * JSCONTEXT_DESTROY callback is not allowed to fail and must
              * return true.
              */
-            DebugOnly<JSBool> callbackStatus = cxCallback(cx, JSCONTEXT_DESTROY);
-            JS_ASSERT(callbackStatus);
+            JS_ALWAYS_TRUE(cxCallback(cx, JSCONTEXT_DESTROY));
         }
     }
 
     JS_REMOVE_LINK(&cx->link);
     bool last = !rt->hasContexts();
     if (last) {
         JS_ASSERT(!rt->gcRunning);
 
-#ifdef JS_THREADSAFE
-        {
-            AutoLockGC lock(rt);
-            rt->gcHelperThread.waitBackgroundSweepEnd();
-        }
-#endif
-
         /*
          * Dump remaining type inference results first. This printing
          * depends on atoms still existing.
          */
         for (CompartmentsIter c(rt); !c.done(); c.next())
             c->types.print(cx, false);
 
         /* Unpin all common atoms before final GC. */
-        FinishCommonAtoms(cx->runtime);
+        FinishCommonAtoms(rt);
 
         /* Clear debugging state to remove GC roots. */
         for (CompartmentsIter c(rt); !c.done(); c.next())
-            c->clearTraps(cx);
+            c->clearTraps(rt->defaultFreeOp());
         JS_ClearAllWatchPoints(cx);
 
         PrepareForFullGC(rt);
-        GC(cx, GC_NORMAL, gcreason::LAST_CONTEXT);
-    } else if (mode == JSDCM_FORCE_GC) {
+        GC(rt, GC_NORMAL, gcreason::LAST_CONTEXT);
+    } else if (mode == DCM_FORCE_GC) {
         JS_ASSERT(!rt->gcRunning);
         PrepareForFullGC(rt);
-        GC(cx, GC_NORMAL, gcreason::DESTROY_CONTEXT);
-    } else if (mode == JSDCM_MAYBE_GC) {
-        JS_ASSERT(!rt->gcRunning);
-        JS_MaybeGC(cx);
+        GC(rt, GC_NORMAL, gcreason::DESTROY_CONTEXT);
     }
-
-#ifdef JS_THREADSAFE
-    {
-        AutoLockGC lock(rt);
-        rt->gcHelperThread.waitBackgroundSweepEnd();
-    }
-#endif
     Foreground::delete_(cx);
 }
 
 namespace js {
 
 bool
 AutoResolving::alreadyStartedSlow() const
 {
@@ -880,40 +862,24 @@ js_InvokeOperationCallback(JSContext *cx
     /*
      * Reset the callback counter first, then run GC and yield. If another
      * thread is racing us here we will accumulate another callback request
      * which will be serviced at the next opportunity.
      */
     JS_ATOMIC_SET(&rt->interrupt, 0);
 
     if (rt->gcIsNeeded)
-        GCSlice(cx, GC_NORMAL, rt->gcTriggerReason);
-
-#ifdef JS_THREADSAFE
-    /*
-     * We automatically yield the current context every time the operation
-     * callback is hit since we might be called as a result of an impending
-     * GC on another thread, which would deadlock if we do not yield.
-     * Operation callbacks are supposed to happen rarely (seconds, not
-     * milliseconds) so it is acceptable to yield at every callback.
-     *
-     * As the GC can be canceled before it does any request checks we yield
-     * even if rt->gcIsNeeded was true above. See bug 590533.
-     */
-    JS_YieldRequest(cx);
-#endif
-
-    JSOperationCallback cb = cx->operationCallback;
+        GCSlice(rt, GC_NORMAL, rt->gcTriggerReason);
 
     /*
      * Important: Additional callbacks can occur inside the callback handler
      * if it re-enters the JS engine. The embedding must ensure that the
      * callback is disconnected before attempting such re-entry.
      */
-
+    JSOperationCallback cb = cx->operationCallback;
     return !cb || cb(cx);
 }
 
 JSBool
 js_HandleExecutionInterrupt(JSContext *cx)
 {
     JSBool result = JS_TRUE;
     if (cx->runtime->interrupt)
@@ -985,19 +951,16 @@ JSContext::JSContext(JSRuntime *rt)
 #ifdef JS_METHODJIT
     methodJitEnabled(false),
 #endif
     inferenceEnabled(false),
 #ifdef MOZ_TRACE_JSCALLS
     functionCallback(NULL),
 #endif
     enumerators(NULL),
-#ifdef JS_THREADSAFE
-    gcBackgroundFree(NULL),
-#endif
     activeCompilations(0)
 #ifdef DEBUG
     , stackIterAssertionEnabled(true)
 #endif
 {
     PodZero(&link);
 #ifdef JSGC_ROOT_ANALYSIS
     PodArrayZero(thingGCRooters);
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -141,25 +141,18 @@ struct ConservativeGCData
      */
     uintptr_t           *nativeStackTop;
 
     union {
         jmp_buf         jmpbuf;
         uintptr_t       words[JS_HOWMANY(sizeof(jmp_buf), sizeof(uintptr_t))];
     } registerSnapshot;
 
-    /*
-     * Cycle collector uses this to communicate that the native stack of the
-     * GC thread should be scanned only if the thread have more than the given
-     * threshold of requests.
-     */
-    unsigned requestThreshold;
-
     ConservativeGCData()
-      : nativeStackTop(NULL), requestThreshold(0)
+      : nativeStackTop(NULL)
     {}
 
     ~ConservativeGCData() {
 #ifdef JS_THREADSAFE
         /*
          * The conservative GC scanner should be disabled when the thread leaves
          * the last request.
          */
@@ -178,16 +171,23 @@ struct ConservativeGCData
     }
 #endif
 
     bool hasStackToScan() const {
         return !!nativeStackTop;
     }
 };
 
+/*
+ * A FreeOp can do one thing: free memory. For convenience, it has delete_
+ * convenience methods that also call destructors.
+ *
+ * FreeOp is passed to finalizers and other sweep-phase hooks so that we do not
+ * need to pass a JSContext to those hooks.
+ */
 class FreeOp : public JSFreeOp {
     bool        shouldFreeLater_;
     bool        onBackgroundThread_;
 
   public:
     static FreeOp *get(JSFreeOp *fop) {
         return static_cast<FreeOp *>(fop);
     }
@@ -210,17 +210,17 @@ class FreeOp : public JSFreeOp {
     inline void free_(void* p);
 
     JS_DECLARE_DELETE_METHODS(free_, inline)
 
     static void staticAsserts() {
         /*
          * Check that JSFreeOp is the first base class for FreeOp and we can
          * reinterpret a pointer to JSFreeOp as a pointer to FreeOp without
-         * any offset adjustments. JSClass::freeOp <-> Class::freeOp depends
+         * any offset adjustments. JSClass::finalize <-> Class::finalize depends
          * on this.
          */
         JS_STATIC_ASSERT(offsetof(FreeOp, shouldFreeLater_) == sizeof(JSFreeOp));
     }
 };
 
 } /* namespace js */
 
@@ -1114,24 +1114,16 @@ struct JSContext : js::ContextFriendFiel
         return genStack.append(gen);
     }
 
     void leaveGenerator(JSGenerator *gen) {
         JS_ASSERT(genStack.back() == gen);
         genStack.popBack();
     }
 
-#ifdef JS_THREADSAFE
-    /*
-     * When non-null JSContext::free_ delegates the job to the background
-     * thread.
-     */
-    js::GCHelperThread *gcBackgroundFree;
-#endif
-
     inline void* malloc_(size_t bytes) {
         return runtime->malloc_(bytes, this);
     }
 
     inline void* mallocNoReport(size_t bytes) {
         JS_ASSERT(bytes != 0);
         return runtime->malloc_(bytes, NULL);
     }
@@ -1145,22 +1137,16 @@ struct JSContext : js::ContextFriendFiel
         return runtime->realloc_(p, bytes, this);
     }
 
     inline void* realloc_(void* p, size_t oldBytes, size_t newBytes) {
         return runtime->realloc_(p, oldBytes, newBytes, this);
     }
 
     inline void free_(void* p) {
-#ifdef JS_THREADSAFE
-        if (gcBackgroundFree) {
-            gcBackgroundFree->freeLater(p);
-            return;
-        }
-#endif
         runtime->free_(p);
     }
 
     JS_DECLARE_NEW_METHODS(malloc_, inline)
     JS_DECLARE_DELETE_METHODS(free_, inline)
 
     void purge();
 
@@ -1456,34 +1442,33 @@ public:
         return get();
     }
 
     JSContext *operator ->() const {
         return get();
     }
 };
 
-} /* namespace js */
-
 /*
  * Create and destroy functions for JSContext, which is manually allocated
  * and exclusively owned.
  */
 extern JSContext *
-js_NewContext(JSRuntime *rt, size_t stackChunkSize);
+NewContext(JSRuntime *rt, size_t stackChunkSize);
 
-typedef enum JSDestroyContextMode {
-    JSDCM_NO_GC,
-    JSDCM_MAYBE_GC,
-    JSDCM_FORCE_GC,
-    JSDCM_NEW_FAILED
-} JSDestroyContextMode;
+enum DestroyContextMode {
+    DCM_NO_GC,
+    DCM_FORCE_GC,
+    DCM_NEW_FAILED
+};
 
 extern void
-js_DestroyContext(JSContext *cx, JSDestroyContextMode mode);
+DestroyContext(JSContext *cx, DestroyContextMode mode);
+
+} /* namespace js */
 
 #ifdef va_start
 extern JSBool
 js_ReportErrorVA(JSContext *cx, unsigned flags, const char *format, va_list ap);
 
 extern JSBool
 js_ReportErrorNumberVA(JSContext *cx, unsigned flags, JSErrorCallback callback,
                        void *userRef, const unsigned errorNumber,
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -385,17 +385,17 @@ CallSetter(JSContext *cx, JSObject *obj,
     if (attrs & JSPROP_GETTER)
         return js_ReportGetterOnlyAssignment(cx);
 
     if (attrs & JSPROP_SHORTID)
         id = INT_TO_JSID(shortid);
     return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp);
 }
 
-static inline JSAtom **
+static inline HeapPtrAtom *
 FrameAtomBase(JSContext *cx, js::StackFrame *fp)
 {
     return fp->script()->atoms;
 }
 
 }  /* namespace js */
 
 inline JSVersion
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -741,32 +741,32 @@ JSCompartment::removeDebuggee(FreeOp *fo
     if (debuggees.empty()) {
         debugModeBits &= ~DebugFromJS;
         if (wasEnabled && !debugMode())
             updateForDebugMode(fop);
     }
 }
 
 void
-JSCompartment::clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSObject *handler)
+JSCompartment::clearBreakpointsIn(FreeOp *fop, js::Debugger *dbg, JSObject *handler)
 {
     for (gc::CellIter i(this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         JSScript *script = i.get<JSScript>();
         if (script->hasAnyBreakpointsOrStepMode())
-            script->clearBreakpointsIn(cx, dbg, handler);
+            script->clearBreakpointsIn(fop, dbg, handler);
     }
 }
 
 void
-JSCompartment::clearTraps(JSContext *cx)
+JSCompartment::clearTraps(FreeOp *fop)
 {
     for (gc::CellIter i(this, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
         JSScript *script = i.get<JSScript>();
         if (script->hasAnyBreakpointsOrStepMode())
-            script->clearTraps(cx->runtime->defaultFreeOp());
+            script->clearTraps(fop);
     }
 }
 
 void
 JSCompartment::sweepBreakpoints(FreeOp *fop)
 {
     if (JS_CLIST_IS_EMPTY(&rt->debuggerList))
         return;
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -450,18 +450,18 @@ struct JSCompartment
 
   public:
     js::GlobalObjectSet &getDebuggees() { return debuggees; }
     bool addDebuggee(JSContext *cx, js::GlobalObject *global);
     void removeDebuggee(js::FreeOp *fop, js::GlobalObject *global,
                         js::GlobalObjectSet::Enum *debuggeesEnum = NULL);
     bool setDebugModeFromC(JSContext *cx, bool b);
 
-    void clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSObject *handler);
-    void clearTraps(JSContext *cx);
+    void clearBreakpointsIn(js::FreeOp *fop, js::Debugger *dbg, JSObject *handler);
+    void clearTraps(js::FreeOp *fop);
 
   private:
     void sweepBreakpoints(js::FreeOp *fop);
 
   public:
     js::WatchpointMap *watchpointMap;
 };
 
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -226,17 +226,17 @@ JS_PUBLIC_API(void)
 JS_ClearScriptTraps(JSContext *cx, JSScript *script)
 {
     script->clearTraps(cx->runtime->defaultFreeOp());
 }
 
 JS_PUBLIC_API(void)
 JS_ClearAllTrapsForCompartment(JSContext *cx)
 {
-    cx->compartment->clearTraps(cx);
+    cx->compartment->clearTraps(cx->runtime->defaultFreeOp());
 }
 
 JS_PUBLIC_API(JSBool)
 JS_SetInterrupt(JSRuntime *rt, JSInterruptHook hook, void *closure)
 {
     rt->debugHooks.interruptHook = hook;
     rt->debugHooks.interruptHookData = closure;
     return JS_TRUE;
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -140,31 +140,31 @@ js::PrepareCompartmentForGC(JSCompartmen
 JS_FRIEND_API(void)
 js::PrepareForFullGC(JSRuntime *rt)
 {
     for (CompartmentsIter c(rt); !c.done(); c.next())
         c->scheduleGC();
 }
 
 JS_FRIEND_API(void)
-js::GCForReason(JSContext *cx, gcreason::Reason reason)
+js::GCForReason(JSRuntime *rt, gcreason::Reason reason)
 {
-    GC(cx, GC_NORMAL, reason);
+    GC(rt, GC_NORMAL, reason);
 }
 
 JS_FRIEND_API(void)
-js::ShrinkingGC(JSContext *cx, gcreason::Reason reason)
+js::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason)
 {
-    GC(cx, GC_SHRINK, reason);
+    GC(rt, GC_SHRINK, reason);
 }
 
 JS_FRIEND_API(void)
-js::IncrementalGC(JSContext *cx, gcreason::Reason reason)
+js::IncrementalGC(JSRuntime *rt, gcreason::Reason reason)
 {
-    GCSlice(cx, GC_NORMAL, reason);
+    GCSlice(rt, GC_NORMAL, reason);
 }
 
 JS_FRIEND_API(void)
 JS_ShrinkGCBuffers(JSRuntime *rt)
 {
     ShrinkGCBuffers(rt);
 }
 
@@ -649,36 +649,16 @@ GetOwnerThread(const JSContext *cx)
     return cx->runtime->ownerThread();
 }
 
 JS_FRIEND_API(unsigned)
 GetContextOutstandingRequests(const JSContext *cx)
 {
     return cx->outstandingRequests;
 }
-
-AutoSkipConservativeScan::AutoSkipConservativeScan(JSContext *cx
-                                                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
-  : context(cx)
-{
-    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-
-    JSRuntime *rt = context->runtime;
-    JS_ASSERT(rt->requestDepth >= 1);
-    JS_ASSERT(!rt->conservativeGC.requestThreshold);
-    if (rt->requestDepth == 1)
-        rt->conservativeGC.requestThreshold = 1;
-}
-
-AutoSkipConservativeScan::~AutoSkipConservativeScan()
-{
-    JSRuntime *rt = context->runtime;
-    if (rt->requestDepth == 1)
-        rt->conservativeGC.requestThreshold = 0;
-}
 #endif
 
 JS_FRIEND_API(JSCompartment *)
 GetContextCompartment(const JSContext *cx)
 {
     return cx->compartment;
 }
 
@@ -728,50 +708,36 @@ GCDescription::formatMessage(JSRuntime *
 }
 
 jschar *
 GCDescription::formatJSON(JSRuntime *rt, uint64_t timestamp) const
 {
     return rt->gcStats.formatJSON(timestamp);
 }
 
-JS_FRIEND_API(bool)
-WantGCSlice(JSRuntime *rt)
+JS_FRIEND_API(void)
+NotifyDidPaint(JSRuntime *rt)
 {
-    if (rt->gcZeal() == gc::ZealFrameVerifierValue || rt->gcZeal() == gc::ZealFrameGCValue)
-        return true;
-
-    if (rt->gcIncrementalState != gc::NO_INCREMENTAL)
-        return true;
-
-    return false;
-}
-
-JS_FRIEND_API(void)
-NotifyDidPaint(JSContext *cx)
-{
-    JSRuntime *rt = cx->runtime;
-
     if (rt->gcZeal() == gc::ZealFrameVerifierValue) {
-        gc::VerifyBarriers(cx);
+        gc::VerifyBarriers(rt);
         return;
     }
 
     if (rt->gcZeal() == gc::ZealFrameGCValue) {
         PrepareForFullGC(rt);
-        GCSlice(cx, GC_NORMAL, gcreason::REFRESH_FRAME);
+        GCSlice(rt, GC_NORMAL, gcreason::REFRESH_FRAME);
         return;
     }
 
     if (rt->gcIncrementalState != gc::NO_INCREMENTAL && !rt->gcInterFrameGC) {
         for (CompartmentsIter c(rt); !c.done(); c.next()) {
             if (c->needsBarrier())
                 PrepareCompartmentForGC(c);
         }
-        GCSlice(cx, GC_NORMAL, gcreason::REFRESH_FRAME);
+        GCSlice(rt, GC_NORMAL, gcreason::REFRESH_FRAME);
     }
 
     rt->gcInterFrameGC = false;
 }
 
 extern JS_FRIEND_API(bool)
 IsIncrementalGCEnabled(JSRuntime *rt)
 {
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -564,27 +564,16 @@ JS_FRIEND_API(JSString *)
 GetPCCountScriptContents(JSContext *cx, size_t script);
 
 #ifdef JS_THREADSAFE
 JS_FRIEND_API(void *)
 GetOwnerThread(const JSContext *cx);
 
 JS_FRIEND_API(unsigned)
 GetContextOutstandingRequests(const JSContext *cx);
-
-class JS_FRIEND_API(AutoSkipConservativeScan)
-{
-  public:
-    AutoSkipConservativeScan(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
-    ~AutoSkipConservativeScan();
-
-  private:
-    JSContext *context;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
 #endif
 
 JS_FRIEND_API(JSCompartment *)
 GetContextCompartment(const JSContext *cx);
 
 JS_FRIEND_API(bool)
 HasUnrootedGlobal(const JSContext *cx);
 
@@ -675,23 +664,23 @@ PrepareForFullGC(JSRuntime *rt);
 /*
  * When triggering a GC using one of the functions below, it is first necessary
  * to select the compartments to be collected. To do this, you can call
  * PrepareCompartmentForGC on each compartment, or you can call PrepareForFullGC
  * to select all compartments. Failing to select any compartment is an error.
  */
 
 extern JS_FRIEND_API(void)
-GCForReason(JSContext *cx, gcreason::Reason reason);
+GCForReason(JSRuntime *rt, gcreason::Reason reason);
 
 extern JS_FRIEND_API(void)
-ShrinkingGC(JSContext *cx, gcreason::Reason reason);
+ShrinkingGC(JSRuntime *rt, gcreason::Reason reason);
 
 extern JS_FRIEND_API(void)
-IncrementalGC(JSContext *cx, gcreason::Reason reason);
+IncrementalGC(JSRuntime *rt, gcreason::Reason reason);
 
 extern JS_FRIEND_API(void)
 SetGCSliceTimeBudget(JSContext *cx, int64_t millis);
 
 enum GCProgress {
     /*
      * During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END
      * callbacks. During an incremental GC, the sequence of callbacks is as
@@ -719,25 +708,22 @@ struct JS_FRIEND_API(GCDescription) {
 };
 
 typedef void
 (* GCSliceCallback)(JSRuntime *rt, GCProgress progress, const GCDescription &desc);
 
 extern JS_FRIEND_API(GCSliceCallback)
 SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback);
 
-extern JS_FRIEND_API(bool)
-WantGCSlice(JSRuntime *rt);
-
 /*
  * Signals a good place to do an incremental slice, because the browser is
  * drawing a frame.
  */
 extern JS_FRIEND_API(void)
-NotifyDidPaint(JSContext *cx);
+NotifyDidPaint(JSRuntime *rt);
 
 extern JS_FRIEND_API(bool)
 IsIncrementalGCEnabled(JSRuntime *rt);
 
 extern JS_FRIEND_API(void)
 DisableIncrementalGC(JSRuntime *rt);
 
 extern JS_FRIEND_API(bool)
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -152,20 +152,20 @@ const size_t GC_ALLOCATION_THRESHOLD = 3
  */
 const float GC_HEAP_GROWTH_FACTOR = 3.0f;
 
 /* Perform a Full GC every 20 seconds if MaybeGC is called */
 static const uint64_t GC_IDLE_FULL_SPAN = 20 * 1000 * 1000;
 
 #ifdef JS_GC_ZEAL
 static void
-StartVerifyBarriers(JSContext *cx);
+StartVerifyBarriers(JSRuntime *rt);
 
 static void
-EndVerifyBarriers(JSContext *cx);
+EndVerifyBarriers(JSRuntime *rt);
 
 void
 FinishVerifier(JSRuntime *rt);
 #endif
 
 /* This array should be const, but that doesn't link right under GCC. */
 AllocKind slotsToThingKind[] = {
     /* 0 */  FINALIZE_OBJECT0,  FINALIZE_OBJECT2,  FINALIZE_OBJECT2,  FINALIZE_OBJECT4,
@@ -1046,16 +1046,17 @@ MarkIfGCThingWord(JSTracer *trc, uintptr
 
     JSGCTraceKind traceKind = MapAllocToTraceKind(thingKind);
 #ifdef DEBUG
     const char pattern[] = "machine_stack %p";
     char nameBuf[sizeof(pattern) - 2 + sizeof(thing) * 2];
     JS_snprintf(nameBuf, sizeof(nameBuf), pattern, thing);
     JS_SET_TRACING_NAME(trc, nameBuf);
 #endif
+    JS_SET_TRACING_LOCATION(trc, (void *)w);
     void *tmp = thing;
     MarkKind(trc, &tmp, traceKind);
     JS_ASSERT(tmp == thing);
 
 #ifdef DEBUG
     if (trc->runtime->gcIncrementalState == MARK_ROOTS)
         trc->runtime->gcSavedRoots.append(JSRuntime::SavedGCRoot(thing, traceKind));
 #endif
@@ -1107,17 +1108,17 @@ MarkConservativeStackRoots(JSTracer *trc
     if (rt->gcIncrementalState == MARK_ROOTS)
         rt->gcSavedRoots.clearAndFree();
 #endif
 
     ConservativeGCData *cgcd = &rt->conservativeGC;
     if (!cgcd->hasStackToScan()) {
 #ifdef JS_THREADSAFE
         JS_ASSERT(!rt->suspendCount);
-        JS_ASSERT(rt->requestDepth <= cgcd->requestThreshold);
+        JS_ASSERT(!rt->requestDepth);
 #endif
         return;
     }
 
     uintptr_t *stackMin, *stackEnd;
 #if JS_STACK_GROWTH_DIRECTION > 0
     stackMin = rt->nativeStackBase;
     stackEnd = cgcd->nativeStackTop;
@@ -1175,18 +1176,17 @@ ConservativeGCData::recordStackTop()
 
 static void
 RecordNativeStackTopForGC(JSRuntime *rt)
 {
     ConservativeGCData *cgcd = &rt->conservativeGC;
 
 #ifdef JS_THREADSAFE
     /* Record the stack top here only if we are called from a request. */
-    JS_ASSERT(rt->requestDepth >= cgcd->requestThreshold);
-    if (rt->requestDepth == cgcd->requestThreshold)
+    if (!rt->requestDepth)
         return;
 #endif
     cgcd->recordStackTop();
 }
 
 } /* namespace js */
 
 bool
@@ -1643,17 +1643,17 @@ ArenaLists::finalizeScripts(FreeOp *fop)
 
 static void
 RunLastDitchGC(JSContext *cx, gcreason::Reason reason)
 {
     JSRuntime *rt = cx->runtime;
 
     /* The last ditch GC preserves all atoms. */
     AutoKeepAtoms keep(rt);
-    GC(cx, GC_NORMAL, reason);
+    GC(rt, GC_NORMAL, reason);
 }
 
 /* static */ void *
 ArenaLists::refillFreeList(JSContext *cx, AllocKind thingKind)
 {
     JS_ASSERT(cx->compartment->arenas.freeLists[thingKind].isEmpty());
 
     JSCompartment *comp = cx->compartment;
@@ -2003,16 +2003,17 @@ GCMarker::markBufferedGrayRoots()
     JS_ASSERT(!grayFailed);
 
     for (GrayRoot *elem = grayRoots.begin(); elem != grayRoots.end(); elem++) {
 #ifdef DEBUG
         debugPrinter = elem->debugPrinter;
         debugPrintArg = elem->debugPrintArg;
         debugPrintIndex = elem->debugPrintIndex;
 #endif
+        JS_SET_TRACING_LOCATION(this, (void *)&elem->thing);
         void *tmp = elem->thing;
         MarkKind(this, &tmp, elem->kind);
         JS_ASSERT(tmp == elem->thing);
     }
 
     grayRoots.clearAndFree();
 }
 
@@ -2069,16 +2070,17 @@ gc_root_traversal(JSTracer *trc, const R
     else
         MarkValueRoot(trc, reinterpret_cast<Value *>(entry.key), name);
 }
 
 static void
 gc_lock_traversal(const GCLocks::Entry &entry, JSTracer *trc)
 {
     JS_ASSERT(entry.value >= 1);
+    JS_SET_TRACING_LOCATION(trc, (void *)&entry.key);
     void *tmp = entry.key;
     MarkGCThingRoot(trc, &tmp, "locked object");
     JS_ASSERT(tmp == entry.key);
 }
 
 namespace js {
 
 void
@@ -2192,17 +2194,17 @@ AutoGCRooter::trace(JSTracer *trc)
       case IDVECTOR: {
         AutoIdVector::VectorImpl &vector = static_cast<AutoIdVector *>(this)->vector;
         MarkIdRootRange(trc, vector.length(), vector.begin(), "js::AutoIdVector.vector");
         return;
       }
 
       case SHAPEVECTOR: {
         AutoShapeVector::VectorImpl &vector = static_cast<js::AutoShapeVector *>(this)->vector;
-        MarkShapeRootRange(trc, vector.length(), const_cast<Shape **>(vector.begin()), 
+        MarkShapeRootRange(trc, vector.length(), const_cast<Shape **>(vector.begin()),
                            "js::AutoShapeVector.vector");
         return;
       }
 
       case OBJVECTOR: {
         AutoObjectVector::VectorImpl &vector = static_cast<AutoObjectVector *>(this)->vector;
         MarkObjectRootRange(trc, vector.length(), vector.begin(), "js::AutoObjectVector.vector");
         return;
@@ -2387,53 +2389,53 @@ TriggerCompartmentGC(JSCompartment *comp
 void
 MaybeGC(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
     JS_ASSERT(rt->onOwnerThread());
 
     if (rt->gcZeal() == ZealAllocValue || rt->gcZeal() == ZealPokeValue) {
         PrepareForFullGC(rt);
-        GC(cx, GC_NORMAL, gcreason::MAYBEGC);
+        GC(rt, GC_NORMAL, gcreason::MAYBEGC);
+        return;
+    }
+
+    if (rt->gcIsNeeded) {
+        GCSlice(rt, GC_NORMAL, gcreason::MAYBEGC);
         return;
     }
 
     JSCompartment *comp = cx->compartment;
-    if (rt->gcIsNeeded) {
-        GCSlice(cx, GC_NORMAL, gcreason::MAYBEGC);
-        return;
-    }
-
     if (comp->gcBytes > 8192 &&
         comp->gcBytes >= 3 * (comp->gcTriggerBytes / 4) &&
         rt->gcIncrementalState == NO_INCREMENTAL)
     {
         PrepareCompartmentForGC(comp);
-        GCSlice(cx, GC_NORMAL, gcreason::MAYBEGC);
+        GCSlice(rt, GC_NORMAL, gcreason::MAYBEGC);
         return;
     }
 
     if (comp->gcMallocAndFreeBytes > comp->gcTriggerMallocAndFreeBytes) {
         PrepareCompartmentForGC(comp);
-        GCSlice(cx, GC_NORMAL, gcreason::MAYBEGC);
+        GCSlice(rt, GC_NORMAL, gcreason::MAYBEGC);
         return;
     }
 
     /*
      * Access to the counters and, on 32 bit, setting gcNextFullGCTime below
      * is not atomic and a race condition could trigger or suppress the GC. We
      * tolerate this.
      */
     int64_t now = PRMJ_Now();
     if (rt->gcNextFullGCTime && rt->gcNextFullGCTime <= now) {
         if (rt->gcChunkAllocationSinceLastGC ||
             rt->gcNumArenasFreeCommitted > FreeCommittedArenasThreshold)
         {
             PrepareForFullGC(rt);
-            GCSlice(cx, GC_SHRINK, gcreason::MAYBEGC);
+            GCSlice(rt, GC_SHRINK, gcreason::MAYBEGC);
         } else {
             rt->gcNextFullGCTime = now + GC_IDLE_FULL_SPAN;
         }
     }
 }
 
 static void
 DecommitArenasFromAvailableList(JSRuntime *rt, Chunk **availableListHeadp)
@@ -2689,35 +2691,34 @@ GCHelperThread::prepareForBackgroundSwee
 {
     JS_ASSERT(state == IDLE);
     size_t maxArenaLists = MAX_BACKGROUND_FINALIZE_KINDS * rt->compartments.length();
     return finalizeVector.reserve(maxArenaLists);
 }
 
 /* Must be called with the GC lock taken. */
 void
-GCHelperThread::startBackgroundSweep(JSContext *cx, bool shouldShrink)
+GCHelperThread::startBackgroundSweep(bool shouldShrink)
 {
     /* The caller takes the GC lock. */
     JS_ASSERT(state == IDLE);
-    JS_ASSERT(cx);
-    JS_ASSERT(!finalizationContext);
-    finalizationContext = cx;
+    JS_ASSERT(!sweepFlag);
+    sweepFlag = true;
     shrinkFlag = shouldShrink;
     state = SWEEPING;
     PR_NotifyCondVar(wakeup);
 }
 
 /* Must be called with the GC lock taken. */
 void
 GCHelperThread::startBackgroundShrink()
 {
     switch (state) {
       case IDLE:
-        JS_ASSERT(!finalizationContext);
+        JS_ASSERT(!sweepFlag);
         shrinkFlag = true;
         state = SWEEPING;
         PR_NotifyCondVar(wakeup);
         break;
       case SWEEPING:
         shrinkFlag = true;
         break;
       case ALLOCATING:
@@ -2778,18 +2779,18 @@ GCHelperThread::replenishAndFreeLater(vo
     } while (false);
     Foreground::free_(ptr);
 }
 
 /* Must be called with the GC lock taken. */
 void
 GCHelperThread::doSweep()
 {
-    if (finalizationContext) {
-        finalizationContext = NULL;
+    if (sweepFlag) {
+        sweepFlag = false;
         AutoUnlockGC unlock(rt);
 
         /*
          * We must finalize in the insert order, see comments in
          * finalizeObjects.
          */
         FreeOp fop(rt, false, true);
         for (ArenaHeader **i = finalizeVector.begin(); i != finalizeVector.end(); ++i)
@@ -2892,16 +2893,28 @@ PurgeRuntime(JSTracer *trc)
 
     for (ContextIter acx(rt); !acx.done(); acx.next())
         acx->purge();
 }
 
 static void
 BeginMarkPhase(JSRuntime *rt)
 {
+    rt->gcMarker.start(rt);
+    JS_ASSERT(!rt->gcMarker.callback);
+    JS_ASSERT(IS_GC_MARKING_TRACER(&rt->gcMarker));
+
+    /* For non-incremental GC the following sweep discards the jit code. */
+    if (rt->gcIncrementalState != NO_INCREMENTAL) {
+        for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
+            gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_DISCARD_CODE);
+            c->discardJitCode(rt->defaultFreeOp());
+        }
+    }
+
     GCMarker *gcmarker = &rt->gcMarker;
 
     rt->gcStartNumber = rt->gcNumber;
 
     /* Reset weak map list. */
     WeakMapBase::resetWeakMapList(rt);
 
     /*
@@ -2962,56 +2975,57 @@ MarkGrayAndWeak(JSRuntime *rt)
     SliceBudget budget;
     gcmarker->drainMarkStack(budget);
     MarkWeakReferences(gcmarker);
     JS_ASSERT(gcmarker->isDrained());
 }
 
 #ifdef DEBUG
 static void
-ValidateIncrementalMarking(JSContext *cx);
+ValidateIncrementalMarking(JSRuntime *rt);
 #endif
 
 static void
-EndMarkPhase(JSContext *cx)
+EndMarkPhase(JSRuntime *rt)
 {
-    JSRuntime *rt = cx->runtime;
-
     {
         gcstats::AutoPhase ap1(rt->gcStats, gcstats::PHASE_MARK);
         gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_MARK_OTHER);
         MarkGrayAndWeak(rt);
     }
 
     JS_ASSERT(rt->gcMarker.isDrained());
 
 #ifdef DEBUG
     if (rt->gcIncrementalState != NO_INCREMENTAL)
-        ValidateIncrementalMarking(cx);
+        ValidateIncrementalMarking(rt);
 #endif
 
 #ifdef DEBUG
     /* Make sure that we didn't mark an object in another compartment */
     for (CompartmentsIter c(rt); !c.done(); c.next()) {
         JS_ASSERT_IF(!c->isCollecting() && c != rt->atomsCompartment,
                      c->arenas.checkArenaListAllUnmarked());
     }
 #endif
+
+    rt->gcMarker.stop();
+
+    /* We do not discard JIT here code as the following sweeping does that. */
 }
 
 #ifdef DEBUG
 static void
-ValidateIncrementalMarking(JSContext *cx)
+ValidateIncrementalMarking(JSRuntime *rt)
 {
     typedef HashMap<Chunk *, uintptr_t *, GCChunkHasher, SystemAllocPolicy> BitmapMap;
     BitmapMap map;
     if (!map.init())
         return;
 
-    JSRuntime *rt = cx->runtime;
     GCMarker *gcmarker = &rt->gcMarker;
 
     /* Save existing mark bits. */
     for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
         ChunkBitmap *bitmap = &r.front()->bitmap;
         uintptr_t *entry = (uintptr_t *)js_malloc(sizeof(bitmap->bitmap));
         if (!entry)
             return;
@@ -3087,20 +3101,18 @@ ValidateIncrementalMarking(JSContext *cx
     WeakMapBase::resetWeakMapList(rt);
     WeakMapBase::restoreWeakMapList(rt, weakmaps);
 
     rt->gcIncrementalState = state;
 }
 #endif
 
 static void
-SweepPhase(JSContext *cx, JSGCInvocationKind gckind)
+SweepPhase(JSRuntime *rt, JSGCInvocationKind gckind, bool *startBackgroundSweep)
 {
-    JSRuntime *rt = cx->runtime;
-
     /*
      * Sweep phase.
      *
      * Finalize as we sweep, outside of rt->gcLock but with rt->gcRunning set
      * so that any attempt to allocate a GC-thing from a finalizer will fail,
      * rather than nest badly and leave the unmarked newborn to be swept.
      *
      * We first sweep atom state so we can use IsAboutToBeFinalized on
@@ -3108,29 +3120,26 @@ SweepPhase(JSContext *cx, JSGCInvocation
      * freed. Note that even after the entry is freed, JSObject finalizers can
      * continue to access the corresponding JSString* assuming that they are
      * unique. This works since the atomization API must not be called during
      * the GC.
      */
     gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP);
 
 #ifdef JS_THREADSAFE
-    if (rt->hasContexts() && rt->gcHelperThread.prepareForBackgroundSweep())
-        cx->gcBackgroundFree = &rt->gcHelperThread;
+    *startBackgroundSweep = (rt->hasContexts() && rt->gcHelperThread.prepareForBackgroundSweep());
+#else
+    *startBackgroundSweep = false;
 #endif
 
     /* Purge the ArenaLists before sweeping. */
     for (GCCompartmentsIter c(rt); !c.done(); c.next())
         c->arenas.purge();
 
-#ifdef JS_THREADSAFE
-    FreeOp fop(rt, !!cx->gcBackgroundFree, false);
-#else
-    FreeOp fop(rt, false, false);
-#endif
+    FreeOp fop(rt, *startBackgroundSweep, false);
     {
         gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_FINALIZE_START);
         if (rt->gcFinalizeCallback)
             rt->gcFinalizeCallback(&fop, JSFINALIZE_START);
     }
 
     /* Finalize unreachable (key,value) pairs in all weak maps. */
     WeakMapBase::sweepAll(&rt->gcMarker);
@@ -3217,37 +3226,27 @@ SweepPhase(JSContext *cx, JSGCInvocation
         if (rt->gcFinalizeCallback)
             rt->gcFinalizeCallback(&fop, JSFINALIZE_END);
     }
 
     for (CompartmentsIter c(rt); !c.done(); c.next())
         c->setGCLastBytes(c->gcBytes, c->gcMallocAndFreeBytes, gckind);
 }
 
-/* Perform mark-and-sweep GC. If comp is set, we perform a single-compartment GC. */
 static void
-MarkAndSweep(JSContext *cx, JSGCInvocationKind gckind)
+NonIncrementalMark(JSRuntime *rt, JSGCInvocationKind gckind)
 {
-    JSRuntime *rt = cx->runtime;
-
-    AutoUnlockGC unlock(rt);
-
-    rt->gcMarker.start(rt);
-    JS_ASSERT(!rt->gcMarker.callback);
-
+    JS_ASSERT(rt->gcIncrementalState == NO_INCREMENTAL);
     BeginMarkPhase(rt);
     {
         gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK);
         SliceBudget budget;
         rt->gcMarker.drainMarkStack(budget);
     }
-    EndMarkPhase(cx);
-    SweepPhase(cx, gckind);
-
-    rt->gcMarker.stop();
+    EndMarkPhase(rt);
 }
 
 /*
  * This class should be used by any code that needs to exclusive access to the
  * heap in order to trace through it...
  */
 class AutoHeapSession {
   public:
@@ -3337,28 +3336,26 @@ ResetIncrementalGC(JSRuntime *rt, const 
 
     JS_ASSERT(!rt->gcStrictCompartmentChecking);
 
     rt->gcStats.reset(reason);
 }
 
 class AutoGCSlice {
   public:
-    AutoGCSlice(JSContext *cx);
+    AutoGCSlice(JSRuntime *rt);
     ~AutoGCSlice();
 
   private:
-    JSContext *context;
+    JSRuntime *runtime;
 };
 
-AutoGCSlice::AutoGCSlice(JSContext *cx)
-  : context(cx)
+AutoGCSlice::AutoGCSlice(JSRuntime *rt)
+  : runtime(rt)
 {
-    JSRuntime *rt = context->runtime;
-
     /*
      * During incremental GC, the compartment's active flag determines whether
      * there are stack frames active for any of its scripts. Normally this flag
      * is set at the beginning of the mark phase. During incremental GC, we also
      * set it at the start of every phase.
      */
     rt->stackSpace.markActiveCompartments();
 
@@ -3368,24 +3365,22 @@ AutoGCSlice::AutoGCSlice(JSContext *cx)
             c->needsBarrier_ = false;
         else
             JS_ASSERT(!c->needsBarrier_);
     }
 }
 
 AutoGCSlice::~AutoGCSlice()
 {
-    JSRuntime *rt = context->runtime;
-
-    for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
-        if (rt->gcIncrementalState == MARK) {
+    for (GCCompartmentsIter c(runtime); !c.done(); c.next()) {
+        if (runtime->gcIncrementalState == MARK) {
             c->needsBarrier_ = true;
-            c->arenas.prepareForIncrementalGC(rt);
+            c->arenas.prepareForIncrementalGC(runtime);
         } else {
-            JS_ASSERT(rt->gcIncrementalState == NO_INCREMENTAL);
+            JS_ASSERT(runtime->gcIncrementalState == NO_INCREMENTAL);
             c->needsBarrier_ = false;
         }
     }
 }
 
 class AutoCopyFreeListToArenas {
     JSRuntime *rt;
 
@@ -3398,44 +3393,33 @@ class AutoCopyFreeListToArenas {
 
     ~AutoCopyFreeListToArenas() {
         for (CompartmentsIter c(rt); !c.done(); c.next())
             c->arenas.clearFreeListsInArenas();
     }
 };
 
 static void
-IncrementalGCSlice(JSContext *cx, int64_t budget, JSGCInvocationKind gckind)
+IncrementalMarkSlice(JSRuntime *rt, int64_t budget, JSGCInvocationKind gckind, bool *shouldSweep)
 {
-    JSRuntime *rt = cx->runtime;
-
-    AutoUnlockGC unlock(rt);
-    AutoGCSlice slice(cx);
+    AutoGCSlice slice(rt);
 
     gc::State initialState = rt->gcIncrementalState;
 
     if (rt->gcIncrementalState == NO_INCREMENTAL) {
         rt->gcIncrementalState = MARK_ROOTS;
         rt->gcLastMarkSlice = false;
     }
 
     if (rt->gcIncrementalState == MARK_ROOTS) {
-        rt->gcMarker.start(rt);
-        JS_ASSERT(IS_GC_MARKING_TRACER(&rt->gcMarker));
-
-        for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
-            gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_DISCARD_CODE);
-            c->discardJitCode(rt->defaultFreeOp());
-        }
-
         BeginMarkPhase(rt);
-
         rt->gcIncrementalState = MARK;
     }
 
+    *shouldSweep = false;
     if (rt->gcIncrementalState == MARK) {
         gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK);
         SliceBudget sliceBudget(budget);
 
         /* If we needed delayed marking for gray roots, then collect until done. */
         if (!rt->gcMarker.hasBufferedGrayRoots())
             sliceBudget.reset();
 
@@ -3445,36 +3429,27 @@ IncrementalGCSlice(JSContext *cx, int64_
                  obj != rt->gcSelectedForMarking.end(); obj++)
             {
                 MarkObjectUnbarriered(&rt->gcMarker, obj, "selected obj");
             }
         }
 #endif
 
         bool finished = rt->gcMarker.drainMarkStack(sliceBudget);
-
         if (finished) {
             JS_ASSERT(rt->gcMarker.isDrained());
-            if (initialState == MARK && !rt->gcLastMarkSlice && budget != SliceBudget::Unlimited)
+            if (initialState == MARK && !rt->gcLastMarkSlice && budget != SliceBudget::Unlimited) {
                 rt->gcLastMarkSlice = true;
-            else
-                rt->gcIncrementalState = SWEEP;
+            } else {
+                EndMarkPhase(rt);
+                rt->gcIncrementalState = NO_INCREMENTAL;
+                *shouldSweep = true;
+            }
         }
     }
-
-    if (rt->gcIncrementalState == SWEEP) {
-        EndMarkPhase(cx);
-        SweepPhase(cx, gckind);
-
-        rt->gcMarker.stop();
-
-        /* JIT code was already discarded during sweeping. */
-
-        rt->gcIncrementalState = NO_INCREMENTAL;
-    }
 }
 
 class IncrementalSafety
 {
     const char *reason_;
 
     IncrementalSafety(const char *reason) : reason_(reason) {}
 
@@ -3553,79 +3528,82 @@ BudgetIncrementalGC(JSRuntime *rt, int64
 
 /*
  * GC, repeatedly if necessary, until we think we have not created any new
  * garbage. We disable inlining to ensure that the bottom of the stack with
  * possible GC roots recorded in MarkRuntime excludes any pointers we use during
  * the marking implementation.
  */
 static JS_NEVER_INLINE void
-GCCycle(JSContext *cx, bool incremental, int64_t budget, JSGCInvocationKind gckind)
+GCCycle(JSRuntime *rt, bool incremental, int64_t budget, JSGCInvocationKind gckind)
 {
-    JSRuntime *rt = cx->runtime;
-
 #ifdef DEBUG
     for (CompartmentsIter c(rt); !c.done(); c.next())
         JS_ASSERT_IF(rt->gcMode == JSGC_MODE_GLOBAL, c->isGCScheduled());
 #endif
 
     /* Recursive GC is no-op. */
     if (rt->gcRunning)
         return;
 
-    AutoGCSession gcsession(rt);
-
     /* Don't GC if we are reporting an OOM. */
     if (rt->inOOMReport)
         return;
 
+    AutoLockGC lock(rt);
+    AutoGCSession gcsession(rt);
+
 #ifdef JS_THREADSAFE
     /*
      * As we about to purge caches and clear the mark bits we must wait for
      * any background finalization to finish. We must also wait for the
      * background allocation to finish so we can avoid taking the GC lock
      * when manipulating the chunks during the GC.
      */
     {
         gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_WAIT_BACKGROUND_THREAD);
-
-        JS_ASSERT(!cx->gcBackgroundFree);
         rt->gcHelperThread.waitBackgroundSweepOrAllocEnd();
     }
 #endif
 
-    if (!incremental) {
-        /* If non-incremental GC was requested, reset incremental GC. */
-        ResetIncrementalGC(rt, "requested");
-        rt->gcStats.nonincremental("requested");
-    } else {
-        BudgetIncrementalGC(rt, &budget);
-    }
-
-    AutoCopyFreeListToArenas copy(rt);
-
-    if (budget == SliceBudget::Unlimited && rt->gcIncrementalState == NO_INCREMENTAL)
-        MarkAndSweep(cx, gckind);
-    else
-        IncrementalGCSlice(cx, budget, gckind);
+    bool startBackgroundSweep = false;
+    {
+        AutoUnlockGC unlock(rt);
+
+        if (!incremental) {
+            /* If non-incremental GC was requested, reset incremental GC. */
+            ResetIncrementalGC(rt, "requested");
+            rt->gcStats.nonincremental("requested");
+        } else {
+            BudgetIncrementalGC(rt, &budget);
+        }
+
+        AutoCopyFreeListToArenas copy(rt);
+
+        bool shouldSweep;
+        if (budget == SliceBudget::Unlimited && rt->gcIncrementalState == NO_INCREMENTAL) {
+            NonIncrementalMark(rt, gckind);
+            shouldSweep = true;
+        } else {
+            IncrementalMarkSlice(rt, budget, gckind, &shouldSweep);
+        }
 
 #ifdef DEBUG
-    if (rt->gcIncrementalState == NO_INCREMENTAL) {
-        for (CompartmentsIter c(rt); !c.done(); c.next())
-            JS_ASSERT(!c->needsBarrier_);
+        if (rt->gcIncrementalState == NO_INCREMENTAL) {
+            for (CompartmentsIter c(rt); !c.done(); c.next())
+                JS_ASSERT(!c->needsBarrier_);
+        }
+#endif
+        if (shouldSweep)
+            SweepPhase(rt, gckind, &startBackgroundSweep);
     }
-#endif
+        
 #ifdef JS_THREADSAFE
-    if (rt->gcIncrementalState == NO_INCREMENTAL) {
-        if (cx->gcBackgroundFree) {
-            JS_ASSERT(cx->gcBackgroundFree == &rt->gcHelperThread);
-            cx->gcBackgroundFree = NULL;
-            rt->gcHelperThread.startBackgroundSweep(cx, gckind == GC_SHRINK);
-        }
-    }
+    if (startBackgroundSweep)
+        rt->gcHelperThread.startBackgroundSweep(gckind == GC_SHRINK);
 #endif
 }
 
 #ifdef JS_GC_ZEAL
 static bool
 IsDeterministicGCReason(gcreason::Reason reason)
 {
     if (reason > gcreason::DEBUG_GC && reason != gcreason::CC_FORCED)
@@ -3634,48 +3612,47 @@ IsDeterministicGCReason(gcreason::Reason
     if (reason == gcreason::MAYBEGC)
         return false;
 
     return true;
 }
 #endif
 
 static void
-Collect(JSContext *cx, bool incremental, int64_t budget,
+Collect(JSRuntime *rt, bool incremental, int64_t budget,
         JSGCInvocationKind gckind, gcreason::Reason reason)
 {
-    JSRuntime *rt = cx->runtime;
     JS_AbortIfWrongThread(rt);
 
 #ifdef JS_GC_ZEAL
     if (rt->gcDeterministicOnly && !IsDeterministicGCReason(reason))
         return;
 #endif
 
     JS_ASSERT_IF(!incremental || budget != SliceBudget::Unlimited, JSGC_INCREMENTAL);
 
 #ifdef JS_GC_ZEAL
-    bool restartVerify = cx->runtime->gcVerifyData &&
-                         cx->runtime->gcZeal() == ZealVerifierValue &&
+    bool restartVerify = rt->gcVerifyData &&
+                         rt->gcZeal() == ZealVerifierValue &&
                          reason != gcreason::CC_FORCED;
 
     struct AutoVerifyBarriers {
-        JSContext *cx;
+        JSRuntime *runtime;
         bool restart;
-        AutoVerifyBarriers(JSContext *cx, bool restart)
-          : cx(cx), restart(restart)
+        AutoVerifyBarriers(JSRuntime *rt, bool restart)
+          : runtime(rt), restart(restart)
         {
-            if (cx->runtime->gcVerifyData)
-                EndVerifyBarriers(cx);
+            if (rt->gcVerifyData)
+                EndVerifyBarriers(rt);
         }
         ~AutoVerifyBarriers() {
             if (restart)
-                StartVerifyBarriers(cx);
+                StartVerifyBarriers(runtime);
         }
-    } av(cx, restartVerify);
+    } av(rt, restartVerify);
 #endif
 
     RecordNativeStackTopForGC(rt);
 
     int compartmentCount = 0;
     int collectedCount = 0;
     for (CompartmentsIter c(rt); !c.done(); c.next()) {
         if (rt->gcMode == JSGC_MODE_GLOBAL)
@@ -3699,20 +3676,18 @@ Collect(JSContext *cx, bool incremental,
          */
         if (rt->gcIncrementalState == NO_INCREMENTAL) {
             gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_GC_BEGIN);
             if (JSGCCallback callback = rt->gcCallback)
                 callback(rt, JSGC_BEGIN);
         }
 
         {
-            /* Lock out other GC allocator and collector invocations. */
-            AutoLockGC lock(rt);
             rt->gcPoke = false;
-            GCCycle(cx, incremental, budget, gckind);
+            GCCycle(rt, incremental, budget, gckind);
         }
 
         if (rt->gcIncrementalState == NO_INCREMENTAL) {
             gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_GC_END);
             if (JSGCCallback callback = rt->gcCallback)
                 callback(rt, JSGC_END);
         }
 
@@ -3721,33 +3696,33 @@ Collect(JSContext *cx, bool incremental,
          * stop creating garbage.
          */
     } while (!rt->hasContexts() && rt->gcPoke);
 }
 
 namespace js {
 
 void
-GC(JSContext *cx, JSGCInvocationKind gckind, gcreason::Reason reason)
+GC(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason)
 {
-    Collect(cx, false, SliceBudget::Unlimited, gckind, reason);
+    Collect(rt, false, SliceBudget::Unlimited, gckind, reason);
 }
 
 void
-GCSlice(JSContext *cx, JSGCInvocationKind gckind, gcreason::Reason reason)
+GCSlice(JSRuntime *rt, JSGCInvocationKind gckind, gcreason::Reason reason)
 {
-    Collect(cx, true, cx->runtime->gcSliceBudget, gckind, reason);
+    Collect(rt, true, rt->gcSliceBudget, gckind, reason);
 }
 
 void
-GCDebugSlice(JSContext *cx, bool limit, int64_t objCount)
+GCDebugSlice(JSRuntime *rt, bool limit, int64_t objCount)
 {
     int64_t budget = limit ? SliceBudget::WorkBudget(objCount) : SliceBudget::Unlimited;
-    PrepareForDebugGC(cx->runtime);
-    Collect(cx, true, budget, GC_NORMAL, gcreason::API);
+    PrepareForDebugGC(rt);
+    Collect(rt, true, budget, GC_NORMAL, gcreason::API);
 }
 
 /* Schedule a full GC unless a compartment will already be collected. */
 void
 PrepareForDebugGC(JSRuntime *rt)
 {
     for (CompartmentsIter c(rt); !c.done(); c.next()) {
         if (c->isGCScheduled())
@@ -4162,20 +4137,18 @@ NextNode(VerifyNode *node)
     if (node->count == 0)
         return (VerifyNode *)((char *)node + sizeof(VerifyNode) - sizeof(EdgeValue));
     else
         return (VerifyNode *)((char *)node + sizeof(VerifyNode) +
 			      sizeof(EdgeValue)*(node->count - 1));
 }
 
 static void
-StartVerifyBarriers(JSContext *cx)
+StartVerifyBarriers(JSRuntime *rt)
 {
-    JSRuntime *rt = cx->runtime;
-
     if (rt->gcVerifyData || rt->gcIncrementalState != NO_INCREMENTAL)
         return;
 
     AutoLockGC lock(rt);
     AutoHeapSession session(rt);
 
     if (!IsIncrementalGCSafe(rt))
         return;
@@ -4309,20 +4282,18 @@ static void
 CheckReachable(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
 {
     VerifyTracer *trc = (VerifyTracer *)jstrc;
     NodeMap::Ptr p = trc->nodemap.lookup(*thingp);
     JS_ASSERT_IF(!p, IsMarkedOrAllocated(static_cast<Cell *>(*thingp)));
 }
 
 static void
-EndVerifyBarriers(JSContext *cx)
+EndVerifyBarriers(JSRuntime *rt)
 {
-    JSRuntime *rt = cx->runtime;
-
     AutoLockGC lock(rt);
     AutoHeapSession session(rt);
 
 #ifdef JS_THREADSAFE
     rt->gcHelperThread.waitBackgroundSweepOrAllocEnd();
 #endif
 
     AutoUnlockGC unlock(rt);
@@ -4401,58 +4372,58 @@ FinishVerifier(JSRuntime *rt)
 {
     if (VerifyTracer *trc = (VerifyTracer *)rt->gcVerifyData) {
         trc->~VerifyTracer();
         js_free(trc);
     }
 }
 
 void
-VerifyBarriers(JSContext *cx)
+VerifyBarriers(JSRuntime *rt)
 {
-    JSRuntime *rt = cx->runtime;
     if (rt->gcVerifyData)
-        EndVerifyBarriers(cx);
+        EndVerifyBarriers(rt);
     else
-        StartVerifyBarriers(cx);
+        StartVerifyBarriers(rt);
 }
 
 void
 MaybeVerifyBarriers(JSContext *cx, bool always)
 {
-    if (cx->runtime->gcZeal() != ZealVerifierValue) {
-        if (cx->runtime->gcVerifyData)
-            EndVerifyBarriers(cx);
+    JSRuntime *rt = cx->runtime;
+
+    if (rt->gcZeal() != ZealVerifierValue) {
+        if (rt->gcVerifyData)
+            EndVerifyBarriers(rt);
         return;
     }
 
-    uint32_t freq = cx->runtime->gcZealFrequency;
-
-    JSRuntime *rt = cx->runtime;
+    uint32_t freq = rt->gcZealFrequency;
+
     if (VerifyTracer *trc = (VerifyTracer *)rt->gcVerifyData) {
         if (++trc->count < freq && !always)
             return;
 
-        EndVerifyBarriers(cx);
+        EndVerifyBarriers(rt);
     }
-    StartVerifyBarriers(cx);
+    StartVerifyBarriers(rt);
 }
 
 #endif /* JS_GC_ZEAL */
 
 } /* namespace gc */
 
-static void ReleaseAllJITCode(JSContext *cx)
+static void ReleaseAllJITCode(FreeOp *fop)
 {
 #ifdef JS_METHODJIT
-    for (GCCompartmentsIter c(cx->runtime); !c.done(); c.next()) {
+    for (GCCompartmentsIter c(fop->runtime()); !c.done(); c.next()) {
         mjit::ClearAllFrames(c);
         for (CellIter i(c, FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
-            mjit::ReleaseScriptCode(cx->runtime->defaultFreeOp(), script);
+            mjit::ReleaseScriptCode(fop, script);
         }
     }
 #endif
 }
 
 /*
  * There are three possible PCCount profiling states:
  *
@@ -4473,70 +4444,70 @@ static void ReleaseAllJITCode(JSContext 
  * Function                 None      Profile   Query
  * --------
  * StartPCCountProfiling    Profile   Profile   Profile
  * StopPCCountProfiling     None      Query     Query
  * PurgePCCounts            None      None      None
  */
 
 static void
-ReleaseScriptCounts(JSContext *cx)
+ReleaseScriptCounts(FreeOp *fop)
 {
-    JSRuntime *rt = cx->runtime;
+    JSRuntime *rt = fop->runtime();
     JS_ASSERT(rt->scriptAndCountsVector);
 
     ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
 
     for (size_t i = 0; i < vec.length(); i++)
-        vec[i].scriptCounts.destroy(cx);
-
-    cx->delete_(rt->scriptAndCountsVector);
+        vec[i].scriptCounts.destroy(fop);
+
+    fop->delete_(rt->scriptAndCountsVector);
     rt->scriptAndCountsVector = NULL;
 }
 
 JS_FRIEND_API(void)
 StartPCCountProfiling(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
 
     if (rt->profilingScripts)
         return;
 
     if (rt->scriptAndCountsVector)
-        ReleaseScriptCounts(cx);
-
-    ReleaseAllJITCode(cx);
+        ReleaseScriptCounts(rt->defaultFreeOp());
+
+    ReleaseAllJITCode(rt->defaultFreeOp());
 
     rt->profilingScripts = true;
 }
 
 JS_FRIEND_API(void)
 StopPCCountProfiling(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
 
     if (!rt->profilingScripts)
         return;
     JS_ASSERT(!rt->scriptAndCountsVector);
 
-    ReleaseAllJITCode(cx);
+    ReleaseAllJITCode(rt->defaultFreeOp());
 
     ScriptAndCountsVector *vec = cx->new_<ScriptAndCountsVector>(SystemAllocPolicy());
     if (!vec)
         return;
 
     for (GCCompartmentsIter c(rt); !c.done(); c.next()) {
         for (CellIter i(c, FINALIZE_SCRIPT); !i.done(); i.next()) {
             JSScript *script = i.get<JSScript>();
             if (script->scriptCounts && script->types) {
                 ScriptAndCounts info;
                 info.script = script;
                 info.scriptCounts.steal(script->scriptCounts);
                 if (!vec->append(info))
-                    info.scriptCounts.destroy(cx);
+                    info.scriptCounts.destroy(rt->defaultFreeOp());
             }
         }
     }
 
     rt->profilingScripts = false;
     rt->scriptAndCountsVector = vec;
 }
 
@@ -4544,17 +4515,17 @@ JS_FRIEND_API(void)
 PurgePCCounts(JSContext *cx)
 {
     JSRuntime *rt = cx->runtime;
 
     if (!rt->scriptAndCountsVector)
         return;
     JS_ASSERT(!rt->profilingScripts);
 
-    ReleaseScriptCounts(cx);
+    ReleaseScriptCounts(rt->defaultFreeOp());
 }
 
 } /* namespace js */
 
 JS_PUBLIC_API(void)
 JS_IterateCompartments(JSRuntime *rt, void *data,
                        JSIterateCompartmentCallback compartmentCallback)
 {
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -79,17 +79,16 @@ class GCHelperThread;
 struct Shape;
 
 namespace gc {
 
 enum State {
     NO_INCREMENTAL,
     MARK_ROOTS,
     MARK,
-    SWEEP,
     INVALID
 };
 
 struct Arena;
 
 /*
  * This must be an upper bound, but we do not need the least upper bound, so
  * we just exclude non-background objects.
@@ -1393,23 +1392,23 @@ typedef enum JSGCInvocationKind {
     /* Normal invocation. */
     GC_NORMAL           = 0,
 
     /* Minimize GC triggers and release empty GC chunks right away. */
     GC_SHRINK             = 1
 } JSGCInvocationKind;
 
 extern void
-GC(JSContext *cx, JSGCInvocationKind gckind, js::gcreason::Reason reason);
+GC(JSRuntime *rt, JSGCInvocationKind gckind, js::gcreason::Reason reason);
 
 extern void
-GCSlice(JSContext *cx, JSGCInvocationKind gckind, js::gcreason::Reason reason);
+GCSlice(JSRuntime *rt, JSGCInvocationKind gckind, js::gcreason::Reason reason);
 
 extern void
-GCDebugSlice(JSContext *cx, bool limit, int64_t objCount);
+GCDebugSlice(JSRuntime *rt, bool limit, int64_t objCount);
 
 extern void
 PrepareForDebugGC(JSRuntime *rt);
 
 } /* namespace js */
 
 namespace js {
 
@@ -1441,17 +1440,17 @@ class GCHelperThread {
     static const size_t FREE_ARRAY_LENGTH = FREE_ARRAY_SIZE / sizeof(void *);
 
     JSRuntime         *const rt;
     PRThread          *thread;
     PRCondVar         *wakeup;
     PRCondVar         *done;
     volatile State    state;
 
-    JSContext         *finalizationContext;
+    bool              sweepFlag;
     bool              shrinkFlag;
 
     Vector<void **, 16, js::SystemAllocPolicy> freeVector;
     void            **freeCursor;
     void            **freeCursorEnd;
 
     Vector<js::gc::ArenaHeader *, 64, js::SystemAllocPolicy> finalizeVector;
 
@@ -1477,28 +1476,28 @@ class GCHelperThread {
 
   public:
     GCHelperThread(JSRuntime *rt)
       : rt(rt),
         thread(NULL),
         wakeup(NULL),
         done(NULL),
         state(IDLE),
-        finalizationContext(NULL),
+        sweepFlag(false),
         shrinkFlag(false),
         freeCursor(NULL),
         freeCursorEnd(NULL),
         backgroundAllocation(true)
     { }
 
     bool init();
     void finish();
 
     /* Must be called with the GC lock taken. */
-    void startBackgroundSweep(JSContext *cx, bool shouldShrink);
+    void startBackgroundSweep(bool shouldShrink);
 
     /* Must be called with the GC lock taken. */
     void startBackgroundShrink();
 
     /* Must be called with the GC lock taken. */
     void waitBackgroundSweepEnd();
 
     /* Must be called with the GC lock taken. */
@@ -1989,25 +1988,25 @@ const int ZealAllocValue = 2;
 const int ZealFrameGCValue = 3;
 const int ZealVerifierValue = 4;
 const int ZealFrameVerifierValue = 5;
 
 #ifdef JS_GC_ZEAL
 
 /* Check that write barriers have been used correctly. See jsgc.cpp. */
 void
-VerifyBarriers(JSContext *cx);
+VerifyBarriers(JSRuntime *rt);
 
 void
 MaybeVerifyBarriers(JSContext *cx, bool always = false);
 
 #else
 
 static inline void
-VerifyBarriers(JSContext *cx)
+VerifyBarriers(JSRuntime *rt)
 {
 }
 
 static inline void
 MaybeVerifyBarriers(JSContext *cx, bool always = false)
 {
 }
 
--- a/js/src/jsgcmark.cpp
+++ b/js/src/jsgcmark.cpp
@@ -105,16 +105,17 @@ MarkInternal(JSTracer *trc, T **thingp)
      * Don't mark things outside a compartment if we are in a per-compartment
      * GC.
      */
     if (!trc->callback) {
         if (thing->compartment()->isCollecting())
             PushMarkStack(static_cast<GCMarker *>(trc), thing);
     } else {
         trc->callback(trc, (void **)thingp, GetGCThingTraceKind(thing));
+        JS_SET_TRACING_LOCATION(trc, NULL);
     }
 
 #ifdef DEBUG
     trc->debugPrinter = NULL;
     trc->debugPrintArg = NULL;
 #endif
 }
 
@@ -264,16 +265,17 @@ MarkGCThingRoot(JSTracer *trc, void **th
     MarkKind(trc, thingp, GetGCThingTraceKind(*thingp));
 }
 
 /*** ID Marking ***/
 
 static inline void
 MarkIdInternal(JSTracer *trc, jsid *id)
 {
+    JS_SET_TRACING_LOCATION(trc, (void *)id);
     if (JSID_IS_STRING(*id)) {
         JSString *str = JSID_TO_STRING(*id);
         MarkInternal(trc, &str);
         *id = ATOM_TO_JSID(reinterpret_cast<JSAtom *>(str));
     } else if (JS_UNLIKELY(JSID_IS_OBJECT(*id))) {
         JSObject *obj = JSID_TO_OBJECT(*id);
         MarkInternal(trc, &obj);
         *id = OBJECT_TO_JSID(obj);
@@ -314,16 +316,17 @@ MarkIdRootRange(JSTracer *trc, size_t le
     }
 }
 
 /*** Value Marking ***/
 
 static inline void
 MarkValueInternal(JSTracer *trc, Value *v)
 {
+    JS_SET_TRACING_LOCATION(trc, (void *)v);
     if (v->isMarkable()) {
         JS_ASSERT(v->toGCThing());
         void *thing = v->toGCThing();
         MarkKind(trc, &thing, v->gcKind());
         if (v->isString())
             v->setString((JSString *)thing);
         else
             v->setObjectOrNull((JSObject *)thing);
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1504,17 +1504,17 @@ js::Interpret(JSContext *cx, StackFrame 
 
     /*
      * Initialize the index segment register used by LOAD_ATOM and
      * GET_FULL_INDEX macros below. As a register we use a pointer based on
      * the atom map to turn frequently executed LOAD_ATOM into simple array
      * access. For less frequent object loads we have to recover the segment
      * from atoms pointer first.
      */
-    JSAtom **atoms = script->atoms;
+    HeapPtrAtom *atoms = script->atoms;
 
 #if JS_HAS_GENERATORS
     if (JS_UNLIKELY(regs.fp()->isGeneratorFrame())) {
         JS_ASSERT((size_t) (regs.pc - script->code) <= script->length);
         JS_ASSERT((size_t) (regs.sp - regs.fp()->base()) <= StackDepth(script));
 
         /*
          * To support generator_throw and to catch ignored exceptions,
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -5256,17 +5256,17 @@ js_SetPropertyHelper(JSContext *cx, JSOb
                         return ReportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
                     return true;
                 }
             }
 
             prop = NULL;
         }
     } else {
-        /* We should never add properties to lexical blocks.  */
+        /* We should never add properties to lexical blocks. */
         JS_ASSERT(!obj->isBlock());
 
         if (obj->isGlobal() &&
             (defineHow & DNP_UNQUALIFIED) &&
             !js::CheckUndeclaredVarAssignment(cx, JSID_TO_STRING(id))) {
             return JS_FALSE;
         }
     }
--- a/js/src/jsscope.h
+++ b/js/src/jsscope.h
@@ -797,17 +797,17 @@ struct Shape : public js::gc::Cell
      *
      * Property cache entries only record the shapes of the first and last
      * objects along the search path, so if the search traverses more than those
      * two objects, then those first and last shapes must determine the shapes
      * of everything else along the path. The js_PurgeScopeChain stuff takes
      * care of making this work, but that suffices only because we require that
      * start points with the same shape have the same successor object in the
      * search path --- a cache hit means the starting shapes were equal, which
-     * means the seach path tail (everything but the first object in the path)
+     * means the search path tail (everything but the first object in the path)
      * was shared, which in turn means the effects of a purge will be seen by
      * all affected starting search points.
      *
      * For call and run-time block objects, the "successor object" is the scope
      * chain parent. Unlike prototype objects (of which there are usually few),
      * scope chain parents are created frequently (possibly on every call), so
      * following the shape-implies-parent rule blindly would lead one to give
      * every call and block its own shape.
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -669,18 +669,26 @@ js::XDRScript(XDRState<mode> *xdr, JSScr
     if (mode == XDR_DECODE) {
         script->lineno = lineno;
         script->nslots = uint16_t(nslots);
         script->staticLevel = uint16_t(nslots >> 16);
         xdr->initScriptPrincipals(script);
     }
 
     for (i = 0; i != natoms; ++i) {
-        if (!XDRAtom(xdr, &script->atoms[i]))
-            return false;
+        if (mode == XDR_DECODE) {
+            JSAtom *tmp = NULL;
+            if (!XDRAtom(xdr, &tmp))
+                return false;
+            script->atoms[i].init(tmp);
+        } else {
+            JSAtom *tmp = script->atoms[i];
+            if (!XDRAtom(xdr, &tmp))
+                return false;
+        }
     }
 
     /*
      * Here looping from 0-to-length to xdr objects is essential. It ensures
      * that block objects from the script->objects array will be written and
      * restored in the outer-to-inner order. js_XDRBlockObject relies on this
      * to restore the parent chain.
      */
@@ -1101,17 +1109,17 @@ JSScript::NewScript(JSContext *cx, uint3
         JS_ASSERT(reinterpret_cast<uintptr_t>(cursor) % sizeof(jsval) == 0);
         script->consts()->length = nconsts;
         script->consts()->vector = (HeapValue *)cursor;
         cursor += nconsts * sizeof(script->consts()->vector[0]);
     }
 
     if (natoms != 0) {
         script->natoms = natoms;
-        script->atoms = reinterpret_cast<JSAtom **>(cursor);
+        script->atoms = reinterpret_cast<HeapPtrAtom *>(cursor);
         cursor += natoms * sizeof(script->atoms[0]);
     }
 
     if (nobjects != 0) {
         script->objects()->length = nobjects;
         script->objects()->vector = (HeapPtr<JSObject> *)cursor;
         cursor += nobjects * sizeof(script->objects()->vector[0]);
     }
@@ -1200,17 +1208,17 @@ JSScript::NewScriptFromEmitter(JSContext
 
     JS_ASSERT(script->mainOffset == 0);
     script->mainOffset = prologLength;
     PodCopy<jsbytecode>(script->code, bce->prologBase(), prologLength);
     PodCopy<jsbytecode>(script->main(), bce->base(), mainLength);
     nfixed = bce->inFunction() ? bce->bindings.countVars() : 0;
     JS_ASSERT(nfixed < SLOTNO_LIMIT);
     script->nfixed = uint16_t(nfixed);
-    js_InitAtomMap(cx, bce->atomIndices.getMap(), script->atoms);
+    InitAtomMap(cx, bce->atomIndices.getMap(), script->atoms);
 
     filename = bce->parser->tokenStream.getFilename();
     if (filename) {
         script->filename = SaveScriptFilename(cx, filename);
         if (!script->filename)
             return NULL;
     }
     script->lineno = bce->firstLine;
@@ -1783,30 +1791,30 @@ JSScript::destroyBreakpointSite(FreeOp *
 
     if (--debug->numSites == 0 && !stepModeEnabled()) {
         fop->free_(debug);
         debug = NULL;
     }
 }
 
 void
-JSScript::clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSObject *handler)
+JSScript::clearBreakpointsIn(FreeOp *fop, js::Debugger *dbg, JSObject *handler)
 {
     if (!hasAnyBreakpointsOrStepMode())
         return;
 
     jsbytecode *end = code + length;
     for (jsbytecode *pc = code; pc < end; pc++) {
         BreakpointSite *site = getBreakpointSite(pc);
         if (site) {
             Breakpoint *nextbp;
             for (Breakpoint *bp = site->firstBreakpoint(); bp; bp = nextbp) {
                 nextbp = bp->nextInSite();
                 if ((!dbg || bp->debugger == dbg) && (!handler || bp->getHandler() == handler))
-                    bp->destroy(cx->runtime->defaultFreeOp());
+                    bp->destroy(fop);
             }
         }
     }
 }
 
 void
 JSScript::clearTraps(FreeOp *fop)
 {
@@ -1823,17 +1831,17 @@ JSScript::clearTraps(FreeOp *fop)
 
 void
 JSScript::markChildren(JSTracer *trc)
 {
     JS_ASSERT_IF(trc->runtime->gcStrictCompartmentChecking, compartment()->isCollecting());
 
     for (uint32_t i = 0; i < natoms; ++i) {
         if (atoms[i])
-            MarkStringUnbarriered(trc, &atoms[i], "atom");
+            MarkString(trc, &atoms[i], "atom");
     }
 
     if (JSScript::isValidOffset(objectsOffset)) {
         JSObjectArray *objarray = objects();
         MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
     }
 
     if (JSScript::isValidOffset(regexpsOffset)) {
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -296,17 +296,17 @@ class ScriptCounts
      */
     PCCounts *pcCountsVector;
 
  public:
 
     ScriptCounts() : pcCountsVector(NULL) {
     }
 
-    inline void destroy(JSContext *cx);
+    inline void destroy(FreeOp *fop);
 
     void steal(ScriptCounts &other) {
         *this = other;
         js::PodZero(&other);
     }
 
     // Boolean conversion, for 'if (scriptCounts) ...'
     operator void*() const {
@@ -404,17 +404,17 @@ struct JSScript : public js::gc::Cell
     // Word-sized fields.
 
   public:
     jsbytecode      *code;      /* bytecodes and their immediate operands */
     uint8_t         *data;      /* pointer to variable-length data array (see 
                                    comment above NewScript() for details) */
 
     const char      *filename;  /* source filename or null */
-    JSAtom          **atoms;    /* maps immediate index to literal struct */
+    js::HeapPtrAtom *atoms;     /* maps immediate index to literal struct */
 
     JSPrincipals    *principals;/* principals for this script */
     JSPrincipals    *originPrincipals; /* see jsapi.h 'originPrincipals' comment */
 
     jschar          *sourceMap; /* source map file or null */
 
     /*
      * A global object for the script.
@@ -750,17 +750,17 @@ struct JSScript : public js::gc::Cell
     uint32_t nClosedArgs() {
         return isValidOffset(closedArgsOffset) ? closedArgs()->length : 0;
     }
 
     uint32_t nClosedVars() {
         return isValidOffset(closedVarsOffset) ? closedVars()->length : 0;
     }
 
-    JSAtom *getAtom(size_t index) {
+    js::HeapPtrAtom &getAtom(size_t index) const {
         JS_ASSERT(index < natoms);
         return atoms[index];
     }
 
     js::PropertyName *getName(size_t index) {
         return getAtom(index)->asPropertyName();
     }
 
@@ -826,17 +826,17 @@ struct JSScript : public js::gc::Cell
         return debug ? debug->breakpoints[pc - code] : NULL;
     }
 
     js::BreakpointSite *getOrCreateBreakpointSite(JSContext *cx, jsbytecode *pc,
                                                   js::GlobalObject *scriptGlobal);
 
     void destroyBreakpointSite(js::FreeOp *fop, jsbytecode *pc);
 
-    void clearBreakpointsIn(JSContext *cx, js::Debugger *dbg, JSObject *handler);
+    void clearBreakpointsIn(js::FreeOp *fop, js::Debugger *dbg, JSObject *handler);
     void clearTraps(js::FreeOp *fop);
 
     void markTrapClosures(JSTracer *trc);
 
     /*
      * Set or clear the single-step flag. If the flag is set or the count
      * (adjusted by changeStepModeCount) is non-zero, then the script is in
      * single-step mode. (JSD uses an on/off-style interface; Debugger uses a
--- a/js/src/jsscriptinlines.h
+++ b/js/src/jsscriptinlines.h
@@ -134,19 +134,19 @@ CurrentScriptFileLineOrigin(JSContext *c
         *origin = script->originPrincipals;
         return;
     }
 
     CurrentScriptFileLineOriginSlow(cx, file, linenop, origin);
 }
 
 inline void
-ScriptCounts::destroy(JSContext *cx)
+ScriptCounts::destroy(FreeOp *fop)
 {
-    cx->free_(pcCountsVector);
+    fop->free_(pcCountsVector);
 }
 
 } // namespace js
 
 inline void
 JSScript::setFunction(JSFunction *fun)
 {
     function_ = fun;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -641,17 +641,17 @@ Debugger::slowPathOnLeaveFrame(JSContext
     }
 
     /*
      * If this is an eval frame, then from the debugger's perspective the
      * script is about to be destroyed. Remove any breakpoints in it.
      */
     if (fp->isEvalFrame()) {
         JSScript *script = fp->script();
-        script->clearBreakpointsIn(cx, NULL, NULL);
+        script->clearBreakpointsIn(cx->runtime->defaultFreeOp(), NULL, NULL);
     }
 
     /* Establish (status, value) as our resumption value. */
     switch (status) {
       case JSTRAP_RETURN:
         fp->setReturnValue(value);
         return true;
 
@@ -1782,17 +1782,17 @@ Debugger::getNewestFrame(JSContext *cx, 
     return true;
 }
 
 JSBool
 Debugger::clearAllBreakpoints(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_DEBUGGER(cx, argc, vp, "clearAllBreakpoints", args, dbg);
     for (GlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront())
-        r.front()->compartment()->clearBreakpointsIn(cx, dbg, NULL);
+        r.front()->compartment()->clearBreakpointsIn(cx->runtime->defaultFreeOp(), dbg, NULL);
     return true;
 }
 
 JSBool
 Debugger::construct(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
@@ -2895,27 +2895,27 @@ DebuggerScript_clearBreakpoint(JSContext
     REQUIRE_ARGC("Debugger.Script.clearBreakpoint", 1);
     THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "clearBreakpoint", args, obj, script);
     Debugger *dbg = Debugger::fromChildJSObject(obj);
 
     JSObject *handler = NonNullObject(cx, args[0]);
     if (!handler)
         return false;
 
-    script->clearBreakpointsIn(cx, dbg, handler);
+    script->clearBreakpointsIn(cx->runtime->defaultFreeOp(), dbg, handler);
     args.rval().setUndefined();
     return true;
 }
 
 static JSBool
 DebuggerScript_clearAllBreakpoints(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "clearAllBreakpoints", args, obj, script);
     Debugger *dbg = Debugger::fromChildJSObject(obj);
-    script->clearBreakpointsIn(cx, dbg, NULL);
+    script->clearBreakpointsIn(cx->runtime->defaultFreeOp(), dbg, NULL);
     args.rval().setUndefined();
     return true;
 }
 
 static JSBool
 DebuggerScript_construct(JSContext *cx, unsigned argc, Value *vp)
 {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR, "Debugger.Script");
@@ -4300,17 +4300,17 @@ DebuggerEnv_getObject(JSContext *cx, uns
         return false;
     args.rval() = rval;
     return true;
 }
 
 static JSBool
 DebuggerEnv_names(JSContext *cx, unsigned argc, Value *vp)
 {
-    THIS_DEBUGENV_OWNER(cx, argc, vp, "get type", args, envobj, env, dbg);
+    THIS_DEBUGENV_OWNER(cx, argc, vp, "names", args, envobj, env, dbg);
 
     AutoIdVector keys(cx);
     {
         AutoCompartment ac(cx, env);
         if (!ac.enter())
             return false;
 
         ErrorCopier ec(ac, dbg->toJSObject());
@@ -4333,17 +4333,17 @@ DebuggerEnv_names(JSContext *cx, unsigne
     args.rval().setObject(*arr);
     return true;
 }
 
 static JSBool
 DebuggerEnv_find(JSContext *cx, unsigned argc, Value *vp)
 {
     REQUIRE_ARGC("Debugger.Environment.find", 1);
-    THIS_DEBUGENV_OWNER(cx, argc, vp, "get type", args, envobj, env, dbg);
+    THIS_DEBUGENV_OWNER(cx, argc, vp, "find", args, envobj, env, dbg);
 
     jsid id;
     if (!ValueToIdentifier(cx, args[0], &id))
         return false;
 
     {
         AutoCompartment ac(cx, env);
         if (!ac.enter() || !cx->compartment->wrapId(cx, &id))
@@ -4359,26 +4359,96 @@ DebuggerEnv_find(JSContext *cx, unsigned
             if (prop)
                 break;
         }
     }
 
     return dbg->wrapEnvironment(cx, env, &args.rval());
 }
 
+static JSBool
+DebuggerEnv_getVariable(JSContext *cx, unsigned argc, Value *vp)
+{
+    REQUIRE_ARGC("Debugger.Environment.getVariable", 1);
+    THIS_DEBUGENV_OWNER(cx, argc, vp, "getVariable", args, envobj, env, dbg);
+
+    jsid id;
+    if (!ValueToIdentifier(cx, args[0], &id))
+        return false;
+
+    Value v;
+    {
+        AutoCompartment ac(cx, env);
+        if (!ac.enter() || !cx->compartment->wrapId(cx, &id))
+            return false;
+
+        /* This can trigger getters. */
+        ErrorCopier ec(ac, dbg->toJSObject());
+        if (!env->getGeneric(cx, id, &v))
+            return false;
+    }
+
+    if (!dbg->wrapDebuggeeValue(cx, &v))
+        return false;
+    args.rval() = v;
+    return true;
+}
+
+static JSBool
+DebuggerEnv_setVariable(JSContext *cx, unsigned argc, Value *vp)
+{
+    REQUIRE_ARGC("Debugger.Environment.setVariable", 2);
+    THIS_DEBUGENV_OWNER(cx, argc, vp, "setVariable", args, envobj, env, dbg);
+
+    jsid id;
+    if (!ValueToIdentifier(cx, args[0], &id))
+        return false;
+
+    Value v = args[1];
+    if (!dbg->unwrapDebuggeeValue(cx, &v))
+        return false;
+
+    {
+        AutoCompartment ac(cx, env);
+        if (!ac.enter() || !cx->compartment->wrapId(cx, &id) || !cx->compartment->wrap(cx, &v))
+            return false;
+
+        /* This can trigger setters. */
+        ErrorCopier ec(ac, dbg->toJSObject());
+
+        /* Make sure the environment actually has the specified binding. */
+        bool has;
+        if (!env->hasProperty(cx, id, &has))
+            return false;
+        if (!has) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEBUG_VARIABLE_NOT_FOUND);
+            return false;
+        }
+
+        /* Just set the property. */
+        if (!env->setGeneric(cx, id, &v, true))
+            return false;
+    }
+
+    args.rval().setUndefined();
+    return true;
+}
+
 static JSPropertySpec DebuggerEnv_properties[] = {
     JS_PSG("type", DebuggerEnv_getType, 0),
     JS_PSG("object", DebuggerEnv_getObject, 0),
     JS_PSG("parent", DebuggerEnv_getParent, 0),
     JS_PS_END
 };
 
 static JSFunctionSpec DebuggerEnv_methods[] = {
     JS_FN("names", DebuggerEnv_names, 0, 0),
     JS_FN("find", DebuggerEnv_find, 1, 0),
+    JS_FN("getVariable", DebuggerEnv_getVariable, 1, 0),
+    JS_FN("setVariable", DebuggerEnv_setVariable, 2, 0),
     JS_FS_END
 };
 
 
 
 /*** Glue ****************************************************************************************/
 
 extern JS_PUBLIC_API(JSBool)
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -256,39 +256,35 @@ interface nsIXPCComponents_Utils : nsISu
     [implicit_jscontext]
     xpcIJSWeakReference getWeakReference(in jsval obj);
 
     /*
      * To be called from JS only.
      *
      * Force an immediate garbage collection cycle.
      */
-    [implicit_jscontext]
     void forceGC();
     
     /*
      * To be called from JS only.
      *
      * Force an immediate shrinking garbage collection cycle.
      */
-    [implicit_jscontext]
     void forceShrinkingGC();
 
     /*
      * Schedule a garbage collection cycle for a point in the future when no JS
      * is running. Call the provided function once this has occurred.
      */
-    [implicit_jscontext]
     void schedulePreciseGC(in ScheduledGCCallback callback);
     
     /*
      * Schedule a shrinking garbage collection cycle for a point in the future
      * when no JS is running. Call the provided function once this has occured.
      */
-    [implicit_jscontext]
     void schedulePreciseShrinkingGC(in ScheduledGCCallback callback);
 
     /**
      * Return the keys in a weak map.  This operation is
      * non-deterministic because it is affected by the scheduling of the
      * garbage collector and the cycle collector.
      *
      * This should only be used to write tests of the interaction of
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -547,19 +547,20 @@ DumpXPC(JSContext *cx, unsigned argc, js
         xpc->DebugDump(int16_t(depth));
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 static JSBool
 GC(JSContext *cx, unsigned argc, jsval *vp)
 {
-    JS_GC(cx);
+    JSRuntime *rt = JS_GetRuntime(cx);
+    JS_GC(rt);
 #ifdef JS_GCMETER
-    js_DumpGCStats(JS_GetRuntime(cx), stdout);
+    js_DumpGCStats(rt, stdout);
 #endif
     JS_SET_RVAL(cx, vp, JSVAL_VOID);
     return true;
 }
 
 #ifdef JS_GC_ZEAL
 static JSBool
 GCZeal(JSContext *cx, unsigned argc, jsval *vp)
@@ -2008,22 +2009,22 @@ main(int argc, char **argv, char **envp)
 #ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
             // test of late call and release (see below)
             nsCOMPtr<nsIJSContextStack> bogus;
             xpc->WrapJS(cx, glob, NS_GET_IID(nsIJSContextStack),
                         (void**) getter_AddRefs(bogus));
 #endif
             JS_DropPrincipals(rt, gJSPrincipals);
             JS_ClearScope(cx, glob);
-            JS_GC(cx);
+            JS_GC(rt);
             JSContext *oldcx;
             cxstack->Pop(&oldcx);
             NS_ASSERTION(oldcx == cx, "JS thread context push/pop mismatch");
             cxstack = nsnull;