merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Mon, 05 Dec 2016 15:33:22 +0100
changeset 325285 8103c612b79c2587ea4ca1b0a9f9f82db4b185b8
parent 325277 e1152318b454bb603352e20ba06a8bdd29050652 (current diff)
parent 325284 590c70d2662affa6021df4e32c7814977fcb4dd0 (diff)
child 325286 3ec83fde43f2e1ba1dc583df0c722033c63ab7b7
child 325287 f38852711f383117b245c47db466764cd0a0b8b8
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersmerge
milestone53.0a1
merge mozilla-inbound to mozilla-central a=merge
layout/svg/tests/example.xml
layout/svg/tests/svg.css
--- a/devtools/client/framework/options-panel.css
+++ b/devtools/client/framework/options-panel.css
@@ -100,8 +100,13 @@
 
 #devtools-sourceeditor-keybinding-select {
   min-width: 130px;
 }
 
 #devtools-sourceeditor-tabsize-select {
   min-width: 80px;
 }
+
+#screenshot-icon::before {
+  background-image: url(chrome://devtools/skin/images/command-screenshot.svg);
+  margin-inline-start: 5px;
+}
--- a/devtools/client/framework/toolbox-options.xhtml
+++ b/devtools/client/framework/toolbox-options.xhtml
@@ -102,16 +102,34 @@
           <span>&options.stylesheetSourceMaps.label;</span>
         </label>
         <label title="&options.stylesheetAutocompletion.tooltip;">
           <input type="checkbox"
                  data-pref="devtools.styleeditor.autocompletion-enabled"/>
           <span>&options.stylesheetAutocompletion.label;</span>
         </label>
       </fieldset>
