Merge "Automated commit: libchrome r1156709 uprev" into main
diff --git a/BASE_VER b/BASE_VER
index 356632b..2e52c9a 100644
--- a/BASE_VER
+++ b/BASE_VER
@@ -1 +1 @@
-1155635
+1156709
diff --git a/base/allocator/partition_alloc_features.cc b/base/allocator/partition_alloc_features.cc
index dec1888..57c0ade 100644
--- a/base/allocator/partition_alloc_features.cc
+++ b/base/allocator/partition_alloc_features.cc
@@ -163,8 +163,8 @@
 };
 
 const base::FeatureParam<BackupRefPtrMode> kBackupRefPtrModeParam{
-    &kPartitionAllocBackupRefPtr, "brp-mode", BackupRefPtrMode::kEnabled,
-    &kBackupRefPtrModeOptions};
+    &kPartitionAllocBackupRefPtr, "brp-mode",
+    BackupRefPtrMode::kEnabledWithMemoryReclaimer, &kBackupRefPtrModeOptions};
 
 BASE_FEATURE(kPartitionAllocMemoryTagging,
              "PartitionAllocMemoryTagging",
diff --git a/base/allocator/partition_alloc_support.cc b/base/allocator/partition_alloc_support.cc
index 876c964..40c403e 100644
--- a/base/allocator/partition_alloc_support.cc
+++ b/base/allocator/partition_alloc_support.cc
@@ -301,8 +301,11 @@
                                features::BackupRefPtrMode::kDisabled) {
     brp_nondefault_behavior = true;
   }
-  if (brp_finch_enabled && features::kBackupRefPtrModeParam.Get() ==
-                               features::BackupRefPtrMode::kEnabled) {
+  if (brp_finch_enabled &&
+      (features::kBackupRefPtrModeParam.Get() ==
+           features::BackupRefPtrMode::kEnabled ||
+       features::kBackupRefPtrModeParam.Get() ==
+           features::BackupRefPtrMode::kEnabledWithMemoryReclaimer)) {
     brp_truly_enabled = true;
   }
 #endif  // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
diff --git a/base/allocator/partition_alloc_support_unittest.cc b/base/allocator/partition_alloc_support_unittest.cc
index 6f9a848..29b38ba 100644
--- a/base/allocator/partition_alloc_support_unittest.cc
+++ b/base/allocator/partition_alloc_support_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/allocator/partition_allocator/partition_alloc_buildflags.h"
 #include "base/feature_list.h"
 #include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/gtest_util.h"
 #include "base/test/scoped_feature_list.h"
@@ -126,6 +127,13 @@
     "EnabledBeforeAlloc_";
 #endif
 
+constexpr base::StringPiece kBRPEnabledWithMemoryReclaimerMode =
+#if BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT)
+    "EnabledPrevSlotWithMemoryReclaimer_";
+#else
+    "EnabledBeforeAllocWithMemoryReclaimer_";
+#endif
+
 // Parameterized basic test for BRP + PCScan enablement.
 // The parameter denotes
 // *  whether PCScan is enabled,
@@ -147,6 +155,8 @@
         testing::Values(
             BRPConfigPair{"disabled", "Disabled"},
             BRPConfigPair{"enabled", kBRPEnabledMode},
+            BRPConfigPair{"enabled-with-memory-reclaimer",
+                          kBRPEnabledWithMemoryReclaimerMode},
             BRPConfigPair{"disabled-but-2-way-split", "DisabledBut2WaySplit_"},
             BRPConfigPair{"disabled-but-3-way-split", "DisabledBut3WaySplit_"}),
         testing::Values(BRPConfigPair{"browser-only", "BrowserOnly"},
@@ -177,7 +187,7 @@
 #if BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
   brp_expectation =
       pcscan_enabled ? "Ignore_PCScanIsOn" : brp_mode.mapped_feature_string;
-  brp_truly_enabled = (brp_mode.arg_string == "enabled");
+  brp_truly_enabled = base::StartsWith(brp_mode.arg_string, "enabled");
   brp_nondefault_behavior = (brp_mode.arg_string != "disabled");
 #endif  // BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT)
   if (brp_expectation[brp_expectation.length() - 1] == '_') {
diff --git a/base/allocator/partition_allocator/partition_alloc.gni b/base/allocator/partition_allocator/partition_alloc.gni
index a344a4f..e0c141b 100644
--- a/base/allocator/partition_allocator/partition_alloc.gni
+++ b/base/allocator/partition_allocator/partition_alloc.gni
@@ -213,15 +213,16 @@
 # enable_backup_ref_ptr_support is true.
 assert(
     enable_backup_ref_ptr_support || !put_ref_count_in_previous_slot,
-    "Can't put ref count in the previous slot if BackupRefPtr isn't enabled at all")
+    "Can't put ref count in the previous slot if BackupRefPtr isn't enabled " +
+        "at all")
 
-# enable_backup_ref_ptr_slow_checks can only be used if enable_backup_ref_ptr_support
-# is true.
+# enable_backup_ref_ptr_slow_checks can only be used if
+# enable_backup_ref_ptr_support is true.
 assert(enable_backup_ref_ptr_support || !enable_backup_ref_ptr_slow_checks,
        "Can't enable additional BackupRefPtr checks if it isn't enabled at all")
 
-# enable_dangling_raw_ptr_checks can only be used if enable_backup_ref_ptr_support
-# is true.
+# enable_dangling_raw_ptr_checks can only be used if
+# enable_backup_ref_ptr_support is true.
 assert(
     enable_backup_ref_ptr_support || !enable_dangling_raw_ptr_checks,
     "Can't enable dangling raw_ptr checks if BackupRefPtr isn't enabled at all")
@@ -232,18 +233,21 @@
     enable_dangling_raw_ptr_checks || !enable_dangling_raw_ptr_perf_experiment,
     "Missing dangling pointer checks feature for its performance experiment")
 
-# To poison OOB pointers for BackupRefPtr, the underlying feature must
-# be enabled, too.
+# To poison OOB pointers for BackupRefPtr, the underlying feature must be
+# enabled, too.
 assert(
     enable_backup_ref_ptr_support || !backup_ref_ptr_poison_oob_ptr,
-    "Can't enable poisoning for OOB pointers if BackupRefPtr isn't enabled at all")
+    "Can't enable poisoning for OOB pointers if BackupRefPtr isn't enabled " +
+        "at all")
 assert(has_64_bit_pointers || !backup_ref_ptr_poison_oob_ptr,
        "Can't enable poisoning for OOB pointers if pointers are only 32-bit")
 
