Merge m-c to f-t
authorPhil Ringnalda <philringnalda@gmail.com>
Sun, 16 Mar 2014 21:55:27 -0700
changeset 192085 309dd572373ba60e9878f9f89a60da5aa34784d3
parent 192084 3f54c130e895e9063878ddccb07bcc326b9f28f5 (current diff)
parent 192068 25cfa01ba05440e5abe1b06f4b73cb104e224a82 (diff)
child 192086 28a725269bfa2e32c029fe9c3d4eca20292f6793
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to f-t
dom/file/DOMFileRequest.cpp
dom/file/DOMFileRequest.h
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -258,17 +258,16 @@ skip-if = true # bug 432425
 [browser_sanitize-timespans.js]
 [browser_sanitizeDialog.js]
 [browser_sanitizeDialog_treeView.js]
 skip-if = true  # disabled until the tree view is added
                 # back to the clear recent history dialog (sanitize.xul), if
                 # it ever is (bug 480169)
 [browser_save_link-perwindowpb.js]
 [browser_save_private_link_perwindowpb.js]
-skip-if = os == "linux" # bug 857427
 [browser_save_video.js]
 [browser_scope.js]
 [browser_selectTabAtIndex.js]
 [browser_star_hsts.js]
 [browser_subframe_favicons_not_used.js]
 [browser_tabDrop.js]
 [browser_tabMatchesInAwesomebar_perwindowpb.js]
 [browser_tab_drag_drop_perwindow.js]
--- a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
+++ b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js
@@ -31,86 +31,86 @@ function test() {
       }
     };
     function Visitor() {}
 
     var storage = cache.diskCacheStorage(LoadContextInfo.default, false);
     storage.asyncVisitStorage(new Visitor(), true /* Do walk entries */);
   }
 