+
+      <fieldset id="screenshot-options" class="options-groupbox">
+        <legend>&options.screenshot.label;
+          <span id="screenshot-icon" class="devtools-button"></span>
+        </legend>
+        <label title="&options.screenshot.clipboard.tooltip;">
+          <input type="checkbox"
+                 id="devtools-screenshot-clipboard"
+                 data-pref="devtools.screenshot.clipboard.enabled"/>
+          <span>&options.screenshot.clipboard.label;</span>
+        </label>
+        <label title="&options.screenshot.audio.tooltip;">
+          <input type="checkbox"
+                 id="devtools-screenshot-audio"
+                 data-pref="devtools.screenshot.audio.enabled"/>
+          <span>&options.screenshot.audio.label;</span>
+        </label>
+      </fieldset>
     </div>
 
     <div class="options-vertical-pane">
       <fieldset id="sourceeditor-options" class="options-groupbox">
         <legend>&options.sourceeditor.label;</legend>
         <label title="&options.sourceeditor.detectindentation.tooltip;">
           <input type="checkbox"
                  id="devtools-sourceeditor-detectindentation"
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -368,16 +368,18 @@ Toolbox.prototype = {
 
       this.closeButton = this.doc.getElementById("toolbox-close");
       this.closeButton.addEventListener("click", this.destroy, true);
 
       Services.prefs.addObserver("devtools.cache.disabled", this._applyCacheSettings,
                                 false);
       Services.prefs.addObserver("devtools.serviceWorkers.testing.enabled",
                                  this._applyServiceWorkersTestingSettings, false);
+      Services.prefs.addObserver("devtools.screenshot.clipboard.enabled",
+                                 this._buildButtons, false);
 
       let framesMenu = this.doc.getElementById("command-button-frames");
       framesMenu.addEventListener("click", this.showFramesMenu, false);
 
       let noautohideMenu = this.doc.getElementById("command-button-noautohide");
       noautohideMenu.addEventListener("click", this._toggleAutohide, true);
 
       this.textBoxContextMenuPopup =
@@ -964,25 +966,29 @@ Toolbox.prototype = {
     // Disable gcli in browser toolbox until there is usages of it
     if (this.target.chrome) {
       return promise.resolve();
     }
 
     const options = {
       environment: CommandUtils.createEnvironment(this, "_target")
     };
+
     return CommandUtils.createRequisition(this.target, options).then(requisition => {
       this._requisition = requisition;
 
-      const spec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec");
+      let spec = this.getToolbarSpec();
       return CommandUtils.createButtons(spec, this.target, this.doc, requisition)
         .then(buttons => {
           let container = this.doc.getElementById("toolbox-buttons");
           buttons.forEach(button => {
-            if (button) {
+            let currentButton = this.doc.getElementById(button.id);
+            if (currentButton) {
+              container.replaceChild(button, currentButton);
+            } else {
               container.appendChild(button);
             }
           });
           this.setToolboxButtonsVisibility();
         });
     });
   },
 
@@ -1060,16 +1066,34 @@ Toolbox.prototype = {
     if (this.target.activeTab) {
       this.target.activeTab.reconfigure({
         "serviceWorkersTestingEnabled": serviceWorkersTestingEnabled
       });
     }
   },
 
   /**
+   * Get the toolbar spec for toolbox
+   */
+  getToolbarSpec: function () {
+    let spec = CommandUtils.getCommandbarSpec("devtools.toolbox.toolbarSpec");
+    // Special case for screenshot command button to check for clipboard preference
+    const clipboardEnabled = Services.prefs
+      .getBoolPref("devtools.screenshot.clipboard.enabled");
+    if (clipboardEnabled) {
+      for (let i = 0; i < spec.length; i++) {
+        if (spec[i] == "screenshot --fullpage --file") {
+          spec[i] += " --clipboard";
+        }
+      }
+    }
+    return spec;
+  },
+
+  /**
    * Setter for the checked state of the picker button in the toolbar
    * @param {Boolean} isChecked
    */
   set pickerButtonChecked(isChecked) {
     if (isChecked) {
       this._pickerButton.setAttribute("checked", "true");
     } else {
       this._pickerButton.removeAttribute("checked");
--- a/devtools/client/inspector/inspector.js
+++ b/devtools/client/inspector/inspector.js
@@ -1718,26 +1718,29 @@ Inspector.prototype = {
     }
 
     this.selection.nodeFront.getUniqueSelector().then((selector) => {
       clipboardHelper.copyString(selector);
     }).then(null, console.error);
   },
 
   /**
-   * Initiate gcli screenshot command on selected node
+   * Initiate gcli screenshot command on selected node.
    */
   screenshotNode: function () {
+    const command = Services.prefs.getBoolPref("devtools.screenshot.clipboard.enabled") ?
+      "screenshot --file --clipboard --selector" :
+      "screenshot --file --selector";
     CommandUtils.createRequisition(this._target, {
       environment: CommandUtils.createEnvironment(this, "_target")
     }).then(requisition => {
       // Bug 1180314 -  CssSelector might contain white space so need to make sure it is
       // passed to screenshot as a single parameter.  More work *might* be needed if
       // CssSelector could contain escaped single- or double-quotes, backslashes, etc.
-      requisition.updateExec("screenshot --selector '" + this.selectionCssSelector + "'");
+      requisition.updateExec(`${command} '${this.selectionCssSelector}'`);
     });
   },
 
   /**
    * Scroll the node into view.
    */
   scrollNodeIntoView: function () {
     if (!this.selection.isNode()) {
--- a/devtools/client/locales/en-US/toolbox.dtd
+++ b/devtools/client/locales/en-US/toolbox.dtd
@@ -178,16 +178,31 @@
 <!ENTITY options.stylesheetSourceMaps.label      "Show original sources">
 <!ENTITY options.stylesheetSourceMaps.tooltip    "Show original sources (e.g. Sass files) in the Style Editor and Inspector">
 
 <!-- LOCALIZATION NOTE (options.stylesheetAutocompletion.label): This is the
    - label for the checkbox that toggles autocompletion of css in the Style Editor -->
 <!ENTITY options.stylesheetAutocompletion.label      "Autocomplete CSS">
 <!ENTITY options.stylesheetAutocompletion.tooltip    "Autocomplete CSS properties, values and selectors in Style Editor as you type">
 
+<!-- LOCALIZATION NOTE (options.screenshot.label): This is the label for the
+   -  heading of the group of Screenshot preferences in the options
+   -  panel. -->
+<!ENTITY options.screenshot.label            "Screenshot Behavior">
+
+<!-- LOCALIZATION NOTE (options.screenshot.clipboard.label): This is the
+   - label for the checkbox that toggles screenshot to clipboard feature. -->
+<!ENTITY options.screenshot.clipboard.label      "Screenshot to clipboard">
+<!ENTITY options.screenshot.clipboard.tooltip    "Saves to the screenshot directly to the clipboard">
+
+<!-- LOCALIZATION NOTE (options.screenshot.audio.label): This is the
+   - label for the checkbox that toggles the camera shutter audio for screenshot tool -->
+<!ENTITY options.screenshot.audio.label      "Play camera shutter sound">
+<!ENTITY options.screenshot.audio.tooltip    "Enables the camera audio sound when taking screenshot">
+
 <!-- LOCALIZATION NOTE (options.commonprefs): This is the label for the heading
       of all preferences that affect both the Web Console and the Network
       Monitor -->
 <!ENTITY options.commonPrefs.label           "Common Preferences">
 
 <!-- LOCALIZATION NOTE (options.enablePersistentLogs.label): This is the
   -  label for the checkbox that toggles persistent logs in the Web Console and
   -  network monitor,  i.e. devtools.webconsole.persistlog a boolean preference in
--- a/devtools/client/preferences/devtools.js
+++ b/devtools/client/preferences/devtools.js
@@ -25,17 +25,17 @@ pref("devtools.toolbar.visible", false);
 pref("devtools.webide.enabled", true);
 
 // Toolbox preferences
 pref("devtools.toolbox.footer.height", 250);
 pref("devtools.toolbox.sidebar.width", 500);
 pref("devtools.toolbox.host", "bottom");
 pref("devtools.toolbox.previousHost", "side");
 pref("devtools.toolbox.selectedTool", "webconsole");
-pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","scratchpad","resize toggle","screenshot --fullpage", "rulers", "measure"]');
+pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","scratchpad","resize toggle","screenshot --fullpage --file", "rulers", "measure"]');
 pref("devtools.toolbox.sideEnabled", true);
 pref("devtools.toolbox.zoomValue", "1");
 pref("devtools.toolbox.splitconsoleEnabled", false);
 pref("devtools.toolbox.splitconsoleHeight", 100);
 
 // Toolbox Button preferences
 pref("devtools.command-button-frames.enabled", true);
 pref("devtools.command-button-splitconsole.enabled", true);
@@ -209,16 +209,20 @@ pref("devtools.storage.enabled", false);
 pref("devtools.styleeditor.enabled", true);
 pref("devtools.styleeditor.source-maps-enabled", true);
 pref("devtools.styleeditor.autocompletion-enabled", true);
 pref("devtools.styleeditor.showMediaSidebar", true);
 pref("devtools.styleeditor.mediaSidebarWidth", 238);
 pref("devtools.styleeditor.navSidebarWidth", 245);
 pref("devtools.styleeditor.transitions", true);
 
+// Screenshot Option Settings.
+pref("devtools.screenshot.clipboard.enabled", false);
+pref("devtools.screenshot.audio.enabled", true);
+
 // Enable the Shader Editor.
 pref("devtools.shadereditor.enabled", false);
 
 // Enable the Canvas Debugger.
 pref("devtools.canvasdebugger.enabled", false);
 
 // Enable the Web Audio Editor
 pref("devtools.webaudioeditor.enabled", false);
--- a/devtools/shared/gcli/commands/screenshot.js
+++ b/devtools/shared/gcli/commands/screenshot.js
@@ -22,16 +22,17 @@ loader.lazyImporter(this, "PrivateBrowsi
 const BRAND_SHORT_NAME = Cc["@mozilla.org/intl/stringbundle;1"]
                            .getService(Ci.nsIStringBundleService)
                            .createBundle("chrome://branding/locale/brand.properties")
                            .GetStringFromName("brandShortName");
 
 // String used as an indication to generate default file name in the following
 // format: "Screen Shot yyyy-mm-dd at HH.MM.SS.png"
 const FILENAME_DEFAULT_VALUE = " ";
+const CONTAINER_FLASHING_DURATION = 500;
 
 /*
  * There are 2 commands and 1 converter here. The 2 commands are nearly
  * identical except that one runs on the client and one in the server.
  *
  * The server command is hidden, and is designed to be called from the client
  * command.
  */
@@ -90,17 +91,23 @@ const standardParams = {
       manual: l10n.lookup("screenshotFullPageManual")
     },
     {
       name: "selector",
       type: "node",
       defaultValue: null,
       description: l10n.lookup("inspectNodeDesc"),
       manual: l10n.lookup("inspectNodeManual")
-    }
+    },
+    {
+      name: "file",
+      type: "boolean",
+      description: l10n.lookup("screenshotFileDesc"),
+      manual: l10n.lookup("screenshotFileManual"),
+    },
   ]
 };
 
 exports.items = [
   {
     /**
      * Format an 'imageSummary' (as output by the screenshot command).
      * An 'imageSummary' is a simple JSON object that looks like this:
@@ -205,22 +212,24 @@ exports.items = [
 ];
 
 /**
  * This function is called to simulate camera effects
  */
 function simulateCameraEffect(document, effect) {
   let window = document.defaultView;
   if (effect === "shutter") {
-    const audioCamera = new window.Audio("resource://devtools/client/themes/audio/shutter.wav");
-    audioCamera.play();
+    if (Services.prefs.getBoolPref("devtools.screenshot.audio.enabled")) {
+      const audioCamera = new window.Audio("resource://devtools/client/themes/audio/shutter.wav");
+      audioCamera.play();
+    }
   }
   if (effect == "flash") {
     const frames = Cu.cloneInto({ opacity: [ 0, 1 ] }, window);
-    document.documentElement.animate(frames, 500);
+    document.documentElement.animate(frames, CONTAINER_FLASHING_DURATION);
   }
 }
 
 /**
  * This function simply handles the --delay argument before calling
  * createScreenshotData
  */
 function captureScreenshot(args, document) {
@@ -242,17 +251,17 @@ function captureScreenshot(args, documen
  */
 const SKIP = Promise.resolve();
 
 /**
  * Save the captured screenshot to one of several destinations.
  */
 function saveScreenshot(args, context, reply) {
   const fileNeeded = args.filename != FILENAME_DEFAULT_VALUE ||
-                      (!args.imgur && !args.clipboard);
+    (!args.imgur && !args.clipboard) || args.file;
 
   return Promise.all([
     args.clipboard ? saveToClipboard(context, reply) : SKIP,
     args.imgur     ? uploadToImgur(reply)            : SKIP,
     fileNeeded     ? saveToFile(context, reply)      : SKIP,
   ]).then(() => reply);
 }
 
--- a/devtools/shared/locales/en-US/gclicommands.properties
+++ b/devtools/shared/locales/en-US/gclicommands.properties
@@ -85,26 +85,36 @@ screenshotDelayManual=The time to wait (
 # a dialog when the user is using this command.
 screenshotDPRDesc=Device pixel ratio
 
 # LOCALIZATION NOTE (screenshotDPRManual) A fuller description of the
 # 'dpr' parameter to the 'screenshot' command, displayed when the user
 # asks for help on what it does.
 screenshotDPRManual=The device pixel ratio to use when taking the screenshot
 
-# LOCALIZATION NOTE (screenshotFullscreenDesc) A very short string to describe
-# the 'fullscreen' parameter to the 'screenshot' command, which is displayed in
+# LOCALIZATION NOTE (screenshotFullPageDesc) A very short string to describe
+# the 'fullpage' parameter to the 'screenshot' command, which is displayed in
 # a dialog when the user is using this command.
 screenshotFullPageDesc=Entire webpage? (true/false)
 
-# LOCALIZATION NOTE (screenshotFullscreenManual) A fuller description of the
-# 'fullscreen' parameter to the 'screenshot' command, displayed when the user
+# LOCALIZATION NOTE (screenshotFullPageManual) A fuller description of the
+# 'fullpage' parameter to the 'screenshot' command, displayed when the user
 # asks for help on what it does.
 screenshotFullPageManual=True if the screenshot should also include parts of the webpage which are outside the current scrolled bounds.
 
+# LOCALIZATION NOTE (screenshotFileDesc) A very short string to describe
+# the 'file' parameter to the 'screenshot' command, which is displayed in
+# a dialog when the user is using this command.
+screenshotFileDesc=Save to file? (true/false)
+
+# LOCALIZATION NOTE (screenshotFileManual) A fuller description of the
+# 'file' parameter to the 'screenshot' command, displayed when the user
+# asks for help on what it does.
+screenshotFileManual=True if the screenshot should save the file even when other options are enabled (eg. clipboard).
+
 # LOCALIZATION NOTE (screenshotGeneratedFilename) The auto generated filename
 # when no file name is provided. The first argument (%1$S) is the date string
 # in yyyy-mm-dd format and the second argument (%2$S) is the time string
 # in HH.MM.SS format. Please don't add the extension here.
 screenshotGeneratedFilename=Screen Shot %1$S at %2$S
 
 # LOCALIZATION NOTE (screenshotErrorSavingToFile) Text displayed to user upon
 # encountering error while saving the screenshot to the file specified.
--- a/dom/base/test/browser_use_counters.js
+++ b/dom/base/test/browser_use_counters.js
@@ -293,17 +293,19 @@ var check_use_counter_direct = async fun
   // destroyed, which might not have happened yet due to GC/CC effects, etc.
   // Try to force document destruction.
   await waitForDestroyedDocuments();
 
   // Grab histograms again and compare.
   let [histogram_page_after, histogram_document_after,
        histogram_docs_after, histogram_toplevel_docs_after] =
       await grabHistogramsFromContent(use_counter_middlefix, histogram_page_before);
-  (xfail ? todo_is : is)(histogram_page_after, histogram_page_before + 1,
-                         "page counts for " + use_counter_middlefix + " after are correct");
-  (xfail ? todo_is : is)(histogram_document_after, histogram_document_before + 1,
-                         "document counts for " + use_counter_middlefix + " after are correct");
+  if (!xfail) {
+    is(histogram_page_after, histogram_page_before + 1,
+       "page counts for " + use_counter_middlefix + " after are correct");
+    is(histogram_document_after, histogram_document_before + 1,
+       "document counts for " + use_counter_middlefix + " after are correct");
+  }
   ok(histogram_toplevel_docs_after >= histogram_toplevel_docs_before + 1,
      "top level document counts are correct");
   ok(histogram_docs_after >= histogram_docs_before + 1,
      "document counts are correct");
 };
--- a/js/src/jit/BaselineCacheIR.cpp
+++ b/js/src/jit/BaselineCacheIR.cpp
@@ -223,20 +223,20 @@ class MOZ_RAII CacheRegisterAllocator
 
     // Removes spilled values from the native stack. This should only be
     // called after all registers have been allocated.
     void discardStack(MacroAssembler& masm);
 
     // Returns the register for the given operand. If the operand is currently
     // not in a register, it will load it into one.
     ValueOperand useValueRegister(MacroAssembler& masm, ValOperandId val);
-    Register useRegister(MacroAssembler& masm, ObjOperandId obj);
+    Register useRegister(MacroAssembler& masm, TypedOperandId typedId);
 
     // Allocates an output register for the given operand.
-    Register defineRegister(MacroAssembler& masm, ObjOperandId obj);
+    Register defineRegister(MacroAssembler& masm, TypedOperandId typedId);
     ValueOperand defineValueRegister(MacroAssembler& masm, ValOperandId val);
 };
 
 // RAII class to allocate a scratch register and release it when we're done
 // with it.
 class MOZ_RAII AutoScratchRegister
 {
     CacheRegisterAllocator& alloc_;
@@ -676,33 +676,33 @@ CacheRegisterAllocator::useValueRegister
       case OperandLocation::Uninitialized:
         break;
     }
 
     MOZ_CRASH();
 }
 
 Register
-CacheRegisterAllocator::useRegister(MacroAssembler& masm, ObjOperandId op)
+CacheRegisterAllocator::useRegister(MacroAssembler& masm, TypedOperandId typedId)
 {
-    OperandLocation& loc = operandLocations_[op.id()];
+    OperandLocation& loc = operandLocations_[typedId.id()];
     switch (loc.kind()) {
       case OperandLocation::PayloadReg:
         currentOpRegs_.add(loc.payloadReg());
         return loc.payloadReg();
 
       case OperandLocation::ValueReg: {
         // It's possible the value is still boxed: as an optimization, we unbox
         // the first time we use a value as object.
         ValueOperand val = loc.valueReg();
         availableRegs_.add(val);
         Register reg = val.scratchReg();
         availableRegs_.take(reg);
         masm.unboxObject(val, reg);
-        loc.setPayloadReg(reg, JSVAL_TYPE_OBJECT);
+        loc.setPayloadReg(reg, typedId.type());
         currentOpRegs_.add(reg);
         return reg;
       }
 
       case OperandLocation::PayloadStack: {
         // The payload is on the stack. If it's on top of the stack we can just
         // pop it, else we emit a load.
         Register reg = allocateRegister(masm);
@@ -727,35 +727,35 @@ CacheRegisterAllocator::useRegister(Macr
             masm.addToStackPtr(Imm32(sizeof(js::Value)));
             MOZ_ASSERT(stackPushed_ >= sizeof(js::Value));
             stackPushed_ -= sizeof(js::Value);
         } else {
             MOZ_ASSERT(loc.valueStack() < stackPushed_);
             masm.unboxObject(Address(masm.getStackPointer(), stackPushed_ - loc.valueStack()),
                              reg);
         }
-        loc.setPayloadReg(reg, JSVAL_TYPE_OBJECT);
+        loc.setPayloadReg(reg, typedId.type());
         return reg;
       }
 
       case OperandLocation::Uninitialized:
         break;
     }
 
     MOZ_CRASH();
 }
 
 Register
-CacheRegisterAllocator::defineRegister(MacroAssembler& masm, ObjOperandId op)
+CacheRegisterAllocator::defineRegister(MacroAssembler& masm, TypedOperandId typedId)
 {
-    OperandLocation& loc = operandLocations_[op.id()];
+    OperandLocation& loc = operandLocations_[typedId.id()];
     MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized);
 
     Register reg = allocateRegister(masm);
-    loc.setPayloadReg(reg, JSVAL_TYPE_OBJECT);
+    loc.setPayloadReg(reg, typedId.type());
     return reg;
 }
 
 ValueOperand
 CacheRegisterAllocator::defineValueRegister(MacroAssembler& masm, ValOperandId val)
 {
     OperandLocation& loc = operandLocations_[val.id()];
     MOZ_ASSERT(loc.kind() == OperandLocation::Uninitialized);
@@ -918,16 +918,27 @@ BaselineCacheIRCompiler::emitGuardIsObje
     FailurePath* failure;
     if (!addFailurePath(&failure))
         return false;
     masm.branchTestObject(Assembler::NotEqual, input, failure->label());
     return true;
 }
 
 bool
+BaselineCacheIRCompiler::emitGuardIsString()
+{
+    ValueOperand input = allocator.useValueRegister(masm, reader.valOperandId());
+    FailurePath* failure;
+    if (!addFailurePath(&failure))
+        return false;
+    masm.branchTestString(Assembler::NotEqual, input, failure->label());
+    return true;
+}
+
+bool
 BaselineCacheIRCompiler::emitGuardType()
 {
     ValueOperand input = allocator.useValueRegister(masm, reader.valOperandId());
     JSValueType type = reader.valueType();
 
     FailurePath* failure;
     if (!addFailurePath(&failure))
         return false;
@@ -1076,16 +1087,30 @@ BaselineCacheIRCompiler::emitGuardSpecif
         return false;
 
     Address addr(stubAddress(reader.stubOffset()));
     masm.branchPtr(Assembler::NotEqual, addr, obj, failure->label());
     return true;
 }
 
 bool
+BaselineCacheIRCompiler::emitGuardMagicValue()
+{
+    ValueOperand val = allocator.useValueRegister(masm, reader.valOperandId());
+    JSWhyMagic magic = reader.whyMagic();
+
+    FailurePath* failure;
+    if (!addFailurePath(&failure))
+        return false;
+
+    masm.branchTestMagicValue(Assembler::NotEqual, val, magic, failure->label());
+    return true;
+}
+
+bool
 BaselineCacheIRCompiler::emitGuardNoUnboxedExpando()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
 
     FailurePath* failure;
     if (!addFailurePath(&failure))
         return false;
 
@@ -1281,16 +1306,48 @@ BaselineCacheIRCompiler::emitGuardNoDeta
     if (!addFailurePath(&failure))
         return false;
 
     CheckForTypedObjectWithDetachedStorage(cx_, masm, failure->label());
     return true;
 }
 
 bool
+BaselineCacheIRCompiler::emitGuardFrameHasNoArgumentsObject()
+{
+    FailurePath* failure;
+    if (!addFailurePath(&failure))
+        return false;
+
+    masm.branchTest32(Assembler::NonZero,
+                      Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
+                      Imm32(BaselineFrame::HAS_ARGS_OBJ),
+                      failure->label());
+    return true;
+}
+
+bool
+BaselineCacheIRCompiler::emitLoadFrameCalleeResult()
+{
+    Address callee(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken());
+    masm.loadFunctionFromCalleeToken(callee, R0.scratchReg());
+    masm.tagValue(JSVAL_TYPE_OBJECT, R0.scratchReg(), R0);
+    return true;
+}
+
+bool
+BaselineCacheIRCompiler::emitLoadFrameNumActualArgsResult()
+{
+    Address actualArgs(BaselineFrameReg, BaselineFrame::offsetOfNumActualArgs());
+    masm.loadPtr(actualArgs, R0.scratchReg());
+    masm.tagValue(JSVAL_TYPE_INT32, R0.scratchReg(), R0);
+    return true;
+}
+
+bool
 BaselineCacheIRCompiler::emitLoadTypedObjectResult()
 {
     Register obj = allocator.useRegister(masm, reader.objOperandId());
     AutoScratchRegister scratch1(allocator, masm);
     AutoScratchRegister scratch2(allocator, masm);
 
     TypedThingLayout layout = reader.typedThingLayout();
     uint32_t typeDescr = reader.typeDescrKey();
@@ -1396,16 +1453,27 @@ BaselineCacheIRCompiler::emitLoadArgumen
     // Shift out arguments length and return it. No need to type monitor
     // because this stub always returns int32.
     masm.rshiftPtr(Imm32(ArgumentsObject::PACKED_BITS_COUNT), scratch);
     masm.tagValue(JSVAL_TYPE_INT32, scratch, R0);
     return true;
 }
 
 bool
+BaselineCacheIRCompiler::emitLoadStringLengthResult()
+{
+    Register str = allocator.useRegister(masm, reader.stringOperandId());
+    AutoScratchRegister scratch(allocator, masm);
+
+    masm.loadStringLength(str, R0.scratchReg());
+    masm.tagValue(JSVAL_TYPE_INT32, R0.scratchReg(), R0);
+    return true;
+}
+
+bool
 BaselineCacheIRCompiler::emitTypeMonitorResult()
 {
     allocator.discardStack(masm);
     EmitEnterTypeMonitorIC(masm);
     return true;
 }
 
 bool
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -977,16 +977,18 @@ BaselineInspector::commonSetPropFunction
 
 static MIRType
 GetCacheIRExpectedInputType(ICCacheIR_Monitored* stub)
 {
     CacheIRReader reader(stub->stubInfo());
 
     if (reader.matchOp(CacheOp::GuardIsObject, ValOperandId(0)))
         return MIRType::Object;
+    if (reader.matchOp(CacheOp::GuardIsString, ValOperandId(0)))
+        return MIRType::String;
     if (reader.matchOp(CacheOp::GuardType, ValOperandId(0))) {
         JSValueType type = reader.valueType();
         return MIRTypeFromValueType(type);
     }
     MOZ_CRASH("Unexpected instruction");
 }
 
 MIRType
@@ -1009,17 +1011,16 @@ BaselineInspector::expectedPropertyAcces
           case ICStub::GetElem_Fallback:
             if (stub->toGetElem_Fallback()->hadUnoptimizableAccess())
                 return MIRType::Value;
             continue;
 
           case ICStub::GetProp_Generic:
             return MIRType::Value;
 
-          case ICStub::GetProp_ArgumentsLength:
           case ICStub::GetElem_Arguments:
             // Either an object or magic arguments.
             return MIRType::Value;
 
           case ICStub::GetElem_NativeSlotName:
           case ICStub::GetElem_NativeSlotSymbol:
           case ICStub::GetElem_NativePrototypeSlotName:
           case ICStub::GetElem_NativePrototypeSlotSymbol:
@@ -1030,20 +1031,16 @@ BaselineInspector::expectedPropertyAcces
           case ICStub::GetElem_UnboxedPropertyName:
           case ICStub::GetElem_String:
           case ICStub::GetElem_Dense:
           case ICStub::GetElem_TypedArray:
           case ICStub::GetElem_UnboxedArray:
             stubType = MIRType::Object;
             break;
 
-          case ICStub::GetProp_StringLength:
-            stubType = MIRType::String;
-            break;
-
           case ICStub::CacheIR_Monitored:
             stubType = GetCacheIRExpectedInputType(stub->toCacheIR_Monitored());
             if (stubType == MIRType::Value)
                 return MIRType::Value;
             break;
 
           default:
             MOZ_CRASH("Unexpected stub");
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -72,16 +72,20 @@ GetPropIRGenerator::tryAttachStub()
             return true;
         if (tryAttachProxy(obj, objId))
             return true;
         return false;
     }
 
     if (tryAttachPrimitive(valId))
         return true;
+    if (tryAttachStringLength(valId))
+        return true;
+    if (tryAttachMagicArguments(valId))
+        return true;
 
     return false;
 }
 
 static bool
 IsCacheableNoProperty(JSContext* cx, JSObject* obj, JSObject* holder, Shape* shape, jsid id,
                       jsbytecode* pc)
 {
@@ -718,8 +722,44 @@ GetPropIRGenerator::tryAttachPrimitive(V
     writer.guardType(valId, primitiveType);
 
     ObjOperandId protoId = writer.loadObject(proto);
     writer.guardShape(protoId, proto->lastProperty());
     EmitLoadSlotResult(writer, protoId, proto, shape);
     writer.typeMonitorResult();
     return true;
 }
+
+bool
+GetPropIRGenerator::tryAttachStringLength(ValOperandId valId)
+{
+    if (!val_.isString() || name_ != cx_->names().length)
+        return false;
+
+    StringOperandId strId = writer.guardIsString(valId);
+    writer.loadStringLengthResult(strId);
+    writer.returnFromIC();
+    return true;
+}
+
+bool
+GetPropIRGenerator::tryAttachMagicArguments(ValOperandId valId)
+{
+    if (!val_.isMagic(JS_OPTIMIZED_ARGUMENTS))
+        return false;
+
+    if (name_ != cx_->names().length && name_ != cx_->names().callee)
+        return false;
+
+    writer.guardMagicValue(valId, JS_OPTIMIZED_ARGUMENTS);
+    writer.guardFrameHasNoArgumentsObject();
+
+    if (name_ == cx_->names().length) {
+        writer.loadFrameNumActualArgsResult();
+        writer.returnFromIC();
+    } else {
+        MOZ_ASSERT(name_ == cx_->names().callee);
+        writer.loadFrameCalleeResult();
+        writer.typeMonitorResult();
+    }
+
+    return true;
+}
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -74,27 +74,52 @@ class ObjOperandId : public OperandId
   public:
     ObjOperandId() = default;
     explicit ObjOperandId(uint16_t id) : OperandId(id) {}
 
     bool operator==(const ObjOperandId& other) const { return id_ == other.id_; }
     bool operator!=(const ObjOperandId& other) const { return id_ != other.id_; }
 };
 
+class StringOperandId : public OperandId
+{
+  public:
+    StringOperandId() = default;
+    explicit StringOperandId(uint16_t id) : OperandId(id) {}
+};
+
+class TypedOperandId : public OperandId
+{
+    JSValueType type_;
+
+  public:
+    MOZ_IMPLICIT TypedOperandId(ObjOperandId id)
+      : OperandId(id.id()), type_(JSVAL_TYPE_OBJECT)
+    {}
+    MOZ_IMPLICIT TypedOperandId(StringOperandId id)
+      : OperandId(id.id()), type_(JSVAL_TYPE_STRING)
+    {}
+
+    JSValueType type() const { return type_; }
+};
+
 #define CACHE_IR_OPS(_)                   \
     _(GuardIsObject)                      \
+    _(GuardIsString)                      \
     _(GuardType)                          \
     _(GuardShape)                         \
     _(GuardGroup)                         \
     _(GuardProto)                         \
     _(GuardClass)                         \
     _(GuardIsProxy)                       \
     _(GuardNotDOMProxy)                   \
     _(GuardSpecificObject)                \
     _(GuardNoDetachedTypedObjects)        \
+    _(GuardMagicValue)                    \
+    _(GuardFrameHasNoArgumentsObject)     \
     _(GuardNoUnboxedExpando)              \
     _(GuardAndLoadUnboxedExpando)         \
     _(LoadObject)                         \
     _(LoadProto)                          \
                                           \
     _(LoadDOMExpandoValue)                \
     _(GuardDOMExpandoObject)              \
     _(GuardDOMExpandoGeneration)          \
@@ -102,16 +127,19 @@ class ObjOperandId : public OperandId
     /* The *Result ops load a value into the cache's result register. */ \
     _(LoadFixedSlotResult)                \
     _(LoadDynamicSlotResult)              \
     _(LoadUnboxedPropertyResult)          \
     _(LoadTypedObjectResult)              \
     _(LoadInt32ArrayLengthResult)         \
     _(LoadUnboxedArrayLengthResult)       \
     _(LoadArgumentsObjectLengthResult)    \
+    _(LoadStringLengthResult)             \
+    _(LoadFrameCalleeResult)              \
+    _(LoadFrameNumActualArgsResult)       \
     _(CallScriptedGetterResult)           \
     _(CallNativeGetterResult)             \
     _(CallProxyGetResult)                 \
     _(LoadUndefinedResult)                \
                                           \
     _(TypeMonitorResult)                  \
     _(ReturnFromIC)
 
@@ -305,16 +333,20 @@ class MOZ_RAII CacheIRWriter : public JS
     uint32_t codeLength() const {
         return buffer_.length();
     }
 
     ObjOperandId guardIsObject(ValOperandId val) {
         writeOpWithOperandId(CacheOp::GuardIsObject, val);
         return ObjOperandId(val.id());
     }
+    StringOperandId guardIsString(ValOperandId val) {
+        writeOpWithOperandId(CacheOp::GuardIsString, val);
+        return StringOperandId(val.id());
+    }
     void guardType(ValOperandId val, JSValueType type) {
         writeOpWithOperandId(CacheOp::GuardType, val);
         static_assert(sizeof(type) == sizeof(uint8_t), "JSValueType should fit in a byte");
         buffer_.writeByte(uint32_t(type));
     }
     void guardShape(ObjOperandId obj, Shape* shape) {
         writeOpWithOperandId(CacheOp::GuardShape, obj);
         addStubField(uintptr_t(shape), StubField::Type::Shape);
@@ -338,19 +370,32 @@ class MOZ_RAII CacheIRWriter : public JS
     }
     void guardNotDOMProxy(ObjOperandId obj) {
         writeOpWithOperandId(CacheOp::GuardNotDOMProxy, obj);
     }
     void guardSpecificObject(ObjOperandId obj, JSObject* expected) {
         writeOpWithOperandId(CacheOp::GuardSpecificObject, obj);
         addStubField(uintptr_t(expected), StubField::Type::JSObject);
     }
+    void guardMagicValue(ValOperandId val, JSWhyMagic magic) {
+        writeOpWithOperandId(CacheOp::GuardMagicValue, val);
+        buffer_.writeByte(uint32_t(magic));
+    }
     void guardNoDetachedTypedObjects() {
         writeOp(CacheOp::GuardNoDetachedTypedObjects);
     }
+    void guardFrameHasNoArgumentsObject() {
+        writeOp(CacheOp::GuardFrameHasNoArgumentsObject);
+    }
+    void loadFrameCalleeResult() {
+        writeOp(CacheOp::LoadFrameCalleeResult);
+    }
+    void loadFrameNumActualArgsResult() {
+        writeOp(CacheOp::LoadFrameNumActualArgsResult);
+    }
     void guardNoUnboxedExpando(ObjOperandId obj) {
         writeOpWithOperandId(CacheOp::GuardNoUnboxedExpando, obj);
     }
     ObjOperandId guardAndLoadUnboxedExpando(ObjOperandId obj) {
         ObjOperandId res(nextOperandId_++);
         writeOpWithOperandId(CacheOp::GuardAndLoadUnboxedExpando, obj);
         writeOperandId(res);
         return res;
@@ -420,16 +465,19 @@ class MOZ_RAII CacheIRWriter : public JS
         writeOpWithOperandId(CacheOp::LoadInt32ArrayLengthResult, obj);
     }
     void loadUnboxedArrayLengthResult(ObjOperandId obj) {
         writeOpWithOperandId(CacheOp::LoadUnboxedArrayLengthResult, obj);
     }
     void loadArgumentsObjectLengthResult(ObjOperandId obj) {
         writeOpWithOperandId(CacheOp::LoadArgumentsObjectLengthResult, obj);
     }
+    void loadStringLengthResult(StringOperandId str) {
+        writeOpWithOperandId(CacheOp::LoadStringLengthResult, str);
+    }
     void callScriptedGetterResult(ObjOperandId obj, JSFunction* getter) {
         writeOpWithOperandId(CacheOp::CallScriptedGetterResult, obj);
         addStubField(uintptr_t(getter), StubField::Type::JSObject);
     }
     void callNativeGetterResult(ObjOperandId obj, JSFunction* getter) {
         writeOpWithOperandId(CacheOp::CallNativeGetterResult, obj);
         addStubField(uintptr_t(getter), StubField::Type::JSObject);
     }
@@ -466,28 +514,26 @@ class MOZ_RAII CacheIRReader
     explicit CacheIRReader(const CacheIRStubInfo* stubInfo);
 
     bool more() const { return buffer_.more(); }
 
     CacheOp readOp() {
         return CacheOp(buffer_.readByte());
     }
 
-    ValOperandId valOperandId() {
-        return ValOperandId(buffer_.readByte());
-    }
-    ObjOperandId objOperandId() {
-        return ObjOperandId(buffer_.readByte());
-    }
+    ValOperandId valOperandId() { return ValOperandId(buffer_.readByte()); }
+    ObjOperandId objOperandId() { return ObjOperandId(buffer_.readByte()); }
+    StringOperandId stringOperandId() { return StringOperandId(buffer_.readByte()); }
 
     uint32_t stubOffset() { return buffer_.readByte() * sizeof(uintptr_t); }
     GuardClassKind guardClassKind() { return GuardClassKind(buffer_.readByte()); }
     JSValueType valueType() { return JSValueType(buffer_.readByte()); }
     TypedThingLayout typedThingLayout() { return TypedThingLayout(buffer_.readByte()); }
     uint32_t typeDescrKey() { return buffer_.readByte(); }
+    JSWhyMagic whyMagic() { return JSWhyMagic(buffer_.readByte()); }
 
     bool matchOp(CacheOp op) {
         const uint8_t* pos = buffer_.currentPosition();
         if (readOp() == op)
             return true;
         buffer_.seek(pos, 0);
         return false;
     }
@@ -532,16 +578,18 @@ class MOZ_RAII GetPropIRGenerator
     bool tryAttachWindowProxy(HandleObject obj, ObjOperandId objId);
 
     bool tryAttachGenericProxy(HandleObject obj, ObjOperandId objId);
     bool tryAttachDOMProxyShadowed(HandleObject obj, ObjOperandId objId);
     bool tryAttachDOMProxyUnshadowed(HandleObject obj, ObjOperandId objId);
     bool tryAttachProxy(HandleObject obj, ObjOperandId objId);
 
     bool tryAttachPrimitive(ValOperandId valId);
+    bool tryAttachStringLength(ValOperandId valId);
+    bool tryAttachMagicArguments(ValOperandId valId);
 
     GetPropIRGenerator(const GetPropIRGenerator&) = delete;
     GetPropIRGenerator& operator=(const GetPropIRGenerator&) = delete;
 
   public:
     GetPropIRGenerator(JSContext* cx, jsbytecode* pc, ICStubEngine engine,
                        bool* isTemporarilyUnoptimizable,
                        HandleValue val, HandlePropertyName name, MutableHandleValue res);
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -2057,83 +2057,16 @@ ICCompare_Int32WithBoolean::Compiler::ge
     EmitStubGuardFailure(masm);
     return true;
 }
 
 //
 // GetProp_Fallback
 //
 
