Merge mozilla-central to mozilla-inbound
authorEd Morley <emorley@mozilla.com>
Tue, 12 Feb 2013 14:57:45 +0000
changeset 131512 628f616b8ddfd3e153cd58080e533de6ca073be4
parent 131472 860d7a47b675b212f98ccbc2cfe6a242ec0c377c (current diff)
parent 131511 06090cb1dc1f501c160acd8288516b346f24ccdd (diff)
child 131513 7da05ff6231c31163d9f3f0fe723fe44d848fccd
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone21.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 mozilla-central to mozilla-inbound
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -324,24 +324,28 @@ nsTextEquivUtils::AppendFromDOMNode(nsIC
 
   return AppendFromDOMChildren(aContent, aString);
 }
 
 bool
 nsTextEquivUtils::AppendString(nsAString *aString,
                                const nsAString& aTextEquivalent)
 {
-  // Insert spaces to insure that words from controls aren't jammed together.
   if (aTextEquivalent.IsEmpty())
     return false;
 
-  if (!aString->IsEmpty())
+  // Insert spaces to insure that words from controls aren't jammed together.
+  if (!aString->IsEmpty() && !IsWhitespace(aString->Last()))
     aString->Append(PRUnichar(' '));
 
   aString->Append(aTextEquivalent);
+
+  if (!IsWhitespace(aString->Last()))
+    aString->Append(PRUnichar(' '));
+
   return true;
 }
 
 bool
 nsTextEquivUtils::IsWhitespaceString(const nsSubstring& aString)
 {
   nsSubstring::const_char_iterator iterBegin, iterEnd;
 
--- a/accessible/tests/mochitest/name/test_general.html
+++ b/accessible/tests/mochitest/name/test_general.html
@@ -86,16 +86,19 @@
 
       // Gets the name from html:p content, which doesn't allow name from
       // subtree, ignore @title attribute on label
       testName("from_p_ignoretitle", "Choose country from.");
 
       // Gets the name from html:input value, ignore @title attribute on input
       testName("from_input_ignoretitle", "Custom country");
 
+      // Insert spaces around the control's value to not jamm sibling text nodes
+      testName("insert_spaces_around_control", "start value end");
+
       // Gets the name from @title, ignore whitespace content
       testName("from_label_ignore_ws_subtree", "about");
 
       //////////////////////////////////////////////////////////////////////////
       // label element
 
       // The label element contains the button. The name is calculated from
       // this button.
@@ -257,16 +260,21 @@
      title="HTML acronym and abbr names should be provided by @title">
     Bug 704416
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=812041"
      title="ARIA slider and spinbutton don't provide a value for name computation">
     Bug 812041
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=823927"
+     title="Text is jammed with control's text in name computation">
+    Bug 823927
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- aria-label, simple label -->
   <span id="btn_simple_aria_label" role="button" aria-label="I am a button"/>
   <br/>
@@ -384,16 +392,21 @@
 
   <!-- the name from subtree, name from html:input value rather than from its
     title attribute -->
   <p id="from_input_ignoretitle" aria-labelledby="input_ignoretitle">Country</p>
   <input id="input_ignoretitle"
          value="Custom country"
          title="Input your country of origin"/ >
 
+  <!-- name from subtree, surround control by spaces to not jamm the text -->
+  <label id="insert_spaces_around_control">
+    start<input value="value">end
+  </label>
+
   <!-- no name from subtree because it holds whitespaces only -->
   <a id="from_label_ignore_ws_subtree" href="about:" title="about">&nbsp;&nbsp;  </a>
 
   <!-- label element, label contains control -->
   <label>text<button id="btn_label_inside">10</button>text</label>
   <br/>
 
   <!-- label element, label and the button are in the same form -->
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -169,18 +169,16 @@ pref("geo.enabled", true);
 // see https://bugzilla.mozilla.org/show_bug.cgi?id=481566#c9
 pref("content.sink.enable_perf_mode",  2); // 0 - switch, 1 - interactive, 2 - perf
 pref("content.sink.pending_event_mode", 0);
 pref("content.sink.perf_deflect_count", 1000000);
 pref("content.sink.perf_parse_time", 50000000);
 
 // Maximum scripts runtime before showing an alert
 pref("dom.max_chrome_script_run_time", 0); // disable slow script dialog for chrome
-// Bug 817230 - disable the dialog until we implement its checkbox properly
-pref("dom.max_script_run_time", 0);
 
 // plugins
 pref("plugin.disable", true);
 pref("dom.ipc.plugins.enabled", true);
 
 // product URLs
 // The breakpad report server to link to in about:crashes
 pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
--- a/browser/themes/pinstripe/browser.css
+++ b/browser/themes/pinstripe/browser.css
@@ -2157,32 +2157,28 @@ toolbarbutton.chevron > .toolbarbutton-m
   list-style-image: url("chrome://browser/skin/tabbrowser/connecting.png");
 }
 
 .tab-throbber[progress] {
   list-style-image: url("chrome://browser/skin/tabbrowser/loading.png");
 }
 
 @media (min-resolution: 2dppx) {
-  .tab-throbber,
   .tab-icon-image {
     list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png");
+    image-rendering: -moz-crisp-edges;
   }
 
   .tab-throbber {
     list-style-image: url("chrome://browser/skin/tabbrowser/connecting@2x.png");
   }
 
   .tab-throbber[progress] {
     list-style-image: url("chrome://browser/skin/tabbrowser/loading@2x.png");
   }
-
-  .tab-icon-image {
-    image-rendering: -moz-crisp-edges;
-  }
 }
 
 .tabbrowser-tab:not(:hover) > .tab-stack > .tab-content > .tab-icon-image:not([selected="true"]) {
   opacity: .8;
 }
 
 .tabbrowser-tab:not([pinned]):not([fadein]) {
   transition: min-width 200ms ease-out /* copied from browser/base/content/browser.css */,
--- a/build/stlport/stl/config/_android.h.in
+++ b/build/stlport/stl/config/_android.h.in
@@ -9,15 +9,19 @@
 
 // No rtti support
 #undef _STLP_NO_RTTI
 #define _STLP_NO_RTTI 1
 
 // No throwing exceptions
 #undef _STLP_NO_EXCEPTIONS
 #define _STLP_NO_EXCEPTIONS 1
+#undef _STLP_NO_EXCEPTION_HEADER
+#define _STLP_NO_EXCEPTION_HEADER 1
+#undef _STLP_NO_UNCAUGHT_EXCEPT_SUPPORT
+#define _STLP_NO_UNCAUGHT_EXCEPT_SUPPORT 1
 
 #undef _STLP_NATIVE_CPP_C_HEADER
 #define _STLP_NATIVE_CPP_C_HEADER(header) <../../system/include/header>
 #undef _STLP_NATIVE_CPP_RUNTIME_HEADER
 #define _STLP_NATIVE_CPP_RUNTIME_HEADER(header) <../../system/include/header>
 
 #endif /* mozilla_stl_config__android_h */
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -420,12 +420,8 @@ DOMCI_CLASS(MozActivity)
 
 #ifdef MOZ_TIME_MANAGER
 DOMCI_CLASS(MozTimeManager)
 #endif
 
 #ifdef MOZ_WEBRTC
 DOMCI_CLASS(DataChannel)
 #endif
-
-#ifdef MOZ_AUDIO_CHANNEL_MANAGER
-DOMCI_CLASS(AudioChannelManager)
-#endif
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -128,16 +128,19 @@ static PRLogModuleInfo* gJSDiagnostics;
 // Don't allow an incremental GC to lock out the CC for too long.
 #define NS_MAX_CC_LOCKEDOUT_TIME    (15 * PR_USEC_PER_SEC) // 15 seconds
 
 // Trigger a CC if the purple buffer exceeds this size when we check it.
 #define NS_CC_PURPLE_LIMIT          200
 
 #define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT
 
+// Large value used to specify that a script should run essentially forever
+#define NS_UNLIMITED_SCRIPT_RUNTIME (0x40000000LL << 32)
+
 // if you add statics here, add them to the list in nsJSRuntime::Startup
 
 static nsITimer *sGCTimer;
 static nsITimer *sShrinkGCBuffersTimer;
 static nsITimer *sCCTimer;
 static nsITimer *sFullGCTimer;
 static nsITimer *sInterSliceGCTimer;
 
@@ -881,18 +884,23 @@ nsJSContext::DOMOperationCallback(JSCont
                          &buttonPressed);
 
   ::JS_SetOperationCallback(cx, DOMOperationCallback);
 
   if (NS_SUCCEEDED(rv) && (buttonPressed == 0)) {
     // Allow the script to continue running
 
     if (neverShowDlgChk) {
-      Preferences::SetInt(isTrackingChromeCodeTime ?
-        "dom.max_chrome_script_run_time" : "dom.max_script_run_time", 0);
+      if (isTrackingChromeCodeTime) {
+        Preferences::SetInt("dom.max_chrome_script_run_time", 0);
+        sMaxChromeScriptRunTime = NS_UNLIMITED_SCRIPT_RUNTIME;
+      } else {
+        Preferences::SetInt("dom.max_script_run_time", 0);
+        sMaxScriptRunTime = NS_UNLIMITED_SCRIPT_RUNTIME;
+      }
     }
 
     ctx->mOperationCallbackTime = PR_Now();
     return JS_TRUE;
   }
   else if ((buttonPressed == 2) && debugPossible) {
     return js_CallContextDebugHandler(cx);
   }
@@ -3372,18 +3380,17 @@ MaxScriptRunTimePrefChangedCallback(cons
   // Default limit on script run time to 10 seconds. 0 means let
   // scripts run forever.
   bool isChromePref =
     strcmp(aPrefName, "dom.max_chrome_script_run_time") == 0;
   int32_t time = Preferences::GetInt(aPrefName, isChromePref ? 20 : 10);
 
   PRTime t;
   if (time <= 0) {
-    // Let scripts run for a really, really long time.
-    t = 0x40000000LL << 32;
+    t = NS_UNLIMITED_SCRIPT_RUNTIME;
   } else {
     t = time * PR_USEC_PER_SEC;
   }
 
   if (isChromePref) {
     sMaxChromeScriptRunTime = t;
   } else {
     sMaxScriptRunTime = t;
--- a/ipc/unixsocket/UnixSocket.cpp
+++ b/ipc/unixsocket/UnixSocket.cpp
@@ -47,16 +47,17 @@ public:
                  const nsACString& aAddress)
     : mConsumer(aConsumer)
     , mIOLoop(nullptr)
     , mFd(-1)
     , mConnector(aConnector)
     , mCurrentTaskIsCanceled(false)
     , mTask(nullptr)
     , mAddress(aAddress)
+    , mLock("UnixSocketImpl.mLock")
   {
   }
 
   ~UnixSocketImpl()
   {
     StopTask();
     mReadWatcher.StopWatchingFileDescriptor();
     mWriteWatcher.StopWatchingFileDescriptor();
@@ -70,40 +71,42 @@ public:
 
   bool isFdValid()
   {
     return mFd > 0;
   }
 
   void CancelTask()
   {
-    if (!mTask) {
-      return;
-    }
-    mTask->Cancel();
-    mTask = nullptr;
+    MutexAutoLock lock(mLock);
     mCurrentTaskIsCanceled = true;
   }
   
+  bool IsCanceled()
+  {
+    MutexAutoLock lock(mLock);
+    return mCurrentTaskIsCanceled;
+  }
+
   void UnsetTask()
   {
     mTask = nullptr;
   }
 
   void EnqueueTask(int aDelayMs, CancelableTask* aTask)
   {
     MessageLoopForIO* ioLoop = MessageLoopForIO::current();
     if (!ioLoop) {
       NS_WARNING("No IOLoop to attach to, cancelling self!");
       return;
     }
     if (mTask) {
       return;
     }
-    if (mCurrentTaskIsCanceled) {
+    if (IsCanceled()) {
       return;
     }
     mTask = aTask;
     if (aDelayMs) {
       ioLoop->PostDelayedTask(FROM_HERE, mTask, aDelayMs);
     } else {
       ioLoop->PostTask(FROM_HERE, mTask);
     }
@@ -131,24 +134,30 @@ public:
   void Listen();
 
   /** 
    * Accept an incoming connection
    */
   void Accept();
 
   /** 
+   * Close an open connection
+   */
+  void Close();
+
+  /**
    * Stop whatever connect/accept task is running
    */
   void StopTask()
   {
     if (mTask) {
       mTask->Cancel();
       mTask = nullptr;
     }
+    MutexAutoLock lock(mLock);
     mCurrentTaskIsCanceled = true;
   }
 
   /** 
    * Set up nonblocking flags on whatever our current file descriptor is.
    *
    * @return true if successful, false otherwise
    */
@@ -247,16 +256,20 @@ private:
    */
   socklen_t mAddrSize;
 
   /**
    * Address struct of the socket currently in use
    */
   sockaddr mAddr;
 
+  /**
+   * Protects mCurrentTaskIsCanceled
+   */
+  mozilla::Mutex mLock;
 };
 
 template<class T>
 class DeleteInstanceRunnable : public nsRunnable
 {
 public:
   DeleteInstanceRunnable(T* aInstance)
   : mInstance(aInstance)
@@ -360,30 +373,31 @@ public:
   }
 
 private:
   nsRefPtr<UnixSocketConsumer> mConsumer;
   UnixSocketImpl* mImpl;
   UnixSocketRawData* mData;
 };
 
-class SocketCloseTask : public nsRunnable
+class SocketCloseTask : public Task
 {
 public:
   SocketCloseTask(UnixSocketImpl* aImpl)
     : mImpl(aImpl)
   {
     MOZ_ASSERT(aImpl);
   }
 
-  NS_IMETHOD
-  Run()
+  void Run()
   {
-    mImpl->mConsumer->CloseSocket();
-    return NS_OK;
+    NS_ENSURE_TRUE_VOID(mImpl);
+
+    mImpl->UnsetTask();
+    mImpl->Close();
   }
 
 private:
   UnixSocketImpl* mImpl;
 };
 
 class StartImplReadingTask : public Task
 {
@@ -434,16 +448,29 @@ void SocketConnectTask::Run() {
   mImpl->UnsetTask();
   if (mCanceled) {
     return;
   }
   mImpl->Connect();
 }
 
 void
+UnixSocketImpl::Close()
+{
+  mReadWatcher.StopWatchingFileDescriptor();
+  mWriteWatcher.StopWatchingFileDescriptor();
+
+  nsRefPtr<nsIRunnable> t(new DeleteInstanceRunnable<UnixSocketImpl>(this));
+  NS_ENSURE_TRUE_VOID(t);
+
+  nsresult rv = NS_DispatchToMainThread(t);
+  NS_ENSURE_SUCCESS_VOID(rv);
+}
+
+void
 UnixSocketImpl::Accept()
 {
 
   if (!mConnector) {
     NS_WARNING("No connector object available!");
     return;
   }
 
@@ -473,38 +500,17 @@ UnixSocketImpl::Accept()
 #ifdef DEBUG
       LOG("...listen(%d) gave errno %d", mFd.get(), errno);
 #endif
       return;
     }
 
   }
 
-  int client_fd;
-  client_fd = accept(mFd.get(), &mAddr, &mAddrSize);
-  if (client_fd < 0) {
-    EnqueueTask(SOCKET_RETRY_TIME_MS, new SocketAcceptTask(this));
-    return;
-  }
-
-  if (!mConnector->SetUp(client_fd)) {
-    NS_WARNING("Could not set up socket!");
-    return;
-  }
-  mFd.reset(client_fd);
-
-  nsRefPtr<OnSocketEventTask> t =
-    new OnSocketEventTask(this, OnSocketEventTask::CONNECT_SUCCESS);
-  NS_DispatchToMainThread(t);
-
-  // Due to the fact that we've dispatched our OnConnectSuccess message before
-  // starting reading, we're guaranteed that any subsequent read tasks will
-  // happen after the object has been notified of a successful connect.
-  XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
-                                   new StartImplReadingTask(this));
+  SetUpIO();
 }
 
 void
 UnixSocketImpl::Connect()
 {
   if(mFd.get() < 0)
   {
     mFd = mConnector->Create();
@@ -559,21 +565,16 @@ UnixSocketImpl::SetNonblockFlags()
     return false;
   }
 
   flags |= FD_CLOEXEC;
   if (-1 == fcntl(mFd, F_SETFD, flags)) {
     return false;
   }
 
-  // Select non-blocking IO.
-  if (-1 == fcntl(mFd, F_SETFL, O_NONBLOCK)) {
-    return false;
-  }
-
   return true;
 }
 
 UnixSocketConsumer::UnixSocketConsumer() : mImpl(nullptr)
                                          , mConnectionStatus(SOCKET_DISCONNECTED)
 {
 }
 
@@ -619,79 +620,101 @@ UnixSocketConsumer::CloseSocket()
   if (!mImpl) {
     return;
   }
   UnixSocketImpl* impl = mImpl;
   // To make sure the owner doesn't die on the IOThread, remove pointer here
   mImpl = nullptr;
   // Line it up to be destructed on the IO Thread
   impl->mConsumer.forget();
-  impl->StopTask();
 
-  // The receiver task should have been stopped at this point, but
-  // SocketReceiverTask runnables might still be pending the main
-  // thread. We enqueue the DeleteInstanceRunnable _after_ any pending
-  // SocketReceiverTask. Otherwise we might free 'impl' before those
-  // runnables have been executed.
-  nsRefPtr<nsIRunnable> t(new DeleteInstanceRunnable<UnixSocketImpl>(impl));
-  NS_ENSURE_TRUE_VOID(t);
-  nsresult rv = NS_DispatchToMainThread(t);
-  NS_ENSURE_SUCCESS_VOID(rv);
-  t.forget();
+  impl->CancelTask();
+  XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketCloseTask(impl));
 
   NotifyDisconnect();
 }
 
 void
 UnixSocketImpl::OnFileCanReadWithoutBlocking(int aFd)
 {
-  // Keep reading data until either
-  //
-  //   - mIncoming is completely read
-  //     If so, sConsumer->MessageReceived(mIncoming.forget())
-  //
-  //   - mIncoming isn't completely read, but there's no more
-  //     data available on the socket
-  //     If so, break;
-  while (true) {
-    if (!mIncoming) {
-      uint8_t data[MAX_READ_SIZE];
-      ssize_t ret = read(aFd, data, MAX_READ_SIZE);
-      if (ret < 0) {
-        if (ret == -1) {
-          if (errno == EINTR) {
-            continue; // retry system call when interrupted
-          }
-          else if (errno == EAGAIN || errno == EWOULDBLOCK) {
-            return; // no data available: return and re-poll
+  enum SocketConnectionStatus status = mConsumer->GetConnectionStatus();
+
+  if (status == SOCKET_CONNECTED) {
+
+    // Keep reading data until either
+    //
+    //   - mIncoming is completely read
+    //     If so, sConsumer->MessageReceived(mIncoming.forget())
+    //
+    //   - mIncoming isn't completely read, but there's no more
+    //     data available on the socket
+    //     If so, break;
+    while (true) {
+      if (!mIncoming) {
+        uint8_t data[MAX_READ_SIZE];
+        ssize_t ret = read(aFd, data, MAX_READ_SIZE);
+        if (ret < 0) {
+          if (ret == -1) {
+            if (errno == EINTR) {
+              continue; // retry system call when interrupted
+            }
+            else if (errno == EAGAIN || errno == EWOULDBLOCK) {
+              return; // no data available: return and re-poll
+            }
+            // else fall through to error handling on other errno's
           }
-          // else fall through to error handling on other errno's
-        }
 #ifdef DEBUG
-        NS_WARNING("Cannot read from network");
+          NS_WARNING("Cannot read from network");
 #endif
-        // At this point, assume that we can't actually access
-        // the socket anymore
-        mReadWatcher.StopWatchingFileDescriptor();
-        mWriteWatcher.StopWatchingFileDescriptor();
-        nsRefPtr<SocketCloseTask> t = new SocketCloseTask(this);
-        NS_DispatchToMainThread(t);
-        return;
-      }
-      if (ret) {
-        mIncoming = new UnixSocketRawData(ret);
-        memcpy(mIncoming->mData, data, ret);
-        nsRefPtr<SocketReceiveTask> t =
-          new SocketReceiveTask(this, mIncoming.forget());
-        NS_DispatchToMainThread(t);
-      }
-      if (ret < ssize_t(MAX_READ_SIZE)) {
-        return;
+          // At this point, assume that we can't actually access
+          // the socket anymore
+          mReadWatcher.StopWatchingFileDescriptor();
+          mWriteWatcher.StopWatchingFileDescriptor();
+          XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketCloseTask(this));
+          return;
+        }
+        if (ret) {
+          mIncoming = new UnixSocketRawData(ret);
+          memcpy(mIncoming->mData, data, ret);
+          nsRefPtr<SocketReceiveTask> t =
+            new SocketReceiveTask(this, mIncoming.forget());
+          NS_DispatchToMainThread(t);
+        }
+        if (ret < ssize_t(MAX_READ_SIZE)) {
+          return;
+        }
       }
     }
+  } else if (status == SOCKET_LISTENING) {
+
+    int client_fd = accept(mFd.get(), &mAddr, &mAddrSize);
+
+    if (client_fd < 0) {
+      return;
+    }
+
+    if (!mConnector->SetUp(client_fd)) {
+      NS_WARNING("Could not set up socket!");
+      return;
+    }
+
+    mReadWatcher.StopWatchingFileDescriptor();
+    mWriteWatcher.StopWatchingFileDescriptor();
+
+    mFd.reset(client_fd);
+
+    nsRefPtr<OnSocketEventTask> t =
+      new OnSocketEventTask(this, OnSocketEventTask::CONNECT_SUCCESS);
+    NS_DispatchToMainThread(t);
+
+    // Due to the fact that we've dispatched our OnConnectSuccess message before
+    // starting reading, we're guaranteed that any subsequent read tasks will
+    // happen after the object has been notified of a successful connect.
+    XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
+                                     new StartImplReadingTask(this));
   }
 }
 
 void
 UnixSocketImpl::OnFileCanWriteWithoutBlocking(int aFd)
 {
   // Try to write the bytes of mCurrentRilRawData.  If all were written, continue.
   //
@@ -780,47 +803,47 @@ UnixSocketConsumer::ConnectSocket(UnixSo
   if (mImpl) {
     NS_WARNING("Socket already connecting/connected!");
     return false;
   }
   nsCString addr;
   addr.Assign(aAddress);
   mImpl = new UnixSocketImpl(this, aConnector, addr);
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
+  mConnectionStatus = SOCKET_CONNECTING;
   if (aDelayMs > 0) {
     ioLoop->PostDelayedTask(FROM_HERE, new SocketConnectTask(mImpl), aDelayMs);
   } else {
     ioLoop->PostTask(FROM_HERE, new SocketConnectTask(mImpl));
   }
-  mConnectionStatus = SOCKET_CONNECTING;
   return true;
 }
 
 bool
 UnixSocketConsumer::ListenSocket(UnixSocketConnector* aConnector)
 {
   MOZ_ASSERT(aConnector);
   MOZ_ASSERT(NS_IsMainThread());
   if (mImpl) {
     NS_WARNING("Socket already connecting/connected!");
     return false;
   }
   nsCString addr;
   mImpl = new UnixSocketImpl(this, aConnector, addr);
+  mConnectionStatus = SOCKET_LISTENING;
   XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
                                    new SocketAcceptTask(mImpl));
-  mConnectionStatus = SOCKET_LISTENING;
   return true;
 }
 
 void
 UnixSocketConsumer::CancelSocketTask()
 {
   mConnectionStatus = SOCKET_DISCONNECTED;
   if(!mImpl) {
     NS_WARNING("No socket implementation to cancel task on!");
     return;
   }
-  mImpl->CancelTask();
+  mImpl->StopTask();
 }
 
 } // namespace ipc
 } // namespace mozilla
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -2862,16 +2862,24 @@ IonBuilder::inlineScriptedCall(HandleFun
 
     // Make sure there is enough place in the slots
     uint32_t depth = current->stackDepth() + callInfo.argc() + 2;
     if (depth > current->nslots()) {
         if (!current->increaseSlots(depth - current->nslots()))
             return false;
     }
 
+    // Create new |this| on the caller-side for inlined constructors.
+    if (callInfo.constructing()) {
+        MDefinition *thisDefn = createThis(target, callInfo.fun());
+        if (!thisDefn)
+            return false;
+        callInfo.setThis(thisDefn);
+    }
+
     // Push formals to capture in the resumepoint
     callInfo.pushFormals(current);
 
     MResumePoint *resumePoint =
         MResumePoint::New(current, pc, callerResumePoint_, MResumePoint::Outer);
     if (!resumePoint)
         return false;
 
@@ -2893,24 +2901,16 @@ IonBuilder::inlineScriptedCall(HandleFun
 
     TypeInferenceOracle oracle;
     if (!oracle.init(cx, calleeScript))
         return false;
 
     IonBuilder inlineBuilder(cx, &temp(), &graph(), &oracle,
                              info, inliningDepth + 1, loopDepth_);
 
-    // Create new |this| on the caller-side for inlined constructors.
-    if (callInfo.constructing()) {
-        MDefinition *thisDefn = createThis(target, callInfo.fun());
-        if (!thisDefn)
-            return false;
-        callInfo.setThis(thisDefn);
-    }
-
     // Build the graph.
     if (!inlineBuilder.buildInline(this, resumePoint, callInfo)) {
         JS_ASSERT(calleeScript->hasAnalysis());
 
         // Inlining the callee failed. Disable inlining the function
         if (inlineBuilder.abortReason_ == AbortReason_Disable)
             calleeScript->analysis()->setIonUninlineable();
 
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -1213,17 +1213,17 @@ class MParNew : public MUnaryInstruction
 
 // Could be allocating either a new array or a new object.
 class MParBailout : public MAryControlInstruction<0, 0>
 {
   public:
     INSTRUCTION_HEADER(ParBailout);
 
     MParBailout()
-      : MAryControlInstruction()
+      : MAryControlInstruction<0, 0>()
     {
         setResultType(MIRType_Undefined);
         setGuard();
     }
 };
 
 // Slow path for adding a property to an object without a known base.
 class MInitProp
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -190,40 +190,33 @@ static const AllocKind FinalizePhaseStri
 static const AllocKind FinalizePhaseScripts[] = {
     FINALIZE_SCRIPT
 };
 
 static const AllocKind FinalizePhaseIonCode[] = {
     FINALIZE_IONCODE
 };
 
-static const AllocKind FinalizePhaseShapes[] = {
-    FINALIZE_TYPE_OBJECT
-};
-
 static const AllocKind* FinalizePhases[] = {
     FinalizePhaseStrings,
     FinalizePhaseScripts,
-    FinalizePhaseIonCode,
-    FinalizePhaseShapes
+    FinalizePhaseIonCode
 };
 static const int FinalizePhaseCount = sizeof(FinalizePhases) / sizeof(AllocKind*);
 
 static const int FinalizePhaseLength[] = {
     sizeof(FinalizePhaseStrings) / sizeof(AllocKind),
     sizeof(FinalizePhaseScripts) / sizeof(AllocKind),
-    sizeof(FinalizePhaseIonCode) / sizeof(AllocKind),
-    sizeof(FinalizePhaseShapes) / sizeof(AllocKind)
+    sizeof(FinalizePhaseIonCode) / sizeof(AllocKind)
 };
 
 static const gcstats::Phase FinalizePhaseStatsPhase[] = {
     gcstats::PHASE_SWEEP_STRING,
     gcstats::PHASE_SWEEP_SCRIPT,
-    gcstats::PHASE_SWEEP_IONCODE,
-    gcstats::PHASE_SWEEP_SHAPE
+    gcstats::PHASE_SWEEP_IONCODE
 };
 
 /*
  * Finalization order for things swept in the background.
  */
 
 static const AllocKind BackgroundPhaseObjects[] = {
     FINALIZE_OBJECT0_BACKGROUND,
@@ -236,17 +229,18 @@ static const AllocKind BackgroundPhaseOb
 
 static const AllocKind BackgroundPhaseStrings[] = {
     FINALIZE_SHORT_STRING,
     FINALIZE_STRING
 };
 
 static const AllocKind BackgroundPhaseShapes[] = {
     FINALIZE_SHAPE,
-    FINALIZE_BASE_SHAPE
+    FINALIZE_BASE_SHAPE,
+    FINALIZE_TYPE_OBJECT
 };
 
 static const AllocKind* BackgroundPhases[] = {
     BackgroundPhaseObjects,
     BackgroundPhaseStrings,
     BackgroundPhaseShapes
 };
 static const int BackgroundPhaseCount = sizeof(BackgroundPhases) / sizeof(AllocKind*);
@@ -1475,20 +1469,19 @@ ArenaLists::queueIonCodeForSweep(FreeOp 
     queueForForegroundSweep(fop, FINALIZE_IONCODE);
 }
 
 void
 ArenaLists::queueShapesForSweep(FreeOp *fop)
 {
     gcstats::AutoPhase ap(fop->runtime()->gcStats, gcstats::PHASE_SWEEP_SHAPE);
 
-    queueForForegroundSweep(fop, FINALIZE_TYPE_OBJECT);
-
     queueForBackgroundSweep(fop, FINALIZE_SHAPE);
     queueForBackgroundSweep(fop, FINALIZE_BASE_SHAPE);
+    queueForBackgroundSweep(fop, FINALIZE_TYPE_OBJECT);
 }
 
 static void *
 RunLastDitchGC(JSContext *cx, JS::Zone *zone, AllocKind thingKind)
 {
     /*
      * In parallel sections, we do not attempt to refill the free list
      * and hence do not encounter last ditch GC.
@@ -4583,24 +4576,30 @@ JS::ShrinkGCBuffers(JSRuntime *rt)
     JS_ASSERT(!rt->isHeapBusy());
 
     if (!rt->useHelperThreads())
         ExpireChunksAndArenas(rt, true);
     else
         rt->gcHelperThread.startBackgroundShrink();
 }
 
+void
+js::gc::FinishBackgroundFinalize(JSRuntime *rt)
+{
+    rt->gcHelperThread.waitBackgroundSweepEnd();
+}
+
 AutoFinishGC::AutoFinishGC(JSRuntime *rt)
 {
     if (IsIncrementalGCInProgress(rt)) {
         PrepareForIncrementalGC(rt);
         FinishIncrementalGC(rt, gcreason::API);
     }
 
-    rt->gcHelperThread.waitBackgroundSweepEnd();
+    gc::FinishBackgroundFinalize(rt);
 }
 
 AutoPrepareForTracing::AutoPrepareForTracing(JSRuntime *rt)
   : finish(rt),
     session(rt),
     copy(rt)
 {
     RecordNativeStackTopForGC(rt);
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -163,18 +163,18 @@ IsBackgroundFinalized(AllocKind kind)
         false,     /* FINALIZE_OBJECT8 */
         true,      /* FINALIZE_OBJECT8_BACKGROUND */
         false,     /* FINALIZE_OBJECT12 */
         true,      /* FINALIZE_OBJECT12_BACKGROUND */
         false,     /* FINALIZE_OBJECT16 */
         true,      /* FINALIZE_OBJECT16_BACKGROUND */
         false,     /* FINALIZE_SCRIPT */
         true,      /* FINALIZE_SHAPE */
-        true,     /* FINALIZE_BASE_SHAPE */
-        false,     /* FINALIZE_TYPE_OBJECT */
+        true,      /* FINALIZE_BASE_SHAPE */
+        true,      /* FINALIZE_TYPE_OBJECT */
         true,      /* FINALIZE_SHORT_STRING */
         true,      /* FINALIZE_STRING */
         false,     /* FINALIZE_EXTERNAL_STRING */
         false,     /* FINALIZE_IONCODE */
     };
     JS_STATIC_ASSERT(JS_ARRAY_LENGTH(map) == FINALIZE_LIMIT);
     return map[kind];
 }
@@ -329,16 +329,20 @@ struct ArenaLists {
         }
     }
 
     bool doneBackgroundFinalize(AllocKind kind) const {
         return backgroundFinalizeState[kind] == BFS_DONE ||
                backgroundFinalizeState[kind] == BFS_JUST_FINISHED;
     }
 
+    bool needBackgroundFinalizeWait(AllocKind kind) const {
+        return backgroundFinalizeState[kind] != BFS_DONE;
+    }
+
     /*
      * Return the free list back to the arena so the GC finalization will not
      * run the finalizers over unitialized bytes from free things.
      */
     void purge() {
         for (size_t i = 0; i != FINALIZE_LIMIT; ++i) {
             FreeSpan *headSpan = &freeLists[i];
             if (!headSpan->isEmpty()) {
@@ -1180,16 +1184,20 @@ void
 RunDebugGC(JSContext *cx);
 
 void
 SetDeterministicGC(JSContext *cx, bool enabled);
 
 void
 SetValidateGC(JSContext *cx, bool enabled);
 
+/* Wait for the background thread to finish sweeping if it is running. */
+void
+FinishBackgroundFinalize(JSRuntime *rt);
+
 const int ZealPokeValue = 1;
 const int ZealAllocValue = 2;
 const int ZealFrameGCValue = 3;
 const int ZealVerifierPreValue = 4;
 const int ZealFrameVerifierPreValue = 5;
 // These two values used to be distinct.  They no longer are, but both were
 // kept to avoid breaking fuzz tests.  Avoid using ZealStackRootingValue__2.
 const int ZealStackRootingValue = 6;
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -352,23 +352,28 @@ class CellIter : public CellIterImpl
 #ifdef DEBUG
     size_t *counter;
 #endif
   public:
     CellIter(JSCompartment *comp, AllocKind kind)
       : lists(&comp->zone()->allocator.arenas),
         kind(kind)
     {
+
         /*
          * We have a single-threaded runtime, so there's no need to protect
          * against other threads iterating or allocating. However, we do have
-         * background finalization; make sure people aren't using CellIter to
-         * walk such allocation kinds.
+         * background finalization; we have to wait for this to finish if it's
+         * currently active.
          */
-        JS_ASSERT(!IsBackgroundFinalized(kind));
+        if (IsBackgroundFinalized(kind) &&
+            comp->zone()->allocator.arenas.needBackgroundFinalizeWait(kind))
+        {
+            gc::FinishBackgroundFinalize(comp->rt);
+        }
         if (lists->isSynchronizedFreeList(kind)) {
             lists = NULL;
         } else {
             JS_ASSERT(!comp->rt->isHeapBusy());
             lists->copyFreeListToArena(kind);
         }
 #ifdef DEBUG
         counter = &comp->rt->noGCOrAllocationCheck;
--- a/memory/mozalloc/mozalloc.h
+++ b/memory/mozalloc/mozalloc.h
@@ -17,16 +17,17 @@
 #if defined(__cplusplus)
 #  include <new>
 #endif
 #include "xpcom-config.h"
 
 #if defined(__cplusplus)
 #include "mozilla/fallible.h"
 #endif
+#include "mozilla/Attributes.h"
 
 #define MOZALLOC_HAVE_XMALLOC
 
 #if defined(MOZALLOC_EXPORT)
 /* do nothing: it's been defined to __declspec(dllexport) by
  * mozalloc*.cpp on platforms where that's required. */
 #elif defined(XP_WIN) || (defined(XP_OS2) && defined(__declspec))
 #  define MOZALLOC_EXPORT __declspec(dllimport)
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -28,19 +28,17 @@
 
 /*
  * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the
  * method decorated with it must be inlined, even if the compiler thinks
  * otherwise.  This is only a (much) stronger version of the MOZ_INLINE hint:
  * compilers are not guaranteed to respect it (although they're much more likely
  * to do so).
  */
-#if defined(DEBUG)
-#  define MOZ_ALWAYS_INLINE     MOZ_INLINE
-#elif defined(_MSC_VER)
+#if defined(_MSC_VER)
 #  define MOZ_ALWAYS_INLINE     __forceinline
 #elif defined(__GNUC__)
 #  define MOZ_ALWAYS_INLINE     __attribute__((always_inline)) MOZ_INLINE
 #else
 #  define MOZ_ALWAYS_INLINE     MOZ_INLINE
 #endif
 
 /*
--- a/toolkit/components/perf/test_pm.xul
+++ b/toolkit/components/perf/test_pm.xul
@@ -17,33 +17,28 @@ function test()
 {
   SimpleTest.waitForExplicitFinish();
 
   Components.utils.import("resource://gre/modules/PerfMeasurement.jsm");
   let pm = new PerfMeasurement(PerfMeasurement.ALL);
   if (pm.eventsMeasured == 0) {
     todo(false, "stub, skipping test");
   } else {
-    is(pm.eventsMeasured, PerfMeasurement.ALL, "all events measurable");
-
     pm.start();
     for (let i = 0; i < 10000; i++) ;
       pm.stop();
 
-    isnot(pm.cpu_cycles, -1, "cpu_cycles");
-    isnot(pm.instructions, -1, "instructions");
-    isnot(pm.cache_references, -1, "cache_references");
-    isnot(pm.cache_misses, -1, "cache_misses");
-    isnot(pm.branch_instructions, -1, "branch_instructions");
-    isnot(pm.branch_misses, -1, "branch_misses");
-    isnot(pm.bus_cycles, -1, "bus_cycles");
-    isnot(pm.page_faults, -1, "page_faults");
-    isnot(pm.major_page_faults, -1, "major_page_faults");
-    isnot(pm.context_switches, -1, "context_switches");
-    isnot(pm.cpu_migrations, -1, "cpu_migrations");
+    events = ["cpu_cycles", "instructions", "cache_references", "cache_misses",
+              "branch_instructions", "branch_misses", "bus_cycles", "page_faults",
+              "major_page_faults", "context_switches", "cpu_migrations"];
+
+    for (var i = 0; i < events.length; i++) {
+        var e = events[i];
+        ((pm.eventsMeasured & PerfMeasurement[e.toUpperCase()]) ? isnot : todo_is)(pm[e], -1, e);
+    }
   }
   SimpleTest.finish();
 }
 ]]></script>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
     <p id="display"></p>
     <div id="content" style="display:none;"></div>
--- a/toolkit/content/devicestorage.properties
+++ b/toolkit/content/devicestorage.properties
@@ -1,4 +1,4 @@
 # Extensions we recognize for DeviceStorage storage areas
 pictures=*.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp;
-music=*.mp3; *.ogg; *.m4a; *.m4b; *.m4p; *.m4r; *.3gp; *.mp4; *.aac; *.m3u; *.pls;
+music=*.mp3; *.ogg; *.m4a; *.m4b; *.m4p; *.m4r; *.3gp; *.mp4; *.aac; *.m3u; *.pls; *.opus;
 videos=*.mp4; *.mpeg; *.mpg; *.ogv; *.ogx; *.webm; *.3gp; *.ogg;
--- a/toolkit/content/tests/chrome/test_screenPersistence.xul
+++ b/toolkit/content/tests/chrome/test_screenPersistence.xul
@@ -9,26 +9,28 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
 
 <script class="testbody" type="application/javascript"><![CDATA[
   SimpleTest.waitForExplicitFinish();
   let win;
+  var left = 60 + screen.availLeft;
+  var upper = 60 + screen.availTop;
 
   function runTest() {
     win = window.openDialog("window_screenPosSize.xul",
                             null,
-                            "chrome,dialog=no,all,screenX=60,screenY=60,outerHeight=200,outerWidth=200");
+                            "chrome,dialog=no,all,screenX=" + left + ",screenY=" + upper + ",outerHeight=200,outerWidth=200");
     SimpleTest.waitForFocus(checkTest, win);
   }
   function checkTest() {
-    is(win.screenX, 60, "The window should be placed now at x=60px");
-    is(win.screenY, 60, "The window should be placed now at y=60px");
+    is(win.screenX, left, "The window should be placed now at x=" + left + "px");
+    is(win.screenY, upper, "The window should be placed now at y=" + upper + "px");
     is(win.outerHeight, 200, "The window size should be height=200px");
     is(win.outerWidth, 200, "The window size should be width=200px");
     runTest2();
   }
   function runTest2() {
     win.close();
     win = window.openDialog("window_screenPosSize.xul",
                             null,