Merge m-c to b2g-inbound
authorWes Kocher <wkocher@mozilla.com>
Wed, 09 Oct 2013 20:48:56 -0700
changeset 164119 4275b265451268af7f64845a8a58e881bcbad3e4
parent 164118 1e6cb8ed2c776cf10de4d0585ab495d92152c4cc (current diff)
parent 164087 aa986b6ce882b4d2fcd6e4d857cb619cffe480ea (diff)
child 164120 863ebb578c978d8f4aa7768588beac6d6fd6c309
child 164145 4290f5bc73b4298980939b0a69aebceca3c021c3
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.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 b2g-inbound
CLOBBER
config/mozLock.pm
--- a/CLOBBER
+++ b/CLOBBER
@@ -13,9 +13,9 @@
 #          |               |
 #          O <-- Clobber   O  <-- Clobber
 #
 # Note: The description below will be part of the error message shown to users.
 #
 # Modifying this file will now automatically clobber the buildbot machines \o/
 #
 
-Bug 915002 needs clobber on windows.
+Bug 899574 needed a clobber, at least on Windows.
--- a/build/clang-plugin/Makefile.in
+++ b/build/clang-plugin/Makefile.in
@@ -36,16 +36,16 @@ all: $(PLUGIN) $(TESTS)
 
 TESTFLAGS := -fsyntax-only -Xclang -verify \
 	-Xclang -load -Xclang $(CURDIR)/$(PLUGIN) \
 	-Xclang -add-plugin -Xclang moz-check
 
 $(TESTS): test-%: tests/%.cpp $(PLUGIN)
 	$(CXX) $(TESTFLAGS) $<
 
-compile libs export tools: all
+compile binaries libs export tools: all
 
 distclean clean:
 	rm -f $(OBJS) $(TESTS) $(PLUGIN)
 
 check:
 