-static bool
-TryAttachMagicArgumentsGetPropStub(JSContext* cx, SharedStubInfo* info,
-                                   ICGetProp_Fallback* stub, HandlePropertyName name,
-                                   HandleValue val, HandleValue res, bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (!val.isMagic(JS_OPTIMIZED_ARGUMENTS))
-        return true;
-
-    // Try handling arguments.callee on optimized arguments.
-    if (name == cx->names().callee) {
-        MOZ_ASSERT(info->script()->hasMappedArgsObj());
-
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(MagicArgs.callee) stub");
-
-        // Unlike ICGetProp_ArgumentsLength, only magic argument stubs are
-        // supported at the moment.
-        ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
-        ICGetProp_ArgumentsCallee::Compiler compiler(cx, info->engine(), monitorStub);
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(info->outerScript(cx)));
-        if (!newStub)
-            return false;
-        stub->addNewStub(newStub);
-
-        *attached = true;
-        return true;
-    }
-
-    return true;
-}
-
-static bool
-TryAttachLengthStub(JSContext* cx, SharedStubInfo* info,
-                    ICGetProp_Fallback* stub, HandleValue val,
-                    HandleValue res, bool* attached)
-{
-    MOZ_ASSERT(!*attached);
-
-    if (val.isString()) {
-        MOZ_ASSERT(res.isInt32());
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(String.length) stub");
-        ICGetProp_StringLength::Compiler compiler(cx, info->engine());
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(info->outerScript(cx)));
-        if (!newStub)
-            return false;
-
-        *attached = true;
-        stub->addNewStub(newStub);
-        return true;
-    }
-
-    if (val.isMagic(JS_OPTIMIZED_ARGUMENTS) && res.isInt32()) {
-        JitSpew(JitSpew_BaselineIC, "  Generating GetProp(MagicArgs.length) stub");
-        ICGetProp_ArgumentsLength::Compiler compiler(cx, info->engine(), ICGetProp_ArgumentsLength::Magic);
-        ICStub* newStub = compiler.getStub(compiler.getStubSpace(info->outerScript(cx)));
-        if (!newStub)
-            return false;
-
-        *attached = true;
-        stub->addNewStub(newStub);
-        return true;
-    }
-
-    return true;
-}
-
 // Return whether obj is in some PreliminaryObjectArray and has a structure
 // that might change in the future.
 bool
 IsPreliminaryObject(JSObject* obj)
 {
     if (obj->isSingleton())
         return false;
 
@@ -2497,30 +2430,16 @@ DoGetPropFallback(JSContext* cx, void* p
 
     // Add a type monitor stub for the resulting value.
     if (!stub->addMonitorStubForValue(cx, &info, res))
         return false;
 
     if (attached)
         return true;
 
-    if (op == JSOP_LENGTH) {
-        if (!TryAttachLengthStub(cx, &info, stub, val, res, &attached))
-            return false;
-        if (attached)
-            return true;
-    }
-
-    if (!TryAttachMagicArgumentsGetPropStub(cx, &info, stub, name, val,
-                                            res, &attached))
-        return false;
-    if (attached)
-        return true;
-
-
     MOZ_ASSERT(!attached);
     if (!isTemporarilyUnoptimizable)
         stub->noteUnoptimizableAccess();
 
     return true;
 }
 
 typedef bool (*DoGetPropFallbackFn)(JSContext*, void*, ICGetProp_Fallback*,
@@ -2576,35 +2495,16 @@ void
 ICGetProp_Fallback::Compiler::postGenerateStubCode(MacroAssembler& masm, Handle<JitCode*> code)
 {
     if (engine_ == Engine::Baseline) {
         void* address = code->raw() + returnOffset_;
         cx->compartment()->jitCompartment()->initBaselineGetPropReturnAddr(address);
     }
 }
 
-bool
-ICGetProp_StringLength::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    Label failure;
-    masm.branchTestString(Assembler::NotEqual, R0, &failure);
-
-    // Unbox string and load its length.
-    Register string = masm.extractString(R0, ExtractTemp0);
-    masm.loadStringLength(string, string);
-
-    masm.tagValue(JSVAL_TYPE_INT32, string, R0);
-    EmitReturnFromIC(masm);
-
-    // Failure case - jump to next stub
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
 ICGetPropNativeStub*
 ICGetPropNativeCompiler::getStub(ICStubSpace* space)
 {
     ReceiverGuard guard(obj_);
 
     switch (kind) {
       case ICStub::GetName_Global: {
         MOZ_ASSERT(obj_ != holder_);
@@ -2872,71 +2772,16 @@ ICGetPropCallNativeCompiler::getStub(ICS
                                                    getter_, pcOffset_);
       }
 
       default:
         MOZ_CRASH("Bad stub kind");
     }
 }
 
-bool
-ICGetProp_ArgumentsLength::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    MOZ_ASSERT(which_ == ICGetProp_ArgumentsLength::Magic);
-
-    Label failure;
-
-    // Ensure that this is lazy arguments.
-    masm.branchTestMagicValue(Assembler::NotEqual, R0, JS_OPTIMIZED_ARGUMENTS, &failure);
-
-    // Ensure that frame has not loaded different arguments object since.
-    masm.branchTest32(Assembler::NonZero,
-                      Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
-                      Imm32(BaselineFrame::HAS_ARGS_OBJ),
-                      &failure);
-
-    Address actualArgs(BaselineFrameReg, BaselineFrame::offsetOfNumActualArgs());
-    masm.loadPtr(actualArgs, R0.scratchReg());
-    masm.tagValue(JSVAL_TYPE_INT32, R0.scratchReg(), R0);
-    EmitReturnFromIC(masm);
-
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
-ICGetProp_ArgumentsCallee::ICGetProp_ArgumentsCallee(JitCode* stubCode, ICStub* firstMonitorStub)
-  : ICMonitoredStub(GetProp_ArgumentsCallee, stubCode, firstMonitorStub)
-{ }
-
-bool
-ICGetProp_ArgumentsCallee::Compiler::generateStubCode(MacroAssembler& masm)
-{
-    Label failure;
-
-    // Ensure that this is lazy arguments.
-    masm.branchTestMagicValue(Assembler::NotEqual, R0, JS_OPTIMIZED_ARGUMENTS, &failure);
-
-    // Ensure that frame has not loaded different arguments object since.
-    masm.branchTest32(Assembler::NonZero,
-                      Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFlags()),
-                      Imm32(BaselineFrame::HAS_ARGS_OBJ),
-                      &failure);
-
-    Address callee(BaselineFrameReg, BaselineFrame::offsetOfCalleeToken());
-    masm.loadFunctionFromCalleeToken(callee, R0.scratchReg());
-    masm.tagValue(JSVAL_TYPE_OBJECT, R0.scratchReg(), R0);
-
-    EmitEnterTypeMonitorIC(masm);
-
-    masm.bind(&failure);
-    EmitStubGuardFailure(masm);
-    return true;
-}
-
 /* static */ ICGetProp_Generic*
 ICGetProp_Generic::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
                          ICGetProp_Generic& other)
 {
     return New<ICGetProp_Generic>(cx, space, other.jitCode(), firstMonitorStub);
 }
 
 static bool
