Merge mozilla-central to inbound. a=merge CLOSED TREE
authorMargareta Eliza Balazs <ebalazs@mozilla.com>
Mon, 16 Apr 2018 21:51:56 +0300
changeset 467406 c95f5a65950c40a4315f8c4b9cfb81916c63710f
parent 467405 970da641be1aa033bd3aa5f6b928de7bb75b6d22 (current diff)
parent 467362 6a87ef9c1acc5f6af848c00b8b9f608444ff8a72 (diff)
child 467407 0ceabd10aac2272e83850e278c7876f32dbae42e
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone61.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 inbound. a=merge CLOSED TREE
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -284,17 +284,17 @@ GMPChild::RecvPreloadLibs(const nsCStrin
   // Items in this must be lowercase!
   constexpr static const char16_t* whitelist[] = {
     u"dxva2.dll", // Get monitor information
     u"evr.dll", // MFGetStrideForBitmapInfoHeader
     u"mfplat.dll", // MFCreateSample, MFCreateAlignedMemoryBuffer, MFCreateMediaType
     u"msmpeg2vdec.dll", // H.264 decoder
     u"psapi.dll", // For GetMappedFileNameW, see bug 1383611
   };
-  constexpr static bool (*IsASCII)(const char16_t*) = NS_IsAscii;
+  constexpr static bool (*IsASCII)(const char16_t*) = NS_ConstExprIsAscii;
   static_assert(AllOf(std::begin(whitelist), std::end(whitelist), IsASCII),
                 "Items in the whitelist must not contain non-ASCII "
                 "characters!");
 
   nsTArray<nsCString> libs;
   SplitAt(", ", aLibs, libs);
   for (nsCString lib : libs) {
     ToLowerCase(lib);
--- a/mfbt/HashFunctions.h
+++ b/mfbt/HashFunctions.h
@@ -205,26 +205,39 @@ MOZ_MUST_USE inline uint32_t
 HashGeneric(Args... aArgs)
 {
   return AddToHash(0, aArgs...);
 }
 
 namespace detail {
 
 template<typename T>
-constexpr uint32_t
+uint32_t
 HashUntilZero(const T* aStr)
 {
   uint32_t hash = 0;
-  for (; T c = *aStr; aStr++) {
+  for (T c; (c = *aStr); aStr++) {
     hash = AddToHash(hash, c);
   }
   return hash;
 }
 
+// This is a `constexpr` alternative to HashUntilZero(const T*). It should
+// only be used for compile-time computation because it uses recursion.
+// XXX: once support for GCC 4.9 is dropped, this function should be removed
+// and HashUntilZero(const T*) should be made `constexpr`.
+template<typename T>
+constexpr uint32_t
+ConstExprHashUntilZero(const T* aStr, uint32_t aHash)
+{
+  return !*aStr
+       ? aHash
+       : ConstExprHashUntilZero(aStr + 1, AddToHash(aHash, *aStr));
+}
+
 template<typename T>
 uint32_t
 HashKnownLength(const T* aStr, size_t aLength)
 {
   uint32_t hash = 0;
   for (size_t i = 0; i < aLength; i++) {
     hash = AddToHash(hash, aStr[i]);
   }
@@ -253,23 +266,35 @@ HashString(const char* aStr, size_t aLen
 
 MOZ_MUST_USE
 inline uint32_t
 HashString(const unsigned char* aStr, size_t aLength)
 {
   return detail::HashKnownLength(aStr, aLength);
 }
 
+MOZ_MUST_USE inline uint32_t
+HashString(const char16_t* aStr)
+{
+  return detail::HashUntilZero(aStr);
+}
+
+// This is a `constexpr` alternative to HashString(const char16_t*). It should
+// only be used for compile-time computation because it uses recursion.
+//
 // You may need to use the
 // MOZ_{PUSH,POP}_DISABLE_INTEGRAL_CONSTANT_OVERFLOW_WARNING macros if you use
 // this function. See the comment on those macros' definitions for more detail.
+//
+// XXX: once support for GCC 4.9 is dropped, this function should be removed
+// and HashString(const char16_t*) should be made `constexpr`.
 MOZ_MUST_USE constexpr uint32_t
-HashString(const char16_t* aStr)
+ConstExprHashString(const char16_t* aStr)
 {
-  return detail::HashUntilZero(aStr);
+  return detail::ConstExprHashUntilZero(aStr, 0);
 }
 
 MOZ_MUST_USE inline uint32_t
 HashString(const char16_t* aStr, size_t aLength)
 {
   return detail::HashKnownLength(aStr, aLength);
 }
 
--- a/xpcom/base/nsCRTGlue.cpp
+++ b/xpcom/base/nsCRTGlue.cpp
@@ -211,16 +211,53 @@ NS_IsUpper(char aChar)
 }
 
 bool
 NS_IsLower(char aChar)
 {
   return aChar != (char)nsLowerUpperUtils::kLower2Upper[(unsigned char)aChar];
 }
 
+bool
+NS_IsAscii(const char16_t* aString)
+{
+  while (*aString) {
+    if (0x0080 <= *aString) {
+      return false;
+    }
+    aString++;
+  }
+  return true;
+}
+
+bool
+NS_IsAscii(const char* aString)
+{
+  while (*aString) {
+    if (0x80 & *aString) {
+      return false;
+    }
+    aString++;
+  }
+  return true;
+}
+
+bool
+NS_IsAscii(const char* aString, uint32_t aLength)
+{
+  const char* end = aString + aLength;
+  while (aString < end) {
+    if (0x80 & *aString) {
+      return false;
+    }
+    ++aString;
+  }
+  return true;
+}
+
 #ifndef XPCOM_GLUE_AVOID_NSPR
 
 void
 NS_MakeRandomString(char* aBuf, int32_t aBufLen)
 {
 #define TABLE_SIZE 36
   static const char table[] = {
     'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
--- a/xpcom/base/nsCRTGlue.h
+++ b/xpcom/base/nsCRTGlue.h
@@ -99,51 +99,44 @@ bool NS_IsUpper(char aChar);
 bool NS_IsLower(char aChar);
 
 constexpr bool
 NS_IsAscii(char16_t aChar)
 {
   return (0x0080 > aChar);
 }
 
+bool NS_IsAscii(const char16_t* aString);
+bool NS_IsAscii(const char* aString);
+bool NS_IsAscii(const char* aString, uint32_t aLength);
+
+// These three functions are `constexpr` alternatives to NS_IsAscii. It should
+// only be used for compile-time computation because it uses recursion.
+// XXX: once support for GCC 4.9 is dropped, this function should be removed
+// and NS_IsAscii should be made `constexpr`.
 constexpr bool
-NS_IsAscii(const char16_t* aString)
+NS_ConstExprIsAscii(const char16_t* aString)
 {
-  while (*aString) {
-    if (0x0080 <= *aString) {
-      return false;
-    }
-    aString++;
-  }
-  return true;
+  return !*aString ? true :
+    !NS_IsAscii(*aString) ? false : NS_ConstExprIsAscii(aString + 1);
 }
 
 constexpr bool
-NS_IsAscii(const char* aString)
+NS_ConstExprIsAscii(const char* aString)
 {
-  while (*aString) {
-    if (0x80 & *aString) {
-      return false;
-    }
-    aString++;
-  }
-  return true;
+  return !*aString ? true :
+    !NS_IsAscii(*aString) ? false : NS_ConstExprIsAscii(aString + 1);
 }
 
 constexpr bool
-NS_IsAscii(const char* aString, uint32_t aLength)
+NS_ConstExprIsAscii(const char* aString, uint32_t aLength)
 {
-  const char* end = aString + aLength;
-  while (aString < end) {
-    if (0x80 & *aString) {
-      return false;
-    }
-    aString++;
-  }
-  return true;
+  return aLength == 0 ? true :
+    !NS_IsAscii(*aString) ? false :
+    NS_ConstExprIsAscii(aString + 1, aLength - 1);
 }
 
 constexpr bool
 NS_IsAsciiWhitespace(char16_t aChar)
 {
   return aChar == ' ' ||
          aChar == '\r' ||
          aChar == '\n' ||
--- a/xpcom/ds/nsAtom.h
+++ b/xpcom/ds/nsAtom.h
@@ -102,17 +102,17 @@ public:
 
   typedef mozilla::TrueType HasThreadSafeRefCnt;
 
 protected:
   // Used by nsStaticAtom.
   constexpr nsAtom(const char16_t* aStr, uint32_t aLength)
     : mLength(aLength)
     , mKind(static_cast<uint32_t>(nsAtom::AtomKind::Static))
-    , mHash(mozilla::HashString(aStr))
+    , mHash(mozilla::ConstExprHashString(aStr))
   {}
 
   // Used by nsDynamicAtom.
   nsAtom(AtomKind aKind, const nsAString& aString, uint32_t aHash)
     : mLength(aString.Length())
     , mKind(static_cast<uint32_t>(aKind))
     , mHash(aHash)
   {