-  function contextMenuOpened(aWindow, event) {
-    cache.clear();
-
-    event.currentTarget.removeEventListener("popupshown", contextMenuOpened);
-
-    // Create the folder the image will be saved into.
-    var destDir = createTemporarySaveDirectory();
-    var destFile = destDir.clone();
-
-    MockFilePicker.displayDirectory = destDir;
-    MockFilePicker.showCallback = function(fp) {
-      fileName = fp.defaultString;
-      destFile.append (fileName);
-      MockFilePicker.returnFiles = [destFile];
-      MockFilePicker.filterIndex = 1; // kSaveAsType_URL
-    };
-
-    mockTransferCallback = onTransferComplete;
-    mockTransferRegisterer.register();
-
-    registerCleanupFunction(function () {
-      mockTransferRegisterer.unregister();
-      MockFilePicker.cleanup();
-      destDir.remove(true);
-    });
-
-    // Select "Save Image As" option from context menu
-    var saveVideoCommand = aWindow.document.getElementById("context-saveimage");
-    saveVideoCommand.doCommand();
-
-    event.target.hidePopup();
-  }
-
   function onTransferComplete(downloadSuccess) {
     ok(downloadSuccess, "Image file should have been downloaded successfully");
 
     // Give the request a chance to finish and create a cache entry
     executeSoon(function() {
       checkDiskCacheFor(fileName, finish);
+      mockTransferCallback = null;
     });
   }
 
   function createTemporarySaveDirectory() {
     var saveDir = Cc["@mozilla.org/file/directory_service;1"]
                     .getService(Ci.nsIProperties)
                     .get("TmpD", Ci.nsIFile);
     saveDir.append("testsavedir");
     if (!saveDir.exists())
       saveDir.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
     return saveDir;
   }
 
   function doTest(aIsPrivateMode, aWindow, aCallback) {
+    function contextMenuOpened(event) {
+      cache.clear();
+
+      aWindow.document.removeEventListener("popupshown", contextMenuOpened);
+
+      // Create the folder the image will be saved into.
+      var destDir = createTemporarySaveDirectory();
+      var destFile = destDir.clone();
+
+      MockFilePicker.displayDirectory = destDir;
+      MockFilePicker.showCallback = function(fp) {
+        fileName = fp.defaultString;
+        destFile.append (fileName);
+        MockFilePicker.returnFiles = [destFile];
+        MockFilePicker.filterIndex = 1; // kSaveAsType_URL
+      };
+
+      mockTransferCallback = onTransferComplete;
+      mockTransferRegisterer.register();
+
+      registerCleanupFunction(function () {
+        mockTransferRegisterer.unregister();
+        MockFilePicker.cleanup();
+        destDir.remove(true);
+      });
+
+      // Select "Save Image As" option from context menu
+      var saveVideoCommand = aWindow.document.getElementById("context-saveimage");
+      saveVideoCommand.doCommand();
+
+      event.target.hidePopup();
+    }
+
     aWindow.gBrowser.addEventListener("pageshow", function pageShown(event) {
       // If data: -url PAC file isn't loaded soon enough, we may get about:privatebrowsing loaded
       if (event.target.location == "about:blank" ||
           event.target.location == "about:privatebrowsing") {
         aWindow.gBrowser.selectedBrowser.loadURI(testURI);
         return;
       }
       aWindow.gBrowser.removeEventListener("pageshow", pageShown);
 
-      executeSoon(function () {
-        aWindow.document.addEventListener("popupshown",
-                                          function(e) contextMenuOpened(aWindow, e), false);
+      waitForFocus(function () {
+        aWindow.document.addEventListener("popupshown", contextMenuOpened, false);
         var img = aWindow.gBrowser.selectedBrowser.contentDocument.getElementById("img");
         EventUtils.synthesizeMouseAtCenter(img,
                                            { type: "contextmenu", button: 2 },
                                            aWindow.gBrowser.contentWindow);
-      });
+      }, aWindow.gBrowser.selectedBrowser.contentWindow);
     });
   }
 
   function testOnWindow(aOptions, aCallback) {
     whenNewWindowLoaded(aOptions, function(aWin) {
       windowsToClose.push(aWin);
       // execute should only be called when need, like when you are opening
       // web pages on the test. If calling executeSoon() is not necesary, then
--- a/content/canvas/public/nsICanvasRenderingContextInternal.h
+++ b/content/canvas/public/nsICanvasRenderingContextInternal.h
@@ -92,16 +92,17 @@ public:
   // of the canvas at the time it was called.
   virtual mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() = 0;
 
   // If this context is opaque, the backing store of the canvas should
   // be created as opaque; all compositing operators should assume the
   // dst alpha is always 1.0.  If this is never called, the context
   // defaults to false (not opaque).
   NS_IMETHOD SetIsOpaque(bool isOpaque) = 0;
+  virtual bool GetIsOpaque() = 0;
 
   // Invalidate this context and release any held resources, in preperation
   // for possibly reinitializing with SetDimensions/InitializeWithSurface.
   NS_IMETHOD Reset() = 0;
 
   // Return the CanvasLayer for this context, creating
   // one for the given layer manager if not available.
   virtual already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -983,16 +983,20 @@ CanvasRenderingContext2D::InitializeWith
 NS_IMETHODIMP
 CanvasRenderingContext2D::SetIsOpaque(bool isOpaque)
 {
   if (isOpaque != mOpaque) {
     mOpaque = isOpaque;
     ClearTarget();
   }
 
+  if (mOpaque) {
+    EnsureTarget();
+  }
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 CanvasRenderingContext2D::SetIsIPC(bool isIPC)
 {
   if (isIPC != mIPC) {
     mIPC = isIPC;
@@ -1057,16 +1061,20 @@ CanvasRenderingContext2D::SetContextOpti
   ContextAttributes2D attributes;
   NS_ENSURE_TRUE(attributes.Init(aCx, aOptions), NS_ERROR_UNEXPECTED);
 
   if (Preferences::GetBool("gfx.canvas.willReadFrequently.enable", false)) {
     // Use software when there is going to be a lot of readback
     mForceSoftware = attributes.mWillReadFrequently;
   }
 
+  if (!attributes.mAlpha) {
+    SetIsOpaque(true);
+  }
+
   return NS_OK;
 }
 
 void
 CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer,
                                          int32_t* aFormat)
 {
   *aImageBuffer = nullptr;
@@ -3802,16 +3810,40 @@ CanvasRenderingContext2D::GetImageDataAr
   }
 
   // NOTE! dst is the same as src, and this relies on reading
   // from src and advancing that ptr before writing to dst.
   // NOTE! I'm not sure that it is, I think this comment might have been
   // inherited from Thebes canvas and is no longer true
   uint8_t* dst = data + dstWriteRect.y * (aWidth * 4) + dstWriteRect.x * 4;
 
+  if (mOpaque) {
+    for (int32_t j = 0; j < dstWriteRect.height; ++j) {
+      for (int32_t i = 0; i < dstWriteRect.width; ++i) {
+        // XXX Is there some useful swizzle MMX we can use here?
+#if MOZ_LITTLE_ENDIAN
+        uint8_t b = *src++;
+        uint8_t g = *src++;
+        uint8_t r = *src++;
+        src++;
+#else
+        src++;
+        uint8_t r = *src++;
+        uint8_t g = *src++;
+        uint8_t b = *src++;
+#endif
+        *dst++ = r;
+        *dst++ = g;
+        *dst++ = b;
+        *dst++ = 255;
+      }
+      src += srcStride - (dstWriteRect.width * 4);
+      dst += (aWidth * 4) - (dstWriteRect.width * 4);
+    }
+  } else
   for (int32_t j = 0; j < dstWriteRect.height; ++j) {
     for (int32_t i = 0; i < dstWriteRect.width; ++i) {
       // XXX Is there some useful swizzle MMX we can use here?
 #if MOZ_LITTLE_ENDIAN
       uint8_t b = *src++;
       uint8_t g = *src++;
       uint8_t r = *src++;
       uint8_t a = *src++;
--- a/content/canvas/src/CanvasRenderingContext2D.h
+++ b/content/canvas/src/CanvasRenderingContext2D.h
@@ -403,16 +403,17 @@ public:
                             const char16_t* aEncoderOptions,
                             nsIInputStream **aStream) MOZ_OVERRIDE;
   NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
 
   mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE
   { EnsureTarget(); return mTarget->Snapshot(); }
 
   NS_IMETHOD SetIsOpaque(bool isOpaque) MOZ_OVERRIDE;
+  bool GetIsOpaque() MOZ_OVERRIDE { return mOpaque; }
   NS_IMETHOD Reset() MOZ_OVERRIDE;
   already_AddRefed<CanvasLayer> GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                                CanvasLayer *aOldLayer,
                                                LayerManager *aManager) MOZ_OVERRIDE;
   virtual bool ShouldForceInactiveLayer(LayerManager *aManager) MOZ_OVERRIDE;
   void MarkContextClean() MOZ_OVERRIDE;
   NS_IMETHOD SetIsIPC(bool isIPC) MOZ_OVERRIDE;
   // this rect is in canvas device space
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -173,16 +173,17 @@ public:
     virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
     NS_IMETHOD GetInputStream(const char* aMimeType,
                               const char16_t* aEncoderOptions,
                               nsIInputStream **aStream) MOZ_OVERRIDE;
     NS_IMETHOD GetThebesSurface(gfxASurface **surface) MOZ_OVERRIDE;
     mozilla::TemporaryRef<mozilla::gfx::SourceSurface> GetSurfaceSnapshot() MOZ_OVERRIDE;
 
     NS_IMETHOD SetIsOpaque(bool b) MOZ_OVERRIDE { return NS_OK; };
+    bool GetIsOpaque() MOZ_OVERRIDE { return false; }
     NS_IMETHOD SetContextOptions(JSContext* aCx,
                                  JS::Handle<JS::Value> aOptions) MOZ_OVERRIDE;
 
     NS_IMETHOD SetIsIPC(bool b) MOZ_OVERRIDE { return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD Redraw(const gfxRect&) { return NS_ERROR_NOT_IMPLEMENTED; }
     NS_IMETHOD Swap(mozilla::ipc::Shmem& aBack,
                     int32_t x, int32_t y, int32_t w, int32_t h)
                     { return NS_ERROR_NOT_IMPLEMENTED; }
--- a/content/canvas/test/test_canvas.html
+++ b/content/canvas/test/test_canvas.html
@@ -21572,16 +21572,34 @@ function test_linedash() {
   isPixel(ctx, 120, 25, 0, 255, 0, 255, 0);
   isPixel(ctx, 115, 40, 0, 0, 0, 0, 0);
   isPixel(ctx, 105, 40, 0, 255, 0, 255, 0);
   isPixel(ctx, 90, 35, 0, 0, 0, 0, 0);
   isPixel(ctx, 90, 25, 0, 255, 0, 255, 0);
 }
 </script>
 
+<p>Canvas test: test_opaque</p>
+<canvas id="c688" width="150" height="50"></canvas>
+<script type="text/javascript">
+
+function test_opaque() {
+  var c = document.getElementById("c688");
+  var ctx = c.getContext("2d", {alpha: false});
+  ctx.fillStyle = "green";
+  ctx.fillRect(0,0,10,10);
+  ctx.fillStyle = "rgba(255,0,0,.5)";
+  ctx.fillRect(10,0,10,10);
+
+  isPixel(ctx, 20, 20, 0, 0, 0, 255, 0);
+  isPixel(ctx, 5, 5, 0, 128, 0, 255, 0);
+  isPixel(ctx, 15, 5, 128, 0, 0, 255, 0);
+}
+</script>
+
 <script>
 
 function asyncTestsDone() {
 	if (isDone_test_2d_drawImage_animated_apng &&
 		isDone_test_2d_drawImage_animated_gif) {
 		SimpleTest.finish();
 	} else {
 		setTimeout(asyncTestsDone, 500);
@@ -24868,16 +24886,22 @@ function runTests() {
   ok(false, "unexpected exception thrown in: test_getImageData_after_zero_canvas");
  }
  try {
   test_linedash();
  } catch(e) {
   throw e;
   ok(false, "unexpected exception thrown in: test_linedash");
  }
+try {
+  test_opaque();
+ } catch(e) {
+  throw e;
+  ok(false, "unexpected exception thrown in: test_opaque");
+ }
  try {
   // run this test last since it replaces the getContext method
   test_type_replace();
  } catch (e) {
   ok(false, "unexpected exception thrown in: test_type_replace");
  }
  
  //run the asynchronous tests
--- a/content/html/content/src/HTMLCanvasElement.cpp
+++ b/content/html/content/src/HTMLCanvasElement.cpp
@@ -776,17 +776,17 @@ HTMLCanvasElement::MozGetIPCContext(cons
 nsresult
 HTMLCanvasElement::UpdateContext(JSContext* aCx, JS::Handle<JS::Value> aNewContextOptions)
 {
   if (!mCurrentContext)
     return NS_OK;
 
   nsIntSize sz = GetWidthHeight();
 
-  nsresult rv = mCurrentContext->SetIsOpaque(GetIsOpaque());
+  nsresult rv = mCurrentContext->SetIsOpaque(HasAttr(kNameSpaceID_None, nsGkAtoms::moz_opaque));
   if (NS_FAILED(rv)) {
     mCurrentContext = nullptr;
     mCurrentContextId.Truncate();
     return rv;
   }
 
   rv = mCurrentContext->SetContextOptions(aCx, aNewContextOptions);
   if (NS_FAILED(rv)) {
@@ -898,16 +898,20 @@ HTMLCanvasElement::GetContextAtIndex(int
     return mCurrentContext;
 
   return nullptr;
 }
 
 bool
 HTMLCanvasElement::GetIsOpaque()
 {
+  if (mCurrentContext) {
+    return mCurrentContext->GetIsOpaque();
+  }
+
   return HasAttr(kNameSpaceID_None, nsGkAtoms::moz_opaque);
 }
 
 already_AddRefed<CanvasLayer>
 HTMLCanvasElement::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
                                   CanvasLayer *aOldLayer,
                                   LayerManager *aManager)
 {
--- a/content/html/content/test/test_ignoreuserfocus.html
+++ b/content/html/content/test/test_ignoreuserfocus.html
@@ -4,16 +4,17 @@
     <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
     <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   </head>
   <body>
     <script type="application/javascript;version=1.7">
       "use strict";
 
+      SimpleTest.requestCompleteLog();
       SimpleTest.waitForExplicitFinish();
 
       // Copied from EventUtils.js, but we want *ToWindow methods.
       function synthesizeMouseAtPoint(left, top, aEvent, aWindow) {
         var utils = _getDOMWindowUtils(aWindow);
         var defaultPrevented = false;
         if (utils) {
           var button = aEvent.button || 0;
--- a/content/media/gstreamer/GStreamerAllocator.cpp
+++ b/content/media/gstreamer/GStreamerAllocator.cpp
@@ -55,17 +55,17 @@ G_DEFINE_TYPE(MozGfxBufferPool, moz_gfx_
 
 void
 moz_gfx_memory_reset(MozGfxMemory *mem)
 {
   if (mem->image)
     mem->image->Release();
 
   ImageContainer* container = ((MozGfxMemoryAllocator*) mem->memory.allocator)->reader->GetImageContainer();
-  mem->image = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(ImageFormat::PLANAR_YCBCR).get());
+  mem->image = reinterpret_cast<PlanarYCbCrImage*>(container->CreateImage(ImageFormat::PLANAR_YCBCR).take());
   mem->data = mem->image->AllocateAndGetNewBuffer(mem->memory.size);
 }
 
 static GstMemory*
 moz_gfx_memory_allocator_alloc(GstAllocator* aAllocator, gsize aSize,
     GstAllocationParams* aParams)
 {
   MozGfxMemory* mem = g_slice_new (MozGfxMemory);
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -405,17 +405,17 @@ DOMInterfaces = {
 },
 
 'FileReaderSync': {
     'workers': True,
     'wrapperCache': False,
 },
 
 'FileRequest': {
-    'nativeType': 'mozilla::dom::file::DOMFileRequest',
+    'nativeType': 'mozilla::dom::file::FileRequest',
 },
 
 'FormData': [
 {
     'nativeType': 'nsFormData'
 },
 {
     'workers': True,
deleted file mode 100644
--- a/dom/file/DOMFileRequest.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "DOMFileRequest.h"
-
-#include "mozilla/dom/FileRequestBinding.h"
-#include "LockedFile.h"
-
-USING_FILE_NAMESPACE
-
-DOMFileRequest::DOMFileRequest(nsPIDOMWindow* aWindow)
-  : FileRequest(aWindow)
-{
-}
-
-// static
-already_AddRefed<DOMFileRequest>
-DOMFileRequest::Create(nsPIDOMWindow* aOwner, LockedFile* aLockedFile)
-{
-  MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
-
-  nsRefPtr<DOMFileRequest> request = new DOMFileRequest(aOwner);
-  request->mLockedFile = aLockedFile;
-
-  return request.forget();
-}
-
-/* virtual */ JSObject*
-DOMFileRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
-{
-  return FileRequestBinding::Wrap(aCx, aScope, this);
-}
-
-nsIDOMLockedFile*
-DOMFileRequest::GetLockedFile() const
-{
-  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  return mLockedFile;
-}
deleted file mode 100644
--- a/dom/file/DOMFileRequest.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* 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 mozilla_dom_file_DOMFileRequest_h
-#define mozilla_dom_file_DOMFileRequest_h
-
-#include "FileRequest.h"
-
-class nsIDOMLockedFile;
-
-BEGIN_FILE_NAMESPACE
-
-class DOMFileRequest : public FileRequest
-{
-public:
-  static already_AddRefed<DOMFileRequest>
-  Create(nsPIDOMWindow* aOwner, LockedFile* aLockedFile);
-
-  virtual JSObject* WrapObject(JSContext* aCx,
-                               JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
-
-  nsIDOMLockedFile* GetLockedFile() const;
-  IMPL_EVENT_HANDLER(progress)
-
-protected:
-  DOMFileRequest(nsPIDOMWindow* aWindow);
-};
-
-END_FILE_NAMESPACE
-
-#endif // mozilla_dom_file_DOMFileRequest_h
--- a/dom/file/FileHandle.cpp
+++ b/dom/file/FileHandle.cpp
@@ -159,17 +159,18 @@ FileHandle::GetFile(ErrorResult& aError)
 
   nsRefPtr<LockedFile> lockedFile =
     LockedFile::Create(this, FileMode::Readonly, LockedFile::PARALLEL);
   if (!lockedFile) {
     aError.Throw(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
     return nullptr;
   }
 
-  nsRefPtr<FileRequest> request = FileRequest::Create(GetOwner(), lockedFile);
+  nsRefPtr<FileRequest> request =
+    FileRequest::Create(GetOwner(), lockedFile, /* aWrapAsDOMRequest */ true);
 
   nsRefPtr<MetadataParameters> params = new MetadataParameters(true, false);
 
   nsRefPtr<GetFileHelper> helper =
     new GetFileHelper(lockedFile, request, params, this);
 
   nsresult rv = helper->Enqueue();
   if (NS_FAILED(rv)) {
--- a/dom/file/FileRequest.cpp
+++ b/dom/file/FileRequest.cpp
@@ -1,46 +1,48 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "FileRequest.h"
 
-#include "DOMFileRequest.h"
+#include "mozilla/dom/FileRequestBinding.h"
 #include "nsCxPusher.h"
 #include "nsEventDispatcher.h"
 #include "nsError.h"
 #include "nsIDOMProgressEvent.h"
 #include "nsDOMClassInfoID.h"
 #include "FileHelper.h"
 #include "LockedFile.h"
 
 USING_FILE_NAMESPACE
 
 FileRequest::FileRequest(nsPIDOMWindow* aWindow)
-  : DOMRequest(aWindow)
+  : DOMRequest(aWindow), mWrapAsDOMRequest(false)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 FileRequest::~FileRequest()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 }
 
 // static
 already_AddRefed<FileRequest>
-FileRequest::Create(nsPIDOMWindow* aOwner, LockedFile* aLockedFile)
+FileRequest::Create(nsPIDOMWindow* aOwner, LockedFile* aLockedFile,
+                    bool aWrapAsDOMRequest)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsRefPtr<FileRequest> request = new FileRequest(aOwner);
   request->mLockedFile = aLockedFile;
+  request->mWrapAsDOMRequest = aWrapAsDOMRequest;
 
   return request.forget();
 }
 
 nsresult
 FileRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@@ -96,16 +98,33 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED_1(Fil
                                      mLockedFile)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileRequest)
 NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
 
 NS_IMPL_ADDREF_INHERITED(FileRequest, DOMRequest)
 NS_IMPL_RELEASE_INHERITED(FileRequest, DOMRequest)
 
+// virtual
+JSObject*
+FileRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
+{
+  if (mWrapAsDOMRequest) {
+    return DOMRequest::WrapObject(aCx, aScope);
+  }
+  return FileRequestBinding::Wrap(aCx, aScope, this);
+}
+
+nsIDOMLockedFile*
+FileRequest::GetLockedFile() const
+{
+  MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
+  return mLockedFile;
+}
+
 void
 FileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
 {
   if (NS_FAILED(CheckInnerWindowCorrectness())) {
     return;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
--- a/dom/file/FileRequest.h
+++ b/dom/file/FileRequest.h
@@ -7,48 +7,63 @@
 #ifndef mozilla_dom_file_filerequest_h__
 #define mozilla_dom_file_filerequest_h__
 
 #include "mozilla/Attributes.h"
 #include "FileCommon.h"
 
 #include "DOMRequest.h"
 
+class nsIDOMLockedFile;
+
 BEGIN_FILE_NAMESPACE
 
 class FileHelper;
 class LockedFile;
 
 class FileRequest : public mozilla::dom::DOMRequest
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileRequest, DOMRequest)
 
   static already_AddRefed<FileRequest>
-  Create(nsPIDOMWindow* aOwner, LockedFile* aLockedFile);
+  Create(nsPIDOMWindow* aOwner, LockedFile* aLockedFile,
+         bool aWrapAsDOMRequest);
 
   // nsIDOMEventTarget
   virtual nsresult
   PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
 
   void
   OnProgress(uint64_t aProgress, uint64_t aProgressMax)
   {
     FireProgressEvent(aProgress, aProgressMax);
   }
 
   nsresult
   NotifyHelperCompleted(FileHelper* aFileHelper);
 
+  // nsWrapperCache
+  virtual JSObject*
+  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
+
+  // WebIDL
+  nsIDOMLockedFile*
+  GetLockedFile() const;
+
+  IMPL_EVENT_HANDLER(progress)
+
 protected:
   FileRequest(nsPIDOMWindow* aWindow);
   ~FileRequest();
 
   void
   FireProgressEvent(uint64_t aLoaded, uint64_t aTotal);
 
   nsRefPtr<LockedFile> mLockedFile;
+
+  bool mWrapAsDOMRequest;
 };
 
 END_FILE_NAMESPACE
 
 #endif // mozilla_dom_file_filerequest_h__
--- a/dom/file/LockedFile.cpp
+++ b/dom/file/LockedFile.cpp
@@ -17,19 +17,19 @@
 #include "nsNetUtil.h"
 #include "nsDOMClassInfoID.h"
 #include "nsJSUtils.h"
 #include "nsStringStream.h"
 #include "nsWidgetsCID.h"
 #include "xpcpublic.h"
 
 #include "AsyncHelper.h"
-#include "DOMFileRequest.h"
 #include "FileHandle.h"
 #include "FileHelper.h"
+#include "FileRequest.h"
 #include "FileService.h"
 #include "FileStreamWrappers.h"
 #include "MemoryStreams.h"
 #include "MetadataHelper.h"
 #include "nsError.h"
 #include "nsContentUtils.h"
 
 #include "mozilla/dom/EncodingUtils.h"
@@ -415,21 +415,21 @@ LockedFile::GetOrCreateStream(nsISupport
   }
 
   nsCOMPtr<nsISupports> stream(mStream);
   stream.forget(aStream);
 
   return NS_OK;
 }
 
-already_AddRefed<DOMFileRequest>
+already_AddRefed<FileRequest>
 LockedFile::GenerateFileRequest()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
-  return DOMFileRequest::Create(GetOwner(), this);
+  return FileRequest::Create(GetOwner(), this, /* aWrapAsDOMRequest */ false);
 }
 
 bool
 LockedFile::IsOpen() const
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   // If we haven't started anything then we're open.
@@ -551,17 +551,17 @@ LockedFile::GetMetadata(JS::Handle<JS::V
   NS_ENSURE_TRUE(result, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
   nsRefPtr<MetadataParameters> params =
     new MetadataParameters(config.mSize, config.mLastModified);
   if (!params->IsConfigured()) {
     return NS_ERROR_TYPE_ERR;
   }
 
-  nsRefPtr<DOMFileRequest> fileRequest = GenerateFileRequest();
+  nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
 
   nsRefPtr<MetadataHelper> helper =
     new MetadataHelper(this, fileRequest, params);
 
   nsresult rv = helper->Enqueue();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
   nsRefPtr<nsIDOMDOMRequest> request = fileRequest.forget();
@@ -588,17 +588,17 @@ LockedFile::ReadAsArrayBuffer(uint64_t a
     return NS_ERROR_TYPE_ERR;
   }
 
   // Do nothing if the window is closed
   if (!GetOwner()) {
     return NS_OK;
   }
 
-  nsRefPtr<DOMFileRequest> fileRequest = GenerateFileRequest();
+  nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
 
   nsRefPtr<ReadHelper> helper =
     new ReadHelper(this, fileRequest, mLocation, aSize);
 
   nsresult rv = helper->Init();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
   rv = helper->Enqueue();
@@ -630,17 +630,17 @@ LockedFile::ReadAsText(uint64_t aSize,
     return NS_ERROR_TYPE_ERR;
   }
 
   // Do nothing if the window is closed
   if (!GetOwner()) {
     return NS_OK;
   }
 
-  nsRefPtr<DOMFileRequest> fileRequest = GenerateFileRequest();
+  nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
 
   nsRefPtr<ReadTextHelper> helper =
     new ReadTextHelper(this, fileRequest, mLocation, aSize, aEncoding);
 
   nsresult rv = helper->Init();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
   rv = helper->Enqueue();
@@ -701,17 +701,17 @@ LockedFile::Truncate(uint64_t aSize,
     location = mLocation;
   }
 
   // Do nothing if the window is closed
   if (!GetOwner()) {
     return NS_OK;
   }
 
-  nsRefPtr<DOMFileRequest> fileRequest = GenerateFileRequest();
+  nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
 
   nsRefPtr<TruncateHelper> helper =
     new TruncateHelper(this, fileRequest, location);
 
   nsresult rv = helper->Enqueue();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
   if (aOptionalArgCount) {
@@ -736,17 +736,17 @@ LockedFile::Flush(nsISupports** _retval)
     return NS_ERROR_DOM_FILEHANDLE_READ_ONLY_ERR;
   }
 
   // Do nothing if the window is closed
   if (!GetOwner()) {
     return NS_OK;
   }
 
-  nsRefPtr<DOMFileRequest> fileRequest = GenerateFileRequest();
+  nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
 
   nsRefPtr<FlushHelper> helper = new FlushHelper(this, fileRequest);
 
   nsresult rv = helper->Enqueue();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
 
   nsRefPtr<nsIDOMDOMRequest> request = fileRequest.forget();
   request.forget(_retval);
@@ -858,17 +858,17 @@ LockedFile::WriteOrAppend(JS::Handle<JS:
     GetInputStreamForJSVal(aValue, aCx, getter_AddRefs(inputStream),
                            &inputLength);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!inputLength) {
     return NS_OK;
   }
 
-  nsRefPtr<DOMFileRequest> fileRequest = GenerateFileRequest();
+  nsRefPtr<FileRequest> fileRequest = GenerateFileRequest();
 
   uint64_t location = aAppend ? UINT64_MAX : mLocation;
 
   nsRefPtr<WriteHelper> helper =
     new WriteHelper(this, fileRequest, location, inputStream, inputLength);
 
   rv = helper->Enqueue();
   NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
--- a/dom/file/LockedFile.h
+++ b/dom/file/LockedFile.h
@@ -14,17 +14,16 @@
 #include "nsIRunnable.h"
 
 #include "nsDOMEventTargetHelper.h"
 
 class nsIInputStream;
 
 BEGIN_FILE_NAMESPACE
 
-class DOMFileRequest;
 class FileHandle;
 class FileRequest;
 class MetadataHelper;
 
 class LockedFile : public nsDOMEventTargetHelper,
                    public nsIDOMLockedFile,
                    public nsIRunnable
 {
@@ -93,17 +92,17 @@ private:
   ~LockedFile();
 
   void
   OnNewRequest();
 
   void
   OnRequestFinished();
 
-  inline already_AddRefed<DOMFileRequest>
+  already_AddRefed<FileRequest>
   GenerateFileRequest();
 
   nsresult
   WriteOrAppend(JS::Handle<JS::Value> aValue, JSContext* aCx,
                 nsISupports** _retval, bool aAppend);
 
   nsresult
   Finish();
--- a/dom/file/moz.build
+++ b/dom/file/moz.build
@@ -17,33 +17,32 @@ EXPORTS += [
 ]
 
 EXPORTS.mozilla.dom.file += [
     'ArchiveEvent.h',
     'ArchiveReader.h',
     'ArchiveRequest.h',
     'ArchiveZipEvent.h',
     'ArchiveZipFile.h',
-    'DOMFileRequest.h',
     'File.h',
     'FileCommon.h',
     'FileHandle.h',
     'FileHelper.h',
+    'FileRequest.h',
     'FileService.h',
     'LockedFile.h',
 ]
 
 UNIFIED_SOURCES += [
     'ArchiveEvent.cpp',
     'ArchiveReader.cpp',
     'ArchiveRequest.cpp',
     'ArchiveZipEvent.cpp',
     'ArchiveZipFile.cpp',
     'AsyncHelper.cpp',
-    'DOMFileRequest.cpp',
     'File.cpp',
     'FileHandle.cpp',
     'FileHelper.cpp',
     'FileRequest.cpp',
     'FileService.cpp',
     'FileStreamWrappers.cpp',
     'LockedFile.cpp',
     'MemoryStreams.cpp',
--- a/dom/file/test/mochitest.ini
+++ b/dom/file/test/mochitest.ini
@@ -8,16 +8,18 @@ support-files =
 skip-if = buildapp == 'b2g'
 [test_archivereader.html]
 skip-if = buildapp == 'b2g'
 [test_archivereader_nonUnicode.html]
 skip-if = buildapp == 'b2g'
 [test_archivereader_zip_in_zip.html]
 skip-if = buildapp == 'b2g'
 [test_bug_793311.html]
+[test_getFile.html]
+skip-if = buildapp == 'b2g'
 [test_getFileId.html]
 [test_location.html]
 skip-if = buildapp == 'b2g'
 [test_lockedfile_lifetimes.html]
 skip-if = buildapp == 'b2g'
 [test_lockedfile_lifetimes_nested.html]
 skip-if = buildapp == 'b2g'
 [test_lockedfile_ordering.html]
new file mode 100644
--- /dev/null
+++ b/dom/file/test/test_getFile.html
@@ -0,0 +1,43 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html>
+<head>
+  <title>File Handle Test</title>
+
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+  <script type="text/javascript;version=1.7">
+  function testSteps()
+  {
+    for each (let fileStorage in fileStorages) {
+      let request = getFileHandle(fileStorage.key, "test.txt");
+      request.onerror = errorHandler;
+      request.onsuccess = grabEventAndContinueHandler;
+      let event = yield undefined;
+
+      let fileHandle = event.target.result;
+      fileHandle.onerror = errorHandler;
+
+      request = fileHandle.getFile();
+      ok(request instanceof DOMRequest, "Correct interface");
+      ok(!(request instanceof FileRequest), "Correct interface");
+      ok(!('lockedFile' in request), "Property should not exist");
+      ok(request.lockedFile === undefined, "Property should not exist");
+      ok(!('onprogress' in request), "Property should not exist");
+      ok(request.onprogress === undefined, "Property should not exist");
+    }
+
+    finishTest();
+    yield undefined;
+  }
+  </script>
+  <script type="text/javascript;version=1.7" src="helpers.js"></script>
+
+</head>
+
+<body onload="runTest();"></body>
+
+</html>
--- a/dom/webidl/CanvasRenderingContext2D.webidl
+++ b/dom/webidl/CanvasRenderingContext2D.webidl
@@ -11,16 +11,18 @@
  * and create derivative works of this document.
  */
 
 enum CanvasWindingRule { "nonzero", "evenodd" };
 
 dictionary ContextAttributes2D {
   // whether or not we're planning to do a lot of readback operations
   boolean willReadFrequently = false;
+  // signal if the canvas contains an alpha channel
+  boolean alpha = true;
 };
 
 dictionary HitRegionOptions {
   DOMString id = "";
   Element? control = null;
 };
 
 interface CanvasRenderingContext2D {
--- a/js/src/builtin/TypeRepresentation.cpp
+++ b/js/src/builtin/TypeRepresentation.cpp
@@ -304,53 +304,53 @@ StructTypeRepresentation::init(JSContext
                                AutoPropertyNameVector &names,
                                AutoObjectVector &typeReprOwners)
 {
     JS_ASSERT(names.length() == typeReprOwners.length());
     fieldCount_ = names.length();
 
     // We compute alignment into the field `align_` directly in the
     // loop below, but not `size_` because we have to very careful
-    // about overflow. For now, we always use a uint32_t for
+    // about overflow. For now, we always use a int32_t for
     // consistency across build environments.
-    uint32_t totalSize = 0;
+    int32_t totalSize = 0;
 
     // These will be adjusted in the loop below:
     alignment_ = 1;
     opaque_ = false;
 
     for (size_t i = 0; i < names.length(); i++) {
         SizedTypeRepresentation *fieldTypeRepr =
             fromOwnerObject(*typeReprOwners[i])->asSized();
 
         if (fieldTypeRepr->opaque())
             opaque_ = true;
 
-        uint32_t alignedSize = alignTo(totalSize, fieldTypeRepr->alignment());
+        int32_t alignedSize = alignTo(totalSize, fieldTypeRepr->alignment());
         if (alignedSize < totalSize) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
                                  JSMSG_TYPEDOBJECT_TOO_BIG);
             return false;
         }
 
         new(fields() + i) StructField(i, names[i],
                                       fieldTypeRepr, alignedSize);
         alignment_ = js::Max(alignment_, fieldTypeRepr->alignment());
 
-        uint32_t incrementedSize = alignedSize + fieldTypeRepr->size();
+        int32_t incrementedSize = alignedSize + fieldTypeRepr->size();
         if (incrementedSize < alignedSize) {
             JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
                                  JSMSG_TYPEDOBJECT_TOO_BIG);
             return false;
         }
 
         totalSize = incrementedSize;
     }
 
-    uint32_t alignedSize = alignTo(totalSize, alignment_);
+    int32_t alignedSize = alignTo(totalSize, alignment_);
     if (alignedSize < totalSize) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
                              JSMSG_TYPEDOBJECT_TOO_BIG);
         return false;
     }
 
     size_ = alignedSize;
     return true;
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -2296,16 +2296,22 @@ TypedObject::constructSized(JSContext *c
         return true;
     }
 
     // Buffer constructor.
     if (args[0].isObject() && args[0].toObject().is<ArrayBufferObject>()) {
         Rooted<ArrayBufferObject*> buffer(cx);
         buffer = &args[0].toObject().as<ArrayBufferObject>();
 
+        if (buffer->isNeutered()) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage,
+                                 nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
+            return false;
+        }
+
         int32_t offset;
         if (args.length() >= 2 && !args[1].isUndefined()) {
             if (!args[1].isInt32()) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage,
                                      nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
                 return false;
             }
 
@@ -2402,16 +2408,22 @@ TypedObject::constructUnsized(JSContext 
         return true;
     }
 
     // Buffer constructor.
     if (args[0].isObject() && args[0].toObject().is<ArrayBufferObject>()) {
         Rooted<ArrayBufferObject*> buffer(cx);
         buffer = &args[0].toObject().as<ArrayBufferObject>();
 
+        if (buffer->isNeutered()) {
+            JS_ReportErrorNumber(cx, js_GetErrorMessage,
+                                 nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
+            return false;
+        }
+
         int32_t offset;
         if (args.length() >= 2 && !args[1].isUndefined()) {
             if (!args[1].isInt32()) {
                 JS_ReportErrorNumber(cx, js_GetErrorMessage,
                                      nullptr, JSMSG_TYPEDOBJECT_BAD_ARGS);
                 return false;
             }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/atopneuteredbuffer.js
@@ -0,0 +1,23 @@
+// Bug 976697. Check for various quirks when instantiating a typed
+// object atop an already neutered buffer.
+
+if (typeof TypedObject === "undefined")
+  quit();
+
+load(libdir + "asserts.js")
+
+var {StructType, uint32, Object, Any, storage, objectType} = TypedObject;
+
+function main() { // once a C programmer, always a C programmer.
+  var Uints = uint32.array();
+  var Unit = new StructType({});   // Empty struct type
+  var buffer = new ArrayBuffer(0); // Empty buffer
+  var p = new Unit(buffer);        // OK
+  neuter(buffer);
+  assertThrowsInstanceOf(() => new Unit(buffer), TypeError,
+                         "Able to instantiate atop neutered buffer");
+  assertThrowsInstanceOf(() => new Uints(buffer, 0), TypeError,
+                         "Able to instantiate atop neutered buffer");
+}
+
+main();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/bug976530.js
@@ -0,0 +1,10 @@
+// |jit-test| error:Error
+
+// Test that we don't permit structs whose fields exceed 32 bits.
+
+if (!this.hasOwnProperty("TypedObject"))
+  throw new Error();
+
+var Vec3u16Type = TypedObject.uint16.array((1073741823));
+var PairVec3u16Type = new TypedObject.StructType({ fst: Vec3u16Type, snd: Vec3u16Type });
+new PairVec3u16Type();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/bug976697.js
@@ -0,0 +1,13 @@
+// Test that instantiating a typed array on top of a neutered buffer
+// doesn't trip any asserts.
+//
+// Any copyright is dedicated to the Public Domain.
+// http://creativecommons.org/licenses/publicdomain/
+
+if (!this.hasOwnProperty("TypedObject"))
+  quit();
+
+x = ArrayBuffer();
+neuter(x);
+Uint32Array(x);
+gc();
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -1802,21 +1802,16 @@ Assembler::patchConstantPoolLoad(void* l
 
 uint32_t
 Assembler::placeConstantPoolBarrier(int offset)
 {
     // BUG: 700526
     // this is still an active path, however, we do not hit it in the test
     // suite at all.
     MOZ_ASSUME_UNREACHABLE("ARMAssembler holdover");
-#if 0
-    offset = (offset - sizeof(ARMWord)) >> 2;
-    ASSERT((offset <= BOFFSET_MAX && offset >= BOFFSET_MIN));
-    return AL | B | (offset & BRANCH_MASK);
-#endif
 }
 
 // Control flow stuff:
 
 // bx can *only* branch to a register
 // never to an immediate.
 BufferOffset
 Assembler::as_bx(Register r, Condition c, bool isPatchable)
--- a/js/src/jit/arm/Bailouts-arm.cpp
+++ b/js/src/jit/arm/Bailouts-arm.cpp
@@ -8,64 +8,16 @@
 #include "jscompartment.h"
 
 #include "jit/Bailouts.h"
 #include "jit/JitCompartment.h"
 
 using namespace js;
 using namespace js::jit;
 
-#if 0
-// no clue what these asserts should be.
-JS_STATIC_ASSERT(sizeof(BailoutStack) ==
-                 sizeof(uintptr_t) +
-                 sizeof(double) * 8 +
-                 sizeof(uintptr_t) * 8 +
-                 sizeof(uintptr_t));
-
-JS_STATIC_ASSERT(sizeof(ExtendedBailoutStack) ==
-                 sizeof(BailoutStack) +
-                 sizeof(uintptr_t));
-
-#endif
-#if 0
-BailoutEnvironment::BailoutEnvironment(JitCompartment *ion, void **sp)
-  : sp_(sp)
-{
-    bailout_ = reinterpret_cast<ExtendedBailoutStack *>(sp);
-
-    if (bailout_->frameClass() != FrameSizeClass::None()) {
-        frameSize_ = bailout_->frameSize();
-        frame_ = &sp_[sizeof(BailoutStack) / sizeof(void *)];
-
-        // Compute the bailout ID.
-        JitCode *code = ion->getBailoutTable(bailout_->frameClass());
-        uintptr_t tableOffset = bailout_->tableOffset();
-        uintptr_t tableStart = reinterpret_cast<uintptr_t>(code->raw());
-
-        JS_ASSERT(tableOffset >= tableStart &&
-                  tableOffset < tableStart + code->instructionsSize());
-        JS_ASSERT((tableOffset - tableStart) % BAILOUT_TABLE_ENTRY_SIZE == 0);
-
-        bailoutId_ = ((tableOffset - tableStart) / BAILOUT_TABLE_ENTRY_SIZE) - 1;
-        JS_ASSERT(bailoutId_ < BAILOUT_TABLE_SIZE);
-    } else {
-        frameSize_ = bailout_->frameSize();
-        frame_ = &sp_[sizeof(ExtendedBailoutStack) / sizeof(void *)];
-    }
-}
-
-IonFramePrefix *
-BailoutEnvironment::top() const
-{
-    return (IonFramePrefix *)&frame_[frameSize_ / sizeof(void *)];
-}
-
-#endif
-
 namespace js {
 namespace jit {
 
 class BailoutStack
 {
     uintptr_t frameClassId_;
     // This is pushed in the bailout handler.  Both entry points into the handler
     // inserts their own value int lr, which is then placed onto the stack along
--- a/js/src/jit/arm/CodeGenerator-arm.cpp
+++ b/js/src/jit/arm/CodeGenerator-arm.cpp
@@ -237,33 +237,18 @@ CodeGeneratorARM::bailoutFrom(Label *lab
     if (!encode(snapshot))
         return false;
 
     // Though the assembler doesn't track all frame pushes, at least make sure
     // the known value makes sense. We can't use bailout tables if the stack
     // isn't properly aligned to the static frame size.
     JS_ASSERT_IF(frameClass_ != FrameSizeClass::None(),
                  frameClass_.frameSize() == masm.framePushed());
-    // This involves retargeting a label, which I've declared is always going
-    // to be a pc-relative branch to an absolute address!
-    // With no assurance that this is going to be a local branch, I am wary to
-    // implement this.  Moreover, If it isn't a local branch, it will be large
-    // and possibly slow.  I believe that the correct way to handle this is to
-    // subclass label into a fatlabel, where we generate enough room for a load
-    // before the branch
-#if 0
-    if (assignBailoutId(snapshot)) {
-        uint8_t *code = deoptTable_->raw() + snapshot->bailoutId() * BAILOUT_TABLE_ENTRY_SIZE;
-        masm.retarget(label, code, Relocation::HARDCODED);
-        return true;
-    }
-#endif
-    // We could not use a jump table, either because all bailout IDs were
-    // reserved, or a jump table is not optimal for this frame size or
-    // platform. Whatever, we will generate a lazy bailout.
+
+    // On ARM we don't use a bailout table.
     OutOfLineBailout *ool = new(alloc()) OutOfLineBailout(snapshot, masm.framePushed());
     if (!addOutOfLineCode(ool)) {
         return false;
     }
 
     masm.retarget(label, ool->entry());
 
     return true;
@@ -1656,24 +1641,16 @@ CodeGeneratorARM::visitNotD(LNotD *ins)
         masm.ma_lsr(Imm32(28), dest, dest);
         masm.ma_alu(dest, lsr(dest, 2), dest, op_orr); // 28 + 2 = 30
         masm.ma_and(Imm32(1), dest);
     } else {
         masm.as_vmrs(pc);
         masm.ma_mov(Imm32(0), dest);
         masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal);
         masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow);
-#if 0
-        masm.as_vmrs(ToRegister(dest));
-        // Mask out just the two bits we care about.  If neither bit is set,
-        // the dest is already zero
-        masm.ma_and(Imm32(0x50000000), dest, dest, Assembler::SetCond);
-        // If it is non-zero, then force it to be 1.
-        masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::NotEqual);
-#endif
     }
     return true;
 }
 
 bool
 CodeGeneratorARM::visitNotF(LNotF *ins)
 {
     // Since this operation is not, we want to set a bit if
@@ -1693,24 +1670,16 @@ CodeGeneratorARM::visitNotF(LNotF *ins)
         masm.ma_lsr(Imm32(28), dest, dest);
         masm.ma_alu(dest, lsr(dest, 2), dest, op_orr); // 28 + 2 = 30
         masm.ma_and(Imm32(1), dest);
     } else {
         masm.as_vmrs(pc);
         masm.ma_mov(Imm32(0), dest);
         masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal);
         masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow);
-#if 0
-        masm.as_vmrs(ToRegister(dest));
-        // Mask out just the two bits we care about.  If neither bit is set,
-        // the dest is already zero
-        masm.ma_and(Imm32(0x50000000), dest, dest, Assembler::SetCond);
-        // If it is non-zero, then force it to be 1.
-        masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::NotEqual);
-#endif
     }
     return true;
 }
 
 bool
 CodeGeneratorARM::visitLoadSlotV(LLoadSlotV *load)
 {
     const ValueOperand out = ToOutValue(load);
--- a/js/src/jit/arm/Trampoline-arm.cpp
+++ b/js/src/jit/arm/Trampoline-arm.cpp
@@ -143,28 +143,16 @@ JitRuntime::generateEnterJIT(JSContext *
     // Save stack pointer.
     if (type == EnterJitBaseline)
         masm.movePtr(sp, r11);
 
     // Load the number of actual arguments into r10.
     masm.loadPtr(slot_vp, r10);
     masm.unboxInt32(Address(r10, 0), r10);
 
-#if 0
-    // This is in case we want to go back to using frames that
-    // aren't 8 byte alinged
-    // there are r1 2-word arguments to the js code
-    // we want 2 word alignment, so this shouldn't matter.
-    // After the arguments have been pushed, we want to push an additional 3 words of
-    // data, so in all, we want to decrease sp by 4 if it is currently aligned to
-    // 8, and not touch it otherwise
-    aasm->as_sub(sp, sp, Imm8(4));
-    aasm->as_orr(sp, sp, Imm8(4));
-#endif
-
     // Subtract off the size of the arguments from the stack pointer, store elsewhere
     aasm->as_sub(r4, sp, O2RegImmShift(r1, LSL, 3)); //r4 = sp - argc*8
     // Get the final position of the stack pointer into the stack pointer
     aasm->as_sub(sp, r4, Imm8(16)); // sp' = sp - argc*8 - 16
     // Get a copy of the number of args to use as a decrement counter, also
     // Set the zero condition code
     aasm->as_mov(r5, O2Reg(r1), SetCond);
 
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -298,16 +298,17 @@ ArrayBufferObject::class_constructor(JSC
  * with the cx if available and fall back to the runtime.  If oldptr is given,
  * it's expected to be a previously-allocated ObjectElements* pointer that we
  * then realloc.
  */
 static ObjectElements *
 AllocateArrayBufferContents(JSContext *maybecx, uint32_t nbytes, void *oldptr = nullptr)
 {
     uint32_t size = nbytes + sizeof(ObjectElements);
+    JS_ASSERT(size > nbytes); // be wary of rollover
     ObjectElements *newheader;
 
     // if oldptr is given, then we need to do a realloc
     if (oldptr) {
         ObjectElements *oldheader = static_cast<ObjectElements *>(oldptr);
         uint32_t oldnbytes = ArrayBufferObject::headerInitializedLength(oldheader);
 
         void *p = maybecx ? maybecx->runtime()->reallocCanGC(oldptr, size) : js_realloc(oldptr, size);
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -297,17 +297,24 @@ PostBarrierTypedArrayObject(JSObject *ob
 inline void
 InitArrayBufferViewDataPointer(ArrayBufferViewObject *obj, ArrayBufferObject *buffer, size_t byteOffset)
 {
     /*
      * N.B. The base of the array's data is stored in the object's
      * private data rather than a slot to avoid alignment restrictions
      * on private Values.
      */
-    obj->initPrivate(buffer->dataPointer() + byteOffset);
+
+    if (buffer->isNeutered()) {
+        JS_ASSERT(byteOffset == 0);
+        obj->initPrivate(nullptr);
+    } else {
+        obj->initPrivate(buffer->dataPointer() + byteOffset);
+    }
+
     PostBarrierTypedArrayObject(obj);
 }
 
 /*
  * Tests for either ArrayBufferObject or SharedArrayBufferObject.
  * For specific class testing, use e.g., obj->is<ArrayBufferObject>().
  */
 bool IsArrayBuffer(HandleValue v);
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -357,17 +357,17 @@ class TypedArrayObjectTemplate : public 
         if (!empty)
             return nullptr;
         obj->setLastPropertyInfallible(empty);
 
 #ifdef DEBUG
         uint32_t bufferByteLength = buffer->byteLength();
         uint32_t arrayByteLength = obj->byteLength();
         uint32_t arrayByteOffset = obj->byteOffset();
-        JS_ASSERT(buffer->dataPointer() <= obj->viewData());
+        JS_ASSERT_IF(!buffer->isNeutered(), buffer->dataPointer() <= obj->viewData());
         JS_ASSERT(bufferByteLength - arrayByteOffset >= arrayByteLength);
         JS_ASSERT(arrayByteOffset <= bufferByteLength);
 
         // Verify that the private slot is at the expected place
         JS_ASSERT(obj->numFixedSlots() == DATA_SLOT);
 #endif
 
         buffer->addView(obj);
--- a/toolkit/components/passwordmgr/test/test_privbrowsing_perwindowpb.html
+++ b/toolkit/components/passwordmgr/test/test_privbrowsing_perwindowpb.html
@@ -19,16 +19,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 /** Test for Bug 248970 **/
 // based on test_notifications.html
 
 const Ci = SpecialPowers.Ci;
 const Cc = SpecialPowers.Cc;
 const Cr = SpecialPowers.Cr;
 
+Components.utils.import("resource://gre/modules/Services.jsm");
+
 var testpath = "/tests/toolkit/components/passwordmgr/test/";
 var prefix = "http://test2.example.com" + testpath;
 var subtests = [
                    "subtst_privbrowsing_1.html", // 1
                    "subtst_privbrowsing_1.html", // 2
                    "subtst_privbrowsing_1.html", // 3
                    "subtst_privbrowsing_2.html", // 4
                    "subtst_privbrowsing_2.html", // 5
@@ -186,34 +188,45 @@ var mainWindow = window.QueryInterface(C
                     .getInterface(Ci.nsIWebNavigation)
                     .QueryInterface(Ci.nsIDocShellTreeItem)
                     .rootTreeItem
                     .QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIDOMWindow);
 var contentPage = "http://mochi.test:8888/tests/toolkit/components/passwordmgr/test/privbrowsing_perwindowpb_iframe.html";
 var testWindows = [];
 
+function whenDelayedStartupFinished(aWindow, aCallback) {
+  Services.obs.addObserver(function observer(aSubject, aTopic) {
+    if (aWindow == aSubject) {
+      Services.obs.removeObserver(observer, aTopic);
+      setTimeout(aCallback, 0);
+    }
+  }, "browser-delayed-startup-finished", false);
+}
+
 function testOnWindow(aIsPrivate, aCallback) {
   var win = mainWindow.OpenBrowserWindow({private: aIsPrivate});
   win.addEventListener("load", function onLoad() {
     win.removeEventListener("load", onLoad, false);
-    win.addEventListener("DOMContentLoaded", function onInnerLoad() {
-      if (win.content.location.href != contentPage) {
-        win.gBrowser.loadURI(contentPage);
-        return;
-      }
-      win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
+    whenDelayedStartupFinished(win, function() {
+      win.addEventListener("DOMContentLoaded", function onInnerLoad() {
+        if (win.content.location.href != contentPage) {
+          win.gBrowser.loadURI(contentPage);
+          return;
+        }
+        win.removeEventListener("DOMContentLoaded", onInnerLoad, true);
 
-      win.content.addEventListener('load', function innerLoad2() {
-        win.content.removeEventListener('load', innerLoad2, false);
-        testWindows.push(win);
-        SimpleTest.executeSoon(function() { aCallback(win); });
-      }, false, true);
-    }, true);
-    SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); });
+        win.content.addEventListener('load', function innerLoad2() {
+          win.content.removeEventListener('load', innerLoad2, false);
+          testWindows.push(win);
+          SimpleTest.executeSoon(function() { aCallback(win); });
+        }, false, true);
+      }, true);
+      SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); });
+    });
   }, true);
 }
 
 var ignoreLoad = false;
 function handleLoad(aEvent) {
   // ignore every other load event ... We get one for loading the subtest (which
   // we want to ignore), and another when the subtest's form submits itself
   // (which we want to handle, to start the next test).
--- a/toolkit/content/tests/chrome/test_dialogfocus.xul
+++ b/toolkit/content/tests/chrome/test_dialogfocus.xul
@@ -19,64 +19,73 @@
 <pre id="test">
 </pre>
 </body>
 
 <script>
 <![CDATA[
 
 SimpleTest.waitForExplicitFinish();
+SimpleTest.requestCompleteLog();
 
 var expected = [ "one", "_extra2", "tab", "one", "tabbutton2", "tabbutton", "two", "textbox-yes", "one" ];
 // non-Mac will always focus the default button if any of the dialog buttons
 // would be focused
 if (navigator.platform.indexOf("Mac") == -1)
   expected[1] = "_accept";
 
 var step = 0;
 var fullKeyboardAccess = false;
 
 function startTest()
 {
   var testButton = document.getElementById("test");
   synthesizeKey("VK_TAB", { });
   fullKeyboardAccess = (document.activeElement == testButton);
+  info("We " + (fullKeyboardAccess ? "have" : "don't have") + " full keyboard access");
   runTest();
 }
 
 function runTest()
 {
   step++;
+  info("runTest(), step = " + step + ", expected = " + expected[step - 1]);
   if (step > expected.length || (!fullKeyboardAccess && step == 2)) {
+    info("finishing");
     SimpleTest.finish();
     return;
   }
 
   var expectedFocus = expected[step - 1];
   var win = window.openDialog("dialog_dialogfocus.xul", "_new", "chrome,dialog", step);
 
   function checkDialogFocus(event)
   {
+    info("checkDialogFocus()");
     // if full keyboard access is not on, just skip the tests
     var match = false;
     if (fullKeyboardAccess) {
-      if (!(event.target instanceof Element))
+      if (!(event.target instanceof Element)) {
+        info("target not an Element");
         return;
+      }
 
       if (expectedFocus == "textbox-yes")
         match = (win.document.activeElement == win.document.getElementById(expectedFocus).inputField);
       else if (expectedFocus[0] == "_")
         match = (win.document.activeElement.dlgType == expectedFocus.substring(1));
       else
         match = (win.document.activeElement.id == expectedFocus);
+      info("match = " + match);
       if (!match)
         return;
     }
     else {
       match = (win.document.activeElement == win.document.documentElement);
+      info("match = " + match);
     }
 
     win.removeEventListener("focus", checkDialogFocus, true);
     ok(match, "focus step " + step);
 
     win.close();
     SimpleTest.waitForFocus(runTest, window);
   }