-# AsanBackupRefPtr and AsanUnownedPtr are mutually exclusive variants of raw_ptr.
+# AsanBackupRefPtr and AsanUnownedPtr are mutually exclusive variants of
+# raw_ptr.
 assert(
     !use_asan_unowned_ptr || !use_asan_backup_ref_ptr,
-    "Both AsanUnownedPtr and AsanBackupRefPtr can't be enabled at the same time")
+    "Both AsanUnownedPtr and AsanBackupRefPtr can't be enabled at the same " +
+        "time")
 
 # BackupRefPtr and AsanBackupRefPtr are mutually exclusive variants of raw_ptr.
 assert(
@@ -254,15 +258,19 @@
 assert(!enable_backup_ref_ptr_support || !use_asan_unowned_ptr,
        "Both BackupRefPtr and AsanUnownedPtr can't be enabled at the same time")
 
-# RawPtrHookableImpl and BackupRefPtr are mutually exclusive variants of raw_ptr.
+# RawPtrHookableImpl and BackupRefPtr are mutually exclusive variants of
+# raw_ptr.
 assert(
     !use_hookable_raw_ptr || !enable_backup_ref_ptr_support,
-    "Both RawPtrHookableImpl and BackupRefPtr can't be enabled at the same time")
+    "Both RawPtrHookableImpl and BackupRefPtr can't be enabled at the same " +
+        "time")
 
-# RawPtrHookableImpl and AsanUnownedPtr are mutually exclusive variants of raw_ptr.
+# RawPtrHookableImpl and AsanUnownedPtr are mutually exclusive variants of
+# raw_ptr.
 assert(
     !use_hookable_raw_ptr || !use_asan_unowned_ptr,
-    "Both RawPtrHookableImpl and AsanUnownedPtr can't be enabled at the same time")
+    "Both RawPtrHookableImpl and AsanUnownedPtr can't be enabled at the same " +
+        "time")
 
 assert(!use_asan_backup_ref_ptr || is_asan,
        "AsanBackupRefPtr requires AddressSanitizer")
@@ -279,8 +287,8 @@
 }
 
 # AsanBackupRefPtr is not supported outside Chromium. The implementation is
-# entangled with `//base`. The code is only physically located with the
-# rest of `raw_ptr` to keep it together.
+# entangled with `//base`. The code is only physically located with the rest of
+# `raw_ptr` to keep it together.
 assert(build_with_chromium || !use_asan_backup_ref_ptr,
        "AsanBackupRefPtr is not supported outside Chromium")
 
@@ -288,9 +296,9 @@
        "AsanBackupRefPtr requires RawPtrHookableImpl")
 
 declare_args() {
-  # pkeys support is explicitly disabled in all Cronet builds, as some test dependencies that
-  # use partition_allocator are compiled in AOSP against a version of glibc that does not
-  # include pkeys syscall numbers.
+  # pkeys support is explicitly disabled in all Cronet builds, as some test
+  # dependencies that use partition_allocator are compiled in AOSP against a
+  # version of glibc that does not include pkeys syscall numbers.
   enable_pkeys = is_linux && target_cpu == "x64" && !is_cronet_build
 }
 assert(!enable_pkeys || (is_linux && target_cpu == "x64"),
diff --git a/base/allocator/partition_allocator/partition_alloc_base/types/strong_alias.h b/base/allocator/partition_allocator/partition_alloc_base/types/strong_alias.h
index 1c139d8..0e096bf 100644
--- a/base/allocator/partition_allocator/partition_alloc_base/types/strong_alias.h
+++ b/base/allocator/partition_allocator/partition_alloc_base/types/strong_alias.h
@@ -5,6 +5,7 @@
 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_TYPES_STRONG_ALIAS_H_
 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_BASE_TYPES_STRONG_ALIAS_H_
 
+#include <functional>
 #include <type_traits>
 #include <utility>
 
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h
index 879653b..de66fee 100644
--- a/base/allocator/partition_allocator/partition_root.h
+++ b/base/allocator/partition_allocator/partition_root.h
@@ -786,6 +786,13 @@
     return internal::TagAddr(SlotStartToObjectAddr(slot_start));
   }
 