-.PHONY: compile libs export tools distclean clean check
+.PHONY: compile binaries libs export tools distclean clean check
deleted file mode 100644
--- a/config/mozLock.pm
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mozLock;
-
-use strict;
-use IO::File;
-use Cwd;
-
-BEGIN {
-    use Exporter ();
-    use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
-
-    $VERSION = 1.00;
-    @ISA = qw(Exporter);
-    @EXPORT = qw(&mozLock &mozUnlock);
-    %EXPORT_TAGS = ( );
-    @EXPORT_OK = qw();
-}
-
-my $lockcounter = 0;
-my $locklimit = 100;
-my $locksleep = 0.1;
-my %lockhash;
-
-# File::Spec->rel2abs appears to be broken in ActiveState Perl 5.22
-# so roll our own
-sub priv_abspath($) {
-    my ($file) = @_;
-    my ($dir, $out);
-    my (@inlist, @outlist);
-
-    # Force files to have unix paths.
-    $file =~ s/\\/\//g;
-
-    # Check if file is already absolute
-    if ($file =~ m/^\// || substr($file, 1, 1) eq ':') {
-	return $file;
-    }
-    $out = cwd . "/$file";
-
-    # Do what File::Spec->canonpath should do
-    @inlist = split(/\//, $out);
-    foreach $dir (@inlist) {
-	if ($dir eq '..') {
-	    pop @outlist;
-	} else {
-	    push @outlist, $dir;
-	}
-    }
-    $out = join '/',@outlist;
-    return $out;
-}
-
-sub mozLock($) {
-    my ($inlockfile) = @_;
-    my ($lockhandle, $lockfile);
-    $lockfile = priv_abspath($inlockfile);
-    #print "LOCK: $lockfile\n";
-    $lockcounter = 0;
-    $lockhandle = new IO::File || die "Could not create filehandle for $lockfile: $!\n";    
-    while ($lockcounter < $locklimit) {
-	if (! -e $lockfile) {
-	    open($lockhandle, ">$lockfile") || die "$lockfile: $!\n";
-	    $lockhash{$lockfile} = $lockhandle;
-	    last;
-	}
-	$lockcounter++;
-	select(undef,undef,undef, $locksleep);
-    }
-    if ($lockcounter >= $locklimit) {
-	undef $lockhandle;
-	die "$0: Could not get lockfile $lockfile.\nRemove $lockfile to clear up\n";
-    }
-}
-
-sub mozUnlock($) {
-    my ($inlockfile) = @_;
-    my ($lockhandle, $lockfile);
-    #$lockfile = File::Spec->rel2abs($inlockfile);
-    $lockfile = priv_abspath($inlockfile);
-    #print "UNLOCK: $lockfile\n";
-    $lockhandle = $lockhash{$lockfile};
-    if (defined($lockhandle)) {
-	close($lockhandle);
-	$lockhash{$lockfile} = undef;
-	unlink($lockfile);
-    } else {
-	print "WARNING: $0: lockhandle for $lockfile not defined.  Lock may not be removed.\n";
-    }
-}
-
-END {};
-
-1;
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -22,16 +22,18 @@
 #include "nsINode.h"                     // for base class
 #include "nsIScriptGlobalObject.h"       // for member (in nsCOMPtr)
 #include "nsIStructuredCloneContainer.h" // for member (in nsCOMPtr)
 #include "nsPIDOMWindow.h"               // for use in inline functions
 #include "nsPropertyTable.h"             // for member
 #include "nsTHashtable.h"                // for member
 #include "mozilla/dom/DocumentBinding.h"
 #include "Units.h"
+#include "nsExpirationTracker.h"
+#include "nsClassHashtable.h"
 
 class imgIRequest;
 class nsAString;
 class nsBindingManager;
 class nsCSSStyleSheet;
 class nsDOMNavigationTiming;
 class nsDOMTouchList;
 class nsEventStates;
@@ -75,16 +77,17 @@ class nsSMILAnimationController;
 class nsStyleSet;
 class nsTextNode;
 class nsWindowSizes;
 class nsSmallVoidArray;
 class nsDOMCaretPosition;
 class nsViewportInfo;
 class nsDOMEvent;
 class nsIGlobalObject;
+class nsCSSSelectorList;
 
 namespace mozilla {
 class ErrorResult;
 
 namespace css {
 class Loader;
 class ImageLoader;
 } // namespace css
@@ -655,17 +658,71 @@ public:
 
   bool DidDocumentOpen() {
     return mDidDocumentOpen;
   }
 
 protected:
   virtual Element *GetRootElementInternal() const = 0;
 
+private:
+  class SelectorCacheKey
+  {
+    public:
+      SelectorCacheKey(const nsAString& aString) : mKey(aString)
+      {
+        MOZ_COUNT_CTOR(SelectorCacheKey);
+      }
+
+      nsString mKey;
+      nsExpirationState mState;
+
+      nsExpirationState* GetExpirationState() { return &mState; }
+
+      ~SelectorCacheKey()
+      {
+        MOZ_COUNT_DTOR(SelectorCacheKey);
+      }
+  };
+
+  class SelectorCacheKeyDeleter;
+
 public:
+  class SelectorCache MOZ_FINAL
+    : public nsExpirationTracker<SelectorCacheKey, 4>
+  {
+    public:
+      SelectorCache();
+
+      // CacheList takes ownership of aSelectorList.
+      void CacheList(const nsAString& aSelector, nsCSSSelectorList* aSelectorList);
+
+      virtual void NotifyExpired(SelectorCacheKey* aSelector) MOZ_OVERRIDE;
+
+      // We do not call MarkUsed because it would just slow down lookups and
+      // because we're OK expiring things after a few seconds even if they're
+      // being used.
+      nsCSSSelectorList* GetList(const nsAString& aSelector)
+      {
+        return mTable.Get(aSelector);
+      }
+
+      ~SelectorCache()
+      {
+        AgeAllGenerations();
+      }
+
+    private:
+      nsClassHashtable<nsStringHashKey, nsCSSSelectorList> mTable;
+  };
+
+  SelectorCache& GetSelectorCache()
+  {
+    return mSelectorCache;
+  }
   // Get the root <html> element, or return null if there isn't one (e.g.
   // if the root isn't <html>)
   Element* GetHtmlElement() const;
   // Returns the first child of GetHtmlContent which has the given tag,
   // or nullptr if that doesn't exist.
   Element* GetHtmlChildElement(nsIAtom* aTag);
   // Get the canonical <body> element, or return null if there isn't one (e.g.
   // if the root isn't <html> or if the <body> isn't there)
@@ -2128,16 +2185,17 @@ public:
 
   virtual nsHTMLDocument* AsHTMLDocument() { return nullptr; }
 
   virtual JSObject* WrapObject(JSContext *aCx,
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 private:
   uint64_t mWarnedAbout;
+  SelectorCache mSelectorCache;
 
 protected:
   ~nsIDocument();
   nsPropertyTable* GetExtraPropertyTable(uint16_t aCategory);
 
   // Never ever call this. Only call GetWindow!
   virtual nsPIDOMWindow *GetWindowInternal() const = 0;
 
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -158,17 +158,20 @@ nsDOMFileBase::GetMozFullPath(nsAString 
   }
   aFileName.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileBase::GetMozFullPathInternal(nsAString &aFileName)
 {
-  NS_ASSERTION(mIsFile, "Should only be called on files");
+  if (!mIsFile) {
+    return NS_ERROR_FAILURE;
+  }
+
   aFileName.Truncate();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMFileBase::GetSize(uint64_t *aSize)
 {
   *aSize = mLength;
--- a/content/base/src/nsDOMMutationObserver.cpp
+++ b/content/base/src/nsDOMMutationObserver.cpp
@@ -521,21 +521,21 @@ void
 nsDOMMutationObserver::TakeRecords(
                          nsTArray<nsRefPtr<nsDOMMutationRecord> >& aRetVal)
 {
   aRetVal.Clear();
   mPendingMutations.SwapElements(aRetVal);
 }
 
 void
-nsDOMMutationObserver::GetObservingInfo(nsTArray<Nullable<MutationObservingInfoInitializer> >& aResult)
+nsDOMMutationObserver::GetObservingInfo(nsTArray<Nullable<MutationObservingInfo> >& aResult)
 {
   aResult.SetCapacity(mReceivers.Count());
   for (int32_t i = 0; i < mReceivers.Count(); ++i) {
-    MutationObservingInfoInitializer& info = aResult.AppendElement()->SetValue();
+    MutationObservingInfo& info = aResult.AppendElement()->SetValue();
     nsMutationReceiver* mr = mReceivers[i];
     info.mChildList = mr->ChildList();
     info.mAttributes = mr->Attributes();
     info.mCharacterData = mr->CharacterData();
     info.mSubtree = mr->Subtree();
     info.mAttributeOldValue = mr->AttributeOldValue();
     info.mCharacterDataOldValue = mr->CharacterDataOldValue();
     nsCOMArray<nsIAtom>& filters = mr->AttributeFilter();
--- a/content/base/src/nsDOMMutationObserver.h
+++ b/content/base/src/nsDOMMutationObserver.h
@@ -21,17 +21,17 @@
 #include "nsClassHashtable.h"
 #include "nsNodeUtils.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsWrapperCache.h"
 #include "mozilla/dom/MutationObserverBinding.h"
 #include "nsIDocument.h"
 
 class nsDOMMutationObserver;
-using mozilla::dom::MutationObservingInfoInitializer;
+using mozilla::dom::MutationObservingInfo;
 
 class nsDOMMutationRecord : public nsISupports,
                             public nsWrapperCache
 {
 public:
   nsDOMMutationRecord(const nsAString& aType, nsISupports* aOwner)
   : mType(aType), mOwner(aOwner)
   {
@@ -374,17 +374,17 @@ public:
                mozilla::ErrorResult& aRv);
 
   void Disconnect();
 
   void TakeRecords(nsTArray<nsRefPtr<nsDOMMutationRecord> >& aRetVal);
 
   void HandleMutation();
 
-  void GetObservingInfo(nsTArray<Nullable<MutationObservingInfoInitializer> >& aResult);
+  void GetObservingInfo(nsTArray<Nullable<MutationObservingInfo> >& aResult);
 
   mozilla::dom::MutationCallback* MutationCallback() { return mCallback; }
 
   // static methods
   static void HandleMutations()
   {
     if (sScheduledMutationObservers) {
       HandleMutationsInternal();
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1310,16 +1310,59 @@ nsDOMStyleSheetSetList::GetSets(nsTArray
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   return NS_OK;
 }
 
 // ==================================================================
+nsIDocument::SelectorCache::SelectorCache()
+  : nsExpirationTracker<SelectorCacheKey, 4>(1000) { }
+
+// CacheList takes ownership of aSelectorList.
+void nsIDocument::SelectorCache::CacheList(const nsAString& aSelector,
+                                           nsCSSSelectorList* aSelectorList)
+{
+  SelectorCacheKey* key = new SelectorCacheKey(aSelector);
+  mTable.Put(key->mKey, aSelectorList);
+  AddObject(key);
+}
+
+class nsIDocument::SelectorCacheKeyDeleter MOZ_FINAL : public nsRunnable
+{
+public:
+  explicit SelectorCacheKeyDeleter(SelectorCacheKey* aToDelete)
+    : mSelector(aToDelete)
+  {
+    MOZ_COUNT_CTOR(SelectorCacheKeyDeleter);
+  }
+
+  ~SelectorCacheKeyDeleter()
+  {
+    MOZ_COUNT_DTOR(SelectorCacheKeyDeleter);
+  }
+
+  NS_IMETHOD Run()
+  {
+    return NS_OK;
+  }
+
+private:
+  nsAutoPtr<SelectorCacheKey> mSelector;
+};
+
+void nsIDocument::SelectorCache::NotifyExpired(SelectorCacheKey* aSelector)
+{
+  RemoveObject(aSelector);
+  mTable.Remove(aSelector->mKey);
+  nsCOMPtr<nsIRunnable> runnable = new SelectorCacheKeyDeleter(aSelector);
+  NS_DispatchToCurrentThread(runnable);
+}
+
 
 struct nsIDocument::FrameRequest
 {
   FrameRequest(const FrameRequestCallbackHolder& aCallback,
                int32_t aHandle) :
     mCallback(aCallback),
     mHandle(aHandle)
   {}
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -2332,31 +2332,40 @@ AddScopeElements(TreeMatchContext& aMatc
 
 // Actually find elements matching aSelectorList (which must not be
 // null) and which are descendants of aRoot and put them in aList.  If
 // onlyFirstMatch, then stop once the first one is found.
 template<bool onlyFirstMatch, class T>
 inline static nsresult
 FindMatchingElements(nsINode* aRoot, const nsAString& aSelector, T &aList)
 {
-  nsAutoPtr<nsCSSSelectorList> selectorList;
-  nsresult rv = ParseSelectorList(aRoot, aSelector,
-                                  getter_Transfers(selectorList));
-  if (NS_FAILED(rv)) {
-    // We hit this for syntax errors, which are quite common, so don't
-    // use NS_ENSURE_SUCCESS.  (For example, jQuery has an extended set
-    // of selectors, but it sees if we can parse them first.)
-    return rv;
+
+  nsIDocument* doc = aRoot->OwnerDoc();
+  nsIDocument::SelectorCache& cache = doc->GetSelectorCache();
+  nsCSSSelectorList* selectorList = cache.GetList(aSelector);
+
+  if (!selectorList) {
+    nsresult rv = ParseSelectorList(aRoot, aSelector,
+                                    &selectorList);
+    if (NS_FAILED(rv)) {
+      delete selectorList;
+      // We hit this for syntax errors, which are quite common, so don't
+      // use NS_ENSURE_SUCCESS.  (For example, jQuery has an extended set
+      // of selectors, but it sees if we can parse them first.)
+      return rv;
+    }
+
+    NS_ENSURE_TRUE(selectorList, NS_OK);
+
+    cache.CacheList(aSelector, selectorList);
   }
-  NS_ENSURE_TRUE(selectorList, NS_OK);
 
   NS_ASSERTION(selectorList->mSelectors,
                "How can we not have any selectors?");
 
-  nsIDocument* doc = aRoot->OwnerDoc();
   TreeMatchContext matchingContext(false, nsRuleWalker::eRelevantLinkUnvisited,
                                    doc, TreeMatchContext::eNeverMatchVisited);
   doc->FlushPendingLinkUpdates();
   AddScopeElements(matchingContext, aRoot);
 
   // Fast-path selectors involving IDs.  We can only do this if aRoot
   // is in the document and the document is not in quirks mode, since
   // ID selectors are case-insensitive in quirks mode.  Also, only do
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -906,17 +906,17 @@ WebGLContext::GetCanvasLayer(nsDisplayLi
     canvasLayer->Updated();
 
     mResetLayer = false;
 
     return canvasLayer.forget();
 }
 
 void
-WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributesInitializer> &retval)
+WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributes> &retval)
 {
     retval.SetNull();
     if (IsContextLost())
         return;
 
     dom::WebGLContextAttributes& result = retval.SetValue();
 
     const PixelBufferFormat& format = gl->GetPixelFormat();
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -71,17 +71,16 @@ class WebGLRenderbuffer;
 class WebGLShaderPrecisionFormat;
 class WebGLTexture;
 class WebGLVertexArray;
 
 namespace dom {
 class ImageData;
 
 struct WebGLContextAttributes;
-struct WebGLContextAttributesInitializer;
 template<typename> struct Nullable;
 }
 
 namespace gfx {
 class SourceSurface;
 }
 
 using WebGLTexelConversions::WebGLTexelFormat;
@@ -253,17 +252,17 @@ public:
     void SetupContextLossTimer();
     void TerminateContextLossTimer();
 
     // WebIDL WebGLRenderingContext API
     dom::HTMLCanvasElement* GetCanvas() const { return mCanvasElement; }
     GLsizei DrawingBufferWidth() const { return IsContextLost() ? 0 : mWidth; }
     GLsizei DrawingBufferHeight() const { return IsContextLost() ? 0 : mHeight; }
 
-    void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributesInitializer>& retval);
+    void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
     bool IsContextLost() const { return mContextStatus != ContextNotLost; }
     void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval);
     JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv);
     void ActiveTexture(GLenum texture);
     void AttachShader(WebGLProgram* program, WebGLShader* shader);
     void BindAttribLocation(WebGLProgram* program, GLuint location,
                             const nsAString& name);
     void BindFramebuffer(GLenum target, WebGLFramebuffer* wfb);
--- a/content/canvas/src/WebGLProgram.cpp
+++ b/content/canvas/src/WebGLProgram.cpp
@@ -229,20 +229,15 @@ WebGLProgram::GetUniformInfoForMappedIde
     // if there is a bracket, we're either an array or an entry in an array.
     if (hadBracketPart)
         mutableName.AppendLiteral("[0]");
 
     WebGLUniformInfo info;
     mUniformInfoMap->Get(mutableName, &info);
     // we don't check if that Get failed, as if it did, it left info with default values
 
-    // if there is a bracket and it's not [0], then we're not an array, we're just an entry in an array
-    if (hadBracketPart && !bracketPart.EqualsLiteral("[0]")) {
-        info.isArray = false;
-        info.arraySize = 1;
-    }
     return info;
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(WebGLProgram, mAttachedShaders)
 
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLProgram, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLProgram, Release)
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -264,29 +264,81 @@ struct DeltaValues
     deltaX(aEvent->deltaX), deltaY(aEvent->deltaY)
   {
   }
 
   double deltaX;
   double deltaY;
 };
 
+/******************************************************************/
+/* nsScrollbarsForWheel                                           */
+/******************************************************************/
+
+class nsScrollbarsForWheel {
+public:
+  static void PrepareToScrollText(nsEventStateManager* aESM,
+                                  nsIFrame* aTargetFrame,
+                                  WheelEvent* aEvent);
+  static void SetActiveScrollTarget(nsIScrollableFrame* aScrollTarget);
+  // Hide all scrollbars (both mActiveOwner's and mActivatedScrollTargets')
+  static void MayInactivate();
+  static void Inactivate();
+  static bool IsActive();
+  static void OwnWheelTransaction(bool aOwn);
+
+protected:
+  static const size_t         kNumberOfTargets = 4;
+  static const DeltaValues    directions[kNumberOfTargets];
+  static nsWeakFrame          sActiveOwner;
+  static nsWeakFrame          sActivatedScrollTargets[kNumberOfTargets];
+  static bool                 sHadWheelStart;
+  static bool                 sOwnWheelTransaction;
+
+
+  /**
+   * These two methods are called upon NS_WHEEL_START/NS_WHEEL_STOP events
+   * to show/hide the right scrollbars.
+   */
+  static void TemporarilyActivateAllPossibleScrollTargets(
+                                  nsEventStateManager* aESM,
+                                  nsIFrame* aTargetFrame,
+                                  WheelEvent* aEvent);
+  static void DeactivateAllTemporarilyActivatedScrollTargets();
+};
+
+const DeltaValues nsScrollbarsForWheel::directions[kNumberOfTargets] = {
+  DeltaValues(-1, 0), DeltaValues(+1, 0), DeltaValues(0, -1), DeltaValues(0, +1)
+};
+nsWeakFrame nsScrollbarsForWheel::sActiveOwner = nullptr;
+nsWeakFrame nsScrollbarsForWheel::sActivatedScrollTargets[kNumberOfTargets] = {
+  nullptr, nullptr, nullptr, nullptr
+};
+bool nsScrollbarsForWheel::sHadWheelStart = false;
+bool nsScrollbarsForWheel::sOwnWheelTransaction = false;
+
+/******************************************************************/
+/* nsMouseWheelTransaction                                        */
+/******************************************************************/
+
 class nsMouseWheelTransaction {
 public:
   static nsIFrame* GetTargetFrame() { return sTargetFrame; }
   static void BeginTransaction(nsIFrame* aTargetFrame,
                                WheelEvent* aEvent);
   // Be careful, UpdateTransaction may fire a DOM event, therefore, the target
   // frame might be destroyed in the event handler.
   static bool UpdateTransaction(WheelEvent* aEvent);
+  static void MayEndTransaction();
   static void EndTransaction();
   static void OnEvent(WidgetEvent* aEvent);
   static void Shutdown();
   static uint32_t GetTimeoutTime();
 
+  static void OwnScrollbars(bool aOwn);
 
   static DeltaValues AccelerateWheelDelta(WheelEvent* aEvent,
                                           bool aAllowScrollSpeedOverride);
 
   enum {
     kScrollSeriesTimeout = 80
   };
 protected:
@@ -294,66 +346,78 @@ protected:
   static void OnFailToScrollTarget();
   static void OnTimeout(nsITimer *aTimer, void *aClosure);
   static void SetTimeout();
   static uint32_t GetIgnoreMoveDelayTime();
   static int32_t GetAccelerationStart();
   static int32_t GetAccelerationFactor();
   static DeltaValues OverrideSystemScrollSpeed(WheelEvent* aEvent);
   static double ComputeAcceleratedWheelDelta(double aDelta, int32_t aFactor);
+  static bool OutOfTime(uint32_t aBaseTime, uint32_t aThreshold);
 
   static nsWeakFrame sTargetFrame;
   static uint32_t    sTime;        // in milliseconds
   static uint32_t    sMouseMoved;  // in milliseconds
   static nsITimer*   sTimer;
   static int32_t     sScrollSeriesCounter;
+  static bool        sOwnScrollbars;
 };
 
 nsWeakFrame nsMouseWheelTransaction::sTargetFrame(nullptr);
 uint32_t    nsMouseWheelTransaction::sTime        = 0;
 uint32_t    nsMouseWheelTransaction::sMouseMoved  = 0;
 nsITimer*   nsMouseWheelTransaction::sTimer       = nullptr;
 int32_t     nsMouseWheelTransaction::sScrollSeriesCounter = 0;
-
-static bool
-OutOfTime(uint32_t aBaseTime, uint32_t aThreshold)
-{
-  uint32_t now = PR_IntervalToMilliseconds(PR_IntervalNow());
-  return (now - aBaseTime > aThreshold);
-}
+bool        nsMouseWheelTransaction::sOwnScrollbars = false;
 
 static bool
 CanScrollInRange(nscoord aMin, nscoord aValue, nscoord aMax, double aDirection)
 {
   return aDirection > 0.0 ? aValue < static_cast<double>(aMax) :
                             static_cast<double>(aMin) < aValue;
 }
 
 static bool
-CanScrollOn(nsIScrollableFrame* aScrollFrame, double aDeltaX, double aDeltaY)
+CanScrollOn(nsIScrollableFrame* aScrollFrame, double aDirectionX, double aDirectionY)
 {
   MOZ_ASSERT(aScrollFrame);
-  NS_ASSERTION(aDeltaX || aDeltaY,
+  NS_ASSERTION(aDirectionX || aDirectionY,
                "One of the delta values must be non-zero at least");
 
   nsPoint scrollPt = aScrollFrame->GetScrollPosition();
   nsRect scrollRange = aScrollFrame->GetScrollRange();
   uint32_t directions = aScrollFrame->GetPerceivedScrollingDirections();
 
-  return (aDeltaX && (directions & nsIScrollableFrame::HORIZONTAL) &&
-          CanScrollInRange(scrollRange.x, scrollPt.x, scrollRange.XMost(), aDeltaX)) ||
-         (aDeltaY && (directions & nsIScrollableFrame::VERTICAL) &&
-          CanScrollInRange(scrollRange.y, scrollPt.y, scrollRange.YMost(), aDeltaY));
+  return (aDirectionX && (directions & nsIScrollableFrame::HORIZONTAL) &&
+          CanScrollInRange(scrollRange.x, scrollPt.x, scrollRange.XMost(), aDirectionX)) ||
+         (aDirectionY && (directions & nsIScrollableFrame::VERTICAL) &&
+          CanScrollInRange(scrollRange.y, scrollPt.y, scrollRange.YMost(), aDirectionY));
+}
+
+bool
+nsMouseWheelTransaction::OutOfTime(uint32_t aBaseTime, uint32_t aThreshold)
+{
+  uint32_t now = PR_IntervalToMilliseconds(PR_IntervalNow());
+  return (now - aBaseTime > aThreshold);
+}
+
+void
+nsMouseWheelTransaction::OwnScrollbars(bool aOwn)
+{
+  sOwnScrollbars = aOwn;
 }
 
 void
 nsMouseWheelTransaction::BeginTransaction(nsIFrame* aTargetFrame,
                                           WheelEvent* aEvent)
 {
   NS_ASSERTION(!sTargetFrame, "previous transaction is not finished!");
+  MOZ_ASSERT(aEvent->message == NS_WHEEL_WHEEL,
+             "Transaction must be started with a wheel event");
+  nsScrollbarsForWheel::OwnWheelTransaction(false);
   sTargetFrame = aTargetFrame;
   sScrollSeriesCounter = 0;
   if (!UpdateTransaction(aEvent)) {
     NS_ERROR("BeginTransaction is called even cannot scroll the frame");
     EndTransaction();
   }
 }
 
@@ -381,22 +445,37 @@ nsMouseWheelTransaction::UpdateTransacti
   // 2. If the computer runs slowly by other processes eating the CPU resource,
   //    the event creation time doesn't keep real time.
   sTime = PR_IntervalToMilliseconds(PR_IntervalNow());
   sMouseMoved = 0;
   return true;
 }
 
 void
+nsMouseWheelTransaction::MayEndTransaction()
+{
+  if (!sOwnScrollbars && nsScrollbarsForWheel::IsActive()) {
+    nsScrollbarsForWheel::OwnWheelTransaction(true);
+  } else {
+    EndTransaction();
+  }
+}
+
+void
 nsMouseWheelTransaction::EndTransaction()
 {
   if (sTimer)
     sTimer->Cancel();
   sTargetFrame = nullptr;
   sScrollSeriesCounter = 0;
+  if (sOwnScrollbars) {
+    sOwnScrollbars = false;
+    nsScrollbarsForWheel::OwnWheelTransaction(false);
+    nsScrollbarsForWheel::Inactivate();
+  }
 }
 
 void
 nsMouseWheelTransaction::OnEvent(WidgetEvent* aEvent)
 {
   if (!sTargetFrame)
     return;
 
@@ -410,28 +489,28 @@ nsMouseWheelTransaction::OnEvent(WidgetE
   }
 
   switch (aEvent->message) {
     case NS_WHEEL_WHEEL:
       if (sMouseMoved != 0 &&
           OutOfTime(sMouseMoved, GetIgnoreMoveDelayTime())) {
         // Terminate the current mousewheel transaction if the mouse moved more
         // than ignoremovedelay milliseconds ago
-        EndTransaction();
+        MayEndTransaction();
       }
       return;
     case NS_MOUSE_MOVE:
     case NS_DRAGDROP_OVER:
       if (IsMouseEventReal(aEvent)) {
         // If the cursor is moving to be outside the frame,
         // terminate the scrollwheel transaction.
         nsIntPoint pt = GetScreenPoint(static_cast<WidgetGUIEvent*>(aEvent));
         nsIntRect r = sTargetFrame->GetScreenRectExternal();
         if (!r.Contains(pt)) {
-          EndTransaction();
+          MayEndTransaction();
           return;
         }
 
         // If the cursor is moving inside the frame, and it is less than
         // ignoremovedelay milliseconds since the last scroll operation, ignore
         // the mouse move; otherwise, record the current mouse move time to be
         // checked later
         if (OutOfTime(sTime, GetIgnoreMoveDelayTime())) {
@@ -470,33 +549,34 @@ nsMouseWheelTransaction::OnFailToScrollT
     nsContentUtils::DispatchTrustedEvent(
                       sTargetFrame->GetContent()->OwnerDoc(),
                       sTargetFrame->GetContent(),
                       NS_LITERAL_STRING("MozMouseScrollFailed"),
                       true, true);
   }
   // The target frame might be destroyed in the event handler, at that time,
   // we need to finish the current transaction
-  if (!sTargetFrame)
+  if (!sTargetFrame) {
     EndTransaction();
+  }
 }
 
 void
 nsMouseWheelTransaction::OnTimeout(nsITimer* aTimer, void* aClosure)
 {
   if (!sTargetFrame) {
     // The transaction target was destroyed already
     EndTransaction();
     return;
   }
   // Store the sTargetFrame, the variable becomes null in EndTransaction.
   nsIFrame* frame = sTargetFrame;
   // We need to finish current transaction before DOM event firing. Because
   // the next DOM event might create strange situation for us.
-  EndTransaction();
+  MayEndTransaction();
 
   if (Preferences::GetBool("test.mousescroll", false)) {
     // This event is used for automated tests, see bug 442774.
     nsContentUtils::DispatchTrustedEvent(
                       frame->GetContent()->OwnerDoc(),
                       frame->GetContent(),
                       NS_LITERAL_STRING("MozMouseScrollTransactionTimeout"),
                       true, true);
@@ -621,16 +701,137 @@ nsMouseWheelTransaction::OverrideSystemS
   nsresult rv =
     widget->OverrideSystemMouseScrollSpeed(aEvent->deltaX, aEvent->deltaY,
                                            overriddenDeltaValues.deltaX,
                                            overriddenDeltaValues.deltaY);
   return NS_FAILED(rv) ? DeltaValues(aEvent) : overriddenDeltaValues;
 }
 
 /******************************************************************/
+/* nsScrollbarsForWheel                                           */
+/******************************************************************/
+
+void
+nsScrollbarsForWheel::PrepareToScrollText(
+                                  nsEventStateManager* aESM,
+                                  nsIFrame* aTargetFrame,
+                                  WheelEvent* aEvent)
+{
+  if (aEvent->message == NS_WHEEL_START) {
+    nsMouseWheelTransaction::OwnScrollbars(false);
+    if (!IsActive()) {
+      TemporarilyActivateAllPossibleScrollTargets(aESM, aTargetFrame, aEvent);
+      sHadWheelStart = true;
+    }
+  } else {
+    DeactivateAllTemporarilyActivatedScrollTargets();
+  }
+}
+
+void
+nsScrollbarsForWheel::SetActiveScrollTarget(nsIScrollableFrame* aScrollTarget)
+{
+  if (!sHadWheelStart) {
+    return;
+  }
+  nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(aScrollTarget);
+  if (!scrollbarOwner) {
+    return;
+  }
+  sHadWheelStart = false;
+  sActiveOwner = do_QueryFrame(aScrollTarget);
+  scrollbarOwner->ScrollbarActivityStarted();
+}
+
+void
+nsScrollbarsForWheel::MayInactivate()
+{
+  if (!sOwnWheelTransaction && nsMouseWheelTransaction::GetTargetFrame()) {
+    nsMouseWheelTransaction::OwnScrollbars(true);
+  } else {
+    Inactivate();
+  }
+}
+
+void
+nsScrollbarsForWheel::Inactivate()
+{
+  nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sActiveOwner);
+  if (scrollbarOwner) {
+    scrollbarOwner->ScrollbarActivityStopped();
+  }
+  sActiveOwner = nullptr;
+  DeactivateAllTemporarilyActivatedScrollTargets();
+  if (sOwnWheelTransaction) {
+    sOwnWheelTransaction = false;
+    nsMouseWheelTransaction::OwnScrollbars(false);
+    nsMouseWheelTransaction::EndTransaction();
+  }
+}
+
+bool
+nsScrollbarsForWheel::IsActive()
+{
+  if (sActiveOwner) {
+    return true;
+  }
+  for (size_t i = 0; i < kNumberOfTargets; ++i) {
+    if (sActivatedScrollTargets[i]) {
+      return true;
+    }
+  }
+  return false;
+}
+
+void
+nsScrollbarsForWheel::OwnWheelTransaction(bool aOwn)
+{
+  sOwnWheelTransaction = aOwn;
+}
+
+void
+nsScrollbarsForWheel::TemporarilyActivateAllPossibleScrollTargets(
+                                               nsEventStateManager* aESM,
+                                               nsIFrame* aTargetFrame,
+                                               WheelEvent* aEvent)
+{
+  for (size_t i = 0; i < kNumberOfTargets; i++) {
+    const DeltaValues *dir = &directions[i];
+    nsWeakFrame* scrollTarget = &sActivatedScrollTargets[i];
+    MOZ_ASSERT(!*scrollTarget, "scroll target still temporarily activated!");
+    nsIScrollableFrame* target =
+      aESM->ComputeScrollTarget(aTargetFrame, dir->deltaX, dir->deltaY, aEvent, 
+                                nsEventStateManager::COMPUTE_DEFAULT_ACTION_TARGET);
+    if (target) {
+      nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(target);
+      if (scrollbarOwner) {
+        nsIFrame* targetFrame = do_QueryFrame(target);
+        *scrollTarget = targetFrame;
+        scrollbarOwner->ScrollbarActivityStarted();
+      }
+    }
+  }
+}
+
+void
+nsScrollbarsForWheel::DeactivateAllTemporarilyActivatedScrollTargets()
+{
+  for (size_t i = 0; i < kNumberOfTargets; i++) {
+    nsWeakFrame* scrollTarget = &sActivatedScrollTargets[i];
+    if (*scrollTarget) {
+      nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(*scrollTarget);
+      if (scrollbarOwner) {
+        scrollbarOwner->ScrollbarActivityStopped();
+      }
+      *scrollTarget = nullptr;
+    }
+  }
+}
+
+/******************************************************************/
 /* nsEventStateManager                                            */
 /******************************************************************/
 
 nsEventStateManager::nsEventStateManager()
   : mLockCursor(0),
     mPreLockPoint(0,0),
     mCurrentTarget(nullptr),
     mLastMouseOverFrame(nullptr),
@@ -972,23 +1173,30 @@ nsEventStateManager::PreHandleEvent(nsPr
   case NS_KEY_UP:
     {
       nsIContent* content = GetFocusedContent();
       if (content)
         mCurrentTargetContent = content;
     }
     break;
   case NS_WHEEL_WHEEL:
+  case NS_WHEEL_START:
+  case NS_WHEEL_STOP:
     {
       NS_ASSERTION(aEvent->mFlags.mIsTrusted,
                    "Untrusted wheel event shouldn't be here");
 
       nsIContent* content = GetFocusedContent();
-      if (content)
+      if (content) {
         mCurrentTargetContent = content;
+      }
+
+      if (aEvent->message != NS_WHEEL_WHEEL) {
+        break;
+      }
 
       WheelEvent* wheelEvent = static_cast<WheelEvent*>(aEvent);
       WheelPrefs::GetInstance()->ApplyUserPrefsToDelta(wheelEvent);
 
       // If we won't dispatch a DOM event for this event, nothing to do anymore.
       if (!wheelEvent->IsAllowedToDispatchDOMEvent()) {
         break;
       }
@@ -2541,16 +2749,30 @@ nsEventStateManager::SendPixelScrollEven
                               &event, nullptr, aStatus);
 }
 
 nsIScrollableFrame*
 nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
                                          WheelEvent* aEvent,
                                          ComputeScrollTargetOptions aOptions)
 {
+  return ComputeScrollTarget(aTargetFrame, aEvent->deltaX, aEvent->deltaY,
+                             aEvent, aOptions);
+}
+
+// Overload ComputeScrollTarget method to allow passing "test" dx and dy when looking
+// for which scrollbarowners to activate when two finger down on trackpad
+// and before any actual motion
+nsIScrollableFrame*
+nsEventStateManager::ComputeScrollTarget(nsIFrame* aTargetFrame,
+                                         double aDirectionX,
+                                         double aDirectionY,
+                                         WheelEvent* aEvent,
+                                         ComputeScrollTargetOptions aOptions)
+{
   if (aOptions & PREFER_MOUSE_WHEEL_TRANSACTION) {
     // If the user recently scrolled with the mousewheel, then they probably
     // want to scroll the same view as before instead of the view under the
     // cursor.  nsMouseWheelTransaction tracks the frame currently being
     // scrolled with the mousewheel. We consider the transaction ended when the
     // mouse moves more than "mousewheel.transaction.ignoremovedelay"
     // milliseconds after the last scroll operation, or any time the mouse moves
     // out of the frame, or when more than "mousewheel.transaction.timeout"
@@ -2564,24 +2786,24 @@ nsEventStateManager::ComputeScrollTarget
         return frameToScroll;
       }
     }
   }
 
   // If the event doesn't cause scroll actually, we cannot find scroll target
   // because we check if the event can cause scroll actually on each found
   // scrollable frame.
-  if (!aEvent->deltaX && !aEvent->deltaY) {
+  if (!aDirectionX && !aDirectionY) {
     return nullptr;
   }
 
   bool checkIfScrollableX =
-    aEvent->deltaX && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS);
+    aDirectionX && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS);
   bool checkIfScrollableY =
-    aEvent->deltaY && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS);
+    aDirectionY && (aOptions & PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS);
 
   nsIScrollableFrame* frameToScroll = nullptr;
   nsIFrame* scrollFrame =
     !(aOptions & START_FROM_PARENT) ? aTargetFrame :
                                       GetParentFrameToScroll(aTargetFrame);
   for (; scrollFrame; scrollFrame = GetParentFrameToScroll(scrollFrame)) {
     // Check whether the frame wants to provide us with a scrollable view.
     frameToScroll = scrollFrame->GetScrollTargetFrame();
@@ -2599,18 +2821,17 @@ nsEventStateManager::ComputeScrollTarget
     if ((hiddenForV && hiddenForH) ||
         (checkIfScrollableY && !checkIfScrollableX && hiddenForV) ||
         (checkIfScrollableX && !checkIfScrollableY && hiddenForH)) {
       continue;
     }
 
     // For default action, we should climb up the tree if cannot scroll it
     // by the event actually.
-    bool canScroll = CanScrollOn(frameToScroll,
-                                 aEvent->deltaX, aEvent->deltaY);
+    bool canScroll = CanScrollOn(frameToScroll, aDirectionX, aDirectionY);
     // Comboboxes need special care.
     nsIComboboxControlFrame* comboBox = do_QueryFrame(scrollFrame);
     if (comboBox) {
       if (comboBox->IsDroppedDown()) {
         // Don't propagate to parent when drop down menu is active.
         return canScroll ? frameToScroll : nullptr;
       }
       // Always propagate when not dropped down (even if focused).
@@ -3165,43 +3386,61 @@ nsEventStateManager::PostHandleEvent(nsP
 
       nsIPresShell *shell = presContext->GetPresShell();
       if (shell) {
         nsRefPtr<nsFrameSelection> frameSelection = shell->FrameSelection();
         frameSelection->SetMouseDownState(false);
       }
     }
     break;
+  case NS_WHEEL_STOP:
+    {
+      MOZ_ASSERT(aEvent->mFlags.mIsTrusted);
+      nsScrollbarsForWheel::MayInactivate();
+    }
+    break;
   case NS_WHEEL_WHEEL:
+  case NS_WHEEL_START:
     {
       MOZ_ASSERT(aEvent->mFlags.mIsTrusted);
 
       if (*aStatus == nsEventStatus_eConsumeNoDefault) {
+        nsScrollbarsForWheel::Inactivate();
         break;
       }
 
       WheelEvent* wheelEvent = static_cast<WheelEvent*>(aEvent);
       switch (WheelPrefs::GetInstance()->ComputeActionFor(wheelEvent)) {
         case WheelPrefs::ACTION_SCROLL: {
-          if (!wheelEvent->deltaX && !wheelEvent->deltaY) {
+          // For scrolling of default action, we should honor the mouse wheel
+          // transaction.
+          
+          nsScrollbarsForWheel::PrepareToScrollText(this, aTargetFrame, wheelEvent);
+          
+          if (aEvent->message != NS_WHEEL_WHEEL ||
+              (!wheelEvent->deltaX && !wheelEvent->deltaY)) {
             break;
           }
-          // For scrolling of default action, we should honor the mouse wheel
-          // transaction.
+
           nsIScrollableFrame* scrollTarget =
             ComputeScrollTarget(aTargetFrame, wheelEvent,
                                 COMPUTE_DEFAULT_ACTION_TARGET);
+
+          nsScrollbarsForWheel::SetActiveScrollTarget(scrollTarget);
+
           wheelEvent->overflowDeltaX = wheelEvent->deltaX;
           wheelEvent->overflowDeltaY = wheelEvent->deltaY;
+
           WheelPrefs::GetInstance()->
             CancelApplyingUserPrefsFromOverflowDelta(wheelEvent);
           if (scrollTarget) {
             DoScrollText(scrollTarget, wheelEvent);
           } else {
             nsMouseWheelTransaction::EndTransaction();
+            nsScrollbarsForWheel::Inactivate();
           }
           break;
         }
         case WheelPrefs::ACTION_HISTORY: {
           // If this event doesn't cause NS_MOUSE_SCROLL event or the direction
           // is oblique, don't perform history back/forward.
           int32_t intDelta = wheelEvent->GetPreferredIntDelta();
           if (!intDelta) {
--- a/content/events/src/nsEventStateManager.h
+++ b/content/events/src/nsEventStateManager.h
@@ -41,16 +41,17 @@ class TabParent;
 /*
  * Event listener manager
  */
 
 class nsEventStateManager : public nsSupportsWeakReference,
                             public nsIObserver
 {
   friend class nsMouseWheelTransaction;
+  friend class nsScrollbarsForWheel;
 public:
 
   typedef mozilla::TimeStamp TimeStamp;
   typedef mozilla::TimeDuration TimeDuration;
   typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
 
   nsEventStateManager();
   virtual ~nsEventStateManager();
@@ -552,16 +553,22 @@ protected:
       (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_X_AXIS | START_FROM_PARENT),
     COMPUTE_SCROLLABLE_ANCESTOR_ALONG_Y_AXIS     =
       (PREFER_ACTUAL_SCROLLABLE_TARGET_ALONG_Y_AXIS | START_FROM_PARENT)
   };
   nsIScrollableFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
                                           mozilla::WheelEvent* aEvent,
                                           ComputeScrollTargetOptions aOptions);
 
+  nsIScrollableFrame* ComputeScrollTarget(nsIFrame* aTargetFrame,
+                                          double aDirectionX,
+                                          double aDirectionY,
+                                          mozilla::WheelEvent* aEvent,
+                                          ComputeScrollTargetOptions aOptions);
+
   /**
    * GetScrollAmount() returns the scroll amount in app uints of one line or
    * one page.  If the wheel event scrolls a page, returns the page width and
    * height.  Otherwise, returns line height for both its width and height.
    *
    * @param aScrollableFrame    A frame which will be scrolled by the event.
    *                            The result of ComputeScrollTarget() is
    *                            expected for this value.
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -524,16 +524,22 @@ public:
   }
 
 private:
   nsRefPtr<HTMLInputElement> mInput;
   nsCOMPtr<nsIFile> mTopDir;
   nsTArray<nsCOMPtr<nsIDOMFile> > mFileList;
 };
 
+/**
+ * This may return nullptr if aDomFile's implementation of
+ * nsIDOMFile::mozFullPathInternal does not successfully return a non-empty
+ * string that is a valid path. This can happen on Firefox OS, for example,
+ * where the file picker can create Blobs.
+ */
 static already_AddRefed<nsIFile>
 DOMFileToLocalFile(nsIDOMFile* aDomFile)
 {
   nsString path;
   nsresult rv = aDomFile->GetMozFullPathInternal(path);
   if (NS_FAILED(rv) || path.IsEmpty()) {
     return nullptr;
   }
@@ -625,20 +631,22 @@ HTMLInputElement::nsFilePickerShownCallb
   }
 
   if (newFiles.IsEmpty()) {
     return NS_OK;
   }
 
   // Store the last used directory using the content pref service:
   nsCOMPtr<nsIFile> file = DOMFileToLocalFile(newFiles[0]);
-  nsCOMPtr<nsIFile> lastUsedDir;
-  file->GetParent(getter_AddRefs(lastUsedDir));
-  HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
-    mInput->OwnerDoc(), lastUsedDir);
+  if (file) {
+    nsCOMPtr<nsIFile> lastUsedDir;
+    file->GetParent(getter_AddRefs(lastUsedDir));
+    HTMLInputElement::gUploadLastDir->StoreLastUsedDirectory(
+      mInput->OwnerDoc(), lastUsedDir);
+  }
 
   // The text control frame (if there is one) isn't going to send a change
   // event because it will think this is done by a script.
   // So, we can safely send one by ourself.
   mInput->SetFiles(newFiles, true);
   return nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
                                               static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
                                               NS_LITERAL_STRING("change"), true,
--- a/content/html/content/test/mochitest.ini
+++ b/content/html/content/test/mochitest.ini
@@ -381,8 +381,9 @@ support-files =
 [test_srcdoc-2.html]
 [test_srcdoc.html]
 [test_style_attributes_reflection.html]
 [test_track.html]
 [test_track_disabled.html]
 [test_ul_attributes_reflection.html]
 [test_undoManager.html]
 [test_video_wakelock.html]
+[test_input_files_not_nsIFile.html]
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_input_files_not_nsIFile.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for &lt;input type='file'&gt; handling when its "files" do not implement nsIFile</title>
+  <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>
+
+<div id="content">
+  <input id='a' type='file'>
+</div>
+<button id='b' onclick="document.getElementById('a').click();">Show Filepicker</button>
+
+<input type="file" id="file" />
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+var MockFilePicker = SpecialPowers.MockFilePicker;
+MockFilePicker.init(window);
+
+SimpleTest.waitForFocus(function() {
+  MockFilePicker.useBlobFile();
+  MockFilePicker.returnValue = MockFilePicker.returnOK;
+
+  var b = document.getElementById('b');
+  b.focus(); // Be sure the element is visible.
+
+  document.getElementById('a').addEventListener("change", function(aEvent) {
+    ok(true, "change event correctly sent");
+
+    SimpleTest.executeSoon(function() {
+      MockFilePicker.cleanup();
+      SimpleTest.finish();
+    });
+  }, false);
+
+  b.click();
+});
+
+</script>
+</pre>
+</body>
+</html>
+
--- a/content/media/MediaRecorder.cpp
+++ b/content/media/MediaRecorder.cpp
@@ -487,17 +487,17 @@ MediaRecorder::CreateAndDispatchBlobEven
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
 
   if (!CheckPrincipal()) {
     // Media is not same-origin, don't allow the data out.
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
-  BlobEventInitInitializer init;
+  BlobEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
   init.mData = aSession->GetEncodedData();
   nsRefPtr<BlobEvent> event =
     BlobEvent::Constructor(this,
                            NS_LITERAL_STRING("dataavailable"),
                            init);
   event->SetTrusted(true);
--- a/content/media/TextTrackList.cpp
+++ b/content/media/TextTrackList.cpp
@@ -115,17 +115,17 @@ TextTrackList::DispatchTrackEvent(TrackE
 {
   return DispatchTrustedEvent(aEvent);
 }
 
 void
 TextTrackList::CreateAndDispatchTrackEventRunner(TextTrack* aTrack,
                                                  const nsAString& aEventName)
 {
-  TrackEventInitInitializer eventInit;
+  TrackEventInit eventInit;
   eventInit.mBubbles = false;
   eventInit.mCancelable = false;
   eventInit.mTrack = aTrack;
   nsRefPtr<TrackEvent> trackEvent =
     TrackEvent::Constructor(this, aEventName, eventInit);
 
   // Dispatch the TrackEvent asynchronously.
   nsCOMPtr<nsIRunnable> event = new TrackEventRunner(this, trackEvent);
--- a/content/media/webspeech/recognition/SpeechRecognition.cpp
+++ b/content/media/webspeech/recognition/SpeechRecognition.cpp
@@ -708,17 +708,17 @@ SpeechRecognition::Start(ErrorResult& aR
   nsresult rv;
   mRecognitionService = do_GetService(speechRecognitionServiceCID.get(), &rv);
   NS_ENSURE_SUCCESS_VOID(rv);
 
   rv = mRecognitionService->Initialize(this->asWeakPtr());
   NS_ENSURE_SUCCESS_VOID(rv);
 
   AutoSafeJSContext cx;
-  MediaStreamConstraintsInitializer constraints;
+  MediaStreamConstraints constraints;
   constraints.mAudio.SetAsBoolean() = true;
 
   if (!mTestConfig.mFakeFSMEvents) {
     MediaManager* manager = MediaManager::Get();
     manager->GetUserMedia(cx,
                           false,
                           GetOwner(),
                           constraints,
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -4994,17 +4994,17 @@ nsGlobalWindow::DispatchResizeEvent(cons
   nsRefPtr<nsDOMEvent> domEvent =
     mDoc->CreateEvent(NS_LITERAL_STRING("CustomEvent"), res);
   if (res.Failed()) {
     return false;
   }
 
   AutoSafeJSContext cx;
   JSAutoCompartment ac(cx, mJSObject);
-  DOMWindowResizeEventDetailInitializer detail;
+  DOMWindowResizeEventDetail detail;
   detail.mWidth = aSize.width;
   detail.mHeight = aSize.height;
   JS::Rooted<JS::Value> detailValue(cx);
   if (!detail.ToObject(cx, JS::NullPtr(), &detailValue)) {
     return false;
   }
 
   CustomEvent* customEvent = static_cast<CustomEvent*>(domEvent.get());
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3539,19 +3539,23 @@ for (uint32_t i = 0; i < length; ++i) {
     if type.isDictionary():
         # There are no nullable dictionaries
         assert not type.nullable()
         # All optional dictionaries always have default values, so we
         # should be able to assume not isOptional here.
         assert not isOptional
 
         typeName = CGDictionary.makeDictionaryName(type.inner)
-        actualTypeName = typeName
-
-        declType = CGGeneric(actualTypeName)
+        if not isMember:
+            # Since we're not a member and not nullable or optional, no one will
+            # see our real type, so we can do the fast version of the dictionary
+            # that doesn't pre-initialize members.
+            typeName = "dictionary_detail::Fast" + typeName
+
+        declType = CGGeneric(typeName)
 
         # We do manual default value handling here, because we
         # actually do want a jsval, and we only handle null anyway
         # NOTE: if isNullOrUndefined or isDefinitelyObject are true,
         # we know we have a value, so we don't have to worry about the
         # default value.
         if (not isNullOrUndefined and not isDefinitelyObject and
             defaultValue is not None):
@@ -4419,18 +4423,17 @@ def getRetvalDeclarationForType(returnTy
         else:
             rooter = None
         result = CGTemplatedType("nsTArray", result)
         if nullable:
             result = CGTemplatedType("Nullable", result)
         return result, True, rooter, None
     if returnType.isDictionary():
         nullable = returnType.nullable()
-        dictName = (CGDictionary.makeDictionaryName(returnType.unroll().inner) +
-                    "Initializer")
+        dictName = CGDictionary.makeDictionaryName(returnType.unroll().inner)
         result = CGGeneric(dictName)
         if not isMember and typeNeedsRooting(returnType):
             if nullable:
                 result = CGTemplatedType("NullableRootedDictionary", result)
             else:
                 result = CGTemplatedType("RootedDictionary", result)
             resultArgs = "cx"
         else:
@@ -8374,17 +8377,30 @@ if (""",
     def getStructs(self):
         d = self.dictionary
         selfName = self.makeClassName(d)
         members = [ClassMember(self.makeMemberName(m[0].identifier.name),
                                self.getMemberType(m),
                                visibility="public",
                                body=self.getMemberInitializer(m))
                    for m in self.memberInfo]
-        ctors = [ClassConstructor([], bodyInHeader=True, visibility="public")]
+        ctors = [
+            ClassConstructor(
+                [],
+                visibility="public",
+                body=(
+                    "// Safe to pass a null context if we pass a null value\n"
+                    "Init(nullptr, JS::NullHandleValue);")),
+            ClassConstructor(
+                [Argument("int", "")],
+                visibility="protected",
+                explicit=True,
+                bodyInHeader=True,
+                body='// Do nothing here; this is used by our "Fast" subclass')
+            ]
         methods = []
 
         if self.needToInitIds:
             methods.append(self.initIdsMethod())
 
         methods.append(self.initMethod())
         methods.append(self.initFromJSONMethod())
         methods.append(self.toObjectMethod())
@@ -8408,27 +8424,33 @@ if (""",
             bases=[ClassBase(self.base())],
             members=members,
             constructors=ctors,
             methods=methods,
             isStruct=True,
             disallowCopyConstruction=disallowCopyConstruction)
 
 
-        initializerCtor = ClassConstructor([],
+        fastDictionaryCtor = ClassConstructor(
+            [],
             visibility="public",
-            body=(
-                "// Safe to pass a null context if we pass a null value\n"
-                "Init(nullptr, JS::NullHandleValue);"))
-        initializerStruct = CGClass(selfName + "Initializer",
+            bodyInHeader=True,
+            baseConstructors=["%s(42)" % selfName],
+            body="// Doesn't matter what int we pass to the parent constructor"
+            )
+
+        fastStruct = CGClass("Fast" + selfName,
             bases=[ClassBase(selfName)],
-            constructors=[initializerCtor],
+            constructors=[fastDictionaryCtor],
             isStruct=True)
 
-        return CGList([struct, initializerStruct])
+        return CGList([struct,
+                       CGNamespace.build(['dictionary_detail'],
+                                         fastStruct)],
+                      "\n")
 
     def deps(self):
         return self.dictionary.getDeps()
 
     @staticmethod
     def makeDictionaryName(dictionary):
         return dictionary.identifier.name
 
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -582,17 +582,17 @@ public:
   void MethodRenamedTo(int8_t);
   int8_t AttributeGetterRenamedTo();
   int8_t AttributeRenamedTo();
   void SetAttributeRenamedTo(int8_t);
 
   // Dictionary tests
   void PassDictionary(JSContext*, const Dict&);
   void ReceiveDictionary(JSContext*, Dict&);
-  void ReceiveNullableDictionary(JSContext*, Nullable<DictInitializer>&);
+  void ReceiveNullableDictionary(JSContext*, Nullable<Dict>&);
   void PassOtherDictionary(const GrandparentDict&);
   void PassSequenceOfDictionaries(JSContext*, const Sequence<Dict>&);
   void PassDictionaryOrLong(JSContext*, const Dict&);
   void PassDictionaryOrLong(int32_t);
   void PassDictContainingDict(JSContext*, const DictContainingDict&);
   void PassDictContainingSequence(JSContext*, const DictContainingSequence&);
   void ReceiveDictContainingSequence(JSContext*, DictContainingSequence&);
 
--- a/dom/browser-element/BrowserElementParent.cpp
+++ b/dom/browser-element/BrowserElementParent.cpp
@@ -129,17 +129,17 @@ BrowserElementParent::DispatchOpenWindow
                         const nsAString& aName,
                         const nsAString& aFeatures)
 {
   // Dispatch a CustomEvent at aOpenerFrameElement with a detail object
   // (OpenWindowEventDetail) containing aPopupFrameElement, aURL, aName, and
   // aFeatures.
 
   // Create the event's detail object.
-  OpenWindowEventDetailInitializer detail;
+  OpenWindowEventDetail detail;
   detail.mUrl = aURL;
   detail.mName = aName;
   detail.mFeatures = aFeatures;
   detail.mFrameElement = aPopupFrameElement;
 
   AutoJSContext cx;
   JS::Rooted<JS::Value> val(cx);
 
@@ -302,17 +302,17 @@ private:
 NS_IMETHODIMP DispatchAsyncScrollEventRunnable::Run()
 {
   nsCOMPtr<Element> frameElement = mTabParent->GetOwnerElement();
   nsIDocument *doc = frameElement->OwnerDoc();
   nsCOMPtr<nsIGlobalObject> globalObject = doc->GetScopeObject();
   NS_ENSURE_TRUE(globalObject, NS_ERROR_UNEXPECTED);
 
   // Create the event's detail object.
-  AsyncScrollEventDetailInitializer detail;
+  AsyncScrollEventDetail detail;
   detail.mLeft = mContentRect.x;
   detail.mTop = mContentRect.y;
   detail.mWidth = mContentRect.width;
   detail.mHeight = mContentRect.height;
   detail.mScrollWidth = mContentRect.width;
   detail.mScrollHeight = mContentRect.height;
 
   AutoSafeJSContext cx;
--- a/dom/gamepad/GamepadService.cpp
+++ b/dom/gamepad/GamepadService.cpp
@@ -239,17 +239,17 @@ GamepadService::NewButtonEvent(uint32_t 
 void
 GamepadService::FireButtonEvent(EventTarget* aTarget,
                                 Gamepad* aGamepad,
                                 uint32_t aButton,
                                 double aValue)
 {
   nsString name = aValue == 1.0L ? NS_LITERAL_STRING("gamepadbuttondown") :
                                    NS_LITERAL_STRING("gamepadbuttonup");
-  GamepadButtonEventInitInitializer init;
+  GamepadButtonEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
   init.mGamepad = aGamepad;
   init.mButton = aButton;
   nsRefPtr<GamepadButtonEvent> event =
     GamepadButtonEvent::Constructor(aTarget, name, init);
 
   event->SetTrusted(true);
@@ -302,17 +302,17 @@ GamepadService::NewAxisMoveEvent(uint32_
 }
 
 void
 GamepadService::FireAxisMoveEvent(EventTarget* aTarget,
                                   Gamepad* aGamepad,
                                   uint32_t aAxis,
                                   double aValue)
 {
-  GamepadAxisMoveEventInitInitializer init;
+  GamepadAxisMoveEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
   init.mGamepad = aGamepad;
   init.mAxis = aAxis;
   init.mValue = aValue;
   nsRefPtr<GamepadAxisMoveEvent> event =
     GamepadAxisMoveEvent::Constructor(aTarget,
                                       NS_LITERAL_STRING("gamepadaxismove"),
@@ -383,17 +383,17 @@ GamepadService::NewConnectionEvent(uint3
 
 void
 GamepadService::FireConnectionEvent(EventTarget* aTarget,
                                     Gamepad* aGamepad,
                                     bool aConnected)
 {
   nsString name = aConnected ? NS_LITERAL_STRING("gamepadconnected") :
                                NS_LITERAL_STRING("gamepaddisconnected");
-  GamepadEventInitInitializer init;
+  GamepadEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
   init.mGamepad = aGamepad;
   nsRefPtr<GamepadEvent> event =
     GamepadEvent::Constructor(aTarget, name, init);
 
   event->SetTrusted(true);
 
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -938,17 +938,17 @@ PeerConnectionObserver.prototype = {
     this._dompc._executeNext();
   },
 
   onIceCandidate: function(level, mid, candidate) {
     this.foundIceCandidate(new this._dompc._win.mozRTCIceCandidate(
         {
             candidate: candidate,
             sdpMid: mid,
-            sdpMLineIndex: level
+            sdpMLineIndex: level - 1
         }
     ));
   },
 
 
   // This method is primarily responsible for updating two attributes:
   // iceGatheringState and iceConnectionState. These states are defined
   // in the WebRTC specification as follows:
--- a/dom/permission/PermissionPromptHelper.jsm
+++ b/dom/permission/PermissionPromptHelper.jsm
@@ -29,18 +29,16 @@ else
 const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 this.EXPORTED_SYMBOLS = ["PermissionPromptHelper"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/PermissionsInstaller.jsm");
-Cu.import("resource://gre/modules/PermissionsTable.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
                                    "@mozilla.org/parentprocessmessagemanager;1",
                                    "nsIMessageListenerManager");
 
 XPCOMUtils.defineLazyServiceGetter(this, "permissionPromptService",
                                    "@mozilla.org/permission-prompt-service;1",
                                    "nsIPermissionPromptService");
--- a/dom/system/gonk/NetworkManager.js
+++ b/dom/system/gonk/NetworkManager.js
@@ -911,16 +911,35 @@ NetworkManager.prototype = {
 
     debug("setWifiTethering: " + (msg ? msg : "success"));
 
     if (callback) {
       callback.wifiTetheringEnabledChange(msg);
     }
   },
 
+  // Enable/Disable DHCP server.
+  setDhcpServer: function setDhcpServer(enabled, config, callback) {
+    if (null === config) {
+      config = {};
+    }
+
+    config.cmd = "setDhcpServer";
+    config.isAsync = true;
+    config.enabled = enabled;
+
+    this.controlMessage(config, function setDhcpServerResult(response) {
+      if (!response.success) {
+        callback.dhcpServerResult('Set DHCP server error');
+        return;
+      }
+      callback.dhcpServerResult(null);
+    });
+  },
+
   // Enable/disable WiFi tethering by sending commands to netd.
   setWifiTethering: function setWifiTethering(enable, network, config, callback) {
     if (!network) {
       this.notifyError(true, callback, "invalid network information");
       return;
     }
 
     if (!config) {
--- a/dom/system/gonk/net_worker.js
+++ b/dom/system/gonk/net_worker.js
@@ -209,16 +209,50 @@ self.onmessage = function onmessage(even
   // to NetworkManager later.
   let ret = self[message.cmd](message);
   if (!message.isAsync) {
     postMessage({id: message.id, ret: ret});
   }
 };
 
 /**
+ * Start/Stop DHCP server.
+ */
+function setDhcpServer(config) {
+  function onSuccess() {
+    postMessage({ id: config.id, success: true });
+    return true;
+  }
+
+  function onError() {
+    postMessage({ id: config.id, success: false });
+  }
+
+  let startDhcpServerChain = [setInterfaceUp,
+                              startTethering,
+                              onSuccess];
+
+  let stopDhcpServerChain = [stopTethering,
+                             onSuccess];
+
+  if (config.enabled) {
+    let params = { wifiStartIp: config.startIp,
+                   wifiEndIp: config.endIp,
+                   ip: config.serverIp,
+                   prefix: config.maskLength,
+                   ifname: config.ifname,
+                   link: "up" };
+
+    chain(params, startDhcpServerChain, onError);
+  } else {
+    chain({}, stopDhcpServerChain, onError);
+  }
+}
+
+/**
  * Set DNS servers for given network interface.
  */
 function setDNS(options) {
   let ifprops = getIFProperties(options.ifname);
   let dns1_str = options.dns1_str || ifprops.dns1_str;
   let dns2_str = options.dns2_str || ifprops.dns2_str;
   libcutils.property_set("net.dns1", dns1_str);
   libcutils.property_set("net.dns2", dns2_str);
@@ -450,18 +484,24 @@ function setIpForwardingEnabled(params, 
 
 function startTethering(params, callback) {
   let command;
   // We don't need to start tethering again.
   // Send the dummy command to continue the function chain.
   if (params.resultReason.indexOf("started") !== -1) {
     command = DUMMY_COMMAND;
   } else {
-    command = "tether start " + params.wifiStartIp + " " + params.wifiEndIp +
-              " " + params.usbStartIp + " " + params.usbEndIp;
+    command = "tether start " + params.wifiStartIp + " " + params.wifiEndIp;
+
+    // If usbStartIp/usbEndIp is not valid, don't append them since
+    // the trailing white spaces will be parsed to extra empty args
+    // See: http://androidxref.com/4.3_r2.1/xref/system/core/libsysutils/src/FrameworkListener.cpp#78
+    if (params.usbStartIp && params.usbEndIp) {
+      command += " " + params.usbStartIp + " " + params.usbEndIp;
+    }
   }
   return doCommand(command, callback);
 }
 
 function tetheringStatus(params, callback) {
   let command = "tether status";
   return doCommand(command, callback);
 }
--- a/dom/system/gonk/nsINetworkManager.idl
+++ b/dom/system/gonk/nsINetworkManager.idl
@@ -112,20 +112,33 @@ interface nsIWifiOperationModeCallback :
    *
    * @param error
    *        An error message if the operation wasn't successful,
    *        or `null` if it was.
    */
   void wifiOperationModeResult(in jsval error);
 };
 
+[scriptable, function, uuid(097878b0-19fc-11e3-8ffd-0800200c9a66)]
+interface nsISetDhcpServerCallback : nsISupports
+{
+  /**
+   * Callback function used to report DHCP server result
+   *
+   * @param error
+   *        An error message if the operation wasn't successful,
+   *        or `null` if it was.
+   */
+  void dhcpServerResult(in jsval error);
+};
+
 /**
  * Manage network interfaces.
  */
-[scriptable, uuid(fad3fb08-664f-48e3-bba3-423186988c61)]
+[scriptable, uuid(f658c740-26bb-11e3-8224-0800200c9a66)]
 interface nsINetworkManager : nsISupports
 {
   /**
    * Register the given network interface with the network manager.
    *
    * Consumers will be notified with the 'network-interface-registered'
    * observer notification.
    *
@@ -201,16 +214,40 @@ interface nsINetworkManager : nsISupport
    *        Callback function used to report status to WifiManager.
    */
   void setWifiTethering(in boolean enabled,
                         in nsINetworkInterface networkInterface,
                         in jsval config,
                         in nsIWifiTetheringCallback callback);
 
   /**
+   * Enable or disable DHCP server
+   *
+   * @param enabled
+   *        Boolean that indicates enabling or disabling DHCP server.
+   *
+   * @param config
+   *        Config used to enable the DHCP server. It contains
+   *        .startIp    start of the ip lease range (string)
+   *        .endIp      end of the ip lease range (string)
+   *        .serverIp   ip of the DHCP server (string)
+   *        .maskLength the length of the subnet mask
+   *        .ifname     the interface name
+   *
+   *        As for disabling the DHCP server, put this value |null|.
+   *
+   * @param callback
+   *        Callback function used to report status.
+   */
+  void setDhcpServer(in boolean enabled,
+                     in jsval config,
+                     in nsISetDhcpServerCallback callback);
+
+
+  /**
    * Retrieve network interface stats.
    *
    * @param networkName
    *        Select the Network interface to request estats.
    *
    * @param callback
    *        Callback to notify result and provide stats, connectionType
    *        and the date when stats are retrieved
--- a/dom/system/nsDeviceSensors.cpp
+++ b/dom/system/nsDeviceSensors.cpp
@@ -234,17 +234,17 @@ nsDeviceSensors::Notify(const mozilla::h
     }
   }
 }
 
 void
 nsDeviceSensors::FireDOMLightEvent(mozilla::dom::EventTarget* aTarget,
                                    double aValue)
 {
-  DeviceLightEventInitInitializer init;
+  DeviceLightEventInit init;
   init.mBubbles = true;
   init.mCancelable = false;
   init.mValue = aValue;
   nsRefPtr<DeviceLightEvent> event =
     DeviceLightEvent::Constructor(aTarget, NS_LITERAL_STRING("devicelight"), init);
 
   event->SetTrusted(true);
 
@@ -253,17 +253,17 @@ nsDeviceSensors::FireDOMLightEvent(mozil
 }
 
 void
 nsDeviceSensors::FireDOMProximityEvent(mozilla::dom::EventTarget* aTarget,
                                        double aValue,
                                        double aMin,
                                        double aMax)
 {
-  DeviceProximityEventInitInitializer init;
+  DeviceProximityEventInit init;
   init.mBubbles = true;
   init.mCancelable = false;
   init.mValue = aValue;
   init.mMin = aMin;
   init.mMax = aMax;
   nsRefPtr<DeviceProximityEvent> event =
     DeviceProximityEvent::Constructor(aTarget,
                                       NS_LITERAL_STRING("deviceproximity"),
@@ -284,17 +284,17 @@ nsDeviceSensors::FireDOMProximityEvent(m
     FireDOMUserProximityEvent(aTarget, mIsUserProximityNear);
   }
 }
 
 void
 nsDeviceSensors::FireDOMUserProximityEvent(mozilla::dom::EventTarget* aTarget,
                                            bool aNear)
 {
-  UserProximityEventInitInitializer init;
+  UserProximityEventInit init;
   init.mBubbles = true;
   init.mCancelable = false;
   init.mNear = aNear;
   nsRefPtr<UserProximityEvent> event =
     UserProximityEvent::Constructor(aTarget,
                                     NS_LITERAL_STRING("userproximity"),
                                     init);
 
--- a/gfx/2d/QuartzSupport.h
+++ b/gfx/2d/QuartzSupport.h
@@ -82,18 +82,18 @@ private:
   void *mWrapperCALayer;
   GLuint                    mFBOTexture;
   _CGLContextObject        *mOpenGLContext;
   CGImageRef                mCGImage;
   void                     *mCGData;
   mozilla::RefPtr<MacIOSurface> mIOSurface;
   uint32_t                  mFBO;
   uint32_t                  mIOTexture;
-  uint32_t                  mUnsupportedWidth;
-  uint32_t                  mUnsupportedHeight;
+  int                       mUnsupportedWidth;
+  int                       mUnsupportedHeight;
   AllowOfflineRendererEnum  mAllowOfflineRenderer;
   double                    mContentsScaleFactor;
 };
 
 enum CGContextType {
   CG_CONTEXT_TYPE_UNKNOWN = 0,
   // These are found by inspection, it's possible they could be changed
   CG_CONTEXT_TYPE_BITMAP = 4,
--- a/gfx/2d/QuartzSupport.mm
+++ b/gfx/2d/QuartzSupport.mm
@@ -802,17 +802,18 @@ void nsCARenderer::AttachIOSurface(RefPt
                                            mIOSurface->GetDevicePixelHeight(),
                                            GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
                                            mIOSurface->mIOSurfacePtr, 0);
     ::glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
 
     // Rebind the FBO to make it live
     ::glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
 
-    if (mIOSurface->GetWidth() != width || mIOSurface->GetHeight() != height) {
+    if (static_cast<int>(mIOSurface->GetWidth()) != width ||
+        static_cast<int>(mIOSurface->GetHeight()) != height) {
       width = mIOSurface->GetWidth();
       height = mIOSurface->GetHeight();
       SetBounds(width, height);
       SetViewport(width, height);
     }
 
     if (oldContext) {
       ::CGLSetCurrentContext(oldContext);
--- a/gfx/thebes/gfxPlatformMac.cpp
+++ b/gfx/thebes/gfxPlatformMac.cpp
@@ -435,86 +435,30 @@ gfxPlatformMac::SupportsOffMainThreadCom
     return true;
   }
   return GetPrefLayersOffMainThreadCompositionForceEnabled();
 }
 
 qcms_profile *
 gfxPlatformMac::GetPlatformCMSOutputProfile()
 {
-    qcms_profile *profile = nullptr;
-    CMProfileRef cmProfile;
-    CMProfileLocation *location;
-    UInt32 locationSize;
-
-    /* There a number of different ways that we could try to get a color
-       profile to use.  On 10.5 all of these methods seem to give the same
-       results. On 10.6, the results are different and the following method,
-       using CGMainDisplayID() seems to best match what we are looking for.
-       Currently, both Google Chrome and Qt4 use a similar method.
-
-       CMTypes.h describes CMDisplayIDType:
-       "Data type for ColorSync DisplayID reference
-        On 8 & 9 this is a AVIDType
-	On X this is a CGSDisplayID"
-
-       CGMainDisplayID gives us a CGDirectDisplayID which presumeably
-       corresponds directly to a CGSDisplayID */
-    CGDirectDisplayID displayID = CGMainDisplayID();
-
-    CMError err = CMGetProfileByAVID(static_cast<CMDisplayIDType>(displayID), &cmProfile);
-    if (err != noErr)
-        return nullptr;
-
-    // get the size of location
-    err = NCMGetProfileLocation(cmProfile, nullptr, &locationSize);
-    if (err != noErr)
+    CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
+    if (!cspace) {
+        cspace = ::CGColorSpaceCreateDeviceRGB();
+    }
+    if (!cspace) {
         return nullptr;
-
-    // allocate enough room for location
-    location = static_cast<CMProfileLocation*>(malloc(locationSize));
-    if (!location)
-        goto fail_close;
-
-    err = NCMGetProfileLocation(cmProfile, location, &locationSize);
-    if (err != noErr)
-        goto fail_location;
-
-    switch (location->locType) {
-#ifndef __LP64__
-    case cmFileBasedProfile: {
-        FSRef fsRef;
-        if (!FSpMakeFSRef(&location->u.fileLoc.spec, &fsRef)) {
-            char path[512];
-            if (!FSRefMakePath(&fsRef, reinterpret_cast<UInt8*>(path), sizeof(path))) {
-                profile = qcms_profile_from_path(path);
-#ifdef DEBUG_tor
-                if (profile)
-                    fprintf(stderr,
-                            "ICM profile read from %s fileLoc successfully\n", path);
-#endif
-            }
-        }
-        break;
-    }
-#endif
-    case cmPathBasedProfile:
-        profile = qcms_profile_from_path(location->u.pathLoc.path);
-#ifdef DEBUG_tor
-        if (profile)
-            fprintf(stderr,
-                    "ICM profile read from %s pathLoc successfully\n",
-                    device.u.pathLoc.path);
-#endif
-        break;
-    default:
-#ifdef DEBUG_tor
-        fprintf(stderr, "Unhandled ColorSync profile location\n");
-#endif
-        break;
     }
 
-fail_location:
-    free(location);
-fail_close:
-    CMCloseProfile(cmProfile);
+    CFDataRef iccp = ::CGColorSpaceCopyICCProfile(cspace);
+
+    ::CFRelease(cspace);
+
+    if (!iccp) {
+        return nullptr;
+    }
+
+    qcms_profile* profile = qcms_profile_from_memory(::CFDataGetBytePtr(iccp), static_cast<size_t>(::CFDataGetLength(iccp)));
+
+    ::CFRelease(iccp);
+
     return profile;
 }
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1561,28 +1561,27 @@ class _GenerateProtocolCode(ipdl.ast.Vis
 
         msgenum.addId(self.protocol.name +'End')
         ns.addstmts([ StmtDecl(Decl(msgenum, '')), Whitespace.NL ])
 
         tfDecl, tfDefn = _splitFuncDeclDefn(self.genTransitionFunc())
         ns.addstmts([ tfDecl, Whitespace.NL ])
         self.funcDefns.append(tfDefn)
 
-        typedefs = self.protocol.decl.cxxtypedefs
         for md in p.messageDecls:
             ns.addstmts([
                 _generateMessageClass(md.msgClass(), md.msgId(),
-                                      typedefs, md.prettyMsgName(p.name+'::'),
+                                      md.prettyMsgName(p.name+'::'),
                                       md.decl.type.compress),
                 Whitespace.NL ])
             if md.hasReply():
                 ns.addstmts([
                     _generateMessageClass(
                         md.replyClass(), md.replyId(),
-                        typedefs, md.prettyReplyName(p.name+'::'),
+                        md.prettyReplyName(p.name+'::'),
                         md.decl.type.compress),
                     Whitespace.NL ])
 
         ns.addstmts([ Whitespace.NL, Whitespace.NL ])
 
 
     def genBridgeFunc(self, bridge):
         p = self.protocol
@@ -1763,22 +1762,18 @@ class _GenerateProtocolCode(ipdl.ast.Vis
             # all --> Error transitions break to here
             StmtExpr(ExprAssn(ExprDeref(nextvar), _errorState())),
             StmtReturn(ExprLiteral.FALSE)
         ])
         return transitionfunc
 
 ##--------------------------------------------------
 
-def _generateMessageClass(clsname, msgid, typedefs, prettyName, compress):
+def _generateMessageClass(clsname, msgid, prettyName, compress):
     cls = Class(name=clsname, inherits=[ Inherit(Type('IPC::Message')) ])
-    cls.addstmt(Label.PRIVATE)
-    cls.addstmts(typedefs)
-    cls.addstmt(Whitespace.NL)
-
     cls.addstmt(Label.PUBLIC)
 
     idenum = TypeEnum()
     idenum.addId('ID', msgid)
     cls.addstmt(StmtDecl(Decl(idenum, '')))
 
     # make the message constructor
     if compress:
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -2,16 +2,18 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef js_HeapAPI_h
 #define js_HeapAPI_h
 
+#include <limits.h>
+
 #include "jspubtd.h"
 
 #include "js/Utility.h"
 
 /* These values are private to the JS engine. */
 namespace js {
 
 // Whether the current thread is permitted access to any part of the specified
@@ -129,18 +131,19 @@ GetGCThingRuntime(const void *thing)
 static JS_ALWAYS_INLINE void
 GetGCThingMarkWordAndMask(const void *thing, uint32_t color,
                           uintptr_t **wordp, uintptr_t *maskp)
 {
     uintptr_t addr = uintptr_t(thing);
     size_t bit = (addr & js::gc::ChunkMask) / js::gc::CellSize + color;
     JS_ASSERT(bit < js::gc::ChunkMarkBitmapBits);
     uintptr_t *bitmap = GetGCThingMarkBitmap(thing);
-    *maskp = uintptr_t(1) << (bit % JS_BITS_PER_WORD);
-    *wordp = &bitmap[bit / JS_BITS_PER_WORD];
+    const uintptr_t nbits = sizeof(*bitmap) * CHAR_BIT;
+    *maskp = uintptr_t(1) << (bit % nbits);
+    *wordp = &bitmap[bit / nbits];
 }
 
 static JS_ALWAYS_INLINE JS::shadow::ArenaHeader *
 GetGCThingArena(void *thing)
 {
     uintptr_t addr = uintptr_t(thing);
     addr &= ~js::gc::ArenaMask;
     return reinterpret_cast<JS::shadow::ArenaHeader *>(addr);
--- a/js/src/ds/BitArray.h
+++ b/js/src/ds/BitArray.h
@@ -4,25 +4,28 @@
  * 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 ds_BitArray_h
 #define ds_BitArray_h
 
 #include "mozilla/TemplateLib.h"
 
+#include <limits.h>
+
 #include "jstypes.h"
 
 namespace js {
 
 template <size_t nbits>
 class BitArray {
   private:
+    static const size_t bitsPerElement = sizeof(uintptr_t) * CHAR_BIT;
     static const size_t numSlots =
-        nbits / JS_BITS_PER_WORD + (nbits % JS_BITS_PER_WORD == 0 ? 0 : 1);
+        nbits / bitsPerElement + (nbits % bitsPerElement == 0 ? 0 : 1);
     uintptr_t map[numSlots];
 
   public:
     void clear(bool value) {
         memset(map, value ? 0xFF : 0, sizeof(map));
     }
 
     inline bool get(size_t offset) const {
@@ -49,16 +52,18 @@ class BitArray {
                 return false;
         }
         return true;
     }
 
   private:
     inline void getMarkWordAndMask(size_t offset,
                                    uintptr_t *indexp, uintptr_t *maskp) const {
-        *indexp = offset >> mozilla::tl::FloorLog2<JS_BITS_PER_WORD>::value;
-        *maskp = uintptr_t(1) << (offset & (JS_BITS_PER_WORD - 1));
+        static_assert(bitsPerElement == 32 || bitsPerElement == 64,
+                      "unexpected bitsPerElement value");
+        *indexp = offset / bitsPerElement;
+        *maskp = uintptr_t(1) << (offset % bitsPerElement);
     }
 };
 
 } /* namespace js */
 
 #endif /* ds_BitArray_h */
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -2761,17 +2761,22 @@ CodeGenerator::generateBody()
                 return false;
         }
 
 #if defined(JS_ION_PERF)
         perfSpewer->startBasicBlock(current->mir(), masm);
 #endif
 
         for (; iter != current->end(); iter++) {
-            IonSpew(IonSpew_Codegen, "instruction %s", iter->opName());
+            IonSpewStart(IonSpew_Codegen, "instruction %s", iter->opName());
+#ifdef DEBUG
+            if (const char *extra = iter->extraName())
+                IonSpewCont(IonSpew_Codegen, ":%s", extra);
+#endif
+            IonSpewFin(IonSpew_Codegen);
 
             if (counts)
                 blockCounts.ref().visitInstruction(*iter);
 
             if (iter->safepoint() && pushedArgumentSlots_.length()) {
                 if (!markArgumentSlots(iter->safepoint()))
                     return false;
             }
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -163,16 +163,19 @@ class LPointer : public LInstructionHelp
     { }
 
     void *ptr() const {
         return ptr_;
     }
     Kind kind() const {
         return kind_;
     }
+    const char *extraName() const {
+        return kind_ == GC_THING ? "GC_THING" : "NON_GC_THING";
+    }
 
     gc::Cell *gcptr() const {
         JS_ASSERT(kind() == GC_THING);
         return (gc::Cell *) ptr_;
     }
 };
 
 // Constant double.
@@ -1537,16 +1540,19 @@ class LCompare : public LInstructionHelp
         return getOperand(0);
     }
     const LAllocation *right() {
         return getOperand(1);
     }
     MCompare *mir() {
         return mir_->toCompare();
     }
+    const char *extraName() const {
+        return js_CodeName[jsop_];
+    }
 };
 
 // Compares two integral values of the same JS type, either integer or object.
 // For objects, both operands are in registers.
 class LCompareAndBranch : public LControlInstructionHelper<2, 2, 0>
 {
     JSOp jsop_;
 
@@ -1575,16 +1581,19 @@ class LCompareAndBranch : public LContro
         return getOperand(0);
     }
     const LAllocation *right() {
         return getOperand(1);
     }
     MCompare *mir() {
         return mir_->toCompare();
     }
+    const char *extraName() const {
+        return js_CodeName[jsop_];
+    }
 };
 
 class LCompareD : public LInstructionHelper<1, 2, 0>
 {
   public:
     LIR_HEADER(CompareD)
     LCompareD(const LAllocation &left, const LAllocation &right) {
         setOperand(0, left);
@@ -2015,17 +2024,17 @@ class LBitOpI : public LInstructionHelpe
 
     LBitOpI(JSOp op)
       : op_(op)
     { }
 
     const char *extraName() const {
         if (bitop() == JSOP_URSH && mir_->toUrsh()->canOverflow())
             return "UrshCanOverflow";
-        return nullptr;
+        return js_CodeName[op_];
     }
 
     JSOp bitop() const {
         return op_;
     }
 };
 
 // Call a VM function to perform a bitwise operation.
@@ -2039,16 +2048,20 @@ class LBitOpV : public LCallInstructionH
     LBitOpV(JSOp jsop)
       : jsop_(jsop)
     { }
 
     JSOp jsop() const {
         return jsop_;
     }
 
+    const char *extraName() const {
+        return js_CodeName[jsop_];
+    }
+
     static const size_t LhsInput = 0;
     static const size_t RhsInput = BOX_PIECES;
 };
 
 // Shift operation, taking two 32-bit integers as inputs and returning
 // a 32-bit integer result as an output.
 class LShiftI : public LBinaryMath<0>
 {
@@ -2063,16 +2076,20 @@ class LShiftI : public LBinaryMath<0>
 
     JSOp bitop() {
         return op_;
     }
 
     MInstruction *mir() {
         return mir_->toInstruction();
     }
+
+    const char *extraName() const {
+        return js_CodeName[op_];
+    }
 };
 
 class LUrshD : public LBinaryMath<1>
 {
   public:
     LIR_HEADER(UrshD)
 
     LUrshD(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) {
@@ -2118,16 +2135,19 @@ class LMinMaxI : public LInstructionHelp
         return this->getOperand(1);
     }
     const LDefinition *output() {
         return this->getDef(0);
     }
     MMinMax *mir() const {
         return mir_->toMinMax();
     }
+    const char *extraName() const {
+        return mir()->isMax() ? "Max" : "Min";
+    }
 };
 
 class LMinMaxD : public LInstructionHelper<1, 2, 0>
 {
   public:
     LIR_HEADER(MinMaxD)
     LMinMaxD(const LAllocation &first, const LAllocation &second) 
     {
@@ -2142,16 +2162,19 @@ class LMinMaxD : public LInstructionHelp
         return this->getOperand(1);
     }
     const LDefinition *output() {
         return this->getDef(0);
     }
     MMinMax *mir() const {
         return mir_->toMinMax();
     }
+    const char *extraName() const {
+        return mir()->isMax() ? "Max" : "Min";
+    }
 };
 
 // Negative of an integer
 class LNegI : public LInstructionHelper<1, 1, 0>
 {
   public:
     LIR_HEADER(NegI);
     LNegI(const LAllocation &num) {
@@ -2307,16 +2330,19 @@ class LMathFunctionD : public LCallInstr
     }
 
     const LDefinition *temp() {
         return getTemp(0);
     }
     MMathFunction *mir() const {
         return mir_->toMathFunction();
     }
+    const char *extraName() const {
+        return MMathFunction::FunctionName(mir()->function());
+    }
 };
 
 // Adds two integers, returning an integer value.
 class LAddI : public LBinaryMath<0>
 {
     bool recoversInput_;
 
   public:
@@ -2372,16 +2398,20 @@ class LMathD : public LBinaryMath<0>
 
     LMathD(JSOp jsop)
       : jsop_(jsop)
     { }
 
     JSOp jsop() const {
         return jsop_;
     }
+
+    const char *extraName() const {
+        return js_CodeName[jsop_];
+    }
 };
 
 // Performs an add, sub, mul, or div on two double values.
 class LMathF: public LBinaryMath<0>
 {
     JSOp jsop_;
 
   public:
@@ -2389,16 +2419,20 @@ class LMathF: public LBinaryMath<0>
 
     LMathF(JSOp jsop)
       : jsop_(jsop)
     { }
 
     JSOp jsop() const {
         return jsop_;
     }
+
+    const char *extraName() const {
+        return js_CodeName[jsop_];
+    }
 };
 
 class LModD : public LBinaryMath<1>
 {
   public:
     LIR_HEADER(ModD)
 
     LModD(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) {
@@ -2426,16 +2460,20 @@ class LBinaryV : public LCallInstruction
     LBinaryV(JSOp jsop)
       : jsop_(jsop)
     { }
 
     JSOp jsop() const {
         return jsop_;
     }
 
+    const char *extraName() const {
+        return js_CodeName[jsop_];
+    }
+
     static const size_t LhsInput = 0;
     static const size_t RhsInput = BOX_PIECES;
 };
 
 // Adds two string, returning a string.
 class LConcat : public LInstructionHelper<1, 2, 4>
 {
   public:
@@ -3996,16 +4034,19 @@ class LSetPropertyPolymorphicT : public 
         return getTemp(0);
     }
     MIRType valueType() const {
         return valueType_;
     }
     const MSetPropertyPolymorphic *mir() const {
         return mir_->toSetPropertyPolymorphic();
     }
+    const char *extraName() const {
+        return StringFromMIRType(valueType_);
+    }
 };
 
 class LGetElementCacheV : public LInstructionHelper<BOX_PIECES, 1 + BOX_PIECES, 0>
 {
   public:
     LIR_HEADER(GetElementCacheV)
     BOX_OUTPUT_ACCESSORS()
 
@@ -4351,16 +4392,19 @@ class LSetPropertyCacheT : public LInstr
     }
 
     const MSetPropertyCache *mir() const {
         return mir_->toSetPropertyCache();
     }
     MIRType valueType() {
         return valueType_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(valueType_);
+    }
 };
 
 class LSetElementCacheV : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 3>
 {
   public:
     LIR_HEADER(SetElementCacheV);
 
     static const size_t Index = 1;
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -549,16 +549,55 @@ MAssertRange::printOpcode(FILE *fp) cons
 {
     MDefinition::printOpcode(fp);
     Sprinter sp(GetIonContext()->cx);
     sp.init();
     assertedRange()->print(sp);
     fprintf(fp, " %s", sp.string());
 }
 
+const char *
+MMathFunction::FunctionName(Function function)
+{
+    switch (function) {
+      case Log:    return "Log";
+      case Sin:    return "Sin";
+      case Cos:    return "Cos";
+      case Exp:    return "Exp";
+      case Tan:    return "Tan";
+      case ACos:   return "ACos";
+      case ASin:   return "ASin";
+      case ATan:   return "ATan";
+      case Log10:  return "Log10";
+      case Log2:   return "Log2";
+      case Log1P:  return "Log1P";
+      case ExpM1:  return "ExpM1";
+      case CosH:   return "CosH";
+      case SinH:   return "SinH";
+      case TanH:   return "TanH";
+      case ACosH:  return "ACosH";
+      case ASinH:  return "ASinH";
+      case ATanH:  return "ATanH";
+      case Sign:   return "Sign";
+      case Trunc:  return "Trunc";
+      case Cbrt:   return "Cbrt";
+      case Floor:  return "Floor";
+      case Round:  return "Round";
+      default:
+        MOZ_ASSUME_UNREACHABLE("Unknown math function");
+    }
+}
+
+void
+MMathFunction::printOpcode(FILE *fp) const
+{
+    MDefinition::printOpcode(fp);
+    fprintf(fp, " %s", FunctionName(function()));
+}
+
 MParameter *
 MParameter::New(int32_t index, types::TemporaryTypeSet *types)
 {
     return new MParameter(index, types);
 }
 
 void
 MParameter::printOpcode(FILE *fp) const
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3653,16 +3653,20 @@ class MMathFunction
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
     bool possiblyCalls() const {
         return true;
     }
+
+    void printOpcode(FILE *fp) const;
+
+    static const char *FunctionName(Function function);
 };
 
 class MAdd : public MBinaryArithInstruction
 {
     // Is this instruction really an int at heart?
     MAdd(MDefinition *left, MDefinition *right)
       : MBinaryArithInstruction(left, right)
     {
--- a/js/src/jit/arm/LIR-arm.h
+++ b/js/src/jit/arm/LIR-arm.h
@@ -21,16 +21,19 @@ class LBox : public LInstructionHelper<2
       : type_(type)
     {
         setOperand(0, in_payload);
     }
 
     MIRType type() const {
         return type_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(type_);
+    }
 };
 
 class LBoxFloatingPoint : public LInstructionHelper<2, 1, 1>
 {
     MIRType type_;
 
   public:
     LIR_HEADER(BoxFloatingPoint);
@@ -40,16 +43,19 @@ class LBoxFloatingPoint : public LInstru
     {
         setOperand(0, in);
         setTemp(0, temp);
     }
 
     MIRType type() const {
         return type_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(type_);
+    }
 };
 
 class LUnbox : public LInstructionHelper<1, 2, 0>
 {
   public:
     LIR_HEADER(Unbox);
 
     MUnbox *mir() const {
@@ -78,16 +84,19 @@ class LUnboxFloatingPoint : public LInst
 
     MUnbox *mir() const {
         return mir_->toUnbox();
     }
 
     MIRType type() const {
         return type_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(type_);
+    }
 };
 
 // Convert a 32-bit unsigned integer to a double.
 class LUInt32ToDouble : public LInstructionHelper<1, 1, 0>
 {
   public:
     LIR_HEADER(UInt32ToDouble)
 
--- a/js/src/jit/x64/LIR-x64.h
+++ b/js/src/jit/x64/LIR-x64.h
@@ -22,16 +22,19 @@ class LBox : public LInstructionHelper<1
       : type_(type)
     {
         setOperand(0, payload);
     }
 
     MIRType type() const {
         return type_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(type_);
+    }
 };
 
 // Given an untyped input, guards on whether it's a specific type and returns
 // the unboxed payload.
 class LUnboxBase : public LInstructionHelper<1, 1, 0>
 {
   public:
     LUnboxBase(const LAllocation &input) {
@@ -63,16 +66,19 @@ class LUnboxFloatingPoint : public LUnbo
     LUnboxFloatingPoint(const LAllocation &input, MIRType type)
       : LUnboxBase(input),
         type_(type)
     { }
 
     MIRType type() const {
         return type_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(type_);
+    }
 };
 
 // Convert a 32-bit unsigned integer to a double.
 class LAsmJSUInt32ToDouble : public LInstructionHelper<1, 1, 0>
 {
   public:
     LIR_HEADER(AsmJSUInt32ToDouble)
 
--- a/js/src/jit/x86/LIR-x86.h
+++ b/js/src/jit/x86/LIR-x86.h
@@ -21,16 +21,19 @@ class LBox : public LInstructionHelper<2
       : type_(type)
     {
         setOperand(0, in_payload);
     }
 
     MIRType type() const {
         return type_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(type_);
+    }
 };
 
 class LBoxFloatingPoint : public LInstructionHelper<2, 1, 1>
 {
     MIRType type_;
 
   public:
     LIR_HEADER(BoxFloatingPoint);
@@ -41,16 +44,19 @@ class LBoxFloatingPoint : public LInstru
         JS_ASSERT(IsFloatingPointType(type));
         setOperand(0, in);
         setTemp(0, temp);
     }
 
     MIRType type() const {
         return type_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(type_);
+    }
 };
 
 class LUnbox : public LInstructionHelper<1, 2, 0>
 {
   public:
     LIR_HEADER(Unbox);
 
     MUnbox *mir() const {
@@ -79,16 +85,19 @@ class LUnboxFloatingPoint : public LInst
 
     MUnbox *mir() const {
         return mir_->toUnbox();
     }
 
     MIRType type() const {
         return type_;
     }
+    const char *extraName() const {
+        return StringFromMIRType(type_);
+    }
 };
 
 // Convert a 32-bit unsigned integer to a double.
 class LAsmJSUInt32ToDouble : public LInstructionHelper<1, 1, 1>
 {
   public:
     LIR_HEADER(AsmJSUInt32ToDouble)
 
--- a/js/src/jsutil.h
+++ b/js/src/jsutil.h
@@ -9,16 +9,18 @@
  */
 
 #ifndef jsutil_h
 #define jsutil_h
 
 #include "mozilla/Compiler.h"
 #include "mozilla/GuardObjects.h"
 
+#include <limits.h>
+
 #ifdef USE_ZLIB
 #include <zlib.h>
 #endif
 
 #include "js/Utility.h"
 
 static JS_ALWAYS_INLINE void *
 js_memcpy(void *dst_, const void *src_, size_t len)
@@ -199,34 +201,36 @@ UnsignedPtrDiff(const void *bigger, cons
 {
     return size_t(bigger) - size_t(smaller);
 }
 
 /*****************************************************************************/
 
 /* A bit array is an array of bits represented by an array of words (size_t). */
 
+static const size_t BitArrayElementBits = sizeof(size_t) * CHAR_BIT;
+
 static inline unsigned
 NumWordsForBitArrayOfLength(size_t length)
 {
-    return (length + (JS_BITS_PER_WORD - 1)) / JS_BITS_PER_WORD;
+    return (length + (BitArrayElementBits - 1)) / BitArrayElementBits;
 }
 
 static inline unsigned
 BitArrayIndexToWordIndex(size_t length, size_t bitIndex)
 {
-    unsigned wordIndex = bitIndex / JS_BITS_PER_WORD;
+    unsigned wordIndex = bitIndex / BitArrayElementBits;
     JS_ASSERT(wordIndex < length);
     return wordIndex;
 }
 
 static inline size_t
 BitArrayIndexToWordMask(size_t i)
 {
-    return size_t(1) << (i % JS_BITS_PER_WORD);
+    return size_t(1) << (i % BitArrayElementBits);
 }
 
 static inline bool
 IsBitArrayElementSet(size_t *array, size_t length, size_t i)
 {
     return array[BitArrayIndexToWordIndex(length, i)] & BitArrayIndexToWordMask(i);
 }
 
@@ -336,22 +340,23 @@ JS_DumpBasicStats(JSBasicStats *bs, cons
 extern void
 JS_DumpHistogram(JSBasicStats *bs, FILE *fp);
 #else
 # define JS_BASIC_STATS_ACCUM(bs,val)
 #endif
 
 /* A jsbitmap_t is a long integer that can be used for bitmaps. */
 typedef size_t jsbitmap;
-#define JS_TEST_BIT(_map,_bit)  ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &      \
-                                 ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
-#define JS_SET_BIT(_map,_bit)   ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |=     \
-                                 ((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
-#define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &=     \
-                                 ~((jsbitmap)1<<((_bit)&(JS_BITS_PER_WORD-1))))
+#define JS_BITMAP_NBITS (sizeof(jsbitmap) * CHAR_BIT)
+#define JS_TEST_BIT(_map,_bit)  ((_map)[(_bit)/JS_BITMAP_NBITS] &             \
+                                 (jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
+#define JS_SET_BIT(_map,_bit)   ((_map)[(_bit)/JS_BITMAP_NBITS] |=            \
+                                 (jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
+#define JS_CLEAR_BIT(_map,_bit) ((_map)[(_bit)/JS_BITMAP_NBITS] &=            \
+                                 ~(jsbitmap(1)<<((_bit)%JS_BITMAP_NBITS)))
 
 /* Wrapper for various macros to stop warnings coming from their expansions. */
 #if defined(__clang__)
 # define JS_SILENCE_UNUSED_VALUE_IN_EXPR(expr)                                \
     JS_BEGIN_MACRO                                                            \
         _Pragma("clang diagnostic push")                                      \
         /* If these _Pragmas cause warnings for you, try disabling ccache. */ \
         _Pragma("clang diagnostic ignored \"-Wunused-value\"")                \
--- a/js/src/tests/lib/jittests.py
+++ b/js/src/tests/lib/jittests.py
@@ -72,18 +72,18 @@ class Test:
 
     def __init__(self, path):
         # Absolute path of the test file.
         self.path = path
 
         # Path relative to the top mozilla/ directory.
         self.relpath_top = os.path.relpath(path, TOP_SRC_DIR)
 
-        # Path relative to mozilla/js/src/.
-        self.relpath_js = os.path.relpath(path, JS_DIR)
+        # Path relative to mozilla/js/src/jit-test/tests/.
+        self.relpath_tests = os.path.relpath(path, TEST_DIR)
 
         self.jitflags = []     # jit flags to enable
         self.slow = False      # True means the test is slow-running
         self.allow_oom = False # True means that OOM is not considered a failure
         self.valgrind = False  # True means run under valgrind
         self.tz_pacific = False # True means force Pacific time for the test
         self.expect_error = '' # Errors to expect and consider passing
         self.expect_status = 0 # Exit status to expect from shell
@@ -553,24 +553,24 @@ def process_test_results(results, num_te
             if options.show_output:
                 sys.stdout.write(res.out)
                 sys.stdout.write(res.err)
                 sys.stdout.write('Exit code: %s\n' % res.rc)
             if res.test.valgrind:
                 sys.stdout.write(res.err)
 
             ok = check_output(res.out, res.err, res.rc, res.test)
-            doing = 'after %s' % res.test.relpath_js
+            doing = 'after %s' % res.test.relpath_tests
             if not ok:
                 failures.append(res)
                 if res.timed_out:
-                    pb.message("TIMEOUT - %s" % res.test.relpath_js)
+                    pb.message("TIMEOUT - %s" % res.test.relpath_tests)
                     timeouts += 1
                 else:
-                    pb.message("FAIL - %s" % res.test.relpath_js)
+                    pb.message("FAIL - %s" % res.test.relpath_tests)
 
             if options.tinderbox:
                 print_tinderbox(ok, res)
 
             n = i + 1
             pb.update(n, {
                 'PASS': n - len(failures),
                 'FAIL': len(failures),
--- a/js/src/yarr/YarrPattern.cpp
+++ b/js/src/yarr/YarrPattern.cpp
@@ -761,17 +761,20 @@ public:
             PatternTerm& term = terms[termIndex];
 
             if (term.m_capture)
                 return true;
 
             if (term.type == PatternTerm::TypeParenthesesSubpattern) {
                 PatternDisjunction* nestedDisjunction = term.parentheses.disjunction;
                 for (unsigned alt = 0; alt < nestedDisjunction->m_alternatives.size(); ++alt) {
-                    if (containsCapturingTerms(nestedDisjunction->m_alternatives[alt], 0, nestedDisjunction->m_alternatives[alt]->m_terms.size() - 1))
+                    PatternAlternative *pattern = nestedDisjunction->m_alternatives[alt];
+                    if (pattern->m_terms.size() == 0)
+                        continue;
+                    if (containsCapturingTerms(pattern, 0, pattern->m_terms.size() - 1))
                         return true;
                 }
             }
         }
 
         return false;
     }
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -72,16 +72,32 @@ NS_NewHTMLScrollFrame(nsIPresShell* aPre
 NS_IMPL_FRAMEARENA_HELPERS(nsHTMLScrollFrame)
 
 nsHTMLScrollFrame::nsHTMLScrollFrame(nsIPresShell* aShell, nsStyleContext* aContext, bool aIsRoot)
   : nsContainerFrame(aContext),
     mInner(ALLOW_THIS_IN_INITIALIZER_LIST(this), aIsRoot)
 {
 }
 
+void
+nsHTMLScrollFrame::ScrollbarActivityStarted() const
+{
+  if (mInner.mScrollbarActivity) {
+    mInner.mScrollbarActivity->ActivityStarted();
+  }
+}
+ 
+void
+nsHTMLScrollFrame::ScrollbarActivityStopped() const
+{
+  if (mInner.mScrollbarActivity) {
+    mInner.mScrollbarActivity->ActivityStopped();
+  }
+}
+ 
 nsresult
 nsHTMLScrollFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
 {
   return mInner.CreateAnonymousContent(aElements);
 }
 
 void
 nsHTMLScrollFrame::AppendAnonymousContentTo(nsBaseContentList& aElements,
@@ -897,16 +913,32 @@ nsXULScrollFrame::nsXULScrollFrame(nsIPr
                                    bool aIsRoot, bool aClipAllDescendants)
   : nsBoxFrame(aShell, aContext, aIsRoot),
     mInner(ALLOW_THIS_IN_INITIALIZER_LIST(this), aIsRoot)
 {
   SetLayoutManager(nullptr);
   mInner.mClipAllDescendants = aClipAllDescendants;
 }
 
+void
+nsXULScrollFrame::ScrollbarActivityStarted() const
+{
+  if (mInner.mScrollbarActivity) {
+    mInner.mScrollbarActivity->ActivityStarted();
+  }
+}
+ 
+void
+nsXULScrollFrame::ScrollbarActivityStopped() const
+{
+  if (mInner.mScrollbarActivity) {
+    mInner.mScrollbarActivity->ActivityStopped();
+  }
+}
+ 
 nsMargin
 nsGfxScrollFrameInner::GetDesiredScrollbarSizes(nsBoxLayoutState* aState)
 {
   NS_ASSERTION(aState && aState->GetRenderingContext(),
                "Must have rendering context in layout state for size "
                "computations");
 
   nsMargin result(0, 0, 0, 0);
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -515,16 +515,19 @@ public:
   virtual void AppendAnonymousContentTo(nsBaseContentList& aElements,
                                         uint32_t aFilter) MOZ_OVERRIDE;
 
   // nsIScrollbarOwner
   virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
     return mInner.GetScrollbarBox(aVertical);
   }
 
+  virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
+  virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE;
+
   // nsIScrollableFrame
   virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE {
     return mInner.GetScrolledFrame();
   }
   virtual mozilla::ScrollbarStyles GetScrollbarStyles() const {
     return mInner.GetScrollbarStylesFromFrame();
   }
   virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE {
@@ -805,16 +808,19 @@ public:
   static void AdjustReflowStateForPrintPreview(nsBoxLayoutState& aState, bool& aSetBack);
   static void AdjustReflowStateBack(nsBoxLayoutState& aState, bool aSetBack);
 
   // nsIScrollbarOwner
   virtual nsIFrame* GetScrollbarBox(bool aVertical) MOZ_OVERRIDE {
     return mInner.GetScrollbarBox(aVertical);
   }
 
+  virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
+  virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE;
+
   // nsIScrollableFrame
   virtual nsIFrame* GetScrolledFrame() const MOZ_OVERRIDE {
     return mInner.GetScrolledFrame();
   }
   virtual mozilla::ScrollbarStyles GetScrollbarStyles() const {
     return mInner.GetScrollbarStylesFromFrame();
   }
   virtual uint32_t GetScrollbarVisibility() const MOZ_OVERRIDE {
--- a/layout/generic/nsIScrollbarOwner.h
+++ b/layout/generic/nsIScrollbarOwner.h
@@ -18,11 +18,18 @@ class nsIScrollbarOwner : public nsQuery
 public:
   NS_DECL_QUERYFRAME_TARGET(nsIScrollbarOwner)
 
   /**
    * Obtain the frame for the horizontal or vertical scrollbar, or null
    * if there is no such box.
    */
   virtual nsIFrame* GetScrollbarBox(bool aVertical) = 0;
+
+  /**
+   * Show or hide scrollbars on 2 fingers touch.
+   * Subclasses should call their ScrollbarActivity's corresponding methods.
+   */
+  virtual void ScrollbarActivityStarted() const = 0;
+  virtual void ScrollbarActivityStopped() const = 0;
 };
 
 #endif
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -4491,16 +4491,32 @@ nsTreeBodyFrame::PostScrollEvent()
   if (NS_FAILED(NS_DispatchToCurrentThread(ev))) {
     NS_WARNING("failed to dispatch ScrollEvent");
   } else {
     mScrollEvent = ev;
   }
 }
 
 void
+nsTreeBodyFrame::ScrollbarActivityStarted() const
+{
+  if (mScrollbarActivity) {
+    mScrollbarActivity->ActivityStarted();
+  }
+}
+ 
+void
+nsTreeBodyFrame::ScrollbarActivityStopped() const
+{
+  if (mScrollbarActivity) {
+    mScrollbarActivity->ActivityStopped();
+  }
+}
+ 
+void
 nsTreeBodyFrame::DetachImageListeners()
 {
   mCreatedListeners.Clear();
 }
 
 void
 nsTreeBodyFrame::RemoveTreeImageListener(nsTreeImageListener* aListener)
 {
--- a/layout/xul/tree/nsTreeBodyFrame.h
+++ b/layout/xul/tree/nsTreeBodyFrame.h
@@ -459,16 +459,19 @@ protected:
     ScrollEvent(nsTreeBodyFrame *aInner) : mInner(aInner) {}
     void Revoke() { mInner = nullptr; }
   private:
     nsTreeBodyFrame* mInner;
   };
 
   void PostScrollEvent();
   void FireScrollEvent();
+  
+  virtual void ScrollbarActivityStarted() const MOZ_OVERRIDE;
+  virtual void ScrollbarActivityStopped() const MOZ_OVERRIDE;
 
   /**
    * Clear the pointer to this frame for all nsTreeImageListeners that were
    * created by this frame.
    */
   void DetachImageListeners();
 
 #ifdef ACCESSIBILITY
--- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
+++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.cpp
@@ -218,16 +218,21 @@ void VcmSIPCCBinding::setSTSThread(nsIEv
   gSTSThread = thread;
 }
 
 nsIThread* VcmSIPCCBinding::getMainThread()
 {
   return gMainThread;
 }
 
+nsIEventTarget* VcmSIPCCBinding::getSTSThread()
+{
+  return gSTSThread;
+}
+
 void VcmSIPCCBinding::connectCandidateSignal(
     NrIceMediaStream *stream)
 {
   stream->SignalCandidate.connect(gSelf,
                                   &VcmSIPCCBinding::CandidateReady);
 }
 
 /* static */
@@ -470,65 +475,97 @@ void vcmRxAllocPort(cc_mcapid_t mcap_id,
       obs->registerStream(call_handle, stream_id, isVideo);
 
     CSFLogDebug( logTag, "vcmRxAllocPort(): allocated port %d", port);
     *port_allocated = port;
 }
 
 
 /**
- *  Gets the ICE parameters for a stream. Called "alloc" for style consistency
+ *  Gets the ICE objects for a stream.
  *
  *  @param[in]  mcap_id - Media Capability ID
  *  @param[in]  group_id - group identifier to which stream belongs.
  *  @param[in]  stream_id - stream identifier
  *  @param[in]  call_handle  - call identifier
  *  @param[in]  peerconnection - the peerconnection in use
+ *  @param[in]  level - the m-line index (1-based)
+ *  @param[out] ctx - the NrIceCtx
+ *  @param[out] stream - the NrIceStream
+ */
+
+static short vcmGetIceStream_m(cc_mcapid_t mcap_id,
+                               cc_groupid_t group_id,
+                               cc_streamid_t stream_id,
+                               cc_call_handle_t  call_handle,
+                               const char *peerconnection,
+                               uint16_t level,
+                               mozilla::RefPtr<NrIceCtx> *ctx,
+                               mozilla::RefPtr<NrIceMediaStream> *stream)
+{
+  CSFLogDebug( logTag, "%s: group_id=%d stream_id=%d call_handle=%d PC = %s",
+    __FUNCTION__, group_id, stream_id, call_handle, peerconnection);
+
+  // Note: we don't acquire any media resources here, and we assume that the
+  // ICE streams already exist, so we're just acquiring them. Any logic
+  // to make them on demand is elsewhere.
+  sipcc::PeerConnectionWrapper pc(peerconnection);
+  ENSURE_PC(pc, VCM_ERROR);
+
+  *ctx = pc.impl()->media()->ice_ctx();
+  MOZ_ASSERT(*ctx);
+  if (!*ctx)
+    return VCM_ERROR;
+
+  CSFLogDebug( logTag, "%s: Getting stream %d", __FUNCTION__, level);
+  *stream = pc.impl()->media()->ice_media_stream(level-1);
+  MOZ_ASSERT(*stream);
+  if (!*stream) {
+    return VCM_ERROR;
+  }
+
+  return 0;
+}
+
+/**
+ *  Gets the ICE parameters for a stream. Called "alloc" for style consistency
+ *  @param[in]  ctx_in - the ICE ctx
+ *  @param[in]  stream_in - the ICE stream
+ *  @param[in]  call_handle  - call identifier
+ *  @param[in]  stream_id - stream identifier
+ *  @param[in]  level - the m-line index (1-based)
  *  @param[out] default_addrp - the ICE default addr
  *  @param[out] port_allocatedp - the ICE default port
  *  @param[out] candidatesp - the ICE candidate array
  *  @param[out] candidate_ctp length of the array
  *
  *  @return 0 for success; VCM_ERROR for failure
  *
  */
-static short vcmRxAllocICE_m(cc_mcapid_t mcap_id,
-                             cc_groupid_t group_id,
+static short vcmRxAllocICE_s(TemporaryRef<NrIceCtx> ctx_in,
+			     TemporaryRef<NrIceMediaStream> stream_in,
+                             cc_call_handle_t  call_handle,
                              cc_streamid_t stream_id,
-                             cc_call_handle_t  call_handle,
-                             const char *peerconnection,
                              uint16_t level,
                              char **default_addrp, /* Out */
                              int *default_portp, /* Out */
                              char ***candidatesp, /* Out */
                              int *candidate_ctp /* Out */
 )
 {
+  // Make a concrete reference to ctx_in and stream_in so we
+  // can use the pointers (TemporaryRef is not dereferencable).
+  RefPtr<NrIceCtx> ctx(ctx_in);
+  RefPtr<NrIceMediaStream> stream(stream_in);
+
   *default_addrp = NULL;
   *default_portp = -1;
   *candidatesp = NULL;
   *candidate_ctp = 0;
 
-  CSFLogDebug( logTag, "%s: group_id=%d stream_id=%d call_handle=%d PC = %s",
-    __FUNCTION__, group_id, stream_id, call_handle, peerconnection);
-
-  // Note: we don't acquire any media resources here, and we assume that the
-  // ICE streams already exist, so we're just acquiring them. Any logic
-  // to make them on demand is elsewhere.
-  sipcc::PeerConnectionWrapper pc(peerconnection);
-  ENSURE_PC(pc, VCM_ERROR);
-
-  CSFLogDebug( logTag, "%s: Getting stream %d", __FUNCTION__, level);
-  mozilla::RefPtr<NrIceMediaStream> stream = pc.impl()->media()->
-    ice_media_stream(level-1);
-  MOZ_ASSERT(stream);
-  if (!stream) {
-    return VCM_ERROR;
-  }
-
   // Set the opaque so we can correlate events.
   stream->SetOpaque(new VcmIceOpaque(stream_id, call_handle, level));
 
   // Attach ourself to the candidate signal.
   VcmSIPCCBinding::connectCandidateSignal(stream);
 
   std::vector<std::string> candidates = stream->GetCandidates();
   CSFLogDebug( logTag, "%s: Got %lu candidates", __FUNCTION__, candidates.size());
@@ -564,22 +601,22 @@ static short vcmRxAllocICE_m(cc_mcapid_t
   *default_portp = default_port; /* This is the signal that things are cool */
   return 0;
 }
 
 
 /**
  *  Gets the ICE parameters for a stream. Called "alloc" for style consistency
  *
- *  This is a thunk to vcmRxAllocICE_m
- *
+ *  @param[in]  mcap_id  - media cap id
  *  @param[in]  group_id - group identifier to which stream belongs.
  *  @param[in]  stream_id - stream identifier
  *  @param[in]  call_handle  - call identifier
  *  @param[in]  peerconnection - the peerconnection in use
+ *  @param[in]  level - the m-line index (1-based)
  *  @param[out] default_addrp - the ICE default addr
  *  @param[out] port_allocatedp - the ICE default port
  *  @param[out] candidatesp - the ICE candidate array
  *  @param[out] candidate_ctp length of the array
  *
  *  @return 0 for success; VCM_ERROR for failure
  *
  */
@@ -591,29 +628,54 @@ short vcmRxAllocICE(cc_mcapid_t mcap_id,
                    uint16_t level,
                    char **default_addrp, /* Out */
                    int *default_portp, /* Out */
                    char ***candidatesp, /* Out */
                    int *candidate_ctp /* Out */
                    )
 {
   int ret;
-  mozilla::SyncRunnable::DispatchToThread(VcmSIPCCBinding::getMainThread(),
-      WrapRunnableNMRet(&vcmRxAllocICE_m,
+
+  mozilla::RefPtr<NrIceCtx> ctx;
+  mozilla::RefPtr<NrIceMediaStream> stream;
+
+  // First, get a strong ref to the ICE context and stream from the
+  // main thread.
+  mozilla::SyncRunnable::DispatchToThread(
+      VcmSIPCCBinding::getMainThread(),
+      WrapRunnableNMRet(&vcmGetIceStream_m,
                         mcap_id,
                         group_id,
                         stream_id,
                         call_handle,
                         peerconnection,
                         level,
+                        &ctx,
+                        &stream,
+                        &ret));
+  if (ret)
+    return ret;
+
+  // Now get the ICE parameters from the STS thread.
+  // We .forget() the strong refs so that they can be
+  // released on the STS thread.
+  mozilla::SyncRunnable::DispatchToThread(
+      VcmSIPCCBinding::getSTSThread(),
+                        WrapRunnableNMRet(&vcmRxAllocICE_s,
+                        ctx.forget(),
+                        stream.forget(),
+                        call_handle,
+                        stream_id,
+                        level,
                         default_addrp,
                         default_portp,
                         candidatesp,
                         candidate_ctp,
                         &ret));
+
   return ret;
 }
 
 /* Get ICE global parameters (ufrag and pwd)
  *  @param[in]  peerconnection - the peerconnection in use
  *  @param[out] ufragp - where to put the ufrag
  *  @param[out] pwdp - where to put the pwd
  *
--- a/media/webrtc/signaling/src/media/VcmSIPCCBinding.h
+++ b/media/webrtc/signaling/src/media/VcmSIPCCBinding.h
@@ -58,16 +58,17 @@ namespace CSF
         static void setAudioCodecs(int codecMask);
         static void setVideoCodecs(int codecMask);
 
         static int getAudioCodecs();
         static int getVideoCodecs();
 
 	static void setMainThread(nsIThread *thread);
 	static nsIThread *getMainThread();
+	static nsIEventTarget *getSTSThread();
 
 	static void setSTSThread(nsIEventTarget *thread);
 
 	static void connectCandidateSignal(mozilla::NrIceMediaStream* stream);
 
     private:
 	void CandidateReady(mozilla::NrIceMediaStream* stream,
 			    const std::string& candidate);
--- a/mfbt/FloatingPoint.h
+++ b/mfbt/FloatingPoint.h
@@ -134,17 +134,22 @@ IsNegative(double d)
 static MOZ_ALWAYS_INLINE bool
 IsNegativeZero(double d)
 {
   /* Only the sign bit is set if the double is -0. */
   uint64_t bits = BitwiseCast<uint64_t>(d);
   return bits == DoubleSignBit;
 }
 
-/** Returns the exponent portion of the double. */
+/**
+ * Returns the exponent portion of the double.
+ *
+ * Zero is not special-cased, so ExponentComponent(0.0) is
+ * -int_fast16_t(DoubleExponentBias).
+ */
 static MOZ_ALWAYS_INLINE int_fast16_t
 ExponentComponent(double d)
 {
   /*
    * The exponent component of a double is an unsigned number, biased from its
    * actual value.  Subtract the bias to retrieve the actual exponent.
    */
   uint64_t bits = BitwiseCast<uint64_t>(d);
--- a/mfbt/tests/TestFloatingPoint.cpp
+++ b/mfbt/tests/TestFloatingPoint.cpp
@@ -3,16 +3,18 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/FloatingPoint.h"
 
 #include <math.h>
 
 using mozilla::DoublesAreIdentical;
+using mozilla::DoubleExponentBias;
+using mozilla::ExponentComponent;
 using mozilla::IsFinite;
 using mozilla::IsInfinite;
 using mozilla::IsNaN;
 using mozilla::IsNegative;
 using mozilla::IsNegativeZero;
 using mozilla::NegativeInfinity;
 using mozilla::PositiveInfinity;
 using mozilla::SpecificNaN;
@@ -98,16 +100,32 @@ TestDoublesAreIdentical()
   ShouldNotBeIdentical(UnspecifiedNaN(), -0.0);
   ShouldNotBeIdentical(UnspecifiedNaN(), 1.0);
   ShouldNotBeIdentical(UnspecifiedNaN(), -1.0);
   ShouldNotBeIdentical(UnspecifiedNaN(), PositiveInfinity());
   ShouldNotBeIdentical(UnspecifiedNaN(), NegativeInfinity());
 }
 
 static void
+TestExponentComponent()
+{
+  MOZ_ASSERT(ExponentComponent(0.0) == -int_fast16_t(DoubleExponentBias));
+  MOZ_ASSERT(ExponentComponent(-0.0) == -int_fast16_t(DoubleExponentBias));
+  MOZ_ASSERT(ExponentComponent(0.125) == -3);
+  MOZ_ASSERT(ExponentComponent(0.5) == -1);
+  MOZ_ASSERT(ExponentComponent(1.0) == 0);
+  MOZ_ASSERT(ExponentComponent(1.5) == 0);
+  MOZ_ASSERT(ExponentComponent(2.0) == 1);
+  MOZ_ASSERT(ExponentComponent(7) == 2);
+  MOZ_ASSERT(ExponentComponent(PositiveInfinity()) == DoubleExponentBias + 1);
+  MOZ_ASSERT(ExponentComponent(NegativeInfinity()) == DoubleExponentBias + 1);
+  MOZ_ASSERT(ExponentComponent(UnspecifiedNaN()) == DoubleExponentBias + 1);
+}
+
+static void
 TestPredicates()
 {
   MOZ_ASSERT(IsNaN(UnspecifiedNaN()));
   MOZ_ASSERT(IsNaN(SpecificNaN(1, 17)));;
   MOZ_ASSERT(IsNaN(SpecificNaN(0, 0xfffffffffff0fULL)));
   MOZ_ASSERT(!IsNaN(0));
   MOZ_ASSERT(!IsNaN(-0.0));
   MOZ_ASSERT(!IsNaN(1.0));
@@ -147,10 +165,11 @@ TestPredicates()
   MOZ_ASSERT(!IsNegativeZero(-1.0));
   MOZ_ASSERT(!IsNegativeZero(1.0));
 }
 
 int
 main()
 {
   TestDoublesAreIdentical();
+  TestExponentComponent();
   TestPredicates();
 }
--- a/netwerk/cache2/OldWrappers.cpp
+++ b/netwerk/cache2/OldWrappers.cpp
@@ -699,16 +699,21 @@ NS_IMETHODIMP _OldStorage::AsyncOpenURI(
 
   nsAutoCString cacheKey;
   rv = AssembleCacheKey(aURI, aIdExtension, cacheKey);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!mAppCache && (mLookupAppCache || mOfflineStorage)) {
     rv = ChooseApplicationCache(cacheKey, getter_AddRefs(mAppCache));
     NS_ENSURE_SUCCESS(rv, rv);
+
+    if (mAppCache) {
+      // From a chosen appcache open only as readonly
+      aFlags &= ~nsICacheStorage::OPEN_TRUNCATE;
+    }
   }
 
   nsRefPtr<_OldCacheLoad> cacheLoad =
     new _OldCacheLoad(cacheKey, aCallback, mAppCache,
                       mLoadInfo, mWriteToDisk, aFlags);
 
   rv = cacheLoad->Start();
   NS_ENSURE_SUCCESS(rv, rv);
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -2527,17 +2527,17 @@ nsHttpChannel::OpenCacheEntry(bool using
     else {
         rv = cacheStorageService->DiskCacheStorage(info,
             mChooseApplicationCache || (mLoadFlags & LOAD_CHECK_OFFLINE_CACHE),
             getter_AddRefs(cacheStorage));
     }
     NS_ENSURE_SUCCESS(rv, rv);
 
     uint32_t cacheEntryOpenFlags;
-    if (BYPASS_LOCAL_CACHE(mLoadFlags))
+    if (BYPASS_LOCAL_CACHE(mLoadFlags) && !mApplicationCache)
         cacheEntryOpenFlags = nsICacheStorage::OPEN_TRUNCATE;
     else
         cacheEntryOpenFlags = nsICacheStorage::OPEN_NORMALLY;
 
     if (mLoadAsBlocking || mLoadUnblocked ||
         (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)) {
         cacheEntryOpenFlags |= nsICacheStorage::OPEN_PRIORITY;
     }
--- a/testing/marionette/client/marionette/marionette.py
+++ b/testing/marionette/client/marionette/marionette.py
@@ -1181,24 +1181,16 @@ class Marionette(object):
           marionette.import_script(js)
           assert "i'm a test function!" == self.marionette.execute_script("return testFunc();")
         '''
         js = ''
         with open(js_file, 'r') as f:
             js = f.read()
         return self._send_message('importScript', 'ok', script=js)
 
-    def clear_imported_scripts(self):
-        '''
-        Clears all imported scripts in this context, ie: calling clear_imported_scripts in chrome
-        context will clear only scripts you imported in chrome, and will leave the scripts
-        you imported in content context.
-        '''
-        return self._send_message('clearImportedScripts', 'ok')
-
     def add_cookie(self, cookie):
         """
         Adds a cookie to your current session.
 
         :param cookie: A dictionary object, with required keys - "name" and
          "value"; optional keys - "path", "domain", "secure", "expiry".
 
         Usage example:
--- a/testing/marionette/client/marionette/tests/unit/test_import_script.py
+++ b/testing/marionette/client/marionette/tests/unit/test_import_script.py
@@ -1,110 +1,23 @@
+
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import os
 from marionette_test import MarionetteTestCase
-from errors import JavascriptException
 
 class TestImportScript(MarionetteTestCase):
-    def setUp(self):
-        MarionetteTestCase.setUp(self)
-
-    def clear_other_context(self):
-        self.marionette.set_context("chrome")
-        self.marionette.clear_imported_scripts()
-        self.marionette.set_context("content")
-
-    def check_file_exists(self):
-        return self.marionette.execute_script("""
-          let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm").FileUtils;
-          let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); 
-          return importedScripts.exists();
-        """, special_powers=True)
-
-    def get_file_size(self):
-        return self.marionette.execute_script("""
-          let FileUtils = SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm").FileUtils;
-          let importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']); 
-          return importedScripts.fileSize;
-        """, special_powers=True)
-
     def test_import_script(self):
         js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
         self.marionette.import_script(js)
         self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
         self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
 
-    def test_import_script_twice(self):
-        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
-        self.marionette.import_script(js)
-        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
-        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
-        self.assertTrue(self.check_file_exists())
-        file_size = self.get_file_size()
-        self.assertNotEqual(file_size, None)
-        self.marionette.import_script(js)
-        file_size = self.get_file_size()
-        self.assertEqual(file_size, self.get_file_size())
-        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
-        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
-
-    def test_import_two_scripts_twice(self):
-        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
-        self.marionette.import_script(js)
-        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
-        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
-        self.assertTrue(self.check_file_exists())
-        file_size = self.get_file_size()
-        self.assertNotEqual(file_size, None)
-        self.marionette.import_script(js)
-        # same script should not append to file
-        self.assertEqual(file_size, self.get_file_size())
-        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
-        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
-        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
-        self.marionette.import_script(js)
-        new_size = self.get_file_size()
-        # new script should append to file
-        self.assertNotEqual(file_size, new_size)
-        file_size = new_size
-        self.assertEqual("i'm yet another test function!",
-                    self.marionette.execute_script("return testAnotherFunc();"))
-        self.assertEqual("i'm yet another test function!",
-                    self.marionette.execute_async_script("marionetteScriptFinished(testAnotherFunc());"))
-        self.marionette.import_script(js)
-        # same script should not append to file
-        self.assertEqual(file_size, self.get_file_size())
-
-    def test_import_script_and_clear(self):
-        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
-        self.marionette.import_script(js)
-        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
-        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
-        self.marionette.clear_imported_scripts()
-        self.assertFalse(self.check_file_exists())
-        self.assertRaises(JavascriptException, self.marionette.execute_script, "return testFunc();")
-        self.assertRaises(JavascriptException, self.marionette.execute_async_script, "marionetteScriptFinished(testFunc());")
-
-    def test_import_script_and_clear_in_chrome(self):
-        js = os.path.abspath(os.path.join(__file__, os.path.pardir, "importscript.js"))
-        self.marionette.import_script(js)
-        self.assertTrue(self.check_file_exists())
-        file_size = self.get_file_size()
-        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
-        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
-        self.clear_other_context()
-        # clearing other context's script file should not affect ours
-        self.assertTrue(self.check_file_exists())
-        self.assertEqual(file_size, self.get_file_size())
-        self.assertEqual("i'm a test function!", self.marionette.execute_script("return testFunc();"))
-        self.assertEqual("i'm a test function!", self.marionette.execute_async_script("marionetteScriptFinished(testFunc());"))
-
     def test_importing_another_script_and_check_they_append(self):
         firstjs = os.path.abspath(
                 os.path.join(__file__, os.path.pardir, "importscript.js"))
         secondjs = os.path.abspath(
                 os.path.join(__file__, os.path.pardir, "importanotherscript.js"))
 
         self.marionette.import_script(firstjs)
         self.marionette.import_script(secondjs)
@@ -113,46 +26,9 @@ class TestImportScript(MarionetteTestCas
                 self.marionette.execute_script("return testFunc();"))
 
         self.assertEqual("i'm yet another test function!",
                     self.marionette.execute_script("return testAnotherFunc();"))
 
 class TestImportScriptChrome(TestImportScript):
     def setUp(self):
         MarionetteTestCase.setUp(self)
-        self.marionette.set_script_timeout(30000)
         self.marionette.set_context("chrome")
-
-    def clear_other_context(self):
-        self.marionette.set_context("content")
-        self.marionette.clear_imported_scripts()
-        self.marionette.set_context("chrome")
-
-    def check_file_exists(self):
-        return self.marionette.execute_async_script("""
-          Components.utils.import("resource://gre/modules/FileUtils.jsm");
-          let checkTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
-          let f = function() {
-            if (typeof FileUtils === 'undefined') {
-              checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
-              return;
-            }
-            let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); 
-            marionetteScriptFinished(importedScripts.exists());
-          };
-          checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
-        """)
-
-    def get_file_size(self):
-        return self.marionette.execute_async_script("""
-          Components.utils.import("resource://gre/modules/FileUtils.jsm");
-          let checkTimer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
-          let f = function() {
-            if (typeof FileUtils === 'undefined') {
-              checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
-              return;
-            }
-            let importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']); 
-            marionetteScriptFinished(importedScripts.fileSize);
-          };
-          checkTimer.initWithCallback(f, 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
-        """)
-
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -91,17 +91,17 @@ let modalHandler = function() {
  * If the actor returns an ID, we start the listeners. Otherwise, nothing happens.
  */
 function registerSelf() {
   let msg = {value: winUtil.outerWindowID, href: content.location.href};
   let register = sendSyncMessage("Marionette:register", msg);
 
   if (register[0]) {
     listenerId = register[0].id;
-    importedScripts = FileUtils.getFile('TmpD', ['marionetteContentScripts']);
+    importedScripts = FileUtils.File(register[0].importedScripts);
     startListeners();
   }
 }
 
 /**
  * Add a message listener that's tied to our listenerId.
  */
 function addMessageListenerId(messageName, handler) {
--- a/testing/marionette/marionette-server.js
+++ b/testing/marionette/marionette-server.js
@@ -129,18 +129,17 @@ function MarionetteServerConnection(aPre
   this.pageTimeout = null;
   this.timer = null;
   this.inactivityTimer = null;
   this.heartbeatCallback = function () {}; // called by simpletest methods
   this.marionetteLog = new MarionetteLogObj();
   this.command_id = null;
   this.mainFrame = null; //topmost chrome frame
   this.curFrame = null; // chrome iframe that currently has focus
-  this.importedScripts = FileUtils.getFile('TmpD', ['marionetteChromeScripts']);
-  this.importedScriptHashes = {"chrome" : [], "content": []};
+  this.importedScripts = FileUtils.getFile('TmpD', ['marionettescriptchrome']);
   this.currentFrameElement = null;
   this.testName = null;
   this.mozBrowserClose = null;
 }
 
 MarionetteServerConnection.prototype = {
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
@@ -462,26 +461,16 @@ MarionetteServerConnection.prototype = {
     }
   },
 
   getCommandId: function MDA_getCommandId() {
     return this.uuidGen.generateUUID().toString();
   },
 
   /**
-    * Given a file name, this will delete the file from the temp directory if it exists
-    */
-  deleteFile: function(filename) {
-    let file = FileUtils.getFile('TmpD', [filename.toString()]);
-    if (file.exists()) {
-      file.remove(true);
-    }
-  },
-
-  /**
    * Marionette API:
    *
    * All methods implementing a command from the client should create a
    * command_id, and then use this command_id in all messages exchanged with
    * the frame scripts and with responses sent to the client.  This prevents
    * commands and responses from getting out-of-sync, which can happen in
    * the case of execute_async calls that timeout and then later send a
    * response, and other situations.  See bug 779011. See setScriptTimeout()
@@ -1939,23 +1928,17 @@ MarionetteServerConnection.prototype = {
       let winEnum = this.getWinEnumerator();
       while (winEnum.hasMoreElements()) {
         numOpenWindows += 1;
         winEnum.getNext(); 
       }
 
       // if there is only 1 window left, delete the session
       if (numOpenWindows === 1){
-        try {
-          this.sessionTearDown();
-        }
-        catch (e) {
-          this.sendError("Could not clear session", 500, e.name + ": " + e.message, command_id);
-          return;
-        }
+        this.sessionTearDown();
         this.sendOk(command_id);
         return;
       }
 
       try{
         this.messageManager.removeDelayedFrameScript(FRAME_SCRIPT); 
         this.getCurrentWindow().close();
         this.sendOk(command_id);
@@ -2002,33 +1985,30 @@ MarionetteServerConnection.prototype = {
       this.curBrowser.frameManager.removeMessageManagerListeners(this.globalMessageManager);
     }
     this.switchToGlobalMessageManager();
     // reset frame to the top-most frame
     this.curFrame = null;
     if (this.mainFrame) {
       this.mainFrame.focus();
     }
-    this.deleteFile('marionetteChromeScripts');
-    this.deleteFile('marionetteContentScripts');
+    try {
+      this.importedScripts.remove(false);
+    }
+    catch (e) {
+    }
   },
 
   /**
    * Processes the 'deleteSession' request from the client by tearing down
    * the session and responding 'ok'.
    */
-  deleteSession: function MDA_deleteSession() {
+  deleteSession: function MDA_sessionTearDown() {
     let command_id = this.command_id = this.getCommandId();
-    try {
-      this.sessionTearDown();
-    }
-    catch (e) {
-      this.sendError("Could not delete session", 500, e.name + ": " + e.message, command_id);
-      return;
-    }
+    this.sessionTearDown();
     this.sendOk(command_id);
   },
 
   /**
    * Returns the current status of the Application Cache
    */
   getAppCacheStatus: function MDA_getAppCacheStatus(aRequest) {
     this.command_id = this.getCommandId();
@@ -2069,33 +2049,16 @@ MarionetteServerConnection.prototype = {
     catch(e) {
       this.sendError(e.message, e.code, e.stack, -1);
       return;
     }
   },
   
   importScript: function MDA_importScript(aRequest) {
     let command_id = this.command_id = this.getCommandId();
-    let converter =
-      Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
-          createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
-    converter.charset = "UTF-8";
-    let result = {};
-    let data = converter.convertToByteArray(aRequest.script, result);
-    let ch = Components.classes["@mozilla.org/security/hash;1"]
-                       .createInstance(Components.interfaces.nsICryptoHash);
-    ch.init(ch.MD5);
-    ch.update(data, data.length);
-    let hash = ch.finish(true);
-    if (this.importedScriptHashes[this.context].indexOf(hash) > -1) {
-        //we have already imported this script
-        this.sendOk(command_id);
-        return;
-    }
-    this.importedScriptHashes[this.context].push(hash);
     if (this.context == "chrome") {
       let file;
       if (this.importedScripts.exists()) {
         file = FileUtils.openFileOutputStream(this.importedScripts,
             FileUtils.MODE_APPEND | FileUtils.MODE_WRONLY);
       }
       else {
         //Note: The permission bits here don't actually get set (bug 804563)
@@ -2111,33 +2074,16 @@ MarionetteServerConnection.prototype = {
     }
     else {
       this.sendAsync("importScript",
                      { script: aRequest.script },
                      command_id);
     }
   },
 
-  clearImportedScripts: function MDA_clearImportedScripts(aRequest) {
-    let command_id = this.command_id = this.getCommandId();
-    try {
-      if (this.context == "chrome") {
-        this.deleteFile('marionetteChromeScripts');
-      }
-      else {
-        this.deleteFile('marionetteContentScripts');
-      }
-    }
-    catch (e) {
-      this.sendError("Could not clear imported scripts", 500, e.name + ": " + e.message, command_id);
-      return;
-    }
-    this.sendOk(command_id);
-  },
-
   /**
    * Takes a screenshot of a DOM node. If there is no node given a screenshot
    * of the window will be taken.
    */
   screenShot: function MDA_saveScreenshot(aRequest) {
     this.command_id = this.getCommandId();
     this.sendAsync("screenShot",
                    {
@@ -2245,16 +2191,17 @@ MarionetteServerConnection.prototype = {
         }
         let reg = {};
         if (!browserType || browserType != "content") {
           //curBrowser holds all the registered frames in knownFrames
           reg.id = this.curBrowser.register(this.generateFrameId(message.json.value),
                                             listenerWindow);
         }
         this.curBrowser.elementManager.seenItems[reg.id] = Cu.getWeakReference(listenerWindow);
+        reg.importedScripts = this.importedScripts.path;
         if (nullPrevious && (this.curBrowser.curFrameId != null)) {
           if (!this.sendAsync("newSession",
                               { B2G: (appName == "B2G") },
                               this.newSessionCommandId)) {
             return;
           }
           if (this.curBrowser.newSession) {
             this.sendResponse(reg.id, this.newSessionCommandId);
@@ -2309,17 +2256,16 @@ MarionetteServerConnection.prototype.req
   "getWindow":  MarionetteServerConnection.prototype.getWindow,
   "getWindows":  MarionetteServerConnection.prototype.getWindows,
   "getActiveFrame": MarionetteServerConnection.prototype.getActiveFrame,
   "switchToFrame": MarionetteServerConnection.prototype.switchToFrame,
   "switchToWindow": MarionetteServerConnection.prototype.switchToWindow,
   "deleteSession": MarionetteServerConnection.prototype.deleteSession,
   "emulatorCmdResult": MarionetteServerConnection.prototype.emulatorCmdResult,
   "importScript": MarionetteServerConnection.prototype.importScript,
-  "clearImportedScripts": MarionetteServerConnection.prototype.clearImportedScripts,
   "getAppCacheStatus": MarionetteServerConnection.prototype.getAppCacheStatus,
   "closeWindow": MarionetteServerConnection.prototype.closeWindow,
   "setTestName": MarionetteServerConnection.prototype.setTestName,
   "screenShot": MarionetteServerConnection.prototype.screenShot,
   "addCookie": MarionetteServerConnection.prototype.addCookie,
   "getAllCookies": MarionetteServerConnection.prototype.getAllCookies,
   "deleteAllCookies": MarionetteServerConnection.prototype.deleteAllCookies,
   "deleteCookie": MarionetteServerConnection.prototype.deleteCookie,
--- a/testing/specialpowers/content/MockFilePicker.jsm
+++ b/testing/specialpowers/content/MockFilePicker.jsm
@@ -43,17 +43,21 @@ this.MockFilePicker = {
   filterImages: Ci.nsIFilePicker.filterImages,
   filterXML: Ci.nsIFilePicker.filterXML,
   filterXUL: Ci.nsIFilePicker.filterXUL,
   filterApps: Ci.nsIFilePicker.filterApps,
   filterAllowURLs: Ci.nsIFilePicker.filterAllowURLs,
   filterAudio: Ci.nsIFilePicker.filterAudio,
   filterVideo: Ci.nsIFilePicker.filterVideo,
 
+  window: null,
+
   init: function(window) {
+    this.window = window;
+
     this.reset();
     this.factory = newFactory(window);
     if (!registrar.isCIDRegistered(newClassID)) {
       oldClassID = registrar.contractIDToCID(CONTRACT_ID);
       oldFactory = Cm.getClassObject(Cc[CONTRACT_ID], Ci.nsIFactory);
       registrar.unregisterFactory(oldClassID, oldFactory);
       registrar.registerFactory(newClassID, "", CONTRACT_ID, this.factory);
     }
@@ -81,16 +85,32 @@ this.MockFilePicker = {
       registrar.registerFactory(oldClassID, "", CONTRACT_ID, oldFactory);
     }
   },
 
   useAnyFile: function() {
     var file = FileUtils.getFile("TmpD", ["testfile"]);
     file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0644);
     this.returnFiles = [file];
+  },
+
+  useBlobFile: function() {
+    var blob = new this.window.Blob([]);
+    var file = new this.window.File(blob, { name: 'helloworld.txt', type: 'plain/text' });
+    this.returnFiles = [file];
+  },
+
+  isNsIFile: function(aFile) {
+    let ret = false;
+    try {
+      if (aFile.QueryInterface(Ci.nsIFile))
+        ret = true;
+    } catch(e) {}
+
+    return ret;
   }
 };
 
 function MockFilePickerInstance(window) {
   this.window = window;
 };
 MockFilePickerInstance.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
@@ -108,55 +128,76 @@ MockFilePickerInstance.prototype = {
       MockFilePicker.appendFiltersCallback(this, aFilterMask);
   },
   defaultString: "",
   defaultExtension: "",
   parent: null,
   filterIndex: 0,
   displayDirectory: null,
   get file() {
-    if (MockFilePicker.returnFiles.length >= 1)
+    if (MockFilePicker.returnFiles.length >= 1 &&
+        // window.File does not implement nsIFile
+        MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
       return MockFilePicker.returnFiles[0];
+    }
+
     return null;
   },
   get domfile()  {
     if (MockFilePicker.returnFiles.length >= 1) {
+      // window.File does not implement nsIFile
+      if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
+        return MockFilePicker.returnFiles[0];
+      }
+
       let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDOMWindowUtils);
       return utils.wrapDOMFile(MockFilePicker.returnFiles[0]);
     }
     return null;
   },
   get fileURL() {
-    if (MockFilePicker.returnFiles.length >= 1)
+    if (MockFilePicker.returnFiles.length >= 1 &&
+        // window.File does not implement nsIFile
+        MockFilePicker.isNsIFile(MockFilePicker.returnFiles[0])) {
       return Services.io.newFileURI(MockFilePicker.returnFiles[0]);
+    }
+
     return null;
   },
   get files() {
     return {
       index: 0,
       QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
       hasMoreElements: function() {
         return this.index < MockFilePicker.returnFiles.length;
       },
       getNext: function() {
+        // window.File does not implement nsIFile
+        if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
+          return null;
+        }
         return MockFilePicker.returnFiles[this.index++];
       }
     };
   },
   get domfiles()  {
     let utils = this.parent.QueryInterface(Ci.nsIInterfaceRequestor)
-                      .getInterface(Ci.nsIDOMWindowUtils);
+                           .getInterface(Ci.nsIDOMWindowUtils);
     return {
       index: 0,
       QueryInterface: XPCOMUtils.generateQI([Ci.nsISimpleEnumerator]),
       hasMoreElements: function() {
         return this.index < MockFilePicker.returnFiles.length;
       },
       getNext: function() {
+        // window.File does not implement nsIFile
+        if (!MockFilePicker.isNsIFile(MockFilePicker.returnFiles[this.index])) {
+          return MockFilePicker.returnFiles[this.index++];
+        }
         return utils.wrapDOMFile(MockFilePicker.returnFiles[this.index++]);
       }
     };
   },
   show: function() {
     MockFilePicker.displayDirectory = this.displayDirectory;
     MockFilePicker.shown = true;
     if (typeof MockFilePicker.showCallback == "function") {
--- a/toolkit/components/aboutmemory/content/aboutMemory.js
+++ b/toolkit/components/aboutmemory/content/aboutMemory.js
@@ -45,20 +45,18 @@ XPCOMUtils.defineLazyGetter(this, "nsGzi
                             () => CC("@mozilla.org/streamconv;1?from=gzip&to=uncompressed",
                                      "nsIStreamConverter"));
 
 let gMgr = Cc["@mozilla.org/memory-reporter-manager;1"]
              .getService(Ci.nsIMemoryReporterManager);
 
 // We need to know about "child-memory-reporter-update" events from child
 // processes.
-let gOs = Cc["@mozilla.org/observer-service;1"]
-            .getService(Ci.nsIObserverService);
-gOs.addObserver(updateAboutMemoryFromReporters,
-                "child-memory-reporter-update", false);
+Services.obs.addObserver(updateAboutMemoryFromReporters,
+                         "child-memory-reporter-update", false);
 
 let gUnnamedProcessStr = "Main Process";
 
 let gIsDiff = false;
 
 //---------------------------------------------------------------------------
 
 // Forward slashes in URLs in paths are represented with backslashes to avoid
@@ -117,18 +115,18 @@ function debug(x)
   let section = appendElement(document.body, 'div', 'section');
   appendElementWithText(section, "div", "debug", JSON.stringify(x));
 }
 
 //---------------------------------------------------------------------------
 
 function onUnload()
 {
-  gOs.removeObserver(updateAboutMemoryFromReporters,
-                     "child-memory-reporter-update");
+  Services.obs.removeObserver(updateAboutMemoryFromReporters,
+                              "child-memory-reporter-update");
 }
 
 //---------------------------------------------------------------------------
 
 /**
  * Iterates over each reporter.
  *
  * @param aHandleReport
@@ -406,46 +404,42 @@ function onLoad()
   }
 }
 
 //---------------------------------------------------------------------------
 
 function doGC()
 {
   Cu.forceGC();
-  let os = Cc["@mozilla.org/observer-service;1"]
-             .getService(Ci.nsIObserverService);
-  os.notifyObservers(null, "child-gc-request", null);
+  Services.obs.notifyObservers(null, "child-gc-request", null);
   updateMainAndFooter("Garbage collection completed", HIDE_FOOTER);
 }
 
 function doCC()
 {
   window.QueryInterface(Ci.nsIInterfaceRequestor)
         .getInterface(Ci.nsIDOMWindowUtils)
         .cycleCollect();
-  let os = Cc["@mozilla.org/observer-service;1"]
-             .getService(Ci.nsIObserverService);
-  os.notifyObservers(null, "child-cc-request", null);
+  Services.obs.notifyObservers(null, "child-cc-request", null);
   updateMainAndFooter("Cycle collection completed", HIDE_FOOTER);
 }
 
 function doMMU()
 {
   gMgr.minimizeMemoryUsage(
     () => updateMainAndFooter("Memory minimization completed", HIDE_FOOTER));
 }
 
 function doMeasure()
 {
   // Notify any children that they should measure memory consumption, then
   // update the page.  If any reports come back from children,
   // updateAboutMemoryFromReporters() will be called again and the page will
   // regenerate.
-  gOs.notifyObservers(null, "child-memory-reporter-request", null);
+  Services.obs.notifyObservers(null, "child-memory-reporter-request", null);
   updateAboutMemoryFromReporters();
 }
 
 /**
  * Top-level function that does the work of generating the page from the memory
  * reporters.
  */
 function updateAboutMemoryFromReporters()
@@ -611,26 +605,24 @@ function updateAboutMemoryFromTwoFiles(a
 
 /**
  * Like updateAboutMemoryFromFile(), but gets its data from the clipboard
  * instead of a file.
  */
 function updateAboutMemoryFromClipboard()
 {
   // Get the clipboard's contents.
-  let cb = Cc["@mozilla.org/widget/clipboard;1"].
-           getService(Components.interfaces.nsIClipboard);
   let transferable = Cc["@mozilla.org/widget/transferable;1"]
                        .createInstance(Ci.nsITransferable);
   let loadContext = window.QueryInterface(Ci.nsIInterfaceRequestor)
                           .getInterface(Ci.nsIWebNavigation)
                           .QueryInterface(Ci.nsILoadContext);
   transferable.init(loadContext);
   transferable.addDataFlavor('text/unicode');
-  cb.getData(transferable, Ci.nsIClipboard.kGlobalClipboard);
+  Services.clipboard.getData(transferable, Ci.nsIClipboard.kGlobalClipboard);
 
   var cbData = {};
   try {
     transferable.getTransferData('text/unicode', cbData,
                                  /* out dataLen (ignored) */ {});
     let cbString = cbData.value.QueryInterface(Ci.nsISupportsString).data;
 
     // Success!  Now use the string to generate about:memory.
--- a/toolkit/components/startup/StartupTimeline.h
+++ b/toolkit/components/startup/StartupTimeline.h
@@ -1,16 +1,18 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifdef mozilla_StartupTimeline_Event
 mozilla_StartupTimeline_Event(PROCESS_CREATION, "process")
 mozilla_StartupTimeline_Event(START, "start")
 mozilla_StartupTimeline_Event(MAIN, "main")
+mozilla_StartupTimeline_Event(SELECT_PROFILE, "selectProfile")
+mozilla_StartupTimeline_Event(AFTER_PROFILE_LOCKED, "afterProfileLocked")
 // Record the beginning and end of startup crash detection to compare with crash stats to know whether
 // detection should be improved to start or end sooner.
 mozilla_StartupTimeline_Event(STARTUP_CRASH_DETECTION_BEGIN, "startupCrashDetectionBegin")
 mozilla_StartupTimeline_Event(STARTUP_CRASH_DETECTION_END, "startupCrashDetectionEnd")
 mozilla_StartupTimeline_Event(FIRST_PAINT, "firstPaint")
 mozilla_StartupTimeline_Event(SESSION_RESTORED, "sessionRestored")
 mozilla_StartupTimeline_Event(CREATE_TOP_LEVEL_WINDOW, "createTopLevelWindow")
 mozilla_StartupTimeline_Event(LINKER_INITIALIZED, "linkerInitialized")
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -2032,16 +2032,18 @@ static bool gDoProfileReset = false;
 // 3) check for -ProfileManager
 // 4) use the default profile, if there is one
 // 5) if there are *no* profiles, set up profile-migration
 // 6) display the profile-manager UI
 static nsresult
 SelectProfile(nsIProfileLock* *aResult, nsIToolkitProfileService* aProfileSvc, nsINativeAppSupport* aNative,
               bool* aStartOffline, nsACString* aProfileName)
 {
+  StartupTimeline::Record(StartupTimeline::SELECT_PROFILE);
+
   nsresult rv;
   ArgResult ar;
   const char* arg;
   *aResult = nullptr;
   *aStartOffline = false;
 
   ar = CheckArg("offline", true);
   if (ar == ARG_BAD) {
@@ -2306,27 +2308,41 @@ SelectProfile(nsIProfileLock* *aResult, 
 
         nsCOMPtr<nsIToolkitProfile> newProfile;
         rv = CreateResetProfile(aProfileSvc, getter_AddRefs(newProfile));
         if (NS_SUCCEEDED(rv))
           profile = newProfile;
         else
           gDoProfileReset = false;
       }
+
+      // If you close Firefox and very quickly reopen it, the old Firefox may
+      // still be closing down. Rather than immediately showing the
+      // "Firefox is running but is not responding" message, we spend a few
+      // seconds retrying first.
+
+      static const int kLockRetrySeconds = 5;
+      static const int kLockRetrySleepMS = 100;
+
       nsCOMPtr<nsIProfileUnlocker> unlocker;
-      rv = profile->Lock(getter_AddRefs(unlocker), aResult);
-      if (NS_SUCCEEDED(rv)) {
-        // Try to grab the profile name.
-        if (aProfileName) {
-          rv = profile->GetName(*aProfileName);
-          if (NS_FAILED(rv))
-            aProfileName->Truncate(0);
+      const TimeStamp start = TimeStamp::Now();
+      do {
+        rv = profile->Lock(getter_AddRefs(unlocker), aResult);
+        if (NS_SUCCEEDED(rv)) {
+          StartupTimeline::Record(StartupTimeline::AFTER_PROFILE_LOCKED);
+          // Try to grab the profile name.
+          if (aProfileName) {
+            rv = profile->GetName(*aProfileName);
+            if (NS_FAILED(rv))
+              aProfileName->Truncate(0);
+          }
+          return NS_OK;
         }
-        return NS_OK;
-      }
+        PR_Sleep(kLockRetrySleepMS);
+      } while (TimeStamp::Now() - start < TimeDuration::FromSeconds(kLockRetrySeconds));
 
       return ProfileLockedDialog(profile, unlocker, aNative, aResult);
     }
   }
 
   return ShowProfileManager(aProfileSvc, aNative);
 }
 
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -424,16 +424,18 @@ enum nsEventStructType
 
 // Pointerlock DOM API
 #define NS_POINTERLOCK_START         5300
 #define NS_POINTERLOCKCHANGE         (NS_POINTERLOCK_START)
 #define NS_POINTERLOCKERROR          (NS_POINTERLOCK_START + 1)
 
 #define NS_WHEEL_EVENT_START         5400
 #define NS_WHEEL_WHEEL               (NS_WHEEL_EVENT_START)
+#define NS_WHEEL_START               (NS_WHEEL_EVENT_START + 1)
+#define NS_WHEEL_STOP                (NS_WHEEL_EVENT_START + 2)
 
 //System time is changed
 #define NS_MOZ_TIME_CHANGE_EVENT     5500
 
 // Network packet events.
 #define NS_NETWORK_EVENT_START       5600
 #define NS_NETWORK_UPLOAD_EVENT      (NS_NETWORK_EVENT_START + 1)
 #define NS_NETWORK_DOWNLOAD_EVENT    (NS_NETWORK_EVENT_START + 2)
--- a/widget/cocoa/nsChildView.h
+++ b/widget/cocoa/nsChildView.h
@@ -200,16 +200,22 @@ typedef NSInteger NSEventGestureAxis;
 - (void)trackSwipeEventWithOptions:(NSEventSwipeTrackingOptions)options
           dampenAmountThresholdMin:(CGFloat)minDampenThreshold
                                max:(CGFloat)maxDampenThreshold
                       usingHandler:(void (^)(CGFloat gestureAmount, NSEventPhase phase, BOOL isComplete, BOOL *stop))trackingHandler;
 @end
 #endif // #ifdef __LP64__
 #endif // #if !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
 
+#if !defined(MAC_OS_X_VERSION_10_8) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
+enum {
+  NSEventPhaseMayBegin    = 0x1 << 5
+};
+#endif // #if !defined(MAC_OS_X_VERSION_10_8) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
+
 // Undocumented scrollPhase flag that lets us discern between real scrolls and
 // automatically firing momentum scroll events.
 @interface NSEvent (ScrollPhase)
 // Leopard and SnowLeopard
 - (long long)_scrollPhase;
 // Lion and above
 - (NSEventPhase)momentumPhase;
 @end
@@ -246,16 +252,21 @@ typedef NSInteger NSEventGestureAxis;
 
   // when acceptsFirstMouse: is called, we store the event here (strong)
   NSEvent* mClickThroughMouseDownEvent;
 
   // rects that were invalidated during a draw, so have pending drawing
   NSMutableArray* mPendingDirtyRects;
   BOOL mPendingFullDisplay;
   BOOL mPendingDisplay;
+  
+  // WheelStart/Stop events should always come in pairs. This BOOL records the
+  // last received event so that, when we receive one of the events, we make sure
+  // to send its pair event first, in case we didn't yet for any reason.
+  BOOL mExpectingWheelStop;
 
   // Holds our drag service across multiple drag calls. The reference to the
   // service is obtained when the mouse enters the view and is released when
   // the mouse exits or there is a drop. This prevents us from having to
   // re-establish the connection to the service manager many times per second
   // when handling |draggingUpdated:| messages.
   nsIDragService* mDragService;
 
@@ -349,16 +360,18 @@ typedef NSInteger NSEventGestureAxis;
 // http://cocoadex.com/2008/02/nsevent-modifications-swipe-ro.html
 - (void)swipeWithEvent:(NSEvent *)anEvent;
 - (void)beginGestureWithEvent:(NSEvent *)anEvent;
 - (void)magnifyWithEvent:(NSEvent *)anEvent;
 - (void)smartMagnifyWithEvent:(NSEvent *)anEvent;
 - (void)rotateWithEvent:(NSEvent *)anEvent;
 - (void)endGestureWithEvent:(NSEvent *)anEvent;
 
+- (void)scrollWheel:(NSEvent *)anEvent;
+
 // Helper function for Lion smart magnify events
 + (BOOL)isLionSmartMagnifyEvent:(NSEvent*)anEvent;
 
 // Support for fluid swipe tracking.
 #ifdef __LP64__
 - (void)maybeTrackScrollEventAsSwipe:(NSEvent *)anEvent
                       scrollOverflow:(double)overflow;
 #endif
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -135,18 +135,20 @@ uint32_t nsChildView::sLastInputEventCou
 
 @interface ChildView(Private)
 
 // sets up our view, attaching it to its owning gecko view
 - (id)initWithFrame:(NSRect)inFrame geckoChild:(nsChildView*)inChild;
 - (void)forceRefreshOpenGL;
 
 // set up a gecko mouse event based on a cocoa mouse event
+- (void) convertCocoaMouseWheelEvent:(NSEvent*)aMouseEvent
+                        toGeckoEvent:(WidgetWheelEvent*)outWheelEvent;
 - (void) convertCocoaMouseEvent:(NSEvent*)aMouseEvent
-                   toGeckoEvent:(WidgetInputEvent*)outGeckoEvent;
+                   toGeckoEvent:(WidgetInputEvent*)outWheelEvent;
 
 - (NSMenu*)contextMenu;
 
 - (void)setIsPluginView:(BOOL)aIsPlugin;
 - (void)setPluginEventModel:(NPEventModel)eventModel;
 - (void)setPluginDrawingModel:(NPDrawingModel)drawingModel;
 - (NPDrawingModel)pluginDrawingModel;
 
@@ -2771,16 +2773,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
     // We don't support the Quickdraw drawing model any more but it's still
     // the default model for i386 per NPAPI.
     mPluginDrawingModel = NPDrawingModelQuickDraw;
 #else
     mPluginDrawingModel = NPDrawingModelCoreGraphics;
 #endif
     mPendingDisplay = NO;
     mBlockedLastMouseDown = NO;
+    mExpectingWheelStop = NO;
 
     mLastMouseDownEvent = nil;
     mClickThroughMouseDownEvent = nil;
     mDragService = nullptr;
 
     mGestureState = eGestureState_None;
     mCumulativeMagnification = 0.0;
     mCumulativeRotation = 0.0;
@@ -4700,50 +4703,63 @@ NSEvent* gLastDragMouseDownEvent = nil;
 }
 
 static int32_t RoundUp(double aDouble)
 {
   return aDouble < 0 ? static_cast<int32_t>(floor(aDouble)) :
                        static_cast<int32_t>(ceil(aDouble));
 }
 
+- (void)sendWheelStartOrStop:(uint32_t)msg forEvent:(NSEvent *)theEvent
+{
+  WidgetWheelEvent wheelEvent(true, msg, mGeckoChild);
+  [self convertCocoaMouseWheelEvent:theEvent toGeckoEvent:&wheelEvent];
+  mExpectingWheelStop = (msg == NS_WHEEL_START);
+  mGeckoChild->DispatchWindowEvent(wheelEvent);
+}
+
+- (void)sendWheelCondition:(BOOL)condition first:(uint32_t)first second:(uint32_t)second forEvent:(NSEvent *)theEvent
+{
+  if (mExpectingWheelStop == condition) {
+    [self sendWheelStartOrStop:first forEvent:theEvent];
+  }
+  [self sendWheelStartOrStop:second forEvent:theEvent];
+}
+
 - (void)scrollWheel:(NSEvent*)theEvent
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   nsAutoRetainCocoaObject kungFuDeathGrip(self);
 
   ChildViewMouseTracker::MouseScrolled(theEvent);
 
   if ([self maybeRollup:theEvent]) {
     return;
   }
 
   if (!mGeckoChild) {
     return;
   }
 
-  WheelEvent wheelEvent(true, NS_WHEEL_WHEEL, mGeckoChild);
-  [self convertCocoaMouseEvent:theEvent toGeckoEvent:&wheelEvent];
-  wheelEvent.deltaMode =
-    Preferences::GetBool("mousewheel.enable_pixel_scrolling", true) ?
-      nsIDOMWheelEvent::DOM_DELTA_PIXEL : nsIDOMWheelEvent::DOM_DELTA_LINE;
-
-  // Calling deviceDeltaX or deviceDeltaY on theEvent will trigger a Cocoa
-  // assertion and an Objective-C NSInternalInconsistencyException if the
-  // underlying "Carbon" event doesn't contain pixel scrolling information.
-  // For these events, carbonEventKind is kEventMouseWheelMoved instead of
-  // kEventMouseScroll.
-  if (wheelEvent.deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) {
-    EventRef theCarbonEvent = [theEvent _eventRef];
-    UInt32 carbonEventKind = theCarbonEvent ? ::GetEventKind(theCarbonEvent) : 0;
-    if (carbonEventKind != kEventMouseScroll) {
-      wheelEvent.deltaMode = nsIDOMWheelEvent::DOM_DELTA_LINE;
-    }
-  }
+  NSEventPhase phase = [theEvent phase];
+
+  // Fire NS_WHEEL_START/STOP events when 2 fingers touch/release the touchpad.
+  if (phase & NSEventPhaseMayBegin) {
+    [self sendWheelCondition:YES first:NS_WHEEL_STOP second:NS_WHEEL_START forEvent:theEvent];
+    return;
+  }
+  
+  if (phase & (NSEventPhaseEnded | NSEventPhaseCancelled)) {
+    [self sendWheelCondition:NO first:NS_WHEEL_START second:NS_WHEEL_STOP forEvent:theEvent];
+    return;
+  }
+
+  WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, mGeckoChild);
+  [self convertCocoaMouseWheelEvent:theEvent toGeckoEvent:&wheelEvent];
 
   wheelEvent.lineOrPageDeltaX = RoundUp(-[theEvent deltaX]);
   wheelEvent.lineOrPageDeltaY = RoundUp(-[theEvent deltaY]);
 
   if (wheelEvent.deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) {
     // Some scrolling devices supports pixel scrolling, e.g. a Macbook
     // touchpad or a Mighty Mouse. On those devices, [theEvent deviceDeltaX/Y]
     // contains the amount of pixels to scroll. Since Lion this has changed 
@@ -4765,18 +4781,16 @@ static int32_t RoundUp(double aDouble)
   //       revert the sign.
   // wheelEvent.deltaZ = [theEvent deltaZ];
 
   if (!wheelEvent.deltaX && !wheelEvent.deltaY && !wheelEvent.deltaZ) {
     // No sense in firing off a Gecko event.
     return;
   }
 
-  wheelEvent.isMomentum = nsCocoaUtils::IsMomentumScrollEvent(theEvent);
-
   NPCocoaEvent cocoaEvent;
   ChildViewMouseTracker::AttachPluginEvent(wheelEvent, self, theEvent,
                                            NPCocoaEventScrollWheel,
                                            &cocoaEvent);
 
   mGeckoChild->DispatchWindowEvent(wheelEvent);
   if (!mGeckoChild) {
     return;
@@ -4842,16 +4856,39 @@ static int32_t RoundUp(double aDouble)
   if ([superView respondsToSelector:@selector(contextMenu)])
     return [(NSView<mozView>*)superView contextMenu];
 
   return nil;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
+- (void) convertCocoaMouseWheelEvent:(NSEvent*)aMouseEvent
+                        toGeckoEvent:(WidgetWheelEvent*)outWheelEvent
+{
+  [self convertCocoaMouseEvent:aMouseEvent toGeckoEvent:outWheelEvent];
+  outWheelEvent->deltaMode =
+    Preferences::GetBool("mousewheel.enable_pixel_scrolling", true) ?
+      nsIDOMWheelEvent::DOM_DELTA_PIXEL : nsIDOMWheelEvent::DOM_DELTA_LINE;
+
+  // Calling deviceDeltaX or deviceDeltaY on theEvent will trigger a Cocoa
+  // assertion and an Objective-C NSInternalInconsistencyException if the
+  // underlying "Carbon" event doesn't contain pixel scrolling information.
+  // For these events, carbonEventKind is kEventMouseWheelMoved instead of
+  // kEventMouseScroll.
+  if (outWheelEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) {
+    EventRef theCarbonEvent = [aMouseEvent _eventRef];
+    UInt32 carbonEventKind = theCarbonEvent ? ::GetEventKind(theCarbonEvent) : 0;
+    if (carbonEventKind != kEventMouseScroll) {
+      outWheelEvent->deltaMode = nsIDOMWheelEvent::DOM_DELTA_LINE;
+    }
+  }
+  outWheelEvent->isMomentum = nsCocoaUtils::IsMomentumScrollEvent(aMouseEvent);
+}
+
 - (void) convertCocoaMouseEvent:(NSEvent*)aMouseEvent
                    toGeckoEvent:(WidgetInputEvent*)outGeckoEvent
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
 
   NS_ASSERTION(outGeckoEvent, "convertCocoaMouseEvent:toGeckoEvent: requires non-null aoutGeckoEvent");
   if (!outGeckoEvent)
     return;
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -488,17 +488,17 @@ nsComponentManagerImpl::RegisterCIDEntry
         char idstr[NSID_LENGTH];
         aEntry->cid->ToProvidedString(idstr);
 
         nsCString existing;
         if (f->mModule)
             existing = f->mModule->Description();
         else
             existing = "<unknown module>";
-
+        SafeMutexAutoUnlock unlock(mLock);
         LogMessage("While registering XPCOM module %s, trying to re-register CID '%s' already registered by %s.",
                    aModule->Description().get(),
                    idstr,
                    existing.get());
         return;
     }
 
     f = new nsFactoryEntry(aEntry, aModule);
--- a/xpcom/ds/nsExpirationTracker.h
+++ b/xpcom/ds/nsExpirationTracker.h
@@ -291,16 +291,17 @@ template <class T, uint32_t K> class nsE
       void Init(nsExpirationTracker<T,K> *obj) {
         mOwner = obj;
         nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
         if (obs) {
           obs->AddObserver(this, "memory-pressure", false);
         }
       }
       void Destroy() {
+        mOwner = nullptr;
         nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
         if (obs)
           obs->RemoveObserver(this, "memory-pressure");
       }
       NS_DECL_ISUPPORTS
       NS_DECL_NSIOBSERVER
     private:
       nsExpirationTracker<T,K> *mOwner;
@@ -329,17 +330,17 @@ template <class T, uint32_t K> class nsE
 };
 
 template<class T, uint32_t K>
 NS_IMETHODIMP
 nsExpirationTracker<T, K>::ExpirationTrackerObserver::Observe(nsISupports     *aSubject,
                                                               const char      *aTopic,
                                                               const PRUnichar *aData)
 {
-  if (!strcmp(aTopic, "memory-pressure"))
+  if (!strcmp(aTopic, "memory-pressure") && mOwner)
     mOwner->AgeAllGenerations();
   return NS_OK;
 }
 
 template <class T, uint32_t K>
 NS_IMETHODIMP_(nsrefcnt)
 nsExpirationTracker<T,K>::ExpirationTrackerObserver::AddRef(void)
 {
--- a/xpcom/io/CocoaFileUtils.mm
+++ b/xpcom/io/CocoaFileUtils.mm
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 // vim:set ts=2 sts=2 sw=2 et cin:
 /* 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 "CocoaFileUtils.h"
+#include "nsCocoaUtils.h"
 #include <Cocoa/Cocoa.h>
 #include "nsObjCExceptions.h"
 #include "nsDebug.h"
 
 namespace CocoaFileUtils {
 
 nsresult RevealFileInFinder(CFURLRef url)
 {
@@ -43,28 +44,35 @@ nsresult OpenURL(CFURLRef url)
 
 nsresult GetFileCreatorCode(CFURLRef url, OSType *creatorCode)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   NS_ENSURE_ARG_POINTER(url);
   NS_ENSURE_ARG_POINTER(creatorCode);
 
-  nsresult rv = NS_ERROR_FAILURE;
+  nsAutoreleasePool localPool;
 
-  NSAutoreleasePool* ap = [[NSAutoreleasePool alloc] init];
-  NSDictionary* dict = [[NSFileManager defaultManager] fileAttributesAtPath:[(NSURL*)url path] traverseLink:YES];
+  NSString *resolvedPath = [[(NSURL*)url path] stringByResolvingSymlinksInPath];
+  if (!resolvedPath) {
+    return NS_ERROR_FAILURE;
+  }
+
+  NSDictionary* dict = [[NSFileManager defaultManager] attributesOfItemAtPath:resolvedPath error:nil];
+  if (!dict) {
+    return NS_ERROR_FAILURE;
+  }
+
   NSNumber* creatorNum = (NSNumber*)[dict objectForKey:NSFileHFSCreatorCode];
-  if (creatorNum) {
-    *creatorCode = [creatorNum unsignedLongValue];
-    rv = NS_OK;
+  if (!creatorNum) {
+    return NS_ERROR_FAILURE;
   }
-  [ap release];
 
-  return rv;
+  *creatorCode = [creatorNum unsignedLongValue];
+  return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 nsresult SetFileCreatorCode(CFURLRef url, OSType creatorCode)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
@@ -81,28 +89,35 @@ nsresult SetFileCreatorCode(CFURLRef url
 
 nsresult GetFileTypeCode(CFURLRef url, OSType *typeCode)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   NS_ENSURE_ARG_POINTER(url);
   NS_ENSURE_ARG_POINTER(typeCode);
 
-  nsresult rv = NS_ERROR_FAILURE;
+  nsAutoreleasePool localPool;
 
-  NSAutoreleasePool* ap = [[NSAutoreleasePool alloc] init];
-  NSDictionary* dict = [[NSFileManager defaultManager] fileAttributesAtPath:[(NSURL*)url path] traverseLink:YES];
+  NSString *resolvedPath = [[(NSURL*)url path] stringByResolvingSymlinksInPath];
+  if (!resolvedPath) {
+    return NS_ERROR_FAILURE;
+  }
+
+  NSDictionary* dict = [[NSFileManager defaultManager] attributesOfItemAtPath:resolvedPath error:nil];
+  if (!dict) {
+    return NS_ERROR_FAILURE;
+  }
+
   NSNumber* typeNum = (NSNumber*)[dict objectForKey:NSFileHFSTypeCode];
-  if (typeNum) {
-    *typeCode = [typeNum unsignedLongValue];
-    rv = NS_OK;
+  if (!typeNum) {
+    return NS_ERROR_FAILURE;
   }
-  [ap release];
 
-  return rv;
+  *typeCode = [typeNum unsignedLongValue];
+  return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 nsresult SetFileTypeCode(CFURLRef url, OSType typeCode)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
--- a/xpcom/io/nsLocalFileUnix.h
+++ b/xpcom/io/nsLocalFileUnix.h
@@ -56,17 +56,19 @@
 #elif defined(HAVE_STATFS64)
     #define STATFS statfs64
     #define F_BSIZE f_bsize
 #elif defined(HAVE_STATFS)
     #define STATFS statfs
     #define F_BSIZE f_bsize
 #endif
 
-#if defined(HAVE_STAT64) && defined(HAVE_LSTAT64)
+// stat64 and lstat64 are deprecated on OS X. Normal stat and lstat are
+// 64-bit by default on OS X 10.6+.
+#if defined(HAVE_STAT64) && defined(HAVE_LSTAT64) && !defined(XP_MACOSX)
     #if defined (AIX)
         #if defined STAT
             #undef STAT
         #endif
     #endif
     #define STAT stat64
     #define LSTAT lstat64
     #define HAVE_STATS64 1
--- a/xpcom/tests/component/TestComponent.cpp
+++ b/xpcom/tests/component/TestComponent.cpp
@@ -14,16 +14,17 @@ NS_DEFINE_NAMED_CID(NS_TESTING_CID);
 static nsresult
 DummyConstructorFunc(nsISupports* aOuter, const nsIID& aIID, void** aResult)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 static const mozilla::Module::CIDEntry kTestCIDs[] = {
   { &kNS_TESTING_CID, false, NULL, DummyConstructorFunc },
+  { &kNS_TESTING_CID, false, NULL, DummyConstructorFunc },
   { NULL }
 };
 
 static const mozilla::Module kTestModule = {
   mozilla::Module::kVersion,
   kTestCIDs
 };