Roll abseil_revision 1963f10ae5..2617970857

Change Log:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/1963f10ae5..2617970857
Full diff:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/1963f10ae5..2617970857

Bug: None
Change-Id: I1a91ade59ebe815732abbbbe9d626eab0495554b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3683513
Reviewed-by: Danil Chapovalov <danilchap@chromium.org>
Commit-Queue: Mirko Bonadei <mbonadei@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1013020}
NOKEYCHECK=True
GitOrigin-RevId: 9318c25aa47e13ed86332e984d2adb8c13f97d22
diff --git a/README.chromium b/README.chromium
index 97472dc..d837f8d 100644
--- a/README.chromium
+++ b/README.chromium
@@ -4,7 +4,7 @@
 License: Apache 2.0
 License File: LICENSE
 Version: 0
-Revision: 1963f10ae5cb32a7ea6d96b928f69d3c7fba0139
+Revision: 2617970857c46e6ec971865d54f00445c260f682
 Security Critical: yes
 
 Description:
diff --git a/absl/base/config.h b/absl/base/config.h
index a0d599f..4223629 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -212,11 +212,12 @@
 #endif
 
 // ABSL_HAVE_TLS is defined to 1 when __thread should be supported.
-// We assume __thread is supported on Linux when compiled with Clang or compiled
-// against libstdc++ with _GLIBCXX_HAVE_TLS defined.
+// We assume __thread is supported on Linux or Asylo when compiled with Clang or
+// compiled against libstdc++ with _GLIBCXX_HAVE_TLS defined.
 #ifdef ABSL_HAVE_TLS
 #error ABSL_HAVE_TLS cannot be directly set
-#elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS))
+#elif (defined(__linux__) || defined(__ASYLO__)) && \
+    (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS))
 #define ABSL_HAVE_TLS 1
 #endif
 
@@ -882,4 +883,19 @@
 #define ABSL_INTERNAL_HAVE_SSSE3 1
 #endif
 
+// ABSL_INTERNAL_HAVE_ARM_ACLE is used for compile-time detection of ACLE (ARM
+// C language extensions).
+#ifdef ABSL_INTERNAL_HAVE_ARM_ACLE
+#error ABSL_INTERNAL_HAVE_ARM_ACLE cannot be directly set
+// __cls, __rbit were added quite late in clang. They are not supported
+// by GCC as well. __cls can be replaced with __builtin_clrsb but clang does
+// not recognize cls instruction in latest versions.
+// TODO(b/233604649): Relax to __builtin_clrsb and __builtin_bitreverse64 (note
+// that the latter is not supported by GCC).
+#elif defined(__ARM_ACLE) && defined(__clang__) && \
+    ABSL_HAVE_BUILTIN(__builtin_arm_cls64) &&      \
+    ABSL_HAVE_BUILTIN(__builtin_arm_rbit64)
+#define ABSL_INTERNAL_HAVE_ARM_ACLE 1
+#endif
+
 #endif  // ABSL_BASE_CONFIG_H_
diff --git a/absl/base/internal/invoke.h b/absl/base/internal/invoke.h
index e9efb2f..4a644c6 100644
--- a/absl/base/internal/invoke.h
+++ b/absl/base/internal/invoke.h
@@ -49,6 +49,7 @@
 
 using std::invoke;
 using std::invoke_result_t;
+using std::is_invocable_r;
 
 }  // namespace base_internal
 ABSL_NAMESPACE_END
@@ -201,6 +202,26 @@
   return Invoker<F, Args...>::type::Invoke(std::forward<F>(f),
                                            std::forward<Args>(args)...);
 }
+
+template <typename AlwaysVoid, typename, typename, typename...>
+struct IsInvocableRImpl : std::false_type {};
+
+template <typename R, typename F, typename... Args>
+struct IsInvocableRImpl<
+    absl::void_t<absl::base_internal::invoke_result_t<F, Args...> >, R, F,
+    Args...>
+    : std::integral_constant<
+          bool,
+          std::is_convertible<absl::base_internal::invoke_result_t<F, Args...>,
+                              R>::value ||
+              std::is_void<R>::value> {};
+
+// Type trait whose member `value` is true if invoking `F` with `Args` is valid,
+// and either the return type is convertible to `R`, or `R` is void.
+// C++11-compatible version of `std::is_invocable_r`.
+template <typename R, typename F, typename... Args>
+using is_invocable_r = IsInvocableRImpl<void, R, F, Args...>;
+
 }  // namespace base_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/base/internal/spinlock_linux.inc b/absl/base/internal/spinlock_linux.inc
index 202f7cd..fe8ba67 100644
--- a/absl/base/internal/spinlock_linux.inc
+++ b/absl/base/internal/spinlock_linux.inc
@@ -57,13 +57,10 @@
 extern "C" {
 
 ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockDelay)(
-    std::atomic<uint32_t> *w, uint32_t value, int loop,
+    std::atomic<uint32_t> *w, uint32_t value, int,
     absl::base_internal::SchedulingMode) {
   absl::base_internal::ErrnoSaver errno_saver;
-  struct timespec tm;
-  tm.tv_sec = 0;
-  tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop);
-  syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm);
+  syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, nullptr);
 }
 
 ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(AbslInternalSpinLockWake)(
diff --git a/absl/base/invoke_test.cc b/absl/base/invoke_test.cc
index bcdef36..7be26f6 100644
--- a/absl/base/invoke_test.cc
+++ b/absl/base/invoke_test.cc
@@ -31,6 +31,14 @@
 
 int Function(int a, int b) { return a - b; }
 
+void VoidFunction(int& a, int& b) {
+  a += b;
+  b = a - b;
+  a -= b;
+}
+
+int ZeroArgFunction() { return -1937; }
+
 int Sink(std::unique_ptr<int> p) {
   return *p;
 }
@@ -223,6 +231,100 @@
   EXPECT_THAT(CallMaybeWithArg(Factory), ::testing::Pointee(42));
 }
 