+  PA_ALWAYS_INLINE void* TaggedSlotStartToObject(
+      void* tagged_slot_start) const {
+    // TODO(bartekn): Check that |slot_start| is indeed a slot start.
+    return reinterpret_cast<void*>(
+        SlotStartToObjectAddr(reinterpret_cast<uintptr_t>(tagged_slot_start)));
+  }
+
   PA_ALWAYS_INLINE uintptr_t ObjectToSlotStart(void* object) const {
     return UntagPtr(object) - settings.extras_offset;
     // TODO(bartekn): Check that the result is indeed a slot start.
@@ -1238,7 +1245,6 @@
     if (PA_LIKELY(slot_size <= internal::kMaxMemoryTaggingSize)) {
       // slot_span is untagged at this point, so we have to recover its tag
       // again to increment and provide use-after-free mitigations.
-      uintptr_t slot_start_to_object_delta = object_addr - slot_start;
       size_t tag_size = slot_size;
 #if PA_CONFIG(INCREASE_REF_COUNT_SIZE_FOR_MTE)
       tag_size -= root->settings.ref_count_size;
@@ -1247,9 +1253,7 @@
           internal::TagAddr(slot_start), tag_size);
       // Incrementing the MTE-tag in the memory range invalidates the |object|'s
       // tag, so it must be retagged.
-      object = reinterpret_cast<void*>(
-          reinterpret_cast<uintptr_t>(retagged_slot_start) +
-          slot_start_to_object_delta);
+      object = root->TaggedSlotStartToObject(retagged_slot_start);
     }
   }
 #else
diff --git a/base/android/build_info.cc b/base/android/build_info.cc
index d6c295d..2521c71 100644
--- a/base/android/build_info.cc
+++ b/base/android/build_info.cc
@@ -85,7 +85,8 @@
       is_automotive_(GetIntParam(params, 27)),
       is_at_least_u_(GetIntParam(params, 28)),
       targets_at_least_u_(GetIntParam(params, 29)),
-      codename_(StrDupParam(params, 30)) {}
+      codename_(StrDupParam(params, 30)),
+      vulkan_deqp_level_(GetIntParam(params, 31)) {}
 
 // static
 BuildInfo* BuildInfo::GetInstance() {
diff --git a/base/android/build_info.h b/base/android/build_info.h
index d61b306..a79723b 100644
--- a/base/android/build_info.h
+++ b/base/android/build_info.h
@@ -152,6 +152,9 @@
 
   const char* codename() const { return codename_; }
 
+  // Available only on Android T+.
+  int32_t vulkan_deqp_level() const { return vulkan_deqp_level_; }
+
  private:
   friend struct BuildInfoSingletonTraits;
 
@@ -193,6 +196,7 @@
   const bool is_at_least_u_;
   const bool targets_at_least_u_;
   const char* const codename_;
+  const int32_t vulkan_deqp_level_;
 };
 
 }  // namespace android
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java
index d7907d4..5c723c7 100644
--- a/base/android/java/src/org/chromium/base/BuildInfo.java
+++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -9,6 +9,7 @@
 import android.app.UiModeManager;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.FeatureInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
@@ -65,6 +66,10 @@
     public final boolean isTV;
     /** Whether we're running on an Android Automotive OS device or not. */
     public final boolean isAutomotive;
+    /**
+     * version of the FEATURE_VULKAN_DEQP_LEVEL, if available. Queried only on Android T or above
+     */
+    public final int vulkanDeqpLevel;
 
     private static class Holder { private static BuildInfo sInstance = new BuildInfo(); }
 
@@ -112,6 +117,7 @@
                 BuildCompat.isAtLeastU() ? "1" : "0",
                 targetsAtLeastU() ? "1" : "0",
                 Build.VERSION.CODENAME,
+                String.valueOf(vulkanDeqpLevel),
         };
     }
 
@@ -228,6 +234,20 @@
             isAutomotive = false;
         }
         this.isAutomotive = isAutomotive;
