Merge m-c to b2g-inbound
authorWes Kocher <wkocher@mozilla.com>
Mon, 24 Feb 2014 18:28:37 -0800
changeset 170727 c1d012d7de79599713595c07777ae6fb645297c3
parent 170726 6b0b53d91c112c9c2c6fad555ebc01077129def6 (current diff)
parent 170669 e3daaa4c73dd1748533a330926b0811240c2fb08 (diff)
child 170728 248dfb3b0442aec69c304f5bd5c9da38f0bf2331
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
milestone30.0a1
Merge m-c to b2g-inbound
--- a/b2g/app/Makefile.in
+++ b/b2g/app/Makefile.in
@@ -42,22 +42,16 @@ LIBS += \
   -lbinder \
   -lutils \
   $(NULL)
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 OS_LIBS += $(call EXPAND_LIBNAME,version)
 endif
-
-ifdef _MSC_VER
-# Always enter a Windows program through wmain, whether or not we're
-# a console application.
-WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
-endif
 endif #LIBXUL_SDK
 
 UA_UPDATE_FILE = ua-update.json
 
 $(UA_UPDATE_FILE): % : %.in
 	# strip out comment lines, which are not valid in JSON
 	sed -e '/^ *\/\//d' -e '/^ *$$/d' $^ > $@
 
--- a/b2g/app/moz.build
+++ b/b2g/app/moz.build
@@ -7,16 +7,20 @@
 if not CONFIG['LIBXUL_SDK']:
     if CONFIG['GAIADIR']:
         PROGRAM = CONFIG['MOZ_APP_NAME'] + "-bin"
     else:
         PROGRAM = CONFIG['MOZ_APP_NAME']
     SOURCES += [
         'nsBrowserApp.cpp',
     ]
+    if CONFIG['_MSC_VER']:
+        # Always enter a Windows program through wmain, whether or not we're
+        # a console application.
+        WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
 
 if CONFIG['ENABLE_MARIONETTE']:
     DEFINES['ENABLE_MARIONETTE'] = 1
 
 DEFINES['XPCOM_GLUE'] = True
 
 for var in ('MOZ_APP_NAME', 'MOZ_APP_VERSION', 'MOZ_UPDATER'):
     DEFINES[var] = CONFIG[var]
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -49,22 +49,16 @@ endif
 endif
 
 # This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
 # shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
 NSDISTMODE = copy
 
 include $(topsrcdir)/config/config.mk
 
-ifdef _MSC_VER
-# Always enter a Windows program through wmain, whether or not we're
-# a console application.
-WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
-endif
-
 ifeq ($(OS_ARCH),WINNT)
 RCINCLUDE = splash.rc
 # Rebuild firefox.exe if the manifest changes - it's included by splash.rc.
 # (this dependency should really be just for firefox.exe, not other targets)
 # Note the manifest file exists in the tree, so we use the explicit filename
 # here.
 EXTRA_DEPS += firefox.exe.manifest
 ifndef GNU_CC
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -27,8 +27,13 @@ GENERATED_INCLUDES += [
     '/build',
 ]
 
 LOCAL_INCLUDES += [
     '/toolkit/xre',
     '/xpcom/base',
     '/xpcom/build',
 ]
+
+if CONFIG['_MSC_VER']:
+    # Always enter a Windows program through wmain, whether or not we're
+    # a console application.
+    WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1376,11 +1376,16 @@ pref("identity.fxaccounts.remote.signin.
 // The URL we take the user to when they opt to "manage" their Firefox Account.
 // Note that this will always need to be in the same TLD as the
 // "identity.fxaccounts.remote.uri" pref.
 pref("identity.fxaccounts.settings.uri", "https://accounts.firefox.com/settings");
 
 // The URL of the Firefox Accounts auth server backend
 pref("identity.fxaccounts.auth.uri", "https://api.accounts.firefox.com/v1");
 
+// On GTK, we now default to showing the menubar only when alt is pressed:
+#ifdef MOZ_WIDGET_GTK
+pref("ui.key.menuAccessKeyFocuses", true);
+#endif
+
 
 // Temporarily turn the new http cache v2 on for Desktop Firefox only
 pref("browser.cache.use_new_backend_temp", true);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4273,18 +4273,25 @@ function onViewToolbarsPopupShowing(aEve
 function onViewToolbarCommand(aEvent) {
   var toolbarId = aEvent.originalTarget.getAttribute("toolbarId");
   var toolbar = document.getElementById(toolbarId);
   var isVisible = aEvent.originalTarget.getAttribute("checked") == "true";
   setToolbarVisibility(toolbar, isVisible);
 }
 
 function setToolbarVisibility(toolbar, isVisible) {
-  var hidingAttribute = toolbar.getAttribute("type") == "menubar" ?
-                        "autohide" : "collapsed";
+  let hidingAttribute;
+  if (toolbar.getAttribute("type") == "menubar") {
+    hidingAttribute = "autohide";
+#ifdef MOZ_WIDGET_GTK
+    Services.prefs.setBoolPref("ui.key.menuAccessKeyFocuses", !isVisible);
+#endif
+  } else {
+    hidingAttribute = "collapsed";
+  }
 
   toolbar.setAttribute(hidingAttribute, !isVisible);
   document.persist(toolbar.id, hidingAttribute);
   let eventParams = {
     detail: {
       visible: isVisible
     },
     bubbles: true
--- a/content/media/webvtt/WebVTTParserWrapper.js
+++ b/content/media/webvtt/WebVTTParserWrapper.js
@@ -47,17 +47,17 @@ WebVTTParserWrapper.prototype =
 
   convertCueToDOMTree: function(window, cue)
   {
     return WebVTTParser.convertCueToDOMTree(window, cue.text);
   },
 
   processCues: function(window, cues, overlay)
   {
-    WebVTTParser.processCues(window, cues, null, overlay);
+    WebVTTParser.processCues(window, cues, overlay);
   },
 
   classDescription: "Wrapper for the JS WebVTTParser (vtt.js)",
   classID: Components.ID(WEBVTTPARSERWRAPPER_CID),
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebVTTParserWrapper]),
   classInfo: XPCOMUtils.generateCI({
     classID:    WEBVTTPARSERWRAPPER_CID,
     contractID: WEBVTTPARSERWRAPPER_CONTRACTID,
--- a/content/media/webvtt/vtt.jsm
+++ b/content/media/webvtt/vtt.jsm
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 this.EXPORTED_SYMBOLS = ["WebVTTParser"];
 
 /**
  * Code below is vtt.js the JS WebVTTParser.
  * Current source code can be found at http://github.com/andreasgal/vtt.js
  *
- * Code taken from commit d819872e198d051dfcebcfb7ecf260462c9a9c6f
+ * Code taken from commit b812cd783d4284de1bc6b0349b7bda151052a1df
  */
 /**
  * Copyright 2013 vtt.js Contributors
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
@@ -96,30 +96,28 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
           this.set(k, v);
           break;
         }
       }
     },
     // Accept a setting if its a valid (signed) integer.
     integer: function(k, v) {
       if (/^-?\d+$/.test(v)) { // integer
-        this.set(k, parseInt(v, 10));
+        // Only take values in the range of -1000 ~ 1000
+        this.set(k, Math.min(Math.max(parseInt(v, 10), -1000), 1000));
       }
     },
     // Accept a setting if its a valid percentage.
-    percent: function(k, v, frac) {
+    percent: function(k, v) {
       var m;
       if ((m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) {
-        v = v.replace("%", "");
-        if (!m[2] || (m[2] && frac)) {
-          v = parseFloat(v);
-          if (v >= 0 && v <= 100) {
-            this.set(k, v);
-            return true;
-          }
+        v = parseFloat(v);
+        if (v >= 0 && v <= 100) {
+          this.set(k, v);
+          return true;
         }
       }
       return false;
     }
   };
 
   // Helper function to parse input into groups separated by 'groupDelim', and
   // interprete each group as a key/value pair separated by 'keyValueDelim'.
@@ -659,35 +657,69 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
     for (var i = 0; i < trackList.length && trackList[i] !== track; i++) {
       if (trackList[i].mode === "showing") {
         count++;
       }
     }
     return ++count * -1;
   }
 
-  function BoundingBox() {
+  function StyleBox() {
   }
 
-  BoundingBox.prototype.applyStyles = function(styles) {
-    var div = this.div;
+  // Apply styles to a div. If there is no div passed then it defaults to the
+  // div on 'this'.
+  StyleBox.prototype.applyStyles = function(styles, div) {
+    div = div || this.div;
     Object.keys(styles).forEach(function(style) {
       div.style[style] = styles[style];
     });
   };
 
-  BoundingBox.prototype.formatStyle = function(val, unit) {
+  StyleBox.prototype.formatStyle = function(val, unit) {
     return val === 0 ? 0 : val + unit;
   };
 
-  function BasicBoundingBox(window, cue) {
-    BoundingBox.call(this);
+  // Constructs the computed display state of the cue (a div). Places the div
+  // into the overlay which should be a block level element (usually a div).
+  function CueStyleBox(window, cue, styleOptions) {
+    StyleBox.call(this);
+    this.cue = cue;
 
-    // Parse our cue's text into a DOM tree rooted at 'div'.
-    this.div = parseContent(window, cue.text);
+    // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will
+    // have inline positioning and will function as the cue background box.
+    this.cueDiv = parseContent(window, cue.text);
+    this.applyStyles({
+      color: "rgba(255, 255, 255, 1)",
+      backgroundColor: "rgba(0, 0, 0, 0.8)",
+      position: "relative",
+      left: 0,
+      right: 0,
+      top: 0,
+      bottom: 0,
+      display: "inline"
+    }, this.cueDiv);
+
+    // Create an absolutely positioned div that will be used to position the cue
+    // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS
+    // mirrors of them except "middle" which is "center" in CSS.
+    this.div = window.document.createElement("div");
+    this.applyStyles({
+      textAlign: cue.align === "middle" ? "center" : cue.align,
+      direction: determineBidi(this.cueDiv),
+      writingMode: cue.vertical === "" ? "horizontal-tb"
+                                       : cue.vertical === "lr" ? "vertical-lr"
+                                                               : "vertical-rl",
+      unicodeBidi: "plaintext",
+      font: styleOptions.font,
+      whiteSpace: "pre-line",
+      position: "absolute"
+    });
+
+    this.div.appendChild(this.cueDiv);
 
     // Calculate the distance from the reference edge of the viewport to the text
     // position of the cue box. The reference edge will be resolved later when
     // the box orientation styles are applied.
     var textPos = 0;
     switch (cue.positionAlign) {
     case "start":
       textPos = cue.position;
@@ -713,159 +745,287 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
     // downwards from there.
     } else {
       this.applyStyles({
         top: this.formatStyle(textPos, "%"),
         height: this.formatStyle(cue.size, "%")
       });
     }
 
-    // All WebVTT cue-setting alignments are equivalent to the CSS mirrors of
-    // them except "middle" which is "center" in CSS.
-    this.applyStyles({
-      "textAlign": cue.align === "middle" ? "center" : cue.align
-    });
+    this.move = function(box) {
+      this.applyStyles({
+        top: this.formatStyle(box.top, "px"),
+        bottom: this.formatStyle(box.bottom, "px"),
+        left: this.formatStyle(box.left, "px"),
+        right: this.formatStyle(box.right, "px"),
+        height: this.formatStyle(box.height, "px"),
+        width: this.formatStyle(box.width, "px"),
+      });
+    };
   }
-  BasicBoundingBox.prototype = Object.create(BoundingBox.prototype);
-  BasicBoundingBox.prototype.constructor = BasicBoundingBox;
+  CueStyleBox.prototype = Object.create(StyleBox.prototype);
+  CueStyleBox.prototype.constructor = CueStyleBox;
+
+  // Represents the co-ordinates of an Element in a way that we can easily
+  // compute things with such as if it overlaps or intersects with another Element.
+  // Can initialize it with either a StyleBox or another BoxPosition.
+  function BoxPosition(obj) {
+    var self = this;
+
+    // Either a BoxPosition was passed in and we need to copy it, or a StyleBox
+    // was passed in and we need to copy the results of 'getBoundingClientRect'
+    // as the object returned is readonly. All co-ordinate values are in reference
+    // to the viewport origin (top left).
+    var lh;
+    if (obj.div) {
+      var rects = (rects = obj.div.childNodes) && (rects = rects[0]) &&
+                  rects.getClientRects && rects.getClientRects();
+      obj = obj.div.getBoundingClientRect();
+      // In certain cases the outter div will be slightly larger then the sum of
+      // the inner div's lines. This could be due to bold text, etc, on some platforms.
+      // In this case we should get the average line height and use that. This will
+      // result in the desired behaviour.
+      lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length)
+                 : 0;
+    }
+    this.left = obj.left;
+    this.right = obj.right;
+    this.top = obj.top;
+    this.height = obj.height;
+    this.bottom = obj.bottom;
+    this.width = obj.width;
+    this.lineHeight = lh !== undefined ? lh : obj.lineHeight;
+  }
 
-  const CUE_FONT_SIZE = 2.5;
-  const SCROLL_DURATION = 0.433;
-  const LINE_HEIGHT = 0.0533;
-  const REGION_FONT_SIZE = 1.3;
+  // Move the box along a particular axis. If no amount to move is passed, via
+  // the val parameter, then the default amount is the line height of the box.
+  BoxPosition.prototype.move = function(axis, val) {
+    val = val !== undefined ? val : this.lineHeight;
+    switch (axis) {
+    case "+x":
+      this.left += val;
+      this.right += val;
+      break;
+    case "-x":
+      this.left -= val;
+      this.right -= val;
+      break;
+    case "+y":
+      this.top += val;
+      this.bottom += val;
+      break;
+    case "-y":
+      this.top -= val;
+      this.bottom -= val;
+      break;
+    }
+  };
+
+  // Check if this box overlaps another box, b2.
+  BoxPosition.prototype.overlaps = function(b2) {
+    return this.left < b2.right &&
+           this.right > b2.left &&
+           this.top < b2.bottom &&
+           this.bottom > b2.top;
+  };
+
+  // Check if this box overlaps any other boxes in boxes.
+  BoxPosition.prototype.overlapsAny = function(boxes) {
+    for (var i = 0; i < boxes.length; i++) {
+      if (this.overlaps(boxes[i])) {
+        return true;
+      }
+    }
+    return false;
+  };
 
-  // Constructs the computed display state of the cue (a div). Places the div
-  // into the overlay which should be a block level element (usually a div).
-  function CueBoundingBox(window, cue, overlay) {
-    BasicBoundingBox.call(this, window, cue);
-    this.applyStyles({
-      direction: determineBidi(this.div),
-      writingMode: cue.vertical === "" ? "horizontal-tb"
-                                       : cue.vertical === "lr" ? "vertical-lr"
-                                                               : "vertical-rl",
-      position: "absolute",
-      unicodeBidi: "plaintext",
-      fontSize: CUE_FONT_SIZE + "vh",
-      fontFamily: "sans-serif",
-      color: "rgba(255, 255, 255, 1)",
-      backgroundColor: "rgba(0, 0, 0, 0.8)",
-      whiteSpace: "pre-line"
-    });
+  // Check if this box is within another box.
+  BoxPosition.prototype.within = function(container) {
+    return this.top >= container.top &&
+           this.bottom <= container.bottom &&
+           this.left >= container.left &&
+           this.right <= container.right;
+  };
 
-    // Append the div to the overlay so we can get the computed styles of the
-    // element in order to position for overlap avoidance.
-    overlay.appendChild(this.div);
+  // Check if this box is entirely within the container or it is overlapping
+  // on the edge opposite of the axis direction passed. For example, if "+x" is
+  // passed and the box is overlapping on the left edge of the container, then
+  // return true.
+  BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) {
+    switch (axis) {
+    case "+x":
+      return this.left < container.left;
+    case "-x":
+      return this.right > container.right;
+    case "+y":
+      return this.top < container.top;
+    case "-y":
+      return this.bottom > container.bottom;
+    }
+  };
+
+  // Find the percentage of the area that this box is overlapping with another
+  // box.
+  BoxPosition.prototype.intersectPercentage = function(b2) {
+    var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)),
+        y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)),
+        intersectArea = x * y;
+    return intersectArea / (this.height * this.width);
+  };
+
+  // Convert the positions from this box to CSS compatible positions using
+  // the reference container's positions. This has to be done because this
+  // box's positions are in reference to the viewport origin, whereas, CSS
+  // values are in referecne to their respective edges.
+  BoxPosition.prototype.toCSSCompatValues = function(reference) {
+    return {
+      top: this.top - reference.top,
+      bottom: reference.bottom - this.bottom,
+      left: this.left - reference.left,
+      right: reference.right - this.right,
+      height: this.height,
+      width: this.width
+    };
+  };
 
-    // Calculate the distance from the reference edge of the viewport to the line
-    // position of the cue box. The reference edge will be resolved later when
-    // the box orientation styles are applied. Default if snapToLines is not set
-    // is 85.
-    var linePos = 85;
-    if (!cue.snapToLines) {
-      var computedLinePos = computeLinePos(cue),
-          boxComputedStyle = window.getComputedStyle(this.div),
-          size = cue.vertical === "" ? boxComputedStyle.getPropertyValue("height") :
-                                       boxComputedStyle.getPropertyValue("width"),
-          // Get the percentage value of the computed height as getPropertyValue
-          // returns pixels.
-          overlayHeight = window.getComputedStyle(overlay).getPropertyValue("height"),
-          calculatedPercentage = (size.replace("px", "") / overlayHeight.replace("px", "")) * 100;
+  // Get an object that represents the box's position without anything extra.
+  // Can pass a StyleBox, HTMLElement, or another BoxPositon.
+  BoxPosition.getSimpleBoxPosition = function(obj) {
+    obj = obj.div ? obj.div.getBoundingClientRect() :
+                  obj.tagName ? obj.getBoundingClientRect() : obj;
+    return {
+      left: obj.left,
+      right: obj.right,
+      top: obj.top,
+      height: obj.height,
+      bottom: obj.bottom,
+      width: obj.width
+    };
+  };
+
+  // Move a StyleBox to its specified, or next best, position. The containerBox
+  // is the box that contains the StyleBox, such as a div. boxPositions are
+  // a list of other boxes that the styleBox can't overlap with.
+  function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) {
 
-      switch (cue.lineAlign) {
-      case "start":
-        linePos = computedLinePos;
-        break;
-      case "middle":
-        linePos = computedLinePos - (calculatedPercentage / 2);
-        break;
-      case "end":
-        linePos = computedLinePos - calculatedPercentage;
-        break;
+    // Find the best position for a cue box, b, on the video. The axis parameter
+    // is a list of axis, the order of which, it will move the box along. For example:
+    // Passing ["+x", "-x"] will move the box first along the x axis in the positive
+    // direction. If it doesn't find a good position for it there it will then move
+    // it along the x axis in the negative direction.
+    function findBestPosition(b, axis) {
+      var bestPosition,
+          specifiedPosition = new BoxPosition(b),
+          percentage = 1; // Highest possible so the first thing we get is better.
+
+      for (var i = 0; i < axis.length; i++) {
+        while (b.overlapsOppositeAxis(containerBox, axis[i]) ||
+               (b.within(containerBox) && b.overlapsAny(boxPositions))) {
+          b.move(axis[i]);
+        }
+        // We found a spot where we aren't overlapping anything. This is our
+        // best position.
+        if (b.within(containerBox)) {
+          return b;
+        }
+        var p = b.intersectPercentage(containerBox);
+        // If we're outside the container box less then we were on our last try
+        // then remember this position as the best position.
+        if (percentage > p) {
+          bestPosition = new BoxPosition(b);
+          percentage = p;
+        }
+        // Reset the box position to the specified position.
+        b = new BoxPosition(specifiedPosition);
       }
+      return bestPosition || specifiedPosition;
     }
 
-    switch (cue.vertical) {
-    case "":
-      this.applyStyles({
-        top: this.formatStyle(linePos, "%")
+    function reverseAxis(axis) {
+      return axis.map(function(a) {
+        return a.indexOf("+") !== -1 ? a.replace("+", "-") : a.replace("-", "+");
       });
-      break;
-    case "rl":
-      this.applyStyles({
-        left: this.formatStyle(linePos, "%")
-      });
-      break;
-    case "lr":
-      this.applyStyles({
-        right: this.formatStyle(linePos, "%")
-      });
-      break;
     }
 
-    cue.displayState = this.div;
-  }
-  CueBoundingBox.prototype = Object.create(BasicBoundingBox.prototype);
-  CueBoundingBox.prototype.constuctor = CueBoundingBox;
-
-  function RegionBoundingBox(window, region) {
-    BoundingBox.call(this);
-    this.div = window.document.createElement("div");
-
-    var left = region.viewportAnchorX -
-               region.regionAnchorX * region.width / 100,
-        top = region.viewportAnchorY -
-              region.regionAnchorY * region.lines * LINE_HEIGHT / 100;
+    var boxPosition = new BoxPosition(styleBox),
+        cue = styleBox.cue,
+        linePos = computeLinePos(cue),
+        axis = [];
 
-    this.applyStyles({
-      position: "absolute",
-      writingMode: "horizontal-tb",
-      backgroundColor: "rgba(0, 0, 0, 0.8)",
-      wordWrap: "break-word",
-      overflowWrap: "break-word",
-      font: REGION_FONT_SIZE + "vh/" + LINE_HEIGHT + "vh sans-serif",
-      lineHeight: LINE_HEIGHT + "vh",
-      color: "rgba(255, 255, 255, 1)",
-      overflow: "hidden",
-      width: this.formatStyle(region.width, "%"),
-      minHeight: "0",
-      // TODO: This value is undefined in the spec, but I am assuming that they
-      // refer to lines * line height to get the max height See issue #107.
-      maxHeight: this.formatStyle(region.lines * LINE_HEIGHT, "px"),
-      left: this.formatStyle(left, "%"),
-      top: this.formatStyle(top, "%"),
-      display: "inline-flex",
-      flexFlow: "column",
-      justifyContent: "flex-end"
-    });
+    // If we have a line number to align the cue to.
+    if (cue.snapToLines) {
+      switch (cue.vertical) {
+      case "":
+        axis = [ "+y", "-y" ];
+        break;
+      case "rl":
+        axis = [ "+x", "-x" ];
+        break;
+      case "lr":
+        axis = [ "-x", "+x" ];
+        break;
+      }
 
-    this.maybeAddCue = function(cue) {
-      if (region.id !== cue.regionId) {
-        return false;
+      // If computed line position returns negative then line numbers are
+      // relative to the bottom of the video instead of the top. Therefore, we
+      // need to increase our initial position by the length or width of the
+      // video, depending on the writing direction, and reverse our axis directions.
+      var initialPosition = boxPosition.lineHeight * Math.floor(linePos + 0.5),
+          initialAxis = axis[0];
+      if (linePos < 0) {
+        initialPosition += cue.vertical === "" ? containerBox.height : containerBox.width;
+        axis = reverseAxis(axis);
       }
 
-      var basicBox = new BasicBoundingBox(window, cue);
-      basicBox.applyStyles({
-        position: "relative",
-        unicodeBidi: "plaintext",
-        width: "auto"
-      });
+      // Move the box to the specified position. This may not be its best
+      // position.
+      boxPosition.move(initialAxis, initialPosition);
+
+    } else {
+      // If we have a percentage line value for the cue.
+      var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100;
 
-      if (this.div.childNodes.length === 1 && region.scroll === "up") {
-        this.applyStyles({
-          transitionProperty: "top",
-          transitionDuration: SCROLL_DURATION + "s"
-        });
+      switch (cue.lineAlign) {
+      case "middle":
+        linePos -= (calculatedPercentage / 2);
+        break;
+      case "end":
+        linePos -= calculatedPercentage;
+        break;
       }
 
-      this.div.appendChild(basicBox.div);
-      return true;
-    };
+      // Apply initial line position to the cue box.
+      switch (cue.vertical) {
+      case "":
+        styleBox.applyStyles({
+          top: styleBox.formatStyle(linePos, "%")
+        });
+        break;
+      case "rl":
+        styleBox.applyStyles({
+          left: styleBox.formatStyle(linePos, "%")
+        });
+        break;
+      case "lr":
+        styleBox.applyStyles({
+          right: styleBox.formatStyle(linePos, "%")
+        });
+        break;
+      }
+
+      axis = [ "+y", "-x", "+x", "-y" ];
+
+      // Get the box position again after we've applied the specified positioning
+      // to it.
+      boxPosition = new BoxPosition(styleBox);
+    }
+
+    var bestPosition = findBestPosition(boxPosition, axis);
+    styleBox.move(bestPosition.toCSSCompatValues(containerBox));
   }
-  RegionBoundingBox.prototype = Object.create(BoundingBox.prototype);
-  RegionBoundingBox.prototype.constructor = RegionBoundingBox;
 
   function WebVTTParser(window, decoder) {
     this.window = window;
     this.state = "INITIAL";
     this.buffer = "";
     this.decoder = decoder || new TextDecoder("utf8");
   }
 
@@ -886,55 +1046,83 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
 
   WebVTTParser.convertCueToDOMTree = function(window, cuetext) {
     if (!window || !cuetext) {
       return null;
     }
     return parseContent(window, cuetext);
   };
 
+  const FONT_SIZE_PERCENT = 0.05;
+  const FONT_STYLE = "sans-serif";
+  const CUE_BACKGROUND_PADDING = "1.5%";
+
   // Runs the processing model over the cues and regions passed to it.
   // @param overlay A block level element (usually a div) that the computed cues
   //                and regions will be placed into.
-  WebVTTParser.processCues = function(window, cues, regions, overlay) {
+  WebVTTParser.processCues = function(window, cues, overlay) {
     if (!window || !cues || !overlay) {
       return null;
     }
 
     // Remove all previous children.
     while (overlay.firstChild) {
       overlay.removeChild(overlay.firstChild);
     }
 
-    var regionBoxes = regions ? regions.map(function(region) {
-      return new RegionBoundingBox(window, region);
-    }) : null;
+    var paddedOverlay = window.document.createElement("div");
+    paddedOverlay.style.position = "absolute";
+    paddedOverlay.style.left = "0";
+    paddedOverlay.style.right = "0";
+    paddedOverlay.style.top = "0";
+    paddedOverlay.style.bottom = "0";
+    paddedOverlay.style.margin = CUE_BACKGROUND_PADDING;
+    overlay.appendChild(paddedOverlay);
 
-    function mapCueToRegion(cue) {
-      for (var i = 0; i < regionBoxes.length; i++) {
-        if (regionBoxes[i].maybeAddCue(cue)) {
+    // Determine if we need to compute the display states of the cues. This could
+    // be the case if a cue's state has been changed since the last computation or
+    // if it has not been computed yet.
+    function shouldCompute(cues) {
+      for (var i = 0; i < cues.length; i++) {
+        if (cues[i].hasBeenReset || !cues[i].displayState) {
           return true;
         }
       }
       return false;
     }
 
-    for (var i = 0; i < cues.length; i++) {
-      // Check to see if this cue is contained within a VTTRegion.
-      if (regionBoxes && mapCueToRegion(cues[i])) {
-        continue;
-      }
-      // Check to see if we can just reuse the last computed styles of the cue.
-      if (cues[i].hasBeenReset !== true && cues[i].displayState) {
-        overlay.appendChild(cues[i].displayState);
-        continue;
-      }
-      // Compute the position of the cue box on the cue overlay.
-      var cueBox = new CueBoundingBox(window, cues[i], overlay);
+    // We don't need to recompute the cues' display states. Just reuse them.
+    if (!shouldCompute(cues)) {
+      cues.forEach(function(cue) {
+        paddedOverlay.appendChild(cue.displayState);
+      });
+      return;
     }
+
+    var boxPositions = [],
+        containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay),
+        fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100;
+    var styleOptions = {
+      font: fontSize + "px " + FONT_STYLE
+    };
+
+    cues.forEach(function(cue) {
+      // Compute the intial position and styles of the cue div.
+      var styleBox = new CueStyleBox(window, cue, styleOptions);
+      paddedOverlay.appendChild(styleBox.div);
+
+      // Move the cue div to it's correct line position.
+      moveBoxToLinePosition(window, styleBox, containerBox, boxPositions);
+
+      // Remember the computed div so that we don't have to recompute it later
+      // if we don't have too.
+      cue.displayState = styleBox.div;
+
+      boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox));
+    });
   };
 
   WebVTTParser.prototype = {
     parse: function (data) {
       var self = this;
 
       // If there is no data then we won't decode it, but will just try to parse
       // whatever is in buffer already. This may occur in circumstances, for
@@ -967,32 +1155,32 @@ this.EXPORTED_SYMBOLS = ["WebVTTParser"]
         var settings = new Settings();
 
         parseOptions(input, function (k, v) {
           switch (k) {
           case "id":
             settings.set(k, v);
             break;
           case "width":
-            settings.percent(k, v, true);
+            settings.percent(k, v);
             break;
           case "lines":
             settings.integer(k, v);
             break;
           case "regionanchor":
           case "viewportanchor":
             var xy = v.split(',');
             if (xy.length !== 2) {
               break;
             }
             // We have to make sure both x and y parse, so use a temporary
             // settings object here.
             var anchor = new Settings();
-            anchor.percent("x", xy[0], true);
-            anchor.percent("y", xy[1], true);
+            anchor.percent("x", xy[0]);
+            anchor.percent("y", xy[1]);
             if (!anchor.has("x") || !anchor.has("y")) {
               break;
             }
             settings.set(k + "X", anchor.get("x"));
             settings.set(k + "Y", anchor.get("y"));
             break;
           case "scroll":
             settings.alt(k, v, ["up"]);
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1765,27 +1765,43 @@ MediaManager::Observe(nsISupports* aSubj
   return NS_OK;
 }
 
 static PLDHashOperator
 WindowsHashToArrayFunc (const uint64_t& aId,
                         StreamListeners* aData,
                         void *userArg)
 {
-    nsISupportsArray *array =
-        static_cast<nsISupportsArray *>(userArg);
-    nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
-      (nsGlobalWindow::GetInnerWindowWithId(aId));
-    (void) aData;
+  nsISupportsArray *array =
+    static_cast<nsISupportsArray *>(userArg);
+  nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
+    (nsGlobalWindow::GetInnerWindowWithId(aId));
 
-    MOZ_ASSERT(window);
-    if (window) {
+  MOZ_ASSERT(window);
+  if (window) {
+    // mActiveWindows contains both windows that have requested device
+    // access and windows that are currently capturing media. We want
+    // to return only the latter. See bug 975177.
+    bool capturing = false;
+    if (aData) {
+      uint32_t length = aData->Length();
+      for (uint32_t i = 0; i < length; ++i) {
+        nsRefPtr<GetUserMediaCallbackMediaStreamListener> listener =
+          aData->ElementAt(i);
+        if (listener->CapturingVideo() || listener->CapturingAudio()) {
+          capturing = true;
+          break;
+        }
+      }
+    }
+
+    if (capturing)
       array->AppendElement(window);
-    }
-    return PL_DHASH_NEXT;
+  }
+  return PL_DHASH_NEXT;
 }
 
 
 nsresult
 MediaManager::GetActiveMediaCaptureWindows(nsISupportsArray **aArray)
 {
   MOZ_ASSERT(aArray);
   nsISupportsArray *array;
--- a/dom/plugins/ipc/hangui/Makefile.in
+++ b/dom/plugins/ipc/hangui/Makefile.in
@@ -8,12 +8,8 @@ RCINCLUDE = HangUIDlg.rc
 
 STL_FLAGS = \
   -D_HAS_EXCEPTIONS=0 \
   $(NULL)
 
 MOZ_GLUE_LDFLAGS =
 
 include $(topsrcdir)/config/rules.mk
-
-ifdef GNU_CC
-WIN32_EXE_LDFLAGS = -municode
-endif
--- a/dom/plugins/ipc/hangui/moz.build
+++ b/dom/plugins/ipc/hangui/moz.build
@@ -10,8 +10,11 @@ PROGRAM = 'plugin-hang-ui'
 
 UNIFIED_SOURCES += [
     'MiniShmChild.cpp',
     'PluginHangUIChild.cpp',
 ]
 include('/ipc/chromium/chromium-config.mozbuild')
 
 DEFINES['NS_NO_XPCOM'] = True
+
+if CONFIG['GNU_CC']:
+    WIN32_EXE_LDFLAGS += ['-municode']
--- a/dom/xbl/nsXBLDocumentInfo.cpp
+++ b/dom/xbl/nsXBLDocumentInfo.cpp
@@ -218,97 +218,101 @@ nsXBLDocGlobalObject::GetPrincipal()
   if (!document)
     return nullptr;
 
   return document->NodePrincipal();
 }
 
 /* Implementation file */
 
-static PLDHashOperator
-TraverseProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
+static bool
+TraverseProtos(nsHashKey *aKey, void *aData, void* aClosure)
 {
-  nsCycleCollectionTraversalCallback *cb =
+  nsCycleCollectionTraversalCallback *cb = 
     static_cast<nsCycleCollectionTraversalCallback*>(aClosure);
-  aProto->Traverse(*cb);
-  return PL_DHASH_NEXT;
+  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
+  proto->Traverse(*cb);
+  return kHashEnumerateNext;
 }
 
-static PLDHashOperator
-UnlinkProtoJSObjects(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
+static bool
+UnlinkProtoJSObjects(nsHashKey *aKey, void *aData, void* aClosure)
 {
-  aProto->UnlinkJSObjects();
-  return PL_DHASH_NEXT;
+  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
+  proto->UnlinkJSObjects();
+  return kHashEnumerateNext;
 }
 
 struct ProtoTracer
 {
   const TraceCallbacks &mCallbacks;
   void *mClosure;
 };
 
-static PLDHashOperator
-TraceProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
+static bool
+TraceProtos(nsHashKey *aKey, void *aData, void* aClosure)
 {
   ProtoTracer* closure = static_cast<ProtoTracer*>(aClosure);
-  aProto->Trace(closure->mCallbacks, closure->mClosure);
-  return PL_DHASH_NEXT;
+  nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
+  proto->Trace(closure->mCallbacks, closure->mClosure);
+  return kHashEnumerateNext;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
   if (tmp->mBindingTable) {
-    tmp->mBindingTable->EnumerateRead(UnlinkProtoJSObjects, nullptr);
+    tmp->mBindingTable->Enumerate(UnlinkProtoJSObjects, nullptr);
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobalObject)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo)
   if (tmp->mDocument &&
       nsCCUncollectableMarker::InGeneration(cb, tmp->mDocument->GetMarkedCCGeneration())) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
   if (tmp->mBindingTable) {
-    tmp->mBindingTable->EnumerateRead(TraverseProtos, &cb);
+    tmp->mBindingTable->Enumerate(TraverseProtos, &cb);
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObject)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
   if (tmp->mBindingTable) {
     ProtoTracer closure = { aCallbacks, aClosure };
-    tmp->mBindingTable->EnumerateRead(TraceProtos, &closure);
+    tmp->mBindingTable->Enumerate(TraceProtos, &closure);
   }
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 static void
 UnmarkXBLJSObject(void* aP, const char* aName, void* aClosure)
 {
   JS::ExposeObjectToActiveJS(static_cast<JSObject*>(aP));
 }
 
-static PLDHashOperator
-UnmarkProtos(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
+static bool
+UnmarkProtos(nsHashKey* aKey, void* aData, void* aClosure)
 {
-  aProto->Trace(TraceCallbackFunc(UnmarkXBLJSObject), nullptr);
-  return PL_DHASH_NEXT;
+  nsXBLPrototypeBinding* proto = static_cast<nsXBLPrototypeBinding*>(aData);
+  proto->Trace(TraceCallbackFunc(UnmarkXBLJSObject), nullptr);
+  return kHashEnumerateNext;
 }
 
 void
 nsXBLDocumentInfo::MarkInCCGeneration(uint32_t aGeneration)
 {
   if (mDocument) {
     mDocument->MarkUncollectableForCCGeneration(aGeneration);
   }
   // Unmark any JS we hold
   if (mBindingTable) {
-    mBindingTable->EnumerateRead(UnmarkProtos, nullptr);
+    mBindingTable->Enumerate(UnmarkProtos, nullptr);
   }
   if (mGlobalObject) {
     mGlobalObject->UnmarkCompilationGlobal();
   }
 }
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLDocumentInfo)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
@@ -317,16 +321,17 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXBLDocumentInfo)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXBLDocumentInfo)
 
 nsXBLDocumentInfo::nsXBLDocumentInfo(nsIDocument* aDocument)
   : mDocument(aDocument),
     mScriptAccess(true),
     mIsChrome(false),
+    mBindingTable(nullptr),
     mFirstBinding(nullptr)
 {
   nsIURI* uri = aDocument->GetDocumentURI();
   if (IsChromeURI(uri)) {
     // Cache whether or not this chrome XBL can execute scripts.
     nsCOMPtr<nsIXULChromeRegistry> reg =
       mozilla::services::GetXULChromeRegistryService();
     if (reg) {
@@ -357,63 +362,84 @@ nsXBLDocumentInfo::nsXBLDocumentInfo(nsI
 }
 
 nsXBLDocumentInfo::~nsXBLDocumentInfo()
 {
   /* destructor code */
   if (mGlobalObject) {
     mGlobalObject->ClearGlobalObjectOwner(); // just in case
   }
-  mozilla::DropJSObjects(this);
+  if (mBindingTable) {
+    delete mBindingTable;
+    mBindingTable = nullptr;
+    mozilla::DropJSObjects(this);
+  }
 }
 
 nsXBLPrototypeBinding*
 nsXBLDocumentInfo::GetPrototypeBinding(const nsACString& aRef)
 {
   if (!mBindingTable)
     return nullptr;
 
   if (aRef.IsEmpty()) {
     // Return our first binding
     return mFirstBinding;
   }
 
-  return mBindingTable->Get(aRef);
+  const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
+  nsCStringKey key(flat.get());
+  return static_cast<nsXBLPrototypeBinding*>(mBindingTable->Get(&key));
+}
+
+static bool
+DeletePrototypeBinding(nsHashKey* aKey, void* aData, void* aClosure)
+{
+  nsXBLPrototypeBinding* binding = static_cast<nsXBLPrototypeBinding*>(aData);
+  delete binding;
+  return true;
 }
 
 nsresult
 nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding)
 {
   if (!mBindingTable) {
-    mBindingTable = new nsClassHashtable<nsCStringHashKey, nsXBLPrototypeBinding>();
+    mBindingTable = new nsObjectHashtable(nullptr, nullptr, DeletePrototypeBinding, nullptr);
+
     mozilla::HoldJSObjects(this);
   }
 
-  NS_ENSURE_STATE(!mBindingTable->Get(aRef));
-  mBindingTable->Put(aRef, aBinding);
+  const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
+  nsCStringKey key(flat.get());
+  NS_ENSURE_STATE(!mBindingTable->Get(&key));
+  mBindingTable->Put(&key, aBinding);
 
   return NS_OK;
 }
 
 void
 nsXBLDocumentInfo::RemovePrototypeBinding(const nsACString& aRef)
 {
   if (mBindingTable) {
-    mBindingTable->Remove(aRef);
+    // Use a flat string to avoid making a copy.
+    const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
+    nsCStringKey key(flat);
+    mBindingTable->Remove(&key);
   }
 }
 
 // Callback to enumerate over the bindings from this document and write them
 // out to the cache.
-static PLDHashOperator
-WriteBinding(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
+bool
+WriteBinding(nsHashKey *aKey, void *aData, void* aClosure)
 {
-  aProto->Write((nsIObjectOutputStream*)aClosure);
+  nsXBLPrototypeBinding* binding = static_cast<nsXBLPrototypeBinding *>(aData);
+  binding->Write((nsIObjectOutputStream*)aClosure);
 
-  return PL_DHASH_NEXT;
+  return kHashEnumerateNext;
 }
 
 // static
 nsresult
 nsXBLDocumentInfo::ReadPrototypeBindings(nsIURI* aURI, nsXBLDocumentInfo** aDocInfo)
 {
   *aDocInfo = nullptr;
 
@@ -499,19 +525,18 @@ nsXBLDocumentInfo::WritePrototypeBinding
   rv = NewObjectOutputWrappedStorageStream(getter_AddRefs(stream),
                                            getter_AddRefs(storageStream),
                                            true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = stream->Write32(XBLBinding_Serialize_Version);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (mBindingTable) {
-    mBindingTable->EnumerateRead(WriteBinding, stream);
-  }
+  if (mBindingTable)
+    mBindingTable->Enumerate(WriteBinding, stream);
 
   // write a end marker at the end
   rv = stream->Write8(XBLBinding_Serialize_NoMoreBindings);
   NS_ENSURE_SUCCESS(rv, rv);
 
   stream->Close();
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -524,29 +549,28 @@ nsXBLDocumentInfo::WritePrototypeBinding
 }
 
 void
 nsXBLDocumentInfo::SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding)
 {
   mFirstBinding = aBinding;
 }
 
-static PLDHashOperator
-FlushScopedSkinSheets(const nsACString &aKey, nsXBLPrototypeBinding *aProto, void* aClosure)
+bool FlushScopedSkinSheets(nsHashKey* aKey, void* aData, void* aClosure)
 {
-  aProto->FlushSkinSheets();
-  return PL_DHASH_NEXT;
+  nsXBLPrototypeBinding* proto = (nsXBLPrototypeBinding*)aData;
+  proto->FlushSkinSheets();
+  return true;
 }
 
 void
 nsXBLDocumentInfo::FlushSkinStylesheets()
 {
-  if (mBindingTable) {
-    mBindingTable->EnumerateRead(FlushScopedSkinSheets, nullptr);
-  }
+  if (mBindingTable)
+    mBindingTable->Enumerate(FlushScopedSkinSheets);
 }
 
 JSObject*
 nsXBLDocumentInfo::GetCompilationGlobal()
 {
   EnsureGlobalObject();
   return mGlobalObject->GetCompilationGlobal();
 }
--- a/dom/xbl/nsXBLDocumentInfo.h
+++ b/dom/xbl/nsXBLDocumentInfo.h
@@ -8,16 +8,17 @@
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsWeakReference.h"
 #include "nsIDocument.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsXBLPrototypeBinding;
+class nsObjectHashtable;
 class nsXBLDocGlobalObject;
 
 class nsXBLDocumentInfo : public nsSupportsWeakReference
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   nsXBLDocumentInfo(nsIDocument* aDocument);
@@ -35,17 +36,17 @@ public:
                                nsXBLPrototypeBinding* aBinding);
 
   // This removes the binding without deleting it
   void RemovePrototypeBinding(const nsACString& aRef);
 
   nsresult WritePrototypeBindings();
 
   void SetFirstPrototypeBinding(nsXBLPrototypeBinding* aBinding);
-
+  
   void FlushSkinStylesheets();
 
   bool IsChrome() { return mIsChrome; }
 
   JSObject* GetCompilationGlobal();
 
   void MarkInCCGeneration(uint32_t aGeneration);
 
@@ -54,18 +55,17 @@ public:
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsXBLDocumentInfo)
 
 private:
   void EnsureGlobalObject();
   nsCOMPtr<nsIDocument> mDocument;
   bool mScriptAccess;
   bool mIsChrome;
   // the binding table owns each nsXBLPrototypeBinding
-  nsAutoPtr<nsClassHashtable<nsCStringHashKey, nsXBLPrototypeBinding>> mBindingTable;
-
+  nsObjectHashtable* mBindingTable;
   // non-owning pointer to the first binding in the table
   nsXBLPrototypeBinding* mFirstBinding;
 
   nsRefPtr<nsXBLDocGlobalObject> mGlobalObject;
 };
 
 #ifdef DEBUG
 void AssertInCompilationScope();
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -159,17 +159,17 @@ struct DrawSurfaceOptions {
 /*
  * This class is used to store gradient stops, it can only be used with a
  * matching DrawTarget. Not adhering to this condition will make a draw call
  * fail.
  */
 class GradientStops : public RefCounted<GradientStops>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(GradientStops)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStops)
   virtual ~GradientStops() {}
 
   virtual BackendType GetBackendType() const = 0;
 
 protected:
   GradientStops() {}
 };
 
@@ -312,17 +312,17 @@ public:
 /*
  * This is the base class for source surfaces. These objects are surfaces
  * which may be used as a source in a SurfacePattern or a DrawSurface call.
  * They cannot be drawn to directly.
  */
 class SourceSurface : public RefCounted<SourceSurface>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(SourceSurface)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurface)
   virtual ~SourceSurface() {}
 
   virtual SurfaceType GetType() const = 0;
   virtual IntSize GetSize() const = 0;
   virtual SurfaceFormat GetFormat() const = 0;
 
   /* This returns false if some event has made this source surface invalid for
    * usage with current DrawTargets. For example in the case of Direct2D this
@@ -336,16 +336,17 @@ public:
    * DataSourceSurface's data can be accessed directly.
    */
   virtual TemporaryRef<DataSourceSurface> GetDataSurface() = 0;
 };
 
 class DataSourceSurface : public SourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurface)
   DataSourceSurface()
     : mIsMapped(false)
   {
   }
 
   struct MappedSurface {
     uint8_t *mData;
     int32_t mStride;
@@ -393,17 +394,17 @@ public:
 
   DebugOnly<bool> mIsMapped;
 };
 
 /* This is an abstract object that accepts path segments. */
 class PathSink : public RefCounted<PathSink>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(PathSink)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSink)
   virtual ~PathSink() {}
 
   /* Move the current point in the path, any figure currently being drawn will
    * be considered closed during fill operations, however when stroking the
    * closing line segment will not be drawn.
    */
   virtual void MoveTo(const Point &aPoint) = 0;
   /* Add a linesegment to the current figure */
@@ -432,17 +433,17 @@ class PathBuilder;
 class FlattenedPath;
 
 /* The path class is used to create (sets of) figures of any shape that can be
  * filled or stroked to a DrawTarget
  */
 class Path : public RefCounted<Path>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(Path)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(Path)
   virtual ~Path();
   
   virtual BackendType GetBackendType() const = 0;
 
   /* This returns a PathBuilder object that contains a copy of the contents of
    * this path and is still writable.
    */
   virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const = 0;
@@ -501,16 +502,17 @@ protected:
 };
 
 /* The PathBuilder class allows path creation. Once finish is called on the
  * pathbuilder it may no longer be written to.
  */
 class PathBuilder : public PathSink
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilder)
   /* Finish writing to the path and return a Path object that can be used for
    * drawing. Future use of the builder results in a crash!
    */
   virtual TemporaryRef<Path> Finish() = 0;
 };
 
 struct Glyph
 {
@@ -532,17 +534,17 @@ struct GlyphBuffer
 
 /* This class is an abstraction of a backend/platform specific font object
  * at a particular size. It is passed into text drawing calls to describe
  * the font used for the drawing call.
  */
 class ScaledFont : public RefCounted<ScaledFont>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(ScaledFont)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFont)
   virtual ~ScaledFont() {}
 
   typedef void (*FontFileDataOutput)(const uint8_t *aData, uint32_t aLength, uint32_t aIndex, Float aGlyphSize, void *aBaton);
 
   virtual FontType GetType() const = 0;
 
   /* This allows getting a path that describes the outline of a set of glyphs.
    * A target is passed in so that the guarantee is made the returned path
@@ -591,34 +593,34 @@ struct FontOptions
  * parameters to the glyph drawing functions. This is an empty wrapper class
  * merely used to allow holding on to and passing around platform specific
  * parameters. This is because different platforms have unique rendering
  * parameters.
  */
 class GlyphRenderingOptions : public RefCounted<GlyphRenderingOptions>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(GlyphRenderingOptions)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptions)
   virtual ~GlyphRenderingOptions() {}
 
   virtual FontType GetType() const = 0;
 
 protected:
   GlyphRenderingOptions() {}
 };
 
 /* This is the main class used for all the drawing. It is created through the
  * factory and accepts drawing commands. The results of drawing to a target
  * may be used either through a Snapshot or by flushing the target and directly
  * accessing the backing store a DrawTarget was created with.
  */
 class DrawTarget : public RefCounted<DrawTarget>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(DrawTarget)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTarget)
   DrawTarget() : mTransformDirty(false), mPermitSubpixelAA(false) {}
   virtual ~DrawTarget() {}
 
   virtual BackendType GetType() const = 0;
   /**
    * Returns a SourceSurface which is a snapshot of the current contents of the DrawTarget.
    * Multiple calls to Snapshot() without any drawing operations in between will
    * normally return the same SourceSurface object.
@@ -991,17 +993,17 @@ protected:
   bool mPermitSubpixelAA : 1;
 
   SurfaceFormat mFormat;
 };
 
 class DrawEventRecorder : public RefCounted<DrawEventRecorder>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(DrawEventRecorder)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorder)
   virtual ~DrawEventRecorder() { }
 };
 
 class GFX2D_API Factory
 {
 public:
   static bool HasSSE2();
 
--- a/gfx/2d/DataSourceSurfaceWrapper.h
+++ b/gfx/2d/DataSourceSurfaceWrapper.h
@@ -11,16 +11,17 @@
 namespace mozilla {
 namespace gfx {
 
 // Wraps a DataSourceSurface and forwards all methods except for GetType(),
 // from which it always returns SurfaceType::DATA.
 class DataSourceSurfaceWrapper : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceWrapper)
   DataSourceSurfaceWrapper(DataSourceSurface *aSurface)
    : mSurface(aSurface)
   {}
 
   virtual SurfaceType GetType() const MOZ_OVERRIDE { return SurfaceType::DATA; }
 
   virtual uint8_t *GetData() MOZ_OVERRIDE { return mSurface->GetData(); }
   virtual int32_t Stride() MOZ_OVERRIDE { return mSurface->Stride(); }
--- a/gfx/2d/DrawEventRecorder.h
+++ b/gfx/2d/DrawEventRecorder.h
@@ -20,16 +20,17 @@
 namespace mozilla {
 namespace gfx {
 
 class PathRecording;
 
 class DrawEventRecorderPrivate : public DrawEventRecorder
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPrivate)
   DrawEventRecorderPrivate(std::ostream *aStream);
   virtual ~DrawEventRecorderPrivate() { }
 
   void RecordEvent(const RecordedEvent &aEvent);
   void WritePath(const PathRecording *aPath);
 
   void AddStoredPath(const ReferencePtr aPath) {
     mStoredPaths.insert(aPath);
@@ -59,16 +60,17 @@ protected:
 
   ObjectSet mStoredPaths;
   ObjectSet mStoredScaledFonts;
 };
 
 class DrawEventRecorderFile : public DrawEventRecorderPrivate
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderFile)
   DrawEventRecorderFile(const char *aFilename);
   ~DrawEventRecorderFile();
 
 private:
   virtual void Flush();
 
   std::ofstream mOutputFile;
 };
--- a/gfx/2d/DrawTargetCG.cpp
+++ b/gfx/2d/DrawTargetCG.cpp
@@ -346,16 +346,17 @@ static CGColorRef ColorToCGColor(CGColor
 {
   CGFloat components[4] = {aColor.r, aColor.g, aColor.b, aColor.a};
   return CGColorCreate(aColorSpace, components);
 }
 
 class GradientStopsCG : public GradientStops
 {
   public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsCG)
   //XXX: The skia backend uses a vector and passes in aNumStops. It should do better
   GradientStopsCG(GradientStop* aStops, uint32_t aNumStops, ExtendMode aExtendMode)
   {
     mExtend = aExtendMode;
     if (aExtendMode == ExtendMode::CLAMP) {
       //XXX: do the stops need to be in any particular order?
       // what should we do about the color space here? we certainly shouldn't be
       // recreating it all the time
--- a/gfx/2d/DrawTargetCG.h
+++ b/gfx/2d/DrawTargetCG.h
@@ -90,16 +90,17 @@ SetStrokeOptions(CGContextRef cg, const 
     delete[] dashes;
   }
 }
 
 
 class DrawTargetCG : public DrawTarget
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCG)
   friend class BorrowedCGContext;
   DrawTargetCG();
   virtual ~DrawTargetCG();
 
   virtual BackendType GetType() const;
   virtual TemporaryRef<SourceSurface> Snapshot();
 
   virtual void DrawSurface(SourceSurface *aSurface,
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -15,16 +15,17 @@
 namespace mozilla {
 namespace gfx {
 
 class SourceSurfaceCairo;
 
 class GradientStopsCairo : public GradientStops
 {
   public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsCairo)
     GradientStopsCairo(GradientStop* aStops, uint32_t aNumStops,
                        ExtendMode aExtendMode)
      : mExtendMode(aExtendMode)
     {
       for (uint32_t i = 0; i < aNumStops; ++i) {
         mStops.push_back(aStops[i]);
       }
     }
@@ -46,16 +47,17 @@ class GradientStopsCairo : public Gradie
   private:
     std::vector<GradientStop> mStops;
     ExtendMode mExtendMode;
 };
 
 class DrawTargetCairo : public DrawTarget
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCairo)
   friend class BorrowedCairoContext;
 
   DrawTargetCairo();
   virtual ~DrawTargetCairo();
 
   virtual BackendType GetType() const { return BackendType::CAIRO; }
   virtual TemporaryRef<SourceSurface> Snapshot();
   virtual IntSize GetSize();
--- a/gfx/2d/DrawTargetD2D.h
+++ b/gfx/2d/DrawTargetD2D.h
@@ -38,16 +38,17 @@ struct PrivateD3D10DataD2D
   RefPtr<ID3D10InputLayout> mInputLayout;
   RefPtr<ID3D10Buffer> mVB;
   RefPtr<ID3D10BlendState> mBlendStates[size_t(CompositionOp::OP_COUNT)];
 };
 
 class DrawTargetD2D : public DrawTarget
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetD2D)
   DrawTargetD2D();
   virtual ~DrawTargetD2D();
 
   virtual BackendType GetType() const { return BackendType::DIRECT2D; }
   virtual TemporaryRef<SourceSurface> Snapshot();
   virtual IntSize GetSize() { return mSize; }
 
   virtual void Flush();
--- a/gfx/2d/DrawTargetD2D1.h
+++ b/gfx/2d/DrawTargetD2D1.h
@@ -30,16 +30,17 @@ class SourceSurfaceD2D1;
 class GradientStopsD2D;
 class ScaledFontDWrite;
 
 const int32_t kLayerCacheSize1 = 5;
 
 class DrawTargetD2D1 : public DrawTarget
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetD2D1)
   DrawTargetD2D1();
   virtual ~DrawTargetD2D1();
 
   virtual BackendType GetType() const { return BackendType::DIRECT2D1_1; }
   virtual TemporaryRef<SourceSurface> Snapshot();
   virtual IntSize GetSize() { return mSize; }
 
   virtual void Flush();
--- a/gfx/2d/DrawTargetDual.h
+++ b/gfx/2d/DrawTargetDual.h
@@ -30,16 +30,17 @@ namespace gfx {
  * source DrawTarget is used at the source for the second destination
  * DrawTarget (mB). This class facilitates black-background/white-background
  * drawing for per-component alpha extraction for backends which do not support
  * native component alpha.
  */
 class DrawTargetDual : public DrawTarget
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetDual)
   DrawTargetDual(DrawTarget *aA, DrawTarget *aB)
     : mA(aA)
     , mB(aB)
   { 
     mFormat = aA->GetFormat();
   }
      
   virtual BackendType GetType() const { return mA->GetType(); }
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -12,16 +12,17 @@
 #include "Filters.h"
 
 namespace mozilla {
 namespace gfx {
 
 class SourceSurfaceRecording : public SourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceRecording)
   SourceSurfaceRecording(SourceSurface *aFinalSurface, DrawEventRecorderPrivate *aRecorder)
     : mFinalSurface(aFinalSurface), mRecorder(aRecorder)
   {
   }
 
   ~SourceSurfaceRecording()
   {
     mRecorder->RecordEvent(RecordedSourceSurfaceDestruction(this));
@@ -34,16 +35,17 @@ public:
 
   RefPtr<SourceSurface> mFinalSurface;
   RefPtr<DrawEventRecorderPrivate> mRecorder;
 };
 
 class GradientStopsRecording : public GradientStops
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsRecording)
   GradientStopsRecording(GradientStops *aFinalGradientStops, DrawEventRecorderPrivate *aRecorder)
     : mFinalGradientStops(aFinalGradientStops), mRecorder(aRecorder)
   {
   }
 
   ~GradientStopsRecording()
   {
     mRecorder->RecordEvent(RecordedGradientStopsDestruction(this));
@@ -73,16 +75,17 @@ GetGradientStops(GradientStops *aStops)
   }
 
   return static_cast<GradientStopsRecording*>(aStops)->mFinalGradientStops;
 }
 
 class FilterNodeRecording : public FilterNode
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeRecording)
   using FilterNode::SetAttribute;
 
   FilterNodeRecording(FilterNode *aFinalFilterNode, DrawEventRecorderPrivate *aRecorder)
     : mFinalFilterNode(aFinalFilterNode), mRecorder(aRecorder)
   {
   }
 
   ~FilterNodeRecording()
--- a/gfx/2d/DrawTargetRecording.h
+++ b/gfx/2d/DrawTargetRecording.h
@@ -10,16 +10,17 @@
 #include "DrawEventRecorder.h"
 
 namespace mozilla {
 namespace gfx {
 
 class DrawTargetRecording : public DrawTarget
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetRecording)
   DrawTargetRecording(DrawEventRecorder *aRecorder, DrawTarget *aDT, bool aHasData = false);
   ~DrawTargetRecording();
 
   virtual BackendType GetType() const { return mFinalDT->GetType(); }
 
   virtual TemporaryRef<SourceSurface> Snapshot();
 
   virtual IntSize GetSize() { return mFinalDT->GetSize(); }
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -31,16 +31,17 @@
 #include <algorithm>
 
 namespace mozilla {
 namespace gfx {
 
 class GradientStopsSkia : public GradientStops
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsSkia)
   GradientStopsSkia(const std::vector<GradientStop>& aStops, uint32_t aNumStops, ExtendMode aExtendMode)
     : mCount(aNumStops)
     , mExtendMode(aExtendMode)
   {
     if (mCount == 0) {
       return;
     }
 
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -21,16 +21,17 @@
 namespace mozilla {
 namespace gfx {
 
 class SourceSurfaceSkia;
 
 class DrawTargetSkia : public DrawTarget
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetSkia)
   DrawTargetSkia();
   virtual ~DrawTargetSkia();
 
   virtual BackendType GetType() const { return BackendType::SKIA; }
   virtual TemporaryRef<SourceSurface> Snapshot();
   virtual IntSize GetSize() { return mSize; }
   virtual void Flush();
   virtual void DrawSurface(SourceSurface *aSurface,
--- a/gfx/2d/FilterNodeD2D1.h
+++ b/gfx/2d/FilterNodeD2D1.h
@@ -12,16 +12,17 @@
 #include <cguid.h>
 
 namespace mozilla {
 namespace gfx {
 
 class FilterNodeD2D1 : public FilterNode
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeD2D1)
   static TemporaryRef<FilterNode> Create(DrawTarget* aDT, ID2D1DeviceContext *aDC, FilterType aType);
 
   FilterNodeD2D1(DrawTarget* aDT, ID2D1Effect *aEffect, FilterType aType)
     : mDT(aDT)
     , mEffect(aEffect)
     , mType(aType)
   {
     InitUnmappedProperties();
@@ -60,16 +61,17 @@ protected:
   RefPtr<DrawTarget> mDT;
   RefPtr<ID2D1Effect> mEffect;
   FilterType mType;
 };
 
 class FilterNodeConvolveD2D1 : public FilterNodeD2D1
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeConvolveD2D1)
   FilterNodeConvolveD2D1(DrawTarget *aDT, ID2D1DeviceContext *aDC);
 
   virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface);
   virtual void SetInput(uint32_t aIndex, FilterNode *aFilter);
 
   virtual void SetAttribute(uint32_t aIndex, uint32_t aValue);
   virtual void SetAttribute(uint32_t aIndex, const IntSize &aValue);
   virtual void SetAttribute(uint32_t aIndex, const IntPoint &aValue);
@@ -90,16 +92,17 @@ private:
   IntPoint mTarget;
   IntSize mKernelSize;
   IntRect mSourceRect;
 };
 
 class FilterNodeComponentTransferD2D1 : public FilterNodeD2D1
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeComponentTransferD2D1)
   FilterNodeComponentTransferD2D1(DrawTarget *aDT, ID2D1DeviceContext *aDC, ID2D1Effect *aEffect, FilterType aType);
 
 protected:
   virtual ID2D1Effect* InputEffect() MOZ_OVERRIDE { return mPrePremultiplyEffect.get(); }
   virtual ID2D1Effect* OutputEffect() MOZ_OVERRIDE { return mPostUnpremultiplyEffect.get(); }
 
 private:
   RefPtr<ID2D1Effect> mPrePremultiplyEffect;
--- a/gfx/2d/FilterNodeSoftware.h
+++ b/gfx/2d/FilterNodeSoftware.h
@@ -33,16 +33,17 @@ public:
  * This is the base class for the software (i.e. pure CPU, non-accelerated)
  * FilterNode implementation. The software implementation is backend-agnostic,
  * so it can be used as a fallback for all DrawTarget implementations.
  */
 class FilterNodeSoftware : public FilterNode,
                            public FilterInvalidationListener
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeSoftware)
   virtual ~FilterNodeSoftware();
 
   // Factory method, intended to be called from DrawTarget*::CreateFilter.
   static TemporaryRef<FilterNode> Create(FilterType aType);
 
   // Draw the filter, intended to be called by DrawTarget*::DrawFilter.
   void Draw(DrawTarget* aDrawTarget, const Rect &aSourceRect,
             const Point &aDestPoint, const DrawOptions &aOptions);
@@ -212,16 +213,17 @@ protected:
   RefPtr<DataSourceSurface> mCachedOutput;
 };
 
 // Subclasses for specific filters.
 
 class FilterNodeTransformSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTransformSoftware)
   FilterNodeTransformSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Transform"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aGraphicsFilter) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Matrix &aMatrix) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
@@ -233,16 +235,17 @@ protected:
 private:
   Matrix mMatrix;
   Filter mFilter;
 };
 
 class FilterNodeBlendSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlendSoftware)
   FilterNodeBlendSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Blend"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aBlendMode) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -251,16 +254,17 @@ protected:
 
 private:
   BlendMode mBlendMode;
 };
 
 class FilterNodeMorphologySoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeMorphologySoftware)
   FilterNodeMorphologySoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Morphology"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntSize &aRadii) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
@@ -271,16 +275,17 @@ protected:
 private:
   IntSize mRadii;
   MorphologyOperator mOperator;
 };
 
 class FilterNodeColorMatrixSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeColorMatrixSoftware)
   virtual const char* GetName() MOZ_OVERRIDE { return "ColorMatrix"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Matrix5x4 &aMatrix) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aAlphaMode) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -290,32 +295,34 @@ protected:
 private:
   Matrix5x4 mMatrix;
   AlphaMode mAlphaMode;
 };
 
 class FilterNodeFloodSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeFloodSoftware)
   virtual const char* GetName() MOZ_OVERRIDE { return "Flood"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Color &aColor) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> GetOutput(const IntRect &aRect) MOZ_OVERRIDE;
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
 
 private:
   Color mColor;
 };
 
 class FilterNodeTileSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTileSoftware)
   virtual const char* GetName() MOZ_OVERRIDE { return "Tile"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aSourceRect) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
@@ -326,16 +333,17 @@ private:
 };
 
 /**
  * Baseclass for the four different component transfer filters.
  */
 class FilterNodeComponentTransferSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeComponentTransferSoftware)
   FilterNodeComponentTransferSoftware();
 
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, bool aDisable) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -349,16 +357,17 @@ protected:
   bool mDisableG;
   bool mDisableB;
   bool mDisableA;
 };
 
 class FilterNodeTableTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTableTransferSoftware)
   virtual const char* GetName() MOZ_OVERRIDE { return "TableTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
 private:
@@ -368,16 +377,17 @@ private:
   std::vector<Float> mTableG;
   std::vector<Float> mTableB;
   std::vector<Float> mTableA;
 };
 
 class FilterNodeDiscreteTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDiscreteTransferSoftware)
   virtual const char* GetName() MOZ_OVERRIDE { return "DiscreteTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
 private:
@@ -387,16 +397,17 @@ private:
   std::vector<Float> mTableG;
   std::vector<Float> mTableB;
   std::vector<Float> mTableA;
 };
 
 class FilterNodeLinearTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeLinearTransformSoftware)
   FilterNodeLinearTransferSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "LinearTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
@@ -411,16 +422,17 @@ private:
   Float mInterceptG;
   Float mInterceptB;
   Float mInterceptA;
 };
 
 class FilterNodeGammaTransferSoftware : public FilterNodeComponentTransferSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeGammaTransferSoftware)
   FilterNodeGammaTransferSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "GammaTransfer"; }
   using FilterNodeComponentTransferSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
 
 protected:
   virtual void FillLookupTable(ptrdiff_t aComponent, uint8_t aTable[256]) MOZ_OVERRIDE;
 
@@ -439,16 +451,17 @@ private:
   Float mOffsetG;
   Float mOffsetB;
   Float mOffsetA;
 };
 
 class FilterNodeConvolveMatrixSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeConvolveMatrixSoftware)
   FilterNodeConvolveMatrixSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "ConvolveMatrix"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const IntSize &aKernelSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Float* aMatrix, uint32_t aSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, Float aValue) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Size &aKernelUnitLength) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aSourceRect) MOZ_OVERRIDE;
@@ -480,16 +493,17 @@ private:
   ConvolveMatrixEdgeMode mEdgeMode;
   Size mKernelUnitLength;
   bool mPreserveAlpha;
 };
 
 class FilterNodeDisplacementMapSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDisplacementMapSoftware)
   FilterNodeDisplacementMapSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "DisplacementMap"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aScale) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
@@ -503,16 +517,17 @@ private:
   Float mScale;
   ColorChannel mChannelX;
   ColorChannel mChannelY;
 };
 
 class FilterNodeTurbulenceSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeTurbulenceSoftware)
   FilterNodeTurbulenceSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Turbulence"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Size &aSize) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const IntRect &aRenderRect) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, bool aStitchable) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aValue) MOZ_OVERRIDE;
 
@@ -528,16 +543,17 @@ private:
   uint32_t mSeed;
   bool mStitchable;
   TurbulenceType mType;
 };
 
 class FilterNodeArithmeticCombineSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeArithmeticCombineSoftware)
   FilterNodeArithmeticCombineSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "ArithmeticCombine"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Float* aFloat, uint32_t aSize) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -549,16 +565,17 @@ private:
   Float mK2;
   Float mK3;
   Float mK4;
 };
 
 class FilterNodeCompositeSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCompositeSoftware)
   FilterNodeCompositeSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Composite"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aOperator) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
@@ -568,45 +585,49 @@ protected:
 private:
   CompositeOperator mOperator;
 };
 
 // Base class for FilterNodeGaussianBlurSoftware and
 // FilterNodeDirectionalBlurSoftware.
 class FilterNodeBlurXYSoftware : public FilterNodeSoftware
 {
+public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeBlurXYSoftware)
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   IntRect InflatedSourceOrDestRect(const IntRect &aDestRect);
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 
   // Implemented by subclasses.
   virtual Size StdDeviationXY() = 0;
 };
 
 class FilterNodeGaussianBlurSoftware : public FilterNodeBlurXYSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeGaussianBlurSoftware)
   FilterNodeGaussianBlurSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "GaussianBlur"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aStdDeviation) MOZ_OVERRIDE;
 
 protected:
   virtual Size StdDeviationXY() MOZ_OVERRIDE;
 
 private:
   Float mStdDeviation;
 };
 
 class FilterNodeDirectionalBlurSoftware : public FilterNodeBlurXYSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeDirectionalBlurSoftware)
   FilterNodeDirectionalBlurSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "DirectionalBlur"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float aStdDeviation) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, uint32_t aBlurDirection) MOZ_OVERRIDE;
 
 protected:
   virtual Size StdDeviationXY() MOZ_OVERRIDE;
@@ -614,16 +635,17 @@ protected:
 private:
   Float mStdDeviation;
   BlurDirection mBlurDirection;
 };
 
 class FilterNodeCropSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeCropSoftware)
   virtual const char* GetName() MOZ_OVERRIDE { return "Crop"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, const Rect &aSourceRect) MOZ_OVERRIDE;
 
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
@@ -631,39 +653,42 @@ protected:
 
 private:
   IntRect mCropRect;
 };
 
 class FilterNodePremultiplySoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodePremultiplySoftware)
   virtual const char* GetName() MOZ_OVERRIDE { return "Premultiply"; }
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 };
 
 class FilterNodeUnpremultiplySoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeUnpremultiplySoftware)
   virtual const char* GetName() MOZ_OVERRIDE { return "Unpremultiply"; }
 protected:
   virtual TemporaryRef<DataSourceSurface> Render(const IntRect& aRect) MOZ_OVERRIDE;
   virtual IntRect GetOutputRectInRect(const IntRect& aRect) MOZ_OVERRIDE;
   virtual int32_t InputIndex(uint32_t aInputEnumIndex) MOZ_OVERRIDE;
   virtual void RequestFromInputsForRect(const IntRect &aRect) MOZ_OVERRIDE;
 };
 
 template<typename LightType, typename LightingType>
 class FilterNodeLightingSoftware : public FilterNodeSoftware
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeLightingSoftware)
   FilterNodeLightingSoftware();
   virtual const char* GetName() MOZ_OVERRIDE { return "Lighting"; }
   using FilterNodeSoftware::SetAttribute;
   virtual void SetAttribute(uint32_t aIndex, Float) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Size &) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Point3D &) MOZ_OVERRIDE;
   virtual void SetAttribute(uint32_t aIndex, const Color &) MOZ_OVERRIDE;
 
--- a/gfx/2d/Filters.h
+++ b/gfx/2d/Filters.h
@@ -461,17 +461,17 @@ enum PremultiplyInputs
 enum UnpremultiplyInputs
 {
   IN_UNPREMULTIPLY_IN = 0
 };
 
 class FilterNode : public RefCounted<FilterNode>
 {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(FilterMode)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNode)
   virtual ~FilterNode() {}
 
   virtual FilterBackend GetBackendType() = 0;
 
   virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) { MOZ_CRASH(); }
   virtual void SetInput(uint32_t aIndex, FilterNode *aFilter) { MOZ_CRASH(); }
 
   virtual void SetAttribute(uint32_t aIndex, bool) { MOZ_CRASH(); }
--- a/gfx/2d/GradientStopsD2D.h
+++ b/gfx/2d/GradientStopsD2D.h
@@ -11,16 +11,17 @@
 #include <d2d1.h>
 
 namespace mozilla {
 namespace gfx {
 
 class GradientStopsD2D : public GradientStops
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsD2D)
   GradientStopsD2D(ID2D1GradientStopCollection *aStopCollection)
     : mStopCollection(aStopCollection)
   {}
 
   virtual BackendType GetBackendType() const { return BackendType::DIRECT2D; }
 
 private:
   friend class DrawTargetD2D;
--- a/gfx/2d/MacIOSurface.h
+++ b/gfx/2d/MacIOSurface.h
@@ -57,30 +57,30 @@ enum CGContextType {
   CG_CONTEXT_TYPE_BITMAP = 4,
   CG_CONTEXT_TYPE_IOSURFACE = 8
 };
 
 CGContextType GetContextType(CGContextRef ref);
 
 class MacIOSurface : public mozilla::RefCounted<MacIOSurface> {
 public:
-  MOZ_DECLARE_REFCOUNTED_TYPENAME(MacIOSurface)
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(MacIOSurface)
   typedef mozilla::gfx::SourceSurface SourceSurface;
 
   static mozilla::TemporaryRef<MacIOSurface> CreateIOSurface(int aWidth, int aHeight,
                                                              double aContentsScaleFactor = 1.0,
                                                              bool aHasAlpha = true);
   static void ReleaseIOSurface(MacIOSurface *aIOSurface);
   static mozilla::TemporaryRef<MacIOSurface> LookupSurface(IOSurfaceID aSurfaceID,
                                                            double aContentsScaleFactor = 1.0,
                                                            bool aHasAlpha = true);
 
   MacIOSurface(const void *aIOSurfacePtr, double aContentsScaleFactor = 1.0, bool aHasAlpha = true)
     : mIOSurfacePtr(aIOSurfacePtr), mContentsScaleFactor(aContentsScaleFactor), mHasAlpha(aHasAlpha) {}
-  ~MacIOSurface();
+  virtual ~MacIOSurface();
   IOSurfaceID GetIOSurfaceID();
   void *GetBaseAddress();
   // GetWidth() and GetHeight() return values in "display pixels".  A
   // "display pixel" is the smallest fully addressable part of a display.
   // But in HiDPI modes each "display pixel" corresponds to more than one
   // device pixel.  Use GetDevicePixel**() to get device pixels.
   size_t GetWidth();
   size_t GetHeight();
@@ -107,16 +107,17 @@ private:
   friend class nsCARenderer;
   const void* mIOSurfacePtr;
   double mContentsScaleFactor;
   bool mHasAlpha;
 };
 
 class MacIOSurfaceLib: public MacIOSurface {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(MacIOSurfaceLib)
   static void                        *sIOSurfaceFramework;
   static void                        *sOpenGLFramework;
   static void                        *sCoreGraphicsFramework;
   static bool                         isLoaded;
   static IOSurfaceCreateFunc          sCreate;
   static IOSurfaceGetIDFunc           sGetID;
   static IOSurfaceLookupFunc          sLookup;
   static IOSurfaceGetBaseAddressFunc  sGetBaseAddress;
--- a/gfx/2d/PathAnalysis.h
+++ b/gfx/2d/PathAnalysis.h
@@ -18,16 +18,17 @@ struct FlatPathOp
 
   OpType mType;
   Point mPoint;
 };
 
 class FlattenedPath : public PathSink
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FlattenedPath)
   FlattenedPath() : mCachedLength(0)
                   , mCalculatedLength(false)
   {
   }
 
   virtual void MoveTo(const Point &aPoint);
   virtual void LineTo(const Point &aPoint);
   virtual void BezierTo(const Point &aCP1,
--- a/gfx/2d/PathCG.h
+++ b/gfx/2d/PathCG.h
@@ -12,16 +12,17 @@
 namespace mozilla {
 namespace gfx {
 
 class PathCG;
 
 class PathBuilderCG : public PathBuilder
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilderCG)
   // absorbs a reference of aPath
   PathBuilderCG(CGMutablePathRef aPath, FillRule aFillRule)
     : mFillRule(aFillRule)
   {
       mCGPath = aPath;
   }
 
   PathBuilderCG(FillRule aFillRule)
@@ -56,16 +57,17 @@ private:
   Point mCurrentPoint;
   Point mBeginPoint;
   FillRule mFillRule;
 };
 
 class PathCG : public Path
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathCG)
   PathCG(CGMutablePathRef aPath, FillRule aFillRule)
     : mPath(aPath)
     , mFillRule(aFillRule)
   {
     CGPathRetain(mPath);
   }
   virtual ~PathCG() { CGPathRelease(mPath); }
 
--- a/gfx/2d/PathCairo.h
+++ b/gfx/2d/PathCairo.h
@@ -14,16 +14,17 @@ namespace mozilla {
 namespace gfx {
 
 class DrawTargetCairo;
 class PathCairo;
 
 class PathBuilderCairo : public PathBuilder
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilderCairo)
   PathBuilderCairo(FillRule aFillRule);
 
   virtual void MoveTo(const Point &aPoint);
   virtual void LineTo(const Point &aPoint);
   virtual void BezierTo(const Point &aCP1,
                         const Point &aCP2,
                         const Point &aCP3);
   virtual void QuadraticBezierTo(const Point &aCP1,
@@ -43,16 +44,17 @@ private: // data
   // point is a little tricky.
   Point mCurrentPoint;
   Point mBeginPoint;
 };
 
 class PathCairo : public Path
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathCairo)
   PathCairo(FillRule aFillRule, std::vector<cairo_path_data_t> &aPathData, const Point &aCurrentPoint);
   PathCairo(cairo_t *aContext);
   ~PathCairo();
 
   virtual BackendType GetBackendType() const { return BackendType::CAIRO; }
 
   virtual TemporaryRef<PathBuilder> CopyToBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const;
   virtual TemporaryRef<PathBuilder> TransformedCopyToBuilder(const Matrix &aTransform,
--- a/gfx/2d/PathD2D.h
+++ b/gfx/2d/PathD2D.h
@@ -13,16 +13,17 @@
 namespace mozilla {
 namespace gfx {
 
 class PathD2D;
 
 class PathBuilderD2D : public PathBuilder
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilderD2D)
   PathBuilderD2D(ID2D1GeometrySink *aSink, ID2D1PathGeometry *aGeom, FillRule aFillRule)
     : mSink(aSink)
     , mGeometry(aGeom)
     , mFigureActive(false)
     , mFillRule(aFillRule)
   {
   }
   virtual ~PathBuilderD2D();
@@ -55,16 +56,17 @@ private:
   Point mCurrentPoint;
   Point mBeginPoint;
   FillRule mFillRule;
 };
 
 class PathD2D : public Path
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathD2D)
   PathD2D(ID2D1PathGeometry *aGeometry, bool aEndedActive,
           const Point &aEndPoint, FillRule aFillRule)
     : mGeometry(aGeometry)
     , mEndedActive(aEndedActive)
     , mEndPoint(aEndPoint)
     , mFillRule(aFillRule)
   {}
   
--- a/gfx/2d/PathRecording.h
+++ b/gfx/2d/PathRecording.h
@@ -32,16 +32,17 @@ struct PathOp
 const int32_t sPointCount[] = { 1, 1, 3, 2, 0, 0 };
 
 class PathRecording;
 class DrawEventRecorderPrivate;
 
 class PathBuilderRecording : public PathBuilder
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilderRecording)
   PathBuilderRecording(PathBuilder *aBuilder, FillRule aFillRule)
     : mPathBuilder(aBuilder), mFillRule(aFillRule)
   {
   }
 
   /* Move the current point in the path, any figure currently being drawn will
    * be considered closed during fill operations, however when stroking the
    * closing line segment will not be drawn.
@@ -77,16 +78,17 @@ private:
   RefPtr<PathBuilder> mPathBuilder;
   FillRule mFillRule;
   std::vector<PathOp> mPathOps;
 };
 
 class PathRecording : public Path
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathRecording)
   PathRecording(Path *aPath, const std::vector<PathOp> aOps, FillRule aFillRule)
     : mPath(aPath), mPathOps(aOps), mFillRule(aFillRule)
   {
   }
 
   ~PathRecording();
 
   virtual BackendType GetBackendType() const { return BackendType::RECORDING; }
--- a/gfx/2d/PathSkia.h
+++ b/gfx/2d/PathSkia.h
@@ -12,16 +12,17 @@
 namespace mozilla {
 namespace gfx {
 
 class PathSkia;
 
 class PathBuilderSkia : public PathBuilder
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilderSkia)
   PathBuilderSkia(const Matrix& aTransform, const SkPath& aPath, FillRule aFillRule);
   PathBuilderSkia(FillRule aFillRule);
 
   virtual void MoveTo(const Point &aPoint);
   virtual void LineTo(const Point &aPoint);
   virtual void BezierTo(const Point &aCP1,
                         const Point &aCP2,
                         const Point &aCP3);
@@ -41,16 +42,17 @@ private:
 
   SkPath mPath;
   FillRule mFillRule;
 };
 
 class PathSkia : public Path
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSkia)
   PathSkia(SkPath& aPath, FillRule aFillRule)
     : mFillRule(aFillRule)
   {
     mPath.swap(aPath);
   }
   
   virtual BackendType GetBackendType() const { return BackendType::SKIA; }
 
--- a/gfx/2d/ScaledFontBase.h
+++ b/gfx/2d/ScaledFontBase.h
@@ -24,16 +24,17 @@
 class gfxFont;
 
 namespace mozilla {
 namespace gfx {
 
 class ScaledFontBase : public ScaledFont
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontBase)
   ScaledFontBase(Float aSize);
   virtual ~ScaledFontBase();
 
   virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
 
   virtual void CopyGlyphsToBuilder(const GlyphBuffer &aBuffer, PathBuilder *aBuilder, BackendType aBackendType, const Matrix *aTransformHint);
 
   float GetSize() { return mSize; }
--- a/gfx/2d/ScaledFontCairo.h
+++ b/gfx/2d/ScaledFontCairo.h
@@ -11,32 +11,34 @@
 #include "cairo.h"
 
 namespace mozilla {
 namespace gfx {
 
 class ScaledFontCairo : public ScaledFontBase
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontCairo)
 
   ScaledFontCairo(cairo_scaled_font_t* aScaledFont, Float aSize);
 
 #if defined(USE_SKIA) && defined(MOZ_ENABLE_FREETYPE)
   virtual SkTypeface* GetSkTypeface();
 #endif
 };
 
 // We need to be able to tell Skia whether or not to use
 // hinting when rendering text, so that the glyphs it renders
 // are the same as what layout is expecting. At the moment, only
 // Skia uses this class when rendering with FreeType, as gfxFT2Font
 // is the only gfxFont that honours gfxPlatform::FontHintingEnabled().
 class GlyphRenderingOptionsCairo : public GlyphRenderingOptions
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsCairo)
   GlyphRenderingOptionsCairo()
     : mHinting(FontHinting::NORMAL)
     , mAutoHinting(false)
   {
   }
 
   void SetHinting(FontHinting aHinting) { mHinting = aHinting; }
   void SetAutoHinting(bool aAutoHinting) { mAutoHinting = aAutoHinting; }
--- a/gfx/2d/ScaledFontDWrite.h
+++ b/gfx/2d/ScaledFontDWrite.h
@@ -12,16 +12,17 @@
 struct ID2D1GeometrySink;
 
 namespace mozilla {
 namespace gfx {
 
 class ScaledFontDWrite MOZ_FINAL : public ScaledFontBase
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontDwrite)
   ScaledFontDWrite(IDWriteFontFace *aFont, Float aSize)
     : mFontFace(aFont)
     , ScaledFontBase(aSize)
   {}
   ScaledFontDWrite(uint8_t *aData, uint32_t aSize, uint32_t aIndex, Float aGlyphSize);
 
   virtual FontType GetType() const { return FontType::DWRITE; }
 
@@ -43,16 +44,17 @@ public:
 #endif
 
   RefPtr<IDWriteFontFace> mFontFace;
 };
 
 class GlyphRenderingOptionsDWrite : public GlyphRenderingOptions
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GlyphRenderingOptionsDWrite)
   GlyphRenderingOptionsDWrite(IDWriteRenderingParams *aParams)
     : mParams(aParams)
   {
   }
 
   virtual FontType GetType() const { return FontType::DWRITE; }
 
 private:
--- a/gfx/2d/ScaledFontMac.h
+++ b/gfx/2d/ScaledFontMac.h
@@ -12,16 +12,17 @@
 #include "ScaledFontBase.h"
 
 namespace mozilla {
 namespace gfx {
 
 class ScaledFontMac : public ScaledFontBase
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontMac)
   ScaledFontMac(CGFontRef aFont, Float aSize);
   virtual ~ScaledFontMac();
 
   virtual FontType GetType() const { return FontType::MAC; }
 #ifdef USE_SKIA
   virtual SkTypeface* GetSkTypeface();
 #endif
   virtual TemporaryRef<Path> GetPathForGlyphs(const GlyphBuffer &aBuffer, const DrawTarget *aTarget);
--- a/gfx/2d/ScaledFontWin.h
+++ b/gfx/2d/ScaledFontWin.h
@@ -10,16 +10,17 @@
 #include <windows.h>
 
 namespace mozilla {
 namespace gfx {
 
 class ScaledFontWin : public ScaledFontBase
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(ScaledFontWin)
   ScaledFontWin(LOGFONT* aFont, Float aSize);
 
   virtual FontType GetType() const { return FontType::GDI; }
 #ifdef USE_SKIA
   virtual SkTypeface* GetSkTypeface();
 #endif
 private:
 #ifdef USE_SKIA
--- a/gfx/2d/SourceSurfaceCG.h
+++ b/gfx/2d/SourceSurfaceCG.h
@@ -21,16 +21,17 @@ CreateCGImage(void *aInfo,
               int32_t aStride,
               SurfaceFormat aFormat);
 
 class DrawTargetCG;
 
 class SourceSurfaceCG : public SourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceCG)
   SourceSurfaceCG() {}
   SourceSurfaceCG(CGImageRef aImage) : mImage(aImage) {}
   ~SourceSurfaceCG();
 
   virtual SurfaceType GetType() const { return SurfaceType::COREGRAPHICS_IMAGE; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
   virtual TemporaryRef<DataSourceSurface> GetDataSurface();
@@ -49,16 +50,17 @@ private:
    * deduce the format to save space in SourceSurfaceCG,
    * for now we just store it in mFormat */
   SurfaceFormat mFormat;
 };
 
 class DataSourceSurfaceCG : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCG)
   DataSourceSurfaceCG() {}
   DataSourceSurfaceCG(CGImageRef aImage);
   ~DataSourceSurfaceCG();
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const { return mFormat; }
 
@@ -83,23 +85,25 @@ private:
   /* It might be better to just use the bitmap info from the CGImageRef to
    * deduce the format to save space in SourceSurfaceCG,
    * for now we just store it in mFormat */
 };
 
 class SourceSurfaceCGContext : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCGContext)
   virtual void DrawTargetWillChange() = 0;
   virtual CGImageRef GetImage() = 0;
 };
 
 class SourceSurfaceCGBitmapContext : public SourceSurfaceCGContext
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCGBitmapContext)
   SourceSurfaceCGBitmapContext(DrawTargetCG *);
   ~SourceSurfaceCGBitmapContext();
 
   virtual SurfaceType GetType() const { return SurfaceType::COREGRAPHICS_CGCONTEXT; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const { return mFormat; }
   virtual TemporaryRef<DataSourceSurface> GetDataSurface()
   {
@@ -145,16 +149,17 @@ private:
 
   int32_t mStride;
   IntSize mSize;
 };
 
 class SourceSurfaceCGIOSurfaceContext : public SourceSurfaceCGContext
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCGIOSurfaceContext)
   SourceSurfaceCGIOSurfaceContext(DrawTargetCG *);
   ~SourceSurfaceCGIOSurfaceContext();
 
   virtual SurfaceType GetType() const { return SurfaceType::COREGRAPHICS_CGCONTEXT; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const { return mFormat; }
 
   CGImageRef GetImage() { EnsureImage(); return mImage; }
--- a/gfx/2d/SourceSurfaceCairo.h
+++ b/gfx/2d/SourceSurfaceCairo.h
@@ -11,16 +11,17 @@
 namespace mozilla {
 namespace gfx {
 
 class DrawTargetCairo;
 
 class SourceSurfaceCairo : public SourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceCairo)
   // Create a SourceSurfaceCairo. The surface will not be copied, but simply
   // referenced.
   // If aDrawTarget is non-nullptr, it is assumed that this is a snapshot source
   // surface, and we'll call DrawTargetCairo::RemoveSnapshot(this) on it when
   // we're destroyed.
   SourceSurfaceCairo(cairo_surface_t* aSurface, const IntSize& aSize,
                      const SurfaceFormat& aFormat,
                      DrawTargetCairo* aDrawTarget = nullptr);
@@ -42,16 +43,17 @@ private: // data
   SurfaceFormat mFormat;
   cairo_surface_t* mSurface;
   DrawTargetCairo* mDrawTarget;
 };
 
 class DataSourceSurfaceCairo : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCairo)
   DataSourceSurfaceCairo(cairo_surface_t* imageSurf);
   virtual ~DataSourceSurfaceCairo();
   virtual unsigned char *GetData();
   virtual int32_t Stride();
 
   virtual SurfaceType GetType() const { return SurfaceType::CAIRO_IMAGE; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
--- a/gfx/2d/SourceSurfaceD2D.h
+++ b/gfx/2d/SourceSurfaceD2D.h
@@ -13,16 +13,17 @@
 namespace mozilla {
 namespace gfx {
 
 class DataSourceSurfaceD2D;
 
 class SourceSurfaceD2D : public SourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceD2D)
   SourceSurfaceD2D();
   ~SourceSurfaceD2D();
 
   virtual SurfaceType GetType() const { return SurfaceType::D2D1_BITMAP; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
   virtual bool IsValid() const;
 
@@ -50,16 +51,17 @@ private:
   SurfaceFormat mFormat;
   IntSize mSize;
 };
 
 
 class DataSourceSurfaceD2D : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceD2D)
   DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface);
   virtual ~DataSourceSurfaceD2D();
 
   virtual unsigned char* GetData();
   virtual int32_t Stride();
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
   virtual bool Map(MapType, MappedSurface *aMappedSurface);
--- a/gfx/2d/SourceSurfaceD2D1.h
+++ b/gfx/2d/SourceSurfaceD2D1.h
@@ -15,16 +15,17 @@
 namespace mozilla {
 namespace gfx {
 
 class DrawTargetD2D1;
 
 class SourceSurfaceD2D1 : public SourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceD2D1)
   SourceSurfaceD2D1(ID2D1Image* aImage, ID2D1DeviceContext *aDC,
                     SurfaceFormat aFormat, const IntSize &aSize,
                     DrawTargetD2D1 *aDT = nullptr);
   ~SourceSurfaceD2D1();
 
   virtual SurfaceType GetType() const { return SurfaceType::D2D1_1_IMAGE; }
   virtual IntSize GetSize() const { return mSize; }
   virtual SurfaceFormat GetFormat() const { return mFormat; }
@@ -57,16 +58,17 @@ private:
   SurfaceFormat mFormat;
   IntSize mSize;
   RefPtr<DrawTargetD2D1> mDrawTarget;
 };
 
 class DataSourceSurfaceD2D1 : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceD2D1)
   DataSourceSurfaceD2D1(ID2D1Bitmap1 *aMappableBitmap, SurfaceFormat aFormat);
   ~DataSourceSurfaceD2D1();
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const { return mFormat; }
   virtual uint8_t *GetData();
   virtual int32_t Stride();
--- a/gfx/2d/SourceSurfaceD2DTarget.h
+++ b/gfx/2d/SourceSurfaceD2DTarget.h
@@ -14,16 +14,17 @@
 namespace mozilla {
 namespace gfx {
 
 class DrawTargetD2D;
 
 class SourceSurfaceD2DTarget : public SourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceD2DTarget)
   SourceSurfaceD2DTarget(DrawTargetD2D* aDrawTarget, ID3D10Texture2D* aTexture,
                          SurfaceFormat aFormat);
   ~SourceSurfaceD2DTarget();
 
   virtual SurfaceType GetType() const { return SurfaceType::D2D1_DRAWTARGET; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
   virtual TemporaryRef<DataSourceSurface> GetDataSurface();
@@ -55,16 +56,17 @@ private:
   mutable RefPtr<ID3D10Texture2D> mTexture;
   SurfaceFormat mFormat;
   bool mOwnsCopy;
 };
 
 class DataSourceSurfaceD2DTarget : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceD2DTarget)
   DataSourceSurfaceD2DTarget(SurfaceFormat aFormat);
   ~DataSourceSurfaceD2DTarget();
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
   virtual uint8_t *GetData();
   virtual int32_t Stride();
--- a/gfx/2d/SourceSurfaceDual.h
+++ b/gfx/2d/SourceSurfaceDual.h
@@ -12,16 +12,17 @@ namespace mozilla {
 namespace gfx {
 
 class DualSurface;
 class DualPattern;
 
 class SourceSurfaceDual : public SourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceDual)
   SourceSurfaceDual(DrawTarget *aDTA, DrawTarget *aDTB)
     : mA(aDTA->Snapshot())
     , mB(aDTB->Snapshot())
   { }
 
   virtual SurfaceType GetType() const { return SurfaceType::DUAL_DT; }
   virtual IntSize GetSize() const { return mA->GetSize(); }
   virtual SurfaceFormat GetFormat() const { return mA->GetFormat(); }
--- a/gfx/2d/SourceSurfaceRawData.h
+++ b/gfx/2d/SourceSurfaceRawData.h
@@ -10,16 +10,17 @@
 #include "Tools.h"
 
 namespace mozilla {
 namespace gfx {
 
 class SourceSurfaceRawData : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceRawData)
   SourceSurfaceRawData() {}
   ~SourceSurfaceRawData() { if(mOwnData) delete [] mRawData; }
 
   virtual uint8_t *GetData() { return mRawData; }
   virtual int32_t Stride() { return mStride; }
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const { return mSize; }
@@ -37,16 +38,17 @@ private:
   SurfaceFormat mFormat;
   IntSize mSize;
   bool mOwnData;
 };
 
 class SourceSurfaceAlignedRawData : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceAlignedRawData)
   SourceSurfaceAlignedRawData() {}
 
   virtual uint8_t *GetData() { return mArray; }
   virtual int32_t Stride() { return mStride; }
 
   virtual SurfaceType GetType() const { return SurfaceType::DATA; }
   virtual IntSize GetSize() const { return mSize; }
   virtual SurfaceFormat GetFormat() const { return mFormat; }
--- a/gfx/2d/SourceSurfaceSkia.h
+++ b/gfx/2d/SourceSurfaceSkia.h
@@ -14,16 +14,17 @@
 namespace mozilla {
 namespace gfx {
 
 class DrawTargetSkia;
 
 class SourceSurfaceSkia : public DataSourceSurface
 {
 public:
+  MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceSkia)
   SourceSurfaceSkia();
   ~SourceSurfaceSkia();
 
   virtual SurfaceType GetType() const { return SurfaceType::SKIA; }
   virtual IntSize GetSize() const;
   virtual SurfaceFormat GetFormat() const;
 
   SkBitmap& GetBitmap() { return mBitmap; }
--- a/gfx/layers/basic/TextureClientX11.cpp
+++ b/gfx/layers/basic/TextureClientX11.cpp
@@ -36,18 +36,18 @@ TextureClientX11::IsAllocated() const
   return !!mSurface;
 }
 
 bool
 TextureClientX11::Lock(OpenMode aMode)
 {
   // XXX - Turn this into a fatal assertion as soon as Bug 952507 is fixed
   NS_WARN_IF_FALSE(!mLocked, "The TextureClient is already Locked!");
-  mLocked = true;
-  return IsValid() && IsAllocated();
+  mLocked = IsValid() && IsAllocated();
+  return mLocked;
 }
 
 void
 TextureClientX11::Unlock()
 {
   // XXX - Turn this into a fatal assertion as soon as Bug 952507 is fixed
   NS_WARN_IF_FALSE(mLocked, "The TextureClient is already Unlocked!");
   mLocked = false;
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -50,37 +50,47 @@ HasOpaqueAncestorLayer(Layer* aLayer)
 /**
  * Returns a rectangle of content painted opaquely by aLayer. Very consertative;
  * bails by returning an empty rect in any tricky situations.
  */
 static nsIntRect
 GetOpaqueRect(Layer* aLayer)
 {
   nsIntRect result;
+  gfx::Matrix matrix;
+  bool is2D = aLayer->GetBaseTransform().Is2D(&matrix);
+
   // Just bail if there's anything difficult to handle.
-  if (!aLayer->GetEffectiveTransform().IsIdentity() ||
-      aLayer->GetEffectiveOpacity() != 1.0f ||
-      aLayer->GetMaskLayer()) {
+  if (!is2D || aLayer->GetMaskLayer() ||
+    aLayer->GetEffectiveOpacity() != 1.0f ||
+    matrix.HasNonIntegerTranslation()) {
     return result;
   }
+
   if (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) {
     result = aLayer->GetEffectiveVisibleRegion().GetLargestRectangle();
   } else {
     // Drill down into RefLayers because that's what we particularly care about;
     // layer construction for aLayer will not have known about the opaqueness
     // of any RefLayer subtrees.
     RefLayer* refLayer = aLayer->AsRefLayer();
     if (refLayer && refLayer->GetFirstChild()) {
       result = GetOpaqueRect(refLayer->GetFirstChild());
     }
   }
+
+  // Translate our opaque region to cover the child
+  gfx::Point point = matrix.GetTranslation();
+  result.MoveBy(static_cast<int>(point.x), static_cast<int>(point.y));
+
   const nsIntRect* clipRect = aLayer->GetEffectiveClipRect();
   if (clipRect) {
     result.IntersectRect(result, *clipRect);
   }
+
   return result;
 }
 
 struct LayerVelocityUserData : public LayerUserData {
 public:
   LayerVelocityUserData() {
     MOZ_COUNT_CTOR(LayerVelocityUserData);
   }
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -1973,17 +1973,17 @@ void AsyncPanZoomController::SetContentR
 void AsyncPanZoomController::TimeoutContentResponse() {
   mContentResponseTimeoutTask = nullptr;
   ContentReceivedTouch(false);
 }
 
 void AsyncPanZoomController::UpdateZoomConstraints(const ZoomConstraints& aConstraints) {
   APZC_LOG("%p updating zoom constraints to %d %f %f\n", this, aConstraints.mAllowZoom,
     aConstraints.mMinZoom.scale, aConstraints.mMaxZoom.scale);
-  if (IsFloatNaN(aConstraints.mMinZoom.scale) || IsFloatNaN(aConstraints.mMinZoom.scale)) {
+  if (IsFloatNaN(aConstraints.mMinZoom.scale) || IsFloatNaN(aConstraints.mMaxZoom.scale)) {
     NS_WARNING("APZC received zoom constraints with NaN values; dropping...\n");
     return;
   }
   // inf float values and other bad cases should be sanitized by the code below.
   mZoomConstraints.mAllowZoom = aConstraints.mAllowZoom;
   mZoomConstraints.mMinZoom = (MIN_ZOOM > aConstraints.mMinZoom ? MIN_ZOOM : aConstraints.mMinZoom);
   mZoomConstraints.mMaxZoom = (MAX_ZOOM > aConstraints.mMaxZoom ? aConstraints.mMaxZoom : MAX_ZOOM);
   if (mZoomConstraints.mMaxZoom < mZoomConstraints.mMinZoom) {
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -92,22 +92,22 @@ ShadowChild(const OpInsertAfter& op)
 }
 static ShadowLayerParent*
 ShadowAfter(const OpInsertAfter& op)
 {
   return cast(op.afterParent());
 }
 
 static ShadowLayerParent*
-ShadowContainer(const OpAppendChild& op)
+ShadowContainer(const OpPrependChild& op)
 {
   return cast(op.containerParent());
 }
 static ShadowLayerParent*
-ShadowChild(const OpAppendChild& op)
+ShadowChild(const OpPrependChild& op)
 {
   return cast(op.childLayerParent());
 }
 
 static ShadowLayerParent*
 ShadowContainer(const OpRemoveChild& op)
 {
   return cast(op.containerParent());
@@ -411,20 +411,20 @@ LayerTransactionParent::RecvUpdate(const
       ContainerLayerComposite* container = ShadowContainer(oia)->AsContainerLayerComposite();
       if (!container ||
           !container->InsertAfter(child, ShadowAfter(oia)->AsLayer()))
       {
         return false;
       }
       break;
     }
-    case Edit::TOpAppendChild: {
-      MOZ_LAYERS_LOG(("[ParentSide] AppendChild"));
+    case Edit::TOpPrependChild: {
+      MOZ_LAYERS_LOG(("[ParentSide] PrependChild"));
 
-      const OpAppendChild& oac = edit.get_OpAppendChild();
+      const OpPrependChild& oac = edit.get_OpPrependChild();
       Layer* child = ShadowChild(oac)->AsLayer();
       if (!child) {
         return false;
       }
       ContainerLayerComposite* container = ShadowContainer(oac)->AsContainerLayerComposite();
       if (!container ||
           !container->InsertAfter(child, nullptr))
       {
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -242,17 +242,17 @@ struct LayerAttributes {
 struct OpSetLayerAttributes {
   PLayer layer;
   LayerAttributes attrs;
 };
 
 // Monkey with the tree structure
 struct OpSetRoot          { PLayer root; };
 struct OpInsertAfter      { PLayer container; PLayer childLayer; PLayer after; };
-struct OpAppendChild      { PLayer container; PLayer childLayer; };
+struct OpPrependChild     { PLayer container; PLayer childLayer; };
 struct OpRemoveChild      { PLayer container; PLayer childLayer; };
 struct OpRepositionChild  { PLayer container; PLayer childLayer; PLayer after; };
 struct OpRaiseToTopChild  { PLayer container; PLayer childLayer; };
 
 struct OpSetDiagnosticTypes { DiagnosticTypes diagnostics; };
 
 // Paint (buffer update)
 struct OpPaintTiledLayerBuffer {
@@ -366,17 +366,17 @@ union Edit {
   OpCreateCanvasLayer;
   OpCreateRefLayer;
 
   OpSetLayerAttributes;
   OpSetDiagnosticTypes;
 
   OpSetRoot;
   OpInsertAfter;
-  OpAppendChild;
+  OpPrependChild;
   OpRemoveChild;
   OpRepositionChild;
   OpRaiseToTopChild;
 
   OpAttachCompositable;
   OpAttachAsyncCompositable;
 
   CompositableOperation;
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -271,18 +271,18 @@ ShadowLayerForwarder::InsertAfter(Shadow
                                   ShadowableLayer* aChild,
                                   ShadowableLayer* aAfter)
 {
   if (aAfter)
     mTxn->AddEdit(OpInsertAfter(nullptr, Shadow(aContainer),
                                 nullptr, Shadow(aChild),
                                 nullptr, Shadow(aAfter)));
   else
-    mTxn->AddEdit(OpAppendChild(nullptr, Shadow(aContainer),
-                                nullptr, Shadow(aChild)));
+    mTxn->AddEdit(OpPrependChild(nullptr, Shadow(aContainer),
+                                 nullptr, Shadow(aChild)));
 }
 void
 ShadowLayerForwarder::RemoveChild(ShadowableLayer* aContainer,
                                   ShadowableLayer* aChild)
 {
   MOZ_LAYERS_LOG(("[LayersForwarder] OpRemoveChild container=%p child=%p\n",
                   aContainer->AsLayer(), aChild->AsLayer()));
 
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -819,18 +819,25 @@ CompositorOGL::GetShaderConfigFor(Effect
   switch(aEffect->mType) {
   case EFFECT_SOLID_COLOR:
     config.SetRenderColor(true);
     break;
   case EFFECT_YCBCR:
     config.SetYCbCr(true);
     break;
   case EFFECT_COMPONENT_ALPHA:
+  {
     config.SetComponentAlpha(true);
+    EffectComponentAlpha* effectComponentAlpha =
+      static_cast<EffectComponentAlpha*>(aEffect);
+    gfx::SurfaceFormat format = effectComponentAlpha->mOnWhite->GetFormat();
+    config.SetRBSwap(format == gfx::SurfaceFormat::B8G8R8A8 ||
+                     format == gfx::SurfaceFormat::B8G8R8X8);
     break;
+  }
   case EFFECT_RENDER_TARGET:
     config.SetTextureTarget(mFBOTextureTarget);
     break;
   default:
   {
     MOZ_ASSERT(aEffect->mType == EFFECT_RGB);
     TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffect);
--- a/gfx/skia/moz.build
+++ b/gfx/skia/moz.build
@@ -739,17 +739,16 @@ if CONFIG['MOZ_WIDGET_QT']:
         'trunk/src/ports/SkDebug_stdio.cpp',
         'trunk/src/ports/SkFontHost_cairo.cpp',
         'trunk/src/ports/SkFontHost_FreeType.cpp',
         'trunk/src/ports/SkFontHost_FreeType_common.cpp',
         'trunk/src/ports/SkOSFile_posix.cpp',
         'trunk/src/ports/SkTime_Unix.cpp',
         'trunk/src/ports/SkTLS_pthread.cpp',
         'trunk/src/utils/SkThreadUtils_pthread.cpp',
-        'trunk/src/utils/SkThreadUtils_pthread_linux.cpp',
     ]
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     SOURCES += [
         'trunk/src/ports/SkDebug_win.cpp',
         'trunk/src/ports/SkFontHost_win.cpp',
         'trunk/src/ports/SkFontMgr_default_gdi.cpp',
         'trunk/src/ports/SkOSFile_win.cpp',
         'trunk/src/ports/SkTime_win.cpp',
--- a/ipc/app/Makefile.in
+++ b/ipc/app/Makefile.in
@@ -31,22 +31,16 @@ endif
 endif
 
 # This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that
 # shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall.
 NSDISTMODE = copy
 
 include $(topsrcdir)/config/config.mk
 
-ifdef _MSC_VER
-# Always enter a Windows program through wmain, whether or not we're
-# a console application.
-WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
-endif
-
 include $(topsrcdir)/config/rules.mk
 
 LDFLAGS += $(MOZ_ALLOW_HEAP_EXECUTE_FLAGS)
 
 ifeq ($(OS_ARCH),WINNT) #{
 
 ifdef MOZ_CONTENT_SANDBOX
 LIBS += ../../security/sandbox/$(LIB_PREFIX)sandbox_s.$(LIB_SUFFIX)
--- a/ipc/app/moz.build
+++ b/ipc/app/moz.build
@@ -24,8 +24,13 @@ LOCAL_INCLUDES += [
 
 if CONFIG['MOZ_CONTENT_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
     # For sandbox includes and the include dependencies those have
     LOCAL_INCLUDES += [
         '/security',
         '/security/sandbox',
         '/security/sandbox/chromium',
     ]
+
+if CONFIG['_MSC_VER']:
+    # Always enter a Windows program through wmain, whether or not we're
+    # a console application.
+    WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
--- a/ipc/ipdl/test/cxx/app/Makefile.in
+++ b/ipc/ipdl/test/cxx/app/Makefile.in
@@ -7,13 +7,9 @@ NSDISTMODE = copy
 LIBS = \
   $(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
   $(LIBXUL_LIBS) \
   $(NSPR_LIBS) \
   $(NULL)
 
 include $(topsrcdir)/config/config.mk
 
-ifdef _MSC_VER
-WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
-endif
-
 include $(topsrcdir)/config/rules.mk
--- a/ipc/ipdl/test/cxx/app/moz.build
+++ b/ipc/ipdl/test/cxx/app/moz.build
@@ -11,8 +11,10 @@ SOURCES += [
 ]
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/toolkit/xre',
     '/xpcom/base',
 ]
 
+if CONFIG['_MSC_VER']:
+    WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
--- a/js/public/ProfilingStack.h
+++ b/js/public/ProfilingStack.h
@@ -73,16 +73,20 @@ class ProfileEntry
     static size_t offsetOfStackAddress() { return offsetof(ProfileEntry, sp); }
     static size_t offsetOfPCIdx() { return offsetof(ProfileEntry, idx); }
     static size_t offsetOfScript() { return offsetof(ProfileEntry, script_); }
 
     // The index used in the entry can either be a line number or the offset of
     // a pc into a script's code. To signify a nullptr pc, use a -1 index. This
     // is checked against in pc() and setPC() to set/get the right pc.
     static const int32_t NullPCIndex = -1;
+
+    // This bit is added to the stack address to indicate that copying the
+    // frame label is not necessary when taking a sample of the pseudostack.
+    static const uintptr_t NoCopyBit = 1;
 };
 
 JS_FRIEND_API(void)
 SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size,
                          uint32_t max);
 
 JS_FRIEND_API(void)
 EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled);
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -1043,17 +1043,17 @@ static JSObject *
 InitClass(JSContext *cx, Handle<GlobalObject*> global, const Class *clasp, JSProtoKey key, Native construct,
           const JSPropertySpec *properties, const JSFunctionSpec *methods)
 {
     Rooted<JSObject*> proto(cx, global->createBlankPrototype(cx, clasp));
     if (!proto)
         return nullptr;
     proto->setPrivate(nullptr);
 
-    Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 1));
+    Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 0));
     if (!ctor ||
         !LinkConstructorAndPrototype(cx, ctor, proto) ||
         !DefinePropertiesAndBrand(cx, proto, properties, methods) ||
         !DefineConstructorAndPrototype(cx, global, key, ctor, proto))
     {
         return nullptr;
     }
     return proto;
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -631,20 +631,19 @@ bool
 js::regexp_exec(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod(cx, IsRegExp, regexp_exec_impl, args);
 }
 
 /* Separate interface for use by IonMonkey. */
 bool
-js::regexp_exec_raw(JSContext *cx, HandleObject regexp, HandleString input, Value *vp)
+js::regexp_exec_raw(JSContext *cx, HandleObject regexp, HandleString input, MutableHandleValue output)
 {
-    MutableHandleValue vpHandle = MutableHandleValue::fromMarkedLocation(vp);
-    return regexp_exec_impl(cx, regexp, input, UpdateRegExpStatics, vpHandle);
+    return regexp_exec_impl(cx, regexp, input, UpdateRegExpStatics, output);
 }
 
 bool
 js::regexp_exec_no_statics(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     JS_ASSERT(args.length() == 2);
     JS_ASSERT(IsRegExp(args[0]));
--- a/js/src/builtin/RegExp.h
+++ b/js/src/builtin/RegExp.h
@@ -40,17 +40,17 @@ ExecuteRegExpLegacy(JSContext *cx, RegEx
                     size_t *lastIndex, bool test, MutableHandleValue rval);
 
 /* Translation from MatchPairs to a JS array in regexp_exec()'s output format. */
 bool
 CreateRegExpMatchResult(JSContext *cx, HandleString input, const MatchPairs &matches,
                         MutableHandleValue rval);
 
 extern bool
-regexp_exec_raw(JSContext *cx, HandleObject regexp, HandleString input, Value *vp);
+regexp_exec_raw(JSContext *cx, HandleObject regexp, HandleString input, MutableHandleValue output);
 
 extern bool
 regexp_exec(JSContext *cx, unsigned argc, Value *vp);
 
 bool
 regexp_test_raw(JSContext *cx, HandleObject regexp, HandleString input, bool *result);
 
 extern bool
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -2422,16 +2422,21 @@ TypedObject::constructUnsized(JSContext 
             return false;
         args.rval().setObject(*obj);
         return true;
     }
 
     // Length constructor.
     if (args[0].isInt32()) {
         int32_t length = args[0].toInt32();
+        if (length < 0) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage,
+                                 nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
+            return nullptr;
+        }
         Rooted<TypedObject*> obj(cx, createZeroed(cx, callee, length));
         if (!obj)
             return false;
         args.rval().setObject(*obj);
         return true;
     }
 
     // Buffer constructor.
--- a/js/src/jit-test/jit_test.py
+++ b/js/src/jit-test/jit_test.py
@@ -1,14 +1,14 @@
 #!/usr/bin/env python
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-import os, posixpath, shlex, shutil, subprocess, sys, traceback
+import math, os, posixpath, shlex, shutil, subprocess, sys, traceback
 
 def add_libdir_to_path():
     from os.path import dirname, exists, join, realpath
     js_src_dir = dirname(dirname(realpath(sys.argv[0])))
     assert exists(join(js_src_dir,'jsapi.h'))
     sys.path.insert(0, join(js_src_dir, 'lib'))
     sys.path.insert(0, join(js_src_dir, 'tests', 'lib'))
 
@@ -92,16 +92,20 @@ def main(argv):
     op.add_option('--remoteTestRoot', dest='remote_test_root', action='store',
                   type='string', default='/data/local/tests',
                   help='The remote directory to use as test root (eg. /data/local/tests)')
     op.add_option('--localLib', dest='local_lib', action='store',
                   type='string',
                   help='The location of libraries to push -- preferably stripped')
     op.add_option('--repeat', type=int, default=1,
                   help='Repeat tests the given number of times.')
+    op.add_option('--this-chunk', type=int, default=1,
+                  help='The test chunk to run.')
+    op.add_option('--total-chunks', type=int, default=1,
+                  help='The total number of test chunks.')
 
     options, args = op.parse_args(argv)
     if len(args) < 1:
         op.error('missing JS_SHELL argument')
     # We need to make sure we are using backslashes on Windows.
     test_args = args[1:]
 
     if jittests.stdio_might_be_broken():
@@ -155,16 +159,25 @@ def main(argv):
         print >> sys.stderr, "No tests found matching command line arguments."
         sys.exit(0)
 
     test_list = [jittests.Test.from_file(_, options) for _ in test_list]
 
     if not options.run_slow:
         test_list = [ _ for _ in test_list if not _.slow ]
 
+    # If chunking is enabled, determine which tests are part of this chunk.
+    # This code was adapted from testing/mochitest/runtestsremote.py.
+    if options.total_chunks > 1:
+        total_tests = len(test_list)
+        tests_per_chunk = math.ceil(total_tests / float(options.total_chunks))
+        start = int(round((options.this_chunk - 1) * tests_per_chunk))
+        end = int(round(options.this_chunk * tests_per_chunk))
+        test_list = test_list[start:end]
+
     # The full test list is ready. Now create copies for each JIT configuration.
     job_list = []
     if options.tbpl:
         # Running all bits would take forever. Instead, we test a few interesting combinations.
         for test in test_list:
             for variant in TBPL_FLAGS:
                 new_test = test.copy()
                 new_test.jitflags.extend(variant)
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/bug959119.js
@@ -0,0 +1,21 @@
+// This test exposed a bug in float32 optimization.
+// The (inlined and optimized) code for `add()` created
+// MDiv instructions specialized to integers, which was
+// then "respecialized" to float32, leading to internal
+// assertion errors.
+//
+// Public domain.
+
+if (!this.hasOwnProperty("TypedObject"))
+  quit();
+
+var {StructType,uint8,float32} = TypedObject;
+var RgbColor2 = new StructType({r: uint8, g: float32, b: uint8});
+RgbColor2.prototype.add = function(c) {
+  this.g += c;
+  this.b += c;
+};
+var gray = new RgbColor2({r: 129, g: 128, b: 127});
+gray.add(1);
+gray.add(2);
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/bug970285.js
@@ -0,0 +1,11 @@
+// |jit-test| error:TypeError
+
+if (!this.hasOwnProperty("TypedObject"))
+  throw new TypeError();
+
+// Test that we detect invalid lengths supplied to unsized array
+// constructor. Public domain.
+
+var AA = TypedObject.uint8.array(2147483647).array();
+var aa = new AA(-1);
+
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/testBug975182.js
@@ -0,0 +1,18 @@
+Function("\
+    g = (function(t,foreign){\
+        \"use asm\";\
+        var ff = foreign.ff;\
+        function f() {\
+            +ff()\
+        }\
+        return f\
+    })(this, {\
+        ff: arguments.callee\
+    }, ArrayBuffer(4096))\
+")()
+function m(f) {
+    for (var j = 0; j < 6000; ++j) {
+        f();
+    }
+}
+m(g);
--- a/js/src/jit-test/tests/collections/Map-surfaces-1.js
+++ b/js/src/jit-test/tests/collections/Map-surfaces-1.js
@@ -4,17 +4,17 @@ load(libdir + "iteration.js");
 
 var desc = Object.getOwnPropertyDescriptor(this, "Map");
 assertEq(desc.enumerable, false);
 assertEq(desc.configurable, true);
 assertEq(desc.writable, true);
 
 assertEq(typeof Map, 'function');
 assertEq(Object.keys(Map).length, 0);
-assertEq(Map.length, 1);
+assertEq(Map.length, 0);
 assertEq(Map.name, "Map");
 
 assertEq(Object.getPrototypeOf(Map.prototype), Object.prototype);
 assertEq(Object.prototype.toString.call(Map.prototype), "[object Map]");
 assertEq(Object.prototype.toString.call(new Map), "[object Map]");
 assertEq(Object.prototype.toString.call(Map()), "[object Map]");
 assertEq(Object.keys(Map.prototype).join(), "");
 assertEq(Map.prototype.constructor, Map);
--- a/js/src/jit-test/tests/collections/Set-surfaces-1.js
+++ b/js/src/jit-test/tests/collections/Set-surfaces-1.js
@@ -4,17 +4,17 @@ load(libdir + "iteration.js");
 
 var desc = Object.getOwnPropertyDescriptor(this, "Set");
 assertEq(desc.enumerable, false);
 assertEq(desc.configurable, true);
 assertEq(desc.writable, true);
 
 assertEq(typeof Set, 'function');
 assertEq(Object.keys(Set).length, 0);
-assertEq(Set.length, 1);
+assertEq(Set.length, 0);
 assertEq(Set.name, "Set");
 
 assertEq(Object.getPrototypeOf(Set.prototype), Object.prototype);
 assertEq(Object.prototype.toString.call(Set.prototype), "[object Set]");
 assertEq(Object.prototype.toString.call(new Set), "[object Set]");
 assertEq(Object.prototype.toString.call(Set()), "[object Set]");
 assertEq(Object.keys(Set.prototype).join(), "");
 assertEq(Set.prototype.constructor, Set);
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -828,19 +828,50 @@ AsmJSModule::deserialize(ExclusiveContex
     (cursor = DeserializeVector(cx, cursor, &exports_)) &&
     (cursor = DeserializePodVector(cx, cursor, &heapAccesses_)) &&
     (cursor = staticLinkData_.deserialize(cx, cursor));
 
     loadedFromCache_ = true;
     return cursor;
 }
 
+// When a module is cloned, we memcpy its executable code. If, right before or
+// during the clone, another thread calls AsmJSModule::protectCode() then the
+// executable code will become inaccessible. In theory, we could take away only
+// PROT_EXEC, but this seems to break emulators.
+class AutoUnprotectCodeForClone
+{
+    JSRuntime *rt_;
+    JSRuntime::AutoLockForOperationCallback lock_;
+    const AsmJSModule &module_;
+    const bool protectedBefore_;
+
+  public:
+    AutoUnprotectCodeForClone(JSContext *cx, const AsmJSModule &module)
+      : rt_(cx->runtime()),
+        lock_(rt_),
+        module_(module),
+        protectedBefore_(module_.codeIsProtected(rt_))
+    {
+        if (protectedBefore_)
+            module_.unprotectCode(rt_);
+    }
+
+    ~AutoUnprotectCodeForClone()
+    {
+        if (protectedBefore_)
+            module_.protectCode(rt_);
+    }
+};
+
 bool
-AsmJSModule::clone(ExclusiveContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) const
+AsmJSModule::clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) const
 {
+    AutoUnprotectCodeForClone cloneGuard(cx, *this);
+
     *moduleOut = cx->new_<AsmJSModule>(scriptSource_, charsBegin_);
     if (!*moduleOut)
         return false;
 
     AsmJSModule &out = **moduleOut;
 
     // Mirror the order of serialize/deserialize in cloning:
 
@@ -866,16 +897,58 @@ AsmJSModule::clone(ExclusiveContext *cx,
     }
 
     out.loadedFromCache_ = loadedFromCache_;
 
     out.restoreToInitialState(maybeHeap_, cx);
     return true;
 }
 
+void
+AsmJSModule::protectCode(JSRuntime *rt) const
+{
+    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+
+    // Technically, we should be able to only take away the execute permissions,
+    // however this seems to break our emulators which don't always check
+    // execute permissions while executing code.
+#if defined(XP_WIN)
+    DWORD oldProtect;
+    if (!VirtualProtect(codeBase(), functionBytes(), PAGE_NOACCESS, &oldProtect))
+        MOZ_CRASH();
+#else  // assume Unix
+    if (mprotect(codeBase(), functionBytes(), PROT_NONE))
+        MOZ_CRASH();
+#endif
+
+    codeIsProtected_ = true;
+}
+
+void
+AsmJSModule::unprotectCode(JSRuntime *rt) const
+{
+#if defined(XP_WIN)
+    DWORD oldProtect;
+    if (!VirtualProtect(codeBase(), functionBytes(), PAGE_EXECUTE_READWRITE, &oldProtect))
+        MOZ_CRASH();
+#else  // assume Unix
+    if (mprotect(codeBase(), functionBytes(), PROT_READ | PROT_WRITE | PROT_EXEC))
+        MOZ_CRASH();
+#endif
+
+    codeIsProtected_ = false;
+}
+
+bool
+AsmJSModule::codeIsProtected(JSRuntime *rt) const
+{
+    JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
+    return codeIsProtected_;
+}
+
 static bool
 GetCPUID(uint32_t *cpuId)
 {
     enum Arch {
         X86 = 0x1,
         X64 = 0x2,
         ARM = 0x3,
         ARCH_BITS = 2
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -411,16 +411,21 @@ class AsmJSModule
     bool                                  loadedFromCache_;
     HeapPtr<ArrayBufferObject>            maybeHeap_;
 
     uint32_t                              charsBegin_;
     ScriptSource *                        scriptSource_;
 
     FunctionCountsVector                  functionCounts_;
 
+    // This field is accessed concurrently when triggering the operation
+    // callback and access must be sychronized via the runtime's operation
+    // callback lock.
+    mutable bool                          codeIsProtected_;
+
   public:
     explicit AsmJSModule(ScriptSource *scriptSource, uint32_t charsBegin);
     ~AsmJSModule();
 
     void trace(JSTracer *trc) {
         for (unsigned i = 0; i < globals_.length(); i++)
             globals_[i].trace(trc);
         for (unsigned i = 0; i < exports_.length(); i++)
@@ -801,17 +806,23 @@ class AsmJSModule
     void addSizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t *asmJSModuleCode,
                        size_t *asmJSModuleData);
 
     size_t serializedSize() const;
     uint8_t *serialize(uint8_t *cursor) const;
     const uint8_t *deserialize(ExclusiveContext *cx, const uint8_t *cursor);
     bool loadedFromCache() const { return loadedFromCache_; }
 
-    bool clone(ExclusiveContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) const;
+    bool clone(JSContext *cx, ScopedJSDeletePtr<AsmJSModule> *moduleOut) const;
+
+    // These methods may only be called while holding the Runtime's operation
+    // callback lock.
+    void protectCode(JSRuntime *rt) const;
+    void unprotectCode(JSRuntime *rt) const;
+    bool codeIsProtected(JSRuntime *rt) const;
 };
 
 // Store the just-parsed module in the cache using AsmJSCacheOps.
 extern bool
 StoreAsmJSModuleInCache(AsmJSParser &parser,
                         const AsmJSModule &module,
                         ExclusiveContext *cx);
 
--- a/js/src/jit/AsmJSSignalHandlers.cpp
+++ b/js/src/jit/AsmJSSignalHandlers.cpp
@@ -453,19 +453,17 @@ HandleException(PEXCEPTION_POINTERS exce
     // If we faulted trying to execute code in 'module', this must be an
     // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
     // execution to a trampoline which will call js_HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
         *ppc = module.operationCallbackExit();
-        DWORD oldProtect;
-        if (!VirtualProtect(module.codeBase(), module.functionBytes(), PAGE_EXECUTE, &oldProtect))
-            MOZ_CRASH();
+        module.unprotectCode(rt);
         return true;
     }
 
 # if defined(JS_CODEGEN_X64)
     // These checks aren't necessary, but, since we can, check anyway to make
     // sure we aren't covering up a real bug.
     if (!module.maybeHeap() ||
         faultingAddress < module.maybeHeap() ||
@@ -640,32 +638,32 @@ HandleMachException(JSRuntime *rt, const
         return true;
 
     AsmJSActivation *activation = rt->mainThread.asmJSActivationStackFromAnyThread();
     if (!activation)
         return false;
 
     const AsmJSModule &module = activation->module();
     if (HandleSimulatorInterrupt(rt, activation, faultingAddress)) {
-        mprotect(module.codeBase(), module.functionBytes(), PROT_EXEC);
+        module.unprotectCode(rt);
         return true;
     }
 
     if (!module.containsPC(pc))
         return false;
 
     // If we faulted trying to execute code in 'module', this must be an
     // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
     // execution to a trampoline which will call js_HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
         *ppc = module.operationCallbackExit();
-        mprotect(module.codeBase(), module.functionBytes(), PROT_EXEC);
+        module.unprotectCode(rt);
 
         // Update the thread state with the new pc.
         kret = thread_set_state(rtThread, x86_THREAD_STATE, (thread_state_t)&state, x86_THREAD_STATE_COUNT);
         return kret == KERN_SUCCESS;
     }
 
 # if defined(JS_CODEGEN_X64)
     // These checks aren't necessary, but, since we can, check anyway to make
@@ -887,32 +885,32 @@ HandleSignal(int signum, siginfo_t *info
         return true;
 
     AsmJSActivation *activation = InnermostAsmJSActivation();
     if (!activation)
         return false;
 
     const AsmJSModule &module = activation->module();
     if (HandleSimulatorInterrupt(rt, activation, faultingAddress)) {
-        mprotect(module.codeBase(), module.functionBytes(), PROT_EXEC);
+        module.unprotectCode(rt);
         return true;
     }
 
     if (!module.containsPC(pc))
         return false;
 
     // If we faulted trying to execute code in 'module', this must be an
     // operation callback (see TriggerOperationCallbackForAsmJSCode). Redirect
     // execution to a trampoline which will call js_HandleExecutionInterrupt.
     // The trampoline will jump to activation->resumePC if execution isn't
     // interrupted.
     if (module.containsPC(faultingAddress)) {
         activation->setResumePC(pc);
         *ppc = module.operationCallbackExit();
-        mprotect(module.codeBase(), module.functionBytes(), PROT_EXEC);
+        module.unprotectCode(rt);
         return true;
     }
 
 # if defined(JS_CODEGEN_X64)
     // These checks aren't necessary, but, since we can, check anyway to make
     // sure we aren't covering up a real bug.
     if (!module.maybeHeap() ||
         faultingAddress < module.maybeHeap() ||
@@ -1022,26 +1020,17 @@ void
 js::TriggerOperationCallbackForAsmJSCode(JSRuntime *rt)
 {
     JS_ASSERT(rt->currentThreadOwnsOperationCallbackLock());
 
     AsmJSActivation *activation = rt->mainThread.asmJSActivationStackFromAnyThread();
     if (!activation)
         return;
 
-    const AsmJSModule &module = activation->module();
-
-#if defined(XP_WIN)
-    DWORD oldProtect;
-    if (!VirtualProtect(module.codeBase(), module.functionBytes(), PAGE_NOACCESS, &oldProtect))
-        MOZ_CRASH();
-#else  // assume Unix
-    if (mprotect(module.codeBase(), module.functionBytes(), PROT_NONE))
-        MOZ_CRASH();
-#endif
+    activation->module().protectCode(rt);
 }
 
 #if defined(MOZ_ASAN) && defined(JS_STANDALONE)
 // Usually, this definition is found in mozglue (see mozglue/build/AsanOptions.cpp).
 // However, when doing standalone JS builds, mozglue is not used and we must ensure
 // that we still allow custom SIGSEGV handlers for asm.js and ion to work correctly.
 extern "C" MOZ_ASAN_BLACKLIST
 const char* __asan_default_options() {
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -2476,33 +2476,33 @@ DoBinaryArithFallback(JSContext *cx, Bas
     // generating stubs.
     RootedValue lhsCopy(cx, lhs);
     RootedValue rhsCopy(cx, rhs);
 
     // Perform the compare operation.
     switch(op) {
       case JSOP_ADD:
         // Do an add.
-        if (!AddValues(cx, &lhsCopy, &rhsCopy, ret.address()))
+        if (!AddValues(cx, &lhsCopy, &rhsCopy, ret))
             return false;
         break;
       case JSOP_SUB:
-        if (!SubValues(cx, &lhsCopy, &rhsCopy, ret.address()))
+        if (!SubValues(cx, &lhsCopy, &rhsCopy, ret))
             return false;
         break;
       case JSOP_MUL:
-        if (!MulValues(cx, &lhsCopy, &rhsCopy, ret.address()))
+        if (!MulValues(cx, &lhsCopy, &rhsCopy, ret))
             return false;
         break;
       case JSOP_DIV:
-        if (!DivValues(cx, &lhsCopy, &rhsCopy, ret.address()))
+        if (!DivValues(cx, &lhsCopy, &rhsCopy, ret))
             return false;
         break;
       case JSOP_MOD:
-        if (!ModValues(cx, &lhsCopy, &rhsCopy, ret.address()))
+        if (!ModValues(cx, &lhsCopy, &rhsCopy, ret))
             return false;
         break;
       case JSOP_BITOR: {
         int32_t result;
         if (!BitOr(cx, lhs, rhs, &result))
             return false;
         ret.setInt32(result);
         break;
@@ -2531,17 +2531,17 @@ DoBinaryArithFallback(JSContext *cx, Bas
       case JSOP_RSH: {
         int32_t result;
         if (!BitRsh(cx, lhs, rhs, &result))
             return false;
         ret.setInt32(result);
         break;
       }
       case JSOP_URSH: {
-        if (!UrshOperation(cx, lhs, rhs, ret.address()))
+        if (!UrshOperation(cx, lhs, rhs, ret))
             return false;
         break;
       }
       default:
         MOZ_ASSUME_UNREACHABLE("Unhandled baseline arith op");
     }
 
     if (ret.isDouble())
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -872,17 +872,17 @@ static const VMFunction CloneRegExpObjec
 bool
 CodeGenerator::visitRegExp(LRegExp *lir)
 {
     pushArg(ImmGCPtr(lir->mir()->source()));
     return callVM(CloneRegExpObjectInfo, lir);
 }
 
 typedef bool (*RegExpExecRawFn)(JSContext *cx, HandleObject regexp,
-                                HandleString input, Value *vp);
+                                HandleString input, MutableHandleValue output);
 static const VMFunction RegExpExecRawInfo = FunctionInfo<RegExpExecRawFn>(regexp_exec_raw);
 
 bool
 CodeGenerator::visitRegExpExec(LRegExpExec *lir)
 {
     pushArg(ToRegister(lir->string()));
     pushArg(ToRegister(lir->regexp()));
     return callVM(RegExpExecRawInfo, lir);
@@ -4361,18 +4361,18 @@ CodeGenerator::visitModD(LModD *ins)
 
     if (gen->compilingAsmJS())
         masm.callWithABI(AsmJSImm_ModD, MoveOp::DOUBLE);
     else
         masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, NumberMod), MoveOp::DOUBLE);
     return true;
 }
 
-typedef bool (*BinaryFn)(JSContext *, MutableHandleValue, MutableHandleValue, Value *);
-typedef bool (*BinaryParFn)(ForkJoinContext *, HandleValue, HandleValue, Value *);
+typedef bool (*BinaryFn)(JSContext *, MutableHandleValue, MutableHandleValue, MutableHandleValue);
+typedef bool (*BinaryParFn)(ForkJoinContext *, HandleValue, HandleValue, MutableHandleValue);
 
 static const VMFunction AddInfo = FunctionInfo<BinaryFn>(js::AddValues);
 static const VMFunction SubInfo = FunctionInfo<BinaryFn>(js::SubValues);
 static const VMFunction MulInfo = FunctionInfo<BinaryFn>(js::MulValues);
 static const VMFunction DivInfo = FunctionInfo<BinaryFn>(js::DivValues);
 static const VMFunction ModInfo = FunctionInfo<BinaryFn>(js::ModValues);
 static const VMFunctionsModal UrshInfo = VMFunctionsModal(
     FunctionInfo<BinaryFn>(js::UrshValues),
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -794,48 +794,48 @@ TypeAnalyzer::markPhiConsumers()
         if (mir->shouldCancel("Ensure Float32 commutativity - Consumer Phis - Initial state"))
             return false;
 
         for (MPhiIterator phi(block->phisBegin()); phi != block->phisEnd(); ++phi) {
             JS_ASSERT(!phi->isInWorklist());
             bool canConsumeFloat32 = true;
             for (MUseDefIterator use(*phi); canConsumeFloat32 && use; use++) {
                 MDefinition *usedef = use.def();
-                canConsumeFloat32 &= usedef->isPhi() || usedef->canConsumeFloat32();
+                canConsumeFloat32 &= usedef->isPhi() || usedef->canConsumeFloat32(use.use());
             }
             phi->setCanConsumeFloat32(canConsumeFloat32);
             if (canConsumeFloat32 && !addPhiToWorklist(*phi))
                 return false;
         }
     }
 
     while (!phiWorklist_.empty()) {
         if (mir->shouldCancel("Ensure Float32 commutativity - Consumer Phis - Fixed point"))
             return false;
 
         MPhi *phi = popPhi();
-        JS_ASSERT(phi->canConsumeFloat32());
+        JS_ASSERT(phi->canConsumeFloat32(nullptr /* unused */));
 
         bool validConsumer = true;
         for (MUseDefIterator use(phi); use; use++) {
             MDefinition *def = use.def();
-            if (def->isPhi() && !def->canConsumeFloat32()) {
+            if (def->isPhi() && !def->canConsumeFloat32(use.use())) {
                 validConsumer = false;
                 break;
             }
         }
 
         if (validConsumer)
             continue;
 
         // Propagate invalidated phis
         phi->setCanConsumeFloat32(false);
         for (size_t i = 0, e = phi->numOperands(); i < e; ++i) {
             MDefinition *input = phi->getOperand(i);
-            if (input->isPhi() && !input->isInWorklist() && input->canConsumeFloat32())
+            if (input->isPhi() && !input->isInWorklist() && input->canConsumeFloat32(nullptr /* unused */))
             {
                 if (!addPhiToWorklist(input->toPhi()))
                     return false;
             }
         }
     }
     return true;
 }
@@ -971,17 +971,17 @@ TypeAnalyzer::checkFloatCoherency()
             return false;
 
         for (MDefinitionIterator def(*block); def; def++) {
             if (def->type() != MIRType_Float32)
                 continue;
 
             for (MUseDefIterator use(*def); use; use++) {
                 MDefinition *consumer = use.def();
-                JS_ASSERT(consumer->isConsistentFloat32Use());
+                JS_ASSERT(consumer->isConsistentFloat32Use(use.use()));
             }
         }
     }
 #endif
     return true;
 }
 
 bool
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -38,17 +38,17 @@ ConvertDefinitionToDouble(TempAllocator 
     consumer->block()->insertBefore(consumer, replace);
 }
 
 static bool
 CheckUsesAreFloat32Consumers(MInstruction *ins)
 {
     bool allConsumerUses = true;
     for (MUseDefIterator use(ins); allConsumerUses && use; use++)
-        allConsumerUses &= use.def()->canConsumeFloat32();
+        allConsumerUses &= use.def()->canConsumeFloat32(use.use());
     return allConsumerUses;
 }
 
 void
 MDefinition::PrintOpcodeName(FILE *fp, MDefinition::Opcode op)
 {
     static const char * const names[] =
     {
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -465,22 +465,22 @@ class MDefinition : public MNode
 
         return !resultTypeSet() || resultTypeSet()->mightBeType(ValueTypeFromMIRType(type));
     }
 
     // Float32 specialization operations (see big comment in IonAnalysis before the Float32
     // specialization algorithm).
     virtual bool isFloat32Commutative() const { return false; }
     virtual bool canProduceFloat32() const { return false; }
-    virtual bool canConsumeFloat32() const { return false; }
+    virtual bool canConsumeFloat32(MUse *use) const { return false; }
     virtual void trySpecializeFloat32(TempAllocator &alloc) {}
 #ifdef DEBUG
     // Used during the pass that checks that Float32 flow into valid MDefinitions
-    virtual bool isConsistentFloat32Use() const {
-        return type() == MIRType_Float32 || canConsumeFloat32();
+    virtual bool isConsistentFloat32Use(MUse *use) const {
+        return type() == MIRType_Float32 || canConsumeFloat32(use);
     }
 #endif
 
     // Returns the beginning of this definition's use chain.
     MUseIterator usesBegin() const {
         return uses_.begin();
     }
 
@@ -1324,17 +1324,17 @@ class MTest
 
     void markOperandCantEmulateUndefined() {
         operandMightEmulateUndefined_ = false;
     }
     bool operandMightEmulateUndefined() const {
         return operandMightEmulateUndefined_;
     }
 #ifdef DEBUG
-    bool isConsistentFloat32Use() const {
+    bool isConsistentFloat32Use(MUse *use) const {
         return true;
     }
 #endif
 };
 
 // Returns from this function to the previous caller.
 class MReturn
   : public MAryControlInstruction<1, 0>,
@@ -2055,17 +2055,17 @@ class MAssertFloat32 : public MUnaryInst
 
   public:
     INSTRUCTION_HEADER(AssertFloat32)
 
     static MAssertFloat32 *New(TempAllocator &alloc, MDefinition *value, bool mustBeFloat32) {
         return new(alloc) MAssertFloat32(value, mustBeFloat32);
     }
 
-    bool canConsumeFloat32() const { return true; }
+    bool canConsumeFloat32(MUse *use) const { return true; }
 
     bool mustBeFloat32() const { return mustBeFloat32_; }
 };
 
 class MGetDynamicName
   : public MAryInstruction<2>,
     public MixPolicy<ObjectPolicy<0>, ConvertToStringPolicy<1> >
 {
@@ -2331,17 +2331,18 @@ class MCompare
     void collectRangeInfoPreTrunc();
 
     void trySpecializeFloat32(TempAllocator &alloc);
     bool isFloat32Commutative() const { return true; }
     bool truncate();
     bool isOperandTruncated(size_t index) const;
 
 # ifdef DEBUG
-    bool isConsistentFloat32Use() const {
+    bool isConsistentFloat32Use(MUse *use) const {
+        // Both sides of the compare can be Float32
         return compareType_ == Compare_Float32;
     }
 # endif
 
   protected:
     bool congruentTo(MDefinition *ins) const {
         if (!MBinaryInstruction::congruentTo(ins))
             return false;
@@ -2897,17 +2898,17 @@ class MToDouble
         return AliasSet::None();
     }
 
     void computeRange(TempAllocator &alloc);
     bool truncate();
     bool isOperandTruncated(size_t index) const;
 
 #ifdef DEBUG
-    bool isConsistentFloat32Use() const { return true; }
+    bool isConsistentFloat32Use(MUse *use) const { return true; }
 #endif
 };
 
 // Converts a primitive (either typed or untyped) to a float32. If the input is
 // not primitive at runtime, a bailout occurs.
 class MToFloat32
   : public MUnaryInstruction,
     public ToDoublePolicy
@@ -2956,17 +2957,17 @@ class MToFloat32
         return congruentIfOperandsEqual(ins);
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
     void computeRange(TempAllocator &alloc);
 
-    bool canConsumeFloat32() const { return true; }
+    bool canConsumeFloat32(MUse *use) const { return true; }
     bool canProduceFloat32() const { return true; }
 };
 
 // Converts a uint32 to a double (coming from asm.js).
 class MAsmJSUnsignedToDouble
   : public MUnaryInstruction
 {
     MAsmJSUnsignedToDouble(MDefinition *def)
@@ -3072,17 +3073,17 @@ class MToInt32
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
     void computeRange(TempAllocator &alloc);
 
 #ifdef DEBUG
-    bool isConsistentFloat32Use() const { return true; }
+    bool isConsistentFloat32Use(MUse *use) const { return true; }
 #endif
 };
 
 // Converts a value or typed input to a truncated int32, for use with bitwise
 // operations. This is an infallible ValueToECMAInt32.
 class MTruncateToInt32 : public MUnaryInstruction
 {
     MTruncateToInt32(MDefinition *def)
@@ -3108,17 +3109,17 @@ class MTruncateToInt32 : public MUnaryIn
     }
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
     void computeRange(TempAllocator &alloc);
     bool isOperandTruncated(size_t index) const;
 # ifdef DEBUG
-    bool isConsistentFloat32Use() const {
+    bool isConsistentFloat32Use(MUse *use) const {
         return true;
     }
 #endif
 };
 
 // Converts any type to a string
 class MToString : public MUnaryInstruction
 {
@@ -4569,17 +4570,17 @@ class MPhi MOZ_FINAL : public MDefinitio
     bool canProduceFloat32() const {
         return canProduceFloat32_;
     }
 
     void setCanProduceFloat32(bool can) {
         canProduceFloat32_ = can;
     }
 
-    bool canConsumeFloat32() const {
+    bool canConsumeFloat32(MUse *use) const {
         return canConsumeFloat32_;
     }
 
     void setCanConsumeFloat32(bool can) {
         canConsumeFloat32_ = can;
     }
 };
 
@@ -5661,17 +5662,17 @@ class MNot
     TypePolicy *typePolicy() {
         return this;
     }
     void collectRangeInfoPreTrunc();
 
     void trySpecializeFloat32(TempAllocator &alloc);
     bool isFloat32Commutative() const { return true; }
 #ifdef DEBUG
-    bool isConsistentFloat32Use() const {
+    bool isConsistentFloat32Use(MUse *use) const {
         return true;
     }
 #endif
 };
 
 // Bailout if index + minimum < 0 or index + maximum >= length. The length used
 // in a bounds check must not be negative, or the wrong result may be computed
 // (unsigned comparisons may be used).
@@ -6353,17 +6354,19 @@ class MStoreTypedArrayElement
     bool racy() const {
         return racy_;
     }
     void setRacy() {
         racy_ = true;
     }
     bool isOperandTruncated(size_t index) const;
 
-    bool canConsumeFloat32() const { return arrayType_ == ScalarTypeDescr::TYPE_FLOAT32; }
+    bool canConsumeFloat32(MUse *use) const {
+        return use->index() == 2 && arrayType_ == ScalarTypeDescr::TYPE_FLOAT32;
+    }
 };
 
 class MStoreTypedArrayElementHole
   : public MAryInstruction<4>,
     public StoreTypedArrayHolePolicy
 {
     int arrayType_;
 
@@ -6419,17 +6422,19 @@ class MStoreTypedArrayElementHole
     MDefinition *value() const {
         return getOperand(3);
     }
     AliasSet getAliasSet() const {
         return AliasSet::Store(AliasSet::TypedArrayElement);
     }
     bool isOperandTruncated(size_t index) const;
 
-    bool canConsumeFloat32() const { return arrayType_ == ScalarTypeDescr::TYPE_FLOAT32; }
+    bool canConsumeFloat32(MUse *use) const {
+        return use->index() == 3 && arrayType_ == ScalarTypeDescr::TYPE_FLOAT32;
+    }
 };
 
 // Store a value infallibly to a statically known typed array.
 class MStoreTypedArrayElementStatic :
     public MBinaryInstruction
   , public StoreTypedArrayElementStaticPolicy
 {
     MStoreTypedArrayElementStatic(TypedArrayObject *typedArray, MDefinition *ptr, MDefinition *v)
@@ -6464,17 +6469,19 @@ class MStoreTypedArrayElementStatic :
 
     MDefinition *ptr() const { return getOperand(0); }
     MDefinition *value() const { return getOperand(1); }
     AliasSet getAliasSet() const {
         return AliasSet::Store(AliasSet::TypedArrayElement);
     }
     bool isOperandTruncated(size_t index) const;
 
-    bool canConsumeFloat32() const { return typedArray_->type() == ScalarTypeDescr::TYPE_FLOAT32; }
+    bool canConsumeFloat32(MUse *use) const {
+        return use->index() == 1 && typedArray_->type() == ScalarTypeDescr::TYPE_FLOAT32;
+    }
 };
 
 // Compute an "effective address", i.e., a compound computation of the form:
 //   base + index * scale + displacement
 class MEffectiveAddress : public MBinaryInstruction
 {
     MEffectiveAddress(MDefinition *base, MDefinition *index, Scale scale, int32_t displacement)
       : MBinaryInstruction(base, index), scale_(scale), displacement_(displacement)
@@ -7852,17 +7859,17 @@ class MSetElementCache
     bool guardHoles() const {
         return guardHoles_;
     }
 
     TypePolicy *typePolicy() {
         return this;
     }
 
-    bool canConsumeFloat32() const { return true; }
+    bool canConsumeFloat32(MUse *use) const { return use->index() == 2; }
 };
 
 class MCallGetProperty
   : public MUnaryInstruction,
     public BoxInputsPolicy
 {
     CompilerRootPropertyName name_;
     bool idempotent_;
@@ -8238,17 +8245,17 @@ class MFloor
     TypePolicy *typePolicy() {
         return this;
     }
     bool isFloat32Commutative() const {
         return true;
     }
     void trySpecializeFloat32(TempAllocator &alloc);
 #ifdef DEBUG
-    bool isConsistentFloat32Use() const {
+    bool isConsistentFloat32Use(MUse *use) const {
         return true;
     }
 #endif
 };
 
 // Inlined version of Math.round().
 class MRound
   : public MUnaryInstruction,
@@ -8883,20 +8890,20 @@ class MPostWriteBarrier
 
     bool hasValue() const {
         return hasValue_;
     }
     MDefinition *value() const {
         return getOperand(1);
     }
 #ifdef DEBUG
-    bool isConsistentFloat32Use() const {
+    bool isConsistentFloat32Use(MUse *use) const {
         // During lowering, values that neither have object nor value MIR type
         // are ignored, thus Float32 can show up at this point without any issue.
-        return true;
+        return use->index() == 1;
     }
 #endif
 };
 
 class MNewSlots : public MNullaryInstruction
 {
     unsigned nslots_;
 
--- a/js/src/jit/ParallelFunctions.cpp
+++ b/js/src/jit/ParallelFunctions.cpp
@@ -536,26 +536,26 @@ jit::BitRshPar(ForkJoinContext *cx, Hand
 {
     BIT_OP(left >> (right & 31));
 }
 
 #undef BIT_OP
 
 bool
 jit::UrshValuesPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs,
-                   Value *out)
+                   MutableHandleValue out)
 {
     uint32_t left;
     int32_t right;
     if (lhs.isObject() || rhs.isObject())
         return false;
     if (!NonObjectToUint32(cx, lhs, &left) || !NonObjectToInt32(cx, rhs, &right))
         return false;
     left >>= right & 31;
-    out->setNumber(uint32_t(left));
+    out.setNumber(uint32_t(left));
     return true;
 }
 
 void
 jit::AbortPar(ParallelBailoutCause cause, JSScript *outermostScript, JSScript *currentScript,
               jsbytecode *bytecode)
 {
     // Spew before asserts to help with diagnosing failures.
--- a/js/src/jit/ParallelFunctions.h
+++ b/js/src/jit/ParallelFunctions.h
@@ -58,17 +58,17 @@ bool StringsUnequalPar(ForkJoinContext *
 
 bool BitNotPar(ForkJoinContext *cx, HandleValue in, int32_t *out);
 bool BitXorPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out);
 bool BitOrPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out);
 bool BitAndPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out);
 bool BitLshPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out);
 bool BitRshPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, int32_t *out);
 
-bool UrshValuesPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, Value *out);
+bool UrshValuesPar(ForkJoinContext *cx, HandleValue lhs, HandleValue rhs, MutableHandleValue out);
 
 // Make a new rest parameter in parallel.
 JSObject *InitRestParameterPar(ForkJoinContext *cx, uint32_t length, Value *rest,
                                HandleObject templateObj, HandleObject res);
 
 // Abort and debug tracing functions.
 void AbortPar(ParallelBailoutCause cause, JSScript *outermostScript, JSScript *currentScript,
               jsbytecode *bytecode);
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -617,24 +617,24 @@ BitRsh(JSContext *cx, HandleValue lhs, H
     int32_t left, right;
     if (!ToInt32(cx, lhs, &left) || !ToInt32(cx, rhs, &right))
         return false;
     *out = left >> (right & 31);
     return true;
 }
 
 static MOZ_ALWAYS_INLINE bool
-UrshOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *out)
+UrshOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, MutableHandleValue out)
 {
     uint32_t left;
     int32_t  right;
     if (!ToUint32(cx, lhs, &left) || !ToInt32(cx, rhs, &right))
         return false;
     left >>= right & 31;
-    out->setNumber(uint32_t(left));
+    out.setNumber(uint32_t(left));
     return true;
 }
 
 #undef RELATIONAL_OP
 
 inline JSFunction *
 ReportIfNotFunction(JSContext *cx, HandleValue v, MaybeConstruct construct = NO_CONSTRUCT)
 {
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1199,23 +1199,23 @@ ComputeImplicitThis(JSContext *cx, Handl
     if (!nobj)
         return false;
 
     vp.setObject(*nobj);
     return true;
 }
 
 static MOZ_ALWAYS_INLINE bool
-AddOperation(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res)
+AddOperation(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
 {
     if (lhs.isInt32() && rhs.isInt32()) {
         int32_t l = lhs.toInt32(), r = rhs.toInt32();
         int32_t t;
         if (MOZ_LIKELY(SafeAdd(l, r, &t))) {
-            res->setInt32(t);
+            res.setInt32(t);
             return true;
         }
     }
 
     if (!ToPrimitive(cx, lhs))
         return false;
     if (!ToPrimitive(cx, rhs))
         return false;
@@ -1242,73 +1242,73 @@ AddOperation(JSContext *cx, MutableHandl
         }
         JSString *str = ConcatStrings<NoGC>(cx, lstr, rstr);
         if (!str) {
             RootedString nlstr(cx, lstr), nrstr(cx, rstr);
             str = ConcatStrings<CanGC>(cx, nlstr, nrstr);
             if (!str)
                 return false;
         }
-        res->setString(str);
+        res.setString(str);
     } else {
         double l, r;
         if (!ToNumber(cx, lhs, &l) || !ToNumber(cx, rhs, &r))
             return false;
-        res->setNumber(l + r);
+        res.setNumber(l + r);
     }
 
     return true;
 }
 
 static MOZ_ALWAYS_INLINE bool
-SubOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *res)
+SubOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
 {
     double d1, d2;
     if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
         return false;
-    res->setNumber(d1 - d2);
+    res.setNumber(d1 - d2);
     return true;
 }
 
 static MOZ_ALWAYS_INLINE bool
-MulOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *res)
+MulOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
 {
     double d1, d2;
     if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
         return false;
-    res->setNumber(d1 * d2);
+    res.setNumber(d1 * d2);
     return true;
 }
 
 static MOZ_ALWAYS_INLINE bool
-DivOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *res)
+DivOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
 {
     double d1, d2;
     if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
         return false;
-    res->setNumber(NumberDiv(d1, d2));
+    res.setNumber(NumberDiv(d1, d2));
     return true;
 }
 
 static MOZ_ALWAYS_INLINE bool
-ModOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, Value *res)
+ModOperation(JSContext *cx, HandleValue lhs, HandleValue rhs, MutableHandleValue res)
 {
     int32_t l, r;
     if (lhs.isInt32() && rhs.isInt32() &&
         (l = lhs.toInt32()) >= 0 && (r = rhs.toInt32()) > 0) {
         int32_t mod = l % r;
-        res->setInt32(mod);
+        res.setInt32(mod);
         return true;
     }
 
     double d1, d2;
     if (!ToNumber(cx, lhs, &d1) || !ToNumber(cx, rhs, &d2))
         return false;
 
-    res->setNumber(NumberMod(d1, d2));
+    res.setNumber(NumberMod(d1, d2));
     return true;
 }
 
 static MOZ_ALWAYS_INLINE bool
 SetObjectElementOperation(JSContext *cx, Handle<JSObject*> obj, HandleId id, const Value &value,
                           bool strict, JSScript *script = nullptr, jsbytecode *pc = nullptr)
 {
     types::TypeScript::MonitorAssign(cx, obj, id);
@@ -2194,71 +2194,77 @@ CASE(JSOP_RSH)
 END_CASE(JSOP_RSH)
 
 #undef SIGNED_SHIFT_OP
 
 CASE(JSOP_URSH)
 {
     HandleValue lval = REGS.stackHandleAt(-2);
     HandleValue rval = REGS.stackHandleAt(-1);
-    if (!UrshOperation(cx, lval, rval, &REGS.sp[-2]))
+    MutableHandleValue res = REGS.stackHandleAt(-2);
+    if (!UrshOperation(cx, lval, rval, res))
         goto error;
     REGS.sp--;
 }
 END_CASE(JSOP_URSH)
 
 CASE(JSOP_ADD)
 {
     MutableHandleValue lval = REGS.stackHandleAt(-2);
     MutableHandleValue rval = REGS.stackHandleAt(-1);
-    if (!AddOperation(cx, lval, rval, &REGS.sp[-2]))
+    MutableHandleValue res = REGS.stackHandleAt(-2);
+    if (!AddOperation(cx, lval, rval, res))
         goto error;
     REGS.sp--;
 }
 END_CASE(JSOP_ADD)
 
 CASE(JSOP_SUB)
 {
     RootedValue &lval = rootValue0, &rval = rootValue1;
     lval = REGS.sp[-2];
     rval = REGS.sp[-1];
-    if (!SubOperation(cx, lval, rval, &REGS.sp[-2]))
+    MutableHandleValue res = REGS.stackHandleAt(-2);
+    if (!SubOperation(cx, lval, rval, res))
         goto error;
     REGS.sp--;
 }
 END_CASE(JSOP_SUB)
 
 CASE(JSOP_MUL)
 {
     RootedValue &lval = rootValue0, &rval = rootValue1;
     lval = REGS.sp[-2];
     rval = REGS.sp[-1];
-    if (!MulOperation(cx, lval, rval, &REGS.sp[-2]))
+    MutableHandleValue res = REGS.stackHandleAt(-2);
+    if (!MulOperation(cx, lval, rval, res))
         goto error;
     REGS.sp--;
 }
 END_CASE(JSOP_MUL)
 
 CASE(JSOP_DIV)
 {
     RootedValue &lval = rootValue0, &rval = rootValue1;
     lval = REGS.sp[-2];
     rval = REGS.sp[-1];
-    if (!DivOperation(cx, lval, rval, &REGS.sp[-2]))
+    MutableHandleValue res = REGS.stackHandleAt(-2);
+    if (!DivOperation(cx, lval, rval, res))
         goto error;
     REGS.sp--;
 }
 END_CASE(JSOP_DIV)
 
 CASE(JSOP_MOD)
 {
     RootedValue &lval = rootValue0, &rval = rootValue1;
     lval = REGS.sp[-2];
     rval = REGS.sp[-1];
-    if (!ModOperation(cx, lval, rval, &REGS.sp[-2]))
+    MutableHandleValue res = REGS.stackHandleAt(-2);
+    if (!ModOperation(cx, lval, rval, res))
         goto error;
     REGS.sp--;
 }
 END_CASE(JSOP_MOD)
 
 CASE(JSOP_NOT)
 {
     bool cond = ToBooleanOp(REGS);
@@ -3821,47 +3827,47 @@ js::SetObjectElement(JSContext *cx, Hand
 
 bool
 js::InitElementArray(JSContext *cx, jsbytecode *pc, HandleObject obj, uint32_t index, HandleValue value)
 {
     return InitArrayElemOperation(cx, pc, obj, index, value);
 }
 
 bool
-js::AddValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res)
+js::AddValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
 {
     return AddOperation(cx, lhs, rhs, res);
 }
 
 bool
-js::SubValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res)
+js::SubValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
 {
     return SubOperation(cx, lhs, rhs, res);
 }
 
 bool
-js::MulValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res)
+js::MulValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
 {
     return MulOperation(cx, lhs, rhs, res);
 }
 
 bool
-js::DivValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res)
+js::DivValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
 {
     return DivOperation(cx, lhs, rhs, res);
 }
 
 bool
-js::ModValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res)
+js::ModValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
 {
     return ModOperation(cx, lhs, rhs, res);
 }
 
 bool
-js::UrshValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res)
+js::UrshValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res)
 {
     return UrshOperation(cx, lhs, rhs, res);
 }
 
 bool
 js::DeleteNameOperation(JSContext *cx, HandlePropertyName name, HandleObject scopeObj,
                         MutableHandleValue res)
 {
--- a/js/src/vm/Interpreter.h
+++ b/js/src/vm/Interpreter.h
@@ -383,32 +383,32 @@ bool
 SetObjectElement(JSContext *cx, HandleObject obj, HandleValue index, HandleValue value,
                  bool strict, HandleScript script, jsbytecode *pc);
 
 bool
 InitElementArray(JSContext *cx, jsbytecode *pc,
                  HandleObject obj, uint32_t index, HandleValue value);
 
 bool
-AddValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res);
+AddValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
 
 bool
-SubValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res);
+SubValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
 
 bool
-MulValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res);
+MulValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
 
 bool
-DivValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res);
+DivValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
 
 bool
-ModValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res);
+ModValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
 
 bool
-UrshValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Value *res);
+UrshValues(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, MutableHandleValue res);
 
 template <bool strict>
 bool
 SetProperty(JSContext *cx, HandleObject obj, HandleId id, const Value &value);
 
 template <bool strict>
 bool
 DeleteProperty(JSContext *ctx, HandleValue val, HandlePropertyName name, bool *bv);
--- a/js/src/vm/SPSProfiler.cpp
+++ b/js/src/vm/SPSProfiler.cpp
@@ -207,17 +207,17 @@ SPSProfiler::enterNative(const char *str
 void
 SPSProfiler::push(const char *string, void *sp, JSScript *script, jsbytecode *pc)
 {
     /* these operations cannot be re-ordered, so volatile-ize operations */
     volatile ProfileEntry *stack = stack_;
     volatile uint32_t *size = size_;
     uint32_t current = *size;
 
-    JS_ASSERT(enabled());
+    JS_ASSERT(installed());
     if (current < max_) {
         stack[current].setLabel(string);
         stack[current].setStackAddress(sp);
         stack[current].setScript(script);
         stack[current].setPC(pc);
     }
     *size = current + 1;
 }
@@ -286,22 +286,22 @@ SPSProfiler::allocProfileString(JSScript
     return cstr;
 }
 
 SPSEntryMarker::SPSEntryMarker(JSRuntime *rt
                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
     : profiler(&rt->spsProfiler)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    if (!profiler->enabled()) {
+    if (!profiler->installed()) {
         profiler = nullptr;
         return;
     }
     size_before = *profiler->size_;
-    profiler->push("js::RunScript", this, nullptr, nullptr);
+    profiler->pushNoCopy("js::RunScript", this, nullptr, nullptr);
 }
 
 SPSEntryMarker::~SPSEntryMarker()
 {
     if (profiler != nullptr) {
         profiler->pop();
         JS_ASSERT(size_before == *profiler->size_);
     }
--- a/js/src/vm/SPSProfiler.h
+++ b/js/src/vm/SPSProfiler.h
@@ -123,16 +123,22 @@ class SPSProfiler
     uint32_t             *size_;
     uint32_t             max_;
     bool                 slowAssertions;
     uint32_t             enabled_;
     PRLock               *lock_;
 
     const char *allocProfileString(JSScript *script, JSFunction *function);
     void push(const char *string, void *sp, JSScript *script, jsbytecode *pc);
+    void pushNoCopy(const char *string, void *sp,
+                    JSScript *script, jsbytecode *pc) {
+        push(string, reinterpret_cast<void*>(
+            reinterpret_cast<uintptr_t>(sp) | ProfileEntry::NoCopyBit),
+            script, pc);
+    }
     void pop();
 
   public:
     SPSProfiler(JSRuntime *rt);
     ~SPSProfiler();
 
     bool init();
 
--- a/js/xpconnect/shell/Makefile.in
+++ b/js/xpconnect/shell/Makefile.in
@@ -16,18 +16,12 @@ LIBS +=	$(NSPR_LIBS)
 NSDISTMODE = copy
 
 ifeq ($(OS_TEST),ia64)
 LIBS += $(JEMALLOC_LIBS)
 endif
 
 include $(topsrcdir)/config/rules.mk
 
-ifdef _MSC_VER
-# Always enter a Windows program through wmain, whether or not we're
-# a console application.
-WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
-endif
-
 ifdef MOZ_VTUNE
 CXXFLAGS += -IC:/Program\ Files/Intel/VTune/Analyzer/Include
 LIBS += C:/Program\ Files/Intel/VTune/Analyzer/Lib/VtuneApi.lib
 endif
--- a/js/xpconnect/shell/moz.build
+++ b/js/xpconnect/shell/moz.build
@@ -27,8 +27,12 @@ if CONFIG['MOZ_VTUNE']:
     DEFINES['MOZ_VTUNE'] = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/toolkit/xre',
 ]
 
+if CONFIG['_MSC_VER']:
+    # Always enter a Windows program through wmain, whether or not we're
+    # a console application.
+    WIN32_EXE_LDFLAGS += ['-ENTRY:wmainCRTStartup']
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -2026,30 +2026,30 @@ public:
 
   ~nsIRenderingContextBidiProcessor()
   {
     mCtx->SetTextRunRTL(false);
   }
 
   virtual void SetText(const char16_t* aText,
                        int32_t          aLength,
-                       nsBidiDirection  aDirection)
+                       nsBidiDirection  aDirection) MOZ_OVERRIDE
   {
     mTextRunConstructionContext->SetTextRunRTL(aDirection==NSBIDI_RTL);
     mText = aText;
     mLength = aLength;
   }
 
-  virtual nscoord GetWidth()
+  virtual nscoord GetWidth() MOZ_OVERRIDE
   {
     return mTextRunConstructionContext->GetWidth(mText, mLength);
   }
 
   virtual void DrawText(nscoord aXOffset,
-                        nscoord)
+                        nscoord) MOZ_OVERRIDE
   {
     mCtx->FontMetrics()->DrawString(mText, mLength, mPt.x + aXOffset, mPt.y,
                                     mCtx, mTextRunConstructionContext);
   }
 
 private:
   nsRenderingContext* mCtx;
   nsRenderingContext* mTextRunConstructionContext;
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -4888,27 +4888,26 @@ nsDisplaySVGEffects::BuildLayer(nsDispla
   if (opacity == 0.0f)
     return nullptr;
 
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
 
-  bool isOK = true;
+  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
   effectProperties.GetClipPathFrame(&isOK);
   effectProperties.GetMaskFrame(&isOK);
-  bool hasFilter = effectProperties.GetFilterFrame(&isOK) != nullptr;
 
   if (!isOK) {
     return nullptr;
   }
 
   ContainerLayerParameters newContainerParameters = aContainerParameters;
-  if (hasFilter) {
+  if (effectProperties.HasValidFilter()) {
     newContainerParameters.mDisableSubpixelAntialiasingInDescendants = true;
   }
 
   nsRefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
                            newContainerParameters, nullptr);
 
   return container.forget();
@@ -4967,17 +4966,17 @@ nsDisplaySVGEffects::PrintEffects(nsACSt
   }
   if (clipPathFrame) {
     if (!first) {
       aTo += ", ";
     }
     aTo += nsPrintfCString("clip(%s)", clipPathFrame->IsTrivial() ? "trivial" : "non-trivial");
     first = false;
   }
-  if (effectProperties.GetFilterFrame(&isOK)) {
+  if (effectProperties.HasValidFilter()) {
     if (!first) {
       aTo += ", ";
     }
     aTo += "filter";
     first = false;
   }
   if (effectProperties.GetMaskFrame(&isOK)) {
     if (!first) {
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -1726,22 +1726,23 @@ public:
     MOZ_COUNT_CTOR(nsDisplayGeneric);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayGeneric() {
     MOZ_COUNT_DTOR(nsDisplayGeneric);
   }
 #endif
   
-  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE {
+  virtual void Paint(nsDisplayListBuilder* aBuilder,
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE {
     mPaint(mFrame, aCtx, mVisibleRect, ToReferenceFrame());
   }
   NS_DISPLAY_DECL_NAME(mName, mType)
 
-  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) {
+  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE {
     if (mType == nsDisplayItem::TYPE_HEADER_FOOTER) {
       bool snap;
       return GetBounds(aBuilder, &snap);
     }
     return nsRect();
   }
 
 protected:
@@ -1903,17 +1904,17 @@ public:
 
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                    nsRegion* aVisibleRegion,
                                    const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
   
-  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder);
+  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion* aInvalidRegion) MOZ_OVERRIDE;
 };
 
 /**
  * A simple display item that just renders a solid color across the
@@ -2222,19 +2223,19 @@ public:
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                    nsRegion* aVisibleRegion,
                                    const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
   
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion* aInvalidRegion);
+                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE;
   
-  virtual bool ApplyOpacity(float aOpacity)
+  virtual bool ApplyOpacity(float aOpacity) MOZ_OVERRIDE
   {
     mOpacity = aOpacity;
     return true;
   }
 
   nsRect GetBoundsInternal();
 
 private:
@@ -2259,17 +2260,17 @@ public:
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                    nsRegion* aVisibleRegion,
                                    const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
   
-  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
+  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     return new nsDisplayBoxShadowInnerGeometry(this, aBuilder);
   }
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion* aInvalidRegion) MOZ_OVERRIDE
   {
@@ -2460,17 +2461,17 @@ public:
       }
       aRect = aRect.Union(temp);
     }
     aRect += ToReferenceFrame();
     return !aRect.IsEmpty();
   }
   NS_DISPLAY_DECL_NAME("WrapList", TYPE_WRAP_LIST)
 
-  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder);
+  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
                                     
   virtual nsDisplayList* GetSameCoordinateSystemChildren() MOZ_OVERRIDE
   {
     NS_ASSERTION(mList.IsEmpty() || !ReferenceFrame() ||
                  !mList.GetBottom()->ReferenceFrame() ||
                  mList.GetBottom()->ReferenceFrame() == ReferenceFrame(),
                  "Children must have same reference frame");
     return &mList;
@@ -2591,17 +2592,18 @@ public:
 class nsDisplayMixBlendMode : public nsDisplayWrapList {
 public:
   nsDisplayMixBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                         nsDisplayList* aList, uint32_t aFlags = 0);
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayMixBlendMode();
 #endif
 
-  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder, bool* aSnap);
+  nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE;
 
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion* aInvalidRegion) MOZ_OVERRIDE
   {
@@ -2918,30 +2920,33 @@ public:
                       nsDisplayList* aList);
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplaySVGEffects();
 #endif
   
   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                    bool* aSnap) MOZ_OVERRIDE;
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE {
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE {
     *aSnap = false;
     return mEffectsBounds + ToReferenceFrame();
   }
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                    nsRegion* aVisibleRegion,
                                    const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;  
-  virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
+  virtual bool TryMerge(nsDisplayListBuilder* aBuilder,
+                        nsDisplayItem* aItem) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("SVGEffects", TYPE_SVG_EFFECTS)
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
-                                   const ContainerLayerParameters& aParameters);
+                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
  
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
   
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion* aInvalidRegion) MOZ_OVERRIDE
@@ -2999,17 +3004,17 @@ public:
   virtual ~nsDisplayTransform()
   {
     MOZ_COUNT_DTOR(nsDisplayTransform);
   }
 #endif
 
   NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
 
-  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
+  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
       return nsRect();
     bool snap;
     return GetBounds(aBuilder, &snap);
   }
 
   virtual nsDisplayList* GetChildren() MOZ_OVERRIDE { return mStoredList.GetChildren(); }
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -442,17 +442,17 @@ public:
 };
 
 class nsDocumentShownDispatcher : public nsRunnable
 {
 public:
   nsDocumentShownDispatcher(nsCOMPtr<nsIDocument> aDocument)
   : mDocument(aDocument) {}
 
-  NS_IMETHOD Run();
+  NS_IMETHOD Run() MOZ_OVERRIDE;
 
 private:
   nsCOMPtr<nsIDocument> mDocument;
 };
 
 
 //------------------------------------------------------------------
 // nsDocumentViewer
--- a/layout/base/nsFrameTraversal.cpp
+++ b/layout/base/nsFrameTraversal.cpp
@@ -14,23 +14,23 @@ class nsFrameIterator : public nsIFrameE
 {
 public:
   typedef nsIFrame::ChildListID ChildListID;
 
   NS_DECL_ISUPPORTS
 
   virtual ~nsFrameIterator() {}
 
-  virtual void First();
-  virtual void Next();
-  virtual nsIFrame* CurrentItem();
-  virtual bool IsDone();
+  virtual void First() MOZ_OVERRIDE;
+  virtual void Next() MOZ_OVERRIDE;
+  virtual nsIFrame* CurrentItem() MOZ_OVERRIDE;
+  virtual bool IsDone() MOZ_OVERRIDE;
 
-  virtual void Last();
-  virtual void Prev();
+  virtual void Last() MOZ_OVERRIDE;
+  virtual void Prev() MOZ_OVERRIDE;
 
   nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
                   nsIteratorType aType, bool aLockScroll, bool aFollowOOFs);
 
 protected:
   void      setCurrent(nsIFrame *aFrame){mCurrent = aFrame;}
   nsIFrame *getCurrent(){return mCurrent;}
   nsIFrame *getStart(){return mStart;}
@@ -101,21 +101,21 @@ private:
 class nsVisualIterator: public nsFrameIterator
 {
 public:
   nsVisualIterator(nsPresContext* aPresContext, nsIFrame *aStart,
                    nsIteratorType aType, bool aLockScroll, bool aFollowOOFs) :
   nsFrameIterator(aPresContext, aStart, aType, aLockScroll, aFollowOOFs) {}
 
 protected:
-  nsIFrame* GetFirstChildInner(nsIFrame* aFrame);
-  nsIFrame* GetLastChildInner(nsIFrame* aFrame);  
+  nsIFrame* GetFirstChildInner(nsIFrame* aFrame) MOZ_OVERRIDE;
+  nsIFrame* GetLastChildInner(nsIFrame* aFrame) MOZ_OVERRIDE;  
   
-  nsIFrame* GetNextSiblingInner(nsIFrame* aFrame);
-  nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame);  
+  nsIFrame* GetNextSiblingInner(nsIFrame* aFrame) MOZ_OVERRIDE;
+  nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame) MOZ_OVERRIDE;  
 };
 
 /************IMPLEMENTATIONS**************/
 
 nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult)
 {
   NS_ENSURE_ARG_POINTER(aResult);
   *aResult = nullptr;
--- a/layout/base/nsLayoutDebugger.cpp
+++ b/layout/base/nsLayoutDebugger.cpp
@@ -22,32 +22,32 @@ using namespace mozilla::layers;
 #ifdef DEBUG
 class nsLayoutDebugger : public nsILayoutDebugger {
 public:
   nsLayoutDebugger();
   virtual ~nsLayoutDebugger();
 
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD SetShowFrameBorders(bool aEnable);
+  NS_IMETHOD SetShowFrameBorders(bool aEnable) MOZ_OVERRIDE;
 
-  NS_IMETHOD GetShowFrameBorders(bool* aResult);
+  NS_IMETHOD GetShowFrameBorders(bool* aResult) MOZ_OVERRIDE;
 
-  NS_IMETHOD SetShowEventTargetFrameBorder(bool aEnable);
+  NS_IMETHOD SetShowEventTargetFrameBorder(bool aEnable) MOZ_OVERRIDE;
 
-  NS_IMETHOD GetShowEventTargetFrameBorder(bool* aResult);
+  NS_IMETHOD GetShowEventTargetFrameBorder(bool* aResult) MOZ_OVERRIDE;
 
   NS_IMETHOD GetContentSize(nsIDocument* aDocument,
-                            int32_t* aSizeInBytesResult);
+                            int32_t* aSizeInBytesResult) MOZ_OVERRIDE;
 
   NS_IMETHOD GetFrameSize(nsIPresShell* aPresentation,
-                          int32_t* aSizeInBytesResult);
+                          int32_t* aSizeInBytesResult) MOZ_OVERRIDE;
 
   NS_IMETHOD GetStyleSize(nsIPresShell* aPresentation,
-                          int32_t* aSizeInBytesResult);
+                          int32_t* aSizeInBytesResult) MOZ_OVERRIDE;
 
 };
 
 nsresult
 NS_NewLayoutDebugger(nsILayoutDebugger** aResult)
 {
   NS_PRECONDITION(aResult, "null OUT ptr");
   if (!aResult) {
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2557,17 +2557,17 @@ struct BoxToRect : public nsLayoutUtils:
   nsIFrame* mRelativeTo;
   nsLayoutUtils::RectCallback* mCallback;
   uint32_t mFlags;
 
   BoxToRect(nsIFrame* aRelativeTo, nsLayoutUtils::RectCallback* aCallback,
             uint32_t aFlags)
     : mRelativeTo(aRelativeTo), mCallback(aCallback), mFlags(aFlags) {}
 
-  virtual void AddBox(nsIFrame* aFrame) {
+  virtual void AddBox(nsIFrame* aFrame) MOZ_OVERRIDE {
     nsRect r;
     nsIFrame* outer = nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(aFrame, &r);
     if (!outer) {
       outer = aFrame;
       switch (mFlags & nsLayoutUtils::RECTS_WHICH_BOX_MASK) {
         case nsLayoutUtils::RECTS_USE_CONTENT_BOX:
           r = aFrame->GetContentRectRelativeToSelf();
           break;
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2457,17 +2457,17 @@ public:
   DelayedFireDOMPaintEvent(nsPresContext* aPresContext,
                            nsInvalidateRequestList* aList)
     : mPresContext(aPresContext)
   {
     MOZ_ASSERT(mPresContext->GetContainerWeak(),
                "DOMPaintEvent requested for a detached pres context");
     mList.TakeFrom(aList);
   }
-  NS_IMETHOD Run()
+  NS_IMETHOD Run() MOZ_OVERRIDE
   {
     // The pres context might have been detached during the delay -
     // that's fine, just don't fire the event.
     if (mPresContext->GetContainerWeak()) {
       mPresContext->FireDOMPaintEvent(&mList);
     }
     return NS_OK;
   }
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -443,17 +443,17 @@ public:
   PresShell* mShell;
 };
 
 class MOZ_STACK_CLASS nsPresShellEventCB : public nsDispatchingCallback
 {
 public:
   nsPresShellEventCB(PresShell* aPresShell) : mPresShell(aPresShell) {}
 
-  virtual void HandleEvent(nsEventChainPostVisitor& aVisitor)
+  virtual void HandleEvent(nsEventChainPostVisitor& aVisitor) MOZ_OVERRIDE
   {
     if (aVisitor.mPresContext && aVisitor.mEvent->eventStructType != NS_EVENT) {
       if (aVisitor.mEvent->message == NS_MOUSE_BUTTON_DOWN ||
           aVisitor.mEvent->message == NS_MOUSE_BUTTON_UP) {
         // Mouse-up and mouse-down events call nsFrame::HandlePress/Release
         // which call GetContentOffsetsFromPoint which requires up-to-date layout.
         // Bring layout up-to-date now so that GetCurrentEventFrame() below
         // will return a real frame and we don't have to worry about
@@ -496,17 +496,17 @@ public:
 class nsBeforeFirstPaintDispatcher : public nsRunnable
 {
 public:
   nsBeforeFirstPaintDispatcher(nsIDocument* aDocument)
   : mDocument(aDocument) {}
 
   // Fires the "before-first-paint" event so that interested parties (right now, the
   // mobile browser) are aware of it.
-  NS_IMETHOD Run()
+  NS_IMETHOD Run() MOZ_OVERRIDE
   {
     nsCOMPtr<nsIObserverService> observerService =
       mozilla::services::GetObserverService();
     if (observerService) {
       observerService->NotifyObservers(mDocument, "before-first-paint",
                                        nullptr);
     }
     return NS_OK;
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -68,16 +68,18 @@
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #include "nsXULContentUtils.h"
 #include "nsXULPrototypeCache.h"
 #include "nsXULTooltipListener.h"
 
 #include "inDOMView.h"
+
+#include "nsMenuBarListener.h"
 #endif
 
 #include "nsHTMLEditor.h"
 #include "nsTextServicesDocument.h"
 
 #ifdef MOZ_WEBSPEECH
 #include "nsSynthVoiceRegistry.h"
 #endif
@@ -276,16 +278,20 @@ nsLayoutStatics::Initialize()
   ProcessPriorityManager::Init();
 
   nsPermissionManager::AppClearDataObserverInit();
   nsCookieService::AppClearDataObserverInit();
   nsApplicationCacheService::AppClearDataObserverInit();
 
   HTMLVideoElement::Init();
 
+#ifdef MOZ_XUL
+  nsMenuBarListener::InitializeStatics();
+#endif
+
   CacheObserver::Init();
 
   return NS_OK;
 }
 
 void
 nsLayoutStatics::Shutdown()
 {
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -68,18 +68,19 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayButtonBoxShadowOuter() {
     MOZ_COUNT_DTOR(nsDisplayButtonBoxShadowOuter);
   }
 #endif  
   
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("ButtonBoxShadowOuter", TYPE_BUTTON_BOX_SHADOW_OUTER)
 private:
   nsButtonFrameRenderer* mBFR;
 };
 
 nsRect
 nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
   *aSnap = false;
@@ -107,22 +108,24 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayButtonBorderBackground() {
     MOZ_COUNT_DTOR(nsDisplayButtonBorderBackground);
   }
 #endif  
   
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE {
     aOutFrames->AppendElement(mFrame);
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE;
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion *aInvalidRegion) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND)
 private:
   nsButtonFrameRenderer* mBFR;
 };
 
@@ -142,17 +145,17 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayButtonForeground() {
     MOZ_COUNT_DTOR(nsDisplayButtonForeground);
   }
 #endif  
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("ButtonForeground", TYPE_BUTTON_FOREGROUND)
 private:
   nsButtonFrameRenderer* mBFR;
 };
 
 void
 nsDisplayButtonBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                                            const nsDisplayItemGeometry* aGeometry,
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -70,17 +70,17 @@ class nsPresState;
  * combo box is toggled to open or close. this is used by Accessibility which presses
  * that button Programmatically.
  */
 class nsComboButtonListener : public nsIDOMEventListener
 {
 public:
   NS_DECL_ISUPPORTS
 
-  NS_IMETHOD HandleEvent(nsIDOMEvent*)
+  NS_IMETHOD HandleEvent(nsIDOMEvent*) MOZ_OVERRIDE
   {
     mComboBox->ShowDropDown(!mComboBox->IsDroppedDown());
     return NS_OK;
   }
 
   nsComboButtonListener(nsComboboxControlFrame* aCombobox)
   {
     mComboBox = aCombobox;
@@ -366,24 +366,24 @@ public:
   {
     MOZ_COUNT_CTOR(nsResizeDropdownAtFinalPosition);
   }
   ~nsResizeDropdownAtFinalPosition()
   {
     MOZ_COUNT_DTOR(nsResizeDropdownAtFinalPosition);
   }
 
-  virtual bool ReflowFinished()
+  virtual bool ReflowFinished() MOZ_OVERRIDE
   {
     Run();
     NS_RELEASE_THIS();
     return false;
   }
 
-  virtual void ReflowCallbackCanceled()
+  virtual void ReflowCallbackCanceled() MOZ_OVERRIDE
   {
     NS_RELEASE_THIS();
   }
 
   NS_IMETHODIMP Run()
   {
     if (mFrame.IsAlive()) {
       static_cast<nsComboboxControlFrame*>(mFrame.GetFrame())->
@@ -1213,28 +1213,28 @@ public:
   nsComboboxDisplayFrame (nsStyleContext* aContext,
                           nsComboboxControlFrame* aComboBox)
     : nsBlockFrame(aContext),
       mComboBox(aComboBox)
   {}
 
   // Need this so that line layout knows that this block's width
   // depends on the available width.
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsBlockFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplacedContainsBlock));
   }
 
   virtual nsresult Reflow(nsPresContext*           aPresContext,
                           nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
-                          nsReflowStatus&          aStatus);
+                          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
 protected:
   nsComboboxControlFrame* mComboBox;
 };
@@ -1444,17 +1444,17 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayComboboxFocus() {
     MOZ_COUNT_DTOR(nsDisplayComboboxFocus);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("ComboboxFocus", TYPE_COMBOBOX_FOCUS)
 };
 
 void nsDisplayComboboxFocus::Paint(nsDisplayListBuilder* aBuilder,
                                    nsRenderingContext* aCtx)
 {
   static_cast<nsComboboxControlFrame*>(mFrame)
     ->PaintFocus(*aCtx, ToReferenceFrame());
--- a/layout/forms/nsComboboxControlFrame.h
+++ b/layout/forms/nsComboboxControlFrame.h
@@ -71,17 +71,17 @@ public:
 
   virtual nsresult Reflow(nsPresContext*           aCX,
                           nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
                           nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual nsresult HandleEvent(nsPresContext* aPresContext,
                                mozilla::WidgetGUIEvent* aEvent,
-                               nsEventStatus* aEventStatus);
+                               nsEventStatus* aEventStatus) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   void PaintFocus(nsRenderingContext& aRenderingContext, nsPoint aPt);
 
   // XXXbz this is only needed to prevent the quirk percent height stuff from
@@ -90,30 +90,30 @@ public:
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsBlockFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
   }
 
-  virtual nsIScrollableFrame* GetScrollTargetFrame() {
+  virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE {
     return do_QueryFrame(mDropdownFrame);
   }
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
   virtual nsresult SetInitialChildList(ChildListID     aListID,
                                        nsFrameList&    aChildList) MOZ_OVERRIDE;
   virtual const nsFrameList& GetChildList(ChildListID aListID) const MOZ_OVERRIDE;
   virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
 
-  virtual nsIFrame* GetContentInsertionFrame();
+  virtual nsIFrame* GetContentInsertionFrame() MOZ_OVERRIDE;
 
   // nsIFormControlFrame
   virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE;
   /**
    * Inform the control that it got (or lost) focus.
    * If it lost focus, the dropdown menu will be rolled up if needed,
    * and FireOnChange() will be called.
    * @param aOn true if got focus, false if lost focus.
--- a/layout/forms/nsFieldSetFrame.cpp
+++ b/layout/forms/nsFieldSetFrame.cpp
@@ -101,19 +101,20 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayFieldSetBorderBackground() {
     MOZ_COUNT_DTOR(nsDisplayFieldSetBorderBackground);
   }
 #endif
 
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion *aInvalidRegion) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("FieldSetBorderBackground", TYPE_FIELDSET_BORDER_BACKGROUND)
 };
 
 void nsDisplayFieldSetBorderBackground::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                                                 HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
--- a/layout/forms/nsFieldSetFrame.h
+++ b/layout/forms/nsFieldSetFrame.h
@@ -1,84 +1,85 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsFieldSetFrame_h___
 #define nsFieldSetFrame_h___
 
+#include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
 
 class nsFieldSetFrame MOZ_FINAL : public nsContainerFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   nsFieldSetFrame(nsStyleContext* aContext);
 
   NS_HIDDEN_(nscoord)
     GetIntrinsicWidth(nsRenderingContext* aRenderingContext,
                       nsLayoutUtils::IntrinsicWidthType);
-  virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext);
+  virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
   virtual nsSize ComputeSize(nsRenderingContext *aRenderingContext,
                              nsSize aCBSize, nscoord aAvailableWidth,
                              nsSize aMargin, nsSize aBorder, nsSize aPadding,
                              uint32_t aFlags) MOZ_OVERRIDE;
-  virtual nscoord GetBaseline() const;
+  virtual nscoord GetBaseline() const MOZ_OVERRIDE;
 
   /**
    * The area to paint box-shadows around.  It's the border rect except
    * when there's a <legend> we offset the y-position to the center of it.
    */
   virtual nsRect VisualBorderRectRelativeToSelf() const MOZ_OVERRIDE;
 
   virtual nsresult Reflow(nsPresContext*           aPresContext,
                           nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
-                          nsReflowStatus&          aStatus);
+                          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
                                
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   void PaintBorderBackground(nsRenderingContext& aRenderingContext,
     nsPoint aPt, const nsRect& aDirtyRect, uint32_t aBGFlags);
 
   virtual nsresult AppendFrames(ChildListID    aListID,
-                                nsFrameList&   aFrameList);
+                                nsFrameList&   aFrameList) MOZ_OVERRIDE;
   virtual nsresult InsertFrames(ChildListID    aListID,
                                 nsIFrame*      aPrevFrame,
-                                nsFrameList&   aFrameList);
+                                nsFrameList&   aFrameList) MOZ_OVERRIDE;
   virtual nsresult RemoveFrame(ChildListID    aListID,
-                               nsIFrame*      aOldFrame);
+                               nsIFrame*      aOldFrame) MOZ_OVERRIDE;
 
-  virtual nsIAtom* GetType() const;
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsContainerFrame::IsFrameOfType(aFlags &
              ~nsIFrame::eCanContainOverflowContainers);
   }
   virtual nsIScrollableFrame* GetScrollTargetFrame() MOZ_OVERRIDE
   {
     return do_QueryFrame(GetInner());
   }
 
 #ifdef ACCESSIBILITY  
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
 #ifdef DEBUG
   virtual nsresult SetInitialChildList(ChildListID    aListID,
-                                       nsFrameList&   aChildList);
+                                       nsFrameList&   aChildList) MOZ_OVERRIDE;
 #endif
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const {
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE {
     return MakeFrameName(NS_LITERAL_STRING("FieldSet"), aResult);
   }
 #endif
 
   /**
    * Return the anonymous frame that contains all descendants except
    * the legend frame.  This is currently always a block frame with
    * pseudo nsCSSAnonBoxes::fieldsetContent -- this may change in the
--- a/layout/forms/nsFileControlFrame.h
+++ b/layout/forms/nsFileControlFrame.h
@@ -44,18 +44,18 @@ public:
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
                                     nsIAtom*        aAttribute,
                                     int32_t         aModType) MOZ_OVERRIDE;
-  virtual void ContentStatesChanged(nsEventStates aStates);
-  virtual bool IsLeaf() const
+  virtual void ContentStatesChanged(nsEventStates aStates) MOZ_OVERRIDE;
+  virtual bool IsLeaf() const MOZ_OVERRIDE
   {
     return true;
   }
 
   // nsIAnonymousContentCreator
   virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
--- a/layout/forms/nsNumberControlFrame.h
+++ b/layout/forms/nsNumberControlFrame.h
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsNumberControlFrame_h__
 #define nsNumberControlFrame_h__
 
+#include "mozilla/Attributes.h"
 #include "nsContainerFrame.h"
 #include "nsIFormControlFrame.h"
 #include "nsIAnonymousContentCreator.h"
 #include "nsCOMPtr.h"
 
 class nsPresContext;
 
 namespace mozilla {
@@ -38,17 +39,17 @@ class nsNumberControlFrame MOZ_FINAL : p
   nsNumberControlFrame(nsStyleContext* aContext);
 
 public:
   NS_DECL_QUERYFRAME_TARGET(nsNumberControlFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
-  virtual void ContentStatesChanged(nsEventStates aStates);
+  virtual void ContentStatesChanged(nsEventStates aStates) MOZ_OVERRIDE;
   virtual bool IsLeaf() const MOZ_OVERRIDE { return true; }
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
   virtual nscoord GetMinWidth(nsRenderingContext* aRenderingContext) MOZ_OVERRIDE;
 
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -162,26 +162,27 @@ public:
       mStyle(aStyle), mAscent(aAscent), mIndex(aIndex) {
     MOZ_COUNT_CTOR(nsDisplayTextOverflowMarker);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayTextOverflowMarker() {
     MOZ_COUNT_DTOR(nsDisplayTextOverflowMarker);
   }
 #endif
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE {
     *aSnap = false;
     nsRect shadowRect =
       nsLayoutUtils::GetTextShadowRectsUnion(mRect, mFrame);
     return mRect.Union(shadowRect);
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
 
-  virtual uint32_t GetPerFrameKey() { 
+  virtual uint32_t GetPerFrameKey() MOZ_OVERRIDE { 
     return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); 
   }
   void PaintTextToContext(nsRenderingContext* aCtx,
                           nsPoint aOffsetFromRect);
   NS_DISPLAY_DECL_NAME("TextOverflow", TYPE_TEXT_OVERFLOW)
 private:
   nsRect          mRect;   // in reference frame coordinates
   const nsStyleTextOverflowSide* mStyle;
--- a/layout/generic/nsBRFrame.cpp
+++ b/layout/generic/nsBRFrame.cpp
@@ -21,38 +21,39 @@
 using namespace mozilla;
 
 class BRFrame : public nsFrame {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewBRFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
-  virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
+  virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint) MOZ_OVERRIDE;
 
-  virtual bool PeekOffsetNoAmount(bool aForward, int32_t* aOffset);
+  virtual bool PeekOffsetNoAmount(bool aForward, int32_t* aOffset) MOZ_OVERRIDE;
   virtual bool PeekOffsetCharacter(bool aForward, int32_t* aOffset,
-                                     bool aRespectClusters = true);
-  virtual bool PeekOffsetWord(bool aForward, bool aWordSelectEatSpace, bool aIsKeyboardSelect,
-                                int32_t* aOffset, PeekWordState* aState);
+                                     bool aRespectClusters = true) MOZ_OVERRIDE;
+  virtual bool PeekOffsetWord(bool aForward, bool aWordSelectEatSpace,
+                              bool aIsKeyboardSelect, int32_t* aOffset,
+                              PeekWordState* aState) MOZ_OVERRIDE;
 
   virtual nsresult Reflow(nsPresContext* aPresContext,
                           nsHTMLReflowMetrics& aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
-                          nsReflowStatus& aStatus);
+                          nsReflowStatus& aStatus) MOZ_OVERRIDE;
   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
-                                 InlineMinWidthData *aData);
+                                 InlineMinWidthData *aData) MOZ_OVERRIDE;
   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
-                                  InlinePrefWidthData *aData);
-  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext);
-  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext);
-  virtual nsIAtom* GetType() const;
-  virtual nscoord GetBaseline() const;
+                                  InlinePrefWidthData *aData) MOZ_OVERRIDE;
+  virtual nscoord GetMinWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
+  virtual nscoord GetBaseline() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eReplaced |
                                              nsIFrame::eLineParticipant));
   }
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -201,43 +201,45 @@ public:
     MOZ_COUNT_CTOR(nsDisplayBullet);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayBullet() {
     MOZ_COUNT_DTOR(nsDisplayBullet);
   }
 #endif
 
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE
   {
     *aSnap = false;
     return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
   }
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE {
     aOutFrames->AppendElement(mFrame);
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("Bullet", TYPE_BULLET)
 
-  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
+  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     bool snap;
     return GetBounds(aBuilder, &snap);
   }
 
-  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
+  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     return new nsDisplayBulletGeometry(this, aBuilder);
   }
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion *aInvalidRegion)
+                                         nsRegion *aInvalidRegion) MOZ_OVERRIDE
   {
     const nsDisplayBulletGeometry* geometry = static_cast<const nsDisplayBulletGeometry*>(aGeometry);
     nsBulletFrame* f = static_cast<nsBulletFrame*>(mFrame);
 
     if (f->GetOrdinal() != geometry->mOrdinal) {
       bool snap;
       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
       return;
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -296,26 +296,27 @@ public:
     : nsDisplayItem(aBuilder, aFrame)
   {
     MOZ_COUNT_CTOR(nsDisplayCanvasFocus);
   }
   virtual ~nsDisplayCanvasFocus() {
     MOZ_COUNT_DTOR(nsDisplayCanvasFocus);
   }
 
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE
   {
     *aSnap = false;
     // This is an overestimate, but that's not a problem.
     nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
     return frame->CanvasArea() + ToReferenceFrame();
   }
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx)
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE
   {
     nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
     frame->PaintFocus(*aCtx, ToReferenceFrame());
   }
 
   NS_DISPLAY_DECL_NAME("CanvasFocus", TYPE_CANVAS_FOCUS)
 };
 
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -1346,17 +1346,17 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplaySelectionOverlay() {
     MOZ_COUNT_DTOR(nsDisplaySelectionOverlay);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("SelectionOverlay", TYPE_SELECTION_OVERLAY)
 private:
   int16_t mSelectionValue;
 };
 
 void nsDisplaySelectionOverlay::Paint(nsDisplayListBuilder* aBuilder,
                                       nsRenderingContext* aCtx)
 {
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -78,46 +78,46 @@ void nsFramesetDrag::UnSet()
  * nsHTMLFramesetBorderFrame
  ******************************************************************************/
 class nsHTMLFramesetBorderFrame : public nsLeafFrame
 {
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const;
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 
   virtual nsresult HandleEvent(nsPresContext* aPresContext,
                                WidgetGUIEvent* aEvent,
-                               nsEventStatus* aEventStatus);
+                               nsEventStatus* aEventStatus) MOZ_OVERRIDE;
 
   virtual nsresult GetCursor(const nsPoint&    aPoint,
-                             nsIFrame::Cursor& aCursor);
+                             nsIFrame::Cursor& aCursor) MOZ_OVERRIDE;
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   virtual nsresult Reflow(nsPresContext*           aPresContext,
                           nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
-                          nsReflowStatus&          aStatus);
+                          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   bool GetVisibility() { return mVisibility || mVisibilityOverride; }
   void SetVisibility(bool aVisibility);
   void SetColor(nscolor aColor);
 
   void PaintBorder(nsRenderingContext& aRenderingContext, nsPoint aPt);
 
 protected:
   nsHTMLFramesetBorderFrame(nsStyleContext* aContext, int32_t aWidth, bool aVertical, bool aVisible);
   virtual ~nsHTMLFramesetBorderFrame();
-  virtual nscoord GetIntrinsicWidth();
-  virtual nscoord GetIntrinsicHeight();
+  virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE;
+  virtual nscoord GetIntrinsicHeight() MOZ_OVERRIDE;
 
   // the prev and next neighbors are indexes into the row (for a horizontal border) or col (for
   // a vertical border) of nsHTMLFramesetFrames or nsHTMLFrames
   int32_t mPrevNeighbor;
   int32_t mNextNeighbor;
   nscolor mColor;
   int32_t mWidth;
   bool mVertical;
@@ -132,36 +132,36 @@ protected:
 class nsHTMLFramesetBlankFrame : public nsLeafFrame
 {
 public:
   NS_DECL_QUERYFRAME_TARGET(nsHTMLFramesetBlankFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("FramesetBlank"), aResult);
   }
 #endif
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   virtual nsresult Reflow(nsPresContext*           aPresContext,
                           nsHTMLReflowMetrics&     aDesiredSize,
                           const nsHTMLReflowState& aReflowState,
-                          nsReflowStatus&          aStatus);
+                          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
 protected:
   nsHTMLFramesetBlankFrame(nsStyleContext* aContext) : nsLeafFrame(aContext) {}
   virtual ~nsHTMLFramesetBlankFrame();
-  virtual nscoord GetIntrinsicWidth();
-  virtual nscoord GetIntrinsicHeight();
+  virtual nscoord GetIntrinsicWidth() MOZ_OVERRIDE;
+  virtual nscoord GetIntrinsicHeight() MOZ_OVERRIDE;
 
   friend class nsHTMLFramesetFrame;
   friend class nsHTMLFrameset;
 };
 
 /*******************************************************************************
  * nsHTMLFramesetFrame
  ******************************************************************************/
@@ -1465,21 +1465,22 @@ public:
   virtual ~nsDisplayFramesetBorder() {
     MOZ_COUNT_DTOR(nsDisplayFramesetBorder);
   }
 #endif
 
   // REVIEW: see old GetFrameForPoint
   // Receives events in its bounds
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE {
     aOutFrames->AppendElement(mFrame);
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("FramesetBorder", TYPE_FRAMESET_BORDER)
 };
 
 void nsDisplayFramesetBorder::Paint(nsDisplayListBuilder* aBuilder,
                                     nsRenderingContext* aCtx)
 {
   static_cast<nsHTMLFramesetBorderFrame*>(mFrame)->
     PaintBorder(*aCtx, ToReferenceFrame());
@@ -1668,17 +1669,18 @@ public:
     MOZ_COUNT_CTOR(nsDisplayFramesetBlank);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayFramesetBlank() {
     MOZ_COUNT_DTOR(nsDisplayFramesetBlank);
   }
 #endif
 
-  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
+  virtual void Paint(nsDisplayListBuilder* aBuilder,
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("FramesetBlank", TYPE_FRAMESET_BLANK)
 };
 
 void nsDisplayFramesetBlank::Paint(nsDisplayListBuilder* aBuilder,
                                    nsRenderingContext* aCtx)
 {
   nscolor white = NS_RGB(255,255,255);
   aCtx->SetColor(white);
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1330,17 +1330,17 @@ public:
     if (!RefreshDriver(aCallee)->AddRefreshObserver(this, Flush_Style)) {
       return false;
     }
 
     mCallee = aCallee;
     return true;
   }
 
-  virtual void WillRefresh(mozilla::TimeStamp aTime) {
+  virtual void WillRefresh(mozilla::TimeStamp aTime) MOZ_OVERRIDE {
     // The callback may release "this".
     // We don't access members after returning, so no need for KungFuDeathGrip.
     ScrollFrameHelper::AsyncScrollCallback(mCallee, aTime);
   }
 
 private:
   ScrollFrameHelper *mCallee;
 
@@ -2191,23 +2191,23 @@ public:
     , mScrollFrame(aScrollFrame)
     , mScrolledFrame(aScrolledFrame)
   {
     SetCount(0);
   }
 
   virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
                                   nsIFrame* aFrame,
-                                  nsDisplayList* aList) {
+                                  nsDisplayList* aList) MOZ_OVERRIDE {
     SetCount(++mCount);
     return new (aBuilder) nsDisplayScrollLayer(aBuilder, aList, mScrolledFrame, mScrolledFrame, mScrollFrame);
   }
 
   virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
-                                  nsDisplayItem* aItem) {
+                                  nsDisplayItem* aItem) MOZ_OVERRIDE {
 
     SetCount(++mCount);
     return new (aBuilder) nsDisplayScrollLayer(aBuilder, aItem, aItem->Frame(), mScrolledFrame, mScrollFrame);
   }
 
 protected:
   void SetCount(intptr_t aCount) {
     mProps.Set(nsIFrame::ScrollLayerCount(), reinterpret_cast<void*>(aCount));
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -531,17 +531,17 @@ public:
 
   virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
   virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE;
 
   // nsIScrollableFrame
   virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE {
     return mHelper.GetScrolledFrame();
   }
-  virtual mozilla::ScrollbarStyles GetScrollbarStyles() const {
+  virtual mozilla::ScrollbarStyles GetScrollbarStyles() const MOZ_OVERRIDE {
     return mHelper.GetScrollbarStylesFromFrame();
   }
   virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE {
     return mHelper.GetScrollbarVisibility();
   }
   virtual nsMargin GetActualScrollbarSizes() const MOZ_OVERRIDE {
     return mHelper.GetActualScrollbarSizes();
   }
@@ -838,17 +838,17 @@ public:
 
   virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
   virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE;
 
   // nsIScrollableFrame
   virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE {
     return mHelper.GetScrolledFrame();
   }
-  virtual mozilla::ScrollbarStyles GetScrollbarStyles() const {
+  virtual mozilla::ScrollbarStyles GetScrollbarStyles() const MOZ_OVERRIDE {
     return mHelper.GetScrollbarStylesFromFrame();
   }
   virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE {
     return mHelper.GetScrollbarVisibility();
   }
   virtual nsMargin GetActualScrollbarSizes() const MOZ_OVERRIDE {
     return mHelper.GetActualScrollbarSizes();
   }
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -31,44 +31,45 @@ public:
   virtual ~nsDisplayCanvas() {
     MOZ_COUNT_DTOR(nsDisplayCanvas);
   }
 #endif
 
   NS_DISPLAY_DECL_NAME("nsDisplayCanvas", TYPE_CANVAS)
 
   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
-                                   bool* aSnap) {
+                                   bool* aSnap) MOZ_OVERRIDE {
     *aSnap = false;
     nsIFrame* f = Frame();
     HTMLCanvasElement *canvas =
       HTMLCanvasElement::FromContent(f->GetContent());
     nsRegion result;
     if (canvas->GetIsOpaque()) {
       result = GetBounds(aBuilder, aSnap);
     }
     return result;
   }
 
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE {
     *aSnap = true;
     nsHTMLCanvasFrame* f = static_cast<nsHTMLCanvasFrame*>(Frame());
     return f->GetInnerArea() + ToReferenceFrame();
   }
 
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
-                                             const ContainerLayerParameters& aContainerParameters)
+                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE
   {
     return static_cast<nsHTMLCanvasFrame*>(mFrame)->
       BuildLayer(aBuilder, aManager, this, aContainerParameters);
   }
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
-                                   const ContainerLayerParameters& aParameters)
+                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
   {
     if (HTMLCanvasElement::FromContent(mFrame->GetContent())->ShouldForceInactiveLayer(aManager))
       return LAYER_INACTIVE;
 
     // If compositing is cheap, just do that
     if (aManager->IsCompositingCheap() ||
         ActiveLayerTracker::IsContentActive(mFrame))
       return mozilla::LAYER_ACTIVE;
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1067,23 +1067,25 @@ struct nsRecessedBorder : public nsStyle
   }
 };
 
 class nsDisplayAltFeedback : public nsDisplayItem {
 public:
   nsDisplayAltFeedback(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
     : nsDisplayItem(aBuilder, aFrame) {}
 
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE
   {
     *aSnap = false;
     return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
   }
 
-  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx)
+  virtual void Paint(nsDisplayListBuilder* aBuilder,
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE
   {
     nsImageFrame* f = static_cast<nsImageFrame*>(mFrame);
     nsEventStates state = f->GetContent()->AsElement()->State();
     f->DisplayAltFeedback(*aCtx,
                           mVisibleRect,
                           IMAGE_OK(state, true)
                              ? nsImageFrame::gIconLoad->mLoadingImage
                              : nsImageFrame::gIconLoad->mBrokenImage,
--- a/layout/generic/nsImageMap.cpp
+++ b/layout/generic/nsImageMap.cpp
@@ -261,19 +261,19 @@ void Area::HasFocus(bool aHasFocus)
 }
 
 //----------------------------------------------------------------------
 
 class DefaultArea : public Area {
 public:
   DefaultArea(nsIContent* aArea);
 
-  virtual bool IsInside(nscoord x, nscoord y) const;
-  virtual void Draw(nsIFrame* aFrame, nsRenderingContext& aRC);
-  virtual void GetRect(nsIFrame* aFrame, nsRect& aRect);
+  virtual bool IsInside(nscoord x, nscoord y) const MOZ_OVERRIDE;
+  virtual void Draw(nsIFrame* aFrame, nsRenderingContext& aRC) MOZ_OVERRIDE;
+  virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) MOZ_OVERRIDE;
 };
 
 DefaultArea::DefaultArea(nsIContent* aArea)
   : Area(aArea)
 {
 }
 
 bool DefaultArea::IsInside(nscoord x, nscoord y) const
@@ -306,20 +306,20 @@ void DefaultArea::GetRect(nsIFrame* aFra
 }
 
 //----------------------------------------------------------------------
 
 class RectArea : public Area {
 public:
   RectArea(nsIContent* aArea);
 
-  virtual void ParseCoords(const nsAString& aSpec);
-  virtual bool IsInside(nscoord x, nscoord y) const;
-  virtual void Draw(nsIFrame* aFrame, nsRenderingContext& aRC);
-  virtual void GetRect(nsIFrame* aFrame, nsRect& aRect);
+  virtual void ParseCoords(const nsAString& aSpec) MOZ_OVERRIDE;
+  virtual bool IsInside(nscoord x, nscoord y) const MOZ_OVERRIDE;
+  virtual void Draw(nsIFrame* aFrame, nsRenderingContext& aRC) MOZ_OVERRIDE;
+  virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) MOZ_OVERRIDE;
 };
 
 RectArea::RectArea(nsIContent* aArea)
   : Area(aArea)
 {
 }
 
 void RectArea::ParseCoords(const nsAString& aSpec)
@@ -408,20 +408,20 @@ void RectArea::GetRect(nsIFrame* aFrame,
 }
 
 //----------------------------------------------------------------------
 
 class PolyArea : public Area {
 public:
   PolyArea(nsIContent* aArea);
 
-  virtual void ParseCoords(const nsAString& aSpec);
-  virtual bool IsInside(nscoord x, nscoord y) const;
-  virtual void Draw(nsIFrame* aFrame, nsRenderingContext& aRC);
-  virtual void GetRect(nsIFrame* aFrame, nsRect& aRect);
+  virtual void ParseCoords(const nsAString& aSpec) MOZ_OVERRIDE;
+  virtual bool IsInside(nscoord x, nscoord y) const MOZ_OVERRIDE;
+  virtual void Draw(nsIFrame* aFrame, nsRenderingContext& aRC) MOZ_OVERRIDE;
+  virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) MOZ_OVERRIDE;
 };
 
 PolyArea::PolyArea(nsIContent* aArea)
   : Area(aArea)
 {
 }
 
 void PolyArea::ParseCoords(const nsAString& aSpec)
@@ -548,20 +548,20 @@ void PolyArea::GetRect(nsIFrame* aFrame,
 }
 
 //----------------------------------------------------------------------
 
 class CircleArea : public Area {
 public:
   CircleArea(nsIContent* aArea);
 
-  virtual void ParseCoords(const nsAString& aSpec);
-  virtual bool IsInside(nscoord x, nscoord y) const;
-  virtual void Draw(nsIFrame* aFrame, nsRenderingContext& aRC);
-  virtual void GetRect(nsIFrame* aFrame, nsRect& aRect);
+  virtual void ParseCoords(const nsAString& aSpec) MOZ_OVERRIDE;
+  virtual bool IsInside(nscoord x, nscoord y) const MOZ_OVERRIDE;
+  virtual void Draw(nsIFrame* aFrame, nsRenderingContext& aRC) MOZ_OVERRIDE;
+  virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) MOZ_OVERRIDE;
 };
 
 CircleArea::CircleArea(nsIContent* aArea)
   : Area(aArea)
 {
 }
 
 void CircleArea::ParseCoords(const nsAString& aSpec)
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -850,33 +850,34 @@ public:
     MOZ_COUNT_CTOR(nsDisplayPluginReadback);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayPluginReadback() {
     MOZ_COUNT_DTOR(nsDisplayPluginReadback);
   }
 #endif
 
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE;
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                    nsRegion* aVisibleRegion,
-                                   const nsRect& aAllowVisibleRegionExpansion);
+                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
 
   NS_DISPLAY_DECL_NAME("PluginReadback", TYPE_PLUGIN_READBACK)
 
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
-                                             const ContainerLayerParameters& aContainerParameters)
+                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE
   {
     return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
   }
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
-                                   const ContainerLayerParameters& aParameters)
+                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
   {
     return LAYER_ACTIVE;
   }
 };
 
 static nsRect
 GetDisplayItemBounds(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, nsIFrame* aFrame)
 {
@@ -920,33 +921,34 @@ public:
     MOZ_COUNT_CTOR(nsDisplayPluginVideo);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayPluginVideo() {
     MOZ_COUNT_DTOR(nsDisplayPluginVideo);
   }
 #endif
 
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE;
   virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                    nsRegion* aVisibleRegion,
-                                   const nsRect& aAllowVisibleRegionExpansion);
+                                   const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
 
   NS_DISPLAY_DECL_NAME("PluginVideo", TYPE_PLUGIN_VIDEO)
 
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
-                                             const ContainerLayerParameters& aContainerParameters)
+                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE
   {
     return static_cast<nsObjectFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
   }
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
-                                   const ContainerLayerParameters& aParameters)
+                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
   {
     return LAYER_ACTIVE;
   }
 
   nsNPAPIPluginInstance::VideoInfo* VideoInfo() { return mVideoInfo; }
 
 private:
   nsNPAPIPluginInstance::VideoInfo* mVideoInfo;
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -195,17 +195,17 @@ public:
   }
 
   nsresult SetDelay(uint32_t aDelay)
   {
     mDelay = aDelay;
     return NS_OK;
   }
 
-  NS_IMETHOD Notify(nsITimer *timer)
+  NS_IMETHOD Notify(nsITimer *timer) MOZ_OVERRIDE
   {
     if (mSelection && mPresContext)
     {
       nsWeakFrame frame =
         mContent ? mPresContext->GetPrimaryFrameFor(mContent) : nullptr;
       if (!frame)
         return NS_OK;
       mContent = nullptr;
--- a/layout/generic/nsSplittableFrame.h
+++ b/layout/generic/nsSplittableFrame.h
@@ -91,17 +91,17 @@ protected:
    */
   nscoord GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState,
                                      nscoord aConsumed = NS_INTRINSICSIZE) const;
 
   /**
    * @see nsIFrame::GetSkipSides()
    * @see nsIFrame::ApplySkipSides()
    */
-  virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const;
+  virtual int GetSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE;
 
 #ifdef DEBUG
   virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) MOZ_OVERRIDE;
 #endif
 
   nsIFrame*   mPrevContinuation;
   nsIFrame*   mNextContinuation;
 };
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -972,27 +972,27 @@ public:
   public:
     BreakSink(gfxTextRun* aTextRun, gfxContext* aContext, uint32_t aOffsetIntoTextRun,
               bool aExistingTextRun) :
                 mTextRun(aTextRun), mContext(aContext),
                 mOffsetIntoTextRun(aOffsetIntoTextRun),
                 mChangedBreaks(false), mExistingTextRun(aExistingTextRun) {}
 
     virtual void SetBreaks(uint32_t aOffset, uint32_t aLength,
-                           uint8_t* aBreakBefore) {
+                           uint8_t* aBreakBefore) MOZ_OVERRIDE {
       if (mTextRun->SetPotentialLineBreaks(aOffset + mOffsetIntoTextRun, aLength,
                                            aBreakBefore, mContext)) {
         mChangedBreaks = true;
         // Be conservative and assume that some breaks have been set
         mTextRun->ClearFlagBits(nsTextFrameUtils::TEXT_NO_BREAKS);
       }
     }
     
     virtual void SetCapitalization(uint32_t aOffset, uint32_t aLength,
-                                   bool* aCapitalize) {
+                                   bool* aCapitalize) MOZ_OVERRIDE {
       NS_ASSERTION(mTextRun->GetFlags() & nsTextFrameUtils::TEXT_IS_TRANSFORMED,
                    "Text run should be transformed!");
       nsTransformedTextRun* transformedTextRun =
         static_cast<nsTransformedTextRun*>(mTextRun);
       transformedTextRun->SetCapitalization(aOffset + mOffsetIntoTextRun, aLength,
                                             aCapitalize, mContext);
     }
 
@@ -3920,54 +3920,56 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
   friend nsIFrame* NS_NewContinuingTextFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
 
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
-
-  virtual nsIFrame* GetPrevContinuation() const {
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
+
+  virtual nsIFrame* GetPrevContinuation() const MOZ_OVERRIDE {
     return mPrevContinuation;
   }
-  virtual void SetPrevContinuation(nsIFrame* aPrevContinuation) {
+  virtual void SetPrevContinuation(nsIFrame* aPrevContinuation) MOZ_OVERRIDE {
     NS_ASSERTION (!aPrevContinuation || GetType() == aPrevContinuation->GetType(),
                   "setting a prev continuation with incorrect type!");
     NS_ASSERTION (!nsSplittableFrame::IsInPrevContinuationChain(aPrevContinuation, this),
                   "creating a loop in continuation chain!");
     mPrevContinuation = aPrevContinuation;
     RemoveStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
   }
-  virtual nsIFrame* GetPrevInFlowVirtual() const { return GetPrevInFlow(); }
+  virtual nsIFrame* GetPrevInFlowVirtual() const MOZ_OVERRIDE {
+    return GetPrevInFlow();
+  }
   nsIFrame* GetPrevInFlow() const {
     return (GetStateBits() & NS_FRAME_IS_FLUID_CONTINUATION) ? mPrevContinuation : nullptr;
   }
   virtual void SetPrevInFlow(nsIFrame* aPrevInFlow) MOZ_OVERRIDE {
     NS_ASSERTION (!aPrevInFlow || GetType() == aPrevInFlow->GetType(),
                   "setting a prev in flow with incorrect type!");
     NS_ASSERTION (!nsSplittableFrame::IsInPrevContinuationChain(aPrevInFlow, this),
                   "creating a loop in continuation chain!");
     mPrevContinuation = aPrevInFlow;
     AddStateBits(NS_FRAME_IS_FLUID_CONTINUATION);
   }
   virtual nsIFrame* FirstInFlow() const MOZ_OVERRIDE;
   virtual nsIFrame* FirstContinuation() const MOZ_OVERRIDE;
 
   virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext,
-                                 InlineMinWidthData *aData);
+                                 InlineMinWidthData *aData) MOZ_OVERRIDE;
   virtual void AddInlinePrefWidth(nsRenderingContext *aRenderingContext,
-                                  InlinePrefWidthData *aData);
+                                  InlinePrefWidthData *aData) MOZ_OVERRIDE;
   
   virtual nsresult GetRenderedText(nsAString* aString = nullptr,
                                    gfxSkipChars* aSkipChars = nullptr,
                                    gfxSkipCharsIterator* aSkipIter = nullptr,
                                    uint32_t aSkippedStartOffset = 0,
-                                   uint32_t aSkippedMaxLength = UINT32_MAX)
+                                   uint32_t aSkippedMaxLength = UINT32_MAX) MOZ_OVERRIDE
   { return NS_ERROR_NOT_IMPLEMENTED; } // Call on a primary text frame only
 
 protected:
   nsContinuingTextFrame(nsStyleContext* aContext) : nsTextFrame(aContext) {}
   nsIFrame* mPrevContinuation;
 };
 
 void
@@ -4473,47 +4475,49 @@ public:
     MOZ_COUNT_CTOR(nsDisplayText);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayText() {
     MOZ_COUNT_DTOR(nsDisplayText);
   }
 #endif
 
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE {
     *aSnap = false;
     nsRect temp = mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
     // Bug 748228
     temp.Inflate(mFrame->PresContext()->AppUnitsPerDevPixel());
     return temp;
   }
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE {
     if (nsRect(ToReferenceFrame(), mFrame->GetSize()).Intersects(aRect)) {
       aOutFrames->AppendElement(mFrame);
     }
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("Text", TYPE_TEXT)
 
-  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
+  virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     bool snap;
     return GetBounds(aBuilder, &snap);
   }
 
-  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder)
+  virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
   {
     return new nsDisplayTextGeometry(this, aBuilder);
   }
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion *aInvalidRegion)
+                                         nsRegion *aInvalidRegion) MOZ_OVERRIDE
   {
     const nsDisplayTextGeometry* geometry = static_cast<const nsDisplayTextGeometry*>(aGeometry);
     nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
 
     nsTextFrame::TextDecorations decorations;
     f->GetTextDecorations(f->PresContext(), nsTextFrame::eResolvedColors, decorations);
 
     bool snap;
@@ -4521,17 +4525,19 @@ public:
     nsRect oldRect = GetBounds(aBuilder, &snap);
     if (decorations != geometry->mDecorations ||
         !oldRect.IsEqualInterior(newRect) ||
         !geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
       aInvalidRegion->Or(oldRect, newRect);
     }
   }
   
-  virtual void DisableComponentAlpha() { mDisableSubpixelAA = true; }
+  virtual void DisableComponentAlpha() MOZ_OVERRIDE {
+    mDisableSubpixelAA = true;
+  }
 
   bool mDisableSubpixelAA;
 };
 
 void
 nsDisplayText::Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx) {
   PROFILER_LABEL("nsDisplayText", "Paint");
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -225,17 +225,17 @@ nsVideoFrame::BuildLayer(nsDisplayListBu
   return result.forget();
 }
 
 class DispatchResizeToControls : public nsRunnable
 {
 public:
   DispatchResizeToControls(nsIContent* aContent)
     : mContent(aContent) {}
-  NS_IMETHOD Run() {
+  NS_IMETHOD Run() MOZ_OVERRIDE {
     nsContentUtils::DispatchTrustedEvent(mContent->OwnerDoc(), mContent,
                                          NS_LITERAL_STRING("resizevideocontrols"),
                                          false, false);
     return NS_OK;
   }
   nsCOMPtr<nsIContent> mContent;
 };
 
@@ -378,33 +378,33 @@ public:
   // It would be great if we could override GetOpaqueRegion to return nonempty here,
   // but it's probably not safe to do so in general. Video frames are
   // updated asynchronously from decoder threads, and it's possible that
   // we might have an opaque video frame when GetOpaqueRegion is called, but
   // when we come to paint, the video frame is transparent or has gone
   // away completely (e.g. because of a decoder error). The problem would
   // be especially acute if we have off-main-thread rendering.
 
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
   {
     *aSnap = true;
     nsIFrame* f = Frame();
     return f->GetContentRect() - f->GetPosition() + ToReferenceFrame();
   }
 
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
-                                             const ContainerLayerParameters& aContainerParameters)
+                                             const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE
   {
     return static_cast<nsVideoFrame*>(mFrame)->BuildLayer(aBuilder, aManager, this, aContainerParameters);
   }
 
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
-                                   const ContainerLayerParameters& aParameters)
+                                   const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
   {
     if (aManager->IsCompositingCheap()) {
       // Since ImageLayers don't require additional memory of the
       // video frames we have to have anyway, we can't save much by
       // making layers inactive. Also, for many accelerated layer
       // managers calling imageContainer->GetCurrentAsSurface can be
       // very expensive. So just always be active when compositing is
       // cheap (i.e. hardware accelerated).
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -75,17 +75,17 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayMathMLError() {
     MOZ_COUNT_DTOR(nsDisplayMathMLError);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("MathMLError", TYPE_MATHML_ERROR)
 };
 
 void nsDisplayMathMLError::Paint(nsDisplayListBuilder* aBuilder,
                                  nsRenderingContext* aCtx)
 {
   // Set color and font ...
   nsRefPtr<nsFontMetrics> fm;
@@ -1314,20 +1314,20 @@ nsMathMLContainerFrame::PositionRowChild
     FinishReflowChild(child.Frame(), PresContext(), child.ReflowMetrics(),
                       nullptr, dx, dy, 0);
     ++child;
   }
 }
 
 class ForceReflow : public nsIReflowCallback {
 public:
-  virtual bool ReflowFinished() {
+  virtual bool ReflowFinished() MOZ_OVERRIDE {
     return true;
   }
-  virtual void ReflowCallbackCanceled() {}
+  virtual void ReflowCallbackCanceled() MOZ_OVERRIDE {}
 };
 
 // We only need one of these so we just make it a static global, no need
 // to dynamically allocate/destroy it.
 static ForceReflow gForceReflow;
 
 void
 nsMathMLContainerFrame::SetIncrementScriptLevel(int32_t aChildIndex, bool aIncrement)
--- a/layout/mathml/nsMathMLFrame.cpp
+++ b/layout/mathml/nsMathMLFrame.cpp
@@ -279,17 +279,17 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayMathMLBoundingMetrics() {
     MOZ_COUNT_DTOR(nsDisplayMathMLBoundingMetrics);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("MathMLBoundingMetrics", TYPE_MATHML_BOUNDING_METRICS)
 private:
   nsRect    mRect;
 };
 
 void nsDisplayMathMLBoundingMetrics::Paint(nsDisplayListBuilder* aBuilder,
                                            nsRenderingContext* aCtx)
 {
@@ -324,17 +324,17 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayMathMLBar() {
     MOZ_COUNT_DTOR(nsDisplayMathMLBar);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("MathMLBar", TYPE_MATHML_BAR)
 private:
   nsRect    mRect;
 };
 
 void nsDisplayMathMLBar::Paint(nsDisplayListBuilder* aBuilder,
                                nsRenderingContext* aCtx)
 {
--- a/layout/mathml/nsMathMLmencloseFrame.cpp
+++ b/layout/mathml/nsMathMLmencloseFrame.cpp
@@ -719,17 +719,17 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayNotation() {
     MOZ_COUNT_DTOR(nsDisplayNotation);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("MathMLMencloseNotation", TYPE_MATHML_MENCLOSE_NOTATION)
 
 private:
   nsRect             mRect;
   nscoord            mThickness;
   nsMencloseNotation mType;
 };
 
--- a/layout/mathml/nsMathMLmfracFrame.cpp
+++ b/layout/mathml/nsMathMLmfracFrame.cpp
@@ -514,17 +514,18 @@ public:
     MOZ_COUNT_CTOR(nsDisplayMathMLSlash);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayMathMLSlash() {
     MOZ_COUNT_DTOR(nsDisplayMathMLSlash);
   }
 #endif
 
-  virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
+  virtual void Paint(nsDisplayListBuilder* aBuilder,
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("MathMLSlash", TYPE_MATHML_SLASH)
 
 private:
   nsRect    mRect;
   nscoord   mThickness;
   bool      mRTL;
 };
 
--- a/layout/mathml/nsMathMLmtableFrame.h
+++ b/layout/mathml/nsMathMLmtableFrame.h
@@ -189,20 +189,20 @@ public:
 
   // overloaded nsTableCellFrame methods
 
   virtual nsresult
   AttributeChanged(int32_t  aNameSpaceID,
                    nsIAtom* aAttribute,
                    int32_t  aModType) MOZ_OVERRIDE;
 
-  virtual uint8_t GetVerticalAlign() const;
+  virtual uint8_t GetVerticalAlign() const MOZ_OVERRIDE;
   virtual nsresult ProcessBorders(nsTableFrame* aFrame,
                                   nsDisplayListBuilder* aBuilder,
-                                  const nsDisplayListSet& aLists);
+                                  const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   virtual int32_t GetRowSpan() MOZ_OVERRIDE;
   virtual int32_t GetColSpan() MOZ_OVERRIDE;
   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsTableCellFrame::IsFrameOfType(aFlags & ~(nsIFrame::eMathML));
   }
 
@@ -241,17 +241,17 @@ public:
          nsReflowStatus&          aStatus) MOZ_OVERRIDE;
 
   virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsBlockFrame::IsFrameOfType(aFlags &
       ~(nsIFrame::eMathML | nsIFrame::eExcludesIgnorableWhitespace));
   }
 
-  virtual const nsStyleText* StyleTextForLineLayout();
+  virtual const nsStyleText* StyleTextForLineLayout() MOZ_OVERRIDE;
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 
 protected:
   nsMathMLmtdInnerFrame(nsStyleContext* aContext);
   virtual ~nsMathMLmtdInnerFrame();
 
   nsStyleText* mUniqueStyleText;
 
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -3600,17 +3600,17 @@ nsPrintEngine::Observe(nsISupports *aSub
 //---------------------------------------------------------------
 class nsPrintCompletionEvent : public nsRunnable {
 public:
   nsPrintCompletionEvent(nsIDocumentViewerPrint *docViewerPrint)
     : mDocViewerPrint(docViewerPrint) {
     NS_ASSERTION(mDocViewerPrint, "mDocViewerPrint is null.");
   }
 
-  NS_IMETHOD Run() {
+  NS_IMETHOD Run() MOZ_OVERRIDE {
     if (mDocViewerPrint)
       mDocViewerPrint->OnDonePrinting();
     return NS_OK;
   }
 
 private:
   nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
 };
--- a/layout/style/StyleRule.cpp
+++ b/layout/style/StyleRule.cpp
@@ -965,29 +965,29 @@ class DOMCSSStyleRule;
 }
 
 class DOMCSSDeclarationImpl : public nsDOMCSSDeclaration
 {
 public:
   DOMCSSDeclarationImpl(css::StyleRule *aRule);
   virtual ~DOMCSSDeclarationImpl(void);
 
-  NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent);
+  NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) MOZ_OVERRIDE;
   void DropReference(void);
-  virtual css::Declaration* GetCSSDeclaration(bool aAllocate);
-  virtual nsresult SetCSSDeclaration(css::Declaration* aDecl);
-  virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv);
-  virtual nsIDocument* DocToUpdate();
+  virtual css::Declaration* GetCSSDeclaration(bool aAllocate) MOZ_OVERRIDE;
+  virtual nsresult SetCSSDeclaration(css::Declaration* aDecl) MOZ_OVERRIDE;
+  virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) MOZ_OVERRIDE;
+  virtual nsIDocument* DocToUpdate() MOZ_OVERRIDE;
 
   // Override |AddRef| and |Release| for being a member of
   // |DOMCSSStyleRule|.  Also, we need to forward QI for cycle
   // collection things to DOMCSSStyleRule.
   NS_DECL_ISUPPORTS_INHERITED
 
-  virtual nsINode *GetParentObject()
+  virtual nsINode *GetParentObject() MOZ_OVERRIDE
   {
     return mRule ? mRule->GetDocument() : nullptr;
   }
 
   friend class css::DOMCSSStyleRule;
 
 protected:
   // This reference is not reference-counted. The rule object tells us
--- a/layout/style/html.css
+++ b/layout/style/html.css
@@ -724,18 +724,16 @@ audio:not([controls]) {
   display: block !important;
   /* we want to be an absolute and fixed container */
   -moz-transform: translate(0) !important;
 }
 
 video > .caption-box {
   position: relative;
   overflow: hidden;
-  padding: 1.5%;
-  box-sizing: border-box;
 }
 
 /* emulation of non-standard HTML <marquee> tag */
 marquee {
   width: -moz-available;
   display: inline-block;
   vertical-align: text-bottom;
   text-align: start;
--- a/layout/style/nsDOMCSSAttrDeclaration.h
+++ b/layout/style/nsDOMCSSAttrDeclaration.h
@@ -34,17 +34,17 @@ public:
   // is owned by our current style rule.
   virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate);
   virtual void GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) MOZ_OVERRIDE;
   NS_IMETHOD GetParentRule(nsIDOMCSSRule **aParent) MOZ_OVERRIDE;
 
   virtual nsINode* GetParentObject() MOZ_OVERRIDE;
 
   NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID,
-                              const nsAString& aValue);
+                              const nsAString& aValue) MOZ_OVERRIDE;
 
 protected:
   virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) MOZ_OVERRIDE;
   virtual nsIDocument* DocToUpdate() MOZ_OVERRIDE;
 
   nsRefPtr<Element> mElement;
 
   /* If true, this indicates that this nsDOMCSSAttributeDeclaration
--- a/layout/style/nsFontFaceLoader.h
+++ b/layout/style/nsFontFaceLoader.h
@@ -4,16 +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/. */
 
 /* code for loading in @font-face defined font data */
 
 #ifndef nsFontFaceLoader_h_
 #define nsFontFaceLoader_h_
 
+#include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsIStreamLoader.h"
 #include "nsIChannel.h"
 #include "gfxUserFontSet.h"
 #include "nsHashKeys.h"
 #include "nsTHashtable.h"
 #include "nsCSSRules.h"
 
@@ -31,29 +32,29 @@ public:
 
   // Called when this font set is no longer associated with a presentation.
   void Destroy();
 
   // starts loading process, creating and initializing a nsFontFaceLoader obj
   // returns whether load process successfully started or not
   nsresult StartLoad(gfxMixedFontFamily* aFamily,
                      gfxProxyFontEntry* aFontToLoad,
-                     const gfxFontFaceSrc* aFontFaceSrc);
+                     const gfxFontFaceSrc* aFontFaceSrc) MOZ_OVERRIDE;
 
   // Called by nsFontFaceLoader when the loader has completed normally.
   // It's removed from the mLoaders set.
   void RemoveLoader(nsFontFaceLoader* aLoader);
 
   bool UpdateRules(const nsTArray<nsFontFaceRuleContainer>& aRules);
 
   nsPresContext* GetPresContext() { return mPresContext; }
 
   virtual void ReplaceFontEntry(gfxMixedFontFamily* aFamily,
                                 gfxProxyFontEntry* aProxy,
-                                gfxFontEntry* aFontEntry);
+                                gfxFontEntry* aFontEntry) MOZ_OVERRIDE;
 
   nsCSSFontFaceRule* FindRuleForEntry(gfxFontEntry* aFontEntry);
 
 protected:
   // The font-set keeps track of the collection of rules, and their
   // corresponding font entries (whether proxies or real entries),
   // so that we can update the set without having to throw away
   // all the existing fonts.
@@ -65,26 +66,26 @@ protected:
   void InsertRule(nsCSSFontFaceRule* aRule, uint8_t aSheetType,
                   nsTArray<FontFaceRuleRecord>& oldRules,
                   bool& aFontSetModified);
 
   virtual nsresult LogMessage(gfxMixedFontFamily* aFamily,
                               gfxProxyFontEntry* aProxy,
                               const char* aMessage,
                               uint32_t aFlags = nsIScriptError::errorFlag,
-                              nsresult aStatus = NS_OK);
+                              nsresult aStatus = NS_OK) MOZ_OVERRIDE;
 
   virtual nsresult CheckFontLoad(const gfxFontFaceSrc* aFontFaceSrc,
                                  nsIPrincipal** aPrincipal,
-                                 bool* aBypassCache);
+                                 bool* aBypassCache) MOZ_OVERRIDE;
 
   virtual nsresult SyncLoadFontData(gfxProxyFontEntry* aFontToLoad,
                                     const gfxFontFaceSrc* aFontFaceSrc,
                                     uint8_t*& aBuffer,
-                                    uint32_t& aBufferLength);
+                                    uint32_t& aBufferLength) MOZ_OVERRIDE;
 
   virtual bool GetPrivateBrowsing() MOZ_OVERRIDE;
 
   nsPresContext* mPresContext;  // weak reference
 
   // Set of all loaders pointing to us. These are not strong pointers,
   // but that's OK because nsFontFaceLoader always calls RemoveLoader on
   // us before it dies (unless we die first).
--- a/layout/svg/SVGFEContainerFrame.cpp
+++ b/layout/svg/SVGFEContainerFrame.cpp
@@ -26,46 +26,46 @@ protected:
     : SVGFEContainerFrameBase(aContext)
   {
     AddStateBits(NS_FRAME_SVG_LAYOUT | NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return SVGFEContainerFrameBase::IsFrameOfType(
             aFlags & ~(nsIFrame::eSVG | nsIFrame::eSVGContainer));
   }
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGFEContainer"), aResult);
   }
 #endif
 
 #ifdef DEBUG
   virtual void Init(nsIContent* aContent,
                     nsIFrame*   aParent,
                     nsIFrame*   aPrevInFlow) MOZ_OVERRIDE;
 #endif
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgFEContainerFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
-                                    int32_t  aModType);
+                                    int32_t  aModType) MOZ_OVERRIDE;
 
-  virtual bool UpdateOverflow() {
+  virtual bool UpdateOverflow() MOZ_OVERRIDE {
     // We don't maintain a visual overflow rect
     return false;
   }
 };
 
 nsIFrame*
 NS_NewSVGFEContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
--- a/layout/svg/SVGFEImageFrame.cpp
+++ b/layout/svg/SVGFEImageFrame.cpp
@@ -29,42 +29,42 @@ protected:
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   virtual void Init(nsIContent* aContent,
                     nsIFrame*   aParent,
                     nsIFrame*   aPrevInFlow) MOZ_OVERRIDE;
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return SVGFEImageFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
   }
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGFEImage"), aResult);
   }
 #endif
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgFEImageFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
-                                    int32_t  aModType);
+                                    int32_t  aModType) MOZ_OVERRIDE;
 
-  virtual bool UpdateOverflow() {
+  virtual bool UpdateOverflow() MOZ_OVERRIDE {
     // We don't maintain a visual overflow rect
     return false;
   }
 };
 
 nsIFrame*
 NS_NewSVGFEImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
--- a/layout/svg/SVGFELeafFrame.cpp
+++ b/layout/svg/SVGFELeafFrame.cpp
@@ -30,40 +30,40 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
 #ifdef DEBUG
   virtual void Init(nsIContent* aContent,
                     nsIFrame*   aParent,
                     nsIFrame*   aPrevInFlow) MOZ_OVERRIDE;
 #endif
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return SVGFELeafFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
   }
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGFELeaf"), aResult);
   }
 #endif
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgFELeafFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
-                                    int32_t  aModType);
+                                    int32_t  aModType) MOZ_OVERRIDE;
 
-  virtual bool UpdateOverflow() {
+  virtual bool UpdateOverflow() MOZ_OVERRIDE {
     // We don't maintain a visual overflow rect
     return false;
   }
 };
 
 nsIFrame*
 NS_NewSVGFELeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
--- a/layout/svg/SVGFEUnstyledLeafFrame.cpp
+++ b/layout/svg/SVGFEUnstyledLeafFrame.cpp
@@ -24,40 +24,40 @@ protected:
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
                               const nsRect&           aDirtyRect,
                               const nsDisplayListSet& aLists) MOZ_OVERRIDE {}
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return SVGFEUnstyledLeafFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
   }
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGFEUnstyledLeaf"), aResult);
   }
 #endif
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgFEUnstyledLeafFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
-                                    int32_t  aModType);
+                                    int32_t  aModType) MOZ_OVERRIDE;
 
-  virtual bool UpdateOverflow() {
+  virtual bool UpdateOverflow() MOZ_OVERRIDE {
     // We don't maintain a visual overflow rect
     return false;
   }
 };
 
 nsIFrame*
 NS_NewSVGFEUnstyledLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -2702,27 +2702,27 @@ public:
     : DrawPathCallbacks(aShouldPaintSVGGlyphs),
       gfx(aContext->ThebesContext()),
       mRenderMode(SVGAutoRenderState::GetRenderMode(aContext)),
       mFrame(aFrame),
       mCanvasTM(aCanvasTM)
   {
   }
 
-  void NotifyBeforeText(nscolor aColor);
-  void NotifyGlyphPathEmitted();
-  void NotifyBeforeSVGGlyphPainted();
-  void NotifyAfterSVGGlyphPainted();
-  void NotifyAfterText();
-  void NotifyBeforeSelectionBackground(nscolor aColor);
-  void NotifySelectionBackgroundPathEmitted();
-  void NotifyBeforeDecorationLine(nscolor aColor);
-  void NotifyDecorationLinePathEmitted();
-  void NotifyBeforeSelectionDecorationLine(nscolor aColor);
-  void NotifySelectionDecorationLinePathEmitted();
+  void NotifyBeforeText(nscolor aColor) MOZ_OVERRIDE;
+  void NotifyGlyphPathEmitted() MOZ_OVERRIDE;
+  void NotifyBeforeSVGGlyphPainted() MOZ_OVERRIDE;
+  void NotifyAfterSVGGlyphPainted() MOZ_OVERRIDE;
+  void NotifyAfterText() MOZ_OVERRIDE;
+  void NotifyBeforeSelectionBackground(nscolor aColor) MOZ_OVERRIDE;
+  void NotifySelectionBackgroundPathEmitted() MOZ_OVERRIDE;
+  void NotifyBeforeDecorationLine(nscolor aColor) MOZ_OVERRIDE;
+  void NotifyDecorationLinePathEmitted() MOZ_OVERRIDE;
+  void NotifyBeforeSelectionDecorationLine(nscolor aColor) MOZ_OVERRIDE;
+  void NotifySelectionDecorationLinePathEmitted() MOZ_OVERRIDE;
 
 private:
   void FillWithOpacity();
 
   void SetupContext();
 
   /**
    * Paints a piece of text geometry.  This is called when glyphs
@@ -3081,19 +3081,20 @@ public:
 #endif
 
   NS_DISPLAY_DECL_NAME("nsDisplaySVGText", TYPE_SVG_TEXT)
 
   virtual void DisableComponentAlpha() MOZ_OVERRIDE {
     mDisableSubpixelAA = true;
   }
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
 private:
   bool mDisableSubpixelAA;
 };
 
 void
 nsDisplaySVGText::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                           HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
 {
--- a/layout/svg/SVGViewFrame.cpp
+++ b/layout/svg/SVGViewFrame.cpp
@@ -35,40 +35,40 @@ public:
   NS_DECL_FRAMEARENA_HELPERS
 
 #ifdef DEBUG
   virtual void Init(nsIContent* aContent,
                     nsIFrame*   aParent,
                     nsIFrame*   aPrevInFlow) MOZ_OVERRIDE;
 #endif
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return SVGViewFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
   }
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGView"), aResult);
   }
 #endif
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgFELeafFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
   virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                     nsIAtom* aAttribute,
-                                    int32_t  aModType);
+                                    int32_t  aModType) MOZ_OVERRIDE;
 
-  virtual bool UpdateOverflow() {
+  virtual bool UpdateOverflow() MOZ_OVERRIDE {
     // We don't maintain a visual overflow rect
     return false;
   }
 };
 
 nsIFrame*
 NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
--- a/layout/svg/moz.build
+++ b/layout/svg/moz.build
@@ -1,24 +1,26 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS += [
+    'nsFilterInstance.h',
     'nsSVGEffects.h',
     'nsSVGFilterInstance.h',
     'nsSVGForeignObjectFrame.h',
     'nsSVGIntegrationUtils.h',
     'nsSVGUtils.h',
     'SVGImageContext.h',
 ]
 
 UNIFIED_SOURCES += [
+    'nsFilterInstance.cpp',
     'nsSVGAFrame.cpp',
     'nsSVGClipPathFrame.cpp',
     'nsSVGContainerFrame.cpp',
     'nsSVGEffects.cpp',
     'nsSVGFilterFrame.cpp',
     'nsSVGFilterInstance.cpp',
     'nsSVGForeignObjectFrame.cpp',
     'nsSVGGenericContainerFrame.cpp',
copy from layout/svg/nsSVGFilterInstance.cpp
copy to layout/svg/nsFilterInstance.cpp
--- a/layout/svg/nsSVGFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -1,228 +1,142 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Main header first:
-#include "nsSVGFilterInstance.h"
+#include "nsFilterInstance.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "nsISVGChildFrame.h"
 #include "nsRenderingContext.h"
-#include "mozilla/dom/SVGFilterElement.h"
-#include "nsSVGFilterFrame.h"
+#include "nsSVGFilterInstance.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGUtils.h"
 #include "SVGContentUtils.h"
 #include "FilterSupport.h"
 #include "gfx2DGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 
 nsresult
-nsSVGFilterInstance::PaintFilteredFrame(nsSVGFilterFrame* aFilterFrame,
-                                        nsRenderingContext *aContext,
-                                        nsIFrame *aFilteredFrame,
-                                        nsSVGFilterPaintCallback *aPaintCallback,
-                                        const nsRect *aDirtyArea,
-                                        nsIFrame* aTransformRoot)
+nsFilterInstance::PaintFilteredFrame(nsRenderingContext *aContext,
+                                     nsIFrame *aFilteredFrame,
+                                     nsSVGFilterPaintCallback *aPaintCallback,
+                                     const nsRect *aDirtyArea,
+                                     nsIFrame* aTransformRoot)
 {
-  nsSVGFilterInstance instance(aFilteredFrame, aFilterFrame, aPaintCallback,
-                               aDirtyArea, nullptr, nullptr, nullptr,
-                               aTransformRoot);
+  nsFilterInstance instance(aFilteredFrame, aPaintCallback, aDirtyArea,
+                            nullptr, nullptr, nullptr,
+                            aTransformRoot);
   if (!instance.IsInitialized()) {
     return NS_OK;
   }
   return instance.Render(aContext->ThebesContext());
 }
 
 nsRect
-nsSVGFilterInstance::GetPostFilterDirtyArea(nsSVGFilterFrame* aFilterFrame,
-                                            nsIFrame *aFilteredFrame,
-                                            const nsRect& aPreFilterDirtyRect)
+nsFilterInstance::GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
+                                         const nsRect& aPreFilterDirtyRect)
 {
   if (aPreFilterDirtyRect.IsEmpty()) {
     return nsRect();
   }
 
-  nsSVGFilterInstance instance(aFilteredFrame, aFilterFrame, nullptr, nullptr,
-                               &aPreFilterDirtyRect);
+  nsFilterInstance instance(aFilteredFrame, nullptr, nullptr,
+                            &aPreFilterDirtyRect);
   if (!instance.IsInitialized()) {
     return nsRect();
   }
   // We've passed in the source's dirty area so the instance knows about it.
   // Now we can ask the instance to compute the area of the filter output
   // that's dirty.
   nsRect dirtyRect;
   nsresult rv = instance.ComputePostFilterDirtyRect(&dirtyRect);
   if (NS_SUCCEEDED(rv)) {
     return dirtyRect;
   }
   return nsRect();
 }
 
 nsRect
-nsSVGFilterInstance::GetPreFilterNeededArea(nsSVGFilterFrame* aFilterFrame,
-                                            nsIFrame *aFilteredFrame,
-                                            const nsRect& aPostFilterDirtyRect)
+nsFilterInstance::GetPreFilterNeededArea(nsIFrame *aFilteredFrame,
+                                         const nsRect& aPostFilterDirtyRect)
 {
-  nsSVGFilterInstance instance(aFilteredFrame, aFilterFrame, nullptr,
-                               &aPostFilterDirtyRect);
+  nsFilterInstance instance(aFilteredFrame, nullptr, &aPostFilterDirtyRect);
   if (!instance.IsInitialized()) {
     return nsRect();
   }
   // Now we can ask the instance to compute the area of the source
   // that's needed.
   nsRect neededRect;
   nsresult rv = instance.ComputeSourceNeededRect(&neededRect);
   if (NS_SUCCEEDED(rv)) {
     return neededRect;
   }
   return nsRect();
 }
 
 nsRect
-nsSVGFilterInstance::GetPostFilterBounds(nsSVGFilterFrame* aFilterFrame,
-                                         nsIFrame *aFilteredFrame,
-                                         const gfxRect *aOverrideBBox,
-                                         const nsRect *aPreFilterBounds)
+nsFilterInstance::GetPostFilterBounds(nsIFrame *aFilteredFrame,
+                                      const gfxRect *aOverrideBBox,
+                                      const nsRect *aPreFilterBounds)
 {
   MOZ_ASSERT(!(aFilteredFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) ||
              !(aFilteredFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY),
              "Non-display SVG do not maintain visual overflow rects");
 
-  nsSVGFilterInstance instance(aFilteredFrame, aFilterFrame, nullptr, nullptr,
-                               aPreFilterBounds, aPreFilterBounds,
-                               aOverrideBBox);
+  nsFilterInstance instance(aFilteredFrame, nullptr, nullptr,
+                            aPreFilterBounds, aPreFilterBounds,
+                            aOverrideBBox);
   if (!instance.IsInitialized()) {
     return nsRect();
   }
   nsRect bbox;
   nsresult rv = instance.ComputePostFilterExtents(&bbox);
   if (NS_SUCCEEDED(rv)) {
     return bbox;
   }
   return nsRect();
 }
 
-nsSVGFilterInstance::nsSVGFilterInstance(nsIFrame *aTargetFrame,
-                                         nsSVGFilterFrame *aFilterFrame,
-                                         nsSVGFilterPaintCallback *aPaintCallback,
-                                         const nsRect *aPostFilterDirtyRect,
-                                         const nsRect *aPreFilterDirtyRect,
-                                         const nsRect *aPreFilterVisualOverflowRectOverride,
-                                         const gfxRect *aOverrideBBox,
-                                         nsIFrame* aTransformRoot) :
+nsFilterInstance::nsFilterInstance(nsIFrame *aTargetFrame,
+                                   nsSVGFilterPaintCallback *aPaintCallback,
+                                   const nsRect *aPostFilterDirtyRect,
+                                   const nsRect *aPreFilterDirtyRect,
+                                   const nsRect *aPreFilterVisualOverflowRectOverride,
+                                   const gfxRect *aOverrideBBox,
+                                   nsIFrame* aTransformRoot) :
   mTargetFrame(aTargetFrame),
   mPaintCallback(aPaintCallback),
   mTransformRoot(aTransformRoot),
   mInitialized(false) {
 
-  mFilterElement =  aFilterFrame->GetFilterContent();
-
-  mPrimitiveUnits =
-    aFilterFrame->GetEnumValue(SVGFilterElement::PRIMITIVEUNITS);
-
   mTargetBBox = aOverrideBBox ?
     *aOverrideBBox : nsSVGUtils::GetBBox(mTargetFrame);
 
-  // Get the filter region (in the filtered element's user space):
-
-  // XXX if filterUnits is set (or has defaulted) to objectBoundingBox, we
-  // should send a warning to the error console if the author has used lengths
-  // with units. This is a common mistake and can result in filterRes being
-  // *massive* below (because we ignore the units and interpret the number as
-  // a factor of the bbox width/height). We should also send a warning if the
-  // user uses a number without units (a future SVG spec should really
-  // deprecate that, since it's too confusing for a bare number to be sometimes
-  // interpreted as a fraction of the bounding box and sometimes as user-space
-  // units). So really only percentage values should be used in this case.
-  
-  nsSVGLength2 XYWH[4];
-  NS_ABORT_IF_FALSE(sizeof(mFilterElement->mLengthAttributes) == sizeof(XYWH),
-                    "XYWH size incorrect");
-  memcpy(XYWH, mFilterElement->mLengthAttributes, 
-    sizeof(mFilterElement->mLengthAttributes));
-  XYWH[0] = *aFilterFrame->GetLengthValue(SVGFilterElement::ATTR_X);
-  XYWH[1] = *aFilterFrame->GetLengthValue(SVGFilterElement::ATTR_Y);
-  XYWH[2] = *aFilterFrame->GetLengthValue(SVGFilterElement::ATTR_WIDTH);
-  XYWH[3] = *aFilterFrame->GetLengthValue(SVGFilterElement::ATTR_HEIGHT);
-  uint16_t filterUnits =
-    aFilterFrame->GetEnumValue(SVGFilterElement::FILTERUNITS);
-  // The filter region in user space, in user units:
-  mFilterRegion = nsSVGUtils::GetRelativeRect(filterUnits,
-    XYWH, mTargetBBox, mTargetFrame);
-
-  if (mFilterRegion.Width() <= 0 || mFilterRegion.Height() <= 0) {
-    // 0 disables rendering, < 0 is error. dispatch error console warning
-    // or error as appropriate.
+  nsresult rv = BuildPrimitives();
+  if (NS_FAILED(rv)) {
     return;
   }
 
-  // Calculate filterRes (the width and height of the pixel buffer of the
-  // temporary offscreen surface that we would/will create to paint into when
-  // painting the entire filtered element) and, if necessary, adjust
-  // mFilterRegion out slightly so that it aligns with pixel boundaries of this
-  // buffer:
-
-  gfxIntSize filterRes;
-  const nsSVGIntegerPair* filterResAttrs =
-    aFilterFrame->GetIntegerPairValue(SVGFilterElement::FILTERRES);
-  if (filterResAttrs->IsExplicitlySet()) {
-    int32_t filterResX = filterResAttrs->GetAnimValue(nsSVGIntegerPair::eFirst);
-    int32_t filterResY = filterResAttrs->GetAnimValue(nsSVGIntegerPair::eSecond);
-    if (filterResX <= 0 || filterResY <= 0) {
-      // 0 disables rendering, < 0 is error. dispatch error console warning?
-      return;
-    }
-
-    mFilterRegion.Scale(filterResX, filterResY);
-    mFilterRegion.RoundOut();
-    mFilterRegion.Scale(1.0 / filterResX, 1.0 / filterResY);
-    // We don't care if this overflows, because we can handle upscaling/
-    // downscaling to filterRes
-    bool overflow;
-    filterRes =
-      nsSVGUtils::ConvertToSurfaceSize(gfxSize(filterResX, filterResY),
-                                       &overflow);
-    // XXX we could send a warning to the error console if the author specified
-    // filterRes doesn't align well with our outer 'svg' device space.
-  } else {
-    // Match filterRes as closely as possible to the pixel density of the nearest
-    // outer 'svg' device space:
-    gfxMatrix canvasTM =
-      nsSVGUtils::GetCanvasTM(mTargetFrame, nsISVGChildFrame::FOR_OUTERSVG_TM);
-    if (canvasTM.IsSingular()) {
-      // nothing to draw
-      return;
-    }
-
-    gfxSize scale = canvasTM.ScaleFactors(true);
-    mFilterRegion.Scale(scale.width, scale.height);
-    mFilterRegion.RoundOut();
-    // We don't care if this overflows, because we can handle upscaling/
-    // downscaling to filterRes
-    bool overflow;
-    filterRes = nsSVGUtils::ConvertToSurfaceSize(mFilterRegion.Size(),
-                                                 &overflow);
-    mFilterRegion.Scale(1.0 / scale.width, 1.0 / scale.height);
+  if (mPrimitiveDescriptions.IsEmpty()) {
+    // Nothing should be rendered.
+    return;
   }
 
-  mFilterSpaceBounds.SetRect(nsIntPoint(0, 0), filterRes);
-
   // Get various transforms:
 
-  gfxMatrix filterToUserSpace(mFilterRegion.Width() / filterRes.width, 0.0f,
-                              0.0f, mFilterRegion.Height() / filterRes.height,
+  gfxMatrix filterToUserSpace(mFilterRegion.Width() / mFilterSpaceBounds.width, 0.0f,
+                              0.0f, mFilterRegion.Height() / mFilterSpaceBounds.height,
                               mFilterRegion.X(), mFilterRegion.Y());
 
   // Only used (so only set) when we paint:
   if (mPaintCallback) {
     mFilterSpaceToDeviceSpaceTransform = filterToUserSpace *
               nsSVGUtils::GetCanvasTM(mTargetFrame, nsISVGChildFrame::FOR_PAINTING);
   }
 
@@ -245,256 +159,76 @@ nsSVGFilterInstance::nsSVGFilterInstance
   } else {
     nsRect preFilterVOR = mTargetFrame->GetPreEffectsVisualOverflowRect();
     mTargetBounds = FrameSpaceToFilterSpace(&preFilterVOR);
   }
 
   mInitialized = true;
 }
 
-float
-nsSVGFilterInstance::GetPrimitiveNumber(uint8_t aCtxType, float aValue) const
-{
-  nsSVGLength2 val;
-  val.Init(aCtxType, 0xff, aValue,
-           nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
-
-  float value;
-  if (mPrimitiveUnits == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
-    value = nsSVGUtils::ObjectSpace(mTargetBBox, &val);
-  } else {
-    value = nsSVGUtils::UserSpace(mTargetFrame, &val);
-  }
-
-  switch (aCtxType) {
-  case SVGContentUtils::X:
-    return value * mFilterSpaceBounds.width / mFilterRegion.Width();
-  case SVGContentUtils::Y:
-    return value * mFilterSpaceBounds.height / mFilterRegion.Height();
-  case SVGContentUtils::XY:
-  default:
-    return value * SVGContentUtils::ComputeNormalizedHypotenuse(
-                     mFilterSpaceBounds.width / mFilterRegion.Width(),
-                     mFilterSpaceBounds.height / mFilterRegion.Height());
-  }
-}
-
-Point3D
-nsSVGFilterInstance::ConvertLocation(const Point3D& aPoint) const
-{
-  nsSVGLength2 val[4];
-  val[0].Init(SVGContentUtils::X, 0xff, aPoint.x,
-              nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
-  val[1].Init(SVGContentUtils::Y, 0xff, aPoint.y,
-              nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
-  // Dummy width/height values
-  val[2].Init(SVGContentUtils::X, 0xff, 0,
-              nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
-  val[3].Init(SVGContentUtils::Y, 0xff, 0,
-              nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
-
-  gfxRect feArea = nsSVGUtils::GetRelativeRect(mPrimitiveUnits,
-    val, mTargetBBox, mTargetFrame);
-  gfxRect r = UserSpaceToFilterSpace(feArea);
-  return Point3D(r.x, r.y, GetPrimitiveNumber(SVGContentUtils::XY, aPoint.z));
-}
-
 gfxRect
-nsSVGFilterInstance::UserSpaceToFilterSpace(const gfxRect& aRect) const
+nsFilterInstance::UserSpaceToFilterSpace(const gfxRect& aRect) const
 {
   gfxRect r = aRect - mFilterRegion.TopLeft();
   r.Scale(mFilterSpaceBounds.width / mFilterRegion.Width(),
           mFilterSpaceBounds.height / mFilterRegion.Height());
   return r;
 }
 
-gfxPoint
-nsSVGFilterInstance::FilterSpaceToUserSpace(const gfxPoint& aPt) const
-{
-  return gfxPoint(aPt.x * mFilterRegion.Width() / mFilterSpaceBounds.width + mFilterRegion.X(),
-                  aPt.y * mFilterRegion.Height() / mFilterSpaceBounds.height + mFilterRegion.Y());
-}
-
 gfxMatrix
-nsSVGFilterInstance::GetUserSpaceToFilterSpaceTransform() const
+nsFilterInstance::GetUserSpaceToFilterSpaceTransform() const
 {
   gfxFloat widthScale = mFilterSpaceBounds.width / mFilterRegion.Width();
   gfxFloat heightScale = mFilterSpaceBounds.height / mFilterRegion.Height();
   return gfxMatrix(widthScale, 0.0f,
                    0.0f, heightScale,
                    -mFilterRegion.X() * widthScale, -mFilterRegion.Y() * heightScale);
 }
 
-IntRect
-nsSVGFilterInstance::ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement,
-                                                     const nsTArray<int32_t>& aInputIndices)
-{
-  nsSVGFE* fE = aFilterElement;
-
-  IntRect defaultFilterSubregion(0,0,0,0);
-  if (fE->SubregionIsUnionOfRegions()) {
-    for (uint32_t i = 0; i < aInputIndices.Length(); ++i) {
-      int32_t inputIndex = aInputIndices[i];
-      IntRect inputSubregion = inputIndex >= 0 ?
-        mPrimitiveDescriptions[inputIndex].PrimitiveSubregion() :
-        ToIntRect(mFilterSpaceBounds);
-
-      defaultFilterSubregion = defaultFilterSubregion.Union(inputSubregion);
-    }
-  } else {
-    defaultFilterSubregion = ToIntRect(mFilterSpaceBounds);
-  }
-
-  gfxRect feArea = nsSVGUtils::GetRelativeRect(mPrimitiveUnits,
-    &fE->mLengthAttributes[nsSVGFE::ATTR_X], mTargetBBox, mTargetFrame);
-  Rect region = ToRect(UserSpaceToFilterSpace(feArea));
-
-  if (!fE->mLengthAttributes[nsSVGFE::ATTR_X].IsExplicitlySet())
-    region.x = defaultFilterSubregion.X();
-  if (!fE->mLengthAttributes[nsSVGFE::ATTR_Y].IsExplicitlySet())
-    region.y = defaultFilterSubregion.Y();
-  if (!fE->mLengthAttributes[nsSVGFE::ATTR_WIDTH].IsExplicitlySet())
-    region.width = defaultFilterSubregion.Width();
-  if (!fE->mLengthAttributes[nsSVGFE::ATTR_HEIGHT].IsExplicitlySet())
-    region.height = defaultFilterSubregion.Height();
-
-  // We currently require filter primitive subregions to be pixel-aligned.
-  // Following the spec, any pixel partially in the region is included
-  // in the region.
-  region.RoundOut();
-
-  return RoundedToInt(region);
-}
-
-void
-nsSVGFilterInstance::GetInputsAreTainted(const nsTArray<int32_t>& aInputIndices,
-                                         nsTArray<bool>& aOutInputsAreTainted)
+nsresult
+nsFilterInstance::BuildPrimitives()
 {
-  for (uint32_t i = 0; i < aInputIndices.Length(); i++) {
-    int32_t inputIndex = aInputIndices[i];
-    if (inputIndex < 0) {
-      // SourceGraphic, SourceAlpha, FillPaint and StrokePaint are tainted.
-      aOutInputsAreTainted.AppendElement(true);
-    } else {
-      aOutInputsAreTainted.AppendElement(mPrimitiveDescriptions[inputIndex].IsTainted());
-    }
-  }
-}
-
-static nsresult
-GetSourceIndices(nsSVGFE* aFilterElement,
-                 int32_t aCurrentIndex,
-                 const nsDataHashtable<nsStringHashKey, int32_t>& aImageTable,
-                 nsTArray<int32_t>& aSourceIndices)
-{
-  nsAutoTArray<nsSVGStringInfo,2> sources;
-  aFilterElement->GetSourceImageNames(sources);
-
-  for (uint32_t j = 0; j < sources.Length(); j++) {
-    nsAutoString str;
-    sources[j].mString->GetAnimValue(str, sources[j].mElement);
+  NS_ASSERTION(!mPrimitiveDescriptions.Length(),
+               "expected to start building primitives from scratch");
 
-    int32_t sourceIndex = 0;
-    if (str.EqualsLiteral("SourceGraphic")) {
-      sourceIndex = FilterPrimitiveDescription::kPrimitiveIndexSourceGraphic;
-    } else if (str.EqualsLiteral("SourceAlpha")) {
-      sourceIndex = FilterPrimitiveDescription::kPrimitiveIndexSourceAlpha;
-    } else if (str.EqualsLiteral("FillPaint")) {
-      sourceIndex = FilterPrimitiveDescription::kPrimitiveIndexFillPaint;
-    } else if (str.EqualsLiteral("StrokePaint")) {
-      sourceIndex = FilterPrimitiveDescription::kPrimitiveIndexStrokePaint;
-    } else if (str.EqualsLiteral("BackgroundImage") ||
-               str.EqualsLiteral("BackgroundAlpha")) {
-      return NS_ERROR_NOT_IMPLEMENTED;
-    } else if (str.EqualsLiteral("")) {
-      sourceIndex = aCurrentIndex == 0 ?
-        FilterPrimitiveDescription::kPrimitiveIndexSourceGraphic :
-        aCurrentIndex - 1;
-    } else {
-      bool inputExists = aImageTable.Get(str, &sourceIndex);
-      if (!inputExists)
-        return NS_ERROR_FAILURE;
+  const nsTArray<nsStyleFilter>& filters = mTargetFrame->StyleSVGReset()->mFilters;
+  for (uint32_t i = 0; i < filters.Length(); i++) {
+    nsresult rv = BuildPrimitivesForFilter(filters[i]);
+    if (NS_FAILED(rv)) {
+      return rv;
     }
-
-    MOZ_ASSERT(sourceIndex < aCurrentIndex);
-    aSourceIndices.AppendElement(sourceIndex);
   }
   return NS_OK;
 }
 
 nsresult
-nsSVGFilterInstance::BuildPrimitives()
+nsFilterInstance::BuildPrimitivesForFilter(const nsStyleFilter& aFilter)
 {
-  nsTArray<nsRefPtr<nsSVGFE> > primitives;
-  for (nsIContent* child = mFilterElement->nsINode::GetFirstChild();
-       child;
-       child = child->GetNextSibling()) {
-    nsRefPtr<nsSVGFE> primitive;
-    CallQueryInterface(child, (nsSVGFE**)getter_AddRefs(primitive));
-    if (primitive) {
-      primitives.AppendElement(primitive);
-    }
-  }
-
-  // Maps source image name to source index.
-  nsDataHashtable<nsStringHashKey, int32_t> imageTable(10);
-
-  // The principal that we check principals of any loaded images against.
-  nsCOMPtr<nsIPrincipal> principal = mTargetFrame->GetContent()->NodePrincipal();
-
-  for (uint32_t i = 0; i < primitives.Length(); ++i) {
-    nsSVGFE* filter = primitives[i];
-
-    nsAutoTArray<int32_t,2> sourceIndices;
-    nsresult rv = GetSourceIndices(filter, i, imageTable, sourceIndices);
-    if (NS_FAILED(rv)) {
-      return rv;
+  if (aFilter.GetType() == NS_STYLE_FILTER_URL) {
+    // Build primitives for an SVG filter.
+    nsSVGFilterInstance svgFilterInstance(aFilter, mTargetFrame, mTargetBBox);
+    if (!svgFilterInstance.IsInitialized()) {
+      return NS_ERROR_FAILURE;
     }
 
-    IntRect primitiveSubregion =
-      ComputeFilterPrimitiveSubregion(filter, sourceIndices);
-
-    nsTArray<bool> sourcesAreTainted;
-    GetInputsAreTainted(sourceIndices, sourcesAreTainted);
-
-    FilterPrimitiveDescription descr =
-      filter->GetPrimitiveDescription(this, primitiveSubregion, sourcesAreTainted, mInputImages);
-
-    descr.SetIsTainted(filter->OutputIsTainted(sourcesAreTainted, principal));
-    descr.SetPrimitiveSubregion(primitiveSubregion);
+    // For now, we use the last SVG filter region as the overall filter region
+    // for the filter chain. Eventually, we will compute the overall filter
+    // using all of the generated FilterPrimitiveDescriptions.
+    mFilterRegion = svgFilterInstance.GetFilterRegion();
+    mFilterSpaceBounds = svgFilterInstance.GetFilterSpaceBounds();
 
-    for (uint32_t j = 0; j < sourceIndices.Length(); j++) {
-      int32_t inputIndex = sourceIndices[j];
-      descr.SetInputPrimitive(j, inputIndex);
-      ColorSpace inputColorSpace =
-        inputIndex < 0 ? SRGB : mPrimitiveDescriptions[inputIndex].OutputColorSpace();
-      ColorSpace desiredInputColorSpace = filter->GetInputColorSpace(j, inputColorSpace);
-      descr.SetInputColorSpace(j, desiredInputColorSpace);
-      if (j == 0) {
-        // the output color space is whatever in1 is if there is an in1
-        descr.SetOutputColorSpace(desiredInputColorSpace);
-      }
-    }
-
-    if (sourceIndices.Length() == 0) {
-      descr.SetOutputColorSpace(filter->GetOutputColorSpace());
-    }
-
-    mPrimitiveDescriptions.AppendElement(descr);
-
-    nsAutoString str;
-    filter->GetResultImageName().GetAnimValue(str, filter);
-    imageTable.Put(str, i);
+    return svgFilterInstance.BuildPrimitives(mPrimitiveDescriptions, mInputImages);
   }
 
-  return NS_OK;
+  // Eventually, we will build primitives for CSS filters, too.
+  return NS_ERROR_FAILURE;
 }
 
 void
-nsSVGFilterInstance::ComputeNeededBoxes()
+nsFilterInstance::ComputeNeededBoxes()
 {
   if (mPrimitiveDescriptions.IsEmpty())
     return;
 
   nsIntRegion sourceGraphicNeededRegion;
   nsIntRegion fillPaintNeededRegion;
   nsIntRegion strokePaintNeededRegion;
 
@@ -514,19 +248,19 @@ nsSVGFilterInstance::ComputeNeededBoxes(
   sourceGraphicNeededRegion.And(sourceGraphicNeededRegion, sourceBoundsInt);
 
   mSourceGraphic.mNeededBounds = sourceGraphicNeededRegion.GetBounds();
   mFillPaint.mNeededBounds = fillPaintNeededRegion.GetBounds();
   mStrokePaint.mNeededBounds = strokePaintNeededRegion.GetBounds();
 }
 
 nsresult
-nsSVGFilterInstance::BuildSourcePaint(SourceInfo *aSource,
-                                      gfxASurface* aTargetSurface,
-                                      DrawTarget* aTargetDT)
+nsFilterInstance::BuildSourcePaint(SourceInfo *aSource,
+                                   gfxASurface* aTargetSurface,
+                                   DrawTarget* aTargetDT)
 {
   nsIntRect neededRect = aSource->mNeededBounds;
 
   RefPtr<DrawTarget> offscreenDT;
   nsRefPtr<gfxASurface> offscreenSurface;
   nsRefPtr<gfxContext> ctx;
   if (aTargetSurface) {
     offscreenSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(
@@ -581,36 +315,36 @@ nsSVGFilterInstance::BuildSourcePaint(So
     aSource->mSourceSurface = offscreenDT->Snapshot();
   }
   aSource->mSurfaceRect = ToIntRect(neededRect);
 
   return NS_OK;
 }
 
 nsresult
-nsSVGFilterInstance::BuildSourcePaints(gfxASurface* aTargetSurface,
-                                       DrawTarget* aTargetDT)
+nsFilterInstance::BuildSourcePaints(gfxASurface* aTargetSurface,
+                                    DrawTarget* aTargetDT)
 {
   nsresult rv = NS_OK;
 
   if (!mFillPaint.mNeededBounds.IsEmpty()) {
     rv = BuildSourcePaint(&mFillPaint, aTargetSurface, aTargetDT);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (!mStrokePaint.mNeededBounds.IsEmpty()) {
     rv = BuildSourcePaint(&mStrokePaint, aTargetSurface, aTargetDT);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return  rv;
 }
 
 nsresult
-nsSVGFilterInstance::BuildSourceImage(gfxASurface* aTargetSurface,
-                                      DrawTarget* aTargetDT)
+nsFilterInstance::BuildSourceImage(gfxASurface* aTargetSurface,
+                                   DrawTarget* aTargetDT)
 {
   nsIntRect neededRect = mSourceGraphic.mNeededBounds;
   if (neededRect.IsEmpty()) {
     return NS_OK;
   }
 
   RefPtr<DrawTarget> offscreenDT;
   nsRefPtr<gfxASurface> offscreenSurface;
@@ -670,27 +404,18 @@ nsSVGFilterInstance::BuildSourceImage(gf
 
   mSourceGraphic.mSourceSurface = sourceGraphicSource;
   mSourceGraphic.mSurfaceRect = ToIntRect(neededRect);
    
   return NS_OK;
 }
 
 nsresult
-nsSVGFilterInstance::Render(gfxContext* aContext)
+nsFilterInstance::Render(gfxContext* aContext)
 {
-  nsresult rv = BuildPrimitives();
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (mPrimitiveDescriptions.IsEmpty()) {
-    // Nothing should be rendered.
-    return NS_OK;
-  }
-
   nsIntRect filterRect = mPostFilterDirtyRect.Intersect(mFilterSpaceBounds);
   gfxMatrix ctm = GetFilterSpaceToDeviceSpaceTransform();
 
   if (filterRect.IsEmpty() || ctm.IsSingular()) {
     return NS_OK;
   }
 
   Matrix oldDTMatrix;
@@ -713,17 +438,17 @@ nsSVGFilterInstance::Render(gfxContext* 
     oldDTMatrix = dt->GetTransform();
     Matrix matrix = ToMatrix(ctm);
     matrix.Translate(filterRect.x, filterRect.y);
     dt->SetTransform(matrix * oldDTMatrix);
   }
 
   ComputeNeededBoxes();
 
-  rv = BuildSourceImage(resultImage, dt);
+  nsresult rv = BuildSourceImage(resultImage, dt);
   if (NS_FAILED(rv))
     return rv;
   rv = BuildSourcePaints(resultImage, dt);
   if (NS_FAILED(rv))
     return rv;
 
   IntRect filterSpaceBounds = ToIntRect(mFilterSpaceBounds);
   FilterDescription filter(mPrimitiveDescriptions, filterSpaceBounds);
@@ -745,55 +470,38 @@ nsSVGFilterInstance::Render(gfxContext* 
   } else {
     dt->SetTransform(oldDTMatrix);
   }
 
   return NS_OK;
 }
 
 nsresult
-nsSVGFilterInstance::ComputePostFilterDirtyRect(nsRect* aPostFilterDirtyRect)
+nsFilterInstance::ComputePostFilterDirtyRect(nsRect* aPostFilterDirtyRect)
 {
   *aPostFilterDirtyRect = nsRect();
   if (mPreFilterDirtyRect.IsEmpty()) {
     return NS_OK;
   }
 
-  nsresult rv = BuildPrimitives();
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (mPrimitiveDescriptions.IsEmpty()) {
-    // Nothing should be rendered, so nothing can be dirty.
-    return NS_OK;
-  }
-
   IntRect filterSpaceBounds = ToIntRect(mFilterSpaceBounds);
   FilterDescription filter(mPrimitiveDescriptions, filterSpaceBounds);
   nsIntRegion resultChangeRegion =
     FilterSupport::ComputeResultChangeRegion(filter,
       mPreFilterDirtyRect, nsIntRegion(), nsIntRegion());
   *aPostFilterDirtyRect =
     FilterSpaceToFrameSpace(resultChangeRegion.GetBounds());
   return NS_OK;
 }
 
 nsresult
-nsSVGFilterInstance::ComputePostFilterExtents(nsRect* aPostFilterExtents)
+nsFilterInstance::ComputePostFilterExtents(nsRect* aPostFilterExtents)
 {
   *aPostFilterExtents = nsRect();
 
-  nsresult rv = BuildPrimitives();
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (mPrimitiveDescriptions.IsEmpty()) {
-    return NS_OK;
-  }
-
   nsIntRect sourceBoundsInt;
   gfxRect sourceBounds = UserSpaceToFilterSpace(mTargetBBox);
   sourceBounds.RoundOut();
   // Detect possible float->int overflow
   if (!gfxUtils::GfxRectToIntRect(sourceBounds, &sourceBoundsInt))
     return NS_ERROR_FAILURE;
   sourceBoundsInt.UnionRect(sourceBoundsInt, mTargetBounds);
 
@@ -801,35 +509,26 @@ nsSVGFilterInstance::ComputePostFilterEx
   FilterDescription filter(mPrimitiveDescriptions, filterSpaceBounds);
   nsIntRegion postFilterExtents =
     FilterSupport::ComputePostFilterExtents(filter, sourceBoundsInt);
   *aPostFilterExtents = FilterSpaceToFrameSpace(postFilterExtents.GetBounds());
   return NS_OK;
 }
 
 nsresult
-nsSVGFilterInstance::ComputeSourceNeededRect(nsRect* aDirty)
+nsFilterInstance::ComputeSourceNeededRect(nsRect* aDirty)
 {
-  nsresult rv = BuildPrimitives();
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (mPrimitiveDescriptions.IsEmpty()) {
-    // Nothing should be rendered, so nothing is needed.
-    return NS_OK;
-  }
-
   ComputeNeededBoxes();
   *aDirty = FilterSpaceToFrameSpace(mSourceGraphic.mNeededBounds);
 
   return NS_OK;
 }
 
 nsIntRect
-nsSVGFilterInstance::FrameSpaceToFilterSpace(const nsRect* aRect) const
+nsFilterInstance::FrameSpaceToFilterSpace(const nsRect* aRect) const
 {
   nsIntRect rect = mFilterSpaceBounds;
   if (aRect) {
     if (aRect->IsEmpty()) {
       return nsIntRect();
     }
     gfxRect rectInCSSPx =
       nsLayoutUtils::RectToGfxRect(*aRect, mAppUnitsPerCSSPx);
@@ -840,28 +539,28 @@ nsSVGFilterInstance::FrameSpaceToFilterS
     if (gfxUtils::GfxRectToIntRect(rectInFilterSpace, &intRect)) {
       rect = intRect;
     }
   }
   return rect;
 }
 
 nsRect
-nsSVGFilterInstance::FilterSpaceToFrameSpace(const nsIntRect& aRect) const
+nsFilterInstance::FilterSpaceToFrameSpace(const nsIntRect& aRect) const
 {
   if (aRect.IsEmpty()) {
     return nsRect();
   }
   gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
   r = mFilterSpaceToFrameSpaceInCSSPxTransform.TransformBounds(r);
   return nsLayoutUtils::RoundGfxRectToAppRect(r, mAppUnitsPerCSSPx);
 }
 
 gfxMatrix
-nsSVGFilterInstance::GetUserSpaceToFrameSpaceInCSSPxTransform() const
+nsFilterInstance::GetUserSpaceToFrameSpaceInCSSPxTransform() const
 {
   gfxMatrix userToFrameSpaceInCSSPx;
 
   if ((mTargetFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
     // As currently implemented by Mozilla for the purposes of filters, user
     // space is the coordinate system established by GetCanvasTM(), since
     // that's what we use to set filterToDeviceSpace above. In other words,
     // for SVG, user space is actually the coordinate system aTarget
copy from layout/svg/nsSVGFilterInstance.h
copy to layout/svg/nsFilterInstance.h
--- a/layout/svg/nsSVGFilterInstance.h
+++ b/layout/svg/nsFilterInstance.h
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef __NS_SVGFILTERINSTANCE_H__
-#define __NS_SVGFILTERINSTANCE_H__
+#ifndef __NS_FILTERINSTANCE_H__
+#define __NS_FILTERINSTANCE_H__
 
 #include "gfxMatrix.h"
 #include "gfxPoint.h"
 #include "gfxRect.h"
 #include "nsCOMPtr.h"
 #include "nsHashKeys.h"
 #include "nsPoint.h"
 #include "nsRect.h"
@@ -17,163 +17,128 @@
 #include "nsSVGFilters.h"
 #include "nsSVGNumber2.h"
 #include "nsSVGNumberPair.h"
 #include "nsTArray.h"
 #include "nsIFrame.h"
 #include "mozilla/gfx/2D.h"
 
 class gfxASurface;
-class gfxImageSurface;
 class nsIFrame;
-class nsSVGFilterFrame;
 class nsSVGFilterPaintCallback;
 
-namespace mozilla {
-namespace dom {
-class SVGFilterElement;
-}
-}
-
 /**
  * This class performs all filter processing.
  * 
  * We build a graph of the filter image data flow, essentially
  * converting the filter graph to SSA. This lets us easily propagate
  * analysis data (such as bounding-boxes) over the filter primitive graph.
  *
  * Definition of "filter space": filter space is a coordinate system that is
  * aligned with the user space of the filtered element, with its origin located
- * at the top left of the filter region (as specified by our ctor's
- * aFilterRegion, and returned by our GetFilterRegion, specifically), and with
- * one unit equal in size to one pixel of the offscreen surface into which the
- * filter output would/will be painted.
+ * at the top left of the filter region, and with one unit equal in size to one
+ * pixel of the offscreen surface into which the filter output would/will be
+ * painted.
  *
  * The definition of "filter region" can be found here:
  * http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion
  */
-class nsSVGFilterInstance
+class nsFilterInstance
 {
-  typedef mozilla::gfx::Point3D Point3D;
   typedef mozilla::gfx::IntRect IntRect;
   typedef mozilla::gfx::SourceSurface SourceSurface;
   typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
 
 public:
   /**
    * Paint the given filtered frame.
    * @param aDirtyArea The area than needs to be painted, in aFilteredFrame's
    *   frame space (i.e. relative to its origin, the top-left corner of its
    *   border box).
    */
-  static nsresult PaintFilteredFrame(nsSVGFilterFrame* aFilterFrame,
-                                     nsRenderingContext *aContext,
+  static nsresult PaintFilteredFrame(nsRenderingContext *aContext,
                                      nsIFrame *aFilteredFrame,
                                      nsSVGFilterPaintCallback *aPaintCallback,
                                      const nsRect* aDirtyArea,
                                      nsIFrame* aTransformRoot = nullptr);
 
   /**
    * Returns the post-filter area that could be dirtied when the given
    * pre-filter area of aFilteredFrame changes.
    * @param aPreFilterDirtyRect The pre-filter area of aFilteredFrame that has
    *   changed, relative to aFilteredFrame, in app units.
    */
-  static nsRect GetPostFilterDirtyArea(nsSVGFilterFrame* aFilterFrame,
-                                       nsIFrame *aFilteredFrame,
+  static nsRect GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
                                        const nsRect& aPreFilterDirtyRect);
 
   /**
    * Returns the pre-filter area that is needed from aFilteredFrame when the
    * given post-filter area needs to be repainted.
    * @param aPostFilterDirtyRect The post-filter area that is dirty, relative
    *   to aFilteredFrame, in app units.
    */
-  static nsRect GetPreFilterNeededArea(nsSVGFilterFrame* aFilterFrame,
-                                       nsIFrame *aFilteredFrame,
+  static nsRect GetPreFilterNeededArea(nsIFrame *aFilteredFrame,
                                        const nsRect& aPostFilterDirtyRect);
 
   /**
    * Returns the post-filter visual overflow rect (paint bounds) of
    * aFilteredFrame.
    * @param aOverrideBBox A user space rect, in user units, that should be used
    *   as aFilteredFrame's bbox ('bbox' is a specific SVG term), if non-null.
    * @param aPreFilterBounds The pre-filter visual overflow rect of
    *   aFilteredFrame, if non-null.
    */
-  static nsRect GetPostFilterBounds(nsSVGFilterFrame* aFilterFrame,
-                                    nsIFrame *aFilteredFrame,
+  static nsRect GetPostFilterBounds(nsIFrame *aFilteredFrame,
                                     const gfxRect *aOverrideBBox = nullptr,
                                     const nsRect *aPreFilterBounds = nullptr);
 
   /**
    * @param aTargetFrame The frame of the filtered element under consideration.
-   * @param aFilterFrame The frame of the SVG filter element.
    * @param aPaintCallback [optional] The callback that Render() should use to
    *   paint. Only required if you will call Render().
    * @param aPostFilterDirtyRect [optional] The bounds of the post-filter area
    *   that has to be repainted, in filter space. Only required if you will
    *   call ComputeSourceNeededRect() or Render().
    * @param aPreFilterDirtyRect [optional] The bounds of the pre-filter area of
    *   the filtered element that changed, in filter space. Only required if you
    *   will call ComputePostFilterDirtyRect().
    * @param aOverridePreFilterVisualOverflowRect [optional] Use a different
    *   visual overflow rect for the target element.
    * @param aOverrideBBox [optional] Use a different SVG bbox for the target
    *   element.
    * @param aTransformRoot [optional] The transform root frame for painting.
    */
-  nsSVGFilterInstance(nsIFrame *aTargetFrame,
-                      nsSVGFilterFrame *aFilterFrame,
-                      nsSVGFilterPaintCallback *aPaintCallback,
-                      const nsRect *aPostFilterDirtyRect = nullptr,
-                      const nsRect *aPreFilterDirtyRect = nullptr,
-                      const nsRect *aOverridePreFilterVisualOverflowRect = nullptr,
-                      const gfxRect *aOverrideBBox = nullptr,
-                      nsIFrame* aTransformRoot = nullptr);
+  nsFilterInstance(nsIFrame *aTargetFrame,
+                   nsSVGFilterPaintCallback *aPaintCallback,
+                   const nsRect *aPostFilterDirtyRect = nullptr,
+                   const nsRect *aPreFilterDirtyRect = nullptr,
+                   const nsRect *aOverridePreFilterVisualOverflowRect = nullptr,
+                   const gfxRect *aOverrideBBox = nullptr,
+                   nsIFrame* aTransformRoot = nullptr);
 
   /**
    * Returns true if the filter instance was created successfully.
    */
   bool IsInitialized() const { return mInitialized; }
 
   /**
-   * Returns the user specified "filter region", in the filtered element's user
-   * space, after it has been adjusted out (if necessary) so that its edges
-   * coincide with pixel boundaries of the offscreen surface into which the
-   * filtered output would/will be painted.
-   */
-  gfxRect GetFilterRegion() const { return mFilterRegion; }
-
-  /**
-   * Returns the size of the user specified "filter region", in filter space.
-   * The size will be {filterRes.x by filterRes.y}, whether the user specified
-   * the filter's filterRes attribute explicitly, or the implementation chose
-   * the filterRes values. (The top-left of the filter region is the origin of
-   * filter space, which is why this method returns an nsIntSize and not an
-   * nsIntRect.)
-   */
-  uint32_t GetFilterResX() const { return mFilterSpaceBounds.width; }
-  uint32_t GetFilterResY() const { return mFilterSpaceBounds.height; }
-
-  /**
    * Draws the filter output into aContext. The area that
    * needs to be painted must have been specified before calling this method
    * by passing it as the aPostFilterDirtyRect argument to the
-   * nsSVGFilterInstance constructor.
+   * nsFilterInstance constructor.
    */
   nsresult Render(gfxContext* aContext);
 
   /**
    * Sets the aPostFilterDirtyRect outparam to the post-filter bounds in frame
    * space of the area that would be dirtied by mTargetFrame when a given
    * pre-filter area of mTargetFrame is dirtied. The pre-filter area must have
    * been specified before calling this method by passing it as the
-   * aPreFilterDirtyRect argument to the nsSVGFilterInstance constructor.
+   * aPreFilterDirtyRect argument to the nsFilterInstance constructor.
    */
   nsresult ComputePostFilterDirtyRect(nsRect* aPostFilterDirtyRect);
 
   /**
    * Sets the aPostFilterExtents outparam to the post-filter bounds in frame
    * space for the whole filter output. This is not necessarily equivalent to
    * the area that would be dirtied in the result when the entire pre-filter
    * area is dirtied, because some filter primitives can generate output
@@ -181,65 +146,33 @@ public:
    */
   nsresult ComputePostFilterExtents(nsRect* aPostFilterExtents);
 
   /**
    * Sets the aDirty outparam to the pre-filter bounds in frame space of the
    * area of mTargetFrame that is needed in order to paint the filtered output
    * for a given post-filter dirtied area. The post-filter area must have been
    * specified before calling this method by passing it as the aPostFilterDirtyRect
-   * argument to the nsSVGFilterInstance constructor.
+   * argument to the nsFilterInstance constructor.
    */
   nsresult ComputeSourceNeededRect(nsRect* aDirty);
 
-  float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumber2 *aNumber) const
-  {
-    return GetPrimitiveNumber(aCtxType, aNumber->GetAnimValue());
-  }
-  float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumberPair *aNumberPair,
-                           nsSVGNumberPair::PairIndex aIndex) const
-  {
-    return GetPrimitiveNumber(aCtxType, aNumberPair->GetAnimValue(aIndex));
-  }
-
-  /**
-   * Converts a userSpaceOnUse/objectBoundingBoxUnits unitless point
-   * into filter space, depending on the value of mPrimitiveUnits. (For
-   * objectBoundingBoxUnits, the bounding box offset is applied to the point.)
-   */
-  Point3D ConvertLocation(const Point3D& aPoint) const;
-
   /**
    * Returns the transform from the filtered element's user space to filter
    * space. This will be a simple translation and/or scale.
    */
   gfxMatrix GetUserSpaceToFilterSpaceTransform() const;
 
   /**
    * Returns the transform from filter space to outer-<svg> device space.
    */
   gfxMatrix GetFilterSpaceToDeviceSpaceTransform() const {
     return mFilterSpaceToDeviceSpaceTransform;
   }
 
-  gfxPoint FilterSpaceToUserSpace(const gfxPoint& aPt) const;
-
-  /**
-   * Returns the transform from filter space to frame space, in CSS px. This
-   * transform does not transform to frame space in its normal app units, since
-   * app units are ints, requiring appropriate rounding which can't be done by
-   * a transform matrix. Callers have to do that themselves as appropriate for
-   * their needs.
-   */
-  gfxMatrix GetFilterSpaceToFrameSpaceInCSSPxTransform() const {
-    return mFilterSpaceToFrameSpaceInCSSPxTransform;
-  }
-
-  int32_t AppUnitsPerCSSPixel() const { return mAppUnitsPerCSSPx; }
-
 private:
   struct SourceInfo {
     // Specifies which parts of the source need to be rendered.
     // Set by ComputeNeededBoxes().
     nsIntRect mNeededBounds;
 
     // The surface that contains the input rendering.
     // Set by BuildSourceImage / BuildSourcePaint.
@@ -276,40 +209,28 @@ private:
   /**
    * Build the list of FilterPrimitiveDescriptions that describes the filter's
    * filter primitives and their connections. This populates
    * mPrimitiveDescriptions and mInputImages.
    */
   nsresult BuildPrimitives();
 
   /**
+   * Add to the list of FilterPrimitiveDescriptions for a particular SVG
+   * reference filter or CSS filter. This populates mPrimitiveDescrs and
+   * mInputImages.
+   */
+  nsresult BuildPrimitivesForFilter(const nsStyleFilter& aFilter);
+
+  /**
    * Computes the filter space bounds of the areas that we actually *need* from
    * the filter sources, based on the value of mPostFilterDirtyRect.
    * This sets mNeededBounds on the corresponding SourceInfo structs.
    */
-   void ComputeNeededBoxes();
-
-  /**
-   * Computes the filter primitive subregion for the given primitive.
-   */
-  IntRect ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement,
-                                          const nsTArray<int32_t>& aInputIndices);
-
-  /**
-   * Takes the input indices of a filter primitive and returns for each input
-   * whether the input's output is tainted.
-   */
-  void GetInputsAreTainted(const nsTArray<int32_t>& aInputIndices,
-                           nsTArray<bool>& aOutInputsAreTainted);
-
-  /**
-   * Scales a numeric filter primitive length in the X, Y or "XY" directions
-   * into a length in filter space (no offset is applied).
-   */
-  float GetPrimitiveNumber(uint8_t aCtxType, float aValue) const;
+  void ComputeNeededBoxes();
 
   gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpace) const;
 
   /**
    * Converts an nsRect that is relative to a filtered frame's origin (i.e. the
    * top-left corner of its border box) into filter space.
    * Returns the entire filter region if aRect is null, or if the result is too
    * large to be stored in an nsIntRect.
@@ -327,21 +248,16 @@ private:
   /**
    * The frame for the element that is currently being filtered.
    */
   nsIFrame*               mTargetFrame;
 
   nsSVGFilterPaintCallback* mPaintCallback;
 
   /**
-   * The filter element referenced by mTargetFrame's element.
-   */
-  const mozilla::dom::SVGFilterElement* mFilterElement;
-
-  /**
    * The SVG bbox of the element that is being filtered, in user space.
    */
   gfxRect                 mTargetBBox;
 
   /**
    * The transform from filter space to outer-<svg> device space.
    */
   gfxMatrix               mFilterSpaceToDeviceSpaceTransform;
@@ -374,21 +290,16 @@ private:
   /**
    * If set, this is the filter space bounds of the outer-<svg> device bounds
    * of the pre-filter area of the filtered element that changed. (As
    * bounds-of-bounds, this may be a fair bit bigger than we actually need,
    * unfortunately.)
    */
   nsIntRect               mPreFilterDirtyRect;
 
-  /**
-   * The 'primitiveUnits' attribute value (objectBoundingBox or userSpaceOnUse).
-   */
-  uint16_t                mPrimitiveUnits;
-
   SourceInfo              mSourceGraphic;
   SourceInfo              mFillPaint;
   SourceInfo              mStrokePaint;
   nsIFrame*               mTransformRoot;
   nsTArray<mozilla::RefPtr<SourceSurface>> mInputImages;
   nsTArray<FilterPrimitiveDescription> mPrimitiveDescriptions;
   int32_t                 mAppUnitsPerCSSPx;
   bool                    mInitialized;
--- a/layout/svg/nsSVGAFrame.cpp
+++ b/layout/svg/nsSVGAFrame.cpp
@@ -30,33 +30,33 @@ public:
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 #endif
 
   // nsIFrame:
   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
                                      nsIAtom*        aAttribute,
-                                     int32_t         aModType);
+                                     int32_t         aModType) MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgAFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGA"), aResult);
   }
 #endif
   // nsISVGChildFrame interface:
-  virtual void NotifySVGChanged(uint32_t aFlags);
+  virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
   
   // nsSVGContainerFrame methods:
   virtual gfxMatrix GetCanvasTM(uint32_t aFor,
                                 nsIFrame* aTransformRoot = nullptr) MOZ_OVERRIDE;
 
 private:
   nsAutoPtr<gfxMatrix> mCanvasTM;
 };
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -261,24 +261,16 @@ nsSVGFilterProperty::IsInObserverLists()
 void
 nsSVGFilterProperty::Invalidate()
 {
   for (uint32_t i = 0; i < mReferences.Length(); i++) {
     mReferences[i]->Invalidate();
   }
 }
 
-nsSVGFilterFrame *
-nsSVGFilterProperty::GetFilterFrame()
-{
-  // Eventually, callers will ask nsSVGFilterProperty for an nsStyleFilter
-  // chain, not a single nsSVGFilterFrame, and this function will go away.
-  return mReferences.Length() > 0 ? mReferences[0]->GetFilterFrame() : nullptr;
-}
-
 NS_IMPL_ISUPPORTS_INHERITED1(nsSVGFilterReference,
                              nsSVGIDRenderingObserver,
                              nsISVGFilterReference);
 
 nsSVGFilterFrame *
 nsSVGFilterReference::GetFilterFrame()
 {
   return static_cast<nsSVGFilterFrame *>
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -202,21 +202,16 @@ public:
                       nsIFrame *aFilteredFrame);
   virtual ~nsSVGFilterProperty();
 
   const nsTArray<nsStyleFilter>& GetFilters() { return mFilters; }
   bool ReferencesValidResources();
   bool IsInObserverLists() const;
   void Invalidate();
 
-  /**
-   * @return the filter frame, or null if there is no filter frame
-   */
-  nsSVGFilterFrame *GetFilterFrame();
-
   // nsISupports
   NS_DECL_ISUPPORTS
 
 private:
   nsTArray<nsSVGFilterReference*> mReferences;
   nsTArray<nsStyleFilter> mFilters;
 };
 
@@ -369,30 +364,23 @@ public:
     nsSVGClipPathFrame *GetClipPathFrame(bool *aOK);
     /**
      * @return the mask frame, or null if there is no mask frame
      * @param aOK if a mask was specified and the designated element
      * exists but is an element of the wrong type, *aOK is set to false.
      * Otherwise *aOK is untouched.
      */
     nsSVGMaskFrame *GetMaskFrame(bool *aOK);
-    /**
-     * @return the filter frame, or null if there is no filter frame
-     * @param aOK if a filter was specified but the designated element
-     * does not exist or is an element of the wrong type, *aOK is set
-     * to false. Otherwise *aOK is untouched.
-     */
-    nsSVGFilterFrame *GetFilterFrame(bool *aOK) {
-      if (!mFilter)
-        return nullptr;
-      nsSVGFilterFrame *filter = mFilter->GetFilterFrame();
-      if (!filter) {
-        *aOK = false;
-      }
-      return filter;
+
+    bool HasValidFilter() {
+      return mFilter && mFilter->ReferencesValidResources();
+    }
+
+    bool HasNoFilterOrHasValidFilter() {
+      return !mFilter || mFilter->ReferencesValidResources();
     }
   };
 
   /**
    * @param aFrame should be the first continuation
    */
   static EffectProperties GetEffectProperties(nsIFrame *aFrame);
 
@@ -410,20 +398,16 @@ public:
    * XXX rename to something more meaningful like RefreshResourceReferences?
    */
   static void UpdateEffects(nsIFrame *aFrame);
 
   /**
    * @param aFrame should be the first continuation
    */
   static nsSVGFilterProperty *GetFilterProperty(nsIFrame *aFrame);
-  static nsSVGFilterFrame *GetFilterFrame(nsIFrame *aFrame) {
-    nsSVGFilterProperty *prop = GetFilterProperty(aFrame);
-    return prop ? prop->GetFilterFrame() : nullptr;
-  }
 
   /**
    * @param aFrame must be a first-continuation.
    */
   static void AddRenderingObserver(Element *aElement, nsSVGRenderingObserver *aObserver);
   /**
    * @param aFrame must be a first-continuation.
    */
--- a/layout/svg/nsSVGFilterInstance.cpp
+++ b/layout/svg/nsSVGFilterInstance.cpp
@@ -7,133 +7,51 @@
 #include "nsSVGFilterInstance.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "nsISVGChildFrame.h"
 #include "nsRenderingContext.h"
 #include "mozilla/dom/SVGFilterElement.h"
+#include "nsReferencedElement.h"
 #include "nsSVGFilterFrame.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGUtils.h"
 #include "SVGContentUtils.h"
 #include "FilterSupport.h"
 #include "gfx2DGlue.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::gfx;
 
-nsresult
-nsSVGFilterInstance::PaintFilteredFrame(nsSVGFilterFrame* aFilterFrame,
-                                        nsRenderingContext *aContext,
-                                        nsIFrame *aFilteredFrame,
-                                        nsSVGFilterPaintCallback *aPaintCallback,
-                                        const nsRect *aDirtyArea,
-                                        nsIFrame* aTransformRoot)
-{
-  nsSVGFilterInstance instance(aFilteredFrame, aFilterFrame, aPaintCallback,
-                               aDirtyArea, nullptr, nullptr, nullptr,
-                               aTransformRoot);
-  if (!instance.IsInitialized()) {
-    return NS_OK;
-  }
-  return instance.Render(aContext->ThebesContext());
-}
+nsSVGFilterInstance::nsSVGFilterInstance(const nsStyleFilter& aFilter,
+                                         nsIFrame *aTargetFrame,
+                                         const gfxRect& aTargetBBox) :
+  mFilter(aFilter),
+  mTargetFrame(aTargetFrame),
+  mTargetBBox(aTargetBBox),
+  mInitialized(false) {
 
-nsRect
-nsSVGFilterInstance::GetPostFilterDirtyArea(nsSVGFilterFrame* aFilterFrame,
-                                            nsIFrame *aFilteredFrame,
-                                            const nsRect& aPreFilterDirtyRect)
-{
-  if (aPreFilterDirtyRect.IsEmpty()) {
-    return nsRect();
+  // Get the filter frame.
+  mFilterFrame = GetFilterFrame();
+  if (!mFilterFrame) {
+    return;
   }
 
-  nsSVGFilterInstance instance(aFilteredFrame, aFilterFrame, nullptr, nullptr,
-                               &aPreFilterDirtyRect);
-  if (!instance.IsInitialized()) {
-    return nsRect();
-  }
-  // We've passed in the source's dirty area so the instance knows about it.
-  // Now we can ask the instance to compute the area of the filter output
-  // that's dirty.
-  nsRect dirtyRect;
-  nsresult rv = instance.ComputePostFilterDirtyRect(&dirtyRect);
-  if (NS_SUCCEEDED(rv)) {
-    return dirtyRect;
-  }
-  return nsRect();
-}
-
-nsRect
-nsSVGFilterInstance::GetPreFilterNeededArea(nsSVGFilterFrame* aFilterFrame,
-                                            nsIFrame *aFilteredFrame,
-                                            const nsRect& aPostFilterDirtyRect)
-{
-  nsSVGFilterInstance instance(aFilteredFrame, aFilterFrame, nullptr,
-                               &aPostFilterDirtyRect);
-  if (!instance.IsInitialized()) {
-    return nsRect();
-  }
-  // Now we can ask the instance to compute the area of the source
-  // that's needed.
-  nsRect neededRect;
-  nsresult rv = instance.ComputeSourceNeededRect(&neededRect);
-  if (NS_SUCCEEDED(rv)) {
-    return neededRect;
+  // Get the filter element.
+  mFilterElement = mFilterFrame->GetFilterContent();
+  if (!mFilterElement) {
+    NS_NOTREACHED("filter frame should have a related element");
+    return;
   }
-  return nsRect();
-}
-
-nsRect
-nsSVGFilterInstance::GetPostFilterBounds(nsSVGFilterFrame* aFilterFrame,
-                                         nsIFrame *aFilteredFrame,
-                                         const gfxRect *aOverrideBBox,
-                                         const nsRect *aPreFilterBounds)
-{
-  MOZ_ASSERT(!(aFilteredFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) ||
-             !(aFilteredFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY),
-             "Non-display SVG do not maintain visual overflow rects");
-
-  nsSVGFilterInstance instance(aFilteredFrame, aFilterFrame, nullptr, nullptr,
-                               aPreFilterBounds, aPreFilterBounds,
-                               aOverrideBBox);
-  if (!instance.IsInitialized()) {
-    return nsRect();
-  }
-  nsRect bbox;
-  nsresult rv = instance.ComputePostFilterExtents(&bbox);
-  if (NS_SUCCEEDED(rv)) {
-    return bbox;
-  }
-  return nsRect();
-}
-
-nsSVGFilterInstance::nsSVGFilterInstance(nsIFrame *aTargetFrame,
-                                         nsSVGFilterFrame *aFilterFrame,
-                                         nsSVGFilterPaintCallback *aPaintCallback,
-                                         const nsRect *aPostFilterDirtyRect,
-                                         const nsRect *aPreFilterDirtyRect,
-                                         const nsRect *aPreFilterVisualOverflowRectOverride,
-                                         const gfxRect *aOverrideBBox,
-                                         nsIFrame* aTransformRoot) :
-  mTargetFrame(aTargetFrame),
-  mPaintCallback(aPaintCallback),
-  mTransformRoot(aTransformRoot),
-  mInitialized(false) {
-
-  mFilterElement =  aFilterFrame->GetFilterContent();
 
   mPrimitiveUnits =
-    aFilterFrame->GetEnumValue(SVGFilterElement::PRIMITIVEUNITS);
-
-  mTargetBBox = aOverrideBBox ?
-    *aOverrideBBox : nsSVGUtils::GetBBox(mTargetFrame);
+    mFilterFrame->GetEnumValue(SVGFilterElement::PRIMITIVEUNITS);
 
   // Get the filter region (in the filtered element's user space):
 
   // XXX if filterUnits is set (or has defaulted) to objectBoundingBox, we
   // should send a warning to the error console if the author has used lengths
   // with units. This is a common mistake and can result in filterRes being
   // *massive* below (because we ignore the units and interpret the number as
   // a factor of the bbox width/height). We should also send a warning if the
@@ -142,22 +60,22 @@ nsSVGFilterInstance::nsSVGFilterInstance
   // interpreted as a fraction of the bounding box and sometimes as user-space
   // units). So really only percentage values should be used in this case.
   
   nsSVGLength2 XYWH[4];
   NS_ABORT_IF_FALSE(sizeof(mFilterElement->mLengthAttributes) == sizeof(XYWH),
                     "XYWH size incorrect");
   memcpy(XYWH, mFilterElement->mLengthAttributes, 
     sizeof(mFilterElement->mLengthAttributes));
-  XYWH[0] = *aFilterFrame->GetLengthValue(SVGFilterElement::ATTR_X);
-  XYWH[1] = *aFilterFrame->GetLengthValue(SVGFilterElement::ATTR_Y);
-  XYWH[2] = *aFilterFrame->GetLengthValue(SVGFilterElement::ATTR_WIDTH);
-  XYWH[3] = *aFilterFrame->GetLengthValue(SVGFilterElement::ATTR_HEIGHT);
+  XYWH[0] = *mFilterFrame->GetLengthValue(SVGFilterElement::ATTR_X);
+  XYWH[1] = *mFilterFrame->GetLengthValue(SVGFilterElement::ATTR_Y);
+  XYWH[2] = *mFilterFrame->GetLengthValue(SVGFilterElement::ATTR_WIDTH);
+  XYWH[3] = *mFilterFrame->GetLengthValue(SVGFilterElement::ATTR_HEIGHT);
   uint16_t filterUnits =
-    aFilterFrame->GetEnumValue(SVGFilterElement::FILTERUNITS);
+    mFilterFrame->GetEnumValue(SVGFilterElement::FILTERUNITS);
   // The filter region in user space, in user units:
   mFilterRegion = nsSVGUtils::GetRelativeRect(filterUnits,
     XYWH, mTargetBBox, mTargetFrame);
 
   if (mFilterRegion.Width() <= 0 || mFilterRegion.Height() <= 0) {
     // 0 disables rendering, < 0 is error. dispatch error console warning
     // or error as appropriate.
     return;
@@ -166,17 +84,17 @@ nsSVGFilterInstance::nsSVGFilterInstance
   // Calculate filterRes (the width and height of the pixel buffer of the
   // temporary offscreen surface that we would/will create to paint into when
   // painting the entire filtered element) and, if necessary, adjust
   // mFilterRegion out slightly so that it aligns with pixel boundaries of this
   // buffer:
 
   gfxIntSize filterRes;
   const nsSVGIntegerPair* filterResAttrs =
-    aFilterFrame->GetIntegerPairValue(SVGFilterElement::FILTERRES);
+    mFilterFrame->GetIntegerPairValue(SVGFilterElement::FILTERRES);
   if (filterResAttrs->IsExplicitlySet()) {
     int32_t filterResX = filterResAttrs->GetAnimValue(nsSVGIntegerPair::eFirst);
     int32_t filterResY = filterResAttrs->GetAnimValue(nsSVGIntegerPair::eSecond);
     if (filterResX <= 0 || filterResY <= 0) {
       // 0 disables rendering, < 0 is error. dispatch error console warning?
       return;
     }
 
@@ -209,50 +127,59 @@ nsSVGFilterInstance::nsSVGFilterInstance
     bool overflow;
     filterRes = nsSVGUtils::ConvertToSurfaceSize(mFilterRegion.Size(),
                                                  &overflow);
     mFilterRegion.Scale(1.0 / scale.width, 1.0 / scale.height);
   }
 
   mFilterSpaceBounds.SetRect(nsIntPoint(0, 0), filterRes);
 
-  // Get various transforms:
+  mInitialized = true;
+}
 
-  gfxMatrix filterToUserSpace(mFilterRegion.Width() / filterRes.width, 0.0f,
-                              0.0f, mFilterRegion.Height() / filterRes.height,
-                              mFilterRegion.X(), mFilterRegion.Y());
+nsSVGFilterFrame*
+nsSVGFilterInstance::GetFilterFrame()
+{
+  if (mFilter.GetType() != NS_STYLE_FILTER_URL) {
+    // The filter is not an SVG reference filter.
+    return nullptr;
+  }
 
-  // Only used (so only set) when we paint:
-  if (mPaintCallback) {
-    mFilterSpaceToDeviceSpaceTransform = filterToUserSpace *
-              nsSVGUtils::GetCanvasTM(mTargetFrame, nsISVGChildFrame::FOR_PAINTING);
+  nsIURI* url = mFilter.GetURL();
+  if (!url) {
+    NS_NOTREACHED("an nsStyleFilter of type URL should have a non-null URL");
+    return nullptr;
   }
 
-  // Convert the passed in rects from frame to filter space:
-
-  mAppUnitsPerCSSPx = mTargetFrame->PresContext()->AppUnitsPerCSSPixel();
-
-  mFilterSpaceToFrameSpaceInCSSPxTransform =
-    filterToUserSpace * GetUserSpaceToFrameSpaceInCSSPxTransform();
-  // mFilterSpaceToFrameSpaceInCSSPxTransform is always invertible
-  mFrameSpaceInCSSPxToFilterSpaceTransform =
-    mFilterSpaceToFrameSpaceInCSSPxTransform;
-  mFrameSpaceInCSSPxToFilterSpaceTransform.Invert();
-
-  mPostFilterDirtyRect = FrameSpaceToFilterSpace(aPostFilterDirtyRect);
-  mPreFilterDirtyRect = FrameSpaceToFilterSpace(aPreFilterDirtyRect);
-  if (aPreFilterVisualOverflowRectOverride) {
-    mTargetBounds = 
-      FrameSpaceToFilterSpace(aPreFilterVisualOverflowRectOverride);
-  } else {
-    nsRect preFilterVOR = mTargetFrame->GetPreEffectsVisualOverflowRect();
-    mTargetBounds = FrameSpaceToFilterSpace(&preFilterVOR);
+  // Get the target element to use as a point of reference for looking up the
+  // filter element.
+  nsIContent* targetElement = mTargetFrame->GetContent();
+  if (!targetElement) {
+    // There is no element associated with the target frame.
+    return nullptr;
   }
 
-  mInitialized = true;
+  // Look up the filter element by URL.
+  nsReferencedElement filterElement;
+  bool watch = false;
+  filterElement.Reset(targetElement, url, watch);
+  Element* element = filterElement.get();
+  if (!element) {
+    // The URL points to no element.
+    return nullptr;
+  }
+
+  // Get the frame of the filter element.
+  nsIFrame* frame = element->GetPrimaryFrame();
+  if (frame->GetType() != nsGkAtoms::svgFilterFrame) {
+    // The URL points to an element that's not an SVG filter element.
+    return nullptr;
+  }
+
+  return static_cast<nsSVGFilterFrame*>(frame);
 }
 
 float
 nsSVGFilterInstance::GetPrimitiveNumber(uint8_t aCtxType, float aValue) const
 {
   nsSVGLength2 val;
   val.Init(aCtxType, 0xff, aValue,
            nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER);
@@ -301,45 +228,39 @@ gfxRect
 nsSVGFilterInstance::UserSpaceToFilterSpace(const gfxRect& aRect) const
 {
   gfxRect r = aRect - mFilterRegion.TopLeft();
   r.Scale(mFilterSpaceBounds.width / mFilterRegion.Width(),
           mFilterSpaceBounds.height / mFilterRegion.Height());
   return r;
 }
 
-gfxPoint
-nsSVGFilterInstance::FilterSpaceToUserSpace(const gfxPoint& aPt) const
-{
-  return gfxPoint(aPt.x * mFilterRegion.Width() / mFilterSpaceBounds.width + mFilterRegion.X(),
-                  aPt.y * mFilterRegion.Height() / mFilterSpaceBounds.height + mFilterRegion.Y());
-}
-
 gfxMatrix
 nsSVGFilterInstance::GetUserSpaceToFilterSpaceTransform() const
 {
   gfxFloat widthScale = mFilterSpaceBounds.width / mFilterRegion.Width();
   gfxFloat heightScale = mFilterSpaceBounds.height / mFilterRegion.Height();
   return gfxMatrix(widthScale, 0.0f,
                    0.0f, heightScale,
                    -mFilterRegion.X() * widthScale, -mFilterRegion.Y() * heightScale);
 }
 
 IntRect
 nsSVGFilterInstance::ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement,
+                                                     const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                                      const nsTArray<int32_t>& aInputIndices)
 {
   nsSVGFE* fE = aFilterElement;
 
   IntRect defaultFilterSubregion(0,0,0,0);
   if (fE->SubregionIsUnionOfRegions()) {
     for (uint32_t i = 0; i < aInputIndices.Length(); ++i) {
       int32_t inputIndex = aInputIndices[i];
       IntRect inputSubregion = inputIndex >= 0 ?
-        mPrimitiveDescriptions[inputIndex].PrimitiveSubregion() :
+        aPrimitiveDescrs[inputIndex].PrimitiveSubregion() :
         ToIntRect(mFilterSpaceBounds);
 
       defaultFilterSubregion = defaultFilterSubregion.Union(inputSubregion);
     }
   } else {
     defaultFilterSubregion = ToIntRect(mFilterSpaceBounds);
   }
 
@@ -360,26 +281,27 @@ nsSVGFilterInstance::ComputeFilterPrimit
   // Following the spec, any pixel partially in the region is included
   // in the region.
   region.RoundOut();
 
   return RoundedToInt(region);
 }
 
 void
-nsSVGFilterInstance::GetInputsAreTainted(const nsTArray<int32_t>& aInputIndices,
+nsSVGFilterInstance::GetInputsAreTainted(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
+                                         const nsTArray<int32_t>& aInputIndices,
                                          nsTArray<bool>& aOutInputsAreTainted)
 {
   for (uint32_t i = 0; i < aInputIndices.Length(); i++) {
     int32_t inputIndex = aInputIndices[i];
     if (inputIndex < 0) {
       // SourceGraphic, SourceAlpha, FillPaint and StrokePaint are tainted.
       aOutInputsAreTainted.AppendElement(true);
     } else {
-      aOutInputsAreTainted.AppendElement(mPrimitiveDescriptions[inputIndex].IsTainted());
+      aOutInputsAreTainted.AppendElement(aPrimitiveDescrs[inputIndex].IsTainted());
     }
   }
 }
 
 static nsresult
 GetSourceIndices(nsSVGFE* aFilterElement,
                  int32_t aCurrentIndex,
                  const nsDataHashtable<nsStringHashKey, int32_t>& aImageTable,
@@ -416,17 +338,18 @@ GetSourceIndices(nsSVGFE* aFilterElement
 
     MOZ_ASSERT(sourceIndex < aCurrentIndex);
     aSourceIndices.AppendElement(sourceIndex);
   }
   return NS_OK;
 }
 
 nsresult
-nsSVGFilterInstance::BuildPrimitives()
+nsSVGFilterInstance::BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
+                                     nsTArray<mozilla::RefPtr<SourceSurface>>& aInputImages)
 {
   nsTArray<nsRefPtr<nsSVGFE> > primitives;
   for (nsIContent* child = mFilterElement->nsINode::GetFirstChild();
        child;
        child = child->GetNextSibling()) {
     nsRefPtr<nsSVGFE> primitive;
     CallQueryInterface(child, (nsSVGFE**)getter_AddRefs(primitive));
     if (primitive) {
@@ -445,443 +368,45 @@ nsSVGFilterInstance::BuildPrimitives()
 
     nsAutoTArray<int32_t,2> sourceIndices;
     nsresult rv = GetSourceIndices(filter, i, imageTable, sourceIndices);
     if (NS_FAILED(rv)) {
       return rv;
     }
 
     IntRect primitiveSubregion =
-      ComputeFilterPrimitiveSubregion(filter, sourceIndices);
+      ComputeFilterPrimitiveSubregion(filter, aPrimitiveDescrs, sourceIndices);
 
     nsTArray<bool> sourcesAreTainted;
-    GetInputsAreTainted(sourceIndices, sourcesAreTainted);
+    GetInputsAreTainted(aPrimitiveDescrs, sourceIndices, sourcesAreTainted);
 
     FilterPrimitiveDescription descr =
-      filter->GetPrimitiveDescription(this, primitiveSubregion, sourcesAreTainted, mInputImages);
+      filter->GetPrimitiveDescription(this, primitiveSubregion, sourcesAreTainted, aInputImages);
 
     descr.SetIsTainted(filter->OutputIsTainted(sourcesAreTainted, principal));
     descr.SetPrimitiveSubregion(primitiveSubregion);
 
     for (uint32_t j = 0; j < sourceIndices.Length(); j++) {
       int32_t inputIndex = sourceIndices[j];
       descr.SetInputPrimitive(j, inputIndex);
       ColorSpace inputColorSpace =
-        inputIndex < 0 ? SRGB : mPrimitiveDescriptions[inputIndex].OutputColorSpace();
+        inputIndex < 0 ? SRGB : aPrimitiveDescrs[inputIndex].OutputColorSpace();
       ColorSpace desiredInputColorSpace = filter->GetInputColorSpace(j, inputColorSpace);
       descr.SetInputColorSpace(j, desiredInputColorSpace);
       if (j == 0) {
         // the output color space is whatever in1 is if there is an in1
         descr.SetOutputColorSpace(desiredInputColorSpace);
       }
     }
 
     if (sourceIndices.Length() == 0) {
       descr.SetOutputColorSpace(filter->GetOutputColorSpace());
     }
 
-    mPrimitiveDescriptions.AppendElement(descr);
+    aPrimitiveDescrs.AppendElement(descr);
 
     nsAutoString str;
     filter->GetResultImageName().GetAnimValue(str, filter);
     imageTable.Put(str, i);
   }
 
   return NS_OK;
 }
-
-void
-nsSVGFilterInstance::ComputeNeededBoxes()
-{
-  if (mPrimitiveDescriptions.IsEmpty())
-    return;
-
-  nsIntRegion sourceGraphicNeededRegion;
-  nsIntRegion fillPaintNeededRegion;
-  nsIntRegion strokePaintNeededRegion;
-
-  FilterDescription filter(mPrimitiveDescriptions, ToIntRect(mFilterSpaceBounds));
-  FilterSupport::ComputeSourceNeededRegions(
-    filter, mPostFilterDirtyRect,
-    sourceGraphicNeededRegion, fillPaintNeededRegion, strokePaintNeededRegion);
-
-  nsIntRect sourceBoundsInt;
-  gfxRect sourceBounds = UserSpaceToFilterSpace(mTargetBBox);
-  sourceBounds.RoundOut();
-  // Detect possible float->int overflow
-  if (!gfxUtils::GfxRectToIntRect(sourceBounds, &sourceBoundsInt))
-    return;
-  sourceBoundsInt.UnionRect(sourceBoundsInt, mTargetBounds);
-
-  sourceGraphicNeededRegion.And(sourceGraphicNeededRegion, sourceBoundsInt);
-
-  mSourceGraphic.mNeededBounds = sourceGraphicNeededRegion.GetBounds();
-  mFillPaint.mNeededBounds = fillPaintNeededRegion.GetBounds();
-  mStrokePaint.mNeededBounds = strokePaintNeededRegion.GetBounds();
-}
-
-nsresult
-nsSVGFilterInstance::BuildSourcePaint(SourceInfo *aSource,
-                                      gfxASurface* aTargetSurface,
-                                      DrawTarget* aTargetDT)
-{
-  nsIntRect neededRect = aSource->mNeededBounds;
-
-  RefPtr<DrawTarget> offscreenDT;
-  nsRefPtr<gfxASurface> offscreenSurface;
-  nsRefPtr<gfxContext> ctx;
-  if (aTargetSurface) {
-    offscreenSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(
-      neededRect.Size().ToIntSize(), gfxContentType::COLOR_ALPHA);
-    if (!offscreenSurface || offscreenSurface->CairoStatus()) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    ctx = new gfxContext(offscreenSurface);
-  } else {
-    offscreenDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
-      ToIntSize(neededRect.Size()), SurfaceFormat::B8G8R8A8);
-    if (!offscreenDT) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    ctx = new gfxContext(offscreenDT);
-  }
-
-  ctx->Translate(-neededRect.TopLeft());
-
-  nsRenderingContext tmpCtx;
-  tmpCtx.Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
-
-  gfxMatrix m = GetUserSpaceToFilterSpaceTransform();
-  m.Invert();
-  gfxRect r = m.TransformBounds(mFilterSpaceBounds);
-
-  gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
-  gfxContext *gfx = tmpCtx.ThebesContext();
-  gfx->Multiply(deviceToFilterSpace);
-
-  gfx->Save();
-
-  gfxMatrix matrix =
-    nsSVGUtils::GetCanvasTM(mTargetFrame, nsISVGChildFrame::FOR_PAINTING,
-                            mTransformRoot);
-  if (!matrix.IsSingular()) {
-    gfx->Multiply(matrix);
-    gfx->Rectangle(r);
-    if ((aSource == &mFillPaint && 
-         nsSVGUtils::SetupCairoFillPaint(mTargetFrame, gfx)) ||
-        (aSource == &mStrokePaint &&
-         nsSVGUtils::SetupCairoStrokePaint(mTargetFrame, gfx))) {
-      gfx->Fill();
-    }
-  }
-  gfx->Restore();
-
-  if (offscreenSurface) {
-    aSource->mSourceSurface =
-      gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTargetDT, offscreenSurface);
-  } else {
-    aSource->mSourceSurface = offscreenDT->Snapshot();
-  }
-  aSource->mSurfaceRect = ToIntRect(neededRect);
-
-  return NS_OK;
-}
-
-nsresult
-nsSVGFilterInstance::BuildSourcePaints(gfxASurface* aTargetSurface,
-                                       DrawTarget* aTargetDT)
-{
-  nsresult rv = NS_OK;
-
-  if (!mFillPaint.mNeededBounds.IsEmpty()) {
-    rv = BuildSourcePaint(&mFillPaint, aTargetSurface, aTargetDT);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if (!mStrokePaint.mNeededBounds.IsEmpty()) {
-    rv = BuildSourcePaint(&mStrokePaint, aTargetSurface, aTargetDT);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  return  rv;
-}
-
-nsresult
-nsSVGFilterInstance::BuildSourceImage(gfxASurface* aTargetSurface,
-                                      DrawTarget* aTargetDT)
-{
-  nsIntRect neededRect = mSourceGraphic.mNeededBounds;
-  if (neededRect.IsEmpty()) {
-    return NS_OK;
-  }
-
-  RefPtr<DrawTarget> offscreenDT;
-  nsRefPtr<gfxASurface> offscreenSurface;
-  nsRefPtr<gfxContext> ctx;
-  if (aTargetSurface) {
-    offscreenSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(
-      neededRect.Size().ToIntSize(), gfxContentType::COLOR_ALPHA);
-    if (!offscreenSurface || offscreenSurface->CairoStatus()) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    ctx = new gfxContext(offscreenSurface);
-  } else {
-    offscreenDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
-      ToIntSize(neededRect.Size()), SurfaceFormat::B8G8R8A8);
-    if (!offscreenDT) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    ctx = new gfxContext(offscreenDT);
-  }
-
-  ctx->Translate(-neededRect.TopLeft());
-
-  nsRenderingContext tmpCtx;
-  tmpCtx.Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
-
-  gfxMatrix m = GetUserSpaceToFilterSpaceTransform();
-  m.Invert();
-  gfxRect r = m.TransformBounds(neededRect);
-  r.RoundOut();
-  nsIntRect dirty;
-  if (!gfxUtils::GfxRectToIntRect(r, &dirty))
-    return NS_ERROR_FAILURE;
-
-  // SVG graphics paint to device space, so we need to set an initial device
-  // space to filter space transform on the gfxContext that SourceGraphic
-  // and SourceAlpha will paint to.
-  //
-  // (In theory it would be better to minimize error by having filtered SVG
-  // graphics temporarily paint to user space when painting the sources and
-  // only set a user space to filter space transform on the gfxContext
-  // (since that would eliminate the transform multiplications from user
-  // space to device space and back again). However, that would make the
-  // code more complex while being hard to get right without introducing
-  // subtle bugs, and in practice it probably makes no real difference.)
-  gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
-  tmpCtx.ThebesContext()->Multiply(deviceToFilterSpace);
-  mPaintCallback->Paint(&tmpCtx, mTargetFrame, &dirty, mTransformRoot);
-
-  RefPtr<SourceSurface> sourceGraphicSource;
-
-  if (offscreenSurface) {
-    sourceGraphicSource =
-      gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTargetDT, offscreenSurface);
-  } else {
-    sourceGraphicSource = offscreenDT->Snapshot();
-  }
-
-  mSourceGraphic.mSourceSurface = sourceGraphicSource;
-  mSourceGraphic.mSurfaceRect = ToIntRect(neededRect);
-   
-  return NS_OK;
-}
-
-nsresult
-nsSVGFilterInstance::Render(gfxContext* aContext)
-{
-  nsresult rv = BuildPrimitives();
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (mPrimitiveDescriptions.IsEmpty()) {
-    // Nothing should be rendered.
-    return NS_OK;
-  }
-
-  nsIntRect filterRect = mPostFilterDirtyRect.Intersect(mFilterSpaceBounds);
-  gfxMatrix ctm = GetFilterSpaceToDeviceSpaceTransform();
-
-  if (filterRect.IsEmpty() || ctm.IsSingular()) {
-    return NS_OK;
-  }
-
-  Matrix oldDTMatrix;
-  nsRefPtr<gfxASurface> resultImage;
-  RefPtr<DrawTarget> dt;
-  if (aContext->IsCairo()) {
-    resultImage =
-      gfxPlatform::GetPlatform()->CreateOffscreenSurface(filterRect.Size().ToIntSize(),
-                                                         gfxContentType::COLOR_ALPHA);
-    if (!resultImage || resultImage->CairoStatus())
-      return NS_ERROR_OUT_OF_MEMORY;
-
-    // Create a Cairo DrawTarget around resultImage.
-    dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(
-           resultImage, ToIntSize(filterRect.Size()));
-  } else {
-    // When we have a DrawTarget-backed context, we can call DrawFilter
-    // directly on the target DrawTarget and don't need a temporary DT.
-    dt = aContext->GetDrawTarget();
-    oldDTMatrix = dt->GetTransform();
-    Matrix matrix = ToMatrix(ctm);
-    matrix.Translate(filterRect.x, filterRect.y);
-    dt->SetTransform(matrix * oldDTMatrix);
-  }
-
-  ComputeNeededBoxes();
-
-  rv = BuildSourceImage(resultImage, dt);
-  if (NS_FAILED(rv))
-    return rv;
-  rv = BuildSourcePaints(resultImage, dt);
-  if (NS_FAILED(rv))
-    return rv;
-
-  IntRect filterSpaceBounds = ToIntRect(mFilterSpaceBounds);
-  FilterDescription filter(mPrimitiveDescriptions, filterSpaceBounds);
-
-  FilterSupport::RenderFilterDescription(
-    dt, filter, ToRect(filterRect),
-    mSourceGraphic.mSourceSurface, mSourceGraphic.mSurfaceRect,
-    mFillPaint.mSourceSurface, mFillPaint.mSurfaceRect,
-    mStrokePaint.mSourceSurface, mStrokePaint.mSurfaceRect,
-    mInputImages);
-
-  if (resultImage) {
-    aContext->Save();
-    aContext->Multiply(ctm);
-    aContext->Translate(filterRect.TopLeft());
-    aContext->SetSource(resultImage);
-    aContext->Paint();
-    aContext->Restore();
-  } else {
-    dt->SetTransform(oldDTMatrix);
-  }
-
-  return NS_OK;
-}
-
-nsresult
-nsSVGFilterInstance::ComputePostFilterDirtyRect(nsRect* aPostFilterDirtyRect)
-{
-  *aPostFilterDirtyRect = nsRect();
-  if (mPreFilterDirtyRect.IsEmpty()) {
-    return NS_OK;
-  }
-
-  nsresult rv = BuildPrimitives();
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (mPrimitiveDescriptions.IsEmpty()) {
-    // Nothing should be rendered, so nothing can be dirty.
-    return NS_OK;
-  }
-
-  IntRect filterSpaceBounds = ToIntRect(mFilterSpaceBounds);
-  FilterDescription filter(mPrimitiveDescriptions, filterSpaceBounds);
-  nsIntRegion resultChangeRegion =
-    FilterSupport::ComputeResultChangeRegion(filter,
-      mPreFilterDirtyRect, nsIntRegion(), nsIntRegion());
-  *aPostFilterDirtyRect =
-    FilterSpaceToFrameSpace(resultChangeRegion.GetBounds());
-  return NS_OK;
-}
-
-nsresult
-nsSVGFilterInstance::ComputePostFilterExtents(nsRect* aPostFilterExtents)
-{
-  *aPostFilterExtents = nsRect();
-
-  nsresult rv = BuildPrimitives();
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (mPrimitiveDescriptions.IsEmpty()) {
-    return NS_OK;
-  }
-
-  nsIntRect sourceBoundsInt;
-  gfxRect sourceBounds = UserSpaceToFilterSpace(mTargetBBox);
-  sourceBounds.RoundOut();
-  // Detect possible float->int overflow
-  if (!gfxUtils::GfxRectToIntRect(sourceBounds, &sourceBoundsInt))
-    return NS_ERROR_FAILURE;
-  sourceBoundsInt.UnionRect(sourceBoundsInt, mTargetBounds);
-
-  IntRect filterSpaceBounds = ToIntRect(mFilterSpaceBounds);
-  FilterDescription filter(mPrimitiveDescriptions, filterSpaceBounds);
-  nsIntRegion postFilterExtents =
-    FilterSupport::ComputePostFilterExtents(filter, sourceBoundsInt);
-  *aPostFilterExtents = FilterSpaceToFrameSpace(postFilterExtents.GetBounds());
-  return NS_OK;
-}
-
-nsresult
-nsSVGFilterInstance::ComputeSourceNeededRect(nsRect* aDirty)
-{
-  nsresult rv = BuildPrimitives();
-  if (NS_FAILED(rv))
-    return rv;
-
-  if (mPrimitiveDescriptions.IsEmpty()) {
-    // Nothing should be rendered, so nothing is needed.
-    return NS_OK;
-  }
-
-  ComputeNeededBoxes();
-  *aDirty = FilterSpaceToFrameSpace(mSourceGraphic.mNeededBounds);
-
-  return NS_OK;
-}
-
-nsIntRect
-nsSVGFilterInstance::FrameSpaceToFilterSpace(const nsRect* aRect) const
-{
-  nsIntRect rect = mFilterSpaceBounds;
-  if (aRect) {
-    if (aRect->IsEmpty()) {
-      return nsIntRect();
-    }
-    gfxRect rectInCSSPx =
-      nsLayoutUtils::RectToGfxRect(*aRect, mAppUnitsPerCSSPx);
-    gfxRect rectInFilterSpace =
-      mFrameSpaceInCSSPxToFilterSpaceTransform.TransformBounds(rectInCSSPx);
-    rectInFilterSpace.RoundOut();
-    nsIntRect intRect;
-    if (gfxUtils::GfxRectToIntRect(rectInFilterSpace, &intRect)) {
-      rect = intRect;
-    }
-  }
-  return rect;
-}
-
-nsRect
-nsSVGFilterInstance::FilterSpaceToFrameSpace(const nsIntRect& aRect) const
-{
-  if (aRect.IsEmpty()) {
-    return nsRect();
-  }
-  gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height);
-  r = mFilterSpaceToFrameSpaceInCSSPxTransform.TransformBounds(r);
-  return nsLayoutUtils::RoundGfxRectToAppRect(r, mAppUnitsPerCSSPx);
-}
-
-gfxMatrix
-nsSVGFilterInstance::GetUserSpaceToFrameSpaceInCSSPxTransform() const
-{
-  gfxMatrix userToFrameSpaceInCSSPx;
-
-  if ((mTargetFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
-    // As currently implemented by Mozilla for the purposes of filters, user
-    // space is the coordinate system established by GetCanvasTM(), since
-    // that's what we use to set filterToDeviceSpace above. In other words,
-    // for SVG, user space is actually the coordinate system aTarget
-    // establishes for _its_ children (i.e. after taking account of any x/y
-    // and viewBox attributes), not the coordinate system that is established
-    // for it by its 'transform' attribute (or by its _parent_) as it's
-    // normally defined. (XXX We should think about fixing this.) The only
-    // frame type for which these extra transforms are not simply an x/y
-    // translation is nsSVGInnerSVGFrame, hence we treat it specially here.
-    if (mTargetFrame->GetType() == nsGkAtoms::svgInnerSVGFrame) {
-      userToFrameSpaceInCSSPx =
-        static_cast<nsSVGElement*>(mTargetFrame->GetContent())->
-          PrependLocalTransformsTo(gfxMatrix());
-    } else {
-      gfxPoint targetsUserSpaceOffset =
-        nsLayoutUtils::RectToGfxRect(mTargetFrame->GetRect(),
-                                     mAppUnitsPerCSSPx).TopLeft();
-      userToFrameSpaceInCSSPx.Translate(-targetsUserSpaceOffset);
-    }
-  }
-  // else, for all other frames, leave as the identity matrix
-  return userToFrameSpaceInCSSPx;
-}
--- a/layout/svg/nsSVGFilterInstance.h
+++ b/layout/svg/nsSVGFilterInstance.h
@@ -2,198 +2,88 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGFILTERINSTANCE_H__
 #define __NS_SVGFILTERINSTANCE_H__
 
 #include "gfxMatrix.h"
-#include "gfxPoint.h"
 #include "gfxRect.h"
-#include "nsCOMPtr.h"
-#include "nsHashKeys.h"
-#include "nsPoint.h"
-#include "nsRect.h"
-#include "nsSize.h"
 #include "nsSVGFilters.h"
 #include "nsSVGNumber2.h"
 #include "nsSVGNumberPair.h"
 #include "nsTArray.h"
 #include "nsIFrame.h"
-#include "mozilla/gfx/2D.h"
 
-class gfxASurface;
-class gfxImageSurface;
 class nsIFrame;
 class nsSVGFilterFrame;
 class nsSVGFilterPaintCallback;
 
 namespace mozilla {
 namespace dom {
 class SVGFilterElement;
 }
 }
 
 /**
- * This class performs all filter processing.
- * 
- * We build a graph of the filter image data flow, essentially
- * converting the filter graph to SSA. This lets us easily propagate
- * analysis data (such as bounding-boxes) over the filter primitive graph.
+ * This class helps nsFilterInstance build its filter graph by processing a
+ * single SVG reference filter.
  *
- * Definition of "filter space": filter space is a coordinate system that is
- * aligned with the user space of the filtered element, with its origin located
- * at the top left of the filter region (as specified by our ctor's
- * aFilterRegion, and returned by our GetFilterRegion, specifically), and with
- * one unit equal in size to one pixel of the offscreen surface into which the
- * filter output would/will be painted.
- *
- * The definition of "filter region" can be found here:
- * http://www.w3.org/TR/SVG11/filters.html#FilterEffectsRegion
+ * In BuildPrimitives, this class iterates through the referenced <filter>
+ * element's primitive elements, creating a FilterPrimitiveDescription for
+ * each one.
  */
 class nsSVGFilterInstance
 {
   typedef mozilla::gfx::Point3D Point3D;
   typedef mozilla::gfx::IntRect IntRect;
   typedef mozilla::gfx::SourceSurface SourceSurface;
-  typedef mozilla::gfx::DrawTarget DrawTarget;
   typedef mozilla::gfx::FilterPrimitiveDescription FilterPrimitiveDescription;
 
 public:
   /**
-   * Paint the given filtered frame.
-   * @param aDirtyArea The area than needs to be painted, in aFilteredFrame's
-   *   frame space (i.e. relative to its origin, the top-left corner of its
-   *   border box).
-   */
-  static nsresult PaintFilteredFrame(nsSVGFilterFrame* aFilterFrame,
-                                     nsRenderingContext *aContext,
-                                     nsIFrame *aFilteredFrame,
-                                     nsSVGFilterPaintCallback *aPaintCallback,
-                                     const nsRect* aDirtyArea,
-                                     nsIFrame* aTransformRoot = nullptr);
-
-  /**
-   * Returns the post-filter area that could be dirtied when the given
-   * pre-filter area of aFilteredFrame changes.
-   * @param aPreFilterDirtyRect The pre-filter area of aFilteredFrame that has
-   *   changed, relative to aFilteredFrame, in app units.
-   */
-  static nsRect GetPostFilterDirtyArea(nsSVGFilterFrame* aFilterFrame,
-                                       nsIFrame *aFilteredFrame,
-                                       const nsRect& aPreFilterDirtyRect);
-
-  /**
-   * Returns the pre-filter area that is needed from aFilteredFrame when the
-   * given post-filter area needs to be repainted.
-   * @param aPostFilterDirtyRect The post-filter area that is dirty, relative
-   *   to aFilteredFrame, in app units.
+   * @param aFilter The SVG reference filter to process.
+   * @param aTargetFrame The frame of the filtered element under consideration.
+   * @param aTargetBBox The SVG bbox to use for the target frame, computed by
+   *   the caller. The caller may decide to override the actual SVG bbox.
    */
-  static nsRect GetPreFilterNeededArea(nsSVGFilterFrame* aFilterFrame,
-                                       nsIFrame *aFilteredFrame,
-                                       const nsRect& aPostFilterDirtyRect);
-
-  /**
-   * Returns the post-filter visual overflow rect (paint bounds) of
-   * aFilteredFrame.
-   * @param aOverrideBBox A user space rect, in user units, that should be used
-   *   as aFilteredFrame's bbox ('bbox' is a specific SVG term), if non-null.
-   * @param aPreFilterBounds The pre-filter visual overflow rect of
-   *   aFilteredFrame, if non-null.
-   */
-  static nsRect GetPostFilterBounds(nsSVGFilterFrame* aFilterFrame,
-                                    nsIFrame *aFilteredFrame,
-                                    const gfxRect *aOverrideBBox = nullptr,
-                                    const nsRect *aPreFilterBounds = nullptr);
-
-  /**
-   * @param aTargetFrame The frame of the filtered element under consideration.
-   * @param aFilterFrame The frame of the SVG filter element.
-   * @param aPaintCallback [optional] The callback that Render() should use to
-   *   paint. Only required if you will call Render().
-   * @param aPostFilterDirtyRect [optional] The bounds of the post-filter area
-   *   that has to be repainted, in filter space. Only required if you will
-   *   call ComputeSourceNeededRect() or Render().
-   * @param aPreFilterDirtyRect [optional] The bounds of the pre-filter area of
-   *   the filtered element that changed, in filter space. Only required if you
-   *   will call ComputePostFilterDirtyRect().
-   * @param aOverridePreFilterVisualOverflowRect [optional] Use a different
-   *   visual overflow rect for the target element.
-   * @param aOverrideBBox [optional] Use a different SVG bbox for the target
-   *   element.
-   * @param aTransformRoot [optional] The transform root frame for painting.
-   */
-  nsSVGFilterInstance(nsIFrame *aTargetFrame,
-                      nsSVGFilterFrame *aFilterFrame,
-                      nsSVGFilterPaintCallback *aPaintCallback,
-                      const nsRect *aPostFilterDirtyRect = nullptr,
-                      const nsRect *aPreFilterDirtyRect = nullptr,
-                      const nsRect *aOverridePreFilterVisualOverflowRect = nullptr,
-                      const gfxRect *aOverrideBBox = nullptr,
-                      nsIFrame* aTransformRoot = nullptr);
+  nsSVGFilterInstance(const nsStyleFilter& aFilter,
+                      nsIFrame *aTargetFrame,
+                      const gfxRect& aTargetBBox);
 
   /**
    * Returns true if the filter instance was created successfully.
    */
   bool IsInitialized() const { return mInitialized; }
 
   /**
+   * Iterates through the <filter> element's primitive elements, creating a
+   * FilterPrimitiveDescription for each one. Appends the new
+   * FilterPrimitiveDescription(s) to the aPrimitiveDescrs list. Also, appends
+   * new images from feImage filter primitive elements to the aInputImages list.
+   */
+  nsresult BuildPrimitives(nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
+                           nsTArray<mozilla::RefPtr<SourceSurface>>& aInputImages);
+
+  /**
    * Returns the user specified "filter region", in the filtered element's user
    * space, after it has been adjusted out (if necessary) so that its edges
    * coincide with pixel boundaries of the offscreen surface into which the
    * filtered output would/will be painted.
    */
   gfxRect GetFilterRegion() const { return mFilterRegion; }
 
   /**
    * Returns the size of the user specified "filter region", in filter space.
    * The size will be {filterRes.x by filterRes.y}, whether the user specified
    * the filter's filterRes attribute explicitly, or the implementation chose
-   * the filterRes values. (The top-left of the filter region is the origin of
-   * filter space, which is why this method returns an nsIntSize and not an
-   * nsIntRect.)
-   */
-  uint32_t GetFilterResX() const { return mFilterSpaceBounds.width; }
-  uint32_t GetFilterResY() const { return mFilterSpaceBounds.height; }
-
-  /**
-   * Draws the filter output into aContext. The area that
-   * needs to be painted must have been specified before calling this method
-   * by passing it as the aPostFilterDirtyRect argument to the
-   * nsSVGFilterInstance constructor.
+   * the filterRes values.
    */
-  nsresult Render(gfxContext* aContext);
-
-  /**
-   * Sets the aPostFilterDirtyRect outparam to the post-filter bounds in frame
-   * space of the area that would be dirtied by mTargetFrame when a given
-   * pre-filter area of mTargetFrame is dirtied. The pre-filter area must have
-   * been specified before calling this method by passing it as the
-   * aPreFilterDirtyRect argument to the nsSVGFilterInstance constructor.
-   */
-  nsresult ComputePostFilterDirtyRect(nsRect* aPostFilterDirtyRect);
-
-  /**
-   * Sets the aPostFilterExtents outparam to the post-filter bounds in frame
-   * space for the whole filter output. This is not necessarily equivalent to
-   * the area that would be dirtied in the result when the entire pre-filter
-   * area is dirtied, because some filter primitives can generate output
-   * without any input.
-   */
-  nsresult ComputePostFilterExtents(nsRect* aPostFilterExtents);
-
-  /**
-   * Sets the aDirty outparam to the pre-filter bounds in frame space of the
-   * area of mTargetFrame that is needed in order to paint the filtered output
-   * for a given post-filter dirtied area. The post-filter area must have been
-   * specified before calling this method by passing it as the aPostFilterDirtyRect
-   * argument to the nsSVGFilterInstance constructor.
-   */
-  nsresult ComputeSourceNeededRect(nsRect* aDirty);
+  nsIntRect GetFilterSpaceBounds() const { return mFilterSpaceBounds; }
 
   float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumber2 *aNumber) const
   {
     return GetPrimitiveNumber(aCtxType, aNumber->GetAnimValue());
   }
   float GetPrimitiveNumber(uint8_t aCtxType, const nsSVGNumberPair *aNumberPair,
                            nsSVGNumberPair::PairIndex aIndex) const
   {
@@ -208,190 +98,84 @@ public:
   Point3D ConvertLocation(const Point3D& aPoint) const;
 
   /**
    * Returns the transform from the filtered element's user space to filter
    * space. This will be a simple translation and/or scale.
    */
   gfxMatrix GetUserSpaceToFilterSpaceTransform() const;
 
+private:
   /**
-   * Returns the transform from filter space to outer-<svg> device space.
-   */
-  gfxMatrix GetFilterSpaceToDeviceSpaceTransform() const {
-    return mFilterSpaceToDeviceSpaceTransform;
-  }
-
-  gfxPoint FilterSpaceToUserSpace(const gfxPoint& aPt) const;
-
-  /**
-   * Returns the transform from filter space to frame space, in CSS px. This
-   * transform does not transform to frame space in its normal app units, since
-   * app units are ints, requiring appropriate rounding which can't be done by
-   * a transform matrix. Callers have to do that themselves as appropriate for
-   * their needs.
+   * Finds the filter frame associated with this SVG filter.
    */
-  gfxMatrix GetFilterSpaceToFrameSpaceInCSSPxTransform() const {
-    return mFilterSpaceToFrameSpaceInCSSPxTransform;
-  }
-
-  int32_t AppUnitsPerCSSPixel() const { return mAppUnitsPerCSSPx; }
-
-private:
-  struct SourceInfo {
-    // Specifies which parts of the source need to be rendered.
-    // Set by ComputeNeededBoxes().
-    nsIntRect mNeededBounds;
-
-    // The surface that contains the input rendering.
-    // Set by BuildSourceImage / BuildSourcePaint.
-    mozilla::RefPtr<SourceSurface> mSourceSurface;
-
-    // The position and size of mSourceSurface in filter space.
-    // Set by BuildSourceImage / BuildSourcePaint.
-    IntRect mSurfaceRect;
-  };
-
-  /**
-   * Creates a SourceSurface for either the FillPaint or StrokePaint graph
-   * nodes
-   */
-  nsresult BuildSourcePaint(SourceInfo *aPrimitive,
-                            gfxASurface* aTargetSurface,
-                            DrawTarget* aTargetDT);
-
-  /**
-   * Creates a SourceSurface for either the FillPaint and StrokePaint graph
-   * nodes, fills its contents and assigns it to mFillPaint.mSourceSurface and
-   * mStrokePaint.mSourceSurface respectively.
-   */
-  nsresult BuildSourcePaints(gfxASurface* aTargetSurface,
-                             DrawTarget* aTargetDT);
-
-  /**
-   * Creates the SourceSurface for the SourceGraphic graph node, paints its
-   * contents, and assigns it to mSourceGraphic.mSourceSurface.
-   */
-  nsresult BuildSourceImage(gfxASurface* aTargetSurface,
-                            DrawTarget* aTargetDT);
-
-  /**
-   * Build the list of FilterPrimitiveDescriptions that describes the filter's
-   * filter primitives and their connections. This populates
-   * mPrimitiveDescriptions and mInputImages.
-   */
-  nsresult BuildPrimitives();
-
-  /**
-   * Computes the filter space bounds of the areas that we actually *need* from
-   * the filter sources, based on the value of mPostFilterDirtyRect.
-   * This sets mNeededBounds on the corresponding SourceInfo structs.
-   */
-   void ComputeNeededBoxes();
+  nsSVGFilterFrame* GetFilterFrame();
 
   /**
    * Computes the filter primitive subregion for the given primitive.
    */
   IntRect ComputeFilterPrimitiveSubregion(nsSVGFE* aFilterElement,
+                                          const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
                                           const nsTArray<int32_t>& aInputIndices);
 
   /**
    * Takes the input indices of a filter primitive and returns for each input
    * whether the input's output is tainted.
    */
-  void GetInputsAreTainted(const nsTArray<int32_t>& aInputIndices,
+  void GetInputsAreTainted(const nsTArray<FilterPrimitiveDescription>& aPrimitiveDescrs,
+                           const nsTArray<int32_t>& aInputIndices,
                            nsTArray<bool>& aOutInputsAreTainted);
 
   /**
    * Scales a numeric filter primitive length in the X, Y or "XY" directions
    * into a length in filter space (no offset is applied).
    */
   float GetPrimitiveNumber(uint8_t aCtxType, float aValue) const;
 
   gfxRect UserSpaceToFilterSpace(const gfxRect& aUserSpace) const;
 
   /**
-   * Converts an nsRect that is relative to a filtered frame's origin (i.e. the
-   * top-left corner of its border box) into filter space.
-   * Returns the entire filter region if aRect is null, or if the result is too
-   * large to be stored in an nsIntRect.
-   */
-  nsIntRect FrameSpaceToFilterSpace(const nsRect* aRect) const;
-  nsRect FilterSpaceToFrameSpace(const nsIntRect& aRect) const;
-
-  /**
    * Returns the transform from frame space to the coordinate space that
    * GetCanvasTM transforms to. "Frame space" is the origin of a frame, aka the
    * top-left corner of its border box, aka the top left corner of its mRect.
    */
   gfxMatrix GetUserSpaceToFrameSpaceInCSSPxTransform() const;
 
   /**
+   * The SVG reference filter originally from the style system.
+   */
+  const nsStyleFilter mFilter;
+
+  /**
    * The frame for the element that is currently being filtered.
    */
   nsIFrame*               mTargetFrame;
 
-  nsSVGFilterPaintCallback* mPaintCallback;
-
   /**
    * The filter element referenced by mTargetFrame's element.
    */
   const mozilla::dom::SVGFilterElement* mFilterElement;
 
   /**
+   * The frame for the SVG filter element.
+   */
+  nsSVGFilterFrame* mFilterFrame;
+
+  /**
    * The SVG bbox of the element that is being filtered, in user space.
    */
   gfxRect                 mTargetBBox;
 
   /**
-   * The transform from filter space to outer-<svg> device space.
-   */
-  gfxMatrix               mFilterSpaceToDeviceSpaceTransform;
-
-  /**
-   * Transform rects between filter space and frame space in CSS pixels.
-   */
-  gfxMatrix               mFilterSpaceToFrameSpaceInCSSPxTransform;
-  gfxMatrix               mFrameSpaceInCSSPxToFilterSpaceTransform;
-
-  /**
    * The "filter region", in the filtered element's user space.
    */
   gfxRect                 mFilterRegion;
   nsIntRect               mFilterSpaceBounds;
 
   /**
-   * Pre-filter paint bounds of the element that is being filtered, in filter
-   * space.
-   */
-  nsIntRect               mTargetBounds;
-
-  /**
-   * If set, this is the filter space bounds of the outer-<svg> device space
-   * bounds of the dirty area that needs to be repainted. (As bounds-of-bounds,
-   * this may be a fair bit bigger than we actually need, unfortunately.)
-   */
-  nsIntRect               mPostFilterDirtyRect;
-
-  /**
-   * If set, this is the filter space bounds of the outer-<svg> device bounds
-   * of the pre-filter area of the filtered element that changed. (As
-   * bounds-of-bounds, this may be a fair bit bigger than we actually need,
-   * unfortunately.)
-   */
-  nsIntRect               mPreFilterDirtyRect;
-
-  /**
    * The 'primitiveUnits' attribute value (objectBoundingBox or userSpaceOnUse).
    */
   uint16_t                mPrimitiveUnits;
 
-  SourceInfo              mSourceGraphic;
-  SourceInfo              mFillPaint;
-  SourceInfo              mStrokePaint;
-  nsIFrame*               mTransformRoot;
-  nsTArray<mozilla::RefPtr<SourceSurface>> mInputImages;
-  nsTArray<FilterPrimitiveDescription> mPrimitiveDescriptions;
-  int32_t                 mAppUnitsPerCSSPx;
   bool                    mInitialized;
 };
 
 #endif
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -55,40 +55,40 @@ protected:
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsISVGChildFrame interface:
   virtual nsresult PaintSVG(nsRenderingContext *aContext,
                             const nsIntRect *aDirtyRect,
                             nsIFrame* aTransformRoot) MOZ_OVERRIDE;
-  virtual nsIFrame* GetFrameForPoint(const nsPoint &aPoint);
-  virtual void ReflowSVG();
+  virtual nsIFrame* GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE;
+  virtual void ReflowSVG() MOZ_OVERRIDE;
 
   // nsSVGPathGeometryFrame methods:
   virtual uint16_t GetHitTestFlags() MOZ_OVERRIDE;
 
   // nsIFrame interface:
   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
                                      nsIAtom*        aAttribute,
-                                     int32_t         aModType);
+                                     int32_t         aModType) MOZ_OVERRIDE;
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgImageFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGImage"), aResult);
   }
 #endif
 
   // nsIReflowCallback
   virtual bool ReflowFinished() MOZ_OVERRIDE;
   virtual void ReflowCallbackCanceled() MOZ_OVERRIDE;
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -5,23 +5,22 @@
 
 // Main header first:
 #include "nsSVGIntegrationUtils.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxDrawable.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsDisplayList.h"
+#include "nsFilterInstance.h"
 #include "nsLayoutUtils.h"
 #include "nsRenderingContext.h"
 #include "nsSVGClipPathFrame.h"
 #include "nsSVGEffects.h"
 #include "nsSVGElement.h"
-#include "nsSVGFilterFrame.h"
-#include "nsSVGFilterInstance.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGMaskFrame.h"
 #include "nsSVGPaintServerFrame.h"
 #include "nsSVGUtils.h"
 #include "FrameLayerBuilder.h"
 #include "BasicLayers.h"
 #include "mozilla/gfx/Point.h"
 
@@ -53,17 +52,17 @@ public:
     : mFirstContinuation(aFirstContinuation)
     , mCurrentFrame(aCurrentFrame)
     , mCurrentFrameOverflowArea(aCurrentFrameOverflowArea)
   {
     NS_ASSERTION(!mFirstContinuation->GetPrevContinuation(),
                  "We want the first continuation here");
   }
 
-  virtual void AddBox(nsIFrame* aFrame) {
+  virtual void AddBox(nsIFrame* aFrame) MOZ_OVERRIDE {
     nsRect overflow = (aFrame == mCurrentFrame) ?
       mCurrentFrameOverflowArea : GetPreEffectsVisualOverflowRect(aFrame);
     mResult.UnionRect(mResult, overflow + aFrame->GetOffsetTo(mFirstContinuation));
   }
 
   nsRect GetResult() const {
     return mResult;
   }
@@ -253,36 +252,35 @@ nsRect
 {
   NS_ASSERTION(!(aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT),
                  "Don't call this on SVG child frames");
 
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
-  nsSVGFilterFrame *filterFrame = effectProperties.mFilter ?
-    effectProperties.mFilter->GetFilterFrame() : nullptr;
-  if (!filterFrame)
+  if (!effectProperties.HasValidFilter()) {
     return aPreEffectsOverflowRect;
+  }
 
   // Create an override bbox - see comment above:
   nsPoint firstFrameToUserSpace = GetOffsetToUserSpace(firstFrame);
   // overrideBBox is in "user space", in _CSS_ pixels:
   // XXX Why are we rounding out to pixel boundaries? We don't do that in
   // GetSVGBBoxForNonSVGFrame, and it doesn't appear to be necessary.
   gfxRect overrideBBox =
     nsLayoutUtils::RectToGfxRect(
       GetPreEffectsVisualOverflowUnion(firstFrame, aFrame,
                                        aPreEffectsOverflowRect,
                                        firstFrameToUserSpace),
       aFrame->PresContext()->AppUnitsPerCSSPixel());
   overrideBBox.RoundOut();
 
   nsRect overflowRect =
-    nsSVGFilterInstance::GetPostFilterBounds(filterFrame, firstFrame, &overrideBBox);
+    nsFilterInstance::GetPostFilterBounds(firstFrame, &overrideBBox);
 
   // Return overflowRect relative to aFrame, rather than "user space":
   return overflowRect - (aFrame->GetOffsetTo(firstFrame) + firstFrameToUserSpace);
 }
 
 nsIntRect
 nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(nsIFrame* aFrame,
                                                       const nsPoint& aToReferenceFrame,
@@ -291,30 +289,24 @@ nsSVGIntegrationUtils::AdjustInvalidArea
   if (aInvalidRect.IsEmpty()) {
     return nsIntRect();
   }
 
   // Don't bother calling GetEffectProperties; the filter property should
   // already have been set up during reflow/ComputeFrameEffectsRect
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
-  nsSVGEffects::EffectProperties effectProperties =
-    nsSVGEffects::GetEffectProperties(firstFrame);
-  if (!effectProperties.mFilter)
-    return aInvalidRect;
-
   nsSVGFilterProperty *prop = nsSVGEffects::GetFilterProperty(firstFrame);
   if (!prop || !prop->IsInObserverLists()) {
     return aInvalidRect;
   }
 
   int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
 
-  nsSVGFilterFrame* filterFrame = prop->GetFilterFrame();
-  if (!filterFrame) {
+  if (!prop || !prop->ReferencesValidResources()) {
     // The frame is either not there or not currently available,
     // perhaps because we're in the middle of tearing stuff down.
     // Be conservative, return our visual overflow rect relative
     // to the reference frame.
     nsRect overflow = aFrame->GetVisualOverflowRect() + aToReferenceFrame;
     return overflow.ToOutsidePixels(appUnitsPerDevPixel);
   }
 
@@ -323,43 +315,43 @@ nsSVGIntegrationUtils::AdjustInvalidArea
     aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame);
   // The initial rect was relative to the reference frame, so we need to
   // remove that offset to get a rect relative to the current frame.
   toUserSpace -= aToReferenceFrame;
   nsRect preEffectsRect = aInvalidRect.ToAppUnits(appUnitsPerDevPixel) + toUserSpace;
 
   // Adjust the dirty area for effects, and shift it back to being relative to
   // the reference frame.
-  nsRect result = nsSVGFilterInstance::GetPostFilterDirtyArea(filterFrame,
-    firstFrame, preEffectsRect) - toUserSpace;
+  nsRect result = nsFilterInstance::GetPostFilterDirtyArea(firstFrame,
+    preEffectsRect) - toUserSpace;
   // Return the result, in pixels relative to the reference frame.
   return result.ToOutsidePixels(appUnitsPerDevPixel);
 }
 
 nsRect
 nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(nsIFrame* aFrame,
                                                        const nsRect& aDirtyRect)
 {
   // Don't bother calling GetEffectProperties; the filter property should
   // already have been set up during reflow/ComputeFrameEffectsRect
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
-  nsSVGFilterFrame* filterFrame =
-    nsSVGEffects::GetFilterFrame(firstFrame);
-  if (!filterFrame)
+  nsSVGFilterProperty *prop = nsSVGEffects::GetFilterProperty(firstFrame);
+  if (!prop || !prop->ReferencesValidResources()) {
     return aDirtyRect;
+  }
   
   // Convert aDirtyRect into "user space" in app units:
   nsPoint toUserSpace =
     aFrame->GetOffsetTo(firstFrame) + GetOffsetToUserSpace(firstFrame);
   nsRect postEffectsRect = aDirtyRect + toUserSpace;
 
   // Return ther result, relative to aFrame, not in user space:
-  return nsSVGFilterInstance::GetPreFilterNeededArea(filterFrame, firstFrame,
-    postEffectsRect) - toUserSpace;
+  return nsFilterInstance::GetPreFilterNeededArea(firstFrame, postEffectsRect)
+    - toUserSpace;
 }
 
 bool
 nsSVGIntegrationUtils::HitTestFrameForEffects(nsIFrame* aFrame, const nsPoint& aPt)
 {
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
   // Convert aPt to user space:
@@ -379,17 +371,18 @@ class RegularFramePaintCallback : public
 public:
   RegularFramePaintCallback(nsDisplayListBuilder* aBuilder,
                             LayerManager* aManager,
                             const nsPoint& aOffset)
     : mBuilder(aBuilder), mLayerManager(aManager),
       mOffset(aOffset) {}
 
   virtual void Paint(nsRenderingContext *aContext, nsIFrame *aTarget,
-                     const nsIntRect* aDirtyRect, nsIFrame* aTransformRoot)
+                     const nsIntRect* aDirtyRect,
+                     nsIFrame* aTransformRoot) MOZ_OVERRIDE
   {
     BasicLayerManager* basic = static_cast<BasicLayerManager*>(mLayerManager);
     basic->SetTarget(aContext->ThebesContext());
     nsRenderingContext::AutoPushTranslation push(aContext, -mOffset);
     mLayerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer, mBuilder);
   }
 
 private:
@@ -450,19 +443,18 @@ nsSVGIntegrationUtils::PaintFramesWithEf
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrIBSplitSibling(aFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
 
-  bool isOK = true;
+  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
   nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
-  nsSVGFilterFrame *filterFrame = effectProperties.GetFilterFrame(&isOK);
   nsSVGMaskFrame *maskFrame = effectProperties.GetMaskFrame(&isOK);
   if (!isOK) {
     return; // Some resource is missing. We shouldn't paint anything.
   }
 
   bool isTrivialClip = clipPathFrame ? clipPathFrame->IsTrivial() : true;
 
   gfxContext* gfx = aCtx->ThebesContext();
@@ -509,22 +501,21 @@ nsSVGIntegrationUtils::PaintFramesWithEf
    * we can just do normal painting and get it clipped appropriately.
    */
   if (clipPathFrame && isTrivialClip) {
     gfx->Save();
     clipPathFrame->ClipPaint(aCtx, aFrame, cssPxToDevPxMatrix);
   }
 
   /* Paint the child */
-  if (filterFrame) {
+  if (effectProperties.HasValidFilter()) {
     RegularFramePaintCallback callback(aBuilder, aLayerManager,
                                        offsetWithoutSVGGeomFramePos);
     nsRect dirtyRect = aDirtyRect - offset;
-    nsSVGFilterInstance::PaintFilteredFrame(filterFrame, aCtx, aFrame,
-                                            &callback, &dirtyRect);
+    nsFilterInstance::PaintFilteredFrame(aCtx, aFrame, &callback, &dirtyRect);
   } else {
     gfx->SetMatrix(matrixAutoSaveRestore.Matrix());
     aLayerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer, aBuilder);
     aCtx->Translate(offsetWithoutSVGGeomFramePos);
   }
 
   if (clipPathFrame && isTrivialClip) {
     gfx->Restore();
@@ -590,17 +581,17 @@ public:
    : mFrame(aFrame)
    , mPaintServerSize(aPaintServerSize)
    , mRenderSize(aRenderSize)
    , mFlags (aFlags)
   {}
   virtual bool operator()(gfxContext* aContext,
                             const gfxRect& aFillRect,
                             const GraphicsFilter& aFilter,
-                            const gfxMatrix& aTransform);
+                            const gfxMatrix& aTransform) MOZ_OVERRIDE;
 private:
   nsIFrame* mFrame;
   nsSize mPaintServerSize;
   gfxIntSize mRenderSize;
   uint32_t mFlags;
 };
 
 bool
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -502,23 +502,24 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayOuterSVG() {
     MOZ_COUNT_DTOR(nsDisplayOuterSVG);
   }
 #endif
 
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
-                                         nsRegion* aInvalidRegion);
+                                         nsRegion* aInvalidRegion) MOZ_OVERRIDE;
 
   NS_DISPLAY_DECL_NAME("SVGOuterSVG", TYPE_SVG_OUTER_SVG)
 };
 
 void
 nsDisplayOuterSVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                            HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
 {
--- a/layout/svg/nsSVGPathGeometryFrame.h
+++ b/layout/svg/nsSVGPathGeometryFrame.h
@@ -60,17 +60,17 @@ public:
   {
     return nsSVGPathGeometryFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eSVG | nsIFrame::eSVGGeometry));
   }
 
   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
                                      nsIAtom*        aAttribute,
                                      int32_t         aModType) MOZ_OVERRIDE;
 
-  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
+  virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgPathGeometryFrame
    */
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
--- a/layout/svg/nsSVGStopFrame.cpp
+++ b/layout/svg/nsSVGStopFrame.cpp
@@ -37,32 +37,32 @@ public:
 #endif
 
   void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                         const nsRect&           aDirtyRect,
                         const nsDisplayListSet& aLists) MOZ_OVERRIDE {}
 
   virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
                                     nsIAtom*        aAttribute,
-                                    int32_t         aModType);
+                                    int32_t         aModType) MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgStopFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     return nsSVGStopFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
   }
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGStop"), aResult);
   }
 #endif
 };
 
 //----------------------------------------------------------------------
 // Implementation
--- a/layout/svg/nsSVGSwitchFrame.cpp
+++ b/layout/svg/nsSVGSwitchFrame.cpp
@@ -33,38 +33,38 @@ public:
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 #endif
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgSwitchFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGSwitch"), aResult);
   }
 #endif
 
   virtual void BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                 const nsRect&           aDirtyRect,
                                 const nsDisplayListSet& aLists) MOZ_OVERRIDE;
 
   // nsISVGChildFrame interface:
   virtual nsresult PaintSVG(nsRenderingContext* aContext,
                             const nsIntRect *aDirtyRect,
                             nsIFrame* aTransformRoot) MOZ_OVERRIDE;
-  nsIFrame* GetFrameForPoint(const nsPoint &aPoint);
-  nsRect GetCoveredRegion();
-  virtual void ReflowSVG();
+  nsIFrame* GetFrameForPoint(const nsPoint &aPoint) MOZ_OVERRIDE;
+  nsRect GetCoveredRegion() MOZ_OVERRIDE;
+  virtual void ReflowSVG() MOZ_OVERRIDE;
   virtual SVGBBox GetBBoxContribution(const Matrix &aToBBoxUserspace,
-                                      uint32_t aFlags);
+                                      uint32_t aFlags) MOZ_OVERRIDE;
 
 private:
   nsIFrame *GetActiveChildFrame();
 };
 
 //----------------------------------------------------------------------
 // Implementation
 
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -33,44 +33,44 @@ public:
   
   // nsIFrame interface:
   virtual void Init(nsIContent*      aContent,
                     nsIFrame*        aParent,
                     nsIFrame*        aPrevInFlow) MOZ_OVERRIDE;
 
   virtual nsresult  AttributeChanged(int32_t         aNameSpaceID,
                                      nsIAtom*        aAttribute,
-                                     int32_t         aModType);
+                                     int32_t         aModType) MOZ_OVERRIDE;
 
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   /**
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgUseFrame
    */
-  virtual nsIAtom* GetType() const;
+  virtual nsIAtom* GetType() const MOZ_OVERRIDE;
 
-  virtual bool IsLeaf() const;
+  virtual bool IsLeaf() const MOZ_OVERRIDE;
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGUse"), aResult);
   }
 #endif
 
   // nsISVGChildFrame interface:
-  virtual void ReflowSVG();
-  virtual void NotifySVGChanged(uint32_t aFlags);
+  virtual void ReflowSVG() MOZ_OVERRIDE;
+  virtual void NotifySVGChanged(uint32_t aFlags) MOZ_OVERRIDE;
 
   // nsIAnonymousContentCreator
-  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements);
+  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
-                                        uint32_t aFilter);
+                                        uint32_t aFilter) MOZ_OVERRIDE;
 
 private:
   bool mHasValidDimensions;
 };
 
 //----------------------------------------------------------------------
 // Implementation
 
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -15,33 +15,32 @@
 #include "gfxMatrix.h"
 #include "gfxPlatform.h"
 #include "gfxRect.h"
 #include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/Preferences.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsDisplayList.h"
+#include "nsFilterInstance.h"
 #include "nsFrameList.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsIPresShell.h"
 #include "nsISVGChildFrame.h"
 #include "nsPresContext.h"
 #include "nsRenderingContext.h"
 #include "nsStyleCoord.h"
 #include "nsStyleStruct.h"
 #include "nsSVGClipPathFrame.h"
 #include "nsSVGContainerFrame.h"
 #include "nsSVGEffects.h"
-#include "nsSVGFilterFrame.h"
-#include "nsSVGFilterInstance.h"
 #include "nsSVGFilterPaintCallback.h"
 #include "nsSVGForeignObjectFrame.h"
 #include "gfxSVGGlyphs.h"
 #include "nsSVGInnerSVGFrame.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGLength2.h"
 #include "nsSVGMaskFrame.h"
 #include "nsSVGOuterSVGFrame.h"
@@ -155,23 +154,22 @@ nsSVGUtils::GetNearestSVGViewport(nsIFra
 
 nsRect
 nsSVGUtils::GetPostFilterVisualOverflowRect(nsIFrame *aFrame,
                                             const nsRect &aPreFilterRect)
 {
   NS_ABORT_IF_FALSE(aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT,
                     "Called on invalid frame type");
 
-  nsSVGFilterFrame *filterFrame = nsSVGEffects::GetFilterFrame(aFrame);
-  if (!filterFrame) {
+  nsSVGFilterProperty *property = nsSVGEffects::GetFilterProperty(aFrame);
+  if (!property || !property->ReferencesValidResources()) {
     return aPreFilterRect;
   }
 
-  return nsSVGFilterInstance::GetPostFilterBounds(filterFrame, aFrame, nullptr,
-                                                  &aPreFilterRect);
+  return nsFilterInstance::GetPostFilterBounds(aFrame, nullptr, &aPreFilterRect);
 }
 
 bool
 nsSVGUtils::OuterSVGIsCallingReflowSVG(nsIFrame *aFrame)
 {
   return GetOuterSVGFrame(aFrame)->IsCallingReflowSVG();
 }
 
@@ -433,17 +431,18 @@ nsSVGUtils::NotifyChildrenOfSVGChange(ns
 }
 
 // ************************************************************
 
 class SVGPaintCallback : public nsSVGFilterPaintCallback
 {
 public:
   virtual void Paint(nsRenderingContext *aContext, nsIFrame *aTarget,
-                     const nsIntRect* aDirtyRect, nsIFrame* aTransformRoot)
+                     const nsIntRect* aDirtyRect,
+                     nsIFrame* aTransformRoot) MOZ_OVERRIDE
   {
     nsISVGChildFrame *svgChildFrame = do_QueryFrame(aTarget);
     NS_ASSERTION(svgChildFrame, "Expected SVG frame here");
 
     nsIntRect* dirtyRect = nullptr;
     nsIntRect tmpDirtyRect;
 
     // aDirtyRect is in user-space pixels, we need to convert to
@@ -493,18 +492,17 @@ nsSVGUtils::PaintFrameWithEffects(nsRend
   }
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
 
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(aFrame);
 
-  bool isOK = true;
-  nsSVGFilterFrame *filterFrame = effectProperties.GetFilterFrame(&isOK);
+  bool isOK = effectProperties.HasNoFilterOrHasValidFilter();
 
   if (aDirtyRect &&
       !(aFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY)) {
     // Here we convert aFrame's paint bounds to outer-<svg> device space,
     // compare it to aDirtyRect, and return early if they don't intersect.
     // We don't do this optimization for nondisplay SVG since nondisplay
     // SVG doesn't maintain bounds/overflow rects.
     nsRect overflowRect = aFrame->GetVisualOverflowRectRelativeToSelf();
@@ -595,17 +593,17 @@ nsSVGUtils::PaintFrameWithEffects(nsRend
    * we can just do normal painting and get it clipped appropriately.
    */
   if (clipPathFrame && isTrivialClip) {
     gfx->Save();
     clipPathFrame->ClipPaint(aContext, aFrame, matrix);
   }
 
   /* Paint the child */
-  if (filterFrame) {
+  if (effectProperties.HasValidFilter()) {
     nsRect* dirtyRect = nullptr;
     nsRect tmpDirtyRect;
     if (aDirtyRect) {
       // aDirtyRect is in outer-<svg> device pixels, but the filter code needs
       // it in frame space.
       gfxMatrix userToDeviceSpace =
         GetUserToCanvasTM(aFrame, nsISVGChildFrame::FOR_OUTERSVG_TM);
       if (userToDeviceSpace.IsSingular()) {
@@ -618,19 +616,18 @@ nsSVGUtils::PaintFrameWithEffects(nsRend
                                       aDirtyRect->width, aDirtyRect->height));
       tmpDirtyRect =
         nsLayoutUtils::RoundGfxRectToAppRect(
           dirtyBounds, aFrame->PresContext()->AppUnitsPerCSSPixel()) -
         aFrame->GetPosition();
       dirtyRect = &tmpDirtyRect;
     }
     SVGPaintCallback paintCallback;
-    nsSVGFilterInstance::PaintFilteredFrame(filterFrame, aContext, aFrame,
-                                            &paintCallback, dirtyRect,
-                                            aTransformRoot);
+    nsFilterInstance::PaintFilteredFrame(aContext, aFrame, &paintCallback,
+                                         dirtyRect, aTransformRoot);
   } else {
     svgChildFrame->PaintSVG(aContext, aDirtyRect, aTransformRoot);
   }
 
   if (clipPathFrame && isTrivialClip) {
     gfx->Restore();
   }
 
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -380,22 +380,24 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayTableCellBackground() {
     MOZ_COUNT_DTOR(nsDisplayTableCellBackground);
   }
 #endif
 
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE {
     aOutFrames->AppendElement(mFrame);
   }
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
-  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
+  virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
+                           bool* aSnap) MOZ_OVERRIDE;
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion *aInvalidRegion) MOZ_OVERRIDE;
 
   NS_DISPLAY_DECL_NAME("TableCellBackground", TYPE_TABLE_CELL_BACKGROUND)
 };
 
 void nsDisplayTableCellBackground::Paint(nsDisplayListBuilder* aBuilder,
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -1057,17 +1057,17 @@ public:
     MOZ_COUNT_DTOR(nsDisplayTableBorderBackground);
   }
 #endif
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion *aInvalidRegion) MOZ_OVERRIDE;
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("TableBorderBackground", TYPE_TABLE_BORDER_BACKGROUND)
 };
 
 #ifdef DEBUG
 static bool
 IsFrameAllowedInTable(nsIAtom* aType)
 {
   return IS_TABLE_CELL(aType) ||
@@ -4518,17 +4518,17 @@ GetColorAndStyle(const nsIFrame*  aFrame
   aWidth = nsPresContext::AppUnitsToIntCSSPixels(width);
 }
 
 class nsDelayedCalcBCBorders : public nsRunnable {
 public:
   nsDelayedCalcBCBorders(nsIFrame* aFrame) :
     mFrame(aFrame) {}
 
-  NS_IMETHOD Run() {
+  NS_IMETHOD Run() MOZ_OVERRIDE {
     if (mFrame) {
       nsTableFrame* tableFrame = static_cast <nsTableFrame*>(mFrame.GetFrame());
       if (tableFrame->NeedToCalcBCBorders()) {
         tableFrame->CalcBCBorders();
       }
     }
     return NS_OK;
   }
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -19,19 +19,19 @@ public:
 
   // nsISupports
   virtual nsIAtom* GetType() const MOZ_OVERRIDE;
   friend nsIFrame* NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsStyleContext*  aContext);
 
   virtual nsSize ComputeAutoSize(nsRenderingContext *aRenderingContext,
                                  nsSize aCBSize, nscoord aAvailableWidth,
                                  nsSize aMargin, nsSize aBorder,
-                                 nsSize aPadding, bool aShrinkWrap);
+                                 nsSize aPadding, bool aShrinkWrap) MOZ_OVERRIDE;
 
-  virtual nsIFrame* GetParentStyleContextFrame() const;
+  virtual nsIFrame* GetParentStyleContextFrame() const MOZ_OVERRIDE;
 
 #ifdef ACCESSIBILITY
   virtual mozilla::a11y::AccType AccessibleType() MOZ_OVERRIDE;
 #endif
 
 #ifdef DEBUG_FRAME_DUMP
   virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -533,17 +533,17 @@ public:
     MOZ_COUNT_DTOR(nsDisplayTableRowBackground);
   }
 #endif
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion *aInvalidRegion) MOZ_OVERRIDE;
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("TableRowBackground", TYPE_TABLE_ROW_BACKGROUND)
 };
 
 void
 nsDisplayTableRowBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                                        const nsDisplayItemGeometry* aGeometry,
                                                        nsRegion *aInvalidRegion)
 {
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -136,17 +136,17 @@ public:
     MOZ_COUNT_DTOR(nsDisplayTableRowGroupBackground);
   }
 #endif
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion *aInvalidRegion) MOZ_OVERRIDE;
   virtual void Paint(nsDisplayListBuilder* aBuilder,
-                     nsRenderingContext* aCtx);
+                     nsRenderingContext* aCtx) MOZ_OVERRIDE;
 
   NS_DISPLAY_DECL_NAME("TableRowGroupBackground", TYPE_TABLE_ROW_GROUP_BACKGROUND)
 };
 
 void
 nsDisplayTableRowGroupBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                                             const nsDisplayItemGeometry* aGeometry,
                                                             nsRegion *aInvalidRegion)
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -2005,17 +2005,18 @@ public:
                               nsIFrame* aFrame, nsDisplayItem* aItem,
                               nsIFrame* aTargetFrame)
     : nsDisplayWrapList(aBuilder, aFrame, aItem), mTargetFrame(aTargetFrame) {}
   nsDisplayXULEventRedirector(nsDisplayListBuilder* aBuilder,
                               nsIFrame* aFrame, nsDisplayList* aList,
                               nsIFrame* aTargetFrame)
     : nsDisplayWrapList(aBuilder, aFrame, aList), mTargetFrame(aTargetFrame) {}
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                       HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
+                       HitTestState* aState,
+                       nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
   NS_DISPLAY_DECL_NAME("XULEventRedirector", TYPE_XUL_EVENT_REDIRECTOR)
 private:
   nsIFrame* mTargetFrame;
 };
 
 void nsDisplayXULEventRedirector::HitTest(nsDisplayListBuilder* aBuilder,
     const nsRect& aRect, HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
 {
@@ -2048,22 +2049,23 @@ void nsDisplayXULEventRedirector::HitTes
 }
 
 class nsXULEventRedirectorWrapper : public nsDisplayWrapper
 {
 public:
   nsXULEventRedirectorWrapper(nsIFrame* aTargetFrame)
       : mTargetFrame(aTargetFrame) {}
   virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
-                                  nsIFrame* aFrame, nsDisplayList* aList) {
+                                  nsIFrame* aFrame,
+                                  nsDisplayList* aList) MOZ_OVERRIDE {
     return new (aBuilder)
         nsDisplayXULEventRedirector(aBuilder, aFrame, aList, mTargetFrame);
   }
   virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
-                                  nsDisplayItem* aItem) {
+                                  nsDisplayItem* aItem) MOZ_OVERRIDE {
     return new (aBuilder)
         nsDisplayXULEventRedirector(aBuilder, aItem->Frame(), aItem,
                                     mTargetFrame);
   }
 private:
   nsIFrame* mTargetFrame;
 };
 
--- a/layout/xul/nsDocElementBoxFrame.cpp
+++ b/layout/xul/nsDocElementBoxFrame.cpp
@@ -25,42 +25,42 @@
 //#define DEBUG_REFLOW
 
 using namespace mozilla::dom;
 
 class nsDocElementBoxFrame : public nsBoxFrame,
                              public nsIAnonymousContentCreator
 {
 public:
-  virtual void DestroyFrom(nsIFrame* aDestructRoot);
+  virtual void DestroyFrom(nsIFrame* aDestructRoot) MOZ_OVERRIDE;
 
   friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell,
                                   nsStyleContext* aContext);
 
   nsDocElementBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext)
     :nsBoxFrame(aShell, aContext, true) {}
 
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
   // nsIAnonymousContentCreator
-  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements);
+  virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) MOZ_OVERRIDE;
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
-                                        uint32_t aFilter);
+                                        uint32_t aFilter) MOZ_OVERRIDE;
 
-  virtual bool IsFrameOfType(uint32_t aFlags) const
+  virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE
   {
     // Override nsBoxFrame.
     if (aFlags & (nsIFrame::eReplacedContainsBlock | nsIFrame::eReplaced))
       return false;
     return nsBoxFrame::IsFrameOfType(aFlags);
   }
 
 #ifdef DEBUG_FRAME_DUMP
-  virtual nsresult GetFrameName(nsAString& aResult) const;
+  virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE;
 #endif
 private:
   nsCOMPtr<Element> mPopupgroupContent;
   nsCOMPtr<Element> mTooltipContent;
 };
 
 //----------------------------------------------------------------------
 
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -56,17 +56,17 @@ using namespace mozilla;
 using namespace mozilla::layers;
 
 class nsImageBoxFrameEvent : public nsRunnable
 {
 public:
   nsImageBoxFrameEvent(nsIContent *content, uint32_t message)
     : mContent(content), mMessage(message) {}
 
-  NS_IMETHOD Run();
+  NS_IMETHOD Run() MOZ_OVERRIDE;
 
 private:
   nsCOMPtr<nsIContent> mContent;
   uint32_t mMessage;
 };
 
 NS_IMETHODIMP
 nsImageBoxFrameEvent::Run()
--- a/layout/xul/nsListBoxObject.cpp
+++ b/layout/xul/nsListBoxObject.cpp
@@ -17,23 +17,23 @@
 
 class nsListBoxObject : public nsPIListBoxObject, public nsBoxObject
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSILISTBOXOBJECT
 
   // nsPIListBoxObject
-  virtual nsListBoxBodyFrame* GetListBoxBody(bool aFlush);
+  virtual nsListBoxBodyFrame* GetListBoxBody(bool aFlush) MOZ_OVERRIDE;
 
   nsListBoxObject();
 
   // nsPIBoxObject
-  virtual void Clear();
-  virtual void ClearCachedValues();
+  virtual void Clear() MOZ_OVERRIDE;
+  virtual void ClearCachedValues() MOZ_OVERRIDE;
   
 protected:
   nsListBoxBodyFrame *mListBoxBody;
 };
 
 NS_IMPL_ISUPPORTS_INHERITED2(nsListBoxObject, nsBoxObject, nsIListBoxObject,
                              nsPIListBoxObject)
 
--- a/layout/xul/nsMenuBarFrame.cpp
+++ b/layout/xul/nsMenuBarFrame.cpp
@@ -286,17 +286,17 @@ public:
                       nsIContent *aOldMenu,
                       nsIContent *aNewMenu,
                       bool aSelectFirstItem)
     : mMenuBar(aMenuBar), mOldMenu(aOldMenu), mNewMenu(aNewMenu),
       mSelectFirstItem(aSelectFirstItem)
   {
   }
 
-  NS_IMETHOD Run()
+  NS_IMETHOD Run() MOZ_OVERRIDE
   {
     nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
     if (!pm)
       return NS_ERROR_UNEXPECTED;
 
     // if switching from one menu to another, set a flag so that the call to
     // HidePopup doesn't deactivate the menubar when the first menu closes.
     nsMenuBarFrame* menubar = nullptr;
--- a/layout/xul/nsMenuBarListener.cpp
+++ b/layout/xul/nsMenuBarListener.cpp
@@ -47,16 +47,23 @@ nsMenuBarListener::nsMenuBarListener(nsM
   mMenuBarFrame = aMenuBar;
 }
 
 ////////////////////////////////////////////////////////////////////////
 nsMenuBarListener::~nsMenuBarListener() 
 {
 }
 
+void
+nsMenuBarListener::InitializeStatics()
+{
+  Preferences::AddBoolVarCache(&mAccessKeyFocuses,
+                               "ui.key.menuAccessKeyFocuses");
+}
+
 nsresult
 nsMenuBarListener::GetMenuAccessKey(int32_t* aAccessKey)
 {
   if (!aAccessKey)
     return NS_ERROR_INVALID_POINTER;
   InitAccessKey();
   *aAccessKey = mAccessKey;
   return NS_OK;
@@ -84,18 +91,16 @@ void nsMenuBarListener::InitAccessKey()
   else if (mAccessKey == nsIDOMKeyEvent::DOM_VK_CONTROL)
     mAccessKeyMask = MODIFIER_CONTROL;
   else if (mAccessKey == nsIDOMKeyEvent::DOM_VK_ALT)
     mAccessKeyMask = MODIFIER_ALT;
   else if (mAccessKey == nsIDOMKeyEvent::DOM_VK_META)
     mAccessKeyMask = MODIFIER_META;
   else if (mAccessKey == nsIDOMKeyEvent::DOM_VK_WIN)
     mAccessKeyMask = MODIFIER_OS;
-
-  mAccessKeyFocuses = Preferences::GetBool("ui.key.menuAccessKeyFocuses");
 }
 
 void
 nsMenuBarListener::ToggleMenuActiveState()
 {
   nsMenuFrame* closemenu = mMenuBarFrame->ToggleMenuActiveState();
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (pm && closemenu) {
--- a/layout/xul/nsMenuBarListener.h
+++ b/layout/xul/nsMenuBarListener.h
@@ -22,16 +22,18 @@ class nsMenuBarListener : public nsIDOME
 {
 public:
   /** default constructor
    */
   nsMenuBarListener(nsMenuBarFrame* aMenuBar);
   /** default destructor
    */
   virtual ~nsMenuBarListener();
+
+  static void InitializeStatics();
    
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) MOZ_OVERRIDE;