--- a/js/src/jit/SharedIC.h
+++ b/js/src/jit/SharedIC.h
@@ -2335,40 +2335,16 @@ class ICGetProp_Generic : public ICMonit
         {}
 
         ICStub* getStub(ICStubSpace* space) {
             return newStub<ICGetProp_Generic>(space, getStubCode(), firstMonitorStub_);
         }
     };
 };
 
-// Stub for accessing a string's length.
-class ICGetProp_StringLength : public ICStub
-{
-    friend class ICStubSpace;
-
-    explicit ICGetProp_StringLength(JitCode* stubCode)
-      : ICStub(GetProp_StringLength, stubCode)
-    {}
-
-  public:
-    class Compiler : public ICStubCompiler {
-        MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        explicit Compiler(JSContext* cx, Engine engine)
-          : ICStubCompiler(cx, ICStub::GetProp_StringLength, engine)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_StringLength>(space, getStubCode());
-        }
-    };
-};
-
 // Base class for native GetProp stubs.
 class ICGetPropNativeStub : public ICMonitoredStub
 {
     // Object shape/group.
     HeapReceiverGuard receiverGuard_;
 
     // Fixed or dynamic slot offset.
     uint32_t offset_;
@@ -2669,77 +2645,16 @@ class ICGetPropCallNativeCompiler : publ
       : ICGetPropCallGetter::Compiler(cx, kind, engine, firstMonitorStub, receiver, holder,
                                       getter, pcOffset),
         inputDefinitelyObject_(inputDefinitelyObject)
     {}
 
     ICStub* getStub(ICStubSpace* space);
 };
 