+TEST(IsInvocableRTest, CallableExactMatch) {
+  static_assert(
+      base_internal::is_invocable_r<int, decltype(Function), int, int>::value,
+      "Should be true for exact match of types on a free function");
+}
+
+TEST(IsInvocableRTest, CallableArgumentConversionMatch) {
+  static_assert(
+      base_internal::is_invocable_r<int, decltype(Function), char, int>::value,
+      "Should be true for convertible argument type");
+}
+
+TEST(IsInvocableRTest, CallableReturnConversionMatch) {
+  static_assert(base_internal::is_invocable_r<double, decltype(Function), int,
+                                              int>::value,
+                "Should be true for convertible return type");
+}
+
+TEST(IsInvocableRTest, CallableReturnVoid) {
+  static_assert(base_internal::is_invocable_r<void, decltype(VoidFunction),
+                                              int&, int&>::value,
+                "Should be true for void expected and actual return types");
+  static_assert(
+      base_internal::is_invocable_r<void, decltype(Function), int, int>::value,
+      "Should be true for void expected and non-void actual return types");
+}
+
+TEST(IsInvocableRTest, CallableRefQualifierMismatch) {
+  static_assert(!base_internal::is_invocable_r<void, decltype(VoidFunction),
+                                               int&, const int&>::value,
+                "Should be false for reference constness mismatch");
+  static_assert(!base_internal::is_invocable_r<void, decltype(VoidFunction),
+                                               int&&, int&>::value,
+                "Should be false for reference value category mismatch");
+}
+
+TEST(IsInvocableRTest, CallableArgumentTypeMismatch) {
+  static_assert(!base_internal::is_invocable_r<int, decltype(Function),
+                                               std::string, int>::value,
+                "Should be false for argument type mismatch");
+}
+
+TEST(IsInvocableRTest, CallableReturnTypeMismatch) {
+  static_assert(!base_internal::is_invocable_r<std::string, decltype(Function),
+                                               int, int>::value,
+                "Should be false for return type mismatch");
+}
+
+TEST(IsInvocableRTest, CallableTooFewArgs) {
+  static_assert(
+      !base_internal::is_invocable_r<int, decltype(Function), int>::value,
+      "Should be false for too few arguments");
+}
+
+TEST(IsInvocableRTest, CallableTooManyArgs) {
+  static_assert(!base_internal::is_invocable_r<int, decltype(Function), int,
+                                               int, int>::value,
+                "Should be false for too many arguments");
+}
+
+TEST(IsInvocableRTest, MemberFunctionAndReference) {
+  static_assert(base_internal::is_invocable_r<int, decltype(&Class::Method),
+                                              Class&, int, int>::value,
+                "Should be true for exact match of types on a member function "
+                "and class reference");
+}
+
+TEST(IsInvocableRTest, MemberFunctionAndPointer) {
+  static_assert(base_internal::is_invocable_r<int, decltype(&Class::Method),
+                                              Class*, int, int>::value,
+                "Should be true for exact match of types on a member function "
+                "and class pointer");
+}
+
+TEST(IsInvocableRTest, DataMemberAndReference) {
+  static_assert(base_internal::is_invocable_r<int, decltype(&Class::member),
+                                              Class&>::value,
+                "Should be true for exact match of types on a data member and "
+                "class reference");
+}
+
+TEST(IsInvocableRTest, DataMemberAndPointer) {
+  static_assert(base_internal::is_invocable_r<int, decltype(&Class::member),
+                                              Class*>::value,
+                "Should be true for exact match of types on a data member and "
+                "class pointer");
+}
+
+TEST(IsInvocableRTest, CallableZeroArgs) {
+  static_assert(
+      base_internal::is_invocable_r<int, decltype(ZeroArgFunction)>::value,
+      "Should be true for exact match for a zero-arg free function");
+}
+
 }  // namespace
 }  // namespace base_internal
 ABSL_NAMESPACE_END
diff --git a/absl/container/btree_set.h b/absl/container/btree_set.h
index 7b6655a..32a7c50 100644
--- a/absl/container/btree_set.h
+++ b/absl/container/btree_set.h
@@ -752,6 +752,11 @@
   }
 
   template <typename Alloc>
+  static void construct(Alloc *alloc, slot_type *slot, const slot_type *other) {
+    absl::allocator_traits<Alloc>::construct(*alloc, slot, *other);
+  }
+
+  template <typename Alloc>
   static void destroy(Alloc *alloc, slot_type *slot) {
     absl::allocator_traits<Alloc>::destroy(*alloc, slot);
   }
