Merge latest green birch changeset and mozilla-central
authorEd Morley <emorley@mozilla.com>
Tue, 18 Jun 2013 11:57:48 +0100
changeset 146908 58b1f6b4b57092c69417511f92f6f456cac1d3c9
parent 146907 2ee9d156eb15da58997621ffedb1fa5ccefdf7a9 (current diff)
parent 146901 2bcc1f75895aad545fec1662a294a596296ff6de (diff)
child 146918 24308e64b91cf7d26c8f29444391d7de6c3c9973
child 146953 a4d01597aecbd4a295c176a65c05df1f9dc36863
child 147081 0d9da02c7108210024cc10e8bdd96052cf22fdc6
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge latest green birch changeset and mozilla-central
b2g/app/b2g.js
browser/metro/base/tests/mochitest/browser_plugin_input.html
browser/metro/base/tests/mochitest/browser_plugin_input_keyboard.js
browser/metro/base/tests/mochitest/browser_plugin_input_mouse.js
js/src/jspropertycache.cpp
js/src/jspropertycache.h
js/src/jspropertycacheinlines.h
netwerk/base/public/nsIThreadRetargetableRequest.idl
netwerk/base/public/nsIThreadRetargetableStreamListener.idl
netwerk/test/mochitests/Makefile.in
netwerk/test/mochitests/moz.build
netwerk/test/mochitests/partial_content.sjs
netwerk/test/mochitests/test_partially_cached_content.html
testing/mochitest/harness-overlay.xul
testing/mozbase/mozinfo/README.md
testing/mozbase/mozinstall/README.md
toolkit/components/search/tests/xpcshell/test_engineselect.js
--- a/CLOBBER
+++ b/CLOBBER
@@ -12,10 +12,9 @@
 #          O               O
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
-Bug 879831 needed to clobber for the removal of jsprobes.cpp
-bug 882904:  move LIBS to moz.build (logic).
+Bug 704356 needed to clobber for the removal of jspropertycache.cpp
--- a/accessible/src/jsat/TraversalRules.jsm
+++ b/accessible/src/jsat/TraversalRules.jsm
@@ -9,16 +9,18 @@ const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
 
 this.EXPORTED_SYMBOLS = ['TraversalRules'];
 
 Cu.import('resource://gre/modules/accessibility/Utils.jsm');
 Cu.import('resource://gre/modules/XPCOMUtils.jsm');
 
+let gSkipEmptyImages = new PrefCache('accessibility.accessfu.skip_empty_images');
+
 function BaseTraversalRule(aRoles, aMatchFunc) {
   this._matchRoles = aRoles;
   this._matchFunc = aMatchFunc;
 }
 
 BaseTraversalRule.prototype = {
     getMatchRoles: function BaseTraversalRule_getmatchRoles(aRules) {
       aRules.value = this._matchRoles;
@@ -98,16 +100,18 @@ this.TraversalRules = {
           let parent = aAccessible.parent;
           // Ignore prefix static text in list items. They are typically bullets or numbers.
           if (parent.childCount > 1 && aAccessible.indexInParent == 0 &&
               parent.role == Ci.nsIAccessibleRole.ROLE_LISTITEM)
             return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
 
           return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
         }
+      case Ci.nsIAccessibleRole.ROLE_GRAPHIC:
+        return TraversalRules._shouldSkipImage(aAccessible);
       default:
         // Ignore the subtree, if there is one. So that we don't land on
         // the same content that was already presented by its parent.
         return Ci.nsIAccessibleTraversalRule.FILTER_MATCH |
           Ci.nsIAccessibleTraversalRule.FILTER_IGNORE_SUBTREE;
       }
     }
   ),
@@ -163,17 +167,20 @@ this.TraversalRules = {
      Ci.nsIAccessibleRole.ROLE_PAGETAB,
      Ci.nsIAccessibleRole.ROLE_RADIOBUTTON,
      Ci.nsIAccessibleRole.ROLE_RADIO_MENU_ITEM,
      Ci.nsIAccessibleRole.ROLE_SLIDER,
      Ci.nsIAccessibleRole.ROLE_CHECKBUTTON,
      Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM]),
 
   Graphic: new BaseTraversalRule(
-    [Ci.nsIAccessibleRole.ROLE_GRAPHIC]),
+    [Ci.nsIAccessibleRole.ROLE_GRAPHIC],
+    function Graphic_match(aAccessible) {
+      return TraversalRules._shouldSkipImage(aAccessible);
+    }),
 
   Heading: new BaseTraversalRule(
     [Ci.nsIAccessibleRole.ROLE_HEADING]),
 
   ListItem: new BaseTraversalRule(
     [Ci.nsIAccessibleRole.ROLE_LISTITEM,
      Ci.nsIAccessibleRole.ROLE_TERM]),
 
@@ -206,10 +213,17 @@ this.TraversalRules = {
   Separator: new BaseTraversalRule(
     [Ci.nsIAccessibleRole.ROLE_SEPARATOR]),
 
   Table: new BaseTraversalRule(
     [Ci.nsIAccessibleRole.ROLE_TABLE]),
 
   Checkbox: new BaseTraversalRule(
     [Ci.nsIAccessibleRole.ROLE_CHECKBUTTON,
-     Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM])
+     Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM]),
+
+  _shouldSkipImage: function _shouldSkipImage(aAccessible) {
+    if (gSkipEmptyImages.value && aAccessible.name === '') {
+      return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
+    }
+    return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
+  }
 };
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -639,16 +639,18 @@ pref("dom.ipc.processPrelaunch.delayMs",
 // whichever comes first.
 pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
 
 // Ignore the "dialog=1" feature in window.open.
 pref("dom.disable_window_open_dialog_feature", true);
 
 // Screen reader support
 pref("accessibility.accessfu.activate", 2);
+// Whether to skip images with empty alt text
+pref("accessibility.accessfu.skip_empty_images", true);
 
 // Enable hit-target fluffing
 pref("ui.touch.radius.enabled", false);
 pref("ui.touch.radius.leftmm", 3);
 pref("ui.touch.radius.topmm", 5);
 pref("ui.touch.radius.rightmm", 3);
 pref("ui.touch.radius.bottommm", 2);
 
--- a/browser/base/content/test/browser_locationBarCommand.js
+++ b/browser/base/content/test/browser_locationBarCommand.js
@@ -29,26 +29,26 @@ saveURL = function() {
 function runAltLeftClickTest() {
   info("Running test: Alt left click");
   triggerCommand(true, { altKey: true });
 }
 
 function runShiftLeftClickTest() {
   let listener = new WindowListener(getBrowserURL(), function(aWindow) {
     Services.wm.removeListener(listener);
-    addPageShowListener(aWindow.gBrowser, function() {
+    addPageShowListener(aWindow.gBrowser.selectedBrowser, function() {
       info("URL should be loaded in a new window");
       is(gURLBar.value, "", "Urlbar reverted to original value");       
       is(gFocusManager.focusedElement, null, "There should be no focused element");
       is(gFocusManager.focusedWindow, aWindow.gBrowser.contentWindow, "Content window should be focused");
       is(aWindow.gURLBar.value, TEST_VALUE, "New URL is loaded in new window");
 
       aWindow.close();
       runNextTest();
-    });
+    }, "http://example.com/");
   });
   Services.wm.addListener(listener);
 
   info("Running test: Shift left click");
   triggerCommand(true, { shiftKey: true });
 }
 
 function runNextTest() {
@@ -56,17 +56,17 @@ function runNextTest() {
   if (!test) {
     finish();
     return;
   }
   
   info("Running test: " + test.desc);
   // Tab will be blank if test.startValue is null
   let tab = gBrowser.selectedTab = gBrowser.addTab(test.startValue);
-  addPageShowListener(gBrowser, function() {
+  addPageShowListener(gBrowser.selectedBrowser, function() {
     triggerCommand(test.click, test.event);
     test.check(tab);
 
     // Clean up
     while (gBrowser.tabs.length > 1)
       gBrowser.removeTab(gBrowser.selectedTab)
     runNextTest();
   });
@@ -158,20 +158,23 @@ function checkCurrent(aTab) {
 function checkNewTab(aTab) {
   info("URL should be loaded in a new focused tab");
   is(gURLBar.value, TEST_VALUE, "Urlbar still has the value we entered");
   is(gFocusManager.focusedElement, null, "There should be no focused element");
   is(gFocusManager.focusedWindow, gBrowser.contentWindow, "Content window should be focused");
   isnot(gBrowser.selectedTab, aTab, "New URL was loaded in a new tab");
 }
 
-function addPageShowListener(aBrowser, aFunc) {
-  aBrowser.selectedBrowser.addEventListener("pageshow", function loadListener() {
-    aBrowser.selectedBrowser.removeEventListener("pageshow", loadListener, false);
-    aFunc();
+function addPageShowListener(browser, cb, expectedURL) {
+  browser.addEventListener("pageshow", function pageShowListener() {
+    info("pageshow: " + browser.currentURI.spec);
+    if (expectedURL && browser.currentURI.spec != expectedURL)
+      return; // ignore pageshows for non-expected URLs
+    browser.removeEventListener("pageshow", pageShowListener, false);
+    cb();
   });
 }
 
 function WindowListener(aURL, aCallback) {
   this.callback = aCallback;
   this.url = aURL;
 }
 WindowListener.prototype = {
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -312,16 +312,33 @@ BrowserGlue.prototype = {
             reporter.getProvider("org.mozilla.searches").recordSearch(name,
                                                                       "urlbar");
           } catch (ex) {
             Cu.reportError(ex);
           }
         });
         break;
 #endif
+      case "browser-search-engine-modified":
+        if (data != "engine-default" && data != "engine-current") {
+          break;
+        }
+        // Enforce that the search service's defaultEngine is always equal to
+        // its currentEngine. The search service will notify us any time either
+        // of them are changed (either by directly setting the relevant prefs,
+        // i.e. if add-ons try to change this directly, or if the
+        // nsIBrowserSearchService setters are called).
+        let ss = Services.search;
+        if (ss.currentEngine.name == ss.defaultEngine.name)
+          return;
+        if (data == "engine-current")
+          ss.defaultEngine = ss.currentEngine;
+        else
+          ss.currentEngine = ss.defaultEngine;
+        break;
     }
   },
 
   // initialization (called on application startup) 
   _init: function BG__init() {
     let os = Services.obs;
     os.addObserver(this, "prefservice:after-app-defaults", false);
     os.addObserver(this, "final-ui-startup", false);
@@ -346,16 +363,17 @@ BrowserGlue.prototype = {
     os.addObserver(this, "distribution-customization-complete", false);
     os.addObserver(this, "places-shutdown", false);
     this._isPlacesShutdownObserver = true;
     os.addObserver(this, "handle-xul-text-link", false);
     os.addObserver(this, "profile-before-change", false);
 #ifdef MOZ_SERVICES_HEALTHREPORT
     os.addObserver(this, "keyword-search", false);
 #endif
+    os.addObserver(this, "browser-search-engine-modified", false);
   },
 
   // cleanup (called on application shutdown)
   _dispose: function BG__dispose() {
     let os = Services.obs;
     os.removeObserver(this, "prefservice:after-app-defaults");
     os.removeObserver(this, "final-ui-startup");
     os.removeObserver(this, "sessionstore-windows-restored");
@@ -379,16 +397,17 @@ BrowserGlue.prototype = {
       os.removeObserver(this, "places-database-locked");
     if (this._isPlacesShutdownObserver)
       os.removeObserver(this, "places-shutdown");
     os.removeObserver(this, "handle-xul-text-link");
     os.removeObserver(this, "profile-before-change");
 #ifdef MOZ_SERVICES_HEALTHREPORT
     os.removeObserver(this, "keyword-search");
 #endif
+    os.removeObserver(this, "browser-search-engine-modified");
   },
 
   _onAppDefaults: function BG__onAppDefaults() {
     // apply distribution customizations (prefs)
     // other customizations are applied in _finalUIStartup()
     this._distributionCustomizer.applyPrefDefaults();
   },
 
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -489,33 +489,26 @@ let SessionStoreInternal = {
 
     XPCOMUtils.defineLazyGetter(this, "_max_windows_undo", function () {
       this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
       return this._prefBranch.getIntPref("sessionstore.max_windows_undo");
     });
   },
 
   _initWindow: function ssi_initWindow(aWindow) {
-    if (!aWindow || this._loadState == STATE_RUNNING) {
-      // make sure that all browser windows which try to initialize
-      // SessionStore are really tracked by it
-      if (aWindow && (!aWindow.__SSi || !this._windows[aWindow.__SSi]))
-        this.onLoad(aWindow);
+    if (aWindow) {
+      this.onLoad(aWindow);
+    } else if (this._loadState == STATE_STOPPED) {
       // If init is being called with a null window, it's possible that we
       // just want to tell sessionstore that a session is live (as is the case
       // with starting Firefox with -private, for example; see bug 568816),
       // so we should mark the load state as running to make sure that
       // things like setBrowserState calls will succeed in restoring the session.
-      if (!aWindow && this._loadState == STATE_STOPPED)
-        this._loadState = STATE_RUNNING;
-      return;
+      this._loadState = STATE_RUNNING;
     }
-
-    // As this is called at delayedStartup, restoration must be initiated here
-    this.onLoad(aWindow);
   },
 
   /**
    * Start tracking a window.
    *
    * This function also initializes the component if it is not
    * initialized yet.
    */
--- a/browser/config/mozconfigs/linux32/debug
+++ b/browser/config/mozconfigs/linux32/debug
@@ -1,12 +1,11 @@
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-signmar
-ENABLE_MARIONETTE=1
 
 . $topsrcdir/build/unix/mozconfig.linux32
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
--- a/browser/config/mozconfigs/linux64/debug
+++ b/browser/config/mozconfigs/linux64/debug
@@ -1,12 +1,11 @@
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-signmar
-ENABLE_MARIONETTE=1
 
 . $topsrcdir/build/unix/mozconfig.linux
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
--- a/browser/config/mozconfigs/macosx64/debug
+++ b/browser/config/mozconfigs/macosx64/debug
@@ -1,15 +1,14 @@
 . $topsrcdir/build/macosx/mozconfig.common
 
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-accessibility
 ac_add_options --enable-signmar
-ENABLE_MARIONETTE=1
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 ac_add_options --with-macbundlename-prefix=Firefox
 
 # Treat warnings as errors in directories with FAIL_ON_WARNINGS.
 ac_add_options --enable-warnings-as-errors
--- a/browser/config/mozconfigs/win32/debug
+++ b/browser/config/mozconfigs/win32/debug
@@ -1,17 +1,15 @@
 . "$topsrcdir/browser/config/mozconfigs/common"
 
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-signmar
 ac_add_options --enable-metro
 
-ENABLE_MARIONETTE=1
-
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 if test -z "${_PYMAKE}"; then
   mk_add_options MOZ_MAKE_FLAGS=-j1
 fi
 
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
--- a/browser/config/mozconfigs/win64/debug
+++ b/browser/config/mozconfigs/win64/debug
@@ -2,17 +2,16 @@
 
 ac_add_options --target=x86_64-pc-mingw32
 ac_add_options --host=x86_64-pc-mingw32
 
 ac_add_options --enable-debug
 ac_add_options --enable-trace-malloc
 ac_add_options --enable-signmar
 ac_add_options --enable-metro
-ENABLE_MARIONETTE=1
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 if test -z "${_PYMAKE}"; then
   mk_add_options MOZ_MAKE_FLAGS=-j1
 fi
 
--- a/browser/devtools/webconsole/test/Makefile.in
+++ b/browser/devtools/webconsole/test/Makefile.in
@@ -44,16 +44,17 @@ MOCHITEST_BROWSER_FILES = \
 	browser_webconsole_output_order.js \
 	browser_webconsole_property_provider.js \
 	browser_webconsole_bug_587617_output_copy.js \
 	browser_webconsole_bug_585237_line_limit.js \
 	browser_webconsole_bug_582201_duplicate_errors.js \
 	browser_webconsole_bug_580454_timestamp_l10n.js \
 	browser_webconsole_netlogging.js \
 	browser_webconsole_bug_583816_No_input_and_Tab_key_pressed.js \
+	browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js \
 	browser_webconsole_bug_594477_clickable_output.js \
 	browser_webconsole_bug_589162_css_filter.js \
 	browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js \
 	browser_webconsole_bug_595350_multiple_windows_and_tabs.js \
 	browser_webconsole_bug_594497_history_arrow_keys.js \
 	browser_webconsole_bug_588342_document_focus.js \
 	browser_webconsole_bug_595934_message_categories.js \
 	browser_webconsole_bug_601352_scroll.js \
new file mode 100644
--- /dev/null
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js
@@ -0,0 +1,39 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* 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/. */
+
+const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/browser/test-console.html";
+
+function test() {
+  addTab(TEST_URI);
+  browser.addEventListener("load", function onLoad() {
+    browser.removeEventListener("load", onLoad, true);
+    openConsole(null, testInputChange);
+  }, true);
+}
+
+function testInputChange(hud) {
+  var jsterm = hud.jsterm;
+  var input = jsterm.inputNode;
+
+  is(input.getAttribute("focused"), "true", "input has focus");
+  EventUtils.synthesizeKey("VK_TAB", {});
+  is(input.getAttribute("focused"), "", "focus moved away");
+
+  // Test user changed something
+  input.focus();
+  EventUtils.synthesizeKey("A", {});
+  EventUtils.synthesizeKey("VK_TAB", {});
+  is(input.getAttribute("focused"), "true", "input is still focused");
+
+  // Test non empty input but not changed since last focus
+  input.blur();
+  input.focus();
+  EventUtils.synthesizeKey("VK_RIGHT", {});
+  EventUtils.synthesizeKey("VK_TAB", {});
+  is(input.getAttribute("focused"), "", "input moved away");
+
+  jsterm = input = null;
+  finishTest();
+}
--- a/browser/devtools/webconsole/webconsole.js
+++ b/browser/devtools/webconsole/webconsole.js
@@ -2792,18 +2792,19 @@ function JSTerm(aWebConsoleFrame)
   // this.execute().
   this.historyIndex = 0; // incremented on this.execute()
 
   // Holds the index of the history entry that the user is currently viewing.
   // This is reset to this.history.length when this.execute() is invoked.
   this.historyPlaceHolder = 0;
   this._objectActorsInVariablesViews = new Map();
 
-  this._keyPress = this.keyPress.bind(this);
-  this._inputEventHandler = this.inputEventHandler.bind(this);
+  this._keyPress = this._keyPress.bind(this);
+  this._inputEventHandler = this._inputEventHandler.bind(this);
+  this._focusEventHandler = this._focusEventHandler.bind(this);
   this._onKeypressInVariablesView = this._onKeypressInVariablesView.bind(this);
 
   EventEmitter.decorate(this);
 }
 
 JSTerm.prototype = {
   SELECTED_FRAME: -1,
 
@@ -2848,21 +2849,28 @@ JSTerm.prototype = {
 
   /**
    * Last input value.
    * @type string
    */
   lastInputValue: "",
 
   /**
+   * Indicate input node changed since last focus.
+   *
+   * @private
+   * @type boolean
+   */
+  _inputChanged: false,
+
+  /**
    * History of code that was executed.
    * @type array
    */
   history: null,
-
   autocompletePopup: null,
   inputNode: null,
   completeNode: null,
 
   /**
    * Getter for the element that holds the messages we display.
    * @type nsIDOMElement
    */
@@ -2898,16 +2906,17 @@ JSTerm.prototype = {
                                                    autocompleteOptions);
 
     let doc = this.hud.document;
     this.completeNode = doc.querySelector(".jsterm-complete-node");
     this.inputNode = doc.querySelector(".jsterm-input-node");
     this.inputNode.addEventListener("keypress", this._keyPress, false);
     this.inputNode.addEventListener("input", this._inputEventHandler, false);
     this.inputNode.addEventListener("keyup", this._inputEventHandler, false);
+    this.inputNode.addEventListener("focus", this._focusEventHandler, false);
 
     this.lastInputValue && this.setInputValue(this.lastInputValue);
   },
 
   /**
    * The JavaScript evaluation response handler.
    *
    * @private
@@ -3655,38 +3664,40 @@ JSTerm.prototype = {
    * @returns void
    */
   setInputValue: function JST_setInputValue(aNewValue)
   {
     this.inputNode.value = aNewValue;
     this.lastInputValue = aNewValue;
     this.completeNode.value = "";
     this.resizeInput();
+    this._inputChanged = true;
   },
 
   /**
    * The inputNode "input" and "keyup" event handler.
-   *
-   * @param nsIDOMEvent aEvent
+   * @private
    */
-  inputEventHandler: function JSTF_inputEventHandler(aEvent)
+  _inputEventHandler: function JST__inputEventHandler()
   {
     if (this.lastInputValue != this.inputNode.value) {
       this.resizeInput();
       this.complete(this.COMPLETE_HINT_ONLY);
       this.lastInputValue = this.inputNode.value;
+      this._inputChanged = true;
     }
   },
 
   /**
    * The inputNode "keypress" event handler.
    *
+   * @private
    * @param nsIDOMEvent aEvent
    */
-  keyPress: function JSTF_keyPress(aEvent)
+  _keyPress: function JST__keyPress(aEvent)
   {
     if (aEvent.ctrlKey) {
       let inputNode = this.inputNode;
       let closePopup = false;
       switch (aEvent.charCode) {
         case 97:
           // control-a
           if (Services.appinfo.OS == "WINNT") {
@@ -3811,28 +3822,36 @@ JSTerm.prototype = {
 
       case Ci.nsIDOMKeyEvent.DOM_VK_TAB:
         // Generate a completion and accept the first proposed value.
         if (this.complete(this.COMPLETE_HINT_ONLY) &&
             this.lastCompletion &&
             this.acceptProposedCompletion()) {
           aEvent.preventDefault();
         }
-        else {
+        else if (this._inputChanged) {
           this.updateCompleteNode(l10n.getStr("Autocomplete.blank"));
           aEvent.preventDefault();
         }
         break;
-
       default:
         break;
     }
   },
 
   /**
+   * The inputNode "focus" event handler.
+   * @private
+   */
+  _focusEventHandler: function JST__focusEventHandler()
+  {
+    this._inputChanged = false;
+  },
+
+  /**
    * Go up/down the history stack of input values.
    *
    * @param number aDirection
    *        History navigation direction: HISTORY_BACK or HISTORY_FORWARD.
    *
    * @returns boolean
    *          True if the input value changed, false otherwise.
    */
@@ -4218,16 +4237,17 @@ JSTerm.prototype = {
                 .getElementById("webConsole_autocompletePopup");
     if (popup) {
       popup.parentNode.removeChild(popup);
     }
 
     this.inputNode.removeEventListener("keypress", this._keyPress, false);
     this.inputNode.removeEventListener("input", this._inputEventHandler, false);
     this.inputNode.removeEventListener("keyup", this._inputEventHandler, false);
+    this.inputNode.removeEventListener("focus", this._focusEventHandler, false);
 
     this.hud = null;
   },
 };
 
 /**
  * Utils: a collection of globally used functions.
  */
--- a/browser/metro/base/tests/mochitest/Makefile.in
+++ b/browser/metro/base/tests/mochitest/Makefile.in
@@ -29,21 +29,16 @@ BROWSER_TESTS = \
   browser_test.js \
   browser_tiles.js \
   browser_tilegrid.xul \
   browser_topsites.js \
   browser_form_auto_complete.js \
   browser_form_auto_complete.html \
   $(NULL)
 
-# disabled due to timeouts and lack of plugin support.
-#  browser_plugin_input.html \
-#  browser_plugin_input_mouse.js \
-#  browser_plugin_input_keyboard.js \
-
 ifndef MOZ_DEBUG
 BROWSER_TESTS += \
   browser_selection_basic.js \
   browser_selection_basic.html \
   browser_selection_textarea.js \
   browser_selection_textarea.html \
   browser_selection_frame_content.js \
   browser_selection_frame_content.html \
deleted file mode 100644
--- a/browser/metro/base/tests/mochitest/browser_plugin_input.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-<head>
-  <title>Test Plugin Input</title>
-</head>
-<body>
-  <embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
-</body>
-</html>
deleted file mode 100644
--- a/browser/metro/base/tests/mochitest/browser_plugin_input_keyboard.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
-  runTests();
-}
-
-gTests.push({
-  desc: "Plugin keyboard input",
-  run: function() {
-    Services.prefs.setBoolPref("plugin.disable", false);
-    Services.prefs.setBoolPref("plugins.click_to_play", false);
-    registerCleanupFunction(Services.prefs.clearUserPref.bind(null, "plugin.disable"));
-    registerCleanupFunction(Services.prefs.clearUserPref.bind(null, "plugins.click_to_play"));
-
-    let tab = yield addTab(chromeRoot + "browser_plugin_input.html");
-
-    yield hideContextUI();
-
-    let doc = tab.browser.contentDocument;
-    let plugin = doc.getElementById("plugin1");
-    let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-    ok(objLoadingContent.activated, "Plugin activated");
-    plugin.focus();
-
-    try {
-      is(plugin.getLastKeyText(), "", "Plugin should not have received "
-                                    + "any character events yet.");
-    } catch(e) {
-      ok(false, "plugin.getLastKeyText should not throw: " + e);
-    }
-
-    let keys = [{ kbLayout: arSpanish,
-                  keyCode: 65,
-                  modifiers: 0,
-                  expectedChar: 'a' }];
-
-    /* XXX: Re-enable this once bug 837293 is fixed
-                { kbLayout: arSpanish,
-                  keyCode: 65,
-                  modifiers: rightAlt,
-                  expectedChar: "á" }];
-    */
-
-    while (keys.length > 0) {
-      let key = keys.shift();
-      info("Sending keypress: " + key.expectedChar);
-      synthesizeNativeKey(key.kbLayout, key.keyCode, key.modifiers);
-      let success = yield waitForCondition(function() plugin.getLastKeyText() == key.expectedChar);
-      ok(success && !(success instanceof Error),
-         "Plugin received char: " + key.expectedChar);
-    }
-  }
-});
deleted file mode 100644
--- a/browser/metro/base/tests/mochitest/browser_plugin_input_mouse.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-function test() {
-  runTests();
-}
-
-gTests.push({
-  desc: "Plugin mouse input",
-  run: function() {
-    // This test needs "Switch primary and secondary buttons" disabled.
-    let origValue = MetroUtils.swapMouseButton(false);
-    registerCleanupFunction(function() MetroUtils.swapMouseButton(origValue));
-
-    Services.prefs.setBoolPref("plugin.disable", false);
-    Services.prefs.setBoolPref("plugins.click_to_play", false);
-    registerCleanupFunction(Services.prefs.clearUserPref.bind(null, "plugin.disable"));
-    registerCleanupFunction(Services.prefs.clearUserPref.bind(null, "plugins.click_to_play"));
-
-    let tab = yield addTab(chromeRoot + "browser_plugin_input.html");
-
-    yield hideContextUI();
-
-    let doc = tab.browser.contentDocument;
-    let plugin = doc.getElementById("plugin1");
-    let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
-    ok(objLoadingContent.activated, "Plugin activated");
-
-    // XXX: This shouldn't be necessary, but removing it causes the first click to
-    //      sometimes not register
-    let wait = yield waitForMs(0);
-    ok(wait, "Initial wait");
-
-    try {
-      is(plugin.getMouseUpEventCount(), 0, "Plugin should not have received "
-                                         + "any mouse up events yet.");
-    } catch(e) {
-      ok(false, "plugin.getMouseUpEventCount should not throw: " + e);
-    }
-
-    let bottom = plugin.getBoundingClientRect().height - 1;
-    let right = plugin.getBoundingClientRect().width - 1;
-    let middleX = right / 2;
-    let middleY = bottom / 2;
-    let left = 1;
-    let top = 1;
-
-    let clicks = [{ x: left, y: top},          // left top corner
-                  { x: left, y: middleY},      // left middle
-                  { x: left, y: bottom},       // left bottom corner
-                  { x: middleX, y: bottom},    // bottom middle
-                  { x: right, y: bottom},      // right bottom corner
-                  { x: right, y: middleY},     // right middle
-                  { x: right, y: top},         // right top corner
-                  { x: middleX, y: top},       // top middle
-                  { x: middleX, y: middleY}];  // middle
-
-    let curClicks = 0;
-    while (clicks.length > 0) {
-      let click = clicks.shift();
-      curClicks++;
-      info("Sending click " + curClicks + " { x: " + click.x + ", y: " + click.y + "}");
-      synthesizeNativeMouseLDown(plugin, click.x, click.y);
-      synthesizeNativeMouseLUp(plugin, click.x, click.y);
-      let success = yield waitForCondition(function() plugin.getMouseUpEventCount() == curClicks);
-      ok(success && !(success instanceof Error),
-         "Plugin received click " + curClicks);
-    }
-  }
-});
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -25,27 +25,22 @@ sys.path.insert(0, SCRIPT_DIR)
 import automationutils
 
 # --------------------------------------------------------------
 # TODO: this is a hack for mozbase without virtualenv, remove with bug 849900
 #
 here = os.path.dirname(__file__)
 mozbase = os.path.realpath(os.path.join(os.path.dirname(here), 'mozbase'))
 
-try:
-    import mozcrash
-except:
-    deps = ['mozcrash',
-            'mozfile',
-            'mozlog']
-    for dep in deps:
-        module = os.path.join(mozbase, dep)
-        if module not in sys.path:
-            sys.path.append(module)
-    import mozcrash
+if os.path.isdir(mozbase):
+    for package in os.listdir(mozbase):
+        sys.path.append(os.path.join(mozbase, package))
+
+import mozcrash
+
 # ---------------------------------------------------------------
 
 _DEFAULT_PREFERENCE_FILE = os.path.join(SCRIPT_DIR, 'prefs_general.js')
 
 _DEFAULT_WEB_SERVER = "127.0.0.1"
 _DEFAULT_HTTP_PORT = 8888
 _DEFAULT_SSL_PORT = 4443
 _DEFAULT_WEBSOCKET_PORT = 9988
--- a/content/base/src/nsDOMTokenList.cpp
+++ b/content/base/src/nsDOMTokenList.cpp
@@ -226,32 +226,44 @@ nsDOMTokenList::Remove(const nsAString& 
   if (!attr || !attr->Contains(aToken)) {
     return;
   }
 
   RemoveInternal(attr, aToken);
 }
 
 bool
-nsDOMTokenList::Toggle(const nsAString& aToken, ErrorResult& aError)
+nsDOMTokenList::Toggle(const nsAString& aToken,
+                       const Optional<bool>& aForce,
+                       ErrorResult& aError)
 {
   aError = CheckToken(aToken);
   if (aError.Failed()) {
     return false;
   }
 
   const nsAttrValue* attr = GetParsedAttr();
+  const bool forceOn = aForce.WasPassed() && aForce.Value();
+  const bool forceOff = aForce.WasPassed() && !aForce.Value();
 
-  if (attr && attr->Contains(aToken)) {
-    RemoveInternal(attr, aToken);
-    return false;
+  bool isPresent = attr && attr->Contains(aToken);
+
+  if (isPresent) {
+    if (!forceOn) {
+      RemoveInternal(attr, aToken);
+      isPresent = false;
+    }
+  } else {
+    if (!forceOff) {
+      AddInternal(attr, aToken);
+      isPresent = true;
+    }
   }
 
-  AddInternal(attr, aToken);
-  return true;
+  return isPresent;
 }
 
 void
 nsDOMTokenList::Stringify(nsAString& aResult)
 {
   if (!mElement) {
     aResult.Truncate();
     return;
--- a/content/base/src/nsDOMTokenList.h
+++ b/content/base/src/nsDOMTokenList.h
@@ -8,16 +8,17 @@
 
 #ifndef nsDOMTokenList_h___
 #define nsDOMTokenList_h___
 
 #include "nsCOMPtr.h"
 #include "nsDOMString.h"
 #include "nsWrapperCache.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/BindingDeclarations.h"
 
 namespace mozilla {
 class ErrorResult;
 
 } // namespace mozilla
 
 class nsAttrValue;
 class nsIAtom;
@@ -54,17 +55,19 @@ public:
     if (!found) {
       SetDOMStringToNull(aResult);
     }
   }
   void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aResult);
   bool Contains(const nsAString& aToken, mozilla::ErrorResult& aError);
   void Add(const nsAString& aToken, mozilla::ErrorResult& aError);
   void Remove(const nsAString& aToken, mozilla::ErrorResult& aError);
-  bool Toggle(const nsAString& aToken, mozilla::ErrorResult& aError);
+  bool Toggle(const nsAString& aToken,
+              const mozilla::dom::Optional<bool>& force,
+              mozilla::ErrorResult& aError);
   void Stringify(nsAString& aResult);
 
 protected:
   virtual ~nsDOMTokenList();
 
   nsresult CheckToken(const nsAString& aStr);
   void AddInternal(const nsAttrValue* aAttr, const nsAString& aToken);
   void RemoveInternal(const nsAttrValue* aAttr, const nsAString& aToken);
--- a/content/base/test/test_classList.html
+++ b/content/base/test/test_classList.html
@@ -30,35 +30,36 @@ function onAttrModified(event) {
 
   gMutationEvents.push({
     attrChange: event.attrChange,
     prevValue: event.prevValue,
     newValue: event.newValue,
   });
 }
 
-function checkModification(e, funcName, argument, expectedRes, before, after, expectedException) {
+function checkModification(e, funcName, args, expectedRes, before, after, expectedException) {
   var shouldThrow = typeof(expectedException) === "string";
   if (shouldThrow) {
     // If an exception is thrown, the class attribute shouldn't change.
     after = before;
   }
   if (before === null)
     e.removeAttribute("class");
   else
     e.setAttribute("class", before);
 
-  var contextMsg = "(checkModification: funcName=" + funcName + ",argument=" +
-                   argument + ",expectedRes=" + expectedRes + ",before=" +
-                   before + ",after=" + after + ")";
+  var contextMsg = "(checkModification: funcName=" + funcName + ",args=" +
+                   JSON.stringify(args) + ",expectedRes=" + expectedRes +
+                   ",before=" + before + ",after=" + after + ")";
 
   gMutationEvents = [];
   e.addEventListener("DOMAttrModified", onAttrModified, false);
   try {
-    var res = e.classList[funcName](argument);
+    var list = e.classList;
+    var res = list[funcName].apply(list, args);
     if (shouldThrow)
       ok(false, "classList modification didn't throw " + contextMsg);
   } catch (e) {
     if (!shouldThrow)
       ok(false, "classList modification threw an exception " + contextMsg);
     is(e.name, expectedException, "wrong exception thrown " + contextMsg);
   }
   e.removeEventListener("DOMAttrModified", onAttrModified, false);
@@ -253,17 +254,17 @@ function testClassList(e) {
   // Test for bug 530171
   e.setAttribute("class", "null undefined");
   is(e.classList.contains(null), true, "wrong classList.contains() result");
   is(e.classList.contains(undefined), true, "wrong classList.contains() result");
 
   // add() method
 
   function checkAdd(before, argument, after, expectedException) {
-    checkModification(e, "add", argument, null, before, after, expectedException);
+    checkModification(e, "add", [argument], null, before, after, expectedException);
   }
 
   checkAdd(null, "", null, "SyntaxError");
   checkAdd(null, " ", null, "InvalidCharacterError");
   checkAdd(null, "aa ", null, "InvalidCharacterError");
 
   checkAdd("a", "a", "a");
   checkAdd("aa", "AA", "aa AA");
@@ -279,17 +280,17 @@ function testClassList(e) {
 
   // Test for bug 530171
   checkAdd(null, null, "null");
   checkAdd(null, undefined, "undefined");
 
   // remove() method
 
   function checkRemove(before, argument, after, expectedException) {
-    checkModification(e, "remove", argument, null, before, after, expectedException);
+    checkModification(e, "remove", [argument], null, before, after, expectedException);
   }
 
   checkRemove(null, "", null, "SyntaxError");
   checkRemove(null, " ", null, "InvalidCharacterError");
   checkRemove(null, "aa ", null, "InvalidCharacterError");
 
   checkRemove(null, "a", null);
   checkRemove("", "a", "");
@@ -318,17 +319,17 @@ function testClassList(e) {
 
   // Test for bug 530171
   checkRemove("null", null, "");
   checkRemove("undefined", undefined, "");
 
   // toggle() method
 
   function checkToggle(before, argument, expectedRes, after, expectedException) {
-    checkModification(e, "toggle", argument, expectedRes, before, after, expectedException);
+    checkModification(e, "toggle", [argument], expectedRes, before, after, expectedException);
   }
 
   checkToggle(null, "", null, null, "SyntaxError");
   checkToggle(null, "aa ", null, null, "InvalidCharacterError");
 
   checkToggle(null, "a", true, "a");
   checkToggle("", "a", true, "a");
   checkToggle(" ", "a", true, " a");
@@ -346,17 +347,34 @@ function testClassList(e) {
   checkToggle(" a b  c  ", "c", false, " a b");
   checkToggle(" a b c ", "a", false, "b c ");
 
   // Test for bug 530171
   checkToggle("null", null, false, "");
   checkToggle("", null, true, "null");
   checkToggle("undefined", undefined, false, "");
   checkToggle("", undefined, true, "undefined");
+
+
+  // tests for the force argument handling
+  
+  function checkForceToggle(before, argument, force, expectedRes, after, expectedException) {
+    checkModification(e, "toggle", [argument, force], expectedRes, before, after, expectedException);
+  }
+
+  checkForceToggle("", "a", true, true, "a");
+  checkForceToggle("a", "a", true, true, "a");
+  checkForceToggle("a", "b", true, true, "a b");
+  checkForceToggle("a b", "b", true, true, "a b");
+  checkForceToggle("", "a", false, false, "");
+  checkForceToggle("a", "a", false, false, "");
+  checkForceToggle("a", "b", false, false, "a");
+  checkForceToggle("a b", "b", false, false, "a");
 }
+
 var content = document.getElementById("content");
 
 var htmlNode = document.createElement("div");
 content.appendChild(htmlNode);
 testClassList(htmlNode);
 
 var xhtmlNode = document.createElementNS(XHTML_NS, "div");
 content.appendChild(xhtmlNode);
--- a/content/html/content/src/nsDOMStringMap.cpp
+++ b/content/html/content/src/nsDOMStringMap.cpp
@@ -5,59 +5,70 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsError.h"
 #include "nsDOMStringMap.h"
 
 #include "nsGenericHTMLElement.h"
 #include "nsContentUtils.h"
 #include "mozilla/dom/DOMStringMapBinding.h"
+#include "nsIDOMMutationEvent.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMStringMap)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMStringMap)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
   // Check that mElement exists in case the unlink code is run more than once.
   if (tmp->mElement) {
     // Call back to element to null out weak reference to this object.
     tmp->mElement->ClearDataset();
+    tmp->mElement->RemoveMutationObserver(tmp);
     tmp->mElement = nullptr;
   }
+  ++tmp->mExpandoAndGeneration.generation;
+  tmp->mExpandoAndGeneration.expando = JS::UndefinedValue();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMStringMap)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+  if (tmp->PreservingWrapper()) {
+    NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mExpandoAndGeneration.expando);
+  }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMStringMap)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+  NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMStringMap)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMStringMap)
 
 nsDOMStringMap::nsDOMStringMap(nsGenericHTMLElement* aElement)
   : mElement(aElement),
     mRemovingProp(false)
 {
   SetIsDOMBinding();
+
+  mElement->AddMutationObserver(this);
 }
 
 nsDOMStringMap::~nsDOMStringMap()
 {
   // Check if element still exists, may have been unlinked by cycle collector.
   if (mElement) {
     // Call back to element to null out weak reference to this object.
     mElement->ClearDataset();
+    mElement->RemoveMutationObserver(this);
   }
 }
 
 /* virtual */
 JSObject*
 nsDOMStringMap::WrapObject(JSContext *cx, JS::Handle<JSObject*> scope)
 {
   return DOMStringMapBinding::Wrap(cx, scope, this);
@@ -230,8 +241,22 @@ bool nsDOMStringMap::AttrToDataProp(cons
     } else {
       // Simply append character if camel case is not necessary.
       aResult.Append(*cur);
     }
   }
 
   return true;
 }
+
+void
+nsDOMStringMap::AttributeChanged(nsIDocument *aDocument, Element* aElement,
+                                 int32_t aNameSpaceID, nsIAtom* aAttribute,
+                                 int32_t aModType)
+{
+  if ((aModType == nsIDOMMutationEvent::ADDITION ||
+       aModType == nsIDOMMutationEvent::REMOVAL) &&
+      aNameSpaceID == kNameSpaceID_None &&
+      StringBeginsWith(nsDependentAtomString(aAttribute),
+                       NS_LITERAL_STRING("data-"))) {
+    ++mExpandoAndGeneration.generation;
+  }
+}
--- a/content/html/content/src/nsDOMStringMap.h
+++ b/content/html/content/src/nsDOMStringMap.h
@@ -8,28 +8,31 @@
 #define nsDOMStringMap_h
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsAutoPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsWrapperCache.h"
 #include "nsGenericHTMLElement.h"
+#include "jsfriendapi.h"
 
 namespace mozilla {
 class ErrorResult;
 }
 
-class nsDOMStringMap : public nsISupports,
+class nsDOMStringMap : public nsStubMutationObserver,
                        public nsWrapperCache
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMStringMap)
 
+  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
+
   nsINode* GetParentObject()
   {
     return mElement;
   }
 
   nsDOMStringMap(nsGenericHTMLElement* aElement);
 
   // WebIDL API
@@ -37,16 +40,18 @@ public:
                                JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
   void NamedGetter(const nsAString& aProp, bool& found,
                    mozilla::dom::DOMString& aResult) const;
   void NamedSetter(const nsAString& aProp, const nsAString& aValue,
                    mozilla::ErrorResult& rv);
   void NamedDeleter(const nsAString& aProp, bool &found);
   void GetSupportedNames(nsTArray<nsString>& aNames);
 
+  js::ExpandoAndGeneration mExpandoAndGeneration;
+
 private:
   virtual ~nsDOMStringMap();
 
 protected:
   nsRefPtr<nsGenericHTMLElement> mElement;
   // Flag to guard against infinite recursion.
   bool mRemovingProp;
   static bool DataPropToAttr(const nsAString& aProp, nsAutoString& aResult);
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -302,40 +302,61 @@ MOCHITEST_FILES = \
 		file_iframe_sandbox_c_if7.html \
 		file_iframe_sandbox_c_if8.html \
 		file_iframe_sandbox_form_fail.html \
 		file_iframe_sandbox_form_pass.html \
 		file_iframe_sandbox_open_window_fail.html \
 		file_iframe_sandbox_pass.js \
 		file_iframe_sandbox_fail.js \
 		test_iframe_sandbox_navigation.html \
+		test_iframe_sandbox_navigation2.html \
 		file_iframe_sandbox_d_if1.html \
 		file_iframe_sandbox_d_if2.html \
 		file_iframe_sandbox_d_if3.html \
 		file_iframe_sandbox_d_if4.html \
 		file_iframe_sandbox_d_if5.html \
 		file_iframe_sandbox_d_if6.html \
 		file_iframe_sandbox_d_if7.html \
 		file_iframe_sandbox_d_if8.html \
 		file_iframe_sandbox_d_if9.html \
 		file_iframe_sandbox_d_if10.html \
 		file_iframe_sandbox_d_if11.html \
 		file_iframe_sandbox_d_if12.html \
 		file_iframe_sandbox_d_if13.html \
+		file_iframe_sandbox_d_if14.html \
+		file_iframe_sandbox_d_if15.html \
+		file_iframe_sandbox_d_if16.html \
+		file_iframe_sandbox_d_if17.html \
+		file_iframe_sandbox_d_if18.html \
+		file_iframe_sandbox_d_if19.html \
+		file_iframe_sandbox_d_if20.html \
+		file_iframe_sandbox_d_if21.html \
+		file_iframe_sandbox_d_if22.html \
 		file_iframe_sandbox_navigation_start.html \
 		file_iframe_sandbox_navigation_pass.html \
 		file_iframe_sandbox_navigation_fail.html \
 		file_iframe_sandbox_e_if1.html \
 		file_iframe_sandbox_e_if2.html \
 		file_iframe_sandbox_e_if3.html \
 		file_iframe_sandbox_e_if4.html \
 		file_iframe_sandbox_e_if5.html \
 		file_iframe_sandbox_e_if6.html \
+		file_iframe_sandbox_e_if7.html \
+		file_iframe_sandbox_e_if8.html \
+		file_iframe_sandbox_e_if9.html \
+		file_iframe_sandbox_e_if10.html \
+		file_iframe_sandbox_e_if11.html \
+		file_iframe_sandbox_e_if12.html \
+		file_iframe_sandbox_e_if13.html \
+		file_iframe_sandbox_e_if14.html \
+		file_iframe_sandbox_e_if15.html \
+		file_iframe_sandbox_e_if16.html \
 		file_iframe_sandbox_top_navigation_pass.html \
 		file_iframe_sandbox_top_navigation_fail.html \
+		file_iframe_sandbox_window_navigation_fail.html \
 		test_iframe_sandbox_plugins.html \
 		file_iframe_sandbox_f_if1.html \
 		file_iframe_sandbox_f_if2.html \
 		file_iframe_sandbox_f_if2.html^headers^ \
 		test_iframe_sandbox_workers.html \
 		file_iframe_sandbox_g_if1.html \
 		file_iframe_sandbox_worker.js \
 		test_named_options.html \
@@ -353,16 +374,17 @@ MOCHITEST_FILES = \
 		test_element_prototype.html \
 		test_formData.html \
 		test_audio_wakelock.html \
 		test_video_wakelock.html \
 		wakelock.ogg \
 		wakelock.ogv \
 		test_bug869040.html \
 		allowMedia.sjs \
+		test_bug874758.html \
 		$(NULL)
 
 MOCHITEST_CHROME_FILES = \
 		test_allowMedia.html \
 		$(NULL)
 
 MOCHITEST_BROWSER_FILES = \
 		browser_bug649778.js \
--- a/content/html/content/test/file_iframe_sandbox_d_if1.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if1.html
@@ -9,11 +9,11 @@
 <script type="application/javascript">
 function doTest() {
   sendMouseEvent({type:'click'}, 'anchor');
 }
 </script>
 <body onload="doTest()">
   I am sandboxed with 'allow-scripts'
 
-  <a href="file_iframe_sandbox_navigation_pass.html?if_1" target="_self" id='anchor'>
+  <a href="file_iframe_sandbox_navigation_pass.html?Test 1:%20" target="_self" id='anchor'>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if14.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Tests for Bug 838692</title>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script type="text/javascript">
+  var test20Context = "Test 20: Navigate another window (not opened by us): ";
+
+  function doTest() {
+    // Try to navigate auxiliary browsing context (window) not opened by us.
+    // We should not be able to do this as we are sandboxed.
+    sendMouseEvent({type:'click'}, 'navigate_window');
+    window.parent.postMessage("test attempted", "*");
+
+    // Try to navigate auxiliary browsing context (window) not opened by us, using window.open().
+    // We should not be able to do this as we are sandboxed.
+    try {
+      window.open("file_iframe_sandbox_window_navigation_fail.html?" + escape(test20Context), "window_to_navigate2");
+      window.parent.postMessage("test attempted", "*");
+    } catch(error) {
+      window.parent.postMessage({ok: true, desc: test20Context + "as expected, error thrown during window.open(..., \"window_to_navigate2\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed but with "allow-scripts allow-same-origin allow-top-navigation".
+
+  <a href="file_iframe_sandbox_window_navigation_fail.html?Test 14: Navigate another window (not opened by us):%20" target="window_to_navigate" id="navigate_window">navigate window</a>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if15.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<body>
+  I am an unsandboxed iframe.
+
+  <iframe sandbox="allow-same-origin allow-scripts" id="if_16" src="file_iframe_sandbox_d_if16.html" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if16.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+</head>
+
+<script type="application/javascript">
+function doTest() {
+  window.parent.parent.postMessage("test attempted", "*");
+  sendMouseEvent({type:'click'}, 'anchor');
+}
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-same-origin allow-scripts'
+
+  <a href="file_iframe_sandbox_navigation_fail.html?Test 16: Navigate parent/ancestor by name:%20" target='if_parent' id='anchor'>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if17.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script type="application/javascript">
+  var testContext = "Test 17: navigate _self with window.open(): ";
+
+  function doTest() {
+    try {
+      window.open("file_iframe_sandbox_navigation_pass.html?" + escape(testContext), "_self");
+    } catch(error) {
+      window.parent.postMessage({ok: false, desc: testContext + "error thrown during window.open(..., \"_self\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if18.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+</head>
+
+<script type="application/javascript">
+  window.addEventListener("message", receiveMessage, false);
+
+  function receiveMessage(event) {
+    window.parent.postMessage(event.data, "*");
+  }
+
+  var testContext = "Test 18: navigate child with window.open(): ";
+
+  function doTest() {
+    try {
+      window.open("file_iframe_sandbox_navigation_pass.html?" + escape(testContext), "foo");
+    } catch(error) {
+      window.parent.postMessage({ok: false, desc: testContext + " error thrown during window.open(..., \"foo\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+
+  <iframe name="foo" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if19.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+  I am sandboxed with 'allow-scripts'
+
+  <iframe sandbox="allow-scripts" id="if_20" src="file_iframe_sandbox_d_if20.html" height="10" width="10"></iframe>
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_d_if2.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if2.html
@@ -5,24 +5,24 @@
   <title>Test for Bug 341604</title>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <script type="application/javascript">
 // needed to forward the message to the main test page
 window.addEventListener("message", receiveMessage, false);
 
-function receiveMessage(event) { 
-  window.parent.postMessage({ok: event.data.ok, desc: event.data.desc}, "*");
+function receiveMessage(event) {
+  window.parent.postMessage(event.data, "*");
 }
 
 function doTest() {
   sendMouseEvent({type:'click'}, 'anchor');
 }
 </script>
 <body onload="doTest()">
   I am sandboxed with 'allow-scripts'
 
   <iframe name="foo" src="file_iframe_sandbox_navigation_start.html" height="10" width="10"></iframe>
 
-  <a href="file_iframe_sandbox_navigation_pass.html?if2" target='foo' id='anchor'>
+  <a href="file_iframe_sandbox_navigation_pass.html?Test 2:%20" target='foo' id='anchor'>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if20.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script type="application/javascript">
+  var testContext = "Test 19: navigate _parent with window.open(): ";
+
+  function doTest() {
+    try {
+      window.open("file_iframe_sandbox_navigation_fail.html?" + escape(testContext), "_parent");
+      window.parent.parent.postMessage("test attempted", "*");
+    } catch(error) {
+      window.parent.parent.postMessage({ok: true, desc: testContext + "as expected, error thrown during window.open(..., \"_parent\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if21.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<body>
+  I am an unsandboxed iframe.
+
+  <iframe sandbox="allow-same-origin allow-scripts" id="if_22" src="file_iframe_sandbox_d_if22.html" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if22.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script type="application/javascript">
+  var testContext = "Test 21: navigate parent by name with window.open(): ";
+
+  function doTest() {
+    try {
+      window.open("file_iframe_sandbox_navigation_fail.html?" + escape(testContext), "if_parent2");
+      window.parent.parent.postMessage("test attempted", "*");
+    } catch(error) {
+      window.parent.parent.postMessage({ok: true, desc: testContext + "as expected, error thrown during window.open(..., \"if_parent2\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-same-origin allow-scripts'
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_d_if4.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if4.html
@@ -3,16 +3,17 @@
 <head>
   <meta charset="utf-8">
   <title>Test for Bug 341604</title>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <script type="application/javascript">
 function doTest() {
+  window.parent.parent.postMessage("test attempted", "*");
   sendMouseEvent({type:'click'}, 'anchor');
 }
 </script>
 <body onload="doTest()">
   I am sandboxed with 'allow-scripts'
 
   <a href="file_iframe_sandbox_navigation_fail.html" target='_parent' id='anchor'>
 </body>
--- a/content/html/content/test/file_iframe_sandbox_d_if5.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if5.html
@@ -4,16 +4,17 @@
   <meta charset="utf-8">
   <title>Test for Bug 341604</title>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <script type="application/javascript">
 function doTest() {
   sendMouseEvent({type:'click'}, 'anchor');
+  window.parent.postMessage("test attempted", "*");
 }
 </script>
 <body onload="doTest()">
   I am sandboxed with 'allow-scripts allow-same-origin'
 
-  <a href="file_iframe_sandbox_navigation_fail.html" target='sibling' id='anchor'>
+  <a href="file_iframe_sandbox_navigation_fail.html?Test 4: Navigate sibling iframe by name:%20" target='if_sibling' id='anchor'>
 </body>
 </html>
--- a/content/html/content/test/file_iframe_sandbox_d_if7.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if7.html
@@ -1,16 +1,20 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script type="application/javascript">
-function doTest() {
-  window.parent.ok_wrapper(false, "a sandboxed document when navigated should still NOT be same-origin with its parent");
-}
-</script>
-<body onload="doTest()">
-  I am sandboxed with 'allow-scripts'
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script type="application/javascript">
+function doTest() {
+  try {
+    window.parent.ok_wrapper(false, "a sandboxed document when navigated should still NOT be same-origin with its parent");
+  } catch(error) {
+    window.parent.postMessage({ok: true, desc: "sandboxed document's attempt to access parent after navigation blocked, as not same-origin."}, "*");
+  }
+}
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_d_if8.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if8.html
@@ -1,16 +1,24 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script type="application/javascript">
-function doTest() {
-  window.parent.modify_if_8();
-}
-</script>
-<body onload="doTest()">
-  I am sandboxed with 'allow-scripts' and 'allow-same-origin' the first time I am loaded, and with 'allow-scripts' the second time
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script type="application/javascript">
+function doTest() {
+  if (location.search == "?onreload") {
+    try {
+      window.parent.modify_if_8();
+    } catch (error) {
+      window.parent.postMessage({ok: true, desc: "allow-same-origin is no longer in effect after reload - parent access blocked."}, "*");
+    }
+  } else {
+    window.parent.modify_if_8();
+  }
+}
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts' and 'allow-same-origin' the first time I am loaded, and with 'allow-scripts' the second time
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_e_if1.html
+++ b/content/html/content/test/file_iframe_sandbox_e_if1.html
@@ -1,24 +1,20 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-  <script>
-    window.addEventListener("message", receiveMessage, false);
-
-    function receiveMessage(event)
-    {
-      window.parent.postMessage("close", "*");
-
-      SimpleTest.executeSoon(function() {
-        window.close();
-      }); 
-    }
-  </script>
-  <iframe sandbox='allow-scripts allow-same-origin' id='if_6' src="file_iframe_sandbox_e_if6.html" height="10" width="10"></iframe>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = location.search == "" ? "?Test 10: Navigate _top:%20" : location.search;
+    document.getElementById("if_6").src = "file_iframe_sandbox_e_if6.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts' id='if_6' height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if10.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = "?Test 23: Nested navigate _top with window.open():%20";
+    document.getElementById("if_9").src = "file_iframe_sandbox_e_if9.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts allow-top-navigation' id='if_9' height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if11.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+  function doTest() {
+    var testContext = location.search.substring(1);
+    try {
+      var topsOpener = window.top.opener;
+      window.open("file_iframe_sandbox_top_navigation_pass.html?" + testContext, "_top");
+      topsOpener.postMessage({ok: true, desc: unescape(testContext) + "top navigation should be allowed by a document sandboxed with 'allow-top-navigation.'"}, "*");
+    } catch(error) {
+      window.top.opener.postMessage({ok: false, desc: unescape(testContext) + "error thrown during window.open(..., \"_top\")"}, "*");
+      window.top.close();
+    }
+  }
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts and allow-top-navigation'
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if12.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = location.search == "" ? "?Test 24: Navigate _top with window.open():%20" : location.search;
+    document.getElementById("if_14").src = "file_iframe_sandbox_e_if14.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts' id='if_14' height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if13.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = "?Test 25: Nested navigate _top with window.open():%20";
+    document.getElementById("if_12").src = "file_iframe_sandbox_e_if12.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts allow-top-navigation' id='if_12' height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if14.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+  function doTest() {
+    var testContext = location.search.substring(1);
+    try {
+      var topsOpener = window.top.opener;
+      window.open("file_iframe_sandbox_top_navigation_fail.html?" + testContext, "_top");
+      topsOpener.postMessage({ok: false, desc: unescape(testContext) + "top navigation should NOT be allowed by a document sandboxed without 'allow-top-navigation.'"}, "*");
+    } catch(error) {
+      window.top.opener.postMessage({ok: true, desc: unescape(testContext) + "as expected error thrown during window.open(..., \"_top\")"}, "*");
+      window.top.close();
+    }
+  }
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if15.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  // Set our name, to allow an attempt to navigate us by name.
+  window.name = "e_if15";
+</script>
+
+<body>
+  <iframe sandbox='allow-scripts' id='if_16' src="file_iframe_sandbox_e_if16.html" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if16.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Tests for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  var testContext = "Test 26: navigate top by name with window.open(): ";
+
+  function doTest() {
+    try {
+      var topsOpener = window.top.opener;
+      window.open("file_iframe_sandbox_top_navigation_fail.html?" + escape(testContext), "e_if15");
+      topsOpener.postMessage({ok: false, desc: unescape(testContext) + "top navigation should NOT be allowed by a document sandboxed without 'allow-top-navigation.'"}, "*");
+    } catch(error) {
+      window.top.opener.postMessage({ok: true, desc: testContext + "as expected, error thrown during window.open(..., \"e_if15\")"}, "*");
+      window.top.close();
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed but with "allow-scripts"
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_e_if2.html
+++ b/content/html/content/test/file_iframe_sandbox_e_if2.html
@@ -1,22 +1,12 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-  <script>
-    window.addEventListener("message", receiveMessage, false);
-
-    function receiveMessage(event)
-    {
-      SimpleTest.executeSoon(function() {
-        window.close();
-      });
-    }
-  </script>
-  <iframe sandbox='allow-scripts allow-top-navigation allow-same-origin' id='if_1' src="file_iframe_sandbox_e_if1.html" height="10" width="10"></iframe>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body>
+  <iframe sandbox='allow-scripts allow-top-navigation allow-same-origin' id='if_1' src="file_iframe_sandbox_e_if1.html?Test 11: Nested navigate _top:%20" height="10" width="10"></iframe>
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_e_if6.html
+++ b/content/html/content/test/file_iframe_sandbox_e_if6.html
@@ -1,24 +1,22 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<script type="application/javascript">
-function doTest() {
-  sendMouseEvent({type:'click'}, 'anchor');
-
-   SimpleTest.executeSoon(function() {
-     window.parent.postMessage("close", "*");
-   });
-}
-</script>
-<body onload="doTest()">
-  I am sandboxed with 'allow-scripts'
-
-  <a href="file_iframe_sandbox_top_navigation_fail.html" target='_top' id='anchor'>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<script type="application/javascript">
+function doTest() {
+  document.getElementById('anchor').href = "file_iframe_sandbox_top_navigation_fail.html" + location.search;
+  window.top.opener.postMessage("test attempted", "*");
+  sendMouseEvent({type:'click'}, 'anchor');
+}
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+
+  <a target='_top' id='anchor'>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if7.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  // Set our name, to allow an attempt to navigate us by name.
+  window.name = "e_if7";
+</script>
+
+<body>
+  <iframe sandbox='allow-scripts' id='if_8' src="file_iframe_sandbox_e_if8.html" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if8.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Tests for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+</head>
+
+<script>
+  function doTest() {
+    // Try to navigate top using its name (e_if7).  We should not be able to do this as allow-top-navigation is not specified.
+    window.top.opener.postMessage("test attempted", "*");
+    sendMouseEvent({type:'click'}, 'navigate_top');
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed but with "allow-scripts"
+
+  <a href="file_iframe_sandbox_top_navigation_fail.html?Test 15: Navigate top by name:%20" target="e_if7" id="navigate_top">navigate top</a>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if9.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = location.search == "" ? "?Test 22: Navigate _top with window.open():%20" : location.search;
+    document.getElementById("if_11").src = "file_iframe_sandbox_e_if11.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts allow-top-navigation' id='if_11' height="10" width="10"></iframe>
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_navigation_fail.html
+++ b/content/html/content/test/file_iframe_sandbox_navigation_fail.html
@@ -1,16 +1,17 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onLoad="doStuff()">
-FAIL
-</body>
-<script>
-  function doStuff() {
-    window.parent.postMessage({ok: false, desc: "this navigation should NOT be allowed by a sandboxed document"}, "*");
-  }
-</script>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onLoad="doStuff()">
+FAIL
+</body>
+<script>
+  function doStuff() {
+    var testContext = unescape(location.search.substring(1));
+    window.parent.postMessage({ok: false, desc: testContext + "this navigation should NOT be allowed by a sandboxed document", addToAttempted: false}, "*");
+  }
+</script>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_navigation_pass.html
+++ b/content/html/content/test/file_iframe_sandbox_navigation_pass.html
@@ -1,16 +1,17 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script>
-function doStuff() {
-  window.parent.postMessage({ok: true, desc: "this navigation should be allowed by a sandboxed document"}, "*");
-}
-</script>
-<body onLoad="doStuff()">
-PASS
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+function doStuff() {
+  var testContext = unescape(location.search.substring(1));
+  window.parent.postMessage({ok: true, desc: testContext + "this navigation should be allowed by a sandboxed document"}, "*");
+}
+</script>
+<body onLoad="doStuff()">
+PASS
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_top_navigation_fail.html
+++ b/content/html/content/test/file_iframe_sandbox_top_navigation_fail.html
@@ -1,17 +1,18 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script>
-function doStuff() {
-	window.opener.postMessage({ok: false, desc:  "top navigation should NOT be allowed by a document sandboxed without 'allow-top-navigation'"}, "*");
-	window.close();
-}
-</script>
-<body onLoad="doStuff()">
-FAIL\
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+function doStuff() {
+  var testContext = unescape(location.search.substring(1));
+  window.opener.postMessage({ok: false, desc: testContext + "top navigation should NOT be allowed by a document sandboxed without 'allow-top-navigation'", addToAttempted: false}, "*");
+  window.close();
+}
+</script>
+<body onLoad="doStuff()">
+FAIL\
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_top_navigation_pass.html
+++ b/content/html/content/test/file_iframe_sandbox_top_navigation_pass.html
@@ -1,17 +1,18 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script>
-function doStuff() {
-	window.opener.postMessage({ok: true, desc:  "top navigation should be allowed by a document sandboxed with 'allow-top-navigation'"}, "*");
-	window.close();
-}
-</script>
-<body onLoad="doStuff()">
-PASS
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+function doStuff() {
+  var testContext = unescape(location.search.substring(1));
+  window.opener.postMessage({ok: true, desc: testContext + "top navigation should be allowed by a document sandboxed with 'allow-top-navigation'"}, "*");
+  window.close();
+}
+</script>
+<body onLoad="doStuff()">
+PASS
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_window_navigation_fail.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+function doStuff() {
+  var testContext = unescape(location.search.substring(1));
+  window.opener.postMessage({ok: false, desc: testContext + "a sandboxed document should not be able to navigate a window it hasn't opened.", addToAttempted: false}, "*");
+  window.close();
+}
+</script>
+
+<body onLoad="doStuff()">
+FAIL
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug874758.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html data-expando-prop="xyz">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=874758
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 874758</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 874758 **/
+  Object.prototype.expandoProp = 5;
+  is({}.expandoProp, 5, "Should see this on random objects");
+
+  is(document.head.dataset.expandoProp, 5, "Should see this on dataset too");
+  is(document.documentElement.dataset.expandoProp, "xyz",
+     "But if the dataset has it, we should get it from there");
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=874758">Mozilla Bug 874758</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/content/html/content/test/test_iframe_sandbox_navigation.html
+++ b/content/html/content/test/test_iframe_sandbox_navigation.html
@@ -1,234 +1,271 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=341604
-Implement HTML5 sandbox attribute for IFRAMEs
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604 - navigation</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-	<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script type="application/javascript">
-
-SimpleTest.expectAssertions(1, 2);
-
-/** Test for Bug 341604 - Implement HTML5 sandbox attribute for IFRAMEs **/
-/** Navigation tests **/
-
-SimpleTest.waitForExplicitFinish();
-// a postMessage handler that is used by sandboxed iframes without
-// 'allow-same-origin'/other windows to communicate pass/fail back to this main page.
-// it expects to be called with an object like {ok: true/false, desc:
-// <description of the test> which it then forwards to ok()
-window.addEventListener("message", receiveMessage, false);
-
-var testPassesReceived = 0;
-
-function receiveMessage(event) {
-  // this message is part of if_10's test
-  if (event.data.test == 'if_10') {
-    doIf10TestPart2();
-    return;
-  }
-
-  ok_wrapper(event.data.ok, event.data.desc);
-}
-
-var completedTests = 0;
-var passedTests = 0;
-
-function ok_wrapper(result, desc) {
-  ok(result, desc);
-
-  completedTests++;
-
-  if (result) {
-    passedTests++;
-  }
-
-  if (completedTests == 6) {
-    is(passedTests, 6, "There are 6 navigation tests that should pass");
-
-    SimpleTest.finish();
-  }
-}
-
-function doTest() {
-  // passes if good
-  // 1) A sandboxed iframe is allowed to navigate itself
-  // (done by file_iframe_sandbox_d_if1.html which has 'allow-scripts' and navigates to
-  // file_iframe_sandbox_navigation_pass.html).
-
-  // passes if good
-  // 2) A sandboxed iframe is allowed to navigate its children, even if they are sandboxed
-  // (done by file_iframe_sandbox_d_if2.html which has 'allow-scripts', it navigates a child
-  // iframe containing file_iframe_sandbox_navigation_start.html to file_iframe_sandbox_navigation_pass.html).
-
-  // fails if bad
-  // 3) A sandboxed iframe is not allowed to navigate its ancestor
-  // (done by file_iframe_sandbox_d_if4.html contained within file_iframe_sandbox_d_if3.html,
-  // it attempts to navigate file_iframe_sandbox_d_if3.html to file_iframe_sandbox_navigation_fail.html).
-
-  // fails if bad
-  // 4) A sandboxed iframe is not allowed to navigate its sibling
-  // (done by file_iframe_sandbox_d_if5.html which has 'allow scripts allow-same-origin'
-  // and attempts to navigate file_iframe_navigation_start.html contained in if_sibling on this
-  // page to file_iframe_sandbox_navigation_fail.html).
-
-  // fails if bad
-  // 5) When a link is clicked in a sandboxed iframe, the document navigated to is sandboxed
-  // the same as the original document and is not same origin with parent document
-  // (done by file_iframe_sandbox_d_if6.html which simulates a link click and navigates
-  // to file_iframe_sandbox_d_if7.html which attempts to call back into its parent).
-
-  // fails if bad
-  // 6) An iframe (if_8) has sandbox="allow-same-origin allow-scripts", the sandboxed document
-  // (file_iframe_sandbox_d_if_8.html) that it contains accesses its parent (this file) and removes
-  // 'allow-same-origin' and then triggers a reload.
-  // The document should not be able to access its parent (this file).
-
-  // fails if bad
-  // 7) An iframe (if_9) has sandbox="allow-same-origin allow-scripts", the sandboxed document
-  // (file_iframe_sandbox_d_if_9.html) that it contains accesses its parent (this file) and removes
-  // 'allow-scripts' and then triggers a reload.
-  // The document should not be able to run a script and access its parent (this file).
-
-  // passes if good
-  // 8) a document in an iframe with sandbox='allow-scripts' should have a different null
-  // principal in its original document than a document to which it navigates itself
-  // file_iframe_sandbox_d_if_10.html does this, co-ordinating with this page via postMessage
-  
-  // passes if good
-  // 9) a document (file_iframe_sandbox_d_if11.html in an iframe (if_11) with sandbox='allow-scripts'
-  // is navigated to file_iframe_sandbox_d_if12.html - when that document loads
-  // a message is sent back to this document, which adds 'allow-same-origin' to if_11 and then
-  // calls .back on it - file_iframe_sandbox_if12.html should be able to call back into this
-  // document - this is all contained in file_iframe_sandbox_d_if13.html which is opened in another
-  // tab so it has its own isolated session history
-  window.open("file_iframe_sandbox_d_if13.html");
-  
-  // open up the top navigation tests
-
-  // fails if bad
-  // 10) iframe with sandbox='allow-scripts' can NOT navigate top
-  // file_iframe_sandbox_e_if1.html contains file_iframe_sandbox_e_if6.html which
-  // attempts to navigate top
-  window.open("file_iframe_sandbox_e_if1.html");
-
-  // fails if bad
-  // 11) iframe with sandbox='allow-scripts' nested inside iframe with
-  // 'allow-top-navigation allow-scripts' can NOT navigate top
-  // file_iframe_sandbox_e_if2.html contains file_iframe_sandbox_e_if1.html which
-  // contains file_iframe_sandbox_e_if6.html which attempts to navigate top
-  window.open("file_iframe_sandbox_e_if2.html");
-
-  // passes if good
-  // 12) iframe with sandbox='allow-top-navigation allow-scripts' can navigate top
-  // file_iframe_sandbox_e_if3.html contains file_iframe_sandbox_e_if5.html which navigates top
-  window.open("file_iframe_sandbox_e_if3.html");
-
-  // passes if good
-  // 131) iframe with sandbox='allow-top-navigation allow-scripts' nested inside an iframe with
-  // 'allow-top-navigation allow-scripts' can navigate top
-  // file_iframe_sandbox_e_if4.html contains file_iframe_sandbox_e_if3.html which contains
-  // file_iframe_sandbox_e_if5.html which navigates top
-  window.open("file_iframe_sandbox_e_if4.html");
-}
-
-addLoadEvent(doTest);
-
-window.modified_if_8 = false;
-
-function reload_if_8() {
-  var if_8 = document.getElementById('if_8');
-  if_8.src = 'file_iframe_sandbox_d_if8.html';
-}
-
-function modify_if_8() {
-  // If this is the second time this has been called
-  // that's a failed test (allow-same-origin was removed
-  // the first time).
-  if (window.modified_if_8) {
-    ok_wrapper(false, "an sandboxed iframe from which 'allow-same-origin' was removed should not be able to access its parent");
-
-    // need to return here since we end up in an infinite loop otherwise
-    return;
-  }
-
-  var if_8 = document.getElementById('if_8');
-  window.modified_if_8 = true;
-
-  if_8.sandbox = 'allow-scripts';
-  sendMouseEvent({type:'click'}, 'a_button');
-}
-
-window.modified_if_9 = false;
-
-function reload_if_9() {
-  var if_9 = document.getElementById('if_9');
-  if_9.src = 'file_iframe_sandbox_d_if9.html';
-}
-
-function modify_if_9() {
-  // If this is the second time this has been called
-  // that's a failed test (allow-scripts was removed
-  // the first time).
-  if (window.modified_if_9) {
-    ok_wrapper(false, "an sandboxed iframe from which 'allow-scripts' should be removed should not be able to access its parent via a script");
-
-    // need to return here since we end up in an infinite loop otherwise
-    return;
-  }
-
-  var if_9 = document.getElementById('if_9');
-  window.modified_if_9 = true;
-
-  if_9.sandbox = 'allow-same-origin';
-
-  sendMouseEvent({type:'click'}, 'a_button2');
-}
-
-var firstPrincipal = "";
-var secondPrincipal;
-
-function doIf10TestPart1() {
-  if (firstPrincipal != "")
-    return;
-
-  // use SpecialPowers to get the principal of if_10.
-  // NB: We stringify here and below because special-powers wrapping doesn't
-  // preserve identity.
-  var if_10 = document.getElementById('if_10');
-  firstPrincipal = SpecialPowers.wrap(if_10).contentDocument.nodePrincipal.origin;
-  if_10.src = 'file_iframe_sandbox_d_if10.html';
-
-}
-function doIf10TestPart2() {
-  var if_10 = document.getElementById('if_10');
-  // use SpecialPowers to get the principal of if_10
-  secondPrincipal = SpecialPowers.wrap(if_10).contentDocument.nodePrincipal.origin;
-  ok_wrapper(firstPrincipal != secondPrincipal, "documents should NOT have the same principal if they are sandboxed without" +
-    " allow-same-origin and the first document is navigated to the second");
-}
-</script>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=341604">Mozilla Bug 341604</a> - Implement HTML5 sandbox attribute for IFRAMEs
-<p id="display"></p>
-<div id="content">
-<iframe sandbox="allow-scripts" id="if_1" src="file_iframe_sandbox_d_if1.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-scripts" id="if_2" src="file_iframe_sandbox_d_if2.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-scripts" id="if_3" src="file_iframe_sandbox_d_if3.html" height="10" width="10"></iframe>
-<iframe sandbox="allow_scripts allow-same-origin" id="if_5" src="file_iframe_sandbox_d_if5.html" height="10" width="10"></iframe>
-<iframe id="if_sibling" src="file_iframe_sandbox_navigation_start.html" height="10" width="10"></iframe>
-<iframe sandbox="allow_scripts" id="if_6" src="file_iframe_sandbox_d_if6.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-same-origin allow-scripts" id="if_8" src="file_iframe_sandbox_d_if8.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-same-origin allow-scripts" id="if_9" src="file_iframe_sandbox_d_if9.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-scripts" id="if_10" src="file_iframe_sandbox_navigation_start.html" onload='doIf10TestPart1()' height="10" width="10"></iframe>
-</div>
-<input type='button' id="a_button" onclick='reload_if_8()'>
-<input type='button' id="a_button2" onclick='reload_if_9()'>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=341604
+Implement HTML5 sandbox attribute for IFRAMEs
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604 - navigation</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script type="application/javascript">
+/** Test for Bug 341604 - Implement HTML5 sandbox attribute for IFRAMEs **/
+/** Navigation tests Part 1**/
+
+SimpleTest.expectAssertions(1, 3);
+SimpleTest.waitForExplicitFinish();
+// a postMessage handler that is used by sandboxed iframes without
+// 'allow-same-origin'/other windows to communicate pass/fail back to this main page.
+// it expects to be called with an object like {ok: true/false, desc:
+// <description of the test> which it then forwards to ok()
+window.addEventListener("message", receiveMessage, false);
+
+var testPassesReceived = 0;
+
+function receiveMessage(event) {
+  // this message is part of if_10's test
+  if (event.data.test == 'if_10') {
+    doIf10TestPart2();
+  } else if (event.data == "test attempted") {
+    testAttempted();
+  } else {
+    ok_wrapper(event.data.ok, event.data.desc, event.data.addToAttempted);
+  }
+}
+
+// Open windows for tests to attempt to navigate later.
+var windowsToClose = new Array();
+windowsToClose.push(window.open("about:blank", "window_to_navigate"));
+windowsToClose.push(window.open("about:blank", "window_to_navigate2"));
+
+var attemptedTests = 0;
+var passedTests = 0;
+var totalTestsToPass = 8;
+var totalTestsToAttempt = 13;
+
+function ok_wrapper(result, desc, addToAttempted = true) {
+  ok(result, desc);
+
+  if (result) {
+    passedTests++;
+  }
+
+  if (addToAttempted) {
+    testAttempted();
+  }
+}
+
+// Added so that tests that don't register unless they fail,
+// can at least notify that they've attempted to run.
+function testAttempted() {
+  attemptedTests++;
+  if (attemptedTests == totalTestsToAttempt) {
+    // Make sure all tests have had a chance to complete.
+    setTimeout(function() {finish();}, 1000);
+  }
+}
+
+var finishCalled = false;
+
+function finish() {
+  if (!finishCalled) {
+    finishCalled = true;
+    is(passedTests, totalTestsToPass, "There are " + totalTestsToPass + " navigation tests that should pass");
+
+    for (var i = 0; i < windowsToClose.length; i++) {
+      windowsToClose[i].close();
+    }
+
+    SimpleTest.finish();
+  }
+}
+
+function checkTestsFinished() {
+  // If our own finish() has not been called, probably failed due to a timeout, so close remaining windows.
+  if (!finishCalled) {
+    for (var i = 0; i < windowsToClose.length; i++) {
+      windowsToClose[i].close();
+    }
+  }
+}
+
+function doTest() {
+  // passes if good
+  // 1) A sandboxed iframe is allowed to navigate itself
+  // (done by file_iframe_sandbox_d_if1.html which has 'allow-scripts' and navigates to
+  // file_iframe_sandbox_navigation_pass.html).
+
+  // passes if good
+  // 2) A sandboxed iframe is allowed to navigate its children, even if they are sandboxed
+  // (done by file_iframe_sandbox_d_if2.html which has 'allow-scripts', it navigates a child
+  // iframe containing file_iframe_sandbox_navigation_start.html to file_iframe_sandbox_navigation_pass.html).
+
+  // fails if bad
+  // 3) A sandboxed iframe is not allowed to navigate its ancestor
+  // (done by file_iframe_sandbox_d_if4.html contained within file_iframe_sandbox_d_if3.html,
+  // it attempts to navigate file_iframe_sandbox_d_if3.html to file_iframe_sandbox_navigation_fail.html).
+
+  // fails if bad
+  // 4) A sandboxed iframe is not allowed to navigate its sibling
+  // (done by file_iframe_sandbox_d_if5.html which has 'allow scripts allow-same-origin'
+  // and attempts to navigate file_iframe_navigation_start.html contained in if_sibling on this
+  // page to file_iframe_sandbox_navigation_fail.html).
+
+  // passes if good, fails if bad
+  // 5) When a link is clicked in a sandboxed iframe, the document navigated to is sandboxed
+  // the same as the original document and is not same origin with parent document
+  // (done by file_iframe_sandbox_d_if6.html which simulates a link click and navigates
+  // to file_iframe_sandbox_d_if7.html which attempts to call back into its parent).
+
+  // passes if good, fails if bad
+  // 6) An iframe (if_8) has sandbox="allow-same-origin allow-scripts", the sandboxed document
+  // (file_iframe_sandbox_d_if_8.html) that it contains accesses its parent (this file) and removes
+  // 'allow-same-origin' and then triggers a reload.
+  // The document should not be able to access its parent (this file).
+
+  // fails if bad
+  // 7) An iframe (if_9) has sandbox="allow-same-origin allow-scripts", the sandboxed document
+  // (file_iframe_sandbox_d_if_9.html) that it contains accesses its parent (this file) and removes
+  // 'allow-scripts' and then triggers a reload.
+  // The document should not be able to run a script and access its parent (this file).
+
+  // passes if good
+  // 8) a document in an iframe with sandbox='allow-scripts' should have a different null
+  // principal in its original document than a document to which it navigates itself
+  // file_iframe_sandbox_d_if_10.html does this, co-ordinating with this page via postMessage
+
+  // passes if good
+  // 9) a document (file_iframe_sandbox_d_if11.html in an iframe (if_11) with sandbox='allow-scripts'
+  // is navigated to file_iframe_sandbox_d_if12.html - when that document loads
+  // a message is sent back to this document, which adds 'allow-same-origin' to if_11 and then
+  // calls .back on it - file_iframe_sandbox_if12.html should be able to call back into this
+  // document - this is all contained in file_iframe_sandbox_d_if13.html which is opened in another
+  // tab so it has its own isolated session history
+  window.open("file_iframe_sandbox_d_if13.html");
+
+  // open up the top navigation tests
+
+  // fails if bad
+  // 10) iframe with sandbox='allow-scripts' can NOT navigate top
+  // file_iframe_sandbox_e_if1.html contains file_iframe_sandbox_e_if6.html which
+  // attempts to navigate top
+  windowsToClose.push(window.open("file_iframe_sandbox_e_if1.html"));
+
+  // fails if bad
+  // 11) iframe with sandbox='allow-scripts' nested inside iframe with
+  // 'allow-top-navigation allow-scripts' can NOT navigate top
+  // file_iframe_sandbox_e_if2.html contains file_iframe_sandbox_e_if1.html which
+  // contains file_iframe_sandbox_e_if6.html which attempts to navigate top
+  windowsToClose.push(window.open("file_iframe_sandbox_e_if2.html"));
+
+  // passes if good
+  // 12) iframe with sandbox='allow-top-navigation allow-scripts' can navigate top
+  // file_iframe_sandbox_e_if3.html contains file_iframe_sandbox_e_if5.html which navigates top
+  window.open("file_iframe_sandbox_e_if3.html");
+
+  // passes if good
+  // 13) iframe with sandbox='allow-top-navigation allow-scripts' nested inside an iframe with
+  // 'allow-top-navigation allow-scripts' can navigate top
+  // file_iframe_sandbox_e_if4.html contains file_iframe_sandbox_e_if3.html which contains
+  // file_iframe_sandbox_e_if5.html which navigates top
+  window.open("file_iframe_sandbox_e_if4.html");
+}
+
+addLoadEvent(doTest);
+
+window.modified_if_8 = false;
+
+function reload_if_8() {
+  var if_8 = document.getElementById('if_8');
+  if_8.src = 'file_iframe_sandbox_d_if8.html?onreload';
+}
+
+function modify_if_8() {
+  // If this is the second time this has been called
+  // that's a failed test (allow-same-origin was removed
+  // the first time).
+  if (window.modified_if_8) {
+    ok_wrapper(false, "an sandboxed iframe from which 'allow-same-origin' was removed should not be able to access its parent");
+
+    // need to return here since we end up in an infinite loop otherwise
+    return;
+  }
+
+  var if_8 = document.getElementById('if_8');
+  window.modified_if_8 = true;
+
+  if_8.sandbox = 'allow-scripts';
+  sendMouseEvent({type:'click'}, 'a_button');
+}
+
+window.modified_if_9 = false;
+
+function reload_if_9() {
+  var if_9 = document.getElementById('if_9');
+  if_9.src = 'file_iframe_sandbox_d_if9.html';
+}
+
+function modify_if_9() {
+  // If this is the second time this has been called
+  // that's a failed test (allow-scripts was removed
+  // the first time).
+  if (window.modified_if_9) {
+    ok_wrapper(false, "an sandboxed iframe from which 'allow-scripts' should be removed should not be able to access its parent via a script", false);
+
+    // need to return here since we end up in an infinite loop otherwise
+    return;
+  }
+
+  var if_9 = document.getElementById('if_9');
+  window.modified_if_9 = true;
+
+  if_9.sandbox = 'allow-same-origin';
+
+  sendMouseEvent({type:'click'}, 'a_button2');
+  testAttempted();
+}
+
+var firstPrincipal = "";
+var secondPrincipal;
+
+function doIf10TestPart1() {
+  if (firstPrincipal != "")
+    return;
+
+  // use SpecialPowers to get the principal of if_10.
+  // NB: We stringify here and below because special-powers wrapping doesn't
+  // preserve identity.
+  var if_10 = document.getElementById('if_10');
+  firstPrincipal = SpecialPowers.wrap(if_10).contentDocument.nodePrincipal.origin;
+  if_10.src = 'file_iframe_sandbox_d_if10.html';
+}
+
+function doIf10TestPart2() {
+  var if_10 = document.getElementById('if_10');
+  // use SpecialPowers to get the principal of if_10
+  secondPrincipal = SpecialPowers.wrap(if_10).contentDocument.nodePrincipal.origin;
+  ok_wrapper(firstPrincipal != secondPrincipal, "documents should NOT have the same principal if they are sandboxed without" +
+    " allow-same-origin and the first document is navigated to the second");
+}
+</script>
+<body onunload="checkTestsFinished()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=341604">Mozilla Bug 341604</a> - Implement HTML5 sandbox attribute for IFRAMEs
+<p id="display"></p>
+<div id="content">
+<iframe sandbox="allow-scripts" id="if_1" src="file_iframe_sandbox_d_if1.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_2" src="file_iframe_sandbox_d_if2.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_3" src="file_iframe_sandbox_d_if3.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts allow-same-origin" id="if_5" src="file_iframe_sandbox_d_if5.html" height="10" width="10"></iframe>
+<iframe id="if_sibling" name="if_sibling" src="file_iframe_sandbox_navigation_start.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_6" src="file_iframe_sandbox_d_if6.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-same-origin allow-scripts" id="if_8" src="file_iframe_sandbox_d_if8.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-same-origin allow-scripts" id="if_9" src="file_iframe_sandbox_d_if9.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_10" src="file_iframe_sandbox_navigation_start.html" onload='doIf10TestPart1()' height="10" width="10"></iframe>
+</div>
+<input type='button' id="a_button" onclick='reload_if_8()'>
+<input type='button' id="a_button2" onclick='reload_if_9()'>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_iframe_sandbox_navigation2.html
@@ -0,0 +1,187 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=341604
+Implement HTML5 sandbox attribute for IFRAMEs
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604 - navigation</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script type="application/javascript">
+/** Test for Bug 341604 - Implement HTML5 sandbox attribute for IFRAMEs **/
+/** Navigation tests Part 2**/
+
+SimpleTest.expectAssertions(0);
+SimpleTest.waitForExplicitFinish();
+// a postMessage handler that is used by sandboxed iframes without
+// 'allow-same-origin'/other windows to communicate pass/fail back to this main page.
+// it expects to be called with an object like {ok: true/false, desc:
+// <description of the test> which it then forwards to ok()
+window.addEventListener("message", receiveMessage, false);
+
+var testPassesReceived = 0;
+
+function receiveMessage(event) {
+  if (event.data == "test attempted") {
+    testAttempted();
+  } else {
+    ok_wrapper(event.data.ok, event.data.desc, event.data.addToAttempted);
+  }
+}
+
+// Open windows for tests to attempt to navigate later.
+var windowsToClose = new Array();
+windowsToClose.push(window.open("about:blank", "window_to_navigate"));
+windowsToClose.push(window.open("about:blank", "window_to_navigate2"));
+
+var attemptedTests = 0;
+var passedTests = 0;
+var totalTestsToPass = 10;
+var totalTestsToAttempt = 13;
+
+function ok_wrapper(result, desc, addToAttempted = true) {
+  ok(result, desc);
+
+  if (result) {
+    passedTests++;
+  }
+
+  if (addToAttempted) {
+    testAttempted();
+  }
+}
+
+// Added so that tests that don't register unless they fail,
+// can at least notify that they've attempted to run.
+function testAttempted() {
+  attemptedTests++;
+  if (attemptedTests == totalTestsToAttempt) {
+    // Make sure all tests have had a chance to complete.
+    setTimeout(function() {finish();}, 1000);
+  }
+}
+
+var finishCalled = false;
+
+function finish() {
+  if (!finishCalled) {
+    finishCalled = true;
+    is(passedTests, totalTestsToPass, "There are " + totalTestsToPass + " navigation tests that should pass");
+
+    for (var i = 0; i < windowsToClose.length; i++) {
+      windowsToClose[i].close();
+    }
+
+    SimpleTest.finish();
+  }
+}
+
+function checkTestsFinished() {
+  // If our own finish() has not been called, probably failed due to a timeout, so close remaining windows.
+  if (!finishCalled) {
+    for (var i = 0; i < windowsToClose.length; i++) {
+      windowsToClose[i].close();
+    }
+  }
+}
+
+function doTest() {
+  // fails if bad
+  // 14) iframe with sandbox='allow-same-origin allow-scripts allow-top-navigation' should not
+  // be able to navigate another window (opened by another browsing context) using its name.
+  // file_iframe_sandbox_d_if14.html in if_14 attempts to navigate "window_to_navigate",
+  // which has been opened in preparation.
+
+  // fails if bad
+  // 15) iframe with sandbox='allow-scripts' should not be able to navigate top using its
+  // real name (instead of _top) as allow-top-navigation is not specified.
+  // file_iframe_sandbox_e_if7.html contains file_iframe_sandbox_e_if8.html, which
+  // attempts to navigate top by name.
+  windowsToClose.push(window.open("file_iframe_sandbox_e_if7.html"));
+
+  // fails if bad
+  // 16) iframe with sandbox='allow-same-origin allow-scripts allow-top-navigation' should not
+  // be able to use its parent's name (instead of _parent) to navigate it, when it is not top.
+  // (Note: this would apply to other ancestors that are not top as well.)
+  // file_iframe_sandbox_d_if15.html in if_15 contains file_iframe_sandbox_d_if16.html, which
+  // tries to navigate if_15 by its name (if_parent).
+
+  // passes if good, fails if bad
+  // 17) A sandboxed iframe is allowed to navigate itself using window.open().
+  // (Done by file_iframe_sandbox_d_if17.html which has 'allow-scripts' and navigates to
+  // file_iframe_sandbox_navigation_pass.html).
+
+  // passes if good, fails if bad
+  // 18) A sandboxed iframe is allowed to navigate its children with window.open(), even if
+  // they are sandboxed.  (Done by file_iframe_sandbox_d_if18.html which has 'allow-scripts',
+  // it navigates a child iframe to file_iframe_sandbox_navigation_pass.html).
+
+  // passes if good, fails if bad
+  // 19) A sandboxed iframe is not allowed to navigate its ancestor with window.open().
+  // (Done by file_iframe_sandbox_d_if20.html contained within file_iframe_sandbox_d_if19.html,
+  // it attempts to navigate file_iframe_sandbox_d_if19.html to file_iframe_sandbox_navigation_fail.html).
+
+  // passes if good, fails if bad
+  // 20) iframe with sandbox='allow-same-origin allow-scripts allow-top-navigation' should not
+  // be able to navigate another window (opened by another browsing context) using window.open(..., "<name>").
+  // file_iframe_sandbox_d_if14.html in if_14 attempts to navigate "window_to_navigate2",
+  // which has been opened in preparation, using window.open(..., "window_to_navigate2").
+
+  // passes if good, fails if bad
+  // 21) iframe with sandbox='allow-same-origin allow-scripts allow-top-navigation' should not
+  // be able to use its parent's name (not _parent) to navigate it using window.open(), when it is not top.
+  // (Note: this would apply to other ancestors that are not top as well.)
+  // file_iframe_sandbox_d_if21.html in if_21 contains file_iframe_sandbox_d_if22.html, which
+  // tries to navigate if_21 by its name (if_parent2).
+
+  // passes if good, fails if bad
+  // 22) iframe with sandbox='allow-top-navigation allow-scripts' can navigate top with window.open().
+  // file_iframe_sandbox_e_if9.html contains file_iframe_sandbox_e_if11.html which navigates top.
+  window.open("file_iframe_sandbox_e_if9.html");
+
+  // passes if good, fails if bad
+  // 23) iframe with sandbox='allow-top-navigation allow-scripts' nested inside an iframe with
+  // 'allow-top-navigation allow-scripts' can navigate top, with window.open().
+  // file_iframe_sandbox_e_if10.html contains file_iframe_sandbox_e_if9.html which contains
+  // file_iframe_sandbox_e_if11.html which navigates top.
+  window.open("file_iframe_sandbox_e_if10.html");
+
+  // passes if good, fails if bad
+  // 24) iframe with sandbox='allow-scripts' can NOT navigate top with window.open().
+  // file_iframe_sandbox_e_if12.html contains file_iframe_sandbox_e_if14.html which navigates top.
+  window.open("file_iframe_sandbox_e_if12.html");
+
+  // passes if good, fails if bad
+  // 25) iframe with sandbox='allow-scripts' nested inside an iframe with
+  // 'allow-top-navigation allow-scripts' can NOT navigate top, with window.open(..., "_top").
+  // file_iframe_sandbox_e_if13.html contains file_iframe_sandbox_e_if12.html which contains
+  // file_iframe_sandbox_e_if14.html which navigates top.
+  window.open("file_iframe_sandbox_e_if13.html");
+
+  // passes if good, fails if bad
+  // 26) iframe with sandbox='allow-scripts' should not be able to navigate top using its real name
+  // (not with _top e.g. window.open(..., "topname")) as allow-top-navigation is not specified.
+  // file_iframe_sandbox_e_if15.html contains file_iframe_sandbox_e_if16.html, which
+  // attempts to navigate top by name using window.open().
+  window.open("file_iframe_sandbox_e_if15.html");
+}
+
+addLoadEvent(doTest);
+</script>
+<body onunload="checkTestsFinished()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=341604">Mozilla Bug 341604</a> - Implement HTML5 sandbox attribute for IFRAMEs
+<p id="display"></p>
+<div id="content">
+<iframe sandbox="allow-same-origin allow-scripts allow-top-navigation" id="if_14" src="file_iframe_sandbox_d_if14.html" height="10" width="10"></iframe>
+<iframe id="if_15" name="if_parent" src="file_iframe_sandbox_d_if15.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_17" src="file_iframe_sandbox_d_if17.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_18" src="file_iframe_sandbox_d_if18.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_19" src="file_iframe_sandbox_d_if19.html" height="10" width="10"></iframe>
+<iframe id="if_21" name="if_parent2" src="file_iframe_sandbox_d_if21.html" height="10" width="10"></iframe>
+</div>
+</body>
+</html>
--- a/content/svg/content/src/SVGFETurbulenceElement.cpp
+++ b/content/svg/content/src/SVGFETurbulenceElement.cpp
@@ -259,17 +259,17 @@ SVGFETurbulenceElement::InitSeed(int32_t
 #define S_CURVE(t) ( t * t * (3. - 2. * t) )
 #define LERP(t, a, b) ( a + t * (b - a) )
 double
 SVGFETurbulenceElement::Noise2(int aColorChannel, double aVec[2],
                                StitchInfo *aStitchInfo)
 {
   int bx0, bx1, by0, by1, b00, b10, b01, b11;
   double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
-  register long i, j;
+  long i, j;
   t = aVec[0] + sPerlinN;
   bx0 = (int) t;
   bx1 = bx0 + 1;
   rx0 = t - (int) t;
   rx1 = rx0 - 1.0f;
   t = aVec[1] + sPerlinN;
   by0 = (int) t;
   by1 = by0 + 1;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -3082,24 +3082,28 @@ nsDocShell::FindItemWithName(const PRUni
     NS_ENSURE_ARG_POINTER(_retval);
 
     // If we don't find one, we return NS_OK and a null result
     *_retval = nullptr;
 
     if (!*aName)
         return NS_OK;
 
-    if (!aRequestor)
-    {
-        nsCOMPtr<nsIDocShellTreeItem> foundItem;
+    if (aRequestor) {
+        // If aRequestor is not null we don't need to check special names, so
+        // just hand straight off to the search by actual name function.
+        return DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
+                                  _retval);
+    } else {
 
         // This is the entry point into the target-finding algorithm.  Check
         // for special names.  This should only be done once, hence the check
         // for a null aRequestor.
 
+        nsCOMPtr<nsIDocShellTreeItem> foundItem;
         nsDependentString name(aName);
         if (name.LowerCaseEqualsLiteral("_self")) {
             foundItem = this;
         }
         else if (name.LowerCaseEqualsLiteral("_blank"))
         {
             // Just return null.  Caller must handle creating a new window with
             // a blank name himself.
@@ -3138,26 +3142,29 @@ nsDocShell::FindItemWithName(const PRUni
                 // Note: _content should always exist.  If we don't have one
                 // hanging off the treeowner, just create a named window....
                 // so don't return here, in case we did that and can now find
                 // it.                
                 // XXXbz should we be using |root| instead of creating
                 // a new window?
             }
 #endif
+        } else {
+            // Do the search for item by an actual name.
+            DoFindItemWithName(aName, aRequestor, aOriginalRequestor,
+                               getter_AddRefs(foundItem));
         }
 
         if (foundItem && !CanAccessItem(foundItem, aOriginalRequestor)) {
             foundItem = nullptr;
         }
 
+        // DoFindItemWithName only returns active items and we don't check if
+        // the item is active for the special cases.
         if (foundItem) {
-            // We return foundItem here even if it's not an active
-            // item since all the names we've dealt with so far are
-            // special cases that we won't bother looking for further.
 
             // If our document is sandboxed, we need to do some extra checks.
             uint32_t sandboxFlags = 0;
 
             nsCOMPtr<nsIDocument> doc = do_GetInterface(aOriginalRequestor);
 
             if (doc) {
                 sandboxFlags = doc->GetSandboxFlags();
@@ -3169,27 +3176,24 @@ nsDocShell::FindItemWithName(const PRUni
 
                 // Is the found item not a top level browsing context and not ourself ?
                 nsCOMPtr<nsIDocShellTreeItem> selfAsItem = static_cast<nsIDocShellTreeItem *>(this);
                 if (foundItem != root && foundItem != selfAsItem) {
                     // Are we an ancestor of the foundItem ?
                     bool isAncestor = false;
 
                     nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
-                    GetSameTypeParent(getter_AddRefs(parentAsItem));
-
+                    foundItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
                     while (parentAsItem) {
-                        nsCOMPtr<nsIDocShellTreeItem> tmp;
-                        parentAsItem->GetParent(getter_AddRefs(tmp));
-
-                        if (tmp && tmp == selfAsItem) {
+                        if (parentAsItem == selfAsItem) {
                             isAncestor = true;
                             break;
                         }
-                        parentAsItem = tmp;
+                        nsCOMPtr<nsIDocShellTreeItem> tmp = parentAsItem;
+                        tmp->GetSameTypeParent(getter_AddRefs(parentAsItem));
                     }
 
                     if (!isAncestor) {
                         // No, we are not an ancestor and our document is
                         // sandboxed, we can't allow this.
                         foundItem = nullptr;
                     }
                 } else {
@@ -3207,22 +3211,27 @@ nsDocShell::FindItemWithName(const PRUni
                             break;
                         }
                         tmp->GetParent(getter_AddRefs(tmp));
                     }
                 }
             }
 
             foundItem.swap(*_retval);
-            return NS_OK;
-        }
-    }
-
-    // Keep looking
-        
+        }
+        return NS_OK;
+    }
+}
+
+nsresult
+nsDocShell::DoFindItemWithName(const PRUnichar* aName,
+                               nsISupports* aRequestor,
+                               nsIDocShellTreeItem* aOriginalRequestor,
+                               nsIDocShellTreeItem** _retval)
+{
     // First we check our name.
     if (mName.Equals(aName) && ItemIsActive(this) &&
         CanAccessItem(this, aOriginalRequestor)) {
         NS_ADDREF(*_retval = this);
         return NS_OK;
     }
 
     // This QI may fail, but the places where we want to compare, comparing
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -869,16 +869,23 @@ protected:
 private:
     nsCString         mForcedCharset;
     nsCString         mParentCharset;
     nsTObserverArray<nsWeakPtr> mPrivacyObservers;
     nsTObserverArray<nsWeakPtr> mReflowObservers;
     int32_t           mParentCharsetSource;
     nsCString         mOriginalUriString;
 
+    // Separate function to do the actual name (i.e. not _top, _self etc.)
+    // searching for FindItemWithName.
+    nsresult DoFindItemWithName(const PRUnichar* aName,
+                                nsISupports* aRequestor,
+                                nsIDocShellTreeItem* aOriginalRequestor,
+                                nsIDocShellTreeItem** _retval);
+
 #ifdef DEBUG
     // We're counting the number of |nsDocShells| to help find leaks
     static unsigned long gNumberOfDocShells;
 #endif /* DEBUG */
 
 public:
     class InterfaceRequestorProxy : public nsIInterfaceRequestor {
     public:
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -55,57 +55,36 @@ ThrowErrorMessage(JSContext* aCx, const 
   va_start(ap, aErrorNumber);
   JS_ReportErrorNumberVA(aCx, GetErrorMessage, nullptr,
                          static_cast<const unsigned>(aErrorNumber), ap);
   va_end(ap);
   return false;
 }
 
 bool
-ThrowInvalidMethodThis(JSContext* aCx, const JS::CallArgs& aArgs,
-                       const char* aInterfaceName)
+ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
+                 const ErrNum aErrorNumber,
+                 const char* aInterfaceName)
 {
   NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName);
-  // This should only be called for DOM methods, which are JSNative-backed
-  // functions, so we can assume that JS_ValueToFunction and
-  // JS_GetFunctionDisplayId will both return non-null and that
-  // JS_GetStringCharsZ returns non-null.
+  // This should only be called for DOM methods/getters/setters, which
+  // are JSNative-backed functions, so we can assume that
+  // JS_ValueToFunction and JS_GetFunctionDisplayId will both return
+  // non-null and that JS_GetStringCharsZ returns non-null.
   JS::Rooted<JSFunction*> func(aCx, JS_ValueToFunction(aCx, aArgs.calleev()));
   MOZ_ASSERT(func);
   JS::Rooted<JSString*> funcName(aCx, JS_GetFunctionDisplayId(func));
   MOZ_ASSERT(funcName);
   JS_ReportErrorNumberUC(aCx, GetErrorMessage, nullptr,
-                         static_cast<const unsigned>(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE),
+                         static_cast<const unsigned>(aErrorNumber),
                          JS_GetStringCharsZ(aCx, funcName),
                          ifaceName.get());
   return false;
 }
 
-bool
-ThrowInvalidGetterThis(JSContext* aCx, const char* aInterfaceName)
-{
-  // Sadly for getters we have no way to get the name of the property.
-  NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName);
-  JS_ReportErrorNumberUC(aCx, GetErrorMessage, nullptr,
-                         static_cast<const unsigned>(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE),
-                         ifaceName.get());
-  return false;
-}
-
-bool
-ThrowInvalidSetterThis(JSContext* aCx, const char* aInterfaceName)
-{
-  // Sadly for setters we have no way to get the name of the property.
-  NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName);
-  JS_ReportErrorNumberUC(aCx, GetErrorMessage, nullptr,
-                         static_cast<const unsigned>(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE),
-                         ifaceName.get());
-  return false;
-}
-
 } // namespace dom
 
 struct ErrorResult::Message {
   nsTArray<nsString> mArgs;
   dom::ErrNum mErrorNumber;
 };
 
 void
@@ -845,28 +824,28 @@ XrayResolveAttribute(JSContext* cx, JS::
           const JSPropertySpec& attrSpec = attributeSpecs[i];
           // Because of centralization, we need to make sure we fault in the
           // JitInfos as well. At present, until the JSAPI changes, the easiest
           // way to do this is wrap them up as functions ourselves.
           desc->attrs = attrSpec.flags & ~JSPROP_NATIVE_ACCESSORS;
           // They all have getters, so we can just make it.
           JS::Rooted<JSObject*> global(cx, JS_GetGlobalForObject(cx, wrapper));
           JS::Rooted<JSFunction*> fun(cx,
-                                      JS_NewFunction(cx, (JSNative)attrSpec.getter.op,
-                                                     0, 0, global, nullptr));
+                                      JS_NewFunctionById(cx, (JSNative)attrSpec.getter.op,
+                                                         0, 0, global, id));
           if (!fun)
             return false;
           SET_JITINFO(fun, attrSpec.getter.info);
           JSObject *funobj = JS_GetFunctionObject(fun);
           desc->getter = js::CastAsJSPropertyOp(funobj);
           desc->attrs |= JSPROP_GETTER;
           if (attrSpec.setter.op) {
             // We have a setter! Make it.
-            fun = JS_NewFunction(cx, (JSNative)attrSpec.setter.op, 1, 0,
-                                 global, nullptr);
+            fun = JS_NewFunctionById(cx, (JSNative)attrSpec.setter.op, 1, 0,
+                                     global, id);
             if (!fun)
               return false;
             SET_JITINFO(fun, attrSpec.setter.info);
             funobj = JS_GetFunctionObject(fun);
             desc->setter = js::CastAsJSStrictPropertyOp(funobj);
             desc->attrs |= JSPROP_SETTER;
           } else {
             desc->setter = nullptr;
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -55,22 +55,19 @@ UnwrapArg(JSContext* cx, jsval v, Interf
                                     vp);
   *ppArgRef = static_cast<StrongRefType*>(argRef);
   return rv;
 }
 
 bool
 ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...);
 bool
-ThrowInvalidMethodThis(JSContext* aCx, const JS::CallArgs& aArgs,
-                       const char* aInterfaceName);
-bool
-ThrowInvalidGetterThis(JSContext* aCx, const char* aInterfaceName);
-bool
-ThrowInvalidSetterThis(JSContext* aCx, const char* aInterfaceName);
+ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
+                 const ErrNum aErrorNumber,
+                 const char* aInterfaceName);
 
 template<bool mainThread>
 inline bool
 Throw(JSContext* cx, nsresult rv)
 {
   using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
 
   // XXX Introduce exception machinery.
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -5180,17 +5180,17 @@ def MakeNativeName(name):
 class CGGenericMethod(CGAbstractBindingMethod):
     """
     A class for generating the C++ code for an IDL method..
     """
     def __init__(self, descriptor):
         args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'),
                 Argument('JS::Value*', 'vp')]
         unwrapFailureCode = (
-            'return ThrowInvalidMethodThis(cx, args, \"%s\");' %
+            'return ThrowInvalidThis(cx, args, MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, \"%s\");' %
             descriptor.interface.identifier.name)
         CGAbstractBindingMethod.__init__(self, descriptor, 'genericMethod',
                                          args,
                                          unwrapFailureCode=unwrapFailureCode)
 
     def generate_code(self):
         return CGIndenter(CGGeneric(
             "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
@@ -5317,17 +5317,17 @@ class CGGenericGetter(CGAbstractBindingM
                 "if (!ReportLenientThisUnwrappingFailure(cx, obj)) {\n"
                 "  return false;\n"
                 "}\n"
                 "args.rval().set(JS::UndefinedValue());\n"
                 "return true;")
         else:
             name = "genericGetter"
             unwrapFailureCode = (
-                'return ThrowInvalidGetterThis(cx, "%s");' %
+                'return ThrowInvalidThis(cx, args, MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "%s");' %
                 descriptor.interface.identifier.name)
         CGAbstractBindingMethod.__init__(self, descriptor, name, args,
                                          unwrapFailureCode)
 
     def generate_code(self):
         return CGIndenter(CGGeneric(
             "const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
             "MOZ_ASSERT(info->type == JSJitInfo::Getter);\n"
@@ -5397,17 +5397,17 @@ class CGGenericSetter(CGAbstractBindingM
                 "if (!ReportLenientThisUnwrappingFailure(cx, obj)) {\n"
                 "  return false;\n"
                 "}\n"
                 "args.rval().set(JS::UndefinedValue());\n"
                 "return true;")
         else:
             name = "genericSetter"
             unwrapFailureCode = (
-                'return ThrowInvalidSetterThis(cx, "%s");' %
+                'return ThrowInvalidThis(cx, args, MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "%s");' %
                 descriptor.interface.identifier.name)
 
         CGAbstractBindingMethod.__init__(self, descriptor, name, args,
                                          unwrapFailureCode)
 
     def generate_code(self):
         return CGIndenter(CGGeneric(
                 "if (args.length() == 0) {\n"
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -19,19 +19,19 @@
  * be replaced with a string value when the error is reported.
  */
 
 MSG_DEF(MSG_INVALID_ENUM_VALUE, 3, "{0} '{1}' is not a valid value for enumeration {2}.")
 MSG_DEF(MSG_MISSING_ARGUMENTS, 1, "Not enough arguments to {0}.")
 MSG_DEF(MSG_NOT_OBJECT, 1, "{0} is not an object.")
 MSG_DEF(MSG_NOT_CALLABLE, 1, "{0} is not callable.")
 MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, "{0} does not implement interface {1}.")
-MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "{0} called on an object that does not implement interface {1}.")
-MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "getter called on an object that does not implement interface {0}.")
-MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "setter called on an object that does not implement interface {0}.")
+MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' called on an object that does not implement interface {1}.")
+MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' getter called on an object that does not implement interface {1}.")
+MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' setter called on an object that does not implement interface {1}.")
 MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "\"this\" object does not implement interface {0}.")
 MSG_DEF(MSG_NOT_IN_UNION, 2, "{0} could not be converted to any of: {1}.")
 MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.")
 MSG_DEF(MSG_NO_PROPERTY_SETTER, 1, "{0} doesn't have an indexed property setter.")
 MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, "Non-finite value is out of range for {0}.")
 MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, "Value is out of range for {0}.")
 MSG_DEF(MSG_NOT_SEQUENCE, 1, "{0} can't be converted to a sequence.")
 MSG_DEF(MSG_NOT_DICTIONARY, 1, "{0} can't be converted to a dictionary.")
--- a/dom/bindings/test/Makefile.in
+++ b/dom/bindings/test/Makefile.in
@@ -70,16 +70,17 @@ MOCHITEST_FILES := \
   test_bug759621.html \
   test_queryInterface.html \
   test_exceptionThrowing.html \
   test_bug852846.html \
   test_bug862092.html \
   test_bug560072.html \
   test_lenientThis.html \
   test_ByteString.html \
+  test_exception_messages.html \
   $(NULL)
 
 MOCHITEST_CHROME_FILES = \
   test_bug775543.html \
   $(NULL)
 
 ifdef GNU_CC
 CXXFLAGS += -Wno-uninitialized
new file mode 100644
--- /dev/null
+++ b/dom/bindings/test/test_exception_messages.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=882653
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 882653</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 882653 **/
+  // Each test is a string to eval, the expected exception message, and the
+  // test description.
+  var tests = [
+      [ 'document.documentElement.appendChild.call({}, new Image())',
+        "'appendChild' called on an object that does not implement interface Node.",
+        "bogus method this object" ],
+      [ 'Object.getOwnPropertyDescriptor(Document.prototype, "documentElement").get.call({})',
+        "'documentElement' getter called on an object that does not implement interface Document.",
+        "bogus getter this object" ],
+      [ 'Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML").set.call({})',
+        "'innerHTML' setter called on an object that does not implement interface Element.",
+        "bogus setter this object" ],
+      [ 'document.documentElement.appendChild(5)',
+        "Argument 1 of Node.appendChild is not an object.",
+        "bogus interface argument" ],
+      [ 'document.documentElement.appendChild(null)',
+        "Argument 1 of Node.appendChild is not an object.",
+        "null interface argument" ],
+      [ 'document.createTreeWalker(document).currentNode = 5',
+        "Value being assigned to TreeWalker.currentNode is not an object.",
+        "interface setter call" ],
+      [ 'document.documentElement.appendChild({})',
+        "Argument 1 of Node.appendChild does not implement interface Node.",
+        "wrong interface argument" ],
+      [ 'document.createTreeWalker(document).currentNode = {}',
+        "Value being assigned to TreeWalker.currentNode does not implement interface Node.",
+        "wrong interface setter call" ],
+      [ 'document.createElement("canvas").getContext("2d").fill("bogus")',
+        "Argument 1 of CanvasRenderingContext2D.fill 'bogus' is not a valid value for enumeration CanvasWindingRule.",
+        "bogus enum value" ],
+      [ 'document.createTreeWalker(document, 0xFFFFFFFF, { acceptNode: 5 }).nextNode()',
+        "Property 'acceptNode' is not callable.",
+        "non-callable callback interface operation property" ],
+      [ '(new TextEncoder).encode("", new RegExp())',
+        "Argument 2 of TextEncoder.encode can't be converted to a dictionary.",
+        "regexp passed for a dictionary" ],
+      [ 'URL.createObjectURL(null, null)',
+        "Argument 1 is not valid for any of the 2-argument overloads of URL.createObjectURL.",
+        "overload resolution failure" ],
+      [ 'document.createElement("select").add({})',
+        "Argument 1 of HTMLSelectElement.add could not be converted to any of: HTMLOptionElement, HTMLOptGroupElement.",
+        "invalid value passed for union" ],
+      [ 'document.createElement("canvas").getContext("2d").createLinearGradient(0, 1, 0, 1).addColorStop(NaN, "")',
+        "Argument 1 of CanvasGradient.addColorStop is not a finite floating-point value.",
+        "invalid float" ]
+  ];
+
+  for (var i = 0; i < tests.length; ++i) {
+      msg = "Correct exception should be thrown for " + tests[i][2];
+      try {
+          eval(tests[i][0]);
+          ok(false, msg);
+      } catch (e) {
+          is(e.message, tests[i][1], msg);
+      }
+  }
+
+  </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=882653">Mozilla Bug 882653</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
--- a/dom/camera/DOMCameraControl.cpp
+++ b/dom/camera/DOMCameraControl.cpp
@@ -395,36 +395,40 @@ NS_IMETHODIMP
 nsDOMCameraControl::ReleaseHardware(nsICameraReleaseCallback* onSuccess, nsICameraErrorCallback* onError)
 {
   return mCameraControl->ReleaseHardware(onSuccess, onError);
 }
 
 class GetCameraResult : public nsRunnable
 {
 public:
-  GetCameraResult(nsDOMCameraControl* aDOMCameraControl, nsresult aResult, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId)
+  GetCameraResult(nsDOMCameraControl* aDOMCameraControl,
+    nsresult aResult,
+    const nsMainThreadPtrHandle<nsICameraGetCameraCallback>& onSuccess,
+    const nsMainThreadPtrHandle<nsICameraErrorCallback>& onError,
+    uint64_t aWindowId)
     : mDOMCameraControl(aDOMCameraControl)
     , mResult(aResult)
     , mOnSuccessCb(onSuccess)
     , mOnErrorCb(onError)
     , mWindowId(aWindowId)
   { }
 
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     if (nsDOMCameraManager::IsWindowStillActive(mWindowId)) {
       DOM_CAMERA_LOGT("%s : this=%p -- BEFORE CALLBACK\n", __func__, this);
       if (NS_FAILED(mResult)) {
-        if (mOnErrorCb) {
+        if (mOnErrorCb.get()) {
           mOnErrorCb->HandleEvent(NS_LITERAL_STRING("FAILURE"));
         }
       } else {
-        if (mOnSuccessCb) {
+        if (mOnSuccessCb.get()) {
           mOnSuccessCb->HandleEvent(mDOMCameraControl);
         }
       }
       DOM_CAMERA_LOGT("%s : this=%p -- AFTER CALLBACK\n", __func__, this);
     }
 
     /**
      * Finally, release the extra reference to the DOM-facing camera control.
@@ -437,23 +441,26 @@ public:
 
 protected:
   /**
    * 'mDOMCameraControl' is a raw pointer to a previously ADDREF()ed object,
    * which is released in Run().
    */
   nsDOMCameraControl* mDOMCameraControl;
   nsresult mResult;
-  nsCOMPtr<nsICameraGetCameraCallback> mOnSuccessCb;
-  nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
+  nsMainThreadPtrHandle<nsICameraGetCameraCallback> mOnSuccessCb;
+  nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
   uint64_t mWindowId;
 };
 
 nsresult
-nsDOMCameraControl::Result(nsresult aResult, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId)
+nsDOMCameraControl::Result(nsresult aResult,
+                           const nsMainThreadPtrHandle<nsICameraGetCameraCallback>& onSuccess,
+                           const nsMainThreadPtrHandle<nsICameraErrorCallback>& onError,
+                           uint64_t aWindowId)
 {
   nsCOMPtr<GetCameraResult> getCameraResult = new GetCameraResult(this, aResult, onSuccess, onError, aWindowId);
   return NS_DispatchToMainThread(getCameraResult);
 }
 
 void
 nsDOMCameraControl::Shutdown()
 {
--- a/dom/camera/DOMCameraControl.h
+++ b/dom/camera/DOMCameraControl.h
@@ -9,31 +9,35 @@
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "DictionaryHelpers.h"
 #include "ICameraControl.h"
 #include "DOMCameraPreview.h"
 #include "nsIDOMCameraManager.h"
 #include "CameraCommon.h"
 #include "AudioChannelAgent.h"
+#include "nsProxyRelease.h"
 
 namespace mozilla {
 
 // Main camera control.
 class nsDOMCameraControl : public nsICameraControl
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMCameraControl)
   NS_DECL_NSICAMERACONTROL
 
   nsDOMCameraControl(uint32_t aCameraId, nsIThread* aCameraThread,
                      nsICameraGetCameraCallback* onSuccess,
                      nsICameraErrorCallback* onError, uint64_t aWindowId);
-  nsresult Result(nsresult aResult, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId);
+  nsresult Result(nsresult aResult,
+                  const nsMainThreadPtrHandle<nsICameraGetCameraCallback>& onSuccess,
+                  const nsMainThreadPtrHandle<nsICameraErrorCallback>& onError,
+                  uint64_t aWindowId);
   nsRefPtr<ICameraControl> GetNativeCameraControl();
 
   void Shutdown();
 
 protected:
   virtual ~nsDOMCameraControl();
 
 private:
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -169,18 +169,18 @@ nsDOMCameraControl::nsDOMCameraControl(u
 
 // Initialize nsGonkCameraControl instance--runs on camera thread.
 class InitGonkCameraControl : public nsRunnable
 {
 public:
   InitGonkCameraControl(nsGonkCameraControl* aCameraControl, nsDOMCameraControl* aDOMCameraControl, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId)
     : mCameraControl(aCameraControl)
     , mDOMCameraControl(aDOMCameraControl)
-    , mOnSuccessCb(onSuccess)
-    , mOnErrorCb(onError)
+    , mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraGetCameraCallback>(onSuccess))
+    , mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
     , mWindowId(aWindowId)
   {
     DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
   }
 
   ~InitGonkCameraControl()
   {
     DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
@@ -190,18 +190,18 @@ public:
   {
     nsresult rv = mCameraControl->Init();
     return mDOMCameraControl->Result(rv, mOnSuccessCb, mOnErrorCb, mWindowId);
   }
 
   nsRefPtr<nsGonkCameraControl> mCameraControl;
   // Raw pointer to DOM-facing camera control--it must NS_ADDREF itself for us
   nsDOMCameraControl* mDOMCameraControl;
-  nsCOMPtr<nsICameraGetCameraCallback> mOnSuccessCb;
-  nsCOMPtr<nsICameraErrorCallback> mOnErrorCb;
+  nsMainThreadPtrHandle<nsICameraGetCameraCallback> mOnSuccessCb;
+  nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
   uint64_t mWindowId;
 };
 
 // Construct nsGonkCameraControl on the main thread.
 nsGonkCameraControl::nsGonkCameraControl(uint32_t aCameraId, nsIThread* aCameraThread, nsDOMCameraControl* aDOMCameraControl, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, uint64_t aWindowId)
   : CameraControlImpl(aCameraId, aCameraThread, aWindowId)
   , mExposureCompensationMin(0.0)
   , mExposureCompensationStep(0.0)
--- a/dom/locales/en-US/chrome/layout/css.properties
+++ b/dom/locales/en-US/chrome/layout/css.properties
@@ -15,16 +15,17 @@ PEExpectEndValue=Expected end of value b
 PERuleTrailing=Expected end of rule but found '%1$S'.
 PESkipAtRuleEOF2=end of at-rule
 PEUnknownAtRule=Unrecognized at-rule or error parsing at-rule '%1$S'.
 PECharsetRuleEOF=charset string in @charset rule
 PECharsetRuleNotString=Expected charset string but found '%1$S'.
 PEGatherMediaEOF=end of media list in @import or @media rule
 PEGatherMediaNotComma=Expected ',' in media list but found '%1$S'.
 PEGatherMediaNotIdent=Expected identifier in media list but found '%1$S'.
+PEGatherMediaReservedMediaType=Found reserved keyword '%1$S' when looking for media type.
 PEImportNotURI=Expected URI in @import rule but found '%1$S'.
 PEImportBadURI=Invalid URI in @import rule: '%1$S'.
 PEImportUnexpected=Found unexpected '%1$S' within @import.
 PEGroupRuleEOF2=end of @media, @supports or @-moz-document rule
 PEGroupRuleNestedAtRule=%1$S rule not allowed within @media or @-moz-document rule.
 PEMozDocRuleBadFunc=Expected url(), url-prefix(), or domain() in @-moz-document rule but found '%1$S'.
 PEMozDocRuleNotURI=Expected URI in @-moz-document rule but found '%1$S'.
 PEMozDocRuleNotString=Expected string in @-moz-document rule regexp() function but found '%1$S'.
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -3293,18 +3293,16 @@ nsPluginInstanceOwner::UpdateDocumentAct
 {
   mPluginDocumentActiveState = aIsActive;
   UpdateWindowPositionAndClipRect(true);
 
 #ifdef MOZ_WIDGET_ANDROID
   if (mInstance) {
     if (!mPluginDocumentActiveState)
       RemovePluginView();
-    else if (mPluginDocumentActiveState && mFullScreen)
-      AddPluginView();
 
     mInstance->NotifyOnScreen(mPluginDocumentActiveState);
 
     // This is, perhaps, incorrect. It is supposed to be sent
     // when "the webview has paused or resumed". The side effect
     // is that Flash video players pause or resume (if they were
     // playing before) based on the value here. I personally think
     // we want that on Android when switching to another tab, so
--- a/dom/webidl/DOMStringMap.webidl
+++ b/dom/webidl/DOMStringMap.webidl
@@ -6,14 +6,15 @@
  * The origin of this IDL file is
  * http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#domstringmap-0
  *
  * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
  * Opera Software ASA. You are granted a license to use, reproduce
  * and create derivative works of this document.
  */
 
+[OverrideBuiltins]
 interface DOMStringMap {
   getter DOMString (DOMString name);
   [Throws]
   setter creator void (DOMString name, DOMString value);
   deleter void (DOMString name);
 };
--- a/dom/webidl/DOMTokenList.webidl
+++ b/dom/webidl/DOMTokenList.webidl
@@ -15,11 +15,11 @@ interface DOMTokenList {
   getter DOMString? item(unsigned long index);
   [Throws]
   boolean contains(DOMString token);
   [Throws]
   void add(DOMString token);
   [Throws]
   void remove(DOMString token);
   [Throws]
-  boolean toggle(DOMString token);
+  boolean toggle(DOMString token, optional boolean force);
   stringifier DOMString ();
 };
--- a/editor/reftests/reftest.list
+++ b/editor/reftests/reftest.list
@@ -103,8 +103,25 @@ needs-focus == 824080-2.html 824080-2-re
 needs-focus == 824080-3.html 824080-3-ref.html
 needs-focus != 824080-2.html 824080-3.html
 needs-focus == 824080-4.html 824080-4-ref.html
 needs-focus == 824080-5.html 824080-5-ref.html
 needs-focus != 824080-4.html 824080-5.html
 needs-focus == 824080-6.html 824080-6-ref.html
 needs-focus == 824080-7.html 824080-7-ref.html
 needs-focus != 824080-6.html 824080-7.html
+# Bug 674927: copy spellcheck-textarea tests to contenteditable
+== spellcheck-contenteditable-attr.html spellcheck-contenteditable-nofocus-ref.html
+fails-if(Android) != spellcheck-contenteditable-attr.html spellcheck-contenteditable-ref.html
+needs-focus == spellcheck-contenteditable-focused.html spellcheck-contenteditable-ref.html
+needs-focus == spellcheck-contenteditable-focused-reframe.html spellcheck-contenteditable-ref.html
+== spellcheck-contenteditable-nofocus.html spellcheck-contenteditable-disabled-ref.html
+fails-if(!Android) == spellcheck-contenteditable-disabled.html spellcheck-contenteditable-disabled-ref.html
+fails-if(!Android) == spellcheck-contenteditable-disabled-partial.html spellcheck-contenteditable-disabled-partial-ref.html
+== spellcheck-contenteditable-attr-inherit.html spellcheck-contenteditable-disabled-ref.html
+== spellcheck-contenteditable-attr-dynamic.html spellcheck-contenteditable-disabled-ref.html
+== spellcheck-contenteditable-attr-dynamic-inherit.html spellcheck-contenteditable-disabled-ref.html
+== spellcheck-contenteditable-property-dynamic.html spellcheck-contenteditable-disabled-ref.html
+== spellcheck-contenteditable-property-dynamic-inherit.html spellcheck-contenteditable-disabled-ref.html
+== spellcheck-contenteditable-attr-dynamic-override.html spellcheck-contenteditable-disabled-ref.html
+== spellcheck-contenteditable-attr-dynamic-override-inherit.html spellcheck-contenteditable-disabled-ref.html
+== spellcheck-contenteditable-property-dynamic-override.html spellcheck-contenteditable-disabled-ref.html
+== spellcheck-contenteditable-property-dynamic-override-inherit.html spellcheck-contenteditable-disabled-ref.html
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-attr-dynamic-inherit.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body onload="init()">
+    <div contenteditable>blahblahblah</div>
+    <script>
+      function init() {
+        document.body.setAttribute("spellcheck", "false");
+      }
+    </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-attr-dynamic-override-inherit.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body onload="init()" spellcheck="true">
+    <div contenteditable>blahblahblah</div>
+    <script>
+      function init() {
+        document.body.setAttribute("spellcheck", "false");
+      }
+    </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-attr-dynamic-override.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body onload="init()">
+    <div contenteditable spellcheck="true">blahblahblah</div>
+    <script>
+      function init() {
+        document.querySelector("div").setAttribute("spellcheck", "false");
+      }
+    </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-attr-dynamic.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body onload="init()">
+    <div contenteditable>blahblahblah</div>
+    <script>
+      function init() {
+        document.querySelector("div").setAttribute("spellcheck", "false");
+      }
+    </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-attr-inherit.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+    <span spellcheck="false"><div contenteditable>blahblahblah</div></span>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-attr.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <div contenteditable>blahblahblah</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-disabled-partial-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <span contenteditable>sakde</span> kreid <span contenteditable>slodv</span>
+  <script>
+    // Adding focus to the textbox should trigger a spellcheck
+    document.querySelector("span").focus();
+    document.querySelector("span + span").focus();
+    document.querySelector("span + span").blur();
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-disabled-partial.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <div contenteditable>sakde <span spellcheck=false>kreid</span> slodv</div>
+  <script>
+    // Adding focus to the textbox should trigger a spellcheck
+    document.querySelector("div").focus();
+    document.querySelector("div").blur();
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-disabled-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <div>blahblahblah</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-disabled.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <div contenteditable spellcheck="false">blahblahblah</div>
+  <script>
+    // Adding focus to the textbox should trigger a spellcheck
+    document.querySelector("div").focus();
+    document.querySelector("div").blur();
+  </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-focused-reframe.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+  <div contenteditable id="testBox" onfocus="reframe(this);">blahblahblah</div>
+  <script type="text/javascript">
+    function reframe(textbox) {
+      textbox.style.display = "none";
+      textbox.style.display = "";
+      textbox.clientWidth;
+    }
+    //Adding focus to the textbox should trigger a spellcheck
+    document.getElementById("testBox").focus();
+    document.getElementById("testBox").blur();
+  </script>
+  
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-focused.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+  <div contenteditable id="testBox">blahblahblah</div>
+  <script type="text/javascript">
+    //Adding focus to the textbox should trigger a spellcheck
+    document.getElementById("testBox").focus();
+    document.getElementById("testBox").blur();
+  </script>
+  
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-nofocus-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <div contenteditable spellcheck="true">blahblahblah</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-nofocus.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <div contenteditable>blahblahblah</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-property-dynamic-inherit.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body onload="init()">
+    <div contenteditable>blahblahblah</div>
+    <script>
+      function init() {
+        document.body.spellcheck = false;
+      }
+    </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-property-dynamic-override-inherit.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body onload="init()" spellcheck="true">
+    <div contenteditable>blahblahblah</div>
+    <script>
+      function init() {
+        document.body.spellcheck = false;
+      }
+    </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-property-dynamic-override.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body onload="init()">
+    <div contenteditable spellcheck="true">blahblahblah</div>
+    <script>
+      function init() {
+        document.querySelector("div").spellcheck = false;
+      }
+    </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-property-dynamic.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body onload="init()">
+    <div contenteditable>blahblahblah</div>
+    <script>
+      function init() {
+        document.querySelector("div").spellcheck = false;
+      }
+    </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/editor/reftests/spellcheck-contenteditable-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <div contenteditable spellcheck="true">blahblahblah</div>
+  <script type="text/javascript">
+    var box = document.getElementsByTagName("div")[0];
+    box.focus(); //Bring the textbox into focus, triggering a spellcheck
+    box.blur(); //Blur in order to make things similar to other tests otherwise
+  </script>
+</body>
+</html>
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -81,16 +81,18 @@ static const char *sExtensionNames[] = {
     "GL_ARB_robustness",
     "GL_EXT_robustness",
     "GL_ARB_sync",
     "GL_OES_EGL_image",
     "GL_OES_EGL_sync",
     "GL_OES_EGL_image_external",
     "GL_EXT_packed_depth_stencil",
     "GL_OES_element_index_uint",
+    "GL_OES_vertex_array_object",
+    "GL_ARB_vertex_array_object",
     nullptr
 };
 
 static int64_t sTextureMemoryUsage = 0;
 
 static int64_t
 GetTextureMemoryUsage()
 {
@@ -543,16 +545,36 @@ GLContext::InitWithPrefix(const char *pr
                 NS_ERROR("GL supports OES_EGL_image without supplying its functions.");
 
                 MarkExtensionUnsupported(OES_EGL_image);
                 mSymbols.fEGLImageTargetTexture2D = nullptr;
                 mSymbols.fEGLImageTargetRenderbufferStorage = nullptr;
             }
         }
 
+        if (IsExtensionSupported(OES_vertex_array_object)) {
+            SymLoadStruct vaoSymbols[] = {
+                { (PRFuncPtr*) &mSymbols.fIsVertexArray, { "IsVertexArray", "IsVertexArrayOES", nullptr } },
+                { (PRFuncPtr*) &mSymbols.fGenVertexArrays, { "GenVertexArrays", "GenVertexArraysOES", nullptr } },
+                { (PRFuncPtr*) &mSymbols.fBindVertexArray, { "BindVertexArrays", "BindVertexArrayOES", nullptr } },
+                { (PRFuncPtr*) &mSymbols.fDeleteVertexArrays, { "DeleteVertexArrays", "DeleteVertexArraysOES", nullptr } },
+                { nullptr, { nullptr } },
+            };
+
+            if (!LoadSymbols(&vaoSymbols[0], trygl, prefix)) {
+                NS_ERROR("GL supports Vertex Array Object without supplying its functions.");
+
+                MarkExtensionUnsupported(OES_vertex_array_object);
+                mSymbols.fIsVertexArray = nullptr;
+                mSymbols.fGenVertexArrays = nullptr;
+                mSymbols.fBindVertexArray = nullptr;
+                mSymbols.fDeleteVertexArrays = nullptr;
+            }
+        }
+
         // Load developer symbols, don't fail if we can't find them.
         SymLoadStruct auxSymbols[] = {
                 { (PRFuncPtr*) &mSymbols.fGetTexImage, { "GetTexImage", nullptr } },
                 { (PRFuncPtr*) &mSymbols.fGetTexLevelParameteriv, { "GetTexLevelParameteriv", nullptr } },
                 { nullptr, { nullptr } },
         };
         bool warnOnFailures = DebugMode();
         LoadSymbols(&auxSymbols[0], trygl, prefix, warnOnFailures);
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -1019,16 +1019,18 @@ public:
         ARB_robustness,
         EXT_robustness,
         ARB_sync,
         OES_EGL_image,
         OES_EGL_sync,
         OES_EGL_image_external,
         EXT_packed_depth_stencil,
         OES_element_index_uint,
+        OES_vertex_array_object,
+        ARB_vertex_array_object,
         Extensions_Max
     };
 
     bool IsExtensionSupported(GLExtensions aKnownExtension) const {
         return mAvailableExtensions[aKnownExtension];
     }
 
     void MarkExtensionUnsupported(GLExtensions aKnownExtension) {
@@ -2865,16 +2867,49 @@ public:
     void fEGLImageTargetRenderbufferStorage(GLenum target, GLeglImage image)
     {
         BEFORE_GL_CALL;
         ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage);
         mSymbols.fEGLImageTargetRenderbufferStorage(target, image);
         AFTER_GL_CALL;
     }
 
+    void GLAPIENTRY fBindVertexArray(GLuint array)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fBindVertexArray);
+        mSymbols.fBindVertexArray(array);
+        AFTER_GL_CALL;
+    }
+
+    void GLAPIENTRY fDeleteVertexArrays(GLsizei n, const GLuint *arrays)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fDeleteVertexArrays);
+        mSymbols.fDeleteVertexArrays(n, arrays);
+        AFTER_GL_CALL;
+    }
+
+    void GLAPIENTRY fGenVertexArrays(GLsizei n, GLuint *arrays)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fGenVertexArrays);
+        mSymbols.fGenVertexArrays(n, arrays);
+        AFTER_GL_CALL;
+    }
+
+    realGLboolean GLAPIENTRY fIsVertexArray(GLuint array)
+    {
+        BEFORE_GL_CALL;
+        ASSERT_SYMBOL_PRESENT(fIsVertexArray);
+        realGLboolean ret = mSymbols.fIsVertexArray(array);
+        AFTER_GL_CALL;
+        return ret;
+    }
+
 #undef ASSERT_SYMBOL_PRESENT
 
 #ifdef DEBUG
     void CreatedProgram(GLContext *aOrigin, GLuint aName);
     void CreatedShader(GLContext *aOrigin, GLuint aName);
     void CreatedBuffers(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void CreatedQueries(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
     void CreatedTextures(GLContext *aOrigin, GLsizei aCount, GLuint *aNames);
--- a/gfx/gl/GLContextSymbols.h
+++ b/gfx/gl/GLContextSymbols.h
@@ -42,16 +42,18 @@ struct GLContextSymbols
     typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
     PFNGLBEGINQUERYPROC fBeginQuery;
     typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name);
     PFNGLBINDATTRIBLOCATIONPROC fBindAttribLocation;
     typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
     PFNGLBINDBUFFERPROC fBindBuffer;
     typedef void (GLAPIENTRY * PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
     PFNGLBINDTEXTUREPROC fBindTexture;
+    typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array);
+    PFNGLBINDVERTEXARRAYPROC fBindVertexArray;
     typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
     PFNGLBLENDCOLORPROC fBlendColor;
     typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode);
     PFNGLBLENDEQUATIONPROC fBlendEquation;
     typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum, GLenum);
     PFNGLBLENDEQUATIONSEPARATEPROC fBlendEquationSeparate;
     typedef void (GLAPIENTRY * PFNGLBLENDFUNCPROC) (GLenum, GLenum);
     PFNGLBLENDFUNCPROC fBlendFunc;
@@ -297,16 +299,18 @@ struct GLContextSymbols
     typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIV) (GLenum target, GLenum attachment, GLenum pname, GLint* value);
     PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIV fGetFramebufferAttachmentParameteriv;
     typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIV) (GLenum target, GLenum pname, GLint* value);
     PFNGLGETRENDERBUFFERPARAMETERIV fGetRenderbufferParameteriv;
     typedef realGLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFER) (GLuint framebuffer);
     PFNGLISFRAMEBUFFER fIsFramebuffer;
     typedef realGLboolean (GLAPIENTRY * PFNGLISRENDERBUFFER) (GLuint renderbuffer);
     PFNGLISRENDERBUFFER fIsRenderbuffer;
+    typedef realGLboolean (GLAPIENTRY * PFNGLISVERTEXARRAY) (GLuint array);
+    PFNGLISVERTEXARRAY fIsVertexArray;
     typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGE) (GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
     PFNGLRENDERBUFFERSTORAGE fRenderbufferStorage;
 
     typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFER) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
     PFNGLBLITFRAMEBUFFER fBlitFramebuffer;
     typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLE) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height);
     PFNGLRENDERBUFFERSTORAGEMULTISAMPLE fRenderbufferStorageMultisample;
 
@@ -349,31 +353,35 @@ struct GLContextSymbols
     typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* queries);
     PFNGLGENQUERIESPROC fGenQueries;
     typedef void (GLAPIENTRY * PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
     PFNGLGENTEXTURESPROC fGenTextures;
     typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERS) (GLsizei n, GLuint* ids);
     PFNGLGENFRAMEBUFFERS fGenFramebuffers;
     typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERS) (GLsizei n, GLuint* ids);
     PFNGLGENRENDERBUFFERS fGenRenderbuffers;
+    typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYS) (GLsizei n, GLuint* arrays);
+    PFNGLGENVERTEXARRAYS fGenVertexArrays;
 
     typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program);
     PFNGLDELETEPROGRAMPROC fDeleteProgram;
     typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader);
     PFNGLDELETESHADERPROC fDeleteShader;
     typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers);
     PFNGLDELETEBUFFERSPROC fDeleteBuffers;
     typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* queries);
     PFNGLDELETEQUERIESPROC fDeleteQueries;
     typedef void (GLAPIENTRY * PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint* textures);
     PFNGLDELETETEXTURESPROC fDeleteTextures;
     typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERS) (GLsizei n, const GLuint* ids);
     PFNGLDELETEFRAMEBUFFERS fDeleteFramebuffers;
     typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERS) (GLsizei n, const GLuint* ids);
     PFNGLDELETERENDERBUFFERS fDeleteRenderbuffers;
+    typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYS) (GLsizei n, const GLuint* arrays);
+    PFNGLDELETEVERTEXARRAYS fDeleteVertexArrays;
 
     typedef void* (GLAPIENTRY * PFNGLMAPBUFFER) (GLenum target, GLenum access);
     PFNGLMAPBUFFER fMapBuffer;
     typedef realGLboolean (GLAPIENTRY * PFNGLUNMAPBUFFER) (GLenum target);
     PFNGLUNMAPBUFFER fUnmapBuffer;
 
     typedef GLenum (GLAPIENTRY * PFNGLGETGRAPHICSRESETSTATUS) (void);
     PFNGLGETGRAPHICSRESETSTATUS fGetGraphicsResetStatus;
--- a/gfx/thebes/gfxFT2Utils.cpp
+++ b/gfx/thebes/gfxFT2Utils.cpp
@@ -112,20 +112,22 @@ gfxFT2LockedFace::GetMetrics(gfxFont::Me
         aMetrics->emAscent = os2->sTypoAscender * yScale;
         aMetrics->emDescent = -os2->sTypoDescender * yScale;
         FT_Short typoHeight =
             os2->sTypoAscender - os2->sTypoDescender + os2->sTypoLineGap;
         lineHeight = typoHeight * yScale;
 
         // maxAscent/maxDescent get used for frame heights, and some fonts
         // don't have the HHEA table ascent/descent set (bug 279032).
-        if (aMetrics->emAscent > aMetrics->maxAscent)
-            aMetrics->maxAscent = aMetrics->emAscent;
-        if (aMetrics->emDescent > aMetrics->maxDescent)
-            aMetrics->maxDescent = aMetrics->emDescent;
+        // We use NS_round here to parallel the pixel-rounded values that
+        // freetype gives us for ftMetrics.ascender/descender.
+        aMetrics->maxAscent =
+            std::max(aMetrics->maxAscent, NS_round(aMetrics->emAscent));
+        aMetrics->maxDescent =
+            std::max(aMetrics->maxDescent, NS_round(aMetrics->emDescent));
     } else {
         aMetrics->emAscent = aMetrics->maxAscent;
         aMetrics->emDescent = aMetrics->maxDescent;
         lineHeight = FLOAT_FROM_26_6(ftMetrics.height);
     }
 
     cairo_text_extents_t extents;
     *aSpaceGlyph = GetCharExtents(' ', &extents);
--- a/js/jsd/jsd_lock.cpp
+++ b/js/jsd/jsd_lock.cpp
@@ -4,17 +4,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/. */
 
 /*
  * JavaScript Debugging support - Locking and threading support
  */
 
 /*                                                                           
-* ifdef JSD_USE_NSPR_LOCKS then you musat build and run against NSPR2.       
+* ifdef JSD_USE_NSPR_LOCKS then you must build and run against NSPR2.       
 * Otherwise, there are stubs that can be filled in with your own locking     
 * code. Also, note that these stubs include a jsd_CurrentThread()            
 * implementation that only works on Win32 - this is needed for the inprocess 
 * Java-based debugger.                                                       
 */                                                                           
 
 #include "jsd.h"
 
--- a/js/jsd/jsd_text.cpp
+++ b/js/jsd/jsd_text.cpp
@@ -167,17 +167,17 @@ strncasecomp (const char* one, const cha
         if (!(*pA && *pB)) 
             return *pA - *pB;
         tmp = tolower(*pA) - tolower(*pB);
         if (tmp) 
             return tmp;
     }
 }
 
-static char file_url_prefix[]    = "file:";
+static const char file_url_prefix[] = "file:";
 #define FILE_URL_PREFIX_LEN     (sizeof file_url_prefix - 1)
 
 char*
 jsd_BuildNormalizedURL( const char* url_string )
 {
     char *new_url_string;
 
     if( ! url_string )
--- a/js/src/TraceLogging.cpp
+++ b/js/src/TraceLogging.cpp
@@ -56,17 +56,17 @@ js::rdtsc(void)
     result = upper;
     result = result<<32;
     result = result|lower;
 
     return(result);
 }
 #endif
 
-const char* TraceLogging::type_name[] = {
+const char* const TraceLogging::type_name[] = {
     "start,ion_compile",
     "stop,ion_compile",
     "start,ion_cannon",
     "stop,ion_cannon",
     "stop,ion_cannon_bailout",
     "start,ion_side_cannon",
     "stop,ion_side_cannon",
     "stop,ion_side_cannon_bailout",
--- a/js/src/TraceLogging.h
+++ b/js/src/TraceLogging.h
@@ -56,17 +56,17 @@ class TraceLogging
 
     uint64_t loggingTime;
     Entry *entries;
     unsigned int curEntry;
     unsigned int numEntries;
     int fileno;
     FILE *out;
 
-    const static char *type_name[];
+    static const char * const type_name[];
     static TraceLogging* _defaultLogger;
   public:
     TraceLogging();
     ~TraceLogging();
 
     void log(Type type, const char* filename, unsigned int line);
     void log(Type type, JSScript* script);
     void log(const char* log);
--- a/js/src/assembler/assembler/ARMAssembler.h
+++ b/js/src/assembler/assembler/ARMAssembler.h
@@ -1198,46 +1198,46 @@ namespace JSC {
             return AL | B | (offset & BRANCH_MASK);
         }
 
         // pretty-printing functions
         static char const * nameGpReg(int reg)
         {
             ASSERT(reg <= 16);
             ASSERT(reg >= 0);
-            static char const * names[] = {
+            static char const * const names[] = {
                 "r0", "r1", "r2", "r3",
                 "r4", "r5", "r6", "r7",
                 "r8", "r9", "r10", "r11",
                 "ip", "sp", "lr", "pc"
             };
             return names[reg];
         }
 
         static char const * nameFpRegD(int reg)
         {
             ASSERT(reg <= 31);
             ASSERT(reg >= 0);
-            static char const * names[] = {
+            static char const * const names[] = {
                  "d0",   "d1",   "d2",   "d3",
                  "d4",   "d5",   "d6",   "d7",
                  "d8",   "d9",  "d10",  "d11",
                 "d12",  "d13",  "d14",  "d15",
                 "d16",  "d17",  "d18",  "d19",
                 "d20",  "d21",  "d22",  "d23",
                 "d24",  "d25",  "d26",  "d27",
                 "d28",  "d29",  "d30",  "d31"
             };
             return names[reg];
         }
         static char const * nameFpRegS(int reg)
         {
             ASSERT(reg <= 31);
             ASSERT(reg >= 0);
-            static char const * names[] = {
+            static char const * const names[] = {
                  "s0",   "s1",   "s2",   "s3",
                  "s4",   "s5",   "s6",   "s7",
                  "s8",   "s9",  "s10",  "s11",
                 "s12",  "s13",  "s14",  "s15",
                 "s16",  "s17",  "s18",  "s19",
                 "s20",  "s21",  "s22",  "s23",
                 "s24",  "s25",  "s26",  "s27",
                 "s28",  "s29",  "s30",  "s31"
@@ -1246,17 +1246,17 @@ namespace JSC {
         }
 
         static char const * nameCC(Condition cc)
         {
             ASSERT(cc <= AL);
             ASSERT((cc & 0x0fffffff) == 0);
 
             uint32_t    ccIndex = cc >> 28;
-            static char const * names[] = {
+            static char const * const names[] = {
                 "eq", "ne",
                 "cs", "cc",
                 "mi", "pl",
                 "vs", "vc",
                 "hi", "ls",
                 "ge", "lt",
                 "gt", "le",
                 "  "        // AL is the default, so don't show it.
--- a/js/src/assembler/assembler/AbstractMacroAssembler.h
+++ b/js/src/assembler/assembler/AbstractMacroAssembler.h
@@ -152,22 +152,22 @@ public:
         int32_t offset;
     };
 
     // AbsoluteAddress:
     //
     // Describes an memory operand given by a pointer.  For regular load & store
     // operations an unwrapped void* will be used, rather than using this.
     struct AbsoluteAddress {
-        explicit AbsoluteAddress(void* ptr)
+        explicit AbsoluteAddress(const void* ptr)
             : m_ptr(ptr)
         {
         }
 
-        void* m_ptr;
+        const void* m_ptr;
     };
 
     // TrustedImmPtr:
     //
     // A pointer sized immediate operand to an instruction - this is wrapped
     // in a class requiring explicit construction in order to differentiate
     // from pointers used as absolute addresses to memory operations
     struct TrustedImmPtr {
@@ -403,22 +403,22 @@ public:
         {
         }
         
         Jump(JmpSrc jmp)    
             : m_jmp(jmp)
         {
         }
         
-        void link(AbstractMacroAssembler<AssemblerType>* masm)
+        void link(AbstractMacroAssembler<AssemblerType>* masm) const
         {
             masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label());
         }
         
-        void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
+        void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const
         {
             masm->m_assembler.linkJump(m_jmp, label.m_label);
         }
 
         bool isSet() const { return m_jmp.isSet(); }
 
     private:
         JmpSrc m_jmp;
--- a/js/src/assembler/assembler/MacroAssemblerARM.h
+++ b/js/src/assembler/assembler/MacroAssemblerARM.h
@@ -1024,17 +1024,17 @@ public:
     {
         m_assembler.ldr_un_imm(ARMRegisters::S1, reinterpret_cast<ARMWord>(address.m_ptr));
         m_assembler.dtr_u(true, ARMRegisters::S1, ARMRegisters::S1, 0);
         sub32(imm, ARMRegisters::S1);
         m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address.m_ptr));
         m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0);
     }
 
-    void load32(void* address, RegisterID dest)
+    void load32(const void* address, RegisterID dest)
     {
         m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
         m_assembler.dtr_u(true, dest, ARMRegisters::S0, 0);
     }
 
     Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
     {
         load32(left.m_ptr, ARMRegisters::S1);
--- a/js/src/assembler/assembler/MacroAssemblerARMv7.h
+++ b/js/src/assembler/assembler/MacroAssemblerARMv7.h
@@ -428,17 +428,17 @@ public:
         load32(setupArmAddress(address), dest);
     }
 
     void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
     {
         load32(setupArmAddress(address), dest);
     }
 
-    void load32(void* address, RegisterID dest)
+    void load32(const void* address, RegisterID dest)
     {
         move(ImmPtr(address), addressTempRegister);
         m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
     }
 
     void load8(ImplicitAddress address, RegisterID dest)
     {
         load8(setupArmAddress(address), dest);
--- a/js/src/assembler/assembler/MacroAssemblerCodeRef.h
+++ b/js/src/assembler/assembler/MacroAssemblerCodeRef.h
@@ -151,17 +151,17 @@ public:
     }
 #if WTF_CPU_ARM_THUMB2
     // To use this pointer as a data address remove the decoration.
     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
 #else
     void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
 #endif
 
-    bool operator!()
+    bool operator!() const
     {
         return !m_value;
     }
 
     ptrdiff_t operator -(const MacroAssemblerCodePtr &other) const
     {
         JS_ASSERT(m_value);
         return reinterpret_cast<uint8_t *>(m_value) -
--- a/js/src/assembler/assembler/MacroAssemblerMIPS.h
+++ b/js/src/assembler/assembler/MacroAssemblerMIPS.h
@@ -856,17 +856,17 @@ public:
             m_assembler.lwr(dest, addrTempRegister, 3);
 #else
             m_assembler.lwl(dest, addrTempRegister, 3);
             m_assembler.lwr(dest, addrTempRegister, 0);
 #endif
         }
     }
 
-    void load32(void* address, RegisterID dest)
+    void load32(const void* address, RegisterID dest)
     {
         /*
             li  addrTemp, address
             lw  dest, 0(addrTemp)
         */
         move(ImmPtr(address), addrTempRegister);
         m_assembler.lw(dest, addrTempRegister, 0);
     }
--- a/js/src/assembler/assembler/MacroAssemblerSparc.h
+++ b/js/src/assembler/assembler/MacroAssemblerSparc.h
@@ -1019,17 +1019,17 @@ namespace JSC {
 
         void sub32(TrustedImm32 imm, AbsoluteAddress address)
         {
             load32(address.m_ptr, SparcRegisters::g2);
             sub32(imm, SparcRegisters::g2);
             store32(SparcRegisters::g2, address.m_ptr);
         }
 
-        void load32(void* address, RegisterID dest)
+        void load32(const void* address, RegisterID dest)
         {
             m_assembler.move_nocheck((int)address, SparcRegisters::g3);
             m_assembler.lduw_r(SparcRegisters::g3, SparcRegisters::g0, dest);
         }
 
         Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
         {
             load32(left.m_ptr, SparcRegisters::g2);
--- a/js/src/assembler/assembler/MacroAssemblerX86_64.h
+++ b/js/src/assembler/assembler/MacroAssemblerX86_64.h
@@ -81,17 +81,17 @@ public:
     }
 
     void sub32(TrustedImm32 imm, AbsoluteAddress address)
     {
         move(ImmPtr(address.m_ptr), scratchRegister);
         sub32(imm, Address(scratchRegister));
     }
 
-    void load32(void* address, RegisterID dest)
+    void load32(const void* address, RegisterID dest)
     {
         if (dest == X86Registers::eax)
             m_assembler.movl_mEAX(address);
         else {
             move(ImmPtr(address), scratchRegister);
             load32(ImplicitAddress(scratchRegister), dest);
         }
     }
@@ -100,17 +100,17 @@ public:
     {
         DataLabelPtr label = moveWithPatch(ImmPtr(address), scratchRegister);
         loadDouble(scratchRegister, dest);
         return label;
     }
 
     void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
     {
-        move(Imm32(*static_cast<int32_t*>(src.m_ptr)), scratchRegister);
+        move(Imm32(*static_cast<const int32_t*>(src.m_ptr)), scratchRegister);
         m_assembler.cvtsi2sd_rr(scratchRegister, dest);
     }
 
     void convertUInt32ToDouble(RegisterID srcDest, FPRegisterID dest)
     {
         zeroExtend32ToPtr(srcDest, srcDest);
         zeroDouble(dest); // break dependency chains
         m_assembler.cvtsq2sd_rr(srcDest, dest);
@@ -292,17 +292,17 @@ public:
         m_assembler.movq_mr(address.offset, address.base, dest);
     }
 
     void loadPtr(BaseIndex address, RegisterID dest)
     {
         m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
     }
 
-    void loadPtr(void* address, RegisterID dest)
+    void loadPtr(const void* address, RegisterID dest)
     {
         if (dest == X86Registers::eax)
             m_assembler.movq_mEAX(address);
         else {
             move(ImmPtr(address), scratchRegister);
             loadPtr(ImplicitAddress(scratchRegister), dest);
         }
     }
--- a/js/src/assembler/assembler/SparcAssembler.h
+++ b/js/src/assembler/assembler/SparcAssembler.h
@@ -1135,34 +1135,34 @@ namespace JSC {
             ExecutableAllocator::cacheFlush(where, 4);
         }
 
     private:
         static char const * nameGpReg(int reg)
         {
             ASSERT(reg <= 31);
             ASSERT(reg >= 0);
-            static char const * names[] = {
+            static char const * const names[] = {
                 "%g0", "%g1", "%g2", "%g3",
                 "%g4", "%g5", "%g6", "%g7",
                 "%o0", "%o1", "%o2", "%o3",
                 "%o4", "%o5", "%sp", "%o7",
                 "%l0", "%l1", "%l2", "%l3",
                 "%l4", "%l5", "%l6", "%l7",
                 "%i0", "%i1", "%i2", "%i3",
                 "%i4", "%i5", "%fp", "%i7"
             };
             return names[reg];
         }
 
         static char const * nameFpReg(int reg)
         {
             ASSERT(reg <= 31);
             ASSERT(reg >= 0);
-            static char const * names[] = {
+            static char const * const names[] = {
                 "%f0",   "%f1",   "%f2",   "%f3",
                 "%f4",   "%f5",   "%f6",   "%f7",
                 "%f8",   "%f9",  "%f10",  "%f11",
                 "%f12",  "%f13",  "%f14",  "%f15",
                 "%f16",  "%f17",  "%f18",  "%f19",
                 "%f20",  "%f21",  "%f22",  "%f23",
                 "%f24",  "%f25",  "%f26",  "%f27",
                 "%f28",  "%f29",  "%f30",  "%f31"
@@ -1171,17 +1171,17 @@ namespace JSC {
         }
 
         static char const * nameICC(Condition cc)
         {
             ASSERT(cc <= ConditionVC);
             ASSERT(cc >= 0);
 
             uint32_t    ccIndex = cc;
-            static char const * inames[] = {
+            static char const * const inames[] = {
                 "   ", "e  ",
                 "le ", "l  ",
                 "leu", "cs ",
                 "neg", "vs ",
                 "a  ", "ne ",
                 "g  ", "ge ",
                 "gu ", "cc ",
                 "   ", "vc "
@@ -1190,17 +1190,17 @@ namespace JSC {
         }
 
         static char const * nameFCC(DoubleCondition cc)
         {
             ASSERT(cc <= DoubleConditionULE);
             ASSERT(cc >= 0);
 
             uint32_t    ccIndex = cc;
-            static char const * fnames[] = {
+            static char const * const fnames[] = {
                 "   ", "ne ",
                 "   ", "ul ",
                 "l  ", "ug ",
                 "g  ", "   ",
                 "   ", "e  ",
                 "ue ", "ge ",
                 "ugu", "le ",
                 "ule", "   "
--- a/js/src/assembler/assembler/X86Assembler.h
+++ b/js/src/assembler/assembler/X86Assembler.h
@@ -89,41 +89,41 @@ namespace X86Registers {
         xmm14,
         xmm15
 #endif
        ,invalid_xmm
     } XMMRegisterID;
 
     static const char* nameFPReg(XMMRegisterID fpreg)
     {
-        static const char* xmmnames[16]
+        static const char* const xmmnames[16]
           = { "%xmm0", "%xmm1", "%xmm2", "%xmm3",
               "%xmm4", "%xmm5", "%xmm6", "%xmm7",
               "%xmm8", "%xmm9", "%xmm10", "%xmm11",
               "%xmm12", "%xmm13", "%xmm14", "%xmm15" };
         int off = (XMMRegisterID)fpreg - (XMMRegisterID)xmm0;
         return (off < 0 || off > 15) ? "%xmm?" : xmmnames[off];
     }
 
     static const char* nameIReg(int szB, RegisterID reg)
     {
-        static const char* r64names[16]
+        static const char* const r64names[16]
           = { "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
               "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" };
-        static const char* r32names[16]
+        static const char* const r32names[16]
           = { "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
               "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d" };
-        static const char* r16names[16]
+        static const char* const r16names[16]
           = { "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
               "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w" };
-        static const char* r8names[16]
+        static const char* const r8names[16]
           = { "%al", "%cl", "%dl", "%bl", "%ah/spl", "%ch/bpl", "%dh/sil", "%bh/dil",
               "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b" };
         int          off = (RegisterID)reg - (RegisterID)eax;
-        const char** tab = r64names;
+        const char* const* tab = r64names;
         switch (szB) {
             case 1: tab = r8names; break;
             case 2: tab = r16names; break;
             case 4: tab = r32names; break;
         }
         return (off < 0 || off > 15) ? "%r???" : tab[off];
     }
 
@@ -164,17 +164,17 @@ public:
         ConditionG,
 
         ConditionC  = ConditionB,
         ConditionNC = ConditionAE
     } Condition;
 
     static const char* nameCC(Condition cc)
     {
-        static const char* names[16]
+        static const char* const names[16]
           = { "o ", "no", "b ", "ae", "e ", "ne", "be", "a ",
               "s ", "ns", "p ", "np", "l ", "ge", "le", "g " };
         int ix = (int)cc;
         return (ix < 0 || ix > 15) ? "??" : names[ix];
     }
 
     // Rounding modes for ROUNDSD.
     typedef enum {
@@ -421,17 +421,17 @@ public:
     void pop_r(RegisterID reg)
     {
         spew("pop        %s", nameIReg(reg));
         m_formatter.oneByteOp(OP_POP_EAX, reg);
     }
 
     void push_i32(int imm)
     {
-        spew("pushl      %s$0x%x",
+        spew("push       %s$0x%x",
              PRETTY_PRINT_OFFSET(imm));
         m_formatter.oneByteOp(OP_PUSH_Iz);
         m_formatter.immediate32(imm);
     }
 
     void push_m(int offset, RegisterID base)
     {
         spew("push       %s0x%x(%s)",
@@ -442,30 +442,30 @@ public:
     void pop_m(int offset, RegisterID base)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
     }
 
     void push_flags()
     {
-        spew("push flags register");
+        spew("pushf");
         m_formatter.oneByteOp(OP_PUSHFLAGS);
     }
 
     void pop_flags()
     {
-        spew("pop flags register");
+        spew("popf");
         m_formatter.oneByteOp(OP_POPFLAGS);
     }
 
     // Arithmetic operations:
 
 #if !WTF_CPU_X86_64
-    void adcl_im(int imm, void* addr)
+    void adcl_im(int imm, const void* addr)
     {
         FIXME_INSN_PRINTING;
         if (CAN_SIGN_EXTEND_8_32(imm)) {
             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
             m_formatter.immediate32(imm);
@@ -553,17 +553,17 @@ public:
             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
             m_formatter.immediate32(imm);
         }
     }
 #else
-    void addl_im(int imm, void* addr)
+    void addl_im(int imm, const void* addr)
     {
         FIXME_INSN_PRINTING;
         if (CAN_SIGN_EXTEND_8_32(imm)) {
             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
             m_formatter.immediate32(imm);
@@ -644,17 +644,17 @@ public:
             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
             m_formatter.immediate32(imm);
         }
     }
 #else
-    void andl_im(int imm, void* addr)
+    void andl_im(int imm, const void* addr)
     {
         FIXME_INSN_PRINTING;
         if (CAN_SIGN_EXTEND_8_32(imm)) {
             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
             m_formatter.immediate32(imm);
@@ -772,17 +772,17 @@ public:
     }
 
     void notq_r(RegisterID dst)
     {
         spew("notq       %s", nameIReg(8,dst));
         m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
     }
 #else
-    void orl_im(int imm, void* addr)
+    void orl_im(int imm, const void* addr)
     {
         FIXME_INSN_PRINTING;
         if (CAN_SIGN_EXTEND_8_32(imm)) {
             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
             m_formatter.immediate32(imm);
@@ -794,17 +794,17 @@ public:
     {
         spew("subl       %s, %s",
              nameIReg(4,src), nameIReg(4,dst));
         m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
     }
 
     void subl_mr(int offset, RegisterID base, RegisterID dst)
     {
-        spew("subl        %s0x%x(%s), %s",
+        spew("subl       %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(4,base), nameIReg(4,dst));
         m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
     }
 
     void subl_rm(RegisterID src, int offset, RegisterID base)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
@@ -857,17 +857,17 @@ public:
             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
             m_formatter.immediate32(imm);
         }
     }
 #else
-    void subl_im(int imm, void* addr)
+    void subl_im(int imm, const void* addr)
     {
         FIXME_INSN_PRINTING;
         if (CAN_SIGN_EXTEND_8_32(imm)) {
             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
             m_formatter.immediate32(imm);
@@ -1030,23 +1030,23 @@ public:
             m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
             m_formatter.immediate8(imm);
         }
     }
 #endif
 
     void imull_rr(RegisterID src, RegisterID dst)
     {
-        spew("imull       %s, %s", nameIReg(4,src), nameIReg(4, dst));
+        spew("imull      %s, %s", nameIReg(4,src), nameIReg(4, dst));
         m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
     }
 
     void imull_mr(int offset, RegisterID base, RegisterID dst)
     {
-        spew("imull       %s0x%x(%s), %s",
+        spew("imull      %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(4,base), nameIReg(4,dst));
         m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
     }
 
     void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
     {
         spew("imull      $%d, %s, %s",
              value, nameIReg(4, src), nameIReg(4, dst));
@@ -1221,23 +1221,23 @@ public:
             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
             m_formatter.immediate32(imm);
         }
     }
 #else
-    void cmpl_rm(RegisterID reg, void* addr)
+    void cmpl_rm(RegisterID reg, const void* addr)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
     }
 
-    void cmpl_im(int imm, void* addr)
+    void cmpl_im(int imm, const void* addr)
     {
         spew("cmpl       $0x%x, 0x%p", imm, addr);
         if (CAN_SIGN_EXTEND_8_32(imm)) {
             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
             m_formatter.immediate8(imm);
         } else {
             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
             m_formatter.immediate32(imm);
@@ -1302,22 +1302,24 @@ public:
         spew("testl      $0x%x, %s0x%x(%s)",
              imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
         m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
         m_formatter.immediate32(imm);
     }
 
     void testb_im(int imm, int offset, RegisterID base)
     {
+        FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
         m_formatter.immediate8(imm);
     }
 
     void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
     {
+        FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
         m_formatter.immediate8(imm);
     }
 
     void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
@@ -1405,17 +1407,17 @@ public:
         FIXME_INSN_PRINTING;
         setne_r(dst);
     }
 
     // Various move ops:
 
     void cdq()
     {
-        spew("cdq              ");
+        spew("cdq        ");
         m_formatter.oneByteOp(OP_CDQ);
     }
 
     void xchgl_rr(RegisterID src, RegisterID dst)
     {
         spew("xchgl      %s, %s",
              nameIReg(4,src), nameIReg(4,dst));
         m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
@@ -1476,17 +1478,17 @@ public:
 
     void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
     {
         spew("movl       %s, %d(%s,%s,%d)",
              nameIReg(4, src), offset, nameIReg(base), nameIReg(index), 1<<scale);
         m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
     }
 
-    void movl_mEAX(void* addr)
+    void movl_mEAX(const void* addr)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_MOV_EAXOv);
 #if WTF_CPU_X86_64
         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
 #else
         m_formatter.immediate32(reinterpret_cast<int>(addr));
 #endif
@@ -1501,17 +1503,17 @@ public:
 
     void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
     }
 
 #if WTF_CPU_X86
-    void movl_mr(void* base, RegisterID index, int scale, RegisterID dst)
+    void movl_mr(const void* base, RegisterID index, int scale, RegisterID dst)
     {
         spew("movl       %d(%s,%d), %s",
              int(base), nameIReg(index), scale, nameIReg(dst));
         m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, index, scale, int(base));
     }
 #endif
 
     void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
@@ -1519,17 +1521,17 @@ public:
         spew("movl       %d(%s,%s,%d), %s",
              offset, nameIReg(base), nameIReg(index), 1<<scale, nameIReg(4, dst));
         m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
     }
 
     void movl_i32r(int imm, RegisterID dst)
     {
         spew("movl       $0x%x, %s",
-             imm, nameIReg(dst));
+             imm, nameIReg(4, dst));
         m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
         m_formatter.immediate32(imm);
     }
 
     void movb_i8m(int imm, int offset, RegisterID base)
     {
         spew("movb       $0x%x, %s0x%x(%s)",
              imm, PRETTY_PRINT_OFFSET(offset), nameIReg(base));
@@ -1574,17 +1576,17 @@ public:
     void movl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
     {
         spew("movl       $0x%x, %d(%s,%s,%d)",
              imm, offset, nameIReg(base), nameIReg(index), 1<<scale);
         m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
         m_formatter.immediate32(imm);
     }
 
-    void movl_EAXm(void* addr)
+    void movl_EAXm(const void* addr)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_MOV_OvEAX);
 #if WTF_CPU_X86_64
         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
 #else
         m_formatter.immediate32(reinterpret_cast<int>(addr));
 #endif
@@ -1613,24 +1615,24 @@ public:
 
     void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
     {
         spew("movq       %s, %s0x%x(%s)",
              nameIReg(8,src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
         m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
     }
 
-    void movq_mEAX(void* addr)
+    void movq_mEAX(const void* addr)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp64(OP_MOV_EAXOv);
         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
     }
 
-    void movq_EAXm(void* addr)
+    void movq_EAXm(const void* addr)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp64(OP_MOV_OvEAX);
         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
     }
 
     void movq_mr(int offset, RegisterID base, RegisterID dst)
     {
@@ -1714,37 +1716,37 @@ public:
     JmpSrc movq_ripr(RegisterID dst)
     {
         spew("movl       \?(%%rip), %s",
              nameIReg(dst));
         m_formatter.oneByteRipOp64(OP_MOV_GvEv, dst, 0);
         return JmpSrc(m_formatter.size());
     }
 #else
-    void movl_rm(RegisterID src, void* addr)
+    void movl_rm(RegisterID src, const void* addr)
     {
         spew("movl       %s, 0(%p)",
              nameIReg(4, src), addr);
         if (src == X86Registers::eax)
             movl_EAXm(addr);
         else
             m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
     }
 
-    void movl_mr(void* addr, RegisterID dst)
+    void movl_mr(const void* addr, RegisterID dst)
     {
         spew("movl       0(%p), %s",
              addr, nameIReg(4, dst));
         if (dst == X86Registers::eax)
             movl_mEAX(addr);
         else
             m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
     }
 
-    void movl_i32m(int imm, void* addr)
+    void movl_i32m(int imm, const void* addr)
     {
         FIXME_INSN_PRINTING;
         m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
         m_formatter.immediate32(imm);
     }
 #endif
 
     void movb_rm(RegisterID src, int offset, RegisterID base)
@@ -1852,17 +1854,17 @@ public:
         m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, index, scale, offset);
     }
 
     void movzbl_rr(RegisterID src, RegisterID dst)
     {
         // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
         // is in the range ESP-EDI, and the src would not have required a REX).  Unneeded
         // REX prefixes are defined to be silently ignored by the processor.
-        spew("movzbl      %s, %s",
+        spew("movzbl     %s, %s",
              nameIReg(1,src), nameIReg(4,dst));
         m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
     }
 
     void leal_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
     {
         spew("leal       %d(%s,%s,%d), %s",
              offset, nameIReg(base), nameIReg(index), 1<<scale, nameIReg(dst));
@@ -2163,17 +2165,17 @@ public:
     {
         spew("cvtsi2sd   %d(%s,%s,%d), %s",
              offset, nameIReg(base), nameIReg(index), 1<<scale, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, index, scale, offset);
     }
 
 #if !WTF_CPU_X86_64
-    void cvtsi2sd_mr(void* address, XMMRegisterID dst)
+    void cvtsi2sd_mr(const void* address, XMMRegisterID dst)
     {
         spew("cvtsi2sd   %p, %s",
              address, nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
     }
 #endif
 
@@ -2207,17 +2209,17 @@ public:
         spew("movd       %s, %s",
              nameIReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_MOVD_VdEd, (RegisterID)dst, src);
     }
 
     void psrldq_ir(int shift, XMMRegisterID dest)
     {
-        spew("psrldq      $%d, %s",
+        spew("psrldq     $%d, %s",
              shift, nameFPReg(dest));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_PSRLDQ_Vd, (RegisterID)3, (RegisterID)dest);
         m_formatter.immediate8(shift);
     }
 
     void psllq_ir(int shift, XMMRegisterID dest)
     {
@@ -2323,25 +2325,25 @@ public:
         spew("movss      %s0x%x(%s), %s",
              PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F3);
         m_formatter.twoByteOp_disp32(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
     }
 
     void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
     {
-        spew("movsd       %s, %d(%s,%s,%d)",
+        spew("movsd      %s, %d(%s,%s,%d)",
              nameFPReg(src), offset, nameIReg(base), nameIReg(index), 1<<scale);
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
     }
 
     void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
     {
-        spew("movss       %s, %d(%s,%s,%d)",
+        spew("movss      %s, %d(%s,%s,%d)",
              nameFPReg(src), offset, nameIReg(base), nameIReg(index), 1<<scale);
         m_formatter.prefix(PRE_SSE_F3);
         m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
     }
 
     void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
     {
         spew("movss      %d(%s,%s,%d), %s",
@@ -2396,25 +2398,25 @@ public:
         spew("movsd      %s, %p",
              nameFPReg(src), address);
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, address);
     }
 #else
     JmpSrc movsd_ripr(XMMRegisterID dst)
     {
-        spew("movsd     \?(%%rip), %s",
+        spew("movsd      \?(%%rip), %s",
              nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteRipOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, 0);
         return JmpSrc(m_formatter.size());
     }
     JmpSrc movsd_rrip(XMMRegisterID src)
     {
-        spew("movsd     %s, \?(%%rip)",
+        spew("movsd      %s, \?(%%rip)",
              nameFPReg(src));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteRipOp(OP2_MOVSD_WsdVsd, (RegisterID)src, 0);
         return JmpSrc(m_formatter.size());
     }
 #endif
 
     void movdqa_rm(XMMRegisterID src, int offset, RegisterID base)
@@ -2422,17 +2424,17 @@ public:
         spew("movdqa     %s, %s0x%x(%s)",
              nameFPReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_MOVDQA_WsdVsd, (RegisterID)src, base, offset);
     }
 
     void movdqa_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
     {
-        spew("movdqa      %s, %d(%s,%s,%d)",
+        spew("movdqa     %s, %d(%s,%s,%d)",
              nameFPReg(src), offset, nameIReg(base), nameIReg(index), 1<<scale);
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.twoByteOp(OP2_MOVDQA_WsdVsd, (RegisterID)src, base, index, scale, offset);
     }
 
     void movdqa_mr(int offset, RegisterID base, XMMRegisterID dst)
     {
         spew("movdqa     %s0x%x(%s), %s",
@@ -2550,17 +2552,17 @@ public:
         spew("sqrtsd     %s, %s",
              nameFPReg(src), nameFPReg(dst));
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     }
 
     void roundsd_rr(XMMRegisterID src, XMMRegisterID dst, RoundingMode mode)
     {
-        spew("roundsd     %s, %s, %d",
+        spew("roundsd    %s, %s, %d",
              nameFPReg(src), nameFPReg(dst), (int)mode);
         m_formatter.prefix(PRE_SSE_66);
         m_formatter.threeByteOp(OP3_ROUNDSD_VsdWsd, ESCAPE_ROUNDSD, (RegisterID)dst, (RegisterID)src);
         m_formatter.immediate8(mode);
     }
 
     void pinsrd_rr(RegisterID src, XMMRegisterID dst)
     {
@@ -2764,17 +2766,17 @@ public:
 
     static void repatchInt32(void* where, int32_t value)
     {
         staticSpew("##relinkInt32 ((where=%p)) ((value=%d))",
                    where, value);
         setInt32(where, value);
     }
 
-    static void repatchPointer(void* where, void* value)
+    static void repatchPointer(void* where, const void* value)
     {
         staticSpew("##repatchPtr ((where=%p)) ((value=%p))",
                    where, value);
         setPointer(where, value);
     }
 
     static void repatchLoadPtrToLEA(void* where)
     {
@@ -2970,17 +2972,17 @@ private:
         {
             m_buffer.ensureSpace(maxInstructionSize);
             emitRexIfNeeded(reg, index, 0);
             m_buffer.putByteUnchecked(opcode);
             memoryModRM_disp32(reg, index, scale, offset);
         }
 
 #if !WTF_CPU_X86_64
-        void oneByteOp(OneByteOpcodeID opcode, int reg, void* address)
+        void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
         {
             m_buffer.ensureSpace(maxInstructionSize);
             m_buffer.putByteUnchecked(opcode);
             memoryModRM(reg, address);
         }
 #else
         void oneByteRipOp(OneByteOpcodeID opcode, int reg, int ripOffset)
         {
--- a/js/src/assembler/jit/ExecutableAllocator.cpp
+++ b/js/src/assembler/jit/ExecutableAllocator.cpp
@@ -26,18 +26,16 @@
  */
 
 #include "ExecutableAllocator.h"
 
 #include "js/MemoryMetrics.h"
 
 #if ENABLE_ASSEMBLER
 
-#include "prmjtime.h"
-
 namespace JSC {
 
 size_t ExecutableAllocator::pageSize = 0;
 size_t ExecutableAllocator::largeAllocSize = 0;
 
 ExecutablePool::~ExecutablePool()
 {
     m_allocator->releasePoolPages(this);
--- a/js/src/assembler/jit/ExecutableAllocator.h
+++ b/js/src/assembler/jit/ExecutableAllocator.h
@@ -25,20 +25,18 @@
 
 #ifndef ExecutableAllocator_h
 #define ExecutableAllocator_h
 
 #include <stddef.h> // for ptrdiff_t
 #include <limits>
 
 #include "jsalloc.h"
-#include "jsapi.h"
-#include "jsprvtd.h"
 
-#include "assembler/wtf/Assertions.h"
+#include "assembler/wtf/Platform.h"
 #include "js/HashTable.h"
 #include "js/Vector.h"
 
 #if WTF_CPU_SPARC
 #ifdef linux  // bugzilla 502369
 static void sync_instruction_memory(caddr_t v, u_int len)
 {
     caddr_t end = v + len;
--- a/js/src/assembler/jit/ExecutableAllocatorPosix.cpp
+++ b/js/src/assembler/jit/ExecutableAllocatorPosix.cpp
@@ -18,23 +18,25 @@
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#include "ExecutableAllocator.h"
+#include "assembler/jit/ExecutableAllocator.h"
 
 #if ENABLE_ASSEMBLER && WTF_OS_UNIX && !WTF_OS_SYMBIAN
 
 #include <sys/mman.h>
 #include <unistd.h>
-#include <wtf/VMTags.h>
+
+#include "assembler/wtf/Assertions.h"
+#include "assembler/wtf/VMTags.h"
 
 namespace JSC {
 
 size_t ExecutableAllocator::determinePageSize()
 {
     return getpagesize();
 }
 
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -1,20 +1,22 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "builtin/Eval.h"
+
+#include "mozilla/HashFunctions.h"
+
 #include "jscntxt.h"
 #include "jsonparser.h"
 
-#include "builtin/Eval.h"
 #include "frontend/BytecodeCompiler.h"
-#include "mozilla/HashFunctions.h"
 #include "vm/GlobalObject.h"
 
 #include "vm/Interpreter-inl.h"
 
 using namespace js;
 
 using mozilla::AddToHash;
 using mozilla::HashString;
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -4,24 +4,25 @@
  * 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 Intl module specified by standard ECMA-402,
  * ECMAScript Internationalization API Specification.
  */
 
+#include "builtin/Intl.h"
+
 #include <string.h>
 
 #include "jsapi.h"
 #include "jsatom.h"
 #include "jscntxt.h"
 #include "jsobj.h"
 
-#include "builtin/Intl.h"
 #include "vm/DateTime.h"
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/Stack.h"
 #include "vm/StringBuffer.h"
 
 #if ENABLE_INTL_API
 #include "unicode/locid.h"
--- a/js/src/builtin/Intl.h
+++ b/js/src/builtin/Intl.h
@@ -2,16 +2,18 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 Intl_h___
 #define Intl_h___
 
+#include "jsapi.h"
+
 #include "js/RootingAPI.h"
 
 struct JSContext;
 class JSObject;
 
 /*
  * The Intl module specified by standard ECMA-402,
  * ECMAScript Internationalization API Specification.
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -9,17 +9,16 @@
 #include "jscntxt.h"
 #include "jsiter.h"
 #include "jsobj.h"
 
 #include "gc/Marking.h"
 #include "js/Utility.h"
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
-#include "vm/Stack.h"
 
 #include "jsobjinlines.h"
 
 #include "gc/Barrier-inl.h"
 
 using namespace js;
 
 using mozilla::DoubleIsInt32;
--- a/js/src/builtin/MapObject.h
+++ b/js/src/builtin/MapObject.h
@@ -2,19 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 MapObject_h__
 #define MapObject_h__
 
-#include "mozilla/FloatingPoint.h"
-#include "mozilla/GuardObjects.h"
-
 #include "jsapi.h"
 #include "jscntxt.h"
 #include "jsobj.h"
 
 namespace js {
 
 /*
  * Comparing two ropes for equality can fail. The js::HashTable template
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -1,24 +1,24 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "builtin/Object.h"
+
 #include "mozilla/Util.h"
 
 #include "jscntxt.h"
 #include "jsobj.h"
 
-#include "builtin/Object.h"
 #include "frontend/BytecodeCompiler.h"
 #include "vm/StringBuffer.h"
 
-#include "jsfuninlines.h"
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace js::types;
 
 using js::frontend::IsIdentifier;
 using mozilla::ArrayLength;
 
--- a/js/src/builtin/ParallelArray.cpp
+++ b/js/src/builtin/ParallelArray.cpp
@@ -1,26 +1,24 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jsapi.h"
 #include "jsobj.h"
-#include "jsarray.h"
 
 #include "builtin/ParallelArray.h"
 
-#include "vm/ForkJoin.h"
 #include "vm/GlobalObject.h"
 #include "vm/String.h"
-#include "vm/ThreadPool.h"
 
-#include "vm/Interpreter-inl.h"
+#include "jsgcinlines.h"
+#include "jsobjinlines.h"
 
 using namespace js;
 
 //
 // ParallelArrayObject
 //
 
 FixedHeapPtr<PropertyName> ParallelArrayObject::ctorNames[NumCtors];
--- a/js/src/builtin/Profilers.cpp
+++ b/js/src/builtin/Profilers.cpp
@@ -1,35 +1,31 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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/. */
 
 /* Profiling-related API */
 
-#include <stdarg.h>
+#include "builtin/Profilers.h"
 
-#include "Profilers.h"
-#include "jsapi.h"
-#include "jscntxt.h"
-
-#include "jscntxtinlines.h"
-#include "vm/Probes-inl.h"
-#include "vm/Stack-inl.h"
+#include <stdarg.h>
 
 #ifdef MOZ_CALLGRIND
 #include <valgrind/callgrind.h>
 #endif
 
 #ifdef __APPLE__
 #include "devtools/sharkctl.h"
 #include "devtools/Instruments.h"
 #endif
 
+#include "jscntxtinlines.h"
+
 using namespace js;
 
 using mozilla::ArrayLength;
 
 /* Thread-unsafe error management */
 
 static char gLastError[2000];
 
@@ -444,17 +440,16 @@ js_DumpCallgrind(const char *outfile)
  * If you include --pid or --output in MOZ_PROFILE_PERF_FLAGS, you're just
  * asking for trouble.
  *
  * Our split-on-spaces logic is lame, so don't expect MOZ_PROFILE_PERF_FLAGS to
  * work if you pass an argument which includes a space (e.g.
  * MOZ_PROFILE_PERF_FLAGS="-e 'foo bar'").
  */
 
-#include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
 #include <signal.h>
 
 static bool perfInitialized = false;
 static pid_t perfPid = 0;
 
 JSBool js_StartPerf()
--- a/js/src/builtin/Profilers.h
+++ b/js/src/builtin/Profilers.h
@@ -6,17 +6,17 @@
 
 /*
  * Functions for controlling profilers from within JS: Valgrind, Perf,
  * Shark, etc.
  */
 #ifndef Profilers_h___
 #define Profilers_h___
 
-#include "jsapi.h"
+#include "jstypes.h"
 
 /**
  * Start any profilers that are available and have been configured on for this
  * platform. This is NOT thread safe.
  *
  * The profileName is used by some profilers to describe the current profiling
  * run. It may be used for part of the filename of the output, but the
  * specifics depend on the profiler. Many profilers will ignore it. Passing in
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -909,18 +909,18 @@ js::testingFunc_inParallelSection(JSCont
 
 static JSObject *objectMetadataFunction = NULL;
 
 static JSObject *
 ShellObjectMetadataCallback(JSContext *cx)
 {
     Value thisv = UndefinedValue();
 
-    Value rval;
-    if (!Invoke(cx, thisv, ObjectValue(*objectMetadataFunction), 0, NULL, &rval)) {
+    RootedValue rval(cx);
+    if (!Invoke(cx, thisv, ObjectValue(*objectMetadataFunction), 0, NULL, rval.address())) {
         cx->clearPendingException();
         return NULL;
     }
 
     return rval.isObject() ? &rval.toObject() : NULL;
 }
 
 static JSBool
--- a/js/src/builtin/embedjs.py
+++ b/js/src/builtin/embedjs.py
@@ -59,17 +59,17 @@ HEADER_TEMPLATE = """\
 /* 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/. */
 
 namespace js {
 namespace selfhosted {
     static const %(sources_type)s data[] = { %(sources_data)s };
 
-    static const %(sources_type)s *%(sources_name)s = reinterpret_cast<const %(sources_type)s *>(data);
+    static const %(sources_type)s * const %(sources_name)s = reinterpret_cast<const %(sources_type)s *>(data);
 
     uint32_t GetCompressedSize() {
         return %(compressed_total_length)i;
     }
 
     uint32_t GetRawScriptsSize() {
         return %(raw_total_length)i;
     }
--- a/js/src/ds/LifoAlloc.h
+++ b/js/src/ds/LifoAlloc.h
@@ -2,33 +2,28 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 LifoAlloc_h__
 #define LifoAlloc_h__
 
-#include "mozilla/Assertions.h"
-#include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
-#include "mozilla/GuardObjects.h"
 #include "mozilla/MemoryChecking.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/TypeTraits.h"
 
 // This data structure supports stacky LIFO allocation (mark/release and
 // LifoAllocScope). It does not maintain one contiguous segment; instead, it
 // maintains a bunch of linked memory segments. In order to prevent malloc/free
 // thrashing, unused segments are deallocated when garbage collection occurs.
 
 #include "jsutil.h"
 
-#include "js/TemplateLib.h"
-
 namespace js {
 
 namespace detail {
 
 static const size_t LIFO_ALLOC_ALIGN = 8;
 
 JS_ALWAYS_INLINE
 char *
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -8,24 +8,21 @@
 
 #include "jsscript.h"
 #include "frontend/BytecodeEmitter.h"
 #include "frontend/FoldConstants.h"
 #include "frontend/NameFunctions.h"
 #include "ion/AsmJS.h"
 #include "vm/GlobalObject.h"
 
-#include "jsinferinlines.h"
 #include "jsobjinlines.h"
 
 #include "frontend/ParseMaps-inl.h"
-#include "frontend/ParseNode-inl.h"
 #include "frontend/Parser-inl.h"
 #include "frontend/SharedContext-inl.h"
-#include "vm/Probes-inl.h"
 
 using namespace js;
 using namespace js::frontend;
 using mozilla::Maybe;
 
 static bool
 CheckLength(JSContext *cx, size_t length)
 {
--- a/js/src/frontend/BytecodeCompiler.h
+++ b/js/src/frontend/BytecodeCompiler.h
@@ -3,19 +3,25 @@
  * 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 BytecodeCompiler_h__
 #define BytecodeCompiler_h__
 
 #include "jsapi.h"
-#include "jsprvtd.h"
+
+class JSLinearString;
 
 namespace js {
+
+class AutoNameVector;
+class LazyScript;
+struct SourceCompressionToken;
+
 namespace frontend {
 
 JSScript *
 CompileScript(JSContext *cx, HandleObject scopeChain, HandleScript evalCaller,
               const CompileOptions &options, const jschar *chars, size_t length,
               JSString *source_ = NULL, unsigned staticLevel = 0,
               SourceCompressionToken *extraSct = NULL);
 
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -9,50 +9,40 @@
  */
 
 #include "frontend/BytecodeEmitter-inl.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/PodOperations.h"
 
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif
 #include <string.h>
 
 #include "jstypes.h"
 #include "jsutil.h"
-#include "jsprf.h"
 #include "jsapi.h"
 #include "jsatom.h"
 #include "jscntxt.h"
-#include "jsversion.h"
 #include "jsfun.h"
 #include "jsnum.h"
 #include "jsopcode.h"
 #include "jsscript.h"
-#include "jsautooplen.h"        // generated headers last
-
-#include "ds/LifoAlloc.h"
+
 #include "frontend/Parser.h"
 #include "frontend/TokenStream.h"
 #include "ion/AsmJS.h"
 #include "vm/Debugger.h"
-#include "vm/RegExpObject.h"
-#include "vm/Shape.h"
 
 #include "jsatominlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "frontend/ParseMaps-inl.h"
 #include "frontend/ParseNode-inl.h"
 #include "frontend/SharedContext-inl.h"
-#include "vm/Shape-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using namespace js::frontend;
 
 using mozilla::DebugOnly;
 using mozilla::DoubleIsInt32;
 using mozilla::PodCopy;
@@ -281,17 +271,17 @@ EmitJump(JSContext *cx, BytecodeEmitter 
     return offset;
 }
 
 /* XXX too many "... statement" L10N gaffes below -- fix via js.msg! */
 const char js_with_statement_str[] = "with statement";
 const char js_finally_block_str[]  = "finally block";
 const char js_script_str[]         = "script";
 
-static const char *statementName[] = {
+static const char * const statementName[] = {
     "label statement",       /* LABEL */
     "if statement",          /* IF */
     "else statement",        /* ELSE */
     "destructuring body",    /* BODY */
     "switch statement",      /* SWITCH */
     "block",                 /* BLOCK */
     js_with_statement_str,   /* WITH */
     "catch block",           /* CATCH */
@@ -6421,17 +6411,17 @@ CGConstList::finish(ConstArray *array)
     for (unsigned i = 0; i < length(); i++)
         array->vector[i] = list[i];
 }
 
 /*
  * We should try to get rid of offsetBias (always 0 or 1, where 1 is
  * JSOP_{NOP,POP}_LENGTH), which is used only by SRC_FOR.
  */
-JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[] = {
+JS_FRIEND_DATA(const JSSrcNoteSpec) js_SrcNoteSpec[] = {
 /*  0 */ {"null",           0},
 
 /*  1 */ {"if",             0},
 /*  2 */ {"if-else",        1},
 /*  3 */ {"cond",           1},
 
 /*  4 */ {"for",            3},
 
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -1,28 +1,24 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "frontend/FoldConstants.h"
+
 #include "mozilla/FloatingPoint.h"
 
 #include "jslibmath.h"
 
-#include "frontend/FoldConstants.h"
 #include "frontend/ParseNode.h"
 #include "frontend/Parser.h"
 #include "vm/NumericConversions.h"
 
-#include "jsatominlines.h"
-
-#include "frontend/Parser-inl.h"
-#include "vm/String-inl.h"
-
 using namespace js;
 using namespace js::frontend;
 
 using mozilla::IsNaN;
 using mozilla::IsNegative;
 
 static ParseNode *
 ContainsVarOrConst(ParseNode *pn)
--- a/js/src/frontend/NameFunctions.cpp
+++ b/js/src/frontend/NameFunctions.cpp
@@ -10,17 +10,16 @@
 #include "jsprf.h"
 
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/ParseNode.h"
 #include "frontend/SharedContext.h"
 
 #include "jsfuninlines.h"
 
-#include "vm/String-inl.h"
 #include "vm/StringBuffer.h"
 
 using namespace js;
 using namespace js::frontend;
 
 class NameResolver
 {
     static const size_t MaxParents = 100;
--- a/js/src/frontend/ParseMaps-inl.h
+++ b/js/src/frontend/ParseMaps-inl.h
@@ -4,17 +4,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/. */
 
 #ifndef ParseMapPool_inl_h__
 #define ParseMapPool_inl_h__
 
 #include "jscntxt.h"
 
-#include "frontend/ParseNode.h" /* Need sizeof(js::Definition). */
 #include "frontend/ParseMaps.h"
 
 namespace js {
 namespace frontend {
 
 template <>
 inline AtomDefnMap *
 ParseMapPool::acquire<AtomDefnMap>()
--- a/js/src/frontend/ParseMaps.cpp
+++ b/js/src/frontend/ParseMaps.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jscntxt.h"
-#include "jscompartment.h"
 #include "FullParseHandler.h"
 #include "SyntaxParseHandler.h"
 
 #include "ParseMaps-inl.h"
 #include "vm/String-inl.h"
 
 using namespace js;
 using namespace js::frontend;
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -3,20 +3,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 "builtin/Module.h"
 #include "frontend/ParseNode.h"
 #include "frontend/Parser.h"
 
-#include "jsscriptinlines.h"
-
-#include "frontend/ParseMaps-inl.h"
-#include "frontend/ParseNode-inl.h"
 #include "frontend/Parser-inl.h"
 
 using namespace js;
 using namespace js::frontend;
 
 using mozilla::IsFinite;
 
 /*
@@ -369,17 +365,17 @@ NameNode::create(ParseNodeKind kind, JSA
         ((NameNode *)pn)->initCommon(pc);
     }
     return (NameNode *)pn;
 }
 
 const char *
 Definition::kindString(Kind kind)
 {
-    static const char *table[] = {
+    static const char * const table[] = {
         "", js_var_str, js_const_str, js_let_str, js_function_str, "argument", "unknown"
     };
 
     JS_ASSERT(unsigned(kind) <= unsigned(ARG));
     return table[kind];
 }
 
 namespace js {
@@ -570,17 +566,17 @@ Parser<FullParseHandler>::cloneLeftHandS
     return pn;
 }
 
 } /* namespace frontend */
 } /* namespace js */
 
 #ifdef DEBUG
 
-static const char *parseNodeNames[] = {
+static const char * const parseNodeNames[] = {
 #define STRINGIFY(name) #name,
     FOR_EACH_PARSE_NODE_KIND(STRINGIFY)
 #undef STRINGIFY
 };
 
 void
 frontend::DumpParseTree(ParseNode *pn, int indent)
 {
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -14,55 +14,42 @@
  * After tree construction, it rewrites trees to fold constants and evaluate
  * compile-time expressions.
  *
  * This parser attempts no error recovery.
  */
 
 #include "frontend/Parser.h"
 
-#include <stdlib.h>
-#include <string.h>
-
 #include "jstypes.h"
-#include "jsutil.h"
 #include "jsapi.h"
-#include "jsarray.h"
 #include "jsatom.h"
 #include "jscntxt.h"
 #include "jsversion.h"
 #include "jsfun.h"
-#include "jsgc.h"
-#include "jsiter.h"
-#include "jslock.h"
-#include "jsnum.h"
 #include "jsobj.h"
 #include "jsopcode.h"
 #include "jsscript.h"
-#include "jsstr.h"
 
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/FoldConstants.h"
 #include "frontend/ParseMaps.h"
 #include "frontend/TokenStream.h"
-#include "gc/Marking.h"
-#include "vm/Interpreter.h"
 #include "vm/Shape.h"
 
 #include "jsatominlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "frontend/ParseMaps-inl.h"
 #include "frontend/ParseNode-inl.h"
 #include "frontend/Parser-inl.h"
 #include "frontend/SharedContext-inl.h"
 
 #include "vm/NumericConversions.h"
-#include "vm/RegExpObject-inl.h"
 #include "vm/RegExpStatics-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using mozilla::Maybe;
 
 namespace js {
 namespace frontend {
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -5,22 +5,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef Parser_h__
 #define Parser_h__
 
 /*
  * JS parser definitions.
  */
-#include "jsversion.h"
 #include "jsprvtd.h"
 #include "jspubtd.h"
-#include "jsatom.h"
-#include "jsscript.h"
-#include "jswin.h"
 
 #include "frontend/BytecodeCompiler.h"
 #include "frontend/FullParseHandler.h"
 #include "frontend/ParseMaps.h"
 #include "frontend/ParseNode.h"
 #include "frontend/SharedContext.h"
 #include "frontend/SyntaxParseHandler.h"
 
--- a/js/src/frontend/SourceNotes.h
+++ b/js/src/frontend/SourceNotes.h
@@ -145,17 +145,17 @@ enum SrcNoteType {
 #define SN_MAKE_TERMINATOR(sn)  (*(sn) = SRC_NULL)
 #define SN_IS_TERMINATOR(sn)    (*(sn) == SRC_NULL)
 
 struct JSSrcNoteSpec {
     const char      *name;      /* name for disassembly/debugging output */
     int8_t          arity;      /* number of offset operands */
 };
 
-extern JS_FRIEND_DATA(JSSrcNoteSpec)  js_SrcNoteSpec[];
+extern JS_FRIEND_DATA(const JSSrcNoteSpec) js_SrcNoteSpec[];
 extern JS_FRIEND_API(unsigned)         js_SrcNoteLength(jssrcnote *sn);
 
 /*
  * Get and set the offset operand identified by which (0 for the first, etc.).
  */
 extern JS_FRIEND_API(ptrdiff_t)
 js_GetSrcNoteOffset(jssrcnote *sn, unsigned which);
 
--- a/js/src/gc/Iteration.cpp
+++ b/js/src/gc/Iteration.cpp
@@ -2,17 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jsapi.h"
 #include "jscntxt.h"
 #include "jsgc.h"
-#include "jsprf.h"
 
 #include "js/HashTable.h"
 #include "gc/GCInternals.h"
 
 #include "jsgcinlines.h"
 
 using namespace js;
 using namespace js::gc;
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -1,26 +1,23 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "gc/Marking.h"
+
 #include "mozilla/DebugOnly.h"
 
-#include "jsprf.h"
-#include "jsstr.h"
-
-#include "gc/Marking.h"
 #include "ion/IonCode.h"
 #include "vm/Shape.h"
 
 #include "jscompartmentinlines.h"
 
-#include "gc/Nursery-inl.h"
 #include "vm/Shape-inl.h"
 #include "vm/String-inl.h"
 
 using namespace js;
 using namespace js::gc;
 
 using mozilla::DebugOnly;
 
--- a/js/src/gc/Memory.cpp
+++ b/js/src/gc/Memory.cpp
@@ -1,21 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "mozilla/Assertions.h"
-
-#include "jsapi.h"
+#include "gc/Memory.h"
 
 #include "js/HeapAPI.h"
-#include "js/Utility.h"
-#include "gc/Memory.h"
 
 using namespace js;
 using namespace js::gc;
 
 /* Unused memory decommiting requires the arena size match the page size. */
 static bool
 DecommitEnabled()
 {
@@ -302,17 +298,16 @@ size_t
 gc::GetPageFaultCount()
 {
     return 0;
 }
 
 #elif defined(XP_UNIX) || defined(XP_MACOSX) || defined(DARWIN)
 
 #include <sys/mman.h>
-#include <sys/time.h>
 #include <sys/resource.h>
 #include <unistd.h>
 
 void
 gc::InitMemorySubsystem()
 {
     if (size_t(sysconf(_SC_PAGESIZE)) != PageSize) {
         fprintf(stderr,"SpiderMonkey compiled with incorrect page size; please update js/public/HeapAPI.h.\n");
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -4,22 +4,25 @@
  * 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/. */
 
 #ifdef JSGC_GENERATIONAL
 
 #include "jscompartment.h"
 #include "jsgc.h"
+#include "jstypedarray.h"
 #include "jsutil.h"
 
 #include "gc/GCInternals.h"
 #include "gc/Memory.h"
 #include "vm/Debugger.h"
 
+#include "jscompartmentinlines.h"
+
 #include "gc/Barrier-inl.h"
 #include "gc/Nursery-inl.h"
 
 using namespace js;
 using namespace gc;
 using namespace mozilla;
 
 bool
--- a/js/src/gc/Statistics.cpp
+++ b/js/src/gc/Statistics.cpp
@@ -273,17 +273,17 @@ struct PhaseInfo
 {
     Phase index;
     const char *name;
     Phase parent;
 };
 
 static const Phase PHASE_NO_PARENT = PHASE_LIMIT;
 
-static PhaseInfo phases[] = {
+static const PhaseInfo phases[] = {
     { PHASE_GC_BEGIN, "Begin Callback", PHASE_NO_PARENT },
     { PHASE_WAIT_BACKGROUND_THREAD, "Wait Background Thread", PHASE_NO_PARENT },
     { PHASE_MARK_DISCARD_CODE, "Mark Discard Code", PHASE_NO_PARENT },
     { PHASE_PURGE, "Purge", PHASE_NO_PARENT },
     { PHASE_MARK, "Mark", PHASE_NO_PARENT },
     { PHASE_MARK_ROOTS, "Mark Roots", PHASE_MARK },
     { PHASE_MARK_TYPES, "Mark Types", PHASE_MARK_ROOTS },
     { PHASE_MARK_DELAYED, "Mark Delayed", PHASE_MARK },
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -19,16 +19,28 @@
 #include "ion/Ion.h"
 #endif
 
 #include "jsgcinlines.h"
 
 using namespace js;
 using namespace js::gc;
 
+void *
+js::Allocator::onOutOfMemory(void *p, size_t nbytes)
+{
+    return zone->rt->onOutOfMemory(p, nbytes);
+}
+
+void
+js::Allocator::reportAllocationOverflow()
+{
+    js_ReportAllocationOverflow(NULL);
+}
+
 JS::Zone::Zone(JSRuntime *rt)
   : rt(rt),
     allocator(this),
     hold(false),
     ionUsingBarriers_(false),
     active(false),
     gcScheduled(false),
     gcState(NoGC),
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -40,19 +40,19 @@ class Allocator : public MallocProvider<
 
   public:
     explicit Allocator(JS::Zone *zone);
 
     js::gc::ArenaLists arenas;
 
     inline void *parallelNewGCThing(gc::AllocKind thingKind, size_t thingSize);
 
-    inline void *onOutOfMemory(void *p, size_t nbytes);
+    void *onOutOfMemory(void *p, size_t nbytes);
     inline void updateMallocCounter(size_t nbytes);
-    inline void reportAllocationOverflow();
+    void reportAllocationOverflow();
 };
 
 typedef Vector<JSCompartment *, 1, SystemAllocPolicy> CompartmentVector;
 
 } /* namespace js */
 
 namespace JS {
 
--- a/js/src/ion/AsmJS.cpp
+++ b/js/src/ion/AsmJS.cpp
@@ -5825,16 +5825,23 @@ GenerateFFIIonExit(ModuleCompiler &m, co
     masm.push(JSReturnReg_Data);
     LoadAsmJSActivationIntoRegister(masm, callee);
     masm.setupUnalignedABICall(1, scratch);
     masm.passABIArg(callee);
     masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, DisableActivation));
     masm.pop(JSReturnReg_Data);
     masm.pop(JSReturnReg_Type);
 
+#ifdef DEBUG
+    masm.branchTestMagicValue(Assembler::Equal, JSReturnOperand, JS_ION_ERROR, throwLabel);
+    masm.branchTestMagic(Assembler::Equal, JSReturnOperand, &ionFailed);
+#else
+    masm.branchTestMagic(Assembler::Equal, JSReturnOperand, throwLabel);
+#endif
+
     switch (exit.use().which()) {
       case Use::NoCoercion:
         break;
       case Use::ToInt32:
         masm.convertValueToInt32(JSReturnOperand, ReturnFloatReg, ReturnReg, &oolConvert);
         break;
       case Use::ToNumber:
         masm.convertValueToDouble(JSReturnOperand, ReturnFloatReg, &oolConvert);
--- a/js/src/ion/BaselineIC.cpp
+++ b/js/src/ion/BaselineIC.cpp
@@ -1311,17 +1311,17 @@ ICTypeMonitor_TypeObject::Compiler::gene
 
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
     return true;
 }
 
 bool
 ICUpdatedStub::addUpdateStubForValue(JSContext *cx, HandleScript script, HandleObject obj,
-                                     jsid id, HandleValue val)
+                                     HandleId id, HandleValue val)
 {
     if (numOptimizedStubs_ >= MAX_OPTIMIZED_STUBS) {
         // TODO: if the TypeSet becomes unknown or has the AnyObject type,
         // replace stubs with a single stub to handle these.
         return true;
     }
 
     if (!obj->getType(cx))
@@ -4210,31 +4210,31 @@ DoSetElemFallback(JSContext *cx, Baselin
                 IonSpew(IonSpew_BaselineIC,
                         "  Generating SetElem_DenseAdd stub "
                         "(shape=%p, type=%p, protoDepth=%u)",
                         obj->lastProperty(), type.get(), protoDepth);
                 ICSetElemDenseAddCompiler compiler(cx, obj, protoDepth);
                 ICUpdatedStub *denseStub = compiler.getStub(compiler.getStubSpace(script));
                 if (!denseStub)
                     return false;
-                if (!denseStub->addUpdateStubForValue(cx, script, obj, JSID_VOID, rhs))
+                if (!denseStub->addUpdateStubForValue(cx, script, obj, JS::JSID_VOIDHANDLE, rhs))
                     return false;
 
                 stub->addNewStub(denseStub);
             } else if (!addingCase &&
                        !DenseSetElemStubExists(cx, ICStub::SetElem_Dense, stub, obj))
             {
                 IonSpew(IonSpew_BaselineIC,
                         "  Generating SetElem_Dense stub (shape=%p, type=%p)",
                         obj->lastProperty(), type.get());
                 ICSetElem_Dense::Compiler compiler(cx, shape, type);
                 ICUpdatedStub *denseStub = compiler.getStub(compiler.getStubSpace(script));
                 if (!denseStub)
                     return false;
-                if (!denseStub->addUpdateStubForValue(cx, script, obj, JSID_VOID, rhs))
+                if (!denseStub->addUpdateStubForValue(cx, script, obj, JS::JSID_VOIDHANDLE, rhs))
                     return false;
 
                 stub->addNewStub(denseStub);
             }
         }
 
         return true;
     }
--- a/js/src/ion/BaselineIC.h
+++ b/js/src/ion/BaselineIC.h
@@ -920,17 +920,17 @@ class ICUpdatedStub : public ICStub
       : ICStub(kind, ICStub::Updated, stubCode),
         firstUpdateStub_(NULL),
         numOptimizedStubs_(0)
     {}
 
   public:
     bool initUpdatingChain(JSContext *cx, ICStubSpace *space);
 
-    bool addUpdateStubForValue(JSContext *cx, HandleScript script, HandleObject obj, jsid id,
+    bool addUpdateStubForValue(JSContext *cx, HandleScript script, HandleObject obj, HandleId id,
                                HandleValue val);
 
     void addOptimizedUpdateStub(ICStub *stub) {
         if (firstUpdateStub_->isTypeUpdate_Fallback()) {
             stub->setNext(firstUpdateStub_);
             firstUpdateStub_ = stub;
         } else {
             ICStub *iter = firstUpdateStub_;
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -1650,17 +1650,17 @@ ion::CanEnterAtBranch(JSContext *cx, JSS
     }
 
     script->ionScript()->resetOsrPcMismatchCounter();
 
     return Method_Compiled;
 }
 
 MethodStatus
-ion::CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp, bool isConstructing)
+ion::CanEnter(JSContext *cx, HandleScript script, AbstractFramePtr fp, bool isConstructing)
 {
     JS_ASSERT(ion::IsEnabled(cx));
 
     // Skip if the script has been disabled.
     if (!script->canIonCompile())
         return Method_Skipped;
 
     // Skip if the script is being compiled off thread.
@@ -1670,23 +1670,21 @@ ion::CanEnter(JSContext *cx, JSScript *s
     // Skip if the code is expected to result in a bailout.
     if (script->hasIonScript() && script->ionScript()->bailoutExpected())
         return Method_Skipped;
 
     // If constructing, allocate a new |this| object before building Ion.
     // Creating |this| is done before building Ion because it may change the
     // type information and invalidate compilation results.
     if (isConstructing && fp.thisValue().isPrimitive()) {
-        RootedScript scriptRoot(cx, script);
         RootedObject callee(cx, fp.callee());
         RootedObject obj(cx, CreateThisForFunction(cx, callee, fp.useNewType()));
         if (!obj || !ion::IsEnabled(cx)) // Note: OOM under CreateThis can disable TI.
             return Method_Skipped;
         fp.thisValue().setObject(*obj);
-        script = scriptRoot;
     }
 
     // Mark as forbidden if frame can't be handled.
     if (!CheckFrame(fp)) {
         ForbidCompilation(cx, script);
         return Method_CantCompile;
     }
 
--- a/js/src/ion/Ion.h
+++ b/js/src/ion/Ion.h
@@ -270,17 +270,17 @@ IonContext *GetIonContext();
 IonContext *MaybeGetIonContext();
 
 bool SetIonContext(IonContext *ctx);
 
 bool CanIonCompileScript(JSContext *cx, HandleScript script, bool osr);
 
 MethodStatus CanEnterAtBranch(JSContext *cx, JSScript *script,
                               AbstractFramePtr fp, jsbytecode *pc, bool isConstructing);
-MethodStatus CanEnter(JSContext *cx, JSScript *script, AbstractFramePtr fp, bool isConstructing);
+MethodStatus CanEnter(JSContext *cx, HandleScript script, AbstractFramePtr fp, bool isConstructing);
 MethodStatus CompileFunctionForBaseline(JSContext *cx, HandleScript script, AbstractFramePtr fp,
                                         bool isConstructing);
 MethodStatus CanEnterUsingFastInvoke(JSContext *cx, HandleScript script, uint32_t numActualArgs);
 
 MethodStatus CanEnterInParallel(JSContext *cx, HandleScript script);
 
 enum IonExecStatus
 {
--- a/js/src/ion/IonCaches.cpp
+++ b/js/src/ion/IonCaches.cpp
@@ -79,17 +79,17 @@ CodeOffsetJump::fixup(MacroAssembler *ma
 #ifdef JS_SMALL_BRANCH
      jumpTableIndex_ = masm->actualIndex(jumpTableIndex_);
 #endif
 }
 
 const char *
 IonCache::CacheName(IonCache::Kind kind)
 {
-    static const char *names[] =
+    static const char * const names[] =
     {
 #define NAME(x) #x,
         IONCACHE_KIND_LIST(NAME)
 #undef NAME
     };
     return names[kind];
 }
 
--- a/js/src/ion/IonFrames.cpp
+++ b/js/src/ion/IonFrames.cpp
@@ -1220,16 +1220,21 @@ InlineFrameIteratorMaybeGC<allowGC>::res
     if (iter) {
         start_ = SnapshotIterator(*iter);
         findNextFrame();
     }
 }
 template void InlineFrameIteratorMaybeGC<NoGC>::resetOn(const IonFrameIterator *iter);
 template void InlineFrameIteratorMaybeGC<CanGC>::resetOn(const IonFrameIterator *iter);
 
+// Disable PGO.
+#if defined(_MSC_VER)
+# pragma optimize("g", off)
+#endif
+
 template <AllowGC allowGC>
 void
 InlineFrameIteratorMaybeGC<allowGC>::findNextFrame()
 {
     JS_ASSERT(more());
 
     si_ = start_;
 
@@ -1276,16 +1281,21 @@ InlineFrameIteratorMaybeGC<allowGC>::fin
         pc_ = script_->code + si_.pcOffset();
     }
 
     framesRead_++;
 }
 template void InlineFrameIteratorMaybeGC<NoGC>::findNextFrame();
 template void InlineFrameIteratorMaybeGC<CanGC>::findNextFrame();
 
+// Reenable default optimization flags.
+#if defined(_MSC_VER)
+# pragma optimize("", on)
+#endif
+
 template <AllowGC allowGC>
 bool
 InlineFrameIteratorMaybeGC<allowGC>::isFunctionFrame() const
 {
     return !!callee_;
 }
 template bool InlineFrameIteratorMaybeGC<NoGC>::isFunctionFrame() const;
 template bool InlineFrameIteratorMaybeGC<CanGC>::isFunctionFrame() const;
--- a/js/src/ion/IonSpewer.cpp
+++ b/js/src/ion/IonSpewer.cpp
@@ -26,17 +26,17 @@ using namespace js::ion;
 
 // IonSpewer singleton.
 static IonSpewer ionspewer;
 
 static bool LoggingChecked = false;
 static uint32_t LoggingBits = 0;
 static uint32_t filteredOutCompilations = 0;
 
-static const char *ChannelNames[] =
+static const char * const ChannelNames[] =
 {
 #define IONSPEW_CHANNEL(name) #name,
     IONSPEW_CHANNEL_LIST(IONSPEW_CHANNEL)
 #undef IONSPEW_CHANNEL
 };
 
 static bool
 FilterContainsLocation(HandleScript function)
--- a/js/src/ion/LIR.cpp
+++ b/js/src/ion/LIR.cpp
@@ -165,17 +165,17 @@ LPhi::New(MIRGenerator *gen, MPhi *ins)
     if (!phi->init(gen))
         return NULL;
     return phi;
 }
 
 void
 LInstruction::printName(FILE *fp, Opcode op)
 {
-    static const char *names[] =
+    static const char * const names[] =
     {
 #define LIROP(x) #x,
         LIR_OPCODE_LIST(LIROP)
 #undef LIROP
     };
     const char *name = names[op];
     size_t len = strlen(name);
     for (size_t i = 0; i < len; i++)
@@ -183,17 +183,17 @@ LInstruction::printName(FILE *fp, Opcode
 }
 
 void
 LInstruction::printName(FILE *fp)
 {
     printName(fp, op());
 }
 
-static const char *TypeChars[] =
+static const char * const TypeChars[] =
 {
     "i",            // INTEGER
     "o",            // OBJECT
     "f",            // DOUBLE
 #ifdef JS_NUNBOX32
     "t",            // TYPE
     "d"             // PAYLOAD
 #elif JS_PUNBOX64
--- a/js/src/ion/LiveRangeAllocator.h
+++ b/js/src/ion/LiveRangeAllocator.h
@@ -373,17 +373,17 @@ class VirtualRegister
         ins_ = ins;
         def_ = def;
         isTemp_ = isTemp;
         LiveInterval *initial = new LiveInterval(def->virtualRegister(), 0);
         if (!initial)
             return false;
         return intervals_.append(initial);
     }
-    uint32_t id() {
+    uint32_t id() const {
         return id_;
     }
     LBlock *block() {
         return block_;
     }
     LInstruction *ins() {
         return ins_;
     }
@@ -629,17 +629,17 @@ class LiveRangeAllocator : public Regist
                 continue;
 
             LSafepoint *safepoint = ins->safepoint();
             safepoint->addLiveRegister(a->toRegister());
         }
     }
 
     // Finds the first safepoint that is within range of an interval.
-    size_t findFirstSafepoint(LiveInterval *interval, size_t startFrom)
+    size_t findFirstSafepoint(const LiveInterval *interval, size_t startFrom) const
     {
         size_t i = startFrom;
         for (; i < graph.numSafepoints(); i++) {
             LInstruction *ins = graph.getSafepoint(i);
             if (interval->start() <= inputOf(ins))
                 break;
         }
         return i;
--- a/js/src/ion/MIR.cpp
+++ b/js/src/ion/MIR.cpp
@@ -23,17 +23,17 @@
 using namespace js;
 using namespace js::ion;
 
 using mozilla::BitwiseCast;
 
 void
 MDefinition::PrintOpcodeName(FILE *fp, MDefinition::Opcode op)
 {
-    static const char *names[] =
+    static const char * const names[] =
     {
 #define NAME(x) #x,
         MIR_OPCODE_LIST(NAME)
 #undef NAME
     };
     const char *name = names[op];
     size_t len = strlen(name);
     for (size_t i = 0; i < len; i++)
--- a/js/src/ion/RegisterAllocator.h
+++ b/js/src/ion/RegisterAllocator.h
@@ -320,44 +320,44 @@ class RegisterAllocator
             allRegisters_.take(AnyRegister(NANReg));
         }
 #endif
     }
 
   protected:
     bool init();
 
-    CodePosition outputOf(uint32_t pos) {
+    CodePosition outputOf(uint32_t pos) const {
         return CodePosition(pos, CodePosition::OUTPUT);
     }
-    CodePosition outputOf(LInstruction *ins) {
+    CodePosition outputOf(const LInstruction *ins) const {
         return CodePosition(ins->id(), CodePosition::OUTPUT);
     }
-    CodePosition inputOf(uint32_t pos) {
+    CodePosition inputOf(uint32_t pos) const {
         return CodePosition(pos, CodePosition::INPUT);
     }
-    CodePosition inputOf(LInstruction *ins) {
+    CodePosition inputOf(const LInstruction *ins) const {
         return CodePosition(ins->id(), CodePosition::INPUT);
     }
 
     LMoveGroup *getInputMoveGroup(uint32_t ins);
     LMoveGroup *getMoveGroupAfter(uint32_t ins);
 
     LMoveGroup *getInputMoveGroup(CodePosition pos) {
         return getInputMoveGroup(pos.ins());
     }
     LMoveGroup *getMoveGroupAfter(CodePosition pos) {
         return getMoveGroupAfter(pos.ins());
     }
 
-    size_t findFirstNonCallSafepoint(CodePosition from)
+    size_t findFirstNonCallSafepoint(CodePosition from) const
     {
         size_t i = 0;
         for (; i < graph.numNonCallSafepoints(); i++) {
-            LInstruction *ins = graph.getNonCallSafepoint(i);
+            const LInstruction *ins = graph.getNonCallSafepoint(i);
             if (from <= inputOf(ins))
                 break;
         }
         return i;
     }
 };
 
 } // namespace ion
--- a/js/src/ion/VMFunctions.cpp
+++ b/js/src/ion/VMFunctions.cpp
@@ -557,17 +557,17 @@ FilterArguments(JSContext *cx, JSString 
     // getChars() is fallible, but cannot GC: it can only allocate a character
     // for the flattened string. If this call fails then the calling Ion code
     // will bailout, resume in the interpreter and likely fail again when
     // trying to flatten the string and unwind the stack.
     const jschar *chars = str->getChars(cx);
     if (!chars)
         return false;
 
-    static jschar arguments[] = {'a', 'r', 'g', 'u', 'm', 'e', 'n', 't', 's'};
+    static const jschar arguments[] = {'a', 'r', 'g', 'u', 'm', 'e', 'n', 't', 's'};
     return !StringHasPattern(chars, str->length(), arguments, mozilla::ArrayLength(arguments));
 }
 
 #ifdef JSGC_GENERATIONAL
 void
 PostWriteBarrier(JSRuntime *rt, JSObject *obj)
 {
 #ifdef JS_GC_ZEAL
--- a/js/src/ion/arm/Architecture-arm.h
+++ b/js/src/ion/arm/Architecture-arm.h
@@ -70,18 +70,18 @@ class Registers
         lr = r14,
         r15,
         pc = r15,
         invalid_reg
     } RegisterID;
     typedef RegisterID Code;
 
     static const char *GetName(Code code) {
-        static const char *Names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-                                       "r8", "r9", "r10", "r11", "r12", "sp", "r14", "pc"};
+        static const char * const Names[] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+                                              "r8", "r9", "r10", "r11", "r12", "sp", "r14", "pc"};
         return Names[code];
     }
 
     static const Code StackPointer = sp;
     static const Code Invalid = invalid_reg;
 
     static const uint32_t Total = 16;
     static const uint32_t Allocatable = 13;
@@ -176,18 +176,18 @@ class FloatRegisters
         d28,
         d29,
         d30,
         invalid_freg
     } FPRegisterID;
     typedef FPRegisterID Code;
 
     static const char *GetName(Code code) {
-        static const char *Names[] = { "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
-                                       "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15"};
+        static const char * const Names[] = { "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
+                                              "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15"};
         return Names[code];
     }
 
     static const Code Invalid = invalid_freg;
 
     static const uint32_t Total = 16;
     static const uint32_t Allocatable = 15;
 
--- a/js/src/ion/x64/Architecture-x64.h
+++ b/js/src/ion/x64/Architecture-x64.h
@@ -31,20 +31,20 @@ static const uint32_t ShadowStackSpace =
 // An offset that is illegal for a local variable's stack allocation.
 static const int32_t INVALID_STACK_SLOT       = -1;
 
 class Registers {
   public:
     typedef JSC::X86Registers::RegisterID Code;
 
     static const char *GetName(Code code) {
-        static const char *Names[] = { "rax", "rcx", "rdx", "rbx",
-                                       "rsp", "rbp", "rsi", "rdi",
-                                       "r8",  "r9",  "r10", "r11",
-                                       "r12", "r13", "r14", "r15" };
+        static const char * const Names[] = { "rax", "rcx", "rdx", "rbx",
+                                              "rsp", "rbp", "rsi", "rdi",
+                                              "r8",  "r9",  "r10", "r11",
+                                              "r12", "r13", "r14", "r15" };
         return Names[code];
     }
 
     static const Code StackPointer = JSC::X86Registers::esp;
     static const Code Invalid = JSC::X86Registers::invalid_reg;
 
     static const uint32_t Total = 16;
     static const uint32_t Allocatable = 14;
@@ -113,20 +113,20 @@ class Registers {
 // Smallest integer type that can hold a register bitmask.
 typedef uint16_t PackedRegisterMask;
 
 class FloatRegisters {
   public:
     typedef JSC::X86Registers::XMMRegisterID Code;
 
     static const char *GetName(Code code) {
-        static const char *Names[] = { "xmm0",  "xmm1",  "xmm2",  "xmm3",
-                                       "xmm4",  "xmm5",  "xmm6",  "xmm7",
-                                       "xmm8",  "xmm9",  "xmm10", "xmm11",
-                                       "xmm12", "xmm13", "xmm14", "xmm15" };
+        static const char * const Names[] = { "xmm0",  "xmm1",  "xmm2",  "xmm3",
+                                              "xmm4",  "xmm5",  "xmm6",  "xmm7",
+                                              "xmm8",  "xmm9",  "xmm10", "xmm11",
+                                              "xmm12", "xmm13", "xmm14", "xmm15" };
         return Names[code];
     }
 
     static const Code Invalid = JSC::X86Registers::invalid_xmm;
 
     static const uint32_t Total = 16;
     static const uint32_t Allocatable = 15;
 
--- a/js/src/ion/x86/Architecture-x86.h
+++ b/js/src/ion/x86/Architecture-x86.h
@@ -38,18 +38,18 @@ static const int32_t NUNBOX32_PAYLOAD_OF
 // Size of each bailout table entry. On x86 this is a 5-byte relative call.
 static const uint32_t BAILOUT_TABLE_ENTRY_SIZE    = 5;
 
 class Registers {
   public:
     typedef JSC::X86Registers::RegisterID Code;
 
     static const char *GetName(Code code) {
-        static const char *Names[] = { "eax", "ecx", "edx", "ebx",
-                                       "esp", "ebp", "esi", "edi" };
+        static const char * const Names[] = { "eax", "ecx", "edx", "ebx",
+                                              "esp", "ebp", "esi", "edi" };
         return Names[code];
     }
 
     static const Code StackPointer = JSC::X86Registers::esp;
     static const Code Invalid = JSC::X86Registers::invalid_reg;
 
     static const uint32_t Total = 8;
     static const uint32_t Allocatable = 7;
@@ -102,18 +102,18 @@ class Registers {
 // Smallest integer type that can hold a register bitmask.
 typedef uint8_t PackedRegisterMask;
 
 class FloatRegisters {
   public:
     typedef JSC::X86Registers::XMMRegisterID Code;
 
     static const char *GetName(Code code) {
-        static const char *Names[] = { "xmm0", "xmm1", "xmm2", "xmm3",
-                                       "xmm4", "xmm5", "xmm6", "xmm7" };
+        static const char * const Names[] = { "xmm0", "xmm1", "xmm2", "xmm3",
+                                              "xmm4", "xmm5", "xmm6", "xmm7" };
         return Names[code];
     }
 
     static const Code Invalid = JSC::X86Registers::invalid_xmm;
 
     static const uint32_t Total = 8;
     static const uint32_t Allocatable = 7;
 
--- a/js/src/ion/x86/MacroAssembler-x86.h
+++ b/js/src/ion/x86/MacroAssembler-x86.h
@@ -660,17 +660,17 @@ class MacroAssemblerX86 : public MacroAs
     {
         JS_ASSERT(cond == Equal || cond == NotEqual);
         if (cond == Equal) {
             // Test for magic
             Label notmagic;
             Condition testCond = testMagic(Equal, val);
             j(InvertCondition(testCond), &notmagic);
             // Test magic value
-            branch32(NotEqual, val.payloadReg(), Imm32(static_cast<int32_t>(why)), label);
+            branch32(Equal, val.payloadReg(), Imm32(static_cast<int32_t>(why)), label);
             bind(&notmagic);
         } else {
             Condition testCond = testMagic(NotEqual, val);
             j(testCond, label);
             branch32(NotEqual, val.payloadReg(), Imm32(static_cast<int32_t>(why)), label);
         }
     }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug883490.js
@@ -0,0 +1,33 @@
+//|jit-test| error: TypeError
+function coerceForeign(stdlib, foreign)
+{
+    "use asm";
+
+    var g = foreign.g;
+    var h = foreign.h;
+
+    function f() {
+        +g(0);
+        +g(1);
+        +g(2);
+        +h(2);
+        +h(3);
+    }
+
+    return f;
+}
+function blaat() {
+
+}
+
+var t = coerceForeign(undefined, {
+  g: function(a) {
+    if (a == 2)
+      var blaat = new blaat();
+  },
+  h: function(b) {
+    print(b);
+  }
+})
+
+t();
--- a/js/src/jsapi-tests/testArgumentsObject.cpp
+++ b/js/src/jsapi-tests/testArgumentsObject.cpp
@@ -25,17 +25,17 @@ static const char STRICT_ZERO[] =
     "function f() { 'use strict'; return arguments; }";
 static const char STRICT_ONE[] =
     "function f() { 'use strict'; return arguments; }";
 static const char STRICT_TWO[] =
     "function f() { 'use strict'; return arguments; }";
 static const char STRICT_THREE[] =
     "function f() { 'use strict'; return arguments; }";
 
-static const char *CALL_CODES[] =
+static const char * const CALL_CODES[] =
     { "f()", "f(0)", "f(0, 1)", "f(0, 1, 2)", "f(0, 1, 2, 3)", "f(0, 1, 2, 3, 4)" };
 
 static const size_t MAX_ELEMS = 6;
 
 static void
 ClearElements(Value elems[MAX_ELEMS])
 {
     for (size_t i = 0; i < MAX_ELEMS - 1; i++)
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -164,18 +164,18 @@ class AutoVersionAPI
 
 #ifdef HAVE_VA_LIST_AS_ARRAY
 #define JS_ADDRESSOF_VA_LIST(ap) ((va_list *)(ap))
 #else
 #define JS_ADDRESSOF_VA_LIST(ap) (&(ap))
 #endif
 
 #ifdef JS_USE_JSID_STRUCT_TYPES
-jsid JSID_VOID  = { size_t(JSID_TYPE_VOID) };
-jsid JSID_EMPTY = { size_t(JSID_TYPE_OBJECT) };
+const jsid JSID_VOID  = { size_t(JSID_TYPE_VOID) };
+const jsid JSID_EMPTY = { size_t(JSID_TYPE_OBJECT) };
 #endif
 
 const jsval JSVAL_NULL  = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_NULL,      0));
 const jsval JSVAL_ZERO  = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_INT32,     0));
 const jsval JSVAL_ONE   = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_INT32,     1));
 const jsval JSVAL_FALSE = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN,   JS_FALSE));
 const jsval JSVAL_TRUE  = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_BOOLEAN,   JS_TRUE));
 const jsval JSVAL_VOID  = IMPL_TO_JSVAL(BUILD_JSVAL(JSVAL_TAG_UNDEFINED, 0));
@@ -1801,26 +1801,26 @@ JS_InitStandardClasses(JSContext *cx, JS
 
 typedef struct JSStdName {
     JSClassInitializerOp init;
     size_t      atomOffset;     /* offset of atom pointer in JSAtomState */
     Class       *clasp;
 } JSStdName;
 
 static Handle<PropertyName*>
-StdNameToPropertyName(JSContext *cx, JSStdName *stdn)
+StdNameToPropertyName(JSContext *cx, const JSStdName *stdn)
 {
     return OFFSET_TO_NAME(cx->runtime(), stdn->atomOffset);
 }
 
 /*
  * Table of class initializers and their atom offsets in rt->atomState.
  * If you add a "standard" class, remember to update this table.
  */
-static JSStdName standard_class_atoms[] = {
+static const JSStdName standard_class_atoms[] = {
     {js_InitFunctionClass,              EAGER_ATOM_AND_CLASP(Function)},
     {js_InitObjectClass,                EAGER_ATOM_AND_CLASP(Object)},
     {js_InitArrayClass,                 EAGER_ATOM_AND_CLASP(Array)},
     {js_InitBooleanClass,               EAGER_ATOM_AND_CLASP(Boolean)},
     {js_InitDateClass,                  EAGER_ATOM_AND_CLASP(Date)},
     {js_InitMathClass,                  EAGER_ATOM_AND_CLASP(Math)},
     {js_InitNumberClass,                EAGER_ATOM_AND_CLASP(Number)},
     {js_InitStringClass,                EAGER_ATOM_AND_CLASP(String)},
@@ -1844,17 +1844,17 @@ static JSStdName standard_class_atoms[] 
     {NULL,                              0, NULL}
 };
 
 /*
  * Table of top-level function and constant names and their init functions.
  * If you add a "standard" global function or property, remember to update
  * this table.
  */
-static JSStdName standard_class_names[] = {
+static const JSStdName standard_class_names[] = {
     {js_InitObjectClass,        EAGER_ATOM(eval), CLASP(Object)},
 
     /* Global properties and functions defined by the Number class. */
     {js_InitNumberClass,        EAGER_ATOM(NaN), CLASP(Number)},
     {js_InitNumberClass,        EAGER_ATOM(Infinity), CLASP(Number)},
     {js_InitNumberClass,        EAGER_ATOM(isNaN), CLASP(Number)},
     {js_InitNumberClass,        EAGER_ATOM(isFinite), CLASP(Number)},
     {js_InitNumberClass,        EAGER_ATOM(parseFloat), CLASP(Number)},
@@ -1895,17 +1895,17 @@ static JSStdName standard_class_names[] 
     {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Float64Array), TYPED_ARRAY_CLASP(TYPE_FLOAT64)},
     {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Uint8ClampedArray),
                                 TYPED_ARRAY_CLASP(TYPE_UINT8_CLAMPED)},
     {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(DataView),     &DataViewObject::class_},
 
     {NULL,                      0, NULL}
 };
 
-static JSStdName object_prototype_names[] = {
+static const JSStdName object_prototype_names[] = {
     /* Object.prototype properties (global delegates to Object.prototype). */
     {js_InitObjectClass,        EAGER_ATOM(proto), CLASP(Object)},
 #if JS_HAS_TOSOURCE
     {js_InitObjectClass,        EAGER_ATOM(toSource), CLASP(Object)},
 #endif
     {js_InitObjectClass,        EAGER_ATOM(toString), CLASP(Object)},
     {js_InitObjectClass,        EAGER_ATOM(toLocaleString), CLASP(Object)},
     {js_InitObjectClass,        EAGER_ATOM(valueOf), CLASP(Object)},
@@ -1927,17 +1927,17 @@ static JSStdName object_prototype_names[
 };
 
 JS_PUBLIC_API(JSBool)
 JS_ResolveStandardClass(JSContext *cx, JSObject *objArg, jsid id, JSBool *resolved)
 {
     RootedObject obj(cx, objArg);
     JSRuntime *rt;
     JSAtom *atom;
-    JSStdName *stdnm;
+    const JSStdName *stdnm;
     unsigned i;
 
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id);
     *resolved = false;
 
     rt = cx->runtime();
@@ -3848,34 +3848,40 @@ DefinePropertyById(JSContext *cx, Handle
     /*
      * When we use DefineProperty, we need full scriptable Function objects rather
      * than JSNatives. However, we might be pulling this property descriptor off
      * of something with JSNative property descriptors. If we are, wrap them in
      * JS Function objects.
      */
     if (attrs & JSPROP_NATIVE_ACCESSORS) {
         JS_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
+        JSFunction::Flags zeroFlags = JSAPIToJSFunctionFlags(0);
+        // We can't just use JS_NewFunctionById here because it
+        // assumes a string id.
+        RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : nullptr);
         attrs &= ~JSPROP_NATIVE_ACCESSORS;
         if (getter) {
             RootedObject global(cx, (JSObject*) &obj->global());
-            JSFunction *getobj = JS_NewFunction(cx, (Native) getter, 0, 0, global, NULL);
+            JSFunction *getobj = NewFunction(cx, NullPtr(), (Native) getter, 0,
+                                             zeroFlags, global, atom);
             if (!getobj)
                 return false;
 
             if (get.info)
                 getobj->setJitInfo(get.info);
 
             getter = JS_DATA_TO_FUNC_PTR(PropertyOp, getobj);
             attrs |= JSPROP_GETTER;
         }
         if (setter) {
             // Root just the getter, since the setter is not yet a JSObject.
             AutoRooterGetterSetter getRoot(cx, JSPROP_GETTER, &getter, NULL);
             RootedObject global(cx, (JSObject*) &obj->global());
-            JSFunction *setobj = JS_NewFunction(cx, (Native) setter, 1, 0, global, NULL);
+            JSFunction *setobj = NewFunction(cx, NullPtr(), (Native) setter, 1,
+                                             zeroFlags, global, atom);
             if (!setobj)
                 return false;
 
             if (set.info)
                 setobj->setJitInfo(set.info);
 
             setter = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setobj);
             attrs |= JSPROP_SETTER;
@@ -4042,17 +4048,17 @@ JS_DefineObject(JSContext *cx, JSObject 
     {
         return NULL;
     }
 
     return nobj;
 }
 
 JS_PUBLIC_API(JSBool)
-JS_DefineConstDoubles(JSContext *cx, JSObject *objArg, JSConstDoubleSpec *cds)
+JS_DefineConstDoubles(JSContext *cx, JSObject *objArg, const JSConstDoubleSpec *cds)
 {
     RootedObject obj(cx, objArg);
     JSBool ok;
     unsigned attrs;
 
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     JSPropertyOpWrapper noget = GetterWrapper(NULL);
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1304,18 +1304,18 @@ static JS_ALWAYS_INLINE JSBool
 JSID_IS_EMPTY(const jsid id)
 {
     return ((size_t)JSID_BITS(id) == JSID_TYPE_OBJECT);
 }
 
 #undef id
 
 #ifdef JS_USE_JSID_STRUCT_TYPES
-extern JS_PUBLIC_DATA(jsid) JSID_VOID;
-extern JS_PUBLIC_DATA(jsid) JSID_EMPTY;
+extern JS_PUBLIC_DATA(const jsid) JSID_VOID;
+extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY;
 #else
 # define JSID_VOID ((jsid)JSID_TYPE_VOID)
 # define JSID_EMPTY ((jsid)JSID_TYPE_OBJECT)
 #endif
 
 /*
  * Returns true iff the given jsval is immune to GC and can be used across
  * multiple JSRuntimes without requiring any conversion API.
@@ -3188,17 +3188,17 @@ JS_FreezeObject(JSContext *cx, JSObject 
 extern JS_PUBLIC_API(JSObject *)
 JS_New(JSContext *cx, JSObject *ctor, unsigned argc, jsval *argv);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
                 JSObject *proto, unsigned attrs);
 
 extern JS_PUBLIC_API(JSBool)
-JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds);
+JS_DefineConstDoubles(JSContext *cx, JSObject *obj, const JSConstDoubleSpec *cds);
 
 extern JS_PUBLIC_API(JSBool)
 JS_DefineProperties(JSContext *cx, JSObject *obj, const JSPropertySpec *ps);
 
 extern JS_PUBLIC_API(JSBool)
 JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value,
                   JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
 
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -38,17 +38,17 @@ using mozilla::ArrayLength;
 using mozilla::RangedPtr;
 
 const char *
 js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes)
 {
     return js_ValueToPrintable(cx, StringValue(atom), bytes);
 }
 
-const char * js::TypeStrings[] = {
+const char * const js::TypeStrings[] = {
     js_undefined_str,
     js_object_str,
     js_function_str,
     js_string_str,
     js_number_str,
     js_boolean_str,
     js_null_str,
 };
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -176,17 +176,17 @@ extern const char js_with_str[];
 extern const char js_yield_str[];
 #if JS_HAS_GENERATORS
 extern const char   js_close_str[];
 extern const char   js_send_str[];
 #endif
 
 namespace js {
 
-extern const char * TypeStrings[];
+extern const char * const TypeStrings[];
 
 /*
  * Initialize atom state. Return true on success, false on failure to allocate
  * memory. The caller must zero rt->atomState before calling this function and
  * only call it after js_InitGC successfully returns.
  */
 extern JSBool
 InitAtoms(JSRuntime *rt);
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -94,16 +94,25 @@ js::TraceCycleDetectionSet(JSTracer *trc
         JSObject *prior = e.front();
         MarkObjectRoot(trc, const_cast<JSObject **>(&e.front()), "cycle detector table entry");
         if (prior != e.front())
             e.rekeyFront(e.front());
     }
 }
 
 void
+NewObjectCache::clearNurseryObjects(JSRuntime *rt)
+{
+    for (unsigned i = 0; i < mozilla::ArrayLength(entries); ++i) {
+        if (IsInsideNursery(rt, entries[i].key))
+            mozilla::PodZero(&entries[i]);
+    }
+}
+
+void
 JSRuntime::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf, JS::RuntimeSizes *rtSizes)
 {
     rtSizes->object = mallocSizeOf(this);
 
     rtSizes->atomsTable = atoms.sizeOfExcludingThis(mallocSizeOf);
 
     rtSizes->contexts = 0;
     for (ContextIter acx(this); !acx.done(); acx.next())
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -17,17 +17,16 @@
 #include <string.h>
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "jsprvtd.h"
 #include "jsatom.h"
 #include "jsclist.h"
 #include "jsgc.h"
-#include "jspropertycache.h"
 #include "jspropertytree.h"
 #include "jsprototypes.h"
 #include "jsutil.h"
 #include "prmjtime.h"
 
 #include "ds/LifoAlloc.h"
 #include "frontend/ParseMaps.h"
 #include "gc/Nursery.h"
@@ -336,17 +335,17 @@ class NewObjectCache
   public:
 
     typedef int EntryIndex;
 
     NewObjectCache() { mozilla::PodZero(this); }
     void purge() { mozilla::PodZero(this); }
 
     /* Remove any cached items keyed on moved objects. */
-    inline void clearNurseryObjects(JSRuntime *rt);
+    void clearNurseryObjects(JSRuntime *rt);
 
     /*
      * Get the entry index for the given lookup, return whether there was a hit
      * on an existing entry.
      */
     inline bool lookupProto(Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry);
     inline bool lookupGlobal(Class *clasp, js::GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry);
     inline bool lookupType(Class *clasp, js::types::TypeObject *type, gc::AllocKind kind, EntryIndex *pentry);
@@ -1257,17 +1256,16 @@ struct JSRuntime : public JS::shadow::Ru
     js::MathCache *mathCache_;
     js::MathCache *createMathCache(JSContext *cx);
   public:
     js::MathCache *getMathCache(JSContext *cx) {
         return mathCache_ ? mathCache_ : createMathCache(cx);
     }
 
     js::GSNCache        gsnCache;
-    js::PropertyCache   propertyCache;
     js::NewObjectCache  newObjectCache;
     js::NativeIterCache nativeIterCache;
     js::SourceDataCache sourceDataCache;
     js::EvalCache       evalCache;
 
     /* State used by jsdtoa.cpp. */
     DtoaState           *dtoaState;
 
@@ -1719,18 +1717,16 @@ struct JSContext : js::ContextFriendFiel
     bool hasWErrorOption() const { return hasOption(JSOPTION_WERROR); }
 
     js::LifoAlloc &tempLifoAlloc() { return runtime()->tempLifoAlloc; }
     inline js::LifoAlloc &analysisLifoAlloc();
     inline js::LifoAlloc &typeLifoAlloc();
 
     inline js::PropertyTree &propertyTree();
 
-    js::PropertyCache &propertyCache() { return runtime()->propertyCache; }
-
 #ifdef JS_THREADSAFE
     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;
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -7,16 +7,18 @@
 #ifndef jscntxtinlines_h___
 #define jscntxtinlines_h___
 
 #include "jscntxt.h"
 
 #include "jscompartment.h"
 #include "jsfriendapi.h"
 #include "jsgc.h"
+#include "jsiter.h"
+
 #include "builtin/Object.h" // For js::obj_construct
 #include "frontend/ParseMaps.h"
 #include "vm/Interpreter.h"
 #include "vm/Probes.h"
 #include "vm/RegExpObject.h"
 
 #include "jsgcinlines.h"
 
@@ -26,25 +28,16 @@ namespace js {
 
 inline void
 NewObjectCache::staticAsserts()
 {
     JS_STATIC_ASSERT(NewObjectCache::MAX_OBJ_SIZE == sizeof(JSObject_Slots16));
     JS_STATIC_ASSERT(gc::FINALIZE_OBJECT_LAST == gc::FINALIZE_OBJECT16_BACKGROUND);
 }
 
-inline void
-NewObjectCache::clearNurseryObjects(JSRuntime *rt)
-{
-    for (unsigned i = 0; i < mozilla::ArrayLength(entries); ++i) {
-        if (IsInsideNursery(rt, entries[i].key))
-            mozilla::PodZero(&entries[i]);
-    }
-}
-
 inline bool
 NewObjectCache::lookup(Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry)
 {
     uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + kind;
     *pentry = hash % mozilla::ArrayLength(entries);
 
     Entry *entry = &entries[*pentry];
 
--- a/js/src/jscompartmentinlines.h
+++ b/js/src/jscompartmentinlines.h
@@ -33,34 +33,22 @@ js::AutoCompartment::AutoCompartment(JSC
     cx_->enterCompartment(target->compartment());
 }
 
 js::AutoCompartment::~AutoCompartment()
 {
     cx_->leaveCompartment(origin_);
 }
 
-void *
-js::Allocator::onOutOfMemory(void *p, size_t nbytes)
-{
-    return zone->rt->onOutOfMemory(p, nbytes);
-}
-
 void
 js::Allocator::updateMallocCounter(size_t nbytes)
 {
     zone->rt->updateMallocCounter(zone, nbytes);
 }
 
-void
-js::Allocator::reportAllocationOverflow()
-{
-    js_ReportAllocationOverflow(NULL);
-}
-
 inline void *
 js::Allocator::parallelNewGCThing(gc::AllocKind thingKind, size_t thingSize)
 {
     return arenas.parallelAllocate(zone, thingKind, thingSize);
 }
 
 namespace js {
 
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -538,31 +538,31 @@ Class js::DateClass = {
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     date_convert
 };
 
 /* for use by date_parse */
 
-static const char* wtb[] = {
+static const char* const wtb[] = {
     "am", "pm",
     "monday", "tuesday", "wednesday", "thursday", "friday",
     "saturday", "sunday",
     "january", "february", "march", "april", "may", "june",
     "july", "august", "september", "october", "november", "december",
     "gmt", "ut", "utc",
     "est", "edt",
     "cst", "cdt",
     "mst", "mdt",
     "pst", "pdt"
     /* time zone table needs to be expanded */
 };
 
-static int ttb[] = {
+static const int ttb[] = {
     -1, -2, 0, 0, 0, 0, 0, 0, 0,       /* AM/PM */
     2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
     10000 + 0, 10000 + 0, 10000 + 0,   /* GMT/UT/UTC */
     10000 + 5 * 60, 10000 + 4 * 60,    /* EST/EDT */
     10000 + 6 * 60, 10000 + 5 * 60,    /* CST/CDT */
     10000 + 7 * 60, 10000 + 6 * 60,    /* MST/MDT */
     10000 + 8 * 60, 10000 + 7 * 60     /* PST/PDT */
 };
@@ -2454,22 +2454,22 @@ date_setYear_impl(JSContext *cx, CallArg
 static JSBool
 date_setYear(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_setYear_impl>(cx, args);
 }
 
 /* constants for toString, toUTCString */
-static char js_NaN_date_str[] = "Invalid Date";
-static const char* days[] =
+static const char js_NaN_date_str[] = "Invalid Date";
+static const char * const days[] =
 {
    "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
 };
-static const char* months[] =
+static const char * const months[] =
 {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 };
 
 
 // Avoid dependence on PRMJ_FormatTimeUSEnglish, because it
 // requires a PRMJTime... which only has 16-bit years.  Sub-ECMA.
 static void
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -887,17 +887,17 @@ js::GetErrorTypeName(JSContext* cx, int1
         return NULL;
     }
     JSProtoKey key = GetExceptionProtoKey(exnType);
     return ClassName(key, cx)->chars();
 }
 
 #if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES )
 /* For use below... get character strings for error name and exception name */
-static struct exnname { char *name; char *exception; } errortoexnname[] = {
+static const struct exnname { char *name; char *exception; } errortoexnname[] = {
 #define MSG_DEF(name, number, count, exception, format) \
     {#name, #exception},
 #include "js.msg"
 #undef MSG_DEF
 };
 #endif /* DEBUG */
 
 JSBool
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -92,17 +92,17 @@ using mozilla::Maybe;
 
 /* Perform a Full GC every 20 seconds if MaybeGC is called */
 static const uint64_t GC_IDLE_FULL_SPAN = 20 * 1000 * 1000;
 
 /* Increase the IGC marking slice time if we are in highFrequencyGC mode. */
 static const int IGC_MARK_SLICE_MULTIPLIER = 2;
 
 /* This array should be const, but that doesn't link right under GCC. */
-AllocKind gc::slotsToThingKind[] = {
+const AllocKind gc::slotsToThingKind[] = {
     /* 0 */  FINALIZE_OBJECT0,  FINALIZE_OBJECT2,  FINALIZE_OBJECT2,  FINALIZE_OBJECT4,
     /* 4 */  FINALIZE_OBJECT4,  FINALIZE_OBJECT8,  FINALIZE_OBJECT8,  FINALIZE_OBJECT8,
     /* 8 */  FINALIZE_OBJECT8,  FINALIZE_OBJECT12, FINALIZE_OBJECT12, FINALIZE_OBJECT12,
     /* 12 */ FINALIZE_OBJECT12, FINALIZE_OBJECT16, FINALIZE_OBJECT16, FINALIZE_OBJECT16,
     /* 16 */ FINALIZE_OBJECT16
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(slotsToThingKind) == SLOTS_TO_THING_KIND_LIMIT);
@@ -171,17 +171,17 @@ static const AllocKind FinalizePhaseScri
     FINALIZE_SCRIPT,
     FINALIZE_LAZY_SCRIPT
 };
 
 static const AllocKind FinalizePhaseIonCode[] = {
     FINALIZE_IONCODE
 };
 
-static const AllocKind* FinalizePhases[] = {
+static const AllocKind * const FinalizePhases[] = {
     FinalizePhaseStrings,
     FinalizePhaseScripts,
     FinalizePhaseIonCode
 };
 static const int FinalizePhaseCount = sizeof(FinalizePhases) / sizeof(AllocKind*);
 
 static const int FinalizePhaseLength[] = {
     sizeof(FinalizePhaseStrings) / sizeof(AllocKind),
@@ -214,17 +214,17 @@ static const AllocKind BackgroundPhaseSt
 };
 
 static const AllocKind BackgroundPhaseShapes[] = {
     FINALIZE_SHAPE,
     FINALIZE_BASE_SHAPE,
     FINALIZE_TYPE_OBJECT
 };
 
-static const AllocKind* BackgroundPhases[] = {
+static const AllocKind * const BackgroundPhases[] = {
     BackgroundPhaseObjects,
     BackgroundPhaseStrings,
     BackgroundPhaseShapes
 };
 static const int BackgroundPhaseCount = sizeof(BackgroundPhases) / sizeof(AllocKind*);
 
 static const int BackgroundPhaseLength[] = {
     sizeof(BackgroundPhaseObjects) / sizeof(AllocKind),
@@ -2566,17 +2566,16 @@ static void
 PurgeRuntime(JSRuntime *rt)
 {
     for (GCCompartmentsIter comp(rt); !comp.done(); comp.next())
         comp->purge();
 
     rt->freeLifoAlloc.transferUnusedFrom(&rt->tempLifoAlloc);
 
     rt->gsnCache.purge();
-    rt->propertyCache.purge(rt);
     rt->newObjectCache.purge();
     rt->nativeIterCache.purge();
     rt->sourceDataCache.purge();
     rt->evalCache.clear();
 
     if (!rt->activeCompilations)
         rt->parseMapPool.purgeAll();
 }
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -10,16 +10,17 @@
 #define jsgc_h___
 
 #include <setjmp.h>
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/Util.h"
 
 #include "jsalloc.h"
+#include "jsclass.h"
 #include "jstypes.h"
 #include "jsprvtd.h"
 #include "jspubtd.h"
 #include "jslock.h"
 #include "jsutil.h"
 #include "jsversion.h"
 
 #include "ds/BitArray.h"
@@ -212,16 +213,31 @@ IsBackgroundFinalized(AllocKind kind)
         true,      /* FINALIZE_STRING */
         false,     /* FINALIZE_EXTERNAL_STRING */
         false,     /* FINALIZE_IONCODE */
     };
     JS_STATIC_ASSERT(JS_ARRAY_LENGTH(map) == FINALIZE_LIMIT);
     return map[kind];
 }
 
+static inline bool
+CanBeFinalizedInBackground(gc::AllocKind kind, Class *clasp)
+{
+    JS_ASSERT(kind <= gc::FINALIZE_OBJECT_LAST);
+    /* If the class has no finalizer or a finalizer that is safe to call on
+     * a different thread, we change the finalize kind. For example,
+     * FINALIZE_OBJECT0 calls the finalizer on the main thread,
+     * FINALIZE_OBJECT0_BACKGROUND calls the finalizer on the gcHelperThread.
+     * IsBackgroundFinalized is called to prevent recursively incrementing
+     * the finalize kind; kind may already be a background finalize kind.
+     */
+    return (!gc::IsBackgroundFinalized(kind) &&
+            (!clasp->finalize || (clasp->flags & JSCLASS_BACKGROUND_FINALIZE)));
+}
+
 inline JSGCTraceKind
 GetGCThingTraceKind(const void *thing);
 
 /*
  * ArenaList::head points to the start of the list. Normally cursor points
  * to the first arena in the list with some free things and all arenas
  * before cursor are fully allocated. However, as the arena currently being
  * allocated from is considered full while its list of free spans is moved
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -46,17 +46,17 @@ struct AutoMarkInDeadZone
     bool scheduled;
 };
 
 namespace gc {
 
 /* Capacity for slotsToThingKind */
 const size_t SLOTS_TO_THING_KIND_LIMIT = 17;
 
-extern AllocKind slotsToThingKind[];
+extern const AllocKind slotsToThingKind[];
 
 /* Get the best kind to use when making an object with the given slot count. */
 static inline AllocKind
 GetGCObjectKind(size_t numSlots)
 {
     if (numSlots >= SLOTS_TO_THING_KIND_LIMIT)
         return FINALIZE_OBJECT16;
     return slotsToThingKind[numSlots];
@@ -72,35 +72,31 @@ GetGCObjectKind(Class *clasp)
         nslots++;
     return GetGCObjectKind(nslots);
 }
 
 /* As for GetGCObjectKind, but for dense array allocation. */
 static inline AllocKind
 GetGCArrayKind(size_t numSlots)
 {
-    extern AllocKind slotsToThingKind[];
-
     /*
      * Dense arrays can use their fixed slots to hold their elements array
      * (less two Values worth of ObjectElements header), but if more than the
      * maximum number of fixed slots is needed then the fixed slots will be
      * unused.
      */
     JS_STATIC_ASSERT(ObjectElements::VALUES_PER_HEADER == 2);
     if (numSlots > JSObject::NELEMENTS_LIMIT || numSlots + 2 >= SLOTS_TO_THING_KIND_LIMIT)
         return FINALIZE_OBJECT2;
     return slotsToThingKind[numSlots + 2];
 }
 
 static inline AllocKind
 GetGCObjectFixedSlotsKind(size_t numFixedSlots)
 {
-    extern AllocKind slotsToThingKind[];
-
     JS_ASSERT(numFixedSlots < SLOTS_TO_THING_KIND_LIMIT);
     return slotsToThingKind[numFixedSlots];
 }
 
 static inline AllocKind
 GetBackgroundAllocKind(AllocKind kind)
 {
     JS_ASSERT(!IsBackgroundFinalized(kind));
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -144,31 +144,31 @@ types::InferSpewColorReset()
         return "";
     return "\x1b[0m";
 }
 
 const char *
 types::InferSpewColor(TypeConstraint *constraint)
 {
     /* Type constraints are printed out using foreground colors. */
-    static const char *colors[] = { "\x1b[31m", "\x1b[32m", "\x1b[33m",
-                                    "\x1b[34m", "\x1b[35m", "\x1b[36m",
-                                    "\x1b[37m" };
+    static const char * const colors[] = { "\x1b[31m", "\x1b[32m", "\x1b[33m",
+                                           "\x1b[34m", "\x1b[35m", "\x1b[36m",
+                                           "\x1b[37m" };
     if (!InferSpewColorable())
         return "";
     return colors[DefaultHasher<TypeConstraint *>::hash(constraint) % 7];
 }
 
 const char *
 types::InferSpewColor(TypeSet *types)
 {
     /* Type sets are printed out using bold colors. */
-    static const char *colors[] = { "\x1b[1;31m", "\x1b[1;32m", "\x1b[1;33m",
-                                    "\x1b[1;34m", "\x1b[1;35m", "\x1b[1;36m",
-                                    "\x1b[1;37m" };
+    static const char * const colors[] = { "\x1b[1;31m", "\x1b[1;32m", "\x1b[1;33m",
+                                           "\x1b[1;34m", "\x1b[1;35m", "\x1b[1;36m",
+                                           "\x1b[1;37m" };
     if (!InferSpewColorable())
         return "";
     return colors[DefaultHasher<TypeSet *>::hash(types) % 7];
 }
 
 const char *
 types::TypeString(Type type)
 {
--- a/js/src/jskwgen.cpp
+++ b/js/src/jskwgen.cpp
@@ -1,23 +1,20 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 <stddef.h>
 #include <assert.h>
+#include <ctype.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#include "jsversion.h"
 
 #include "vm/Keywords.h"
 
 const char * const keyword_list[] = {
 #define KEYWORD_STRING(keyword, name, type, op, version) #keyword,
     FOR_EACH_JAVASCRIPT_KEYWORD(KEYWORD_STRING)
 #undef KEYWORD_STRING
 };
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -68,17 +68,17 @@ using mozilla::SpecificNaN;
 #endif
 #ifndef M_SQRT2
 #define M_SQRT2         1.41421356237309504880
 #endif
 #ifndef M_SQRT1_2
 #define M_SQRT1_2       0.70710678118654752440
 #endif
 
-static JSConstDoubleSpec math_constants[] = {
+static const JSConstDoubleSpec math_constants[] = {
     {M_E,       "E",            0, {0,0,0}},
     {M_LOG2E,   "LOG2E",        0, {0,0,0}},
     {M_LOG10E,  "LOG10E",       0, {0,0,0}},
     {M_LN2,     "LN2",          0, {0,0,0}},
     {M_LN10,    "LN10",         0, {0,0,0}},
     {M_PI,      "PI",           0, {0,0,0}},
     {M_SQRT2,   "SQRT2",        0, {0,0,0}},
     {M_SQRT1_2, "SQRT1_2",      0, {0,0,0}},
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3403,18 +3403,17 @@ DefinePropertyOrElement(JSContext *cx, H
     return true;
 }
 
 bool
 js::DefineNativeProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
                          PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                          unsigned flags, int shortid, unsigned defineHow /* = 0 */)
 {
-    JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_DONT_PURGE |
-                             DNP_SKIP_TYPE)) == 0);
+    JS_ASSERT((defineHow & ~(DNP_DONT_PURGE | DNP_SKIP_TYPE)) == 0);
     JS_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
 
     AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
 
     /*
      * If defining a getter or setter, we must check for its counterpart and
      * update the attributes and property ops.  A getter or setter is really
      * only half of a property.
@@ -3998,19 +3997,16 @@ GetPropertyHelperInline(JSContext *cx,
                : JSObject::getGeneric(cx, obj2Handle, obj2Handle, idHandle, vpHandle);
     }
 
     if (IsImplicitDenseElement(shape)) {
         vp.set(obj2->getDenseElement(JSID_TO_INT(id)));
         return true;
     }
 
-    if (getHow & JSGET_CACHE_RESULT)
-        cx->propertyCache().fill(cx, obj, obj2, shape);
-
     /* This call site is hot -- use the always-inlined variant of js_NativeGet(). */
     if (!NativeGetInline<allowGC>(cx, obj, receiver, obj2, shape, getHow, vp))
         return JS_FALSE;
 
     return JS_TRUE;
 }
 
 bool
@@ -4267,17 +4263,17 @@ JSObject::callMethod(JSContext *cx, Hand
         return false;
     return Invoke(cx, ObjectValue(*obj), fval, argc, argv, vp.address());
 }
 
 JSBool
 baseops::SetPropertyHelper(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
                            unsigned defineHow, MutableHandleValue vp, JSBool strict)
 {
-    JS_ASSERT((defineHow & ~(DNP_CACHE_RESULT | DNP_UNQUALIFIED)) == 0);
+    JS_ASSERT((defineHow & ~DNP_UNQUALIFIED) == 0);
 
     if (JS_UNLIKELY(obj->watched())) {
         /* Fire watchpoints, if any. */
         WatchpointMap *wpmap = cx->compartment()->watchpointMap;
         if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
             return false;
     }
 
@@ -4355,19 +4351,16 @@ baseops::SetPropertyHelper(JSContext *cx
         }
 
         attrs = shape->attributes();
         if (pobj != obj) {
             /*
              * We found id in a prototype object: prepare to share or shadow.
              */
             if (!shape->shadowable()) {
-                if (defineHow & DNP_CACHE_RESULT)
-                    cx->propertyCache().fill(cx, obj, pobj, shape);
-
                 if (shape->hasDefaultSetter() && !shape->hasGetterValue())
                     return JS_TRUE;
 
                 return shape->set(cx, obj, receiver, strict, vp);
             }
 
             /*
              * Preserve attrs except JSPROP_SHARED, getter, and setter when
@@ -4436,19 +4429,16 @@ baseops::SetPropertyHelper(JSContext *cx
 
         if (getter == JS_PropertyStub)
             AddTypePropertyId(cx, obj, id, vp);
 
         return DefinePropertyOrElement(cx, obj, id, getter, setter,
                                        attrs, flags, shortid, vp, true, strict);
     }
 
-    if (defineHow & DNP_CACHE_RESULT)
-        cx->propertyCache().fill(cx, obj, obj, shape);
-
     return js_NativeSet(cx, obj, receiver, shape, strict, vp);
 }
 
 JSBool
 baseops::SetElementHelper(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
                           unsigned defineHow, MutableHandleValue vp, JSBool strict)
 {
     RootedId id(cx);
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -1195,22 +1195,21 @@ extern JSObject *
 CreateThis(JSContext *cx, js::Class *clasp, js::HandleObject callee);
 
 extern JSObject *
 CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto, HandleObject parent);
 
 /*
  * Flags for the defineHow parameter of js_DefineNativeProperty.
  */
-const unsigned DNP_CACHE_RESULT = 1;   /* an interpreter call from JSOP_INITPROP */
-const unsigned DNP_DONT_PURGE   = 2;   /* suppress js_PurgeScopeChain */
-const unsigned DNP_UNQUALIFIED  = 4;   /* Unqualified property set.  Only used in
+const unsigned DNP_DONT_PURGE   = 1;   /* suppress js_PurgeScopeChain */
+const unsigned DNP_UNQUALIFIED  = 2;   /* Unqualified property set.  Only used in
                                        the defineHow argument of
                                        js_SetPropertyHelper. */
-const unsigned DNP_SKIP_TYPE    = 8;   /* Don't update type information */
+const unsigned DNP_SKIP_TYPE    = 4;   /* Don't update type information */
 
 /*
  * Return successfully added or changed shape or NULL on error.
  */
 extern bool
 DefineNativeProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
                      PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
                      unsigned flags, int shortid, unsigned defineHow = 0);
@@ -1287,19 +1286,16 @@ extern bool
 LookupNameWithGlobalDefault(JSContext *cx, HandlePropertyName name, HandleObject scopeChain,
                             MutableHandleObject objp);
 
 }
 
 extern JSObject *
 js_FindVariableScope(JSContext *cx, JSFunction **funp);
 
-/* JSGET_CACHE_RESULT is the analogue of DNP_CACHE_RESULT. */
-const unsigned JSGET_CACHE_RESULT = 1; // from a caching interpreter opcode
-
 /*
  * NB: js_NativeGet and js_NativeSet are called with the scope containing shape
  * (pobj's scope for Get, obj's for Set) locked, and on successful return, that
  * scope is again locked.  But on failure, both functions return false with the
  * scope containing shape unlocked.
  */
 extern JSBool
 js_NativeGet(JSContext *cx, js::Handle<JSObject*> obj, js::Handle<JSObject*> pobj,
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1455,31 +1455,16 @@ class AutoPropertyDescriptorRooter : pri
         getter = desc->getter;
         setter = desc->setter;
         value = desc->value;
     }
 
     friend void AutoGCRooter::trace(JSTracer *trc);
 };
 
-static inline bool
-CanBeFinalizedInBackground(gc::AllocKind kind, Class *clasp)
-{
-    JS_ASSERT(kind <= gc::FINALIZE_OBJECT_LAST);
-    /* If the class has no finalizer or a finalizer that is safe to call on
-     * a different thread, we change the finalize kind. For example,
-     * FINALIZE_OBJECT0 calls the finalizer on the main thread,
-     * FINALIZE_OBJECT0_BACKGROUND calls the finalizer on the gcHelperThread.
-     * IsBackgroundFinalized is called to prevent recursively incrementing
-     * the finalize kind; kind may already be a background finalize kind.
-     */
-    return (!gc::IsBackgroundFinalized(kind) &&
-            (!clasp->finalize || (clasp->flags & JSCLASS_BACKGROUND_FINALIZE)));
-}
-
 /*
  * Make an object with the specified prototype. If parent is null, it will
  * default to the prototype's global if the prototype is non-null.
  */
 JSObject *
 NewObjectWithGivenProto(JSContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
                         gc::AllocKind allocKind, NewObjectKind newKind);
 
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -68,34 +68,34 @@ static const char js_for_each_str[]  = "
 
 const JSCodeSpec js_CodeSpec[] = {
 #define OPDEF(op,val,name,token,length,nuses,ndefs,format) \
     {length,nuses,ndefs,format},
 #include "jsopcode.tbl"
 #undef OPDEF
 };
 
-unsigned js_NumCodeSpecs = JS_ARRAY_LENGTH(js_CodeSpec);
+const unsigned js_NumCodeSpecs = JS_ARRAY_LENGTH(js_CodeSpec);
 
 /*
  * Each element of the array is either a source literal associated with JS
  * bytecode or null.
  */
-static const char *CodeToken[] = {
+static const char * const CodeToken[] = {
 #define OPDEF(op,val,name,token,length,nuses,ndefs,format) \
     token,
 #include "jsopcode.tbl"
 #undef OPDEF
 };
 
 /*
  * Array of JS bytecode names used by PC count JSON, DEBUG-only js_Disassemble
  * and JIT debug spew.
  */
-const char *js_CodeName[] = {
+const char * const js_CodeName[] = {
 #define OPDEF(op,val,name,token,length,nuses,ndefs,format) \
     name,
 #include "jsopcode.tbl"
 #undef OPDEF
 };
 
 /************************************************************************/
 
@@ -167,27 +167,27 @@ js::StackDefs(JSScript *script, jsbyteco
     const JSCodeSpec &cs = js_CodeSpec[op];
     if (cs.ndefs >= 0)
         return cs.ndefs;
 
     uint32_t n = NumBlockSlots(script, pc);
     return op == JSOP_ENTERLET1 ? n + 1 : n;
 }
 
-static const char * countBaseNames[] = {
+static const char * const countBaseNames[] = {
     "interp",
     "mjit",
     "mjit_calls",
     "mjit_code",
     "mjit_pics"
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) == PCCounts::BASE_LIMIT);
 
-static const char * countAccessNames[] = {
+static const char * const countAccessNames[] = {
     "infer_mono",
     "infer_di",
     "infer_poly",
     "infer_barrier",
     "infer_nobarrier",
     "observe_undefined",
     "observe_null",
     "observe_boolean",
@@ -195,42 +195,42 @@ static const char * countAccessNames[] =
     "observe_double",
     "observe_string",
     "observe_object"
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
                  JS_ARRAY_LENGTH(countAccessNames) == PCCounts::ACCESS_LIMIT);
 
-static const char * countElementNames[] = {
+static const char * const countElementNames[] = {
     "id_int",
     "id_double",
     "id_other",
     "id_unknown",
     "elem_typed",
     "elem_packed",
     "elem_dense",
     "elem_other"
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
                  JS_ARRAY_LENGTH(countAccessNames) +
                  JS_ARRAY_LENGTH(countElementNames) == PCCounts::ELEM_LIMIT);
 
-static const char * countPropertyNames[] = {
+static const char * const countPropertyNames[] = {
     "prop_static",
     "prop_definite",
     "prop_other"
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
                  JS_ARRAY_LENGTH(countAccessNames) +
                  JS_ARRAY_LENGTH(countPropertyNames) == PCCounts::PROP_LIMIT);
 
-static const char * countArithNames[] = {
+static const char * const countArithNames[] = {
     "arith_int",
     "arith_double",
     "arith_other",
     "arith_unknown",
 };
 
 JS_STATIC_ASSERT(JS_ARRAY_LENGTH(countBaseNames) +
                  JS_ARRAY_LENGTH(countArithNames) == PCCounts::ARITH_LIMIT);
@@ -2081,17 +2081,18 @@ AppendJSONProperty(StringBuffer &buf, co
 
     buf.append('\"');
     buf.appendInflated(name, strlen(name));
     buf.appendInflated("\":", 2);
 }
 
 static void
 AppendArrayJSONProperties(JSContext *cx, StringBuffer &buf,
-                          double *values, const char **names, unsigned count, MaybeComma &comma)
+                          double *values, const char * const *names, unsigned count,
+                          MaybeComma &comma)
 {
     for (unsigned i = 0; i < count; i++) {
         if (values[i]) {
             AppendJSONProperty(buf, names[i], comma);
             comma = COMMA;
             NumberValueToStringBuffer(cx, DoubleValue(values[i]), buf);
         }
     }
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -210,48 +210,34 @@ struct JSCodeSpec {
     int8_t              nuses;          /* arity, -1 if variadic */
     int8_t              ndefs;          /* number of stack results */
     uint32_t            format;         /* immediate operand format */
 
     uint32_t type() const { return JOF_TYPE(format); }
 };
 
 extern const JSCodeSpec js_CodeSpec[];
-extern unsigned            js_NumCodeSpecs;
-extern const char       *js_CodeName[];
+extern const unsigned   js_NumCodeSpecs;
+extern const char       * const js_CodeName[];
 extern const char       js_EscapeMap[];
 
 /* Silence unreferenced formal parameter warnings */
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(disable:4100)
 #endif
 
 /*
  * Return a GC'ed string containing the chars in str, with any non-printing
  * chars or quotes (' or " as specified by the quote argument) escaped, and
  * with the quote character at the beginning and end of the result string.
  */
 extern JSString *
 js_QuoteString(JSContext *cx, JSString *str, jschar quote);
 
-#define GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom)                       \
-    JS_BEGIN_MACRO                                                            \
-        JS_ASSERT(js_CodeSpec[*(pc)].format & JOF_ATOM);                      \
-        (atom) = (script)->getAtom(GET_UINT32_INDEX((pc) + (pcoff)));         \
-    JS_END_MACRO
-
-#define GET_NAME_FROM_BYTECODE(script, pc, pcoff, name)                       \
-    JS_BEGIN_MACRO                                                            \
-        JSAtom *atom_;                                                        \
-        GET_ATOM_FROM_BYTECODE(script, pc, pcoff, atom_);                     \
-        JS_ASSERT(js_CodeSpec[*(pc)].format & (JOF_NAME | JOF_PROP));         \
-        (name) = atom_->asPropertyName();                                     \
-    JS_END_MACRO
-
 namespace js {
 
 extern unsigned
 StackUses(JSScript *script, jsbytecode *pc);
 
 extern unsigned
 StackDefs(JSScript *script, jsbytecode *pc);
 
@@ -647,17 +633,17 @@ class PCCounts
         }
         if (arithOp(op))
             return ARITH_LIMIT;
         return BASE_LIMIT;
     }
 
     static const char *countName(JSOp op, size_t which);
 
-    double *rawCounts() { return counts; }
+    double *rawCounts() const { return counts; }
 
     double& get(size_t which) {
         JS_ASSERT(which < capacity);
         return counts[which];
     }
 
     /* Boolean conversion, for 'if (counters) ...' */
     operator void*() const {
--- a/js/src/jsopcodeinlines.h
+++ b/js/src/jsopcodeinlines.h
@@ -80,32 +80,16 @@ BytecodeFallsThrough(JSOp op)
       case JSOP_GOSUB:
         /* These fall through indirectly, after executing a 'finally'. */
         return true;
       default:
         return true;
     }
 }
 
-static inline PropertyName *
-GetNameFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op)
-{
-    if (op == JSOP_LENGTH)
-        return cx->names().length;
-
-    // The method JIT's implementation of instanceof contains an internal lookup
-    // of the prototype property.
-    if (op == JSOP_INSTANCEOF)
-        return cx->names().classPrototype;
-
-    PropertyName *name;
-    GET_NAME_FROM_BYTECODE(script, pc, 0, name);
-    return name;
-}
-
 class BytecodeRange {
   public:
     BytecodeRange(JSContext *cx, JSScript *script)
       : script(cx, script), pc(script->code), end(pc + script->length) {}
     bool empty() const { return pc == end; }
     jsbytecode *frontPC() const { return pc; }
     JSOp frontOpcode() const { return JSOp(*pc); }
     size_t frontOffset() const { return pc - script->code; }
deleted file mode 100644
--- a/js/src/jspropertycache.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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 "jspropertycache.h"
-
-#include "mozilla/PodOperations.h"
-
-#include "jscntxt.h"
-
-#include "jsobjinlines.h"
-#include "jsopcodeinlines.h"
-
-using namespace js;
-
-using mozilla::PodArrayZero;
-
-PropertyCacheEntry *
-PropertyCache::fill(JSContext *cx, JSObject *obj, JSObject *pobj, Shape *shape)
-{
-    JS_ASSERT(this == &cx->propertyCache());
-    JS_ASSERT(!cx->runtime()->isHeapBusy());
-
-    /*
-     * Don't cache entries on indexed properties. Indexes can be added or
-     * deleted from the dense elements of objects along the prototype chain
-     * wihout any shape changes.
-     */
-    if (JSID_IS_INT(shape->propid()))
-        return JS_NO_PROP_CACHE_FILL;
-
-    /*
-     * Check for overdeep scope and prototype chain. Because resolve, getter,
-     * and setter hooks can change the prototype chain using JS_SetPrototype
-     * after LookupPropertyWithFlags has returned, we calculate the protoIndex
-     * here and not in LookupPropertyWithFlags.
-     */
-
-    JSObject *tmp = obj;
-    unsigned protoIndex = 0;
-    while (tmp != pobj) {
-        /*
-         * Don't cache entries across prototype lookups which can mutate in
-         * arbitrary ways without a shape change.
-         */
-        if (tmp->hasUncacheableProto()) {
-            PCMETER(noprotos++);
-            return JS_NO_PROP_CACHE_FILL;
-        }
-
-        tmp = tmp->getProto();
-
-        /*
-         * We cannot cache properties coming from native objects behind
-         * non-native ones on the prototype chain. The non-natives can
-         * mutate in arbitrary way without changing any shapes.
-         */
-        if (!tmp || !tmp->isNative()) {
-            PCMETER(noprotos++);
-            return JS_NO_PROP_CACHE_FILL;
-        }
-        ++protoIndex;
-    }
-
-    typedef PropertyCacheEntry Entry;
-    if (protoIndex > Entry::MaxProtoIndex) {
-        PCMETER(longchains++);
-        return JS_NO_PROP_CACHE_FILL;
-    }
-
-    /*
-     * Optimize the cached vword based on our parameters and the current pc's
-     * opcode format flags.
-     */
-    jsbytecode *pc;
-    (void) cx->stack.currentScript(&pc);
-    JSOp op = JSOp(*pc);
-    const JSCodeSpec *cs = &js_CodeSpec[op];
-
-    if ((cs->format & JOF_SET) && obj->watched())
-        return JS_NO_PROP_CACHE_FILL;
-
-    if (obj == pobj) {
-        JS_ASSERT(protoIndex == 0);
-    } else {
-        JS_ASSERT(protoIndex != 0);
-        JS_ASSERT((protoIndex == 1) == (obj->getProto() == pobj));
-
-        if (protoIndex != 1) {
-            /*
-             * Make sure that a later shadowing assignment will enter
-             * PurgeProtoChain and invalidate this entry, bug 479198.
-             */
-            if (!obj->isDelegate())
-                return JS_NO_PROP_CACHE_FILL;
-        }
-    }
-
-    PropertyCacheEntry *entry = &table[hash(pc, obj->lastProperty())];
-    PCMETER(entry->vword.isNull() || recycles++);
-    entry->assign(pc, obj->lastProperty(), pobj->lastProperty(), shape, protoIndex);
-
-    empty = false;
-    PCMETER(fills++);
-
-    /*
-     * The modfills counter is not exact. It increases if a getter or setter
-     * recurse into the interpreter.
-     */
-    PCMETER(entry == pctestentry || modfills++);
-    PCMETER(pctestentry = NULL);
-    return entry;
-}
-
-PropertyName *
-PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject **pobjp,
-                        PropertyCacheEntry *entry)
-{
-    JSObject *obj, *pobj;
-    RootedScript script(cx, cx->stack.currentScript());
-
-    JS_ASSERT(this == &cx->propertyCache());
-    JS_ASSERT(uint32_t(pc - script->code) < script->length);
-
-    JSOp op = JSOp(*pc);
-
-    obj = *objp;
-
-    if (entry->kpc != pc) {
-        PCMETER(kpcmisses++);
-
-        PropertyName *name = GetNameFromBytecode(cx, script, pc, op);
-#ifdef DEBUG_notme
-        JSAutoByteString printable;
-        fprintf(stderr,
-                "id miss for %s from %s:%u"
-                " (pc %u, kpc %u, kshape %p, shape %p)\n",
-                js_AtomToPrintableString(cx, name, &printable),
-                script->filename,
-                js_PCToLineNumber(cx, script, pc),
-                pc - script->code,
-                entry->kpc - script->code,
-                entry->kshape,
-                obj->lastProperty());
-                js_Disassemble1(cx, script, pc,
-                                pc - script->code,
-                                JS_FALSE, stderr);
-#endif
-
-        return name;
-    }
-
-    if (entry->kshape != obj->lastProperty()) {
-        PCMETER(kshapemisses++);
-        return GetNameFromBytecode(cx, script, pc, op);
-    }
-
-    /*
-     * PropertyCache::test handles only the direct and immediate-prototype hit
-     * cases. All others go here.
-     */
-    pobj = obj;
-
-    uint8_t protoIndex = entry->protoIndex;
-    while (protoIndex > 0) {
-        JSObject *tmp = pobj->getProto();
-        if (!tmp || !tmp->isNative())
-            break;
-        pobj = tmp;
-        protoIndex--;
-    }
-
-    if (pobj->lastProperty() == entry->pshape) {
-#ifdef DEBUG
-        Rooted<PropertyName*> name(cx, GetNameFromBytecode(cx, script, pc, op));
-        JS_ASSERT(pobj->nativeContains(cx, name));
-#endif
-        *pobjp = pobj;
-        return NULL;
-    }
-
-    PCMETER(vcapmisses++);
-    return GetNameFromBytecode(cx, script, pc, op);
-}
-
-#ifdef DEBUG
-void
-PropertyCache::assertEmpty()
-{
-    JS_ASSERT(empty);
-    for (unsigned i = 0; i < SIZE; i++) {
-        JS_ASSERT(!table[i].kpc);
-        JS_ASSERT(!table[i].kshape);
-        JS_ASSERT(!table[i].pshape);
-        JS_ASSERT(!table[i].prop);
-        JS_ASSERT(!table[i].protoIndex);
-    }
-}
-#endif
-
-void
-PropertyCache::purge(JSRuntime *rt)
-{
-    if (empty) {
-        assertEmpty();
-        return;
-    }
-
-    PodArrayZero(table);
-    empty = true;
-
-#ifdef JS_PROPERTY_CACHE_METERING
-  { static FILE *fp;
-    if (!fp)
-        fp = fopen("/tmp/propcache.stats", "w");
-    if (fp) {
-        fputs("Property cache stats for ", fp);
-        fprintf(fp, "GC %lu\n", (unsigned long)rt->gcNumber);
-
-# define P(mem) fprintf(fp, "%11s %10lu\n", #mem, (unsigned long)mem)
-        P(fills);
-        P(nofills);
-        P(rofills);
-        P(disfills);
-        P(oddfills);
-        P(add2dictfills);
-        P(modfills);
-        P(brandfills);
-        P(noprotos);
-        P(longchains);
-        P(recycles);
-        P(tests);
-        P(pchits);
-        P(protopchits);
-        P(initests);
-        P(inipchits);
-        P(inipcmisses);
-        P(settests);
-        P(addpchits);
-        P(setpchits);
-        P(setpcmisses);
-        P(setmisses);
-        P(kpcmisses);
-        P(kshapemisses);
-        P(vcapmisses);
-        P(misses);
-        P(flushes);
-        P(pcpurges);
-# undef P
-
-        fprintf(fp, "hit rates: pc %g%% (proto %g%%), set %g%%, ini %g%%, full %g%%\n",
-                (100. * pchits) / tests,
-                (100. * protopchits) / tests,
-                (100. * (addpchits + setpchits))
-                / settests,
-                (100. * inipchits) / initests,
-                (100. * (tests - misses)) / tests);
-        fflush(fp);
-    }
-  }
-#endif
-
-    PCMETER(flushes++);
-}
-
-void
-PropertyCache::restore(PropertyCacheEntry *entry)
-{
-    PropertyCacheEntry *entry2;
-
-    empty = false;
-
-    entry2 = &table[hash(entry->kpc, entry->kshape)];
-    *entry2 = *entry;
-}
deleted file mode 100644
--- a/js/src/jspropertycache.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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 jspropertycache_h___
-#define jspropertycache_h___
-
-#include "mozilla/PodOperations.h"
-
-#include "jsapi.h"
-#include "jsprvtd.h"
-#include "jstypes.h"
-
-#include "vm/String.h"
-
-namespace js {
-
-/*
- * Property cache with structurally typed capabilities for invalidation, for
- * polymorphic callsite method/get/set speedups.  For details, see
- * <https://developer.mozilla.org/en/SpiderMonkey/Internals/Property_cache>.
- */
-class PropertyCache;
-
-struct PropertyCacheEntry
-{
-    jsbytecode    *kpc;           /* pc of cache-testing bytecode */
-    Shape         *kshape;        /* shape of direct (key) object */
-    Shape         *pshape;        /* shape of owning object */
-    Shape         *prop;          /* shape of accessed property */
-
-    friend class PropertyCache;
-
-  private:
-    /* Index into the prototype chain from the object for this entry. */
-    uint8_t       protoIndex;
-
-  public:
-    static const size_t MaxProtoIndex = 15;
-
-    /*
-     * True iff the property lookup will find an own property on the object if
-     * the entry matches.
-     *
-     * This test is applicable only to property lookups, not to identifier
-     * lookups.  It is meaningless to ask this question of an entry for an
-     * identifier lookup.
-     */
-    bool isOwnPropertyHit() const { return protoIndex == 0; }
-
-    /*
-     * True iff the property lookup will find the property on the prototype of
-     * the object if the entry matches.
-     *
-     * This test is applicable only to property lookups, not to identifier
-     * lookups.  It is meaningless to ask this question of an entry for an
-     * identifier lookup.
-     */
-    bool isPrototypePropertyHit() const { return protoIndex == 1; }
-
-    void assign(jsbytecode *kpc, Shape *kshape, Shape *pshape, Shape *prop, unsigned protoIndex) {
-        JS_ASSERT(protoIndex <= MaxProtoIndex);
-
-        this->kpc = kpc;
-        this->kshape = kshape;
-        this->pshape = pshape;
-        this->prop = prop;
-        this->protoIndex = uint8_t(protoIndex);
-    }
-};
-
-/*
- * Special value for functions returning PropertyCacheEntry * to distinguish
- * between failure and no no-cache-fill cases.
- */
-#define JS_NO_PROP_CACHE_FILL ((js::PropertyCacheEntry *) NULL + 1)
-
-#if defined DEBUG_brendan || defined DEBUG_brendaneich
-#define JS_PROPERTY_CACHE_METERING 1
-#endif
-
-class PropertyCache
-{
-  private:
-    enum {
-        SIZE_LOG2 = 8,
-        SIZE = JS_BIT(SIZE_LOG2),
-        MASK = JS_BITMASK(SIZE_LOG2)
-    };
-
-    PropertyCacheEntry  table[SIZE];
-    JSBool              empty;
-
-  public:
-#ifdef JS_PROPERTY_CACHE_METERING
-    PropertyCacheEntry  *pctestentry;   /* entry of the last PC-based test */
-    uint32_t            fills;          /* number of cache entry fills */
-    uint32_t            nofills;        /* couldn't fill (e.g. default get) */
-    uint32_t            rofills;        /* set on read-only prop can't fill */
-    uint32_t            disfills;       /* fill attempts on disabled cache */
-    uint32_t            oddfills;       /* fill attempt after setter deleted */
-    uint32_t            add2dictfills;  /* fill attempt on dictionary object */
-    uint32_t            modfills;       /* fill that rehashed to a new entry */
-    uint32_t            brandfills;     /* scope brandings to type structural
-                                           method fills */
-    uint32_t            noprotos;       /* resolve-returned non-proto pobj */
-    uint32_t            longchains;     /* overlong scope and/or proto chain */
-    uint32_t            recycles;       /* cache entries recycled by fills */
-    uint32_t            tests;          /* cache probes */
-    uint32_t            pchits;         /* fast-path polymorphic op hits */
-    uint32_t            protopchits;    /* pchits hitting immediate prototype */
-    uint32_t            initests;       /* cache probes from JSOP_INITPROP */
-    uint32_t            inipchits;      /* init'ing next property pchit case */
-    uint32_t            inipcmisses;    /* init'ing next property pc misses */
-    uint32_t            settests;       /* cache probes from JOF_SET opcodes */
-    uint32_t            addpchits;      /* adding next property pchit case */
-    uint32_t            setpchits;      /* setting existing property pchit */
-    uint32_t            setpcmisses;    /* setting/adding property pc misses */
-    uint32_t            setmisses;      /* JSOP_SET{NAME,PROP} total misses */
-    uint32_t            kpcmisses;      /* slow-path key id == atom misses */
-    uint32_t            kshapemisses;   /* slow-path key object misses */
-    uint32_t            vcapmisses;     /* value capability misses */
-    uint32_t            misses;         /* cache misses */
-    uint32_t            flushes;        /* cache flushes */
-    uint32_t            pcpurges;       /* shadowing purges on proto chain */
-
-# define PCMETER(x)     x
-#else
-# define PCMETER(x)     ((void)0)
-#endif
-
-    PropertyCache() {
-        mozilla::PodZero(this);
-    }
-
-  private:
-    static inline uintptr_t
-    hash(jsbytecode *pc, const Shape *kshape)
-    {
-        return (((uintptr_t(pc) >> SIZE_LOG2) ^ uintptr_t(pc) ^ ((uintptr_t)kshape >> 3)) & MASK);
-    }
-
-    static inline bool matchShape(JSContext *cx, JSObject *obj, uint32_t shape);
-
-    PropertyName *
-    fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp,
-             JSObject **pobjp, PropertyCacheEntry *entry);
-
-#ifdef DEBUG
-    void assertEmpty();
-#else
-    inline void assertEmpty() {}
-#endif
-
-  public:
-    JS_ALWAYS_INLINE void test(JSContext *cx, jsbytecode *pc,
-                               JSObject **obj, JSObject **pobj,
-                               PropertyCacheEntry **entry, PropertyName **name);
-
-    /*
-     * Test for cached information about a property set on *objp at pc.
-     *
-     * On a hit, set *entryp to the entry and return true.
-     *
-     * On a miss, set *namep to the name of the property being set and return false.
-     */
-    JS_ALWAYS_INLINE bool testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj,
-                                     PropertyCacheEntry **entryp, JSObject **obj2p,
-                                     PropertyName **namep);
-
-    /*
-     * Fill property cache entry for key cx->fp->pc, optimized value word
-     * computed from obj and shape, and entry capability forged from
-     * obj->shape() and an 8-bit protoIndex.
-     *
-     * Return the filled cache entry or JS_NO_PROP_CACHE_FILL if caching was
-     * not possible.
-     */
-    PropertyCacheEntry *fill(JSContext *cx, JSObject *obj, JSObject *pobj, js::Shape *shape);
-
-    void purge(JSRuntime *rt);
-
-    /* Restore an entry that may have been purged during a GC. */
-    void restore(PropertyCacheEntry *entry);
-};
-
-} /* namespace js */
-
-#endif /* jspropertycache_h___ */
deleted file mode 100644
--- a/js/src/jspropertycacheinlines.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- * 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 jspropertycacheinlines_h___
-#define jspropertycacheinlines_h___
-
-#include "jslock.h"
-#include "jspropertycache.h"
-
-#include "vm/Shape.h"
-
-/*
- * This method is designed to inline the fast path in js_Interpret, so it makes
- * "just-so" restrictions on parameters, e.g. pobj and obj should not be the
- * same variable, since for JOF_PROP-mode opcodes, obj must not be changed
- * because of a cache miss.
- *
- * On return, if name is null then obj points to the scope chain element in
- * which the property was found, pobj is locked, and entry is valid. If name is
- * non-null then no object is locked but entry is still set correctly for use,
- * e.g., by PropertyCache::fill and name should be used as the id to find.
- *
- * We must lock pobj on a hit in order to close races with threads that might
- * be deleting a property from its scope, or otherwise invalidating property
- * caches (on all threads) by re-generating JSObject::shape().
- */
-JS_ALWAYS_INLINE void
-js::PropertyCache::test(JSContext *cx, jsbytecode *pc, JSObject **obj,
-                        JSObject **pobj, PropertyCacheEntry **entry, PropertyName **name)
-{
-    JS_ASSERT(this == &cx->propertyCache());
-
-    Shape *kshape = (*obj)->lastProperty();
-    *entry = &table[hash(pc, kshape)];
-    PCMETER(pctestentry = *entry);
-    PCMETER(tests++);
-    JS_ASSERT(obj != pobj);
-    if ((*entry)->kpc == pc && (*entry)->kshape == kshape) {
-        JSObject *tmp;
-        *pobj = *obj;
-        if ((*entry)->isPrototypePropertyHit() &&
-            (tmp = (*pobj)->getProto()) != NULL) {
-            *pobj = tmp;
-        }
-
-        if ((*pobj)->lastProperty() == (*entry)->pshape) {
-            PCMETER(pchits++);
-            PCMETER((*entry)->isOwnPropertyHit() || protopchits++);
-            *name = NULL;
-            return;
-        }
-    }
-    *name = fullTest(cx, pc, obj, pobj, *entry);
-    if (!*name)
-        PCMETER(misses++);
-}
-
-JS_ALWAYS_INLINE bool
-js::PropertyCache::testForSet(JSContext *cx, jsbytecode *pc, JSObject *obj,
-                              PropertyCacheEntry **entryp, JSObject **obj2p, PropertyName **namep)
-{
-    JS_ASSERT(this == &cx->propertyCache());
-
-    Shape *kshape = obj->lastProperty();
-    PropertyCacheEntry *entry = &table[hash(pc, kshape)];
-    *entryp = entry;
-    PCMETER(pctestentry = entry);
-    PCMETER(tests++);
-    PCMETER(settests++);
-    if (entry->kpc == pc && entry->kshape == kshape)
-        return true;
-
-    PropertyName *name = fullTest(cx, pc, &obj, obj2p, entry);
-    JS_ASSERT(name);
-
-    PCMETER(misses++);
-    PCMETER(setmisses++);
-
-    *namep = name;
-    return false;
-}
-
-#endif /* jspropertycacheinlines_h___ */
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -27,32 +27,32 @@
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace js::frontend;
 
 using mozilla::ArrayLength;
 using mozilla::DebugOnly;
 
-char const *js::aopNames[] = {
+char const * const js::aopNames[] = {
     "=",    /* AOP_ASSIGN */
     "+=",   /* AOP_PLUS */
     "-=",   /* AOP_MINUS */
     "*=",   /* AOP_STAR */
     "/=",   /* AOP_DIV */
     "%=",   /* AOP_MOD */
     "<<=",  /* AOP_LSH */
     ">>=",  /* AOP_RSH */
     ">>>=", /* AOP_URSH */
     "|=",   /* AOP_BITOR */
     "^=",   /* AOP_BITXOR */
     "&="    /* AOP_BITAND */
 };
 
-char const *js::binopNames[] = {
+char const * const js::binopNames[] = {
     "==",         /* BINOP_EQ */
     "!=",         /* BINOP_NE */
     "===",        /* BINOP_STRICTEQ */
     "!==",        /* BINOP_STRICTNE */
     "<",          /* BINOP_LT */
     "<=",         /* BINOP_LE */
     ">",          /* BINOP_GT */
     ">=",         /* BINOP_GE */
@@ -66,34 +66,34 @@ char const *js::binopNames[] = {
     "%",          /* BINOP_MOD */
     "|",          /* BINOP_BITOR */
     "^",          /* BINOP_BITXOR */
     "&",          /* BINOP_BITAND */
     "in",         /* BINOP_IN */
     "instanceof", /* BINOP_INSTANCEOF */
 };
 
-char const *js::unopNames[] = {
+char const * const js::unopNames[] = {
     "delete",  /* UNOP_DELETE */
     "-",       /* UNOP_NEG */
     "+",       /* UNOP_POS */
     "!",       /* UNOP_NOT */
     "~",       /* UNOP_BITNOT */
     "typeof",  /* UNOP_TYPEOF */
     "void"     /* UNOP_VOID */
 };
 
-char const *js::nodeTypeNames[] = {
+char const * const js::nodeTypeNames[] = {
 #define ASTDEF(ast, str, method) str,
 #include "jsast.tbl"
 #undef ASTDEF
     NULL
 };
 
-static char const *callbackNames[] = {
+static char const * const callbackNames[] = {
 #define ASTDEF(ast, str, method) method,
 #include "jsast.tbl"
 #undef ASTDEF
     NULL
 };
 
 typedef AutoValueVector NodeVector;
 
--- a/js/src/jsreflect.h
+++ b/js/src/jsreflect.h
@@ -83,16 +83,16 @@ enum VarDeclKind {
 enum PropKind {
     PROP_ERR = -1,
     PROP_INIT = 0,
     PROP_GETTER,
     PROP_SETTER,
     PROP_LIMIT
 };
 
-extern char const *aopNames[];
-extern char const *binopNames[];
-extern char const *unopNames[];
-extern char const *nodeTypeNames[];
+extern char const * const aopNames[];
+extern char const * const binopNames[];
+extern char const * const unopNames[];
+extern char const * const nodeTypeNames[];
 
 } /* namespace js */
 
 #endif /* jsreflect_h___ */
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -360,18 +360,18 @@ static const JSFunctionSpec string_funct
     JS_FN(js_decodeURI_str,          str_decodeURI,             1,0),
     JS_FN(js_encodeURI_str,          str_encodeURI,             1,0),
     JS_FN(js_decodeURIComponent_str, str_decodeURI_Component,   1,0),
     JS_FN(js_encodeURIComponent_str, str_encodeURI_Component,   1,0),
 
     JS_FS_END
 };
 
-jschar      js_empty_ucstr[]  = {0};
-JSSubString js_EmptySubString = {0, js_empty_ucstr};
+const jschar      js_empty_ucstr[]  = {0};
+const JSSubString js_EmptySubString = {0, js_empty_ucstr};
 
 static const unsigned STRING_ELEMENT_ATTRS = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
 
 static JSBool
 str_enumerate(JSContext *cx, HandleObject obj)
 {
     RootedString str(cx, obj->asString().unbox());
     RootedValue value(cx);
@@ -601,22 +601,23 @@ DoSubstr(JSContext *cx, JSString *str, s
          * Create a rope of substrings for both childs.
          */
         JS_ASSERT (begin < rope->leftChild()->length() &&
                    begin + len > rope->leftChild()->length());
 
         size_t lhsLength = rope->leftChild()->length() - begin;
         size_t rhsLength = begin + len - rope->leftChild()->length();
 
-        RootedString lhs(cx, js_NewDependentString(cx, rope->leftChild(),
+        Rooted<JSRope *> ropeRoot(cx, rope);
+        RootedString lhs(cx, js_NewDependentString(cx, ropeRoot->leftChild(),
                                                    begin, lhsLength));
         if (!lhs)
             return NULL;
 
-        RootedString rhs(cx, js_NewDependentString(cx, rope->rightChild(), 0, rhsLength));
+        RootedString rhs(cx, js_NewDependentString(cx, ropeRoot->rightChild(), 0, rhsLength));
         if (!rhs)
             return NULL;
 
         return JSRope::new_<CanGC>(cx, lhs, rhs, len);
     }
 
     return js_NewDependentString(cx, str, begin, len);
 }
--- a/js/src/jsstr.h
+++ b/js/src/jsstr.h
@@ -55,18 +55,18 @@ js_toLowerCase(JSContext *cx, JSString *
 extern JSString * JS_FASTCALL
 js_toUpperCase(JSContext *cx, JSString *str);
 
 struct JSSubString {
     size_t          length;
     const jschar    *chars;
 };
 
-extern jschar      js_empty_ucstr[];
-extern JSSubString js_EmptySubString;
+extern const jschar js_empty_ucstr[];
+extern const JSSubString js_EmptySubString;
 
 /*
  * Shorthands for ASCII (7-bit) decimal and hex conversion.
  * Manually inline isdigit for performance; MSVC doesn't do this for us.
  */
 #define JS7_ISDEC(c)    ((((unsigned)(c)) - '0') <= 9)
 #define JS7_UNDEC(c)    ((c) - '0')
 #define JS7_ISHEX(c)    ((c) < 128 && isxdigit(c))
--- a/js/src/moz.build
+++ b/js/src/moz.build
@@ -162,17 +162,16 @@ CPP_SOURCES += [
     'jsnativestack.cpp',
     'jsnum.cpp',
     'jsobj.cpp',
     'json.cpp',
     'jsonparser.cpp',
     'jsopcode.cpp',
     'jsperf.cpp',
     'jsprf.cpp',
-    'jspropertycache.cpp',
     'jspropertytree.cpp',
     'jsproxy.cpp',
     'jsreflect.cpp',
     'jsscript.cpp',
     'jsstr.cpp',
     'jstypedarray.cpp',
     'jsutil.cpp',
     'jswatchpoint.cpp',
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2057,17 +2057,17 @@ DisassWithSrc(JSContext *cx, unsigned ar
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
 #define LINE_BUF_LEN 512
     unsigned len, line1, line2, bupline;
     FILE *file;
     char linebuf[LINE_BUF_LEN];
     jsbytecode *pc, *end;
-    static char sep[] = ";-------------------------";
+    static const char sep[] = ";-------------------------";
 
     bool ok = true;
     RootedScript script(cx);
     for (unsigned i = 0; ok && i < args.length(); i++) {
         script = ValueToScript(cx, args[i]);
         if (!script)
            return false;
 
@@ -3559,17 +3559,17 @@ GetSelfHostedValue(JSContext *cx, unsign
     }
     RootedAtom srcAtom(cx, ToAtom<CanGC>(cx, args.handleAt(0)));
     if (!srcAtom)
         return false;
     RootedPropertyName srcName(cx, srcAtom->asPropertyName());
     return cx->runtime()->cloneSelfHostedValue(cx, srcName, args.rval());
 }
 
-static JSFunctionSpecWithHelp shell_functions[] = {
+static const JSFunctionSpecWithHelp shell_functions[] = {
     JS_FN_HELP("version", Version, 0, 0,
 "version([number])",
 "  Get or force a script compilation version number."),
 
     JS_FN_HELP("revertVersion", RevertVersion, 0, 0,
 "revertVersion()",
 "  Revert previously set version number."),
 
@@ -3882,17 +3882,17 @@ static JSFunctionSpecWithHelp shell_func
     JS_FN_HELP("objectEmulatingUndefined", ObjectEmulatingUndefined, 0, 0,
 "objectEmulatingUndefined()",
 "  Return a new object obj for which typeof obj === \"undefined\", obj == null\n"
 "  and obj == undefined (and vice versa for !=), and ToBoolean(obj) === false.\n"),
 
     JS_FS_HELP_END
 };
 
-static JSFunctionSpecWithHelp self_hosting_functions[] = {
+static const JSFunctionSpecWithHelp self_hosting_functions[] = {
     JS_FN_HELP("getSelfHostedValue", GetSelfHostedValue, 1, 0,
 "getSelfHostedValue()",
 "  Get a self-hosted value by its name. Note that these values don't get \n"
 "  cached, so repeatedly getting the same value creates multiple distinct clones."),
 
     JS_FS_HELP_END
 };
 
--- a/js/src/shell/jsoptparse.cpp
+++ b/js/src/shell/jsoptparse.cpp
@@ -138,20 +138,20 @@ PrintParagraph(const char *text, unsigne
             JS_NOT_REACHED("unhandled token splitting character in text");
         }
     }
 }
 
 static const char *
 OptionFlagsToFormatInfo(char shortflag, bool isValued, size_t *length)
 {
-    static const char *fmt[4] = { "  -%c --%s ",
-                                  "  --%s ",
-                                  "  -%c --%s=%s ",
-                                  "  --%s=%s " };
+    static const char * const fmt[4] = { "  -%c --%s ",
+                                         "  --%s ",
+                                         "  -%c --%s=%s ",
+                                         "  --%s=%s " };
 
     /* How mny chars w/o longflag? */
     size_t lengths[4] = { strlen(fmt[0]) - 3,
                           strlen(fmt[1]) - 3,
                           strlen(fmt[2]) - 5,
                           strlen(fmt[3]) - 5 };
     int index = isValued ? 2 : 0;
     if (!shortflag)
--- a/js/src/vm/ArgumentsObject-inl.h
+++ b/js/src/vm/ArgumentsObject-inl.h
@@ -2,19 +2,19 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 ArgumentsObject_inl_h___
 #define ArgumentsObject_inl_h___
 
-#include "ArgumentsObject.h"
+#include "vm/ArgumentsObject.h"
 
-#include "ScopeObject-inl.h"
+#include "vm/ScopeObject.h"
 
 namespace js {
 
 inline uint32_t
 ArgumentsObject::initialLength() const
 {
     uint32_t argc = uint32_t(getFixedSlot(INITIAL_LENGTH_SLOT).toInt32()) >> PACKED_BITS_COUNT;
     JS_ASSERT(argc <= StackSpace::ARGS_LENGTH_MAX);
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -1,27 +1,25 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jsgc.h"
+#include "vm/ArgumentsObject-inl.h"
+
 #include "jsinfer.h"
 
 #include "vm/GlobalObject.h"
-#include "vm/Interpreter.h"
 #include "vm/Stack.h"
-#include "vm/Xdr.h"
 
 #include "jsobjinlines.h"
 
 #include "gc/Barrier-inl.h"
 #include "vm/Stack-inl.h"
-#include "vm/ArgumentsObject-inl.h"
 
 #if defined(JS_ION)
 #include "ion/IonFrames.h"
 #endif
 
 using namespace js;
 using namespace js::gc;
 
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -6,16 +6,22 @@
 
 #ifndef ArgumentsObject_h___
 #define ArgumentsObject_h___
 
 #include "jsfun.h"
 
 namespace js {
 
+class AbstractFramePtr;
+
+namespace ion {
+class IonJSFrameLayout;
+}
+
 /*
  * ArgumentsData stores the initial indexed arguments provided to the
  * corresponding and that function itself.  It is used to store arguments[i]
  * and arguments.callee -- up until the corresponding property is modified,
  * when the relevant value is flagged to memorialize the modification.
  */
 struct ArgumentsData
 {
--- a/js/src/vm/CharacterEncoding.cpp
+++ b/js/src/vm/CharacterEncoding.cpp
@@ -3,19 +3,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 "jscntxt.h"
 
 #include "js/CharacterEncoding.h"
 
-#include "jscntxtinlines.h"
-#include "jsscriptinlines.h"
-
 using namespace JS;
 
 Latin1CharsZ
 JS::LossyTwoByteCharsToNewLatin1CharsZ(JSContext *cx, TwoByteChars tbchars)
 {
     JS_ASSERT(cx);
     size_t len = tbchars.length();
     unsigned char *latin1 = cx->pod_malloc<unsigned char>(len + 1);
--- a/js/src/vm/DateTime.h
+++ b/js/src/vm/DateTime.h
@@ -6,18 +6,16 @@
 
 #ifndef DateTime_h___
 #define DateTime_h___
 
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/StandardInteger.h"
 
-#include <math.h>
-
 #include "NumericConversions.h"
 
 namespace js {
 
 /* Constants defined by ES5 15.9.1.10. */
 const double HoursPerDay = 24;
 const double MinutesPerHour = 60;
 const double SecondsPerMinute = 60;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -1,35 +1,32 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "vm/Debugger.h"
 
-#include <limits.h>
-
 #include "jsapi.h"
 #include "jscntxt.h"
 #include "jscompartment.h"
 #include "jsnum.h"
 #include "jsobj.h"
 #include "jswrapper.h"
 
 #include "frontend/BytecodeCompiler.h"
 #include "gc/Marking.h"
 #include "ion/BaselineJIT.h"
 #include "js/Vector.h"
 
 #include "jsgcinlines.h"
 #include "jsopcodeinlines.h"
 
 #include "gc/FindSCCs-inl.h"
-#include "vm/Interpreter-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 
 using js::frontend::IsIdentifier;
 using mozilla::ArrayLength;
 using mozilla::Maybe;
 
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -2,29 +2,25 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 Debugger_h__
 #define Debugger_h__
 
-#include "mozilla/Attributes.h"
 #include "mozilla/LinkedList.h"
 
 #include "jsapi.h"
 #include "jsclist.h"
 #include "jscntxt.h"
 #include "jscompartment.h"
-#include "jsgc.h"
 #include "jsweakmap.h"
-#include "jswrapper.h"
 
 #include "gc/Barrier.h"
-#include "gc/FindSCCs.h"
 #include "js/HashTable.h"
 #include "vm/GlobalObject.h"
 
 namespace js {
 
 /*
  * A weakmap that supports the keys being in different compartments to the
  * values, although all values must be in the same compartment.
--- a/js/src/vm/ForkJoin.cpp
+++ b/js/src/vm/ForkJoin.cpp
@@ -1,43 +1,35 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "jscntxt.h"
-#include "jscompartment.h"
-
-#include "vm/ForkJoin.h"
-#include "vm/Monitor.h"
-#include "gc/Marking.h"
-#include "ion/BaselineJIT.h"
-
-#ifdef JS_ION
-#  include "ion/ParallelArrayAnalysis.h"
-#endif
 
 #ifdef JS_THREADSAFE
 #  include "prthread.h"
 #  include "prprf.h"
 #endif
 
+#include "vm/ForkJoin.h"
+
+#if defined(JS_THREADSAFE)
+#include "ion/BaselineJIT.h"
+#include "vm/Monitor.h"
+#endif
+
 #if defined(DEBUG) && defined(JS_THREADSAFE) && defined(JS_ION)
 #  include "ion/Ion.h"
 #  include "ion/MIR.h"
 #  include "ion/MIRGraph.h"
 #  include "ion/IonCompartment.h"
 #endif // DEBUG && THREADSAFE && ION
 
-// For extracting stack extent for each thread.
-#include "jsnativestack.h"
-
-#include "jsinferinlines.h"
-
 #include "vm/Interpreter-inl.h"
 
 using namespace js;
 using namespace js::parallel;
 using namespace js::ion;
 
 ///////////////////////////////////////////////////////////////////////////
 // Degenerate configurations
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -19,17 +19,16 @@
 #include "builtin/MapObject.h"
 #include "builtin/Object.h"
 #include "builtin/RegExp.h"
 
 #include "jscompartmentinlines.h"
 #include "jsobjinlines.h"
 
 #include "vm/GlobalObject-inl.h"
-#include "vm/RegExpObject-inl.h"
 #include "vm/RegExpStatics-inl.h"
 
 using namespace js;
 
 JSObject *
 js_InitObjectClass(JSContext *cx, HandleObject obj)
 {
     JS_ASSERT(obj->isNative());
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -2,30 +2,27 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 GlobalObject_h___
 #define GlobalObject_h___
 
-#include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 
 #include "jsarray.h"
 #include "jsbool.h"
 #include "jsexn.h"
 #include "jsfun.h"
-#include "jsiter.h"
 #include "jsnum.h"
 
+#include "builtin/RegExp.h"
 #include "js/Vector.h"
 
-#include "builtin/RegExp.h"
-
 extern JSObject *
 js_InitObjectClass(JSContext *cx, js::HandleObject obj);
 
 extern JSObject *
 js_InitFunctionClass(JSContext *cx, js::HandleObject obj);
 
 extern JSObject *
 js_InitTypedArrayClasses(JSContext *cx, js::HandleObject obj);
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -18,17 +18,16 @@
 #include "ion/IonCompartment.h"
 #include "vm/ForkJoin.h"
 #include "vm/Interpreter.h"
 
 #include "jsatominlines.h"
 #include "jsfuninlines.h"
 #include "jsinferinlines.h"
 #include "jsopcodeinlines.h"
-#include "jspropertycacheinlines.h"
 #include "jstypedarrayinlines.h"
 #include "vm/GlobalObject-inl.h"
 #include "vm/Stack-inl.h"
 
 namespace js {
 
 /*
  * Compute the implicit |this| parameter for a call expression where the callee
@@ -195,27 +194,16 @@ NativeGet(JSContext *cx, JSObject *objAr
         RootedObject pobj(cx, pobjArg);
         RootedShape shape(cx, shapeArg);
         if (!js_NativeGet(cx, obj, pobj, shape, getHow, vp))
             return false;
     }
     return true;
 }
 
-#if defined(DEBUG) && !defined(JS_THREADSAFE) && !defined(JSGC_ROOT_ANALYSIS)
-extern void
-AssertValidPropertyCacheHit(JSContext *cx, JSObject *start, JSObject *found,
-                            PropertyCacheEntry *entry);
-#else
-inline void
-AssertValidPropertyCacheHit(JSContext *cx, JSObject *start, JSObject *found,
-                            PropertyCacheEntry *entry)
-{}
-#endif
-
 inline bool
 GetLengthProperty(const Value &lval, MutableHandleValue vp)
 {
     /* Optimize length accesses on strings, arrays, and arguments. */
     if (lval.isString()) {
         vp.setInt32(lval.toString()->length());
         return true;
     }
@@ -241,139 +229,16 @@ GetLengthProperty(const Value &lval, Mut
             vp.setInt32(TypedArray::length(obj));
             return true;
         }
     }
 
     return false;
 }
 
-inline bool
-GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc, MutableHandleValue lval,
-                     MutableHandleValue vp)
-{
-    JSOp op = JSOp(*pc);
-
-    if (op == JSOP_LENGTH) {
-        if (IsOptimizedArguments(cx->fp(), lval.address())) {
-            vp.setInt32(cx->fp()->numActualArgs());
-            return true;
-        }
-
-        if (GetLengthProperty(lval, vp))
-            return true;
-    }
-
-    JSObject *obj = ToObjectFromStack(cx, lval);
-    if (!obj)
-        return false;
-
-    PropertyCacheEntry *entry;
-    JSObject *pobj;
-    PropertyName *name;
-    cx->propertyCache().test(cx, pc, &obj, &pobj, &entry, &name);
-    if (!name) {
-        AssertValidPropertyCacheHit(cx, obj, pobj, entry);
-        return NativeGet(cx, obj, pobj, entry->prop, JSGET_CACHE_RESULT, vp);
-    }
-
-    bool wasObject = lval.isObject();
-
-    RootedId id(cx, NameToId(name));
-    RootedObject nobj(cx, obj);
-
-    if (obj->getOps()->getProperty) {
-        if (!JSObject::getGeneric(cx, nobj, nobj, id, vp))
-            return false;
-    } else {
-        if (!GetPropertyHelper(cx, nobj, id, JSGET_CACHE_RESULT, vp))
-            return false;
-    }
-
-#if JS_HAS_NO_SUCH_METHOD
-    if (op == JSOP_CALLPROP &&
-        JS_UNLIKELY(vp.isPrimitive()) &&
-        wasObject)
-    {
-        if (!OnUnknownMethod(cx, nobj, IdToValue(id), vp))
-            return false;
-    }
-#endif
-
-    return true;
-}
-
-inline bool
-SetPropertyOperation(JSContext *cx, jsbytecode *pc, HandleValue lval, HandleValue rval)
-{
-    JS_ASSERT(*pc == JSOP_SETPROP);
-
-    RootedObject obj(cx, ToObjectFromStack(cx, lval));
-    if (!obj)
-        return false;
-
-    PropertyCacheEntry *entry;
-    JSObject *obj2;
-    PropertyName *name;
-    if (cx->propertyCache().testForSet(cx, pc, obj, &entry, &obj2, &name)) {
-        /*
-         * Property cache hit, only partially confirmed by testForSet. We
-         * know that the entry applies to regs.pc and that obj's shape
-         * matches.
-         *
-         * The entry predicts a set either an existing "own" property, or
-         * on a prototype property that has a setter.
-         */
-        RootedShape shape(cx, entry->prop);
-        JS_ASSERT_IF(shape->isDataDescriptor(), shape->writable());
-        JS_ASSERT_IF(shape->hasSlot(), entry->isOwnPropertyHit());
-
-        if (entry->isOwnPropertyHit() ||
-            ((obj2 = obj->getProto()) && obj2->lastProperty() == entry->pshape)) {
-#ifdef DEBUG
-            if (entry->isOwnPropertyHit()) {
-                JS_ASSERT(obj->nativeLookup(cx, shape->propid()) == shape);
-            } else {
-                JS_ASSERT(obj2->nativeLookup(cx, shape->propid()) == shape);
-                JS_ASSERT(entry->isPrototypePropertyHit());
-                JS_ASSERT(entry->kshape != entry->pshape);
-                JS_ASSERT(!shape->hasSlot());
-            }
-#endif
-
-            if (shape->hasDefaultSetter() && shape->hasSlot()) {
-                /* Fast path for, e.g., plain Object instance properties. */
-                JSObject::nativeSetSlotWithType(cx, obj, shape, rval);
-            } else {
-                RootedValue rref(cx, rval);
-                bool strict = cx->stack.currentScript()->strict;
-                if (!js_NativeSet(cx, obj, obj, shape, strict, &rref))
-                    return false;
-            }
-            return true;
-        }
-
-        GET_NAME_FROM_BYTECODE(cx->stack.currentScript(), pc, 0, name);
-    }
-
-    bool strict = cx->stack.currentScript()->strict;
-    RootedValue rref(cx, rval);
-
-    RootedId id(cx, NameToId(name));
-    if (JS_LIKELY(!obj->getOps()->setProperty)) {
-        if (!baseops::SetPropertyHelper(cx, obj, obj, id, DNP_CACHE_RESULT, &rref, strict))
-            return false;
-    } else {
-        if (!JSObject::setGeneric(cx, obj, obj, id, &rref, strict))
-            return false;
-    }
-
-    return true;
-}
-
 template <bool TypeOf> inline bool
 FetchName(JSContext *cx, HandleObject obj, HandleObject obj2, HandlePropertyName name,
           HandleShape shape, MutableHandleValue vp)
 {
     if (!shape) {
         if (TypeOf) {
             vp.setUndefined();
             return true;
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -9,35 +9,32 @@
  */
 
 #include "Interpreter.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/FloatingPoint.h"
 #include "mozilla/PodOperations.h"
 
-#include <stdio.h>
 #include <string.h>
 
 #include "jsapi.h"
 #include "jsarray.h"
 #include "jsatom.h"
 #include "jscntxt.h"
 #include "jsdbgapi.h"
 #include "jsfun.h"
 #include "jsgc.h"
 #include "jsiter.h"
 #include "jsnum.h"
 #include "jsobj.h"
 #include "jsopcode.h"
 #include "jsprf.h"
-#include "jspropertycache.h"
 #include "jsscript.h"
 #include "jsstr.h"
-#include "jsversion.h"
 #include "builtin/Eval.h"
 #include "ion/BaselineJIT.h"
 #include "ion/Ion.h"
 #include "vm/Debugger.h"
 #include "vm/Shape.h"
 
 #include "jsatominlines.h"
 #include "jsboolinlines.h"
@@ -251,16 +248,86 @@ NoSuchMethod(JSContext *cx, unsigned arg
     args[1].setObject(*argsobj);
     JSBool ok = Invoke(cx, args);
     vp[0] = args.rval();
     return ok;
 }
 
 #endif /* JS_HAS_NO_SUCH_METHOD */
 
+inline bool
+GetPropertyOperation(JSContext *cx, HandleScript script, jsbytecode *pc, MutableHandleValue lval,
+                     MutableHandleValue vp)
+{
+    JSOp op = JSOp(*pc);
+
+    if (op == JSOP_LENGTH) {
+        if (IsOptimizedArguments(cx->fp(), lval.address())) {
+            vp.setInt32(cx->fp()->numActualArgs());
+            return true;
+        }
+
+        if (GetLengthProperty(lval, vp))
+            return true;
+    }
+
+    JSObject *obj = ToObjectFromStack(cx, lval);
+    if (!obj)
+        return false;
+
+    bool wasObject = lval.isObject();
+
+    RootedId id(cx, NameToId(script->getName(pc)));
+    RootedObject nobj(cx, obj);
+
+    if (obj->getOps()->getProperty) {
+        if (!JSObject::getGeneric(cx, nobj, nobj, id, vp))
+            return false;
+    } else {
+        if (!GetPropertyHelper(cx, nobj, id, 0, vp))
+            return false;
+    }
+
+#if JS_HAS_NO_SUCH_METHOD
+    if (op == JSOP_CALLPROP &&
+        JS_UNLIKELY(vp.isPrimitive()) &&
+        wasObject)
+    {
+        if (!OnUnknownMethod(cx, nobj, IdToValue(id), vp))
+            return false;
+    }
+#endif
+
+    return true;
+}
+
+inline bool
+SetPropertyOperation(JSContext *cx, HandleScript script, jsbytecode *pc, HandleValue lval,
+                     HandleValue rval)
+{
+    JS_ASSERT(*pc == JSOP_SETPROP);
+
+    RootedObject obj(cx, ToObjectFromStack(cx, lval));
+    if (!obj)
+        return false;
+
+    RootedValue rref(cx, rval);
+
+    RootedId id(cx, NameToId(script->getName(pc)));
+    if (JS_LIKELY(!obj->getOps()->setProperty)) {
+        if (!baseops::SetPropertyHelper(cx, obj, obj, id, 0, &rref, script->strict))
+            return false;
+    } else {
+        if (!JSObject::setGeneric(cx, obj, obj, id, &rref, script->strict))
+            return false;
+    }
+
+    return true;
+}
+
 bool
 js::ReportIsNotFunction(JSContext *cx, const Value &v, int numToSkip, MaybeConstruct construct)
 {
     unsigned error = construct ? JSMSG_NOT_CONSTRUCTOR : JSMSG_NOT_FUNCTION;
     int spIndex = numToSkip >= 0 ? -(numToSkip + 1) : JSDVG_SEARCH_STACK;
 
     RootedValue val(cx, v);
     js_ReportValueError3(cx, error, spIndex, val, NullPtr(), NULL, NULL);
@@ -906,41 +973,18 @@ inline InterpreterFrames::InterpreterFra
     cx->runtime()->interpreterFrames = this;
 }
 
 inline InterpreterFrames::~InterpreterFrames()
 {
     context->runtime()->interpreterFrames = older;
 }
 
-#if defined(DEBUG) && !defined(JS_THREADSAFE) && !defined(JSGC_ROOT_ANALYSIS)
-void
-js::AssertValidPropertyCacheHit(JSContext *cx, JSObject *start,
-                                JSObject *found, PropertyCacheEntry *entry)
-{
-    jsbytecode *pc;
-    JSScript *script = cx->stack.currentScript(&pc);
-
-    uint64_t sample = cx->runtime()->gcNumber;
-
-    PropertyName *name = GetNameFromBytecode(cx, script, pc, JSOp(*pc));
-    JSObject *pobj;
-    Shape *prop;
-    if (baseops::LookupProperty<NoGC>(cx, start, NameToId(name), &pobj, &prop)) {
-        JS_ASSERT(prop);
-        JS_ASSERT(pobj == found);
-        JS_ASSERT(entry->prop == prop);
-    }
-
-    JS_ASSERT(cx->runtime()->gcNumber == sample);
-}
-#endif /* DEBUG && !JS_THREADSAFE */
-
 /*
- * Ensure that the intrepreter switch can close call-bytecode cases in the
+ * Ensure that the interpreter switch can close call-bytecode cases in the
  * same way as non-call bytecodes.
  */
 JS_STATIC_ASSERT(JSOP_NAME_LENGTH == JSOP_CALLNAME_LENGTH);
 JS_STATIC_ASSERT(JSOP_GETARG_LENGTH == JSOP_CALLARG_LENGTH);
 JS_STATIC_ASSERT(JSOP_GETLOCAL_LENGTH == JSOP_CALLLOCAL_LENGTH);
 
 /*
  * Same for JSOP_SETNAME and JSOP_SETPROP, which differ only slightly but
@@ -2078,17 +2122,17 @@ BEGIN_CASE(JSOP_SETNAME)
 }
 END_CASE(JSOP_SETNAME)
 
 BEGIN_CASE(JSOP_SETPROP)
 {
     HandleValue lval = HandleValue::fromMarkedLocation(&regs.sp[-2]);
     HandleValue rval = HandleValue::fromMarkedLocation(&regs.sp[-1]);
 
-    if (!SetPropertyOperation(cx, regs.pc, lval, rval))
+    if (!SetPropertyOperation(cx, script, regs.pc, lval, rval))
         goto error;
 
     regs.sp[-2] = regs.sp[-1];
     regs.sp--;
 }
 END_CASE(JSOP_SETPROP)
 
 BEGIN_CASE(JSOP_GETELEM)
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -6,17 +6,16 @@
 
 #ifndef Interpreter_h___
 #define Interpreter_h___
 /*
  * JS interpreter interface.
  */
 #include "jsprvtd.h"
 #include "jspubtd.h"
-#include "jsopcode.h"
 
 #include "vm/Stack.h"
 
 namespace js {
 
 /* Implemented in jsdbgapi: */
 
 /*
--- a/js/src/vm/Monitor.h
+++ b/js/src/vm/Monitor.h
@@ -2,21 +2,16 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 Monitor_h__
 #define Monitor_h__
 
-#include <stdlib.h>
-
-#include "mozilla/DebugOnly.h"
-
-#include "js/Utility.h"
 #include "jslock.h"
 
 namespace js {
 
 // A base class used for types intended to be used in a parallel
 // fashion, such as the workers in the |ThreadPool| class.  Combines a
 // lock and a condition variable.  You can acquire the lock or signal
 // the condition variable using the |AutoLockMonitor| type.
--- a/js/src/vm/ObjectImpl.cpp
+++ b/js/src/vm/ObjectImpl.cpp
@@ -1,29 +1,23 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "mozilla/Assertions.h"
-#include "mozilla/Attributes.h"
-
-#include "js/TemplateLib.h"
 #include "js/Value.h"
 #include "vm/Debugger.h"
 #include "vm/ObjectImpl.h"
 
-#include "jsatominlines.h"
 #include "jsobjinlines.h"
 
 #include "gc/Barrier-inl.h"
 #include "gc/Marking.h"
 #include "vm/ObjectImpl-inl.h"
-#include "vm/Shape-inl.h"
 
 using namespace js;
 
 PropDesc::PropDesc()
   : pd_(UndefinedValue()),
     value_(UndefinedValue()),
     get_(UndefinedValue()),
     set_(UndefinedValue()),
--- a/js/src/vm/Probes-inl.h
+++ b/js/src/vm/Probes-inl.h
@@ -5,20 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef Probes_inl_h__
 #define Probes_inl_h__
 
 #include "vm/Probes.h"
 
 #include "jscntxt.h"
-#include "jsobj.h"
-#include "jsscript.h"
-
-#include "vm/Stack-inl.h"
 
 namespace js {
 
 /*
  * Many probe handlers are implemented inline for minimal performance impact,
  * especially important when no backends are enabled.
  */
 
--- a/js/src/vm/Probes.cpp
+++ b/js/src/vm/Probes.cpp
@@ -2,24 +2,21 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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 "Probes-inl.h"
 
 #include "jscntxt.h"
-#include "jsscript.h"
 
 #ifdef INCLUDE_MOZILLA_DTRACE
 #include "jsscriptinlines.h" 
 #endif
 
-#include "vm/Stack-inl.h"
-
 #define TYPEOF(cx,v)    (JSVAL_IS_NULL(v) ? JSTYPE_NULL : JS_TypeOfValue(cx,v))
 
 using namespace js;
 
 const char Probes::nullName[] = "(null)";
 const char Probes::anonymousName[] = "(anonymous)";
 
 bool Probes::ProfilingActive = true;
--- a/js/src/vm/PropertyKey.cpp
+++ b/js/src/vm/PropertyKey.cpp
@@ -1,26 +1,26 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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/. */
 
 /* PropertyKey implementation details. */
 
-#include "mozilla/Assertions.h"
+#include "js/PropertyKey.h"
 
-#include "js/PropertyKey.h"
 #include "js/RootingAPI.h"
 #include "js/Value.h"
 #include "vm/String.h"
 
-#include "jsinferinlines.h"
 #include "jsatominlines.h"
 
+#include "vm/String-inl.h"
+
 using namespace js;
 
 bool
 JS::detail::ToPropertyKeySlow(JSContext *cx, HandleValue v, PropertyKey *key)
 {
     MOZ_ASSERT_IF(v.isInt32(), v.toInt32() < 0);
 
     RootedAtom atom(cx);
--- a/js/src/yarr/PageBlock.h
+++ b/js/src/yarr/PageBlock.h
@@ -27,18 +27,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef PageBlock_h
 #define PageBlock_h
 
 #include "mozilla/StandardInteger.h"
 
-#include <stdlib.h>
-#include "assembler/wtf/Platform.h"
+#include <stddef.h>
 
 namespace WTF {
 
 size_t pageSize();
 inline bool isPageAligned(void* address) { return !(reinterpret_cast<intptr_t>(address) & (pageSize() - 1)); }
 inline bool isPageAligned(size_t size) { return !(size & (pageSize() - 1)); }
 inline bool isPowerOfTwo(size_t size) { return !(size & (size - 1)); }
 
--- a/js/src/yarr/YarrCanonicalizeUCS2.cpp
+++ b/js/src/yarr/YarrCanonicalizeUCS2.cpp
@@ -29,34 +29,34 @@
 
 #include "YarrCanonicalizeUCS2.h"
 
 namespace JSC { namespace Yarr {
 
 #include <stddef.h>
 #include "mozilla/StandardInteger.h"
 
-uint16_t ucs2CharacterSet0[] = { 0x01c4u, 0x01c5u, 0x01c6u, 0 };
-uint16_t ucs2CharacterSet1[] = { 0x01c7u, 0x01c8u, 0x01c9u, 0 };
-uint16_t ucs2CharacterSet2[] = { 0x01cau, 0x01cbu, 0x01ccu, 0 };
-uint16_t ucs2CharacterSet3[] = { 0x01f1u, 0x01f2u, 0x01f3u, 0 };
-uint16_t ucs2CharacterSet4[] = { 0x0392u, 0x03b2u, 0x03d0u, 0 };
-uint16_t ucs2CharacterSet5[] = { 0x0395u, 0x03b5u, 0x03f5u, 0 };
-uint16_t ucs2CharacterSet6[] = { 0x0398u, 0x03b8u, 0x03d1u, 0 };
-uint16_t ucs2CharacterSet7[] = { 0x0345u, 0x0399u, 0x03b9u, 0x1fbeu, 0 };
-uint16_t ucs2CharacterSet8[] = { 0x039au, 0x03bau, 0x03f0u, 0 };
-uint16_t ucs2CharacterSet9[] = { 0x00b5u, 0x039cu, 0x03bcu, 0 };
-uint16_t ucs2CharacterSet10[] = { 0x03a0u, 0x03c0u, 0x03d6u, 0 };
-uint16_t ucs2CharacterSet11[] = { 0x03a1u, 0x03c1u, 0x03f1u, 0 };
-uint16_t ucs2CharacterSet12[] = { 0x03a3u, 0x03c2u, 0x03c3u, 0 };
-uint16_t ucs2CharacterSet13[] = { 0x03a6u, 0x03c6u, 0x03d5u, 0 };
-uint16_t ucs2CharacterSet14[] = { 0x1e60u, 0x1e61u, 0x1e9bu, 0 };
+const uint16_t ucs2CharacterSet0[] = { 0x01c4u, 0x01c5u, 0x01c6u, 0 };
+const uint16_t ucs2CharacterSet1[] = { 0x01c7u, 0x01c8u, 0x01c9u, 0 };
+const uint16_t ucs2CharacterSet2[] = { 0x01cau, 0x01cbu, 0x01ccu, 0 };
+const uint16_t ucs2CharacterSet3[] = { 0x01f1u, 0x01f2u, 0x01f3u, 0 };
+const uint16_t ucs2CharacterSet4[] = { 0x0392u, 0x03b2u, 0x03d0u, 0 };
+const uint16_t ucs2CharacterSet5[] = { 0x0395u, 0x03b5u, 0x03f5u, 0 };
+const uint16_t ucs2CharacterSet6[] = { 0x0398u, 0x03b8u, 0x03d1u, 0 };
+const uint16_t ucs2CharacterSet7[] = { 0x0345u, 0x0399u, 0x03b9u, 0x1fbeu, 0 };
+const uint16_t ucs2CharacterSet8[] = { 0x039au, 0x03bau, 0x03f0u, 0 };
+const uint16_t ucs2CharacterSet9[] = { 0x00b5u, 0x039cu, 0x03bcu, 0 };
+const uint16_t ucs2CharacterSet10[] = { 0x03a0u, 0x03c0u, 0x03d6u, 0 };
+const uint16_t ucs2CharacterSet11[] = { 0x03a1u, 0x03c1u, 0x03f1u, 0 };
+const uint16_t ucs2CharacterSet12[] = { 0x03a3u, 0x03c2u, 0x03c3u, 0 };
+const uint16_t ucs2CharacterSet13[] = { 0x03a6u, 0x03c6u, 0x03d5u, 0 };
+const uint16_t ucs2CharacterSet14[] = { 0x1e60u, 0x1e61u, 0x1e9bu, 0 };
 
 static const size_t UCS2_CANONICALIZATION_SETS = 15;
-uint16_t* characterSetInfo[UCS2_CANONICALIZATION_SETS] = {
+const uint16_t* const characterSetInfo[UCS2_CANONICALIZATION_SETS] = {
     ucs2CharacterSet0,
     ucs2CharacterSet1,
     ucs2CharacterSet2,
     ucs2CharacterSet3,
     ucs2CharacterSet4,
     ucs2CharacterSet5,
     ucs2CharacterSet6,
     ucs2CharacterSet7,
@@ -65,17 +65,17 @@ uint16_t* characterSetInfo[UCS2_CANONICA
     ucs2CharacterSet10,
     ucs2CharacterSet11,
     ucs2CharacterSet12,
     ucs2CharacterSet13,
     ucs2CharacterSet14,
 };
 
 const size_t UCS2_CANONICALIZATION_RANGES = 364;
-UCS2CanonicalizationRange rangeInfo[UCS2_CANONICALIZATION_RANGES] = {
+const UCS2CanonicalizationRange rangeInfo[UCS2_CANONICALIZATION_RANGES] = {
     { 0x0000u, 0x0040u, 0x0000u, CanonicalizeUnique },
     { 0x0041u, 0x005au, 0x0020u, CanonicalizeRangeLo },
     { 0x005bu, 0x0060u, 0x0000u, CanonicalizeUnique },
     { 0x0061u, 0x007au, 0x0020u, CanonicalizeRangeHi },
     { 0x007bu, 0x00b4u, 0x0000u, CanonicalizeUnique },
     { 0x00b5u, 0x00b5u, 0x0009u, CanonicalizeSet },
     { 0x00b6u, 0x00bfu, 0x0000u, CanonicalizeUnique },
     { 0x00c0u, 0x00d6u, 0x0020u, CanonicalizeRangeLo },
@@ -433,17 +433,17 @@ UCS2CanonicalizationRange rangeInfo[UCS2
     { 0xa7aau, 0xff20u, 0x0000u, CanonicalizeUnique },
     { 0xff21u, 0xff3au, 0x0020u, CanonicalizeRangeLo },
     { 0xff3bu, 0xff40u, 0x0000u, CanonicalizeUnique },
     { 0xff41u, 0xff5au, 0x0020u, CanonicalizeRangeHi },
     { 0xff5bu, 0xffffu, 0x0000u, CanonicalizeUnique },
 };
 
 const size_t LATIN_CANONICALIZATION_RANGES = 20;
-LatinCanonicalizationRange latinRangeInfo[LATIN_CANONICALIZATION_RANGES] = {
+const LatinCanonicalizationRange latinRangeInfo[LATIN_CANONICALIZATION_RANGES] = {
     { 0x0000u, 0x0040u, 0x0000u, CanonicalizeLatinSelf },
     { 0x0041u, 0x005au, 0x0000u, CanonicalizeLatinMask0x20 },
     { 0x005bu, 0x0060u, 0x0000u, CanonicalizeLatinSelf },
     { 0x0061u, 0x007au, 0x0000u, CanonicalizeLatinMask0x20 },
     { 0x007bu, 0x00bfu, 0x0000u, CanonicalizeLatinSelf },
     { 0x00c0u, 0x00d6u, 0x0000u, CanonicalizeLatinMask0x20 },
     { 0x00d7u, 0x00d7u, 0x0000u, CanonicalizeLatinSelf },
     { 0x00d8u, 0x00deu, 0x0000u, CanonicalizeLatinMask0x20 },
--- a/js/src/yarr/YarrCanonicalizeUCS2.h
+++ b/js/src/yarr/YarrCanonicalizeUCS2.h
@@ -42,53 +42,53 @@ enum UCS2CanonicalizationType {
     CanonicalizeSet,                  // Value indicates a set in characterSetInfo.
     CanonicalizeRangeLo,              // Value is positive delta to pair, E.g. 0x41 has value 0x20, -> 0x61.
     CanonicalizeRangeHi,              // Value is positive delta to pair, E.g. 0x61 has value 0x20, -> 0x41.
     CanonicalizeAlternatingAligned,   // Aligned consequtive pair, e.g. 0x1f4,0x1f5.
     CanonicalizeAlternatingUnaligned  // Unaligned consequtive pair, e.g. 0x241,0x242.
 };
 struct UCS2CanonicalizationRange { uint16_t begin, end, value, type; };
 extern const size_t UCS2_CANONICALIZATION_RANGES;
-extern uint16_t* characterSetInfo[];
-extern UCS2CanonicalizationRange rangeInfo[];
+extern const uint16_t* const characterSetInfo[];
+extern const UCS2CanonicalizationRange rangeInfo[];
 
 // This table is similar to the full rangeInfo table, however this maps from UCS2 codepoints to
 // the set of Latin1 codepoints that could match.
 enum LatinCanonicalizationType {
     CanonicalizeLatinSelf,     // This character is in the Latin1 range, but has no canonical equivalent in the range.
     CanonicalizeLatinMask0x20, // One of a pair of characters, under the mask 0x20.
     CanonicalizeLatinOther,    // This character is not in the Latin1 range, but canonicalizes to another that is.
     CanonicalizeLatinInvalid   // Cannot match against Latin1 input.
 };
 struct LatinCanonicalizationRange { uint16_t begin, end, value, type; };
 extern const size_t LATIN_CANONICALIZATION_RANGES;
-extern LatinCanonicalizationRange latinRangeInfo[];
+extern const LatinCanonicalizationRange latinRangeInfo[];
 
 // This searches in log2 time over ~364 entries, so should typically result in 8 compares.
-inline UCS2CanonicalizationRange* rangeInfoFor(UChar ch)
+inline const UCS2CanonicalizationRange* rangeInfoFor(UChar ch)
 {
-    UCS2CanonicalizationRange* info = rangeInfo;
+    const UCS2CanonicalizationRange* info = rangeInfo;
     size_t entries = UCS2_CANONICALIZATION_RANGES;
 
     while (true) {
         size_t candidate = entries >> 1;
-        UCS2CanonicalizationRange* candidateInfo = info + candidate;
+        const UCS2CanonicalizationRange* candidateInfo = info + candidate;
         if (ch < candidateInfo->begin)
             entries = candidate;
         else if (ch <= candidateInfo->end)
             return candidateInfo;
         else {
             info = candidateInfo + 1;
             entries -= (candidate + 1);
         }
     }
 }
 
 // Should only be called for characters that have one canonically matching value.
-inline UChar getCanonicalPair(UCS2CanonicalizationRange* info, UChar ch)
+inline UChar getCanonicalPair(const UCS2CanonicalizationRange* info, UChar ch)
 {
     ASSERT(ch >= info->begin && ch <= info->end);
     switch (info->type) {
     case CanonicalizeRangeLo:
         return ch + info->value;
     case CanonicalizeRangeHi:
         return ch - info->value;
     case CanonicalizeAlternatingAligned:
@@ -106,22 +106,22 @@ inline UChar getCanonicalPair(UCS2Canoni
 inline bool isCanonicallyUnique(UChar ch)
 {
     return rangeInfoFor(ch)->type == CanonicalizeUnique;
 }
 
 // Returns true if values are equal, under the canonicalization rules.
 inline bool areCanonicallyEquivalent(UChar a, UChar b)
 {
-    UCS2CanonicalizationRange* info = rangeInfoFor(a);
+    const UCS2CanonicalizationRange* info = rangeInfoFor(a);
     switch (info->type) {
     case CanonicalizeUnique:
         return a == b;
     case CanonicalizeSet: {
-        for (uint16_t* set = characterSetInfo[info->value]; (a = *set); ++set) {
+        for (const uint16_t* set = characterSetInfo[info->value]; (a = *set); ++set) {
             if (a == b)
                 return true;
         }
         return false;
     }
     case CanonicalizeRangeLo:
         return (a == b) || (a + info->value == b);
     case CanonicalizeRangeHi:
--- a/js/src/yarr/YarrPattern.cpp
+++ b/js/src/yarr/YarrPattern.cpp
@@ -85,31 +85,31 @@ public:
 
         // Simple case, not a case-insensitive match.
         if (!m_isCaseInsensitive) {
             addSorted(m_matchesUnicode, ch);
             return;
         }
 
         // Add multiple matches, if necessary.
-        UCS2CanonicalizationRange* info = rangeInfoFor(ch);
+        const UCS2CanonicalizationRange* info = rangeInfoFor(ch);
         if (info->type == CanonicalizeUnique)
             addSorted(m_matchesUnicode, ch);
         else
             putUnicodeIgnoreCase(ch, info);
     }
 
-    void putUnicodeIgnoreCase(UChar ch, UCS2CanonicalizationRange* info)
+    void putUnicodeIgnoreCase(UChar ch, const UCS2CanonicalizationRange* info)
     {
         ASSERT(m_isCaseInsensitive);
         ASSERT(ch > 0x7f);
         ASSERT(ch >= info->begin && ch <= info->end);
         ASSERT(info->type != CanonicalizeUnique);
         if (info->type == CanonicalizeSet) {
-            for (uint16_t* set = characterSetInfo[info->value]; (ch = *set); ++set)
+            for (const uint16_t* set = characterSetInfo[info->value]; (ch = *set); ++set)
                 addSorted(m_matchesUnicode, ch);
         } else {
             addSorted(m_matchesUnicode, ch);
             addSorted(m_matchesUnicode, getCanonicalPair(info, ch));
         }
     }
 
     void putRange(UChar lo, UChar hi)
@@ -130,28 +130,28 @@ public:
             return;
 
         lo = std::max(lo, (UChar)0x80);
         addSortedRange(m_rangesUnicode, lo, hi);
         
         if (!m_isCaseInsensitive)
             return;
 
-        UCS2CanonicalizationRange* info = rangeInfoFor(lo);
+        const UCS2CanonicalizationRange* info = rangeInfoFor(lo);
         while (true) {
             // Handle the range [lo .. end]
             UChar end = std::min<UChar>(info->end, hi);
 
             switch (info->type) {
             case CanonicalizeUnique:
                 // Nothing to do - no canonical equivalents.
                 break;
             case CanonicalizeSet: {
                 UChar ch;
-                for (uint16_t* set = characterSetInfo[info->value]; (ch = *set); ++set)
+                for (const uint16_t* set = characterSetInfo[info->value]; (ch = *set); ++set)
                     addSorted(m_matchesUnicode, ch);
                 break;
             }
             case CanonicalizeRangeLo:
                 addSortedRange(m_rangesUnicode, lo + info->value, end + info->value);
                 break;
             case CanonicalizeRangeHi:
                 addSortedRange(m_rangesUnicode, lo - info->value, end - info->value);
@@ -321,17 +321,17 @@ public:
     {
         // We handle case-insensitive checking of unicode characters which do have both
         // cases by handling them as if they were defined using a CharacterClass.
         if (!m_pattern.m_ignoreCase || isASCII(ch)) {
             m_alternative->m_terms.append(PatternTerm(ch));
             return;
         }
 
-        UCS2CanonicalizationRange* info = rangeInfoFor(ch);
+        const UCS2CanonicalizationRange* info = rangeInfoFor(ch);
         if (info->type == CanonicalizeUnique) {
             m_alternative->m_terms.append(PatternTerm(ch));
             return;
         }
 
         m_characterClassConstructor.putUnicodeIgnoreCase(ch, info);
         CharacterClass* newCharacterClass = m_characterClassConstructor.charClass();
         m_pattern.m_userCharacterClasses.append(newCharacterClass);
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -77,22 +77,22 @@ JSValIsInterfaceOfType(JSContext *cx, Ha
 }
 
 char* xpc_CloneAllAccess()
 {
     static const char allAccess[] = "AllAccess";
     return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
 }
 
-char * xpc_CheckAccessList(const PRUnichar* wideName, const char* list[])
+char * xpc_CheckAccessList(const PRUnichar* wideName, const char* const list[])
 {
     nsAutoCString asciiName;
     CopyUTF16toUTF8(nsDependentString(wideName), asciiName);
 
-    for (const char** p = list; *p; p++)
+    for (const char* const* p = list; *p; p++)
         if (!strcmp(*p, asciiName.get()))
             return xpc_CloneAllAccess();
 
     return nullptr;
 }
 
 /***************************************************************************/
 /***************************************************************************/
@@ -1324,45 +1324,45 @@ NS_IMPL_THREADSAFE_RELEASE(nsXPCComponen
 
 /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in uint32_t enum_op, in JSValPtr statep, out JSID idp); */
 NS_IMETHODIMP
 nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
                                       JSContext * cx, JSObject * obj,
                                       uint32_t enum_op, jsval * statep,
                                       jsid * idp, bool *_retval)
 {
-    void** iter;
+    const void** iter;
 
     switch (enum_op) {
         case JSENUMERATE_INIT:
         case JSENUMERATE_INIT_ALL:
         {
             if (idp)
                 *idp = INT_TO_JSID(nsXPCException::GetNSResultCount());
 
             void** space = (void**) new char[sizeof(void*)];
             *space = nullptr;
             *statep = PRIVATE_TO_JSVAL(space);
             return NS_OK;
         }
         case JSENUMERATE_NEXT:
         {
             const char* name;
-            iter = (void**) JSVAL_TO_PRIVATE(*statep);
+            iter = (const void**) JSVAL_TO_PRIVATE(*statep);
             if (nsXPCException::IterateNSResults(nullptr, &name, nullptr, iter)) {
                 JSString* idstr = JS_NewStringCopyZ(cx, name);
                 if (idstr && JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp))
                     return NS_OK;
             }
             // else... FALL THROUGH
         }
 
         case JSENUMERATE_DESTROY:
         default:
-            iter = (void**) JSVAL_TO_PRIVATE(*statep);
+            iter = (const void**) JSVAL_TO_PRIVATE(*statep);
             delete [] (char*) iter;
             *statep = JSVAL_NULL;
             return NS_OK;
     }
 }
 
 
 /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in uint32_t flags, out JSObjectPtr objp); */
@@ -1373,17 +1373,17 @@ nsXPCComponents_Results::NewResolve(nsIX
                                     JSObject * *objp, bool *_retval)
 {
     RootedObject obj(cx, objArg);
     RootedId id(cx, idArg);
     JSAutoByteString name;
 
     if (JSID_IS_STRING(id) && name.encodeLatin1(cx, JSID_TO_STRING(id))) {
         const char* rv_name;
-        void* iter = nullptr;
+        const void* iter = nullptr;
         nsresult rv;
         while (nsXPCException::IterateNSResults(&rv, &rv_name, nullptr, &iter)) {
             if (!strcmp(name.ptr(), rv_name)) {
                 jsval val = JS_NumberValue((double)rv);
 
                 *objp = obj;
                 if (!JS_DefinePropertyById(cx, obj, id, val,
                                            nullptr, nullptr,
@@ -4390,17 +4390,17 @@ nsXPCComponents_Utils::CanCreateWrapper(
     *_retval = xpc_CloneAllAccess();
     return NS_OK;
 }
 
 /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
 {
-    static const char* allowed[] = { "lookupMethod", "evalInSandbox", nullptr };
+    static const char* const allowed[] = { "lookupMethod", "evalInSandbox", nullptr };
     *_retval = xpc_CheckAccessList(methodName, allowed);
     return NS_OK;
 }
 
 /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
 NS_IMETHODIMP
 nsXPCComponents_Utils::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
 {
@@ -4912,32 +4912,32 @@ nsXPCComponents::CanCreateWrapper(const 
     *_retval = xpc_CloneAllAccess();
     return NS_OK;
 }
 
 /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
 NS_IMETHODIMP
 nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
 {
-    static const char* allowed[] = { "isSuccessCode", "lookupMethod", nullptr };
+    static const char* const allowed[] = { "isSuccessCode", "lookupMethod", nullptr };
     *_retval = xpc_CheckAccessList(methodName, allowed);
     if (*_retval &&
         methodName[0] == 'l' &&
         !nsContentUtils::IsCallerXBL())
     {
         Telemetry::Accumulate(Telemetry::COMPONENTS_LOOKUPMETHOD_ACCESSED_BY_CONTENT, true);
     }
     return NS_OK;
 }
 
 /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
 NS_IMETHODIMP
 nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
 {
-    static const char* allowed[] = { "interfaces", "interfacesByID", "results", nullptr};
+    static const char* const allowed[] = { "interfaces", "interfacesByID", "results", nullptr};
     *_retval = xpc_CheckAccessList(propertyName, allowed);
     if (*_retval &&
         propertyName[0] == 'i' &&
         !nsContentUtils::IsCallerXBL())
     {
         Telemetry::Accumulate(Telemetry::COMPONENTS_INTERFACES_ACCESSED_BY_CONTENT, true);
     }
     return NS_OK;
--- a/js/xpconnect/src/XPCException.cpp
+++ b/js/xpconnect/src/XPCException.cpp
@@ -14,17 +14,17 @@
 /* Quick and dirty mapping of well known result codes to strings. We only
 *  call this when building an exception object, so iterating the short array
 *  is not too bad.
 *
 *  It sure would be nice to have exceptions declared in idl and available
 *  in some more global way at runtime.
 */
 
-static struct ResultMap
+static const struct ResultMap
 {nsresult rv; const char* name; const char* format;} map[] = {
 #define XPC_MSG_DEF(val, format) \
     {(val), #val, format},
 #include "xpc.msg"
 #undef XPC_MSG_DEF
     {NS_OK,0,0}   // sentinel to mark end of array
 };
 
@@ -32,34 +32,34 @@ static struct ResultMap
 
 // static
 JSBool
 nsXPCException::NameAndFormatForNSResult(nsresult rv,
                                          const char** name,
                                          const char** format)
 {
 
-    for (ResultMap* p = map; p->name; p++) {
+    for (const ResultMap* p = map; p->name; p++) {
         if (rv == p->rv) {
             if (name) *name = p->name;
             if (format) *format = p->format;
             return true;
         }
     }
     return false;
 }
 
 // static
-void*
+const void*
 nsXPCException::IterateNSResults(nsresult* rv,
                                  const char** name,
                                  const char** format,
-                                 void** iterp)
+                                 const void** iterp)
 {
-    ResultMap* p = (ResultMap*) *iterp;
+    const ResultMap* p = (const ResultMap*) *iterp;
     if (!p)
         p = map;
     else
         p++;
     if (!p->name)
         p = nullptr;
     else {
         if (rv)
--- a/js/xpconnect/src/XPCJSID.cpp
+++ b/js/xpconnect/src/XPCJSID.cpp
@@ -560,27 +560,27 @@ nsJSIID::CanCreateWrapper(const nsIID * 
     *_retval = xpc_CloneAllAccess();
     return NS_OK;
 }
 
 /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
 NS_IMETHODIMP
 nsJSIID::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
 {
-    static const char* allowed[] = {"equals", "toString", nullptr};
+    static const char* const allowed[] = {"equals", "toString", nullptr};
 
     *_retval = xpc_CheckAccessList(methodName, allowed);
     return NS_OK;
 }
 
 /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
 NS_IMETHODIMP
 nsJSIID::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
 {
-    static const char* allowed[] = {"name", "number", "valid", nullptr};
+    static const char* const allowed[] = {"name", "number", "valid", nullptr};
     *_retval = xpc_CheckAccessList(propertyName, allowed);
     return NS_OK;
 }
 
 /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
 NS_IMETHODIMP
 nsJSIID::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
 {
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -3270,17 +3270,17 @@ void DEBUG_ReportShadowedMembers(XPCNati
 
     XPCNativeScriptableInfo* si = wrapper ?
             wrapper->GetScriptableInfo() :
             proto->GetScriptableInfo();
 
     // We just want to skip some classes...
     if (si) {
         // Add any classnames to skip to this (null terminated) array...
-        static const char* skipClasses[] = {
+        static const char* const skipClasses[] = {
             "Window",
             "HTMLDocument",
             "HTMLCollection",
             "Event",
             "ChromeWindow",
             nullptr
         };
 
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -3095,20 +3095,20 @@ public:
                                  nsIStackFrame *aLocation,
                                  nsISupports *aData,
                                  nsIException** exception);
 
     static JSBool NameAndFormatForNSResult(nsresult rv,
                                            const char** name,
                                            const char** format);
 
-    static void* IterateNSResults(nsresult* rv,
-                                  const char** name,
-                                  const char** format,
-                                  void** iterp);
+    static const void* IterateNSResults(nsresult* rv,
+                                        const char** name,
+                                        const char** format,
+                                        const void** iterp);
 
     static uint32_t GetNSResultCount();
 
     nsXPCException();
     virtual ~nsXPCException();
 
     static void InitStatics() { sEverMadeOneFromFactory = false; }
 
@@ -3584,17 +3584,17 @@ typedef ArrayAutoMarkingPtr<XPCNativeInt
 
 /***************************************************************************/
 // Allocates a string that grants all access ("AllAccess")
 
 extern char* xpc_CloneAllAccess();
 /***************************************************************************/
 // Returns access if wideName is in list
 
-extern char * xpc_CheckAccessList(const PRUnichar* wideName, const char* list[]);
+extern char * xpc_CheckAccessList(const PRUnichar* wideName, const char* const list[]);
 
 /***************************************************************************/
 // in xpcvariant.cpp...
 
 // {1809FD50-91E8-11d5-90F9-0010A4E73D9A}
 #define XPCVARIANT_IID                                                        \
     {0x1809fd50, 0x91e8, 0x11d5,                                              \
       { 0x90, 0xf9, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -8241,18 +8241,20 @@ nsCSSFrameConstructor::ProcessRestyledFr
     if (changeData->mContent) {
       if (!nsAnimationManager::ContentOrAncestorHasAnimation(changeData->mContent) &&
           !nsTransitionManager::ContentOrAncestorHasTransition(changeData->mContent)) {
         nsIFrame* frame = changeData->mContent->GetPrimaryFrame();
         if (frame) {
           DebugVerifyStyleTree(frame);
         }
       }
-    } else {
-      NS_WARNING("Unable to test style tree integrity -- no content node");
+    } else if (!changeData->mFrame ||
+               changeData->mFrame->GetType() != nsGkAtoms::viewportFrame) {
+      NS_WARNING("Unable to test style tree integrity -- no content node "
+                 "(and not a viewport frame)");
     }
 #endif
   }
 
   aChangeList.Clear();
   return NS_OK;
 }
 
--- a/layout/reftests/bugs/598726-1.html
+++ b/layout/reftests/bugs/598726-1.html
@@ -1,33 +1,39 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
   <head>
     <style type="text/css">
       input {
-          -webkit-transition: all 200ms ease-in-out;
-          -moz-transition: all 200ms ease-in-out;
-          transition: all 200ms ease-in-out;
+          -webkit-transition: -webkit-transform 200ms ease-in-out;
+          transition: transform 200ms ease-in-out;
       }
       input:focus {
           -webkit-transform: scale(1.05);
-          -moz-transform: scale(1.05);
           transform: scale(1.05);
       }
     </style>
     <script>
       function boom() {
         var i = document.querySelector("input");
-        i.addEventListener("transitionend", function() {
+        i.addEventListener("transitionend", function(aEvent) {