-class ICGetProp_ArgumentsLength : public ICStub
-{
-  friend class ICStubSpace;
-  public:
-    enum Which { Magic };
-
-  protected:
-    explicit ICGetProp_ArgumentsLength(JitCode* stubCode)
-      : ICStub(ICStub::GetProp_ArgumentsLength, stubCode)
-    { }
-
-  public:
-    class Compiler : public ICStubCompiler {
-      protected:
-        Which which_;
-
-        MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
-
-        virtual int32_t getKey() const {
-            return static_cast<int32_t>(engine_) |
-                  (static_cast<int32_t>(kind) << 1) |
-                  (static_cast<int32_t>(which_) << 17);
-        }
-
-      public:
-        Compiler(JSContext* cx, Engine engine, Which which)
-          : ICStubCompiler(cx, ICStub::GetProp_ArgumentsLength, engine),
-            which_(which)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_ArgumentsLength>(space, getStubCode());
-        }
-    };
-};
-
-class ICGetProp_ArgumentsCallee : public ICMonitoredStub
-{
-    friend class ICStubSpace;
-
-  protected:
-    ICGetProp_ArgumentsCallee(JitCode* stubCode, ICStub* firstMonitorStub);
-
-  public:
-    class Compiler : public ICStubCompiler {
-      protected:
-        ICStub* firstMonitorStub_;
-        MOZ_MUST_USE bool generateStubCode(MacroAssembler& masm);
-
-      public:
-        Compiler(JSContext* cx, Engine engine, ICStub* firstMonitorStub)
-          : ICStubCompiler(cx, ICStub::GetProp_ArgumentsCallee, engine),
-            firstMonitorStub_(firstMonitorStub)
-        {}
-
-        ICStub* getStub(ICStubSpace* space) {
-            return newStub<ICGetProp_ArgumentsCallee>(space, getStubCode(), firstMonitorStub_);
-        }
-    };
-};
-
 // JSOP_NEWARRAY
 // JSOP_NEWINIT
 
 class ICNewArray_Fallback : public ICFallbackStub
 {
     friend class ICStubSpace;
 
     GCPtrObject templateObject_;
--- a/js/src/jit/SharedICList.h
+++ b/js/src/jit/SharedICList.h
@@ -30,20 +30,17 @@ namespace jit {
     _(Compare_NumberWithUndefined)               \
     _(Compare_String)                            \
     _(Compare_Boolean)                           \
     _(Compare_Object)                            \
     _(Compare_ObjectWithUndefined)               \
     _(Compare_Int32WithBoolean)                  \
                                                  \
     _(GetProp_Fallback)                          \
-    _(GetProp_StringLength)                      \
     _(GetProp_CallNativeGlobal)                  \
-    _(GetProp_ArgumentsLength)                   \
-    _(GetProp_ArgumentsCallee)                   \
     _(GetProp_Generic)                           \
                                                  \
     _(CacheIR_Monitored)                         \
                                                  \
 
 } // namespace jit
 } // namespace js
 
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -96,17 +96,17 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Equals, bool,
                    RawServoDeclarationBlockBorrowed a,
                    RawServoDeclarationBlockBorrowed b)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetCssText, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsAString* result)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SerializeOneValue, void,
                    RawServoDeclarationBlockBorrowed declarations,