diff --git a/absl/container/btree_test.cc b/absl/container/btree_test.cc
index 4d4c64b..b3fa98f 100644
--- a/absl/container/btree_test.cc
+++ b/absl/container/btree_test.cc
@@ -14,11 +14,14 @@
 
 #include "absl/container/btree_test.h"
 
+#include <algorithm>
+#include <array>
 #include <cstdint>
 #include <functional>
 #include <limits>
 #include <map>
 #include <memory>
+#include <numeric>
 #include <stdexcept>
 #include <string>
 #include <type_traits>
@@ -1291,7 +1294,7 @@
 
   std::unique_ptr<std::string> &v = m["A"];
   EXPECT_TRUE(v == nullptr);
-  v.reset(new std::string("X"));
+  v = absl::make_unique<std::string>("X");
 
   auto iter = m.find("A");
   EXPECT_EQ("X", *iter->second);
@@ -3081,6 +3084,110 @@
 }
 #endif
 
+class OnlyConstructibleByAllocator {
+  explicit OnlyConstructibleByAllocator(int i) : i_(i) {}
+
+ public:
+  OnlyConstructibleByAllocator(const OnlyConstructibleByAllocator &other)
+      : i_(other.i_) {}
+  OnlyConstructibleByAllocator &operator=(
+      const OnlyConstructibleByAllocator &other) {
+    i_ = other.i_;
+    return *this;
+  }
+  int Get() const { return i_; }
+  bool operator==(int i) const { return i_ == i; }
+
+ private:
+  template <typename T>
+  friend class OnlyConstructibleAllocator;
+
+  int i_;
+};
+
+template <typename T = OnlyConstructibleByAllocator>
+class OnlyConstructibleAllocator : public std::allocator<T> {
+ public:
+  OnlyConstructibleAllocator() = default;
+  template <class U>
+  explicit OnlyConstructibleAllocator(const OnlyConstructibleAllocator<U> &) {}
+
+  void construct(OnlyConstructibleByAllocator *p, int i) {
+    new (p) OnlyConstructibleByAllocator(i);
+  }
+  template <typename Pair>
+  void construct(Pair *p, const int i) {
+    OnlyConstructibleByAllocator only(i);
+    new (p) Pair(std::move(only), i);
+  }
+
+  template <class U>
+  struct rebind {
+    using other = OnlyConstructibleAllocator<U>;
+  };
+};
+
+struct OnlyConstructibleByAllocatorComp {
+  using is_transparent = void;
+  bool operator()(OnlyConstructibleByAllocator a,
+                  OnlyConstructibleByAllocator b) const {
+    return a.Get() < b.Get();
+  }
+  bool operator()(int a, OnlyConstructibleByAllocator b) const {
+    return a < b.Get();
+  }
+  bool operator()(OnlyConstructibleByAllocator a, int b) const {
+    return a.Get() < b;
+  }
+};
+
+TEST(Btree, OnlyConstructibleByAllocatorType) {
+  const std::array<int, 2> arr = {3, 4};
+  {
+    absl::btree_set<OnlyConstructibleByAllocator,
+                    OnlyConstructibleByAllocatorComp,
+                    OnlyConstructibleAllocator<>>
+        set;
+    set.emplace(1);
+    set.emplace_hint(set.end(), 2);
+    set.insert(arr.begin(), arr.end());
+    EXPECT_THAT(set, ElementsAre(1, 2, 3, 4));
+  }
+  {
+    absl::btree_multiset<OnlyConstructibleByAllocator,
+                         OnlyConstructibleByAllocatorComp,
+                         OnlyConstructibleAllocator<>>
+        set;
+    set.emplace(1);
+    set.emplace_hint(set.end(), 2);
+    // TODO(ezb): fix insert_multi to allow this to compile.
+    // set.insert(arr.begin(), arr.end());
+    EXPECT_THAT(set, ElementsAre(1, 2));
+  }
+  {
+    absl::btree_map<OnlyConstructibleByAllocator, int,
+                    OnlyConstructibleByAllocatorComp,
+                    OnlyConstructibleAllocator<>>
+        map;
+    map.emplace(1);
+    map.emplace_hint(map.end(), 2);
+    map.insert(arr.begin(), arr.end());
+    EXPECT_THAT(map,
+                ElementsAre(Pair(1, 1), Pair(2, 2), Pair(3, 3), Pair(4, 4)));
+  }
+  {
+    absl::btree_multimap<OnlyConstructibleByAllocator, int,
+                         OnlyConstructibleByAllocatorComp,
+                         OnlyConstructibleAllocator<>>
+        map;
+    map.emplace(1);
+    map.emplace_hint(map.end(), 2);
+    // TODO(ezb): fix insert_multi to allow this to compile.
+    // map.insert(arr.begin(), arr.end());
+    EXPECT_THAT(map, ElementsAre(Pair(1, 1), Pair(2, 2)));
+  }
+}
+
 }  // namespace
 }  // namespace container_internal
 ABSL_NAMESPACE_END
diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h
index cb39b16..1ff2e6e 100644
--- a/absl/container/internal/btree.h
+++ b/absl/container/internal/btree.h
@@ -504,8 +504,8 @@
 template <typename V>
 struct SearchResult<V, false> {
   SearchResult() {}
-  explicit SearchResult(V value) : value(value) {}
-  SearchResult(V value, MatchKind /*match*/) : value(value) {}
+  explicit SearchResult(V v) : value(v) {}
+  SearchResult(V v, MatchKind /*match*/) : value(v) {}
 
   V value;
 
@@ -1196,7 +1196,9 @@
   }
 
   const key_type &key() const { return node_->key(position_); }
-  slot_type *slot() { return node_->slot(position_); }
+  decltype(std::declval<Node *>()->slot(0)) slot() {
+    return node_->slot(position_);
+  }
 
   void assert_valid_generation() const {
 #ifdef ABSL_BTREE_ENABLE_GENERATIONS
@@ -1225,7 +1227,6 @@
 class btree {
   using node_type = btree_node<Params>;
   using is_key_compare_to = typename Params::is_key_compare_to;
-  using init_type = typename Params::init_type;
   using field_type = typename node_type::field_type;
 
   // We use a static empty node for the root/leftmost/rightmost of empty btrees
@@ -1309,14 +1310,6 @@
   using slot_type = typename Params::slot_type;
 
  private:
-  // For use in copy_or_move_values_in_order.
-  const value_type &maybe_move_from_iterator(const_iterator it) { return *it; }
-  value_type &&maybe_move_from_iterator(iterator it) {
-    // This is a destructive operation on the other container so it's safe for
-    // us to const_cast and move from the keys here even if it's a set.
-    return std::move(const_cast<value_type &>(*it));
-  }
-
   // Copies or moves (depending on the template parameter) the values in
   // other into this btree in their order in other. This btree must be empty
   // before this method is called. This method is used in copy construction,
@@ -2063,12 +2056,12 @@
   // values is the same order we'll store them in.
   auto iter = other.begin();
   if (iter == other.end()) return;
-  insert_multi(maybe_move_from_iterator(iter));
+  insert_multi(iter.slot());
   ++iter;
   for (; iter != other.end(); ++iter) {
     // If the btree is not empty, we can just insert the new value at the end
     // of the tree.
-    internal_emplace(end(), maybe_move_from_iterator(iter));
+    internal_emplace(end(), iter.slot());
   }
 }
 
@@ -2205,8 +2198,11 @@
 template <typename InputIterator>
 void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, char) {
   for (; b != e; ++b) {
-    init_type value(*b);
-    insert_hint_unique(end(), params_type::key(value), std::move(value));
+    // Use a node handle to manage a temp slot.
+    auto node_handle =
+        CommonAccess::Construct<node_handle_type>(get_allocator(), *b);
+    slot_type *slot = CommonAccess::GetSlot(node_handle);
+    insert_hint_unique(end(), params_type::key(slot), slot);
   }
 }
 
diff --git a/absl/container/internal/btree_container.h b/absl/container/internal/btree_container.h
index cc2e179..fc2f740 100644
--- a/absl/container/internal/btree_container.h
+++ b/absl/container/internal/btree_container.h
@@ -166,9 +166,10 @@
 
   // Extract routines.
   node_type extract(iterator position) {
-    // Use Move instead of Transfer, because the rebalancing code expects to
-    // have a valid object to scribble metadata bits on top of.
-    auto node = CommonAccess::Move<node_type>(get_allocator(), position.slot());
+    // Use Construct instead of Transfer because the rebalancing code will
+    // destroy the slot later.
+    auto node =
+        CommonAccess::Construct<node_type>(get_allocator(), position.slot());
     erase(position);
     return node;
   }
@@ -291,8 +292,11 @@
   }
   template <typename... Args>
   std::pair<iterator, bool> emplace(Args &&... args) {
-    init_type v(std::forward<Args>(args)...);
-    return this->tree_.insert_unique(params_type::key(v), std::move(v));
+    // Use a node handle to manage a temp slot.
+    auto node = CommonAccess::Construct<node_type>(this->get_allocator(),
+                                                   std::forward<Args>(args)...);
+    auto *slot = CommonAccess::GetSlot(node);
+    return this->tree_.insert_unique(params_type::key(slot), slot);
   }
   iterator insert(const_iterator hint, const value_type &v) {
     return this->tree_
@@ -306,9 +310,12 @@
   }
   template <typename... Args>
   iterator emplace_hint(const_iterator hint, Args &&... args) {
-    init_type v(std::forward<Args>(args)...);
+    // Use a node handle to manage a temp slot.
+    auto node = CommonAccess::Construct<node_type>(this->get_allocator(),
+                                                   std::forward<Args>(args)...);
+    auto *slot = CommonAccess::GetSlot(node);
     return this->tree_
-        .insert_hint_unique(iterator(hint), params_type::key(v), std::move(v))
+        .insert_hint_unique(iterator(hint), params_type::key(slot), slot)
         .first;
   }
   template <typename InputIterator>
