Merge m-c to autoland a=merge
authorWes Kocher <wkocher@mozilla.com>
Fri, 15 Jul 2016 17:01:59 -0700
changeset 330166 5e2477a249db1cf1c5f1f5a1409ce72cc01257d2
parent 330165 53ee209a0557b5c11e821c980c5a460fd09c1730 (current diff)
parent 330123 0d82d5d030afa2e8f48dd68e86eb75efd0947a5c (diff)
child 330167 1b3826196e7efc0c7442a02207ef833003de2dfe
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone50.0a1
Merge m-c to autoland a=merge
browser/branding/aurora/VisualElementsManifest.xml
browser/branding/nightly/VisualElementsManifest.xml
browser/branding/official/VisualElementsManifest.xml
browser/branding/unofficial/VisualElementsManifest.xml
modules/libpref/init/all.js
deleted file mode 100644
--- a/browser/branding/aurora/VisualElementsManifest.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
-  <VisualElements
-      DisplayName='Firefox Developer Edition'
-      Logo='browser\VisualElements\VisualElements_150.png'
-      SmallLogo='browser\VisualElements\VisualElements_70.png'
-      ForegroundText='light'
-      BackgroundColor='#14171a'/>
-      <DefaultTile ShowName='allLogos'/>
-      <SplashScreen Image='DummyFileNameRequiredByWindows.png'/>
-  </VisualElements>
-</Application>
--- a/browser/branding/branding-common.mozbuild
+++ b/browser/branding/branding-common.mozbuild
@@ -8,17 +8,16 @@
 def FirefoxBranding():
     JS_PREFERENCE_FILES += [
         'pref/firefox-branding.js',
     ]
 
     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
         FINAL_TARGET_FILES['..'] += [
             'firefox.VisualElementsManifest.xml',
-            'VisualElementsManifest.xml',
         ]
         FINAL_TARGET_FILES.VisualElements += [
             'VisualElements_150.png',
             'VisualElements_70.png',
         ]
         BRANDING_FILES += [
             'appname.bmp',
             'bgintro.bmp',
deleted file mode 100644
--- a/browser/branding/nightly/VisualElementsManifest.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
-  <VisualElements
-      DisplayName='Nightly'
-      Logo='browser\VisualElements\VisualElements_150.png'
-      SmallLogo='browser\VisualElements\VisualElements_70.png'
-      ForegroundText='light'
-      BackgroundColor='#14171a'/>
-      <DefaultTile ShowName='allLogos'/>
-      <SplashScreen Image='DummyFileNameRequiredByWindows.png'/>
-  </VisualElements>
-</Application>
deleted file mode 100644
--- a/browser/branding/official/VisualElementsManifest.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<Application xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
-  <VisualElements
-      DisplayName='Mozilla Firefox'
-      Logo='browser\VisualElements\VisualElements_150.png'
-      SmallLogo='browser\VisualElements\VisualElements_70.png'
-      ForegroundText='light'
-      BackgroundColor='#0996f8'/>
-      <DefaultTile ShowName='allLogos'/>
-      <SplashScreen Image='DummyFileNameRequiredByWindows.png'/>
-  </VisualElements>
-</Application>
deleted file mode 100644
--- a/browser/branding/unofficial/VisualElementsManifest.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<Application>
-  <VisualElements
-      DisplayName='Nightly'
-      Logo='browser\VisualElements\VisualElements_150.png'
-      SmallLogo='browser\VisualElements\VisualElements_70.png'
-      ForegroundText='light'
-      BackgroundColor='#14171a'>
-    <DefaultTile ShowName='allLogos'/>
-    <SplashScreen Image='DummyFileNameRequiredByWindows.png'/>
-  </VisualElements>
-</Application>
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -109,17 +109,16 @@
 @BINPATH@/gtk2/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
 #endif
 
 [browser]
 ; [Base Browser Files]
 #ifndef XP_UNIX
 @BINPATH@/@MOZ_APP_NAME@.exe
 @BINPATH@/firefox.VisualElementsManifest.xml
-@BINPATH@/VisualElementsManifest.xml
 @BINPATH@/browser/VisualElements/VisualElements_150.png
 @BINPATH@/browser/VisualElements/VisualElements_70.png
 #else
 @BINPATH@/@MOZ_APP_NAME@-bin
 @BINPATH@/@MOZ_APP_NAME@
 #endif
 @RESPATH@/application.ini
 #ifdef MOZ_UPDATER
--- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp
+++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp
@@ -132,18 +132,16 @@ parseMessage(ZeroCopyInputStream& stream
 
   codedStream.PopLimit(limit);
   return true;
 }
 
 template<typename CharT, typename InternedStringSet>
 struct GetOrInternStringMatcher
 {
-  using ReturnType = const CharT*;
-
   InternedStringSet& internedStrings;
 
   explicit GetOrInternStringMatcher(InternedStringSet& strings) : internedStrings(strings) { }
 
   const CharT* match(const std::string* str) {
     MOZ_ASSERT(str);
     size_t length = str->length() / sizeof(CharT);
     auto tempString = reinterpret_cast<const CharT*>(str->data());
@@ -855,39 +853,33 @@ EstablishBoundaries(JSContext* cx,
 // A variant covering all the various two-byte strings that we can get from the
 // ubi::Node API.
 class TwoByteString : public Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName>
 {
   using Base = Variant<JSAtom*, const char16_t*, JS::ubi::EdgeName>;
 
   struct AsTwoByteStringMatcher
   {
-    using ReturnType = TwoByteString;
-
     TwoByteString match(JSAtom* atom) {
       return TwoByteString(atom);
     }
 
     TwoByteString match(const char16_t* chars) {
       return TwoByteString(chars);
     }
   };
 
   struct IsNonNullMatcher
   {
-    using ReturnType = bool;
-
     template<typename T>
     bool match(const T& t) { return t != nullptr; }
   };
 
   struct LengthMatcher
   {
-    using ReturnType = size_t;
-
     size_t match(JSAtom* atom) {
       MOZ_ASSERT(atom);
       JS::ubi::AtomOrTwoByteChars s(atom);
       return s.length();
     }
 
     size_t match(const char16_t* chars) {
       MOZ_ASSERT(chars);
@@ -897,18 +889,16 @@ class TwoByteString : public Variant<JSA
     size_t match(const JS::ubi::EdgeName& ptr) {
       MOZ_ASSERT(ptr);
       return NS_strlen(ptr.get());
     }
   };
 
   struct CopyToBufferMatcher
   {
-    using ReturnType = size_t;
-
     RangedPtr<char16_t> destination;
     size_t              maxLength;
 
     CopyToBufferMatcher(RangedPtr<char16_t> destination, size_t maxLength)
       : destination(destination)
       , maxLength(maxLength)
     { }
 
@@ -980,18 +970,16 @@ public:
 // because each type is generally a different semantic thing in addition to
 // having a slightly different representation. For example, the set of edge
 // names and the set stack frames' source names naturally tend not to overlap
 // very much if at all.
 struct TwoByteString::HashPolicy {
   using Lookup = TwoByteString;
 
   struct HashingMatcher {
-    using ReturnType  = js::HashNumber;
-
     js::HashNumber match(const JSAtom* atom) {
       return js::DefaultHasher<const JSAtom*>::hash(atom);
     }
 
     js::HashNumber match(const char16_t* chars) {
       MOZ_ASSERT(chars);
       auto length = NS_strlen(chars);
       return HashString(chars, length);
@@ -1004,17 +992,16 @@ struct TwoByteString::HashPolicy {
   };
 
   static js::HashNumber hash(const Lookup& l) {
     HashingMatcher hasher;
     return l.match(hasher);
   }
 
   struct EqualityMatcher {
-    using ReturnType = bool;
     const TwoByteString& rhs;
     explicit EqualityMatcher(const TwoByteString& rhs) : rhs(rhs) { }
 
     bool match(const JSAtom* atom) {
       return rhs.is<JSAtom*>() && rhs.as<JSAtom*>() == atom;
     }
 
     bool match(const char16_t* chars) {
--- a/dom/base/nsHostObjectProtocolHandler.cpp
+++ b/dom/base/nsHostObjectProtocolHandler.cpp
@@ -567,32 +567,29 @@ nsHostObjectProtocolHandler::NewChannel2
                                         stream,
                                         NS_ConvertUTF16toUTF8(contentType),
                                         EmptyCString(), // aContentCharset
                                         aLoadInfo);
   if (NS_WARN_IF(rv.Failed())) {
     return rv.StealNSResult();
   }
 
-  nsString type;
-  blob->GetType(type);
-
   if (blob->IsFile()) {
     nsString filename;
     blob->GetName(filename);
     channel->SetContentDispositionFilename(filename);
   }
 
   uint64_t size = blob->GetSize(rv);
   if (NS_WARN_IF(rv.Failed())) {
     return rv.StealNSResult();
   }
 
   channel->SetOriginalURI(uri);
-  channel->SetContentType(NS_ConvertUTF16toUTF8(type));
+  channel->SetContentType(NS_ConvertUTF16toUTF8(contentType));
   channel->SetContentLength(size);
 
   channel.forget(result);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -88,16 +88,27 @@
  * value0. Note that it only does this if we're in the middle of an incremental
  * GC. Since this is rare, the cost of the write barrier is usually just an
  * extra branch.
  *
  * In practice, we implement the pre-barrier differently based on the type of
  * value0. E.g., see JSObject::writeBarrierPre, which is used if obj->field is
  * a JSObject*. It takes value0 as a parameter.
  *
+ *                                READ-BARRIER
+ *
+ * Incremental GC requires that weak pointers have read barriers. The problem
+ * happens when, during an incremental GC, some code reads a weak pointer and
+ * writes it somewhere on the heap that has been marked black in a previous
+ * slice. Since the weak pointer will not otherwise be marked and will be swept
+ * and finalized in the last slice, this will leave the pointer just written
+ * dangling after the GC. To solve this, we immediately mark black all weak
+ * pointers that get read between slices so that it is safe to store them in an
+ * already marked part of the heap, e.g. in Rooted.
+ *
  *                                POST-BARRIER
  *
  * For generational GC, we want to be able to quickly collect the nursery in a
  * minor collection.  Part of the way this is achieved is to only mark the
  * nursery itself; tenured things, which may form the majority of the heap, are
  * not traced through or marked.  This leads to the problem of what to do about
  * tenured objects that have pointers into the nursery: if such things are not
  * marked, they may be discarded while there are still live objects which
@@ -549,24 +560,18 @@ class ReadBarrieredBase : public Barrier
     // ReadBarrieredBase is not directly instantiable.
     explicit ReadBarrieredBase(T v) : BarrieredBase<T>(v) {}
 
   protected:
     void read() const { InternalBarrierMethods<T>::readBarrier(this->value); }
     void post(T prev, T next) { InternalBarrierMethods<T>::postBarrier(&this->value, prev, next); }
 };
 
-// Incremental GC requires that weak pointers have read barriers. This is mostly
-// an issue for empty shapes stored in JSCompartment. The problem happens when,
-// during an incremental GC, some JS code stores one of the compartment's empty
-// shapes into an object already marked black. Normally, this would not be a
-// problem, because the empty shape would have been part of the initial snapshot
-// when the GC started. However, since this is a weak pointer, it isn't. So we
-// may collect the empty shape even though a live object points to it. To fix
-// this, we mark these empty shapes black whenever they get read out.
+// Incremental GC requires that weak pointers have read barriers. See the block
+// comment at the top of Barrier.h for a complete discussion of why.
 //
 // Note that this class also has post-barriers, so is safe to use with nursery
 // pointers. However, when used as a hashtable key, care must still be taken to
 // insert manual post-barriers on the table for rekeying if the key is based in
 // any way on the address of the object.
 template <typename T>
 class ReadBarriered : public ReadBarrieredBase<T>
 {
--- a/js/src/gc/Tracer.cpp
+++ b/js/src/gc/Tracer.cpp
@@ -128,27 +128,26 @@ js::TraceChildren(JSTracer* trc, void* t
 
 namespace {
 struct TraceIncomingFunctor {
     JSTracer* trc_;
     const JS::CompartmentSet& compartments_;
     TraceIncomingFunctor(JSTracer* trc, const JS::CompartmentSet& compartments)
       : trc_(trc), compartments_(compartments)
     {}
-    using ReturnType = void;
     template <typename T>
-    ReturnType operator()(T tp) {
+    void operator()(T tp) {
         if (!compartments_.has((*tp)->compartment()))
             return;
         TraceManuallyBarrieredEdge(trc_, tp, "cross-compartment wrapper");
     }
     // StringWrappers are just used to avoid copying strings
     // across zones multiple times, and don't hold a strong
     // reference.
-    ReturnType operator()(JSString** tp) {}
+    void operator()(JSString** tp) {}
 };
 } // namespace (anonymous)
 
 JS_PUBLIC_API(void)
 JS::TraceIncomingCCWs(JSTracer* trc, const JS::CompartmentSet& compartments)
 {
     for (js::CompartmentsIter comp(trc->runtime(), SkipAtoms); !comp.done(); comp.next()) {
         if (compartments.has(comp))
--- a/js/src/gc/Verifier.cpp
+++ b/js/src/gc/Verifier.cpp
@@ -230,18 +230,20 @@ gc::GCRuntime::startVerifyPreBarriers()
     }
 
     verifyPreData = trc;
     incrementalState = MARK;
     marker.start();
 
     for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
         PurgeJITCaches(zone);
-        zone->setNeedsIncrementalBarrier(true, Zone::UpdateJit);
-        zone->arenas.purge();
+        if (!zone->usedByExclusiveThread) {
+            zone->setNeedsIncrementalBarrier(true, Zone::UpdateJit);
+            zone->arenas.purge();
+        }
     }
 
     return;
 
 oom:
     incrementalState = NO_INCREMENTAL;
     js_delete(trc);
     verifyPreData = nullptr;
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1286244.js
@@ -0,0 +1,16 @@
+if (typeof verifyprebarriers != 'function' ||
+    typeof offThreadCompileScript != 'function')
+    quit();
+
+try {
+    // This will fail with --no-threads.
+    verifyprebarriers();
+    var lfGlobal = newGlobal();
+    lfGlobal.offThreadCompileScript(`
+      version(185);
+    `);
+}
+catch (e) {
+    quit(0);
+}
+
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -223,17 +223,17 @@ js::MarkPermanentAtoms(JSTracer* trc)
     // Static strings are not included in the permanent atoms table.
     if (rt->staticStrings)
         rt->staticStrings->trace(trc);
 
     if (rt->permanentAtoms) {
         for (FrozenAtomSet::Range r(rt->permanentAtoms->all()); !r.empty(); r.popFront()) {
             const AtomStateEntry& entry = r.front();
 
-            JSAtom* atom = entry.asPtr();
+            JSAtom* atom = entry.asPtrUnbarriered();
             TraceProcessGlobalRoot(trc, atom, "permanent_table");
         }
     }
 }
 
 void
 js::MarkWellKnownSymbols(JSTracer* trc)
 {
@@ -267,17 +267,17 @@ JSRuntime::transformToPermanentAtoms(JSC
     permanentAtoms = cx->new_<FrozenAtomSet>(atoms_);   // takes ownership of atoms_
 
     atoms_ = cx->new_<AtomSet>();
     if (!atoms_ || !atoms_->init(JS_STRING_HASH_COUNT))
         return false;
 
     for (FrozenAtomSet::Range r(permanentAtoms->all()); !r.empty(); r.popFront()) {
         AtomStateEntry entry = r.front();
-        JSAtom* atom = entry.asPtr();
+        JSAtom* atom = entry.asPtr(cx);
         atom->morphIntoPermanentAtom();
     }
 
     return true;
 }
 
 bool
 AtomIsPinned(JSContext* cx, JSAtom* atom)
@@ -317,25 +317,25 @@ AtomizeAndCopyChars(ExclusiveContext* cx
     // Note: when this function is called while the permanent atoms table is
     // being initialized (in initializeAtoms()), |permanentAtoms| is not yet
     // initialized so this lookup is always skipped. Only once
     // transformToPermanentAtoms() is called does |permanentAtoms| get
     // initialized and then this lookup will go ahead.
     if (cx->isPermanentAtomsInitialized()) {
         AtomSet::Ptr pp = cx->permanentAtoms().readonlyThreadsafeLookup(lookup);
         if (pp)
-            return pp->asPtr();
+            return pp->asPtr(cx);
     }
 
     AutoLockForExclusiveAccess lock(cx);
 
     AtomSet& atoms = cx->atoms(lock);
     AtomSet::AddPtr p = atoms.lookupForAdd(lookup);
     if (p) {
-        JSAtom* atom = p->asPtr();
+        JSAtom* atom = p->asPtr(cx);
         p->setPinned(bool(pin));
         return atom;
     }
 
     AutoCompartment ac(cx, cx->atomsCompartment(lock));
 
     JSFlatString* flat = NewStringCopyN<NoGC>(cx, tbchars, length);
     if (!flat) {
@@ -382,17 +382,17 @@ js::AtomizeString(ExclusiveContext* cx, 
         AtomSet::Ptr p = cx->permanentAtoms().readonlyThreadsafeLookup(lookup);
         if (p)
             return &atom;
 
         AutoLockForExclusiveAccess lock(cx);
 
         p = cx->atoms(lock).lookup(lookup);
         MOZ_ASSERT(p); /* Non-static atom must exist in atom state set. */
-        MOZ_ASSERT(p->asPtr() == &atom);
+        MOZ_ASSERT(p->asPtrUnbarriered() == &atom);
         MOZ_ASSERT(pin == PinAtom);
         p->setPinned(bool(pin));
         return &atom;
     }
 
     JSLinearString* linear = str->ensureLinear(cx);
     if (!linear)
         return nullptr;
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -60,17 +60,17 @@ class AtomStateEntry
     /*
      * Non-branching code sequence. Note that the const_cast is safe because
      * the hash function doesn't consider the tag to be a portion of the key.
      */
     void setPinned(bool pinned) const {
         const_cast<AtomStateEntry*>(this)->bits |= uintptr_t(pinned);
     }
 
-    JSAtom* asPtr() const;
+    JSAtom* asPtr(ExclusiveContext* cx) const;
     JSAtom* asPtrUnbarriered() const;
 
     bool needsSweep() {
         JSAtom* atom = asPtrUnbarriered();
         return gc::IsAboutToBeFinalizedUnbarriered(&atom);
     }
 };
 
--- a/js/src/jsatominlines.h
+++ b/js/src/jsatominlines.h
@@ -13,21 +13,21 @@
 #include "mozilla/RangedPtr.h"
 
 #include "jscntxt.h"
 #include "jsnum.h"
 
 #include "vm/String.h"
 
 inline JSAtom*
-js::AtomStateEntry::asPtr() const
+js::AtomStateEntry::asPtr(js::ExclusiveContext* cx) const
 {
-    MOZ_ASSERT(bits != 0);
-    JSAtom* atom = reinterpret_cast<JSAtom*>(bits & NO_TAG_MASK);
-    JSString::readBarrier(atom);
+    JSAtom* atom = asPtrUnbarriered();
+    if (cx->isJSContext())
+        JSString::readBarrier(atom);
     return atom;
 }
 
 inline JSAtom*
 js::AtomStateEntry::asPtrUnbarriered() const
 {
     MOZ_ASSERT(bits != 0);
     return reinterpret_cast<JSAtom*>(bits & NO_TAG_MASK);
@@ -163,17 +163,17 @@ AtomHasher::Lookup::Lookup(const JSAtom*
         twoByteChars = atom->twoByteChars(nogc);
         hash = mozilla::HashString(twoByteChars, length);
     }
 }
 
 inline bool
 AtomHasher::match(const AtomStateEntry& entry, const Lookup& lookup)
 {
-    JSAtom* key = entry.asPtr();
+    JSAtom* key = entry.asPtrUnbarriered();
     if (lookup.atom)
         return lookup.atom == key;
     if (key->length() != lookup.length)
         return false;
 
     if (key->hasLatin1Chars()) {
         const Latin1Char* keyChars = key->latin1Chars(lookup.nogc);
         if (lookup.isLatin1)
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -222,17 +222,16 @@ class WrapperMapRef : public BufferableR
     WrapperMapRef(WrapperMap* map, const CrossCompartmentKey& key)
       : map(map), key(key) {}
 
     struct TraceFunctor {
         JSTracer* trc_;
         const char* name_;
         TraceFunctor(JSTracer *trc, const char* name) : trc_(trc), name_(name) {}
 
-        using ReturnType = void;
         template <class T> void operator()(T* t) { TraceManuallyBarrieredEdge(trc_, t, name_); }
     };
     void trace(JSTracer* trc) override {
         CrossCompartmentKey prior = key;
         key.applyToWrapped(TraceFunctor(trc, "ccw wrapped"));
         key.applyToDebugger(TraceFunctor(trc, "ccw debugger"));
         if (key == prior)
             return;
@@ -245,17 +244,16 @@ class WrapperMapRef : public BufferableR
         /* Rekey the entry. */
         map->rekeyAs(prior, key, key);
     }
 };
 
 #ifdef JSGC_HASH_TABLE_CHECKS
 namespace {
 struct CheckGCThingAfterMovingGCFunctor {
-    using ReturnType = void;
     template <class T> void operator()(T* t) { CheckGCThingAfterMovingGC(*t); }
 };
 } // namespace (anonymous)
 
 void
 JSCompartment::checkWrapperMapAfterMovingGC()
 {
     /*
@@ -270,17 +268,16 @@ JSCompartment::checkWrapperMapAfterMovin
         WrapperMap::Ptr ptr = crossCompartmentWrappers.lookup(e.front().key());
         MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &e.front());
     }
 }
 #endif
 
 namespace {
 struct IsInsideNurseryFunctor {
-    using ReturnType = bool;
     template <class T> bool operator()(T tp) { return IsInsideNursery(*tp); }
 };
 } // namespace (anonymous)
 
 bool
 JSCompartment::putWrapper(JSContext* cx, const CrossCompartmentKey& wrapped,
                           const js::Value& wrapper)
 {
@@ -770,21 +767,19 @@ JSCompartment::sweepCrossCompartmentWrap
     crossCompartmentWrappers.sweep();
 }
 
 namespace {
 struct TraceRootFunctor {
     JSTracer* trc;
     const char* name;
     TraceRootFunctor(JSTracer* trc, const char* name) : trc(trc), name(name) {}
-    using ReturnType = void;
-    template <class T> ReturnType operator()(T* t) { return TraceRoot(trc, t, name); }
+    template <class T> void operator()(T* t) { return TraceRoot(trc, t, name); }
 };
 struct NeedsSweepUnbarrieredFunctor {
-    using ReturnType = bool;
     template <class T> bool operator()(T* t) const { return IsAboutToBeFinalizedUnbarriered(t); }
 };
 } // namespace (anonymous)
 
 void
 CrossCompartmentKey::trace(JSTracer* trc)
 {
     applyToWrapped(TraceRootFunctor(trc, "CrossCompartmentKey::wrapped"));
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -101,68 +101,66 @@ struct CrossCompartmentKey
 
     bool operator==(const CrossCompartmentKey& other) const { return wrapped == other.wrapped; }
     bool operator!=(const CrossCompartmentKey& other) const { return wrapped != other.wrapped; }
 
     template <typename T> bool is() const { return wrapped.is<T>(); }
     template <typename T> const T& as() const { return wrapped.as<T>(); }
 
     template <typename F>
-    auto applyToWrapped(F f) -> typename F::ReturnType {
+    auto applyToWrapped(F f) -> decltype(f(static_cast<JSObject**>(nullptr))) {
+        using ReturnType = decltype(f(static_cast<JSObject**>(nullptr)));
         struct WrappedMatcher {
-            using ReturnType = typename F::ReturnType;
             F f_;
             explicit WrappedMatcher(F f) : f_(f) {}
             ReturnType match(JSObject*& obj) { return f_(&obj); }
             ReturnType match(JSString*& str) { return f_(&str); }
             ReturnType match(DebuggerAndScript& tpl) { return f_(&mozilla::Get<1>(tpl)); }
             ReturnType match(DebuggerAndObject& tpl) { return f_(&mozilla::Get<1>(tpl)); }
         } matcher(f);
         return wrapped.match(matcher);
     }
 
     template <typename F>
-    auto applyToDebugger(F f) -> typename F::ReturnType {
+    auto applyToDebugger(F f) -> decltype(f(static_cast<NativeObject**>(nullptr))) {
+        using ReturnType = decltype(f(static_cast<NativeObject**>(nullptr)));
         struct DebuggerMatcher {
-            using ReturnType = typename F::ReturnType;
             F f_;
             explicit DebuggerMatcher(F f) : f_(f) {}
             ReturnType match(JSObject*& obj) { return ReturnType(); }
             ReturnType match(JSString*& str) { return ReturnType(); }
             ReturnType match(DebuggerAndScript& tpl) { return f_(&mozilla::Get<0>(tpl)); }
             ReturnType match(DebuggerAndObject& tpl) { return f_(&mozilla::Get<0>(tpl)); }
         } matcher(f);
         return wrapped.match(matcher);
     }
 
     // Valid for JSObject* and Debugger keys. Crashes immediately if used on a
     // JSString* key.
     JSCompartment* compartment() {
         struct GetCompartmentFunctor {
-            using ReturnType = JSCompartment*;
-            ReturnType operator()(JSObject** tp) const { return (*tp)->compartment(); }
-            ReturnType operator()(JSScript** tp) const { return (*tp)->compartment(); }
-            ReturnType operator()(JSString** tp) const {
+            JSCompartment* operator()(JSObject** tp) const { return (*tp)->compartment(); }
+            JSCompartment* operator()(JSScript** tp) const { return (*tp)->compartment(); }
+            JSCompartment* operator()(JSString** tp) const {
                 MOZ_CRASH("invalid ccw key"); return nullptr;
             }
         };
         return applyToWrapped(GetCompartmentFunctor());
     }
 
     struct Hasher : public DefaultHasher<CrossCompartmentKey>
     {
         struct HashFunctor {
-            using ReturnType = HashNumber;
-            ReturnType match(JSObject* obj) { return DefaultHasher<JSObject*>::hash(obj); }
-            ReturnType match(JSString* str) { return DefaultHasher<JSString*>::hash(str); }
-            ReturnType match(const DebuggerAndScript& tpl) {
+            HashNumber match(JSObject* obj) { return DefaultHasher<JSObject*>::hash(obj); }
+            HashNumber match(JSString* str) { return DefaultHasher<JSString*>::hash(str); }
+            HashNumber match(const DebuggerAndScript& tpl) {
                 return DefaultHasher<NativeObject*>::hash(mozilla::Get<0>(tpl)) ^
                        DefaultHasher<JSScript*>::hash(mozilla::Get<1>(tpl));
             }
-            ReturnType match(const DebuggerAndObject& tpl) {
+            HashNumber match(const DebuggerAndObject& tpl) {
                 return DefaultHasher<NativeObject*>::hash(mozilla::Get<0>(tpl)) ^
                        DefaultHasher<JSObject*>::hash(mozilla::Get<1>(tpl)) ^
                        (mozilla::Get<2>(tpl) << 5);
             }
         };
         static HashNumber hash(const CrossCompartmentKey& key) {
             return key.wrapped.match(HashFunctor());
         }
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -609,19 +609,18 @@ js::ZoneGlobalsAreAllGray(JS::Zone* zone
 namespace {
 struct VisitGrayCallbackFunctor {
     GCThingCallback callback_;
     void* closure_;
     VisitGrayCallbackFunctor(GCThingCallback callback, void* closure)
       : callback_(callback), closure_(closure)
     {}
 
-    using ReturnType = void;
     template <class T>
-    ReturnType operator()(T tp) const {
+    void operator()(T tp) const {
         if ((*tp)->isTenured() && (*tp)->asTenured().isMarked(gc::GRAY))
             callback_(closure_, JS::GCCellPtr(*tp));
     }
 };
 } // namespace (anonymous)
 
 JS_FRIEND_API(void)
 js::VisitGrayWrapperTargets(Zone* zone, GCThingCallback callback, void* closure)
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -3666,17 +3666,16 @@ class CompartmentCheckTracer : public JS
     JSCompartment* compartment;
 };
 
 namespace {
 struct IsDestComparatorFunctor {
     JS::GCCellPtr dst_;
     explicit IsDestComparatorFunctor(JS::GCCellPtr dst) : dst_(dst) {}
 
-    using ReturnType = bool;
     template <typename T> bool operator()(T* t) { return (*t) == dst_.asCell(); }
 };
 } // namespace (anonymous)
 
 static bool
 InCrossCompartmentMap(JSObject* src, JS::GCCellPtr dst)
 {
     JSCompartment* srccomp = src->compartment();
@@ -4374,19 +4373,18 @@ namespace {
 struct AddOutgoingEdgeFunctor {
     bool needsEdge_;
     ZoneComponentFinder& finder_;
 
     AddOutgoingEdgeFunctor(bool needsEdge, ZoneComponentFinder& finder)
       : needsEdge_(needsEdge), finder_(finder)
     {}
 
-    using ReturnType = void;
     template <typename T>
-    ReturnType operator()(T tp) {
+    void operator()(T tp) {
         TenuredCell& other = (*tp)->asTenured();
 
         /*
          * Add edge to wrapped object compartment if wrapped object is not
          * marked black to indicate that wrapper compartment not be swept
          * after wrapped compartment.
          */
         if (needsEdge_) {
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1856,34 +1856,32 @@ UncompressedSourceCache::sizeOfExcluding
     return n;
 }
 
 const char16_t*
 ScriptSource::chars(JSContext* cx, UncompressedSourceCache::AutoHoldEntry& holder)
 {
     struct CharsMatcher
     {
-        using ReturnType = const char16_t*;
-
         JSContext* cx;
         ScriptSource& ss;
         UncompressedSourceCache::AutoHoldEntry& holder;
 
         explicit CharsMatcher(JSContext* cx, ScriptSource& ss,
                               UncompressedSourceCache::AutoHoldEntry& holder)
           : cx(cx)
           , ss(ss)
           , holder(holder)
         { }
 
-        ReturnType match(Uncompressed& u) {
+        const char16_t* match(Uncompressed& u) {
             return u.string.chars();
         }
 
-        ReturnType match(Compressed& c) {
+        const char16_t* match(Compressed& c) {
             if (const char16_t* decompressed = cx->caches.uncompressedSourceCache.lookup(&ss, holder))
                 return decompressed;
 
             const size_t lengthWithNull = ss.length() + 1;
             UniqueTwoByteChars decompressed(js_pod_malloc<char16_t>(lengthWithNull));
             if (!decompressed) {
                 JS_ReportOutOfMemory(cx);
                 return nullptr;
@@ -1911,25 +1909,25 @@ ScriptSource::chars(JSContext* cx, Uncom
                 if (!str) {
                     JS_ReportOutOfMemory(cx);
                     return nullptr;
                 }
                 ss.data = SourceType(Uncompressed(mozilla::Move(*str)));
                 return ss.data.as<Uncompressed>().string.chars();
             }
 
-            ReturnType ret = decompressed.get();
+            const char16_t* ret = decompressed.get();
             if (!cx->caches.uncompressedSourceCache.put(&ss, Move(decompressed), holder)) {
                 JS_ReportOutOfMemory(cx);
                 return nullptr;
             }
             return ret;
         }
 
-        ReturnType match(Missing&) {
+        const char16_t* match(Missing&) {
             MOZ_CRASH("ScriptSource::chars() on ScriptSource with SourceType = Missing");
             return nullptr;
         }
     };
 
     CharsMatcher cm(cx, *this, holder);
     return data.match(cm);
 }
@@ -2142,45 +2140,41 @@ ScriptSource::addSizeOfIncludingThis(moz
 }
 
 template<XDRMode mode>
 bool
 ScriptSource::performXDR(XDRState<mode>* xdr)
 {
     struct CompressedLengthMatcher
     {
-        using ReturnType = size_t;
-
-        ReturnType match(Uncompressed&) {
+        size_t match(Uncompressed&) {
             return 0;
         }
 
-        ReturnType match(Compressed& c) {
+        size_t match(Compressed& c) {
             return c.raw.length();
         }
 
-        ReturnType match(Missing&) {
+        size_t match(Missing&) {
             MOZ_CRASH("Missing source data in ScriptSource::performXDR");
             return 0;
         }
     };
 
     struct RawDataMatcher
     {
-        using ReturnType = void*;
-
-        ReturnType match(Uncompressed& u) {
+        void* match(Uncompressed& u) {
             return (void*) u.string.chars();
         }
 
-        ReturnType match(Compressed& c) {
+        void* match(Compressed& c) {
             return (void*) c.raw.chars();
         }
 
-        ReturnType match(Missing&) {
+        void* match(Missing&) {
             MOZ_CRASH("Missing source data in ScriptSource::performXDR");
             return nullptr;
         }
     };
 
     uint8_t hasSource = hasSourceData();
     if (!xdr->codeUint8(&hasSource))
         return false;
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -734,27 +734,25 @@ class ScriptSource
     void setSourceRetrievable() { sourceRetrievable_ = true; }
     bool sourceRetrievable() const { return sourceRetrievable_; }
     bool hasSourceData() const { return !data.is<Missing>(); }
     bool hasCompressedSource() const { return data.is<Compressed>(); }
 
     size_t length() const {
         struct LengthMatcher
         {
-            using ReturnType = size_t;
-
-            ReturnType match(const Uncompressed& u) {
+            size_t match(const Uncompressed& u) {
                 return u.string.length();
             }
 
-            ReturnType match(const Compressed& c) {
+            size_t match(const Compressed& c) {
                 return c.uncompressedLength;
             }
 
-            ReturnType match(const Missing& m) {
+            size_t match(const Missing& m) {
                 MOZ_CRASH("ScriptSource::length on a missing source");
                 return 0;
             }
         };
 
         MOZ_ASSERT(hasSourceData());
         return data.match(LengthMatcher());
     }
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -1560,18 +1560,16 @@ ConcreteStackFrame<SavedFrame>::construc
     }
     return true;
 }
 
 // A `mozilla::Variant` matcher that converts the inner value of a
 // `JS::ubi::AtomOrTwoByteChars` string to a `JSAtom*`.
 struct MOZ_STACK_CLASS AtomizingMatcher
 {
-    using ReturnType = JSAtom*;
-
     JSContext* cx;
     size_t     length;
 
     explicit AtomizingMatcher(JSContext* cx, size_t length)
       : cx(cx)
       , length(length)
     { }
 
--- a/js/src/vm/UbiNode.cpp
+++ b/js/src/vm/UbiNode.cpp
@@ -50,18 +50,16 @@ using JS::ubi::EdgeRange;
 using JS::ubi::Node;
 using JS::ubi::EdgeVector;
 using JS::ubi::StackFrame;
 using JS::ubi::TracerConcrete;
 using JS::ubi::TracerConcreteWithCompartment;
 
 struct CopyToBufferMatcher
 {
-    using ReturnType = size_t;
-
     RangedPtr<char16_t> destination;
     size_t              maxLength;
 
     CopyToBufferMatcher(RangedPtr<char16_t> destination, size_t maxLength)
       : destination(destination)
       , maxLength(maxLength)
     { }
 
@@ -103,18 +101,16 @@ size_t
 JS::ubi::AtomOrTwoByteChars::copyToBuffer(RangedPtr<char16_t> destination, size_t length)
 {
     CopyToBufferMatcher m(destination, length);
     return match(m);
 }
 
 struct LengthMatcher
 {
-    using ReturnType = size_t;
-
     size_t
     match(JSAtom* atom)
     {
         return atom ? atom->length() : 0;
     }
 
     size_t
     match(const char16_t* chars)
--- a/mfbt/Variant.h
+++ b/mfbt/Variant.h
@@ -164,20 +164,21 @@ struct VariantImplementation<N, T> {
   }
 
   template<typename Variant>
   static bool
   equal(const Variant& aLhs, const Variant& aRhs) {
       return aLhs.template as<T>() == aRhs.template as<T>();
   }
 
-  template<typename Matcher, typename ConcreteVariant,
-           typename ReturnType = typename RemoveReference<Matcher>::Type::ReturnType>
-  static ReturnType
-  match(Matcher&& aMatcher, ConcreteVariant& aV) {
+  template<typename Matcher, typename ConcreteVariant>
+  static auto
+  match(Matcher&& aMatcher, ConcreteVariant& aV)
+    -> decltype(aMatcher.match(aV.template as<T>()))
+  {
     return aMatcher.match(aV.template as<T>());
   }
 };
 
 // VariantImplementation for some variant type T.
 template<size_t N, typename T, typename... Ts>
 struct VariantImplementation<N, T, Ts...>
 {
@@ -221,20 +222,20 @@ struct VariantImplementation<N, T, Ts...
     if (aLhs.template is<T>()) {
       MOZ_ASSERT(aRhs.template is<T>());
       return aLhs.template as<T>() == aRhs.template as<T>();
     } else {
       return Next::equal(aLhs, aRhs);
     }
   }
 
-  template<typename Matcher, typename ConcreteVariant,
-           typename ReturnType = typename RemoveReference<Matcher>::Type::ReturnType>
-  static ReturnType
+  template<typename Matcher, typename ConcreteVariant>
+  static auto
   match(Matcher&& aMatcher, ConcreteVariant& aV)
+    -> decltype(aMatcher.match(aV.template as<T>()))
   {
     if (aV.template is<T>()) {
       return aMatcher.match(aV.template as<T>());
     } else {
       // If you're seeing compilation errors here like "no matching
       // function for call to 'match'" then that means that the
       // Matcher doesn't exhaust all variant types. There must exist a
       // Matcher::match(T&) for every variant type T.
@@ -365,21 +366,21 @@ struct AsVariantTemporary
  *       } else {
  *         return doSomething(v.as<C>()); // Forgot about case D!
  *       }
  *     }
  *
  *     // Good!
  *     struct FooMatcher
  *     {
- *       using ReturnType = char*;
- *       ReturnType match(A& a) { ... }
- *       ReturnType match(B& b) { ... }
- *       ReturnType match(C& c) { ... }
- *       ReturnType match(D& d) { ... } // Compile-time error to forget D!
+ *       // The return type of all matchers must be identical.
+ *       char* match(A& a) { ... }
+ *       char* match(B& b) { ... }
+ *       char* match(C& c) { ... }
+ *       char* match(D& d) { ... } // Compile-time error to forget D!
  *     }
  *     char* foo(Variant<A, B, C, D>& v) {
  *       return v.match(FooMatcher());
  *     }
  *
  * ## Examples
  *
  * A tree is either an empty leaf, or a node with a value and two children:
@@ -553,25 +554,29 @@ public:
     MOZ_ASSERT(is<T>());
     return T(Move(as<T>()));
   }
 
   // Exhaustive matching of all variant types on the contained value.
 
   /** Match on an immutable const reference. */
   template<typename Matcher>
-  typename RemoveReference<Matcher>::Type::ReturnType
-  match(Matcher&& aMatcher) const {
+  auto
+  match(Matcher&& aMatcher) const
+    -> decltype(Impl::match(aMatcher, *this))
+  {
     return Impl::match(aMatcher, *this);
   }
 
   /** Match on a mutable non-const reference. */
   template<typename Matcher>
-  typename RemoveReference<Matcher>::Type::ReturnType
-  match(Matcher&& aMatcher) {
+  auto
+  match(Matcher&& aMatcher)
+    -> decltype(Impl::match(aMatcher, *this))
+  {
     return Impl::match(aMatcher, *this);
   }
 };
 
 /*
  * AsVariant() is used to construct a Variant<T,...> value containing the
  * provided T value using type inference. It can be used to construct Variant
  * values in expressions or return them from functions without specifying the
--- a/mfbt/tests/TestVariant.cpp
+++ b/mfbt/tests/TestVariant.cpp
@@ -124,18 +124,16 @@ testEquality()
 }
 
 struct Describer
 {
   static const char* little;
   static const char* medium;
   static const char* big;
 
-  using ReturnType = const char*;
-
   const char* match(const uint8_t&) { return little; }
   const char* match(const uint32_t&) { return medium; }
   const char* match(const uint64_t&) { return big; }
 };
 
 const char* Describer::little = "little";
 const char* Describer::medium = "medium";
 const char* Describer::big = "big";
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -508,20 +508,20 @@ pref("media.navigator.audio.full_duplex"
 #endif
 #endif
 
 #if !defined(ANDROID)
 pref("media.getusermedia.screensharing.enabled", true);
 #endif
 
 #ifdef RELEASE_BUILD
-pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org,*.circuit.com,*.yourcircuit.com,circuit.siemens.com,yourcircuit.siemens.com,circuitsandbox.net,*.unify.com,tandi.circuitsandbox.net,*.ericsson.net,*.cct.ericsson.net,*.opentok.com,*.conf.meetecho.com,meet.jit.si,*.meet.jit.si,web.stage.speakeasyapp.net,web.speakeasyapp.net,*.hipchat.me,*.beta-wspbx.com,*.wspbx.com,*.unifiedcloudit.com,*.smartboxuc.com,*.smartbox-uc.com,*.panterranetworks.com,pexipdemo.com,*.pexipdemo.com,pex.me,*.pex.me,*.rd.pexip.com,1click.io,*.1click.io,*.fuze.com,*.fuzemeeting.com,*.thinkingphones.com,gotomeeting.com,*.gotomeeting.com,gotowebinar.com,*.gotowebinar.com,gototraining.com,*.gototraining.com,citrix.com,*.citrix.com,expertcity.com,*.expertcity.com,citrixonline.com,*.citrixonline.com,g2m.me,*.g2m.me,gotomeet.me,*.gotomeet.me,gotomeet.at,*.gotomeet.at,miriadaxdes.miriadax.net,certificacion.miriadax.net,miriadax.net");
+pref("media.getusermedia.screensharing.allowed_domains", "webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org,*.circuit.com,*.yourcircuit.com,circuit.siemens.com,yourcircuit.siemens.com,circuitsandbox.net,*.unify.com,tandi.circuitsandbox.net,*.ericsson.net,*.cct.ericsson.net,*.opentok.com,*.conf.meetecho.com,meet.jit.si,*.meet.jit.si,web.stage.speakeasyapp.net,web.speakeasyapp.net,*.hipchat.me,*.beta-wspbx.com,*.wspbx.com,*.unifiedcloudit.com,*.smartboxuc.com,*.smartbox-uc.com,*.panterranetworks.com,pexipdemo.com,*.pexipdemo.com,pex.me,*.pex.me,*.rd.pexip.com,1click.io,*.1click.io,*.fuze.com,*.fuzemeeting.com,*.thinkingphones.com,gotomeeting.com,*.gotomeeting.com,gotowebinar.com,*.gotowebinar.com,gototraining.com,*.gototraining.com,citrix.com,*.citrix.com,expertcity.com,*.expertcity.com,citrixonline.com,*.citrixonline.com,g2m.me,*.g2m.me,gotomeet.me,*.gotomeet.me,gotomeet.at,*.gotomeet.at,miriadaxdes.miriadax.net,certificacion.miriadax.net,miriadax.net,*.wire.com");
 #else
  // includes Mozilla's test domain: mozilla.github.io (not intended for release)
-pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org,*.circuit.com,*.yourcircuit.com,circuit.siemens.com,yourcircuit.siemens.com,circuitsandbox.net,*.unify.com,tandi.circuitsandbox.net,*.ericsson.net,*.cct.ericsson.net,*.opentok.com,*.conf.meetecho.com,meet.jit.si,*.meet.jit.si,web.stage.speakeasyapp.net,web.speakeasyapp.net,*.hipchat.me,*.beta-wspbx.com,*.wspbx.com,*.unifiedcloudit.com,*.smartboxuc.com,*.smartbox-uc.com,*.panterranetworks.com,pexipdemo.com,*.pexipdemo.com,pex.me,*.pex.me,*.rd.pexip.com,1click.io,*.1click.io,*.fuze.com,*.fuzemeeting.com,*.thinkingphones.com,gotomeeting.com,*.gotomeeting.com,gotowebinar.com,*.gotowebinar.com,gototraining.com,*.gototraining.com,citrix.com,*.citrix.com,expertcity.com,*.expertcity.com,citrixonline.com,*.citrixonline.com,g2m.me,*.g2m.me,gotomeet.me,*.gotomeet.me,gotomeet.at,*.gotomeet.at,miriadaxdes.miriadax.net,certificacion.miriadax.net,miriadax.net");
+pref("media.getusermedia.screensharing.allowed_domains", "mozilla.github.io,webex.com,*.webex.com,ciscospark.com,*.ciscospark.com,projectsquared.com,*.projectsquared.com,*.room.co,room.co,beta.talky.io,talky.io,*.clearslide.com,appear.in,*.appear.in,tokbox.com,*.tokbox.com,*.sso.francetelecom.fr,*.si.francetelecom.fr,*.sso.infra.ftgroup,*.multimedia-conference.orange-business.com,*.espacecollaboration.orange-business.com,free.gotomeeting.com,g2m.me,*.g2m.me,*.mypurecloud.com,*.mypurecloud.com.au,spreed.me,*.spreed.me,*.spreed.com,air.mozilla.org,*.circuit.com,*.yourcircuit.com,circuit.siemens.com,yourcircuit.siemens.com,circuitsandbox.net,*.unify.com,tandi.circuitsandbox.net,*.ericsson.net,*.cct.ericsson.net,*.opentok.com,*.conf.meetecho.com,meet.jit.si,*.meet.jit.si,web.stage.speakeasyapp.net,web.speakeasyapp.net,*.hipchat.me,*.beta-wspbx.com,*.wspbx.com,*.unifiedcloudit.com,*.smartboxuc.com,*.smartbox-uc.com,*.panterranetworks.com,pexipdemo.com,*.pexipdemo.com,pex.me,*.pex.me,*.rd.pexip.com,1click.io,*.1click.io,*.fuze.com,*.fuzemeeting.com,*.thinkingphones.com,gotomeeting.com,*.gotomeeting.com,gotowebinar.com,*.gotowebinar.com,gototraining.com,*.gototraining.com,citrix.com,*.citrix.com,expertcity.com,*.expertcity.com,citrixonline.com,*.citrixonline.com,g2m.me,*.g2m.me,gotomeet.me,*.gotomeet.me,gotomeet.at,*.gotomeet.at,miriadaxdes.miriadax.net,certificacion.miriadax.net,miriadax.net,*.wire.com");
 #endif
 // OS/X 10.6 and XP have screen/window sharing off by default due to various issues - Caveat emptor
 pref("media.getusermedia.screensharing.allow_on_old_platforms", false);
 
 pref("media.getusermedia.audiocapture.enabled", false);
 
 // TextTrack support
 pref("media.webvtt.enabled", true);
@@ -5118,17 +5118,17 @@ pref("browser.safebrowsing.provider.goog
 pref("browser.safebrowsing.provider.google.gethashURL", "https://safebrowsing.google.com/safebrowsing/gethash?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2");
 pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
 
 pref("browser.safebrowsing.reportPhishMistakeURL", "https://%LOCALE%.phish-error.mozilla.com/?hl=%LOCALE%&url=");
 pref("browser.safebrowsing.reportPhishURL", "https://%LOCALE%.phish-report.mozilla.com/?hl=%LOCALE%&url=");
 pref("browser.safebrowsing.reportMalwareMistakeURL", "https://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%&url=");
 
 // The table and global pref for blocking plugin content
-pref("browser.safebrowsing.blockedURIs.enabled", false);
+pref("browser.safebrowsing.blockedURIs.enabled", true);
 pref("urlclassifier.blockedTable", "test-block-simple,mozplugin-block-digest256");
 
 // The protocol version we communicate with mozilla server.
 pref("browser.safebrowsing.provider.mozilla.pver", "2.2");
 pref("browser.safebrowsing.provider.mozilla.lists", "mozstd-track-digest256,mozstd-trackwhite-digest256,mozfull-track-digest256,mozplugin-block-digest256,mozplugin2-block-digest256");
 pref("browser.safebrowsing.provider.mozilla.updateURL", "https://shavar.services.mozilla.com/downloads?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2");
 pref("browser.safebrowsing.provider.mozilla.gethashURL", "https://shavar.services.mozilla.com/gethash?client=SAFEBROWSING_ID&appver=%MAJOR_VERSION%&pver=2.2");
 // Set to a date in the past to force immediate download in new profiles.
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -346,17 +346,17 @@ TLSFilterTransaction::WriteSegments(nsAH
     return NS_ERROR_UNEXPECTED;
   }
 
   mSegmentWriter = aWriter;
   nsresult rv = mTransaction->WriteSegments(this, aCount, outCountWritten);
   if (NS_SUCCEEDED(rv) && NS_FAILED(mFilterReadCode) && !(*outCountWritten)) {
     // nsPipe turns failures into silent OK.. undo that!
     rv = mFilterReadCode;
-    if (mFilterReadCode == NS_BASE_STREAM_WOULD_BLOCK) {
+    if (Connection() && (mFilterReadCode == NS_BASE_STREAM_WOULD_BLOCK)) {
       Connection()->ResumeRecv();
     }
   }
   LOG(("TLSFilterTransaction %p called trans->WriteSegments rv=%x %d\n",
        this, rv, *outCountWritten));
   return rv;
 }
 
--- a/testing/mochitest/runtests.py
+++ b/testing/mochitest/runtests.py
@@ -519,32 +519,32 @@ class MochitestBase(object):
 
     oldcwd = os.getcwd()
     mochijar = os.path.join(SCRIPT_DIR, 'mochijar')
 
     # Path to the test script on the server
     TEST_PATH = "tests"
     NESTED_OOP_TEST_PATH = "nested_oop"
     CHROME_PATH = "redirect.html"
-    urlOpts = []
     log = None
 
     def __init__(self, logger_options):
         self.update_mozinfo()
         self.server = None
         self.wsserver = None
         self.websocketProcessBridge = None
         self.sslTunnel = None
         self._active_tests = None
         self._locations = None
 
         self.marionette = None
         self.start_script = None
         self.mozLogs = None
         self.start_script_args = []
+        self.urlOpts = []
 
         if self.log is None:
             commandline.log_formatters["tbpl"] = (
                 MochitestFormatter,
                 "Mochitest specific tbpl formatter")
             self.log = commandline.setup_logging("mochitest",
                                                  logger_options,
                                                  {
--- a/testing/mochitest/runtestsremote.py
+++ b/testing/mochitest/runtestsremote.py
@@ -177,25 +177,16 @@ class MochiRemote(MochitestDesktop):
             savedTestingModulesDir = options.testingModulesDir
             options.testingModulesDir = self.remoteModulesDir
         else:
             savedTestingModulesDir = None
         manifest = MochitestDesktop.buildProfile(self, options)
         if savedTestingModulesDir:
             options.testingModulesDir = savedTestingModulesDir
         self.localProfile = options.profilePath
-        self._dm.removeDir(self.remoteProfile)
-
-        try:
-            self._dm.pushDir(options.profilePath, self.remoteProfile)
-            self._dm.chmodDir(self.remoteProfile)
-        except mozdevice.DMError:
-            self.log.error(
-                "Automation Error: Unable to copy profile to device.")
-            raise
 
         restoreRemotePaths()
         options.profilePath = self.remoteProfile
         return manifest
 
     def addChromeToProfile(self, options):
         manifest = MochitestDesktop.addChromeToProfile(self, options)
 
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
+++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py
@@ -647,26 +647,29 @@ class DeviceManagerADB(DeviceManager):
                 retries += 1
             else:
                 return ret_code
 
         raise DMError("Timeout exceeded for _checkCmd call after %d retries." % retries)
 
     def chmodDir(self, remoteDir, mask="777"):
         if (self.dirExists(remoteDir)):
-            files = self.listFiles(remoteDir.strip())
-            for f in files:
-                remoteEntry = remoteDir.strip() + "/" + f.strip()
-                if (self.dirExists(remoteEntry)):
-                    self.chmodDir(remoteEntry)
-                else:
-                    self._checkCmd(["shell", "chmod", mask, remoteEntry], timeout=self.short_timeout)
-                    self._logger.info("chmod %s" % remoteEntry)
-            self._checkCmd(["shell", "chmod", mask, remoteDir], timeout=self.short_timeout)
-            self._logger.debug("chmod %s" % remoteDir)
+            if '/sdcard' in remoteDir:
+                self._logger.debug("chmod %s -- skipped (/sdcard)" % remoteDir)
+            else:
+                files = self.listFiles(remoteDir.strip())
+                for f in files:
+                    remoteEntry = remoteDir.strip() + "/" + f.strip()
+                    if (self.dirExists(remoteEntry)):
+                        self.chmodDir(remoteEntry)
+                    else:
+                        self._checkCmd(["shell", "chmod", mask, remoteEntry], timeout=self.short_timeout)
+                        self._logger.info("chmod %s" % remoteEntry)
+                self._checkCmd(["shell", "chmod", mask, remoteDir], timeout=self.short_timeout)
+                self._logger.debug("chmod %s" % remoteDir)
         else:
             self._checkCmd(["shell", "chmod", mask, remoteDir.strip()], timeout=self.short_timeout)
             self._logger.debug("chmod %s" % remoteDir.strip())
 
     def _verifyADB(self):
         """
         Check to see if adb itself can be executed.
         """
--- a/toolkit/mozapps/update/content/updates.js
+++ b/toolkit/mozapps/update/content/updates.js
@@ -399,29 +399,28 @@ var gUpdates = {
           return;
         }
 
         var p = this.update.selectedPatch;
         if (p) {
           let state = p.state;
           let patchFailed = this.update.getProperty("patchingFailed");
           if (patchFailed) {
-            if (patchFailed == "partial" && this.update.patchCount == 2) {
+            if (patchFailed != "partial" || this.update.patchCount != 2) {
+              // If the complete patch failed, which is far less likely, show
+              // the error text held by the update object in the generic errors
+              // page, triggered by the |STATE_DOWNLOAD_FAILED| state. This also
+              // handles the case when an elevation was cancelled on Mac OS X.
+              state = STATE_DOWNLOAD_FAILED;
+            } else {
               // If the system failed to apply the partial patch, show the
               // screen which best describes this condition, which is triggered
               // by the |STATE_FAILED| state.
               state = STATE_FAILED;
             }
-            else {
-              // Otherwise, if the complete patch failed, which is far less
-              // likely, show the error text held by the update object in the
-              // generic errors page, triggered by the |STATE_DOWNLOAD_FAILED|
-              // state.
-              state = STATE_DOWNLOAD_FAILED;
-            }
           }
 
           // Now select the best page to start with, given the current state of
           // the Update.
           switch (state) {
             case STATE_PENDING:
             case STATE_PENDING_SERVICE:
             case STATE_PENDING_ELEVATE:
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -1279,20 +1279,18 @@ function handleUpdateFailure(update, err
                                DEFAULT_CANCELATIONS_OSX_MAX);
       if (osxCancelations >= DEFAULT_CANCELATIONS_OSX_MAX) {
         cleanupActiveUpdate();
       } else {
         writeStatusFile(getUpdatesDir(),
                         update.state = STATE_PENDING_ELEVATE);
       }
       update.statusText = gUpdateBundle.GetStringFromName("elevationFailure");
-      let oldType = update.selectedPatch ? update.selectedPatch.type
-                                         : "complete";
       update.QueryInterface(Ci.nsIWritablePropertyBag);
-      update.setProperty("patchingFailed", oldType);
+      update.setProperty("patchingFailed", "elevationFailure");
       let prompter = Cc["@mozilla.org/updates/update-prompt;1"].
                  createInstance(Ci.nsIUpdatePrompt);
       prompter.showUpdateError(update);
     } else {
       writeStatusFile(getUpdatesDir(), update.state = STATE_PENDING);
     }
     return true;
   }