Merge last PGO-green changeset of mozilla-inbound to mozilla-central
authorEd Morley <emorley@mozilla.com>
Tue, 08 Jan 2013 11:32:07 +0000
changeset 118046 dccab70d85540213d3e824595dfb749b84f9abf9
parent 117972 a85b671b78d599397a3b59cac7b0b8d7532cb36a (current diff)
parent 118045 95c4247fc5b77b9d0e52a3c93e6ae97398c3fb15 (diff)
child 118047 8f818068da0921c6689abb5150e9c781340e7c81
push id24144
push useremorley@mozilla.com
push dateTue, 08 Jan 2013 11:32:43 +0000
treeherdermozilla-central@dccab70d8554 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone21.0a1
first release with
nightly linux32
dccab70d8554 / 21.0a1 / 20130108033457 / files
nightly linux64
dccab70d8554 / 21.0a1 / 20130108033457 / files
nightly mac
dccab70d8554 / 21.0a1 / 20130108033457 / files
nightly win32
dccab70d8554 / 21.0a1 / 20130108033457 / files
nightly win64
dccab70d8554 / 21.0a1 / 20130108033457 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
content/base/test/test_bug654352.html
content/svg/content/src/nsSVGViewElement.cpp
content/svg/content/src/nsSVGViewElement.h
testing/mozbase/mozcrash/README.md
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -87,18 +87,18 @@ using namespace mozilla::a11y;
  * Return true if the element must be accessible.
  */
 static bool
 MustBeAccessible(nsIContent* aContent, DocAccessible* aDocument)
 {
   if (aContent->GetPrimaryFrame()->IsFocusable())
     return true;
 
-  PRUint32 attrCount = aContent->GetAttrCount();
-  for (PRUint32 attrIdx = 0; attrIdx < attrCount; attrIdx++) {
+  uint32_t attrCount = aContent->GetAttrCount();
+  for (uint32_t attrIdx = 0; attrIdx < attrCount; attrIdx++) {
     const nsAttrName* attr = aContent->GetAttrNameAt(attrIdx);
     if (attr->NamespaceEquals(kNameSpaceID_None)) {
       nsIAtom* attrAtom = attr->Atom();
       nsDependentAtomString attrStr(attrAtom);
       if (!StringBeginsWith(attrStr, NS_LITERAL_STRING("aria-")))
         continue; // not ARIA
 
       // A global state or a property and in case of token defined.
--- a/b2g/components/ContentPermissionPrompt.js
+++ b/b2g/components/ContentPermissionPrompt.js
@@ -83,22 +83,42 @@ ContentPermissionPrompt.prototype = {
     if (result == Ci.nsIPermissionManager.DENY_ACTION ||
         result == Ci.nsIPermissionManager.UNKNOWN_ACTION && PROMPT_FOR_UNKNOWN.indexOf(access) < 0) {
       request.cancel();
       return true;
     }
     return false;
   },
 
-  _id: 0,
   prompt: function(request) {
     // returns true if the request was handled
     if (this.handleExistingPermission(request))
        return;
 
+    // If the request was initiated from a hidden iframe
+    // we don't forward it to content and cancel it right away
+    let frame = request.element;
+
+    if (!frame) {
+      this.delegatePrompt(request);
+    }
+
+    var self = this;
+    frame.wrappedJSObject.getVisible().onsuccess = function gv_success(evt) {
+      if (!evt.target.result) {
+        request.cancel();
+        return;
+      }
+
+      self.delegatePrompt(request);
+    };
+  },
+
+  _id: 0,
+  delegatePrompt: function(request) {
     let browser = Services.wm.getMostRecentWindow("navigator:browser");
     let content = browser.getContentWindow();
     if (!content)
       return;
 
     let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
                                                                    request.type;
 
--- a/browser/base/content/browser-social.js
+++ b/browser/base/content/browser-social.js
@@ -127,17 +127,17 @@ let SocialUI = {
 
         case "nsPref:changed":
           if (data == "social.sidebar.open") {
             SocialSidebar.update();
           }
           break;
       }
     } catch (e) {
-      Components.utils.reportError(e + e.stack);
+      Components.utils.reportError(e + "\n" + e.stack);
       throw e;
     }
   },
 
   nonBrowserWindowInit: function SocialUI_nonBrowserInit() {
     // Disable the social menu item in non-browser windows
     document.getElementById("menu_socialAmbientMenu").hidden = true;
   },
@@ -714,16 +714,18 @@ var SocialToolbar = {
     this._dynamicResizer = new DynamicResizeWatcher();
   },
 
   // Called when the Social.provider changes
   updateProvider: function () {
     if (!Social.provider)
       return;
     this.button.style.listStyleImage = "url(" + Social.provider.iconURL + ")";
+    this.button.setAttribute("label", Social.provider.name);
+    this.button.setAttribute("tooltiptext", Social.provider.name);
     this.updateButton();
     this.updateProfile();
     this.populateProviderMenus();
   },
 
   get button() {
     return document.getElementById("social-provider-button");
   },
@@ -774,17 +776,16 @@ var SocialToolbar = {
   },
 
   // XXX doesn't this need to be called for profile changes, given its use of provider.profile?
   updateButton: function SocialToolbar_updateButton() {
     this.updateButtonHiddenState();
     let provider = Social.provider;
     let icons = provider.ambientNotificationIcons;
     let iconNames = Object.keys(icons);
-    let iconBox = document.getElementById("social-toolbar-item");
     let panel = document.getElementById("social-notification-panel");
     panel.hidden = false;
 
     let command = document.getElementById("Social:ToggleNotifications");
     command.setAttribute("checked", Services.prefs.getBoolPref("social.toast-notifications.enabled"));
 
     const CACHE_PREF_NAME = "social.cached.ambientNotificationIcons";
     // provider.profile == undefined means no response yet from the provider
@@ -819,28 +820,27 @@ var SocialToolbar = {
       // "cache" so we can use them next startup.
       let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
       str.data = JSON.stringify({provider: Social.provider.origin, data: icons});
       Services.prefs.setComplexValue(CACHE_PREF_NAME,
                                      Ci.nsISupportsString,
                                      str);
     }
 
-    let iconContainers = document.createDocumentFragment();
+    let toolbarButtons = document.createDocumentFragment();
 
     let createdFrames = [];
 
     for each(let name in iconNames) {
       let icon = icons[name];
 
       let notificationFrameId = "social-status-" + icon.name;
       let notificationFrame = document.getElementById(notificationFrameId);
 
       if (!notificationFrame) {
-
         notificationFrame = SharedFrame.createFrame(
           notificationFrameId, /* frame name */
           panel, /* parent */
           {
             "type": "content",
             "mozbrowser": "true",
             "class": "social-panel-frame",
             "id": notificationFrameId,
@@ -855,85 +855,70 @@ var SocialToolbar = {
         );
 
         createdFrames.push(notificationFrame);
       } else {
         notificationFrame.setAttribute("origin", provider.origin);
         SharedFrame.updateURL(notificationFrameId, icon.contentPanel);
       }
 
-      let iconId = "social-notification-icon-" + icon.name;
-      let imageId = iconId + "-image";
-      let labelId = iconId + "-label";
-      let stackId = iconId + "-stack";
-      let stack = document.getElementById(stackId);
-      let image, label;
-      if (stack) {
-        image = document.getElementById(imageId);
-        label = document.getElementById(labelId);
-      } else {
-        let box = document.createElement("box");
-        box.classList.add("toolbarbutton-1");
-        box.setAttribute("id", iconId);
-        // Use the accessibility menuitem label as tooltiptext.
-        if (icon.label)
-          box.setAttribute("tooltiptext", icon.label);
-        box.addEventListener("mousedown", function (e) {
-          if (e.button == 0)
-            SocialToolbar.showAmbientPopup(box);
-        }, false);
-        box.setAttribute("notificationFrameId", notificationFrameId);
-        stack = document.createElement("stack");
-        stack.setAttribute("id", stackId);
-        stack.classList.add("social-notification-icon-stack");
-        stack.classList.add("toolbarbutton-icon");
-        image = document.createElement("image");
-        image.setAttribute("id", imageId);
-        image.classList.add("social-notification-icon-image");
-        image = stack.appendChild(image);
-        label = document.createElement("label");
-        label.setAttribute("id", labelId);
-        label.classList.add("social-notification-icon-label");
-        let hbox = document.createElement("hbox");
-        hbox.classList.add("social-notification-icon-hbox");
-        hbox.setAttribute("align", "start");
-        hbox.setAttribute("pack", "end");
-        label = hbox.appendChild(label);
-        stack.appendChild(hbox);
-        box.appendChild(stack);
-        iconContainers.appendChild(box);
+      let toolbarButtonContainerId = "social-notification-container-" + icon.name;
+      let toolbarButtonId = "social-notification-icon-" + icon.name;
+      let toolbarButtonContainer = document.getElementById(toolbarButtonContainerId);
+      let toolbarButton = document.getElementById(toolbarButtonId);
+      if (!toolbarButtonContainer) {
+        // The container is used to fix an issue with position:absolute on
+        // generated content not being constrained to the bounding box of a
+        // parent toolbarbutton that has position:relative.
+        toolbarButtonContainer = document.createElement("toolbaritem");
+        toolbarButtonContainer.classList.add("social-notification-container");
+        toolbarButtonContainer.setAttribute("id", toolbarButtonContainerId);
+
+        toolbarButton = document.createElement("toolbarbutton");
+        toolbarButton.classList.add("toolbarbutton-1");
+        toolbarButton.setAttribute("id", toolbarButtonId);
+        toolbarButton.setAttribute("notificationFrameId", notificationFrameId);
+        toolbarButton.addEventListener("mousedown", function (event) {
+          if (event.button == 0)
+            SocialToolbar.showAmbientPopup(toolbarButton);
+        });
+
+        toolbarButtonContainer.appendChild(toolbarButton);
+        toolbarButtons.appendChild(toolbarButtonContainer);
       }
 
-      let labelValue = icon.counter || "";
-      // Only update the value attribute if it has changed to reduce layout changes.
-      if (!label.hasAttribute("value") || label.getAttribute("value") != labelValue)
-        label.setAttribute("value", labelValue);
+      toolbarButton.style.listStyleImage = "url(" + icon.iconURL + ")";
+      toolbarButton.setAttribute("label", icon.label);
+      toolbarButton.setAttribute("tooltiptext", icon.label);
 
-      image.style.listStyleImage = "url(" + icon.iconURL + ")";
+      let badge = icon.counter || "";
+      if (toolbarButton.getAttribute("badge") != badge)
+        toolbarButton.setAttribute("badge", badge);
     }
-    iconBox.appendChild(iconContainers);
+    let socialToolbarItem = document.getElementById("social-toolbar-item");
+    socialToolbarItem.appendChild(toolbarButtons);
 
     for (let frame of createdFrames) {
       if (frame.docShell) {
         frame.docShell.isActive = false;
         frame.docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIWebProgress)
                       .addProgressListener(new SocialErrorListener("notification-panel"),
                                            Ci.nsIWebProgress.NOTIFY_STATE_REQUEST |
                                            Ci.nsIWebProgress.NOTIFY_LOCATION);
       }
     }
   },
 
-  showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButtonBox) {
+  showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButton) {
     // Hide any other social panels that may be open.
     SocialFlyout.panel.hidePopup();
 
     let panel = document.getElementById("social-notification-panel");
-    let notificationFrameId = aToolbarButtonBox.getAttribute("notificationFrameId");
+    let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
     let notificationFrame = document.getElementById(notificationFrameId);
 
     let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
     SharedFrame.setOwner(notificationFrameId, notificationFrame);
 
     // Clear dimensions on all browsers so the panel size will
     // only use the selected browser.
     let frameIter = panel.firstElementChild;
@@ -946,25 +931,32 @@ var SocialToolbar = {
       let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
       evt.initCustomEvent(name, true, true, {});
       notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
     }
 
     let dynamicResizer = this._dynamicResizer;
     panel.addEventListener("popuphidden", function onpopuphiding() {
       panel.removeEventListener("popuphidden", onpopuphiding);
-      aToolbarButtonBox.removeAttribute("open");
+      aToolbarButton.removeAttribute("open");
+      aToolbarButton.parentNode.removeAttribute("open");
       dynamicResizer.stop();
       notificationFrame.docShell.isActive = false;
       dispatchPanelEvent("socialFrameHide");
     });
 
     panel.addEventListener("popupshown", function onpopupshown() {
       panel.removeEventListener("popupshown", onpopupshown);
-      aToolbarButtonBox.setAttribute("open", "true");
+      // This attribute is needed on both the button and the
+      // containing toolbaritem since the buttons on OS X have
+      // moz-appearance:none, while their container gets
+      // moz-appearance:toolbarbutton due to the way that toolbar buttons
+      // get combined on OS X.
+      aToolbarButton.setAttribute("open", "true");
+      aToolbarButton.parentNode.setAttribute("open", "true");
       notificationFrame.docShell.isActive = true;
       notificationFrame.docShell.isAppTab = true;
       if (notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
         dynamicResizer.start(panel, notificationFrame);
         dispatchPanelEvent("socialFrameShow");
       } else {
         // first time load, wait for load and dispatch after load
         notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
@@ -972,19 +964,18 @@ var SocialToolbar = {
           dynamicResizer.start(panel, notificationFrame);
           setTimeout(function() {
             dispatchPanelEvent("socialFrameShow");
           }, 0);
         }, true);
       }
     });
 
-    let imageId = aToolbarButtonBox.getAttribute("id") + "-image";
-    let toolbarButtonImage = document.getElementById(imageId);
-    panel.openPopup(toolbarButtonImage, "bottomcenter topright", 0, 0, false, false);
+    let toolbarButtonIcon = document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-icon");
+    panel.openPopup(toolbarButtonIcon, "bottomcenter topright", 0, 0, false, false);
   },
 
   setPanelErrorMessage: function SocialToolbar_setPanelErrorMessage(aNotificationFrame) {
     if (!aNotificationFrame)
       return;
 
     let src = aNotificationFrame.getAttribute("src");
     aNotificationFrame.removeAttribute("src");
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -613,16 +613,20 @@ html|*#gcli-output-frame,
 .browserStack[responsivemode] {
   transition-property: min-width, max-width, min-height, max-height;
 }
 
 .browserStack[responsivemode][notransition] {
   transition: none;
 }
 
+.social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
+  content: attr(badge);
+}
+
 chatbox {
   -moz-binding: url("chrome://browser/content/socialchat.xml#chatbox");
 }
 
 chatbar {
   -moz-binding: url("chrome://browser/content/socialchat.xml#chatbar");
   height: 0;
 }
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -6920,28 +6920,35 @@ function getNavToolbox() gNavToolbox;
 # code is much more readable this way.
 let gPrivateBrowsingUI = {
   init: function PBUI_init() {
     // Do nothing for normal windows
     if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
       return;
     }
 
+#ifdef XP_MACOSX
+    if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
+      document.documentElement.setAttribute("drawintitlebar", true);
+    }
+#endif
+
     // Disable the Clear Recent History... menu item when in PB mode
     // temporary fix until bug 463607 is fixed
     document.getElementById("Tools:Sanitize").setAttribute("disabled", "true");
 
     // Adjust the window's title
     if (window.location.href == getBrowserURL()) {
       let docElement = document.documentElement;
       docElement.setAttribute("title",
         docElement.getAttribute("title_privatebrowsing"));
       docElement.setAttribute("titlemodifier",
         docElement.getAttribute("titlemodifier_privatebrowsing"));
-      docElement.setAttribute("privatebrowsingmode", "temporary");
+      docElement.setAttribute("privatebrowsingmode",
+        PrivateBrowsingUtils.permanentPrivateBrowsing ? "permanent" : "temporary");
       gBrowser.updateTitlebar();
     }
 
     if (gURLBar) {
       // Disable switch to tab autocompletion for private windows
       gURLBar.setAttribute("autocompletesearchparam", "");
     }
   }
--- a/browser/base/content/test/social/browser_social_mozSocial_API.js
+++ b/browser/base/content/test/social/browser_social_mozSocial_API.js
@@ -23,20 +23,20 @@ var tests = {
     let gotSidebarMessage = false;
 
     function checkNext() {
       if (iconsReady && gotSidebarMessage)
         triggerIconPanel();
     }
 
     function triggerIconPanel() {
-      let statusIcon = document.querySelector("#social-toolbar-item > box");
+      let statusIcon = document.querySelector("#social-toolbar-item > .social-notification-container > .toolbarbutton-1");
       info("status icon is " + statusIcon);
       waitForCondition(function() {
-        statusIcon = document.querySelector("#social-toolbar-item > box");
+        statusIcon = document.querySelector("#social-toolbar-item > .social-notification-container > .toolbarbutton-1");
         info("status icon is " + statusIcon);
         return !!statusIcon;
       }, function() {
         // Click the button to trigger its contentPanel
         let panel = document.getElementById("social-notification-panel");
         EventUtils.synthesizeMouseAtCenter(statusIcon, {});
       }, "Status icon didn't become non-hidden");
     }
--- a/browser/base/content/test/social/browser_social_toolbar.js
+++ b/browser/base/content/test/social/browser_social_toolbar.js
@@ -98,27 +98,28 @@ var tests = {
     Social.provider.setAmbientNotification(ambience);
 
     // for Bug 813834.  Check preference whether stored data is correct.
     is(JSON.parse(Services.prefs.getComplexValue("social.cached.ambientNotificationIcons", Ci.nsISupportsString).data).data.testIcon.label, "Test Ambient 1 \u2046", "label is stored into preference correctly");
 
     Social.provider.setAmbientNotification(ambience2);
     Social.provider.setAmbientNotification(ambience3);
 
-    let statusIcon = document.querySelector("#social-toolbar-item > box");
+    let statusIcon = document.querySelector("#social-toolbar-item > .social-notification-container > .toolbarbutton-1");
     waitForCondition(function() {
-      statusIcon = document.querySelector("#social-toolbar-item > box");
+      statusIcon = document.querySelector("#social-toolbar-item > .social-notification-container > .toolbarbutton-1");
       return !!statusIcon;
     }, function () {
-      let statusIconLabel = statusIcon.querySelector("label");
-      is(statusIconLabel.value, "42", "status value is correct");
+      let badge = statusIcon.getAttribute("badge");
+      is(badge, "42", "status value is correct");
 
       ambience.counter = 0;
       Social.provider.setAmbientNotification(ambience);
-      is(statusIconLabel.value, "", "status value is correct");
+      badge = statusIcon.getAttribute("badge");
+      is(badge, "", "status value is correct");
 
       // The menu bar isn't as easy to instrument on Mac.
       if (navigator.platform.contains("Mac"))
         next();
 
       // Test that keyboard accessible menuitem was added.
       let toolsPopup = document.getElementById("menu_ToolsPopup");
       toolsPopup.addEventListener("popupshown", function ontoolspopupshownAmbient() {
--- a/browser/components/Makefile.in
+++ b/browser/components/Makefile.in
@@ -12,18 +12,21 @@ include $(DEPTH)/config/autoconf.mk
 MODULE = browsercomps
 XPIDL_MODULE = browsercompsbase
 
 XPIDLSRCS = \
   nsIBrowserGlue.idl \
   nsIBrowserHandler.idl \
   $(NULL)
 
+EXTRA_COMPONENTS = \
+  BrowserComponents.manifest \
+  $(NULL)
+
 EXTRA_PP_COMPONENTS = \
-  BrowserComponents.manifest \
   nsBrowserContentHandler.js \
   nsBrowserGlue.js \
   $(NULL)
 
 EXTRA_JS_MODULES = distribution.js
 
 PARALLEL_DIRS = \
   about \
--- a/browser/components/downloads/content/allDownloadsViewOverlay.css
+++ b/browser/components/downloads/content/allDownloadsViewOverlay.css
@@ -8,26 +8,25 @@ richlistitem.download {
 
 .download-state:not(          [state="0"]  /* Downloading        */)
                                            .downloadPauseMenuItem,
 .download-state:not(          [state="4"]  /* Paused             */)
                                            .downloadResumeMenuItem,
 .download-state:not(:-moz-any([state="2"], /* Failed             */
                               [state="4"]) /* Paused             */)
                                            .downloadCancelMenuItem,
-.download-state:not(:-moz-any([state="1"], /* Finished           */
-                              [state="2"], /* Failed             */
-                              [state="3"], /* Canceled           */
-                              [state="6"], /* Blocked (parental) */
-                              [state="8"], /* Blocked (dirty)    */
-                              [state="9"]) /* Blocked (policy)   */)
+.download-state[state]:not(:-moz-any([state="1"], /* Finished           */
+                                     [state="2"], /* Failed             */
+                                     [state="3"], /* Canceled           */
+                                     [state="6"], /* Blocked (parental) */
+                                     [state="8"], /* Blocked (dirty)    */
+                                     [state="9"]) /* Blocked (policy)   */)
                                            .downloadRemoveFromHistoryMenuItem,
 .download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
                               [state="0"], /* Downloading        */
                               [state="1"], /* Finished           */
                               [state="4"], /* Paused             */
                               [state="5"]) /* Starting (queued)  */)
                                            .downloadShowMenuItem,
-.download-state[state="7"]                 .downloadCommandsSeparator,
-.download-state:not([state])                 .downloadCommandsSeparator
+.download-state[state="7"]                 .downloadCommandsSeparator
 {
   display: none;
 }
--- a/browser/components/downloads/content/allDownloadsViewOverlay.js
+++ b/browser/components/downloads/content/allDownloadsViewOverlay.js
@@ -149,18 +149,23 @@ DownloadElementShell.prototype = {
     if (!("__downloadURIObj" in this))
       this.__downloadURIObj = NetUtil.newURI(this.downloadURI);
     return this.__downloadURIObj;
   },
 
   get _icon() {
     if (this._targetFileURI)
       return "moz-icon://" + this._targetFileURI + "?size=32";
-    if (this._placesNode)
-      return this.placesNode.icon;
+    if (this._placesNode) {
+      // Try to extract an extension from the uri.
+      let ext = this._downloadURIObj.QueryInterface(Ci.nsIURL).fileExtension;
+      if (ext)
+        return "moz-icon://." + ext + "?size=32";
+      return this._placesNode.icon || "moz-icon://.unknown?size=32";
+    }
     if (this._dataItem)
       throw new Error("Session-download items should always have a target file uri");
     throw new Error("Unexpected download element state");
   },
 
   // Helper for getting a places annotation set for the download.
   _getAnnotation: function DES__getAnnotation(aAnnotation, aDefaultValue) {
     let value;
--- a/browser/components/downloads/src/DownloadsCommon.jsm
+++ b/browser/components/downloads/src/DownloadsCommon.jsm
@@ -432,17 +432,17 @@ this.DownloadsCommon = {
         try {
           if (Services.prefs.getBoolPref(kPrefBdmScanWhenDone)) {
             showAlert = false;
           }
         } catch (ex) { }
       }
 
       if (showAlert) {
-        let name = this.dataItem.target;
+        let name = aFile.leafName;
         let message =
           DownloadsCommon.strings.fileExecutableSecurityWarning(name, name);
         let title =
           DownloadsCommon.strings.fileExecutableSecurityWarningTitle;
         let dontAsk =
           DownloadsCommon.strings.fileExecutableSecurityWarningDontAsk;
 
         let checkbox = { value: false };
--- a/browser/devtools/jar.mn
+++ b/browser/devtools/jar.mn
@@ -22,17 +22,17 @@ browser.jar:
     content/browser/orion.js                      (sourceeditor/orion/orion.js)
 *   content/browser/source-editor-overlay.xul     (sourceeditor/source-editor-overlay.xul)
     content/browser/debugger.xul                  (debugger/debugger.xul)
     content/browser/debugger.css                  (debugger/debugger.css)
     content/browser/debugger-controller.js        (debugger/debugger-controller.js)
     content/browser/debugger-view.js              (debugger/debugger-view.js)
     content/browser/debugger-toolbar.js           (debugger/debugger-toolbar.js)
     content/browser/debugger-panes.js             (debugger/debugger-panes.js)
-*   content/browser/profiler.xul                  (profiler/profiler.xul)
+    content/browser/profiler.xul                  (profiler/profiler.xul)
     content/browser/profiler.css                  (profiler/profiler.css)
     content/browser/devtools/cleopatra.html       (profiler/cleopatra/cleopatra.html)
     content/browser/devtools/profiler/cleopatra/css/ui.css              (profiler/cleopatra/css/ui.css)
     content/browser/devtools/profiler/cleopatra/css/tree.css            (profiler/cleopatra/css/tree.css)
     content/browser/devtools/profiler/cleopatra/css/devtools.css        (profiler/cleopatra/css/devtools.css)
     content/browser/devtools/profiler/cleopatra/js/parser.js            (profiler/cleopatra/js/parser.js)
     content/browser/devtools/profiler/cleopatra/js/parserWorker.js      (profiler/cleopatra/js/parserWorker.js)
     content/browser/devtools/profiler/cleopatra/js/tree.js              (profiler/cleopatra/js/tree.js)
--- a/browser/themes/gnomestripe/browser.css
+++ b/browser/themes/gnomestripe/browser.css
@@ -2339,73 +2339,51 @@ html|*#gcli-output-frame {
   color: #FDF3DE;
   min-width: 16px;
   text-shadow: none;
   background-image: linear-gradient(#B4211B, #8A1915);
   border-radius: 1px;
   -moz-margin-end: 2px;
 }
 
-#social-toolbar-item {
-  -moz-box-orient: horizontal;
-}
-
-#social-toolbar-item > .toolbarbutton-1 {
-  margin: 0;
-  padding: 0;
-  -moz-appearance: toolbarbutton;
-}
-
-.social-notification-icon-hbox {
-  pointer-events: none;
-}
-
-.social-status-button {
-  list-style-image: none;
-}
-
-#social-provider-button {
-  -moz-image-region: rect(0, 16px, 16px, 0);
-}
-
-#social-provider-button > image {
+#social-toolbar-item > .toolbarbutton-1 > .toolbarbutton-icon,
+.social-notification-container > .toolbarbutton-1 > .toolbarbutton-icon {
   margin: 5px 3px;
 }
 
 #social-provider-button > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
-.social-notification-icon-stack {
-  padding: 0;
-}
-
-.social-notification-icon-image {
-  margin: 5px 3px;
-  -moz-image-region: rect(0, 16px, 16px, 0);
-}
-
-.social-notification-icon-hbox {
-  padding: 0;
-}
-
-.social-notification-icon-label {
+.social-notification-container {
+  /* position:relative on .toolbarbutton-1 does not get position:absolute
+     to work as expected on .toolbarbutton-1 generated content. Placing a
+     simple container outside of .toolbarbutton-1 and setting position:relative
+     on the simple container however will work. */
+  position: relative;
+}
+
+.social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
+  /* The |content| property is set in the content stylesheet. */
+  font-size: 9px;
+  font-weight: bold;
+  padding: 0 1px;
+  color: #fff;
   background-color: rgb(240,61,37);
   border: 1px solid rgb(216,55,34);
-  box-shadow: 0px 1px 0px rgba(0,39,121,0.77);
-  padding-right: 1px;
-  padding-left: 1px;
-  color: white;
-  font-size: 9px;
-  font-weight: bold;
-  margin: 0;
-}
-
-.social-notification-icon-label[value=""] {
-  display: none;
+  border-radius: 2px;
+  box-shadow: 0 1px 0 rgba(0,39,121,0.77);
+  position: absolute;
+  top: 2px;
+  right: 2px;
+}
+
+.social-notification-container > .toolbarbutton-1[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+  left: 2px;
+  right: auto;
 }
 
 /* social toolbar provider menu */
 #social-statusarea-popup {
   margin-top: 0;
   margin-left: -12px;
   margin-right: -12px;
 }
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -2387,17 +2387,17 @@ toolbarbutton.chevron > .toolbarbutton-m
   position: relative;
 }
 
 .tabbrowser-tab:-moz-lwtheme {
   color: inherit;
   text-shadow: inherit;
 }
 
-#navigator-toolbox[tabsontop="true"]:not(:-moz-lwtheme)::before {
+#main-window:not([privatebrowsingmode=temporary]) #navigator-toolbox[tabsontop="true"]:not(:-moz-lwtheme)::before {
   /* We want the titlebar to be unified, but we still want to be able
    * to give #TabsToolbar a background. So we can't set -moz-appearance:
    * toolbar on #TabsToolbar itself. Instead, we set it on a box of the
    * right size which is put underneath #TabsToolbar.
    */
   content: '';
   display: block;
   -moz-appearance: toolbar;
@@ -2997,21 +2997,16 @@ toolbarbutton.chevron > .toolbarbutton-m
   list-style-image: url(chrome://browser/skin/Geolocation-16.png);
 }
 @media (min-resolution: 2dppx) {
   #geo-notification-icon {
     list-style-image: url(chrome://browser/skin/Geolocation-16@2x.png);
   }
 }
 
-#notification-popup .text-link, .panel-arrowcontent .text-link {
-  color: #0073e6;
-  text-decoration: none;
-}
-
 #geolocation-learnmore-link {
   -moz-margin-start: 0; /* override default label margin to match description margin */
 }
 
 #indexedDB-notification-icon {
   list-style-image: url(chrome://global/skin/icons/question-16.png);
 }
 @media (min-resolution: 2dppx) {
@@ -3798,83 +3793,70 @@ html|*#gcli-output-frame {
   min-width: 16px;
   text-shadow: none;
   background-image: linear-gradient(#B4211B, #8A1915);
   border-radius: 1px;
 }
 
 /* === social toolbar button === */
 
-/* button icon for the service */
+toolbar[mode="icons"] > *|* > .social-notification-container {
+  -moz-appearance: toolbarbutton;
+}
+
+.social-notification-container > .toolbarbutton-1 {
+  -moz-appearance: none;
+}
+
 #social-toolbar-item {
-  -moz-box-orient: horizontal;
-}
-
-#social-toolbar-item > .toolbarbutton-1:not(:first-child):not(:last-child) {
-  margin-left: 0;
-  margin-right: 0;
-}
-
-#social-toolbar-item > .toolbarbutton-1:first-child {
-  -moz-margin-end: 0;
-}
-
-#social-toolbar-item > .toolbarbutton-1:last-child {
-  -moz-margin-start: 0;
-}
-
-.social-notification-icon-hbox {
-  pointer-events: none;
-}
-
-.social-status-button {
-  list-style-image: none;
+  margin: 0 4px;
 }
 
 #social-provider-button {
   -moz-image-region: rect(0, 16px, 16px, 0);
 }
 
 #social-provider-button > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
-.social-notification-icon-stack {
-  padding: 0;
-}
-
-.social-notification-icon-hbox {
-  padding: 0;
-}
-.social-notification-icon-label {
-  text-align: end;
+.social-notification-container {
+  /* position:relative on .toolbarbutton-1 does not get position:absolute
+     to work as expected on .toolbarbutton-1 generated content. Placing a
+     simple container outside of .toolbarbutton-1 and setting position:relative
+     on the simple container however will work. */
+  position: relative;
+}
+
+.social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
+  /* The |content| property is set in the content stylesheet. */
   font-size: 9px;
   font-weight: bold;
   padding: 0 1px;
-  color: white;
-  margin: 0;
+  color: #fff;
   background-color: rgb(240,61,37);
   border: 1px solid rgb(216,55,34);
+  border-radius: 2px;
   box-shadow: 0 1px 0 rgba(0,39,121,0.77);
-  -moz-margin-end: -4px;
-  margin-top: -4px;
-}
-
-.social-notification-icon-label[value=""] {
-  display: none;
-}
-
-@media (-moz-mac-lion-theme) {
-  .social-notification-icon-stack > image:-moz-window-inactive {
-    opacity: .5;
-  }
-}
-
-.social-notification-icon-image {
-  -moz-image-region: rect(0, 16px, 16px, 0);
+  position: absolute;
+  top: 2px;
+  right: 0;
+}
+
+.social-notification-container > .toolbarbutton-1[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+  left: 0;
+  right: auto;
+}
+
+toolbar[mode="icons"] > *|* > .social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
+  right: -2px;
+}
+
+toolbar[mode="icons"] > *|* > .social-notification-container > .toolbarbutton-1[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+  left: -2px;
 }
 
 /* === end of social toolbar button === */
 
 /* === social toolbar provider menu  === */
 
 .social-statusarea-user-portrait {
   width: 32px;
@@ -4156,8 +4138,32 @@ panel[type="arrow"][popupid="click-to-pl
 
 .center-item-warning-description {
   color: #828282;
 }
 
 .center-item-button {
   min-width: 0;
 }
+
+%ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+#main-window[privatebrowsingmode=temporary] {
+  background-image: url("chrome://browser/skin/privatebrowsing-mask.png");
+  background-position: top right;
+  background-repeat: no-repeat;
+  background-color: -moz-mac-chrome-active;
+}
+
+@media (-moz-mac-lion-theme) {
+  #main-window[privatebrowsingmode=temporary] {
+    background-position: top right 40px;
+  }
+
+  #main-window[privatebrowsingmode=temporary]:-moz-locale-dir(rtl) {
+    background-position: top left 70px;
+  }
+}
+
+#main-window[privatebrowsingmode=temporary]:-moz-window-inactive {
+  background-color: -moz-mac-chrome-inactive;
+}
+%endif
+
--- a/browser/themes/pinstripe/jar.mn
+++ b/browser/themes/pinstripe/jar.mn
@@ -43,16 +43,17 @@ browser.jar:
   skin/classic/browser/panel-expander-open.png
   skin/classic/browser/panel-expander-open@2x.png
   skin/classic/browser/panel-plus-sign.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/page-livemarks@2x.png
   skin/classic/browser/pageInfo.css
   skin/classic/browser/Privacy-16.png
   skin/classic/browser/Privacy-48.png
+  skin/classic/browser/privatebrowsing-mask.png
   skin/classic/browser/reload-stop-go.png
   skin/classic/browser/reload-stop-go@2x.png
   skin/classic/browser/searchbar-dropmarker.png
   skin/classic/browser/searchbar-dropmarker@2x.png
   skin/classic/browser/searchbar.css
   skin/classic/browser/Search.png
   skin/classic/browser/Search@2x.png
   skin/classic/browser/Secure-Glyph.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..92f60e29f9fd71ed62101b7f7f22ea37423387a0
GIT binary patch
literal 1074
zc$@(;1kL-2P)<h;3K|Lk000e1NJLTq001Tc000yS1^@s6;g3%U000B|Nkl<Zc-qB}
z-%pcw7{xVNvLAoIl4%444X~-(j2g@wIAl{|7I(FnESb1nnPFTI#snP{iYY%Tr4)+3
zv;u9BQY}zdX$!=}mSPLCAVtJ>RX~^&5MjMEIr~0u;<9Y-7q12vAKq`z^E~GqHq3?R
zv&}MRd(&~pOIy}39Nz`j1zXlV=#O{5q%MDiBH0@Nyv<0_pYAjZ2VJln9$FWKG$)#K
zY)0xrov0Y`Mrdd{Q+=QV<}du~0%eB=r;bn;>h!AEMn;TszXjJa?n+`h<b@&K&G3j{
z-N8OIq;^C5=`A#-^@_UjP(SIU(Tv`I-?Xr=iOqTbluaF|%fE|ls@T^C<7fSn2&p}=
z7y3|>ZbidaHr!Hp5pvI9{^2s*x)Ic-b&CIWk7^KeV@u-9&UUoNx}eUm!cja(9$bIQ
zrVf(D6nk3Hoa&ZDonphda|#QOqF8wNC*}exc=p>1%-&nV+~_jAEdktN1tWoF%nmQn
zjCRD`g^4J}U6bU&^`~rZv5UJ6(0_7UlBzux^f!%S+PjG9fkiyMyND;A2z^Cu#{Zn4
zx2R3B*^KWw?TT7|^C)?6{VAJUtn|ZX2r0diRPHvTx7LsF?Fe+)o%ngL8o9~UD9gNp
z`yFBY-t$c4erFhpV|tu@zZ&QEso8Fac+*!mL>^p!%H|d;-l>CjuS1f`kIcA!p$`-G
z8MstFl%zJ|mmLD~l53#(_8P`*Perufw<9;HTAaxa2<TQ0&<(roB@eDYWpj&NNEV>^
z*e*%suIs2gYCzz|B*qv)=PUwUPcUo_V#E^0Nb6&am>y%)%Cz>NI19OEF=m|-Z>o;A
zkO$YFvbn_y617n6>XJmc(~82x%jhb(gCTtozAF>(H$K9kj={cuLLiu~6MxeVn+I`I
z?x9=q;QCWGw^;r*4U`{PIov>5k`ehk)Nm+#@M<2wqYA)N6Tm?I1GMIJqb<(`Z=I;a
z&7d7;xu0(6mOQxrl+7)cyR{Y-Nfs{UNo^?Fu18Ly5_KoqVJq_BrpyER5do)T%aI+c
zK=s!~*h{_QtUk-ab}!Kl-LC3Q+5BR$Dk!$Mt;)r1CKSi(@l#wa&csyU$CxUd+gcA<
z!d0eUMSh%ybdkI`HSN;PYkeu3TkOo1O2`uoC`&M{2HP>BB)$c*_$HB3_AX-@@k%dd
z(3^H&?`HsIOBEwFor;x5&&LRm#kHU$&afs>7G<7_kw>Wmb@@-R!puvKAKp_Se{&rQ
zwlpv<|IajtS(I7yWzDa=VsE{eU-`V?aFy%i=ECU7ch6%jpe)K<imYS+cvGqv@eU)M
s@eSj|8bMj<l>N^x^oPgBwSbrZ7l%*`5<vo2aR2}S07*qoM6N<$f`P3K_W%F@
--- a/browser/themes/winstripe/browser.css
+++ b/browser/themes/winstripe/browser.css
@@ -722,17 +722,18 @@ toolbar[mode=full] .toolbarbutton-1 > .t
   -moz-border-end: none;
 }
 
 @navbarLargeIcons@ .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon {
   padding: 8px 3px 7px;
 }
 
 @navbarLargeIcons@ .toolbarbutton-1:not(:hover):not(:active):not([open]) > .toolbarbutton-menubutton-dropmarker::before,
-@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1:not(:hover) + .toolbarbutton-1:not(:hover)::before {
+@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1:not(:hover) + .social-notification-container:not(:hover) > .toolbarbutton-1::before,
+@navbarLargeIcons@ > #social-toolbar-item > .social-notification-container:not(:hover) + .social-notification-container:not(:hover) > .toolbarbutton-1::before {
   content: "";
   display: -moz-box;
   width: 1px;
   height: 18px;
   -moz-margin-end: -1px;
   background-image: linear-gradient(hsla(210,54%,20%,.2) 0, hsla(210,54%,20%,.2) 18px);
   background-clip: padding-box;
   background-position: center;
@@ -3023,65 +3024,66 @@ html|*#gcli-output-frame {
   min-width: 16px;
   text-shadow: none;
   background-image: linear-gradient(#B4211B, #8A1915);
   border-radius: 1px;
   -moz-margin-end: 5px;
 }
 
 /* Social toolbar item */
+
 #social-provider-button {
   -moz-image-region: rect(0, 16px, 16px, 0);
 }
 
 #social-provider-button > .toolbarbutton-menu-dropmarker {
   display: none;
 }
 
-#social-toolbar-item > .toolbarbutton-1 {
-  padding: 5px;
-  -moz-appearance: toolbarbutton;
-}
-
-@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1 {
-  padding: 6px 0;
-}
-
-@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1:first-child {
-  -moz-padding-start: 5px;
-}
-
-@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1:last-child {
-  -moz-padding-end: 5px;
-}
-
-.social-notification-icon-hbox {
-  pointer-events: none;
-  margin-top: -5px;
-  -moz-margin-end: -12px;
-}
-
-.social-notification-icon-label {
-  text-align: end;
+@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1,
+@navbarLargeIcons@ > #social-toolbar-item > .social-notification-container > .toolbarbutton-1 {
+  padding-left: 0;
+  padding-right: 0;
+}
+
+@navbarLargeIcons@ > #social-toolbar-item {
+  margin-left: 5px;
+  margin-right: 5px;
+}
+
+.social-notification-container {
+  /* position:relative on .toolbarbutton-1 does not get position:absolute
+     to work as expected on .toolbarbutton-1 generated content. Placing a
+     simple container outside of .toolbarbutton-1 and setting position:relative
+     on the simple container however will work. */
+  position: relative;
+}
+
+.social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
+  /* The |content| property is set in the content stylesheet. */
   font-size: 9px;
   font-weight: bold;
   padding: 0 1px;
-  color: white;
+  color: #fff;
   background-color: rgb(240,61,37);
   border: 1px solid rgb(216,55,34);
   border-radius: 2px;
   box-shadow: 0 1px 0 rgba(0,39,121,0.77);
-}
-
-.social-notification-icon-label[value=""] {
-  display: none;
-}
-
-.social-notification-icon-image {
-  -moz-image-region: rect(0, 16px, 16px, 0);
+  position: absolute;
+  top: 2px;
+  right: 2px;
+}
+
+@navbarLargeIcons@ > *|* > .social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
+  top: 7px;
+}
+
+.social-notification-container > .toolbarbutton-1[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
+  left: 2px;
+  right: auto;
 }
 
 /* social toolbar provider menu */
 .social-statusarea-popup {
   margin-top: 0;
   margin-left: -12px;
   margin-right: -12px;
 }
@@ -3372,8 +3374,25 @@ chatbox[minimized="true"] {
 
 .center-item-warning-description {
   color: #828282;
 }
 
 .center-item-button {
   min-width: 0;
 }
+
+%ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
+#main-window[privatebrowsingmode=temporary] #toolbar-menubar {
+  background-image: url("chrome://browser/skin/privatebrowsing-dark.png");
+  background-position: top right;
+  background-repeat: no-repeat;
+}
+
+#main-window[privatebrowsingmode=temporary] #toolbar-menubar:-moz-locale-dir(rtl) {
+  background-position: top left;
+}
+
+#main-window[privatebrowsingmode=temporary] #appmenu-button {
+  list-style-image: url("chrome://browser/skin/privatebrowsing-light.png");
+}
+%endif
+
--- a/browser/themes/winstripe/jar.mn
+++ b/browser/themes/winstripe/jar.mn
@@ -39,16 +39,18 @@ browser.jar:
         skin/classic/browser/menu-forward.png
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
         skin/classic/browser/pageInfo.css
         skin/classic/browser/pageInfo.png
         skin/classic/browser/page-livemarks.png                      (feeds/feedIcon16.png)
         skin/classic/browser/Privacy-16.png
         skin/classic/browser/Privacy-48.png
+        skin/classic/browser/privatebrowsing-light.png
+        skin/classic/browser/privatebrowsing-dark.png
         skin/classic/browser/reload-stop-go.png
         skin/classic/browser/searchbar.css
         skin/classic/browser/searchbar-dropdown-arrow.png
         skin/classic/browser/Secure24.png
         skin/classic/browser/setDesktopBackground.css
         skin/classic/browser/click-to-play-warning-stripes.png
         skin/classic/browser/Toolbar.png
         skin/classic/browser/Toolbar-inverted.png
@@ -261,16 +263,18 @@ browser.jar:
         skin/classic/aero/browser/menu-forward.png                   (menu-forward-aero.png)
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
         skin/classic/aero/browser/pageInfo.css
         skin/classic/aero/browser/pageInfo.png                       (pageInfo-aero.png)
         skin/classic/aero/browser/page-livemarks.png                 (feeds/feedIcon16-aero.png)
         skin/classic/aero/browser/Privacy-16.png                     (Privacy-16-aero.png)
         skin/classic/aero/browser/Privacy-48.png                     (Privacy-48-aero.png)
+        skin/classic/aero/browser/privatebrowsing-light.png
+        skin/classic/aero/browser/privatebrowsing-dark.png
         skin/classic/aero/browser/reload-stop-go.png
         skin/classic/aero/browser/searchbar.css
         skin/classic/aero/browser/searchbar-dropdown-arrow.png       (searchbar-dropdown-arrow-aero.png)
         skin/classic/aero/browser/Secure24.png                       (Secure24-aero.png)
         skin/classic/aero/browser/setDesktopBackground.css
         skin/classic/aero/browser/click-to-play-warning-stripes.png
         skin/classic/aero/browser/Toolbar.png
         skin/classic/aero/browser/Toolbar-inverted.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9eaf3aec7e71bd4d7f3e3d91b47fa3717a17a947
GIT binary patch
literal 1355
zc$@)C1+@B!P)<h;3K|Lk000e1NJLTq000^Q000;W1^@s6<bv(R000FNNkl<Zc-rlj
zTTGK@7{{4{4#uo&DJ{nyILX06!KoAmmV#165Tu17P?*ReD!2i22WQxbY|5M*i+BQ5
zP$^K<Q3rycPDG{`o7ogWG+WH>+)Q@0E&lhs&DR^3-7d?ri(lUFd;b6D`R9G}w)q?Y
z{3HAagBC9FTtF;jYgu581A}{aCSD`l2_dnBaD2hzO1Lo(=XK`hG2K4fk*(~-WwWeI
z&zX6wK`aQDr%Ja~=lfSr6bJ74m3Wrpx2t!VC@z@v#l#|!K;f&G?`SIuc>f90nKxBh
zR3+qx$+%D+AtFyc%V0rnh5ql%<oi|L$&{5HGsw#?6a~EZtbTnL21;&V@`FdjJdR{r
zK)!joaCL-$9}-~ntGZ*-_hI7Q8K&F3_1aEQ?^BvFpp$LyDDbcT?oI#Q^K26=$b*E*
zi`7#&th3-$-UzN$&*FN;V~iEdVOT$dVciU_md>L!-HdE``8B<4`%qKbSzO=w2qW1K
zFq}1mvBEigMLiQ$574z`7)SJju<o8lj=bVFW!TP9lrAZ@c4S*IUOI=dqFG$tdLO4U
zM{#)Ld7RE1$E7Xb!>YfBk=*+@Z5Ts`&Wg*%2e_1V&!%<jCT!l5)HAx3LbuK0O35rb
z4VRE1Eg7K<F$;1}@hv#lvdN6TtSRi*bRkdv*6$gT;@edJGE-Xm4ZZ)-lx)U@&3A2F
z)UowjG;907H1gbKUh4Up_3qbn!mPiEwhRk4`W6n_kIpUGC%3yXtp{6V<<He#x>FLj
z6$Yv+iBKZaPZ+&bCoTQKq_v=T?KI92>{%}@`^jIZ+D4uz&a3owi_+7KPByD)(-~-e
z^3Jdf7PORv<~r?B99Y+dB=79AR10Gw;mYBw5NRsQm9^+uJBgm8Nw8<CRg)$mUL{^3
z1Vo6&JFENCqz-(t{x}l6^d@!-9hf0XysmWD>RJpKZ=y!iO4~Kwit$X_5#k=N@)U#z
z3HhO6UIJxSrlk0Jr+NZi>Z>pYy$v5hWR8fxJWR}21O~guMYEn1ALEUh#8&j>-#}$d
z9bOk}cd`r?<mAkggr<5MpPn|1Vjy=K#|#%xsoID9;9bzmOQ4sPAUCiadsZ}~ebq37
zo?DO?RAJZ2TVd-tntdJ?n$eRpjx?WwUtE{U6)b}Vy+pW2i#N3IO>D$T?Kn<oMsYUd
zI{NdbFjzPZi}4oBhDn%K4WU_i(S~W|5UVkbd6?JM(?Pvm$ycyf(+HI~<v6?5EQ19x
zoSk{n@FY*&T#dQ~Z826H3?0CMATtgGno+;34-FB6wt9VRH$IE)fk`!lLkbJin1?|<
z{b-~5#|dp%>#2L}!jna^*(`&F*mouH;)kb`;pdu!R<y6Nq9M|P&lUY>UU?o3nqE4Z
zIwW|c&n9?eJgkha!{Nj)&=@s{gUkDINNKV4e3W2fA<ra&sBG?XEU*XJaU{e(d}WSW
zyy?fvxP924d;-lWy<j&o(IfM>2%);2JSxW}UT>^)UuW5&`Vb9iXVA31m%JUQimwCp
zK9L9_^T_8(IB~PNAP!Ctx$vaX3SoS6v`Bk1PLwjI5@~PA1S`r&3m}$qf11G|Zn3qo
zq78S+^N>7K;led7t~_}RX<}j#H}kJSYH_N4XFS4}2qhxeP_Fr9?wA*FzZ-APqhu@B
z!{cT+{B2OYD8&Xh%!wQ9Oe`iAvib`iN6zEItxjCs;YI%cX8899{RvW$k=wCC>_q?o
N002ovPDHLkV1hb=mlFU0
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c12f50779858230c939f5f96582437fd60e82610
GIT binary patch
literal 696
zc$@*a0!RIcP)<h;3K|Lk000e1NJLTq000yK000mO1^@s678qX}0007iNkl<Zc-pO$
zTWC^o9LN28J09(5Ii+wms<qTLm{t!hXk8z+K@f{otjj|eHwZ@cu*}%r>LrM%aF_Pf
zOZC)(Vz6XeTWPL2%xlwRT}XRLk0F>L+V2PFfJi<BK78Q(F5eI5|39LjR4UaJL4!(2
zID~)*kN^}Q=b*TrxJqAyaCsuYf*Ue`8dwkLfi1vhpdQcy8bF6V4n6L2871csp-@`S
z2-SX{_eyu?{yp}qmrl6fydGiM^irWvSY3&Pp0@8W?lm`VX!CjBPyET}<2Z9I%sB=J
z`g%@xckK)LeKs8<)SwH6GOdC%rcysWa0iKh5sQADiiCsDtIZ+12#zLj(I}MH(Zn2!
zuFUfb#bWV$KA-<uO#riR<uzm%(19)#(pdPGy)!tR7$2Q%Z8qFgNQwPy?@32Gm5T8}
zc>dIX@%%VLiEdb0Ot&76jZ9)c;QuhEriq1rLkf!K*%{|EZa9DJNXKQ3oE%>(Bj@hk
zx&4S2jymo?#vaa&b{!sA_Abq0AG7E{7YfBtY#O?LZK(VhzjL{0Cc_4Dx!h{mQNR4k
zWP&&=-yOEwhS7m86bj+Ub&Ql82nPHvT=*X%;gAQihtPp86cYGCl!_uvZM!ViWFir+
z47puz-HV=gp344@WHPdQr@2o_k!|SUf7l3tyJ6NyiMhqF)jIX^#dL;c;~<aNZG&TS
z3Aq4R9S`n3Vbke&Hk<wId^PQC-EQp13}*4|(1kJ{p-M)S5H!+a(jgO*Q$P>Y?GQ2m
zCR#!cLa!G%13R5CGhv38RSFRT3o=;LLO>4!9f(wL;S%Ue6%w)zdK-ZT++ip}W2W3u
e>wlZt3;zO0QFaOylzPno0000<MNUMnLSTZXFgdXR
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -69,16 +69,17 @@ class nsViewManager;
 class nsPresContext;
 class nsRange;
 class nsScriptLoader;
 class nsSMILAnimationController;
 class nsStyleSet;
 class nsTextNode;
 class nsWindowSizes;
 class nsSmallVoidArray;
+class nsDOMCaretPosition;
 
 namespace mozilla {
 class ErrorResult;
 
 namespace css {
 class Loader;
 class ImageLoader;
 } // namespace css
@@ -1911,16 +1912,29 @@ public:
   virtual nsIDOMStyleSheetList* StyleSheets() = 0;
   void GetSelectedStyleSheetSet(nsAString& aSheetSet);
   virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) = 0;
   virtual void GetLastStyleSheetSet(nsString& aSheetSet) = 0;
   void GetPreferredStyleSheetSet(nsAString& aSheetSet);
   virtual nsIDOMDOMStringList* StyleSheetSets() = 0;
   virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
   Element* ElementFromPoint(float aX, float aY);
+
+  /**
+   * Retrieve the location of the caret position (DOM node and character
+   * offset within that node), given a point.
+   *
+   * @param aX Horizontal point at which to determine the caret position, in
+   *           page coordinates.
+   * @param aY Vertical point at which to determine the caret position, in
+   *           page coordinates.
+   */
+  already_AddRefed<nsDOMCaretPosition>
+    CaretPositionFromPoint(float aX, float aY);
+
   // QuerySelector and QuerySelectorAll already defined on nsINode
   nsINodeList* GetAnonymousNodes(Element& aElement);
   Element* GetAnonymousElementByAttribute(Element& aElement,
                                           const nsAString& aAttrName,
                                           const nsAString& aAttrValue);
   void AddBinding(Element& aElement, const nsAString& aURI,
                   mozilla::ErrorResult& rv);
   void RemoveBinding(Element& aElement, const nsAString& aURI,
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -8848,42 +8848,39 @@ ResetFullScreen(nsIDocument* aDocument, 
     nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
     os->NotifyObservers(aDocument, "ask-children-to-exit-fullscreen", nullptr);
 
     aDocument->EnumerateSubDocuments(ResetFullScreen, aData);
   }
   return true;
 }
 
-NS_IMETHODIMP
-nsDocument::CaretPositionFromPoint(float aX, float aY, nsISupports** aCaretPos)
-{
-  NS_ENSURE_ARG_POINTER(aCaretPos);
-  *aCaretPos = nullptr;
-
+already_AddRefed<nsDOMCaretPosition>
+nsIDocument::CaretPositionFromPoint(float aX, float aY)
+{
   nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
   nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
   nsPoint pt(x, y);
 
   nsIPresShell *ps = GetShell();
   if (!ps) {
-    return NS_OK;
+    return nullptr;
   }
 
   nsIFrame *rootFrame = ps->GetRootFrame();
 
   // XUL docs, unlike HTML, have no frame tree until everything's done loading
   if (!rootFrame) {
-    return NS_OK; // return null to premature XUL callers as a reminder to wait
+    return nullptr;
   }
 
   nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt, true,
                                                       false);
   if (!ptFrame) {
-    return NS_OK;
+    return nullptr;
   }
 
   // GetContentOffsetsFromPoint requires frame-relative coordinates, so we need
   // to adjust to frame-relative coordinates before we can perform this call.
   // It should also not take into account the padding of the frame.
   nsPoint adjustedPoint = pt - ptFrame->GetOffsetTo(rootFrame);
 
   nsFrame::ContentOffsets offsets =
@@ -8901,18 +8898,25 @@ nsDocument::CaretPositionFromPoint(float
                      isText)) {
       node = nonanon;
     } else {
       node = nullptr;
       offset = 0;
     }
   }
 
-  *aCaretPos = new nsDOMCaretPosition(node, offset);
-  NS_ADDREF(*aCaretPos);
+  nsRefPtr<nsDOMCaretPosition> aCaretPos = new nsDOMCaretPosition(node, offset);
+  return aCaretPos.forget();
+}
+
+NS_IMETHODIMP
+nsDocument::CaretPositionFromPoint(float aX, float aY, nsISupports** aCaretPos)
+{
+  NS_ENSURE_ARG_POINTER(aCaretPos);
+  *aCaretPos = nsIDocument::CaretPositionFromPoint(aX, aY).get();
   return NS_OK;
 }
 
 /* static */
 void
 nsDocument::ExitFullScreen()
 {
   // Clear full-screen stacks in all descendant documents.
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -501,18 +501,18 @@ MOCHITEST_FILES_B = \
 		somedatas.resource^headers^ \
 		delayedServerEvents.sjs \
 		test_html_in_xhr.html \
 		file_html_in_xhr.html \
 		file_html_in_xhr2.html \
 		file_html_in_xhr3.html \
 		file_html_in_xhr.sjs \
 		test_bug647518.html \
-		test_bug654352.html \
-                Ahem.ttf \
+		test_caretPositionFromPoint.html \
+		Ahem.ttf \
 		test_bug664916.html \
 		test_bug666604.html \
 		test_bug675121.html \
 		file_bug675121.sjs \
 		test_bug675166.html \
 		test_bug682554.html \
 		test_bug682592.html \
 		bug682592-subframe.html \
rename from content/base/test/test_bug654352.html
rename to content/base/test/test_caretPositionFromPoint.html
--- a/content/base/test/test_bug654352.html
+++ b/content/base/test/test_caretPositionFromPoint.html
@@ -59,16 +59,26 @@
     //checkOffsetsFromPoint(Math.round(test3Rect.left + test3Rect.width - 1), Math.round(test3Rect.top + 1), 0);
 
     // Check the first and last characters of the input.
     var test4Element = document.getElementById('test4');
     var test4Rect = test4Element.getBoundingClientRect();
     checkOffsetsFromPoint(test4Rect.left + 1, test4Rect.top + 1, 0);
     checkOffsetsFromPoint(Math.round(test4Rect.left + convertEmToPx(3)), Math.round(test4Rect.top + 10), 3);
 
+    // Check to make sure that x or y outside the viewport returns null.
+    var nullCp1 = document.caretPositionFromPoint(-10, 0);
+    ok(!nullCp1, "caret position with negative x should be null");
+    var nullCp2 = document.caretPositionFromPoint(0, -10);
+    ok(!nullCp2, "caret position with negative y should be null");
+    var nullCp3 = document.caretPositionFromPoint(9000, 0);
+    ok(!nullCp3, "caret position with x > viewport width should be null");
+    var nullCp4 = document.caretPositionFromPoint(0, 9000);
+    ok(!nullCp4, "caret position with x > viewport height should be null");
+
     // Check the first and last characters of the marquee.
     SimpleTest.finish();
   }
 
   SimpleTest.waitForExplicitFinish();
 </script>
 </head>
 <body onload="doTesting();">
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -3161,19 +3161,16 @@ WebGLContext::ReadPixels(WebGLint x, Web
 
     if (!pixels)
         return ErrorInvalidValue("readPixels: null destination buffer");
 
     const WebGLRectangleObject *framebufferRect = FramebufferRectangleObject();
     WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
     WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
 
-    uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj());
-    int dataType = JS_GetTypedArrayType(pixels->Obj());
-
     uint32_t channels = 0;
 
     // Check the format param
     switch (format) {
         case LOCAL_GL_ALPHA:
             channels = 1;
             break;
         case LOCAL_GL_RGB:
@@ -3200,32 +3197,35 @@ WebGLContext::ReadPixels(WebGLint x, Web
         case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
             bytesPerPixel = 2;
             requiredDataType = js::ArrayBufferView::TYPE_UINT16;
             break;
         default:
             return ErrorInvalidEnum("readPixels: Bad type");
     }
 
+    int dataType = JS_GetArrayBufferViewType(pixels->Obj());
+
     // Check the pixels param type
     if (dataType != requiredDataType)
         return ErrorInvalidOperation("readPixels: Mismatched type/pixels types");
 
     // Check the pixels param size
     CheckedUint32 checked_neededByteLength =
         GetImageSize(height, width, bytesPerPixel, mPixelStorePackAlignment);
 
     CheckedUint32 checked_plainRowSize = CheckedUint32(width) * bytesPerPixel;
 
     CheckedUint32 checked_alignedRowSize =
         RoundedToNextMultipleOf(checked_plainRowSize, mPixelStorePackAlignment);
 
     if (!checked_neededByteLength.isValid())
         return ErrorInvalidOperation("readPixels: integer overflow computing the needed buffer size");
 
+    uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj());
     if (checked_neededByteLength.value() > dataByteLen)
         return ErrorInvalidOperation("readPixels: buffer too small");
 
     void* data = pixels->Data();
     if (!data) {
         ErrorOutOfMemory("readPixels: buffer storage is null. Did we run out of memory?");
         return rv.Throw(NS_ERROR_OUT_OF_MEMORY);
     }
@@ -4885,17 +4885,17 @@ WebGLContext::TexImage2D(WebGLenum targe
                          WebGLenum type, ArrayBufferView *pixels, ErrorResult& rv)
 {
     if (!IsContextStable())
         return;
 
     return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
                            pixels ? pixels->Data() : 0,
                            pixels ? pixels->Length() : 0,
-                           pixels ? (int)JS_GetTypedArrayType(pixels->Obj()) : -1,
+                           pixels ? (int)JS_GetArrayBufferViewType(pixels->Obj()) : -1,
                            WebGLTexelConversions::Auto, false);
 }
 
 void
 WebGLContext::TexImage2D(WebGLenum target, WebGLint level,
                          WebGLenum internalformat, WebGLenum format,
                          WebGLenum type, ImageData* pixels, ErrorResult& rv)
 {
@@ -5039,17 +5039,17 @@ WebGLContext::TexSubImage2D(WebGLenum ta
         return;
 
     if (!pixels)
         return ErrorInvalidValue("texSubImage2D: pixels must not be null!");
 
     return TexSubImage2D_base(target, level, xoffset, yoffset,
                               width, height, 0, format, type,
                               pixels->Data(), pixels->Length(),
-                              JS_GetTypedArrayType(pixels->Obj()),
+                              JS_GetArrayBufferViewType(pixels->Obj()),
                               WebGLTexelConversions::Auto, false);
 }
 
 void
 WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level,
                             WebGLint xoffset, WebGLint yoffset,
                             WebGLenum format, WebGLenum type, ImageData* pixels,
                             ErrorResult& rv)
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -235,16 +235,21 @@ public:
     nsresult rv;
     nsICSSDeclaration* style = nsMappedAttributeElement::GetStyle(&rv);
     if (NS_FAILED(rv)) {
       aError.Throw(rv);
     }
     return style;
   }
 
+  /**
+   * Determine whether an attribute is an event (onclick, etc.)
+   * @param aName the attribute
+   * @return whether the name is an event handler name
+   */
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by nsINode */
 // The using nsINode::Get/SetOn* are to avoid warnings about shadowing the XPCOM
 // getter and setter on nsINode.
 #define FORWARDED_EVENT(name_, id_, type_, struct_)                           \
   using nsINode::GetOn##name_;                                                \
   using nsINode::SetOn##name_;                                                \
@@ -768,23 +773,16 @@ protected:
       RegUnRegAccessKey(false);
     }
   }
 
 private:
   void RegUnRegAccessKey(bool aDoReg);
 
 protected:
-  /**
-   * Determine whether an attribute is an event (onclick, etc.)
-   * @param aName the attribute
-   * @return whether the name is an event handler name
-   */
-  bool IsEventName(nsIAtom* aName);
-
   virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                  const nsAttrValueOrString* aValue,
                                  bool aNotify);
 
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                 const nsAttrValue* aValue, bool aNotify);
 
   virtual nsEventListenerManager*
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -816,18 +816,18 @@ void MediaDecoder::PlaybackEnded()
         mOutputStreams.RemoveElementAt(i);
       }
     }
   }
 
   PlaybackPositionChanged();
   ChangeState(PLAY_STATE_ENDED);
 
+  UpdateReadyStateForData();
   if (mOwner)  {
-    UpdateReadyStateForData();
     mOwner->PlaybackEnded();
   }
 
   // This must be called after |mOwner->PlaybackEnded()| call above, in order
   // to fire the required durationchange.
   if (IsInfinite()) {
     SetInfinite(false);
   }
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -63,17 +63,16 @@ CPPSRCS		= \
 		nsSVGPolyElement.cpp \
 		nsSVGString.cpp \
 		nsSVGRect.cpp \
 		nsSVGSVGElement.cpp \
 		nsSVGSymbolElement.cpp \
 		nsSVGUnknownElement.cpp \
 		nsSVGUseElement.cpp \
 		nsSVGViewBox.cpp \
-		nsSVGViewElement.cpp \
 		SVGAltGlyphElement.cpp \
 		SVGAngle.cpp \
 		SVGAnimatedAngle.cpp \
 		SVGAnimatedBoolean.cpp \
 		SVGAnimatedLengthList.cpp \
 		SVGAnimatedNumberList.cpp \
 		SVGAnimatedPathSegList.cpp \
 		SVGAnimatedPointList.cpp \
@@ -132,16 +131,17 @@ CPPSRCS		= \
 		SVGTitleElement.cpp \
 		SVGTransform.cpp \
 		SVGTransformableElement.cpp \
 		SVGTransformList.cpp \
 		SVGTransformListParser.cpp \
 		SVGTransformListSMILType.cpp \
 		SVGTSpanElement.cpp \
 		SVGViewBoxSMILType.cpp \
+		SVGViewElement.cpp \
 		$(NULL)
 
 include $(topsrcdir)/config/config.mk
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 EXPORTS =  			\
@@ -183,16 +183,17 @@ EXPORTS_mozilla/dom = \
 	SVGSwitchElement.h \
 	SVGTextContentElement.h \
 	SVGTextElement.h \
 	SVGTextPathElement.h \
 	SVGTextPositioningElement.h \
 	SVGTitleElement.h \
 	SVGTransformableElement.h \
 	SVGTSpanElement.h \
+	SVGViewElement.h \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 INCLUDES += 	\
 		-I$(srcdir)/../../../xml/content/src \
 		-I$(srcdir)/../../../../dom \
 		-I$(srcdir)/../../../base/src \
--- a/content/svg/content/src/SVGFragmentIdentifier.cpp
+++ b/content/svg/content/src/SVGFragmentIdentifier.cpp
@@ -1,17 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "SVGFragmentIdentifier.h"
 #include "nsIDOMSVGDocument.h"
 #include "nsSVGSVGElement.h"
-#include "nsSVGViewElement.h"
+#include "mozilla/dom/SVGViewElement.h"
 #include "SVGAnimatedTransformList.h"
 
 using namespace mozilla;
 
 static bool
 IsMatchingParameter(const nsAString &aString, const nsAString &aParameterName)
 {
   // The first two tests ensure aString.Length() > aParameterName.Length()
@@ -22,22 +22,22 @@ IsMatchingParameter(const nsAString &aSt
 }
 
 inline bool
 IgnoreWhitespace(PRUnichar aChar)
 {
   return false;
 }
 
-static nsSVGViewElement*
+static dom::SVGViewElement*
 GetViewElement(nsIDocument *aDocument, const nsAString &aId)
 {
   dom::Element* element = aDocument->GetElementById(aId);
   return (element && element->IsSVG(nsGkAtoms::view)) ?
-            static_cast<nsSVGViewElement*>(element) : nullptr;
+            static_cast<dom::SVGViewElement*>(element) : nullptr;
 }
 
 void 
 SVGFragmentIdentifier::SaveOldPreserveAspectRatio(nsSVGSVGElement *root)
 {
   if (root->mPreserveAspectRatio.IsExplicitlySet()) {
     root->SetPreserveAspectRatioProperty(root->mPreserveAspectRatio.GetBaseValue());
   }
@@ -231,17 +231,17 @@ SVGFragmentIdentifier::ProcessFragmentId
     static_cast<nsSVGSVGElement*>(aDocument->GetRootElement());
 
   if (!rootElement->mUseCurrentView) {
     SaveOldViewBox(rootElement);
     SaveOldPreserveAspectRatio(rootElement);
     SaveOldZoomAndPan(rootElement);
   }
 
-  const nsSVGViewElement *viewElement = GetViewElement(aDocument, aAnchorName);
+  const dom::SVGViewElement *viewElement = GetViewElement(aDocument, aAnchorName);
 
   if (viewElement) {
     if (!rootElement->mCurrentViewID) {
       rootElement->mCurrentViewID = new nsString();
     }
     *rootElement->mCurrentViewID = aAnchorName;
     rootElement->mUseCurrentView = true;
     rootElement->InvalidateTransformNotifyFrame();
rename from content/svg/content/src/nsSVGViewElement.cpp
rename to content/svg/content/src/SVGViewElement.cpp
--- a/content/svg/content/src/nsSVGViewElement.cpp
+++ b/content/svg/content/src/SVGViewElement.cpp
@@ -1,144 +1,183 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-#include "nsSVGViewElement.h"
+#include "mozilla/dom/SVGViewElement.h"
+#include "mozilla/dom/SVGViewElementBinding.h"
 #include "DOMSVGStringList.h"
 
-using namespace mozilla;
-using namespace mozilla::dom;
+DOMCI_NODE_DATA(SVGViewElement, mozilla::dom::SVGViewElement)
+
+NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(View)
+
+namespace mozilla {
+namespace dom {
 
-nsSVGElement::StringListInfo nsSVGViewElement::sStringListInfo[1] =
+JSObject*
+SVGViewElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
+{
+  return SVGViewElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
+}
+
+nsSVGElement::StringListInfo SVGViewElement::sStringListInfo[1] =
 {
   { &nsGkAtoms::viewTarget }
 };
 
-nsSVGEnumMapping nsSVGViewElement::sZoomAndPanMap[] = {
+nsSVGEnumMapping SVGViewElement::sZoomAndPanMap[] = {
   {&nsGkAtoms::disable, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE},
   {&nsGkAtoms::magnify, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY},
   {nullptr, 0}
 };
 
-nsSVGElement::EnumInfo nsSVGViewElement::sEnumInfo[1] =
+nsSVGElement::EnumInfo SVGViewElement::sEnumInfo[1] =
 {
   { &nsGkAtoms::zoomAndPan,
     sZoomAndPanMap,
     nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY
   }
 };
 
-NS_IMPL_NS_NEW_SVG_ELEMENT(View)
-
 //----------------------------------------------------------------------
 // nsISupports methods
 
-NS_IMPL_ADDREF_INHERITED(nsSVGViewElement,nsSVGViewElementBase)
-NS_IMPL_RELEASE_INHERITED(nsSVGViewElement,nsSVGViewElementBase)
+NS_IMPL_ADDREF_INHERITED(SVGViewElement,SVGViewElementBase)
+NS_IMPL_RELEASE_INHERITED(SVGViewElement,SVGViewElementBase)
 
-DOMCI_NODE_DATA(SVGViewElement, nsSVGViewElement)
-
-NS_INTERFACE_TABLE_HEAD(nsSVGViewElement)
-  NS_NODE_INTERFACE_TABLE6(nsSVGViewElement, nsIDOMNode, nsIDOMElement,
+NS_INTERFACE_TABLE_HEAD(SVGViewElement)
+  NS_NODE_INTERFACE_TABLE6(SVGViewElement, nsIDOMNode, nsIDOMElement,
                            nsIDOMSVGElement, nsIDOMSVGViewElement,
                            nsIDOMSVGFitToViewBox,
                            nsIDOMSVGZoomAndPan)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGViewElement)
-NS_INTERFACE_MAP_END_INHERITING(nsSVGViewElementBase)
+NS_INTERFACE_MAP_END_INHERITING(SVGViewElementBase)
 
 //----------------------------------------------------------------------
 // Implementation
 
-nsSVGViewElement::nsSVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo)
-  : nsSVGViewElementBase(aNodeInfo)
+SVGViewElement::SVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : SVGViewElementBase(aNodeInfo)
 {
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
 
-NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGViewElement)
+NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGViewElement)
 
 //----------------------------------------------------------------------
 // nsIDOMSVGZoomAndPan methods
 
 /* attribute unsigned short zoomAndPan; */
 NS_IMETHODIMP
-nsSVGViewElement::GetZoomAndPan(uint16_t *aZoomAndPan)
+SVGViewElement::GetZoomAndPan(uint16_t *aZoomAndPan)
 {
-  *aZoomAndPan = mEnumAttributes[ZOOMANDPAN].GetAnimValue();
+  *aZoomAndPan = ZoomAndPan();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan)
+SVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan)
+{
+  ErrorResult rv;
+  SetZoomAndPan(aZoomAndPan, rv);
+  return rv.ErrorCode();
+}
+
+void
+SVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
 {
   if (aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE ||
       aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY) {
     mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
-    return NS_OK;
+    return;
   }
 
-  return NS_ERROR_RANGE_ERR;
+  rv.Throw(NS_ERROR_RANGE_ERR);
 }
 
 //----------------------------------------------------------------------
 // nsIDOMSVGFitToViewBox methods
 
 /* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
 NS_IMETHODIMP
-nsSVGViewElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
+SVGViewElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
 {
-  return mViewBox.ToDOMAnimatedRect(aViewBox, this);
+  *aViewBox = ViewBox().get();
+  return NS_OK;
+}
+
+already_AddRefed<nsIDOMSVGAnimatedRect>
+SVGViewElement::ViewBox()
+{
+  nsCOMPtr<nsIDOMSVGAnimatedRect> box;
+  mViewBox.ToDOMAnimatedRect(getter_AddRefs(box), this);
+  return box.forget();
 }
 
 /* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */
 NS_IMETHODIMP
-nsSVGViewElement::GetPreserveAspectRatio(nsISupports
-                                         **aPreserveAspectRatio)
+SVGViewElement::GetPreserveAspectRatio(nsISupports
+                                       **aPreserveAspectRatio)
+{
+  *aPreserveAspectRatio = PreserveAspectRatio().get();
+  return NS_OK;
+}
+
+already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
+SVGViewElement::PreserveAspectRatio()
 {
   nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio;
   mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this);
-  ratio.forget(aPreserveAspectRatio);
-  return NS_OK;
+  return ratio.forget();
 }
 
 //----------------------------------------------------------------------
 // nsIDOMSVGViewElement methods
 
 /* readonly attribute nsIDOMSVGStringList viewTarget; */
-NS_IMETHODIMP nsSVGViewElement::GetViewTarget(nsIDOMSVGStringList * *aViewTarget)
+NS_IMETHODIMP SVGViewElement::GetViewTarget(nsIDOMSVGStringList * *aViewTarget)
 {
-  *aViewTarget = DOMSVGStringList::GetDOMWrapper(
-                   &mStringListAttributes[VIEW_TARGET], this, false, VIEW_TARGET).get();
+  *aViewTarget = ViewTarget().get();
   return NS_OK;
 }
 
+already_AddRefed<nsIDOMSVGStringList>
+SVGViewElement::ViewTarget()
+{
+  return DOMSVGStringList::GetDOMWrapper(
+           &mStringListAttributes[VIEW_TARGET], this, false, VIEW_TARGET);
+}
+
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 nsSVGElement::EnumAttributesInfo
-nsSVGViewElement::GetEnumInfo()
+SVGViewElement::GetEnumInfo()
 {
   return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
                             ArrayLength(sEnumInfo));
 }
 
 nsSVGViewBox *
-nsSVGViewElement::GetViewBox()
+SVGViewElement::GetViewBox()
 {
   return &mViewBox;
 }
 
 SVGAnimatedPreserveAspectRatio *
-nsSVGViewElement::GetPreserveAspectRatio()
+SVGViewElement::GetPreserveAspectRatio()
 {
   return &mPreserveAspectRatio;
 }
 
 nsSVGElement::StringListAttributesInfo
-nsSVGViewElement::GetStringListInfo()
+SVGViewElement::GetStringListInfo()
 {
   return StringListAttributesInfo(mStringListAttributes, sStringListInfo,
                                   ArrayLength(sStringListInfo));
 }
+
+} // namespace dom
+} // namespace mozilla
rename from content/svg/content/src/nsSVGViewElement.h
rename to content/svg/content/src/SVGViewElement.h
--- a/content/svg/content/src/nsSVGViewElement.h
+++ b/content/svg/content/src/SVGViewElement.h
@@ -1,62 +1,79 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-#ifndef __NS_SVGVIEWELEMENT_H__
-#define __NS_SVGVIEWELEMENT_H__
+#ifndef mozilla_dom_SVGViewElement_h
+#define mozilla_dom_SVGViewElement_h
 
 #include "nsIDOMSVGViewElement.h"
 #include "nsIDOMSVGFitToViewBox.h"
 #include "nsIDOMSVGZoomAndPan.h"
 #include "nsSVGElement.h"
 #include "nsSVGEnum.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "SVGStringList.h"
 
+typedef nsSVGElement SVGViewElementBase;
+
+class nsSVGSVGElement;
+class nsSVGOuterSVGFrame;
+
+nsresult NS_NewSVGViewElement(nsIContent **aResult,
+                              already_AddRefed<nsINodeInfo> aNodeInfo);
+
 namespace mozilla {
-  class SVGFragmentIdentifier;
-}
+class SVGFragmentIdentifier;
 
-typedef nsSVGElement nsSVGViewElementBase;
+namespace dom {
 
-class nsSVGViewElement : public nsSVGViewElementBase,
-                         public nsIDOMSVGViewElement,
-                         public nsIDOMSVGFitToViewBox,
-                         public nsIDOMSVGZoomAndPan
+class SVGViewElement : public SVGViewElementBase,
+                       public nsIDOMSVGViewElement,
+                       public nsIDOMSVGFitToViewBox,
+                       public nsIDOMSVGZoomAndPan
 {
+protected:
   friend class mozilla::SVGFragmentIdentifier;
-  friend class nsSVGSVGElement;
-  friend class nsSVGOuterSVGFrame;
-  friend nsresult NS_NewSVGViewElement(nsIContent **aResult,
-                                       already_AddRefed<nsINodeInfo> aNodeInfo);
-  nsSVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  
+  friend class ::nsSVGSVGElement;
+  friend class ::nsSVGOuterSVGFrame;
+  SVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  friend nsresult (::NS_NewSVGViewElement(nsIContent **aResult,
+                                          already_AddRefed<nsINodeInfo> aNodeInfo));
+  virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE;
+
 public:
   // interfaces:
-  
+
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMSVGVIEWELEMENT
   NS_DECL_NSIDOMSVGFITTOVIEWBOX
   NS_DECL_NSIDOMSVGZOOMANDPAN
 
   // xxx If xpcom allowed virtual inheritance we wouldn't need to
   // forward here :-(
   NS_FORWARD_NSIDOMNODE_TO_NSINODE
   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
-  NS_FORWARD_NSIDOMSVGELEMENT(nsSVGViewElementBase::)
+  NS_FORWARD_NSIDOMSVGELEMENT(SVGViewElementBase::)
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   virtual nsXPCClassInfo* GetClassInfo();
 
   virtual nsIDOMNode* AsDOMNode() { return this; }
+
+  // WebIDL
+  uint16_t ZoomAndPan() { return mEnumAttributes[ZOOMANDPAN].GetAnimValue(); }
+  void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
+  already_AddRefed<nsIDOMSVGAnimatedRect> ViewBox();
+  already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
+  already_AddRefed<nsIDOMSVGStringList> ViewTarget();
+
 private:
 
   // nsSVGElement overrides
 
   virtual EnumAttributesInfo GetEnumInfo();
 
   enum { ZOOMANDPAN };
   nsSVGEnum mEnumAttributes[1];
@@ -71,9 +88,12 @@ private:
 
   virtual StringListAttributesInfo GetStringListInfo();
 
   enum { VIEW_TARGET };
   SVGStringList mStringListAttributes[1];
   static StringListInfo sStringListInfo[1];
 };
 
-#endif
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_SVGViewElement_h
--- a/content/svg/content/src/nsDOMSVGZoomEvent.cpp
+++ b/content/svg/content/src/nsDOMSVGZoomEvent.cpp
@@ -2,17 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsDOMSVGZoomEvent.h"
 #include "nsSVGRect.h"
 #include "DOMSVGPoint.h"
 #include "nsSVGSVGElement.h"
-#include "nsIDOMSVGSVGElement.h"
 #include "nsIPresShell.h"
 #include "nsIDocument.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
@@ -39,25 +38,24 @@ nsDOMSVGZoomEvent::nsDOMSVGZoomEvent(nsP
   // been dispatched is not an option since event handler code may change
   // currentScale and currentTranslate in response to this event.
   nsIPresShell *presShell;
   if (mPresContext && (presShell = mPresContext->GetPresShell())) {
     nsIDocument *doc = presShell->GetDocument();
     if (doc) {
       Element *rootElement = doc->GetRootElement();
       if (rootElement) {
-        // If the root element isn't an SVG 'svg' element this QI will fail
+        // If the root element isn't an SVG 'svg' element
         // (e.g. if this event was created by calling createEvent on a
-        // non-SVGDocument). In these circumstances the "New" and "Previous"
+        // non-SVGDocument), then the "New" and "Previous"
         // properties will be left null which is probably what we want.
-        nsCOMPtr<nsIDOMSVGSVGElement> svgElement = do_QueryInterface(rootElement);
-        if (svgElement) {
+        if (rootElement->IsSVG(nsGkAtoms::svg)) {
           nsSVGSVGElement *SVGSVGElement =
             static_cast<nsSVGSVGElement*>(rootElement);
-  
+
           mNewScale = SVGSVGElement->GetCurrentScale();
           mPreviousScale = SVGSVGElement->GetPreviousScale();
 
           const nsSVGTranslatePoint& translate =
             SVGSVGElement->GetCurrentTranslate();
           mNewTranslate =
             new DOMSVGPoint(translate.GetX(), translate.GetY());
           mNewTranslate->SetReadonly(true);
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -23,17 +23,17 @@
 #include "nsIFrame.h"
 #include "nsISVGSVGFrame.h" //XXX
 #include "nsSVGRect.h"
 #include "nsError.h"
 #include "nsISVGChildFrame.h"
 #include "nsGUIEvent.h"
 #include "nsSVGSVGElement.h"
 #include "nsSVGUtils.h"
-#include "nsSVGViewElement.h"
+#include "mozilla/dom/SVGViewElement.h"
 #include "nsStyleUtil.h"
 #include "SVGContentUtils.h"
 
 #include "nsEventDispatcher.h"
 #include "nsSMILTimeContainer.h"
 #include "nsSMILAnimationController.h"
 #include "nsSMILTypes.h"
 #include "nsIContentIterator.h"
@@ -603,21 +603,21 @@ nsSVGSVGElement::GetPreserveAspectRatio(
 
 //----------------------------------------------------------------------
 // nsIDOMSVGZoomAndPan methods
 
 /* attribute unsigned short zoomAndPan; */
 NS_IMETHODIMP
 nsSVGSVGElement::GetZoomAndPan(uint16_t *aZoomAndPan)
 {
-  nsSVGViewElement* viewElement = GetCurrentViewElement();
+  SVGViewElement* viewElement = GetCurrentViewElement();
   if (viewElement && viewElement->mEnumAttributes[
-                       nsSVGViewElement::ZOOMANDPAN].IsExplicitlySet()) {
+                       SVGViewElement::ZOOMANDPAN].IsExplicitlySet()) {
     *aZoomAndPan = viewElement->mEnumAttributes[
-                     nsSVGViewElement::ZOOMANDPAN].GetAnimValue();
+                     SVGViewElement::ZOOMANDPAN].GetAnimValue();
   } else {
     *aZoomAndPan = mEnumAttributes[ZOOMANDPAN].GetAnimValue();
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan)
@@ -969,37 +969,37 @@ nsSVGSVGElement::InvalidateTransformNoti
 
 bool
 nsSVGSVGElement::HasPreserveAspectRatio()
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::preserveAspectRatio) ||
     mPreserveAspectRatio.IsAnimated();
 }
 
-nsSVGViewElement*
+SVGViewElement*
 nsSVGSVGElement::GetCurrentViewElement() const
 {
   if (mCurrentViewID) {
     nsIDocument* doc = GetCurrentDoc();
     if (doc) {
       Element *element = doc->GetElementById(*mCurrentViewID);
       if (element && element->IsSVG(nsGkAtoms::view)) {
-        return static_cast<nsSVGViewElement*>(element);
+        return static_cast<SVGViewElement*>(element);
       }
     }
   }
   return nullptr;
 }
 
 nsSVGViewBoxRect
 nsSVGSVGElement::GetViewBoxWithSynthesis(
   float aViewportWidth, float aViewportHeight) const
 {
   // The logic here should match HasViewBox().
-  nsSVGViewElement* viewElement = GetCurrentViewElement();
+  SVGViewElement* viewElement = GetCurrentViewElement();
   if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
     return viewElement->mViewBox.GetAnimValue();
   }
   if (mViewBox.IsExplicitlySet()) {
     return mViewBox.GetAnimValue();
   }
 
   if (ShouldSynthesizeViewBox()) {
@@ -1024,17 +1024,17 @@ nsSVGSVGElement::GetPreserveAspectRatioW
   nsIDocument* doc = GetCurrentDoc();
   if (doc && doc->IsBeingUsedAsImage()) {
     const SVGPreserveAspectRatio *pAROverridePtr = GetPreserveAspectRatioProperty();
     if (pAROverridePtr) {
       return *pAROverridePtr;
     }
   }
 
-  nsSVGViewElement* viewElement = GetCurrentViewElement();
+  SVGViewElement* viewElement = GetCurrentViewElement();
 
   // This check is equivalent to "!HasViewBox() && ShouldSynthesizeViewBox()".
   // We're just holding onto the viewElement that HasViewBox() would look up,
   // so that we don't have to look it up again later.
   if (!((viewElement && viewElement->mViewBox.IsExplicitlySet()) ||
         mViewBox.IsExplicitlySet()) &&
       ShouldSynthesizeViewBox()) {
     // If we're synthesizing a viewBox, use preserveAspectRatio="none";
@@ -1050,17 +1050,17 @@ nsSVGSVGElement::GetPreserveAspectRatioW
 //----------------------------------------------------------------------
 // nsSVGSVGElement
 
 float
 nsSVGSVGElement::GetLength(uint8_t aCtxType)
 {
   float h, w;
 
-  nsSVGViewElement* viewElement = GetCurrentViewElement();
+  SVGViewElement* viewElement = GetCurrentViewElement();
   const nsSVGViewBoxRect* viewbox = nullptr;
 
   // The logic here should match HasViewBox().
   if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
     viewbox = &viewElement->mViewBox.GetAnimValue();
   } else if (mViewBox.IsExplicitlySet()) {
     viewbox = &mViewBox.GetAnimValue();
   }
@@ -1172,17 +1172,17 @@ SVGAnimatedPreserveAspectRatio *
 nsSVGSVGElement::GetPreserveAspectRatio()
 {
   return &mPreserveAspectRatio;
 }
 
 bool
 nsSVGSVGElement::HasViewBox() const
 {
-  nsSVGViewElement* viewElement = GetCurrentViewElement();
+  SVGViewElement* viewElement = GetCurrentViewElement();
   if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
     return true;
   }
   return mViewBox.IsExplicitlySet();
 }
 
 bool
 nsSVGSVGElement::ShouldSynthesizeViewBox() const
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -16,20 +16,23 @@
 #include "nsSVGLength2.h"
 #include "SVGGraphicsElement.h"
 #include "nsSVGViewBox.h"
 #include "SVGPreserveAspectRatio.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "mozilla/Attributes.h"
 
 class nsSMILTimeContainer;
-class nsSVGViewElement;
 namespace mozilla {
   class DOMSVGMatrix;
   class SVGFragmentIdentifier;
+
+  namespace dom {
+    class SVGViewElement;
+  }
 }
 
 typedef mozilla::dom::SVGGraphicsElement nsSVGSVGElementBase;
 
 class nsSVGSVGElement;
 
 class nsSVGTranslatePoint {
 public:
@@ -256,17 +259,17 @@ private:
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
                               bool aCompileEventHandlers);
   virtual void UnbindFromTree(bool aDeep, bool aNullParent);
 
   // implementation helpers:
 
-  nsSVGViewElement* GetCurrentViewElement() const;
+  mozilla::dom::SVGViewElement* GetCurrentViewElement() const;
 
   // Methods for <image> elements to override my "PreserveAspectRatio" value.
   // These are private so that only our friends (nsSVGImageFrame in
   // particular) have access.
   void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
   void ClearImageOverridePreserveAspectRatio();
 
   // Set/Clear properties to hold old or override versions of attributes
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -1030,16 +1030,22 @@ this.DOMApplicationRegistry = {
     let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
     appFile.moveTo(dir, "application.zip");
     manFile.moveTo(dir, "manifest.webapp");
 
     try {
       tmpDir.remove(true);
     } catch(e) { }
 
+    // Flush the zip reader cache to make sure we use the new application.zip
+    // when re-launching the application.
+    let zipFile = dir.clone();
+    zipFile.append("application.zip");
+    Services.obs.notifyObservers(zipFile, "flush-cache-entry", null);
+
     // Get the manifest, and set properties.
     this.getManifestFor(app.origin, (function(aData) {
       app.downloading = false;
       app.downloadAvailable = false;
       app.downloadSize = 0;
       app.installState = "installed";
       app.readyToApplyDownload = false;
       delete app.retryingDownload;
@@ -1123,16 +1129,22 @@ this.DOMApplicationRegistry = {
 
       // if the app manifestURL has a app:// scheme, we can't have an
       // update.
       if (app.manifestURL.startsWith("app://")) {
         aMm.sendAsyncMessage("Webapps:CheckForUpdate:Return:KO", aData);
         return;
       }
 
+      // Store the new update manifest.
+      let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
+      let manFile = dir.clone();
+      manFile.append("update.webapp");
+      this._writeFile(manFile, JSON.stringify(aManifest), function() { });
+
       let manifest = new ManifestHelper(aManifest, app.manifestURL);
       // A package is available: set downloadAvailable to fire the matching
       // event.
       app.downloadAvailable = true;
       app.downloadSize = manifest.size;
       aData.event = "downloadavailable";
       aData.app = {
         downloadAvailable: true,
@@ -1279,17 +1291,17 @@ this.DOMApplicationRegistry = {
         if (!AppsUtils.checkManifest(manifest)) {
           sendError("INVALID_MANIFEST");
         } else if (!AppsUtils.checkInstallAllowed(manifest, app.installOrigin)) {
           sendError("INSTALL_FROM_DENIED");
         } else {
           app.etag = xhr.getResponseHeader("Etag");
           app.lastCheckedUpdate = Date.now();
           if (app.origin.startsWith("app://")) {
-            updatePackagedApp(manifest);
+            updatePackagedApp.call(this, manifest);
           } else {
             updateHostedApp.call(this, manifest);
           }
         }
         this._saveApps();
       } else if (xhr.status == 304) {
         // The manifest has not changed. We just update lastCheckedUpdate.
         app.lastCheckedUpdate = Date.now();
@@ -2331,28 +2343,27 @@ this.DOMApplicationRegistry = {
 #elifdef XP_MACOSX
     let mwaUtils = Cc["@mozilla.org/widget/mac-web-app-utils;1"]
                      .createInstance(Ci.nsIMacWebAppUtils);
 
     return !!mwaUtils.pathForAppWithIdentifier(aOrigin);
 #elifdef XP_UNIX
     let env = Cc["@mozilla.org/process/environment;1"]
                 .getService(Ci.nsIEnvironment);
-    let xdg_data_home_env = env.get("XDG_DATA_HOME");
+    let xdg_data_home_env;
+    try {
+      xdg_data_home_env = env.get("XDG_DATA_HOME");
+    } catch(ex) {
+    }
 
     let desktopINI;
-    if (xdg_data_home_env != "") {
-      desktopINI = Cc["@mozilla.org/file/local;1"]
-                     .createInstance(Ci.nsIFile);
-      desktopINI.initWithPath(xdg_data_home_env);
-    }
-    else {
-      desktopINI = Services.dirsvc.get("Home", Ci.nsIFile);
-      desktopINI.append(".local");
-      desktopINI.append("share");
+    if (xdg_data_home_env) {
+      desktopINI = new FileUtils.File(xdg_data_home_env);
+    } else {
+      desktopINI = FileUtils.getFile("Home", [".local", "share"]);
     }
     desktopINI.append("applications");
 
     let origin = Services.io.newURI(aOrigin, null, null);
     let uniqueName = origin.scheme + ";" +
                      origin.host +
                      (origin.port != -1 ? ";" + origin.port : "");
 
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -736,17 +736,18 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
   }
 
   mSerial = ++gSerialCounter;
 
 #ifdef DEBUG
   if (!PR_GetEnv("MOZ_QUIET")) {
     printf("++DOMWINDOW == %d (%p) [serial = %d] [outer = %p]\n", gRefCnt,
            static_cast<void*>(static_cast<nsIScriptGlobalObject*>(this)),
-           gSerialCounter, static_cast<void*>(aOuterWindow));
+           gSerialCounter,
+           static_cast<void*>(static_cast<nsIScriptGlobalObject*>(aOuterWindow)));
   }
 #endif
 
 #ifdef PR_LOGGING
   if (gDOMLeakPRLog)
     PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
            ("DOMWINDOW %p created outer=%p", this, aOuterWindow));
 #endif
@@ -811,19 +812,20 @@ nsGlobalWindow::~nsGlobalWindow()
 
       // Data URLs can be very long, so truncate to avoid flooding the log.
       const uint32_t maxURLLength = 1000;
       if (url.Length() > maxURLLength) {
         url.Truncate(maxURLLength);
       }
     }
 
+    nsGlobalWindow* outer = static_cast<nsGlobalWindow*>(mOuterWindow.get());
     printf("--DOMWINDOW == %d (%p) [serial = %d] [outer = %p] [url = %s]\n",
            gRefCnt, static_cast<void*>(static_cast<nsIScriptGlobalObject*>(this)),
-           mSerial, static_cast<void*>(mOuterWindow.get()), url.get());
+           mSerial, static_cast<void*>(static_cast<nsIScriptGlobalObject*>(outer)), url.get());
   }
 #endif
 
 #ifdef PR_LOGGING
   if (gDOMLeakPRLog)
     PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
            ("DOMWINDOW %p destroyed", this));
 #endif
--- a/dom/browser-element/BrowserElementChild.js
+++ b/dom/browser-element/BrowserElementChild.js
@@ -119,16 +119,17 @@ BrowserElementChild.prototype = {
     var self = this;
     function addMsgListener(msg, handler) {
       addMessageListener('browser-element-api:' + msg, handler.bind(self));
     }
 
     addMsgListener("purge-history", this._recvPurgeHistory);
     addMsgListener("get-screenshot", this._recvGetScreenshot);
     addMsgListener("set-visible", this._recvSetVisible);
+    addMsgListener("get-visible", this._recvVisible);
     addMsgListener("send-mouse-event", this._recvSendMouseEvent);
     addMsgListener("send-touch-event", this._recvSendTouchEvent);
     addMsgListener("get-can-go-back", this._recvCanGoBack);
     addMsgListener("get-can-go-forward", this._recvCanGoForward);
     addMsgListener("go-back", this._recvGoBack);
     addMsgListener("go-forward", this._recvGoForward);
     addMsgListener("reload", this._recvReload);
     addMsgListener("stop", this._recvStop);
@@ -612,16 +613,23 @@ BrowserElementChild.prototype = {
   },
 
   _recvSetVisible: function(data) {
     debug("Received setVisible message: (" + data.json.visible + ")");
     this._forcedVisible = data.json.visible;
     this._updateDocShellVisibility();
   },
 
+  _recvVisible: function(data) {
+    sendAsyncMsg('got-visible', {
+      id: data.json.id,
+      successRv: docShell.isActive
+    });
+  },
+
   /**
    * Called when the window which contains this iframe becomes hidden or
    * visible.
    */
   _recvOwnerVisibilityChange: function(data) {
     debug("Received ownerVisibilityChange: (" + data.json.visible + ")");
     this._ownerVisible = data.json.visible;
     this._updateDocShellVisibility();
--- a/dom/browser-element/BrowserElementParent.js
+++ b/dom/browser-element/BrowserElementParent.js
@@ -219,16 +219,17 @@ function BrowserElementParent(frameLoade
   addMessageListener("showmodalprompt", this._handleShowModalPrompt);
   addMessageListener('got-purge-history', this._gotDOMRequestResult);
   addMessageListener('got-screenshot', this._gotDOMRequestResult);
   addMessageListener('got-can-go-back', this._gotDOMRequestResult);
   addMessageListener('got-can-go-forward', this._gotDOMRequestResult);
   addMessageListener('fullscreen-origin-change', this._remoteFullscreenOriginChange);
   addMessageListener('rollback-fullscreen', this._remoteFrameFullscreenReverted);
   addMessageListener('exit-fullscreen', this._exitFullscreen);
+  addMessageListener('got-visible', this._gotDOMRequestResult);
 
   let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
   os.addObserver(this, 'ask-children-to-exit-fullscreen', /* ownsWeak = */ true);
   os.addObserver(this, 'oop-frameloader-crashed', /* ownsWeak = */ true);
 
   function defineMethod(name, fn) {
     XPCNativeWrapper.unwrap(self._frameElement)[name] = function() {
       if (self._isAlive()) {
@@ -242,16 +243,17 @@ function BrowserElementParent(frameLoade
       if (self._isAlive()) {
         return self._sendDOMRequest(msgName);
       }
     };
   }
 
   // Define methods on the frame element.
   defineMethod('setVisible', this._setVisible);
+  defineDOMRequestMethod('getVisible', 'get-visible');
   defineMethod('sendMouseEvent', this._sendMouseEvent);
 
   // 0 = disabled, 1 = enabled, 2 - auto detect
   if (getIntPref(TOUCH_EVENTS_ENABLED_PREF, 0) != 0) {
     defineMethod('sendTouchEvent', this._sendTouchEvent);
   }
   defineMethod('goBack', this._goBack);
   defineMethod('goForward', this._goForward);
--- a/dom/browser-element/mochitest/browserElement_SetVisible.js
+++ b/dom/browser-element/mochitest/browserElement_SetVisible.js
@@ -43,16 +43,33 @@ function runTest() {
         SimpleTest.finish();
       }, 100);
     } else {
       ok(false, 'Too many visibilitychange events');
     }
   }
 
   function iframeLoaded() {
+    testGetVisible();
+  }
+
+  function testGetVisible() {
+    iframe1.setVisible(false);
+    iframe1.getVisible().onsuccess = function(evt) {
+      ok(evt.target.result === false, 'getVisible() responds false after setVisible(false)');
+
+      iframe1.setVisible(true);
+      iframe1.getVisible().onsuccess = function(evt) {
+        ok(evt.target.result === true, 'getVisible() responds true after setVisible(true)');
+        testVisibilityChanges();
+      };
+    };
+  }
+
+  function testVisibilityChanges() {
     mm = SpecialPowers.getBrowserFrameMessageManager(iframe1);
     mm.addMessageListener('test:visibilitychange', recvVisibilityChanged);
     mm.loadFrameScript('data:,(' + iframeScript.toString() + ')();', false);
     iframe1.setVisible(false);
   }
 
   iframe1.addEventListener('mozbrowserloadend', iframeLoaded);
 }
--- a/dom/browser-element/mochitest/browserElement_SetVisibleFrames.js
+++ b/dom/browser-element/mochitest/browserElement_SetVisibleFrames.js
@@ -39,25 +39,39 @@ function runTest() {
   iframe.addEventListener('mozbrowsershowmodalprompt', checkMessage);
   expectMessage('parent:ready', test1);
 
   document.body.appendChild(iframe);
   iframe.src = 'file_browserElement_SetVisibleFrames_Outer.html';
 }
 
 function test1() {
-  expectMessage('child1:hidden', test2);
+  expectMessage('child1:hidden', getVisibleTest1);
   iframe.setVisible(false);
 }
 
+function getVisibleTest1() {
+  iframe.getVisible().onsuccess = function(evt) {
+    ok(evt.target.result === false, 'getVisible shows a hidden frame');
+    test2();
+  };
+}
+
 function test2() {
-  expectMessage('child1:visible', finish);
+  expectMessage('child1:visible', getVisibleTest2);
   iframe.setVisible(true);
 }
 
+function getVisibleTest2() {
+  iframe.getVisible().onsuccess = function(evt) {
+    ok(evt.target.result === true, 'getVisible shows a displayed frame');
+    finish();
+  };
+}
+
 function finish() {
   // We need to remove this listener because when this test finishes and the
   // iframe containing this document is navigated, we'll fire a
   // visibilitychange(false) event on all child iframes.  That's OK and
   // expected, but if we don't remove our listener, then we'll end up causing
   // the /next/ test to fail!
   iframe.removeEventListener('mozbrowsershowmodalprompt', checkMessage);
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -25,17 +25,19 @@
 #include "mozilla/StaticPtr.h"
 #include "mozilla/unused.h"
 #include "mozIApplication.h"
 #include "nsComponentManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsContentUtils.h"
 #include "nsEmbedCID.h"
 #include "nsEventListenerManager.h"
+#ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
+#endif
 #include "mozilla/dom/Element.h"
 #include "nsIAppsService.h"
 #include "nsIBaseWindow.h"
 #include "nsIComponentManager.h"
 #include "nsIDOMClassInfo.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMWindow.h"
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -351,30 +351,29 @@ public:
     MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
     nsRefPtr<SourceMediaStream> stream = gm->CreateSourceStream(nullptr);
 
     // connect the source stream to the track union stream to avoid us blocking
     trackunion->GetStream()->AsProcessedStream()->SetAutofinish(true);
     nsRefPtr<MediaInputPort> port = trackunion->GetStream()->AsProcessedStream()->
       AllocateInputPort(stream, MediaInputPort::FLAG_BLOCK_OUTPUT);
     trackunion->mSourceStream = stream;
-    trackunion->mPort = port;
+    trackunion->mPort = port.forget();
 
     nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
       (nsGlobalWindow::GetInnerWindowWithId(mWindowID));
     if (window && window->GetExtantDoc()) {
       trackunion->CombineWithPrincipal(window->GetExtantDoc()->NodePrincipal());
     }
 
     // The listener was added at the begining in an inactive state.
     // Activate our listener. We'll call Start() on the source when get a callback
     // that the MediaStream has started consuming. The listener is freed
     // when the page is invalidated (on navigation or close).
-    mListener->Activate(stream.forget(), port.forget(),
-                        mAudioSource, mVideoSource);
+    mListener->Activate(stream.forget(), mAudioSource, mVideoSource);
 
     // Dispatch to the media thread to ask it to start the sources,
     // because that can take a while
     nsIThread *mediaThread = MediaManager::GetThread();
     nsRefPtr<MediaOperationRunnable> runnable(
       new MediaOperationRunnable(MEDIA_START, mListener,
                                  mAudioSource, mVideoSource, false));
     mediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
@@ -1064,17 +1063,17 @@ MediaManager::OnNavigation(uint64_t aWin
   if (!listeners) {
     return;
   }
 
   uint32_t length = listeners->Length();
   for (uint32_t i = 0; i < length; i++) {
     nsRefPtr<GetUserMediaCallbackMediaStreamListener> listener =
       listeners->ElementAt(i);
-    listener->Invalidate(true);
+    listener->Invalidate();
     listener->Remove();
   }
   listeners->Clear();
 
   RemoveWindowID(aWindowID);
   // listeners has been deleted
 }
 
@@ -1227,30 +1226,50 @@ MediaManager::GetActiveMediaCaptureWindo
     return rv;
 
   mActiveWindows.EnumerateRead(WindowsHashToArrayFunc, array);
 
   *aArray = array;
   return NS_OK;
 }
 
+// Can be invoked from EITHER MainThread or MSG thread
 void
-GetUserMediaCallbackMediaStreamListener::Invalidate(bool aNeedsFinish)
+GetUserMediaCallbackMediaStreamListener::Invalidate()
 {
+
   nsRefPtr<MediaOperationRunnable> runnable;
   // We can't take a chance on blocking here, so proxy this to another
   // thread.
   // Pass a ref to us (which is threadsafe) so it can query us for the
   // source stream info.
   runnable = new MediaOperationRunnable(MEDIA_STOP,
                                         this, mAudioSource, mVideoSource,
-                                        aNeedsFinish);
+                                        mFinished);
   mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
 }
 
+// Called from the MediaStreamGraph thread
 void
 GetUserMediaCallbackMediaStreamListener::NotifyFinished(MediaStreamGraph* aGraph)
 {
-  Invalidate(false);
+  mFinished = true;
+  Invalidate();
   NS_DispatchToMainThread(new GetUserMediaListenerRemove(mWindowID, this));
 }
 
+// Called from the MediaStreamGraph thread
+// this can be in response to our own RemoveListener() (via ::Remove()), or
+// because the DOM GC'd the DOMLocalMediaStream/etc we're attached to.
+void
+GetUserMediaCallbackMediaStreamListener::NotifyRemoved(MediaStreamGraph* aGraph)
+{
+  {
+    MutexAutoLock lock(mLock); // protect access to mRemoved
+    MM_LOG(("Listener removed by DOM Destroy(), mFinished = %d", (int) mFinished));
+    mRemoved = true;
+  }
+  if (!mFinished) {
+    NotifyFinished(aGraph);
+  }
+}
+
 } // namespace mozilla
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -68,31 +68,33 @@ class GetUserMediaNotificationEvent: pub
  */
 class GetUserMediaCallbackMediaStreamListener : public MediaStreamListener
 {
 public:
   // Create in an inactive state
   GetUserMediaCallbackMediaStreamListener(nsIThread *aThread,
     uint64_t aWindowID)
     : mMediaThread(aThread)
-    , mWindowID(aWindowID) {}
+    , mWindowID(aWindowID)
+    , mFinished(false)
+    , mLock("mozilla::GUMCMSL")
+    , mRemoved(false) {}
 
   ~GetUserMediaCallbackMediaStreamListener()
   {
-    // It's OK to release mStream and mPort on any thread; they have thread-safe
+    // It's OK to release mStream on any thread; they have thread-safe
     // refcounts.
   }
 
   void Activate(already_AddRefed<SourceMediaStream> aStream,
-    already_AddRefed<MediaInputPort> aPort,
     MediaEngineSource* aAudioSource,
     MediaEngineSource* aVideoSource)
   {
+    NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
     mStream = aStream; // also serves as IsActive();
-    mPort = aPort;
     mAudioSource = aAudioSource;
     mVideoSource = aVideoSource;
     mLastEndTimeAudio = 0;
     mLastEndTimeVideo = 0;
 
     mStream->AddListener(this);
   }
 
@@ -102,53 +104,72 @@ public:
   }
   SourceMediaStream *GetSourceStream()
   {
     MOZ_ASSERT(mStream);
     return mStream->AsSourceStream();
   }
 
   // implement in .cpp to avoid circular dependency with MediaOperationRunnable
-  void Invalidate(bool aNeedsFinish);
+  // Can be invoked from EITHER MainThread or MSG thread
+  void Invalidate();
 
   void
   Remove()
   {
     NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
+    // allow calling even if inactive (!mStream) for easier cleanup
     // Caller holds strong reference to us, so no death grip required
-    if (mStream) // allow even if inactive for easier cleanup
+    MutexAutoLock lock(mLock); // protect access to mRemoved
+    if (mStream && !mRemoved) {
+      MM_LOG(("Listener removed on purpose, mFinished = %d", (int) mFinished));
+      mRemoved = true; // RemoveListener is async, avoid races
       mStream->RemoveListener(this);
+    }
   }
 
   // Proxy NotifyPull() to sources
-  void
-  NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime)
+  virtual void
+  NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime) MOZ_OVERRIDE
   {
     // Currently audio sources ignore NotifyPull, but they could
     // watch it especially for fake audio.
     if (mAudioSource) {
       mAudioSource->NotifyPull(aGraph, mStream, kAudioTrack, aDesiredTime, mLastEndTimeAudio);
     }
     if (mVideoSource) {
       mVideoSource->NotifyPull(aGraph, mStream, kVideoTrack, aDesiredTime, mLastEndTimeVideo);
     }
   }
 
-  void
-  NotifyFinished(MediaStreamGraph* aGraph);
+  virtual void
+  NotifyFinished(MediaStreamGraph* aGraph) MOZ_OVERRIDE;
+
+  virtual void
+  NotifyRemoved(MediaStreamGraph* aGraph) MOZ_OVERRIDE;
 
 private:
+  // Set at construction
   nsCOMPtr<nsIThread> mMediaThread;
   uint64_t mWindowID;
-  nsRefPtr<MediaEngineSource> mAudioSource;
-  nsRefPtr<MediaEngineSource> mVideoSource;
-  nsRefPtr<SourceMediaStream> mStream;
-  nsRefPtr<MediaInputPort> mPort;
+
+  // Set at Activate on MainThread
+
+  // Accessed from MediaStreamGraph thread, MediaManager thread, and MainThread
+  // No locking needed as they're only addrefed except on the MediaManager thread
+  nsRefPtr<MediaEngineSource> mAudioSource; // threadsafe refcnt
+  nsRefPtr<MediaEngineSource> mVideoSource; // threadsafe refcnt
+  nsRefPtr<SourceMediaStream> mStream; // threadsafe refcnt
   TrackTicks mLastEndTimeAudio;
   TrackTicks mLastEndTimeVideo;
+  bool mFinished;
+
+  // Accessed from MainThread and MSG thread
+  Mutex mLock; // protects mRemoved access from MainThread
+  bool mRemoved;
 };
 
 typedef enum {
   MEDIA_START,
   MEDIA_STOP
 } MediaOperation;
 
 // Generic class for running long media operations like Start off the main
--- a/dom/network/src/NetworkStatsManager.js
+++ b/dom/network/src/NetworkStatsManager.js
@@ -7,16 +7,26 @@
 const DEBUG = false;
 function debug(s) { dump("-*- NetworkStatsManager: " + s + "\n"); }
 
 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
+Cu.import("resource://gre/modules/ObjectWrapper.jsm");
+
+// Ensure NetworkStatsService and NetworkStatsDB are loaded in the parent process
+// to receive messages from the child processes.
+let appInfo = Cc["@mozilla.org/xre/app-info;1"];
+let isParentProcess = !appInfo || appInfo.getService(Ci.nsIXULRuntime)
+                        .processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+if (isParentProcess) {
+  Cu.import("resource://gre/modules/NetworkStatsService.jsm");
+}
 
 XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
                                    "@mozilla.org/childprocessmessagemanager;1",
                                    "nsISyncMessageSender");
 
 // NetworkStatsData
 const nsIClassInfo              = Ci.nsIClassInfo;
 const NETWORKSTATSDATA_CID      = Components.ID("{3b16fe17-5583-483a-b486-b64a3243221c}");
@@ -38,36 +48,35 @@ NetworkStatsData.prototype = {
   classID : NETWORKSTATSDATA_CID,
   classInfo : XPCOMUtils.generateCI({classID: NETWORKSTATSDATA_CID,
                                      contractID:"@mozilla.org/networkstatsdata;1",
                                      classDescription: "NetworkStatsData",
                                      interfaces: [nsIDOMMozNetworkStatsData],
                                      flags: nsIClassInfo.DOM_OBJECT}),
 
   QueryInterface : XPCOMUtils.generateQI([nsIDOMMozNetworkStatsData])
-}
+};
 
 // NetworkStats
 const NETWORKSTATS_CONTRACTID = "@mozilla.org/networkstats;1";
 const NETWORKSTATS_CID        = Components.ID("{037435a6-f563-48f3-99b3-a0106d8ba5bd}");
 const nsIDOMMozNetworkStats   = Components.interfaces.nsIDOMMozNetworkStats;
 
-function NetworkStats(aStats) {
+function NetworkStats(aWindow, aStats) {
   if (DEBUG) {
     debug("NetworkStats Constructor");
   }
   this.connectionType = aStats.connectionType || null;
   this.start = aStats.start || null;
   this.end = aStats.end || null;
 
-  let samples = [];
+  let samples = this.data = Cu.createArrayIn(aWindow);
   for (let i = 0; i < aStats.data.length; i++) {
     samples.push(new NetworkStatsData(aStats.data[i]));
   }
-  this.data = samples;
 }
 
 NetworkStats.prototype = {
   __exposedProps__: {
                       connectionType: 'r',
                       start: 'r',
                       end:  'r',
                       data:  'r',
@@ -96,17 +105,17 @@ function NetworkStatsManager() {
   }
 }
 
 NetworkStatsManager.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
 
   checkPrivileges: function checkPrivileges() {
     if (!this.hasPrivileges) {
-      throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+      throw Components.Exception("Permission denied", Cr.NS_ERROR_FAILURE);
     }
   },
 
   getNetworkStats: function getNetworkStats(aOptions) {
     this.checkPrivileges();
 
     if (!aOptions.start || !aOptions.end ||
       aOptions.start > aOptions.end) {
@@ -128,29 +137,26 @@ NetworkStatsManager.prototype = {
     let request = this.createRequest();
     cpmm.sendAsyncMessage("NetworkStats:Clear",
                           {id: this.getRequestId(request)});
     return request;
   },
 
   get connectionTypes() {
     this.checkPrivileges();
-
-    return cpmm.sendSyncMessage("NetworkStats:Types")[0];
+    return ObjectWrapper.wrap(cpmm.sendSyncMessage("NetworkStats:Types")[0], this._window);
   },
 
   get sampleRate() {
     this.checkPrivileges();
-
     return cpmm.sendSyncMessage("NetworkStats:SampleRate")[0] / 1000;
   },
 
   get maxStorageSamples() {
     this.checkPrivileges();
-
     return cpmm.sendSyncMessage("NetworkStats:MaxStorageSamples")[0];
   },
 
   receiveMessage: function(aMessage) {
     if (DEBUG) {
       debug("NetworkStatsmanager::receiveMessage: " + aMessage.name);
     }
     let msg = aMessage.json;
@@ -165,17 +171,17 @@ NetworkStatsManager.prototype = {
 
     switch (aMessage.name) {
       case "NetworkStats:Get:Return":
         if (msg.error) {
           Services.DOMRequest.fireError(req, msg.error);
           return;
         }
 
-        let result = new NetworkStats(msg.result);
+        let result = new NetworkStats(this._window, msg.result);
         if (DEBUG) {
           debug("result: " + JSON.stringify(result));
         }
         Services.DOMRequest.fireSuccess(req, result);
         break;
 
       case "NetworkStats:Clear:Return":
         if (msg.error) {
@@ -193,31 +199,36 @@ NetworkStatsManager.prototype = {
     }
   },
 
   init: function(aWindow) {
     // Set navigator.mozNetworkStats to null.
     if (!Services.prefs.getBoolPref("dom.mozNetworkStats.enabled")) {
       return null;
     }
-    this.initHelper(aWindow, ["NetworkStats:Get:Return",
-                              "NetworkStats:Clear:Return"]);
 
     let principal = aWindow.document.nodePrincipal;
     let secMan = Services.scriptSecurityManager;
     let perm = principal == secMan.getSystemPrincipal() ?
                  Ci.nsIPermissionManager.ALLOW_ACTION :
                  Services.perms.testExactPermissionFromPrincipal(principal,
                                                                  "networkstats-manage");
 
     // Only pages with perm set can use the netstats.
     this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
     if (DEBUG) {
       debug("has privileges: " + this.hasPrivileges);
     }
+
+    if (!this.hasPrivileges) {
+      return null;
+    }
+
+    this.initHelper(aWindow, ["NetworkStats:Get:Return",
+                              "NetworkStats:Clear:Return"]);
   },
 
   // Called from DOMRequestIpcHelper
   uninit: function uninit() {
     if (DEBUG) {
       debug("uninit call");
     }
   },
@@ -230,9 +241,9 @@ NetworkStatsManager.prototype = {
                                      contractID: NETWORKSTATSMANAGER_CONTRACTID,
                                      classDescription: "NetworkStatsManager",
                                      interfaces: [nsIDOMMozNetworkStatsManager],
                                      flags: nsIClassInfo.DOM_OBJECT})
 }
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkStatsData,
                                                      NetworkStats,
-                                                     NetworkStatsManager])
+                                                     NetworkStatsManager]);
--- a/dom/network/src/NetworkStatsService.jsm
+++ b/dom/network/src/NetworkStatsService.jsm
@@ -69,16 +69,20 @@ this.NetworkStatsService = {
     this.timer.initWithCallback(this, this._db.sampleRate,
                                 Ci.nsITimer.TYPE_REPEATING_PRECISE);
 
     this.updateQueue = [];
     this.isQueueRunning = false;
   },
 
   receiveMessage: function(aMessage) {
+    if (!aMessage.target.assertPermission("networkstats-manage")) {
+      return;
+    }
+
     if (DEBUG) {
       debug("receiveMessage " + aMessage.name);
     }
     let mm = aMessage.target;
     let msg = aMessage.json;
 
     switch (aMessage.name) {
       case "NetworkStats:Get":
--- a/dom/network/tests/Makefile.in
+++ b/dom/network/tests/Makefile.in
@@ -19,16 +19,19 @@ MOCHITEST_FILES = \
   test_tcpsocket_default_permissions.html \
   test_tcpsocket_enabled_no_perm.html \
   test_tcpsocket_enabled_with_perm.html \
   $(NULL)
 
 ifdef MOZ_B2G_RIL
 MOCHITEST_FILES = \
   test_networkstats_basics.html \
+  test_networkstats_disabled.html \
+  test_networkstats_enabled_no_perm.html \
+  test_networkstats_enabled_perm.html \
   $(NULL)
 endif
 
 MODULE = test_dom_socket
 
 XPCSHELL_TESTS = unit unit_ipc
 
 ifdef MOZ_B2G_RIL
--- a/dom/network/tests/test_networkstats_basics.html
+++ b/dom/network/tests/test_networkstats_basics.html
@@ -7,39 +7,31 @@
 </head>
 <body>
 <p id="display"></p>
 <div id="content" style="display: none">
 </div>
 <pre id="test">
 <script type="application/javascript">
 
-/** Test for NetworkStats **/
+// Test for NetworkStats
 function checkInterface(aInterface) {
   ok(!(aInterface in window), aInterface + " should be prefixed");
   ok(("Moz" + aInterface) in window, aInterface + " should be prefixed");
 }
 
 function test() {
-  var gNetworkStatsEnabled = SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled");
-
-  if (!gNetworkStatsEnabled) {
-    is(navigator.mozNetworkStats, null, "mozNetworkStats is null when not enabled.");
-    SimpleTest.finish();
-  }
-
   // Test interfaces
   checkInterface("NetworkStatsManager");
   checkInterface("NetworkStats");
   checkInterface("NetworkStatsData");
 
   ok('mozNetworkStats' in navigator, "navigator.mozMozNetworkStats should exist");
   ok(navigator.mozNetworkStats, "navigator.mozNetworkStats returns an object");
 
-  SpecialPowers.addPermission("networkstats-manage", true, document);
   netStats = navigator.mozNetworkStats;
 
   // Test IDL attributes
   ok('connectionTypes' in netStats,
    "connectionTypes should be a NetworkStats attribute");
   ok(Array.isArray(netStats.connectionTypes) && netStats.connectionTypes.length > 0,
    "connectionTypes is an array not empty.");
 
@@ -274,16 +266,17 @@ var steps = [
       next();
     };
     req.onerror = function () {
       ok(false, "Get stats for all connectionType failure!");
     }
   },
   function () {
     ok(true, "all done!\n");
+    SpecialPowers.removePermission("networkstats-manage", document);
     SimpleTest.finish();
     return;
   }
 ];
 
 function next() {
   index += 1;
   if (index >= steps.length) {
@@ -293,14 +286,16 @@ function next() {
   try {
     steps[index]();
   } catch(ex) {
     ok(false, "Caught exception", ex);
   }
 }
 
 SimpleTest.waitForExplicitFinish();
-addLoadEvent(test);
+
+SpecialPowers.addPermission("networkstats-manage", true, document);
+SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]}, test);
 
 </script>
 </pre>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/dom/network/tests/test_networkstats_disabled.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test to ensure NetworkStats is not accessible when it is disabled</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+"use strict";
+
+SimpleTest.waitForExplicitFinish();
+
+// Test to ensure NetworkStats is not accessible when it is disabled
+SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", false]]}, function(){
+
+  ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
+  is(navigator.mozNetworkStats, null, "mozNetworkStats should be null when not enabled.");
+
+  SimpleTest.finish();
+});
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/network/tests/test_networkstats_enabled_no_perm.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test to ensure NetworkStats enabled and no networkstats-manage perm does not allow open</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+// Test to ensure NetworkStats is enabled but mozNetworkStats.connectionTypes
+// does not work in content.
+
+SpecialPowers.setBoolPref("dom.mozNetworkStats.enabled", true);
+SpecialPowers.removePermission("networkstats-manage", document);
+
+ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should be accessible if dom.mozNetworkStats.enabled is true");
+
+var error;
+try {
+  navigator.mozNetworkStats.connectionTypes;
+  ok(false, "Accessing navigator.mozNetworkStats.connectionTypes should have thrown!");
+} catch (ex) {
+  error = ex;
+}
+ok(error, "Got an exception accessing navigator.mozNetworkStats.connectionTypes");
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/network/tests/test_networkstats_enabled_perm.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test to ensure NetworkStats is not accessible when it is disabled</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+"use strict";
+
+SimpleTest.waitForExplicitFinish();
+
+// Test to ensure NetworkStats is not accessible when it is disabled
+SpecialPowers.addPermission("networkstats-manage", true, document);
+SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]}, function(){
+
+  ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
+  ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
+      "navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
+
+  SpecialPowers.removePermission("networkstats-manage", document);
+  SimpleTest.finish();
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/system/gonk/SystemWorkerManager.cpp
+++ b/dom/system/gonk/SystemWorkerManager.cpp
@@ -90,17 +90,17 @@ PostToRIL(JSContext *cx, unsigned argc, 
     data = abs.ptr();
   } else if (!JSVAL_IS_PRIMITIVE(v)) {
     JSObject *obj = JSVAL_TO_OBJECT(v);
     if (!JS_IsTypedArrayObject(obj)) {
       JS_ReportError(cx, "Object passed in wasn't a typed array");
       return false;
     }
 
-    uint32_t type = JS_GetTypedArrayType(obj);
+    uint32_t type = JS_GetArrayBufferViewType(obj);
     if (type != js::ArrayBufferView::TYPE_INT8 &&
         type != js::ArrayBufferView::TYPE_UINT8 &&
         type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
       JS_ReportError(cx, "Typed array data is not octets");
       return false;
     }
 
     size = JS_GetTypedArrayByteLength(obj);
@@ -218,17 +218,17 @@ DoNetdCommand(JSContext *cx, unsigned ar
     }
   } else if (!JSVAL_IS_PRIMITIVE(v)) {
     JSObject *obj = JSVAL_TO_OBJECT(v);
     if (!JS_IsTypedArrayObject(obj)) {
       JS_ReportError(cx, "Object passed in wasn't a typed array");
       return false;
     }
 
-    uint32_t type = JS_GetTypedArrayType(obj);
+    uint32_t type = JS_GetArrayBufferViewType(obj);
     if (type != js::ArrayBufferView::TYPE_INT8 &&
         type != js::ArrayBufferView::TYPE_UINT8 &&
         type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
       JS_ReportError(cx, "Typed array data is not octets");
       return false;
     }
 
     size = JS_GetTypedArrayByteLength(obj);
--- a/dom/telephony/Telephony.cpp
+++ b/dom/telephony/Telephony.cpp
@@ -122,18 +122,23 @@ Telephony::NoteDialedCallFromOtherInstan
 }
 
 nsresult
 Telephony::NotifyCallsChanged(TelephonyCall* aCall)
 {
   nsRefPtr<CallEvent> event = CallEvent::Create(aCall);
   NS_ASSERTION(event, "This should never fail!");
 
-  if (aCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_DIALING) {
+  if (aCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_DIALING ||
+      aCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_ALERTING ||
+      aCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_CONNECTED) {
+    NS_ASSERTION(!mActiveCall, "Already have an active call!");
     mActiveCall = aCall;
+  } else if (mActiveCall && mActiveCall->CallIndex() == aCall->CallIndex()) {
+    mActiveCall = nullptr;
   }
 
   nsresult rv =
     event->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("callschanged"));
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
@@ -378,41 +383,36 @@ Telephony::CallStateChanged(uint32_t aCa
   if (!modifiedCall &&
       aCallState != nsIRadioInterfaceLayer::CALL_STATE_INCOMING &&
       outgoingCall) {
     outgoingCall->UpdateCallIndex(aCallIndex);
     modifiedCall.swap(outgoingCall);
   }
 
   if (modifiedCall) {
-
     // See if this should replace our current active call.
     if (aIsActive) {
-      if (aCallState == nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTED) {
-        mActiveCall = nullptr;
-      } else {
         mActiveCall = modifiedCall;
-      }
-    } else {
-      if (mActiveCall && mActiveCall->CallIndex() == aCallIndex) {
-        mActiveCall = nullptr;
-      }
+    } else if (mActiveCall && mActiveCall->CallIndex() == aCallIndex) {
+      mActiveCall = nullptr;
     }
 
     // Change state.
     modifiedCall->ChangeState(aCallState);
 
     return NS_OK;
   }
 
-  // Didn't know anything about this call before now, could be 'incoming' or
-  // 'dialing' that was placed by others.
-  NS_ASSERTION(aCallState == nsIRadioInterfaceLayer::CALL_STATE_INCOMING ||
-               aCallState == nsIRadioInterfaceLayer::CALL_STATE_DIALING,
-               "Serious logic problem here!");
+  // Didn't know anything about this call before now.
+
+  if (aCallState == nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTED) {
+    // Do nothing since we didn't know anything about it before now and it's
+    // been ended already.
+    return NS_OK;
+  }
 
   nsRefPtr<TelephonyCall> call =
     TelephonyCall::Create(this, aNumber, aCallState, aCallIndex);
   NS_ASSERTION(call, "This should never fail!");
 
   NS_ASSERTION(mCalls.Contains(call), "Should have auto-added new call!");
 
   if (aCallState == nsIRadioInterfaceLayer::CALL_STATE_INCOMING) {
@@ -428,34 +428,32 @@ Telephony::CallStateChanged(uint32_t aCa
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState,
                               const nsAString& aNumber, bool aIsActive,
                               bool* aContinue)
 {
-#ifdef DEBUG
   // Make sure we don't somehow add duplicates.
   for (uint32_t index = 0; index < mCalls.Length(); index++) {
-    NS_ASSERTION(mCalls[index]->CallIndex() != aCallIndex,
-                 "Something is really wrong here!");
+    nsRefPtr<TelephonyCall>& tempCall = mCalls[index];
+    if (tempCall->CallIndex() == aCallIndex) {
+      // We have the call already. Skip it.
+      *aContinue = true;
+      return NS_OK;
+    }
   }
-#endif
+
   nsRefPtr<TelephonyCall> call =
     TelephonyCall::Create(this, aNumber, aCallState, aCallIndex);
   NS_ASSERTION(call, "This should never fail!");
 
   NS_ASSERTION(mCalls.Contains(call), "Should have auto-added new call!");
 
-  if (aIsActive) {
-    NS_ASSERTION(!mActiveCall, "Already have an active call!");
-    mActiveCall = call;
-  }
-
   *aContinue = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 Telephony::NotifyError(int32_t aCallIndex,
                        const nsAString& aError)
 {
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -371,17 +371,18 @@ partial interface Document {
     void enableStyleSheetsForSet (DOMString? name);
 /*
 };
 
 http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
 partial interface Document {
 */
     Element? elementFromPoint (float x, float y);
-    //(Not implemented)CaretPosition? caretPositionFromPoint (float x, float y);
+
+    CaretPosition? caretPositionFromPoint (float x, float y);
 /*
 };
 
 http://dvcs.w3.org/hg/undomanager/raw-file/tip/undomanager.html
 partial interface Document {
 */
     [Pref="dom.undo_manager.enabled"]
     readonly attribute UndoManager? undoManager;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGFitToViewBox.webidl
@@ -0,0 +1,20 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.w3.org/TR/SVG2/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGAnimatedRect;
+
+[NoInterfaceObject]
+interface SVGFitToViewBox {
+  readonly attribute SVGAnimatedRect viewBox;
+  readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
+};
+
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGViewElement.webidl
@@ -0,0 +1,21 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.w3.org/TR/SVG2/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+interface SVGStringList;
+
+interface SVGViewElement : SVGElement {
+  readonly attribute SVGStringList viewTarget;
+};
+
+SVGViewElement implements SVGFitToViewBox;
+SVGViewElement implements SVGZoomAndPan;
+
new file mode 100644
--- /dev/null
+++ b/dom/webidl/SVGZoomAndPan.webidl
@@ -0,0 +1,24 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ *
+ * The origin of this IDL file is
+ * http://www.w3.org/TR/SVG2/
+ *
+ * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
+ * liability, trademark and document use rules apply.
+ */
+
+[NoInterfaceObject]
+interface SVGZoomAndPan {
+
+  // Zoom and Pan Types
+  const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0;
+  const unsigned short SVG_ZOOMANDPAN_DISABLE = 1;
+  const unsigned short SVG_ZOOMANDPAN_MAGNIFY = 2;
+
+  [SetterThrows]
+  attribute unsigned short zoomAndPan;
+};
+
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -109,16 +109,17 @@ webidl_files = \
   SVGAnimateMotionElement.webidl \
   SVGAnimateTransformElement.webidl \
   SVGAnimationElement.webidl \
   SVGCircleElement.webidl \
   SVGDefsElement.webidl \
   SVGDescElement.webidl \
   SVGElement.webidl \
   SVGEllipseElement.webidl \
+  SVGFitToViewBox.webidl \
   SVGForeignObjectElement.webidl \
   SVGGElement.webidl \
   SVGGraphicsElement.webidl \
   SVGImageElement.webidl \
   SVGLengthList.webidl \
   SVGLineElement.webidl \
   SVGLocatableElement.webidl \
   SVGMatrix.webidl \
@@ -144,16 +145,18 @@ webidl_files = \
   SVGTextPathElement.webidl \
   SVGTextPositioningElement.webidl \
   SVGTitleElement.webidl \
   SVGTransform.webidl \
   SVGTransformableElement.webidl \
   SVGTransformList.webidl \
   SVGTSpanElement.webidl \
   SVGURIReference.webidl \
+  SVGViewElement.webidl \
+  SVGZoomAndPan.webidl \
   Text.webidl \
   TextDecoder.webidl \
   TextEncoder.webidl \
   URL.webidl \
   WebSocket.webidl \
   UndoManager.webidl \
   XMLHttpRequest.webidl \
   XMLHttpRequestEventTarget.webidl \
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -958,24 +958,22 @@ CreateDedicatedWorkerGlobalScope(JSConte
   }
 
   JSObject* workerProto = worker::InitClass(aCx, global, eventTargetProto,
                                             false);
   if (!workerProto) {
     return NULL;
   }
 
-  if (worker->IsChromeWorker() &&
-      (!chromeworker::InitClass(aCx, global, workerProto, false) ||
-       !DefineChromeWorkerFunctions(aCx, global))) {
-    return NULL;
-  }
-
-  if (!DefineOSFileConstants(aCx, global)) {
-    return NULL;
+  if (worker->IsChromeWorker()) {
+    if (!chromeworker::InitClass(aCx, global, workerProto, false) ||
+        !DefineChromeWorkerFunctions(aCx, global) ||
+        !DefineOSFileConstants(aCx, global)) {
+      return NULL;
+    }
   }
 
   // Init other classes we care about.
   if (!events::InitClasses(aCx, global, false) ||
       !file::InitClasses(aCx, global) ||
       !exceptions::InitClasses(aCx, global) ||
       !location::InitClass(aCx, global) ||
       !imagedata::InitClass(aCx, global) ||
--- a/dom/workers/test/Makefile.in
+++ b/dom/workers/test/Makefile.in
@@ -101,16 +101,18 @@ MOCHITEST_FILES = \
   test_csp.html \
   test_csp.js \
   test_csp.html^headers^ \
   csp_worker.js \
   test_transferable.html \
   transferable_worker.js \
   test_errorwarning.html \
   errorwarning_worker.js \
+  test_contentWorker.html \
+  content_worker.js \
   $(NULL)
 
 _SUBDIRMOCHITEST_FILES = \
   relativeLoad_sub_worker.js \
   relativeLoad_sub_worker2.js \
   relativeLoad_sub_import.js \
   $(NULL)
 
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/content_worker.js
@@ -0,0 +1,12 @@
+/**
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+var props = {
+  'ctypes': 1,
+  'OS': 1
+};
+for (var prop in props) {
+  postMessage({ "prop": prop, "value": self[prop] });
+}
+postMessage({ "testfinished": 1 });
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/test_contentWorker.html
@@ -0,0 +1,48 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for DOM Worker privileged properties</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" language="javascript">
+
+  var workerFilename = "content_worker.js";
+  var worker = new Worker(workerFilename);
+
+  var props = {
+    'ctypes': 1,
+    'OS': 1
+  };
+
+  worker.onmessage = function(event) {
+    if (event.data.testfinished) {
+      SimpleTest.finish();
+      return;
+    }
+    var prop = event.data.prop;
+    ok(prop in props, "checking " + prop);
+    is(event.data.value, undefined, prop + " should be undefined");
+  };
+
+  worker.onerror = function(event) {
+    ok(false, "Worker had an error: " + event.message);
+    SimpleTest.finish();
+  }
+
+  SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
--- a/embedding/browser/webBrowser/Makefile.in
+++ b/embedding/browser/webBrowser/Makefile.in
@@ -19,16 +19,17 @@ LIBXUL_LIBRARY	= 1
 
 
 EXPORTS         = \
                 nsCTooltipTextProvider.h \
                 $(NULL)
 
 LOCAL_INCLUDES	= \
 		-I$(srcdir)/../../../content/base/src \
+		-I$(srcdir)/../../../content/svg/content/src \
 		$(NULL)
 		
 SDK_XPIDLSRCS   = \
 		nsIContextMenuListener.idl  \
 		nsIEmbeddingSiteWindow.idl  \
 		nsITooltipListener.idl	    \
 		nsITooltipTextProvider.idl  \
 		nsIWebBrowser.idl	    \
--- a/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
@@ -28,17 +28,17 @@
 #include "nsITooltipListener.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMElement.h"
 #include "Link.h"
 #include "mozilla/dom/Element.h"
-#include "nsIDOMSVGTitleElement.h"
+#include "mozilla/dom/SVGTitleElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIFormControl.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIDOMHTMLHtmlElement.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLObjectElement.h"
@@ -1023,19 +1023,21 @@ UseSVGTitle(nsIDOMElement *currElement)
 
 /* void getNodeText (in nsIDOMNode aNode, out wstring aText); */
 NS_IMETHODIMP
 DefaultTooltipTextProvider::GetNodeText(nsIDOMNode *aNode, PRUnichar **aText,
                                         bool *_retval)
 {
   NS_ENSURE_ARG_POINTER(aNode);
   NS_ENSURE_ARG_POINTER(aText);
-    
+
   nsString outText;
 
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+
   bool lookingForSVGTitle = true;
   bool found = false;
   nsCOMPtr<nsIDOMNode> current ( aNode );
 
   // If the element implement the constraint validation API and has no title,
   // show the validation message, if any.
   nsCOMPtr<nsIConstraintValidation> cvElement = do_QueryInterface(current);
   if (cvElement) {
@@ -1082,38 +1084,34 @@ DefaultTooltipTextProvider::GetNodeText(
                   found = true;
               }
             }
             else {
               if (lookingForSVGTitle) {
                 lookingForSVGTitle = UseSVGTitle(currElement);
               }
               if (lookingForSVGTitle) {
-                nsCOMPtr<nsIDOMNodeList>childNodes;
-                aNode->GetChildNodes(getter_AddRefs(childNodes));
-                uint32_t childNodeCount;
-                childNodes->GetLength(&childNodeCount);
+                nsINodeList* childNodes = node->ChildNodes();
+                uint32_t childNodeCount = childNodes->Length();
                 for (uint32_t i = 0; i < childNodeCount; i++) {
-                  nsCOMPtr<nsIDOMNode>childNode;
-                  childNodes->Item(i, getter_AddRefs(childNode));
-                  nsCOMPtr<nsIDOMSVGTitleElement> titleElement(do_QueryInterface(childNode));
-                  if (titleElement) {
-                    titleElement->GetTextContent(outText);
+                  nsIContent* child = childNodes->Item(i);
+                  if (child->IsSVG(nsGkAtoms::title)) {
+                    static_cast<dom::SVGTitleElement*>(child)->GetTextContent(outText);
                     if ( outText.Length() )
                       found = true;
                     break;
                   }
                 }
               }
             }
           }
         }
       }
     }
-    
+
     // not found here, walk up to the parent and keep trying
     if ( !found ) {
       nsCOMPtr<nsIDOMNode> temp ( current );
       temp->GetParentNode(getter_AddRefs(current));
     }
   } // while not found
 
   *_retval = found;
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
@@ -68,18 +68,16 @@
 #include "nsIDOMHTMLIFrameElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLEmbedElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIDOMHTMLOptionElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIDOMHTMLDocument.h"
-#include "nsIDOMSVGImageElement.h"
-#include "nsIDOMSVGScriptElement.h"
 #ifdef MOZ_MEDIA
 #include "nsIDOMHTMLSourceElement.h"
 #include "nsIDOMHTMLMediaElement.h"
 #endif // MOZ_MEDIA
  
 #include "nsIImageLoadingContent.h"
 
 #include "ftpCore.h"
@@ -2695,26 +2693,31 @@ nsresult nsWebBrowserPersist::OnWalkDOMN
             if (!href.IsEmpty())
             {
                 StoreURI(NS_ConvertUTF16toUTF8(href).get());
             }
         }
         return NS_OK;
     }
 
+    nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
+    if (!content)
+    {
+        return NS_OK;
+    }
+
     // Test the node to see if it's an image, frame, iframe, css, js
     nsCOMPtr<nsIDOMHTMLImageElement> nodeAsImage = do_QueryInterface(aNode);
     if (nodeAsImage)
     {
         StoreURIAttribute(aNode, "src");
         return NS_OK;
     }
 
-    nsCOMPtr<nsIDOMSVGImageElement> nodeAsSVGImage = do_QueryInterface(aNode);
-    if (nodeAsSVGImage)
+    if (content->IsSVG(nsGkAtoms::img))
     {
         StoreURIAttributeNS(aNode, "http://www.w3.org/1999/xlink", "href");
         return NS_OK;
     }
 
 #ifdef MOZ_MEDIA
     nsCOMPtr<nsIDOMHTMLMediaElement> nodeAsMedia = do_QueryInterface(aNode);
     if (nodeAsMedia)
@@ -2760,18 +2763,17 @@ nsresult nsWebBrowserPersist::OnWalkDOMN
 
     nsCOMPtr<nsIDOMHTMLScriptElement> nodeAsScript = do_QueryInterface(aNode);
     if (nodeAsScript)
     {
         StoreURIAttribute(aNode, "src");
         return NS_OK;
     }
 
-    nsCOMPtr<nsIDOMSVGScriptElement> nodeAsSVGScript = do_QueryInterface(aNode);
-    if (nodeAsSVGScript)
+    if (content->IsSVG(nsGkAtoms::script))
     {
         StoreURIAttributeNS(aNode, "http://www.w3.org/1999/xlink", "href");
         return NS_OK;
     }
 
     nsCOMPtr<nsIDOMHTMLEmbedElement> nodeAsEmbed = do_QueryInterface(aNode);
     if (nodeAsEmbed)
     {
@@ -2986,16 +2988,22 @@ nsWebBrowserPersist::CloneNodeWithFixedU
                 if (comment)
                 {
                     return CallQueryInterface(comment, aNodeOut);
                 }
             }
         }
     }
 
+    nsCOMPtr<nsIContent> content = do_QueryInterface(aNodeIn);
+    if (!content)
+    {
+        return NS_OK;
+    }
+
     // Fix up href and file links in the elements
 
     nsCOMPtr<nsIDOMHTMLAnchorElement> nodeAsAnchor = do_QueryInterface(aNodeIn);
     if (nodeAsAnchor)
     {
         rv = GetNodeToFixup(aNodeIn, aNodeOut);
         if (NS_SUCCEEDED(rv) && *aNodeOut)
         {
@@ -3098,18 +3106,17 @@ nsWebBrowserPersist::CloneNodeWithFixedU
         {
             FixupNodeAttribute(*aNodeOut, "src");
         }
 
         return rv;
     }
 #endif // MOZ_MEDIA
 
-    nsCOMPtr<nsIDOMSVGImageElement> nodeAsSVGImage = do_QueryInterface(aNodeIn);
-    if (nodeAsSVGImage)
+    if (content->IsSVG(nsGkAtoms::img))
     {
         rv = GetNodeToFixup(aNodeIn, aNodeOut);
         if (NS_SUCCEEDED(rv) && *aNodeOut)
         {
             // Disable image loads
             nsCOMPtr<nsIImageLoadingContent> imgCon =
                 do_QueryInterface(*aNodeOut);
             if (imgCon)
@@ -3127,18 +3134,17 @@ nsWebBrowserPersist::CloneNodeWithFixedU
         rv = GetNodeToFixup(aNodeIn, aNodeOut);
         if (NS_SUCCEEDED(rv) && *aNodeOut)
         {
             FixupNodeAttribute(*aNodeOut, "src");
         }
         return rv;
     }
 
-    nsCOMPtr<nsIDOMSVGScriptElement> nodeAsSVGScript = do_QueryInterface(aNodeIn);
-    if (nodeAsSVGScript)
+    if (content->IsSVG(nsGkAtoms::script))
     {
         rv = GetNodeToFixup(aNodeIn, aNodeOut);
         if (NS_SUCCEEDED(rv) && *aNodeOut)
         {
             FixupNodeAttributeNS(*aNodeOut, "http://www.w3.org/1999/xlink", "href");
         }
         return rv;
     }
--- a/extensions/cookie/nsPermissionManager.cpp
+++ b/extensions/cookie/nsPermissionManager.cpp
@@ -750,24 +750,30 @@ nsPermissionManager::AddInternal(nsIPrin
       break;
     }
 
   case eOperationChanging:
     {
       id = entry->GetPermissions()[index].mID;
 
       // If the new expireType is EXPIRE_SESSION, then we have to keep a
-      // copy of the previous permission value. This cached value will be
+      // copy of the previous permission/expireType values. This cached value will be
       // used when restoring the permissions of an app.
       if (entry->GetPermissions()[index].mExpireType != nsIPermissionManager::EXPIRE_SESSION &&
           aExpireType == nsIPermissionManager::EXPIRE_SESSION) {
         entry->GetPermissions()[index].mNonSessionPermission = entry->GetPermissions()[index].mPermission;
+        entry->GetPermissions()[index].mNonSessionExpireType = entry->GetPermissions()[index].mExpireType;
+      } else if (aExpireType != nsIPermissionManager::EXPIRE_SESSION) {
+        entry->GetPermissions()[index].mNonSessionPermission = aPermission;
+        entry->GetPermissions()[index].mNonSessionExpireType = aExpireType;
+        entry->GetPermissions()[index].mExpireTime = aExpireTime;
       }
 
       entry->GetPermissions()[index].mPermission = aPermission;
+      entry->GetPermissions()[index].mExpireType = aExpireType;
 
       if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
         // We care only about the id, the permission and expireType/expireTime here.
         // We pass dummy values for all other parameters.
         UpdateDB(op, mStmtUpdate, id, EmptyCString(), EmptyCString(),
                  aPermission, aExpireType, aExpireTime, 0, false);
 
       if (aNotifyOperation == eNotify) {
@@ -1220,45 +1226,48 @@ nsPermissionManager::RemoveExpiredPermis
   uint32_t* appId = static_cast<uint32_t*>(arg);
 
   for (uint32_t i = 0; i < entry->GetPermissions().Length(); ++i) {
     if (entry->GetKey()->mAppId != *appId) {
       continue;
     }
 
     nsPermissionManager::PermissionEntry& permEntry = entry->GetPermissions()[i];
-    if (permEntry.mExpireType == nsIPermissionManager::EXPIRE_SESSION) {
+    if (permEntry.mExpireType != nsIPermissionManager::EXPIRE_SESSION) {
+      continue;
+    }
+
+    if (permEntry.mNonSessionExpireType == nsIPermissionManager::EXPIRE_SESSION) {
       PermissionEntry oldPermissionEntry = entry->GetPermissions()[i];
 
       entry->GetPermissions().RemoveElementAt(i);
 
       gPermissionManager->NotifyObserversWithPermission(entry->GetKey()->mHost,
                                                         entry->GetKey()->mAppId,
                                                         entry->GetKey()->mIsInBrowserElement,
                                                         gPermissionManager->mTypeArray.ElementAt(oldPermissionEntry.mType),
                                                         oldPermissionEntry.mPermission,
                                                         oldPermissionEntry.mExpireType,
                                                         oldPermissionEntry.mExpireTime,
                                                         NS_LITERAL_STRING("deleted").get());
       --i;
       continue;
     }
 
-    if (permEntry.mNonSessionPermission != permEntry.mPermission) {
-      permEntry.mPermission = permEntry.mNonSessionPermission;
+    permEntry.mPermission = permEntry.mNonSessionPermission;
+    permEntry.mExpireType = permEntry.mNonSessionExpireType;
 
-      gPermissionManager->NotifyObserversWithPermission(entry->GetKey()->mHost,
-                                                        entry->GetKey()->mAppId,
-                                                        entry->GetKey()->mIsInBrowserElement,
-                                                        gPermissionManager->mTypeArray.ElementAt(permEntry.mType),
-                                                        permEntry.mPermission,
-                                                        permEntry.mExpireType,
-                                                        permEntry.mExpireTime,
-                                                        NS_LITERAL_STRING("changed").get());
-    }
+    gPermissionManager->NotifyObserversWithPermission(entry->GetKey()->mHost,
+                                                      entry->GetKey()->mAppId,
+                                                      entry->GetKey()->mIsInBrowserElement,
+                                                      gPermissionManager->mTypeArray.ElementAt(permEntry.mType),
+                                                      permEntry.mPermission,
+                                                      permEntry.mExpireType,
+                                                      permEntry.mExpireTime,
+                                                      NS_LITERAL_STRING("changed").get());
   }
 
   return PL_DHASH_NEXT;
 }
 
 nsresult
 nsPermissionManager::RemoveExpiredPermissionsForApp(uint32_t aAppId)
 {
--- a/extensions/cookie/nsPermissionManager.h
+++ b/extensions/cookie/nsPermissionManager.h
@@ -39,24 +39,26 @@ public:
     PermissionEntry(int64_t aID, uint32_t aType, uint32_t aPermission,
                     uint32_t aExpireType, int64_t aExpireTime)
      : mID(aID)
      , mType(aType)
      , mPermission(aPermission)
      , mExpireType(aExpireType)
      , mExpireTime(aExpireTime)
      , mNonSessionPermission(aPermission)
+     , mNonSessionExpireType(aExpireType)
     {}
 
     int64_t  mID;
     uint32_t mType;
     uint32_t mPermission;
     uint32_t mExpireType;
     int64_t  mExpireTime;
     uint32_t mNonSessionPermission;
+    uint32_t mNonSessionExpireType;
   };
 
   /**
    * PermissionKey is the key used by PermissionHashKey hash table.
    *
    * NOTE: It could be implementing nsIHashable but there is no reason to worry
    * with XPCOM interfaces while we don't need to.
    */
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -193,16 +193,20 @@ dwrite-font-printing.patch: bug 468568; 
 d2d-gradient-ensure-stops.patch: bug 792903, ensure we don't set num_stops to 0
 
 setlcdfilter_in_tree.patch: bug 790139; force cairo to use FT_Library_SetLcdFilter from our in tree library rather than picking it up from the system
 
 dwrite-font-match-robustness.patch: bug 717178, don't crash when _name_tables_match is passed a nil scaled-font
 
 handle-multi-path-clip.patch: bug 813124, handle multiple clip paths correctly
 
+win32-gdi-font-cache.patch: Bug 717178, cache GDI font faces to reduce usage of GDI resources
+
+win32-gdi-font-cache-no-HFONT.patch: Bug 717178, don't cache GDI font faces when an HFONT belonging to the caller is passed in
+
 ==== pixman patches ====
 
 pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.
 
 pixman-rename-and-endian.patch: include cairo-platform.h for renaming of external symbols and endian macros
 
 NOTE: we previously supported ARM assembler on MSVC, this has been removed because of the maintenance burden
 
--- a/gfx/cairo/cairo/src/cairo-debug.c
+++ b/gfx/cairo/cairo/src/cairo-debug.c
@@ -64,16 +64,20 @@ cairo_debug_reset_static_data (void)
     _cairo_scaled_font_map_destroy ();
 
     _cairo_toy_font_face_reset_static_data ();
 
 #if CAIRO_HAS_FT_FONT
     _cairo_ft_font_reset_static_data ();
 #endif
 
+#if CAIRO_HAS_WIN32_FONT
+    _cairo_win32_font_reset_static_data ();
+#endif
+
     _cairo_intern_string_reset_static_data ();
 
     _cairo_scaled_font_reset_static_data ();
 
     _cairo_pattern_reset_static_data ();
 
     _cairo_clip_reset_static_data ();
 
--- a/gfx/cairo/cairo/src/cairo-mutex-list-private.h
+++ b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
@@ -46,16 +46,20 @@ CAIRO_MUTEX_DECLARE (_cairo_intern_strin
 CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex)
 CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex)
 CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex)
 
 #if CAIRO_HAS_FT_FONT
 CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
 #endif
 
+#if CAIRO_HAS_WIN32_FONT
+CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex)
+#endif
+
 #if CAIRO_HAS_XLIB_SURFACE
 CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex)
 #endif
 
 #if CAIRO_HAS_XCB_SURFACE
 CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex)
 #endif
 
--- a/gfx/cairo/cairo/src/cairo-win32-font.c
+++ b/gfx/cairo/cairo/src/cairo-win32-font.c
@@ -42,16 +42,18 @@
 # define _WIN32_WINNT 0x0500
 #endif
 
 #include "cairoint.h"
 
 #include "cairo-win32-private.h"
 #include "cairo-error-private.h"
 
+#include <wchar.h>
+
 #ifndef SPI_GETFONTSMOOTHINGTYPE
 #define SPI_GETFONTSMOOTHINGTYPE 0x200a
 #endif
 #ifndef FE_FONTSMOOTHINGCLEARTYPE
 #define FE_FONTSMOOTHINGCLEARTYPE 2
 #endif
 #ifndef CLEARTYPE_QUALITY
 #define CLEARTYPE_QUALITY 5
@@ -1887,19 +1889,17 @@ struct _cairo_win32_font_face {
     cairo_font_face_t base;
     LOGFONTW logfont;
     HFONT hfont;
 };
 
 /* implement the platform-specific interface */
 
 static void
-_cairo_win32_font_face_destroy (void *abstract_face)
-{
-}
+_cairo_win32_font_face_destroy (void *abstract_face);
 
 static cairo_bool_t
 _is_scale (const cairo_matrix_t *matrix, double scale)
 {
     return matrix->xx == scale && matrix->yy == scale &&
            matrix->xy == 0. && matrix->yx == 0. &&
            matrix->x0 == 0. && matrix->y0 == 0.;
 }
@@ -1932,16 +1932,135 @@ static cairo_status_t
 
 const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
     CAIRO_FONT_TYPE_WIN32,
     _cairo_win32_font_face_create_for_toy,
     _cairo_win32_font_face_destroy,
     _cairo_win32_font_face_scaled_font_create
 };
 
+/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t.
+ * The primary purpose of this mapping is to provide unique
+ * #cairo_font_face_t values so that our cache and mapping from
+ * #cairo_font_face_t => #cairo_scaled_font_t works. Once the
+ * corresponding #cairo_font_face_t objects fall out of downstream
+ * caches, we don't need them in this hash table anymore.
+ *
+ * Modifications to this hash table are protected by
+ * _cairo_win32_font_face_mutex.
+ *
+ * Only #cairo_font_face_t values with null 'hfont' (no
+ * HFONT preallocated by caller) are stored in this table. We rely
+ * on callers to manage the lifetime of the HFONT, and they can't
+ * do that if we share #cairo_font_face_t values with other callers.
+ */
+
+static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL;
+
+static int
+_cairo_win32_font_face_keys_equal (const void *key_a,
+				   const void *key_b);
+
+static void
+_cairo_win32_font_face_hash_table_destroy (void)
+{
+    cairo_hash_table_t *hash_table;
+
+    /* We manually acquire the lock rather than calling
+     * _cairo_win32_font_face_hash_table_lock simply to avoid creating
+     * the table only to destroy it again. */
+    CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
+    hash_table = cairo_win32_font_face_hash_table;
+    cairo_win32_font_face_hash_table = NULL;
+    CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
+
+    if (hash_table != NULL)
+	_cairo_hash_table_destroy (hash_table);
+}
+
+static cairo_hash_table_t *
+_cairo_win32_font_face_hash_table_lock (void)
+{
+    CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
+
+    if (unlikely (cairo_win32_font_face_hash_table == NULL))
+    {
+	cairo_win32_font_face_hash_table =
+	_cairo_hash_table_create (_cairo_win32_font_face_keys_equal);
+
+	if (unlikely (cairo_win32_font_face_hash_table == NULL)) {
+	    CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
+	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	    return NULL;
+	}
+    }
+
+    return cairo_win32_font_face_hash_table;
+}
+
+static void
+_cairo_win32_font_face_hash_table_unlock (void)
+{
+    CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
+}
+
+static void
+_cairo_win32_font_face_init_key (cairo_win32_font_face_t *key,
+				 LOGFONTW                *logfont,
+				 HFONT                    font)
+{
+    unsigned long hash = _CAIRO_HASH_INIT_VALUE;
+
+    key->logfont = *logfont;
+    key->hfont = font;
+
+    hash = _cairo_hash_bytes (0, logfont->lfFaceName, 2*wcslen(logfont->lfFaceName));
+    hash = _cairo_hash_bytes (hash, &logfont->lfWeight, sizeof(logfont->lfWeight));
+    hash = _cairo_hash_bytes (hash, &logfont->lfItalic, sizeof(logfont->lfItalic));
+
+    key->base.hash_entry.hash = hash;
+}
+
+static int
+_cairo_win32_font_face_keys_equal (const void *key_a,
+				   const void *key_b)
+{
+    const cairo_win32_font_face_t *face_a = key_a;
+    const cairo_win32_font_face_t *face_b = key_b;
+
+    if (face_a->logfont.lfWeight         == face_b->logfont.lfWeight &&
+	face_a->logfont.lfItalic         == face_b->logfont.lfItalic &&
+	face_a->logfont.lfUnderline      == face_b->logfont.lfUnderline &&
+	face_a->logfont.lfStrikeOut      == face_b->logfont.lfStrikeOut &&
+	face_a->logfont.lfCharSet        == face_b->logfont.lfCharSet &&
+	face_a->logfont.lfOutPrecision   == face_b->logfont.lfOutPrecision &&
+	face_a->logfont.lfClipPrecision  == face_b->logfont.lfClipPrecision &&
+	face_a->logfont.lfPitchAndFamily == face_b->logfont.lfPitchAndFamily &&
+	(wcscmp (face_a->logfont.lfFaceName, face_b->logfont.lfFaceName) == 0))
+	return TRUE;
+    else
+	return FALSE;
+}
+
+static void
+_cairo_win32_font_face_destroy (void *abstract_face)
+{
+    cairo_hash_table_t *hash_table;
+    cairo_win32_font_face_t *font_face = abstract_face;
+
+    if (!font_face->hfont) {
+        hash_table = _cairo_win32_font_face_hash_table_lock ();
+        if (unlikely (hash_table == NULL)) {
+            return;
+        }
+        _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
+        _cairo_win32_font_face_hash_table_unlock ();
+    }
+}
+
 /**
  * cairo_win32_font_face_create_for_logfontw_hfont:
  * @logfont: A #LOGFONTW structure specifying the font to use.
  *   If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement
  *   fields of this structure are ignored. Otherwise lfWidth, lfOrientation and
  *   lfEscapement must be zero.
  * @font: An #HFONT that can be used when the font matrix is a scale by
  *   -lfHeight and the CTM is identity.
@@ -1954,30 +2073,69 @@ const cairo_font_face_backend_t _cairo_w
  * and can be used with functions such as cairo_win32_scaled_font_select_font().
  *
  * Return value: a newly created #cairo_font_face_t. Free with
  *  cairo_font_face_destroy() when you are done using it.
  **/
 cairo_font_face_t *
 cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
 {
-    cairo_win32_font_face_t *font_face;
+    cairo_win32_font_face_t *font_face, key;
+    cairo_hash_table_t *hash_table;
+    cairo_status_t status;
+
+    if (!font) {
+        hash_table = _cairo_win32_font_face_hash_table_lock ();
+        if (unlikely (hash_table == NULL)) {
+            _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+	    return (cairo_font_face_t *)&_cairo_font_face_nil;
+        }
 
+        _cairo_win32_font_face_init_key (&key, logfont, font);
+
+        /* Return existing unscaled font if it exists in the hash table. */
+        font_face = _cairo_hash_table_lookup (hash_table,
+                                              &key.base.hash_entry);
+        if (font_face != NULL) {
+	    cairo_font_face_reference (&font_face->base);
+	    goto DONE;
+        }
+    }
+
+    /* Otherwise create it and insert into hash table. */
     font_face = malloc (sizeof (cairo_win32_font_face_t));
     if (!font_face) {
         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
-        return (cairo_font_face_t *)&_cairo_font_face_nil;
+	goto FAIL;
+    }
+
+    _cairo_win32_font_face_init_key (font_face, logfont, font);
+    _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
+    assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
+
+    if (!font) {
+        status = _cairo_hash_table_insert (hash_table,
+                                           &font_face->base.hash_entry);
+        if (unlikely (status))
+	    goto FAIL;
     }
 
-    font_face->logfont = *logfont;
-    font_face->hfont = font;
-
-    _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
+DONE:
+    if (!font) {
+        _cairo_win32_font_face_hash_table_unlock ();
+    }
 
     return &font_face->base;
+
+FAIL:
+    if (!font) {
+        _cairo_win32_font_face_hash_table_unlock ();
+    }
+
+    return (cairo_font_face_t *)&_cairo_font_face_nil;
 }
 
 /**
  * cairo_win32_font_face_create_for_logfontw:
  * @logfont: A #LOGFONTW structure specifying the font to use.
  *   The lfHeight, lfWidth, lfOrientation and lfEscapement
  *   fields of this structure are ignored.
  *
@@ -2176,8 +2334,14 @@ cairo_win32_scaled_font_get_device_to_lo
     cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
     if (! _cairo_scaled_font_is_win32 (scaled_font)) {
 	_cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
 	cairo_matrix_init_identity (device_to_logical);
 	return;
     }
     *device_to_logical = win_font->device_to_logical;
 }
+
+void
+_cairo_win32_font_reset_static_data (void)
+{
+    _cairo_win32_font_face_hash_table_destroy ();
+}
--- a/gfx/cairo/cairo/src/cairoint.h
+++ b/gfx/cairo/cairo/src/cairoint.h
@@ -403,16 +403,19 @@ cairo_private void
 _cairo_reset_static_data (void);
 
 cairo_private void
 _cairo_toy_font_face_reset_static_data (void);
 
 cairo_private void
 _cairo_ft_font_reset_static_data (void);
 
+cairo_private void
+_cairo_win32_font_reset_static_data (void);
+
 /* the font backend interface */
 
 struct _cairo_unscaled_font_backend {
     void (*destroy)     	    (void		             *unscaled_font);
 };
 
 /* #cairo_toy_font_face_t - simple family/slant/weight font faces used for
  * the built-in font API
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/win32-gdi-font-cache-no-HFONT.patch
@@ -0,0 +1,145 @@
+# HG changeset patch
+# User Robert O'Callahan <robert@ocallahan.org>
+# Date 1357107533 -46800
+# Node ID ed54dfdd2facb11a4d4158138b460a31de45e9f7
+# Parent ab6457cc16ec14ea07386dcfc57cad6b8a9ac55d
+Bug 717178. Part 3 alternative: don't put Win32 cairo_font_face_ts into the font-face cache if they were created with an explicit HFONT. r=jrmuizel
+
+diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c
+--- a/gfx/cairo/cairo/src/cairo-win32-font.c
++++ b/gfx/cairo/cairo/src/cairo-win32-font.c
+@@ -1941,16 +1942,21 @@ const cairo_font_face_backend_t _cairo_w
+  * The primary purpose of this mapping is to provide unique
+  * #cairo_font_face_t values so that our cache and mapping from
+  * #cairo_font_face_t => #cairo_scaled_font_t works. Once the
+  * corresponding #cairo_font_face_t objects fall out of downstream
+  * caches, we don't need them in this hash table anymore.
+  *
+  * Modifications to this hash table are protected by
+  * _cairo_win32_font_face_mutex.
++ *
++ * Only #cairo_font_face_t values with null 'hfont' (no
++ * HFONT preallocated by caller) are stored in this table. We rely
++ * on callers to manage the lifetime of the HFONT, and they can't
++ * do that if we share #cairo_font_face_t values with other callers.
+  */
+ 
+ static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL;
+ 
+ static int
+ _cairo_win32_font_face_keys_equal (const void *key_a,
+ 				   const void *key_b);
+ 
+@@ -2036,22 +2042,24 @@ static int
+ }
+ 
+ static void
+ _cairo_win32_font_face_destroy (void *abstract_face)
+ {
+     cairo_hash_table_t *hash_table;
+     cairo_win32_font_face_t *font_face = abstract_face;
+ 
+-    hash_table = _cairo_win32_font_face_hash_table_lock ();
+-    if (unlikely (hash_table == NULL)) {
+-        return;
++    if (!font_face->hfont) {
++        hash_table = _cairo_win32_font_face_hash_table_lock ();
++        if (unlikely (hash_table == NULL)) {
++            return;
++        }
++        _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
++        _cairo_win32_font_face_hash_table_unlock ();
+     }
+-    _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
+-    _cairo_win32_font_face_hash_table_unlock ();
+ }
+ 
+ /**
+  * cairo_win32_font_face_create_for_logfontw_hfont:
+  * @logfont: A #LOGFONTW structure specifying the font to use.
+  *   If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement
+  *   fields of this structure are ignored. Otherwise lfWidth, lfOrientation and
+  *   lfEscapement must be zero.
+@@ -2070,55 +2078,63 @@ static void
+  **/
+ cairo_font_face_t *
+ cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
+ {
+     cairo_win32_font_face_t *font_face, key;
+     cairo_hash_table_t *hash_table;
+     cairo_status_t status;
+ 
+-    hash_table = _cairo_win32_font_face_hash_table_lock ();
+-    if (unlikely (hash_table == NULL)) {
+-        _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+-	return (cairo_font_face_t *)&_cairo_font_face_nil;
+-    }
++    if (!font) {
++        hash_table = _cairo_win32_font_face_hash_table_lock ();
++        if (unlikely (hash_table == NULL)) {
++            _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
++	    return (cairo_font_face_t *)&_cairo_font_face_nil;
++        }
+ 
+-    _cairo_win32_font_face_init_key (&key, logfont, font);
++        _cairo_win32_font_face_init_key (&key, logfont, font);
+ 
+-    /* Return existing unscaled font if it exists in the hash table. */
+-    font_face = _cairo_hash_table_lookup (hash_table,
+-					 &key.base.hash_entry);
+-    if (font_face != NULL) {
+-	cairo_font_face_reference (&font_face->base);
+-	goto DONE;
++        /* Return existing unscaled font if it exists in the hash table. */
++        font_face = _cairo_hash_table_lookup (hash_table,
++                                              &key.base.hash_entry);
++        if (font_face != NULL) {
++	    cairo_font_face_reference (&font_face->base);
++	    goto DONE;
++        }
+     }
+ 
+     /* Otherwise create it and insert into hash table. */
+     font_face = malloc (sizeof (cairo_win32_font_face_t));
+     if (!font_face) {
+         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+ 	goto FAIL;
+     }
+ 
+     _cairo_win32_font_face_init_key (font_face, logfont, font);
+     _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
++    assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
+ 
+-    assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
+-    status = _cairo_hash_table_insert (hash_table,
+-				       &font_face->base.hash_entry);
+-    if (unlikely (status))
+-	goto FAIL;
++    if (!font) {
++        status = _cairo_hash_table_insert (hash_table,
++                                           &font_face->base.hash_entry);
++        if (unlikely (status))
++	    goto FAIL;
++    }
+ 
+ DONE:
+-    _cairo_win32_font_face_hash_table_unlock ();
++    if (!font) {
++        _cairo_win32_font_face_hash_table_unlock ();
++    }
+ 
+     return &font_face->base;
+ 
+ FAIL:
+-    _cairo_win32_font_face_hash_table_unlock ();
++    if (!font) {
++        _cairo_win32_font_face_hash_table_unlock ();
++    }
+ 
+     return (cairo_font_face_t *)&_cairo_font_face_nil;
+ }
+ 
+ /**
+  * cairo_win32_font_face_create_for_logfontw:
+  * @logfont: A #LOGFONTW structure specifying the font to use.
+  *   The lfHeight, lfWidth, lfOrientation and lfEscapement
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/win32-gdi-font-cache.patch
@@ -0,0 +1,375 @@
+# HG changeset patch
+# User Andrea Canciani <ranma42@gmail.com>, Adrian Johnson <ajohnson@redneon.com>
+# Date 1354838294 -46800
+# Node ID 390df735b9d5c5ba07a4d3fe9ca2ebc9e7626a78
+# Parent e30a5b6a5a003b85fc1ca8b76719a56ef59d976e
+Bug 717178. Part 2: Import changesets eb29a25d, 6e3e3291 and 101fab7c from upstream.
+======
+
+From 101fab7cd8a90f7cf3d8113c792b3f8c2a9afb7d Mon Sep 17 00:00:00 2001
+From: Andrea Canciani <ranma42@gmail.com>
+Date: Wed, 15 Jun 2011 09:37:36 +0000
+Subject: win32-font: Improve static data reset function
+
+The hashtable is guaranteed to only contain font faces which are
+currently referenced, hence there is no need to remove any font face
+when it is reset (just like for toy-font).
+
+This makes the function simpler and fixes the assertion
+
+Assertion failed: predicate != NULL, file cairo-hash.c, line 373
+
+hit by multiple tests (the first one being "clear").
+
+See https://bugs.freedesktop.org/show_bug.cgi?id=38049
+
+======
+
+From eb29a25dd6dddc511388bf883c9b95843ecdb823 Mon Sep 17 00:00:00 2001
+From: Adrian Johnson <ajohnson@redneon.com>
+Date: Tue, 16 Nov 2010 13:18:39 +0000
+Subject: win32: Use a font_face hash table to provide unique font faces
+
+Similar to the freetype and toy font backends, use a hash table
+to map logfont,hfont to font faces.
+
+This fixes the multiple embedding of the same font in PDF.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=24849
+
+======
+
+From 6e3e329170ab4b96bc0d587c8071e869e228e758 Mon Sep 17 00:00:00 2001
+From: Adrian Johnson <ajohnson@redneon.com>
+Date: Thu, 18 Nov 2010 12:37:45 +0000
+Subject: win32: fix font_face hashing
+
+some bugs were discovered while testing with firefox
+
+======
+
+diff --git a/gfx/cairo/cairo/src/cairo-debug.c b/gfx/cairo/cairo/src/cairo-debug.c
+--- a/gfx/cairo/cairo/src/cairo-debug.c
++++ b/gfx/cairo/cairo/src/cairo-debug.c
+@@ -64,16 +64,20 @@ cairo_debug_reset_static_data (void)
+     _cairo_scaled_font_map_destroy ();
+ 
+     _cairo_toy_font_face_reset_static_data ();
+ 
+ #if CAIRO_HAS_FT_FONT
+     _cairo_ft_font_reset_static_data ();
+ #endif
+ 
++#if CAIRO_HAS_WIN32_FONT
++    _cairo_win32_font_reset_static_data ();
++#endif
++
+     _cairo_intern_string_reset_static_data ();
+ 
+     _cairo_scaled_font_reset_static_data ();
+ 
+     _cairo_pattern_reset_static_data ();
+ 
+     _cairo_clip_reset_static_data ();
+ 
+diff --git a/gfx/cairo/cairo/src/cairo-mutex-list-private.h b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
+--- a/gfx/cairo/cairo/src/cairo-mutex-list-private.h
++++ b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
+@@ -46,16 +46,20 @@ CAIRO_MUTEX_DECLARE (_cairo_intern_strin
+ CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex)
+ CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex)
+ CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex)
+ 
+ #if CAIRO_HAS_FT_FONT
+ CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
+ #endif
+ 
++#if CAIRO_HAS_WIN32_FONT
++CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex)
++#endif
++
+ #if CAIRO_HAS_XLIB_SURFACE
+ CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex)
+ #endif
+ 
+ #if CAIRO_HAS_XCB_SURFACE
+ CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex)
+ #endif
+ 
+diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c
+--- a/gfx/cairo/cairo/src/cairo-win32-font.c
++++ b/gfx/cairo/cairo/src/cairo-win32-font.c
+@@ -42,16 +42,18 @@
+ # define _WIN32_WINNT 0x0500
+ #endif
+ 
+ #include "cairoint.h"
+ 
+ #include "cairo-win32-private.h"
+ #include "cairo-error-private.h"
+ 
++#include <wchar.h>
++
+ #ifndef SPI_GETFONTSMOOTHINGTYPE
+ #define SPI_GETFONTSMOOTHINGTYPE 0x200a
+ #endif
+ #ifndef FE_FONTSMOOTHINGCLEARTYPE
+ #define FE_FONTSMOOTHINGCLEARTYPE 2
+ #endif
+ #ifndef CLEARTYPE_QUALITY
+ #define CLEARTYPE_QUALITY 5
+@@ -1887,19 +1889,17 @@ struct _cairo_win32_font_face {
+     cairo_font_face_t base;
+     LOGFONTW logfont;
+     HFONT hfont;
+ };
+ 
+ /* implement the platform-specific interface */
+ 
+ static void
+-_cairo_win32_font_face_destroy (void *abstract_face)
+-{
+-}
++_cairo_win32_font_face_destroy (void *abstract_face);
+ 
+ static cairo_bool_t
+ _is_scale (const cairo_matrix_t *matrix, double scale)
+ {
+     return matrix->xx == scale && matrix->yy == scale &&
+            matrix->xy == 0. && matrix->yx == 0. &&
+            matrix->x0 == 0. && matrix->y0 == 0.;
+ }
+@@ -1932,16 +1932,128 @@ static cairo_status_t
+ 
+ const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
+     CAIRO_FONT_TYPE_WIN32,
+     _cairo_win32_font_face_create_for_toy,
+     _cairo_win32_font_face_destroy,
+     _cairo_win32_font_face_scaled_font_create
+ };
+ 
++/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t.
++ * The primary purpose of this mapping is to provide unique
++ * #cairo_font_face_t values so that our cache and mapping from
++ * #cairo_font_face_t => #cairo_scaled_font_t works. Once the
++ * corresponding #cairo_font_face_t objects fall out of downstream
++ * caches, we don't need them in this hash table anymore.
++ *
++ * Modifications to this hash table are protected by
++ * _cairo_win32_font_face_mutex.
++ */
++
++static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL;
++
++static int
++_cairo_win32_font_face_keys_equal (const void *key_a,
++				   const void *key_b);
++
++static void
++_cairo_win32_font_face_hash_table_destroy (void)
++{
++    cairo_hash_table_t *hash_table;
++
++    /* We manually acquire the lock rather than calling
++     * _cairo_win32_font_face_hash_table_lock simply to avoid creating
++     * the table only to destroy it again. */
++    CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
++    hash_table = cairo_win32_font_face_hash_table;
++    cairo_win32_font_face_hash_table = NULL;
++    CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
++
++    if (hash_table != NULL)
++	_cairo_hash_table_destroy (hash_table);
++}
++
++static cairo_hash_table_t *
++_cairo_win32_font_face_hash_table_lock (void)
++{
++    CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
++
++    if (unlikely (cairo_win32_font_face_hash_table == NULL))
++    {
++	cairo_win32_font_face_hash_table =
++	_cairo_hash_table_create (_cairo_win32_font_face_keys_equal);
++
++	if (unlikely (cairo_win32_font_face_hash_table == NULL)) {
++	    CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
++	    _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
++	    return NULL;
++	}
++    }
++
++    return cairo_win32_font_face_hash_table;
++}
++
++static void
++_cairo_win32_font_face_hash_table_unlock (void)
++{
++    CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
++}
++
++static void
++_cairo_win32_font_face_init_key (cairo_win32_font_face_t *key,
++				 LOGFONTW                *logfont,
++				 HFONT                    font)
++{
++    unsigned long hash = _CAIRO_HASH_INIT_VALUE;
++
++    key->logfont = *logfont;
++    key->hfont = font;
++
++    hash = _cairo_hash_bytes (0, logfont->lfFaceName, 2*wcslen(logfont->lfFaceName));
++    hash = _cairo_hash_bytes (hash, &logfont->lfWeight, sizeof(logfont->lfWeight));
++    hash = _cairo_hash_bytes (hash, &logfont->lfItalic, sizeof(logfont->lfItalic));
++
++    key->base.hash_entry.hash = hash;
++}
++
++static int
++_cairo_win32_font_face_keys_equal (const void *key_a,
++				   const void *key_b)
++{
++    const cairo_win32_font_face_t *face_a = key_a;
++    const cairo_win32_font_face_t *face_b = key_b;
++
++    if (face_a->logfont.lfWeight         == face_b->logfont.lfWeight &&
++	face_a->logfont.lfItalic         == face_b->logfont.lfItalic &&
++	face_a->logfont.lfUnderline      == face_b->logfont.lfUnderline &&
++	face_a->logfont.lfStrikeOut      == face_b->logfont.lfStrikeOut &&
++	face_a->logfont.lfCharSet        == face_b->logfont.lfCharSet &&
++	face_a->logfont.lfOutPrecision   == face_b->logfont.lfOutPrecision &&
++	face_a->logfont.lfClipPrecision  == face_b->logfont.lfClipPrecision &&
++	face_a->logfont.lfPitchAndFamily == face_b->logfont.lfPitchAndFamily &&
++	(wcscmp (face_a->logfont.lfFaceName, face_b->logfont.lfFaceName) == 0))
++	return TRUE;
++    else
++	return FALSE;
++}
++
++static void
++_cairo_win32_font_face_destroy (void *abstract_face)
++{
++    cairo_hash_table_t *hash_table;
++    cairo_win32_font_face_t *font_face = abstract_face;
++
++    hash_table = _cairo_win32_font_face_hash_table_lock ();
++    if (unlikely (hash_table == NULL)) {
++        return;
++    }
++    _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
++    _cairo_win32_font_face_hash_table_unlock ();
++}
++
+ /**
+  * cairo_win32_font_face_create_for_logfontw_hfont:
+  * @logfont: A #LOGFONTW structure specifying the font to use.
+  *   If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement
+  *   fields of this structure are ignored. Otherwise lfWidth, lfOrientation and
+  *   lfEscapement must be zero.
+  * @font: An #HFONT that can be used when the font matrix is a scale by
+  *   -lfHeight and the CTM is identity.
+@@ -1954,30 +2066,61 @@ const cairo_font_face_backend_t _cairo_w
+  * and can be used with functions such as cairo_win32_scaled_font_select_font().
+  *
+  * Return value: a newly created #cairo_font_face_t. Free with
+  *  cairo_font_face_destroy() when you are done using it.
+  **/
+ cairo_font_face_t *
+ cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
+ {
+-    cairo_win32_font_face_t *font_face;
++    cairo_win32_font_face_t *font_face, key;
++    cairo_hash_table_t *hash_table;
++    cairo_status_t status;
+ 
++    hash_table = _cairo_win32_font_face_hash_table_lock ();
++    if (unlikely (hash_table == NULL)) {
++        _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
++	return (cairo_font_face_t *)&_cairo_font_face_nil;
++    }
++
++    _cairo_win32_font_face_init_key (&key, logfont, font);
++
++    /* Return existing unscaled font if it exists in the hash table. */
++    font_face = _cairo_hash_table_lookup (hash_table,
++					 &key.base.hash_entry);
++    if (font_face != NULL) {
++	cairo_font_face_reference (&font_face->base);
++	goto DONE;
++    }
++
++    /* Otherwise create it and insert into hash table. */
+     font_face = malloc (sizeof (cairo_win32_font_face_t));
+     if (!font_face) {
+         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+-        return (cairo_font_face_t *)&_cairo_font_face_nil;
++	goto FAIL;
+     }
+ 
+-    font_face->logfont = *logfont;
+-    font_face->hfont = font;
+-
++    _cairo_win32_font_face_init_key (font_face, logfont, font);
+     _cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
+ 
++    assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
++    status = _cairo_hash_table_insert (hash_table,
++				       &font_face->base.hash_entry);
++    if (unlikely (status))
++	goto FAIL;
++
++DONE:
++    _cairo_win32_font_face_hash_table_unlock ();
++
+     return &font_face->base;
++
++FAIL:
++    _cairo_win32_font_face_hash_table_unlock ();
++
++    return (cairo_font_face_t *)&_cairo_font_face_nil;
+ }
+ 
+ /**
+  * cairo_win32_font_face_create_for_logfontw:
+  * @logfont: A #LOGFONTW structure specifying the font to use.
+  *   The lfHeight, lfWidth, lfOrientation and lfEscapement
+  *   fields of this structure are ignored.
+  *
+@@ -2176,8 +2319,14 @@ cairo_win32_scaled_font_get_device_to_lo
+     cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
+     if (! _cairo_scaled_font_is_win32 (scaled_font)) {
+ 	_cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
+ 	cairo_matrix_init_identity (device_to_logical);
+ 	return;
+     }
+     *device_to_logical = win_font->device_to_logical;
+ }
++
++void
++_cairo_win32_font_reset_static_data (void)
++{
++    _cairo_win32_font_face_hash_table_destroy ();
++}
+diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h
+--- a/gfx/cairo/cairo/src/cairoint.h
++++ b/gfx/cairo/cairo/src/cairoint.h
+@@ -403,16 +403,19 @@ cairo_private void
+ _cairo_reset_static_data (void);
+ 
+ cairo_private void
+ _cairo_toy_font_face_reset_static_data (void);
+ 
+ cairo_private void
+ _cairo_ft_font_reset_static_data (void);
+ 
++cairo_private void
++_cairo_win32_font_reset_static_data (void);
++
+ /* the font backend interface */
+ 
+ struct _cairo_unscaled_font_backend {
+     void (*destroy)     	    (void		             *unscaled_font);
+ };
+ 
+ /* #cairo_toy_font_face_t - simple family/slant/weight font faces used for
+  * the built-in font API
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -169,17 +169,17 @@ FontPrefsObserver::Observe(nsISupports *
         return NS_ERROR_UNEXPECTED;
     }
     NS_ASSERTION(gfxPlatform::GetPlatform(), "the singleton instance has gone");
     gfxPlatform::GetPlatform()->FontsPrefsChanged(NS_ConvertUTF16toUTF8(someData).get());
 
     return NS_OK;
 }
 
-class OrientationSyncPrefsObserver : public nsIObserver
+class OrientationSyncPrefsObserver MOZ_FINAL : public nsIObserver
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIOBSERVER
 };
 
 NS_IMPL_ISUPPORTS1(OrientationSyncPrefsObserver, nsIObserver)
 
--- a/js/src/assembler/jit/ExecutableAllocator.h
+++ b/js/src/assembler/jit/ExecutableAllocator.h
@@ -262,17 +262,17 @@ public:
     void setRandomize(bool enabled) {
         allocBehavior = enabled ? AllocationCanRandomize : AllocationDeterministic;
     }
 
 private:
     static size_t pageSize;
     static size_t largeAllocSize;
 #if WTF_OS_WINDOWS
-    static int64_t rngSeed;
+    static uint64_t rngSeed;
 #endif
 
     static const size_t OVERSIZE_ALLOCATION = size_t(-1);
 
     static size_t roundUpAllocationSize(size_t request, size_t granularity)
     {
         // Something included via windows.h defines a macro with this name,
         // which causes the function below to fail to compile.
--- a/js/src/assembler/jit/ExecutableAllocatorWin.cpp
+++ b/js/src/assembler/jit/ExecutableAllocatorWin.cpp
@@ -25,22 +25,22 @@
 
 #include "ExecutableAllocator.h"
 
 #if ENABLE_ASSEMBLER && WTF_OS_WINDOWS
 
 #include "jswin.h"
 #include "prmjtime.h"
 
-extern void random_setSeed(int64_t *, int64_t);
-extern uint64_t random_next(int64_t *, int);
+extern void random_setSeed(uint64_t *, uint64_t);
+extern uint64_t random_next(uint64_t *, int);
 
 namespace JSC {
 
-int64_t ExecutableAllocator::rngSeed;
+uint64_t ExecutableAllocator::rngSeed;
 
 void ExecutableAllocator::initSeed()
 {
     random_setSeed(&rngSeed, (PRMJ_Now() / 1000) ^ int64_t(this));
 }
 
 size_t ExecutableAllocator::determinePageSize()
 {
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -138,17 +138,17 @@ ExecuteRegExpImpl(JSContext *cx, RegExpS
 }
 
 /* Legacy ExecuteRegExp behavior is baked into the JSAPI. */
 bool
 js::ExecuteRegExpLegacy(JSContext *cx, RegExpStatics *res, RegExpObject &reobj,
                         Handle<JSStableString*> input, StableCharPtr chars, size_t length,
                         size_t *lastIndex, JSBool test, jsval *rval)
 {
-    RegExpGuard shared;
+    RegExpGuard shared(cx);
     if (!reobj.getShared(cx, &shared))
         return false;
 
     ScopedMatchPairs matches(&cx->tempLifoAlloc());
     MatchConduit conduit(&matches);
 
     RegExpRunStatus status =
         ExecuteRegExpImpl(cx, res, *shared, reobj, input, chars, length, lastIndex, conduit);
@@ -247,17 +247,17 @@ CompileRegExpObject(JSContext *cx, RegEx
         }
 
         /*
          * Only extract the 'flags' out of sourceObj; do not reuse the
          * RegExpShared since it may be from a different compartment.
          */
         RegExpFlag flags;
         {
-            RegExpGuard g;
+            RegExpGuard g(cx);
             if (!RegExpToShared(cx, *sourceObj, &g))
                 return false;
 
             flags = g->getFlags();
         }
 
         /*
          * 'toSource' is a permanent read-only property, so this is equivalent
@@ -551,17 +551,17 @@ js_InitRegExpClass(JSContext *cx, Handle
 }
 
 RegExpRunStatus
 js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string, MatchConduit &matches)
 {
     /* Step 1 (b) was performed by CallNonGenericMethod. */
     Rooted<RegExpObject*> reobj(cx, &regexp->asRegExp());
 
-    RegExpGuard re;
+    RegExpGuard re(cx);
     if (!reobj->getShared(cx, &re))
         return RegExpRunStatus_Error;
 
     RegExpStatics *res = cx->regExpStatics();
 
     /* Step 3. */
     Rooted<JSStableString*> stableInput(cx, string->ensureStable(cx));
     if (!stableInput)
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -4093,16 +4093,39 @@ else
         AC_MSG_ERROR([Cannot find cl -showIncludes prefix.])
     fi
     AC_SUBST(CL_INCLUDES_PREFIX)
     rm -f dummy-hello.c
   fi
 fi
 
 dnl ========================================================
+dnl = Disable -fstrict-aliasing on Linux/Android with GCC 4.4 and earlier.
+dnl = See bug 821502.
+dnl ========================================================
+case "$target" in
+*-android*|*-linuxandroid*|*-*linux*)
+    if test "$GNU_CC"; then
+        changequote(,)
+        GCC_VERSION_FULL=`echo "$CXX_VERSION" | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'`
+        GCC_VERSION=`echo "$GCC_VERSION_FULL" | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'`
+        changequote([,])
+
+        GCC_MAJOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print $1 }'`
+        GCC_MINOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print $2 }'`
+
+        dnl GCC 3.x isn't supported, so we don't need to check for that.
+        if test "$GCC_MAJOR_VERSION" -eq "4" -a "$GCC_MINOR_VERSION" -lt "5" ; then
+            CFLAGS="$CFLAGS -fno-strict-aliasing"
+            CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"
+        fi
+    fi
+esac
+
+dnl ========================================================
 dnl = Link js shell to system readline
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(readline,
 [  --enable-readline       Link js shell to system readline library],
     JS_WANT_READLINE=1,
     JS_WANT_READLINE= )
 
 JS_NATIVE_EDITLINE=
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -2133,17 +2133,17 @@ ConvertToJS(JSContext* cx,
 // ambiguity to a C type. Elements of a Int8Array are converted to
 // ctypes.int8_t, UInt8Array to ctypes.uint8_t, etc.
 bool CanConvertTypedArrayItemTo(JSObject *baseType, JSObject *valObj, JSContext *cx) {
   TypeCode baseTypeCode = CType::GetTypeCode(baseType);
   if (baseTypeCode == TYPE_void_t) {
     return true;
   }
   TypeCode elementTypeCode;
-  switch (JS_GetTypedArrayType(valObj)) {
+  switch (JS_GetArrayBufferViewType(valObj)) {
   case TypedArray::TYPE_INT8:
     elementTypeCode = TYPE_int8_t;
     break;
   case TypedArray::TYPE_UINT8:
   case TypedArray::TYPE_UINT8_CLAMPED:
     elementTypeCode = TYPE_uint8_t;
     break;
   case TypedArray::TYPE_INT16:
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -114,37 +114,35 @@ frontend::IsIdentifier(JSLinearString *s
 #pragma warning(push)
 #pragma warning(disable:4351)
 #endif
 
 /* Initialize members that aren't initialized in |init|. */
 TokenStream::TokenStream(JSContext *cx, const CompileOptions &options,
                          StableCharPtr base, size_t length, StrictModeGetter *smg)
   : tokens(),
-    tokensRoot(cx, &tokens),
     cursor(),
     lookahead(),
     lineno(options.lineno),
     flags(),
     linebase(base.get()),
     prevLinebase(NULL),
-    linebaseRoot(cx, &linebase),
-    prevLinebaseRoot(cx, &prevLinebase),
     userbuf(base.get(), length),
     filename(options.filename),
     sourceMap(NULL),
     listenerTSData(),
     tokenbuf(cx),
     version(options.version),
     banXML(VersionHasAllowXML(options.version) ? 0 : 1),
     moarXML(VersionHasMoarXML(options.version)),
     cx(cx),
     originPrincipals(JSScript::normalizeOriginPrincipals(options.principals,
                                                          options.originPrincipals)),
-    strictModeGetter(smg)
+    strictModeGetter(smg),
+    tokenSkip(cx, &tokens)
 {
     if (originPrincipals)
         JS_HoldPrincipals(originPrincipals);
 
     JSSourceHandler listener = cx->runtime->debugHooks.sourceHandler;
     void *listenerData = cx->runtime->debugHooks.sourceHandlerData;
 
     if (listener)
@@ -1437,18 +1435,16 @@ TokenStream::getTokenInternal()
     int c, qc;
     Token *tp;
     FirstCharKind c1kind;
     const jschar *numStart;
     bool hasFracOrExp;
     const jschar *identStart;
     bool hadUnicodeEscape;
 
-    SkipRoot skipNum(cx, &numStart), skipIdent(cx, &identStart);
-
 #if JS_HAS_XML_SUPPORT
     /*
      * Look for XML text and tags.
      */
     if (flags & (TSF_XMLTEXTMODE|TSF_XMLTAGMODE)) {
         if (!getXMLTextOrTag(&tt, &tp))
             goto error;
         goto out;
--- a/js/src/frontend/TokenStream.h
+++ b/js/src/frontend/TokenStream.h
@@ -847,40 +847,44 @@ class TokenStream
         while (--n >= 0)
             getChar();
     }
 
     void updateLineInfoForEOL();
     void updateFlagsForEOL();
 
     Token               tokens[ntokens];/* circular token buffer */
-    js::SkipRoot        tokensRoot;     /* prevent overwriting of token buffer */
     unsigned            cursor;         /* index of last parsed token */
     unsigned            lookahead;      /* count of lookahead tokens */
     unsigned            lineno;         /* current line number */
     unsigned            flags;          /* flags -- see above */
     const jschar        *linebase;      /* start of current line;  points into userbuf */
     const jschar        *prevLinebase;  /* start of previous line;  NULL if on the first line */
-    js::SkipRoot        linebaseRoot;
-    js::SkipRoot        prevLinebaseRoot;
     TokenBuf            userbuf;        /* user input buffer */
     const char          *filename;      /* input filename or null */
     jschar              *sourceMap;     /* source map's filename or null */
     void                *listenerTSData;/* listener data for this TokenStream */
     CharBuffer          tokenbuf;       /* current token string buffer */
     int8_t              oneCharTokens[128];  /* table of one-char tokens */
     bool                maybeEOL[256];       /* probabilistic EOL lookup table */
     bool                maybeStrSpecial[256];/* speeds up string scanning */
     JSVersion           version;        /* (i.e. to identify keywords) */
     unsigned            banXML;         /* see JSOPTION_ALLOW_XML */
     bool                moarXML;        /* see JSOPTION_MOAR_XML */
     JSContext           *const cx;
     JSPrincipals        *const originPrincipals;
     StrictModeGetter    *strictModeGetter; /* used to test for strict mode */
     Position            lastFunctionKeyword; /* used as a starting point for reparsing strict functions */
+
+    /*
+     * The tokens array stores pointers to JSAtoms. These are rooted by the
+     * atoms table using AutoKeepAtoms in the Parser. This SkipRoot tells the
+     * exact rooting analysis to ignore the atoms in the tokens array.
+     */
+    SkipRoot            tokenSkip;
 };
 
 struct KeywordInfo {
     const char  *chars;         /* C string with keyword text */
     TokenKind   tokentype;
     JSOp        op;             /* JSOp */
     JSVersion   version;        /* JSVersion */
 };
--- a/js/src/gc/Root.h
+++ b/js/src/gc/Root.h
@@ -267,35 +267,23 @@ typedef Handle<Value>        HandleValue
  * If you want to add additional methods to MutableHandle for a specific
  * specialization, define a MutableHandleBase<T> specialization containing
  * them.
  */
 template <typename T>
 class MutableHandle : public js::MutableHandleBase<T>
 {
   public:
-    template <typename S>
-    MutableHandle(MutableHandle<S> handle,
-                  typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
-    {
-        this->ptr = reinterpret_cast<const T *>(handle.address());
-    }
-
-    template <typename S>
-    inline MutableHandle(js::Rooted<S> *root,
-                         typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
+    inline MutableHandle(js::Rooted<T> *root);
 
     void set(T v) {
         JS_ASSERT(!js::RootMethods<T>::poisoned(v));
         *ptr = v;
     }
 
-    template <typename S>
-    inline void set(const js::Unrooted<S> &v);
-
     /*
      * This may be called only if the location of the T is guaranteed
      * to be marked (for some reason other than being a Rooted),
      * e.g., if it is guaranteed to be reachable from an implicit root.
      *
      * Create a MutableHandle from a raw location of a T.
      */
     static MutableHandle fromMarkedLocation(T *p) {
@@ -854,31 +842,23 @@ Handle<T>::Handle(js::Rooted<S> &root,
 template <typename T> template <typename S>
 inline
 Handle<T>::Handle(MutableHandle<S> &root,
                   typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
 {
     ptr = reinterpret_cast<const T *>(root.address());
 }
 
-template <typename T> template <typename S>
+template <typename T>
 inline
-MutableHandle<T>::MutableHandle(js::Rooted<S> *root,
-                                typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
+MutableHandle<T>::MutableHandle(js::Rooted<T> *root)
 {
     ptr = root->address();
 }
 
-template <typename T> template <typename S>
-inline void MutableHandle<T>::set(const js::Unrooted<S> &v)
-{
-    JS_ASSERT(!js::RootMethods<T>::poisoned(v));
-    *ptr = static_cast<S>(v);
-}
-
 /*
  * The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
  * attempted while the guard object is live.  If you have a GC-unsafe operation
  * to perform, use this guard object to protect your operation.
  */
 class AutoAssertNoGC
 {
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
--- a/js/src/ion/CodeGenerator.cpp
+++ b/js/src/ion/CodeGenerator.cpp
@@ -965,17 +965,17 @@ static const VMFunction GetIntrinsicValu
 
 bool
 CodeGenerator::visitCallGetIntrinsicValue(LCallGetIntrinsicValue *lir)
 {
     pushArg(ImmGCPtr(lir->mir()->name()));
     return callVM(GetIntrinsicValueInfo, lir);
 }
 
-typedef bool (*InvokeFunctionFn)(JSContext *, JSFunction *, uint32_t, Value *, Value *);
+typedef bool (*InvokeFunctionFn)(JSContext *, HandleFunction, uint32_t, Value *, Value *);
 static const VMFunction InvokeFunctionInfo = FunctionInfo<InvokeFunctionFn>(InvokeFunction);
 
 bool
 CodeGenerator::emitCallInvokeFunction(LInstruction *call, Register calleereg,
                                       uint32_t argc, uint32_t unusedStack)
 {
     // Nestle %esp up to the argument vector.
     // Each path must account for framePushed_ separately, for callVM to be valid.
@@ -1101,28 +1101,28 @@ CodeGenerator::visitCallGeneric(LCallGen
 
 bool
 CodeGenerator::visitCallKnown(LCallKnown *call)
 {
     JSContext *cx = GetIonContext()->cx;
     Register calleereg = ToRegister(call->getFunction());
     Register objreg    = ToRegister(call->getTempObject());
     uint32_t unusedStack = StackOffsetOfPassedArg(call->argslot());
-    JSFunction *target = call->getSingleTarget();
+    RootedFunction target(cx, call->getSingleTarget());
     Label end, invoke;
 
     // Native single targets are handled by LCallNative.
     JS_ASSERT(!target->isNative());
     // Missing arguments must have been explicitly appended by the IonBuilder.
     JS_ASSERT(target->nargs <= call->numStackArgs());
 
     masm.checkStackAlignment();
 
     // Make sure the function has a JSScript
-    if (target->isInterpretedLazy() && !target->getOrCreateScript(cx))
+    if (target->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, target))
         return false;
 
     // If the function is known to be uncompilable, only emit the call to InvokeFunction.
     ExecutionMode executionMode = gen->info().executionMode();
     RootedScript targetScript(cx, target->nonLazyScript());
     if (GetIonScript(targetScript, executionMode) == ION_DISABLED_SCRIPT) {
         if (!emitCallInvokeFunction(call, calleereg, call->numActualArgs(), unusedStack))
             return false;
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -1067,18 +1067,18 @@ class AutoDestroyAllocator
 };
 
 class SequentialCompileContext {
 public:
     ExecutionMode executionMode() {
         return SequentialExecution;
     }
 
-    bool compile(IonBuilder *builder, MIRGraph *graph,
-                 AutoDestroyAllocator &autoDestroy);
+    AbortReason compile(IonBuilder *builder, MIRGraph *graph,
+                        AutoDestroyAllocator &autoDestroy);
 };
 
 void
 AttachFinishedCompilations(JSContext *cx)
 {
 #ifdef JS_THREADSAFE
     AssertCanGC();
     IonCompartment *ion = cx->compartment->ionCompartment();
@@ -1134,86 +1134,88 @@ AttachFinishedCompilations(JSContext *cx
 
     compilations.clear();
 #endif
 }
 
 static const size_t BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
 
 template <typename CompileContext>
-static bool
+static AbortReason
 IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing,
            CompileContext &compileContext)
 {
     AssertCanGC();
 #if JS_TRACE_LOGGING
     AutoTraceLog logger(TraceLogging::defaultLogger(),
                         TraceLogging::ION_COMPILE_START,
                         TraceLogging::ION_COMPILE_STOP,
                         script);
 #endif
 
     LifoAlloc *alloc = cx->new_<LifoAlloc>(BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
     if (!alloc)
-        return false;
+        return AbortReason_Alloc;
 
     AutoDestroyAllocator autoDestroy(alloc);
 
     TempAllocator *temp = alloc->new_<TempAllocator>(alloc);
     if (!temp)
-        return false;
+        return AbortReason_Alloc;
 
     IonContext ictx(cx, cx->compartment, temp);
 
     if (!cx->compartment->ensureIonCompartmentExists(cx))
-        return false;
+        return AbortReason_Alloc;
 
     MIRGraph *graph = alloc->new_<MIRGraph>(temp);
     ExecutionMode executionMode = compileContext.executionMode();
     CompileInfo *info = alloc->new_<CompileInfo>(script, fun, osrPc, constructing,
                                                  executionMode);
     if (!info)
-        return false;
+        return AbortReason_Alloc;
 
     types::AutoEnterTypeInference enter(cx, true);
     TypeInferenceOracle oracle;
 
     if (!oracle.init(cx, script))
-        return false;
+        return AbortReason_Disable;
 
     AutoFlushCache afc("IonCompile");
 
     types::AutoEnterCompilation enterCompiler(cx, CompilerOutputKind(executionMode));
     if (!enterCompiler.init(script, false, 0))
-        return false;
+        return AbortReason_Disable;
 
     AutoTempAllocatorRooter root(cx, temp);
 
     IonBuilder *builder = alloc->new_<IonBuilder>(cx, temp, graph, &oracle, info);
-    if (!compileContext.compile(builder, graph, autoDestroy)) {
+    if (!builder)
+        return AbortReason_Alloc;
+
+    AbortReason abortReason  = compileContext.compile(builder, graph, autoDestroy);
+    if (abortReason != AbortReason_NoAbort)
         IonSpew(IonSpew_Abort, "IM Compilation failed.");
-        return false;
-    }
 
-    return true;
+    return abortReason;
 }
 
-bool
+AbortReason
 SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
                                   AutoDestroyAllocator &autoDestroy)
 {
     JS_ASSERT(!builder->script()->ion);
     JSContext *cx = GetIonContext()->cx;
 
     RootedScript builderScript(cx, builder->script());
     IonSpewNewFunction(graph, builderScript);
 
     if (!builder->build()) {
         IonSpew(IonSpew_Abort, "Builder failed to build.");
-        return false;
+        return builder->abortReason();
     }
     builder->clearForBackEnd();
 
     // Try to compile the script off thread, if possible. Compilation cannot be
     // performed off thread during an incremental GC, as doing so may trip
     // incremental read barriers. Also skip off thread compilation if script
     // execution is being profiled, as CodeGenerator::maybeCreateScriptCounts
     // will not attach script profiles when running off thread.
@@ -1221,50 +1223,61 @@ SequentialCompileContext::compile(IonBui
         OffThreadCompilationAvailable(cx) &&
         cx->runtime->gcIncrementalState == gc::NO_INCREMENTAL &&
         !cx->runtime->profilingScripts)
     {
         builder->script()->ion = ION_COMPILING_SCRIPT;
 
         if (!StartOffThreadIonCompile(cx, builder)) {
             IonSpew(IonSpew_Abort, "Unable to start off-thread ion compilation.");
-            return false;
+            return AbortReason_Alloc;
         }
 
         // The allocator and associated data will be destroyed after being
         // processed in the finishedOffThreadCompilations list.
         autoDestroy.cancel();
 
-        return true;
+        return AbortReason_NoAbort;
     }
 
     CodeGenerator *codegen = CompileBackEnd(builder);
     if (!codegen) {
         IonSpew(IonSpew_Abort, "Failed during back-end compilation.");
-        return false;
+        return AbortReason_Disable;
     }
 
     bool success = codegen->link();
     js_delete(codegen);
 
     IonSpewEndFunction();
 
-    return success;
+    return success ? AbortReason_NoAbort : AbortReason_Disable;
 }
 
-bool
+MethodStatus
 TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing)
 {
     SequentialCompileContext compileContext;
-    if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext)) {
+
+    AbortReason reason = IonCompile(cx, script, fun, osrPc, constructing, compileContext);
+
+    if (reason == AbortReason_Alloc)
+        return Method_Skipped;
+
+    if (reason == AbortReason_Inlining)
+        return Method_Skipped;
+
+    if (reason == AbortReason_Disable) {
         if (!cx->isExceptionPending())
             ForbidCompilation(cx, script);
-        return false;
+        return Method_CantCompile;
     }
-    return true;
+
+    JS_ASSERT(reason == AbortReason_NoAbort);
+    return Method_Compiled;
 }
 
 static bool
 CheckFrame(StackFrame *fp)
 {
     if (fp->isEvalFrame()) {
         // Eval frames are not yet supported. Supporting this will require new
         // logic in pushBailoutFrame to deal with linking prev.
@@ -1370,20 +1383,22 @@ Compile(JSContext *cx, HandleScript scri
         if (script->getUseCount() < js_IonOptions.usesBeforeCompile)
             return Method_Skipped;
     } else {
         if (script->incUseCount() < js_IonOptions.usesBeforeCompileNoJaeger)
             return Method_Skipped;
     }
 
     SequentialCompileContext compileContext;
-    if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext))
+
+    AbortReason reason = IonCompile(cx, script, fun, osrPc, constructing, compileContext);
+    if (reason == AbortReason_Disable)
         return Method_CantCompile;
 
-    // Compilation succeeded, but we invalidated right away.
+    // Compilation succeeded or we invalidated right away or an inlining/alloc abort
     return script->hasIonScript() ? Method_Compiled : Method_Skipped;
 }
 
 } // namespace ion
 } // namespace js
 
 // Decide if a transition from interpreter execution to Ion code should occur.
 // May compile or recompile the target JSScript.
--- a/js/src/ion/Ion.h
+++ b/js/src/ion/Ion.h
@@ -206,16 +206,23 @@ struct IonOptions
 enum MethodStatus
 {
     Method_Error,
     Method_CantCompile,
     Method_Skipped,
     Method_Compiled
 };
 
+enum AbortReason {
+    AbortReason_Alloc,
+    AbortReason_Inlining,
+    AbortReason_Disable,
+    AbortReason_NoAbort
+};
+
 // An Ion context is needed to enter into either an Ion method or an instance
 // of the Ion compiler. It points to a temporary allocator and the active
 // JSContext, either of which may be NULL, and the active compartment, which
 // will not be NULL.
 
 class IonContext
 {
   public:
@@ -291,17 +298,17 @@ void ToggleBarriers(JSCompartment *comp,
 
 class IonBuilder;
 class MIRGenerator;
 class CodeGenerator;
 
 CodeGenerator *CompileBackEnd(MIRGenerator *mir);
 void AttachFinishedCompilations(JSContext *cx);
 void FinishOffThreadBuilder(IonBuilder *builder);
-bool TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing);
+MethodStatus TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing);
 
 static inline bool IsEnabled(JSContext *cx)
 {
     return cx->hasRunOption(JSOPTION_ION) && cx->typeInferenceEnabled();
 }
 
 void ForbidCompilation(JSContext *cx, UnrootedScript script);
 uint32_t UsesBeforeIonRecompile(UnrootedScript script, jsbytecode *pc);
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -30,16 +30,17 @@ using namespace js::ion;
 using mozilla::DebugOnly;
 
 IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
                        TypeOracle *oracle, CompileInfo *info, size_t inliningDepth, uint32_t loopDepth)
   : MIRGenerator(cx->compartment, temp, graph, info),
     backgroundCodegen_(NULL),
     recompileInfo(cx->compartment->types.compiledInfo),
     cx(cx),
+    abortReason_(AbortReason_Disable),
     loopDepth_(loopDepth),
     callerResumePoint_(NULL),
     callerBuilder_(NULL),
     oracle(oracle),
     inliningDepth(inliningDepth),
     failedBoundsCheck_(info->script()->failedBoundsCheck),
     failedShapeGuard_(info->script()->failedShapeGuard),
     lazyArguments_(NULL)
@@ -341,16 +342,17 @@ IonBuilder::build()
 
     if (!traverseBytecode())
         return false;
 
     if (!processIterators())
         return false;
 
     JS_ASSERT(loopDepth_ == 0);
+    abortReason_ = AbortReason_NoAbort;
     return true;
 }
 
 bool
 IonBuilder::processIterators()
 {
     // Find phis that must directly hold an iterator live.
     Vector<MPhi *, 0, SystemAllocPolicy> worklist;
@@ -2905,18 +2907,26 @@ IonBuilder::jsop_call_inline(HandleFunct
         thisDefn = createThis(callee, constFun);
         if (!thisDefn)
             return false;
     } else {
         thisDefn = argv[0];
     }
 
     // Build the graph.
-    if (!inlineBuilder.buildInline(this, inlineResumePoint, thisDefn, argv))
+    if (!inlineBuilder.buildInline(this, inlineResumePoint, thisDefn, argv)) {
+        JS_ASSERT(calleeScript->hasAnalysis());
+
+        // Inlining the callee failed. Disable inlining the function
+        if (inlineBuilder.abortReason_ == AbortReason_Disable)
+            calleeScript->analysis()->setIonUninlineable();
+
+        abortReason_ = AbortReason_Inlining;
         return false;
+    }
 
     MIRGraphExits &exits = *inlineBuilder.graph().exitAccumulator();
 
     // Replace all MReturns with MGotos, and remember the MDefinition that
     // would have been returned.
     for (MBasicBlock **it = exits.begin(), **end = exits.end(); it != end; ++it) {
         MBasicBlock *exitBlock = *it;
 
--- a/js/src/ion/IonBuilder.h
+++ b/js/src/ion/IonBuilder.h
@@ -470,18 +470,21 @@ class IonBuilder : public MIRGenerator
 
     void clearForBackEnd();
 
     UnrootedScript script() const { return script_.get(); }
 
     CodeGenerator *backgroundCodegen() const { return backgroundCodegen_; }
     void setBackgroundCodegen(CodeGenerator *codegen) { backgroundCodegen_ = codegen; }
 
+    AbortReason abortReason() { return abortReason_; }
+
   private:
     JSContext *cx;
+    AbortReason abortReason_;
 
     jsbytecode *pc;
     MBasicBlock *current;
     uint32_t loopDepth_;
 
     /* Information used for inline-call builders. */
     MResumePoint *callerResumePoint_;
     jsbytecode *callerPC() {
--- a/js/src/ion/VMFunctions.cpp
+++ b/js/src/ion/VMFunctions.cpp
@@ -42,24 +42,24 @@ static inline bool
 ShouldMonitorReturnType(JSFunction *fun)
 {
     return fun->isInterpreted() &&
            (!fun->nonLazyScript()->hasAnalysis() ||
             !fun->nonLazyScript()->analysis()->ranInference());
 }
 
 bool
-InvokeFunction(JSContext *cx, JSFunction *fun, uint32_t argc, Value *argv, Value *rval)
+InvokeFunction(JSContext *cx, HandleFunction fun, uint32_t argc, Value *argv, Value *rval)
 {
-    Value fval = ObjectValue(*fun);
+    AssertCanGC();
 
     // In order to prevent massive bouncing between Ion and JM, see if we keep
     // hitting functions that are uncompilable.
     if (fun->isInterpreted()) {
-        if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
+        if (fun->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, fun))
             return false;
         if (!fun->nonLazyScript()->canIonCompile()) {
             UnrootedScript script = GetTopIonJSScript(cx);
             if (script->hasIonScript() &&
                 ++script->ion->slowCallCount >= js_IonOptions.slowCallLimit)
             {
                 AutoFlushCache afc("InvokeFunction");
 
@@ -82,17 +82,17 @@ InvokeFunction(JSContext *cx, JSFunction
     // path frequently.
     bool needsMonitor = ShouldMonitorReturnType(fun);
 
     // Data in the argument vector is arranged for a JIT -> JIT call.
     Value thisv = argv[0];
     Value *argvWithoutThis = argv + 1;
 
     // Run the function in the interpreter.
-    bool ok = Invoke(cx, thisv, fval, argc, argvWithoutThis, rval);
+    bool ok = Invoke(cx, thisv, ObjectValue(*fun), argc, argvWithoutThis, rval);
     if (ok && needsMonitor)
         types::TypeScript::Monitor(cx, *rval);
 
     return ok;
 }
 
 JSObject *
 NewGCThing(JSContext *cx, gc::AllocKind allocKind, size_t thingSize)
--- a/js/src/ion/VMFunctions.h
+++ b/js/src/ion/VMFunctions.h
@@ -405,17 +405,17 @@ class AutoDetectInvalidation
     }
 
     ~AutoDetectInvalidation() {
         if (!disabled_ && ionScript_->invalidated())
             cx_->runtime->setIonReturnOverride(*rval_);
     }
 };
 
-bool InvokeFunction(JSContext *cx, JSFunction *fun, uint32_t argc, Value *argv, Value *rval);
+bool InvokeFunction(JSContext *cx, HandleFunction fun, uint32_t argc, Value *argv, Value *rval);
 JSObject *NewGCThing(JSContext *cx, gc::AllocKind allocKind, size_t thingSize);
 
 bool CheckOverRecursed(JSContext *cx);
 
 bool DefVarOrConst(JSContext *cx, HandlePropertyName dn, unsigned attrs, HandleObject scopeChain);
 bool InitProp(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value);
 
 template<bool Equal>
--- a/js/src/ion/arm/CodeGenerator-arm.cpp
+++ b/js/src/ion/arm/CodeGenerator-arm.cpp
@@ -1158,17 +1158,17 @@ bool
 CodeGeneratorARM::visitCompareD(LCompareD *comp)
 {
     FloatRegister lhs = ToFloatRegister(comp->left());
     FloatRegister rhs = ToFloatRegister(comp->right());
 
     Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop());
     masm.compareDouble(lhs, rhs);
     emitSet(Assembler::ConditionFromDoubleCondition(cond), ToRegister(comp->output()));
-    return false;
+    return true;
 }
 
 bool
 CodeGeneratorARM::visitCompareDAndBranch(LCompareDAndBranch *comp)
 {
     FloatRegister lhs = ToFloatRegister(comp->left());
     FloatRegister rhs = ToFloatRegister(comp->right());
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug826581.js
@@ -0,0 +1,12 @@
+// Don't crash.
+
+try {
+    x = "          ()    ";
+    for (var y = 0; y < 19; y++) {
+        x += x;
+    }
+} catch (e) {}
+
+try {
+	"".replace(x, "", "gy");
+} catch (e) { }
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-onPop-generators-01.js
@@ -0,0 +1,20 @@
+// Returning {throw:} from an onPop handler when yielding works and
+// does not close the generator-iterator.
+
+load(libdir + "asserts.js");
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+dbg.onDebuggerStatement = function handleDebugger(frame) {
+    frame.onPop = function (c) {
+        return {throw: "fit"};
+    };
+};
+g.eval("function g() { for (var i = 0; i < 10; i++) { debugger; yield i; } }");
+g.eval("var it = g();");
+var rv = gw.evalInGlobal("it.next();");
+assertEq(rv.throw, "fit");
+
+dbg.enabled = false;
+assertEq(g.it.next(), 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-onPop-generators-02.js
@@ -0,0 +1,17 @@
+// Throwing an exception from an onPop handler when yielding terminates the debuggee
+// but does not close the generator-iterator.
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger;
+var gw = dbg.addDebuggee(g);
+dbg.onDebuggerStatement = function handleDebugger(frame) {
+    frame.onPop = function (c) {
+        throw "fit";
+    };
+};
+g.eval("function g() { for (var i = 0; i < 10; i++) { debugger; yield i; } }");
+g.eval("var it = g();");
+assertEq(gw.evalInGlobal("it.next();"), null);
+
+dbg.enabled = false;
+assertEq(g.it.next(), 1);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/bug-826669.js
@@ -0,0 +1,7 @@
+gczeal(9, 2)
+var g1 = newGlobal('new-compartment');
+var g2 = newGlobal('new-compartment');
+var dbg = new Debugger();
+var g1w = dbg.addDebuggee(g1);
+g1.eval('function f() {}');
+scripts = dbg.findScripts({});
--- a/js/src/jsanalyze.h
+++ b/js/src/jsanalyze.h
@@ -879,16 +879,17 @@ class ScriptAnalysis
 
     /* Analyze the effect of invoking 'new' on script. */
     void analyzeTypesNew(JSContext *cx);
 
     bool OOM() const { return outOfMemory; }
     bool failed() const { return hadFailure; }
     bool ionInlineable() const { return isIonInlineable; }
     bool ionInlineable(uint32_t argc) const { return isIonInlineable && argc == script_->function()->nargs; }
+    void setIonUninlineable() { isIonInlineable = false; }
     bool jaegerInlineable() const { return isJaegerInlineable; }
     bool jaegerInlineable(uint32_t argc) const { return isJaegerInlineable && argc == script_->function()->nargs; }
     bool jaegerCompileable() { return isJaegerCompileable; }
 
     /* Number of property read opcodes in the script. */
     uint32_t numPropertyReads() const { return numPropertyReads_; }
 
     /* Whether there are POPV/SETRVAL bytecodes which can write to the frame's rval. */
--- a/js/src/jsapi-tests/testOOM.cpp
+++ b/js/src/jsapi-tests/testOOM.cpp
@@ -3,19 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "tests.h"
 
 #include "mozilla/DebugOnly.h"
 
 BEGIN_TEST(testOOM)
 {
-    JSString *jsstr = JS_ValueToString(cx, INT_TO_JSVAL(9));
-    jsval tmp = STRING_TO_JSVAL(jsstr);
-    JS_SetProperty(cx, global, "rootme", &tmp);
+    js::RootedString jsstr(cx, JS_ValueToString(cx, INT_TO_JSVAL(9)));
     mozilla::DebugOnly<const jschar *> s = JS_GetStringCharsZ(cx, jsstr);
     JS_ASSERT(s[0] == '9' && s[1] == '\0');
     return true;
 }
 
 virtual JSRuntime * createRuntime()
 {
     JSRuntime *rt = JS_NewRuntime(0, JS_USE_HELPER_THREADS);
--- a/js/src/jsapi-tests/testSourcePolicy.cpp
+++ b/js/src/jsapi-tests/testSourcePolicy.cpp
@@ -1,13 +1,14 @@
 /* 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/. */
 
 #include "tests.h"
+#include "jsscript.h"
 
 BEGIN_TEST(testBug795104)
 {
     JS::CompileOptions opts(cx);
     opts.setSourcePolicy(JS::CompileOptions::NO_SOURCE);
     const size_t strLen = 60002;
     char *s = static_cast<char *>(JS_malloc(cx, strLen));
     CHECK(s);
@@ -16,8 +17,31 @@ BEGIN_TEST(testBug795104)
     s[strLen - 1] = '"';
     CHECK(JS::Evaluate(cx, global, opts, s, strLen, NULL));
     CHECK(JS::CompileFunction(cx, global, opts, "f", 0, NULL, s, strLen));
     JS_free(cx, s);
 
     return true;
 }
 END_TEST(testBug795104)
+
+const char *simpleSource = "var x = 4;";
+
+static void
+newScriptHook(JSContext *cx, const char *fn, unsigned lineno,
+              JSScript *script, JSFunction *fun, void *data)
+{
+    if (!JS_StringEqualsAscii(cx, script->sourceData(cx), simpleSource, (JSBool *)data))
+        *((JSBool *)data) = JS_FALSE;
+}
+
+BEGIN_TEST(testScriptSourceReentrant)
+{
+    JS::CompileOptions opts(cx);
+    JSBool match = false;
+    JS_SetNewScriptHook(rt, newScriptHook, &match);
+    CHECK(JS::Evaluate(cx, global, opts, simpleSource, strlen(simpleSource), NULL));
+    CHECK(match);
+    JS_SetNewScriptHook(rt, NULL, NULL);
+
+    return true;
+}
+END_TEST(testScriptSourceReentrant)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -885,17 +885,18 @@ JSRuntime::JSRuntime(JSUseHelperThreads 
     ionJSContext(NULL),
     ionStackLimit(0),
     ionActivation(NULL),
     ionPcScriptCache(NULL),
     threadPool(this),
     ctypesActivityCallback(NULL),
     ionReturnOverride_(MagicValue(JS_ARG_POISON)),
     useHelperThreads_(useHelperThreads),
-    requestedHelperThreadCount(-1)
+    requestedHelperThreadCount(-1),
+    rngNonce(0)
 {
     /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
     JS_INIT_CLIST(&onNewGlobalObjectWatchers);
 
     PodZero(&debugHooks);
     PodZero(&atomState);
 
 #if JS_STACK_GROWTH_DIRECTION > 0
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -260,18 +260,16 @@ js::NewContext(JSRuntime *rt, size_t sta
 
     /*
      * Here the GC lock is still held after js_InitContextThreadAndLockGC took it and
      * the GC is not running on another thread.
      */
     bool first = rt->contextList.isEmpty();
     rt->contextList.insertBack(cx);
 
-    js_InitRandom(cx);
-
     /*
      * If cx is the first context on this runtime, initialize well-known atoms,
      * keywords, numbers, strings and self-hosted scripts. 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 DestroyContext, because
      * cx will be "last" as well as "first".
      */
@@ -1112,17 +1110,16 @@ JSContext::JSContext(JSRuntime *rt)
     errorReporter(NULL),
     operationCallback(NULL),
     data(NULL),
     data2(NULL),
 #ifdef JS_THREADSAFE
     outstandingRequests(0),
 #endif
     resolveFlags(0),
-    rngSeed(0),
     iterValue(MagicValue(JS_NO_ITER_VALUE)),
 #ifdef JS_METHODJIT
     methodJitEnabled(false),
 #endif
 #ifdef MOZ_TRACE_JSCALLS
     functionCallback(NULL),
 #endif
     enumerators(NULL),
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -1215,16 +1215,26 @@ struct JSRuntime : js::RuntimeFriendFiel
 #ifdef JS_THREADSAFE
         if (requestedHelperThreadCount < 0)
             return js::GetCPUCount() - 1;
         return requestedHelperThreadCount;
 #else
         return 0;
 #endif
     }
+
+  private:
+    /*
+     * Used to ensure that compartments created at the same time get different
+     * random number sequences. See js::InitRandom.
+     */
+    uint64_t rngNonce;
+
+  public:
+    uint64_t nextRNGNonce() { return rngNonce++; }
 };
 
 /* Common macros to access thread-local caches in JSRuntime. */
 #define JS_KEEP_ATOMS(rt)   (rt)->gcKeepAtoms++;
 #define JS_UNKEEP_ATOMS(rt) (rt)->gcKeepAtoms--;
 
 namespace js {
 
@@ -1578,19 +1588,16 @@ struct JSContext : js::ContextFriendFiel
     unsigned            outstandingRequests;/* number of JS_BeginRequest calls
                                                without the corresponding
                                                JS_EndRequest. */
 #endif
 
     /* Stored here to avoid passing it around as a parameter. */
     unsigned               resolveFlags;
 
-    /* Random number generator state, used by jsmath.cpp. */
-    int64_t             rngSeed;
-
     /* Location to stash the iteration value between JSOP_MOREITER and JSOP_ITERNEXT. */
     js::Value           iterValue;
 
 #ifdef JS_METHODJIT
     bool                 methodJitEnabled;
 
     js::mjit::JaegerRuntime &jaegerRuntime() { return runtime->jaegerRuntime(); }
 #endif
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -75,16 +75,17 @@ JSCompartment::JSCompartment(JSRuntime *
     gcMallocAndFreeBytes(0),
     gcTriggerMallocAndFreeBytes(0),
     gcIncomingGrayPointers(NULL),
     gcLiveArrayBuffers(NULL),
     gcWeakMapList(NULL),
     gcGrayRoots(),
     gcMallocBytes(0),
     debugModeBits(rt->debugMode ? DebugFromC : 0),
+    rngState(0),
     watchpointMap(NULL),
     scriptCountsMap(NULL),
     debugScriptMap(NULL),
     debugScopes(NULL)
 #ifdef JS_ION
     , ionCompartment_(NULL)
 #endif
 {
@@ -123,16 +124,19 @@ JSCompartment::init(JSContext *cx)
     types.init(cx);
 
     if (!crossCompartmentWrappers.init())
         return false;
 
     if (!regExps.init(cx))
         return false;
 
+    if (cx)
+        InitRandom(cx->runtime, &rngState);
+
 #ifdef JSGC_GENERATIONAL
     /*
      * If we are in the middle of post-barrier verification, we need to
      * immediately begin collecting verification data on new compartments.
      */
     if (rt->gcVerifyPostData) {
         if (!gcNursery.enable())
             return false;
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -465,16 +465,19 @@ struct JSCompartment : private JS::shado
 
     void freeInCompartment(size_t nbytes) {
         JS_ASSERT(gcMallocAndFreeBytes >= nbytes);
         gcMallocAndFreeBytes -= nbytes;
     }
 
     js::DtoaCache dtoaCache;
 
+    /* Random number generator state, used by jsmath.cpp. */
+    uint64_t rngState;
+
   private:
     /*
      * Weak reference to each global in this compartment that is a debuggee.
      * Each global has its own list of debuggers.
      */
     js::GlobalObjectSet              debuggees;
 
   private:
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -447,20 +447,21 @@ JS_ReleaseFunctionLocalNameArray(JSConte
     cx->tempLifoAlloc().release(mark);
 }
 
 JS_PUBLIC_API(JSScript *)
 JS_GetFunctionScript(JSContext *cx, JSFunction *fun)
 {
     if (fun->isNative())
         return NULL;
-    RawScript script;
+    UnrootedScript script;
     if (fun->isInterpretedLazy()) {
-       AutoCompartment funCompartment(cx, fun);
-       script = fun->getOrCreateScript(cx);
+        RootedFunction rootedFun(cx, fun);
+        AutoCompartment funCompartment(cx, rootedFun);
+        script = JSFunction::getOrCreateScript(cx, rootedFun);
         if (!script)
             MOZ_CRASH();
     } else {
         script = fun->nonLazyScript();
     }
     return script;
 }
 
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1078,16 +1078,22 @@ enum ViewType {
     TYPE_FLOAT64,
 
     /*
      * Special type that is a uint8_t, but assignments are clamped to [0, 256).
      * Treat the raw data type as a uint8_t.
      */
     TYPE_UINT8_CLAMPED,
 
+    /*
+     * Type returned for a DataView. Note that there is no single element type
+     * in this case.
+     */
+    TYPE_DATAVIEW,
+
     TYPE_MAX
 };
 
 } /* namespace ArrayBufferView */
 } /* namespace js */
 
 typedef js::ArrayBufferView::ViewType JSArrayBufferViewType;
 
@@ -1251,24 +1257,24 @@ JS_GetObjectAsFloat32Array(JSObject *obj
 extern JS_FRIEND_API(JSObject *)
 JS_GetObjectAsFloat64Array(JSObject *obj, uint32_t *length, double **data);
 extern JS_FRIEND_API(JSObject *)
 JS_GetObjectAsArrayBufferView(JSObject *obj, uint32_t *length, uint8_t **data);
 extern JS_FRIEND_API(JSObject *)
 JS_GetObjectAsArrayBuffer(JSObject *obj, uint32_t *length, uint8_t **data);
 
 /*
- * Get the type of elements in a typed array.
+ * Get the type of elements in a typed array, or TYPE_DATAVIEW if a DataView.
  *
- * |obj| must have passed a JS_IsTypedArrayObject/JS_Is*Array test, or somehow
- * be known that it would pass such a test: it is a typed array or a wrapper of
- * a typed array, and the unwrapping will succeed.
+ * |obj| must have passed a JS_IsArrayBufferView/JS_Is*Array test, or somehow
+ * be known that it would pass such a test: it is an ArrayBufferView or a
+ * wrapper of an ArrayBufferView, and the unwrapping will succeed.
  */
 extern JS_FRIEND_API(JSArrayBufferViewType)
-JS_GetTypedArrayType(JSObject *obj);
+JS_GetArrayBufferViewType(JSObject *obj);
 
 /*
  * Check whether obj supports the JS_GetArrayBuffer* APIs. Note that this may
  * return false if a security wrapper is encountered that denies the
  * unwrapping. If this test succeeds, then it is safe to call the various
  * accessor JSAPI calls defined below.
  */
 extern JS_FRIEND_API(JSBool)
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -86,17 +86,17 @@ fun_getProperty(JSContext *cx, HandleObj
 
     /*
      * Mark the function's script as uninlineable, to expand any of its
      * frames on the stack before we go looking for them. This allows the
      * below walk to only check each explicit frame rather than needing to
      * check any calls that were inlined.
      */
     if (fun->isInterpreted()) {
-        fun->getOrCreateScript(cx)->uninlineable = true;
+        JSFunction::getOrCreateScript(cx, fun)->uninlineable = true;
         MarkTypeObjectFlags(cx, fun, OBJECT_FLAG_UNINLINEABLE);
     }
 
     /* Set to early to null in case of error */
     vp.setNull();
 
     /* Find fun's top-most activation record. */
     StackIter iter(cx);
@@ -336,17 +336,17 @@ fun_resolve(JSContext *cx, HandleObject 
         const uint16_t offset = poisonPillProps[i];
 
         if (JSID_IS_ATOM(id, OFFSET_TO_NAME(cx->runtime, offset))) {
             JS_ASSERT(!IsInternalFunctionObject(fun));
 
             PropertyOp getter;
             StrictPropertyOp setter;
             unsigned attrs = JSPROP_PERMANENT;
-            if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
+            if (fun->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, fun))
                 return false;
             if (fun->isInterpreted() ? fun->strict() : fun->isBoundFunction()) {
                 JSObject *throwTypeError = fun->global().getThrowTypeError();
 
                 getter = CastAsPropertyOp(throwTypeError);
                 setter = CastAsStrictPropertyOp(throwTypeError);
                 attrs |= JSPROP_GETTER | JSPROP_SETTER;
             } else {
@@ -1474,17 +1474,17 @@ js_CloneFunctionObject(JSContext *cx, Ha
         return NULL;
     RootedFunction clone(cx, cloneobj->toFunction());
 
     clone->nargs = fun->nargs;
     clone->flags = fun->flags & ~JSFunction::EXTENDED;
     if (fun->isInterpreted()) {
         if (fun->isInterpretedLazy()) {
             AutoCompartment ac(cx, fun);
-            if (!fun->getOrCreateScript(cx))
+            if (!JSFunction::getOrCreateScript(cx, fun))
                 return NULL;
         }
         clone->initScript(fun->nonLazyScript());
         clone->initEnvironment(parent);
     } else {
         clone->initNative(fun->native(), fun->jitInfo());
     }
     clone->initAtom(fun->displayAtom());
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -176,35 +176,36 @@ class JSFunction : public JSObject
      */
     inline JSObject *environment() const;
     inline void setEnvironment(JSObject *obj);
     inline void initEnvironment(JSObject *obj);
 
     static inline size_t offsetOfEnvironment() { return offsetof(JSFunction, u.i.env_); }
     static inline size_t offsetOfAtom() { return offsetof(JSFunction, atom_); }
 
-    js::UnrootedScript getOrCreateScript(JSContext *cx) {
-        JS_ASSERT(isInterpreted());
-        if (isInterpretedLazy()) {
-            js::RootedFunction self(cx, this);
+    static js::UnrootedScript getOrCreateScript(JSContext *cx, JS::HandleFunction fun) {
+        JS_ASSERT(fun->isInterpreted());
+        if (fun->isInterpretedLazy()) {
             js::MaybeCheckStackRoots(cx);
-            if (!initializeLazyScript(cx))
+            if (!fun->initializeLazyScript(cx))
                 return js::UnrootedScript(NULL);
         }
-        JS_ASSERT(hasScript());
-        return JS::HandleScript::fromMarkedLocation(&u.i.script_);
+        JS_ASSERT(fun->hasScript());
+        return fun->u.i.script_;
     }
 
-    bool maybeGetOrCreateScript(JSContext *cx, js::MutableHandle<JSScript*> script) {
-        if (isNative()) {
+    static bool maybeGetOrCreateScript(JSContext *cx, js::HandleFunction fun,
+                                       js::MutableHandle<JSScript*> script)
+    {
+        if (fun->isNative()) {
             script.set(NULL);
             return true;
         }
-        script.set(getOrCreateScript(cx));
-        return hasScript();
+        script.set(getOrCreateScript(cx, fun));
+        return fun->hasScript();
     }
 
     js::UnrootedScript nonLazyScript() const {
         JS_ASSERT(hasScript());
         return JS::HandleScript::fromMarkedLocation(&u.i.script_);
     }
 
     js::UnrootedScript maybeNonLazyScript() const {
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -1267,17 +1267,17 @@ TypeConstraintCall::newType(JSContext *c
                  callsite->returnTypes == script->analysis()->bytecodeTypes(pc));
 
     if (type.isUnknown() || type.isAnyObject()) {
         /* Monitor calls on unknown functions. */
         cx->compartment->types.monitorBytecode(cx, script, pc - script->code);
         return;
     }
 
-    JSFunction *callee = NULL;
+    RootedFunction callee(cx);
 
     if (type.isSingleObject()) {
         RootedObject obj(cx, type.singleObject());
 
         if (!obj->isFunction()) {
             /* Calls on non-functions are dynamically monitored. */
             return;
         }
@@ -1343,17 +1343,17 @@ TypeConstraintCall::newType(JSContext *c
         callee = type.typeObject()->interpretedFunction;
         if (!callee)
             return;
     } else {
         /* Calls on non-objects are dynamically monitored. */
         return;
     }
 
-    RootedScript calleeScript(cx, callee->getOrCreateScript(cx));
+    RootedScript calleeScript(cx, JSFunction::getOrCreateScript(cx, callee));
     if (!calleeScript)
         return;
     if (!calleeScript->ensureHasTypes(cx))
         return;
 
     unsigned nargs = callee->nargs;
 
     /* Add bindings for the arguments of the call. */
@@ -1392,47 +1392,49 @@ TypeConstraintCall::newType(JSContext *c
          */
         returnTypes->addSubset(cx, callsite->returnTypes);
     }
 }
 
 void
 TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
 {
+    AssertCanGC();
+
     if (type.isUnknown() || type.isAnyObject()) {
         /*
          * The callee is unknown, make sure the call is monitored so we pick up
          * possible this/callee correlations. This only comes into play for
          * CALLPROP, for other calls we are past the type barrier and a
          * TypeConstraintCall will also monitor the call.
          */
         RootedScript script(cx, script_);
         cx->compartment->types.monitorBytecode(cx, script, callpc - script->code);
         return;
     }
 
     /* Ignore calls to natives, these will be handled by TypeConstraintCall. */
-    JSFunction *callee = NULL;
+    RootedFunction callee(cx);
 
     if (type.isSingleObject()) {
         RootedObject object(cx, type.singleObject());
         if (!object->isFunction() || !object->toFunction()->isInterpreted())
             return;
         callee = object->toFunction();
     } else if (type.isTypeObject()) {
         TypeObject *object = type.typeObject();
         if (!object->interpretedFunction)
             return;
         callee = object->interpretedFunction;
     } else {
         /* Ignore calls to primitives, these will go through a stub. */
         return;
     }
 
-    if (!(callee->getOrCreateScript(cx) && callee->nonLazyScript()->ensureHasTypes(cx)))
+    if (!(JSFunction::getOrCreateScript(cx, callee) && callee->nonLazyScript()->ensureHasTypes(cx)))
         return;
 
     TypeSet *thisTypes = TypeScript::ThisTypes(callee->nonLazyScript());
     if (this->types)
         this->types->addSubset(cx, thisTypes);
     else
         thisTypes->addType(cx, this->type);
 }
@@ -5746,17 +5748,18 @@ TypeObject *
 JSObject::makeLazyType(JSContext *cx)
 {
     JS_ASSERT(hasLazyType());
     JS_ASSERT(cx->compartment == compartment());
 
     RootedObject self(cx, this);
     /* De-lazification of functions can GC, so we need to do it up here. */
     if (self->isFunction() && self->toFunction()->isInterpretedLazy()) {
-        if (!self->toFunction()->getOrCreateScript(cx))
+        RootedFunction fun(cx, self->toFunction());
+        if (!JSFunction::getOrCreateScript(cx, fun))
             return NULL;
     }
     JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(getClass());
     Rooted<TaggedProto> proto(cx, getTaggedProto());
     TypeObject *type = cx->compartment->types.newTypeObject(cx, key, proto);
     AutoAssertNoGC nogc;
     if (!type) {
         if (cx->typeInferenceEnabled())
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -385,17 +385,17 @@ js::InvokeKernel(JSContext *cx, CallArgs
     }
 
     /* Invoke native functions. */
     RootedFunction fun(cx, callee.toFunction());
     JS_ASSERT_IF(construct, !fun->isNativeConstructor());
     if (fun->isNative())
         return CallJSNative(cx, fun->native(), args);
 
-    RootedScript script(cx, fun->getOrCreateScript(cx));
+    RootedScript script(cx, JSFunction::getOrCreateScript(cx, fun));
     if (!script)
         return false;
 
     if (!TypeMonitorCall(cx, args, construct))
         return false;
 
     /* Get pointer to new frame/slots, prepare arguments. */
     InvokeFrameGuard ifg;
@@ -2375,17 +2375,17 @@ BEGIN_CASE(JSOP_FUNCALL)
         DO_NEXT_OP(len);
     }
 
     if (!TypeMonitorCall(cx, args, construct))
         goto error;
 
     InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE;
     bool newType = cx->typeInferenceEnabled() && UseNewType(cx, script, regs.pc);
-    RootedScript funScript(cx, fun->getOrCreateScript(cx));
+    RootedScript funScript(cx, JSFunction::getOrCreateScript(cx, fun));
     if (!funScript)
         goto error;
     if (!cx->stack.pushInlineFrame(cx, regs, args, *fun, funScript, initial))
         goto error;
 
     SET_SCRIPT(regs.fp()->script());
 #ifdef JS_METHODJIT
     script->resetLoopCount();
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -738,17 +738,17 @@ js::GetIteratorObject(JSContext *cx, Han
 
 JSBool
 js_ThrowStopIteration(JSContext *cx)
 {
     JS_ASSERT(!JS_IsExceptionPending(cx));
     RootedValue v(cx);
     if (js_FindClassObject(cx, JSProto_StopIteration, &v))
         cx->setPendingException(v);
-    return JS_FALSE;
+    return false;
 }
 
 /*** Iterator objects ****************************************************************************/
 
 JSBool
 js::IteratorConstructor(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
@@ -1033,17 +1033,17 @@ js::CloseIterator(JSContext *cx, HandleO
             ni->props_cursor = ni->props_array;
         }
     }
 #if JS_HAS_GENERATORS
     else if (obj->isGenerator()) {
         return CloseGenerator(cx, obj);
     }
 #endif
-    return JS_TRUE;
+    return true;
 }
 
 bool
 js::UnwindIteratorForException(JSContext *cx, HandleObject obj)
 {
     RootedValue v(cx, cx->getPendingException());
     cx->clearPendingException();
     if (!CloseIterator(cx, obj))
@@ -1293,17 +1293,17 @@ js_IteratorNext(JSContext *cx, HandleObj
 
     return true;
 }
 
 static JSBool
 stopiter_hasInstance(JSContext *cx, HandleObject obj, MutableHandleValue v, JSBool *bp)
 {
     *bp = IsStopIteration(v);
-    return JS_TRUE;
+    return true;
 }
 
 Class js::StopIterationClass = {
     "StopIteration",
     JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration) |
     JSCLASS_FREEZE_PROTO,
     JS_PropertyStub,         /* addProperty */
     JS_PropertyStub,         /* delProperty */
@@ -1506,17 +1506,17 @@ typedef enum JSGeneratorOp {
 static JSBool
 SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj,
                 JSGenerator *gen, const Value &arg)
 {
     AssertCanGC();
 
     if (gen->state == JSGEN_RUNNING || gen->state == JSGEN_CLOSING) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NESTING_GENERATOR);
-        return JS_FALSE;
+        return false;
     }
 
     /*
      * Write barrier is needed since the generator stack can be updated,
      * and it's not barriered in any other way. We need to do it before
      * gen->state changes, which can cause us to trace the generator
      * differently.
      *
@@ -1554,17 +1554,17 @@ SendToGenerator(JSContext *cx, JSGenerat
         break;
     }
 
     JSBool ok;
     {
         GeneratorFrameGuard gfg;
         if (!cx->stack.pushGeneratorFrame(cx, gen, &gfg)) {
             SetGeneratorClosed(cx, gen);
-            return JS_FALSE;
+            return false;
         }
 
         /*
          * Don't change the state until after the frame is successfully pushed
          * or else we might fail to scan some generator values.
          */
         gen->state = futureState;
 
@@ -1579,55 +1579,56 @@ SendToGenerator(JSContext *cx, JSGenerat
         ok = RunScript(cx, script, fp);
 
         gen->enumerators = cx->enumerators;
         cx->enumerators = enumerators;
         cx->leaveGenerator(gen);
     }
 
     if (gen->fp->isYielding()) {
-        /* Yield cannot fail, throw or be called on closing. */
-        JS_ASSERT(ok);
-        JS_ASSERT(!cx->isExceptionPending());
+        /*
+         * Yield is ordinarily infallible, but ok can be false here if a
+         * Debugger.Frame.onPop hook fails.
+         */
         JS_ASSERT(gen->state == JSGEN_RUNNING);
         JS_ASSERT(op != JSGENOP_CLOSE);
         gen->fp->clearYielding();
         gen->state = JSGEN_OPEN;
-        return JS_TRUE;
+        return ok;
     }
 
     gen->fp->clearReturnValue();
     SetGeneratorClosed(cx, gen);
     if (ok) {
         /* Returned, explicitly or by falling off the end. */
         if (op == JSGENOP_CLOSE)
-            return JS_TRUE;
+            return true;
         return js_ThrowStopIteration(cx);
     }
 
     /*
      * An error, silent termination by operation callback or an exception.
      * Propagate the condition to the caller.
      */
-    return JS_FALSE;
+    return false;
 }
 
 static JSBool
 CloseGenerator(JSContext *cx, HandleObject obj)
 {
     JS_ASSERT(obj->isGenerator());
 
     JSGenerator *gen = (JSGenerator *) obj->getPrivate();
     if (!gen) {
         /* Generator prototype object. */
-        return JS_TRUE;
+        return true;
     }
 
     if (gen->state == JSGEN_CLOSED)
-        return JS_TRUE;
+        return true;
 
     return SendToGenerator(cx, JSGENOP_CLOSE, obj, gen, UndefinedValue());
 }
 
 JS_ALWAYS_INLINE bool
 IsGenerator(const Value &v)
 {
     return v.isObject() && v.toObject().hasClass(&GeneratorClass);
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -512,57 +512,58 @@ js_math_pow(JSContext *cx, unsigned argc
 
     vp->setNumber(z);
     return JS_TRUE;
 }
 #if defined(_MSC_VER)
 # pragma optimize("", on)
 #endif
 
-static const int64_t RNG_MULTIPLIER = 0x5DEECE66DLL;
-static const int64_t RNG_ADDEND = 0xBLL;
-static const int64_t RNG_MASK = (1LL << 48) - 1;
+static const uint64_t RNG_MULTIPLIER = 0x5DEECE66DLL;
+static const uint64_t RNG_ADDEND = 0xBLL;
+static const uint64_t RNG_MASK = (1LL << 48) - 1;
 static const double RNG_DSCALE = double(1LL << 53);
 
 /*
  * Math.random() support, lifted from java.util.Random.java.
  */
 extern void
-random_setSeed(int64_t *rngSeed, int64_t seed)
+random_setSeed(uint64_t *rngState, uint64_t seed)
 {
-    *rngSeed = (seed ^ RNG_MULTIPLIER) & RNG_MASK;
+    *rngState = (seed ^ RNG_MULTIPLIER) & RNG_MASK;
 }
 
 void
-js_InitRandom(JSContext *cx)
+js::InitRandom(JSRuntime *rt, uint64_t *rngState)
 {
     /*
-     * Set the seed from current time. Since we have a RNG per context and we often bring
-     * up several contexts at the same time, we xor in some additional values, namely
-     * the context and its successor. We don't just use the context because it might be
-     * possible to reverse engineer the context pointer if one guesses the time right.
+     * Set the seed from current time. Since we have a RNG per compartment and
+     * we often bring up several compartments at the same time, mix in a
+     * different integer each time. This is only meant to prevent all the new
+     * compartments from getting the same sequence of pseudo-random
+     * numbers. There's no security guarantee.
      */
-    random_setSeed(&cx->rngSeed, (PRMJ_Now() / 1000) ^ int64_t(cx) ^ int64_t(cx->getNext()));
+    random_setSeed(rngState, (uint64_t(PRMJ_Now()) << 8) ^ rt->nextRNGNonce());
 }
 
 extern uint64_t
-random_next(int64_t *rngSeed, int bits)
+random_next(uint64_t *rngState, int bits)
 {
-    uint64_t nextseed = *rngSeed * RNG_MULTIPLIER;
-    nextseed += RNG_ADDEND;
-    nextseed &= RNG_MASK;
-    *rngSeed = nextseed;
-    return nextseed >> (48 - bits);
+    uint64_t nextstate = *rngState * RNG_MULTIPLIER;
+    nextstate += RNG_ADDEND;
+    nextstate &= RNG_MASK;
+    *rngState = nextstate;
+    return nextstate >> (48 - bits);
 }
 
 static inline double
 random_nextDouble(JSContext *cx)
 {
-    return double((random_next(&cx->rngSeed, 26) << 27) + random_next(&cx->rngSeed, 27)) /
-           RNG_DSCALE;
+    uint64_t *rng = &cx->compartment->rngState;
+    return double((random_next(rng, 26) << 27) + random_next(rng, 27)) / RNG_DSCALE;
 }
 
 double
 math_random_no_outparam(JSContext *cx)
 {
     /* Calculate random without memory traffic, for use in the JITs. */
     return random_nextDouble(cx);
 }
--- a/js/src/jsmath.h
+++ b/js/src/jsmath.h
@@ -40,28 +40,28 @@ class MathCache
         e.in = x;
         e.f = f;
         return (e.out = f(x));
     }
 
     size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf);
 };
 
+extern void
+InitRandom(JSRuntime *rt, uint64_t *rngState);
+
 } /* namespace js */
 
 /*
  * JS math functions.
  */
 
 extern JSObject *
 js_InitMathClass(JSContext *cx, js::HandleObject obj);
 
-extern void
-js_InitRandom(JSContext *cx);
-
 extern double
 math_random_no_outparam(JSContext *cx);
 
 extern JSBool
 js_math_random(JSContext *cx, unsigned argc, js::Value *vp);
 
 extern JSBool
 js_math_abs(JSContext *cx, unsigned argc, js::Value *vp);
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -940,16 +940,23 @@ SourceCompressorThread::finish()
     if (wakeup)
         PR_DestroyCondVar(wakeup);
     if (done)
         PR_DestroyCondVar(done);
     if (lock)
         PR_DestroyLock(lock);
 }
 
+const jschar *
+SourceCompressorThread::currentChars() const
+{
+    JS_ASSERT(tok);
+    return tok->chars;
+}
+
 bool
 SourceCompressorThread::internalCompress()
 {
     JS_ASSERT(state == COMPRESSING);
     JS_ASSERT(tok);
 
     ScriptSource *ss = tok->ss;
     JS_ASSERT(!ss->ready());
@@ -1046,16 +1053,17 @@ SourceCompressorThread::compress(SourceC
         // We have reentered the compiler. (This can happen through the
         // debugger.) Complete the current compression before starting the next
         // one.
         waitOnCompression(tok);
     JS_ASSERT(state == IDLE);
     JS_ASSERT(!tok);
     stop = false;
     PR_Lock(lock);
+    sct->ss->ready_ = false;
     tok = sct;
     state = COMPRESSING;
     PR_NotifyCondVar(wakeup);
     PR_Unlock(lock);
 }
 
 void
 SourceCompressorThread::waitOnCompression(SourceCompressionToken *userTok)
@@ -1065,19 +1073,17 @@ SourceCompressorThread::waitOnCompressio
     while (state == COMPRESSING)
         PR_WaitCondVar(done, PR_INTERVAL_NO_TIMEOUT);
     JS_ASSERT(state == IDLE);
     SourceCompressionToken *saveTok = tok;
     tok = NULL;
     PR_Unlock(lock);
 
     JS_ASSERT(!saveTok->ss->ready());
-#ifdef DEBUG
     saveTok->ss->ready_ = true;
-#endif
 
     // Update memory accounting.
     if (!saveTok->oom)
         saveTok->cx->runtime->updateMallocCounter(NULL, saveTok->ss->computedSizeOfData());
 
     saveTok->ss = NULL;
     saveTok->chars = NULL;
 }
@@ -1178,20 +1184,24 @@ SourceDataCache::purge()
 {
     js_delete(map_);
     map_ = NULL;
 }
 
 JSFlatString *
 ScriptSource::substring(JSContext *cx, uint32_t start, uint32_t stop)
 {
-    JS_ASSERT(ready());
     const jschar *chars;
 #if USE_ZLIB
     Rooted<JSStableString *> cached(cx, NULL);
+#ifdef JS_THREADSAFE
+    if (!ready()) {
+        chars = cx->runtime->sourceCompressorThread.currentChars();
+    } else
+#endif
     if (compressed()) {
         cached = cx->runtime->sourceDataCache.lookup(this);
         if (!cached) {
             const size_t nbytes = sizeof(jschar) * (length_ + 1);
             jschar *decompressed = static_cast<jschar *>(cx->malloc_(nbytes));
             if (!decompressed)
                 return NULL;
             if (!DecompressString(data.compressed, compressedLength_,
@@ -1224,19 +1234,16 @@ ScriptSource::setSourceCopy(JSContext *c
                             bool argumentsNotIncluded, SourceCompressionToken *tok)
 {
     JS_ASSERT(!hasSourceData());
     length_ = length;
     argumentsNotIncluded_ = argumentsNotIncluded;
 
 #ifdef JS_THREADSAFE
     if (tok && cx->runtime->useHelperThreads()) {
-#ifdef DEBUG
-        ready_ = false;
-#endif
         tok->ss = this;
         tok->chars = src.get();
         cx->runtime->sourceCompressorThread.compress(tok);
     } else
 #endif
     {
         if (!adjustDataSize(sizeof(jschar) * length))
             return false;
@@ -1282,19 +1289,17 @@ SourceCompressionToken::abort()
 }
 
 void
 ScriptSource::destroy(JSRuntime *rt)
 {
     JS_ASSERT(ready());
     adjustDataSize(0);
     js_free(sourceMap_);
-#ifdef DEBUG
     ready_ = false;
-#endif
     js_free(this);
 }
 
 size_t
 ScriptSource::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf)
 {
     JS_ASSERT(ready());
 
@@ -1368,20 +1373,18 @@ ScriptSource::performXDR(XDRState<mode> 
                 js_free(sourceMap_);
                 sourceMap_ = NULL;
             }
             return false;
         }
         sourceMap_[sourceMapLen] = '\0';
     }
 
-#ifdef DEBUG
     if (mode == XDR_DECODE)
         ready_ = true;
-#endif
 
     return true;
 }
 
 bool
 ScriptSource::setSourceMap(JSContext *cx, jschar *sourceMapURL, const char *filename)
 {
     JS_ASSERT(sourceMapURL);
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -1031,52 +1031,46 @@ struct ScriptSource
     uint32_t compressedLength_;
     jschar *sourceMap_;
 
     // True if we can call JSRuntime::sourceHook to load the source on
     // demand. If sourceRetrievable_ and hasSourceData() are false, it is not
     // possible to get source at all.
     bool sourceRetrievable_:1;
     bool argumentsNotIncluded_:1;
-#ifdef DEBUG
     bool ready_:1;
-#endif
 
   public:
     ScriptSource()
       : refs(0),
         length_(0),
         compressedLength_(0),
         sourceMap_(NULL),
         sourceRetrievable_(false),
-        argumentsNotIncluded_(false)
-#ifdef DEBUG
-       ,ready_(true)
-#endif
+        argumentsNotIncluded_(false),
+        ready_(true)
     {
         data.source = NULL;
     }
     void incref() { refs++; }
     void decref(JSRuntime *rt) {
         JS_ASSERT(refs != 0);
         if (--refs == 0)
             destroy(rt);
     }
     bool setSourceCopy(JSContext *cx,
                        StableCharPtr src,
                        uint32_t length,
                        bool argumentsNotIncluded,
                        SourceCompressionToken *tok);
     void setSource(const jschar *src, uint32_t length);
-#ifdef DEBUG
     bool ready() const { return ready_; }
-#endif
     void setSourceRetrievable() { sourceRetrievable_ = true; }
     bool sourceRetrievable() const { return sourceRetrievable_; }
-    bool hasSourceData() const { return !!data.source; }
+    bool hasSourceData() const { return !!data.source || !ready(); }
     uint32_t length() const {
         JS_ASSERT(hasSourceData());
         return length_;
     }
     bool argumentsNotIncluded() const {
         JS_ASSERT(hasSourceData());
         return argumentsNotIncluded_;
     }
@@ -1168,16 +1162,17 @@ class SourceCompressorThread
       lock(NULL),
       wakeup(NULL),
       done(NULL) {}
     void finish();
     bool init();
     void compress(SourceCompressionToken *tok);
     void waitOnCompression(SourceCompressionToken *userTok);
     void abort(SourceCompressionToken *userTok);
+    const jschar *currentChars() const;
 };
 #endif
 
 struct SourceCompressionToken
 {
     friend struct ScriptSource;
     friend class SourceCompressorThread;
   private:
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -1543,17 +1543,19 @@ class StringRegExpGuard
                 if (!sb.append(*it))
                     return NULL;
             }
         }
         return sb.finishAtom();
     }
 
   public:
-    StringRegExpGuard(JSContext *cx) : fm(cx) {}
+    StringRegExpGuard(JSContext *cx)
+      : re_(cx), fm(cx)
+    { }
 
     /* init must succeed in order to call tryFlatMatch or normalizeRegExp. */
     bool init(JSContext *cx, CallArgs args, bool convertVoid = false)
     {
         if (args.length() != 0 && IsObjectWithClass(args[0], ESClass_RegExp, cx)) {
             if (!RegExpToShared(cx, args[0].toObject(), &re_))
                 return false;
         } else {
@@ -1627,17 +1629,17 @@ class StringRegExpGuard
         if (optarg < args.length()) {
             opt = ToString(cx, args[optarg]);
             if (!opt)
                 return false;
         } else {
             opt = NULL;
         }
 
-        JSAtom *patstr;
+        Rooted<JSAtom *> patstr(cx);
         if (flat) {
             patstr = flattenPattern(cx, fm.patstr);
             if (!patstr)
                 return false;
         } else {
             patstr = fm.patstr;
         }
         JS_ASSERT(patstr);
@@ -2779,17 +2781,17 @@ js::str_split(JSContext *cx, unsigned ar
         if (!ToNumber(cx, args[1], &d))
             return false;
         limit = ToUint32(d);
     } else {
         limit = UINT32_MAX;
     }
 
     /* Step 8. */
-    RegExpGuard re;
+    RegExpGuard re(cx);
     JSLinearString *sepstr = NULL;
     bool sepDefined = args.hasDefined(0);
     if (sepDefined) {
         if (IsObjectWithClass(args[0], ESClass_RegExp, cx)) {
             if (!RegExpToShared(cx, args[0].toObject(), &re))
                 return false;
         } else {
             sepstr = ArgToRootedString(cx, args, 0);
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -3766,23 +3766,28 @@ JS_GetTypedArrayByteLength(JSObject *obj
     obj = UnwrapObjectChecked(obj);
     if (!obj)
         return 0;
     JS_ASSERT(obj->isTypedArray());
     return TypedArray::byteLength(obj);
 }
 
 JS_FRIEND_API(JSArrayBufferViewType)
-JS_GetTypedArrayType(JSObject *obj)
+JS_GetArrayBufferViewType(JSObject *obj)
 {
     obj = UnwrapObjectChecked(obj);
     if (!obj)
         return ArrayBufferView::TYPE_MAX;
-    JS_ASSERT(obj->isTypedArray());
-    return static_cast<JSArrayBufferViewType>(TypedArray::type(obj));
+
+    if (obj->isTypedArray())
+        return static_cast<JSArrayBufferViewType>(TypedArray::type(obj));
+    else if (obj->isDataView())
+        return ArrayBufferView::TYPE_DATAVIEW;
+    JS_NOT_REACHED("invalid ArrayBufferView type");
+    return ArrayBufferView::TYPE_MAX;
 }
 
 JS_FRIEND_API(int8_t *)
 JS_GetInt8ArrayData(JSObject *obj)
 {
     obj = UnwrapObjectChecked(obj);
     if (!obj)
         return NULL;
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -2279,16 +2279,19 @@ mjit::Compiler::generateMethod()
         /*
          * Update PC counts for jump opcodes at their start, so that we don't
          * miss them when taking the jump. This is delayed for other opcodes,
          * as we want to skip updating for ops we didn't generate any code for.
          */
         if (script_->hasScriptCounts && JOF_OPTYPE(op) == JOF_JUMP)
             updatePCCounts(PC, &countsUpdated);
 
+        /* Use a common root to avoid frequent re-rooting. */
+        RootedPropertyName name0(cx);
+
     /**********************
      * BEGIN COMPILER OPS *
      **********************/
 
         lastPC = PC;
 
         switch (op) {
           BEGIN_CASE(JSOP_NOP)
@@ -2624,32 +2627,32 @@ mjit::Compiler::generateMethod()
 
           BEGIN_CASE(JSOP_POS)
             jsop_pos();
           END_CASE(JSOP_POS)
 
           BEGIN_CASE(JSOP_DELNAME)
           {
             uint32_t index = GET_UINT32_INDEX(PC);
-            PropertyName *name = script_->getName(index);
+            name0 = script_->getName(index);
 
             prepareStubCall(Uses(0));
-            masm.move(ImmPtr(name), Registers::ArgReg1);
+            masm.move(ImmPtr(name0), Registers::ArgReg1);
             INLINE_STUBCALL(stubs::DelName, REJOIN_FALLTHROUGH);
             pushSyncedEntry(0);
           }
           END_CASE(JSOP_DELNAME)
 
           BEGIN_CASE(JSOP_DELPROP)
           {
             uint32_t index = GET_UINT32_INDEX(PC);
-            PropertyName *name = script_->getName(index);
+            name0 = script_->getName(index);
 
             prepareStubCall(Uses(1));
-            masm.move(ImmPtr(name), Registers::ArgReg1);
+            masm.move(ImmPtr(name0), Registers::ArgReg1);
             INLINE_STUBCALL(STRICT_VARIANT(script_, stubs::DelProp), REJOIN_FALLTHROUGH);
             frame.pop();
             pushSyncedEntry(0);
           }
           END_CASE(JSOP_DELPROP)
 
           BEGIN_CASE(JSOP_DELELEM)
           {
@@ -2668,17 +2671,18 @@ mjit::Compiler::generateMethod()
           BEGIN_CASE(JSOP_VOID)
             frame.pop();
             frame.push(UndefinedValue());
           END_CASE(JSOP_VOID)
 
           BEGIN_CASE(JSOP_GETPROP)
           BEGIN_CASE(JSOP_CALLPROP)
           BEGIN_CASE(JSOP_LENGTH)
-            if (!jsop_getprop(script_->getName(GET_UINT32_INDEX(PC)), knownPushedType(0)))
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
+            if (!jsop_getprop(name0, knownPushedType(0)))
                 return Compile_Error;
           END_CASE(JSOP_GETPROP)
 
           BEGIN_CASE(JSOP_GETELEM)
           BEGIN_CASE(JSOP_CALLELEM)
             if (script_->hasScriptCounts)
                 updateElemCounts(PC, frame.peek(-2), frame.peek(-1));
             if (!jsop_getelem())
@@ -2745,29 +2749,29 @@ mjit::Compiler::generateMethod()
                 JaegerSpew(JSpew_Insns, " --- END SCRIPTED CALL --- \n");
             }
           }
           END_CASE(JSOP_CALL)
 
           BEGIN_CASE(JSOP_NAME)
           BEGIN_CASE(JSOP_CALLNAME)
           {
-            PropertyName *name = script_->getName(GET_UINT32_INDEX(PC));
-            jsop_name(name, knownPushedType(0));
-            frame.extra(frame.peek(-1)).name = name;
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
+            jsop_name(name0, knownPushedType(0));
+            frame.extra(frame.peek(-1)).name = name0;
           }
           END_CASE(JSOP_NAME)
 
           BEGIN_CASE(JSOP_GETINTRINSIC)
           BEGIN_CASE(JSOP_CALLINTRINSIC)
           {
-            PropertyName *name = script_->getName(GET_UINT32_INDEX(PC));
-            if (!jsop_intrinsic(name, knownPushedType(0)))
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
+            if (!jsop_intrinsic(name0, knownPushedType(0)))
                 return Compile_Error;
-            frame.extra(frame.peek(-1)).name = name;
+            frame.extra(frame.peek(-1)).name = name0;
           }
           END_CASE(JSOP_GETINTRINSIC)
 
           BEGIN_CASE(JSOP_IMPLICITTHIS)
           {
             prepareStubCall(Uses(0));
             masm.move(ImmPtr(script_->getName(GET_UINT32_INDEX(PC))), Registers::ArgReg1);
             INLINE_STUBCALL(stubs::ImplicitThis, REJOIN_FALLTHROUGH);
@@ -3020,33 +3024,36 @@ mjit::Compiler::generateMethod()
 
           BEGIN_CASE(JSOP_INITELEM)
             prepareStubCall(Uses(3));
             INLINE_STUBCALL(stubs::InitElem, REJOIN_FALLTHROUGH);
             frame.popn(2);
           END_CASE(JSOP_INITELEM)
 
           BEGIN_CASE(JSOP_BINDNAME)
-            jsop_bindname(script_->getName(GET_UINT32_INDEX(PC)));
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
+            jsop_bindname(name0);
           END_CASE(JSOP_BINDNAME)
 
           BEGIN_CASE(JSOP_SETPROP)
           {
             jsbytecode *next = &PC[JSOP_SETPROP_LENGTH];
             bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
-            if (!jsop_setprop(script_->getName(GET_UINT32_INDEX(PC)), pop))
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
+            if (!jsop_setprop(name0, pop))
                 return Compile_Error;
           }
           END_CASE(JSOP_SETPROP)
 
           BEGIN_CASE(JSOP_SETNAME)
           {
             jsbytecode *next = &PC[JSOP_SETNAME_LENGTH];
             bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
-            if (!jsop_setprop(script_->getName(GET_UINT32_INDEX(PC)), pop))
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
+            if (!jsop_setprop(name0, pop))
                 return Compile_Error;
           }
           END_CASE(JSOP_SETNAME)
 
           BEGIN_CASE(JSOP_THROW)
             prepareStubCall(Uses(1));
             INLINE_STUBCALL(stubs::Throw, REJOIN_NONE);
             frame.pop();
@@ -3114,30 +3121,30 @@ mjit::Compiler::generateMethod()
             masm.move(ImmPtr(innerFun), Registers::ArgReg1);
             INLINE_STUBCALL(STRICT_VARIANT(script_, stubs::DefFun), REJOIN_FALLTHROUGH);
           }
           END_CASE(JSOP_DEFFUN)
 
           BEGIN_CASE(JSOP_DEFVAR)
           BEGIN_CASE(JSOP_DEFCONST)
           {
-            PropertyName *name = script_->getName(GET_UINT32_INDEX(PC));
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
 
             prepareStubCall(Uses(0));
-            masm.move(ImmPtr(name), Registers::ArgReg1);
+            masm.move(ImmPtr(name0), Registers::ArgReg1);
             INLINE_STUBCALL(stubs::DefVarOrConst, REJOIN_FALLTHROUGH);
           }
           END_CASE(JSOP_DEFVAR)
 
           BEGIN_CASE(JSOP_SETCONST)
           {
-            PropertyName *name = script_->getName(GET_UINT32_INDEX(PC));
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
 
             prepareStubCall(Uses(1));
-            masm.move(ImmPtr(name), Registers::ArgReg1);
+            masm.move(ImmPtr(name0), Registers::ArgReg1);
             INLINE_STUBCALL(stubs::SetConst, REJOIN_FALLTHROUGH);
           }
           END_CASE(JSOP_SETCONST)
 
           BEGIN_CASE(JSOP_LAMBDA)
           {
             JSFunction *fun = script_->getFunction(GET_UINT32_INDEX(PC));
 
@@ -3172,17 +3179,18 @@ mjit::Compiler::generateMethod()
             frame.extra(frame.peek(-1)).name = script_->getName(index);
           }
           END_CASE(JSOP_GETGNAME)
 
           BEGIN_CASE(JSOP_SETGNAME)
           {
             jsbytecode *next = &PC[JSOP_SETGNAME_LENGTH];
             bool pop = JSOp(*next) == JSOP_POP && !analysis->jumpTarget(next);
-            if (!jsop_setgname(script_->getName(GET_UINT32_INDEX(PC)), pop))
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
+            if (!jsop_setgname(name0, pop))
                 return Compile_Error;
           }
           END_CASE(JSOP_SETGNAME)
 
           BEGIN_CASE(JSOP_REGEXP)
             if (!jsop_regexp())
                 return Compile_Error;
           END_CASE(JSOP_REGEXP)
@@ -3203,17 +3211,18 @@ mjit::Compiler::generateMethod()
           BEGIN_CASE(JSOP_STOP)
             if (script_->hasScriptCounts)
                 updatePCCounts(PC, &countsUpdated);
             emitReturn(NULL);
             goto done;
           END_CASE(JSOP_STOP)
 
           BEGIN_CASE(JSOP_GETXPROP)
-            if (!jsop_xname(script_->getName(GET_UINT32_INDEX(PC))))
+            name0 = script_->getName(GET_UINT32_INDEX(PC));
+            if (!jsop_xname(name0))
                 return Compile_Error;
           END_CASE(JSOP_GETXPROP)
 
           BEGIN_CASE(JSOP_ENTERBLOCK)
           BEGIN_CASE(JSOP_ENTERLET0)
           BEGIN_CASE(JSOP_ENTERLET1)
             enterBlock(&script_->getObject(GET_UINT32_INDEX(PC))->asStaticBlock());
           END_CASE(JSOP_ENTERBLOCK);
@@ -4921,17 +4930,17 @@ mjit::Compiler::emitStubCmpOp(BoolStub s
 
     JS_ASSERT(fused == JSOP_IFEQ || fused == JSOP_IFNE);
     Jump j = masm.branchTest32(GetStubCompareCondition(fused), Registers::ReturnReg,
                                Registers::ReturnReg);
     return jumpAndRun(j, target);
 }
 
 void
-mjit::Compiler::jsop_setprop_slow(PropertyName *name)
+mjit::Compiler::jsop_setprop_slow(HandlePropertyName name)
 {
     JS_ASSERT(*PC == JSOP_SETPROP || *PC == JSOP_SETNAME);
 
     prepareStubCall(Uses(2));
     masm.move(ImmPtr(name), Registers::ArgReg1);
 
     if (*PC == JSOP_SETPROP)
         INLINE_STUBCALL(stubs::SetProp, REJOIN_FALLTHROUGH);
@@ -4940,17 +4949,17 @@ mjit::Compiler::jsop_setprop_slow(Proper
 
     JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
     frame.shimmy(1);
     if (script_->hasScriptCounts)
         bumpPropCount(PC, PCCounts::PROP_OTHER);
 }
 
 void
-mjit::Compiler::jsop_getprop_slow(PropertyName *name, bool forPrototype)
+mjit::Compiler::jsop_getprop_slow(HandlePropertyName name, bool forPrototype)
 {
     /* See ::jsop_getprop */
     RejoinState rejoin = forPrototype ? REJOIN_THIS_PROTOTYPE : REJOIN_GETTER;
 
     prepareStubCall(Uses(1));
     masm.move(ImmPtr(name), Registers::ArgReg1);
     INLINE_STUBCALL(forPrototype ? stubs::GetPropNoCache : stubs::GetProp, rejoin);
 
@@ -4975,17 +4984,17 @@ mjit::Compiler::passMICAddress(GlobalNam
 #if defined JS_POLYIC
 void
 mjit::Compiler::passICAddress(BaseICInfo *ic)
 {
     ic->paramAddr = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
 }
 
 bool
-mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType,
+mjit::Compiler::jsop_getprop(HandlePropertyName name, JSValueType knownType,
                              bool doTypeCheck, bool forPrototype)
 {
     FrameEntry *top = frame.peek(-1);
 
     /*
      * Use a different rejoin for GETPROP computing the 'this' object, as we
      * can't use the current bytecode within InternalInterpret to tell this is
      * fetching the 'this' value.
@@ -5432,17 +5441,17 @@ mjit::Compiler::testSingletonPropertyTyp
     RootedObject proto(cx);
     if (!js_GetClassPrototype(cx, key, &proto, NULL))
         return false;
 
     return testSingletonProperty(proto, id);
 }
 
 bool
-mjit::Compiler::jsop_getprop_dispatch(PropertyName *name)
+mjit::Compiler::jsop_getprop_dispatch(HandlePropertyName name)
 {
     /*
      * Check for a CALLPROP which is a dynamic dispatch: every value it can
      * push is a singleton, and the pushed value is determined by the type of
      * the object being accessed. Return true if the CALLPROP has been fully
      * processed, false if no code was generated.
      */
     FrameEntry *top = frame.peek(-1);
@@ -5578,17 +5587,17 @@ mjit::Compiler::jsop_getprop_dispatch(Pr
     if (script_->hasScriptCounts)
         bumpPropCount(PC, PCCounts::PROP_DEFINITE);
 
     stubcc.rejoin(Changes(2));
     return true;
 }
 
 bool
-mjit::Compiler::jsop_setprop(PropertyName *name, bool popGuaranteed)
+mjit::Compiler::jsop_setprop(HandlePropertyName name, bool popGuaranteed)
 {
     FrameEntry *lhs = frame.peek(-2);
     FrameEntry *rhs = frame.peek(-1);
 
     /* If the incoming type will never PIC, take slow path. */
     if (lhs->isTypeKnown() && lhs->getKnownType() != JSVAL_TYPE_OBJECT) {
         jsop_setprop_slow(name);
         return true;
@@ -5767,17 +5776,17 @@ mjit::Compiler::jsop_setprop(PropertyNam
     labels.setInlineValueStore(masm, pic.fastPathRejoin, inlineValueStore);
     labels.setInlineShapeJump(masm, pic.shapeGuard, afterInlineShapeJump);
 
     pics.append(pic);
     return true;
 }
 
 bool
-mjit::Compiler::jsop_intrinsic(PropertyName *name, JSValueType type)
+mjit::Compiler::jsop_intrinsic(HandlePropertyName name, JSValueType type)
 {
     if (type == JSVAL_TYPE_UNKNOWN) {
         prepareStubCall(Uses(0));
         masm.move(ImmPtr(name), Registers::ArgReg1);
         INLINE_STUBCALL(stubs::IntrinsicName, REJOIN_FALLTHROUGH);
         testPushedType(REJOIN_FALLTHROUGH, 0, /* ool = */ false);
         frame.pushSynced(JSVAL_TYPE_UNKNOWN);
         return true;
@@ -5786,17 +5795,17 @@ mjit::Compiler::jsop_intrinsic(PropertyN
     RootedValue vp(cx, NullValue());
     if (!cx->global().get()->getIntrinsicValue(cx, name, &vp))
         return false;
     frame.push(vp);
     return true;
 }
 
 void
-mjit::Compiler::jsop_name(PropertyName *name, JSValueType type)
+mjit::Compiler::jsop_name(HandlePropertyName name, JSValueType type)
 {
     PICGenInfo pic(ic::PICInfo::NAME, PC);
 
     RESERVE_IC_SPACE(masm);
 
     pic.shapeReg = frame.allocReg();
     pic.objReg = frame.allocReg();
     pic.typeReg = Registers::ReturnReg;
@@ -5842,17 +5851,17 @@ mjit::Compiler::jsop_name(PropertyName *
     stubcc.rejoin(Changes(1));
 
     pics.append(pic);
 
     finishBarrier(barrier, REJOIN_GETTER, 0);
 }
 
 bool
-mjit::Compiler::jsop_xname(PropertyName *name)
+mjit::Compiler::jsop_xname(HandlePropertyName name)
 {
     PICGenInfo pic(ic::PICInfo::XNAME, PC);
 
     FrameEntry *fe = frame.peek(-1);
     if (fe->isNotType(JSVAL_TYPE_OBJECT)) {
         return jsop_getprop(name, knownPushedType(0));
     }
 
@@ -5904,17 +5913,17 @@ mjit::Compiler::jsop_xname(PropertyName 
 
     pics.append(pic);
 
     finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
     return true;
 }
 
 void
-mjit::Compiler::jsop_bindname(PropertyName *name)
+mjit::Compiler::jsop_bindname(HandlePropertyName name)
 {
     PICGenInfo pic(ic::PICInfo::BIND, PC);
 
     // This code does not check the frame flags to see if scopeChain has been
     // set. Rather, it relies on the up-front analysis statically determining
     // whether BINDNAME can be used, which reifies the scope chain at the
     // prologue.
     JS_ASSERT(analysis->usesScopeChain());
@@ -5956,49 +5965,49 @@ mjit::Compiler::jsop_bindname(PropertyNa
     stubcc.rejoin(Changes(1));
 
     pics.append(pic);
 }
 
 #else /* !JS_POLYIC */
 
 void
-mjit::Compiler::jsop_name(PropertyName *name, JSValueType type, bool isCall)
+mjit::Compiler::jsop_name(HandlePropertyName name, JSValueType type, bool isCall)
 {
     prepareStubCall(Uses(0));
     INLINE_STUBCALL(isCall ? stubs::CallName : stubs::Name, REJOIN_FALLTHROUGH);
     testPushedType(REJOIN_FALLTHROUGH, 0, /* ool = */ false);
     frame.pushSynced(type);
     if (isCall)
         frame.pushSynced(JSVAL_TYPE_UNKNOWN);
 }
 
 bool
-mjit::Compiler::jsop_xname(PropertyName *name)
+mjit::Compiler::jsop_xname(HandlePropertyName name)
 {
     return jsop_getprop(name, knownPushedType(0), pushedTypeSet(0));
 }
 
 bool
-mjit::Compiler::jsop_getprop(PropertyName *name, JSValueType knownType, types::TypeSet *typeSet,
+mjit::Compiler::jsop_getprop(HandlePropertyName name, JSValueType knownType, types::TypeSet *typeSet,
                              bool typecheck, bool forPrototype)
 {
     jsop_getprop_slow(name, forPrototype);
     return true;
 }
 
 bool
-mjit::Compiler::jsop_setprop(PropertyName *name)
+mjit::Compiler::jsop_setprop(HandlePropertyName name)
 {
     jsop_setprop_slow(name);
     return true;
 }
 
 void
-mjit::Compiler::jsop_bindname(PropertyName *name)
+mjit::Compiler::jsop_bindname(HandlePropertyName name)
 {
     RegisterID reg = frame.allocReg();
     Address scopeChain(JSFrameReg, StackFrame::offsetOfScopeChain());
     masm.loadPtr(scopeChain, reg);
 
     Address address(reg, offsetof(JSObject, parent));
 
     Jump j = masm.branchPtr(Assembler::NotEqual, address, ImmPtr(0));
@@ -6562,27 +6571,27 @@ mjit::Compiler::jsop_getgname(uint32_t i
     finishBarrier(barrier, REJOIN_GETTER, 0);
 #else
     jsop_getgname_slow(index);
 #endif
     return true;
 }
 
 void
-mjit::Compiler::jsop_setgname_slow(PropertyName *name)
+mjit::Compiler::jsop_setgname_slow(HandlePropertyName name)
 {
     prepareStubCall(Uses(2));
     masm.move(ImmPtr(name), Registers::ArgReg1);
     INLINE_STUBCALL(stubs::SetName, REJOIN_FALLTHROUGH);
     frame.popn(2);
     pushSyncedEntry(0);
 }
 
 bool
-mjit::Compiler::jsop_setgname(PropertyName *name, bool popGuaranteed)
+mjit::Compiler::jsop_setgname(HandlePropertyName name, bool popGuaranteed)
 {
     if (monitored(PC)) {
         if (script_ == outerScript)
             monitoredBytecodes.append(PC - script_->code);
 
         /* Global accesses are monitored only for a few names like __proto__. */
         jsop_setgname_slow(name);
         return true;
@@ -7009,17 +7018,17 @@ mjit::Compiler::jsop_regexp()
 
     /*
      * Force creation of the RegExpShared in the script's RegExpObject so that
      * we grab it in the getNewObject template copy. A strong reference to the
      * RegExpShared will be added when the jitcode is created. Any GC activity
      * between now and construction of that jitcode could purge the shared
      * info, but such activity will also abort compilation.
      */
-    RegExpGuard g;
+    RegExpGuard g(cx);
     if (!reobj->getShared(cx, &g))
         return false;
 
     rootedRegExps.append(g.re());
 
     RegisterID result = frame.allocReg();
     Jump emptyFreeList = getNewObject(cx, result, obj);
 
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -620,19 +620,19 @@ private:
 
     /* Opcode handlers. */
     bool jumpAndRun(Jump j, jsbytecode *target,
                     Jump *slow = NULL, bool *trampoline = NULL,
                     bool fallthrough = false);
     bool startLoop(jsbytecode *head, Jump entry, jsbytecode *entryTarget);
     bool finishLoop(jsbytecode *head);
     inline bool shouldStartLoop(jsbytecode *head);
-    void jsop_bindname(PropertyName *name);
+    void jsop_bindname(HandlePropertyName name);
     void jsop_setglobal(uint32_t index);
-    void jsop_getprop_slow(PropertyName *name, bool forPrototype = false);
+    void jsop_getprop_slow(HandlePropertyName name, bool forPrototype = false);
     void jsop_aliasedArg(unsigned i, bool get, bool poppedAfter = false);
     void jsop_aliasedVar(ScopeCoordinate sc, bool get, bool poppedAfter = false);
     void jsop_this();
     void emitReturn(FrameEntry *fe);
     void emitFinalReturn(Assembler &masm);
     void loadReturnValue(Assembler *masm, FrameEntry *fe);
     void emitReturnValue(Assembler *masm, FrameEntry *fe);
     void emitInlineReturnValue(FrameEntry *fe);
@@ -647,30 +647,30 @@ private:
     void checkCallApplySpeculation(uint32_t argc, FrameEntry *origCallee, FrameEntry *origThis,
                                    MaybeRegisterID origCalleeType, RegisterID origCalleeData,
                                    MaybeRegisterID origThisType, RegisterID origThisData,
                                    Jump *uncachedCallSlowRejoin, CallPatchInfo *uncachedCallPatch);
     bool inlineCallHelper(uint32_t argc, bool callingNew, FrameSize &callFrameSize);
     void fixPrimitiveReturn(Assembler *masm, FrameEntry *fe);
     bool jsop_getgname(uint32_t index);
     void jsop_getgname_slow(uint32_t index);
-    bool jsop_setgname(PropertyName *name, bool popGuaranteed);
-    void jsop_setgname_slow(PropertyName *name);
+    bool jsop_setgname(HandlePropertyName name, bool popGuaranteed);
+    void jsop_setgname_slow(HandlePropertyName name);
     void jsop_bindgname();
     void jsop_setelem_slow();
     void jsop_getelem_slow();
-    bool jsop_getprop(PropertyName *name, JSValueType type,
+    bool jsop_getprop(HandlePropertyName name, JSValueType type,
                       bool typeCheck = true, bool forPrototype = false);
-    bool jsop_getprop_dispatch(PropertyName *name);
-    bool jsop_setprop(PropertyName *name, bool popGuaranteed);
-    void jsop_setprop_slow(PropertyName *name);
+    bool jsop_getprop_dispatch(HandlePropertyName name);
+    bool jsop_setprop(HandlePropertyName name, bool popGuaranteed);
+    void jsop_setprop_slow(HandlePropertyName name);
     bool jsop_instanceof();
-    bool jsop_intrinsic(PropertyName *name, JSValueType type);
-    void jsop_name(PropertyName *name, JSValueType type);
-    bool jsop_xname(PropertyName *name);
+    bool jsop_intrinsic(HandlePropertyName name, JSValueType type);
+    void jsop_name(HandlePropertyName name, JSValueType type);
+    bool jsop_xname(HandlePropertyName name);
     void enterBlock(StaticBlockObject *block);
     void leaveBlock();
     void emitEval(uint32_t argc);
     bool jsop_tableswitch(jsbytecode *pc);
     Jump getNewObject(JSContext *cx, RegisterID result, JSObject *templateObject);
 
     /* Fast arithmetic. */
     bool jsop_binary_slow(JSOp op, VoidStub stub, JSValueType type, FrameEntry *lhs, FrameEntry *rhs);
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -282,17 +282,17 @@ static inline bool
 UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
                    void **pret, bool *unjittable, uint32_t argc)
 {
     AssertCanGC();
     JSContext *cx = f.cx;
     CallArgs args = CallArgsFromSp(argc, f.regs.sp);
     RootedFunction newfun(cx, args.callee().toFunction());
 
-    RootedScript newscript(cx, newfun->getOrCreateScript(cx));
+    RootedScript newscript(cx, JSFunction::getOrCreateScript(cx, newfun));
     if (!newscript)
         return false;
 
     bool construct = InitialFrameFlagsAreConstructing(initial);
 
     RootedScript fscript(cx, f.script());
     bool newType = construct && cx->typeInferenceEnabled() &&
         types::UseNewType(cx, fscript, f.pc());
--- a/js/src/methodjit/MethodJIT.cpp
+++ b/js/src/methodjit/MethodJIT.cpp
@@ -1654,16 +1654,21 @@ mjit::NativeToPC(JITScript *jit, void *n
 void
 JITChunk::trace(JSTracer *trc)
 {
     JSObject **rootedTemplates_ = rootedTemplates();
     for (size_t i = 0; i < nRootedTemplates; i++) {
         /* We use a manual write barrier in destroyChunk. */
         MarkObjectUnbarriered(trc, &rootedTemplates_[i], "jitchunk_template");
     }
+
+    /* RegExpShared objects require the RegExp source string. */
+    RegExpShared **rootedRegExps_ = rootedRegExps();
+    for (size_t i = 0; i < nRootedRegExps; i++)
+        rootedRegExps_[i]->trace(trc);
 }
 
 void
 JITChunk::purgeCaches()
 {
     ic::Repatcher repatch(this);
 
 #if defined JS_MONOIC
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -95,19 +95,25 @@ stubs::Name(VMFrame &f)
 {
     RootedValue rval(f.cx);
     if (!NameOperation(f.cx, f.pc(), &rval))
         THROW();
     f.regs.sp[0] = rval;
 }
 
 void JS_FASTCALL
-stubs::IntrinsicName(VMFrame &f, PropertyName *name)
+stubs::IntrinsicName(VMFrame &f, PropertyName *nameArg)
 {
     RootedValue rval(f.cx);
+
+    // PropertyNames are atoms and will never be allocated from the nursery,
+    // and the ones passed to this stub are referenced by the script so it will
+    // root them. The compacting GC will discard methodjit code.
+    SkipRoot skip(f.cx, &nameArg);
+    HandlePropertyName name = HandlePropertyName::fromMarkedLocation(&nameArg);
     if (!f.cx->global().get()->getIntrinsicValue(f.cx, name, &rval))
         THROW();
     f.regs.sp[0] = rval;
 }
 
 void JS_FASTCALL
 stubs::GetElem(VMFrame &f)
 {
@@ -834,17 +840,20 @@ stubs::TriggerIonCompile(VMFrame &f)
         if (!script->canIonCompile() || script->isIonCompilingOffThread())
             return;
 
         jsbytecode *osrPC = f.regs.pc;
         if (*osrPC != JSOP_LOOPENTRY)
             osrPC = NULL;
 
         RootedFunction scriptFunction(f.cx, script->function());
-        if (!ion::TestIonCompile(f.cx, script, scriptFunction, osrPC, f.fp()->isConstructing())) {
+        ion::MethodStatus compileStatus =
+            ion::TestIonCompile(f.cx, script, scriptFunction, osrPC, f.fp()->isConstructing());
+
+        if (compileStatus != ion::Method_Compiled) {
             if (f.cx->isExceptionPending())
                 THROW();
         }
 
         return;
     }
 
     ExpandInlineFrames(f.cx->compartment);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1454,17 +1454,17 @@ AssertJit(JSContext *cx, unsigned argc, 
 static UnrootedScript
 ValueToScript(JSContext *cx, jsval v, JSFunction **funp = NULL)
 {
     RootedFunction fun(cx, JS_ValueToFunction(cx, v));
     if (!fun)
         return UnrootedScript(NULL);
 
     RootedScript script(cx);
-    fun->maybeGetOrCreateScript(cx, &script);
+    JSFunction::maybeGetOrCreateScript(cx, fun, &script);
     if (!script)
         JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_SCRIPTS_ONLY);
 
     if (fun && funp)
         *funp = fun;
 
     return script;
 }
@@ -1911,19 +1911,19 @@ DisassembleScript(JSContext *cx, HandleS
     TryNotes(cx, script, sp);
 
     if (recursive && script->hasObjects()) {
         ObjectArray *objects = script->objects();
         for (unsigned i = 0; i != objects->length; ++i) {
             RawObject obj = objects->vector[i];
             if (obj->isFunction()) {
                 Sprint(sp, "\n");
-                RawFunction fun = obj->toFunction();
+                RootedFunction fun(cx, obj->toFunction());
                 RootedScript script(cx);
-                fun->maybeGetOrCreateScript(cx, &script);
+                JSFunction::maybeGetOrCreateScript(cx, fun, &script);
                 if (!DisassembleScript(cx, script, fun, lines, recursive, sp))
                     return false;
             }
         }
     }
     return true;
 }
 
@@ -4972,22 +4972,27 @@ BindScriptArgs(JSContext *cx, JSObject *
                               JSPROP_ENUMERATE)) {
             return false;
         }
     }
 
     return true;
 }
 
+// This function is currently only called from "#if defined(JS_ION)" chunks,
+// so we're guarding the function definition with an #ifdef, too, to avoid
+// build warning for unused function in non-ion-enabled builds:
+#if defined(JS_ION)
 static int
 OptionFailure(const char *option, const char *str)
 {
     fprintf(stderr, "Unrecognized option for %s: %s\n", option, str);
     return EXIT_FAILURE;
 }
+#endif /* JS_ION */
 
 static int
 ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op)
 {
     RootedObject obj(cx, obj_);
 
     if (op->getBoolOption('a'))
         JS_ToggleOptions(cx, JSOPTION_METHODJIT_ALWAYS);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2307,42 +2307,42 @@ class Debugger::ScriptQuery {
         innermost = false;
         return matchAllDebuggeeGlobals();
     }
 
     /*
      * Search all relevant compartments and the stack for scripts matching
      * this query, and append the matching scripts to |vector|.
      */
-    bool findScripts(AutoScriptVector *vector) {
-        AutoAssertNoGC nogc;
-
+    bool findScripts(AutoScriptVector *v) {
         if (!prepareQuery())
             return false;
 
         /* Search each compartment for debuggee scripts. */
+        vector = v;
+        oom = false;
         for (CompartmentSet::Range r = compartments.all(); !r.empty(); r.popFront()) {
-            for (gc::CellIter i(r.front(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
-                RawScript script = i.get<JSScript>();
-                if (!consider(script, vector))
-                    return false;
+            IterateCells(cx->runtime, r.front(), gc::FINALIZE_SCRIPT, this, considerCell);
+            if (oom) {
+                js_ReportOutOfMemory(cx);
+                return false;
             }
         }
 
         /*
          * For most queries, we just accumulate results in 'vector' as we find
          * them. But if this is an 'innermost' query, then we've accumulated the
          * results in the 'innermostForCompartment' map. In that case, we now need to
          * walk that map and populate 'vector'.
          */
         if (innermost) {
             for (CompartmentToScriptMap::Range r = innermostForCompartment.all();
                  !r.empty();
                  r.popFront()) {
-                if (!vector->append(r.front().value)) {
+                if (!v->append(r.front().value)) {
                     js_ReportOutOfMemory(cx);
                     return false;
                 }
             }
         }
 
         return true;
     }
@@ -2380,16 +2380,22 @@ class Debugger::ScriptQuery {
 
     /*
      * For 'innermost' queries, a map from compartments to the innermost script
      * we've seen so far in that compartment. (Template instantiation code size
      * explosion ho!)
      */
     CompartmentToScriptMap innermostForCompartment;
 
+    /* The vector to which to append the scripts found. */
+    AutoScriptVector *vector;
+
+    /* Indicates whether OOM has occurred while matching. */
+    bool oom;
+
     /* Arrange for this ScriptQuery to match only scripts that run in |global|. */
     bool matchSingleGlobal(GlobalObject *global) {
         JS_ASSERT(compartments.count() == 0);
         if (!compartments.put(global->compartment())) {
             js_ReportOutOfMemory(cx);
             return false;
         }
         return true;
@@ -2420,32 +2426,40 @@ class Debugger::ScriptQuery {
         if (url.isString()) {
             if (!urlCString.encode(cx, url.toString()))
                 return false;
         }
 
         return true;
     }
 
+    static void considerCell(JSRuntime *rt, void *data, void *thing,
+                             JSGCTraceKind traceKind, size_t thingSize) {
+        ScriptQuery *self = static_cast<ScriptQuery *>(data);
+        self->consider(static_cast<JSScript *>(thing));
+    }
+
     /*
      * If |script| matches this query, append it to |vector| or place it in
-     * |innermostForCompartment|, as appropriate. Return true if no error
-     * occurs, false if an error occurs.
+     * |innermostForCompartment|, as appropriate. Set |oom| if an out of memory
+     * condition occurred.
      */
-    bool consider(JSScript *script, AutoScriptVector *vector) {
+    void consider(JSScript *script) {
+        if (oom)
+            return;
         JSCompartment *compartment = script->compartment();
         if (!compartments.has(compartment))
-            return true;
+            return;
         if (urlCString.ptr()) {
             if (!script->filename || strcmp(script->filename, urlCString.ptr()) != 0)
-                return true;
+                return;
         }
         if (hasLine) {
             if (line < script->lineno || script->lineno + js_GetScriptLineExtent(script) < line)
-                return true;
+                return;
         }
         if (innermost) {
             /*
              * For 'innermost' queries, we don't place scripts in |vector| right
              * away; we may later find another script that is nested inside this
              * one. Instead, we record the innermost script we've found so far
              * for each compartment in innermostForCompartment, and only
              * populate |vector| at the bottom of findScripts, when we've
@@ -2462,29 +2476,29 @@ class Debugger::ScriptQuery {
                 if (script->staticLevel > incumbent->staticLevel)
                     p->value = script;
             } else {
                 /*
                  * This is the first matching script we've encountered for this
                  * compartment, so it is thus the innermost such script.
                  */
                 if (!innermostForCompartment.add(p, compartment, script)) {
-                    js_ReportOutOfMemory(cx);
-                    return false;
+                    oom = true;
+                    return;
                 }
             }
         } else {
             /* Record this matching script in the results vector. */
             if (!vector->append(script)) {
-                js_ReportOutOfMemory(cx);
-                return false;
+                oom = true;
+                return;
             }
         }
 
-        return true;
+        return;
     }
 };
 
 JSBool
 Debugger::findScripts(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_DEBUGGER(cx, argc, vp, "findScripts", args, dbg);
 
--- a/js/src/vm/ForkJoin.cpp
+++ b/js/src/vm/ForkJoin.cpp
@@ -134,17 +134,17 @@ class js::AutoRendezvous
         threadCx.shared->initiateRendezvous(threadCx);
     }
 
     ~AutoRendezvous() {
         threadCx.shared->endRendezvous(threadCx);
     }
 };
 
-PRUintn ForkJoinSlice::ThreadPrivateIndex;
+unsigned ForkJoinSlice::ThreadPrivateIndex;
 
 class js::AutoSetForkJoinSlice
 {
   public:
     AutoSetForkJoinSlice(ForkJoinSlice *threadCx) {
         PR_SetThreadPrivate(ForkJoinSlice::ThreadPrivateIndex, threadCx);
     }
 
--- a/js/src/vm/ForkJoin.h
+++ b/js/src/vm/ForkJoin.h
@@ -150,17 +150,17 @@ struct ForkJoinSlice
     static bool Initialize();
 
   private:
     friend class AutoRendezvous;
     friend class AutoSetForkJoinSlice;
 
 #ifdef JS_THREADSAFE
     // Initialized by Initialize()
-    static PRUintn ThreadPrivateIndex;
+    static unsigned ThreadPrivateIndex;
 #endif
 
     ForkJoinShared *const shared;
 };
 
 // Generic interface for specifying divisible operations that can be
 // executed in a fork-join fashion.
 struct ForkJoinOp
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -377,23 +377,22 @@ class GlobalObject : public JSObject
         return &self->getPrototype(JSProto_DataView).toObject();
     }
 
     JSObject *intrinsicsHolder() {
         JS_ASSERT(!getSlotRef(INTRINSICS).isUndefined());
         return &getSlotRef(INTRINSICS).toObject();
     }
 
-    bool getIntrinsicValue(JSContext *cx, PropertyName *name, MutableHandleValue value) {
+    bool getIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue value) {
         RootedObject holder(cx, intrinsicsHolder());
         RootedId id(cx, NameToId(name));
         if (HasDataProperty(cx, holder, id, value.address()))
             return true;
-        Rooted<PropertyName*> rootedName(cx, name);
-        if (!cx->runtime->cloneSelfHostedValue(cx, rootedName, value))
+        if (!cx->runtime->cloneSelfHostedValue(cx, name, value))
             return false;
         mozilla::DebugOnly<bool> ok = JS_DefinePropertyById(cx, holder, id, value, NULL, NULL, 0);
         JS_ASSERT(ok);
         return true;
     }
 
     bool setIntrinsicValue(JSContext *cx, PropertyName *name, HandleValue value) {
 #ifdef DEBUG
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -96,17 +96,17 @@ RegExpObjectBuilder::clone(Handle<RegExp
     RegExpFlag origFlags = other->getFlags();
     RegExpFlag staticsFlags = res->getFlags();
     if ((origFlags & staticsFlags) != staticsFlags) {
         RegExpFlag newFlags = RegExpFlag(origFlags | staticsFlags);
         Rooted<JSAtom *> source(cx, other->getSource());
         return build(source, newFlags);
     }
 
-    RegExpGuard g;
+    RegExpGuard g(cx);
     if (!other->getShared(cx, &g))
         return NULL;
 
     Rooted<JSAtom *> source(cx, other->getSource());
     return build(source, *g);
 }
 
 /* MatchPairs */
@@ -401,16 +401,22 @@ RegExpShared::~RegExpShared()
 #if ENABLE_YARR_JIT
     codeBlock.release();
 #endif
     if (bytecode)
         js_delete<BytecodePattern>(bytecode);
 }
 
 void
+RegExpShared::trace(JSTracer *trc)
+{
+    MarkString(trc, &source, "regexpshared source");
+}
+
+void
 RegExpShared::reportYarrError(JSContext *cx, TokenStream *ts, ErrorCode error)
 {
     switch (error) {
       case JSC::Yarr::NoError:
         JS_NOT_REACHED("Called reportYarrError with value for no error");
         return;
 #define COMPILE_EMSG(__code, __msg)                                                              \
       case JSC::Yarr::__code:                                                                    \
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -115,21 +115,21 @@ class RegExpShared
     typedef JSC::Yarr::YarrPattern YarrPattern;
 #if ENABLE_YARR_JIT
     typedef JSC::Yarr::JSGlobalData JSGlobalData;
     typedef JSC::Yarr::YarrCodeBlock YarrCodeBlock;
     typedef JSC::Yarr::YarrJITCompileMode YarrJITCompileMode;
 #endif
 
     /*
-     * Source to the RegExp. Safe to hold: if the RegExpShared is active,
-     * then at least one RegExpObject must be referencing the RegExpShared,
-     * and the RegExpObject keeps alive the source JSAtom.
+     * Source to the RegExp. The RegExpShared must either be protected by a
+     * RegExpGuard, which handles rooting for stacky RegExpShareds,
+     * or trace() must be explicitly called during marking.
      */
-    JSAtom *           source;
+    HeapPtrAtom        source;
     RegExpFlag         flags;
     unsigned           parenCount;
 
 #if ENABLE_YARR_JIT
     /* Note: Native code is valid only if |codeBlock.isFallBack() == false|. */
     YarrCodeBlock   codeBlock;
 #endif
     BytecodePattern *bytecode;
@@ -144,16 +144,18 @@ class RegExpShared
 
     bool compileIfNecessary(JSContext *cx);
     bool compileMatchOnlyIfNecessary(JSContext *cx);
 
   public:
     RegExpShared(JSRuntime *rt, JSAtom *source, RegExpFlag flags);
     ~RegExpShared();
 
+    void trace(JSTracer *trc);
+
     /* Static functions to expose some Yarr logic. */
     static inline bool isJITRuntimeEnabled(JSContext *cx);
     static void reportYarrError(JSContext *cx, TokenStream *ts, ErrorCode error);
     static bool checkSyntax(JSContext *cx, TokenStream *tokenStream, JSLinearString *source);
 
     /* Called when a RegExpShared is installed into a RegExpObject. */
     inline void prepareForUse(JSContext *cx);
 
@@ -193,32 +195,51 @@ class RegExpShared
 
 /*
  * Extend the lifetime of a given RegExpShared to at least the lifetime of
  * the guard object. See Regular Expression comment at the top.
  */
 class RegExpGuard
 {
     RegExpShared *re_;
+
+    /*
+     * Prevent the RegExp source from being collected:
+     * because RegExpShared objects compile at execution time, the source
+     * must remain rooted for the active lifetime of the RegExpShared.
+     */
+    RootedAtom source_;
+
     RegExpGuard(const RegExpGuard &) MOZ_DELETE;
     void operator=(const RegExpGuard &) MOZ_DELETE;
+
   public:
-    RegExpGuard() : re_(NULL) {}
-    RegExpGuard(RegExpShared &re) : re_(&re) {
+    RegExpGuard(JSContext *cx)
+      : re_(NULL), source_(cx)
+    { }
+
+    RegExpGuard(JSContext *cx, RegExpShared &re)
+      : re_(&re), source_(cx, re.source)
+    {
         re_->incRef();
     }
+
+    ~RegExpGuard() {
+        if (re_)
+            re_->decRef();
+    }
+
+  public:
     void init(RegExpShared &re) {
         JS_ASSERT(!re_);
         re_ = &re;
         re_->incRef();
+        source_ = re.source;
     }
-    ~RegExpGuard() {
-        if (re_)
-            re_->decRef();
-    }
+
     bool initialized() const { return !!re_; }
     RegExpShared *re() const { JS_ASSERT(initialized()); return re_; }
     RegExpShared *operator->() { return re(); }
     RegExpShared &operator*() { return *re(); }
 };
 
 class RegExpCompartment
 {
--- a/js/src/vm/RegExpStatics.cpp
+++ b/js/src/vm/RegExpStatics.cpp
@@ -82,17 +82,17 @@ RegExpStatics::executeLazy(JSContext *cx
      * It is not necessary to call aboutToWrite(): evaluation of
      * implicit copies is safe.
      */
 
     size_t length = matchesInput->length();
     StableCharPtr chars(matchesInput->chars(), length);
 
     /* Execute the full regular expression. */
-    RegExpGuard shared;
+    RegExpGuard shared(cx);
     if (!regexp->getShared(cx, &shared))
         return false;
 
     RegExpRunStatus status = shared->execute(cx, chars, length, &this->lastIndex, this->matches);
     if (status == RegExpRunStatus_Error)
         return false;
 
     /* Unset lazy state and remove rooted values that now have no use. */
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -1519,17 +1519,18 @@ CheckTargetAndPopulate(const nsXPTType& 
 }
 
 // Fast conversion of typed arrays to native using memcpy.
 // No float or double canonicalization is done. Called by
 // JSarray2Native whenever a TypedArray is met. ArrayBuffers
 // are not accepted; create a properly typed array view on them
 // first. The element type of array must match the XPCOM
 // type in size, type and signedness exactly. As an exception,
-// Uint8ClampedArray is allowed for arrays of uint8_t.
+// Uint8ClampedArray is allowed for arrays of uint8_t. DataViews
+// are not supported.
 
 // static
 JSBool
 XPCConvert::JSTypedArray2Native(void** d,
                                 JSObject* jsArray,
                                 uint32_t count,
                                 const nsXPTType& type,
                                 nsresult* pErr)
@@ -1545,17 +1546,17 @@ XPCConvert::JSTypedArray2Native(void** d
         if (pErr)
             *pErr = NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY;
 
         return false;
     }
 
     void* output = nullptr;
 
-    switch (JS_GetTypedArrayType(jsArray)) {
+    switch (JS_GetArrayBufferViewType(jsArray)) {
     case js::ArrayBufferView::TYPE_INT8:
         if (!CheckTargetAndPopulate(nsXPTType::T_I8, type,
                                     sizeof(int8_t), count,
                                     jsArray, &output, pErr)) {
             return false;
         }
         break;
 
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -2014,16 +2014,20 @@ nsFlexContainerFrame::Reflow(nsPresConte
                              const nsHTMLReflowState& aReflowState,
                              nsReflowStatus&          aStatus)
 {
   DO_GLOBAL_REFLOW_COUNT("nsFlexContainerFrame");
   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
   PR_LOG(GetFlexContainerLog(), PR_LOG_DEBUG,
          ("Reflow() for nsFlexContainerFrame %p\n", this));
 
+  if (IsFrameTreeTooDeep(aReflowState, aDesiredSize, aStatus)) {
+    return NS_OK;
+  }
+
   // We (and our children) can only depend on our ancestor's height if we have
   // a percent-height.  (There are actually other cases, too -- e.g. if our
   // parent is itself a vertical flex container and we're flexible -- but we'll
   // let our ancestors handle those sorts of cases.)
   if (GetStylePosition()->mHeight.HasPercent()) {
     AddStateBits(NS_FRAME_CONTAINS_RELATIVE_HEIGHT);
   }
 
--- a/layout/generic/test/Makefile.in
+++ b/layout/generic/test/Makefile.in
@@ -113,11 +113,12 @@ MOCHITEST_CHROME_FILES = \
   test_selection_underline.html \
   test_bug632379.xul \
   test_bug508115.xul \
   test_bug469613.xul \
   test_bug469774.xul \
   test_backspace_delete.xul \
   test_bug514732-2.xul \
   file_bug514732_window.xul \
+  test_selection_preventDefault.html \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/layout/generic/test/test_selection_preventDefault.html
@@ -0,0 +1,174 @@
+<!DOCTYPE>
+<html>
+<head>
+<title>selection preventDefault test</title>
+<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+<style type="text/css">
+  #fixedDiv1 {
+    position: fixed;
+    right: 0;
+    overflow: scroll;
+    width: 200px;
+    top: 0;
+  }
+  input {
+    font-size: 16px;
+    height: 16px;
+    width: 80px;
+    margin: 0;
+    padding: 0;
+  }
+</style>
+
+</head>
+<body>
+<input id="input" type="text" value="iiiiiiiii iiiiiiiii iiiiiiiii">
+<div id="fixedDiv1" class="testingDiv">
+dddddd dddddd dddddd
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var fixedDiv1 = document.getElementById("fixedDiv1");
+var input = document.getElementById("input");
+
+function test()
+{
+  function getSelectionForEditor(aEditorElement)
+  {
+    const nsIDOMNSEditableElement =
+      Components.interfaces.nsIDOMNSEditableElement;
+    return aEditorElement.QueryInterface(nsIDOMNSEditableElement).editor.selection;
+  }
+
+  function clear()
+  {
+    var sel = window.getSelection();
+    if (sel.rangeCount > 0)
+      sel.collapseToEnd();
+    sel = getSelectionForEditor(input);
+    if (sel.rangeCount > 0)
+      sel.collapseToEnd();
+  }
+
+  const kFalse = 0;
+  const kTrue  = 1;
+  const kToDo  = 2;
+
+  function check(aFixedDiv1ShouldBeSelected,
+                 aInputShouldBeSelected,
+                 aTestingDescription)
+  {
+    function checkCharacter(aSelectedText,
+                            aShouldBeIncludedCharacter,
+                            aSouldBeSelected,
+                            aElementName)
+    {
+      var boolvalue = aSouldBeSelected & kTrue;
+      var f = aSouldBeSelected & kToDo ? todo : ok;
+      var str = aSelectedText.replace('\n', '\\n');
+      if (boolvalue) {
+        f(aSelectedText.indexOf(aShouldBeIncludedCharacter) >= 0,
+          "The contents of " + aElementName +
+          " aren't selected (" + aTestingDescription +
+          "): Selected String: \"" + str + "\"");
+      } else {
+        f(aSelectedText.indexOf(aShouldBeIncludedCharacter) < 0,
+          "The contents of " + aElementName +
+          " are selected (" + aTestingDescription +
+          "): Selected String: \"" + str + "\"");
+      }
+    }
+
+    var sel = window.getSelection().toString();
+    checkCharacter(sel, "d", aFixedDiv1ShouldBeSelected, "fixedDiv1");
+
+    // input contents must not be included on the parent
+    // selection.
+    checkCharacter(sel, "i", false, "input (checking on parent)");
+
+    var selInput = getSelectionForEditor(input).toString();
+    checkCharacter(selInput, "i", aInputShouldBeSelected, "input");
+  }
+
+  function eventHandler(evt) {
+    evt.preventDefault();
+  }
+
+  // prevent default action on mousedown should prevent selection
+  fixedDiv1.addEventListener("mousedown", eventHandler);
+  synthesizeMouse(fixedDiv1, 30, 5, { type: "mousedown" });
+  synthesizeMouse(fixedDiv1, 40, 5, { type: "mousemove" });
+  synthesizeMouse(fixedDiv1, 40, 5, { type: "mouseup" });
+  check(kFalse, kFalse, "fixedDiv1-fixedDiv1-mousedown");
+  clear();
+
+  input.addEventListener("mousedown", eventHandler);
+  synthesizeMouse(input, 20, 5, { type: "mousedown" });
+  synthesizeMouse(input, 40, 5, { type: "mousemove" });
+  synthesizeMouse(input, 40, 5, { type: "mouseup" });
+  check(kFalse, kFalse, "input-input-mousedown");
+  clear();
+
+  // clean up mousedown listener
+  [fixedDiv1, input].forEach(function(element) {
+     element.removeEventListener("mousedown", eventHandler);
+  });
+
+  // prevent default action on mouseup should not affect the selection state
+  fixedDiv1.addEventListener("mouseup", eventHandler);
+  synthesizeMouse(fixedDiv1, 30, 5, { type: "mousedown" });
+  synthesizeMouse(fixedDiv1, 40, 5, { type: "mousemove" });
+  synthesizeMouse(fixedDiv1, 40, 5, { type: "mouseup" });
+  check(kTrue, kFalse, "fixedDiv1-fixedDiv1-mouseup");
+  clear();
+
+  input.addEventListener("mouseup", eventHandler);
+  synthesizeMouse(input, 20, 5, { type: "mousedown" });
+  synthesizeMouse(input, 40, 5, { type: "mousemove" });
+  synthesizeMouse(input, 40, 5, { type: "mouseup" });
+  check(kFalse, kTrue, "input-input-mouseup");
+  clear();
+
+  [fixedDiv1, input].forEach(function(element) {
+     element.removeEventListener("mouseup", eventHandler);
+  });
+
+  // touchmove event should not affect the selection state
+  synthesizeTouch(fixedDiv1, 30, 5, { type: "touchstart" });
+  synthesizeTouch(fixedDiv1, 40, 5, { type: "touchmove" });
+  check(kFalse, kFalse, "fixedDiv1-fixedDiv1-touchmove");
+  synthesizeTouch(fixedDiv1, 40, 5, { type: "touchend" });
+  clear();
+
+  synthesizeTouch(input, 20, 5, { type: "touchstart" });
+  synthesizeTouch(input, 40, 5, { type: "touchmove" });
+  check(kFalse, kFalse, "input-input-touchmove");
+  synthesizeTouch(input, 40, 5, { type: "touchend" });
+  clear();
+
+  fixedDiv1.addEventListener("touchmove", eventHandler);
+  synthesizeTouch(fixedDiv1, 30, 5, { type: "touchstart" });
+  synthesizeTouch(fixedDiv1, 40, 5, { type: "touchmove" });
+  check(kFalse, kFalse, "fixedDiv1-fixedDiv1-touchmove-preventDefault");
+  synthesizeTouch(fixedDiv1, 40, 5, { type: "touchend" });
+  clear();
+
+  input.addEventListener("touchmove", eventHandler);
+  synthesizeTouch(input, 20, 5, { type: "touchstart" });
+  synthesizeTouch(input, 40, 5, { type: "touchmove" });
+  check(kFalse, kFalse, "input-input-touchmove-preventDefault");
+  synthesizeTouch(input, 40, 5, { type: "touchend" });
+  clear();
+
+  SimpleTest.finish();
+}
+window.onload = function() { setTimeout(test, 0); };
+SimpleTest.waitForExplicitFinish();
+</script>
+</pre>
+</body>
+</html>
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -1517,17 +1517,17 @@ nsMathMLContainerFrame::TransmitAutomati
   }
 
   return NS_OK;
 }
 
 nsresult
 nsMathMLContainerFrame::ReportErrorToConsole(const char*       errorMsgId,
                                              const PRUnichar** aParams,
-                                             PRUint32          aParamCount)
+                                             uint32_t          aParamCount)
 {
   return nsContentUtils::ReportToConsole(nsIScriptError::errorFlag,
                                          "MathML", mContent->OwnerDoc(),
                                          nsContentUtils::eMATHML_PROPERTIES,
                                          errorMsgId, aParams, aParamCount);
 }
 
 nsresult
--- a/layout/mathml/nsMathMLContainerFrame.h
+++ b/layout/mathml/nsMathMLContainerFrame.h
@@ -262,17 +262,17 @@ public:
 
   /*
    * Helper to call ReportToConsole when an error occurs.
    * @param aParams see nsContentUtils::ReportToConsole
    */
   nsresult
   ReportErrorToConsole(const char*       aErrorMsgId,
                        const PRUnichar** aParams = nullptr,
-                       PRUint32          aParamCount = 0);
+                       uint32_t          aParamCount = 0);
 
   // helper method to reflow a child frame. We are inline frames, and we don't
   // know our positions until reflow is finished. That's why we ask the
   // base method not to worry about our position.
   nsresult 
   ReflowChild(nsIFrame*                aKidFrame,
               nsPresContext*          aPresContext,
               nsHTMLReflowMetrics&     aDesiredSize,
--- a/layout/reftests/text-svgglyphs/reftest.list
+++ b/layout/reftests/text-svgglyphs/reftest.list
@@ -1,16 +1,17 @@
 pref(gfx.font_rendering.opentype_svg.enabled,false)   != svg-glyph-basic.svg svg-glyph-basic-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-basic.svg svg-glyph-basic-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,false)   != svg-glyph-positioning.svg svg-glyph-positioning-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-positioning.svg svg-glyph-positioning-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-invalid.html svg-glyph-invalid-ref.html
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-objectfill-solid.svg svg-glyph-objectfill-solid-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-objectstroke-solid.svg svg-glyph-objectstroke-solid-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-objectgradient.svg svg-glyph-objectgradient-ref.svg
+pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-objectgradient-zoom.svg svg-glyph-objectgradient-zoom-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-objectpattern.svg svg-glyph-objectpattern-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == clip.html clip-ref.html
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-objectopacity.svg svg-glyph-objectopacity-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-objectopacity2.svg svg-glyph-objectopacity2-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-paintnone.svg svg-glyph-paintnone-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-cachedopacity.svg svg-glyph-cachedopacity-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-objectvalue.svg svg-glyph-objectvalue-ref.svg
 pref(gfx.font_rendering.opentype_svg.enabled,true)    == svg-glyph-mask.svg svg-glyph-mask-ref.svg
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-svgglyphs/svg-glyph-objectgradient-zoom-ref.svg
@@ -0,0 +1,25 @@
+<svg xmlns="http://www.w3.org/2000/svg" reftest-zoom="0.5">
+
+  <defs>
+    <linearGradient id="grad" x1="0" y1="0" x2="800" y2="800" gradientUnits="userSpaceOnUse">
+      <stop stop-color="purple" offset="0%" />
+      <stop stop-color="lime" offset="100%" />
+    </linearGradient>
+    <radialGradient id="grad2" cx="250" cy="400" r="400" gradientUnits="userSpaceOnUse">
+      <stop stop-color="red" offset="0%" />
+      <stop stop-color="blue" offset="100%" />
+    </radialGradient>
+  </defs>
+
+  <rect x="20" y="20" width="160" height="160" stroke="none"
+    fill="url(#grad)" />
+
+  <rect x="310" y="10" width="180" height="180" fill="url(#grad)"
+    stroke="none" />
+
+  <rect x="20" y="320" width="160" height="160" fill="burlywood"
+    stroke="url(#grad2)" stroke-width="10" />
+
+  <rect x="310" y="310" width="180" height="180" fill="url(#grad2)"
+    stroke="url(#grad)" stroke-width="20" />
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/text-svgglyphs/svg-glyph-objectgradient-zoom.svg
@@ -0,0 +1,35 @@
+<svg xmlns="http://www.w3.org/2000/svg" reftest-zoom="0.5">
+  <!--
+        Test that gradients are inherited from the outer object under zoom
+  -->
+
+  <style type="text/css"><![CDATA[
+    @font-face {
+      font-family: "Liberation";
+      src:url("resources/svg.woff") format("woff");
+    }
+
+    text {
+      font-family: "Liberation";
+      font-size: 200px;
+      stroke-width: 5;
+    }
+  ]]></style>
+
+  <defs>
+    <linearGradient id="grad" x1="0" y1="0" x2="800" y2="800" gradientUnits="userSpaceOnUse">
+      <stop stop-color="purple" offset="0%" />
+      <stop stop-color="lime" offset="100%" />
+    </linearGradient>
+    <radialGradient id="grad2" cx="250" cy="400" r="400" gradientUnits="userSpaceOnUse">
+      <stop stop-color="red" offset="0%" />
+      <stop stop-color="blue" offset="100%" />
+    </radialGradient>
+
+  </defs>
+
+  <text x="0" y="200" fill="url(#grad)" stroke="url(#grad2)">N</text>
+  <text x="300" y="200" fill="url(#grad)" stroke="url(#grad2)">O</text>
+  <text x="0" y="500" fill="url(#grad)" stroke="url(#grad2)">P</text>
+  <text x="300" y="500" fill="url(#grad)" stroke="url(#grad2)">Q</text>
+</svg>
--- a/layout/svg/SVGFEImageFrame.cpp
+++ b/layout/svg/SVGFEImageFrame.cpp
@@ -93,22 +93,19 @@ SVGFEImageFrame::DestroyFrom(nsIFrame* a
   SVGFEImageFrameBase::DestroyFrom(aDestructRoot);
 }
 
 NS_IMETHODIMP
 SVGFEImageFrame::Init(nsIContent* aContent,
                         nsIFrame* aParent,
                         nsIFrame* aPrevInFlow)
 {
-#ifdef DEBUG
-  nsCOMPtr<nsIDOMSVGFEImageElement> elem = do_QueryInterface(aContent);
-  NS_ASSERTION(elem,
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::feImage),
                "Trying to construct an SVGFEImageFrame for a "
                "content element that doesn't support the right interfaces");
-#endif /* DEBUG */
 
   SVGFEImageFrameBase::Init(aContent, aParent, aPrevInFlow);
   nsCOMPtr<nsIImageLoadingContent> imageLoader =
     do_QueryInterface(SVGFEImageFrameBase::mContent);
 
   if (imageLoader) {
     imageLoader->FrameCreated(this);
   }
--- a/layout/svg/SVGViewFrame.cpp
+++ b/layout/svg/SVGViewFrame.cpp
@@ -3,17 +3,17 @@
  * 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/. */
 
 // Keep in (case-insensitive) order:
 #include "nsFrame.h"
 #include "nsGkAtoms.h"
 #include "nsSVGOuterSVGFrame.h"
 #include "nsSVGSVGElement.h"
-#include "nsSVGViewElement.h"
+#include "mozilla/dom/SVGViewElement.h"
 
 typedef nsFrame SVGViewFrameBase;
 
 /**
  * While views are not directly rendered in SVG they can be linked to
  * and thereby override attributes of an <svg> element via a fragment
  * identifier. The SVGViewFrame class passes on any attribute changes
  * the view receives to the overridden <svg> element (if there is one).
@@ -76,18 +76,18 @@ NS_NewSVGViewFrame(nsIPresShell* aPresSh
 NS_IMPL_FRAMEARENA_HELPERS(SVGViewFrame)
 
 #ifdef DEBUG
 NS_IMETHODIMP
 SVGViewFrame::Init(nsIContent* aContent,
                    nsIFrame* aParent,
                    nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGViewElement> elem = do_QueryInterface(aContent);
-  NS_ASSERTION(elem, "Content is not an SVG view");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::view),
+               "Content is not an SVG view");
 
   return SVGViewFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom *
 SVGViewFrame::GetType() const
 {
--- a/layout/svg/nsSVGAFrame.cpp
+++ b/layout/svg/nsSVGAFrame.cpp
@@ -86,18 +86,17 @@ NS_IMPL_FRAMEARENA_HELPERS(nsSVGAFrame)
 //----------------------------------------------------------------------
 // nsIFrame methods
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGAFrame::Init(nsIContent* aContent,
                   nsIFrame* aParent,
                   nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGAElement> elem = do_QueryInterface(aContent);
-  NS_ASSERTION(elem,
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::a),
                "Trying to construct an SVGAFrame for a "
                "content element that doesn't support the right interfaces");
 
   return nsSVGAFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 NS_IMETHODIMP
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Main header first:
 #include "nsSVGClipPathFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxContext.h"
 #include "nsGkAtoms.h"
-#include "nsIDOMSVGClipPathElement.h"
 #include "nsRenderingContext.h"
 #include "nsSVGClipPathElement.h"
 #include "nsSVGEffects.h"
 #include "nsSVGUtils.h"
 
 //----------------------------------------------------------------------
 // Implementation
 
@@ -293,20 +292,18 @@ nsSVGClipPathFrame::AttributeChanged(int
                                                   aAttribute, aModType);
 }
 
 NS_IMETHODIMP
 nsSVGClipPathFrame::Init(nsIContent* aContent,
                          nsIFrame* aParent,
                          nsIFrame* aPrevInFlow)
 {
-#ifdef DEBUG
-  nsCOMPtr<nsIDOMSVGClipPathElement> clipPath = do_QueryInterface(aContent);
-  NS_ASSERTION(clipPath, "Content is not an SVG clipPath!");
-#endif
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::clipPath),
+               "Content is not an SVG clipPath!");
 
   AddStateBits(NS_STATE_SVG_CLIPPATH_CHILD);
   return nsSVGClipPathFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 
 nsIAtom *
 nsSVGClipPathFrame::GetType() const
 {
--- a/layout/svg/nsSVGFilterFrame.cpp
+++ b/layout/svg/nsSVGFilterFrame.cpp
@@ -518,25 +518,25 @@ nsSVGFilterFrame::GetPostFilterBounds(ns
   // the filter output.
   nsIntRect bbox;
   nsresult rv = instance.get()->ComputeOutputBBox(&bbox);
   if (NS_SUCCEEDED(rv)) {
     return TransformFilterSpaceToFrameSpace(instance.get(), &bbox);
   }
   return nsRect();
 }
-  
+
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGFilterFrame::Init(nsIContent* aContent,
                        nsIFrame* aParent,
                        nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGFilterElement> filter = do_QueryInterface(aContent);
-  NS_ASSERTION(filter, "Content is not an SVG filter");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::filter),
+               "Content is not an SVG filter");
 
   return nsSVGFilterFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom *
 nsSVGFilterFrame::GetType() const
 {
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -5,17 +5,16 @@
 
 // Main header first:
 #include "nsSVGForeignObjectFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxContext.h"
 #include "gfxMatrix.h"
 #include "nsGkAtoms.h"
-#include "nsIDOMSVGForeignObjectElem.h"
 #include "nsINameSpaceManager.h"
 #include "nsLayoutUtils.h"
 #include "nsRegion.h"
 #include "nsRenderingContext.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGEffects.h"
 #include "mozilla/dom/SVGForeignObjectElement.h"
 #include "nsSVGIntegrationUtils.h"
@@ -53,20 +52,18 @@ NS_QUERYFRAME_HEAD(nsSVGForeignObjectFra
   NS_QUERYFRAME_ENTRY(nsISVGChildFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsSVGForeignObjectFrameBase)
 
 NS_IMETHODIMP
 nsSVGForeignObjectFrame::Init(nsIContent* aContent,
                               nsIFrame*   aParent,
                               nsIFrame*   aPrevInFlow)
 {
-#ifdef DEBUG
-  nsCOMPtr<nsIDOMSVGForeignObjectElement> foreignObject = do_QueryInterface(aContent);
-  NS_ASSERTION(foreignObject, "Content is not an SVG foreignObject!");
-#endif
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::foreignObject),
+               "Content is not an SVG foreignObject!");
 
   nsresult rv = nsSVGForeignObjectFrameBase::Init(aContent, aParent, aPrevInFlow);
   AddStateBits(aParent->GetStateBits() &
                (NS_STATE_SVG_NONDISPLAY_CHILD | NS_STATE_SVG_CLIPPATH_CHILD));
   AddStateBits(NS_FRAME_FONT_INFLATION_CONTAINER |
                NS_FRAME_FONT_INFLATION_FLOW_ROOT);
   if (NS_SUCCEEDED(rv) &&
       !(mState & NS_STATE_SVG_NONDISPLAY_CHILD)) {
--- a/layout/svg/nsSVGGlyphFrame.cpp
+++ b/layout/svg/nsSVGGlyphFrame.cpp
@@ -967,19 +967,16 @@ nsSVGGlyphFrame::SetupCairoStroke(gfxCon
                                   SVGTextObjectPaint *aThisObjectPaint)
 {
   const nsStyleSVG *style = GetStyleSVG();
   if (style->mStroke.mType == eStyleSVGPaintType_None) {
     aThisObjectPaint->SetStrokeOpacity(0.0f);
     return false;
   }
 
-  gfxContextMatrixAutoSaveRestore matrixRestore(aContext);
-  aContext->IdentityMatrix();
-
   nsSVGUtils::SetupCairoStrokeHitGeometry(this, aContext, aOuterObjectPaint);
   float opacity = nsSVGUtils::GetOpacity(style->mStrokeOpacitySource,
                                          style->mStrokeOpacity,
                                          aOuterObjectPaint);
 
   SetupInheritablePaint(aContext, opacity, aOuterObjectPaint,
                         aThisObjectPaint->mStrokePaint, &nsStyleSVG::mStroke,
                         nsSVGEffects::StrokeProperty());
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -5,22 +5,23 @@
 
 // Main header first:
 #include "nsSVGGradientFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxPattern.h"
 #include "nsContentUtils.h"
 #include "nsIDOMSVGAnimatedNumber.h"
-#include "nsIDOMSVGStopElement.h"
 #include "nsSVGEffects.h"
 #include "nsSVGGradientElement.h"
 #include "SVGAnimatedTransformList.h"
+#include "mozilla/dom/SVGStopElement.h"
 
-using mozilla::SVGAnimatedTransformList;
+using namespace mozilla;
+using namespace mozilla::dom;
 
 //----------------------------------------------------------------------
 // Helper classes
 
 class nsSVGGradientFrame::AutoGradientReferencer
 {
 public:
   AutoGradientReferencer(nsSVGGradientFrame *aFrame)
@@ -98,22 +99,24 @@ nsSVGGradientFrame::GetStopInformation(i
                                        float *aStopOpacity)
 {
   *aOffset = 0.0f;
   *aStopColor = NS_RGBA(0, 0, 0, 0);
   *aStopOpacity = 1.0f;
 
   nsIFrame *stopFrame = nullptr;
   GetStopFrame(aIndex, &stopFrame);
-  nsCOMPtr<nsIDOMSVGStopElement> stopElement =
-    do_QueryInterface(stopFrame->GetContent());
+
+  nsIContent* stopContent = stopFrame->GetContent();
 
-  if (stopElement) {
-    nsCOMPtr<nsIDOMSVGAnimatedNumber> aNum;
-    stopElement->GetOffset(getter_AddRefs(aNum));
+  if (stopContent) {
+    MOZ_ASSERT(stopContent->IsSVG(nsGkAtoms::stop));
+    SVGStopElement* stopElement = nullptr;
+    stopElement = static_cast<SVGStopElement*>(stopContent);
+    nsCOMPtr<nsIDOMSVGAnimatedNumber> aNum = stopElement->Offset();
 
     aNum->GetAnimVal(aOffset);
     if (*aOffset < 0.0f)
       *aOffset = 0.0f;
     else if (*aOffset > 1.0f)
       *aOffset = 1.0f;
   }
 
@@ -414,18 +417,18 @@ nsSVGGradientFrame::GetStopFrame(int32_t
 // -------------------------------------------------------------------------
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGLinearGradientFrame::Init(nsIContent* aContent,
                                nsIFrame* aParent,
                                nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGLinearGradientElement> grad = do_QueryInterface(aContent);
-  NS_ASSERTION(grad, "Content is not an SVG linearGradient");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::linearGradient),
+               "Content is not an SVG linearGradient");
 
   return nsSVGLinearGradientFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom*
 nsSVGLinearGradientFrame::GetType() const
 {
@@ -527,18 +530,18 @@ nsSVGLinearGradientFrame::CreateGradient
 // -------------------------------------------------------------------------
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGRadialGradientFrame::Init(nsIContent* aContent,
                                nsIFrame* aParent,
                                nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGRadialGradientElement> grad = do_QueryInterface(aContent);
-  NS_ASSERTION(grad, "Content is not an SVG radialGradient");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::radialGradient),
+               "Content is not an SVG radialGradient");
 
   return nsSVGRadialGradientFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom*
 nsSVGRadialGradientFrame::GetType() const
 {
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -3,17 +3,16 @@
  * 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/. */
 
 // Keep in (case-insensitive) order:
 #include "gfxContext.h"
 #include "gfxMatrix.h"
 #include "gfxPlatform.h"
 #include "imgIContainer.h"
-#include "nsIDOMSVGImageElement.h"
 #include "nsIImageLoadingContent.h"
 #include "nsLayoutUtils.h"
 #include "nsRenderingContext.h"
 #include "imgINotificationObserver.h"
 #include "nsSVGEffects.h"
 #include "nsSVGPathGeometryFrame.h"
 #include "nsSVGSVGElement.h"
 #include "nsSVGUtils.h"
@@ -128,24 +127,22 @@ nsSVGImageFrame::~nsSVGImageFrame()
   mListener = nullptr;
 }
 
 NS_IMETHODIMP
 nsSVGImageFrame::Init(nsIContent* aContent,
                       nsIFrame* aParent,
                       nsIFrame* aPrevInFlow)
 {
-#ifdef DEBUG
-  nsCOMPtr<nsIDOMSVGImageElement> image = do_QueryInterface(aContent);
-  NS_ASSERTION(image, "Content is not an SVG image!");
-#endif
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::image),
+               "Content is not an SVG image!");
 
   nsresult rv = nsSVGImageFrameBase::Init(aContent, aParent, aPrevInFlow);
   if (NS_FAILED(rv)) return rv;
-  
+
   mListener = new nsSVGImageListener(this);
   if (!mListener) return NS_ERROR_OUT_OF_MEMORY;
   nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
   NS_ENSURE_TRUE(imageLoader, NS_ERROR_UNEXPECTED);
 
   // We should have a PresContext now, so let's notify our image loader that
   // we need to register any image animations with the refresh driver.
   imageLoader->FrameCreated(this);
--- a/layout/svg/nsSVGInnerSVGFrame.cpp
+++ b/layout/svg/nsSVGInnerSVGFrame.cpp
@@ -32,18 +32,18 @@ NS_QUERYFRAME_HEAD(nsSVGInnerSVGFrame)
 NS_QUERYFRAME_TAIL_INHERITING(nsSVGInnerSVGFrameBase)
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGInnerSVGFrame::Init(nsIContent* aContent,
                          nsIFrame* aParent,
                          nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGSVGElement> svg = do_QueryInterface(aContent);
-  NS_ASSERTION(svg, "Content is not an SVG 'svg' element!");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::svg),
+               "Content is not an SVG 'svg' element!");
 
   return nsSVGInnerSVGFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom *
 nsSVGInnerSVGFrame::GetType() const
 {
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -178,18 +178,18 @@ nsSVGMaskFrame::AttributeChanged(int32_t
 }
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGMaskFrame::Init(nsIContent* aContent,
                      nsIFrame* aParent,
                      nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGMaskElement> mask = do_QueryInterface(aContent);
-  NS_ASSERTION(mask, "Content is not an SVG mask");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::mask),
+               "Content is not an SVG mask");
 
   return nsSVGMaskFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom *
 nsSVGMaskFrame::GetType() const
 {
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -6,27 +6,26 @@
 // Main header first:
 #include "nsSVGOuterSVGFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "DOMSVGTests.h"
 #include "gfxMatrix.h"
 #include "nsDisplayList.h"
 #include "nsIDocument.h"
-#include "nsIDOMSVGSVGElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsRenderingContext.h"
 #include "nsStubMutationObserver.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGForeignObjectFrame.h"
 #include "nsSVGSVGElement.h"
 #include "nsSVGTextFrame.h"
-#include "nsSVGViewElement.h"
+#include "mozilla/dom/SVGViewElement.h"
 #include "nsSubDocumentFrame.h"
 
 namespace dom = mozilla::dom;
 
 class nsSVGMutationObserver : public nsStubMutationObserver
 {
 public:
   // nsIMutationObserver interface
@@ -145,20 +144,18 @@ nsSVGOuterSVGFrame::nsSVGOuterSVGFrame(n
   RemoveStateBits(NS_FRAME_SVG_LAYOUT);
 }
 
 NS_IMETHODIMP
 nsSVGOuterSVGFrame::Init(nsIContent* aContent,
                          nsIFrame* aParent,
                          nsIFrame* aPrevInFlow)
 {
-#ifdef DEBUG
-  nsCOMPtr<nsIDOMSVGSVGElement> svgElement = do_QueryInterface(aContent);
-  NS_ASSERTION(svgElement, "Content is not an SVG 'svg' element!");
-#endif
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::svg),
+               "Content is not an SVG 'svg' element!");
 
   AddStateBits(NS_STATE_IS_OUTER_SVG |
                NS_FRAME_FONT_INFLATION_CONTAINER |
                NS_FRAME_FONT_INFLATION_FLOW_ROOT);
 
   // Check for conditional processing attributes here rather than in
   // nsCSSFrameConstructor::FindSVGData because we want to avoid
   // simply giving failing outer <svg> elements an nsSVGContainerFrame.
@@ -281,17 +278,17 @@ nsSVGOuterSVGFrame::GetIntrinsicRatio()
       ratio.width = 0;
     }
     if (ratio.height < 0) {
       ratio.height = 0;
     }
     return ratio;
   }
 
-  nsSVGViewElement* viewElement = content->GetCurrentViewElement();
+  dom::SVGViewElement* viewElement = content->GetCurrentViewElement();
   const nsSVGViewBoxRect* viewbox = nullptr;
 
   // The logic here should match HasViewBox().
   if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
     viewbox = &viewElement->mViewBox.GetAnimValue();
   } else if (content->mViewBox.IsExplicitlySet()) {
     viewbox = &content->mViewBox.GetAnimValue();
   }
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -100,18 +100,17 @@ nsSVGPatternFrame::AttributeChanged(int3
 }
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGPatternFrame::Init(nsIContent* aContent,
                         nsIFrame* aParent,
                         nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGPatternElement> patternElement = do_QueryInterface(aContent);
-  NS_ASSERTION(patternElement, "Content is not an SVG pattern");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::pattern), "Content is not an SVG pattern");
 
   return nsSVGPatternFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom*
 nsSVGPatternFrame::GetType() const
 {
--- a/layout/svg/nsSVGStopFrame.cpp
+++ b/layout/svg/nsSVGStopFrame.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 // Keep in (case-insensitive) order:
 #include "nsFrame.h"
 #include "nsGkAtoms.h"
-#include "nsIDOMSVGStopElement.h"
 #include "nsStyleContext.h"
 #include "nsSVGEffects.h"
 
 // This is a very simple frame whose only purpose is to capture style change
 // events and propagate them to the parent.  Most of the heavy lifting is done
 // within the nsSVGGradientFrame, which is the parent for this frame
 
 typedef nsFrame  nsSVGStopFrameBase;
@@ -78,18 +77,18 @@ NS_IMPL_FRAMEARENA_HELPERS(nsSVGStopFram
 // nsIFrame methods:
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGStopFrame::Init(nsIContent* aContent,
                      nsIFrame* aParent,
                      nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGStopElement> grad = do_QueryInterface(aContent);
-  NS_ASSERTION(grad, "Content doesn't support nsIDOMSVGStopElement");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::stop),
+               "Content doesn't support nsIDOMSVGStopElement");
 
   return nsSVGStopFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 /* virtual */ void
 nsSVGStopFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
--- a/layout/svg/nsSVGSwitchFrame.cpp
+++ b/layout/svg/nsSVGSwitchFrame.cpp
@@ -74,18 +74,18 @@ NS_NewSVGSwitchFrame(nsIPresShell* aPres
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGSwitchFrame)
 
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGSwitchFrame::Init(nsIContent* aContent,
                        nsIFrame* aParent,
                        nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGSwitchElement> svgSwitch = do_QueryInterface(aContent);
-  NS_ASSERTION(svgSwitch, "Content is not an SVG switch\n");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::svgSwitch),
+               "Content is not an SVG switch\n");
 
   return nsSVGSwitchFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom *
 nsSVGSwitchFrame::GetType() const
 {
--- a/layout/svg/nsSVGTSpanFrame.cpp
+++ b/layout/svg/nsSVGTSpanFrame.cpp
@@ -2,18 +2,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Main header first:
 #include "nsSVGTSpanFrame.h"
 
 // Keep others in (case-insensitive) order:
-#include "nsIDOMSVGTSpanElement.h"
-#include "nsIDOMSVGAltGlyphElement.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGUtils.h"
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsIFrame*
 NS_NewSVGTSpanFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -55,19 +53,19 @@ nsSVGTSpanFrame::Init(nsIContent* aConte
     nsIFrame* ancestorFrame = nsSVGUtils::GetFirstNonAAncestorFrame(aParent);
     NS_ASSERTION(ancestorFrame, "Must have ancestor");
 
     nsSVGTextContainerFrame *metrics = do_QueryFrame(ancestorFrame);
     NS_ASSERTION(metrics,
                  "trying to construct an SVGTSpanFrame for an invalid "
                  "container");
 
-    nsCOMPtr<nsIDOMSVGTSpanElement> tspan = do_QueryInterface(aContent);
-    nsCOMPtr<nsIDOMSVGAltGlyphElement> altGlyph = do_QueryInterface(aContent);
-    NS_ASSERTION(tspan || altGlyph, "Content is not an SVG tspan or altGlyph");
+    NS_ASSERTION(aContent->IsSVG() && (aContent->Tag() == nsGkAtoms::altGlyph ||
+                                       aContent->Tag() == nsGkAtoms::tspan),
+                 "Content is not an SVG tspan or altGlyph");
   }
 
   return nsSVGTSpanFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 NS_IMETHODIMP
 nsSVGTSpanFrame::AttributeChanged(int32_t         aNameSpaceID,
--- a/layout/svg/nsSVGTextFrame.cpp
+++ b/layout/svg/nsSVGTextFrame.cpp
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Main header first:
 #include "nsSVGTextFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "nsGkAtoms.h"
 #include "nsIDOMSVGRect.h"
-#include "nsIDOMSVGTextElement.h"
 #include "nsISVGGlyphFragmentNode.h"
 #include "nsSVGGlyphFrame.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGPathElement.h"
 #include "nsSVGTextPathFrame.h"
 #include "nsSVGUtils.h"
 #include "SVGGraphicsElement.h"
 #include "SVGLengthList.h"
@@ -35,18 +34,18 @@ NS_IMPL_FRAMEARENA_HELPERS(nsSVGTextFram
 //----------------------------------------------------------------------
 // nsIFrame methods
 #ifdef DEBUG
 NS_IMETHODIMP
 nsSVGTextFrame::Init(nsIContent* aContent,
                      nsIFrame* aParent,
                      nsIFrame* aPrevInFlow)
 {
-  nsCOMPtr<nsIDOMSVGTextElement> text = do_QueryInterface(aContent);
-  NS_ASSERTION(text, "Content is not an SVG text");
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::text),
+               "Content is not an SVG text");
 
   return nsSVGTextFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 NS_IMETHODIMP
 nsSVGTextFrame::AttributeChanged(int32_t         aNameSpaceID,
                                  nsIAtom*        aAttribute,
--- a/layout/svg/nsSVGTextPathFrame.cpp
+++ b/layout/svg/nsSVGTextPathFrame.cpp
@@ -3,17 +3,16 @@
  * 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/. */
 
 // Main header first:
 #include "nsSVGTextPathFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "nsContentUtils.h"
-#include "nsIDOMSVGTextPathElement.h"
 #include "nsSVGEffects.h"
 #include "nsSVGLength2.h"
 #include "nsSVGPathElement.h"
 #include "mozilla/dom/SVGTextPathElement.h"
 #include "SVGLengthList.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
@@ -38,19 +37,19 @@ nsSVGTextPathFrame::Init(nsIContent* aCo
   NS_ASSERTION(aParent, "null parent");
 
   nsIFrame* ancestorFrame = nsSVGUtils::GetFirstNonAAncestorFrame(aParent);
   NS_ASSERTION(ancestorFrame, "Must have ancestor");
 
   NS_ASSERTION(ancestorFrame->GetType() == nsGkAtoms::svgTextFrame,
                "trying to construct an SVGTextPathFrame for an invalid "
                "container");
-  
-  nsCOMPtr<nsIDOMSVGTextPathElement> textPath = do_QueryInterface(aContent);
-  NS_ASSERTION(textPath, "Content is not an SVG textPath");
+
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::textPath),
+               "Content is not an SVG textPath");
 
   return nsSVGTextPathFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 #endif /* DEBUG */
 
 nsIAtom *
 nsSVGTextPathFrame::GetType() const
 {
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 // Keep in (case-insensitive) order:
 #include "nsIAnonymousContentCreator.h"
-#include "nsIDOMSVGUseElement.h"
 #include "nsSVGGFrame.h"
 #include "nsSVGUseElement.h"
 #include "nsContentList.h"
 
 typedef nsSVGGFrame nsSVGUseFrameBase;
 
 class nsSVGUseFrame : public nsSVGUseFrameBase,
                       public nsIAnonymousContentCreator
@@ -96,20 +95,18 @@ NS_QUERYFRAME_TAIL_INHERITING(nsSVGUseFr
 //----------------------------------------------------------------------
 // nsIFrame methods:
 
 NS_IMETHODIMP
 nsSVGUseFrame::Init(nsIContent* aContent,
                     nsIFrame* aParent,
                     nsIFrame* aPrevInFlow)
 {
-#ifdef DEBUG
-  nsCOMPtr<nsIDOMSVGUseElement> use = do_QueryInterface(aContent);
-  NS_ASSERTION(use, "Content is not an SVG use!");
-#endif /* DEBUG */
+  NS_ASSERTION(aContent->IsSVG(nsGkAtoms::use),
+               "Content is not an SVG use!");
 
   mHasValidDimensions =
     static_cast<nsSVGUseElement*>(aContent)->HasValidDimensions();
 
   return nsSVGUseFrameBase::Init(aContent, aParent, aPrevInFlow);
 }
 
 NS_IMETHODIMP
--- a/media/omx-plugin/OmxPlugin.cpp
+++ b/media/omx-plugin/OmxPlugin.cpp
@@ -79,16 +79,21 @@ ssize_t MediaStreamSource::readAt(MOZ_ST
 {
   char *ptr = reinterpret_cast<char *>(data);
   size_t todo = size;
   while (todo > 0) {
     uint32_t bytesRead;
     if (!mPluginHost->Read(mDecoder, ptr, offset, todo, &bytesRead)) {
       return ERROR_IO;
     }
+
+    if (bytesRead == 0) {
+      return size - todo;
+    }
+
     offset += bytesRead;
     todo -= bytesRead;
     ptr += bytesRead;
   }
   return size;
 }
 
 status_t MediaStreamSource::getSize(MOZ_STAGEFRIGHT_OFF_T *size)
--- a/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c
+++ b/media/webrtc/signaling/src/sipcc/core/sipstack/sip_platform_task.c
@@ -148,17 +148,17 @@ sip_platform_task_init (void)
  *
  * @param[out] out    buffer to be written to
  * @param[in] outlen  length of out buffer so we don't overrun
  * @param[in] suffix  if non-NULL, appended to the template
  *
  * @return            The length of the written output not including the NULL
  *                    terminator, or -1 if an error occurs.
  */
-static PRUint32 sip_get_sock_dir_tmpl(char *out, PRUint32 outlen,
+static uint32_t sip_get_sock_dir_tmpl(char *out, uint32_t outlen,
                                       const char *suffix) {
 
     char *tmpdir;
     tmpdir = getenv("TMPDIR");
 
     if (suffix) {
         return PR_snprintf(out, outlen, "%s/%s%s",
                            tmpdir ? tmpdir : SIP_IPC_TEMP_BASEPATH,
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -495,17 +495,17 @@ abstract public class BrowserApp extends
         }
     }
 
     public void addTab() {
         showAwesomebar(AwesomeBar.Target.NEW_TAB);
     }
 
     public void addPrivateTab() {
-        Tabs.getInstance().loadUrl("about:home", Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_PRIVATE);
+        Tabs.getInstance().loadUrl("about:privatebrowsing", Tabs.LOADURL_NEW_TAB | Tabs.LOADURL_PRIVATE);
     }
 
     public void showNormalTabs() {
         showTabs(TabsPanel.Panel.NORMAL_TABS);
     }
 
     public void showPrivateTabs() {
         showTabs(TabsPanel.Panel.PRIVATE_TABS);
--- a/mobile/android/base/BrowserToolbar.java
+++ b/mobile/android/base/BrowserToolbar.java
@@ -939,19 +939,20 @@ public class BrowserToolbar implements V
 
     public void setTitle(CharSequence title) {
         Tab tab = Tabs.getInstance().getSelectedTab();
 
         // Keep the title unchanged if the tab is entering reader mode
         if (tab != null && tab.isEnteringReaderMode())
             return;
 
-        // Setting a null title for about:home will ensure we just see
+        // Setting a null title will ensure we just see
         // the "Enter Search or Address" placeholder text
-        if (tab != null && "about:home".equals(tab.getURL()))
+        if (tab != null && ("about:home".equals(tab.getURL()) ||
+                            "about:privatebrowsing".equals(tab.getURL())))
             title = null;
 
         mTitle.setText(title);
         mAwesomeBar.setContentDescription(title != null ? title : mTitle.getHint());
     }
 
     public void setFavicon(Bitmap image) {
         if (Tabs.getInstance().getSelectedTab().getState() == Tab.STATE_LOADING)
--- a/mobile/android/base/awesomebar/AllPagesTab.java
+++ b/mobile/android/base/awesomebar/AllPagesTab.java
@@ -597,17 +597,19 @@ public class AllPagesTab extends Awesome
 
         filterSuggestions(mSearchTerm);
     }
 
     private void showSuggestionsOptIn() {
         mSuggestionsOptInPrompt = LayoutInflater.from(mContext).inflate(R.layout.awesomebar_suggestion_prompt, (LinearLayout)getView(), false);
         GeckoTextView promptText = (GeckoTextView) mSuggestionsOptInPrompt.findViewById(R.id.suggestions_prompt_title);
         promptText.setText(getResources().getString(R.string.suggestions_prompt, mSearchEngines.get(0).name));
-        promptText.setPrivateMode(Tabs.getInstance().getSelectedTab().isPrivate());
+        Tab tab = Tabs.getInstance().getSelectedTab();
+        if (tab != null)
+            promptText.setPrivateMode(tab.isPrivate());
 
         final View yesButton = mSuggestionsOptInPrompt.findViewById(R.id.suggestions_prompt_yes);
         final View noButton = mSuggestionsOptInPrompt.findViewById(R.id.suggestions_prompt_no);
         OnClickListener listener = new OnClickListener() {
             public void onClick(View v) {
                 // Prevent the buttons from being clicked multiple times (bug 816902)
                 yesButton.setOnClickListener(null);
                 noButton.setOnClickListener(null);
new file mode 100644
--- /dev/null
+++ b/mobile/android/chrome/content/aboutPrivateBrowsing.xhtml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+# 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/.
+-->
+<!DOCTYPE html [
+  <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+  %htmlDTD;
+  <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
+  %brandDTD;
+  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+  %globalDTD;
+  <!ENTITY % privatebrowsingpageDTD SYSTEM "chrome://browser/locale/aboutPrivateBrowsing.dtd">
+  %privatebrowsingpageDTD;
+]>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <meta name="viewport" content="width=device-width, initial-scale=1; user-scalable=no"/>
+    <link rel="stylesheet" href="chrome://browser/skin/aboutPrivateBrowsing.css" type="text/css" media="all"/>
+    <link rel="icon" type="image/png" href="chrome://branding/content/favicon32.png" />
+    <script type="application/javascript;version=1.7"><![CDATA[
+      const Ci = Components.interfaces;
+      const Cu = Components.utils;
+
+      Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+      if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
+        document.addEventListener("DOMContentLoaded", function () {
+          document.body.setAttribute("class", "normal");
+        }, false);
+      }
+    ]]></script>
+  </head>
+
+  <body class="private">
+    <img class="showPrivate" src="chrome://browser/skin/images/privatebrowsing-mask.png" />
+    <h1 class="showPrivate">&privatebrowsingpage.title;</h1>
+    <h1 class="showNormal">&privatebrowsingpage.issueDesc.normal;</h1>
+
+    <div class="contentSection">
+      <p class="showPrivate">&privatebrowsingpage.description.private;</p>
+      <p class="showNormal">&privatebrowsingpage.description;</p>
+
+      <p>&privatebrowsingpage.moreInfo;</p>
+    </div>
+  </body>
+</html>
--- a/mobile/android/chrome/jar.mn
+++ b/mobile/android/chrome/jar.mn
@@ -10,16 +10,17 @@ chrome.jar:
 * content/about.xhtml                  (content/about.xhtml)
   content/config.xhtml                 (content/config.xhtml)
   content/aboutAddons.xhtml            (content/aboutAddons.xhtml)
   content/aboutAddons.js               (content/aboutAddons.js)
   content/aboutCertError.xhtml         (content/aboutCertError.xhtml)
   content/aboutDownloads.xhtml         (content/aboutDownloads.xhtml)
   content/aboutDownloads.js            (content/aboutDownloads.js)
   content/aboutFeedback.xhtml          (content/aboutFeedback.xhtml)
+  content/aboutPrivateBrowsing.xhtml   (content/aboutPrivateBrowsing.xhtml)
   content/aboutReader.html             (content/aboutReader.html)
   content/aboutReader.js               (content/aboutReader.js)
   content/Readability.js               (content/Readability.js)
   content/JSDOMParser.js               (content/JSDOMParser.js)
   content/readerWorker.js              (content/readerWorker.js)
   content/aboutHome.xhtml              (content/aboutHome.xhtml)
   content/aboutRights.xhtml            (content/aboutRights.xhtml)
   content/aboutApps.xhtml              (content/aboutApps.xhtml)
--- a/mobile/android/components/AboutRedirector.js
+++ b/mobile/android/components/AboutRedirector.js
@@ -62,16 +62,20 @@ let modules = {
   reader: {
     uri: "chrome://browser/content/aboutReader.html",
     privileged: false,
     hide: true
   },
   feedback: {
     uri: "chrome://browser/content/aboutFeedback.xhtml",
     privileged: true
+  },
+  privatebrowsing: {
+    uri: "chrome://browser/content/aboutPrivateBrowsing.xhtml",
+    privileged: true
   }
 }
 
 function AboutRedirector() {}
 AboutRedirector.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
   classID: Components.ID("{322ba47e-7047-4f71-aebf-cb7d69325cd9}"),
 
--- a/mobile/android/components/MobileComponents.manifest
+++ b/mobile/android/components/MobileComponents.manifest
@@ -6,16 +6,17 @@ contract @mozilla.org/network/protocol/a
 contract @mozilla.org/network/protocol/about;1?what=empty {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 contract @mozilla.org/network/protocol/about;1?what=rights {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 contract @mozilla.org/network/protocol/about;1?what=certerror {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 contract @mozilla.org/network/protocol/about;1?what=home {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 contract @mozilla.org/network/protocol/about;1?what=apps {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 contract @mozilla.org/network/protocol/about;1?what=downloads {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 contract @mozilla.org/network/protocol/about;1?what=reader {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 contract @mozilla.org/network/protocol/about;1?what=feedback {322ba47e-7047-4f71-aebf-cb7d69325cd9}
+contract @mozilla.org/network/protocol/about;1?what=privatebrowsing {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 #ifdef MOZ_SAFE_BROWSING
 contract @mozilla.org/network/protocol/about;1?what=blocked {322ba47e-7047-4f71-aebf-cb7d69325cd9}
 #endif
 
 # DirectoryProvider.js
 component {ef0f7a87-c1ee-45a8-8d67-26f586e46a4b} DirectoryProvider.js
 contract @mozilla.org/browser/directory-provider;1 {ef0f7a87-c1ee-45a8-8d67-26f586e46a4b}
 category xpcom-directory-providers browser-directory-provider @mozilla.org/browser/directory-provider;1
new file mode 100644
--- /dev/null
+++ b/mobile/android/themes/core/aboutPrivateBrowsing.css
@@ -0,0 +1,71 @@
+/* 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/. */
+
+body {
+  font-family: Roboto,"Droid Sans",helvetica,arial,clean,sans-serif;
+  font-size: 14px;
+}
+
+body.normal  .showPrivate,
+body.private .showNormal {
+  display: none;
+}
+
+div.contentSection {
+  width: 92%;
+  max-width: 400px;
+  margin: 0 auto;
+}
+
+body.private {
+  color: #9ba3ab;
+  background-image: url("chrome://browser/skin/images/privatebrowsing-bg-textured.png");
+}
+
+body.normal {
+  color: #222;
+  background-image: url("chrome://browser/skin/images/about-bg-lightblue.png");
+}
+
+h1 {
+  font-size: 24px;
+  font-weight: 100;
+  text-align: center;
+  margin: 0;
+}
+
+body.private h1 {
+  color: #d06bff;
+}
+
+img {
+  display: block;
+  width: 125px;
+  height: 125px;
+  margin: -30px auto;
+}
+
+@media all and (max-height: 399px) {
+  body {
+    margin-top: 25px;
+  }
+}
+
+@media all and (min-height: 400px) and (max-height: 599px) {
+  body {
+    margin-top: 50px;
+  }
+}
+
+@media all and (min-height: 600px) and (max-height: 799px) {
+  body {
+    margin-top: 150px;
+  }
+}
+
+@media all and (min-height: 800px) {
+  body {
+    margin-top: 250px;
+  }
+}
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f9ab48016f6ac35917b665665d0103cb79c6b205
GIT binary patch
literal 3904
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
F{{fuS5!e6#
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8acc2985ad3fa95950d13b910daa46c10c9e14c0
GIT binary patch
literal 35627
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
GLSTYDz4c50
--- a/mobile/android/themes/core/jar.mn
+++ b/mobile/android/themes/core/jar.mn
@@ -8,16 +8,17 @@ chrome.jar:
 % skin browser classic/1.0 %skin/
   skin/aboutPage.css                        (aboutPage.css)
   skin/about.css                            (about.css)
   skin/aboutAddons.css                      (aboutAddons.css)
   skin/aboutApps.css                        (aboutApps.css)
 * skin/aboutDownloads.css                   (aboutDownloads.css)
   skin/aboutFeedback.css                    (aboutFeedback.css)
   skin/aboutMemory.css                      (aboutMemory.css)
+* skin/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
   skin/aboutReader.css                      (aboutReader.css)
   skin/aboutSupport.css                     (aboutSupport.css)
 * skin/browser.css                          (browser.css)
 * skin/content.css                          (content.css)
   skin/config.css                           (config.css)
   skin/touchcontrols.css                    (touchcontrols.css)
   skin/netError.css                         (netError.css)
 % override chrome://global/skin/about.css chrome://browser/skin/about.css
@@ -118,8 +119,10 @@ chrome.jar:
   skin/images/reader-toolbar-bg-land-mdpi.png    (images/reader-toolbar-bg-land-mdpi.png)
   skin/images/reader-toolbar-bg-xlarge-mdpi.png  (images/reader-toolbar-bg-xlarge-mdpi.png)
   skin/images/reader-toolbar-bg-port-hdpi.png    (images/reader-toolbar-bg-port-hdpi.png)
   skin/images/reader-toolbar-bg-land-hdpi.png    (images/reader-toolbar-bg-land-hdpi.png)
   skin/images/reader-toolbar-bg-xlarge-hdpi.png  (images/reader-toolbar-bg-xlarge-hdpi.png)
   skin/images/reader-toolbar-bg-port-xhdpi.png   (images/reader-toolbar-bg-port-xhdpi.png)
   skin/images/reader-toolbar-bg-land-xhdpi.png   (images/reader-toolbar-bg-land-xhdpi.png)
   skin/images/reader-toolbar-bg-xlarge-xhdpi.png (images/reader-toolbar-bg-xlarge-xhdpi.png)
+  skin/images/privatebrowsing-mask.png           (images/privatebrowsing-mask.png)
+  skin/images/privatebrowsing-bg-textured.png    (images/privatebrowsing-bg-textured.png)
--- a/security/manager/ssl/src/SharedSSLState.cpp
+++ b/security/manager/ssl/src/SharedSSLState.cpp
@@ -20,18 +20,18 @@
 #include "nsNetCID.h"
 #include "mozilla/unused.h"
 
 using mozilla::psm::SyncRunnableBase;
 using mozilla::unused;
 
 namespace {
 
-static PRInt32 sCertOverrideSvcExists = 0;
-static PRInt32 sCertDBExists = 0;
+static int32_t sCertOverrideSvcExists = 0;
+static int32_t sCertDBExists = 0;
 
 class MainThreadClearer : public SyncRunnableBase
 {
 public:
   MainThreadClearer() : mShouldClearSessionCache(false) {}
 
   void RunOnTargetThread() {
     // In some cases it's possible to cause PSM/NSS to initialize while XPCOM shutdown
--- a/security/manager/ssl/src/nsIdentityChecking.cpp
+++ b/security/manager/ssl/src/nsIdentityChecking.cpp
@@ -1228,20 +1228,17 @@ nsNSSCertificate::hasValidEVOidTag(SECOi
     | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE
     | CERT_REV_M_IGNORE_MISSING_FRESH_INFO
     | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO;
 
   uint64_t revMethodIndependentFlags = 
     CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST
     | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE;
 
-  // We need a PRUint64 here instead of a nice int64_t (until bug 634793 is
-  // fixed) to match the type used in security/nss/lib/certdb/certt.h for
-  // cert_rev_flags_per_method.
-  PRUint64 methodFlags[2];
+  uint64_t methodFlags[2];
   methodFlags[cert_revocation_method_crl] = revMethodFlags;
   methodFlags[cert_revocation_method_ocsp] = revMethodFlags;
 
   CERTRevocationFlags rev;
 
   rev.leafTests.number_of_defined_methods = cert_revocation_method_ocsp +1;
   rev.leafTests.cert_rev_flags_per_method = methodFlags;
   rev.leafTests.number_of_preferred_methods = 1;
deleted file mode 100644
--- a/testing/mozbase/mozcrash/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Mozcrash
-
-Package for getting a stack trace out of processes that have crashed and left behind a minidump file using the Google Breakpad library.
-
-
-## Usage example
-
-TODO
-
-    import mozcrash
-
-    #...
--- a/testing/mozbase/mozcrash/mozcrash/__init__.py
+++ b/testing/mozbase/mozcrash/mozcrash/__init__.py
@@ -1,5 +1,8 @@
 # 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/.
+"""
+mozcrash is a library for getting a stack trace out of processes that have crashed and left behind a minidump file using the Google Breakpad library.
+"""
 
 from mozcrash import *
--- a/testing/mozbase/mozcrash/mozcrash/mozcrash.py
+++ b/testing/mozbase/mozcrash/mozcrash/mozcrash.py
@@ -1,24 +1,27 @@
 # 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/.
 
-from __future__ import with_statement
 __all__ = ['check_for_crashes']
 
-import os, sys, glob, urllib2, tempfile, subprocess, shutil, urlparse, zipfile
+import os, sys, glob, urllib2, tempfile, re, subprocess, shutil, urlparse, zipfile
 import mozlog
 
 def is_url(thing):
   """
   Return True if thing looks like a URL.
   """
   # We want to download URLs like http://... but not Windows paths like c:\...
-  return len(urlparse.urlparse(thing).scheme) >= 2
+  parsed = urlparse.urlparse(thing)
+  if 'scheme' in parsed:
+      return len(parsed.scheme) >= 2
+  else:
+      return len(parsed[0]) >= 2
 
 def extractall(zip, path = None):
     """
     Compatibility shim for Python 2.6's ZipFile.extractall.
     """
     if hasattr(zip, "extractall"):
         return zip.extractall(path)
 
@@ -28,39 +31,48 @@ def extractall(zip, path = None):
     for name in self._zipfile.namelist():
         filename = os.path.normpath(os.path.join(path, name))
         if name.endswith("/"):
             os.makedirs(filename)
         else:
             path = os.path.split(filename)[0]
             if not os.path.isdir(path):
                 os.makedirs(path)
-        with open(filename, "wb") as dest:
-            dest.write(zip.read(name))
+
+        try:
+            f = open(filename, "wb")
+            f.write(zip.read(name))
+        finally:
+            f.close()
 
 def check_for_crashes(dump_directory, symbols_path,
                       stackwalk_binary=None,
                       dump_save_path=None,
                       test_name=None):
     """
-    Print a stack trace for minidumps left behind by a crashing program.
+    Print a stack trace for minidump files left behind by a crashing program.
+
+    `dump_directory` will be searched for minidump files. Any minidump files found will
+    have `stackwalk_binary` executed on them, with `symbols_path` passed as an extra
+    argument.
+
+    `stackwalk_binary` should be a path to the minidump_stackwalk binary.
+    If `stackwalk_binary` is not set, the MINIDUMP_STACKWALK environment variable
+    will be checked and its value used if it is not empty.
 
-    Arguments:
-    dump_directory: The directory in which to look for minidumps.
-    symbols_path: The path to symbols to use for dump processing.
-                  This can either be a path to a directory
-                  containing Breakpad-format symbols, or a URL
-                  to a zip file containing a set of symbols.
-    stackwalk_binary: The path to the minidump_stackwalk binary.
-                      If not set, the environment variable
-                      MINIDUMP_STACKWALK will be checked.
-    dump_save_path: A directory in which to copy minidump files
-                    for safekeeping. If not set, the environment
-                    variable MINIDUMP_SAVE_PATH will be checked.
-    test_name: The test name to be used in log output.
+    `symbols_path` should be a path to a directory containing symbols to use for
+    dump processing. This can either be a path to a directory containing Breakpad-format
+    symbols, or a URL to a zip file containing a set of symbols.
+                  
+    If `dump_save_path` is set, it should be a path to a directory in which to copy minidump
+    files for safekeeping after a stack trace has been printed. If not set, the environment
+    variable MINIDUMP_SAVE_PATH will be checked and its value used if it is not empty.
+                    
+    If `test_name` is set it will be used as the test name in log output. If not set the
+    filename of the calling function will be used.
 
     Returns True if any minidumps were found, False otherwise.
     """
     log = mozlog.getLogger('mozcrash')
     if stackwalk_binary is None:
         stackwalk_binary = os.environ.get('MINIDUMP_STACKWALK', None)
 
     # try to get the caller's filename if no test name is given
@@ -70,68 +82,84 @@ def check_for_crashes(dump_directory, sy
         except:
             test_name = "unknown"
 
     # Check preconditions
     dumps = glob.glob(os.path.join(dump_directory, '*.dmp'))
     if len(dumps) == 0:
         return False
 
-    found_crash = False
     remove_symbols = False 
     # If our symbols are at a remote URL, download them now
-    if is_url(symbols_path):
+    if symbols_path and is_url(symbols_path):
         log.info("Downloading symbols from: %s", symbols_path)
         remove_symbols = True
         # Get the symbols and write them to a temporary zipfile
         data = urllib2.urlopen(symbols_path)
         symbols_file = tempfile.TemporaryFile()
         symbols_file.write(data.read())
         # extract symbols to a temporary directory (which we'll delete after
         # processing all crashes)
         symbols_path = tempfile.mkdtemp()
         zfile = zipfile.ZipFile(symbols_file, 'r')
         extractall(zfile, symbols_path)
         zfile.close()
 
     try:
         for d in dumps:
-            log.info("PROCESS-CRASH | %s | application crashed (minidump found)", test_name)
-            log.info("Crash dump filename: %s", d)
+            stackwalk_output = []
+            stackwalk_output.append("Crash dump filename: " + d)
+            top_frame = None
             if symbols_path and stackwalk_binary and os.path.exists(stackwalk_binary):
                 # run minidump_stackwalk
                 p = subprocess.Popen([stackwalk_binary, d, symbols_path],
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE)
                 (out, err) = p.communicate()
                 if len(out) > 3:
                     # minidump_stackwalk is chatty,
                     # so ignore stderr when it succeeds.
-                    print out
+                    stackwalk_output.append(out)
+                    # The top frame of the crash is always the line after "Thread N (crashed)"
+                    # Examples:
+                    #  0  libc.so + 0xa888
+                    #  0  libnss3.so!nssCertificate_Destroy [certificate.c : 102 + 0x0]
+                    #  0  mozjs.dll!js::GlobalObject::getDebuggers() [GlobalObject.cpp:89df18f9b6da : 580 + 0x0]
+                    #  0  libxul.so!void js::gc::MarkInternal<JSObject>(JSTracer*, JSObject**) [Marking.cpp : 92 + 0x28]
+                    lines = out.splitlines()
+                    for i, line in enumerate(lines):
+                        if "(crashed)" in line:
+                            match = re.search(r"^ 0  (?:.*!)?(?:void )?([^\[]+)", lines[i+1])
+                            if match:
+                                top_frame = "@ %s" % match.group(1).strip()
+                            break
                 else:
-                    print "stderr from minidump_stackwalk:"
-                    print err
+                    stackwalk_output.append("stderr from minidump_stackwalk:")
+                    stackwalk_output.append(err)
                 if p.returncode != 0:
-                    log.error("minidump_stackwalk exited with return code %d", p.returncode)
+                    stackwalk_output.append("minidump_stackwalk exited with return code %d" % p.returncode)
             else:
                 if not symbols_path:
-                    log.warn("No symbols path given, can't process dump.")
+                    stackwalk_output.append("No symbols path given, can't process dump.")
                 if not stackwalk_binary:
-                    log.warn("MINIDUMP_STACKWALK not set, can't process dump.")
+                    stackwalk_output.append("MINIDUMP_STACKWALK not set, can't process dump.")
                 elif stackwalk_binary and not os.path.exists(stackwalk_binary):
-                    log.warn("MINIDUMP_STACKWALK binary not found: %s", stackwalk_binary)
+                    stackwalk_output.append("MINIDUMP_STACKWALK binary not found: %s" % stackwalk_binary)
+            if not top_frame:
+                top_frame = "Unknown top frame"
+            log.error("PROCESS-CRASH | %s | application crashed [%s]", test_name, top_frame)
+            print '\n'.join(stackwalk_output)
             if dump_save_path is None:
                 dump_save_path = os.environ.get('MINIDUMP_SAVE_PATH', None)
             if dump_save_path:
                 shutil.move(d, dump_save_path)
                 log.info("Saved dump as %s", os.path.join(dump_save_path,
                                                           os.path.basename(d)))
             else:
                 os.remove(d)
             extra = os.path.splitext(d)[0] + ".extra"
             if os.path.exists(extra):
                 os.remove(extra)
-            found_crash = True
     finally:
         if remove_symbols:
             shutil.rmtree(symbols_path)
 
-    return found_crash
+    return True
--- a/testing/mozbase/mozcrash/setup.py
+++ b/testing/mozbase/mozcrash/setup.py
@@ -1,32 +1,23 @@
 # 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/.
 
-
-import os
 from setuptools import setup
 
-PACKAGE_VERSION = '0.1'
-
-# get documentation from the README
-try:
-    here = os.path.dirname(os.path.abspath(__file__))
-    description = file(os.path.join(here, 'README.md')).read()
-except (OSError, IOError):
-    description = ''
+PACKAGE_VERSION = '0.3'
 
 # dependencies
-deps = ['']
+deps = []
 
 setup(name='mozcrash',
       version=PACKAGE_VERSION,
-      description="Package for printing stack traces from minidumps left behind by crashed processes.",
-      long_description=description,
+      description="Library for printing stack traces from minidumps left behind by crashed processes",
+      long_description="see http://mozbase.readthedocs.org/",
       classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
       keywords='mozilla',
       author='Mozilla Automation and Tools team',
       author_email='tools@lists.mozilla.org',
       url='https://wiki.mozilla.org/Auto-tools/Projects/MozBase',
       license='MPL',
       packages=['mozcrash'],
       include_package_data=True,
--- a/toolkit/components/osfile/osfile_win_front.jsm
+++ b/toolkit/components/osfile/osfile_win_front.jsm
@@ -309,25 +309,25 @@
        // Now, perform manual truncation
        file.setPosition(0, File.POS_START);
        throw_on_zero("open",
          WinFile.SetEndOfFile(file.fd));
        return file;
      };
 
      /**
-      * Checks if a file exists
+      * Checks if a file or directory exists
       *
       * @param {string} path The path to the file.
       *
       * @return {bool} true if the file exists, false otherwise.
       */
      File.exists = function Win_exists(path) {
        try {
-         let file = File.open(path);
+         let file = File.open(path, FILE_STAT_MODE, FILE_STAT_OPTIONS);
          file.close();
          return true;
        } catch (x) {
          return false;
        }
      };
 
      /**
--- a/toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js
+++ b/toolkit/components/osfile/tests/mochi/worker_test_osfile_front.js
@@ -782,10 +782,16 @@ function test_path()
  */
 function test_exists_file()
 {
   let file_name = OS.Path.join("chrome", "toolkit", "components" ,"osfile",
                                "tests", "mochi", "test_osfile_front.xul");
   info("test_exists_file: starting");
   ok(OS.File.exists(file_name), "test_exists_file: file exists (OS.File.exists)");
   ok(!OS.File.exists(file_name + ".tmp"), "test_exists_file: file does not exists (OS.File.exists)");
+
+  let dir_name = OS.Path.join("chrome", "toolkit", "components" ,"osfile",
+                               "tests", "mochi");
+  ok(OS.File.exists(dir_name), "test_exists_file: directory exists");
+  ok(!OS.File.exists(dir_name) + ".tmp", "test_exists_file: directory does not exist");
+
   info("test_exists_file: complete");
 }
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -8,16 +8,17 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Likely.h"
 
 #include "base/histogram.h"
 #include "base/pickle.h"
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
+#include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "mozilla/ModuleUtils.h"
 #include "nsIXPConnect.h"
 #include "mozilla/Services.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "nsStringGlue.h"
 #include "nsITelemetry.h"
@@ -318,17 +319,17 @@ private:
   nsTHashtable<nsCStringHashKey> mTrackedDBs;
   Mutex mHashMutex;
   HangReports mHangReports;
   Mutex mHangReportsMutex;
   nsIMemoryReporter *mMemoryReporter;
 
   bool mCachedTelemetryData;
   uint32_t mLastShutdownTime;
-  std::vector<nsCOMPtr<nsIFetchTelemetryDataCallback> > mCallbacks;
+  nsCOMArray<nsIFetchTelemetryDataCallback> mCallbacks;
   friend class nsFetchTelemetryData;
 };
 
 TelemetryImpl*  TelemetryImpl::sTelemetry = NULL;
 
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(TelemetryMallocSizeOf)
 
 size_t
@@ -724,20 +725,20 @@ public:
 
 private:
   const char *mFilename;
   nsCOMPtr<TelemetryImpl> mTelemetry;
 
 public:
   void MainThread() {
     mTelemetry->mCachedTelemetryData = true;
-    for (unsigned int i = 0, n = mTelemetry->mCallbacks.size(); i < n; ++i) {
+    for (unsigned int i = 0, n = mTelemetry->mCallbacks.Count(); i < n; ++i) {
       mTelemetry->mCallbacks[i]->Complete();
     }
-    mTelemetry->mCallbacks.clear();
+    mTelemetry->mCallbacks.Clear();
   }
 
   NS_IMETHOD Run() {
     mTelemetry->mLastShutdownTime = ReadLastShutdownDuration(mFilename);
     nsCOMPtr<nsIRunnable> e =
       NS_NewRunnableMethod(this, &nsFetchTelemetryData::MainThread);
     NS_ENSURE_STATE(e);
     NS_DispatchToMainThread(e, NS_DISPATCH_NORMAL);
@@ -794,18 +795,18 @@ TelemetryImpl::AsyncFetchTelemetryData(n
 {
   // We have finished reading the data already, just call the callback.
   if (mCachedTelemetryData) {
     aCallback->Complete();
     return NS_OK;
   }
 
   // We already have a read request running, just remember the callback.
-  if (!mCallbacks.empty()) {
-    mCallbacks.push_back(aCallback);
+  if (mCallbacks.Count() != 0) {
+    mCallbacks.AppendObject(aCallback);
     return NS_OK;
   }
 
   // We make this check so that GetShutdownTimeFileName() doesn't get
   // called; calling that function without telemetry enabled violates
   // assumptions that the write-the-shutdown-timestamp machinery makes.
   if (!Telemetry::CanRecord()) {
     mCachedTelemetryData = true;
@@ -826,17 +827,17 @@ TelemetryImpl::AsyncFetchTelemetryData(n
   // We have to get the filename from the main thread.
   const char *filename = GetShutdownTimeFileName();
   if (!filename) {
     mCachedTelemetryData = true;
     aCallback->Complete();
     return NS_OK;
   }
 
-  mCallbacks.push_back(aCallback);
+  mCallbacks.AppendObject(aCallback);
   nsCOMPtr<nsIRunnable> event = new nsFetchTelemetryData(filename);
 
   targetThread->Dispatch(event, NS_DISPATCH_NORMAL);
   return NS_OK;
 }
 
 TelemetryImpl::TelemetryImpl():
 mHistogramMap(Telemetry::HistogramCount),
--- a/toolkit/content/LightweightThemeConsumer.jsm
+++ b/toolkit/content/LightweightThemeConsumer.jsm
@@ -4,22 +4,29 @@
 
 this.EXPORTED_SYMBOLS = ["LightweightThemeConsumer"];
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeImageOptimizer",
   "resource://gre/modules/LightweightThemeImageOptimizer.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
+  "resource://gre/modules/PrivateBrowsingUtils.jsm");
+
 this.LightweightThemeConsumer =
  function LightweightThemeConsumer(aDocument) {
   this._doc = aDocument;
   this._win = aDocument.defaultView;
   this._footerId = aDocument.documentElement.getAttribute("lightweightthemesfooter");
 
+  if (PrivateBrowsingUtils.isWindowPrivate(this._win)) {
+    return;
+  }
+
   let screen = this._win.screen;
   this._lastScreenWidth = screen.width;
   this._lastScreenHeight = screen.height;
 
   Components.classes["@mozilla.org/observer-service;1"]
             .getService(Components.interfaces.nsIObserverService)
             .addObserver(this, "lightweight-theme-styling-update", false);
 
--- a/toolkit/profile/nsToolkitProfileService.cpp
+++ b/toolkit/profile/nsToolkitProfileService.cpp
@@ -854,17 +854,17 @@ nsToolkitProfileService::CreateTimesInte
     if (exists) {
       return NS_OK;
     }
 
     rv = creationLog->Create(nsIFile::NORMAL_FILE_TYPE, 0700);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // We don't care about microsecond resolution.
-    PRInt64 msec;
+    int64_t msec;
     LL_DIV(msec, PR_Now(), PR_USEC_PER_MSEC);
 
     // Write it out.
     PRFileDesc *writeFile;
     rv = creationLog->OpenNSPRFileDesc(PR_WRONLY, 0700, &writeFile);
     NS_ENSURE_SUCCESS(rv, rv);
 
     PR_fprintf(writeFile, "{\n\"created\": %lld\n}\n", msec);
--- a/widget/gonk/HwcComposer2D.cpp
+++ b/widget/gonk/HwcComposer2D.cpp
@@ -261,17 +261,17 @@ HwcComposer2D::PrepareLayerList(Layer* a
         if (container->UseIntermediateSurface()) {
             LOGD("Container layer needs intermediate surface");
             return false;
         }
         nsAutoTArray<Layer*, 12> children;
         container->SortChildrenBy3DZOrder(children);
 
         //FIXME/bug 810334
-        for (PRUint32 i = 0; i < children.Length(); i++) {
+        for (uint32_t i = 0; i < children.Length(); i++) {
             if (!PrepareLayerList(children[i], aClip)) {
                 return false;
             }
         }
         return true;
     }
 
     LayerOGL* layerGL = static_cast<LayerOGL*>(aLayer->ImplData());
--- a/xpcom/glue/nsProxyRelease.h
+++ b/xpcom/glue/nsProxyRelease.h
@@ -160,16 +160,17 @@ class nsMainThreadPtrHandle
 {
   nsRefPtr<nsMainThreadPtrHolder<T> > mPtr;
 
   public:
   nsMainThreadPtrHandle(nsMainThreadPtrHolder<T> *aHolder) : mPtr(aHolder) {}
   nsMainThreadPtrHandle(const nsMainThreadPtrHandle& aOther) : mPtr(aOther.mPtr) {}
   nsMainThreadPtrHandle& operator=(const nsMainThreadPtrHandle& aOther) {
     mPtr = aOther.mPtr;
+    return *this;
   }
 
   operator nsMainThreadPtrHolder<T>*() { return mPtr.get(); }
 
   // These all call through to nsMainThreadPtrHolder, and thus implicitly
   // assert that we're on the main thread. Off-main-thread consumers must treat
   // these handles as opaque.
   T* get() { return mPtr.get()->get(); }