@@ -598,12 +605,18 @@
   }
   template <typename... Args>
   iterator emplace(Args &&... args) {
-    return this->tree_.insert_multi(init_type(std::forward<Args>(args)...));
+    // Use a node handle to manage a temp slot.
+    auto node = CommonAccess::Construct<node_type>(this->get_allocator(),
+                                                   std::forward<Args>(args)...);
+    return this->tree_.insert_multi(CommonAccess::GetSlot(node));
   }
   template <typename... Args>
   iterator emplace_hint(const_iterator hint, Args &&... args) {
-    return this->tree_.insert_hint_multi(
-        iterator(hint), init_type(std::forward<Args>(args)...));
+    // Use a node handle to manage a temp slot.
+    auto node = CommonAccess::Construct<node_type>(this->get_allocator(),
+                                                   std::forward<Args>(args)...);
+    return this->tree_.insert_hint_multi(iterator(hint),
+                                         CommonAccess::GetSlot(node));
   }
   iterator insert(node_type &&node) {
     if (!node) return this->end();
diff --git a/absl/container/internal/common.h b/absl/container/internal/common.h
index 030e9d4..416d9aa 100644
--- a/absl/container/internal/common.h
+++ b/absl/container/internal/common.h
@@ -84,10 +84,11 @@
     PolicyTraits::transfer(alloc(), slot(), s);
   }
 
-  struct move_tag_t {};
-  node_handle_base(move_tag_t, const allocator_type& a, slot_type* s)
+  struct construct_tag_t {};
+  template <typename... Args>
+  node_handle_base(construct_tag_t, const allocator_type& a, Args&&... args)
       : alloc_(a) {
-    PolicyTraits::construct(alloc(), slot(), s);
+    PolicyTraits::construct(alloc(), slot(), std::forward<Args>(args)...);
   }
 
   void destroy() {
@@ -186,8 +187,8 @@
   }
 
   template <typename T, typename... Args>
-  static T Move(Args&&... args) {
-    return T(typename T::move_tag_t{}, std::forward<Args>(args)...);
+  static T Construct(Args&&... args) {
+    return T(typename T::construct_tag_t{}, std::forward<Args>(args)...);
   }
 };
 
diff --git a/absl/container/internal/container_memory.h b/absl/container/internal/container_memory.h
index e67529e..df49223 100644
--- a/absl/container/internal/container_memory.h
+++ b/absl/container/internal/container_memory.h
@@ -402,6 +402,15 @@
     }
   }
 
+  // Construct this slot by copying from another slot.
+  template <class Allocator>
+  static void construct(Allocator* alloc, slot_type* slot,
+                        const slot_type* other) {
+    emplace(slot);
+    absl::allocator_traits<Allocator>::construct(*alloc, &slot->value,
+                                                 other->value);
+  }
+
   template <class Allocator>
   static void destroy(Allocator* alloc, slot_type* slot) {
     if (kMutableKeys::value) {
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 769af50..d503bc0 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -211,6 +211,10 @@
 #include "absl/numeric/bits.h"
 #include "absl/utility/utility.h"
 
+#ifdef ABSL_INTERNAL_HAVE_ARM_ACLE
+#include <arm_acle.h>
+#endif
+
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace container_internal {
@@ -627,8 +631,40 @@
   uint64_t ctrl;
 };
 
+#ifdef ABSL_INTERNAL_HAVE_ARM_ACLE
+struct GroupAArch64Impl : public GroupPortableImpl {
+  static constexpr size_t kWidth = GroupPortableImpl::kWidth;
+
+  using GroupPortableImpl::GroupPortableImpl;
+
+  uint32_t CountLeadingEmptyOrDeleted() const {
+    assert(IsEmptyOrDeleted(static_cast<ctrl_t>(ctrl & 0xff)));
+    constexpr uint64_t gaps = 0x00FEFEFEFEFEFEFEULL;
+    // cls: Count leading sign bits.
+    // clsll(1ull << 63) -> 0
+    // clsll((1ull << 63) | (1ull << 62)) -> 1
+    // clsll((1ull << 63) | (1ull << 61)) -> 0
+    // clsll(~0ull) -> 63
+    // clsll(1) -> 62
+    // clsll(3) -> 61
+    // clsll(5) -> 60
+    // Note that CountLeadingEmptyOrDeleted is called when first control block
+    // is kDeleted or kEmpty. The implementation is similar to GroupPortableImpl
+    // but avoids +1 and __clsll returns result not including the high bit. Thus
+    // saves one cycle.
+    // kEmpty = -128,   // 0b10000000
+    // kDeleted = -2,   // 0b11111110
+    // ~ctrl & (ctrl >> 7) will have the lowest bit set to 1. After rbit,
+    // it will the highest one.
+    return (__clsll(__rbitll((~ctrl & (ctrl >> 7)) | gaps)) + 8) >> 3;
+  }
+};
+#endif
+
 #ifdef ABSL_INTERNAL_HAVE_SSE2
 using Group = GroupSse2Impl;
+#elif defined(ABSL_INTERNAL_HAVE_ARM_ACLE)
+using Group = GroupAArch64Impl;
 #else
 using Group = GroupPortableImpl;
 #endif
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 914ec0c..c79f864 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -262,16 +262,20 @@
 
   for (ctrl_t empty : empty_examples) {
     std::vector<ctrl_t> e(Group::kWidth, empty);
+    EXPECT_TRUE(IsEmptyOrDeleted(e[0]));
     EXPECT_EQ(Group::kWidth, Group{e.data()}.CountLeadingEmptyOrDeleted());
     for (ctrl_t full : full_examples) {
-      for (size_t i = 0; i != Group::kWidth; ++i) {
+      // First is always kEmpty or kDeleted.
+      for (size_t i = 1; i != Group::kWidth; ++i) {
         std::vector<ctrl_t> f(Group::kWidth, empty);
         f[i] = full;
+        EXPECT_TRUE(IsEmptyOrDeleted(f[0]));
         EXPECT_EQ(i, Group{f.data()}.CountLeadingEmptyOrDeleted());
       }
       std::vector<ctrl_t> f(Group::kWidth, empty);
       f[Group::kWidth * 2 / 3] = full;
       f[Group::kWidth / 2] = full;
+      EXPECT_TRUE(IsEmptyOrDeleted(f[0]));
       EXPECT_EQ(
           Group::kWidth / 2, Group{f.data()}.CountLeadingEmptyOrDeleted());
     }
diff --git a/absl/debugging/internal/elf_mem_image.h b/absl/debugging/internal/elf_mem_image.h
index e4bbf2d..113071a 100644
--- a/absl/debugging/internal/elf_mem_image.h
+++ b/absl/debugging/internal/elf_mem_image.h
@@ -31,8 +31,9 @@
 #error ABSL_HAVE_ELF_MEM_IMAGE cannot be directly set
 #endif
 
-#if defined(__ELF__) && !defined(__OpenBSD__) && !defined(__QNX__) &&  \
-    !defined(__native_client__) && !defined(__asmjs__) && !defined(__wasm__)
+#if defined(__ELF__) && !defined(__OpenBSD__) && !defined(__QNX__) && \
+    !defined(__native_client__) && !defined(__asmjs__) &&             \
+    !defined(__wasm__) && !defined(__HAIKU__)
 #define ABSL_HAVE_ELF_MEM_IMAGE 1
 #endif
 
diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h
index 34914d2..fc1e78b 100644
--- a/absl/status/internal/status_internal.h
+++ b/absl/status/internal/status_internal.h
@@ -69,6 +69,15 @@
 };
 
 absl::StatusCode MapToLocalCode(int value);
+
+// If `status` is not OK, returns a pointer to a newly-allocated string with the
+// given `prefix`, suitable for output as an error message in assertion/CHECK()
+// failures. Otherwise returns nullptr.
+//
+// This is an internal implementation detail for Abseil logging.
+std::string* MakeCheckFailString(const absl::Status& status,
+                                 const char* prefix);
+
 }  // namespace status_internal
 
 ABSL_NAMESPACE_END
diff --git a/absl/status/status.cc b/absl/status/status.cc
index fc5a142..c66009d 100644
--- a/absl/status/status.cc
+++ b/absl/status/status.cc
@@ -599,5 +599,17 @@
                 MessageForErrnoToStatus(error_number, message));
 }
 