-                   const nsIAtom* property, bool is_custom, nsAString* buffer)
+                   nsIAtom* property, bool is_custom, nsAString* buffer)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Count, uint32_t,
                    RawServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetNthProperty, bool,
                    RawServoDeclarationBlockBorrowed declarations,
                    uint32_t index, nsAString* result)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetPropertyValue, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsIAtom* property, bool is_custom, nsAString* value)
deleted file mode 100644
--- a/layout/svg/tests/example.xml
+++ /dev/null
@@ -1,227 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="svg.css" type="text/css"?>
-<!DOCTYPE svg SYSTEM "SVG-20000202.dtd" > 
-<!--<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 10 January 2000//EN" --> 
-<!--  "http://www.w3.org/Graphics/SVG/SVG-19991203.dtd"> --> 
-<svg xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.svg" 
-     xmlns:html="http://www.w3.org/1999/xhtml">
-
-  <html:script>
-<![CDATA[
-
-var gIsInit  = false;
-var barXPnts = new Array();
-var barYPnts = new Array();
-
-var nodes = new Array();
-var gBarMax   = 200;
-var gHeight   = 80;
-var gBarCount = 10;
-var gBarDir   = 1;
-var gGo       = true;
-
-function init()
-{
-  dump("----------------\n");
-  nodes[0] = findNode(document.documentElement, "bar21");
-  nodes[1] = findNode(document.documentElement, "bar22");
-  nodes[2] = findNode(document.documentElement, "bar23");
-  nodes[3] = findNode(document.documentElement, "bargrid21");
-  nodes[4] = findNode(document.documentElement, "bargrid22");
-  nodes[5] = findNode(document.documentElement, "bargrid23");
-  dump("----------------\n");
-  gGo = true;
-  setTimeout("moveit()", 100);
-}
-function stop()
-{
-  gGo = false;
-}
-function ChangeBar(name, height)
-{
-  today = new Date();
-  stime = today.getMilliseconds();
-  dump("----------------\n");
-  str = name+"1";
-  node = findNode(document.documentElement, str); 
-  //node = document.getElementById(str);
-  today = new Date();
-  etime = today.getMilliseconds();
-  dump("1----------------"+(etime-stime)+"\n");
-  attr = document.createAttribute("points"); 
-  attr.value = "30 " + height + " 30 210 50 210 50 " + height;
-  node.attributes.setNamedItem(attr); 
-  today = new Date();
-  stime = today.getMilliseconds();
-  dump("2----------------"+(stime-etime)+"\n");
-
-  str = name+"2";
-  node = findNode(document.documentElement, str); 
-  dump("3----------------\n");
-  attr.value = "30 " + height + " 50 " + height + " 60 " + (height-10) + " 40 " + (height-10);
-  node.attributes.setNamedItem(attr); 
-  dump("4----------------\n");
-
-  str = name+"3";
-  node = findNode(document.documentElement, str); 
-  dump("5----------------\n");
-  attr.value = "50 " + height + " 60 " + (height-10) + " 60 200 50 210";
-  node.attributes.setNamedItem(attr); 
-  dump("=================\n");
-}
-
-function ChangeBarWithNodes(node1, node2, node3, height)
-{
-  attr = document.createAttribute("points"); 
-  attr.value = "30 " + height + " 30 210 50 210 50 " + height;
-  node1.attributes.setNamedItem(attr); 
-
-  attr.value = "30 " + height + " 50 " + height + " 60 " + (height-10) + " 40 " + (height-10);
-  node2.attributes.setNamedItem(attr); 
-
-  attr.value = "50 " + height + " 60 " + (height-10) + " 60 200 50 210";
-  node3.attributes.setNamedItem(attr); 
-}
-
-function moveit()
-{
-  //ChangeBar("bar2", 150);
-  //ChangeBar("bargrid2", 150);
-
-  ChangeBarWithNodes(nodes[0], nodes[1], nodes[2], gHeight);
-  ChangeBarWithNodes(nodes[3], nodes[4], nodes[5], gHeight);
-
-  gHeight += gBarDir;
-  gBarCount--;
-  //dump("gHeight: "+gHeight+"   gBarCount: "+gBarCount+"  gBarDir: "+gBarDir+"\n");
-  if (gHeight > gBarMax || gHeight < 1) {
-    gBarDir *= -1;
-    gBarCount = (Math.random() * 15)+3;
-    //dump("Changining directions: "+gBarDir+"\n");
-    if (gHeight > gBarMax) {
-      gHeight = gBarMax;
-    } else {
-      gHeight = 1;
-    }
-  } else {
-    if (gBarCount < 1) {
-      gBarDir *= -1;
-      gBarCount = (Math.random() * 15)+3;
-      //dump("----> "+gBarCount+"\n");
-    }
-  }
-  if (gGo) {
-    setTimeout("moveit()", 100);
-  }
-
-}
-
-function findNode(node, nodename)
-{
-  var type = node.nodeType;
-  if (type == Node.ELEMENT_NODE) {
-
-      // open tag
-      //dump("\<" + node.tagName);
-
-      // dump the attributes if any
-      attributes = node.attributes;
-      if (null != attributes) {
-        var countAttrs = attributes.length;
-        var index = 0;
-        while(index < countAttrs) {
-          att = attributes[index];
-          if (null != att) {
-            //dump(" " + att.name + "=" + att.value+" ["+nodename+"]\n");
-            if (att.name == "id" && att.value == nodename) {
-              //dump("Found it!\n");
-              return node;
-            }
-          }
-          index++;
-        }
-      }
-
-      // recursively dump the children
-      if (node.hasChildNodes()) {
-	      // close tag
-        //dump(">");
-
-        // get the children
-        var children = node.childNodes;
-        var length = children.length;
-        var count = 0;
-        while(count < length) {
-          child = children[count];
-          fndNode = findNode(child, nodename);
-          if (fndNode != null) {
-            return fndNode;
-          }
-          count++;
-        }
-        //dump("</" + node.tagName + ">");
-      } else {
-	      // close tag
-        //dump("/>");
-      }
-
-      
-  }
-  // if it's a piece of text just dump the text
-  else if (type == Node.TEXT_NODE) {
-      //dump(node.data);
-  }
-  return null;
-}
-
-]]>
-  </html:script>	
-
-  <g>
-    <polyline x="55" y="10" id="bg" points="20 0 220 0 220 200 20 200"/> 
-    <polyline x="55" y="10" id="bg" points="20 0 20 200 0 220 0 20 0 20  20 0"/> 
-    <polyline x="55" y="10" id="bg" points="20 200 220 200 200 220 0 220"/> 
-
-    <polyline x="55" y="10" id="grid" points="20 0 220 0 220 200 20 200"/> 
-    <polyline x="55" y="10" id="grid" points="20 0 20 200 0 220 0 20 0 20"/> 
-    <polyline x="55" y="10" id="grid" points="20 200 220 200 200 220 0 220"/> 
-
-    <polyline x="55" y="10" id="grid" points="20  220 40  200  40   0"/> 
-    <polyline x="55" y="10" id="grid" points="40  220 60  200  60   0"/> 
-    <polyline x="55" y="10" id="grid" points="60  220 80  200  80   0"/> 
-    <polyline x="55" y="10" id="grid" points="80  220 100 200  100  0"/> 
-    <polyline x="55" y="10" id="grid" points="100 220 120 200  120  0"/> 
-    <polyline x="55" y="10" id="grid" points="120 220 140 200  140  0"/> 
-    <polyline x="55" y="10" id="grid" points="140 220 160 200  160  0"/> 
-    <polyline x="55" y="10" id="grid" points="160 220 180 200  180  0"/> 
-    <polyline x="55" y="10" id="grid" points="180 220 200 200  200  0"/> 
-
-    <polygon x="55" y="10" id="bar1" points="30 60 30 210 50 210 50 60"/> 
-    <polygon x="55" y="10" id="bar1" points="30 60 50 60 60 50 40 50"/> 
-    <polygon x="55" y="10" id="bar1" points="50 60 60 50 60 200 50 210"/> 
-
-    <polyline x="55" y="10" id="grid" points="30 60 30 210 50 210 50 60"/> 
-    <polyline x="55" y="10" id="grid" points="30 60 50 60 60 50 40 50"/> 
-    <polyline x="55" y="10" id="grid" points="50 60 60 50 60 200 50 210"/> 
-
-
-    <polygon x="95" y="10" id="bar21" points="30 80 30 210 50 210 50 80"/> 
-    <polygon x="95" y="10" id="bar22" points="30 80 50 80  60 70  40 70"/> 
-    <polygon x="95" y="10" id="bar23" points="50 80 60 70  60 200 50 210"/> 
-
-    <polyline x="95" y="10" id="bargrid21" points="30 80 30 210 50 210 50 80"/> 
-    <polyline x="95" y="10" id="bargrid22" points="30 80 50 80  60 70  40 70"/> 
-    <polyline x="95" y="10" id="bargrid23" points="50 80 60 70  60 200 50 210"/> 
-
-    <polygon x="400" y="20" id="rect" points="10 10 50 10 50 50"/> 
-    <polygon x="400" y="75" id="poly" points="10 10 50 10 50 50 45 70 32 32 80 20"/> 
-    <polyline x="400" y="150" id="poly" points="10 10 50 10 50 50 45 70 32 32 80 20"/> 
-
-  </g>
-  <foreignobject>
-    <html:div style="position:absolute;top:5px;left:385px;">Simple Polygons</html:div>
-    <html:div style="position:absolute;top:240px;left:115px;">A Simple Graph</html:div>
-    <html:input type="button" style="position:absolute;top:260px;left:350px;" onclick="init();" value="Start"/>
-    <html:input type="button" style="position:absolute;top:260px;left:390px;" onclick="stop();" value="Stop"/>
-  </foreignobject>
-</svg> 
deleted file mode 100644
--- a/layout/svg/tests/svg.css
+++ /dev/null
@@ -1,33 +0,0 @@
-
-polygon {
-  color: black;
-}
-
-polygon[id="grid"] {
-  color: black;
-}
-
-polygon[id="bar1"] {
-  color: green;
-}
-
-polygon[id="rect"] {
-  color: blue;
-}
-
-polygon[id="bg"] {
-  color: #DDDDDD;
-}
-
-polygon[id="bar21"], polygon[id="bar22"], polygon[id="bar23"] {
-  color: #6F00DD;
-}
-
-polygon[id="bargrid21"], polygon[id="bargrid22"], polygon[id="bargrid23"] {
-  color: black;
-}
-
-polygon[id="poly"] {
-  color: #c0d0f0;
-}
-