+
+        int vulkanLevel = 0;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+            FeatureInfo[] features = pm.getSystemAvailableFeatures();
+            if (features != null) {
+                for (FeatureInfo feature : features) {
+                    if (PackageManager.FEATURE_VULKAN_DEQP_LEVEL.equals(feature.name)) {
+                        vulkanLevel = feature.version;
+                        break;
+                    }
+                }
+            }
+        }
+        vulkanDeqpLevel = vulkanLevel;
     }
 
     /**
diff --git a/base/android/proguard/chromium_apk.flags b/base/android/proguard/chromium_apk.flags
index da5ab79..16023ab 100644
--- a/base/android/proguard/chromium_apk.flags
+++ b/base/android/proguard/chromium_apk.flags
@@ -14,42 +14,36 @@
 -allowaccessmodification
 
 # Keep all CREATOR fields within Parcelable that are kept.
--keepclassmembers class * implements android.os.Parcelable {
+-keepclassmembers class !cr_allowunused,** implements android.os.Parcelable {
   public static *** CREATOR;
 }
 
-# Keep all default constructors for used Fragments. Required since they are
-# called reflectively when fragments are reinflated after the app is killed.
--keepclassmembers class * extends android.app.Fragment {
-  public <init>();
-}
--keepclassmembers class * extends androidx.fragment.app.Fragment {
-  public <init>();
-}
-
-# SearchView is used in website_preferences_menu.xml and is constructed by
-# Android using reflection.
--keep class androidx.appcompat.widget.SearchView {
-  public <init>(...);
-}
-
 # Don't obfuscate Parcelables as they might be marshalled outside Chrome.
 # If we annotated all Parcelables that get put into Bundles other than
 # for saveInstanceState (e.g. PendingIntents), then we could actually keep the
 # names of just those ones. For now, we'll just keep them all.
--keepnames class * implements android.os.Parcelable {}
+-keepnames class !cr_allowunused,** implements android.os.Parcelable {}
+
+# Keep all default constructors for used Fragments. Required since they are
+# called reflectively when fragments are reinflated after the app is killed.
+-keepclassmembers class !cr_allowunused,** extends android.app.Fragment {
+  public <init>();
+}
+-keepclassmembers class !cr_allowunused,** extends androidx.fragment.app.Fragment {
+  public <init>();
+}
 
 # Keep all enum values and valueOf methods. See
 # http://proguard.sourceforge.net/index.html#manual/examples.html
 # for the reason for this. Also, see http://crbug.com/248037.
--keepclassmembers enum * {
+-keepclassmembers enum !cr_allowunused,** {
     public static **[] values();
 }
 
 # This is to workaround crbug.com/1204690 - an old GMS app version crashes when
 # ObjectWrapper contains > 1 fields, and this prevents R8 from inserting a
 # synthetic field.
--keep,allowaccessmodification class com.google.android.gms.dynamic.ObjectWrapper {
+-keep,allowaccessmodification class !cr_allowunused,com.google.android.gms.dynamic.ObjectWrapper {
   <fields>;
 }
 
diff --git a/base/android/proguard/chromium_code.flags b/base/android/proguard/chromium_code.flags
index fd020b4..6393108 100644
--- a/base/android/proguard/chromium_code.flags
+++ b/base/android/proguard/chromium_code.flags
@@ -6,7 +6,7 @@
 # appropriate for third-party apps to include.
 
 # Allow unused native methods to be removed, but prevent renaming on those that are kept.
--keepclasseswithmembernames,includedescriptorclasses,allowaccessmodification class ** {
+-keepclasseswithmembernames,includedescriptorclasses,allowaccessmodification class !cr_allowunused,** {
   native <methods>;
 }
 
@@ -19,7 +19,7 @@
 }
 
 # Keep all CREATOR fields within Parcelable that are kept.
--keepclassmembers class org.chromium.** implements android.os.Parcelable {
+-keepclassmembers class !cr_allowunused,org.chromium.** implements android.os.Parcelable {
   public static *** CREATOR;
 }
 
@@ -27,19 +27,19 @@
 # If we annotated all Parcelables that get put into Bundles other than
 # for saveInstanceState (e.g. PendingIntents), then we could actually keep the
 # names of just those ones. For now, we'll just keep them all.
--keepnames,allowaccessmodification class org.chromium.** implements android.os.Parcelable {}
+-keepnames,allowaccessmodification class !cr_allowunused,org.chromium.** implements android.os.Parcelable {}
 
 # Keep all enum values and valueOf methods. See
 # http://proguard.sourceforge.net/index.html#manual/examples.html
 # for the reason for this. Also, see http://crbug.com/248037.
--keepclassmembers enum org.chromium.** {
+-keepclassmembers enum !cr_allowunused,org.chromium.** {
     public static **[] values();
 }
 
 # -identifiernamestring doesn't keep the module impl around, we have to
 # explicitly keep it.
 -if @org.chromium.components.module_installer.builder.ModuleInterface interface *
--keep,allowobfuscation,allowaccessmodification class * extends <1> {
+-keep,allowobfuscation,allowaccessmodification class !cr_allowunused,** extends <1> {
   <init>();
 }
 
diff --git a/base/containers/enum_set.h b/base/containers/enum_set.h
index 16b14da..fb63e16 100644
--- a/base/containers/enum_set.h
+++ b/base/containers/enum_set.h
@@ -13,6 +13,7 @@
 
 #include "base/check.h"
 #include "base/check_op.h"
+#include "base/cxx20_is_constant_evaluated.h"
 #include "base/memory/raw_ptr.h"
 #include "build/build_config.h"
 
@@ -23,16 +24,16 @@
 class EnumSet;
 
 template <typename E, E Min, E Max>
-EnumSet<E, Min, Max> Union(EnumSet<E, Min, Max> set1,
-                           EnumSet<E, Min, Max> set2);
+constexpr EnumSet<E, Min, Max> Union(EnumSet<E, Min, Max> set1,
+                                     EnumSet<E, Min, Max> set2);
 
 template <typename E, E Min, E Max>
-EnumSet<E, Min, Max> Intersection(EnumSet<E, Min, Max> set1,
-                                  EnumSet<E, Min, Max> set2);
+constexpr EnumSet<E, Min, Max> Intersection(EnumSet<E, Min, Max> set1,
+                                            EnumSet<E, Min, Max> set2);
 
 template <typename E, E Min, E Max>
-EnumSet<E, Min, Max> Difference(EnumSet<E, Min, Max> set1,
-                                EnumSet<E, Min, Max> set2);
+constexpr EnumSet<E, Min, Max> Difference(EnumSet<E, Min, Max> set1,
+                                          EnumSet<E, Min, Max> set2);
 
 // An EnumSet is a set that can hold enum values between a min and a
 // max value (inclusive of both).  It's essentially a wrapper around
@@ -159,20 +160,37 @@
 
   ~EnumSet() = default;
 
-  constexpr EnumSet(std::initializer_list<E> values)
-      : EnumSet(EnumBitSet(bitstring(values))) {}
+  constexpr EnumSet(std::initializer_list<E> values) {
+    if (base::is_constant_evaluated()) {
+      enums_ = bitstring(values);
+    } else {
+      for (E value : values) {
+        Put(value);
+      }
+    }
+  }
 
   // Returns an EnumSet with all possible values.
   static constexpr EnumSet All() {
-    if (kValueCount == 0) {
-      return EnumSet();
+    if (base::is_constant_evaluated()) {
+      if (kValueCount == 0) {
+        return EnumSet();
+      }
+      // Since `1 << kValueCount` may trigger shift-count-overflow warning if
+      // the `kValueCount` is 64, instead of returning `(1 << kValueCount) - 1`,
+      // the bitmask will be constructed from two parts: the most significant
+      // bits and the remaining.
+      uint64_t mask = 1ULL << (kValueCount - 1);
+      return EnumSet(EnumBitSet(mask - 1 + mask));
+    } else {
+      // When `kValueCount` is greater than 64, we can't use the constexpr path,
+      // and we will build an `EnumSet` value by value.
+      EnumSet enum_set;
+      for (size_t value = 0; value < kValueCount; ++value) {
+        enum_set.Put(FromIndex(value));
+      }
+      return enum_set;
     }
-    // Since `1 << kValueCount` may trigger shift-count-overflow warning if
-    // the `kValueCount` is 64, instead of returning `(1 << kValueCount) - 1`,
-    // the bitmask will be constructed from two parts: the most significant bits
-    // and the remaining.
-    uint64_t mask = 1ULL << (kValueCount - 1);
-    return EnumSet(EnumBitSet(mask - 1 + mask));
   }
 
   // Returns an EnumSet with all the values from start to end, inclusive.
@@ -292,12 +310,14 @@
   bool operator!=(const EnumSet& other) const { return enums_ != other.enums_; }
 
  private:
-  friend EnumSet Union<E, MinEnumValue, MaxEnumValue>(EnumSet set1,
-                                                      EnumSet set2);
-  friend EnumSet Intersection<E, MinEnumValue, MaxEnumValue>(EnumSet set1,
-                                                             EnumSet set2);
-  friend EnumSet Difference<E, MinEnumValue, MaxEnumValue>(EnumSet set1,
-                                                           EnumSet set2);
+  friend constexpr EnumSet Union<E, MinEnumValue, MaxEnumValue>(EnumSet set1,
+                                                                EnumSet set2);
+  friend constexpr EnumSet Intersection<E, MinEnumValue, MaxEnumValue>(
+      EnumSet set1,
+      EnumSet set2);
+  friend constexpr EnumSet Difference<E, MinEnumValue, MaxEnumValue>(
+      EnumSet set1,
+      EnumSet set2);
 
   static constexpr uint64_t bitstring(const std::initializer_list<E>& values) {
     uint64_t result = 0;
@@ -319,8 +339,10 @@
   // can safely remove the constepxr qualifiers from this file, at the cost of
   // some minor optimizations.
   explicit constexpr EnumSet(EnumBitSet enums) : enums_(enums) {
-    static_assert(kValueCount <= 64,
-                  "Max number of enum values is 64 for constexpr constructor");
+    if (base::is_constant_evaluated()) {
+      CHECK(kValueCount <= 64)
+          << "Max number of enum values is 64 for constexpr constructor";
+    }
   }
 
   // Converts a value to/from an index into |enums_|.
@@ -350,20 +372,20 @@
 // The usual set operations.
 
 template <typename E, E Min, E Max>
-EnumSet<E, Min, Max> Union(EnumSet<E, Min, Max> set1,
-                           EnumSet<E, Min, Max> set2) {
+constexpr EnumSet<E, Min, Max> Union(EnumSet<E, Min, Max> set1,
+                                     EnumSet<E, Min, Max> set2) {
   return EnumSet<E, Min, Max>(set1.enums_ | set2.enums_);
 }
 
 template <typename E, E Min, E Max>
-EnumSet<E, Min, Max> Intersection(EnumSet<E, Min, Max> set1,
-                                  EnumSet<E, Min, Max> set2) {
+constexpr EnumSet<E, Min, Max> Intersection(EnumSet<E, Min, Max> set1,
+                                            EnumSet<E, Min, Max> set2) {
   return EnumSet<E, Min, Max>(set1.enums_ & set2.enums_);
 }
 
 template <typename E, E Min, E Max>
-EnumSet<E, Min, Max> Difference(EnumSet<E, Min, Max> set1,
-                                EnumSet<E, Min, Max> set2) {
+constexpr EnumSet<E, Min, Max> Difference(EnumSet<E, Min, Max> set1,
+                                          EnumSet<E, Min, Max> set2) {
   return EnumSet<E, Min, Max>(set1.enums_ & ~set2.enums_);
 }
 
diff --git a/base/containers/enum_set_unittest.cc b/base/containers/enum_set_unittest.cc
index 554ca3e..8495044 100644
--- a/base/containers/enum_set_unittest.cc
+++ b/base/containers/enum_set_unittest.cc
@@ -481,9 +481,7 @@
   sparse.Put(TestEnumSparse::TEST_MAX);
   EXPECT_EQ(sparse.Size(), 2u);
 
-  // TestEnumSparseSet::All() does not compile because there are more than 64
-  // possible values. See NCTEST_ALL_METHOD_DISALLOWED_ON_LARGE_SPARSE_ENUM in
-  // enum_set_unittest.nc.
+  EXPECT_EQ(TestEnumSparseSet::All().Size(), 100u);
 }
 
 TEST_F(EnumSetTest, SparseEnumSmall) {
diff --git a/base/containers/enum_set_unittest.nc b/base/containers/enum_set_unittest.nc
index f3986b2..076dad4 100644
--- a/base/containers/enum_set_unittest.nc
+++ b/base/containers/enum_set_unittest.nc
@@ -10,9 +10,9 @@
 namespace base {
 namespace {
 
-#if defined(NCTEST_ALL_METHOD_DISALLOWED_ON_LARGE_SPARSE_ENUM) // [r"fatal error: static assertion failed due to requirement 'kValueCount <= 64': Max number of enum values is 64 for constexpr constructor"]
+#if defined(NCTEST_ALL_METHOD_DISALLOWED_ON_LARGE_SPARSE_ENUM) // [r"fatal error: constexpr variable 'set' must be initialized by a constant expression"]
 
-void WontCompile() {
+size_t WontCompile() {
   enum class TestEnumSparse {
     TEST_1 = 1,
     TEST_MIN = 1,
@@ -23,9 +23,10 @@
   using TestEnumSparseSet = EnumSet<TestEnumSparse, TestEnumSparse::TEST_MIN,
                                     TestEnumSparse::TEST_MAX>;
 
-  // TestEnumSparseSet::All() does not compile because there are more than 64
-  // possible values.
-  TestEnumSparseSet::All();
+  // TestEnumSparseSet::All() does not compile as constexpr because there are
+  // more than 64 possible values.
+  constexpr auto set = TestEnumSparseSet::All();
+  return set.Size();
 }
 
 #endif
diff --git a/base/containers/span.h b/base/containers/span.h
index ce3e017..c9040f0 100644
--- a/base/containers/span.h
+++ b/base/containers/span.h
@@ -19,6 +19,7 @@
 #include "base/containers/checked_iterators.h"
 #include "base/containers/contiguous_iterator.h"
 #include "base/cxx20_to_address.h"
+#include "base/memory/raw_ptr_exclusion.h"
 #include "base/numerics/safe_math.h"
 
 namespace base {
@@ -452,7 +453,9 @@
   }
 
  private:
-  T* data_;
+  // This field is not a raw_ptr<> because it was filtered by the rewriter
+  // for: #constexpr-ctor-field-initializer, #global-scope, #union
+  RAW_PTR_EXCLUSION T* data_;
 };
 
 // span<T, Extent>::extent can not be declared inline prior to C++17, hence this
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc
index 5d95331..4b9f1cc 100644
--- a/base/test/test_suite.cc
+++ b/base/test/test_suite.cc
@@ -217,6 +217,7 @@
     DCHECK_EQ(thread_pool_set_before_test_, ThreadPoolInstance::Get())
         << " in test " << test.test_case_name() << "." << test.name();
     feature_list_set_before_test_ = nullptr;
+    thread_pool_set_before_test_ = nullptr;
   }
 
   // Check for leaks in test cases (consisting of one or more tests).
@@ -230,6 +231,7 @@
     DCHECK_EQ(thread_pool_set_before_case_, ThreadPoolInstance::Get())
         << " in case " << test_case.name();
     feature_list_set_before_case_ = nullptr;
+    thread_pool_set_before_case_ = nullptr;
   }
 
  private:
diff --git a/base/trace_event/builtin_categories.h b/base/trace_event/builtin_categories.h
index d2cfdef..32d4063 100644
--- a/base/trace_event/builtin_categories.h
+++ b/base/trace_event/builtin_categories.h
@@ -311,7 +311,6 @@
   X("blink,rail")                                                             \
   X("blink.animations,devtools.timeline,benchmark,rail")                      \
   X("blink.user_timing,rail")                                                 \
-  X("blink_gc,devtools.timeline")                                             \
   X("browser,content,navigation")                                             \
   X("browser,navigation")                                                     \
   X("browser,navigation,benchmark")                                           \
diff --git a/build/env_dump.py b/build/env_dump.py
index 1eaf8dc..17d30a7 100755
--- a/build/env_dump.py
+++ b/build/env_dump.py
@@ -9,7 +9,7 @@
 import json
 import optparse
 import os
-import pipes
+import shlex
 import subprocess
 import sys
 
@@ -32,7 +32,7 @@
     if not options.output_json:
       parser.error('Requires --output-json option.')
 
-    envsetup_cmd = ' '.join(map(pipes.quote, args))
+    envsetup_cmd = ' '.join(map(shlex.quote, args))
     full_cmd = [
         'bash', '-c',
         '. %s > /dev/null; %s -d' % (envsetup_cmd, os.path.abspath(__file__))
diff --git a/build/print_python_deps.py b/build/print_python_deps.py
index 07f988a..415e7b0 100755
--- a/build/print_python_deps.py
+++ b/build/print_python_deps.py
@@ -11,7 +11,7 @@
 
 import argparse
 import os
-import pipes
+import shlex
 import sys
 
 # Don't use any helper modules, or else they will end up in the results.
@@ -68,7 +68,7 @@
   if os.name == 'nt':
     return ' '.join(quote(x) for x in args).replace('\\', '/')
   else:
-    return ' '.join(pipes.quote(x) for x in args)
+    return ' '.join(shlex.quote(x) for x in args)
 
 
 def _FindPythonInDirectory(directory, allow_test):
diff --git a/components/policy/core/common/policy_pref_names.cc b/components/policy/core/common/policy_pref_names.cc
index de02f4b..325d8a1 100644
--- a/components/policy/core/common/policy_pref_names.cc
+++ b/components/policy/core/common/policy_pref_names.cc
@@ -144,5 +144,10 @@
 // If this is set to True, the page will be accessible.
 const char kPolicyTestPageEnabled[] = "policy_test_page_enabled";
 
+// A boolean pref indicating whether the new the page with "Cache-Control:
+// no-store" header is allowed to be stored in back/forward cache.
+const char kAllowBackForwardCacheForCacheControlNoStorePageEnabled[] =
+    "policy.allow_back_forward_cache_for_cache_control_no_store_page_enabled";
+
 }  // namespace policy_prefs
 }  // namespace policy
diff --git a/components/policy/core/common/policy_pref_names.h b/components/policy/core/common/policy_pref_names.h
index bdd5a03..2074765 100644
--- a/components/policy/core/common/policy_pref_names.h
+++ b/components/policy/core/common/policy_pref_names.h
@@ -68,6 +68,7 @@
 extern const char kIncognitoModeAvailability[];
 extern const char kBeforeunloadEventCancelByPreventDefaultEnabled[];
 extern const char kPolicyTestPageEnabled[];
+extern const char kAllowBackForwardCacheForCacheControlNoStorePageEnabled[];
 
 }  // namespace policy_prefs
 }  // namespace policy
diff --git a/mojo/core/ipcz_driver/driver.cc b/mojo/core/ipcz_driver/driver.cc
index 6cec269..1bcb379 100644
--- a/mojo/core/ipcz_driver/driver.cc
+++ b/mojo/core/ipcz_driver/driver.cc
@@ -40,7 +40,7 @@
                               IpczDriverHandle transport_handle,
                               uint32_t flags,
                               const void* options,
-                              void* data,
+                              volatile void* data,
                               size_t* num_bytes,
                               IpczDriverHandle* handles,
                               size_t* num_handles) {
@@ -54,8 +54,10 @@
     return IPCZ_RESULT_ABORTED;
   }
 
-  const IpczResult result = transport->SerializeObject(*object, data, num_bytes,
-                                                       handles, num_handles);
+  // TODO(https://crbug.com/1451717): Propagate the volatile qualifier on
+  // `data`.
+  const IpczResult result = transport->SerializeObject(
+      *object, const_cast<void*>(data), num_bytes, handles, num_handles);
   if (result != IPCZ_RESULT_OK) {
     return result;
   }
@@ -65,7 +67,7 @@
   return IPCZ_RESULT_OK;
 }
 
-IpczResult IPCZ_API Deserialize(const void* data,
+IpczResult IPCZ_API Deserialize(const volatile void* data,
                                 size_t num_bytes,
                                 const IpczDriverHandle* handles,
                                 size_t num_handles,
@@ -78,9 +80,13 @@
     return IPCZ_RESULT_INVALID_ARGUMENT;
   }
 
+  // TODO(https://crbug.com/1451717): Propagate the volatile qualifier on
+  // `data`.
   scoped_refptr<ObjectBase> object;
   const IpczResult result = transport->DeserializeObject(
-      base::make_span(static_cast<const uint8_t*>(data), num_bytes),
+      base::make_span(
+          static_cast<const uint8_t*>(const_cast<const void*>(data)),
+          num_bytes),
       base::make_span(handles, num_handles), object);
   if (result != IPCZ_RESULT_OK) {
     return result;
@@ -269,7 +275,7 @@
 IpczResult IPCZ_API MapSharedMemory(IpczDriverHandle driver_memory,
                                     uint32_t flags,
                                     const void* options,
-                                    void** address,
+                                    volatile void** address,
                                     IpczDriverHandle* driver_mapping) {
   SharedBuffer* buffer = SharedBuffer::FromHandle(driver_memory);
   if (!buffer || !driver_mapping) {
diff --git a/mojo/core/ipcz_driver/mojo_message.cc b/mojo/core/ipcz_driver/mojo_message.cc
index d164886..7f6342a 100644
--- a/mojo/core/ipcz_driver/mojo_message.cc
+++ b/mojo/core/ipcz_driver/mojo_message.cc
@@ -101,7 +101,7 @@
 
   parcel_ = std::move(parcel);
 
-  const void* data;
+  const volatile void* data;
   size_t num_bytes;
   size_t num_handles = 0;
   IpczTransaction transaction;
@@ -120,7 +120,15 @@
   if (num_bytes > 0) {
     data_storage_.reset(
         static_cast<uint8_t*>(base::AllocNonScannable(num_bytes)));
-    memcpy(data_storage_.get(), data, num_bytes);
+
+    // Copy into private memory, out of the potentially shared and volatile
+    // `data` buffer. Note that it's fine to cast away volatility here since we
+    // aren't concerned with consistency across reads: a well-behaved peer won't
+    // modify the buffer concurrently, so the copied bytes will always be
+    // correct in that case; and in any other case we don't care what's copied,
+    // as long as all subsequent reads operate on the private copy and not on
+    // `data`.
+    memcpy(data_storage_.get(), const_cast<const void*>(data), num_bytes);
   } else {
     data_storage_.reset();
   }
@@ -267,7 +275,7 @@
 IpczResult MojoMessage::SerializeForIpcz(uintptr_t object,
                                          uint32_t,
                                          const void*,
-                                         void* data,
+                                         volatile void* data,
                                          size_t* num_bytes,
                                          IpczHandle* handles,
                                          size_t* num_handles) {
@@ -368,7 +376,7 @@
   return new_message;
 }
 
-IpczResult MojoMessage::SerializeForIpczImpl(void* data,
+IpczResult MojoMessage::SerializeForIpczImpl(volatile void* data,
                                              size_t* num_bytes,
                                              IpczHandle* handles,
                                              size_t* num_handles) {
@@ -399,7 +407,8 @@
     return IPCZ_RESULT_INVALID_ARGUMENT;
   }
 
-  memcpy(data, data_.data(), data_.size());
+  // TODO(https://crbug.com/1451717): Do a volatile-friendly copy here.
+  memcpy(const_cast<void*>(data), data_.data(), data_.size());
   for (size_t i = 0; i < handles_.size(); ++i) {
     handles[i] = std::exchange(handles_[i], IPCZ_INVALID_HANDLE);
   }
diff --git a/mojo/core/ipcz_driver/mojo_message.h b/mojo/core/ipcz_driver/mojo_message.h
index c9f2e2e..73aa87f 100644
--- a/mojo/core/ipcz_driver/mojo_message.h
+++ b/mojo/core/ipcz_driver/mojo_message.h
@@ -95,7 +95,7 @@
   static IpczResult SerializeForIpcz(uintptr_t object,
                                      uint32_t,
                                      const void*,
-                                     void* data,
+                                     volatile void* data,
                                      size_t* num_bytes,
                                      IpczHandle* handles,
                                      size_t* num_handles);
@@ -115,7 +115,7 @@
   static std::unique_ptr<MojoMessage> UnwrapFrom(MojoMessage& message);
 
  private:
-  IpczResult SerializeForIpczImpl(void* data,
+  IpczResult SerializeForIpczImpl(volatile void* data,
                                   size_t* num_bytes,
                                   IpczHandle* handles,
                                   size_t* num_handles);
diff --git a/third_party/ipcz/include/ipcz/ipcz.h b/third_party/ipcz/include/ipcz/ipcz.h
index 3f65091..7cd6177 100644
--- a/third_party/ipcz/include/ipcz/ipcz.h
+++ b/third_party/ipcz/include/ipcz/ipcz.h
@@ -154,7 +154,7 @@
 typedef IpczResult (*IpczApplicationObjectSerializer)(uintptr_t object,
                                                       uint32_t flags,
                                                       const void* options,
-                                                      void* data,
+                                                      volatile void* data,
                                                       size_t* num_bytes,
                                                       IpczHandle* handles,
                                                       size_t* num_handles);
@@ -228,13 +228,13 @@
                                   IpczDriverHandle transport,  // in
                                   uint32_t flags,              // in
                                   const void* options,         // in
-                                  void* data,                  // out
+                                  volatile void* data,         // out
                                   size_t* num_bytes,           // in/out
                                   IpczDriverHandle* handles,   // out
                                   size_t* num_handles);        // in/out
 
   IpczResult(IPCZ_API* Deserialize)(
-      const void* data,                        // in
+      const volatile void* data,               // in
       size_t num_bytes,                        // in
       const IpczDriverHandle* driver_handles,  // in
       size_t num_driver_handles,               // in
@@ -298,7 +298,7 @@
       IpczDriverHandle driver_memory,     // in
       uint32_t flags,                     // in
       const void* options,                // in
-      void** address,                     // out
+      volatile void** address,            // out
       IpczDriverHandle* driver_mapping);  // out
 
   IpczResult(IPCZ_API* GenerateRandomBytes)(size_t num_bytes,     // in
@@ -371,7 +371,7 @@
   IpczResult(IPCZ_API* BeginGet)(IpczHandle source,              // in
                                  IpczBeginGetFlags flags,        // in
                                  const void* options,            // in
-                                 const void** data,              // out
+                                 const volatile void** data,     // out
                                  size_t* num_bytes,              // out
                                  IpczHandle* handles,            // out
                                  size_t* num_handles,            // in/out