+namespace status_internal {
+
+std::string* MakeCheckFailString(const absl::Status& status,
+                                 const char* prefix) {
+  if (status.ok()) { return nullptr; }
+  return new std::string(
+      absl::StrCat(prefix, " (",
+                   status.ToString(StatusToStringMode::kWithEverything), ")"));
+}
+
+}  // namespace status_internal
+
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/strings/cord.h b/absl/strings/cord.h
index 5ad4ea0..391b2c0 100644
--- a/absl/strings/cord.h
+++ b/absl/strings/cord.h
@@ -289,7 +289,7 @@
   // Cord::EstimatedMemoryUsage()
   //
   // Returns the *approximate* number of bytes held by this cord.
-  // See CordMemoryAccounting for more information on accounting method used.
+  // See CordMemoryAccounting for more information on the accounting method.
   size_t EstimatedMemoryUsage(CordMemoryAccounting accounting_method =
                                   CordMemoryAccounting::kTotal) const;
 
@@ -341,7 +341,7 @@
   //----------------------------------------------------------------------------
   //
   // A `Cord::ChunkIterator` allows iteration over the constituent chunks of its
-  // Cord. Such iteration allows you to perform non-const operatons on the data
+  // Cord. Such iteration allows you to perform non-const operations on the data
   // of a Cord without modifying it.
   //
   // Generally, you do not instantiate a `Cord::ChunkIterator` directly;
@@ -462,7 +462,7 @@
   class ChunkRange {
    public:
     // Fulfill minimum c++ container requirements [container.requirements]
-    // Theses (partial) container type definitions allow ChunkRange to be used
+    // These (partial) container type definitions allow ChunkRange to be used
     // in various utilities expecting a subset of [container.requirements].
     // For example, the below enables using `::testing::ElementsAre(...)`
     using value_type = absl::string_view;
@@ -596,7 +596,7 @@
   // producing an iterator which can be used within a range-based for loop.
   // Construction of a `CharRange` will return an iterator pointing to the first
   // character of the Cord. Generally, do not construct a `CharRange` directly;
-  // instead, prefer to use the `Cord::Chars()` method show below.
+  // instead, prefer to use the `Cord::Chars()` method shown below.
   //
   // Implementation note: `CharRange` is simply a convenience wrapper over
   // `Cord::char_begin()` and `Cord::char_end()`.
@@ -1500,7 +1500,7 @@
   }
 }
 
-// Nonmember Cord-to-Cord relational operarators.
+// Nonmember Cord-to-Cord relational operators.
 inline bool operator==(const Cord& lhs, const Cord& rhs) {
   if (lhs.contents_.IsSame(rhs.contents_)) return true;
   size_t rhs_size = rhs.size();
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h
index c47536d..55e8ac8 100644
--- a/absl/strings/internal/str_format/extension.h
+++ b/absl/strings/internal/str_format/extension.h
@@ -19,6 +19,7 @@
 #include <limits.h>
 
 #include <cstddef>
+#include <cstdint>
 #include <cstring>
 #include <ostream>
 
diff --git a/absl/synchronization/mutex.h b/absl/synchronization/mutex.h
index 9a3e438..b69b708 100644
--- a/absl/synchronization/mutex.h
+++ b/absl/synchronization/mutex.h
@@ -174,9 +174,12 @@
 
   // Mutex::AssertHeld()
   //
-  // Return immediately if this thread holds the `Mutex` exclusively (in write
-  // mode). Otherwise, may report an error (typically by crashing with a
-  // diagnostic), or may return immediately.
+  // Require that the mutex be held exclusively (write mode) by this thread.
+  //
+  // If the mutex is not currently held by this thread, this function may report
+  // an error (typically by crashing with a diagnostic) or it may do nothing.
+  // This function is intended only as a tool to assist debugging; it doesn't
+  // guarantee correctness.
   void AssertHeld() const ABSL_ASSERT_EXCLUSIVE_LOCK();
 
   // ---------------------------------------------------------------------------
@@ -236,9 +239,13 @@
 
   // Mutex::AssertReaderHeld()
   //
-  // Returns immediately if this thread holds the `Mutex` in at least shared
-  // mode (read mode). Otherwise, may report an error (typically by
-  // crashing with a diagnostic), or may return immediately.
+  // Require that the mutex be held at least in shared mode (read mode) by this
+  // thread.
+  //
+  // If the mutex is not currently held by this thread, this function may report
+  // an error (typically by crashing with a diagnostic) or it may do nothing.
+  // This function is intended only as a tool to assist debugging; it doesn't
+  // guarantee correctness.
   void AssertReaderHeld() const ABSL_ASSERT_SHARED_LOCK();
 
   // Mutex::WriterLock()
diff --git a/absl/time/time.h b/absl/time/time.h
index f284aa3..bd01867 100644
--- a/absl/time/time.h
+++ b/absl/time/time.h
@@ -750,23 +750,24 @@
 constexpr Time UniversalEpoch() {
   // 719162 is the number of days from 0001-01-01 to 1970-01-01,
   // assuming the Gregorian calendar.
-  return Time(time_internal::MakeDuration(-24 * 719162 * int64_t{3600}, 0U));
+  return Time(
+      time_internal::MakeDuration(-24 * 719162 * int64_t{3600}, uint32_t{0}));
 }
 
 // InfiniteFuture()
 //
 // Returns an `absl::Time` that is infinitely far in the future.
 constexpr Time InfiniteFuture() {
-  return Time(
-      time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U));
+  return Time(time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(),
+                                          ~uint32_t{0}));
 }
 
 // InfinitePast()
 //
 // Returns an `absl::Time` that is infinitely far in the past.
 constexpr Time InfinitePast() {
-  return Time(
-      time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U));
+  return Time(time_internal::MakeDuration((std::numeric_limits<int64_t>::min)(),
+                                          ~uint32_t{0}));
 }
 
 // FromUnixNanos()
@@ -1422,14 +1423,17 @@
 constexpr uint32_t GetRepLo(Duration d) { return d.rep_lo_; }
 
 // Returns true iff d is positive or negative infinity.
-constexpr bool IsInfiniteDuration(Duration d) { return GetRepLo(d) == ~0U; }
+constexpr bool IsInfiniteDuration(Duration d) {
+  return GetRepLo(d) == ~uint32_t{0};
+}
 
 // Returns an infinite Duration with the opposite sign.
 // REQUIRES: IsInfiniteDuration(d)
 constexpr Duration OppositeInfinity(Duration d) {
   return GetRepHi(d) < 0
-             ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~0U)
-             : MakeDuration((std::numeric_limits<int64_t>::min)(), ~0U);
+             ? MakeDuration((std::numeric_limits<int64_t>::max)(), ~uint32_t{0})
+             : MakeDuration((std::numeric_limits<int64_t>::min)(),
+                            ~uint32_t{0});
 }
 
 // Returns (-n)-1 (equivalently -(n+1)) without avoidable overflow.
@@ -1568,7 +1572,7 @@
 
 constexpr Duration InfiniteDuration() {
   return time_internal::MakeDuration((std::numeric_limits<int64_t>::max)(),
-                                     ~0U);
+                                     ~uint32_t{0});
 }
 
 constexpr Duration FromChrono(const std::chrono::nanoseconds& d) {
diff --git a/symbols_arm64_dbg.def b/symbols_arm64_dbg.def
index 902d2c0..6b1454f 100644
--- a/symbols_arm64_dbg.def
+++ b/symbols_arm64_dbg.def
@@ -1917,6 +1917,7 @@
     ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
     ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?LowestBitSet@?$BitMask@_K$07$02@container_internal@absl@@QEBAIXZ
+    ?MakeCheckFailString@status_internal@absl@@YAPEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@AEBVStatus@2@PEBD@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_J0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_JI@Z
     ?MakeFlatWithExtraCapacity@InlineRep@Cord@absl@@QEAAPEAUCordRepFlat@cord_internal@3@_K@Z
diff --git a/symbols_arm64_rel.def b/symbols_arm64_rel.def
index 40b8d9e..0db1bf9 100644
--- a/symbols_arm64_rel.def
+++ b/symbols_arm64_rel.def
@@ -565,6 +565,7 @@
     ?LogFatalNodeType@cord_internal@absl@@YAXPEAUCordRep@12@@Z
     ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
     ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
+    ?MakeCheckFailString@status_internal@absl@@YAPEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@AEBVStatus@2@PEBD@Z
     ?MakeSeedSeq@absl@@YA?AV?$SaltedSeedSeq@Vseed_seq@Cr@std@@@random_internal@1@XZ
     ?MakeTime@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
     ?MakeTime@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
diff --git a/symbols_x64_dbg.def b/symbols_x64_dbg.def
index 187ef70..2cc16ab 100644
--- a/symbols_x64_dbg.def
+++ b/symbols_x64_dbg.def
@@ -1918,6 +1918,7 @@
     ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
     ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
     ?LowestBitSet@?$BitMask@I$0BA@$0A@@container_internal@absl@@QEBAIXZ
+    ?MakeCheckFailString@status_internal@absl@@YAPEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@AEBVStatus@2@PEBD@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_J0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_JI@Z
     ?MakeFlatWithExtraCapacity@InlineRep@Cord@absl@@QEAAPEAUCordRepFlat@cord_internal@3@_K@Z
diff --git a/symbols_x64_rel.def b/symbols_x64_rel.def
index ad59a9e..3d6db4b 100644
--- a/symbols_x64_rel.def
+++ b/symbols_x64_rel.def
@@ -565,6 +565,7 @@
     ?LogFatalNodeType@cord_internal@absl@@YAXPEAUCordRep@12@@Z
     ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
     ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
+    ?MakeCheckFailString@status_internal@absl@@YAPEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@AEBVStatus@2@PEBD@Z
     ?MakeSeedSeq@absl@@YA?AV?$SaltedSeedSeq@Vseed_seq@Cr@std@@@random_internal@1@XZ
     ?MakeTime@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
     ?MakeTime@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
diff --git a/symbols_x64_rel_asan.def b/symbols_x64_rel_asan.def
index 604aa3b..9680fff 100644
--- a/symbols_x64_rel_asan.def
+++ b/symbols_x64_rel_asan.def
@@ -569,6 +569,7 @@
     ?LogFatalNodeType@cord_internal@absl@@YAXPEAUCordRep@12@@Z
     ?LowLevelHash@hash_internal@absl@@YA_KPEBX_K1QEB_K@Z
     ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPEBE_K@Z
+    ?MakeCheckFailString@status_internal@absl@@YAPEAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@AEBVStatus@2@PEBD@Z
     ?MakeSeedSeq@absl@@YA?AV?$SaltedSeedSeq@Vseed_seq@Cr@std@@@random_internal@1@XZ
     ?MakeTime@TimeZoneInfo@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
     ?MakeTime@TimeZoneLibC@cctz@time_internal@absl@@UEBA?AUcivil_lookup@time_zone@234@AEBV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
diff --git a/symbols_x86_dbg.def b/symbols_x86_dbg.def
index dac603b..7c6715a 100644
--- a/symbols_x86_dbg.def
+++ b/symbols_x86_dbg.def
@@ -1913,6 +1913,7 @@
     ?LowLevelHash@hash_internal@absl@@YA_KPBXI_KQB_K@Z
     ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPBEI@Z
     ?LowestBitSet@?$BitMask@I$0BA@$0A@@container_internal@absl@@QBEIXZ
+    ?MakeCheckFailString@status_internal@absl@@YAPAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@ABVStatus@2@PBD@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_J0@Z
     ?MakeDuration@time_internal@absl@@YA?AVDuration@2@_JI@Z
     ?MakeFlatWithExtraCapacity@InlineRep@Cord@absl@@QAEPAUCordRepFlat@cord_internal@3@I@Z
diff --git a/symbols_x86_rel.def b/symbols_x86_rel.def
index 6f87954..abb24d1 100644
--- a/symbols_x86_rel.def
+++ b/symbols_x86_rel.def
@@ -561,6 +561,7 @@
     ?LogFatalNodeType@cord_internal@absl@@YAXPAUCordRep@12@@Z
     ?LowLevelHash@hash_internal@absl@@YA_KPBXI_KQB_K@Z
     ?LowLevelHashImpl@MixingHashState@hash_internal@absl@@CA_KPBEI@Z
+    ?MakeCheckFailString@status_internal@absl@@YAPAV?$basic_string@DU?$char_traits@D@Cr@std@@V?$allocator@D@23@@Cr@std@@ABVStatus@2@PBD@Z
     ?MakeSeedSeq@absl@@YA?AV?$SaltedSeedSeq@Vseed_seq@Cr@std@@@random_internal@1@XZ
     ?MakeTime@TimeZoneInfo@cctz@time_internal@absl@@UBE?AUcivil_lookup@time_zone@234@ABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z
     ?MakeTime@TimeZoneLibC@cctz@time_internal@absl@@UBE?AUcivil_lookup@time_zone@234@ABV?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@234@@Z