diff --git a/DEPS b/DEPS
index 05306e8..6a5ec14 100644
--- a/DEPS
+++ b/DEPS
@@ -80,6 +80,9 @@
   # build ARC++ support libraries.
   'checkout_android_native_support': 'checkout_android or checkout_chromeos',
 
+  # By default, do not check out Cast3P.
+  'checkout_cast3p': False,
+
   # By default, do not check out Chromium autofill captured sites test
   # dependencies. These dependencies include very large numbers of very
   # large web capture files. Captured sites test dependencies are also
@@ -228,19 +231,19 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '71cb9725180a28eeec13aafbf17f901166b191b8',
+  'skia_revision': 'ff733b3f39098600fd5461dd71778e249cd7d78c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '853a0bd84a0f6963fb38ddb566bc8a033232b1f2',
+  'v8_revision': '8ce61b9d92e07ad3c63da3547bbbf0c8cbbbff3a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': 'afe0dd9edf76dd798af7615e347725afd284924c',
+  'angle_revision': '9994110baeb4741382849c8a909bed00dedd3508',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
-  'swiftshader_revision': '054ff0cd5b7ecaab630dfcf8814ec9e5c88e6a6b',
+  'swiftshader_revision': 'efbbb2f07b3642b570472f01ed75b04bf1eeb4af',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -303,7 +306,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': 'db4c9684f0c5d9f59def0da90f80372cba6f2195',
+  'devtools_frontend_revision': '10474d9f680fe879beb6bfcc21e9baade89d3845',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -339,11 +342,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'shaderc_revision': 'c42db5815fad0424f0f1311de1eec92cdd77203d',
+  'shaderc_revision': 'f6d6dddfabfec1041c0dfb8e7ff3608a5f82227c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '30eeac75784aac8c3a2df867ee21d8188f5f3fad',
+  'dawn_revision': '4420ecc71e275f4675e981610067b426c0282f07',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -616,7 +619,7 @@
   },
 
   'src/ios/third_party/material_components_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '95c4fb354ed585db2daeb2d1dc6c3f758b480bce',
+      'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + 'e1c88bec2a37dcc386f4484a758ccfef6615bcbf',
       'condition': 'checkout_ios',
   },
 
@@ -626,7 +629,7 @@
   },
 
   'src/ios/third_party/material_internationalization_ios/src': {
-      'url': Var('chromium_git') + '/external/github.com/material-foundation/material-internationalization-ios.git' + '@' + '8e4a1eaf376e8a6d40d0f13c3c67b124dc63e0d9',
+      'url': Var('chromium_git') + '/external/github.com/material-foundation/material-internationalization-ios.git' + '@' + '4f71b756289a90e7e559d1851fd1c426a183dbc8',
       'condition': 'checkout_ios',
   },
 
@@ -773,7 +776,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'L-v7Lp_nVRhjXf1b1XWKe2CPp3Vd5WuJqb5nShZ7ZOoC',
+          'version': '3nbPFkI2v6vg5aJKxTomy2I4gV5g7AvfZDQpjRlwSroC',
       },
     ],
     'condition': 'checkout_android',
@@ -918,6 +921,17 @@
       'dep_type': 'cipd',
   },
 
+  'src/third_party/cast_core/prebuilts': {
+      'packages': [
+          {
+              'package': 'cast3p/cast_core/package_qa_vizio_castos_armv7a.tar',
+              'version': 'ZOzcgmEj32ltQEYvSSBfLbwcEo4MA_qtruinWrbbpGAC',
+          },
+      ],
+      'condition': 'checkout_cast3p',
+      'dep_type': 'cipd',
+  },
+
   'src/third_party/google_benchmark/src': {
     'url': Var('chromium_git') + '/external/github.com/google/benchmark.git' + '@' + 'e991355c02b93fe17713efe04cbc2e278e00fdbd',
     'condition': 'checkout_google_benchmark',
@@ -1476,7 +1490,7 @@
       'packages': [
           {
               'package': 'fuchsia/third_party/aemu/linux-amd64',
-              'version': 'y7X4kitLsRPSZc6ksrVllZRbH7mvEXlq9-4wOg7zR5cC'
+              'version': 'RcTpHQNhrkxG2Y4BJhRct_IdU43YwygAOkCuplrWcKQC'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia',
@@ -1619,7 +1633,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'b0291fd966b55a5efc496772555b94842bde1085',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '889ffa4d26fa0059542c7cf5ae2ec43a687b749c',
+    Var('webrtc_git') + '/src.git' + '@' + '9f0b3330764eb4d373d8e2c9775d250ed10cb9f4',
 
   'src/third_party/libgifcodec':
      Var('skia_git') + '/libgifcodec' + '@'+  Var('libgifcodec_revision'),
@@ -1677,7 +1691,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@7066c1b6405040f6890630c0de83c2b237cd77c8',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@5d74f86711c757b493b11e623f3891828001cebf',
     'condition': 'checkout_src_internal',
   },
 
@@ -1685,7 +1699,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/eche_app/app',
-        'version': 'vYdpaWIxUzRyiSS-wpZmGmxnu79kgN9q_kb2w2YlFOoC',
+        'version': 'yesLEVtJiCOq14OvyOrnxowJ-3QNm1AJrrX-gyZPIMAC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4588,6 +4602,17 @@
     ],
   },
 
+  # Download Cast Web Runtime
+  {
+    'name': 'cast_web_runtime',
+    'pattern': '.',
+    'action': [
+      'python3',
+      'src/tools/cast3p/update_runtime.py',
+    ],
+    'condition': 'checkout_cast3p',
+  },
+
   {
     'name': 'Generate location tags for tests',
     'pattern': '.',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 0071a5db..7bf739f9 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -2509,6 +2509,7 @@
     "wm/overlay_layout_manager_unittest.cc",
     "wm/overview/cleanup_animation_observer_unittest.cc",
     "wm/overview/delayed_animation_observer_impl_unittest.cc",
+    "wm/overview/desks_templates/desks_templates_unittest.cc",
     "wm/overview/overview_controller_unittest.cc",
     "wm/overview/overview_grid_unittest.cc",
     "wm/overview/overview_highlight_controller_unittest.cc",
@@ -2636,6 +2637,7 @@
     "//components/account_id",
     "//components/app_restore",
     "//components/arc:notification_test_support",
+    "//components/desks_storage",
     "//components/media_message_center",
     "//components/onc",
     "//components/password_manager/core/browser:hash_password_manager",
diff --git a/ash/DEPS b/ash/DEPS
index ba36485..3e92814 100644
--- a/ash/DEPS
+++ b/ash/DEPS
@@ -6,6 +6,7 @@
   "+chromeos/cryptohome",
   "+components/account_id",
   "+components/app_restore",
+  "+components/desks_storage",
   "+components/discardable_memory/public",
   "+components/discardable_memory/service/discardable_shared_memory_manager.h",
   "+components/live_caption",
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc
index a541854e..0516c523 100644
--- a/ash/app_list/app_list_controller_impl.cc
+++ b/ash/app_list/app_list_controller_impl.cc
@@ -69,7 +69,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/services/app_service/public/cpp/app_registry_cache_wrapper.h"
 #include "extensions/common/constants.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_sequence.h"
 #include "ui/display/manager/display_manager.h"
@@ -274,9 +273,7 @@
 
 AppListControllerImpl::AppListControllerImpl()
     : model_(std::make_unique<AppListModel>()),
-      fullscreen_presenter_(std::make_unique<AppListPresenterImpl>(this)),
-      is_notification_indicator_enabled_(
-          ::features::IsNotificationIndicatorEnabled()) {
+      fullscreen_presenter_(std::make_unique<AppListPresenterImpl>(this)) {
   if (features::IsAppListBubbleEnabled())
     bubble_presenter_ = std::make_unique<AppListBubblePresenter>(this);
 
@@ -621,8 +618,7 @@
 void AppListControllerImpl::OnAppListItemAdded(AppListItem* item) {
   client_->OnItemAdded(profile_id_, item->CloneMetadata());
 
-  if (is_notification_indicator_enabled_ && cache_ &&
-      notification_badging_pref_enabled_.value_or(false)) {
+  if (cache_ && notification_badging_pref_enabled_.value_or(false)) {
     // Update the notification badge indicator for the newly added app list
     // item.
     cache_->ForOneApp(item->id(), [item](const apps::AppUpdate& update) {
@@ -634,30 +630,26 @@
 
 void AppListControllerImpl::OnActiveUserPrefServiceChanged(
     PrefService* pref_service) {
-  if (is_notification_indicator_enabled_) {
-    pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
-    pref_change_registrar_->Init(pref_service);
+  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
+  pref_change_registrar_->Init(pref_service);
 
-    pref_change_registrar_->Add(
-        prefs::kAppNotificationBadgingEnabled,
-        base::BindRepeating(
-            &AppListControllerImpl::UpdateAppNotificationBadging,
-            base::Unretained(this)));
+  pref_change_registrar_->Add(
+      prefs::kAppNotificationBadgingEnabled,
+      base::BindRepeating(&AppListControllerImpl::UpdateAppNotificationBadging,
+                          base::Unretained(this)));
 
-    // Observe AppRegistryCache for the current active account to get
-    // notification updates.
-    AccountId account_id =
-        Shell::Get()->session_controller()->GetActiveAccountId();
-    cache_ =
-        apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id);
-    Observe(cache_);
+  // Observe AppRegistryCache for the current active account to get
+  // notification updates.
+  AccountId account_id =
+      Shell::Get()->session_controller()->GetActiveAccountId();
+  cache_ = apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id);
+  Observe(cache_);
 
-    // Resetting the recorded pref forces the next call to
-    // UpdateAppNotificationBadging() to update notification badging for every
-    // app item.
-    notification_badging_pref_enabled_.reset();
-    UpdateAppNotificationBadging();
-  }
+  // Resetting the recorded pref forces the next call to
+  // UpdateAppNotificationBadging() to update notification badging for every
+  // app item.
+  notification_badging_pref_enabled_.reset();
+  UpdateAppNotificationBadging();
 
   if (!IsTabletMode()) {
     DismissAppList();
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h
index e9dc74b..c3b1bfd0 100644
--- a/ash/app_list/app_list_controller_impl.h
+++ b/ash/app_list/app_list_controller_impl.h
@@ -558,9 +558,6 @@
   // initial notification badge information when app list items are added.
   apps::AppRegistryCache* cache_ = nullptr;
 
-  // Whether the notification indicator flag is enabled.
-  const bool is_notification_indicator_enabled_;
-
   // Observes user profile prefs for the app list.
   std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
 
diff --git a/ash/app_list/app_list_controller_impl_unittest.cc b/ash/app_list/app_list_controller_impl_unittest.cc
index c1314c27..924593b5 100644
--- a/ash/app_list/app_list_controller_impl_unittest.cc
+++ b/ash/app_list/app_list_controller_impl_unittest.cc
@@ -62,7 +62,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/with_feature_override.h"
 #include "ui/base/emoji/emoji_panel_helper.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/events/test/event_generator.h"
@@ -716,9 +715,7 @@
 class AppListControllerImplTestWithNotificationBadging
     : public AppListControllerImplTest {
  public:
-  AppListControllerImplTestWithNotificationBadging() {
-    scoped_features_.InitWithFeatures({::features::kNotificationIndicator}, {});
-  }
+  AppListControllerImplTestWithNotificationBadging() = default;
   AppListControllerImplTestWithNotificationBadging(
       const AppListControllerImplTestWithNotificationBadging& other) = delete;
   AppListControllerImplTestWithNotificationBadging& operator=(
@@ -740,9 +737,6 @@
     static_cast<apps::AppRegistryCache::Observer*>(controller)
         ->OnAppUpdate(test_update);
   }
-
- private:
-  base::test::ScopedFeatureList scoped_features_;
 };
 
 // Tests that when an app has an update to its notification badge, the change
diff --git a/ash/app_list/views/app_list_bubble_apps_page.cc b/ash/app_list/views/app_list_bubble_apps_page.cc
index 4e94930..645ee39 100644
--- a/ash/app_list/views/app_list_bubble_apps_page.cc
+++ b/ash/app_list/views/app_list_bubble_apps_page.cc
@@ -38,6 +38,14 @@
 // Insets for the vertical scroll bar.
 constexpr gfx::Insets kVerticalScrollInsets(1, 0, 1, 1);
 
+// The padding between different sections within the apps page. Also used for
+// interior apps page container margin.
+constexpr int kVerticalPaddingBetweenSections = 16;
+
+// The horizontal interior margin for the apps page container - i.e. the margin
+// between the apps page bounds and the page content.
+constexpr int kHorizontalInteriorMargin = 20;
+
 }  // namespace
 
 AppListBubbleAppsPage::AppListBubbleAppsPage(
@@ -71,8 +79,10 @@
   scroll_view_->SetVerticalScrollBar(std::move(vertical_scroll));
 
   auto scroll_contents = std::make_unique<views::View>();
-  auto* layout = scroll_contents->SetLayoutManager(
-      std::make_unique<BoxLayout>(BoxLayout::Orientation::kVertical));
+  auto* layout = scroll_contents->SetLayoutManager(std::make_unique<BoxLayout>(
+      BoxLayout::Orientation::kVertical,
+      gfx::Insets(kVerticalPaddingBetweenSections, kHorizontalInteriorMargin),
+      kVerticalPaddingBetweenSections));
   layout->set_cross_axis_alignment(BoxLayout::CrossAxisAlignment::kStretch);
 
   // Continue section row.
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc
index a5fc8eb..8a01940f 100644
--- a/ash/app_list/views/app_list_item_view.cc
+++ b/ash/app_list/views/app_list_item_view.cc
@@ -28,7 +28,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/resource/resource_bundle.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/animation/throb_animation.h"
@@ -272,9 +271,7 @@
       is_folder_(item->GetItemType() == AppListFolderItem::kItemType),
       item_weak_(item),
       grid_delegate_(grid_delegate),
-      view_delegate_(view_delegate),
-      is_notification_indicator_enabled_(
-          features::IsNotificationIndicatorEnabled()) {
+      view_delegate_(view_delegate) {
   // TODO(crbug.com/1218186): Remove this, this is in place temporarily to be
   // able to submit accessibility checks. This crashes if fetching a11y node
   // data during paint because message_view_ is null.
@@ -304,7 +301,7 @@
                             false /*animate*/);
   }
 
-  if (is_notification_indicator_enabled_ && !is_folder_) {
+  if (!is_folder_) {
     notification_indicator_ =
         AddChildView(std::make_unique<AppNotificationIndicatorView>(
             item->notification_badge_color()));
@@ -760,7 +757,7 @@
     title_bounds.Inset(title_shadow_margins_);
   title_->SetBoundsRect(title_bounds);
 
-  if (is_notification_indicator_enabled_ && notification_indicator_)
+  if (notification_indicator_)
     notification_indicator_->SetBoundsRect(icon_bounds);
 }
 
@@ -1100,7 +1097,7 @@
 }
 
 void AppListItemView::ItemBadgeVisibilityChanged() {
-  if (is_notification_indicator_enabled_ && notification_indicator_ && icon_)
+  if (notification_indicator_ && icon_)
     notification_indicator_->SetVisible(item_weak_->has_notification_badge());
 }
 
diff --git a/ash/app_list/views/app_list_item_view.h b/ash/app_list/views/app_list_item_view.h
index d7323a7..3ba7796 100644
--- a/ash/app_list/views/app_list_item_view.h
+++ b/ash/app_list/views/app_list_item_view.h
@@ -406,9 +406,6 @@
   // active notification.
   AppNotificationIndicatorView* notification_indicator_ = nullptr;
 
-  // Whether the notification indicator flag is enabled.
-  const bool is_notification_indicator_enabled_;
-
   // Helper to trigger icon load.
   absl::optional<AppIconLoadHelper> icon_load_helper_;
 
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc
index f45ceac..3ff1a4a4 100644
--- a/ash/app_list/views/apps_grid_view.cc
+++ b/ash/app_list/views/apps_grid_view.cc
@@ -1686,7 +1686,7 @@
   // GetAppListConfig() during this object's destruction.
   if (!contents_view_) {
     AppListConfig* config = AppListConfigProvider::Get().GetConfigForType(
-        AppListConfigType::kLarge, /*can_create=*/true);
+        AppListConfigType::kMedium, /*can_create=*/true);
     return *config;
   }
   return contents_view_->app_list_view()->GetAppListConfig();
diff --git a/ash/app_list/views/recent_apps_view.cc b/ash/app_list/views/recent_apps_view.cc
index 14b7136..c7a7b02 100644
--- a/ash/app_list/views/recent_apps_view.cc
+++ b/ash/app_list/views/recent_apps_view.cc
@@ -22,14 +22,14 @@
 #include "base/strings/string_util.h"
 #include "extensions/common/constants.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/views/layout/box_layout.h"
+#include "ui/views/accessibility/view_accessibility.h"
+#include "ui/views/layout/flex_layout.h"
 #include "url/gurl.h"
 
 namespace ash {
 namespace {
 
-// Horizontal space between apps in dips.
-constexpr int kHorizontalSpacing = 8;
+constexpr size_t kMaxRecommendedApps = 5;
 
 // Sorts increasing by display index, then decreasing by position priority.
 struct CompareByDisplayIndexAndPositionPriority {
@@ -74,7 +74,7 @@
   std::vector<SearchResult*> app_suggestion_results =
       SearchModel::FilterSearchResultsByFunction(
           results, base::BindRepeating(is_app_suggestion),
-          /*max_results=*/5);
+          /*max_results=*/kMaxRecommendedApps);
 
   std::sort(app_suggestion_results.begin(), app_suggestion_results.end(),
             CompareByDisplayIndexAndPositionPriority());
@@ -142,7 +142,7 @@
   const AppListConfig& GetAppListConfig() const override {
     // TODO(crbug.com/1211592): Eliminate this method and use the real config.
     return *AppListConfigProvider::Get().GetConfigForType(
-        AppListConfigType::kLarge, /*can_create=*/true);
+        AppListConfigType::kMedium, /*can_create=*/true);
   }
 
  private:
@@ -154,10 +154,8 @@
     : view_delegate_(view_delegate),
       grid_delegate_(std::make_unique<GridDelegateImpl>(view_delegate_)) {
   DCHECK(view_delegate_);
-  auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
-      views::BoxLayout::Orientation::kHorizontal, gfx::Insets(),
-      kHorizontalSpacing));
-  layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kCenter);
+  SetLayoutManager(std::make_unique<views::FlexLayout>())
+      ->SetOrientation(views::LayoutOrientation::kHorizontal);
 
   std::vector<std::string> app_ids =
       GetRecentAppIdsFromSuggestionChips(view_delegate_->GetSearchModel());
@@ -167,10 +165,25 @@
     std::string item_id = ItemIdFromAppId(app_id);
     AppListItem* item = model->FindItem(item_id);
     if (item) {
-      // NOTE: If you change the view structure, update GetItemForTest() as
-      // well.
-      AddChildView(std::make_unique<AppListItemView>(grid_delegate_.get(), item,
-                                                     view_delegate_));
+      auto* item_view = AddChildView(std::make_unique<AppListItemView>(
+          grid_delegate_.get(), item, view_delegate_));
+      item_view->SetProperty(
+          views::kFlexBehaviorKey,
+          views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
+                                   views::MaximumFlexSizeRule::kPreferred));
+
+      // Add a empty-space view used to evenly distribute app list item views
+      // within the available space.
+      if (app_id != app_ids.back()) {
+        auto* flex_view = AddChildView(std::make_unique<views::View>());
+        flex_view->GetViewAccessibility().OverrideIsIgnored(true);
+        flex_view->SetFocusBehavior(views::View::FocusBehavior::NEVER);
+        flex_view->SetCanProcessEventsWithinSubtree(false);
+        flex_view->SetProperty(
+            views::kFlexBehaviorKey,
+            views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
+                                     views::MaximumFlexSizeRule::kUnbounded));
+      }
     }
   }
 }
@@ -182,10 +195,6 @@
     child->SetEnabled(!disabled);
 }
 
-AppListItemView* RecentAppsView::GetItemViewForTest(int index) {
-  return static_cast<AppListItemView*>(children()[index]);
-}
-
 BEGIN_METADATA(RecentAppsView, views::View)
 END_METADATA
 
diff --git a/ash/app_list/views/recent_apps_view.h b/ash/app_list/views/recent_apps_view.h
index 72cab88..815b989 100644
--- a/ash/app_list/views/recent_apps_view.h
+++ b/ash/app_list/views/recent_apps_view.h
@@ -32,8 +32,6 @@
   // See AppsGridView::DisableFocusForShowingActiveFolder().
   void DisableFocusForShowingActiveFolder(bool disabled);
 
-  AppListItemView* GetItemViewForTest(int index);
-
  private:
   AppListViewDelegate* const view_delegate_;
 
diff --git a/ash/app_list/views/recent_apps_view_unittest.cc b/ash/app_list/views/recent_apps_view_unittest.cc
index b26a01b3..8f8f49b 100644
--- a/ash/app_list/views/recent_apps_view_unittest.cc
+++ b/ash/app_list/views/recent_apps_view_unittest.cc
@@ -19,12 +19,26 @@
 #include "ash/public/cpp/app_list/app_list_types.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
+#include "base/strings/stringprintf.h"
 #include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/vector2d.h"
+#include "ui/views/view_utils.h"
 
 namespace ash {
 namespace {
 
+// Used to compare distances between point that allow for certain margin of
+// error when comparing horizontal distance. Used to compare spacing between
+// views that accounts for 1 off rounding errors.
+bool AreVectorsClose(const gfx::Vector2d& v1, const gfx::Vector2d& v2) {
+  const int kHorizontalMarginOfError = 1;
+  return std::abs(v1.x() - v2.x()) <= kHorizontalMarginOfError &&
+         std::abs(v1.y() - v2.y()) == 0;
+}
+
 // Returns the first window with type WINDOW_TYPE_MENU found via depth-first
 // search. Returns nullptr if no such window exists.
 aura::Window* FindMenuWindow(aura::Window* root) {
@@ -74,6 +88,24 @@
     return GetAppListTestHelper()->GetBubbleRecentAppsView();
   }
 
+  // Adds `count` installed app search results.
+  void AddAppResults(int count) {
+    for (int i = 0; i < count; ++i) {
+      std::string id = base::StringPrintf("id%d", i);
+      AddAppListItem(id);
+      AddSearchResult(id, AppListSearchResultType::kInstalledApp);
+    }
+  }
+
+  std::vector<AppListItemView*> GetAppListItemViews(RecentAppsView* view) {
+    std::vector<AppListItemView*> app_list_item_views;
+    for (auto* child : view->children()) {
+      if (views::IsViewClass<AppListItemView>(child))
+        app_list_item_views.push_back(static_cast<AppListItemView*>(child));
+    }
+    return app_list_item_views;
+  }
+
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
@@ -90,7 +122,103 @@
   ShowAppList();
 
   RecentAppsView* view = GetRecentAppsView();
-  EXPECT_EQ(view->children().size(), 4u);
+  EXPECT_EQ(GetAppListItemViews(view).size(), 4u);
+}
+
+TEST_F(RecentAppsViewTest, ItemsEvenlySpacedInTheViewWith5Items) {
+  AddAppResults(5);
+  ShowAppList();
+
+  RecentAppsView* view = GetRecentAppsView();
+  std::vector<AppListItemView*> items = GetAppListItemViews(view);
+  ASSERT_EQ(5u, items.size());
+
+  for (int i = 4; i > 1; --i) {
+    const gfx::Vector2d right_space = items[i]->bounds().left_center() -
+                                      items[i - 1]->bounds().right_center();
+    const gfx::Vector2d left_space = items[i - 1]->bounds().left_center() -
+                                     items[i - 2]->bounds().right_center();
+    EXPECT_TRUE(AreVectorsClose(right_space, left_space))
+        << i << " " << right_space.ToString() << " " << left_space.ToString();
+  }
+}
+
+TEST_F(RecentAppsViewTest, ResultItemsCoverWholeContainerWith5Items) {
+  AddAppResults(5);
+  ShowAppList();
+
+  RecentAppsView* view = GetRecentAppsView();
+  std::vector<AppListItemView*> items = GetAppListItemViews(view);
+  ASSERT_EQ(5u, items.size());
+
+  EXPECT_EQ(view->GetContentsBounds().left_center(),
+            items[0]->bounds().left_center());
+  EXPECT_EQ(view->GetContentsBounds().right_center(),
+            items[4]->bounds().right_center());
+}
+
+TEST_F(RecentAppsViewTest, ItemsEvenlySpacedInTheViewWith4Items) {
+  AddAppResults(4);
+  ShowAppList();
+
+  RecentAppsView* view = GetRecentAppsView();
+  std::vector<AppListItemView*> items = GetAppListItemViews(view);
+  ASSERT_EQ(4u, items.size());
+
+  for (int i = 3; i > 1; --i) {
+    const gfx::Vector2d right_space = items[i]->bounds().left_center() -
+                                      items[i - 1]->bounds().right_center();
+    const gfx::Vector2d left_space = items[i - 1]->bounds().left_center() -
+                                     items[i - 2]->bounds().right_center();
+    EXPECT_TRUE(AreVectorsClose(right_space, left_space))
+        << i << " " << right_space.ToString() << " " << left_space.ToString();
+  }
+}
+
+TEST_F(RecentAppsViewTest, ResultItemsCoverWholeContainerWith4Items) {
+  AddAppResults(4);
+  ShowAppList();
+
+  RecentAppsView* view = GetRecentAppsView();
+  std::vector<AppListItemView*> items = GetAppListItemViews(view);
+  ASSERT_EQ(4u, items.size());
+
+  EXPECT_EQ(view->GetContentsBounds().left_center(),
+            items[0]->bounds().left_center());
+  EXPECT_EQ(view->GetContentsBounds().right_center(),
+            items[3]->bounds().right_center());
+}
+
+TEST_F(RecentAppsViewTest, ItemsEvenlySpacedInTheViewWith3Items) {
+  AddAppResults(3);
+  ShowAppList();
+
+  RecentAppsView* view = GetRecentAppsView();
+  std::vector<AppListItemView*> items = GetAppListItemViews(view);
+  ASSERT_EQ(3u, items.size());
+
+  for (int i = 2; i > 1; --i) {
+    const gfx::Vector2d right_space = items[i]->bounds().left_center() -
+                                      items[i - 1]->bounds().right_center();
+    const gfx::Vector2d left_space = items[i - 1]->bounds().left_center() -
+                                     items[i - 2]->bounds().right_center();
+    EXPECT_TRUE(AreVectorsClose(right_space, left_space))
+        << i << " " << right_space.ToString() << " " << left_space.ToString();
+  }
+}
+
+TEST_F(RecentAppsViewTest, ResultItemsCoverWholeContainerWith3Items) {
+  AddAppResults(3);
+  ShowAppList();
+
+  RecentAppsView* view = GetRecentAppsView();
+  std::vector<AppListItemView*> items = GetAppListItemViews(view);
+  ASSERT_EQ(3u, items.size());
+
+  EXPECT_EQ(view->GetContentsBounds().left_center(),
+            items[0]->bounds().left_center());
+  EXPECT_EQ(view->GetContentsBounds().right_center(),
+            items[2]->bounds().right_center());
 }
 
 TEST_F(RecentAppsViewTest, DoesNotCreateIconsForNonApps) {
@@ -101,7 +229,7 @@
   ShowAppList();
 
   RecentAppsView* view = GetRecentAppsView();
-  EXPECT_EQ(view->children().size(), 0u);
+  EXPECT_EQ(GetAppListItemViews(view).size(), 0u);
 }
 
 TEST_F(RecentAppsViewTest, DoesNotCreateIconForMismatchedId) {
@@ -121,9 +249,10 @@
   ShowAppList();
 
   // Click on the first icon.
-  RecentAppsView* view = GetRecentAppsView();
-  ASSERT_FALSE(view->children().empty());
-  views::View* icon = view->children()[0];
+  std::vector<AppListItemView*> items =
+      GetAppListItemViews(GetRecentAppsView());
+  ASSERT_FALSE(items.empty());
+  views::View* icon = items[0];
   GetEventGenerator()->MoveMouseTo(icon->GetBoundsInScreen().CenterPoint());
   GetEventGenerator()->ClickLeftButton();
 
@@ -138,10 +267,10 @@
   ShowAppList();
 
   // Right click on the first icon.
-  RecentAppsView* view = GetRecentAppsView();
-  ASSERT_FALSE(view->children().empty());
-  views::View* icon = view->children()[0];
-  GetEventGenerator()->MoveMouseTo(icon->GetBoundsInScreen().CenterPoint());
+  std::vector<AppListItemView*> items =
+      GetAppListItemViews(GetRecentAppsView());
+  ASSERT_FALSE(items.empty());
+  GetEventGenerator()->MoveMouseTo(items[0]->GetBoundsInScreen().CenterPoint());
   GetEventGenerator()->ClickRightButton();
 
   // A menu opened.
@@ -163,11 +292,11 @@
   AddSearchResult("id2", AppListSearchResultType::kInstalledApp);
   ShowAppList();
 
-  // There are 2 items.
-  RecentAppsView* view = GetRecentAppsView();
-  ASSERT_EQ(2u, view->children().size());
-  AppListItemView* item1 = view->GetItemViewForTest(0);
-  AppListItemView* item2 = view->GetItemViewForTest(1);
+  std::vector<AppListItemView*> items =
+      GetAppListItemViews(GetRecentAppsView());
+  ASSERT_EQ(2u, items.size());
+  AppListItemView* item1 = items[0];
+  AppListItemView* item2 = items[1];
 
   // The grid delegates are the same, so it doesn't matter which one we use for
   // expectations below.
diff --git a/ash/app_list/views/scrollable_apps_grid_view.cc b/ash/app_list/views/scrollable_apps_grid_view.cc
index c9fb714..10b358a 100644
--- a/ash/app_list/views/scrollable_apps_grid_view.cc
+++ b/ash/app_list/views/scrollable_apps_grid_view.cc
@@ -102,8 +102,15 @@
   int content_width = GetContentsBounds().width();
   int tile_width = GetAppListConfig().grid_tile_width();
   int width_to_distribute = content_width - cols() * tile_width;
-  // Each column has padding on left and on right.
-  int horizontal_tile_padding = width_to_distribute / (cols() * 2);
+
+  // While calculating tile padding, assume no padding between a tile and a
+  // container bounds.
+  DCHECK_GT(cols(), 1);
+  const int spaces_between_items = cols() - 1;
+  // Each column has padding on left and on right, so a space between two tiles
+  // is double the tile padding size.
+  const int horizontal_tile_padding =
+      width_to_distribute / (spaces_between_items * 2);
   return gfx::Insets(-kVerticalTilePadding, -horizontal_tile_padding);
 }
 
diff --git a/ash/app_list/views/scrollable_apps_grid_view_unittest.cc b/ash/app_list/views/scrollable_apps_grid_view_unittest.cc
index 46d0baa..3dd0f790 100644
--- a/ash/app_list/views/scrollable_apps_grid_view_unittest.cc
+++ b/ash/app_list/views/scrollable_apps_grid_view_unittest.cc
@@ -309,8 +309,11 @@
   const int scroll_offset2 = scroll_view_->GetVisibleRect().y();
   EXPECT_GT(scroll_offset2, scroll_offset1);
 
-  // Move the mouse back into the center of the view (not in the scroll margin).
-  generator->MoveMouseTo(scroll_view_->GetBoundsInScreen().CenterPoint());
+  // Move the mouse back into the (vertical) center of the view (not in the
+  // scroll margin). Use a point close to a horizontal edge to avoid hitting an
+  // item bounds (which would trigger reparent instead of reorder timer).
+  generator->MoveMouseTo(scroll_view_->GetBoundsInScreen().left_center() +
+                         gfx::Vector2d(5, 0));
 
   // Scroll position didn't change, auto-scrolling is stopped, and reordering
   // started again.
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd
index c17688e..a006c69b 100644
--- a/ash/ash_strings.grd
+++ b/ash/ash_strings.grd
@@ -533,12 +533,15 @@
       <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIR_NEW_DEVICE" desc="The sub-header label for the button to pair a new device.">
         Pair new device
       </message>
-      <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_CURRENTLY_CONNECTED_DEVICES" desc="The sub-header label for currently connected devices in Bluetooth device list.">
+      <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_CURRENTLY_CONNECTED_DEVICES" desc="The sub-header label for currently connected devices in the Bluetooth device list.">
         Currently connected
       </message>
-      <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_PREVIOUSLY_CONNECTED_DEVICES" desc="The sub-header label for previously connected devices in Bluetooth device list.">
+      <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_PREVIOUSLY_CONNECTED_DEVICES" desc="The sub-header label for previously connected devices in the Bluetooth device list.">
         Previously connected
       </message>
+      <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH_NO_DEVICE_CONNECTED" desc="The sub-header label for no devices connected in the Bluetooth device list.">
+        No device connected
+      </message>
 
       <message name="IDS_ASH_STATUS_TRAY_UPDATE" desc="The label used in the tray popup to notify that the user should restart to get system updates.">
         Restart to update
@@ -3654,13 +3657,22 @@
       <message name="IDS_ASH_SCREEN_CAPTURE_LABEL_MICROPHONE" desc="The capture label message for toggling microphone recording, found in the settings menu.">
         Record microphone
       </message>
-      <message name="IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO" desc="The label of the save to menu group header in capture mode settings.">
+      <message name="IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT" desc="The label of the audio input menu group header in capture mode settings.">
+        Audio input
+      </message>
+      <message name="IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF" desc="The label of the menu option button for no audio input.">
+        Off
+      </message>
+      <message name="IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_MICROPHONE" desc="The label of the menu option button for microphone audio input.">
+        Microphone
+      </message>
+      <message name="IDS_ASH_SCREEN_CAPTURE_SAVE_TO" desc="The label of the save to menu group header in capture mode settings.">
         Save to
       </message>
-      <message name="IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO_DOWNLOADS" desc="The label of the menu option button to select the downloads folder.">
+      <message name="IDS_ASH_SCREEN_CAPTURE_SAVE_TO_DOWNLOADS" desc="The label of the menu option button to select the downloads folder.">
         Downloads
       </message>
-      <message name="IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO_SELECT_FOLDER" desc="The label of the menu item button for selecting a folder to store the captured images and videos.">
+      <message name="IDS_ASH_SCREEN_CAPTURE_SAVE_TO_SELECT_FOLDER" desc="The label of the menu item button for selecting a folder to store the captured images and videos.">
         Select folder...
       </message>
 
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT.png.sha1
new file mode 100644
index 0000000..626479c4
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT.png.sha1
@@ -0,0 +1 @@
+ae438034185f53e0e12d9d760885eb624bbd0935
\ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_MICROPHONE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_MICROPHONE.png.sha1
new file mode 100644
index 0000000..626479c4
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_MICROPHONE.png.sha1
@@ -0,0 +1 @@
+ae438034185f53e0e12d9d760885eb624bbd0935
\ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF.png.sha1
new file mode 100644
index 0000000..626479c4
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF.png.sha1
@@ -0,0 +1 @@
+ae438034185f53e0e12d9d760885eb624bbd0935
\ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_SAVE_TO.png.sha1
similarity index 100%
rename from ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO.png.sha1
rename to ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_SAVE_TO.png.sha1
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO_DOWNLOADS.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_SAVE_TO_DOWNLOADS.png.sha1
similarity index 100%
rename from ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO_DOWNLOADS.png.sha1
rename to ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_SAVE_TO_DOWNLOADS.png.sha1
diff --git a/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO_SELECT_FOLDER.png.sha1 b/ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_SAVE_TO_SELECT_FOLDER.png.sha1
similarity index 100%
rename from ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO_SELECT_FOLDER.png.sha1
rename to ash/ash_strings_grd/IDS_ASH_SCREEN_CAPTURE_SAVE_TO_SELECT_FOLDER.png.sha1
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_BLUETOOTH_NO_DEVICE_CONNECTED.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_BLUETOOTH_NO_DEVICE_CONNECTED.png.sha1
new file mode 100644
index 0000000..7f7df6d
--- /dev/null
+++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_BLUETOOTH_NO_DEVICE_CONNECTED.png.sha1
@@ -0,0 +1 @@
+1087627139c0d0fa0010136ab561cc32462988fd
\ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_advanced_settings_view.cc b/ash/capture_mode/capture_mode_advanced_settings_view.cc
index 581255a..ba4da87 100644
--- a/ash/capture_mode/capture_mode_advanced_settings_view.cc
+++ b/ash/capture_mode/capture_mode_advanced_settings_view.cc
@@ -8,7 +8,7 @@
 
 #include "ash/capture_mode/capture_mode_bar_view.h"
 #include "ash/capture_mode/capture_mode_constants.h"
-#include "ash/capture_mode/capture_mode_menu_group.h"
+#include "ash/capture_mode/capture_mode_controller.h"
 #include "ash/capture_mode/capture_mode_toggle_button.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -18,37 +18,61 @@
 #include "ui/compositor/layer.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/background.h"
+#include "ui/views/controls/separator.h"
 #include "ui/views/layout/box_layout.h"
 
 namespace ash {
 
 namespace {
 
-constexpr gfx::Size kSettingsSize{256, 124};
+constexpr gfx::Size kSettingsSize{256, 248};
 
 constexpr gfx::RoundedCornersF kBorderRadius{10.f};
 
+// All the options in the CaptureMode settings view.
+enum CaptureSettingsOption {
+  kAudioOff = 0,
+  kAudioMicrophone,
+  kDownloadsFolder,
+  kCustomFolder,
+};
+
 }  // namespace
 
 CaptureModeAdvancedSettingsView::CaptureModeAdvancedSettingsView()
-    : save_to_menu_group_(AddChildView(std::make_unique<CaptureModeMenuGroup>(
+    : audio_input_menu_group_(
+          AddChildView(std::make_unique<CaptureModeMenuGroup>(
+              this,
+              kCaptureModeMicIcon,
+              l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT)))),
+      separator_(AddChildView(std::make_unique<views::Separator>())),
+      save_to_menu_group_(AddChildView(std::make_unique<CaptureModeMenuGroup>(
+          this,
           kCaptureModeFolderIcon,
-          l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO)))) {
+          l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_SAVE_TO)))) {
+  audio_input_menu_group_->AddOption(
+      l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_OFF),
+      kAudioOff);
+  audio_input_menu_group_->AddOption(
+      l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_AUDIO_INPUT_MICROPHONE),
+      kAudioMicrophone);
   save_to_menu_group_->AddOption(
-      base::BindRepeating(&CaptureModeAdvancedSettingsView::HandleOptionClick,
-                          base::Unretained(this)),
-      l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO_DOWNLOADS),
-      /*checked=*/true);
+      l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_SAVE_TO_DOWNLOADS),
+      kDownloadsFolder);
   save_to_menu_group_->AddMenuItem(
       base::BindRepeating(&CaptureModeAdvancedSettingsView::HandleMenuClick,
                           base::Unretained(this)),
-      l10n_util::GetStringUTF16(
-          IDS_ASH_SCREEN_CAPTURE_LABEL_SAVE_TO_SELECT_FOLDER));
+      l10n_util::GetStringUTF16(IDS_ASH_SCREEN_CAPTURE_SAVE_TO_SELECT_FOLDER));
+
+  auto* color_provider = AshColorProvider::Get();
+
+  const SkColor separator_color = color_provider->GetContentLayerColor(
+      AshColorProvider::ContentLayerType::kSeparatorColor);
+  separator_->SetColor(separator_color);
 
   SetPaintToLayer();
-  SetBackground(
-      views::CreateSolidBackground(AshColorProvider::Get()->GetBaseLayerColor(
-          AshColorProvider::BaseLayerType::kTransparent80)));
+  SetBackground(views::CreateSolidBackground(color_provider->GetBaseLayerColor(
+      AshColorProvider::BaseLayerType::kTransparent80)));
   layer()->SetFillsBoundsOpaquely(false);
   layer()->SetRoundedCornerRadius(kBorderRadius);
   layer()->SetBackgroundBlur(ColorProvider::kBackgroundBlurSigma);
@@ -73,7 +97,52 @@
       kSettingsSize.width(), kSettingsSize.height());
 }
 
-void CaptureModeAdvancedSettingsView::HandleOptionClick() {}
+void CaptureModeAdvancedSettingsView::OnOptionSelected(int option_id) const {
+  switch (option_id) {
+    case kAudioOff:
+      CaptureModeController::Get()->EnableAudioRecording(false);
+      break;
+    case kAudioMicrophone:
+      CaptureModeController::Get()->EnableAudioRecording(true);
+      break;
+    case kDownloadsFolder:
+    case kCustomFolder:
+      // TODO(conniekxu|afakhry): Handle |kDownloadsFolder| and |kCustomFolder|
+      // options in the following up CLs. For now we only support
+      // |kDownloadsFolder| for |save_to_menu_group_|, that's why we don't need
+      // to handle it explicitly here.
+      break;
+    default:
+      return;
+  }
+}
+
+bool CaptureModeAdvancedSettingsView::IsOptionChecked(int option_id) const {
+  switch (option_id) {
+    case kAudioOff:
+      return !CaptureModeController::Get()->enable_audio_recording();
+    case kAudioMicrophone:
+      return CaptureModeController::Get()->enable_audio_recording();
+    // TODO(conniekxu|afakhry): Handle |kDownloadsFolder| and |kCustomFolder|
+    // options in the following up CLs. For now we only support
+    // |kDownloadsFolder|, hence we return true/false directly here.
+    case kDownloadsFolder:
+      return true;
+    case kCustomFolder:
+      return false;
+    default:
+      return false;
+  }
+}
+
+views::View* CaptureModeAdvancedSettingsView::GetMicrophoneOptionForTesting() {
+  return audio_input_menu_group_->GetOptionForTesting(  // IN-TEST
+      kAudioMicrophone);                                // IN-TEST
+}
+
+views::View* CaptureModeAdvancedSettingsView::GetOffOptionForTesting() {
+  return audio_input_menu_group_->GetOptionForTesting(kAudioOff);  // IN-TEST
+}
 
 void CaptureModeAdvancedSettingsView::HandleMenuClick() {}
 
diff --git a/ash/capture_mode/capture_mode_advanced_settings_view.h b/ash/capture_mode/capture_mode_advanced_settings_view.h
index cf50d3b..6b62511 100644
--- a/ash/capture_mode/capture_mode_advanced_settings_view.h
+++ b/ash/capture_mode/capture_mode_advanced_settings_view.h
@@ -6,20 +6,26 @@
 #define ASH_CAPTURE_MODE_CAPTURE_MODE_ADVANCED_SETTINGS_VIEW_H_
 
 #include "ash/ash_export.h"
+#include "ash/capture_mode/capture_mode_menu_group.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/view.h"
 
+namespace views {
+class Separator;
+}  // namespace views
+
 namespace ash {
 
 class CaptureModeBarView;
-class CaptureModeMenuGroup;
 
 // TODO(conniekxu): This will replace CaptureModeSettingsView once
 // feature 'ImprovedScreenCaptureSettings' is fully launched.
 // A view that acts as the content view of the capture mode settings menu
 // widget. It is the content view of settings widget and it contains
 // `CaptureModeMenuGroup` for each setting, save to, audio input etc.
-class ASH_EXPORT CaptureModeAdvancedSettingsView : public views::View {
+class ASH_EXPORT CaptureModeAdvancedSettingsView
+    : public views::View,
+      public CaptureModeMenuGroup::Delegate {
  public:
   METADATA_HEADER(CaptureModeAdvancedSettingsView);
 
@@ -34,22 +40,31 @@
   // the given 'capture_mode_bar_view'.
   static gfx::Rect GetBounds(CaptureModeBarView* capture_mode_bar_view);
 
-  CaptureModeMenuGroup* save_to_menu_group() const {
-    return save_to_menu_group_;
+  // CaptureModeMenuGroup::Delegate:
+  void OnOptionSelected(int option_id) const override;
+  bool IsOptionChecked(int option_id) const override;
+
+  // For tests only:
+  CaptureModeMenuGroup* GetAudioInputMenuGroupForTesting() {
+    return audio_input_menu_group_;
   }
+  views::View* GetMicrophoneOptionForTesting();
+  views::View* GetOffOptionForTesting();
 
  private:
-  // TODO(conniekxu): This is the callback function on option click. It will
-  // select the clicked/pressed button, and unselect any previously selected
-  // button.
-  void HandleOptionClick();
-
   // TODO(afakhry|conniekxu): This is the callback function on menu item click.
-  // It will be only used by the menu item in `save_to_menu_` for now. It should
-  // open the folder window for user to select to folder to save the captured
-  // files from.
+  // It will be only used by the menu item in |save_to_menu_| for now. It should
+  // open the folder window for user to select a folder to save the captured
+  // files to.
   void HandleMenuClick();
 
+  // "Audio input" menu group that users can select an audio input from for
+  // screen capture recording. It has "Off" and "Microphone" options for now.
+  // "Off" is the default one which means no audio input selected.
+  CaptureModeMenuGroup* audio_input_menu_group_;
+
+  views::Separator* separator_;
+
   // "Save to" menu group that users can select a folder to save the captured
   // files to. It will include the "Downloads" folder as the default one and
   // one more folder selected by users.
diff --git a/ash/capture_mode/capture_mode_controller.cc b/ash/capture_mode/capture_mode_controller.cc
index 4a51ab4..45e7ead 100644
--- a/ash/capture_mode/capture_mode_controller.cc
+++ b/ash/capture_mode/capture_mode_controller.cc
@@ -426,6 +426,13 @@
     return;
 
   enable_audio_recording_ = enable_audio_recording;
+
+  // TODO(conniekxu): remove all code below for this function once feature
+  // 'ImprovedScreenCaptureSettings' is fully launched.
+  // Return directly if |kImprovedScreenCaptureSettings| is enabled because for
+  // the new CaptureMode settings we don't have microphone toggle button.
+  if (features::AreImprovedScreenCaptureSettingsEnabled())
+    return;
   DCHECK(capture_mode_session_);
   capture_mode_session_->OnMicrophoneChanged(enable_audio_recording_);
 }
diff --git a/ash/capture_mode/capture_mode_menu_group.cc b/ash/capture_mode/capture_mode_menu_group.cc
index a0cc50c8..a2cae0e 100644
--- a/ash/capture_mode/capture_mode_menu_group.cc
+++ b/ash/capture_mode/capture_mode_menu_group.cc
@@ -5,6 +5,8 @@
 #include "ash/capture_mode/capture_mode_menu_group.h"
 
 #include <memory>
+#include <string>
+#include <utility>
 #include <vector>
 
 #include "ash/capture_mode/capture_mode_constants.h"
@@ -13,6 +15,10 @@
 #include "ash/style/ash_color_provider.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/animation/ink_drop.h"
+#include "ui/views/animation/ink_drop_highlight.h"
+#include "ui/views/controls/button/button.h"
+#include "ui/views/controls/highlight_path_generator.h"
 #include "ui/views/controls/image_view.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/layout/box_layout.h"
@@ -21,13 +27,13 @@
 
 namespace {
 
-constexpr gfx::Insets kMenuGroupPadding{8, 16};
+constexpr gfx::Insets kMenuGroupPadding{8, 0};
 
-constexpr gfx::Insets kMenuHeaderPadding{8, 0};
+constexpr gfx::Insets kMenuHeaderPadding{8, 16};
 
-constexpr gfx::Insets kOptionPadding{8, 36, 8, 0};
+constexpr gfx::Insets kOptionPadding{8, 52, 8, 16};
 
-constexpr gfx::Insets kMenuItemPadding{10, 36, 10, 0};
+constexpr gfx::Insets kMenuItemPadding{10, 52, 10, 16};
 
 constexpr int kSpaceBetweenMenuItem = 0;
 
@@ -50,6 +56,28 @@
   return box_layout;
 }
 
+void SetInkDropForButton(views::Button* button) {
+  auto* ink_drop = views::InkDrop::Get(button);
+  ink_drop->SetMode(views::InkDropHost::InkDropMode::ON);
+  button->SetHasInkDropActionOnClick(true);
+  ink_drop->SetVisibleOpacity(capture_mode::kInkDropVisibleOpacity);
+  views::InkDrop::UseInkDropForFloodFillRipple(ink_drop,
+                                               /*highlight_on_hover=*/false,
+                                               /*highlight_on_focus=*/false);
+  ink_drop->SetCreateHighlightCallback(base::BindRepeating(
+      [](views::Button* host) {
+        const AshColorProvider::RippleAttributes ripple_attributes =
+            AshColorProvider::Get()->GetRippleAttributes();
+        auto highlight = std::make_unique<views::InkDropHighlight>(
+            gfx::SizeF(host->size()), ripple_attributes.base_color);
+        highlight->set_visible_opacity(ripple_attributes.highlight_opacity);
+        return highlight;
+      },
+      button));
+  ink_drop->SetBaseColor(capture_mode::kInkDropBaseColor);
+  views::InstallRectHighlightPathGenerator(button);
+}
+
 // The header of the menu group, which has an icon and a text label. Not user
 // interactable.
 class CaptureModeMenuHeader : public views::View {
@@ -84,47 +112,6 @@
 BEGIN_METADATA(CaptureModeMenuHeader, views::View)
 END_METADATA
 
-// A button which represents an option of the menu group. It has a text label
-// and a checked icon. The checked icon will be shown on button click and any
-// other option's checked icon will be set to invisible in the meanwhile. One
-// and only one checked icon is visible in the menu group.
-class CaptureModeOption : public views::Button {
- public:
-  METADATA_HEADER(CaptureModeOption);
-
-  CaptureModeOption(views::Button::PressedCallback callback,
-                    std::u16string option_label,
-                    bool checked)
-      : views::Button(callback),
-        label_view_(AddChildView(
-            std::make_unique<views::Label>(std::move(option_label)))),
-        checked_icon_view_(AddChildView(std::make_unique<views::ImageView>())) {
-    checked_icon_view_->SetImageSize(kIconSize);
-    checked_icon_view_->SetPreferredSize(kIconSize);
-    checked_icon_view_->SetImage(gfx::CreateVectorIcon(
-        kHollowCheckCircleIcon,
-        AshColorProvider::Get()->GetContentLayerColor(
-            AshColorProvider::ContentLayerType::kButtonLabelColorBlue)));
-    checked_icon_view_->SetVisible(checked);
-
-    SetBorder(views::CreateEmptyBorder(kOptionPadding));
-    ConfigLabelView(label_view_);
-    auto* box_layout = CreateAndInitBoxLayoutForView(this);
-    box_layout->SetFlexForView(label_view_, 1);
-  }
-
-  CaptureModeOption(const CaptureModeOption&) = delete;
-  CaptureModeOption& operator=(const CaptureModeOption&) = delete;
-  ~CaptureModeOption() override = default;
-
- private:
-  views::Label* label_view_;
-  views::ImageView* checked_icon_view_;
-};
-
-BEGIN_METADATA(CaptureModeOption, views::Button)
-END_METADATA
-
 // A button which has a text label. Its behavior on click can be customized.
 // For selecting folder, a folder window will be opened on click.
 class CaptureModeMenuItem : public views::Button {
@@ -139,6 +126,7 @@
     SetBorder(views::CreateEmptyBorder(kMenuItemPadding));
     ConfigLabelView(label_view_);
     CreateAndInitBoxLayoutForView(this);
+    SetInkDropForButton(this);
   }
 
   CaptureModeMenuItem(const CaptureModeMenuItem&) = delete;
@@ -154,8 +142,63 @@
 
 }  // namespace
 
-CaptureModeMenuGroup::CaptureModeMenuGroup(const gfx::VectorIcon& header_icon,
-                                           std::u16string header_label) {
+// A button which represents an option of the menu group. It has a text label
+// and a checked icon. The checked icon will be shown on button click and any
+// other option's checked icon will be set to invisible in the meanwhile. One
+// and only one checked icon is visible in the menu group.
+class CaptureModeOption : public views::Button {
+ public:
+  METADATA_HEADER(CaptureModeOption);
+
+  CaptureModeOption(views::Button::PressedCallback callback,
+                    std::u16string option_label,
+                    int option_id,
+                    bool checked)
+      : views::Button(callback),
+        label_view_(AddChildView(
+            std::make_unique<views::Label>(std::move(option_label)))),
+        checked_icon_view_(AddChildView(std::make_unique<views::ImageView>())),
+        id_(option_id) {
+    checked_icon_view_->SetImageSize(kIconSize);
+    checked_icon_view_->SetPreferredSize(kIconSize);
+    checked_icon_view_->SetImage(gfx::CreateVectorIcon(
+        kHollowCheckCircleIcon,
+        AshColorProvider::Get()->GetContentLayerColor(
+            AshColorProvider::ContentLayerType::kButtonLabelColorBlue)));
+    checked_icon_view_->SetVisible(checked);
+
+    SetBorder(views::CreateEmptyBorder(kOptionPadding));
+    ConfigLabelView(label_view_);
+    auto* box_layout = CreateAndInitBoxLayoutForView(this);
+    box_layout->SetFlexForView(label_view_, 1);
+    SetInkDropForButton(this);
+  }
+
+  CaptureModeOption(const CaptureModeOption&) = delete;
+  CaptureModeOption& operator=(const CaptureModeOption&) = delete;
+  ~CaptureModeOption() override = default;
+
+  int id() const { return id_; }
+
+  void SetOptionChecked(bool checked) {
+    checked_icon_view_->SetVisible(checked);
+  }
+
+  bool IsOptionChecked() { return checked_icon_view_->GetVisible(); }
+
+ private:
+  views::Label* label_view_;
+  views::ImageView* checked_icon_view_;
+  const int id_;
+};
+
+BEGIN_METADATA(CaptureModeOption, views::Button)
+END_METADATA
+
+CaptureModeMenuGroup::CaptureModeMenuGroup(Delegate* delegate,
+                                           const gfx::VectorIcon& header_icon,
+                                           std::u16string header_label)
+    : delegate_(delegate) {
   AddChildView(std::make_unique<CaptureModeMenuHeader>(
       header_icon, std::move(header_label)));
   options_container_ = AddChildView(std::make_unique<views::View>());
@@ -168,11 +211,14 @@
 
 CaptureModeMenuGroup::~CaptureModeMenuGroup() = default;
 
-void CaptureModeMenuGroup::AddOption(views::Button::PressedCallback callback,
-                                     std::u16string option_label,
-                                     bool checked) {
-  options_container_->AddChildView(std::make_unique<CaptureModeOption>(
-      callback, std::move(option_label), checked));
+void CaptureModeMenuGroup::AddOption(std::u16string option_label,
+                                     int option_id) {
+  options_.push_back(
+      options_container_->AddChildView(std::make_unique<CaptureModeOption>(
+          base::BindRepeating(&CaptureModeMenuGroup::HandleOptionClick,
+                              base::Unretained(this), option_id),
+          std::move(option_label), option_id,
+          /*checked=*/delegate_->IsOptionChecked(option_id))));
 }
 
 void CaptureModeMenuGroup::AddMenuItem(views::Button::PressedCallback callback,
@@ -181,6 +227,24 @@
       std::make_unique<CaptureModeMenuItem>(callback, std::move(item_label)));
 }
 
+views::View* CaptureModeMenuGroup::GetOptionForTesting(int option_id) {
+  for (auto* option : options_) {
+    if (option->id() == option_id)
+      return option;
+  }
+  return nullptr;
+}
+
+bool CaptureModeMenuGroup::IsOptionCheckedForTesting(views::View* option) {
+  return static_cast<CaptureModeOption*>(option)->IsOptionChecked();
+}
+
+void CaptureModeMenuGroup::HandleOptionClick(int option_id) {
+  for (auto* option : options_)
+    option->SetOptionChecked(option_id == option->id());
+  delegate_->OnOptionSelected(option_id);
+}
+
 BEGIN_METADATA(CaptureModeMenuGroup, views::View)
 END_METADATA
 }  // namespace ash
diff --git a/ash/capture_mode/capture_mode_menu_group.h b/ash/capture_mode/capture_mode_menu_group.h
index 0f27f4b..6c47388 100644
--- a/ash/capture_mode/capture_mode_menu_group.h
+++ b/ash/capture_mode/capture_mode_menu_group.h
@@ -5,6 +5,8 @@
 #ifndef ASH_CAPTURE_MODE_CAPTURE_MODE_MENU_GROUP_H_
 #define ASH_CAPTURE_MODE_CAPTURE_MODE_MENU_GROUP_H_
 
+#include <vector>
+
 #include "ash/ash_export.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/controls/button/button.h"
@@ -15,6 +17,8 @@
 
 namespace ash {
 
+class CaptureModeOption;
+
 // Defines a view that groups together related capture mode settings in an
 // independent section in the settings menu. Each group has a header icon and a
 // header label.
@@ -22,7 +26,20 @@
  public:
   METADATA_HEADER(CaptureModeMenuGroup);
 
-  CaptureModeMenuGroup(const gfx::VectorIcon& header_icon,
+  class Delegate {
+   public:
+    // Called when user selects an option.
+    virtual void OnOptionSelected(int option_id) const = 0;
+
+    // Called to determine if an option with the given |option_id| is selected.
+    virtual bool IsOptionChecked(int option_id) const = 0;
+
+   protected:
+    virtual ~Delegate() = default;
+  };
+
+  CaptureModeMenuGroup(Delegate* delegate,
+                       const gfx::VectorIcon& header_icon,
                        std::u16string header_label);
   CaptureModeMenuGroup(const CaptureModeMenuGroup&) = delete;
   CaptureModeMenuGroup& operator=(const CaptureModeMenuGroup&) = delete;
@@ -32,9 +49,7 @@
   // group. When the option is selected, its checked icon is visible. Otherwise
   // its checked icon is invisible. One and only one option's checked icon is
   // visible all the time.
-  void AddOption(views::Button::PressedCallback callback,
-                 std::u16string option_label,
-                 bool checked);
+  void AddOption(std::u16string option_label, int option_id);
 
   // Adds a menu item which has text to the menu group. Each menu item can have
   // its own customized behavior. For example, file save menu group's menu item
@@ -43,11 +58,27 @@
   void AddMenuItem(views::Button::PressedCallback callback,
                    std::u16string item_label);
 
+  // For tests only:
+  views::View* GetOptionForTesting(int option_id);
+  bool IsOptionCheckedForTesting(views::View* option);
+
  private:
-  // It's a container view for the option added via calls "AddOption()" and
-  // owned by its views hierarchy. We need it for grouping up options. For
-  // example, when user selects a custom folder, we need to add it to the end of
-  // the options instead of adding it after the menu item.
+  // This is the callback function on option click. It will select the
+  // clicked/pressed button, and unselect any previously selected button.
+  void HandleOptionClick(int option_id);
+
+  // CaptureModeAdvancedSettingsView is the |delegate_| here. It's owned by
+  // its views hierarchy.
+  const Delegate* const delegate_;
+
+  // Options added via calls "AddOption()". Options are owned by theirs views
+  // hierarchy.
+  std::vector<CaptureModeOption*> options_;
+
+  // It's a container view for |options_|. It's owned by its views hierarchy.
+  // We need it for grouping up options. For example, when user selects a custom
+  // folder, we need to add it to the end of the options instead of adding it
+  // after the menu item.
   views::View* options_container_;
 };
 
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc
index a27a71c..e7aa8500 100644
--- a/ash/capture_mode/capture_mode_unittests.cc
+++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -8,10 +8,12 @@
 #include "ash/accessibility/magnifier/docked_magnifier_controller.h"
 #include "ash/accessibility/magnifier/magnifier_glass.h"
 #include "ash/app_list/app_list_controller_impl.h"
+#include "ash/capture_mode/capture_mode_advanced_settings_view.h"
 #include "ash/capture_mode/capture_mode_bar_view.h"
 #include "ash/capture_mode/capture_mode_button.h"
 #include "ash/capture_mode/capture_mode_constants.h"
 #include "ash/capture_mode/capture_mode_controller.h"
+#include "ash/capture_mode/capture_mode_menu_group.h"
 #include "ash/capture_mode/capture_mode_metrics.h"
 #include "ash/capture_mode/capture_mode_session.h"
 #include "ash/capture_mode/capture_mode_settings_entry_view.h"
@@ -245,6 +247,11 @@
     return session_->capture_mode_settings_view_;
   }
 
+  CaptureModeAdvancedSettingsView* capture_mode_advanced_settings_view() const {
+    EXPECT_TRUE(features::AreImprovedScreenCaptureSettingsEnabled());
+    return session_->capture_mode_advanced_settings_view_;
+  }
+
   views::Widget* capture_mode_settings_widget() const {
     return session_->capture_mode_settings_widget_.get();
   }
@@ -4616,4 +4623,67 @@
                          testing::Values(CaptureModeSource::kFullscreen,
                                          CaptureModeSource::kRegion,
                                          CaptureModeSource::kWindow));
+
+// -----------------------------------------------------------------------------
+// CaptureModeAdvancedSettingsTest:
+
+// Test fixture for CaptureMode advanced settings view.
+class CaptureModeAdvancedSettingsTest : public CaptureModeTest {
+ public:
+  CaptureModeAdvancedSettingsTest() = default;
+  ~CaptureModeAdvancedSettingsTest() override = default;
+
+  // CaptureModeTest:
+  void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kImprovedScreenCaptureSettings);
+    CaptureModeTest::SetUp();
+  }
+
+  CaptureModeAdvancedSettingsView* GetCaptureModeAdvancedSettingsView() const {
+    auto* session = CaptureModeController::Get()->capture_mode_session();
+    DCHECK(session);
+    return CaptureModeSessionTestApi(session)
+        .capture_mode_advanced_settings_view();
+  }
+
+ protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+// Tests that clicking on audio input buttons updates the state in the
+// controller, and persists between sessions.
+TEST_F(CaptureModeAdvancedSettingsTest, AudioInputSettingsMenu) {
+  auto* controller = StartImageRegionCapture();
+  auto* event_generator = GetEventGenerator();
+
+  // Test that the audio recording preference is defaulted to off.
+  ClickOnView(GetSettingsButton(), event_generator);
+  EXPECT_FALSE(controller->enable_audio_recording());
+
+  CaptureModeAdvancedSettingsView* settings_view =
+      GetCaptureModeAdvancedSettingsView();
+  CaptureModeMenuGroup* audio_input_menu_group =
+      settings_view->GetAudioInputMenuGroupForTesting();
+  views::View* microphone_option =
+      settings_view->GetMicrophoneOptionForTesting();
+  views::View* off_option = settings_view->GetOffOptionForTesting();
+  EXPECT_TRUE(audio_input_menu_group->IsOptionCheckedForTesting(off_option));
+  EXPECT_FALSE(
+      audio_input_menu_group->IsOptionCheckedForTesting(microphone_option));
+
+  // Click on the |microphone| option. It should be checked after click along
+  // with |off| is unchecked. Recording preference is set to microphone.
+  ClickOnView(microphone_option, event_generator);
+  EXPECT_TRUE(
+      audio_input_menu_group->IsOptionCheckedForTesting(microphone_option));
+  EXPECT_FALSE(audio_input_menu_group->IsOptionCheckedForTesting(off_option));
+  EXPECT_TRUE(controller->enable_audio_recording());
+
+  // Test that the user selected audio preference for audio recording is
+  // remembered between sessions.
+  SendKey(ui::VKEY_ESCAPE, event_generator);
+  StartImageRegionCapture();
+  EXPECT_TRUE(controller->enable_audio_recording());
+}
 }  // namespace ash
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 1b0ee51b..d06066bf 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -535,6 +535,10 @@
 const base::Feature kFiltersInRecents{"FiltersInRecents",
                                       base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables the firmware updater app.
+const base::Feature kFirmwareUpdaterApp = {"FirmwareUpdaterApp",
+                                           base::FEATURE_DISABLED_BY_DEFAULT};
+
 // When enabled, there will be an alert bubble showing up when the device
 // returns from low brightness (e.g., sleep, closed cover) without a lock screen
 // and the active window is in fullscreen.
@@ -1373,6 +1377,10 @@
   return base::FeatureList::IsEnabled(kFilesSWA);
 }
 
+bool IsFirmwareUpdaterAppEnabled() {
+  return base::FeatureList::IsEnabled(kFirmwareUpdaterApp);
+}
+
 bool IsFullscreenAlertBubbleEnabled() {
   return base::FeatureList::IsEnabled(kFullscreenAlertBubble);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 1a82b71d..e23066f 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -207,6 +207,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesTrash;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFilesZipUnpack;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFiltersInRecents;
+COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFirmwareUpdaterApp;
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::Feature kFullscreenAlertBubble;
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::Feature kFuseBox;
@@ -493,6 +494,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFamilyLinkOnSchoolDeviceEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFastPairEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFileManagerSwaEnabled();
+COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFirmwareUpdaterAppEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsFullscreenAlertBubbleEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGaiaCloseViewMessageEnabled();
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGaiaReauthEndpointEnabled();
diff --git a/ash/projector/projector_controller_impl.cc b/ash/projector/projector_controller_impl.cc
index 96d000bd..9bb65f78 100644
--- a/ash/projector/projector_controller_impl.cc
+++ b/ash/projector/projector_controller_impl.cc
@@ -107,6 +107,9 @@
 }
 
 void ProjectorControllerImpl::OnSpeechRecognitionAvailable(bool available) {
+  if (ProjectorController::AreExtendedProjectorFeaturesDisabled())
+    return;
+
   if (available == is_speech_recognition_available_)
     return;
 
@@ -132,7 +135,8 @@
 }
 
 bool ProjectorControllerImpl::IsEligible() const {
-  return is_speech_recognition_available_;
+  return is_speech_recognition_available_ ||
+         ProjectorController::AreExtendedProjectorFeaturesDisabled();
 }
 
 bool ProjectorControllerImpl::CanStartNewSession() const {
@@ -232,6 +236,9 @@
 }
 
 void ProjectorControllerImpl::StartSpeechRecognition() {
+  if (ProjectorController::AreExtendedProjectorFeaturesDisabled())
+    return;
+
   DCHECK(is_speech_recognition_available_);
   DCHECK(!is_speech_recognition_on_);
   DCHECK_NE(client_, nullptr);
@@ -240,6 +247,9 @@
 }
 
 void ProjectorControllerImpl::StopSpeechRecognition() {
+  if (ProjectorController::AreExtendedProjectorFeaturesDisabled())
+    return;
+
   DCHECK(is_speech_recognition_available_);
   DCHECK(is_speech_recognition_on_);
   DCHECK_NE(client_, nullptr);
diff --git a/ash/public/cpp/projector/projector_controller.cc b/ash/public/cpp/projector/projector_controller.cc
index e8eead1..f1fcabf05 100644
--- a/ash/public/cpp/projector/projector_controller.cc
+++ b/ash/public/cpp/projector/projector_controller.cc
@@ -5,12 +5,19 @@
 #include "ash/public/cpp/projector/projector_controller.h"
 
 #include "base/check_op.h"
+#include "base/command_line.h"
 
 namespace ash {
 
 namespace {
 ProjectorController* g_instance = nullptr;
-}
+
+// Controls whether to enable the extended features of Projector. These include
+// speech recognition and drivefs integration. Only used during development to
+// disable extended features in X11 simulator.
+constexpr char kExtendedProjectorFeaturesDisabled[] =
+    "projector-extended-features-disabled";
+}  // namespace
 
 ProjectorController::ProjectorController() {
   DCHECK_EQ(nullptr, g_instance);
@@ -27,6 +34,12 @@
   return g_instance;
 }
 
+// static
+bool ProjectorController::AreExtendedProjectorFeaturesDisabled() {
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  return command_line->HasSwitch(kExtendedProjectorFeaturesDisabled);
+}
+
 ProjectorController::ScopedInstanceResetterForTest::
     ScopedInstanceResetterForTest()
     : controller_(g_instance) {
diff --git a/ash/public/cpp/projector/projector_controller.h b/ash/public/cpp/projector/projector_controller.h
index 808fd0db..2cd526a 100644
--- a/ash/public/cpp/projector/projector_controller.h
+++ b/ash/public/cpp/projector/projector_controller.h
@@ -36,6 +36,10 @@
 
   static ProjectorController* Get();
 
+  // Returns whether the extended features for projector are enabled. This is
+  // decided based on a command line switch.
+  static bool AreExtendedProjectorFeaturesDisabled();
+
   // Starts a capture mode session for the projector workflow if no video
   // recording is currently in progress. `storage_dir` is the container
   // directory name for screencasts and will be used to create the storage path.
diff --git a/ash/shelf/shelf_app_button.cc b/ash/shelf/shelf_app_button.cc
index 0affda1..614d890 100644
--- a/ash/shelf/shelf_app_button.cc
+++ b/ash/shelf/shelf_app_button.cc
@@ -25,7 +25,6 @@
 #include "ui/accessibility/ax_action_data.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/resource/resource_bundle.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/gfx/animation/animation_delegate.h"
@@ -280,9 +279,7 @@
       shelf_view_(shelf_view),
       indicator_(new AppStatusIndicatorView()),
       notification_indicator_(nullptr),
-      state_(STATE_NORMAL),
-      is_notification_indicator_enabled_(
-          features::IsNotificationIndicatorEnabled()) {
+      state_(STATE_NORMAL) {
   const gfx::ShadowValue kShadows[] = {
       gfx::ShadowValue(gfx::Vector2d(0, 2), 0, SkColorSetARGB(0x1A, 0, 0, 0)),
       gfx::ShadowValue(gfx::Vector2d(0, 3), 1, SkColorSetARGB(0x1A, 0, 0, 0)),
@@ -326,10 +323,9 @@
 
   AddChildView(indicator_);
   AddChildView(icon_view_);
-  if (is_notification_indicator_enabled_) {
-    notification_indicator_ = views::DotIndicator::Install(this);
-    SetNotificationBadgeColor(kDefaultIndicatorColor);
-  }
+  notification_indicator_ = views::DotIndicator::Install(this);
+  SetNotificationBadgeColor(kDefaultIndicatorColor);
+
   views::InkDrop::Get(this)->GetInkDrop()->AddObserver(this);
 
   // Do not set a clip, allow the ink drop to burst out.
@@ -400,7 +396,7 @@
     if (state & STATE_ACTIVE)
       indicator_->ShowActiveStatus(true);
 
-    if (is_notification_indicator_enabled_ && (state & STATE_NOTIFICATION))
+    if (state & STATE_NOTIFICATION)
       notification_indicator_->Show();
 
     if (state & STATE_DRAGGING)
@@ -417,7 +413,7 @@
     if (state & STATE_ACTIVE)
       indicator_->ShowActiveStatus(false);
 
-    if (is_notification_indicator_enabled_ && (state & STATE_NOTIFICATION))
+    if (state & STATE_NOTIFICATION)
       notification_indicator_->Hide();
 
     if (state & STATE_DRAGGING)
@@ -506,12 +502,10 @@
 }
 
 void ShelfAppButton::ReflectItemStatus(const ShelfItem& item) {
-  if (features::IsNotificationIndicatorEnabled()) {
-    if (item.has_notification)
-      AddState(ShelfAppButton::STATE_NOTIFICATION);
-    else
-      ClearState(ShelfAppButton::STATE_NOTIFICATION);
-  }
+  if (item.has_notification)
+    AddState(ShelfAppButton::STATE_NOTIFICATION);
+  else
+    ClearState(ShelfAppButton::STATE_NOTIFICATION);
 
   app_status_ = item.app_status;
 
@@ -705,10 +699,8 @@
 
   icon_view_->SetBoundsRect(icon_view_bounds);
 
-  if (is_notification_indicator_enabled_) {
-    notification_indicator_->SetBoundsRect(
-        GetNotificationIndicatorBounds(icon_scale_));
-  }
+  notification_indicator_->SetBoundsRect(
+      GetNotificationIndicatorBounds(icon_scale_));
 
   // The indicators should be aligned with the icon, not the icon + shadow.
   // Use 1.0 as icon scale for |indicator_midpoint|, otherwise integer rounding
diff --git a/ash/shelf/shelf_app_button.h b/ash/shelf/shelf_app_button.h
index 3425a7a..577bdb97 100644
--- a/ash/shelf/shelf_app_button.h
+++ b/ash/shelf/shelf_app_button.h
@@ -200,9 +200,6 @@
 
   gfx::ShadowValues icon_shadows_;
 
-  // Whether the notification indicator is enabled.
-  const bool is_notification_indicator_enabled_;
-
   // The bitmap image for this app button.
   gfx::ImageSkia icon_image_;
 
diff --git a/ash/shelf/shelf_controller.cc b/ash/shelf/shelf_controller.cc
index d238dda..631d10b 100644
--- a/ash/shelf/shelf_controller.cc
+++ b/ash/shelf/shelf_controller.cc
@@ -23,7 +23,6 @@
 #include "components/prefs/pref_service.h"
 #include "components/services/app_service/public/cpp/app_registry_cache_wrapper.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
 
@@ -99,9 +98,7 @@
 
 }  // namespace
 
-ShelfController::ShelfController()
-    : is_notification_indicator_enabled_(
-          features::IsNotificationIndicatorEnabled()) {
+ShelfController::ShelfController() {
   ShelfModel::SetInstance(&model_);
 
   Shell::Get()->session_controller()->AddObserver(this);
@@ -150,30 +147,27 @@
   pref_change_registrar_->Add(prefs::kShelfPreferences,
                               base::BindRepeating(&SetShelfBehaviorsFromPrefs));
 
-  if (is_notification_indicator_enabled_) {
-    pref_change_registrar_->Add(
-        prefs::kAppNotificationBadgingEnabled,
-        base::BindRepeating(&ShelfController::UpdateAppNotificationBadging,
-                            base::Unretained(this)));
+  pref_change_registrar_->Add(
+      prefs::kAppNotificationBadgingEnabled,
+      base::BindRepeating(&ShelfController::UpdateAppNotificationBadging,
+                          base::Unretained(this)));
 
-    // Observe AppRegistryCache for the current active account to get
-    // notification updates.
-    AccountId account_id =
-        Shell::Get()->session_controller()->GetActiveAccountId();
-    cache_ =
-        apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id);
-    Observe(cache_);
+  // Observe AppRegistryCache for the current active account to get
+  // notification updates.
+  AccountId account_id =
+      Shell::Get()->session_controller()->GetActiveAccountId();
+  cache_ = apps::AppRegistryCacheWrapper::Get().GetAppRegistryCache(account_id);
+  Observe(cache_);
 
-    // Resetting the recorded pref forces the next call to
-    // UpdateAppNotificationBadging() to update notification badging for every
-    // app item.
-    notification_badging_pref_enabled_.reset();
+  // Resetting the recorded pref forces the next call to
+  // UpdateAppNotificationBadging() to update notification badging for every
+  // app item.
+  notification_badging_pref_enabled_.reset();
 
-    // Update the notification badge indicator for all apps. This will also
-    // ensure that apps have the correct notification badge value for the
-    // multiprofile case when switching between users.
-    UpdateAppNotificationBadging();
-  }
+  // Update the notification badge indicator for all apps. This will also
+  // ensure that apps have the correct notification badge value for the
+  // multiprofile case when switching between users.
+  UpdateAppNotificationBadging();
 }
 
 void ShelfController::OnTabletModeStarted() {
@@ -235,8 +229,7 @@
 }
 
 void ShelfController::ShelfItemAdded(int index) {
-  if (!cache_ || !is_notification_indicator_enabled_ ||
-      !notification_badging_pref_enabled_.value_or(false))
+  if (!cache_ || !notification_badging_pref_enabled_.value_or(false))
     return;
 
   auto app_id = model_.items()[index].id.app_id;
diff --git a/ash/shelf/shelf_controller.h b/ash/shelf/shelf_controller.h
index b260ad33..0f67c53 100644
--- a/ash/shelf/shelf_controller.h
+++ b/ash/shelf/shelf_controller.h
@@ -70,9 +70,6 @@
   // The shelf model shared by all shelf instances.
   ShelfModel model_;
 
-  // Whether notification indicators are enabled for app icons in the shelf.
-  const bool is_notification_indicator_enabled_;
-
   // Whether the pref for notification badging is enabled.
   absl::optional<bool> notification_badging_pref_enabled_;
 
diff --git a/ash/shelf/shelf_controller_unittest.cc b/ash/shelf/shelf_controller_unittest.cc
index b55c80d..070c94ec 100644
--- a/ash/shelf/shelf_controller_unittest.cc
+++ b/ash/shelf/shelf_controller_unittest.cc
@@ -24,10 +24,8 @@
 #include "ash/wm/window_util.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "components/prefs/pref_service.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/gfx/image/image_unittest_util.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/public/cpp/notifier_id.h"
@@ -82,8 +80,6 @@
   ~ShelfControllerNotificationIndicatorTest() override = default;
 
   void SetUp() override {
-    scoped_feature_list_.InitWithFeatures({features::kNotificationIndicator},
-                                          {});
     AshTestBase::SetUp();
 
     account_id_ = AccountId::FromUserEmail("test@gmail.com");
@@ -106,7 +102,6 @@
 
  private:
   AccountId account_id_;
-  base::test::ScopedFeatureList scoped_feature_list_;
 };
 
 // Tests that the ShelfController keeps the ShelfModel updated on calls to
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc
index 77d4d298..1bfcb867 100644
--- a/ash/shelf/shelf_view_unittest.cc
+++ b/ash/shelf/shelf_view_unittest.cc
@@ -69,7 +69,6 @@
 #include "ui/aura/window_event_dispatcher.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/test/ui_controls.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/display/display.h"
@@ -2311,27 +2310,9 @@
           .x());
 }
 
-// Test class that enables notification indicators.
-class NotificationIndicatorTest : public ShelfViewTest {
- public:
-  NotificationIndicatorTest() {
-    scoped_feature_list_.InitAndEnableFeature(
-        ::features::kNotificationIndicator);
-  }
-
-  NotificationIndicatorTest(const NotificationIndicatorTest&) = delete;
-  NotificationIndicatorTest& operator=(const NotificationIndicatorTest&) =
-      delete;
-
-  ~NotificationIndicatorTest() override = default;
-
- private:
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
 // Tests that an item has a notification badge indicator when the notification
 // is added and removed.
-TEST_F(NotificationIndicatorTest, ItemHasCorrectNotificationBadgeIndicator) {
+TEST_F(ShelfViewTest, ItemHasCorrectNotificationBadgeIndicator) {
   const ShelfID item_id = AddApp();
   const ShelfAppButton* shelf_app_button = GetButtonByID(item_id);
 
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_controller.cc b/ash/system/bluetooth/bluetooth_detailed_view_controller.cc
index 9782dd99..c86f4f9 100644
--- a/ash/system/bluetooth/bluetooth_detailed_view_controller.cc
+++ b/ash/system/bluetooth/bluetooth_detailed_view_controller.cc
@@ -12,6 +12,7 @@
 #include "ash/system/model/system_tray_model.h"
 #include "base/check.h"
 #include "chromeos/services/bluetooth_config/public/cpp/cros_bluetooth_config_util.h"
+#include "mojo/public/cpp/bindings/clone_traits.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/views/view.h"
@@ -19,6 +20,7 @@
 namespace ash {
 namespace {
 using chromeos::bluetooth_config::IsBluetoothEnabledOrEnabling;
+using chromeos::bluetooth_config::mojom::DeviceConnectionState;
 }  // namespace
 
 BluetoothDetailedViewController::BluetoothDetailedViewController(
@@ -45,6 +47,11 @@
       bluetooth_detailed_view.get());
   BluetoothEnabledStateChanged();
 
+  if (IsBluetoothEnabledOrEnabling(system_state_)) {
+    device_list_controller_->UpdateDeviceList(connected_devices_,
+                                              previously_connected_devices_);
+  }
+
   // We are expected to return an unowned pointer that the caller is responsible
   // for deleting.
   return bluetooth_detailed_view.release()->GetAsView();
@@ -64,6 +71,22 @@
 
   if (has_bluetooth_enabled_state_changed)
     BluetoothEnabledStateChanged();
+
+  connected_devices_.clear();
+  previously_connected_devices_.clear();
+
+  for (auto& paired_device : properties->paired_devices) {
+    if (paired_device->device_properties->connection_state ==
+        DeviceConnectionState::kConnected) {
+      connected_devices_.push_back(std::move(paired_device));
+    } else {
+      previously_connected_devices_.push_back(std::move(paired_device));
+    }
+  }
+  if (device_list_controller_ && IsBluetoothEnabledOrEnabling(system_state_)) {
+    device_list_controller_->UpdateDeviceList(connected_devices_,
+                                              previously_connected_devices_);
+  }
 }
 
 void BluetoothDetailedViewController::OnToggleClicked(bool new_state) {
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_controller.h b/ash/system/bluetooth/bluetooth_detailed_view_controller.h
index 412d961d..b4ee723 100644
--- a/ash/system/bluetooth/bluetooth_detailed_view_controller.h
+++ b/ash/system/bluetooth/bluetooth_detailed_view_controller.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "ash/ash_export.h"
 #include "ash/system/bluetooth/bluetooth_detailed_view.h"
@@ -41,6 +42,10 @@
       const BluetoothDetailedViewController&) = delete;
   ~BluetoothDetailedViewController() override;
 
+ protected:
+  using PairedBluetoothDevicePropertiesPtrs = std::vector<
+      chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr>;
+
  private:
   // DetailedViewControllerBase:
   views::View* CreateView() override;
@@ -73,6 +78,8 @@
       chromeos::bluetooth_config::mojom::BluetoothSystemState::kUnavailable;
   tray::BluetoothDetailedView* view_ = nullptr;
   std::unique_ptr<BluetoothDeviceListController> device_list_controller_;
+  PairedBluetoothDevicePropertiesPtrs connected_devices_;
+  PairedBluetoothDevicePropertiesPtrs previously_connected_devices_;
 };
 
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_controller_unittest.cc b/ash/system/bluetooth/bluetooth_detailed_view_controller_unittest.cc
index 5fa4c51..dc06172c 100644
--- a/ash/system/bluetooth/bluetooth_detailed_view_controller_unittest.cc
+++ b/ash/system/bluetooth/bluetooth_detailed_view_controller_unittest.cc
@@ -5,6 +5,7 @@
 #include "ash/system/bluetooth/bluetooth_detailed_view_controller.h"
 
 #include <memory>
+#include <vector>
 
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/test/test_system_tray_client.h"
@@ -17,15 +18,21 @@
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
 #include "chromeos/services/bluetooth_config/fake_adapter_state_controller.h"
+#include "chromeos/services/bluetooth_config/fake_device_cache.h"
 #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
 #include "chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.h"
+#include "mojo/public/cpp/bindings/clone_traits.h"
 
 namespace ash {
 namespace tray {
 namespace {
 
 using chromeos::bluetooth_config::AdapterStateController;
+using chromeos::bluetooth_config::mojom::BluetoothDeviceProperties;
 using chromeos::bluetooth_config::mojom::BluetoothSystemState;
+using chromeos::bluetooth_config::mojom::DeviceConnectionState;
+using chromeos::bluetooth_config::mojom::PairedBluetoothDeviceProperties;
+using chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr;
 
 class FakeBluetoothDetailedViewFactory : public BluetoothDetailedView::Factory {
  public:
@@ -121,6 +128,22 @@
         ->GetAdapterState();
   }
 
+  PairedBluetoothDevicePropertiesPtr CreatePairedDevice(
+      DeviceConnectionState connection_state) {
+    PairedBluetoothDevicePropertiesPtr paired_properties =
+        PairedBluetoothDeviceProperties::New();
+    paired_properties->device_properties = BluetoothDeviceProperties::New();
+    paired_properties->device_properties->connection_state = connection_state;
+    return paired_properties;
+  }
+
+  void SetPairedDevices(
+      std::vector<PairedBluetoothDevicePropertiesPtr> paired_devices) {
+    scoped_bluetooth_config_test_helper_.fake_device_cache()->SetPairedDevices(
+        std::move(paired_devices));
+    base::RunLoop().RunUntilIdle();
+  }
+
   void SetBluetoothAdapterState(BluetoothSystemState system_state) {
     scoped_bluetooth_config_test_helper_.fake_adapter_state_controller()
         ->SetSystemState(system_state);
@@ -200,5 +223,28 @@
   EXPECT_EQ(1, GetSystemTrayClient()->show_bluetooth_pairing_dialog_count());
 }
 
+TEST_F(BluetoothDetailedViewControllerTest,
+       CorrectlySplitsDevicesByConnectionState) {
+  std::vector<PairedBluetoothDevicePropertiesPtr> paired_devices;
+  paired_devices.push_back(
+      CreatePairedDevice(DeviceConnectionState::kNotConnected));
+  paired_devices.push_back(
+      CreatePairedDevice(DeviceConnectionState::kConnecting));
+  paired_devices.push_back(
+      CreatePairedDevice(DeviceConnectionState::kConnected));
+
+  EXPECT_EQ(0u, bluetooth_device_list_controller()->connected_devices_count());
+  EXPECT_EQ(
+      0u,
+      bluetooth_device_list_controller()->previously_connected_devices_count());
+
+  SetPairedDevices(std::move(paired_devices));
+
+  EXPECT_EQ(1u, bluetooth_device_list_controller()->connected_devices_count());
+  EXPECT_EQ(
+      2u,
+      bluetooth_device_list_controller()->previously_connected_devices_count());
+}
+
 }  // namespace tray
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_impl.cc b/ash/system/bluetooth/bluetooth_detailed_view_impl.cc
index 9a4f6c1..5529751 100644
--- a/ash/system/bluetooth/bluetooth_detailed_view_impl.cc
+++ b/ash/system/bluetooth/bluetooth_detailed_view_impl.cc
@@ -97,6 +97,11 @@
   return scroll_content();
 }
 
+void BluetoothDetailedViewImpl::HandleViewClicked(views::View* view) {
+  delegate()->OnDeviceListItemSelected(
+      static_cast<BluetoothDeviceListItemView*>(view)->device_properties());
+}
+
 const char* BluetoothDetailedViewImpl::GetClassName() const {
   return "BluetoothDetailedViewImpl";
 }
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_impl.h b/ash/system/bluetooth/bluetooth_detailed_view_impl.h
index ebd4e1bb..b12f8b7 100644
--- a/ash/system/bluetooth/bluetooth_detailed_view_impl.h
+++ b/ash/system/bluetooth/bluetooth_detailed_view_impl.h
@@ -58,6 +58,9 @@
   void NotifyDeviceListChanged() override;
   views::View* device_list() override;
 
+  // TrayDetailedView:
+  void HandleViewClicked(views::View* view) override;
+
   // views::View:
   const char* GetClassName() const override;
 
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_unittest.cc b/ash/system/bluetooth/bluetooth_detailed_view_unittest.cc
index 6271baf50..40f3640 100644
--- a/ash/system/bluetooth/bluetooth_detailed_view_unittest.cc
+++ b/ash/system/bluetooth/bluetooth_detailed_view_unittest.cc
@@ -10,6 +10,7 @@
 #include "ash/public/cpp/test/test_system_tray_client.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/bluetooth/bluetooth_detailed_view_impl.h"
+#include "ash/system/bluetooth/bluetooth_device_list_item_view.h"
 #include "ash/system/bluetooth/bluetooth_disabled_detailed_view.h"
 #include "ash/system/tray/detailed_view_delegate.h"
 #include "ash/system/unified/top_shortcut_button.h"
@@ -35,6 +36,9 @@
 namespace tray {
 namespace {
 
+const std::string kDeviceNickname = "mau5";
+
+using chromeos::bluetooth_config::mojom::PairedBluetoothDeviceProperties;
 using chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr;
 
 class FakeBluetoothDetailedViewDelegate
@@ -294,5 +298,28 @@
   EXPECT_EQ(view_center, button_center.y());
 }
 
+TEST_F(BluetoothDetailedViewTest, SelectingDeviceListItemNotifiesDelegate) {
+  bluetooth_detailed_view()->UpdateBluetoothEnabledState(true);
+
+  PairedBluetoothDevicePropertiesPtr paired_properties =
+      PairedBluetoothDeviceProperties::New();
+  paired_properties->nickname = kDeviceNickname;
+
+  BluetoothDeviceListItemView* device_list_item =
+      bluetooth_detailed_view()->AddDeviceListItem();
+  device_list_item->UpdateDeviceProperties(paired_properties);
+
+  bluetooth_detailed_view()->NotifyDeviceListChanged();
+
+  EXPECT_FALSE(
+      bluetooth_detailed_view_delegate()->last_device_list_item_selected());
+  ClickOnAndWait(device_list_item);
+  EXPECT_TRUE(
+      bluetooth_detailed_view_delegate()->last_device_list_item_selected());
+  EXPECT_EQ(kDeviceNickname, bluetooth_detailed_view_delegate()
+                                 ->last_device_list_item_selected()
+                                 ->nickname);
+}
+
 }  // namespace tray
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_device_list_controller_impl.cc b/ash/system/bluetooth/bluetooth_device_list_controller_impl.cc
index 695fef46..c332887 100644
--- a/ash/system/bluetooth/bluetooth_device_list_controller_impl.cc
+++ b/ash/system/bluetooth/bluetooth_device_list_controller_impl.cc
@@ -7,12 +7,32 @@
 #include "ash/constants/ash_features.h"
 #include "ash/strings/grit/ash_strings.h"
 #include "ash/system/bluetooth/bluetooth_detailed_view.h"
+#include "ash/system/bluetooth/bluetooth_device_list_item_view.h"
+#include "ash/system/tray/tray_popup_utils.h"
 #include "ash/system/tray/tri_view.h"
 #include "base/check.h"
 #include "ui/gfx/paint_vector_icon.h"
+#include "ui/views/controls/separator.h"
 #include "ui/views/view.h"
 
 namespace ash {
+namespace {
+
+// Helper function to remove |*view| from its view hierarchy, delete the view,
+// and reset the value of |*view| to be |nullptr|.
+template <class T>
+void RemoveAndResetViewIfExists(T** view) {
+  DCHECK(view);
+
+  views::View* parent = (*view)->parent();
+
+  if (*view && parent) {
+    parent->RemoveChildViewT(*view);
+    *view = nullptr;
+  }
+}
+
+}  // namespace
 
 BluetoothDeviceListControllerImpl::BluetoothDeviceListControllerImpl(
     tray::BluetoothDetailedView* bluetooth_detailed_view)
@@ -20,10 +40,19 @@
   DCHECK(ash::features::IsBluetoothRevampEnabled());
 }
 
+BluetoothDeviceListControllerImpl::~BluetoothDeviceListControllerImpl() =
+    default;
+
 void BluetoothDeviceListControllerImpl::UpdateBluetoothEnabledState(
     bool enabled) {
-  if (is_bluetooth_enabled_ && !enabled)
+  if (is_bluetooth_enabled_ && !enabled) {
+    device_id_to_view_map_.clear();
+    device_list_separator_ = nullptr;
+    connected_sub_header_ = nullptr;
+    no_device_connected_sub_header_ = nullptr;
+    previously_connected_sub_header_ = nullptr;
     bluetooth_detailed_view_->device_list()->RemoveAllChildViews();
+  }
   is_bluetooth_enabled_ = enabled;
 }
 
@@ -31,16 +60,89 @@
     const PairedBluetoothDevicePropertiesPtrs& connected,
     const PairedBluetoothDevicePropertiesPtrs& previously_connected) {
   DCHECK(is_bluetooth_enabled_);
-  currently_connected_devices_sub_header_ = AddOrReorderSubHeader(
-      currently_connected_devices_sub_header_,
-      IDS_ASH_STATUS_TRAY_BLUETOOTH_CURRENTLY_CONNECTED_DEVICES, 1);
-  previously_connected_devices_sub_header_ = AddOrReorderSubHeader(
-      previously_connected_devices_sub_header_,
-      IDS_ASH_STATUS_TRAY_BLUETOOTH_PREVIOUSLY_CONNECTED_DEVICES, 2);
+
+  // This function will create views for new devices, re-use views for existing
+  // devices, and remove views for devices that no longer exist. To do this, we
+  // keep track of all the preexisting views in |previous_views|, removing a
+  // view from this map when the corresponding device is found in |connected| or
+  // |previously_connected|. Before returning, any view remaining in
+  // |previous_views| is no longer needed and is deleted.
+  base::flat_map<std::string, BluetoothDeviceListItemView*> previous_views =
+      std::move(device_id_to_view_map_);
+  device_id_to_view_map_.clear();
+
+  // Since we re-use views when possible, we need to re-order them to match the
+  // order of the devices we are provided with. We use |index| to keep track of
+  // the next index within the device list where a view should be placed, i.e.
+  // all views before |index| are in their final position.
+  int index = 0;
+
+  // The list of connected devices.
+  if (!connected.empty()) {
+    connected_sub_header_ = CreateSubHeaderIfMissingAndReorder(
+        connected_sub_header_,
+        IDS_ASH_STATUS_TRAY_BLUETOOTH_CURRENTLY_CONNECTED_DEVICES, index);
+
+    // Increment |index| since this position was taken by
+    // |connected_sub_header_|.
+    index++;
+
+    index = CreateViewsIfMissingAndReorder(connected, &previous_views, index);
+  } else {
+    RemoveAndResetViewIfExists(&connected_sub_header_);
+  }
+
+  // The separator between the connected and previously connected devices.
+  if (!connected.empty() && !previously_connected.empty()) {
+    if (!device_list_separator_) {
+      device_list_separator_ =
+          bluetooth_detailed_view_->device_list()->AddChildView(
+              TrayPopupUtils::CreateListSubHeaderSeparator());
+    }
+    bluetooth_detailed_view_->device_list()->ReorderChildView(
+        device_list_separator_, index);
+
+    // Increment |index| since this position was taken by
+    // |device_list_separator_|.
+    index++;
+  } else {
+    RemoveAndResetViewIfExists(&device_list_separator_);
+  }
+
+  // The previously connected devices.
+  if (!previously_connected.empty()) {
+    previously_connected_sub_header_ = CreateSubHeaderIfMissingAndReorder(
+        previously_connected_sub_header_,
+        IDS_ASH_STATUS_TRAY_BLUETOOTH_PREVIOUSLY_CONNECTED_DEVICES, index);
+
+    // Increment |index| since this position was taken by
+    // |previously_connected_sub_header_|.
+    index++;
+
+    // Ignore the returned index since we are now done re-ordering the list.
+    CreateViewsIfMissingAndReorder(previously_connected, &previous_views,
+                                   index);
+  } else {
+    RemoveAndResetViewIfExists(&previously_connected_sub_header_);
+  }
+
+  // The header when there are no connected or previously connected devices.
+  if (device_id_to_view_map_.empty()) {
+    no_device_connected_sub_header_ = CreateSubHeaderIfMissingAndReorder(
+        no_device_connected_sub_header_,
+        IDS_ASH_STATUS_TRAY_BLUETOOTH_NO_DEVICE_CONNECTED, index);
+  } else {
+    RemoveAndResetViewIfExists(&no_device_connected_sub_header_);
+  }
+
+  for (const auto& id_and_view : previous_views) {
+    bluetooth_detailed_view_->device_list()->RemoveChildViewT(
+        id_and_view.second);
+  }
   bluetooth_detailed_view_->NotifyDeviceListChanged();
 }
 
-TriView* BluetoothDeviceListControllerImpl::AddOrReorderSubHeader(
+TriView* BluetoothDeviceListControllerImpl::CreateSubHeaderIfMissingAndReorder(
     TriView* sub_header,
     int text_id,
     int index) {
@@ -52,4 +154,34 @@
   return sub_header;
 }
 
+int BluetoothDeviceListControllerImpl::CreateViewsIfMissingAndReorder(
+    const PairedBluetoothDevicePropertiesPtrs& device_property_list,
+    base::flat_map<std::string, BluetoothDeviceListItemView*>* previous_views,
+    int index) {
+  DCHECK(previous_views);
+
+  BluetoothDeviceListItemView* device_view = nullptr;
+
+  for (const auto& device_properties : device_property_list) {
+    const std::string& device_id = device_properties->device_properties->id;
+    auto it = previous_views->find(device_id);
+
+    if (it == previous_views->end()) {
+      device_view = bluetooth_detailed_view_->AddDeviceListItem();
+    } else {
+      device_view = it->second;
+      previous_views->erase(it);
+    }
+    device_id_to_view_map_.emplace(device_id, device_view);
+
+    device_view->UpdateDeviceProperties(device_properties);
+    bluetooth_detailed_view_->device_list()->ReorderChildView(device_view,
+                                                              index);
+
+    // Increment |index| since this position was taken by |device_view|.
+    index++;
+  }
+  return index;
+}
+
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_device_list_controller_impl.h b/ash/system/bluetooth/bluetooth_device_list_controller_impl.h
index 687a047..787747a 100644
--- a/ash/system/bluetooth/bluetooth_device_list_controller_impl.h
+++ b/ash/system/bluetooth/bluetooth_device_list_controller_impl.h
@@ -5,15 +5,24 @@
 #ifndef ASH_SYSTEM_BLUETOOTH_BLUETOOTH_DEVICE_LIST_CONTROLLER_IMPL_H_
 #define ASH_SYSTEM_BLUETOOTH_BLUETOOTH_DEVICE_LIST_CONTROLLER_IMPL_H_
 
+#include <string>
+#include <vector>
+
 #include "ash/ash_export.h"
 #include "ash/system/bluetooth/bluetooth_device_list_controller.h"
+#include "base/containers/flat_map.h"
 #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
 
+namespace views {
+class Separator;
+}  // namespace views
+
 namespace ash {
 namespace tray {
 class BluetoothDetailedView;
 }  // namespace tray
 
+class BluetoothDeviceListItemView;
 class TriView;
 
 // BluetoothDeviceListController implementation.
@@ -26,25 +35,44 @@
       delete;
   BluetoothDeviceListControllerImpl& operator=(
       const BluetoothDeviceListControllerImpl&) = delete;
-  ~BluetoothDeviceListControllerImpl() override = default;
+  ~BluetoothDeviceListControllerImpl() override;
 
  private:
+  friend class BluetoothDeviceListControllerTest;
+
   // BluetoothDeviceListController:
   void UpdateBluetoothEnabledState(bool enabled) override;
   void UpdateDeviceList(
       const PairedBluetoothDevicePropertiesPtrs& connected,
       const PairedBluetoothDevicePropertiesPtrs& previously_connected) override;
 
-  // Adds a new sub-header with |text_id| if |sub_header| is |nullptr|,
-  // otherwise reuses |sub_header|. Whichever sub-header used is then reordered
-  // to |index| and returned.
-  TriView* AddOrReorderSubHeader(TriView* sub_header, int text_id, int index);
+  // Creates a sub-header with text represented by the |text_id| message ID when
+  // |sub_header| is |nullptr|, otherwise uses the provided |sub_header|. The
+  // used sub-header is then moved to index |index| within the device list and
+  // returned.
+  TriView* CreateSubHeaderIfMissingAndReorder(TriView* sub_header,
+                                              int text_id,
+                                              int index);
+
+  // Creates and initializes a view for each of the device properties within
+  // |device_property_list| if a view does not already exist, otherwise re-using
+  // the existing view to avoid disrupting a11y. Each view will be reordered to
+  // start at |index| and will be removed from |previous_views|. The index of
+  // the position after the final view that was added is returned.
+  int CreateViewsIfMissingAndReorder(
+      const PairedBluetoothDevicePropertiesPtrs& device_property_list,
+      base::flat_map<std::string, BluetoothDeviceListItemView*>* previous_views,
+      int index);
 
   tray::BluetoothDetailedView* bluetooth_detailed_view_;
 
   bool is_bluetooth_enabled_ = false;
-  TriView* currently_connected_devices_sub_header_ = nullptr;
-  TriView* previously_connected_devices_sub_header_ = nullptr;
+  base::flat_map<std::string, BluetoothDeviceListItemView*>
+      device_id_to_view_map_;
+  views::Separator* device_list_separator_ = nullptr;
+  TriView* connected_sub_header_ = nullptr;
+  TriView* no_device_connected_sub_header_ = nullptr;
+  TriView* previously_connected_sub_header_ = nullptr;
 };
 
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_device_list_controller_unittest.cc b/ash/system/bluetooth/bluetooth_device_list_controller_unittest.cc
index 43af681d..f619098 100644
--- a/ash/system/bluetooth/bluetooth_device_list_controller_unittest.cc
+++ b/ash/system/bluetooth/bluetooth_device_list_controller_unittest.cc
@@ -5,14 +5,35 @@
 #include "ash/system/bluetooth/bluetooth_device_list_controller_impl.h"
 
 #include <memory>
+#include <string>
+#include <vector>
 
 #include "ash/constants/ash_features.h"
+#include "ash/strings/grit/ash_strings.h"
 #include "ash/system/bluetooth/bluetooth_detailed_view.h"
+#include "ash/system/bluetooth/bluetooth_device_list_item_view.h"
 #include "ash/system/bluetooth/fake_bluetooth_detailed_view.h"
+#include "ash/system/tray/tri_view.h"
 #include "ash/test/ash_test_base.h"
 #include "base/test/scoped_feature_list.h"
+#include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/separator.h"
 
 namespace ash {
+namespace {
+
+using chromeos::bluetooth_config::mojom::BluetoothDeviceProperties;
+using chromeos::bluetooth_config::mojom::DeviceConnectionState;
+using chromeos::bluetooth_config::mojom::PairedBluetoothDeviceProperties;
+using chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr;
+
+const char kDeviceId1[] = "/device/id/1";
+const char kDeviceId2[] = "/device/id/2";
+const char kDeviceNickname[] = "mau5";
+
+}  // namespace
 
 class BluetoothDeviceListControllerTest : public AshTestBase {
  public:
@@ -30,15 +51,140 @@
 
   void TearDown() override { AshTestBase::TearDown(); }
 
-  tray::BluetoothDetailedView* bluetooth_detailed_view() {
-    return fake_bluetooth_detailed_view_.get();
+  const TriView* FindConnectedSubHeader() {
+    return FindSubHeaderWithText(l10n_util::GetStringUTF16(
+        IDS_ASH_STATUS_TRAY_BLUETOOTH_CURRENTLY_CONNECTED_DEVICES));
+  }
+
+  const TriView* FindPreviouslyConnectedSubHeader() {
+    return FindSubHeaderWithText(l10n_util::GetStringUTF16(
+        IDS_ASH_STATUS_TRAY_BLUETOOTH_PREVIOUSLY_CONNECTED_DEVICES));
+  }
+
+  const TriView* FindNoDeviceConnectedSubHeader() {
+    return FindSubHeaderWithText(l10n_util::GetStringUTF16(
+        IDS_ASH_STATUS_TRAY_BLUETOOTH_NO_DEVICE_CONNECTED));
+  }
+
+  const views::Separator* FindSeparator() {
+    for (const auto* view : device_list()->children()) {
+      if (!std::strcmp("Separator", view->GetClassName()))
+        return static_cast<const views::Separator*>(view);
+    }
+    return nullptr;
+  }
+
+  PairedBluetoothDevicePropertiesPtr BuildDeviceProperties(
+      const std::string& id) {
+    PairedBluetoothDevicePropertiesPtr device_properties =
+        PairedBluetoothDeviceProperties::New();
+    device_properties->device_properties = BluetoothDeviceProperties::New();
+    device_properties->device_properties->id = id;
+    return device_properties;
+  }
+
+  const std::u16string& GetSubHeaderText(const TriView* sub_header) {
+    EXPECT_TRUE(sub_header);
+    EXPECT_EQ(1u, sub_header->children().at(1)->children().size());
+    return static_cast<views::Label*>(
+               sub_header->children().at(1)->children().at(0))
+        ->GetText();
+  }
+
+  const char* GetDeviceId(const BluetoothDeviceListItemView* device_item_view) {
+    return device_item_view->device_properties()->device_properties->id.c_str();
+  }
+
+  const BluetoothDeviceListItemView* GetFirstDeviceView() {
+    EXPECT_LT(1u, device_list()->children().size());
+    return static_cast<BluetoothDeviceListItemView*>(
+        device_list()->children().at(1));
+  }
+
+  void CheckDeviceListOrdering(size_t connected_device_count,
+                               size_t previously_connected_device_count) {
+    if (connected_device_count && previously_connected_device_count) {
+      const TriView* connected_sub_header = FindConnectedSubHeader();
+      const TriView* previously_connected_sub_header =
+          FindPreviouslyConnectedSubHeader();
+      const views::Separator* device_list_separator = FindSeparator();
+
+      EXPECT_TRUE(connected_sub_header);
+      EXPECT_TRUE(previously_connected_sub_header);
+      EXPECT_TRUE(device_list_separator);
+
+      const unsigned int connected_index =
+          device_list()->GetIndexOf(connected_sub_header);
+      const unsigned int previously_connected_index =
+          device_list()->GetIndexOf(previously_connected_sub_header);
+      const unsigned int separator_index =
+          device_list()->GetIndexOf(device_list_separator);
+
+      EXPECT_EQ(0u, connected_index);
+      EXPECT_EQ(connected_device_count + 1, separator_index);
+      EXPECT_EQ(separator_index + 1, previously_connected_index);
+      return;
+    }
+
+    if (connected_device_count) {
+      const TriView* connected_sub_header = FindConnectedSubHeader();
+      EXPECT_TRUE(connected_sub_header);
+      EXPECT_EQ(0, device_list()->GetIndexOf(connected_sub_header));
+      EXPECT_EQ(connected_device_count + 1, device_list()->children().size());
+      return;
+    }
+
+    if (previously_connected_device_count) {
+      const TriView* previously_connected_sub_header =
+          FindPreviouslyConnectedSubHeader();
+      EXPECT_TRUE(previously_connected_sub_header);
+      EXPECT_EQ(0, device_list()->GetIndexOf(previously_connected_sub_header));
+      EXPECT_EQ(previously_connected_device_count + 1,
+                device_list()->children().size());
+      return;
+    }
+
+    const TriView* no_device_connected_sub_header =
+        FindNoDeviceConnectedSubHeader();
+    EXPECT_TRUE(no_device_connected_sub_header);
+    EXPECT_EQ(0, device_list()->GetIndexOf(no_device_connected_sub_header));
+    EXPECT_EQ(1u, device_list()->children().size());
+  }
+
+  void CheckNotifyDeviceListChangedCount(size_t call_count) {
+    EXPECT_EQ(call_count, fake_bluetooth_detailed_view()
+                              ->notify_device_list_changed_call_count());
+  }
+
+  views::View* device_list() {
+    return static_cast<tray::BluetoothDetailedView*>(
+               fake_bluetooth_detailed_view_.get())
+        ->device_list();
   }
 
   BluetoothDeviceListController* bluetooth_device_list_controller() {
     return bluetooth_device_list_controller_impl_.get();
   }
 
+  tray::FakeBluetoothDetailedView* fake_bluetooth_detailed_view() {
+    return fake_bluetooth_detailed_view_.get();
+  }
+
+ protected:
+  const std::vector<PairedBluetoothDevicePropertiesPtr> empty_list_;
+
  private:
+  const TriView* FindSubHeaderWithText(const std::u16string text) {
+    for (const auto* view : device_list()->children()) {
+      if (std::strcmp("TriView", view->GetClassName()))
+        continue;
+      const TriView* sub_header = static_cast<const TriView*>(view);
+      if (GetSubHeaderText(sub_header) == text)
+        return sub_header;
+    }
+    return nullptr;
+  }
+
   base::test::ScopedFeatureList feature_list_;
   std::unique_ptr<tray::FakeBluetoothDetailedView>
       fake_bluetooth_detailed_view_;
@@ -46,8 +192,135 @@
       bluetooth_device_list_controller_impl_;
 };
 
-TEST_F(BluetoothDeviceListControllerTest, CanConstruct) {
-  EXPECT_TRUE(true);
+TEST_F(BluetoothDeviceListControllerTest,
+       HasCorrectSubHeaderWithNoPairedDevices) {
+  CheckNotifyDeviceListChangedCount(/*call_count=*/0u);
+
+  bluetooth_device_list_controller()->UpdateBluetoothEnabledState(true);
+  bluetooth_device_list_controller()->UpdateDeviceList(
+      /*connected=*/empty_list_,
+      /*previously_connected=*/empty_list_);
+  CheckNotifyDeviceListChangedCount(/*call_count=*/1u);
+
+  EXPECT_EQ(1u, device_list()->children().size());
+
+  const TriView* no_device_connected_sub_header =
+      FindNoDeviceConnectedSubHeader();
+  EXPECT_TRUE(no_device_connected_sub_header);
+}
+
+TEST_F(BluetoothDeviceListControllerTest,
+       HasCorrectDeviceListOrderWithPairedDevices) {
+  CheckNotifyDeviceListChangedCount(/*call_count=*/0u);
+
+  bluetooth_device_list_controller()->UpdateBluetoothEnabledState(true);
+
+  std::vector<PairedBluetoothDevicePropertiesPtr> connected_list;
+  connected_list.push_back(BuildDeviceProperties(kDeviceId1));
+
+  bluetooth_device_list_controller()->UpdateDeviceList(
+      /*connected=*/connected_list,
+      /*previously_connected=*/empty_list_);
+  CheckNotifyDeviceListChangedCount(/*call_count=*/1u);
+
+  const TriView* connected_devices_sub_header = FindConnectedSubHeader();
+
+  EXPECT_EQ(2u, device_list()->children().size());
+  EXPECT_STREQ(kDeviceId1, GetDeviceId(GetFirstDeviceView()));
+  EXPECT_TRUE(connected_devices_sub_header);
+
+  CheckDeviceListOrdering(
+      /*connected_device_count=*/connected_list.size(),
+      /*previously_connected_device_count=*/empty_list_.size());
+
+  std::vector<PairedBluetoothDevicePropertiesPtr> previously_connected_list;
+  previously_connected_list.push_back(BuildDeviceProperties(kDeviceId2));
+
+  bluetooth_device_list_controller()->UpdateDeviceList(
+      /*connected=*/empty_list_,
+      /*previously_connected=*/previously_connected_list);
+  CheckNotifyDeviceListChangedCount(/*call_count=*/2u);
+
+  const TriView* previously_connected_devices_sub_header =
+      FindPreviouslyConnectedSubHeader();
+
+  EXPECT_EQ(2u, device_list()->children().size());
+  EXPECT_STREQ(kDeviceId2, GetDeviceId(GetFirstDeviceView()));
+  EXPECT_TRUE(previously_connected_devices_sub_header);
+
+  CheckDeviceListOrdering(
+      /*connected_device_count=*/0,
+      /*previously_connected_device_count=*/previously_connected_list.size());
+
+  // "Update" the device list multiple times to be sure that no children are
+  // duplicated and every child is re-ordered correctly.
+  for (int i = 0; i < 2; i++) {
+    bluetooth_device_list_controller()->UpdateDeviceList(
+        /*connected=*/connected_list,
+        /*previously_connected=*/previously_connected_list);
+  }
+
+  CheckNotifyDeviceListChangedCount(/*call_count=*/4u);
+
+  EXPECT_EQ(5u, device_list()->children().size());
+
+  CheckDeviceListOrdering(
+      /*connected_device_count=*/connected_list.size(),
+      /*previously_connected_device_count=*/previously_connected_list.size());
+}
+
+TEST_F(BluetoothDeviceListControllerTest, ExistingDeviceViewsAreUpdated) {
+  CheckNotifyDeviceListChangedCount(/*call_count=*/0u);
+
+  bluetooth_device_list_controller()->UpdateBluetoothEnabledState(true);
+
+  std::vector<PairedBluetoothDevicePropertiesPtr> connected_list;
+  connected_list.push_back(BuildDeviceProperties(kDeviceId1));
+
+  bluetooth_device_list_controller()->UpdateDeviceList(
+      /*connected=*/connected_list,
+      /*previously_connected=*/empty_list_);
+  CheckNotifyDeviceListChangedCount(/*call_count=*/1u);
+
+  EXPECT_EQ(2u, device_list()->children().size());
+
+  const BluetoothDeviceListItemView* first_item = GetFirstDeviceView();
+
+  EXPECT_FALSE(first_item->device_properties()->nickname.has_value());
+
+  connected_list.at(0)->nickname = kDeviceNickname;
+
+  bluetooth_device_list_controller()->UpdateDeviceList(
+      /*connected=*/connected_list,
+      /*previously_connected=*/empty_list_);
+  CheckNotifyDeviceListChangedCount(/*call_count=*/2u);
+
+  EXPECT_EQ(2u, device_list()->children().size());
+  EXPECT_EQ(1, device_list()->GetIndexOf(first_item));
+  EXPECT_TRUE(first_item->device_properties()->nickname.has_value());
+  EXPECT_STREQ(kDeviceNickname,
+               first_item->device_properties()->nickname.value().c_str());
+}
+
+TEST_F(BluetoothDeviceListControllerTest,
+       DeviceListIsClearedWhenBluetoothBecomesDisabled) {
+  CheckNotifyDeviceListChangedCount(/*call_count=*/0u);
+
+  bluetooth_device_list_controller()->UpdateBluetoothEnabledState(true);
+
+  std::vector<PairedBluetoothDevicePropertiesPtr> connected_list;
+  connected_list.push_back(BuildDeviceProperties(kDeviceId1));
+
+  bluetooth_device_list_controller()->UpdateDeviceList(
+      /*connected=*/connected_list,
+      /*previously_connected=*/empty_list_);
+  CheckNotifyDeviceListChangedCount(/*call_count=*/1u);
+
+  EXPECT_EQ(2u, device_list()->children().size());
+
+  bluetooth_device_list_controller()->UpdateBluetoothEnabledState(false);
+
+  EXPECT_EQ(0u, device_list()->children().size());
 }
 
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_device_list_item_view.cc b/ash/system/bluetooth/bluetooth_device_list_item_view.cc
index b4abc9bd..f950a9d 100644
--- a/ash/system/bluetooth/bluetooth_device_list_item_view.cc
+++ b/ash/system/bluetooth/bluetooth_device_list_item_view.cc
@@ -26,4 +26,8 @@
   device_properties_ = mojo::Clone(device_properties);
 }
 
+const char* BluetoothDeviceListItemView::GetClassName() const {
+  return "BluetoothDeviceListItemView";
+}
+
 }  // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_device_list_item_view.h b/ash/system/bluetooth/bluetooth_device_list_item_view.h
index e70b57c..f08d7739 100644
--- a/ash/system/bluetooth/bluetooth_device_list_item_view.h
+++ b/ash/system/bluetooth/bluetooth_device_list_item_view.h
@@ -34,6 +34,9 @@
   }
 
  private:
+  // views::View:
+  const char* GetClassName() const override;
+
   chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr
       device_properties_;
 };
diff --git a/ash/system/bluetooth/fake_bluetooth_detailed_view.cc b/ash/system/bluetooth/fake_bluetooth_detailed_view.cc
index 9f978157..059f2a3c 100644
--- a/ash/system/bluetooth/fake_bluetooth_detailed_view.cc
+++ b/ash/system/bluetooth/fake_bluetooth_detailed_view.cc
@@ -6,13 +6,15 @@
 
 #include "ash/system/bluetooth/bluetooth_device_list_item_view.h"
 #include "ash/system/tray/tri_view.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/views/controls/label.h"
 
 namespace ash {
 namespace tray {
 
 FakeBluetoothDetailedView::FakeBluetoothDetailedView(Delegate* delegate)
     : BluetoothDetailedView(delegate),
-      device_list_(std::make_unique<views::ScrollView>()) {}
+      device_list_(std::make_unique<views::View>()) {}
 
 FakeBluetoothDetailedView::~FakeBluetoothDetailedView() = default;
 
@@ -30,9 +32,13 @@
 }
 
 ash::TriView* FakeBluetoothDetailedView::AddDeviceListSubHeader(
-    const gfx::VectorIcon&,
-    int) {
-  return device_list_->AddChildView(new ash::TriView());
+    const gfx::VectorIcon& /*icon*/,
+    int text_id) {
+  std::unique_ptr<TriView> sub_header = std::make_unique<TriView>();
+  sub_header->AddView(TriView::Container::CENTER,
+                      new views::Label(l10n_util::GetStringUTF16(text_id)));
+  device_list_->AddChildView(sub_header.get());
+  return sub_header.release();
 }
 
 void FakeBluetoothDetailedView::NotifyDeviceListChanged() {
@@ -40,7 +46,7 @@
 }
 
 views::View* FakeBluetoothDetailedView::device_list() {
-  return device_list_->contents();
+  return device_list_.get();
 }
 
 }  // namespace tray
diff --git a/ash/system/bluetooth/fake_bluetooth_detailed_view.h b/ash/system/bluetooth/fake_bluetooth_detailed_view.h
index 197bf4d..59745f4 100644
--- a/ash/system/bluetooth/fake_bluetooth_detailed_view.h
+++ b/ash/system/bluetooth/fake_bluetooth_detailed_view.h
@@ -11,7 +11,6 @@
 #include "ash/system/bluetooth/bluetooth_detailed_view.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/vector_icon_types.h"
-#include "ui/views/controls/scroll_view.h"
 
 namespace views {
 class View;
@@ -47,13 +46,13 @@
   void UpdateBluetoothEnabledState(bool enabled) override;
   BluetoothDeviceListItemView* AddDeviceListItem() override;
   ash::TriView* AddDeviceListSubHeader(const gfx::VectorIcon& /*icon*/,
-                                       int /*text_id*/) override;
+                                       int text_id) override;
   void NotifyDeviceListChanged() override;
   views::View* device_list() override;
 
   size_t notify_device_list_changed_call_count_ = 0;
   absl::optional<bool> last_bluetooth_enabled_state_;
-  std::unique_ptr<views::ScrollView> device_list_;
+  std::unique_ptr<views::View> device_list_;
 };
 
 }  // namespace tray
diff --git a/ash/system/message_center/notifier_settings_view.cc b/ash/system/message_center/notifier_settings_view.cc
index 76ad2bd..0cb811f 100644
--- a/ash/system/message_center/notifier_settings_view.cc
+++ b/ash/system/message_center/notifier_settings_view.cc
@@ -35,7 +35,6 @@
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/base/ui_base_features.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/paint_recorder.h"
 #include "ui/events/event_utils.h"
@@ -554,42 +553,40 @@
   const SkColor separator_color = AshColorProvider::Get()->GetContentLayerColor(
       ContentLayerType::kSeparatorColor);
 
-  if (::features::IsNotificationIndicatorEnabled()) {
-    // Row for the app badging toggle button.
-    auto app_badging_icon = std::make_unique<AdaptiveBadgingIcon>();
-    app_badging_icon->SetImage(gfx::CreateVectorIcon(
-        kSystemTrayAppBadgingIcon, kMenuIconSize, icon_color));
-    auto app_badging_label =
-        std::make_unique<views::Label>(l10n_util::GetStringUTF16(
-            IDS_ASH_MESSAGE_CENTER_APP_BADGING_BUTTON_TOOLTIP));
-    auto app_badging_toggle =
-        base::WrapUnique<views::ToggleButton>(new TrayToggleButton(
-            base::BindRepeating(&NotifierSettingsView::AppBadgingTogglePressed,
-                                base::Unretained(this)),
-            IDS_ASH_MESSAGE_CENTER_APP_BADGING_BUTTON_TOOLTIP));
-    app_badging_toggle_ = app_badging_toggle.get();
+  // Row for the app badging toggle button.
+  auto app_badging_icon = std::make_unique<AdaptiveBadgingIcon>();
+  app_badging_icon->SetImage(gfx::CreateVectorIcon(kSystemTrayAppBadgingIcon,
+                                                   kMenuIconSize, icon_color));
+  auto app_badging_label =
+      std::make_unique<views::Label>(l10n_util::GetStringUTF16(
+          IDS_ASH_MESSAGE_CENTER_APP_BADGING_BUTTON_TOOLTIP));
+  auto app_badging_toggle =
+      base::WrapUnique<views::ToggleButton>(new TrayToggleButton(
+          base::BindRepeating(&NotifierSettingsView::AppBadgingTogglePressed,
+                              base::Unretained(this)),
+          IDS_ASH_MESSAGE_CENTER_APP_BADGING_BUTTON_TOOLTIP));
+  app_badging_toggle_ = app_badging_toggle.get();
 
-    SessionControllerImpl* session_controller =
-        Shell::Get()->session_controller();
-    PrefService* prefs = session_controller->GetLastActiveUserPrefService();
-    if (prefs) {
-      app_badging_toggle_->SetIsOn(
-          prefs->GetBoolean(prefs::kAppNotificationBadgingEnabled));
-    }
-
-    auto app_badging_view = CreateToggleButtonRow(
-        std::move(app_badging_icon), std::move(app_badging_label),
-        std::move(app_badging_toggle));
-    app_badging_view->SetBorder(
-        views::CreateSolidSidedBorder(0, 0, 0, 1, kTopBorderColor));
-    header_view->AddChildView(std::move(app_badging_view));
-
-    // Separator between toggle button rows.
-    auto separator = std::make_unique<AdaptiveSeparator>();
-    separator->SetColor(separator_color);
-    header_view->AddChildView(std::move(separator));
+  SessionControllerImpl* session_controller =
+      Shell::Get()->session_controller();
+  PrefService* prefs = session_controller->GetLastActiveUserPrefService();
+  if (prefs) {
+    app_badging_toggle_->SetIsOn(
+        prefs->GetBoolean(prefs::kAppNotificationBadgingEnabled));
   }
 
+  auto app_badging_view = CreateToggleButtonRow(std::move(app_badging_icon),
+                                                std::move(app_badging_label),
+                                                std::move(app_badging_toggle));
+  app_badging_view->SetBorder(
+      views::CreateSolidSidedBorder(0, 0, 0, 1, kTopBorderColor));
+  header_view->AddChildView(std::move(app_badging_view));
+
+  // Separator between toggle button rows.
+  auto separator = std::make_unique<AdaptiveSeparator>();
+  separator->SetColor(separator_color);
+  header_view->AddChildView(std::move(separator));
+
   // Row for the quiet mode toggle button.
   auto quiet_mode_icon = std::make_unique<views::ImageView>();
   quiet_mode_icon_ = quiet_mode_icon.get();
diff --git a/ash/system/message_center/stacked_notification_bar.cc b/ash/system/message_center/stacked_notification_bar.cc
index 659f0562..3f17e2c1 100644
--- a/ash/system/message_center/stacked_notification_bar.cc
+++ b/ash/system/message_center/stacked_notification_bar.cc
@@ -120,9 +120,8 @@
     : public views::ImageView,
       public ui::LayerAnimationObserver {
  public:
-  StackedNotificationBarIcon(StackedNotificationBar* notification_bar,
-                             const std::string& id)
-      : views::ImageView(), notification_bar_(notification_bar), id_(id) {
+  explicit StackedNotificationBarIcon(const std::string& id)
+      : views::ImageView(), id_(id) {
     SetPaintToLayer();
     layer()->SetFillsBoundsOpaquely(false);
   }
@@ -140,6 +139,11 @@
 
     auto* notification =
         message_center::MessageCenter::Get()->FindVisibleNotificationById(id_);
+    // The notification icon could be waiting to be cleaned up after the
+    // notification removal animation completes.
+    if (!notification)
+      return;
+
     SkColor accent_color = GetNativeTheme()->GetSystemColor(
         ui::NativeTheme::kColorId_NotificationDefaultAccentColor);
     gfx::Image masked_small_icon = notification->GenerateMaskedSmallIcon(
@@ -198,7 +202,13 @@
     layer()->GetAnimator()->StartAnimation(sequence.release());
   }
 
-  void AnimateOut() {
+  using AnimationCompleteCallback = base::OnceCallback<void(views::View*)>;
+
+  void AnimateOut(AnimationCompleteCallback animation_complete_callback) {
+    DCHECK(animation_complete_callback_.is_null());
+
+    animation_complete_callback_ = std::move(animation_complete_callback);
+
     layer()->GetAnimator()->StopAnimating();
 
     std::unique_ptr<ui::InterpolatedTransform> scale =
@@ -235,7 +245,7 @@
   // ui::LayerAnimationObserver:
   void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
     set_animating_out(false);
-    notification_bar_->OnIconAnimatedOut(this);
+    std::move(animation_complete_callback_).Run(this);
     // Note |this| is deleted after this point.
   }
 
@@ -249,57 +259,58 @@
   void set_animating_out(bool animating_out) { animating_out_ = animating_out; }
 
  private:
-  StackedNotificationBar* notification_bar_;
   std::string id_;
   bool animating_out_ = false;
+
+  // Used to notify the parent of animation completion. This is deleted after
+  // the callback is run.
+  // Registered in `AnimateOut()`.
+  AnimationCompleteCallback animation_complete_callback_;
 };
 
 StackedNotificationBar::StackedNotificationBar(
     UnifiedMessageCenterView* message_center_view)
     : message_center_view_(message_center_view),
-      count_label_(new views::Label),
-      clear_all_button_(new StackingBarLabelButton(
+      notification_icons_container_(
+          AddChildView(std::make_unique<views::View>())),
+      count_label_(AddChildView(std::make_unique<views::Label>())),
+      clear_all_button_(AddChildView(std::make_unique<StackingBarLabelButton>(
           base::BindRepeating(&UnifiedMessageCenterView::ClearAllNotifications,
                               base::Unretained(message_center_view_)),
           l10n_util::GetStringUTF16(
               IDS_ASH_MESSAGE_CENTER_CLEAR_ALL_BUTTON_LABEL),
-          message_center_view)),
-      expand_all_button_(new StackingBarLabelButton(
+          message_center_view))),
+      expand_all_button_(AddChildView(std::make_unique<StackingBarLabelButton>(
           base::BindRepeating(&UnifiedMessageCenterView::ExpandMessageCenter,
                               base::Unretained(message_center_view_)),
           l10n_util::GetStringUTF16(
               IDS_ASH_MESSAGE_CENTER_EXPAND_ALL_NOTIFICATIONS_BUTTON_LABEL),
-          message_center_view)) {
+          message_center_view))) {
   SetVisible(false);
   auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kHorizontal));
   layout->set_cross_axis_alignment(
       views::BoxLayout::CrossAxisAlignment::kStretch);
 
-  notification_icons_container_ = new views::View();
   notification_icons_container_->SetLayoutManager(
       std::make_unique<views::BoxLayout>(
           views::BoxLayout::Orientation::kHorizontal,
           kStackedNotificationIconsContainerPadding,
           kStackedNotificationBarIconSpacing));
-  AddChildView(notification_icons_container_);
+
   message_center::MessageCenter::Get()->AddObserver(this);
 
   count_label_->SetEnabledColor(message_center_style::kCountLabelColor);
   count_label_->SetFontList(views::Label::GetDefaultFontList().Derive(
       1, gfx::Font::NORMAL, gfx::Font::Weight::MEDIUM));
-  AddChildView(count_label_);
 
-  views::View* spacer = new views::View;
-  AddChildView(spacer);
+  views::View* spacer = AddChildView(std::make_unique<views::View>());
   layout->SetFlexForView(spacer, 1);
 
   clear_all_button_->SetTooltipText(l10n_util::GetStringUTF16(
       IDS_ASH_MESSAGE_CENTER_CLEAR_ALL_BUTTON_TOOLTIP));
-  AddChildView(clear_all_button_);
 
   expand_all_button_->SetVisible(false);
-  AddChildView(expand_all_button_);
 
   if (!features::IsNotificationsRefreshEnabled())
     SetPaintToLayer();
@@ -360,32 +371,42 @@
 void StackedNotificationBar::AddNotificationIcon(
     message_center::Notification* notification,
     bool at_front) {
-  views::ImageView* icon_view =
-      new StackedNotificationBarIcon(this, notification->id());
   if (at_front)
-    notification_icons_container_->AddChildViewAt(icon_view, 0);
+    notification_icons_container_->AddChildViewAt(
+        std::make_unique<StackedNotificationBarIcon>(notification->id()), 0);
   else
-    notification_icons_container_->AddChildView(icon_view);
+    notification_icons_container_->AddChildView(
+        std::make_unique<StackedNotificationBarIcon>(notification->id()));
 }
 
-void StackedNotificationBar::OnIconAnimatedOut(views::View* icon) {
+void StackedNotificationBar::OnIconAnimatedOut(
+    message_center::Notification* notification,
+    views::View* icon) {
   delete icon;
+
+  // This is only called when icons animate out, so never add icons to the
+  // front.
+  if (notification)
+    AddNotificationIcon(notification, /*at_front=*/false);
+
   Layout();
 }
 
 StackedNotificationBar::StackedNotificationBarIcon*
-StackedNotificationBar::GetFrontIcon() {
+StackedNotificationBar::GetFrontIcon(bool animating_out) {
   const auto i = std::find_if(
       notification_icons_container_->children().cbegin(),
-      notification_icons_container_->children().cend(), [](const auto* v) {
-        return !static_cast<const StackedNotificationBarIcon*>(v)
-                    ->is_animating_out();
+      notification_icons_container_->children().cend(), [&](const auto* v) {
+        return animating_out ==
+               static_cast<const StackedNotificationBarIcon*>(v)
+                   ->is_animating_out();
       });
 
   return (i == notification_icons_container_->children().cend()
               ? nullptr
               : static_cast<StackedNotificationBarIcon*>(*i));
 }
+
 const StackedNotificationBar::StackedNotificationBarIcon*
 StackedNotificationBar::GetIconFromId(const std::string& id) const {
   for (auto* v : notification_icons_container_->children()) {
@@ -399,35 +420,57 @@
 
 void StackedNotificationBar::ShiftIconsLeft(
     std::vector<message_center::Notification*> stacked_notifications) {
+  auto* front_animating_out_icon = GetFrontIcon(/*animating_out=*/true);
+  bool is_already_animating_a_left_shift = front_animating_out_icon != nullptr;
+  // If we need to animate a second icon, the scroll is faster than the icon can
+  // animate out (this is possible with a very fast scroll), so immediately
+  // finish that animation before starting a new one.
+  if (is_already_animating_a_left_shift) {
+    front_animating_out_icon->layer()->GetAnimator()->StopAnimating();
+    // `front_animating_out_icon` is now deleted, and StackedNotificationBar has
+    // been reloaded with another icon in the back.
+  }
+
   int stacked_notification_count = stacked_notifications.size();
   int removed_icons_count =
       std::min(stacked_notification_count_ - stacked_notification_count,
                kStackedNotificationBarMaxIcons);
 
+  stacked_notification_count_ = stacked_notification_count;
+
   // Remove required number of icons from the front.
   // Only animate if we're removing one icon.
-  if (removed_icons_count == 1) {
-    StackedNotificationBarIcon* icon = GetFrontIcon();
-    if (icon) {
-      icon->AnimateOut();
-    }
-  } else {
-    for (int i = 0; i < removed_icons_count; i++) {
-      StackedNotificationBarIcon* icon = GetFrontIcon();
-      if (icon) {
-        delete icon;
-      }
-    }
-  }
-  // Add icons to the back if there was a backfill.
   int backfill_start = kStackedNotificationBarMaxIcons - removed_icons_count;
   int backfill_end =
       std::min(kStackedNotificationBarMaxIcons, stacked_notification_count);
-  for (int i = backfill_start; i < backfill_end; i++) {
-    AddNotificationIcon(stacked_notifications[i], false /*at_front*/);
+  const bool will_animate = removed_icons_count == 1;
+  if (will_animate) {
+    auto* icon = GetFrontIcon(/*animating_out=*/false);
+    if (icon) {
+      // If there are notifications to backfill, do not add the
+      // icon until the animation completes, this avoids a jumping overflow
+      // label/icons and having more than 3 icons in the stack.
+      message_center::Notification* notification_icon_to_show_on_completion =
+          backfill_start < backfill_end ? stacked_notifications[backfill_start]
+                                        : nullptr;
+      icon->AnimateOut(
+          base::BindOnce(&StackedNotificationBar::OnIconAnimatedOut,
+                         weak_ptr_factory_.GetWeakPtr(),
+                         notification_icon_to_show_on_completion));
+    }
+    return;
   }
 
-  stacked_notification_count_ = stacked_notification_count;
+  // No animation.
+  for (int i = 0; i < removed_icons_count; i++) {
+    auto* icon = GetFrontIcon(/*animating_out=*/false);
+    if (icon) {
+      delete icon;
+    }
+  }
+
+  for (int i = backfill_start; i < backfill_end; i++)
+    AddNotificationIcon(stacked_notifications[i], false /*at_front*/);
 }
 
 void StackedNotificationBar::ShiftIconsRight(
@@ -446,9 +489,9 @@
     ++stacked_notification_count_;
   }
   // Animate in the first stacked notification icon.
-  StackedNotificationBarIcon* icon = GetFrontIcon();
+  auto* icon = GetFrontIcon(/*animating_out=*/false);
   if (icon)
-    GetFrontIcon()->AnimateIn();
+    icon->AnimateIn();
 }
 
 void StackedNotificationBar::UpdateStackedNotifications(
diff --git a/ash/system/message_center/stacked_notification_bar.h b/ash/system/message_center/stacked_notification_bar.h
index fa35077b..def490a1 100644
--- a/ash/system/message_center/stacked_notification_bar.h
+++ b/ash/system/message_center/stacked_notification_bar.h
@@ -9,6 +9,7 @@
 #include "ash/system/message_center/message_center_scroll_bar.h"
 #include "ash/system/message_center/unified_message_center_view.h"
 #include "ash/system/message_center/unified_message_list_view.h"
+#include "base/memory/weak_ptr.h"
 #include "ui/compositor/layer_animation_observer.h"
 #include "ui/gfx/animation/animation_delegate.h"
 #include "ui/message_center/message_center_observer.h"
@@ -25,8 +26,8 @@
 namespace ash {
 
 // The header shown above the notification list displaying the number of hidden
-// notifications. There are currently two UI implementations toggled by the
-// NotificationStackedBarRedesign feature flag.
+// notifications. Has a dynamic list of icons which hide/show as notifications
+// are scrolled.
 class StackedNotificationBar : public views::View,
                                public message_center::MessageCenterObserver {
  public:
@@ -54,9 +55,6 @@
   // Set notification bar state to expanded.
   void SetExpanded();
 
-  // Clean up icon view after it's removal animation is complete.
-  void OnIconAnimatedOut(views::View* icon);
-
   // views::View:
   void OnPaint(gfx::Canvas* canvas) override;
   const char* GetClassName() const override;
@@ -70,8 +68,14 @@
   class StackedNotificationBarIcon;
   friend class UnifiedMessageCenterViewTest;
 
-  // Get the first icon which is not animating out.
-  StackedNotificationBarIcon* GetFrontIcon();
+  // Clean up icon view after it's removal animation is complete, adds an icon
+  // for `notification` if needed. Called from a callback registered in
+  // `ShiftIconsLeft()`.
+  void OnIconAnimatedOut(message_center::Notification* notification,
+                         views::View* icon);
+
+  // Get the first icon which is `animating_out`.
+  StackedNotificationBarIcon* GetFrontIcon(bool animating_out);
 
   // Search for a icon view in the stacked notification bar based on a provided
   // notification id.
@@ -109,6 +113,8 @@
   views::Label* const count_label_;
   views::Button* const clear_all_button_;
   views::Button* const expand_all_button_;
+
+  base::WeakPtrFactory<StackedNotificationBar> weak_ptr_factory_{this};
 };
 
 }  // namespace ash
diff --git a/ash/system/message_center/unified_message_center_view_unittest.cc b/ash/system/message_center/unified_message_center_view_unittest.cc
index 791d4d4f..2421a0a 100644
--- a/ash/system/message_center/unified_message_center_view_unittest.cc
+++ b/ash/system/message_center/unified_message_center_view_unittest.cc
@@ -20,6 +20,8 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/prefs/pref_service.h"
+#include "ui/compositor/layer.h"
+#include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/views/message_view.h"
 #include "ui/views/controls/scroll_view.h"
@@ -180,6 +182,11 @@
     return message_center_view()->notification_bar_;
   }
 
+  views::View* GetNotificationBarIconsContainer() {
+    return message_center_view()
+        ->notification_bar_->notification_icons_container_;
+  }
+
   views::View* GetNotificationBarLabel() {
     return message_center_view()->notification_bar_->count_label_;
   }
@@ -481,12 +488,12 @@
             GetScroller()->GetVisibleRect().bottom());
 }
 
-TEST_F(UnifiedMessageCenterViewTest, StackingCounterLayout) {
+// Tests basic layout of the StackingNotificationBar.
+TEST_F(UnifiedMessageCenterViewTest, StackingCounterLabelLayout) {
   AddManyNotifications();
 
   // MessageCenterView is maxed out.
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
 
   EXPECT_GT(GetMessageListView()->bounds().height(),
             message_center_view()->bounds().height());
@@ -497,32 +504,26 @@
             GetScroller()->bounds().y());
   EXPECT_TRUE(GetNotificationBarLabel()->GetVisible());
   EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
+}
 
-  // Scroll to the top, making the counter label invisible.
+// Tests that the NotificationBarLabel is invisible when scrolled to the top.
+TEST_F(UnifiedMessageCenterViewTest, StackingCounterLabelInvisible) {
+  AddManyNotifications();
+  CreateMessageCenterView();
+
+  // Scroll to the top, the counter label should be invisible.
   GetScroller()->ScrollToPosition(GetScrollBar(), 0);
   message_center_view()->OnMessageCenterScrolled();
-  EXPECT_TRUE(GetNotificationBar()->GetVisible());
+
   EXPECT_FALSE(GetNotificationBarLabel()->GetVisible());
+  // ClearAll label should always be visible.
   EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
 }
 
-TEST_F(UnifiedMessageCenterViewTest, StackingCounterMessageListScrolled) {
+// Tests that the NotificationBarLabel is visible when scrolling down.
+TEST_F(UnifiedMessageCenterViewTest, StackingCounterLabelVisible) {
   AddManyNotifications();
   CreateMessageCenterView();
-  EXPECT_TRUE(message_center_view()->GetVisible());
-  EXPECT_TRUE(GetNotificationBarLabel()->GetVisible());
-  EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
-
-  // MessageCenterView is maxed out.
-  EXPECT_GT(GetMessageListView()->bounds().height(),
-            message_center_view()->bounds().height());
-
-  // Scroll to the top, making the counter label invisible.
-  GetScroller()->ScrollToPosition(GetScrollBar(), 0);
-  message_center_view()->OnMessageCenterScrolled();
-  EXPECT_TRUE(GetNotificationBar()->GetVisible());
-  EXPECT_FALSE(GetNotificationBarLabel()->GetVisible());
-  EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
 
   // Scrolling past 5 notifications should make the counter label visible.
   const int scroll_amount = (GetMessageViewVisibleBounds(0).height() * 5) + 1;
@@ -530,16 +531,72 @@
   message_center_view()->OnMessageCenterScrolled();
 
   EXPECT_TRUE(GetNotificationBarLabel()->GetVisible());
+  // ClearAll label should always be visible.
+  EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
+}
+
+// Tests that the +n notifications label hides after being shown.
+TEST_F(UnifiedMessageCenterViewTest, StackingCounterLabelHidesAfterShown) {
+  AddManyNotifications();
+  CreateMessageCenterView();
+
+  // Scroll to the top, making the counter label invisible.
+  GetScroller()->ScrollToPosition(GetScrollBar(), 0);
+  message_center_view()->OnMessageCenterScrolled();
+
+  // Scrolling past 5 notifications should make the counter label visible.
+  const int scroll_amount = (GetMessageViewVisibleBounds(0).height() * 5) + 1;
+  GetScroller()->ScrollToPosition(GetScrollBar(), scroll_amount);
+  message_center_view()->OnMessageCenterScrolled();
+
+  ASSERT_TRUE(GetNotificationBarLabel()->GetVisible());
 
   // Scrolling back to the top should make the
   // counter label invisible again.
   GetScroller()->ScrollToPosition(GetScrollBar(), 0);
   message_center_view()->OnMessageCenterScrolled();
-  EXPECT_TRUE(GetNotificationBar()->GetVisible());
+
   EXPECT_FALSE(GetNotificationBarLabel()->GetVisible());
+  // ClearAll label should always be visible.
   EXPECT_TRUE(GetNotificationBarClearAllButton()->GetVisible());
 }
 
+// Tests that there are never more than 3 stacked icons in the
+// StackedNotificationBar. Also verifies that only one animation happens at a
+// time (this prevents the user from over-scrolling and showing multiple
+// animations when they scroll very quickly). Before, users could scroll fast
+// and have a large amount of icons, instead of keeping it to 3.
+TEST_F(UnifiedMessageCenterViewTest, StackingIconsNeverMoreThanThree) {
+  for (int i = 0; i < 20; ++i)
+    AddNotification(false);
+  CreateMessageCenterView();
+
+  // Force animations to happen, so we can see if multiple animations trigger.
+  ui::ScopedAnimationDurationScaleMode scoped_duration_modifier(
+      ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION);
+  // Scroll past 20 notifications, so we can scroll back up quickly.
+  for (int i = 20; i >= 0; --i) {
+    const int scroll_amount = (GetMessageViewVisibleBounds(0).height() * i) + 1;
+    GetScroller()->ScrollToPosition(GetScrollBar(), scroll_amount);
+    message_center_view()->OnMessageCenterScrolled();
+
+    auto icons_container_children =
+        GetNotificationBarIconsContainer()->children();
+    int animating_count = 0;
+    for (auto* child : icons_container_children) {
+      // Verify that no more than one icon is animating at any one time.
+      if (child->layer()->GetAnimator()->is_animating())
+        animating_count++;
+    }
+    EXPECT_GE(1, animating_count);
+    // Verify that no more than 3 icons are added to the bar at any one time,
+    // regardless of how fast the user scrolls. This test scrolls faster than
+    // the icons can animate away, and animating icons should be removed prior
+    // to starting a new animation.
+    EXPECT_GE(3u, icons_container_children.size());
+  }
+}
+
 // Flaky: crbug.com/1163575
 TEST_F(UnifiedMessageCenterViewTest,
        DISABLED_StackingCounterNotificationRemoval) {
diff --git a/ash/webui/diagnostics_ui/resources/routine_group.js b/ash/webui/diagnostics_ui/resources/routine_group.js
index 01e6f17..89016620 100644
--- a/ash/webui/diagnostics_ui/resources/routine_group.js
+++ b/ash/webui/diagnostics_ui/resources/routine_group.js
@@ -78,16 +78,19 @@
       // Prevent 1st failed test from being overwritten.
       this.failedTest = this.failedTest || status.routine;
 
-      const blocking = !this.nonBlockingRoutines_.has(status.routine);
-      this.inWarningState = this.inWarningState || !blocking;
-      this.progress = isLastRoutine ? ExecutionProgress.kCompleted :
-                                      ExecutionProgress.kWarning;
-      return;
+      const isBlocking = !this.nonBlockingRoutines_.has(status.routine);
+      this.inWarningState = this.inWarningState || !isBlocking;
+
+      // We've encountered a blocking failure.
+      if (this.failedTest && isBlocking) {
+        this.progress = ExecutionProgress.kCompleted;
+        return;
+      }
     }
 
-    // Set status to "completed" only when all routines in this group
-    // are finished running. Otherwise, check if we're in the warning
-    // state before setting the progress to running.
+    // Set status to "completed" only when all routines in this group are
+    // finished running. Otherwise, check if we're in the warning state
+    // before setting the progress to running.
     this.progress = isLastRoutine ?
         ExecutionProgress.kCompleted :
         this.inWarningState ? ExecutionProgress.kWarning :
diff --git a/ash/wm/overview/desks_templates/desks_templates_unittest.cc b/ash/wm/overview/desks_templates/desks_templates_unittest.cc
new file mode 100644
index 0000000..938c2bd4
--- /dev/null
+++ b/ash/wm/overview/desks_templates/desks_templates_unittest.cc
@@ -0,0 +1,117 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <string>
+
+#include "ash/constants/ash_features.h"
+#include "ash/public/cpp/desk_template.h"
+#include "ash/shell.h"
+#include "ash/wm/desks/desks_bar_view.h"
+#include "ash/wm/overview/overview_grid.h"
+#include "ash/wm/overview/overview_session.h"
+#include "ash/wm/overview/overview_test_base.h"
+#include "ash/wm/overview/overview_test_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/guid.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/bind.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/time/time.h"
+#include "components/desks_storage/core/local_desk_data_manager.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+
+class DesksTemplatesTest : public OverviewTestBase {
+ public:
+  DesksTemplatesTest() = default;
+  DesksTemplatesTest(const DesksTemplatesTest&) = delete;
+  DesksTemplatesTest& operator=(const DesksTemplatesTest&) = delete;
+  ~DesksTemplatesTest() override = default;
+
+  desks_storage::LocalDeskDataManager* desk_model() {
+    return desk_model_.get();
+  }
+
+  // Adds an entry to the desks model directly without capturing a desk. Allows
+  // for testing the names and times of the UI directly.
+  void AddEntry(const base::GUID& uuid,
+                const std::string& name,
+                base::Time created_time) {
+    auto desk_template = std::make_unique<DeskTemplate>(
+        uuid.AsLowercaseString(), name, created_time);
+    desk_template->set_desk_restore_data(
+        std::make_unique<app_restore::RestoreData>());
+
+    base::RunLoop loop;
+    desk_model()->AddOrUpdateEntry(
+        std::move(desk_template),
+        base::BindLambdaForTesting(
+            [&](desks_storage::DeskModel::AddOrUpdateEntryStatus status) {
+              EXPECT_EQ(desks_storage::DeskModel::AddOrUpdateEntryStatus::kOk,
+                        status);
+              loop.Quit();
+            }));
+    loop.Run();
+  }
+
+  // OverviewTestBase:
+  void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(features::kDesksTemplates);
+
+    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
+    desk_model_ = std::make_unique<desks_storage::LocalDeskDataManager>(
+        temp_dir_.GetPath());
+
+    OverviewTestBase::SetUp();
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+
+  // The desks model for tests.
+  std::unique_ptr<desks_storage::LocalDeskDataManager> desk_model_;
+
+  // Temporary directory for the local desk model to store data.
+  base::ScopedTempDir temp_dir_;
+};
+
+// Tests that the desks templates button is created when the feature is turned
+// on.
+// TODO(sammiequon): Update this test once more logic is added to the desks
+// templates button.
+TEST_F(DesksTemplatesTest, DesksTemplatesButtonVisibility) {
+  ToggleOverview();
+  auto* overview_session = GetOverviewSession();
+  ASSERT_TRUE(overview_session);
+
+  const auto* overview_grid =
+      overview_session->GetGridWithRootWindow(Shell::GetPrimaryRootWindow());
+  const auto* desks_bar_view = overview_grid->desks_bar_view();
+  EXPECT_TRUE(desks_bar_view->desks_templates_button());
+}
+
+// Tests the helper `AddEntry()`, which will be used in different tests.
+TEST_F(DesksTemplatesTest, AddEntry) {
+  const base::GUID expected_uuid = base::GUID::GenerateRandomV4();
+  const std::string expected_name = "desk name";
+  base::Time expected_time = base::Time::Now();
+  AddEntry(expected_uuid, expected_name, expected_time);
+
+  base::RunLoop loop;
+  desk_model()->GetAllEntries(base::BindLambdaForTesting(
+      [&](desks_storage::DeskModel::GetAllEntriesStatus status,
+          std::vector<ash::DeskTemplate*> entries) {
+        EXPECT_EQ(desks_storage::DeskModel::GetAllEntriesStatus::kOk, status);
+        ASSERT_EQ(1ul, entries.size());
+        EXPECT_EQ(expected_uuid, entries[0]->uuid());
+        EXPECT_EQ(base::UTF8ToUTF16(expected_name),
+                  entries[0]->template_name());
+        EXPECT_EQ(expected_time, entries[0]->created_time());
+        loop.Quit();
+      }));
+  loop.Run();
+}
+
+}  // namespace ash
diff --git a/ash/wm/overview/overview_test_base.cc b/ash/wm/overview/overview_test_base.cc
index 6260e16..c5905bc3 100644
--- a/ash/wm/overview/overview_test_base.cc
+++ b/ash/wm/overview/overview_test_base.cc
@@ -6,7 +6,6 @@
 
 #include "ash/public/cpp/presentation_time_recorder.h"
 #include "ash/shelf/shelf.h"
-#include "ash/shelf/shelf_view_test_api.h"
 #include "ash/shell.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_grid.h"
diff --git a/ash/wm/overview/overview_test_base.h b/ash/wm/overview/overview_test_base.h
index 95469c05..7ab463ec 100644
--- a/ash/wm/overview/overview_test_base.h
+++ b/ash/wm/overview/overview_test_base.h
@@ -5,9 +5,11 @@
 #ifndef ASH_WM_OVERVIEW_OVERVIEW_TEST_BASE_H_
 #define ASH_WM_OVERVIEW_OVERVIEW_TEST_BASE_H_
 
+#include <memory>
 #include <string>
 #include <vector>
 
+#include "ash/shelf/shelf_view_test_api.h"
 #include "ash/test/ash_test_base.h"
 
 namespace views {
@@ -22,7 +24,6 @@
 class OverviewItem;
 class OverviewSession;
 class ScopedOverviewTransformWindow;
-class ShelfViewTestAPI;
 class SplitViewController;
 class WindowPreviewView;
 
@@ -32,6 +33,8 @@
   template <typename... TaskEnvironmentTraits>
   explicit OverviewTestBase(TaskEnvironmentTraits&&... traits)
       : AshTestBase(std::forward<TaskEnvironmentTraits>(traits)...) {}
+  OverviewTestBase(const OverviewTestBase&) = delete;
+  OverviewTestBase& operator=(const OverviewTestBase&) = delete;
   ~OverviewTestBase() override;
 
   // Enters tablet mode. Needed by tests that test dragging and or splitview,
diff --git a/ash/wm/overview/overview_test_util.h b/ash/wm/overview/overview_test_util.h
index 89ce2b7..a29e6e0 100644
--- a/ash/wm/overview/overview_test_util.h
+++ b/ash/wm/overview/overview_test_util.h
@@ -25,8 +25,8 @@
 void ToggleOverview(
     OverviewEnterExitType type = OverviewEnterExitType::kNormal);
 
-// Waits for the overview enter/exit anmations to finish. No-op and immediately
-// return if animations are disabled.
+// Waits for the overview enter/exit animations to finish. No-op and immediately
+// returns if animations are disabled.
 void WaitForOverviewEnterAnimation();
 void WaitForOverviewExitAnimation();
 
diff --git a/build/fuchsia/common_args.py b/build/fuchsia/common_args.py
index 3098f6a2..a357e1d 100644
--- a/build/fuchsia/common_args.py
+++ b/build/fuchsia/common_args.py
@@ -28,7 +28,7 @@
   device_args.add_argument('--device',
                            default=None,
                            choices=BUILTIN_TARGET_NAMES + ['custom'],
-                           help='Choose to run on aemu|qemu|device. '
+                           help='Choose to run on fvdl|aemu|qemu|device. '
                            'By default, Fuchsia will run on AEMU on x64 '
                            'hosts and QEMU on arm64 hosts. Alternatively, '
                            'setting to custom will require specifying the '
@@ -160,6 +160,6 @@
   if args.device:
     device = args.device
   else:
-    device = 'aemu' if args.target_cpu == 'x64' else 'qemu'
+    device = 'fvdl' if args.target_cpu == 'x64' else 'qemu'
 
   return _LoadTargetClass(_GetPathToBuiltinTarget(device)).CreateFromArgs(args)
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 9778107..0a3283f 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-6.20210924.1.1
+6.20210925.0.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 9778107..35260c5 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-6.20210924.1.1
+6.20210924.3.1
diff --git a/chrome/VERSION b/chrome/VERSION
index 7ecd409..5ef82d45 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=96
 MINOR=0
-BUILD=4653
+BUILD=4654
 PATCH=0
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index 2733d3e4..0222e90 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -454,6 +454,8 @@
   "java/res/drawable/arrow_down.xml",
   "java/res/drawable/arrow_up.xml",
   "java/res/drawable/bg_white_dialog.xml",
+  "java/res/drawable/bookmark_save_flow_background.xml",
+  "java/res/drawable/bookmark_save_flow_ripple.xml",
   "java/res/drawable/bookmark_title_bar_shadow.xml",
   "java/res/drawable/bookmark_widget_list_selector.xml",
   "java/res/drawable/btn_back.xml",
@@ -579,6 +581,7 @@
   "java/res/layout/bookmark_folder_select_activity.xml",
   "java/res/layout/bookmark_item_row.xml",
   "java/res/layout/bookmark_main.xml",
+  "java/res/layout/bookmark_save_flow.xml",
   "java/res/layout/bookmark_section_header.xml",
   "java/res/layout/bookmark_widget.xml",
   "java/res/layout/bookmark_widget_icons_only.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 793c97c..535e48b0 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -170,6 +170,10 @@
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java",
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkPromoHeader.java",
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkRow.java",
+  "java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowCoordinator.java",
+  "java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java",
+  "java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java",
+  "java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java",
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkTextInputLayout.java",
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUIObserver.java",
   "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUIState.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
index f8687820..964ebcdc 100644
--- a/chrome/android/chrome_test_java_sources.gni
+++ b/chrome/android/chrome_test_java_sources.gni
@@ -79,6 +79,7 @@
   "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedPromoRenderTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoDismissTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkPersonalizedSigninPromoTest.java",
+  "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTagChipListTest.java",
   "javatests/src/org/chromium/chrome/browser/bookmarks/PowerBookmarkTest.java",
diff --git a/chrome/android/expectations/lint-baseline.xml b/chrome/android/expectations/lint-baseline.xml
index 072cffc5..b20bba2 100644
--- a/chrome/android/expectations/lint-baseline.xml
+++ b/chrome/android/expectations/lint-baseline.xml
@@ -91,86 +91,6 @@
 
     <issue
         id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetCoordinator.java"
-            line="121"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetCoordinator.java"
-            line="127"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetCoordinator.java"
-            line="127"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetCoordinator.java"
-            line="128"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/bottomsheet/BookmarkBottomSheetCoordinator.java"
-            line="128"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java"
-            line="64"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java"
-            line="71"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java"
-            line="73"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkFolderRow.java"
-            line="73"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
-        message="Must be one of: BookmarkType.NORMAL, BookmarkType.PARTNER, BookmarkType.READING_LIST, BookmarkType.LAST">
-        <location
-            file="../../chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java"
-            line="406"/>
-    </issue>
-
-    <issue
-        id="WrongConstant"
         message="Must be one of: PageTransition.FIRST, PageTransition.LINK, PageTransition.TYPED, PageTransition.AUTO_BOOKMARK, PageTransition.AUTO_SUBFRAME, PageTransition.MANUAL_SUBFRAME, PageTransition.GENERATED, PageTransition.AUTO_TOPLEVEL, PageTransition.FORM_SUBMIT, PageTransition.RELOAD, PageTransition.KEYWORD, PageTransition.KEYWORD_GENERATED, PageTransition.LAST_CORE, PageTransition.CORE_MASK, PageTransition.BLOCKED, PageTransition.FORWARD_BACK, PageTransition.FROM_ADDRESS_BAR, PageTransition.HOME_PAGE, PageTransition.FROM_API, PageTransition.CHAIN_START, PageTransition.CHAIN_END, PageTransition.CLIENT_REDIRECT, PageTransition.SERVER_REDIRECT, PageTransition.IS_REDIRECT_MASK, PageTransition.QUALIFIER_MASK">
         <location
             file="../../chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java"
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinder.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinder.java
index e7ed85b9..007032e 100644
--- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinder.java
+++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinder.java
@@ -76,7 +76,10 @@
     private static void setBottomBarHeight(ViewHolder viewHolder, int height) {
         MarginLayoutParams layoutParams =
                 (MarginLayoutParams) viewHolder.tasksSurfaceView.getLayoutParams();
-        if (layoutParams != null) layoutParams.bottomMargin = height;
+        if (layoutParams != null) {
+            layoutParams.bottomMargin = height;
+            viewHolder.tasksSurfaceView.setLayoutParams(layoutParams);
+        }
     }
 
     private static void setTopBarHeight(ViewHolder viewHolder, int height) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java
index 6b3cfe13..fa38099 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUi.java
@@ -4,7 +4,6 @@
 
 package org.chromium.chrome.browser.tasks.tab_management;
 
-import org.chromium.base.supplier.Supplier;
 import org.chromium.chrome.browser.toolbar.bottom.BottomControlsContentDelegate;
 
 /**
@@ -12,7 +11,7 @@
  */
 public interface TabGroupUi extends BottomControlsContentDelegate {
     /**
-     * @return {@link Supplier} that provides dialog visibility.
+     * @return Whether the TabGridDialog is visible.
      */
-    Supplier<Boolean> getTabGridDialogVisibilitySupplier();
+    boolean isTabGridDialogVisible();
 }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
index d1be8d2..e44c6e00 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiCoordinator.java
@@ -186,8 +186,8 @@
      * @return {@link Supplier} that provides dialog visibility.
      */
     @Override
-    public Supplier<Boolean> getTabGridDialogVisibilitySupplier() {
-        return () -> mTabGridDialogCoordinator != null && mTabGridDialogCoordinator.isVisible();
+    public boolean isTabGridDialogVisible() {
+        return mTabGridDialogCoordinator != null && mTabGridDialogCoordinator.isVisible();
     }
 
     /**
diff --git a/chrome/android/java/res/drawable/bookmark_save_flow_background.xml b/chrome/android/java/res/drawable/bookmark_save_flow_background.xml
new file mode 100644
index 0000000..b54fcea
--- /dev/null
+++ b/chrome/android/java/res/drawable/bookmark_save_flow_background.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <solid android:color="@color/default_bg_color" />
+    <stroke android:width="1dp" android:color="@color/hairline_stroke_color"/>
+    <corners android:radius="@dimen/default_rounded_corner_radius" />
+</shape>
diff --git a/chrome/android/java/res/drawable/bookmark_save_flow_ripple.xml b/chrome/android/java/res/drawable/bookmark_save_flow_ripple.xml
new file mode 100644
index 0000000..b990134
--- /dev/null
+++ b/chrome/android/java/res/drawable/bookmark_save_flow_ripple.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="?android:attr/colorControlHighlight">
+    <item android:id="@android:id/mask"
+          android:drawable="@drawable/bookmark_save_flow_background" />
+</ripple>
diff --git a/chrome/android/java/res/layout/bookmark_save_flow.xml b/chrome/android/java/res/layout/bookmark_save_flow.xml
new file mode 100644
index 0000000..afe4c8ab
--- /dev/null
+++ b/chrome/android/java/res/layout/bookmark_save_flow.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<org.chromium.ui.widget.ViewLookupCachingFrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_height="match_parent"
+    android:layout_width="match_parent">
+
+  <LinearLayout
+    android:layout_height="match_parent"
+    android:layout_width="match_parent"
+    android:padding="24dp"
+    android:orientation="vertical">
+
+    <LinearLayout
+      android:layout_height="wrap_content"
+      android:layout_width="match_parent"
+      android:orientation="horizontal">
+
+      <org.chromium.ui.widget.ChromeImageView
+          android:id="@+id/title_start_icon"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_gravity="center_vertical|end" />
+
+      <TextView
+          android:id="@+id/title_text"
+          android:layout_width="0dp"
+          android:layout_height="wrap_content"
+          android:ellipsize="end"
+          android:layout_gravity="center_vertical"
+          android:textAppearance="@style/TextAppearance.HeadlineThick"
+          android:layout_weight="1" />
+
+      <TextView
+          android:id="@+id/bookmark_edit"
+          android:text="@string/edit_bookmark"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:layout_gravity="center_vertical|end"
+          android:textAppearance="@style/TextAppearance.TextMedium.Blue" />
+
+    </LinearLayout>
+
+    <FrameLayout
+        android:background="@drawable/bookmark_save_flow_background"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:layout_marginTop="16dp">
+
+      <LinearLayout
+        android:id="@+id/bookmark_select_folder"
+        android:background="@drawable/bookmark_save_flow_ripple"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:padding="16dp"
+        android:orientation="horizontal">
+
+        <org.chromium.ui.widget.ChromeImageView
+            android:id="@+id/bookmark_folder_icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical" />
+
+        <TextView
+            android:id="@+id/bookmark_folder_text"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:ellipsize="end"
+            android:layout_gravity="center_vertical"
+            android:layout_marginStart="16dp"
+            android:textAppearance="@style/TextAppearance.TextLarge"
+            android:layout_weight="1" />
+
+        <org.chromium.ui.widget.ChromeImageView
+            android:id="@+id/bookmark_folder_edit_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:src="@drawable/ic_edit_24dp"
+            android:tint="@color/default_icon_color_tint_list" />
+      </LinearLayout>
+    </FrameLayout>
+
+    <TextView
+      android:id="@+id/subtitle_text"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:ellipsize="end"
+      android:layout_gravity="center_vertical"
+      android:textAppearance="@style/TextAppearance.TextMedium.Secondary"
+      android:visibility="gone" />
+  </LinearLayout>
+</org.chromium.ui.widget.ViewLookupCachingFrameLayout>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 1939304..9ddfc68 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1677,16 +1677,14 @@
                 assert mStartSurfaceSupplier.get() != null;
                 assert getToolbarManager().getTabGroupUi() != null;
                 // Return true if dialog from either tab switcher or tab strip is visible.
+
                 ToolbarManager toolbarManager = getToolbarManager();
                 TabGroupUi tabGroupUi = toolbarManager.getTabGroupUi();
-                Supplier<Boolean> tabGroupUiDialogVisibilitySupplier =
-                        tabGroupUi.getTabGridDialogVisibilitySupplier();
+                boolean isDialogVisible = tabGroupUi.isTabGridDialogVisible();
+
                 Supplier<Boolean> tabSwitcherDialogVisibilitySupplier =
                         mStartSurfaceSupplier.get().getTabGridDialogVisibilitySupplier();
-                boolean isDialogVisible = false;
-                if (tabGroupUiDialogVisibilitySupplier != null) {
-                    isDialogVisible = tabGroupUiDialogVisibilitySupplier.get();
-                }
+
                 if (tabSwitcherDialogVisibilitySupplier != null) {
                     isDialogVisible = isDialogVisible || tabSwitcherDialogVisibilitySupplier.get();
                 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
index d21ea1c..640137f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkItemsAdapter.java
@@ -24,6 +24,8 @@
 import org.chromium.chrome.browser.bookmarks.BookmarkListEntry.ViewType;
 import org.chromium.chrome.browser.bookmarks.BookmarkRow.Location;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
+import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkMeta;
+import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkType;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.signin.ui.PersonalizedSigninPromoView;
 import org.chromium.chrome.browser.sync.SyncService;
@@ -144,7 +146,8 @@
 
         // Show the tag chiplist only for the shopping folder.
         // TODO(crbug.com/1247825): Clarify how the tag list should interact with promo headers.
-        if (mCurrentFolder.getType() == ViewType.SHOPPING_POWER_BOOKMARK) {
+        PowerBookmarkMeta meta = mDelegate.getModel().getPowerBookmarkMeta(mCurrentFolder);
+        if (meta != null && meta.getType() == PowerBookmarkType.SHOPPING) {
             mElements.add(BookmarkListEntry.createChipList());
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowCoordinator.java
new file mode 100644
index 0000000..cf9a5bf
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowCoordinator.java
@@ -0,0 +1,165 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.base.lifetime.DestroyChecker;
+import org.chromium.chrome.R;
+import org.chromium.components.bookmarks.BookmarkId;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetContent;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
+import org.chromium.ui.widget.ViewLookupCachingFrameLayout;
+
+/** Coordinates the bottom-sheet saveflow. */
+public class BookmarkSaveFlowCoordinator {
+    private final Context mContext;
+    private final PropertyModel mPropertyModel =
+            new PropertyModel(BookmarkSaveFlowProperties.ALL_PROPERTIES);
+    private final PropertyModelChangeProcessor<PropertyModel, ViewLookupCachingFrameLayout,
+            PropertyKey> mChangeProcessor;
+    private final DestroyChecker mDestroyChecker;
+
+    private BottomSheetController mBottomSheetController;
+    private BookmarkSaveFlowBottomSheetContent mBottomSheetContent;
+    private BookmarkSaveFlowMediator mMediator;
+    private View mBookmarkSaveFlowView;
+
+    private BookmarkModel mBookmarkModel;
+
+    /**
+     * @param context The {@link Context} associated with this cooridnator.
+     * @param bottomSheetController Allows displaying content in the bottom sheet.
+     */
+    public BookmarkSaveFlowCoordinator(
+            @NonNull Context context, @NonNull BottomSheetController bottomSheetController) {
+        mContext = context;
+        mBottomSheetController = bottomSheetController;
+        mBookmarkModel = new BookmarkModel();
+        mDestroyChecker = new DestroyChecker();
+
+        mBookmarkSaveFlowView = LayoutInflater.from(mContext).inflate(
+                org.chromium.chrome.R.layout.bookmark_save_flow, /*root=*/null);
+        mMediator =
+                new BookmarkSaveFlowMediator(mBookmarkModel, mPropertyModel, mContext, this::close);
+        mChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel,
+                (ViewLookupCachingFrameLayout) mBookmarkSaveFlowView,
+                new BookmarkSaveFlowViewBinder());
+    }
+
+    /**
+     * Shows the bookmark save flow sheet.
+     */
+    public void show(BookmarkId bookmarkId) {
+        mDestroyChecker.checkNotDestroyed();
+        assert mBookmarkModel.isBookmarkModelLoaded();
+        mBottomSheetContent = new BookmarkSaveFlowBottomSheetContent(mBookmarkSaveFlowView);
+        mBottomSheetController.requestShowContent(mBottomSheetContent, /* animate= */ true);
+        mMediator.show(bookmarkId);
+    }
+
+    private void close() {
+        mDestroyChecker.checkNotDestroyed();
+        mBottomSheetController.hideContent(mBottomSheetContent, true);
+    }
+
+    private void destroy() {
+        mDestroyChecker.checkNotDestroyed();
+        mDestroyChecker.destroy();
+
+        mMediator.destroy();
+        mMediator = null;
+
+        mBookmarkSaveFlowView = null;
+
+        mBookmarkModel.destroy();
+        mBookmarkModel = null;
+
+        mChangeProcessor.destroy();
+    }
+
+    private class BookmarkSaveFlowBottomSheetContent implements BottomSheetContent {
+        private final View mContentView;
+
+        BookmarkSaveFlowBottomSheetContent(View contentView) {
+            mContentView = contentView;
+        }
+
+        @Override
+        public View getContentView() {
+            return mContentView;
+        }
+
+        @Nullable
+        @Override
+        public View getToolbarView() {
+            return null;
+        }
+
+        @Override
+        public int getVerticalScrollOffset() {
+            return 0;
+        }
+
+        @Override
+        public void destroy() {
+            BookmarkSaveFlowCoordinator.this.destroy();
+        }
+
+        @Override
+        public int getPriority() {
+            return BottomSheetContent.ContentPriority.HIGH;
+        }
+
+        @Override
+        public int getPeekHeight() {
+            return BottomSheetContent.HeightMode.DISABLED;
+        }
+
+        @Override
+        public float getFullHeightRatio() {
+            return BottomSheetContent.HeightMode.WRAP_CONTENT;
+        }
+
+        @Override
+        public boolean swipeToDismissEnabled() {
+            return true;
+        }
+
+        @Override
+        public int getSheetContentDescriptionStringId() {
+            return R.string.bookmarks_bottom_sheet_content_description;
+        }
+
+        @Override
+        public int getSheetHalfHeightAccessibilityStringId() {
+            return R.string.bookmarks_bottom_sheet_opened_half;
+        }
+
+        @Override
+        public int getSheetFullHeightAccessibilityStringId() {
+            return R.string.bookmarks_bottom_sheet_opened_full;
+        }
+
+        @Override
+        public int getSheetClosedAccessibilityStringId() {
+            return R.string.bookmarks_bottom_sheet_closed;
+        }
+    }
+
+    @VisibleForTesting
+    View getViewForTesting() {
+        return mBookmarkSaveFlowView;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java
new file mode 100644
index 0000000..31d4cfd
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowMediator.java
@@ -0,0 +1,85 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.content.Context;
+
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
+import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
+import org.chromium.components.bookmarks.BookmarkId;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/** Controls the bookmarks save-flow. */
+public class BookmarkSaveFlowMediator extends BookmarkModelObserver {
+    private final Context mContext;
+    private final Runnable mCloseRunnable;
+    private PropertyModel mPropertyModel;
+    private BookmarkModel mBookmarkModel;
+    private BookmarkId mBookmarkId;
+
+    /**
+     * @param bookmarkModel The {@link BookmarkModel} which supplies the data.
+     * @param propertyModel The {@link PropertyModel} which allows the mediator to push data to the
+     *         model.
+     * @param context The {@link Context} associated with this mediator.
+     * @param closeRunnable A {@link Runnable} which closes the bookmark save flow.
+     */
+    public BookmarkSaveFlowMediator(BookmarkModel bookmarkModel, PropertyModel propertyModel,
+            Context context, Runnable closeRunnable) {
+        mBookmarkModel = bookmarkModel;
+        mPropertyModel = propertyModel;
+        mContext = context;
+        mCloseRunnable = closeRunnable;
+        mBookmarkModel.addObserver(this);
+    }
+
+    /**
+     * Shows bottom sheet save-flow for the given {@link BookmarkId}.
+     *
+     * @param bookmarkId The {@link BookmarkId} to show.
+     */
+    public void show(BookmarkId bookmarkId) {
+        mBookmarkId = bookmarkId;
+
+        bindBookmarkProperties(mBookmarkId);
+        mPropertyModel.set(BookmarkSaveFlowProperties.EDIT_ONCLICK_LISTENER, (v) -> {
+            BookmarkUtils.startEditActivity(mContext, mBookmarkId);
+            mCloseRunnable.run();
+        });
+        mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_ONCLICK_LISTENER, (v) -> {
+            BookmarkUtils.startFolderSelectActivity(mContext, mBookmarkId);
+            mCloseRunnable.run();
+        });
+    }
+
+    private void bindBookmarkProperties(BookmarkId bookmarkId) {
+        BookmarkItem item = mBookmarkModel.getBookmarkById(bookmarkId);
+        mPropertyModel.set(BookmarkSaveFlowProperties.TITLE_START_ICON,
+                BookmarkUtils.getSaveFlowStartIconForBookmark(bookmarkId));
+        mPropertyModel.set(BookmarkSaveFlowProperties.TITLE_TEXT,
+                BookmarkUtils.getSaveFlowTitleForBookmark(mContext, bookmarkId));
+        mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_START_ICON,
+                BookmarkUtils.getFolderIcon(mContext, bookmarkId.getType()));
+        mPropertyModel.set(BookmarkSaveFlowProperties.FOLDER_SELECT_TEXT,
+                mBookmarkModel.getBookmarkTitle(item.getParentId()));
+        mPropertyModel.set(BookmarkSaveFlowProperties.SUBTITLE_TEXT,
+                BookmarkUtils.getSaveFlowSubtitleForBookmark(bookmarkId));
+    }
+
+    void destroy() {
+        mBookmarkModel.removeObserver(this);
+        mBookmarkModel = null;
+        mPropertyModel = null;
+        mBookmarkId = null;
+    }
+
+    // BookmarkModelObserver implementation
+
+    @Override
+    public void bookmarkModelChanged() {
+        if (mBookmarkId == null) return;
+        bindBookmarkProperties(mBookmarkId);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java
new file mode 100644
index 0000000..d154ed91
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowProperties.java
@@ -0,0 +1,36 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.graphics.drawable.Drawable;
+import android.view.View;
+
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
+
+/** Hosts the properties for the bookmarks save flow. */
+public class BookmarkSaveFlowProperties {
+    public static final WritableObjectPropertyKey<View.OnClickListener> EDIT_ONCLICK_LISTENER =
+            new WritableObjectPropertyKey<>();
+    public static final WritableObjectPropertyKey<View.OnClickListener>
+            FOLDER_SELECT_ONCLICK_LISTENER = new WritableObjectPropertyKey<>();
+
+    public static final WritableObjectPropertyKey<Drawable> TITLE_START_ICON =
+            new WritableObjectPropertyKey<>();
+    public static final WritableObjectPropertyKey<CharSequence> TITLE_TEXT =
+            new WritableObjectPropertyKey<>();
+
+    public static final WritableObjectPropertyKey<Drawable> FOLDER_SELECT_START_ICON =
+            new WritableObjectPropertyKey<>();
+    public static final WritableObjectPropertyKey<CharSequence> FOLDER_SELECT_TEXT =
+            new WritableObjectPropertyKey<>();
+
+    public static final WritableObjectPropertyKey<CharSequence> SUBTITLE_TEXT =
+            new WritableObjectPropertyKey<>();
+
+    public static final PropertyKey[] ALL_PROPERTIES = {EDIT_ONCLICK_LISTENER,
+            FOLDER_SELECT_ONCLICK_LISTENER, TITLE_START_ICON, TITLE_TEXT, FOLDER_SELECT_START_ICON,
+            FOLDER_SELECT_TEXT, SUBTITLE_TEXT};
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java
new file mode 100644
index 0000000..3ee0095
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowViewBinder.java
@@ -0,0 +1,48 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.chromium.chrome.R;
+import org.chromium.ui.modelutil.PropertyKey;
+import org.chromium.ui.modelutil.PropertyModel;
+import org.chromium.ui.modelutil.PropertyModelChangeProcessor.ViewBinder;
+import org.chromium.ui.widget.ViewLookupCachingFrameLayout;
+
+/** ViewBinder for the bookmarks save flow. */
+public class BookmarkSaveFlowViewBinder
+        implements ViewBinder<PropertyModel, ViewLookupCachingFrameLayout, PropertyKey> {
+    @Override
+    public void bind(
+            PropertyModel model, ViewLookupCachingFrameLayout view, PropertyKey propertyKey) {
+        if (propertyKey == BookmarkSaveFlowProperties.EDIT_ONCLICK_LISTENER) {
+            view.findViewById(R.id.bookmark_edit)
+                    .setOnClickListener(
+                            model.get(BookmarkSaveFlowProperties.EDIT_ONCLICK_LISTENER));
+        } else if (propertyKey == BookmarkSaveFlowProperties.FOLDER_SELECT_ONCLICK_LISTENER) {
+            view.findViewById(R.id.bookmark_select_folder)
+                    .setOnClickListener(
+                            model.get(BookmarkSaveFlowProperties.FOLDER_SELECT_ONCLICK_LISTENER));
+        } else if (propertyKey == BookmarkSaveFlowProperties.TITLE_START_ICON) {
+            ((ImageView) view.findViewById(R.id.title_start_icon))
+                    .setImageDrawable(model.get(BookmarkSaveFlowProperties.TITLE_START_ICON));
+        } else if (propertyKey == BookmarkSaveFlowProperties.TITLE_TEXT) {
+            ((TextView) view.findViewById(R.id.title_text))
+                    .setText(model.get(BookmarkSaveFlowProperties.TITLE_TEXT));
+        } else if (propertyKey == BookmarkSaveFlowProperties.FOLDER_SELECT_START_ICON) {
+            ((ImageView) view.findViewById(R.id.bookmark_folder_icon))
+                    .setImageDrawable(
+                            model.get(BookmarkSaveFlowProperties.FOLDER_SELECT_START_ICON));
+        } else if (propertyKey == BookmarkSaveFlowProperties.FOLDER_SELECT_TEXT) {
+            ((TextView) view.findViewById(R.id.bookmark_folder_text))
+                    .setText(model.get(BookmarkSaveFlowProperties.FOLDER_SELECT_TEXT));
+        } else if (propertyKey == BookmarkSaveFlowProperties.SUBTITLE_TEXT) {
+            ((TextView) view.findViewById(R.id.subtitle_text))
+                    .setText(model.get(BookmarkSaveFlowProperties.SUBTITLE_TEXT));
+        }
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
index 1504d6dc..cda1735 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
@@ -93,6 +93,15 @@
             return;
         }
 
+        if (isImprovedSaveFlowEnabled()) {
+            BookmarkId newBookmarkId =
+                    addBookmarkAndShowSaveFlow(activity, bookmarkModel, tab, bottomSheetController);
+            callback.onResult(newBookmarkId);
+            return;
+        }
+
+        // TODO(crbug.com/1249283): Add separate entrypoint to save reading list items that uses
+        // the improved save flow.
         if (CachedFeatureFlags.isEnabled(ChromeFeatureList.BOOKMARK_BOTTOM_SHEET)) {
             // Show a bottom sheet to let the user select target bookmark folder.
             showBookmarkBottomSheet(bookmarkModel, tab, snackbarManager, bottomSheetController,
@@ -132,6 +141,17 @@
         });
     }
 
+    private static BookmarkId addBookmarkAndShowSaveFlow(Activity activity,
+            BookmarkModel bookmarkModel, Tab tab, BottomSheetController bottomSheetController) {
+        BookmarkId bookmarkId =
+                addBookmarkInternal(activity, bookmarkModel, tab.getTitle(), tab.getOriginalUrl());
+        BookmarkSaveFlowCoordinator bookmarkSaveFlowCoordinator =
+                new BookmarkSaveFlowCoordinator(activity, bottomSheetController);
+        bookmarkSaveFlowCoordinator.show(bookmarkId);
+
+        return bookmarkId;
+    }
+
     // The legacy code path to add or edit bookmark without triggering the bookmark bottom sheet.
     private static BookmarkId addBookmarkAndShowSnackbar(BookmarkModel bookmarkModel, Tab tab,
             SnackbarManager snackbarManager, Activity activity, boolean fromCustomTab) {
@@ -383,6 +403,11 @@
         }
     }
 
+    /** Starts an {@link BookmarkFolderSelectActivity} for the given {@link BookmarkId}. */
+    public static void startFolderSelectActivity(Context context, BookmarkId bookmarkId) {
+        BookmarkFolderSelectActivity.startFolderSelectActivity(context, bookmarkId);
+    }
+
     /**
      * Opens a bookmark and reports UMA.
      * @param context The current context used to launch the intent.
@@ -453,6 +478,40 @@
                                                    : R.color.default_icon_color_tint_list;
     }
 
+    /**
+     * Retrieve the save flow title for the given bookmark.
+     *
+     * @param context The current Android {@link Context}.
+     * @param bookmarkId The {@link BookmarkId} to get the title for.
+     * @return The title associated with the given bookmarkId.
+     */
+    public static String getSaveFlowTitleForBookmark(Context context, BookmarkId bookmarkId) {
+        // TODO(crbug.com/1243383): Add title for price tracking.
+        return context.getResources().getString(R.string.bookmark_page_saved_default);
+    }
+
+    /**
+     * Retrieve the save flow subtitle for the given bookmark.
+     *
+     * @param bookmarkId The {@link BookmarkId} to get the subtitle for.
+     * @return The subtitle associated with the given bookmarkId.
+     */
+    public static String getSaveFlowSubtitleForBookmark(BookmarkId bookmarkId) {
+        // TODO(crbug.com/1243383): Add subtitle for price tracking.
+        return null;
+    }
+
+    /**
+     * Retrieve the save flow start icon for the given bookmark.
+     *
+     * @param bookmarkId The {@link BookmarkId} to get the start icon for.
+     * @return The start icon associated with the given bookmarkId.
+     */
+    public static Drawable getSaveFlowStartIconForBookmark(BookmarkId bookmarkId) {
+        // TODO(crbug.com/1243383): Add start icon for price tracking.
+        return null;
+    }
+
     private static void openUrl(Context context, String url, ComponentName componentName) {
         Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
         intent.putExtra(
@@ -582,4 +641,9 @@
                     ChromePreferenceKeys.BOOKMARKS_LAST_USED_URL);
         }
     }
+
+    private static boolean isImprovedSaveFlowEnabled() {
+        return ChromeFeatureList.isInitialized()
+                && ChromeFeatureList.isEnabled(ChromeFeatureList.BOOKMARKS_IMPROVED_SAVE_FLOW);
+    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java
new file mode 100644
index 0000000..f3fa70b
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java
@@ -0,0 +1,134 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.bookmarks;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+
+import androidx.test.espresso.Espresso;
+import androidx.test.filters.MediumTest;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.ChromeTabbedActivity;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
+import org.chromium.chrome.browser.profiles.Profile;
+import org.chromium.chrome.test.ChromeActivityTestRule;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.chrome.test.util.BookmarkTestUtil;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
+import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
+import org.chromium.components.bookmarks.BookmarkId;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
+import org.chromium.components.browser_ui.bottomsheet.BottomSheetTestSupport;
+import org.chromium.content_public.browser.test.util.ClickUtils;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.DisableAnimationsTestRule;
+import org.chromium.url.GURL;
+
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+
+/** Tests for the bookmark save flow. */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+@EnableFeatures(ChromeFeatureList.OMNIBOX_ASSISTANT_VOICE_SEARCH)
+public class BookmarkSaveFlowTest {
+    @Rule
+    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
+
+    @Rule
+    public DisableAnimationsTestRule mDisableAnimationsTestRule = new DisableAnimationsTestRule();
+
+    @Rule
+    public ChromeRenderTestRule mRenderTestRule =
+            ChromeRenderTestRule.Builder.withPublicCorpus().build();
+
+    private BookmarkSaveFlowCoordinator mBookmarkSaveFlowCoordinator;
+    private BottomSheetController mBottomSheetController;
+    private BottomSheetTestSupport mBottomSheetTestSupport;
+    private BookmarkModel mBookmarkModel;
+    private BookmarkBridge mBookmarkBridge;
+
+    @Before
+    public void setUp() throws ExecutionException {
+        mActivityTestRule.startMainActivityOnBlankPage();
+        ChromeActivityTestRule.waitForActivityNativeInitializationComplete(
+                mActivityTestRule.getActivity());
+
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+            mBottomSheetController =
+                    cta.getRootUiCoordinatorForTesting().getBottomSheetController();
+            mBottomSheetTestSupport = new BottomSheetTestSupport(mBottomSheetController);
+            mBookmarkSaveFlowCoordinator =
+                    new BookmarkSaveFlowCoordinator(cta, mBottomSheetController);
+            mBookmarkModel = new BookmarkModel(Profile.fromWebContents(
+                    mActivityTestRule.getActivity().getActivityTab().getWebContents()));
+            mBookmarkBridge = mActivityTestRule.getActivity().getBookmarkBridgeForTesting();
+        });
+
+        loadBookmarkModel();
+        BookmarkId id = addBookmark("Test bookmark", new GURL("http://a.com"));
+        TestThreadUtils.runOnUiThreadBlocking(() -> { mBookmarkSaveFlowCoordinator.show(id); });
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    public void testBookmarkSaveFlow() throws IOException {
+        mRenderTestRule.render(
+                mBookmarkSaveFlowCoordinator.getViewForTesting(), "bookmark_save_flow");
+    }
+
+    @Test
+    @MediumTest
+    public void testBookmarkSaveFlowEdit() throws IOException {
+        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+        ClickUtils.clickButton(cta.findViewById(R.id.bookmark_edit));
+        onView(withText(mActivityTestRule.getActivity().getResources().getString(
+                       R.string.edit_bookmark)))
+                .check(matches(isDisplayed()));
+
+        // Dismiss the activity.
+        Espresso.pressBack();
+    }
+
+    @Test
+    @MediumTest
+    public void testBookmarkSaveFlowChooseFolder() throws IOException {
+        ChromeTabbedActivity cta = mActivityTestRule.getActivity();
+        ClickUtils.clickButton(cta.findViewById(R.id.bookmark_select_folder));
+        onView(withText(mActivityTestRule.getActivity().getResources().getString(
+                       R.string.bookmark_choose_folder)))
+                .check(matches(isDisplayed()));
+
+        // Dismiss the activity.
+        Espresso.pressBack();
+    }
+
+    private void loadBookmarkModel() {
+        // Do not read partner bookmarks in setUp(), so that the lazy reading is covered.
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> PartnerBookmarksShim.kickOffReading(mActivityTestRule.getActivity()));
+        BookmarkTestUtil.waitForBookmarkModelLoaded();
+    }
+
+    private BookmarkId addBookmark(final String title, final GURL url) throws ExecutionException {
+        return TestThreadUtils.runOnUiThreadBlocking(
+                () -> mBookmarkModel.addBookmark(mBookmarkModel.getDefaultFolder(), 0, title, url));
+    }
+}
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index aa439b1..83bdf638 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -854,6 +854,9 @@
   <message name="IDS_BLUETOOTH_PAIRING_LEARN_MORE" desc="Bluetooth pairing dialog: Message informing the user on what actions to take in order to see a device in the list of available devices.">
     Make sure your Bluetooth device is in pairing mode and nearby. <ph name="BEGIN_LINK_LEARN_MORE">&lt;a target="_blank" href="$1"&gt;</ph>Learn more<ph name="END_LINK_LEARN_MORE">&lt;/a&gt;</ph>
   </message>
+  <message name="IDS_BLUETOOTH_PAIRING_ENTER_PIN" desc="Bluetooth pairing dialog: Message displayed informing the user to enter a PIN in other to complete device pairing.">
+    Enter PIN to pair with <ph name="DEVICE_NAME">$1<ex>Nexus S</ex></ph>
+  </message>
 
   <!-- Strings for the OOBE packaged license screen -->
   <message name="IDS_OOBE_PACKAGED_LICENSE_TITLE" desc="Title of the screen which advertises use of packaged license.">
diff --git a/chrome/app/chromeos_strings_grdp/IDS_BLUETOOTH_PAIRING_ENTER_PIN.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_BLUETOOTH_PAIRING_ENTER_PIN.png.sha1
new file mode 100644
index 0000000..54d5fa4f
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_BLUETOOTH_PAIRING_ENTER_PIN.png.sha1
@@ -0,0 +1 @@
+dfb28105967fe87eb3934f7d00815bcd21b4d795
\ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index b0de3e10..4c12149 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -46,7 +46,6 @@
 #include "chrome/browser/net/stub_resolver_config_reader.h"
 #include "chrome/browser/net/system_network_context_manager.h"
 #include "chrome/browser/notifications/scheduler/public/features.h"
-#include "chrome/browser/performance_hints/performance_hints_features.h"
 #include "chrome/browser/performance_manager/policies/policy_features.h"
 #include "chrome/browser/permissions/abusive_origin_notifications_permission_revocation_config.h"
 #include "chrome/browser/permissions/quiet_notification_permission_ui_config.h"
@@ -3097,10 +3096,6 @@
      flag_descriptions::kDefaultCalculatorWebAppName,
      flag_descriptions::kDefaultCalculatorWebAppDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(web_app::kDefaultCalculatorWebApp)},
-    {"enable-notification-indicator",
-     flag_descriptions::kNotificationIndicatorName,
-     flag_descriptions::kNotificationIndicatorDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(features::kNotificationIndicator)},
     {"enable-notifications-revamp", flag_descriptions::kNotificationsRevampName,
      flag_descriptions::kNotificationsRevampDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kNotificationsRefresh)},
@@ -3320,6 +3315,10 @@
      flag_descriptions::kWebBluetoothNewPermissionsBackendDescription,
      kOsAndroid | kOsDesktop,
      FEATURE_VALUE_TYPE(features::kWebBluetoothNewPermissionsBackend)},
+    {"enable-webusb-device-detection",
+     flag_descriptions::kWebUsbDeviceDetectionName,
+     flag_descriptions::kWebUsbDeviceDetectionDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(features::kWebUsbDeviceDetection)},
 #if defined(USE_AURA)
     {"overscroll-history-navigation",
      flag_descriptions::kOverscrollHistoryNavigationName,
@@ -5745,6 +5744,11 @@
      flag_descriptions::kEnableShortcutCustomizationAppDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(features::kShortcutCustomizationApp)},
 
+    {"enable-firmware-updater-app",
+     flag_descriptions::kEnableFirmwareUpdaterAppName,
+     flag_descriptions::kEnableFirmwareUpdaterAppDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(ash::features::kFirmwareUpdaterApp)},
+
     {"enhanced-network-voices", flag_descriptions::kEnhancedNetworkVoicesName,
      flag_descriptions::kEnhancedNetworkVoicesDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(features::kEnhancedNetworkVoices)},
@@ -6420,13 +6424,6 @@
                                     kPasswordChangeFeatureVariations,
                                     "PasswordChangeFeatureVariations")},
 
-    {"context-menu-performance-info-and-remote-hints-fetching",
-     flag_descriptions::kContextMenuPerformanceInfoAndRemoteHintFetchingName,
-     flag_descriptions::
-         kContextMenuPerformanceInfoAndRemoteHintFetchingDescription,
-     kOsAndroid,
-     FEATURE_VALUE_TYPE(optimization_guide::features::
-                            kContextMenuPerformanceInfoAndRemoteHintFetching)},
 #endif  // !defined(OS_ANDROID)
 
 #if defined(OS_ANDROID)
@@ -7634,6 +7631,11 @@
      FEATURE_VALUE_TYPE(features::kCanvasOopRasterization)},
 
 #if defined(OS_ANDROID)
+    {"bookmarks-improved-save-flow",
+     flag_descriptions::kBookmarksImprovedSaveFlowName,
+     flag_descriptions::kBookmarksImprovedSaveFlowDescription, kOsAndroid,
+     FEATURE_VALUE_TYPE(chrome::android::kBookmarksImprovedSaveFlow)},
+
     {"bookmarks-refresh", flag_descriptions::kBookmarksRefreshName,
      flag_descriptions::kBookmarksRefreshDescription, kOsAndroid,
      FEATURE_VALUE_TYPE(chrome::android::kBookmarksRefresh)},
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
index 5977f7a6..1aac9e6 100644
--- a/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
+++ b/chrome/browser/ash/accessibility/spoken_feedback_app_list_browsertest.cc
@@ -12,7 +12,6 @@
 #include "ash/public/cpp/test/shell_test_api.h"
 #include "ash/shell.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ash/accessibility/spoken_feedback_browsertest.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_list_client_impl.h"
@@ -145,9 +144,7 @@
 
 class NotificationSpokenFeedbackAppListTest : public SpokenFeedbackAppListTest {
  protected:
-  NotificationSpokenFeedbackAppListTest() {
-    scoped_features_.InitWithFeatures({::features::kNotificationIndicator}, {});
-  }
+  NotificationSpokenFeedbackAppListTest() = default;
   ~NotificationSpokenFeedbackAppListTest() = default;
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
@@ -161,9 +158,6 @@
 
     item->UpdateNotificationBadgeForTesting(has_badge);
   }
-
- private:
-  base::test::ScopedFeatureList scoped_features_;
 };
 
 INSTANTIATE_TEST_SUITE_P(TestAsNormalAndGuestUser,
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
index 6804245..4470cd8 100644
--- a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
@@ -511,26 +511,9 @@
   sm_.Replay();
 }
 
-class ShelfNotificationBadgeSpokenFeedbackTest : public SpokenFeedbackTest {
- protected:
-  ShelfNotificationBadgeSpokenFeedbackTest() {
-    scoped_features_.InitWithFeatures({::features::kNotificationIndicator}, {});
-  }
-  ~ShelfNotificationBadgeSpokenFeedbackTest() override = default;
-
- private:
-  base::test::ScopedFeatureList scoped_features_;
-};
-
-INSTANTIATE_TEST_SUITE_P(TestAsNormalAndGuestUser,
-                         ShelfNotificationBadgeSpokenFeedbackTest,
-                         ::testing::Values(kTestAsNormalUser,
-                                           kTestAsGuestUser));
-
 // Verifies that an announcement is triggered when focusing a ShelfItem with a
 // notification badge shown.
-IN_PROC_BROWSER_TEST_P(ShelfNotificationBadgeSpokenFeedbackTest,
-                       ShelfNotificationBadgeAnnouncement) {
+IN_PROC_BROWSER_TEST_P(SpokenFeedbackTest, ShelfNotificationBadgeAnnouncement) {
   EnableChromeVox();
 
   // Create and add a test app to the shelf model.
diff --git a/chrome/browser/browser_features.cc b/chrome/browser/browser_features.cc
index d22035a..08c07d18 100644
--- a/chrome/browser/browser_features.cc
+++ b/chrome/browser/browser_features.cc
@@ -86,4 +86,9 @@
   return false;
 }
 
+// Enables runtime detection of USB devices which provide a WebUSB landing page
+// descriptor.
+const base::Feature kWebUsbDeviceDetection{"WebUsbDeviceDetection",
+                                           base::FEATURE_ENABLED_BY_DEFAULT};
+
 }  // namespace features
diff --git a/chrome/browser/browser_features.h b/chrome/browser/browser_features.h
index bf1e7fb..d0ce977 100644
--- a/chrome/browser/browser_features.h
+++ b/chrome/browser/browser_features.h
@@ -48,6 +48,8 @@
 // determine whether data migration should occur or not.
 bool ShouldTriggerNetworkDataMigration();
 
+extern const base::Feature kWebUsbDeviceDetection;
+
 }  // namespace features
 
 #endif  // CHROME_BROWSER_BROWSER_FEATURES_H_
diff --git a/chrome/browser/content_creation/reactions/internal/android/BUILD.gn b/chrome/browser/content_creation/reactions/internal/android/BUILD.gn
index 7471a09..4308df6 100644
--- a/chrome/browser/content_creation/reactions/internal/android/BUILD.gn
+++ b/chrome/browser/content_creation/reactions/internal/android/BUILD.gn
@@ -33,5 +33,6 @@
     "java/res/layout/reactions_dialog.xml",
     "java/res/layout/scene.xml",
     "java/res/layout/toolbar.xml",
+    "java/res/values/dimens.xml",
   ]
 }
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reactions_dialog.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reactions_dialog.xml
index 0d951c5..f399ab0 100644
--- a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reactions_dialog.xml
+++ b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reactions_dialog.xml
@@ -3,18 +3,31 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-
-<!-- TODO(crbug.com/1251666): Add android:contentDescription="@string/foo" attribute-->
-<LinearLayout
+<!-- TODO(crbug.com/1252182): Add android:contentDescription="@string/foo" attributes -->
+<RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/lightweight_reactions_dialog"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/default_bg_color"
-    android:orientation="vertical"
-    android:importantForAccessibility="yes">
+    android:orientation="vertical">
 
-    <include layout="@layout/scene"/>
+    <include layout="@layout/scene"
+        android:id="@+id/lightweight_reactions_scene"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_above="@id/lightweight_reactions_divider"/>
 
-    <include layout="@layout/toolbar"/>
-</LinearLayout>
\ No newline at end of file
+    <View
+        android:id="@+id/lightweight_reactions_divider"
+        android:background="@color/divider_line_bg_color"
+        android:layout_above="@id/lightweight_reactions_toolbar"
+        android:layout_height="@dimen/toolbar_separator_height"
+        android:layout_width="match_parent"/>
+
+    <include layout="@layout/toolbar"
+        android:id="@+id/lightweight_reactions_toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/toolbar_total_height"
+        android:layout_alignParentBottom="true"
+        />
+</RelativeLayout>
\ No newline at end of file
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/scene.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/scene.xml
index 750f7a3..346273ae 100644
--- a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/scene.xml
+++ b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/scene.xml
@@ -3,13 +3,13 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<!-- TODO(crbug.com/1252182): Add android:contentDescription="@string/foo" attribute-->
+<!-- TODO(crbug.com/1252182): Add android:contentDescription="@string/foo" attributes -->
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@color/modern_blue_600"
     android:orientation="vertical"
+    android:background="@color/default_scrim_color"
     android:importantForAccessibility="yes">
     <ImageView
         android:id="@+id/lightweight_reactions_background"
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml
index 63d3e51..a0391050 100644
--- a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml
+++ b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml
@@ -3,22 +3,65 @@
      Use of this source code is governed by a BSD-style license that can be
      found in the LICENSE file. -->
 
-<!-- TODO:(crbug.com/1251662) Add android:contentDescription="@string/foo" attribute-->
+<!-- TODO(crbug.com/1252182): Add android:contentDescription="@string/foo" attributes -->
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@color/modern_blue_700"
+    android:layout_height="wrap_content"
     android:orientation="vertical"
     android:importantForAccessibility="yes">
 
-    <TextView
-        android:id="@+id/lightweight_reactions_toolbar_test"
+    <LinearLayout
+        android:id="@+id/lightweight_reactions_toolbar_reaction_picker"
         android:gravity="center"
-        android:layout_height="wrap_content"
-        android:layout_width="wrap_content"
-        android:layout_gravity="center"
-        android:text="@string/sharing_lightweight_reactions"
-        android:textAppearance="@style/TextAppearance.TextMedium.Secondary" />
+        android:orientation="horizontal"
+        android:layout_above="@id/lightweight_reactions_toolbar_controls"
+        android:paddingHorizontal="@dimen/toolbar_button_margin"
+        android:layout_height="@dimen/toolbar_row_height"
+        android:layout_width="match_parent">
+        <!-- Empty for now -->
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/lightweight_reactions_toolbar_controls"
+        android:gravity="center"
+        android:orientation="horizontal"
+        android:paddingHorizontal="@dimen/toolbar_button_margin"
+        android:layout_alignParentBottom="true"
+        android:layout_height="@dimen/toolbar_row_height"
+        android:layout_width="match_parent">
+
+        <org.chromium.ui.widget.ChromeImageButton
+            android:id="@+id/close_button"
+            android:contentDescription="@string/close"
+            android:src="@drawable/btn_close"
+            android:layout_height="match_parent"
+            android:layout_width="@dimen/toolbar_button_size"
+            android:paddingHorizontal="@dimen/toolbar_button_padding"
+            app:tint="@color/default_icon_color_tint_list"
+            style="@style/ToolbarButton"/>
+
+        <TextView
+            android:id="@+id/lightweight_reactions_toolbar_title"
+            android:gravity="center"
+            android:layout_height="wrap_content"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_gravity="center"
+            android:text="@string/sharing_lightweight_reactions"
+            android:textAppearance="@style/TextAppearance.TextMedium.Secondary"/>
+
+        <!-- TODO(crbug.com/1252182): Fix the android:contentDescription attribute -->
+        <org.chromium.ui.widget.ChromeImageButton
+            android:id="@+id/done_button"
+            android:contentDescription="@string/screenshot_save_title"
+            android:src="@drawable/ic_checkmark_24dp"
+            android:layout_height="match_parent"
+            android:layout_width="@dimen/toolbar_button_size"
+            android:paddingHorizontal="@dimen/toolbar_button_padding"
+            app:tint="@color/default_icon_color_tint_list"
+            style="@style/ToolbarButton"/>
+    </LinearLayout>
 </RelativeLayout>
\ No newline at end of file
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/values/dimens.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/values/dimens.xml
new file mode 100644
index 0000000..e1df5f0
--- /dev/null
+++ b/chrome/browser/content_creation/reactions/internal/android/java/res/values/dimens.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<resources>
+    <dimen name="toolbar_row_height">56dp</dimen>
+    <dimen name="toolbar_total_height">112dp</dimen>
+    <dimen name="toolbar_separator_height">1dp</dimen>
+    <dimen name="toolbar_button_size">40dp</dimen>
+    <dimen name="toolbar_button_margin">16dp</dimen>
+    <dimen name="toolbar_button_padding">8dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 8e7e4902..bf8b3dc 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -559,6 +559,11 @@
     "expiry_milestone": 98
   },
   {
+    "name": "bookmarks-improved-save-flow",
+    "owners": ["wylieb", "fgorski", "mdjones"],
+    "expiry_milestone": 100
+  },
+  {
     "name": "bookmarks-refresh",
     "owners": ["wylieb", "fgorski", "mdjones"],
     "expiry_milestone": 100
@@ -791,11 +796,6 @@
     "owners": [ "yusuyoutube@google.com", "benwgold@google.com", "lens-chrome@google.com" ],
     "expiry_milestone": 96
   },
-  {
-    "name": "context-menu-performance-info-and-remote-hints-fetching",
-    "owners": [ "jds" ],
-    "expiry_milestone": 90
-  },
   { "name":"context-menu-phase2",
       "owners":["gambard", "bling-flags@google.com"],
       "expiry_milestone":100
@@ -1914,6 +1914,11 @@
     "expiry_milestone": 85
   },
   {
+    "name": "enable-firmware-updater-app",
+    "owners": [ "zentaro", "jimmyxgong", "swifton", "cros-peripherals@google.com" ],
+    "expiry_milestone": 102
+  },
+  {
     "name": "enable-first-party-sets",
     "owners": [ "chrome-first-party-sets@chromium.org" ],
     "expiry_milestone": 99
@@ -2042,7 +2047,7 @@
   {
     "name": "enable-image-reader",
     "owners": [ "vikassoni", "liberato" ],
-    "expiry_milestone": 95
+    "expiry_milestone": 115
   },
   {
     "name": "enable-immersive-fullscreen-toolbar",
@@ -2146,6 +2151,11 @@
     "expiry_milestone": 92
   },
   {
+    "name": "enable-long-message-duration",
+    "owners": [ "tinazwang", "bling-flags@google.com" ],
+    "expiry_milestone": 110
+  },
+  {
     "name": "enable-magnifier-continuous-mouse-following-mode-setting",
     "owners": [ "josiahk", "//ui/accessibility/OWNERS" ],
     "expiry_milestone": 92
@@ -2251,11 +2261,6 @@
     "expiry_milestone": -1
   },
   {
-    "name": "enable-notification-indicator",
-    "owners": [ "mmourgos", "newcomer" ],
-    "expiry_milestone": 91
-  },
-  {
     "name": "enable-notifications-revamp",
     "owners": [ "amehfooz", "newcomer" ],
     "expiry_milestone": 100
@@ -2859,6 +2864,11 @@
     "expiry_milestone": 88
   },
   {
+    "name": "enable-webusb-device-detection",
+    "owners": [ "reillyg", "deviceapi-team@google.com" ],
+    "expiry_milestone": 104
+  },
+  {
     "name": "enable-windows-gaming-input-data-fetcher",
     "owners": [ "qiaye@microsoft.com" ],
     "expiry_milestone": 92
@@ -5170,7 +5180,15 @@
   {
     "name": "system-keyboard-lock",
     "owners": [ "joedow", "garykac", "jamiewalch" ],
-    "expiry_milestone": 95
+    // This flag allows users to prevent the keyboard-lock API from capturing
+    // system keys (e.g. by using low-level hooks) which might interfere with
+    // their workflows or other apps running on the machine. It is also needed
+    // for browsertests as the test framework relies on low-level keyboard hooks
+    // which prevents testing this feature if this flag is not disabled.
+    // Note that there is a second version of this API being discussed which
+    // allows the caller to select whether system hooks are enabled.
+    // See: https://github.com/WICG/keyboard-lock/blob/gh-pages/explainer2.md
+    "expiry_milestone": -1
   },
   {
     "name": "tab-groups-auto-create",
diff --git a/chrome/browser/flag-never-expire-list.json b/chrome/browser/flag-never-expire-list.json
index 199edf6..3680718 100644
--- a/chrome/browser/flag-never-expire-list.json
+++ b/chrome/browser/flag-never-expire-list.json
@@ -98,6 +98,7 @@
   "show-taps",
   "show-touch-hud",
   "smooth-scrolling",
+  "system-keyboard-lock",
   "tint-composited-content",
   "top-chrome-touch-ui",
   "ui-debug-tools",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 9cd7de5a..54a9924 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -921,6 +921,11 @@
     "embedding an isolated top-level page. See "
     "https://github.com/shivanigithub/fenced-frame";
 
+const char kEnableFirmwareUpdaterAppName[] = "Enable firmware updater app";
+const char kEnableFirmwareUpdaterAppDescription[] =
+    "Enable the firmware updater SWA, allowing users to update firmware "
+    "on supported peripherals.";
+
 const char kEnableGamepadButtonAxisEventsName[] =
     "Gamepad Button and Axis Events";
 const char kEnableGamepadButtonAxisEventsDescription[] =
@@ -1680,11 +1685,6 @@
 const char kNewUsbBackendDescription[] =
     "Enables the new experimental USB backend for macOS";
 
-const char kNotificationIndicatorName[] = "Notification Indicators";
-const char kNotificationIndicatorDescription[] =
-    "Enable notification indicators, which appear on shelf app icons and "
-    "launcher apps when a notification is active.";
-
 const char kNotificationsRevampName[] = "Notifications Revamp";
 const char kNotificationsRevampDescription[] =
     "Enable notification UI revamp and grouped web notifications.";
@@ -2093,10 +2093,13 @@
     "to true, pointer movements wil not be affected by the underlying platform "
     "modications such as mouse accelaration.";
 
-const char kBookmarksRefreshName[] =
-    "Enables the a visual refresh for bookmarks";
+const char kBookmarksImprovedSaveFlowName[] = "Improved bookmarks save flow";
+const char kBookmarksImprovedSaveFlowDescription[] =
+    "Enabled an improved save flow for bookmarks.";
+
+const char kBookmarksRefreshName[] = "Bookmarks visual refresh";
 const char kBookmarksRefreshDescription[] =
-    "Changes the bookmark list visuals.";
+    "Enalbed a visual refresh for bookmarks.";
 
 const char kPrerender2Name[] = "Prerender2";
 const char kPrerender2Description[] =
@@ -2806,6 +2809,13 @@
     "When enabled, WebRTC will only use the Video Encode Accelerator for "
     "video resolutions inside those published as supported.";
 
+const char kWebUsbDeviceDetectionName[] =
+    "Automatic detection of WebUSB-compatible devices";
+const char kWebUsbDeviceDetectionDescription[] =
+    "When enabled, the user will be notified when a device which advertises "
+    "support for WebUSB is connected. Disable if problems with USB devices are "
+    "observed when the browser is running.";
+
 const char kWebXrForceRuntimeName[] = "Force WebXr Runtime";
 const char kWebXrForceRuntimeDescription[] =
     "Force the browser to use a particular runtime, even if it would not "
@@ -3041,13 +3051,6 @@
     "A new method of persisting Tab data across restarts has been devised "
     "and implemented. This actives the new approach.";
 
-const char kContextMenuPerformanceInfoAndRemoteHintFetchingName[] =
-    "Context menu performance info and remote hint fetching";
-const char kContextMenuPerformanceInfoAndRemoteHintFetchingDescription[] =
-    "Enables showing link performance information in the context menu and "
-    "allows communicating with Google servers to fetch performance information "
-    "for the main frame URL.";
-
 const char kContextualSearchDebugName[] = "Contextual Search debug";
 const char kContextualSearchDebugDescription[] =
     "Enables internal debugging of Contextual Search behavior on the client "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 05b5cea..4940328 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -625,6 +625,9 @@
 extern const char kEnableFencedFramesName[];
 extern const char kEnableFencedFramesDescription[];
 
+extern const char kEnableFirmwareUpdaterAppName[];
+extern const char kEnableFirmwareUpdaterAppDescription[];
+
 extern const char kEnableGamepadButtonAxisEventsName[];
 extern const char kEnableGamepadButtonAxisEventsDescription[];
 
@@ -967,9 +970,6 @@
 extern const char kNewUsbBackendName[];
 extern const char kNewUsbBackendDescription[];
 
-extern const char kNotificationIndicatorName[];
-extern const char kNotificationIndicatorDescription[];
-
 extern const char kNotificationsRevampName[];
 extern const char kNotificationsRevampDescription[];
 
@@ -1151,6 +1151,9 @@
 extern const char kPdfXfaFormsName[];
 extern const char kPdfXfaFormsDescription[];
 
+extern const char kBookmarksImprovedSaveFlowName[];
+extern const char kBookmarksImprovedSaveFlowDescription[];
+
 extern const char kBookmarksRefreshName[];
 extern const char kBookmarksRefreshDescription[];
 
@@ -1586,6 +1589,9 @@
 extern const char kWebrtcUseMinMaxVEADimensionsName[];
 extern const char kWebrtcUseMinMaxVEADimensionsDescription[];
 
+extern const char kWebUsbDeviceDetectionName[];
+extern const char kWebUsbDeviceDetectionDescription[];
+
 extern const char kWebXrForceRuntimeName[];
 extern const char kWebXrForceRuntimeDescription[];
 
@@ -1727,9 +1733,6 @@
 extern const char kCriticalPersistedTabDataName[];
 extern const char kCriticalPersistedTabDataDescription[];
 
-extern const char kContextMenuPerformanceInfoAndRemoteHintFetchingName[];
-extern const char kContextMenuPerformanceInfoAndRemoteHintFetchingDescription[];
-
 extern const char kContextualSearchDebugName[];
 extern const char kContextualSearchDebugDescription[];
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 9e97644..8fcfc67 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -238,6 +238,7 @@
     &kOfflineIndicatorV2,
     &kOfflineMeasurementsBackgroundTask,
     &kPageAnnotationsService,
+    &kBookmarksImprovedSaveFlow,
     &kBookmarksRefresh,
     &kProbabilisticCryptidRenderer,
     &kQuickActionSearchWidgetAndroid,
@@ -652,6 +653,9 @@
 const base::Feature kPageAnnotationsService{"PageAnnotationsService",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kBookmarksImprovedSaveFlow{
+    "BookmarksImprovedSaveFlow", base::FEATURE_DISABLED_BY_DEFAULT};
+
 const base::Feature kBookmarksRefresh{"BookmarksRefresh",
                                       base::FEATURE_DISABLED_BY_DEFAULT};
 
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index 9f1412e5..633c2a3 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -108,6 +108,7 @@
 extern const base::Feature kOfflineIndicatorV2;
 extern const base::Feature kOfflineMeasurementsBackgroundTask;
 extern const base::Feature kPageAnnotationsService;
+extern const base::Feature kBookmarksImprovedSaveFlow;
 extern const base::Feature kBookmarksRefresh;
 extern const base::Feature kProbabilisticCryptidRenderer;
 extern const base::Feature kQuickActionSearchWidgetAndroid;
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index bb43df53..af31bbe 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -420,6 +420,7 @@
     public static final String PERMISSION_DELEGATION = "PermissionDelegation";
     public static final String PORTALS = "Portals";
     public static final String PORTALS_CROSS_ORIGIN = "PortalsCrossOrigin";
+    public static final String BOOKMARKS_IMPROVED_SAVE_FLOW = "BookmarksImprovedSaveFlow";
     public static final String BOOKMARKS_REFRESH = "BookmarksRefresh";
     public static final String PREEMPTIVE_LINK_TO_TEXT_GENERATION =
             "PreemptiveLinkToTextGeneration";
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index e831217..ec48479 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -630,7 +630,7 @@
   // misrepresent it as enabled here (and later ignored when analyzing results),
   // in order to keep each population at 33%.
   //
-  // Alsto note that USE_BACKUP_REF_PTR_FAKE is only used to fake that the
+  // Also note that USE_BACKUP_REF_PTR_FAKE is only used to fake that the
   // feature is enabled for the purpose of this Finch setting, while in fact
   // there are no behavior changes.
   ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
@@ -644,6 +644,22 @@
           : "Disabled"
 #endif  // BUILDFLAG(USE_BACKUP_REF_PTR) || BUILDFLAG(USE_BACKUP_REF_PTR_FAKE)
   );
+
+  // This synthetic Finch setting reflects the new USE_BACKUP_REF_PTR behavior,
+  // which simply compiles in the BackupRefPtr support, but keeps it disabled at
+  // run-time (which can be further enabled via Finch).
+  //
+  // Also note that USE_BACKUP_REF_PTR_FAKE is only used to fake that the
+  // feature is enabled for the purpose of this Finch setting, while in fact
+  // there are no behavior changes.
+  ChromeMetricsServiceAccessor::RegisterSyntheticFieldTrial(
+      "BackupRefPtrSupport",
+#if BUILDFLAG(USE_BACKUP_REF_PTR) || BUILDFLAG(USE_BACKUP_REF_PTR_FAKE)
+      "CompiledIn"
+#else
+      "Disabled"
+#endif  // BUILDFLAG(USE_BACKUP_REF_PTR) || BUILDFLAG(USE_BACKUP_REF_PTR_FAKE)
+  );
 #endif  // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
 
 #if defined(OS_ANDROID)
diff --git a/chrome/browser/resources/print_preview/BUILD.gn b/chrome/browser/resources/print_preview/BUILD.gn
index d221d83..9d84705e 100644
--- a/chrome/browser/resources/print_preview/BUILD.gn
+++ b/chrome/browser/resources/print_preview/BUILD.gn
@@ -98,7 +98,7 @@
     "ui/highlight_utils.ts",
     "ui/input_behavior.js",
     "ui/plugin_proxy.js",
-    "ui/select_behavior.js",
+    "ui/select_mixin.ts",
     "ui/settings_behavior.js",
   ]
 
@@ -126,7 +126,7 @@
     "ui/destination_dialog_css.ts",
     "ui/destination_list.ts",
     "ui/destination_list_item.ts",
-    "ui/destination_select_css.js",
+    "ui/destination_select_css.ts",
     "ui/destination_settings.js",
     "ui/dpi_settings.js",
     "ui/duplex_settings.js",
@@ -155,15 +155,15 @@
 
   if (is_chromeos) {
     in_files += [
-      "ui/destination_dropdown_cros.js",
-      "ui/destination_select_cros.js",
+      "ui/destination_dropdown_cros.ts",
+      "ui/destination_select_cros.ts",
       "ui/pin_settings.js",
       "ui/provisional_destination_resolver.ts",
       "ui/destination_dialog_cros.ts",
     ]
   } else {
     in_files += [
-      "ui/destination_select.js",
+      "ui/destination_select.ts",
       "ui/link_container.js",
       "ui/destination_dialog.ts",
     ]
@@ -267,7 +267,7 @@
     "ui/destination_dialog_css.ts",
     "ui/destination_list.ts",
     "ui/destination_list_item.ts",
-    "ui/destination_select_css.js",
+    "ui/destination_select_css.ts",
     "ui/destination_settings.js",
     "ui/dpi_settings.js",
     "ui/duplex_settings.js",
@@ -291,7 +291,7 @@
     "ui/print_preview_shared_css.js",
     "ui/print_preview_vars_css.js",
     "ui/scaling_settings.js",
-    "ui/select_behavior.js",
+    "ui/select_mixin.ts",
     "ui/settings_behavior.js",
     "ui/settings_section.js",
     "ui/settings_select.js",
@@ -305,15 +305,15 @@
       "data/printer_status_cros.ts",
       "native_layer_cros.ts",
       "ui/destination_dialog_cros.ts",
-      "ui/destination_dropdown_cros.js",
-      "ui/destination_select_cros.js",
+      "ui/destination_dropdown_cros.ts",
+      "ui/destination_select_cros.ts",
       "ui/pin_settings.js",
       "ui/provisional_destination_resolver.ts",
     ]
   } else {
     in_files += [
       "ui/destination_dialog.ts",
-      "ui/destination_select.js",
+      "ui/destination_select.ts",
       "ui/link_container.js",
     ]
   }
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index 57b3a60..afb8bb8 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -69,6 +69,6 @@
 export {PreviewAreaState, PrintPreviewPreviewAreaElement} from './ui/preview_area.js';
 export {PrintPreviewSearchBoxElement} from './ui/print_preview_search_box.js';
 export {PrintPreviewScalingSettingsElement} from './ui/scaling_settings.js';
-export {SelectBehavior} from './ui/select_behavior.js';
+export {SelectMixin} from './ui/select_mixin.js';
 export {PrintPreviewSettingsSelectElement, SelectOption} from './ui/settings_select.js';
 export {PrintPreviewSidebarElement} from './ui/sidebar.js';
diff --git a/chrome/browser/resources/print_preview/ui/BUILD.gn b/chrome/browser/resources/print_preview/ui/BUILD.gn
index db1e7ae1..b7e7a56 100644
--- a/chrome/browser/resources/print_preview/ui/BUILD.gn
+++ b/chrome/browser/resources/print_preview/ui/BUILD.gn
@@ -17,7 +17,7 @@
     "destination_dialog_css.ts",
     "destination_list_item.ts",
     "destination_list.ts",
-    "destination_select_css.js",
+    "destination_select_css.ts",
     "destination_settings.js",
     "dpi_settings.js",
     "duplex_settings.js",
@@ -47,15 +47,15 @@
   if (is_chromeos) {
     js_files += [
       "destination_dialog_cros.ts",
-      "destination_dropdown_cros.js",
-      "destination_select_cros.js",
+      "destination_dropdown_cros.ts",
+      "destination_select_cros.ts",
       "pin_settings.js",
       "provisional_destination_resolver.ts",
     ]
   } else {
     js_files += [
       "destination_dialog.ts",
-      "destination_select.js",
+      "destination_select.ts",
     ]
   }
 }
diff --git a/chrome/browser/resources/print_preview/ui/color_settings.js b/chrome/browser/resources/print_preview/ui/color_settings.js
index c4a7d7d..4027a1d5 100644
--- a/chrome/browser/resources/print_preview/ui/color_settings.js
+++ b/chrome/browser/resources/print_preview/ui/color_settings.js
@@ -8,17 +8,17 @@
 
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 import {SettingsBehavior, SettingsBehaviorInterface} from './settings_behavior.js';
 
 /**
  * @constructor
  * @extends {PolymerElement}
- * @implements {SelectBehaviorInterface}
+ * @implements {SelectMixinInterface}
  * @implements {SettingsBehaviorInterface}
  */
 const PrintPreviewColorSettingsElementBase =
-    mixinBehaviors([SettingsBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([SettingsBehavior], SelectMixin(PolymerElement));
 
 /** @polymer */
 export class PrintPreviewColorSettingsElement extends
diff --git a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.ts
similarity index 67%
rename from chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js
rename to chrome/browser/resources/print_preview/ui/destination_dropdown_cros.ts
index 36b1a4f..efb5d34 100644
--- a/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js
+++ b/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.ts
@@ -10,22 +10,23 @@
 
 import './print_preview_vars_css.js';
 
-import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {Destination, DestinationOrigin} from '../data/destination.js';
 import {ERROR_STRING_KEY_MAP, getPrinterStatusIcon, PrinterStatusReason} from '../data/printer_status_cros.js';
 
 
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {I18nBehaviorInterface}
- */
-const PrintPreviewDestinationDropdownCrosElementBase =
-    mixinBehaviors([I18nBehavior], PolymerElement);
+declare global {
+  interface HTMLElementEventMap {
+    'dropdown-value-selected': CustomEvent<HTMLButtonElement>;
+  }
+}
 
-/** @polymer */
+const PrintPreviewDestinationDropdownCrosElementBase =
+    mixinBehaviors([I18nBehavior], PolymerElement) as
+    {new (): PolymerElement & I18nBehavior};
+
 export class PrintPreviewDestinationDropdownCrosElement extends
     PrintPreviewDestinationDropdownCrosElementBase {
   static get is() {
@@ -38,16 +39,13 @@
 
   static get properties() {
     return {
-      /** @type {!Destination} */
       value: Object,
 
-      /** @type {!Array<!Destination>} */
       itemList: {
         type: Array,
         observer: 'enqueueDropdownRefit_',
       },
 
-      /** @type {boolean} */
       disabled: {
         type: Boolean,
         value: false,
@@ -67,11 +65,9 @@
 
       /**
        * Index of the highlighted item in the dropdown.
-       * @private
        */
       highlightedIndex_: Number,
 
-      /** @private */
       dropdownLength_: {
         type: Number,
         computed: 'computeDropdownLength_(itemList, pdfPrinterDisabled, ' +
@@ -82,32 +78,37 @@
     };
   }
 
-  constructor() {
-    super();
+  value: Destination;
+  itemList: Destination[];
+  disabled: boolean;
+  driveDestinationKey: string;
+  noDestinations: boolean;
+  pdfPrinterDisabled: boolean;
+  destinationStatusText: string;
+  private highlightedIndex_: number;
+  private dropdownLength_: number;
 
-    /** @private {boolean} */
-    this.opened_ = false;
-  }
+  private opened_: boolean = false;
+  private dropdownRefitPending_: boolean = false;
 
-  /** @override */
   ready() {
     super.ready();
 
     this.addEventListener('mousemove', e => this.onMouseMove_(e));
   }
 
-  /** @override */
   connectedCallback() {
     super.connectedCallback();
 
     this.updateTabIndex_();
   }
 
-  /**
-   * @param {Element} element
-   * @private
-   */
-  fireDropdownValueSelected_(element) {
+  focus() {
+    this.shadowRoot!.querySelector<HTMLElement>(
+                        '#destination-dropdown')!.focus();
+  }
+
+  private fireDropdownValueSelected_(element: Element) {
     this.dispatchEvent(new CustomEvent(
         'dropdown-value-selected',
         {bubbles: true, composed: true, detail: element}));
@@ -115,10 +116,9 @@
 
   /**
    * Enqueues a task to refit the iron-dropdown if it is open.
-   * @private
    */
-  enqueueDropdownRefit_() {
-    const dropdown = this.shadowRoot.querySelector('iron-dropdown');
+  private enqueueDropdownRefit_() {
+    const dropdown = this.shadowRoot!.querySelector('iron-dropdown')!;
     if (!this.dropdownRefitPending_ && dropdown.opened) {
       this.dropdownRefitPending_ = true;
       setTimeout(() => {
@@ -128,21 +128,19 @@
     }
   }
 
-  /** @private */
-  openDropdown_() {
+  private openDropdown_() {
     if (this.disabled) {
       return;
     }
 
     this.highlightedIndex_ = this.getButtonListFromDropdown_().findIndex(
         item => item.value === this.value.key);
-    this.shadowRoot.querySelector('iron-dropdown').open();
+    this.shadowRoot!.querySelector('iron-dropdown')!.open();
     this.opened_ = true;
   }
 
-  /** @private */
-  closeDropdown_() {
-    this.shadowRoot.querySelector('iron-dropdown').close();
+  private closeDropdown_() {
+    this.shadowRoot!.querySelector('iron-dropdown')!.close();
     this.opened_ = false;
     this.highlightedIndex_ = -1;
   }
@@ -155,20 +153,19 @@
    * @param {!Event} event
    * @private
    */
-  onMouseMove_(event) {
-    const item = /** @type {!Element} */ (event.composedPath().find(
-        elm => elm.classList && elm.classList.contains('list-item')));
+  private onMouseMove_(event: Event) {
+    const item =
+        (event.composedPath() as HTMLElement[])
+            .find(elm => elm.classList && elm.classList.contains('list-item'));
     if (!item) {
       return;
     }
-    this.highlightedIndex_ = this.getButtonListFromDropdown_().indexOf(item);
+    this.highlightedIndex_ =
+        this.getButtonListFromDropdown_().indexOf(item as HTMLButtonElement);
   }
 
-  /** @private */
-  onClick_(event) {
-    const dropdown =
-        /** @type {!IronDropdownElement} */ (
-            this.shadowRoot.querySelector('iron-dropdown'));
+  private onClick_(event: Event) {
+    const dropdown = this.shadowRoot!.querySelector('iron-dropdown')!;
     // Exit if path includes |dropdown| because event will be handled by
     // onSelect_.
     if (event.composedPath().includes(dropdown)) {
@@ -182,21 +179,13 @@
     this.openDropdown_();
   }
 
-  /**
-   * @param {!Event} event
-   * @private
-   */
-  onSelect_(event) {
-    this.dropdownValueSelected_(/** @type {!Element} */ (event.currentTarget));
+  private onSelect_(event: Event) {
+    this.dropdownValueSelected_(event.currentTarget as Element);
   }
 
-  /**
-   * @param {!Event} event
-   * @private
-   */
-  onKeyDown_(event) {
+  private onKeyDown_(event: KeyboardEvent) {
     event.stopPropagation();
-    const dropdown = this.shadowRoot.querySelector('iron-dropdown');
+    const dropdown = this.shadowRoot!.querySelector('iron-dropdown')!;
     switch (event.code) {
       case 'ArrowUp':
       case 'ArrowDown':
@@ -221,12 +210,8 @@
     }
   }
 
-  /**
-   * @param {string} eventCode
-   * @private
-   */
-  onArrowKeyPress_(eventCode) {
-    const dropdown = this.shadowRoot.querySelector('iron-dropdown');
+  private onArrowKeyPress_(eventCode: string) {
+    const dropdown = this.shadowRoot!.querySelector('iron-dropdown')!;
     const items = this.getButtonListFromDropdown_();
     if (items.length === 0) {
       return;
@@ -256,63 +241,52 @@
   }
 
   /**
-   * @param {string} eventCode
-   * @param {number} currentIndex
-   * @param {number} numItems
-   * @return {number} Returns -1 when the next item would be outside the list.
-   * @private
+   * @return -1 when the next item would be outside the list.
    */
-  getNextItemIndexInList_(eventCode, currentIndex, numItems) {
+  private getNextItemIndexInList_(
+      eventCode: string, currentIndex: number, numItems: number): number {
     const nextIndex =
         eventCode === 'ArrowDown' ? currentIndex + 1 : currentIndex - 1;
     return nextIndex >= 0 && nextIndex < numItems ? nextIndex : -1;
   }
 
-  /**
-   * @param {Element|undefined} dropdownItem
-   * @private
-   */
-  dropdownValueSelected_(dropdownItem) {
+  private dropdownValueSelected_(dropdownItem?: Element) {
     this.closeDropdown_();
     if (dropdownItem) {
       this.fireDropdownValueSelected_(dropdownItem);
     }
-    this.shadowRoot.querySelector('#destination-dropdown').focus();
+    this.shadowRoot!.querySelector<HTMLElement>(
+                        '#destination-dropdown')!.focus();
   }
 
   /**
    * Returns list of all the visible items in the dropdown.
-   * @return {!Array<!Element>}
-   * @private
    */
-  getButtonListFromDropdown_() {
+  private getButtonListFromDropdown_(): HTMLButtonElement[] {
     if (!this.shadowRoot) {
       return [];
     }
 
-    const dropdown = this.shadowRoot.querySelector('iron-dropdown');
-    return Array.from(dropdown.getElementsByClassName('list-item'))
+    const dropdown = this.shadowRoot!.querySelector('iron-dropdown')!;
+    return Array
+        .from(dropdown.querySelectorAll<HTMLButtonElement>('.list-item'))
         .filter(item => !item.hidden);
   }
 
   /**
    * Sets tabindex to -1 when dropdown is disabled to prevent the dropdown from
    * being focusable.
-   * @private
    */
-  updateTabIndex_() {
-    this.shadowRoot.querySelector('#destination-dropdown')
-        .setAttribute('tabindex', this.disabled ? '-1' : '0');
+  private updateTabIndex_() {
+    this.shadowRoot!.querySelector('#destination-dropdown')!.setAttribute(
+        'tabindex', this.disabled ? '-1' : '0');
   }
 
   /**
    * Determines if an item in the dropdown should be highlighted based on the
    * current value of |highlightedIndex_|.
-   * @param {string} itemValue
-   * @return {string}
-   * @private
    */
-  getHighlightedClass_(itemValue) {
+  private getHighlightedClass_(itemValue: string): string {
     const itemToHighlight =
         this.getButtonListFromDropdown_()[this.highlightedIndex_];
     return itemToHighlight && itemValue === itemToHighlight.value ?
@@ -323,21 +297,15 @@
   /**
    * Close the dropdown when focus is lost except when an item in the dropdown
    * is the element that received the focus.
-   * @param {!Event} event
-   * @private
    */
-  onBlur_(event) {
+  private onBlur_(event: FocusEvent) {
     if (!this.getButtonListFromDropdown_().includes(
-            /** @type {!Element} */ (event.relatedTarget))) {
+            (event.relatedTarget as HTMLButtonElement))) {
       this.closeDropdown_();
     }
   }
 
-  /**
-   * @return {number}
-   * @private
-   */
-  computeDropdownLength_() {
+  private computeDropdownLength_(): number {
     if (this.noDestinations) {
       return 1;
     }
@@ -357,27 +325,26 @@
     return length;
   }
 
-  /**
-   * @param {!PrinterStatusReason} printerStatusReason
-   * @return {string}
-   * @private
-   */
-  getPrinterStatusErrorString_(printerStatusReason) {
+  private getPrinterStatusErrorString_(printerStatusReason:
+                                           PrinterStatusReason): string {
     const errorStringKey = ERROR_STRING_KEY_MAP.get(printerStatusReason);
     return errorStringKey ? this.i18n(errorStringKey) : '';
   }
 
-  /**
-   * @param {!PrinterStatusReason} printerStatusReason
-   * @param {boolean} isEnterprisePrinter
-   * @return {string}
-   * @private
-   */
-  getPrinterStatusIcon_(printerStatusReason, isEnterprisePrinter) {
+  private getPrinterStatusIcon_(
+      printerStatusReason: PrinterStatusReason,
+      isEnterprisePrinter: boolean): string {
     return getPrinterStatusIcon(printerStatusReason, isEnterprisePrinter);
   }
 }
 
+declare global {
+  interface HTMLElementTagNameMap {
+    'print-preview-destination-dropdown-cros':
+        PrintPreviewDestinationDropdownCrosElement;
+  }
+}
+
 customElements.define(
     PrintPreviewDestinationDropdownCrosElement.is,
     PrintPreviewDestinationDropdownCrosElement);
diff --git a/chrome/browser/resources/print_preview/ui/destination_select.js b/chrome/browser/resources/print_preview/ui/destination_select.ts
similarity index 75%
rename from chrome/browser/resources/print_preview/ui/destination_select.js
rename to chrome/browser/resources/print_preview/ui/destination_select.ts
index ad72996..b4a6c822 100644
--- a/chrome/browser/resources/print_preview/ui/destination_select.js
+++ b/chrome/browser/resources/print_preview/ui/destination_select.ts
@@ -13,32 +13,26 @@
 import 'chrome://resources/cr_elements/md_select_css.m.js';
 import 'chrome://resources/js/util.m.js';
 import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
-import 'chrome://resources/polymer/v3_0/iron-meta/iron-meta.js';
 import './destination_select_css.js';
 import './icons.js';
 import './print_preview_shared_css.js';
 import './throbber_css.js';
 import '../strings.m.js';
 
-import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {Base, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {IronMeta} from 'chrome://resources/polymer/v3_0/iron-meta/iron-meta.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {Destination, DestinationOrigin, GooglePromotedDestinationId, PDF_DESTINATION_KEY, RecentDestination} from '../data/destination.js';
 import {getSelectDropdownBackground} from '../print_preview_utils.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {I18nBehaviorInterface}
- * @implements {SelectBehaviorInterface}
- */
 const PrintPreviewDestinationSelectElementBase =
-    mixinBehaviors([I18nBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([I18nBehavior], SelectMixin(PolymerElement)) as
+    {new (): PolymerElement & I18nBehavior & SelectMixinInterface};
 
-/** @polymer */
 export class PrintPreviewDestinationSelectElement extends
     PrintPreviewDestinationSelectElementBase {
   static get is() {
@@ -55,7 +49,6 @@
 
       dark: Boolean,
 
-      /** @type {!Destination} */
       destination: Object,
 
       disabled: Boolean,
@@ -66,16 +59,13 @@
 
       pdfPrinterDisabled: Boolean,
 
-      /** @type {!Array<!Destination>} */
       recentDestinationList: Array,
 
-      /** @private {string} */
       pdfDestinationKey_: {
         type: String,
         value: PDF_DESTINATION_KEY,
       },
 
-      /** @private {string} */
       statusText_: {
         type: String,
         computed: 'computeStatusText_(destination)',
@@ -84,16 +74,26 @@
     };
   }
 
+  activeUser: string;
+  dark: boolean;
+  destination: Destination;
+  disabled: boolean;
+  loaded: boolean;
+  noDestinations: boolean;
+  pdfPrinterDisabled: boolean;
+  recentDestinationList: Destination[];
+  private pdfDestinationKey_: string;
+  private statusText_: string;
+  private meta_: IronMeta;
+
   constructor() {
     super();
 
-    /** @private {!IronMetaElement} */
-    this.meta_ = /** @type {!IronMetaElement} */ (
-        Base.create('iron-meta', {type: 'iconset'}));
+    this.meta_ = new IronMeta({type: 'iconset', value: undefined});
   }
 
   focus() {
-    this.shadowRoot.querySelector('.md-select').focus();
+    this.shadowRoot!.querySelector<HTMLElement>('.md-select')!.focus();
   }
 
   /** Sets the select to the current value of |destination|. */
@@ -105,10 +105,9 @@
    * Returns the iconset and icon for the selected printer. If printer details
    * have not yet been retrieved from the backend, attempts to return an
    * appropriate icon early based on the printer's sticky information.
-   * @return {string} The iconset and icon for the current selection.
-   * @private
+   * @return The iconset and icon for the current selection.
    */
-  getDestinationIcon_() {
+  private getDestinationIcon_(): string {
     if (!this.selectedValue) {
       return '';
     }
@@ -143,11 +142,10 @@
   }
 
   /**
-   * @return {string} An inline svg corresponding to the icon for the current
+   * @return An inline svg corresponding to the icon for the current
    *     destination and the image for the dropdown arrow.
-   * @private
    */
-  getBackgroundImages_() {
+  private getBackgroundImages_(): string {
     const icon = this.getDestinationIcon_();
     if (!icon) {
       return '';
@@ -163,17 +161,16 @@
     return getSelectDropdownBackground(iconset, iconSetAndIcon[1], this);
   }
 
-  onProcessSelectChange(value) {
+  onProcessSelectChange(value: string) {
     this.dispatchEvent(new CustomEvent(
         'selected-option-change',
         {bubbles: true, composed: true, detail: value}));
   }
 
   /**
-   * @return {string} The connection status text to display.
-   * @private
+   * @return The connection status text to display.
    */
-  computeStatusText_() {
+  private computeStatusText_(): string {
     // |destination| can be either undefined, or null here.
     if (!this.destination) {
       return '';
@@ -191,18 +188,16 @@
     return '';
   }
 
-  /** @private */
-  onStatusTextSet_() {
-    this.shadowRoot.querySelector('.destination-status').innerHTML =
+  private onStatusTextSet_() {
+    this.shadowRoot!.querySelector('.destination-status')!.innerHTML =
         this.statusText_;
   }
 
   /**
    * Return the options currently visible to the user for testing purposes.
-   * @return {!NodeList<!Element>}
    */
-  getVisibleItemsForTest() {
-    return this.shadowRoot.querySelectorAll('option:not([hidden])');
+  getVisibleItemsForTest(): NodeListOf<Element> {
+    return this.shadowRoot!.querySelectorAll('option:not([hidden])');
   }
 }
 
diff --git a/chrome/browser/resources/print_preview/ui/destination_select_cros.js b/chrome/browser/resources/print_preview/ui/destination_select_cros.ts
similarity index 76%
rename from chrome/browser/resources/print_preview/ui/destination_select_cros.js
rename to chrome/browser/resources/print_preview/ui/destination_select_cros.ts
index 7b7ddf4..b5c87df 100644
--- a/chrome/browser/resources/print_preview/ui/destination_select_cros.js
+++ b/chrome/browser/resources/print_preview/ui/destination_select_cros.ts
@@ -7,7 +7,6 @@
 import 'chrome://resources/js/util.m.js';
 import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
-import 'chrome://resources/polymer/v3_0/iron-meta/iron-meta.js';
 import './destination_dropdown_cros.js';
 import './destination_select_css.js';
 import './icons.js';
@@ -16,24 +15,18 @@
 import '../strings.m.js';
 
 import {assert} from 'chrome://resources/js/assert.m.js';
-import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
-import {Base, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CloudOrigins, Destination, DestinationOrigin, GooglePromotedDestinationId, PDF_DESTINATION_KEY, RecentDestination, SAVE_TO_DRIVE_CROS_DESTINATION_KEY} from '../data/destination.js';
 import {ERROR_STRING_KEY_MAP, getPrinterStatusIcon, PrinterStatusReason} from '../data/printer_status_cros.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {I18nBehaviorInterface}
- * @implements {SelectBehaviorInterface}
- */
 const PrintPreviewDestinationSelectCrosElementBase =
-    mixinBehaviors([I18nBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([I18nBehavior], SelectMixin(PolymerElement)) as
+    {new (): I18nBehavior & SelectMixinInterface & PolymerElement};
 
-/** @polymer */
 export class PrintPreviewDestinationSelectCrosElement extends
     PrintPreviewDestinationSelectCrosElementBase {
   static get is() {
@@ -50,7 +43,6 @@
 
       dark: Boolean,
 
-      /** @type {!Destination} */
       destination: Object,
 
       disabled: Boolean,
@@ -63,19 +55,16 @@
 
       pdfPrinterDisabled: Boolean,
 
-      /** @type {!Array<!Destination>} */
       recentDestinationList: {
         type: Array,
         observer: 'onRecentDestinationListChanged_',
       },
 
-      /** @private {string} */
       pdfDestinationKey_: {
         type: String,
         value: PDF_DESTINATION_KEY,
       },
 
-      /** @private {string} */
       statusText_: {
         type: String,
         computed:
@@ -83,15 +72,12 @@
         observer: 'onStatusTextSet_',
       },
 
-      /** @private {string} */
       destinationIcon_: {
         type: String,
-        computed:
-            'computeDestinationIcon_('+
-                'selectedValue, destination, destination.printerStatusReason)',
+        computed: 'computeDestinationIcon_(' +
+            'selectedValue, destination, destination.printerStatusReason)',
       },
 
-      /** @private */
       isCurrentDestinationCrosLocal_: {
         type: Boolean,
         computed: 'computeIsCurrentDestinationCrosLocal_(destination)',
@@ -100,10 +86,17 @@
     };
   }
 
+  destination: Destination;
+  pdfPrinterDisabled: boolean;
+  recentDestinationList: Destination[];
+  private pdfDestinationKey_: string;
+  private statusText_: string;
+  private destinationIcon_: string;
+  private isCurrentDestinationCrosLocal_: boolean;
+
   focus() {
-    this.shadowRoot.querySelector('#dropdown')
-        .shadowRoot.querySelector('#destination-dropdown')
-        .focus();
+    this.shadowRoot!.querySelector(
+                        'print-preview-destination-dropdown-cros')!.focus();
   }
 
   /** Sets the select to the current value of |destination|. */
@@ -115,10 +108,9 @@
    * Returns the iconset and icon for the selected printer. If printer details
    * have not yet been retrieved from the backend, attempts to return an
    * appropriate icon early based on the printer's sticky information.
-   * @return {string} The iconset and icon for the current selection.
-   * @private
+   * @return The iconset and icon for the current selection.
    */
-  computeDestinationIcon_() {
+  private computeDestinationIcon_(): string {
     if (!this.selectedValue) {
       return '';
     }
@@ -163,25 +155,17 @@
     return 'print-preview:print';
   }
 
-  /**
-   * @param {string} value
-   * @private
-   */
-  fireSelectedOptionChange_(value) {
+  private fireSelectedOptionChange_(value: string) {
     this.dispatchEvent(new CustomEvent(
         'selected-option-change',
         {bubbles: true, composed: true, detail: value}));
   }
 
-  onProcessSelectChange(value) {
+  onProcessSelectChange(value: string) {
     this.fireSelectedOptionChange_(value);
   }
 
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  onDropdownValueSelected_(e) {
+  private onDropdownValueSelected_(e: CustomEvent<HTMLButtonElement>) {
     const selectedItem = e.detail;
     if (!selectedItem || selectedItem.value === this.destination.key) {
       return;
@@ -192,9 +176,8 @@
 
   /**
    * Send a printer status request for any new destination in the dropdown.
-   * @private
    */
-  onRecentDestinationListChanged_() {
+  private onRecentDestinationListChanged_() {
     for (const destination of this.recentDestinationList) {
       if (!destination || destination.origin !== DestinationOrigin.CROS) {
         continue;
@@ -208,10 +191,8 @@
   /**
    * Check if the printer is currently in the dropdown then update its status
    *    icon if it's present.
-   * @param {string} destinationKey
-   * @private
    */
-  onPrinterStatusReceived_(destinationKey) {
+  private onPrinterStatusReceived_(destinationKey: string) {
     const indexFound = this.recentDestinationList.findIndex(destination => {
       return destination.key === destinationKey;
     });
@@ -232,11 +213,10 @@
   }
 
   /**
-   * @return {string}  An error status for the current destination. If no error
+   * @return An error status for the current destination. If no error
    *     status exists, an empty string.
-   * @private
    */
-  computeStatusText_() {
+  private computeStatusText_(): string {
     // |destination| can be either undefined, or null here.
     if (!this.destination) {
       return '';
@@ -258,7 +238,7 @@
     }
 
     const printerStatusReason = this.destination.printerStatusReason;
-    if (!printerStatusReason ||
+    if (printerStatusReason === null ||
         printerStatusReason === PrinterStatusReason.NO_ERROR ||
         printerStatusReason === PrinterStatusReason.UNKNOWN_REASON) {
       return '';
@@ -267,38 +247,29 @@
     return this.getErrorString_(printerStatusReason);
   }
 
-  /** @private */
-  onStatusTextSet_() {
-    this.shadowRoot.querySelector('#statusText').innerHTML = this.statusText_;
+  private onStatusTextSet_() {
+    this.shadowRoot!.querySelector('#statusText')!.innerHTML = this.statusText_;
   }
 
-  /**
-   * @param {!PrinterStatusReason} printerStatusReason
-   * @return {!string}
-   * @private
-   */
-  getErrorString_(printerStatusReason) {
+  private getErrorString_(printerStatusReason: PrinterStatusReason): string {
     const errorStringKey = ERROR_STRING_KEY_MAP.get(printerStatusReason);
     return errorStringKey ? this.i18n(errorStringKey) : '';
   }
 
   /**
    * True when the currently selected destination is a CrOS local printer.
-   * @return {boolean}
-   * @private
    */
-  computeIsCurrentDestinationCrosLocal_() {
+  private computeIsCurrentDestinationCrosLocal_(): boolean {
     return this.destination &&
         this.destination.origin === DestinationOrigin.CROS;
   }
 
   /**
    * Return the options currently visible to the user for testing purposes.
-   * @return {!Array<!Element>}
    */
-  getVisibleItemsForTest() {
-    return this.shadowRoot.querySelector('#dropdown')
-        .shadowRoot.querySelectorAll('.list-item:not([hidden])');
+  getVisibleItemsForTest(): NodeListOf<Element> {
+    return this.shadowRoot!.querySelector('#dropdown')!.shadowRoot!
+        .querySelectorAll('.list-item:not([hidden])');
   }
 }
 
diff --git a/chrome/browser/resources/print_preview/ui/destination_select_css.js b/chrome/browser/resources/print_preview/ui/destination_select_css.ts
similarity index 100%
rename from chrome/browser/resources/print_preview/ui/destination_select_css.js
rename to chrome/browser/resources/print_preview/ui/destination_select_css.ts
diff --git a/chrome/browser/resources/print_preview/ui/duplex_settings.js b/chrome/browser/resources/print_preview/ui/duplex_settings.js
index c1c57b5b..536242a 100644
--- a/chrome/browser/resources/print_preview/ui/duplex_settings.js
+++ b/chrome/browser/resources/print_preview/ui/duplex_settings.js
@@ -16,17 +16,17 @@
 import {DuplexMode} from '../data/model.js';
 import {getSelectDropdownBackground} from '../print_preview_utils.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 import {SettingsBehavior, SettingsBehaviorInterface} from './settings_behavior.js';
 
 /**
  * @constructor
  * @extends {PolymerElement}
  * @implements {SettingsBehaviorInterface}
- * @implements {SelectBehaviorInterface}
+ * @implements {SelectMixinInterface}
  */
 const PrintPreviewDuplexSettingsElementBase =
-    mixinBehaviors([SettingsBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([SettingsBehavior], SelectMixin(PolymerElement));
 
 /** @polymer */
 export class PrintPreviewDuplexSettingsElement extends
diff --git a/chrome/browser/resources/print_preview/ui/layout_settings.js b/chrome/browser/resources/print_preview/ui/layout_settings.js
index c027f10..868fbc6 100644
--- a/chrome/browser/resources/print_preview/ui/layout_settings.js
+++ b/chrome/browser/resources/print_preview/ui/layout_settings.js
@@ -8,7 +8,7 @@
 
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 import {SettingsBehavior, SettingsBehaviorInterface} from './settings_behavior.js';
 
 
@@ -16,10 +16,10 @@
  * @constructor
  * @extends {PolymerElement}
  * @implements {SettingsBehaviorInterface}
- * @implements {SelectBehaviorInterface}
+ * @implements {SelectMixinInterface}
  */
 const PrintPreviewLayoutSettingsElementBase =
-    mixinBehaviors([SettingsBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([SettingsBehavior], SelectMixin(PolymerElement));
 
 /** @polymer */
 export class PrintPreviewLayoutSettingsElement extends
diff --git a/chrome/browser/resources/print_preview/ui/margins_settings.js b/chrome/browser/resources/print_preview/ui/margins_settings.js
index ca2c239..49eaaa4f0 100644
--- a/chrome/browser/resources/print_preview/ui/margins_settings.js
+++ b/chrome/browser/resources/print_preview/ui/margins_settings.js
@@ -11,17 +11,17 @@
 import {MarginsType} from '../data/margins.js';
 import {State} from '../data/state.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 import {SettingsBehavior, SettingsBehaviorInterface} from './settings_behavior.js';
 
 /**
  * @constructor
  * @extends {PolymerElement}
- * @implements {SelectBehaviorInterface}
+ * @implements {SelectMixinInterface}
  * @implements {SettingsBehaviorInterface}
  */
 const PrintPreviewMarginsSettingsElementBase =
-    mixinBehaviors([SettingsBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([SettingsBehavior], SelectMixin(PolymerElement));
 
 /** @polymer */
 export class PrintPreviewMarginsSettingsElement extends
diff --git a/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js b/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js
index 8e9c538..d60620d 100644
--- a/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js
+++ b/chrome/browser/resources/print_preview/ui/pages_per_sheet_settings.js
@@ -10,17 +10,17 @@
 
 import {MarginsType} from '../data/margins.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 import {SettingsBehavior, SettingsBehaviorInterface} from './settings_behavior.js';
 
 /**
  * @constructor
  * @extends {PolymerElement}
- * @implements {SelectBehaviorInterface}
+ * @implements {SelectMixinInterface}
  * @implements {SettingsBehaviorInterface}
  */
 const PrintPreviewPagesPerSheetSettingsElementBase =
-    mixinBehaviors([SettingsBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([SettingsBehavior], SelectMixin(PolymerElement));
 
 /** @polymer */
 export class PrintPreviewPagesPerSheetSettingsElement extends
diff --git a/chrome/browser/resources/print_preview/ui/pages_settings.js b/chrome/browser/resources/print_preview/ui/pages_settings.js
index 9956eae..87615dba 100644
--- a/chrome/browser/resources/print_preview/ui/pages_settings.js
+++ b/chrome/browser/resources/print_preview/ui/pages_settings.js
@@ -17,7 +17,7 @@
 import {areRangesEqual} from '../print_preview_utils.js';
 
 import {InputBehavior, InputBehaviorInterface} from './input_behavior.js';
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 import {SettingsBehavior, SettingsBehaviorInterface} from './settings_behavior.js';
 
 /** @enum {number} */
@@ -56,13 +56,13 @@
  * @constructor
  * @extends {PolymerElement}
  * @implements {InputBehaviorInterface}
- * @implements {SelectBehaviorInterface}
+ * @implements {SelectMixinInterface}
  * @implements {SettingsBehaviorInterface}
  * @implements {WebUIListenerBehaviorInterface}
  */
 const PrintPreviewPagesSettingsElementBase = mixinBehaviors(
-    [SettingsBehavior, InputBehavior, SelectBehavior, WebUIListenerBehavior],
-    PolymerElement);
+    [SettingsBehavior, InputBehavior, WebUIListenerBehavior],
+    SelectMixin(PolymerElement));
 
 /** @polymer */
 export class PrintPreviewPagesSettingsElement extends
diff --git a/chrome/browser/resources/print_preview/ui/scaling_settings.js b/chrome/browser/resources/print_preview/ui/scaling_settings.js
index 1cfd4161..d19cdb2 100644
--- a/chrome/browser/resources/print_preview/ui/scaling_settings.js
+++ b/chrome/browser/resources/print_preview/ui/scaling_settings.js
@@ -12,7 +12,7 @@
 
 import {ScalingType} from '../data/scaling.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 import {SettingsBehavior, SettingsBehaviorInterface} from './settings_behavior.js';
 
 /*
@@ -24,11 +24,11 @@
 /**
  * @constructor
  * @extends {PolymerElement}
- * @implements {SelectBehaviorInterface}
+ * @implements {SelectMixinInterface}
  * @implements {SettingsBehaviorInterface}
  */
 const PrintPreviewScalingSettingsElementBase =
-    mixinBehaviors([SettingsBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([SettingsBehavior], SelectMixin(PolymerElement));
 
 /** @polymer */
 export class PrintPreviewScalingSettingsElement extends
diff --git a/chrome/browser/resources/print_preview/ui/select_behavior.js b/chrome/browser/resources/print_preview/ui/select_behavior.js
deleted file mode 100644
index 92bc3d6..0000000
--- a/chrome/browser/resources/print_preview/ui/select_behavior.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-/**
- * Helper functions for a select with timeout. Implemented by select settings
- * sections, so that the preview does not immediately begin generating and
- * freeze the dropdown when the value is changed.
- * Assumes that the elements implementing this behavior have no more than one
- * select element.
- * @polymerBehavior
- */
-export const SelectBehavior = {
-  properties: {
-    selectedValue: {
-      type: String,
-      observer: 'onSelectedValueChange_',
-    },
-  },
-
-  /**
-   * @param {string} current
-   * @param {?string} previous
-   * @private
-   */
-  onSelectedValueChange_(current, previous) {
-    // Don't trigger an extra preview request at startup.
-    if (previous === undefined) {
-      return;
-    }
-
-    this.debounce('select-change', () => {
-      if (this.isConnected) {
-        this.onProcessSelectChange(this.selectedValue);
-        // For testing only
-        this.fire('process-select-change');
-      }
-    }, 100);
-  },
-
-  /**
-   * Should be overridden by elements using this behavior to receive select
-   * value updates.
-   * @param {string} value The new select value to process.
-   */
-  onProcessSelectChange(value) {},
-};
-
-/** @interface */
-export class SelectBehaviorInterface {
-  constructor() {
-    /** @type {string} */
-    this.selectedValue;
-  }
-
-  /**
-   * Should be overridden by elements using this behavior to receive select
-   * value updates.
-   * @param {string} value The new select value to process.
-   */
-  onProcessSelectChange(value) {}
-}
diff --git a/chrome/browser/resources/print_preview/ui/select_mixin.ts b/chrome/browser/resources/print_preview/ui/select_mixin.ts
new file mode 100644
index 0000000..0ada172
--- /dev/null
+++ b/chrome/browser/resources/print_preview/ui/select_mixin.ts
@@ -0,0 +1,70 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+import {Debouncer, dedupingMixin, PolymerElement, timeOut} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+/**
+ * Helper functions for a select with timeout. Implemented by select settings
+ * sections, so that the preview does not immediately begin generating and
+ * freeze the dropdown when the value is changed.
+ * Assumes that the elements using this mixin have no more than one select
+ * element.
+ */
+
+type Constructor<T> = new (...args: any[]) => T;
+
+export const SelectMixin = dedupingMixin(
+    <T extends Constructor<PolymerElement>>(superClass: T): T&
+    Constructor<SelectMixinInterface> => {
+      class SelectMixin extends superClass {
+        static get properties() {
+          return {
+            selectedValue: {
+              type: String,
+              observer: 'onSelectedValueChange_',
+            },
+          };
+        }
+
+        selectedValue: string;
+        private debouncer_: Debouncer|null = null;
+
+        private onSelectedValueChange_(
+            _current: string, previous: string|null|undefined) {
+          // Don't trigger an extra preview request at startup.
+          if (previous === undefined) {
+            return;
+          }
+
+          this.debouncer_ = Debouncer.debounce(
+              this.debouncer_, timeOut.after(100),
+              () => this.callProcessSelectChange_());
+        }
+
+        private callProcessSelectChange_() {
+          if (!this.isConnected) {
+            return;
+          }
+
+          this.onProcessSelectChange(this.selectedValue);
+          // For testing only
+          this.dispatchEvent(new CustomEvent(
+              'process-select-change', {bubbles: true, composed: true}));
+        }
+
+        onProcessSelectChange(_value: string) {}
+      }
+
+      return SelectMixin;
+    });
+
+export interface SelectMixinInterface {
+  selectedValue: string;
+
+  /**
+   * Should be overridden by elements using this mixin to receive select
+   * value updates.
+   * @param value The new select value to process.
+   */
+  onProcessSelectChange(value: string): void;
+}
diff --git a/chrome/browser/resources/print_preview/ui/settings_select.js b/chrome/browser/resources/print_preview/ui/settings_select.js
index 8344d9f..423c2e9d 100644
--- a/chrome/browser/resources/print_preview/ui/settings_select.js
+++ b/chrome/browser/resources/print_preview/ui/settings_select.js
@@ -10,7 +10,7 @@
 
 import {getStringForCurrentLocale} from '../print_preview_utils.js';
 
-import {SelectBehavior, SelectBehaviorInterface} from './select_behavior.js';
+import {SelectMixin, SelectMixinInterface} from './select_mixin.js';
 import {SettingsBehavior, SettingsBehaviorInterface} from './settings_behavior.js';
 
 /**
@@ -28,10 +28,10 @@
  * @constructor
  * @extends {PolymerElement}
  * @implements {SettingsBehaviorInterface}
- * @implements {SelectBehaviorInterface}
+ * @implements {SelectMixinInterface}
  */
 const PrintPreviewSettingsSelectElementBase =
-    mixinBehaviors([SettingsBehavior, SelectBehavior], PolymerElement);
+    mixinBehaviors([SettingsBehavior], SelectMixin(PolymerElement));
 
 /** @polymer */
 export class PrintPreviewSettingsSelectElement extends
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
index aa58459..346c9e7 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_impl_win.cc
@@ -123,11 +123,6 @@
              : ChromeCleanerController::IdleReason::kConnectionLost;
 }
 
-void RecordScannerLogsAcceptanceHistogram(bool logs_accepted) {
-  UMA_HISTOGRAM_BOOLEAN("SoftwareReporter.ScannerLogsAcceptance",
-                        logs_accepted);
-}
-
 void RecordCleanerLogsAcceptanceHistogram(bool logs_accepted) {
   UMA_HISTOGRAM_BOOLEAN("SoftwareReporter.CleanerLogsAcceptance",
                         logs_accepted);
@@ -145,10 +140,6 @@
                             static_cast<int>(SwReporterInvocationType::kMax));
 }
 
-void RecordOnDemandUpdateRequiredHistogram(bool value) {
-  UMA_HISTOGRAM_BOOLEAN("SoftwareReporter.OnDemandUpdateRequired", value);
-}
-
 }  // namespace
 
 ChromeCleanerControllerDelegate::ChromeCleanerControllerDelegate() = default;
@@ -383,7 +374,6 @@
              SwReporterInvocationType::kUserInitiatedWithLogsDisallowed);
 
   const bool logs_enabled = this->logs_enabled(profile);
-  RecordScannerLogsAcceptanceHistogram(logs_enabled);
 
   SwReporterInvocationType invocation_type =
       logs_enabled ? SwReporterInvocationType::kUserInitiatedWithLogsAllowed
@@ -399,8 +389,6 @@
             // The invocations will be modified by the |ReporterRunner|.
             // Give it a copy to keep the cached invocations pristine.
             std::move(copied_sequence)));
-
-    RecordOnDemandUpdateRequiredHistogram(false);
   } else {
     pending_invocation_type_ = invocation_type;
     OnReporterSequenceStarted();
@@ -415,8 +403,6 @@
             base::BindOnce(&ChromeCleanerController::OnReporterSequenceDone,
                            base::Unretained(this),
                            SwReporterInvocationResult::kComponentNotAvailable));
-
-    RecordOnDemandUpdateRequiredHistogram(true);
   }
 }
 
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc
index 93bdafe..a51f9fc 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc
@@ -191,8 +191,6 @@
     return;
   }
   ShowChromeCleanerPrompt();
-  RecordPromptShownWithTypeHistogram(
-      PromptTypeHistogramValue::PROMPT_TYPE_ON_TRANSITION_TO_INFECTED_STATE);
 }
 
 void ChromeCleanerDialogControllerImpl::OnCleaning(
@@ -215,8 +213,6 @@
 
   browser_ = browser;
   ShowChromeCleanerPrompt();
-  RecordPromptShownWithTypeHistogram(
-      PromptTypeHistogramValue::PROMPT_TYPE_ON_BROWSER_WINDOW_AVAILABLE);
   prompt_pending_ = false;
   BrowserList::RemoveObserver(this);
 }
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc
index b2db33b..a86551cb 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.cc
@@ -19,6 +19,7 @@
 #include "base/sequence_checker.h"
 #include "base/synchronization/lock.h"
 #include "base/win/registry.h"
+#include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profile_resetter/profile_resetter.h"
 #include "chrome/browser/profiles/profile.h"
@@ -220,7 +221,6 @@
   DCHECK(profile);
 
   RecordResetPending(true, profile);
-  UMA_HISTOGRAM_BOOLEAN("SoftwareReporter.TaggedProfileForResetting", true);
 }
 
 void PostCleanupSettingsResetter::ResetTaggedProfiles(
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
index 959c0e7..00ae150 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.cc
@@ -89,11 +89,6 @@
   return kSRTPromptGroupNameParam.Get();
 }
 
-void RecordPromptShownWithTypeHistogram(PromptTypeHistogramValue value) {
-  UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.PromptShownWithType", value,
-                            PROMPT_TYPE_MAX);
-}
-
 void RecordPromptNotShownWithReasonHistogram(
     NoPromptReasonHistogramValue value) {
   UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.NoPromptReason", value,
diff --git a/chrome/browser/share/share_submenu_model.cc b/chrome/browser/share/share_submenu_model.cc
index 527c306a..aa06bfd 100644
--- a/chrome/browser/share/share_submenu_model.cc
+++ b/chrome/browser/share/share_submenu_model.cc
@@ -61,7 +61,7 @@
 
 const base::Feature kShareMenu{
     "ShareMenu",
-    base::FEATURE_DISABLED_BY_DEFAULT,
+    base::FEATURE_ENABLED_BY_DEFAULT,
 };
 
 ShareSubmenuModel::ShareSubmenuModel(
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.cc b/chrome/browser/ui/ash/projector/projector_client_impl.cc
index fb9bfc5..ed2a5b6 100644
--- a/chrome/browser/ui/ash/projector/projector_client_impl.cc
+++ b/chrome/browser/ui/ash/projector/projector_client_impl.cc
@@ -30,6 +30,9 @@
 ProjectorClientImpl::ProjectorClientImpl(ash::ProjectorController* controller)
     : controller_(controller) {
   controller_->SetClient(this);
+  if (ash::ProjectorController::AreExtendedProjectorFeaturesDisabled())
+    return;
+
   bool recognition_available =
       OnDeviceSpeechRecognizer::IsOnDeviceSpeechRecognizerAvailable(
           kEnglishLanguageCode) ||
@@ -115,6 +118,9 @@
 
 bool ProjectorClientImpl::GetDriveFsMountPointPath(
     base::FilePath* result) const {
+  // TODO(b/197164300) Implement persisting screencasts in this mode by
+  // creating a temp folder for testing purposes
+
   if (!IsDriveFsMounted())
     return false;
   drive::DriveIntegrationService* integration_service =
diff --git a/chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc b/chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc
index 3dffbf8..8d80c07 100644
--- a/chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/payments/card_unmask_authentication_selection_dialog_controller_impl.cc
@@ -20,12 +20,13 @@
 
 CardUnmaskAuthenticationSelectionDialogControllerImpl::
     ~CardUnmaskAuthenticationSelectionDialogControllerImpl() {
-  // This part of code is executed only if browser window is closed when the
+  // This part of code is executed only if the browser window is closed when the
   // dialog is visible. In this case the controller is destroyed before
   // CardUnmaskAuthenticationSelectionDialogViewImpl::dtor() is called,
-  // but the reference to controller is not reset. Need to reset via
-  // CardUnmaskAuthenticationSelectionDialogView::CloseDialog() to avoid a
-  // crash.
+  // but the reference to controller is not reset. This reference needs to be
+  // reset via
+  // CardUnmaskAuthenticationSelectionDialogView::OnControllerDestroying() to
+  // avoid a crash.
   if (dialog_view_)
     dialog_view_->OnControllerDestroying();
 }
diff --git a/chrome/browser/ui/messages/android/java/res/layout/snackbar.xml b/chrome/browser/ui/messages/android/java/res/layout/snackbar.xml
index 6303c20..a254ba4 100644
--- a/chrome/browser/ui/messages/android/java/res/layout/snackbar.xml
+++ b/chrome/browser/ui/messages/android/java/res/layout/snackbar.xml
@@ -65,7 +65,7 @@
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_gravity="start|center_vertical"
-            android:layout_marginStart="24dp"
+            android:layout_marginStart="@dimen/snackbar_text_view_margin"
             android:layout_marginTop="14dp"
             android:layout_marginBottom="14dp"
             android:layout_weight="1"
diff --git a/chrome/browser/ui/messages/android/java/res/values/dimens.xml b/chrome/browser/ui/messages/android/java/res/values/dimens.xml
index 03cc8738..29ad6b0 100644
--- a/chrome/browser/ui/messages/android/java/res/values/dimens.xml
+++ b/chrome/browser/ui/messages/android/java/res/values/dimens.xml
@@ -9,4 +9,5 @@
     <dimen name="snackbar_width_tablet">450dp</dimen>
     <dimen name="snackbar_margin_tablet">24dp</dimen>
     <dimen name="snackbar_shadow_height">8dp</dimen>
+    <dimen name="snackbar_text_view_margin">24dp</dimen>
 </resources>
diff --git a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
index d1909c3..b3adb456 100644
--- a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
+++ b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarView.java
@@ -22,6 +22,7 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
+import android.widget.LinearLayout.LayoutParams;
 import android.widget.TextView;
 
 import androidx.annotation.Nullable;
@@ -312,8 +313,21 @@
             mActionButtonView.setVisibility(View.VISIBLE);
             mActionButtonView.setContentDescription(snackbar.getActionText());
             setViewText(mActionButtonView, snackbar.getActionText(), animate);
+            // Set the end margin on the message view to 0 when there is action text.
+            if (mMessageView.getLayoutParams() instanceof LayoutParams) {
+                LayoutParams lp = (LayoutParams) mMessageView.getLayoutParams();
+                lp.setMarginEnd(0);
+                mMessageView.setLayoutParams(lp);
+            }
         } else {
             mActionButtonView.setVisibility(View.GONE);
+            // Set a non-zero end margin on the message view when there is no action text.
+            if (mMessageView.getLayoutParams() instanceof LayoutParams) {
+                LayoutParams lp = (LayoutParams) mMessageView.getLayoutParams();
+                lp.setMarginEnd(mParent.getResources().getDimensionPixelSize(
+                        R.dimen.snackbar_text_view_margin));
+                mMessageView.setLayoutParams(lp);
+            }
         }
         Drawable profileImage = snackbar.getProfileImage();
         if (profileImage != null) {
diff --git a/chrome/browser/ui/search/omnibox_utils.cc b/chrome/browser/ui/search/omnibox_utils.cc
index c9033bb6..5a8a491 100644
--- a/chrome/browser/ui/search/omnibox_utils.cc
+++ b/chrome/browser/ui/search/omnibox_utils.cc
@@ -48,8 +48,9 @@
     // Remove focus only if the popup is closed. This will prevent someone
     // from changing the omnibox value and closing the popup without user
     // interaction.
-    if (!omnibox_view->model()->popup_model()->IsOpen())
+    if (!omnibox_view->model()->PopupIsOpen()) {
       web_contents->Focus();
+    }
   }
 }
 
diff --git a/chrome/browser/ui/views/autofill/payments/card_unmask_authentication_selection_dialog_view_impl.cc b/chrome/browser/ui/views/autofill/payments/card_unmask_authentication_selection_dialog_view_impl.cc
index cfbfb8f..08d0f9d 100644
--- a/chrome/browser/ui/views/autofill/payments/card_unmask_authentication_selection_dialog_view_impl.cc
+++ b/chrome/browser/ui/views/autofill/payments/card_unmask_authentication_selection_dialog_view_impl.cc
@@ -39,6 +39,7 @@
 
 CardUnmaskAuthenticationSelectionDialogViewImpl::
     ~CardUnmaskAuthenticationSelectionDialogViewImpl() {
+  // Inform `controller_` of the dialog's destruction.
   if (controller_)
     controller_->OnDialogClosed();
 }
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 5ea4422..1af9a97 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -912,7 +912,7 @@
 
   // Also hide them if the popup is open for any other reason, e.g. ZeroSuggest.
   // The page action icons are not relevant to the displayed suggestions.
-  return omnibox_view_->model()->popup_model()->IsOpen();
+  return omnibox_view_->model()->PopupIsOpen();
 }
 
 // static
@@ -1057,7 +1057,7 @@
 
 OmniboxPopupView* LocationBarView::GetOmniboxPopupView() {
   DCHECK(IsInitialized());
-  return omnibox_view_->model()->popup_model()->view();
+  return omnibox_view_->model()->get_popup_view();
 }
 
 void LocationBarView::KeywordHintViewPressed(const ui::Event& event) {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
index 2762a9f..66310c1 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -222,27 +222,22 @@
   DCHECK(HasMatchAt(index));
 
   OmniboxPopupSelection::LineState line_state = OmniboxPopupSelection::NORMAL;
-  edit_model_->popup_model()->SetSelection(
-      OmniboxPopupSelection(index, line_state));
-  OnPropertyChanged(edit_model_->popup_model(), views::kPropertyEffectsNone);
+  edit_model_->SetPopupSelection(OmniboxPopupSelection(index, line_state));
+  OnPropertyChanged(edit_model_, views::kPropertyEffectsNone);
 }
 
 size_t OmniboxPopupContentsView::GetSelectedIndex() const {
-  return edit_model_->popup_model()->selected_line();
+  return GetSelection().line;
 }
 
 OmniboxPopupSelection OmniboxPopupContentsView::GetSelection() const {
-  // TODO(orinj): This should get full selection straight from popup model
-  // and should be the only selection method; eliminate others and
-  // reconcile with test code overrides of `GetSelectedIndex` and
-  // `SetSelectedIndex`.
-  return OmniboxPopupSelection(
-      GetSelectedIndex(), edit_model_->popup_model()->selected_line_state());
+  return edit_model_->GetPopupSelection();
 }
 
 void OmniboxPopupContentsView::UnselectButton() {
-  edit_model_->popup_model()->SetSelectedLineState(
-      OmniboxPopupSelection::NORMAL);
+  OmniboxPopupSelection selection = edit_model_->GetPopupSelection();
+  selection.state = OmniboxPopupSelection::NORMAL;
+  edit_model_->SetPopupSelection(selection);
 }
 
 OmniboxResultView* OmniboxPopupContentsView::result_view_at(size_t i) {
@@ -412,8 +407,7 @@
                               pref_service, match.suggestion_group_id.value());
       result_view->SetVisible(!match_hidden);
 
-      const SkBitmap* bitmap =
-          edit_model_->popup_model()->RichSuggestionBitmapAt(i);
+      const SkBitmap* bitmap = edit_model_->GetPopupRichSuggestionBitmap(i);
       if (bitmap) {
         result_view->SetRichSuggestionImage(
             gfx::ImageSkia::CreateFrom1xBitmap(*bitmap));
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
index a9dc2bc..d3edc46 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
+++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
@@ -61,7 +61,7 @@
   virtual size_t GetSelectedIndex() const;
 
   // Returns current popup selection (includes line index).
-  OmniboxPopupSelection GetSelection() const;
+  virtual OmniboxPopupSelection GetSelection() const;
 
   // Called by the active result view to inform model (due to mouse event).
   void UnselectButton();
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
index 9315280..659cb4a 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -432,7 +432,7 @@
 
 void OmniboxResultView::ButtonPressed(OmniboxPopupSelection::LineState state,
                                       const ui::Event& event) {
-  model_->popup_model()->TriggerSelectionAction(
+  model_->TriggerPopupSelectionAction(
       OmniboxPopupSelection(model_index_, state), event.time_stamp());
 }
 
@@ -500,11 +500,10 @@
     // The selected match can have a special name, e.g. when is one or more
     // buttons that can be tabbed to.
     std::u16string label =
-        is_selected
-            ? model_->popup_model()->GetAccessibilityLabelForCurrentSelection(
-                  raw_match.contents, false)
-            : AutocompleteMatchType::ToAccessibilityLabel(raw_match,
-                                                          raw_match.contents);
+        is_selected ? model_->GetPopupAccessibilityLabelForCurrentSelection(
+                          raw_match.contents, false)
+                    : AutocompleteMatchType::ToAccessibilityLabel(
+                          raw_match, raw_match.contents);
     node_data->SetName(label);
   }
 
@@ -562,7 +561,7 @@
 void OmniboxResultView::UpdateRemoveSuggestionVisibility() {
   bool old_visibility = remove_suggestion_button_->GetVisible();
   bool new_visibility =
-      model_->popup_model()->IsControlPresentOnMatch(OmniboxPopupSelection(
+      model_->IsPopupControlPresentOnMatch(OmniboxPopupSelection(
           model_index_,
           OmniboxPopupSelection::FOCUSED_BUTTON_REMOVE_SUGGESTION)) &&
       (GetMatchSelected() || IsMouseHovered());
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc
index 5e80712..9b144b9b 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_result_view_unittest.cc
@@ -37,18 +37,20 @@
             /*omnibox_view=*/nullptr,
             edit_model,
             /*location_bar_view=*/nullptr),
-        selected_index_(0) {}
+        selection_(OmniboxPopupSelection(0, OmniboxPopupSelection::NORMAL)) {}
 
   TestOmniboxPopupContentsView(const TestOmniboxPopupContentsView&) = delete;
   TestOmniboxPopupContentsView& operator=(const TestOmniboxPopupContentsView&) =
       delete;
 
-  void SetSelectedIndex(size_t index) override { selected_index_ = index; }
+  void SetSelectedIndex(size_t index) override { selection_.line = index; }
 
-  size_t GetSelectedIndex() const override { return selected_index_; }
+  size_t GetSelectedIndex() const override { return selection_.line; }
+
+  OmniboxPopupSelection GetSelection() const override { return selection_; }
 
  private:
-  size_t selected_index_;
+  OmniboxPopupSelection selection_;
 };
 
 }  // namespace
diff --git a/chrome/browser/ui/views/omnibox/omnibox_row_view.cc b/chrome/browser/ui/views/omnibox/omnibox_row_view.cc
index 70cd11c3..31fc4f0 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_row_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_row_view.cc
@@ -72,8 +72,7 @@
     views::FocusRing::Get(header_toggle_button_)
         ->SetHasFocusPredicate([&](View* view) {
           return view->GetVisible() &&
-                 row_view_->model_->popup_model()->selection() ==
-                     GetHeaderSelection();
+                 row_view_->model_->GetPopupSelection() == GetHeaderSelection();
         });
 
     if (row_view_->pref_service_) {
@@ -125,8 +124,7 @@
     return true;
   }
   void OnMouseReleased(const ui::MouseEvent& event) override {
-    row_view_->model_->popup_model()->TriggerSelectionAction(
-        GetHeaderSelection());
+    row_view_->model_->TriggerPopupSelectionAction(GetHeaderSelection());
   }
   void OnMouseEntered(const ui::MouseEvent& event) override { UpdateUI(); }
   void OnMouseExited(const ui::MouseEvent& event) override { UpdateUI(); }
@@ -150,7 +148,7 @@
   // Updates the UI state for the new hover or selection state.
   void UpdateUI() {
     OmniboxPartState part_state = OmniboxPartState::NORMAL;
-    if (row_view_->model_->popup_model()->selection() == GetHeaderSelection()) {
+    if (row_view_->model_->GetPopupSelection() == GetHeaderSelection()) {
       part_state = OmniboxPartState::SELECTED;
     } else if (IsMouseHovered()) {
       part_state = OmniboxPartState::HOVERED;
@@ -200,8 +198,7 @@
 
  private:
   void HeaderToggleButtonPressed() {
-    row_view_->model_->popup_model()->TriggerSelectionAction(
-        GetHeaderSelection());
+    row_view_->model_->TriggerPopupSelectionAction(GetHeaderSelection());
     // The PrefChangeRegistrar will update the actual button toggle state.
   }
 
@@ -350,8 +347,8 @@
 }
 
 views::View* OmniboxRowView::GetActiveAuxiliaryButtonForAccessibility() const {
-  DCHECK(model_->popup_model()->selection().IsButtonFocused());
-  if (model_->popup_model()->selected_line_state() ==
+  DCHECK(model_->GetPopupSelection().IsButtonFocused());
+  if (model_->GetPopupSelection().state ==
       OmniboxPopupSelection::FOCUSED_BUTTON_HEADER) {
     return header_view_->header_toggle_button();
   }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
index 26c0343..30594bf 100644
--- a/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
+++ b/chrome/browser/ui/views/omnibox/omnibox_suggestion_button_row_view.cc
@@ -265,7 +265,7 @@
       !OmniboxFieldTrial::IsKeywordSearchButtonEnabled()) {
     button->SetVisible(false);
   } else {
-    button->SetVisible(model_->popup_model()->IsControlPresentOnMatch(
+    button->SetVisible(model_->IsPopupControlPresentOnMatch(
         OmniboxPopupSelection(model_index_, state)));
   }
 }
@@ -282,7 +282,7 @@
     // a second click of the button violates assumptions in |AcceptKeyword|.
     // Note: Since keyword mode logic depends on state of the edit model, the
     // selection must first be set to prepare for keyword mode before accepting.
-    model_->popup_model()->SetSelection(selection);
+    model_->SetPopupSelection(selection);
     if (model_->is_keyword_hint()) {
       const auto entry_method =
           event.IsMouseEvent() ? metrics::OmniboxEventProto::CLICK_HINT_VIEW
@@ -290,8 +290,7 @@
       model_->AcceptKeyword(entry_method);
     }
   } else {
-    model_->popup_model()->TriggerSelectionAction(selection,
-                                                  event.time_stamp());
+    model_->TriggerPopupSelectionAction(selection, event.time_stamp());
   }
 }
 
diff --git a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc
index 251d45dd..c0beb18 100644
--- a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc
+++ b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc
@@ -174,14 +174,7 @@
       dot_bounds_updater_(
           std::make_unique<DotBoundsUpdater>(dot_indicator_, image())),
       reading_list_model_(
-          ReadingListModelFactory::GetForBrowserContext(browser_->profile())),
-      contents_wrapper_(std::make_unique<BubbleContentsWrapperT<ReadLaterUI>>(
-          GURL(chrome::kChromeUIReadLaterURL),
-          browser_->profile(),
-          IDS_READ_LATER_TITLE,
-          true)) {
-  contents_wrapper_->ReloadWebContents();
-
+          ReadingListModelFactory::GetForBrowserContext(browser_->profile())) {
   SetVectorIcons(kSidePanelIcon, kSidePanelTouchIcon);
   SetTooltipText(l10n_util::GetStringUTF16(IDS_TOOLTIP_SIDE_PANEL_SHOW));
   button_controller()->set_notify_action(
diff --git a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.h b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.h
index 0a14c5d..510e7b0 100644
--- a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.h
+++ b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.h
@@ -72,7 +72,6 @@
       reading_list_model_scoped_observation_{this};
 
   views::View* side_panel_webview_ = nullptr;
-  std::unique_ptr<BubbleContentsWrapperT<ReadLaterUI>> contents_wrapper_;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_TOOLBAR_READ_LATER_TOOLBAR_BUTTON_H_
diff --git a/chrome/browser/ui/webui/chromeos/bluetooth_shared_load_time_data_provider.cc b/chrome/browser/ui/webui/chromeos/bluetooth_shared_load_time_data_provider.cc
index 9d77139c..fb49dac 100644
--- a/chrome/browser/ui/webui/chromeos/bluetooth_shared_load_time_data_provider.cc
+++ b/chrome/browser/ui/webui/chromeos/bluetooth_shared_load_time_data_provider.cc
@@ -31,6 +31,7 @@
       {"bluetoothPair", IDS_BLUETOOTH_PAIRING_PAIR},
       {"bluetoothReject", IDS_BLUETOOTH_PAIRING_REJECT_PASSKEY},
       {"bluetoothStartConnecting", IDS_BLUETOOTH_PAIRING_START_CONNECTING},
+      {"bluetoothEnterPin", IDS_BLUETOOTH_PAIRING_ENTER_PIN},
       // Device connecting and pairing.
       // These ids are generated in JS using 'bluetooth_' + a value from
       // bluetoothPrivate.PairingEventType (see bluetooth_private.idl).
diff --git a/chrome/browser/usb/web_usb_detector.cc b/chrome/browser/usb/web_usb_detector.cc
index dcdbe63..e8c10fe 100644
--- a/chrome/browser/usb/web_usb_detector.cc
+++ b/chrome/browser/usb/web_usb_detector.cc
@@ -13,6 +13,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
+#include "chrome/browser/browser_features.h"
 #include "chrome/browser/net/referrer.h"
 #include "chrome/browser/notifications/system_notification_helper.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -28,7 +29,6 @@
 #include "components/vector_icons/vector_icons.h"
 #include "content/public/browser/device_service.h"
 #include "content/public/browser/web_contents.h"
-#include "device/base/features.h"
 #include "services/device/public/mojom/usb_device.mojom.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -184,13 +184,10 @@
 WebUsbDetector::~WebUsbDetector() = default;
 
 void WebUsbDetector::Initialize() {
-#if defined(OS_WIN)
-  // The WebUSB device detector is disabled on Windows due to jank and hangs
-  // caused by enumerating devices. The new USB backend is designed to resolve
-  // these issues so enable it for testing. https://crbug.com/656702
-  if (!base::FeatureList::IsEnabled(device::kNewUsbBackend))
+  // The WebUSB device detector can be disabled if it causes trouble due to
+  // buggy devices and drivers.
+  if (!base::FeatureList::IsEnabled(features::kWebUsbDeviceDetection))
     return;
-#endif  // defined(OS_WIN)
 
   // Tests may set a fake manager.
   if (!device_manager_) {
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 2b59e649..2afac7e 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1632505958-ddbb37bcdfa7dbd7b10cf3a9b6a5bc45e7a958a6.profdata
+chrome-linux-main-1632548054-42d159d4e6ae5be86a2b7f9ab12a65b0c796632a.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 24b7016c..39184a0 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1632505958-ecc19202c484df17292092b0300480b0359444be.profdata
+chrome-mac-main-1632548054-2383c30487282da9f24ad124189b84c254f5c156.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index a5a174b..6608e09d 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1632505958-14b6d621069ddb732268efb1d0bc37f7b09da8dd.profdata
+chrome-win32-main-1632548054-6f16a736e66e0c44e71f7c21b592130c479acc9d.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 6d37d23..34f910a1 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1632505958-83c3e60c48b4982e54d0488757ed9325a0b41134.profdata
+chrome-win64-main-1632548054-de492a60f14cd25cedf09e8ac57ba676dd67f040.profdata
diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc
index 03a933e..302370d 100644
--- a/chrome/service/service_utility_process_host.cc
+++ b/chrome/service/service_utility_process_host.cc
@@ -339,8 +339,8 @@
         cmd_line, delegate.GetSandboxType());
 
     base::Process process;
-    sandbox::ResultCode result = content::StartSandboxedProcess(
-        &delegate, cmd_line, handles, &process);
+    sandbox::ResultCode result =
+        content::StartSandboxedProcess(&delegate, *cmd_line, handles, &process);
     if (result != sandbox::SBOX_ALL_OK)
       return false;
 
diff --git a/chrome/test/data/webui/cr_components/chromeos/bluetooth/BUILD.gn b/chrome/test/data/webui/cr_components/chromeos/bluetooth/BUILD.gn
index 9582fa32..79c92ba 100644
--- a/chrome/test/data/webui/cr_components/chromeos/bluetooth/BUILD.gn
+++ b/chrome/test/data/webui/cr_components/chromeos/bluetooth/BUILD.gn
@@ -17,6 +17,7 @@
     ":bluetooth_icon_test",
     ":bluetooth_pairing_device_item_test",
     ":bluetooth_pairing_device_selection_page_test",
+    ":bluetooth_pairing_request_code_page_test",
     ":bluetooth_pairing_ui_test",
     ":fake_bluetooth_config",
     ":fake_bluetooth_discovery_delegate",
@@ -67,6 +68,14 @@
   externs_list = [ "$externs_path/mocha-2.5.js" ]
 }
 
+js_library("bluetooth_pairing_request_code_page_test") {
+  deps = [
+    "../../..:chai_assert",
+    "//ui/webui/resources/cr_components/chromeos/bluetooth:bluetooth_pairing_request_code_page",
+  ]
+  externs_list = [ "$externs_path/mocha-2.5.js" ]
+}
+
 js_library("fake_bluetooth_config") {
   deps = [
     "../../..:chai_assert",
diff --git a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page_test.js b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page_test.js
new file mode 100644
index 0000000..e3ab491d
--- /dev/null
+++ b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page_test.js
@@ -0,0 +1,71 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// clang-format off
+import 'chrome://bluetooth-pairing/strings.m.js';
+
+import {SettingsBluetoothRequestCodePageElement} from 'chrome://resources/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page.js';
+import {ButtonState} from 'chrome://resources/cr_components/chromeos/bluetooth/bluetooth_types.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertEquals, assertTrue} from '../../../chai_assert.js';
+import {createDefaultBluetoothDevice} from './fake_bluetooth_config.js';
+// clang-format on
+
+const mojom = chromeos.bluetoothConfig.mojom;
+
+suite('CrComponentsBluetoothPairingRequestCodePageTest', function() {
+  /** @type {?SettingsBluetoothRequestCodePageElement} */
+  let bluetoothPairingRequestCodePage;
+
+  async function flushAsync() {
+    flush();
+    return new Promise(resolve => setTimeout(resolve));
+  }
+
+  setup(function() {
+    bluetoothPairingRequestCodePage =
+        /** @type {?SettingsBluetoothRequestCodePageElement} */ (
+            document.createElement('bluetooth-pairing-request-code-page'));
+    document.body.appendChild(bluetoothPairingRequestCodePage);
+    assertTrue(!!bluetoothPairingRequestCodePage);
+    flush();
+  });
+
+  test('Message and button states test', async function() {
+    const getInput = () =>
+        bluetoothPairingRequestCodePage.shadowRoot.querySelector('#pin');
+    const getPairButtonState = () => {
+      const basePage = bluetoothPairingRequestCodePage.shadowRoot.querySelector(
+          'bluetooth-base-page');
+      return basePage.buttonBarState.pair;
+    };
+    const deviceName = 'BeatsX';
+    const device = createDefaultBluetoothDevice(
+        /*id=*/ '123456789',
+        /*publicName=*/ deviceName,
+        /*connected=*/ true,
+        /*opt_nickname=*/ 'device1',
+        /*opt_audioCapability=*/
+        mojom.AudioOutputCapability.kCapableOfAudioOutput,
+        /*opt_deviceType=*/ mojom.DeviceType.kMouse);
+
+    bluetoothPairingRequestCodePage.device = device.deviceProperties;
+    await flushAsync();
+
+    const message =
+        bluetoothPairingRequestCodePage.shadowRoot.querySelector('#message');
+    assertTrue(!!message);
+    assertEquals(
+        bluetoothPairingRequestCodePage.i18n('bluetoothEnterPin', deviceName),
+        message.textContent.trim());
+
+    // Test button states.
+    assertEquals(ButtonState.DISABLED, getPairButtonState());
+    assertTrue(!!getInput());
+
+    getInput().value = '12345';
+    await flushAsync();
+    assertEquals(ButtonState.ENABLED, getPairButtonState());
+  });
+});
\ No newline at end of file
diff --git a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js
index a5ac4dc3..cebbf3b 100644
--- a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js
+++ b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js
@@ -59,7 +59,7 @@
     assertEquals(1, deviceSelectionPage.devices.length);
   });
 
-  test('finished event fired on succesful device pair', async function() {
+  test('finished event fired on successful device pair', async function() {
     const id = '12//345&6789';
     const deviceSelectionPage =
         bluetoothPairingUi.shadowRoot.querySelector('#deviceSelectionPage');
@@ -78,7 +78,8 @@
     bluetoothConfig.appendToDiscoveredDeviceList([device.deviceProperties]);
 
     await flushAsync();
-    const event = new CustomEvent('pair-device', {detail: {deviceId: id}});
+    const event = new CustomEvent(
+        'pair-device', {detail: {device: device.deviceProperties}});
     deviceSelectionPage.dispatchEvent(event);
     await flushAsync();
 
@@ -116,7 +117,7 @@
     assertEquals(deviceHandler.getPairDeviceCalledCount(), 0);
 
     let event = new CustomEvent(
-        'pair-device', {detail: {deviceId: device.deviceProperties.id}});
+        'pair-device', {detail: {device: device.deviceProperties}});
     deviceSelectionPage.dispatchEvent(event);
     await flushAsync();
 
@@ -126,7 +127,7 @@
 
     await flushAsync();
     event = new CustomEvent(
-        'pair-device', {detail: {deviceId: device.deviceProperties.id}});
+        'pair-device', {detail: {device: device.deviceProperties}});
     deviceSelectionPage.dispatchEvent(event);
     await flushAsync();
 
diff --git a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js
index 2838cce..81f6ed0 100644
--- a/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js
+++ b/chrome/test/data/webui/cr_components/chromeos/cr_components_chromeos_v3_browsertest.js
@@ -17,6 +17,10 @@
     'DeviceSelectionPage',
     'bluetooth/bluetooth_pairing_device_selection_page_test.js'
   ],
+  [
+    'PairingRequestCodePage',
+    'bluetooth/bluetooth_pairing_request_code_page_test.js'
+  ],
   ['BluetoothIcon', 'bluetooth/bluetooth_icon_test.js'],
   ['PairingUi', 'bluetooth/bluetooth_pairing_ui_test.js'],
   ['PairingDeviceItem', 'bluetooth/bluetooth_pairing_device_item_test.js'],
diff --git a/chrome/test/data/webui/print_preview/select_behavior_test.js b/chrome/test/data/webui/print_preview/select_behavior_test.js
index ea8c301..6c21b585 100644
--- a/chrome/test/data/webui/print_preview/select_behavior_test.js
+++ b/chrome/test/data/webui/print_preview/select_behavior_test.js
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {SelectBehavior} from 'chrome://print/print_preview.js';
+import {SelectMixin} from 'chrome://print/print_preview.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
-import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {eventToPromise} from 'chrome://test/test_util.js';
 
 window.select_behavior_test = {};
-select_behavior_test.suiteName = 'SelectBehaviorTest';
+select_behavior_test.suiteName = 'SelectMixinTest';
 /** @enum {string} */
 select_behavior_test.TestNames = {
   CallProcessSelectChange: 'call process select change',
@@ -21,28 +21,38 @@
   /** @type {string} */
   let settingValue = '0';
 
+  suiteSetup(function() {
+    const TestSelectElementBase = SelectMixin(PolymerElement);
+
+    class TestSelectElement extends TestSelectElementBase {
+      static get is() {
+        return 'test-select';
+      }
+
+      static get template() {
+        return html`
+          <select value="{{selectedValue::change}}">
+            <option value="0" selected>0</option>
+            <option value="1">1</option>
+            <option value="2">2</option>
+          </select>
+        `;
+      }
+
+      onProcessSelectChange(value) {
+        settingValue = value;
+        this.dispatchEvent(new CustomEvent(
+            'process-select-change-called',
+            {bubbles: true, composed: true, detail: value}));
+      }
+    }
+
+    customElements.define(TestSelectElement.is, TestSelectElement);
+  });
+
   /** @override */
   setup(function() {
-    Polymer({
-      is: 'test-select',
-
-      _template: html`
-        <select value="{{selectedValue::change}}">
-          <option value="0" selected>0</option>
-          <option value="1">1</option>
-          <option value="2">2</option>
-        </select>
-      `,
-
-      behaviors: [SelectBehavior],
-
-      onProcessSelectChange: function(value) {
-        settingValue = value;
-        this.fire('process-select-change-called', value);
-      },
-    });
-
-    PolymerTest.clearBody();
+    document.body.innerHTML = '';
     testSelect = document.createElement('test-select');
     document.body.appendChild(testSelect);
     testSelect.selectedValue = '0';
diff --git a/chrome/test/enterprise/e2e/.vpython b/chrome/test/enterprise/e2e/.vpython
index 3ad7696..d53e2d9f 100644
--- a/chrome/test/enterprise/e2e/.vpython
+++ b/chrome/test/enterprise/e2e/.vpython
@@ -11,8 +11,8 @@
 
 wheel: <
   name: "infra/celab/celab/windows-amd64"
-  # Source: https://ci.chromium.org/p/celab/builders/ci/Windows/b8863242163218578192
-  version: "IQHknf30R2DyRmnCQ9PWQToO1x-rS7ecoTeaDqncGmoC"
+  # Source: https://ci.chromium.org/p/celab/builders/ci/Windows/b8839159667690916800
+  version: "ESovjdrWROIDnSgn5pI9YH26d43O2_iYLvqCFSAZ7u0C"
 >
 
 # googleapiclient
diff --git a/chromeos/components/phonehub/cros_state_sender.cc b/chromeos/components/phonehub/cros_state_sender.cc
index 361a070..01786746 100644
--- a/chromeos/components/phonehub/cros_state_sender.cc
+++ b/chromeos/components/phonehub/cros_state_sender.cc
@@ -89,10 +89,16 @@
   bool are_notifications_enabled =
       multidevice_setup_client_->GetFeatureState(
           Feature::kPhoneHubNotifications) == FeatureState::kEnabledByUser;
+  bool is_camera_roll_enabled =
+      multidevice_setup_client_->GetFeatureState(
+          Feature::kPhoneHubCameraRoll) == FeatureState::kEnabledByUser;
 
   PA_LOG(INFO) << "Attempting to send cros state with notifications enabled "
-               << "state as: " << are_notifications_enabled;
-  message_sender_->SendCrosState(are_notifications_enabled);
+               << "state as: " << are_notifications_enabled
+               << " and camera roll enabled state as: "
+               << is_camera_roll_enabled;
+  message_sender_->SendCrosState(are_notifications_enabled,
+                                 is_camera_roll_enabled);
 
   retry_timer_->Start(FROM_HERE, retry_delay_,
                       base::BindOnce(&CrosStateSender::OnRetryTimerFired,
diff --git a/chromeos/components/phonehub/cros_state_sender_unittest.cc b/chromeos/components/phonehub/cros_state_sender_unittest.cc
index 58a32f5..60dbdd7 100644
--- a/chromeos/components/phonehub/cros_state_sender_unittest.cc
+++ b/chromeos/components/phonehub/cros_state_sender_unittest.cc
@@ -106,6 +106,9 @@
   // Set notification feature to be enabled.
   fake_multidevice_setup_client_->SetFeatureState(
       Feature::kPhoneHubNotifications, FeatureState::kEnabledByUser);
+  // Set camera roll feature to be enabled.
+  fake_multidevice_setup_client_->SetFeatureState(Feature::kPhoneHubCameraRoll,
+                                                  FeatureState::kEnabledByUser);
   // Expect no new messages since connection has not been established.
   EXPECT_EQ(0u, fake_message_sender_->GetCrosStateCallCount());
   EXPECT_FALSE(mock_timer_->IsRunning());
@@ -120,7 +123,8 @@
   // Simulate connected state. Expect a new message to be sent.
   fake_connection_manager_->SetStatus(
       secure_channel::ConnectionManager::Status::kConnected);
-  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState());
+  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState().first);
+  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState().second);
   EXPECT_EQ(1u, fake_message_sender_->GetCrosStateCallCount());
 
   // Phone model is populated.
@@ -131,7 +135,8 @@
   // Simulate disconnected state, this should not trigger a new request.
   fake_connection_manager_->SetStatus(
       secure_channel::ConnectionManager::Status::kDisconnected);
-  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState());
+  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState().first);
+  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState().second);
   EXPECT_EQ(1u, fake_message_sender_->GetCrosStateCallCount());
   EXPECT_FALSE(mock_timer_->IsRunning());
 }
@@ -146,7 +151,8 @@
   EXPECT_TRUE(mock_timer_->IsRunning());
 
   // Expect new messages to be sent when connection state is connected.
-  EXPECT_FALSE(fake_message_sender_->GetRecentCrosState());
+  EXPECT_FALSE(fake_message_sender_->GetRecentCrosState().first);
+  EXPECT_FALSE(fake_message_sender_->GetRecentCrosState().second);
   EXPECT_EQ(1u, fake_message_sender_->GetCrosStateCallCount());
   mock_timer_->Fire();
 
@@ -154,7 +160,7 @@
   // enabled.
   fake_multidevice_setup_client_->SetFeatureState(
       Feature::kPhoneHubNotifications, FeatureState::kEnabledByUser);
-  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState());
+  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState().first);
   EXPECT_EQ(2u, fake_message_sender_->GetCrosStateCallCount());
   mock_timer_->Fire();
 
@@ -162,7 +168,7 @@
   // cros state.
   fake_multidevice_setup_client_->SetFeatureState(
       Feature::kSmartLock, FeatureState::kDisabledByUser);
-  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState());
+  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState().first);
   EXPECT_EQ(3u, fake_message_sender_->GetCrosStateCallCount());
   mock_timer_->Fire();
 
@@ -170,12 +176,19 @@
   // disabled.
   fake_multidevice_setup_client_->SetFeatureState(
       Feature::kPhoneHubNotifications, FeatureState::kDisabledByUser);
-  EXPECT_FALSE(fake_message_sender_->GetRecentCrosState());
+  EXPECT_FALSE(fake_message_sender_->GetRecentCrosState().first);
   EXPECT_EQ(4u, fake_message_sender_->GetCrosStateCallCount());
 
+  // Simulate enabling camera roll feature state and expect cros state to be
+  // updated.
+  fake_multidevice_setup_client_->SetFeatureState(Feature::kPhoneHubCameraRoll,
+                                                  FeatureState::kEnabledByUser);
+  EXPECT_TRUE(fake_message_sender_->GetRecentCrosState().second);
+  EXPECT_EQ(5u, fake_message_sender_->GetCrosStateCallCount());
+
   // Firing the timer does not cause the cros state to be sent again.
   mock_timer_->Fire();
-  EXPECT_EQ(4u, fake_message_sender_->GetCrosStateCallCount());
+  EXPECT_EQ(5u, fake_message_sender_->GetCrosStateCallCount());
 }
 
 }  // namespace phonehub
diff --git a/chromeos/components/phonehub/fake_message_sender.cc b/chromeos/components/phonehub/fake_message_sender.cc
index 180d57a8..506fcdd 100644
--- a/chromeos/components/phonehub/fake_message_sender.cc
+++ b/chromeos/components/phonehub/fake_message_sender.cc
@@ -10,8 +10,10 @@
 FakeMessageSender::FakeMessageSender() = default;
 FakeMessageSender::~FakeMessageSender() = default;
 
-void FakeMessageSender::SendCrosState(bool notification_enabled) {
-  cros_states_.push_back(notification_enabled);
+void FakeMessageSender::SendCrosState(bool notification_enabled,
+                                      bool camera_roll_enabled) {
+  cros_states_.push_back(
+      std::make_pair(notification_enabled, camera_roll_enabled));
 }
 
 void FakeMessageSender::SendUpdateNotificationModeRequest(
@@ -77,7 +79,7 @@
   return fetch_camera_roll_items_requests_.size();
 }
 
-bool FakeMessageSender::GetRecentCrosState() const {
+std::pair<bool, bool> FakeMessageSender::GetRecentCrosState() const {
   return cros_states_.back();
 }
 
diff --git a/chromeos/components/phonehub/fake_message_sender.h b/chromeos/components/phonehub/fake_message_sender.h
index 8ac1cfaf..aeb2b82d 100644
--- a/chromeos/components/phonehub/fake_message_sender.h
+++ b/chromeos/components/phonehub/fake_message_sender.h
@@ -22,7 +22,8 @@
   ~FakeMessageSender() override;
 
   // MessageSender:
-  void SendCrosState(bool notification_enabled) override;
+  void SendCrosState(bool notification_enabled,
+                     bool camera_roll_enabled) override;
   void SendUpdateNotificationModeRequest(bool do_not_disturb_enabled) override;
   void SendUpdateBatteryModeRequest(bool battery_saver_mode_enabled) override;
   void SendDismissNotificationRequest(int64_t notification_id) override;
@@ -34,7 +35,7 @@
   void SendFetchCameraRollItemsRequest(
       const proto::FetchCameraRollItemsRequest& request) override;
 
-  bool GetRecentCrosState() const;
+  std::pair<bool, bool> GetRecentCrosState() const;
   bool GetRecentUpdateNotificationModeRequest() const;
   bool GetRecentUpdateBatteryModeRequest() const;
   int64_t GetRecentDismissNotificationRequest() const;
@@ -63,7 +64,9 @@
   size_t GetFetchCameraRollItemsRequestCallCount() const;
 
  private:
-  std::vector<bool> cros_states_;
+  std::vector<std::pair</*is_notifications_setting_enabled*/ bool,
+                        /*is_camera_roll_setting_enabled*/ bool>>
+      cros_states_;
   std::vector<bool> update_notification_mode_requests_;
   std::vector<bool> update_battery_mode_requests_;
   std::vector<int64_t> dismiss_notification_requests_;
diff --git a/chromeos/components/phonehub/message_sender.h b/chromeos/components/phonehub/message_sender.h
index 4cd09b9..a9c52999 100644
--- a/chromeos/components/phonehub/message_sender.h
+++ b/chromeos/components/phonehub/message_sender.h
@@ -22,7 +22,8 @@
   virtual ~MessageSender() = default;
 
   // Sends whether the notification setting is enabled in the Chrome OS device.
-  virtual void SendCrosState(bool notification_setting_enabled) = 0;
+  virtual void SendCrosState(bool notification_setting_enabled,
+                             bool camera_roll_setting_enabled) = 0;
 
   // Requests that the phone enables or disables Do Not Disturb mode.
   virtual void SendUpdateNotificationModeRequest(
diff --git a/chromeos/components/phonehub/message_sender_impl.cc b/chromeos/components/phonehub/message_sender_impl.cc
index d3d2cd312..d16e36d 100644
--- a/chromeos/components/phonehub/message_sender_impl.cc
+++ b/chromeos/components/phonehub/message_sender_impl.cc
@@ -38,13 +38,18 @@
 
 MessageSenderImpl::~MessageSenderImpl() = default;
 
-void MessageSenderImpl::SendCrosState(bool notification_setting_enabled) {
+void MessageSenderImpl::SendCrosState(bool notification_setting_enabled,
+                                      bool camera_roll_setting_enabled) {
   proto::NotificationSetting is_notification_enabled =
       notification_setting_enabled
           ? proto::NotificationSetting::NOTIFICATIONS_ON
           : proto::NotificationSetting::NOTIFICATIONS_OFF;
+  proto::CameraRollSetting is_camera_roll_enabled =
+      camera_roll_setting_enabled ? proto::CameraRollSetting::CAMERA_ROLL_ON
+                                  : proto::CameraRollSetting::CAMERA_ROLL_OFF;
   proto::CrosState request;
   request.set_notification_setting(is_notification_enabled);
+  request.set_camera_roll_setting(is_camera_roll_enabled);
 
   SendMessage(proto::MessageType::PROVIDE_CROS_STATE, &request);
 }
diff --git a/chromeos/components/phonehub/message_sender_impl.h b/chromeos/components/phonehub/message_sender_impl.h
index 0f19ec2..cd689b70 100644
--- a/chromeos/components/phonehub/message_sender_impl.h
+++ b/chromeos/components/phonehub/message_sender_impl.h
@@ -27,7 +27,8 @@
   ~MessageSenderImpl() override;
 
   // MessageSender:
-  void SendCrosState(bool notification_setting_enabled) override;
+  void SendCrosState(bool notification_setting_enabled,
+                     bool camera_roll_setting_enabled) override;
   void SendUpdateNotificationModeRequest(bool do_not_disturb_enabled) override;
   void SendUpdateBatteryModeRequest(bool battery_saver_mode_enabled) override;
   void SendDismissNotificationRequest(int64_t notification_id) override;
diff --git a/chromeos/components/phonehub/message_sender_unittest.cc b/chromeos/components/phonehub/message_sender_unittest.cc
index 5df0ddd..9d1d053 100644
--- a/chromeos/components/phonehub/message_sender_unittest.cc
+++ b/chromeos/components/phonehub/message_sender_unittest.cc
@@ -64,8 +64,10 @@
   proto::CrosState request;
   request.set_notification_setting(
       proto::NotificationSetting::NOTIFICATIONS_ON);
+  request.set_camera_roll_setting(proto::CameraRollSetting::CAMERA_ROLL_OFF);
 
-  message_sender_->SendCrosState(/*notification_enabled=*/true);
+  message_sender_->SendCrosState(/*notification_enabled=*/true,
+                                 /*camera_roll_enabled=*/false);
   VerifyMessage(proto::MessageType::PROVIDE_CROS_STATE, &request,
                 fake_connection_manager_->sent_messages().back());
 }
diff --git a/chromeos/components/phonehub/proto/phonehub_api.proto b/chromeos/components/phonehub/proto/phonehub_api.proto
index 527dee8b..6ff53376 100644
--- a/chromeos/components/phonehub/proto/phonehub_api.proto
+++ b/chromeos/components/phonehub/proto/phonehub_api.proto
@@ -40,6 +40,11 @@
   NOTIFICATIONS_ON = 1;
 }
 
+enum CameraRollSetting {
+  CAMERA_ROLL_OFF = 0;
+  CAMERA_ROLL_ON = 1;
+}
+
 enum ChargingState {
   NOT_CHARGING = 0;
   CHARGING_AC = 1;
@@ -162,6 +167,7 @@
 
 message CrosState {
   NotificationSetting notification_setting = 1;
+  CameraRollSetting camera_roll_setting = 2;
 }
 
 message Action {
diff --git a/chromeos/components/projector_app/annotator_tool.cc b/chromeos/components/projector_app/annotator_tool.cc
index 6d4a0a6..2796c54 100644
--- a/chromeos/components/projector_app/annotator_tool.cc
+++ b/chromeos/components/projector_app/annotator_tool.cc
@@ -6,6 +6,7 @@
 
 #include <string>
 
+#include "base/notreached.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/values.h"
 
@@ -36,6 +37,32 @@
   return success ? color : SK_ColorRED;
 }
 
+std::string ConvertToolTypeToString(AnnotatorToolType type) {
+  switch (type) {
+    case AnnotatorToolType::kMarker:
+      return "marker";
+    case AnnotatorToolType::kPen:
+      return "pen";
+    case AnnotatorToolType::kHighlighter:
+      return "highlighter";
+    case AnnotatorToolType::kEraser:
+      return "eraser";
+  }
+}
+
+AnnotatorToolType ConvertStringToToolType(const std::string& type) {
+  if (type == "marker")
+    return AnnotatorToolType::kMarker;
+  if (type == "pen")
+    return AnnotatorToolType::kPen;
+  if (type == "highlighter")
+    return AnnotatorToolType::kHighlighter;
+  if (type == "eraser")
+    return AnnotatorToolType::kEraser;
+  NOTREACHED();
+  return AnnotatorToolType::kMarker;
+}
+
 }  // namespace
 
 // static
@@ -46,11 +73,11 @@
   DCHECK(value.FindKey(kToolSize));
   DCHECK(value.FindKey(kToolSize)->is_int());
   DCHECK(value.FindKey(kToolType));
-  DCHECK(value.FindKey(kToolType)->is_int());
+  DCHECK(value.FindKey(kToolType)->is_string());
   AnnotatorTool t;
   t.color = ConvertHexStringToColor(*(value.FindStringPath(kToolColor)));
   t.size = *(value.FindIntPath(kToolSize));
-  t.type = static_cast<AnnotatorToolType>(*(value.FindIntPath(kToolType)));
+  t.type = ConvertStringToToolType(*(value.FindStringPath(kToolType)));
   return t;
 }
 
@@ -58,7 +85,7 @@
   base::Value val(base::Value::Type::DICTIONARY);
   val.SetKey(kToolColor, base::Value(ConvertColorToHexString(color)));
   val.SetKey(kToolSize, base::Value(size));
-  val.SetKey(kToolType, base::Value(static_cast<int>(type)));
+  val.SetKey(kToolType, base::Value(ConvertToolTypeToString(type)));
   return val;
 }
 
diff --git a/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkId.java b/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkId.java
index 36b53209..7782661 100644
--- a/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkId.java
+++ b/components/bookmarks/common/android/java/src/org/chromium/components/bookmarks/BookmarkId.java
@@ -86,7 +86,7 @@
      * Returns the bookmark type: {@link BookmarkType#NORMAL} or {@link BookmarkType#PARTNER}.
      */
     @CalledByNative
-    public int getType() {
+    public @BookmarkType int getType() {
         return mType;
     }
 
diff --git a/components/exo/client_controlled_shell_surface.cc b/components/exo/client_controlled_shell_surface.cc
index 8d7e852..3aa694f 100644
--- a/components/exo/client_controlled_shell_surface.cc
+++ b/components/exo/client_controlled_shell_surface.cc
@@ -432,7 +432,12 @@
   if (!widget_)
     CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL);
 
-  widget_->GetNativeWindow()->SetProperty(chromeos::kWindowPinTypeKey, type);
+  if (type == chromeos::WindowPinType::kNone) {
+    ash::WindowState::Get(widget_->GetNativeWindow())->Restore();
+  } else {
+    bool trusted = type == chromeos::WindowPinType::kTrustedPinned;
+    ash::window_util::PinWindow(widget_->GetNativeWindow(), trusted);
+  }
 }
 
 void ClientControlledShellSurface::SetSystemUiVisibility(bool autohide) {
diff --git a/components/exo/client_controlled_shell_surface_unittest.cc b/components/exo/client_controlled_shell_surface_unittest.cc
index caf1ace..d228768 100644
--- a/components/exo/client_controlled_shell_surface_unittest.cc
+++ b/components/exo/client_controlled_shell_surface_unittest.cc
@@ -87,10 +87,7 @@
 }
 
 bool IsWidgetPinned(views::Widget* widget) {
-  chromeos::WindowPinType type =
-      widget->GetNativeWindow()->GetProperty(chromeos::kWindowPinTypeKey);
-  return type == chromeos::WindowPinType::kPinned ||
-         type == chromeos::WindowPinType::kTrustedPinned;
+  return ash::WindowState::Get(widget->GetNativeWindow())->IsPinned();
 }
 
 int GetShadowElevation(aura::Window* window) {
diff --git a/components/feed/core/v2/api_test/feed_api_subscriptions_unittest.cc b/components/feed/core/v2/api_test/feed_api_subscriptions_unittest.cc
index 10c298d..3a3ef6e2 100644
--- a/components/feed/core/v2/api_test/feed_api_subscriptions_unittest.cc
+++ b/components/feed/core/v2/api_test/feed_api_subscriptions_unittest.cc
@@ -153,6 +153,8 @@
       WebFeedSubscriptionRequestStatus::kSuccess, 1);
   histograms.ExpectUniqueSample(
       "ContentSuggestions.Feed.WebFeed.FollowCount.AfterFollow", 1, 1);
+  histograms.ExpectUniqueSample(
+      "ContentSuggestions.Feed.WebFeed.NewFollow.IsRecommended", 0, 1);
 }
 
 TEST_F(FeedApiSubscriptionsTest, FollowRecommendedWebFeedById) {
@@ -172,6 +174,8 @@
       WebFeedSubscriptionRequestStatus::kSuccess, 1);
   histograms.ExpectUniqueSample(
       "ContentSuggestions.Feed.WebFeed.FollowCount.AfterFollow", 1, 1);
+  histograms.ExpectUniqueSample(
+      "ContentSuggestions.Feed.WebFeed.NewFollow.IsRecommended", 1, 1);
 }
 
 // Make two Follow attempts for the same page. Both appear successful, but only
@@ -263,7 +267,29 @@
   EXPECT_EQ("{}", PrintToString(CheckAllSubscriptions()));
 }
 
+TEST_F(FeedApiSubscriptionsTest, CantFollowWebFeedByIdWhileOffline) {
+  base::HistogramTester histograms;
+  is_offline_ = true;
+  network_.InjectResponse(SuccessfulFollowResponse("cats"));
+  CallbackReceiver<WebFeedSubscriptions::FollowWebFeedResult> callback;
+
+  subscriptions().FollowWebFeed("feed_id", callback.Bind());
+
+  EXPECT_EQ(0, network_.GetFollowRequestCount());
+  EXPECT_EQ(WebFeedSubscriptionRequestStatus::kFailedOffline,
+            callback.RunAndGetResult().request_status);
+  EXPECT_EQ("{}", PrintToString(CheckAllSubscriptions()));
+  histograms.ExpectUniqueSample(
+      "ContentSuggestions.Feed.WebFeed.FollowByIdResult",
+      WebFeedSubscriptionRequestStatus::kFailedOffline, 1);
+  histograms.ExpectTotalCount(
+      "ContentSuggestions.Feed.WebFeed.FollowCount.AfterFollow", 0);
+  histograms.ExpectTotalCount(
+      "ContentSuggestions.Feed.WebFeed.NewFollow.IsRecommended", 0);
+}
+
 TEST_F(FeedApiSubscriptionsTest, FollowWebFeedNetworkError) {
+  base::HistogramTester histograms;
   network_.InjectFollowResponse(MakeFailedResponse());
   CallbackReceiver<WebFeedSubscriptions::FollowWebFeedResult> callback;
   EXPECT_FALSE(feedstore::IsKnownStale(stream_->GetMetadata(), kWebFeedStream));
@@ -275,6 +301,9 @@
             callback.RunAndGetResult().request_status);
   EXPECT_EQ("{}", PrintToString(CheckAllSubscriptions()));
   EXPECT_FALSE(feedstore::IsKnownStale(stream_->GetMetadata(), kWebFeedStream));
+  histograms.ExpectUniqueSample(
+      "ContentSuggestions.Feed.WebFeed.FollowUriResult",
+      WebFeedSubscriptionRequestStatus::kFailedUnknownError, 1);
 }
 
 // Follow and then unfollow a web feed successfully.
diff --git a/components/feed/core/v2/metrics_reporter.cc b/components/feed/core/v2/metrics_reporter.cc
index af0c231c..136f613 100644
--- a/components/feed/core/v2/metrics_reporter.cc
+++ b/components/feed/core/v2/metrics_reporter.cc
@@ -799,6 +799,9 @@
     base::UmaHistogramSparse(
         "ContentSuggestions.Feed.WebFeed.FollowCount.AfterFollow",
         result.subscription_count);
+    base::UmaHistogramBoolean(
+        "ContentSuggestions.Feed.WebFeed.NewFollow.IsRecommended",
+        result.web_feed_metadata.is_recommended);
   }
 }
 
diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc
index 6bb01f6a..8b74110 100644
--- a/components/metrics/metrics_state_manager.cc
+++ b/components/metrics/metrics_state_manager.cc
@@ -407,16 +407,16 @@
     std::string client_id_from_prefs = ReadClientId(local_state_);
     // If client id in prefs matches the cached copy, return early.
     if (!client_id_from_prefs.empty() && client_id_from_prefs == client_id_) {
-      UMA_HISTOGRAM_ENUMERATION("UMA.ClientIdSource",
-                                ClientIdSource::kClientIdMatches);
+      base::UmaHistogramEnumeration("UMA.ClientIdSource",
+                                    ClientIdSource::kClientIdMatches);
       return;
     }
     client_id_.swap(client_id_from_prefs);
   }
 
   if (!client_id_.empty()) {
-    UMA_HISTOGRAM_ENUMERATION("UMA.ClientIdSource",
-                              ClientIdSource::kClientIdFromLocalState);
+    base::UmaHistogramEnumeration("UMA.ClientIdSource",
+                                  ClientIdSource::kClientIdFromLocalState);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     LogClientIdChanged(
         metrics::structured::NeutrinoDevicesLocation::kClientIdFromLocalState,
@@ -450,8 +450,8 @@
       recovered_installation_age =
           now - base::Time::FromTimeT(client_info_backup->installation_date);
     }
-    UMA_HISTOGRAM_ENUMERATION("UMA.ClientIdSource",
-                              ClientIdSource::kClientIdBackupRecovered);
+    base::UmaHistogramEnumeration("UMA.ClientIdSource",
+                                  ClientIdSource::kClientIdBackupRecovered);
     UMA_HISTOGRAM_COUNTS_10000("UMA.ClientIdBackupRecoveredWithAge",
                                recovered_installation_age.InHours());
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -472,8 +472,8 @@
   // otherwise (e.g. UMA enabled in a future session), generate a new one.
   if (provisional_client_id_.empty()) {
     client_id_ = base::GenerateGUID();
-    UMA_HISTOGRAM_ENUMERATION("UMA.ClientIdSource",
-                              ClientIdSource::kClientIdNew);
+    base::UmaHistogramEnumeration("UMA.ClientIdSource",
+                                  ClientIdSource::kClientIdNew);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     LogClientIdChanged(
         metrics::structured::NeutrinoDevicesLocation::kClientIdNew,
@@ -482,8 +482,8 @@
   } else {
     client_id_ = provisional_client_id_;
     provisional_client_id_.clear();
-    UMA_HISTOGRAM_ENUMERATION("UMA.ClientIdSource",
-                              ClientIdSource::kClientIdFromProvisionalId);
+    base::UmaHistogramEnumeration("UMA.ClientIdSource",
+                                  ClientIdSource::kClientIdFromProvisionalId);
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     LogClientIdChanged(metrics::structured::NeutrinoDevicesLocation::
                            kClientIdFromProvisionalId,
diff --git a/components/nacl/broker/nacl_broker_listener.cc b/components/nacl/broker/nacl_broker_listener.cc
index 9c4e7c6a..57b2420 100644
--- a/components/nacl/broker/nacl_broker_listener.cc
+++ b/components/nacl/broker/nacl_broker_listener.cc
@@ -109,7 +109,7 @@
 
     base::Process loader_process;
     sandbox::ResultCode result = content::StartSandboxedProcess(
-        this, cmd_line, handles, &loader_process);
+        this, *cmd_line, handles, &loader_process);
 
     if (result == sandbox::SBOX_ALL_OK) {
       mojo::OutgoingInvitation::Send(std::move(invitation),
diff --git a/components/no_state_prefetch/renderer/DEPS b/components/no_state_prefetch/renderer/DEPS
index f94db2aa..49fd61f 100644
--- a/components/no_state_prefetch/renderer/DEPS
+++ b/components/no_state_prefetch/renderer/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
   "+content/public/common",
   "+content/public/renderer",
+  "+media/mojo/mojom/media_player.mojom.h",
   "+mojo/public/cpp/bindings",
   "+third_party/blink/public",
 ]
diff --git a/components/no_state_prefetch/renderer/no_state_prefetch_utils.cc b/components/no_state_prefetch/renderer/no_state_prefetch_utils.cc
index c2e231d..0ed22ab 100644
--- a/components/no_state_prefetch/renderer/no_state_prefetch_utils.cc
+++ b/components/no_state_prefetch/renderer/no_state_prefetch_utils.cc
@@ -4,9 +4,13 @@
 
 #include "components/no_state_prefetch/renderer/no_state_prefetch_utils.h"
 
+#include "base/memory/weak_ptr.h"
 #include "components/no_state_prefetch/renderer/no_state_prefetch_helper.h"
 #include "content/public/common/page_visibility_state.h"
 #include "content/public/renderer/render_frame.h"
+#include "media/mojo/mojom/media_player.mojom.h"
+#include "mojo/public/cpp/bindings/generic_pending_receiver.h"
+#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/public/web/web_view.h"
 #include "third_party/blink/public/web/web_view_observer.h"
@@ -15,13 +19,24 @@
 
 namespace {
 
-// Defers media player loading in background pages until they're visible.
+// Defers media player loading in background pages until they're visible unless
+// the tab has previously played content before.
 class MediaLoadDeferrer : public blink::WebViewObserver {
  public:
-  MediaLoadDeferrer(blink::WebView* web_view,
+  MediaLoadDeferrer(content::RenderFrame* render_frame,
+                    blink::WebView* web_view,
                     base::OnceClosure continue_loading_cb)
       : blink::WebViewObserver(web_view),
-        continue_loading_cb_(std::move(continue_loading_cb)) {}
+        continue_loading_cb_(std::move(continue_loading_cb)) {
+    mojo::PendingReceiver<media::mojom::MediaPlayerObserverClient>
+        media_player_observer_client_receiver =
+            media_player_observer_client_.BindNewPipeAndPassReceiver();
+    render_frame->GetBrowserInterfaceBroker()->GetInterface(
+        std::move(media_player_observer_client_receiver));
+    media_player_observer_client_->GetHasPlayedBefore(
+        base::BindOnce(&MediaLoadDeferrer::OnGetHasPlayedBeforeCallback,
+                       weak_factory_.GetWeakPtr()));
+  }
 
   MediaLoadDeferrer(const MediaLoadDeferrer&) = delete;
   MediaLoadDeferrer& operator=(const MediaLoadDeferrer&) = delete;
@@ -38,8 +53,19 @@
     delete this;
   }
 
+  void OnGetHasPlayedBeforeCallback(bool has_played_before) {
+    if (has_played_before) {
+      std::move(continue_loading_cb_).Run();
+      delete this;
+    }
+  }
+
  private:
+  mojo::Remote<media::mojom::MediaPlayerObserverClient>
+      media_player_observer_client_;
   base::OnceClosure continue_loading_cb_;
+
+  base::WeakPtrFactory<MediaLoadDeferrer> weak_factory_{this};
 };
 
 }  // namespace
@@ -56,7 +82,7 @@
            content::PageVisibilityState::kVisible &&
        !has_played_media_before) ||
       NoStatePrefetchHelper::IsPrefetching(render_frame)) {
-    new MediaLoadDeferrer(render_frame->GetWebFrame()->View(),
+    new MediaLoadDeferrer(render_frame, render_frame->GetWebFrame()->View(),
                           std::move(closure));
     return true;
   }
diff --git a/components/omnibox/browser/omnibox_controller.cc b/components/omnibox/browser/omnibox_controller.cc
index b1d116c..c0e8879e 100644
--- a/components/omnibox/browser/omnibox_controller.cc
+++ b/components/omnibox/browser/omnibox_controller.cc
@@ -46,8 +46,7 @@
                                         bool default_match_changed) {
   DCHECK(controller == autocomplete_controller_.get());
 
-  OmniboxPopupModel* popup = omnibox_edit_model_->popup_model();
-  const bool was_open = popup && popup->IsOpen();
+  const bool was_open = omnibox_edit_model_->PopupIsOpen();
   if (default_match_changed) {
     // The default match has changed, we need to let the OmniboxEditModel know
     // about new inline autocomplete text (blue highlight).
@@ -56,18 +55,17 @@
       omnibox_edit_model_->OnCurrentMatchChanged();
     } else {
       InvalidateCurrentMatch();
-      if (popup)
-        popup->OnResultChanged();
+      omnibox_edit_model_->OnPopupResultChanged();
       omnibox_edit_model_->OnPopupDataChanged(
           std::u16string(),
           /*is_temporary_text=*/false, std::u16string(), std::u16string(), {},
           std::u16string(), false, std::u16string());
     }
-  } else if (popup) {
-    popup->OnResultChanged();
+  } else {
+    omnibox_edit_model_->OnPopupResultChanged();
   }
 
-  if (was_open && !popup->IsOpen()) {
+  if (was_open && !omnibox_edit_model_->PopupIsOpen()) {
     // Accept the temporary text as the user text, because it makes little sense
     // to have temporary text when the popup is closed.
     omnibox_edit_model_->AcceptTemporaryTextAsUserText();
@@ -93,17 +91,16 @@
 }
 
 void OmniboxController::ClearPopupKeywordMode() const {
-  OmniboxPopupModel* popup = omnibox_edit_model_->popup_model();
-  // |popup| can be nullptr in tests.
-  if (popup && popup->IsOpen() &&
-      popup->selected_line_state() == OmniboxPopupSelection::KEYWORD_MODE) {
-    popup->SetSelectedLineState(OmniboxPopupSelection::NORMAL);
+  if (omnibox_edit_model_->PopupIsOpen()) {
+    OmniboxPopupSelection selection = omnibox_edit_model_->GetPopupSelection();
+    if (selection.state == OmniboxPopupSelection::KEYWORD_MODE) {
+      selection.state = OmniboxPopupSelection::NORMAL;
+      omnibox_edit_model_->SetPopupSelection(selection);
+    }
   }
 }
 
 void OmniboxController::SetRichSuggestionBitmap(int result_index,
                                                 const SkBitmap& bitmap) {
-  DCHECK(omnibox_edit_model_->popup_model());
-  omnibox_edit_model_->popup_model()->SetRichSuggestionBitmap(result_index,
-                                                              bitmap);
+  omnibox_edit_model_->SetPopupRichSuggestionBitmap(result_index, bitmap);
 }
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index 95fdf473..9d14d9a 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -169,6 +169,10 @@
   }
 }
 
+OmniboxPopupView* OmniboxEditModel::get_popup_view() {
+  return popup_model_->view();
+}
+
 metrics::OmniboxEventProto::PageClassification
 OmniboxEditModel::GetPageClassification() const {
   return controller()->GetLocationBarModel()->GetPageClassification(
@@ -1770,6 +1774,12 @@
   return popup_model()->StepSelection(direction, step);
 }
 
+bool OmniboxEditModel::IsPopupControlPresentOnMatch(
+    OmniboxPopupSelection selection) const {
+  DCHECK(popup_model());
+  return popup_model()->IsControlPresentOnMatch(selection);
+}
+
 bool OmniboxEditModel::TriggerPopupSelectionAction(
     OmniboxPopupSelection selection,
     base::TimeTicks timestamp,
@@ -1793,6 +1803,24 @@
       match_text, include_positional_info, label_prefix_length);
 }
 
+void OmniboxEditModel::OnPopupResultChanged() {
+  if (popup_model()) {
+    popup_model()->OnResultChanged();
+  }
+}
+
+const SkBitmap* OmniboxEditModel::GetPopupRichSuggestionBitmap(
+    int result_index) const {
+  DCHECK(popup_model());
+  return popup_model()->RichSuggestionBitmapAt(result_index);
+}
+
+void OmniboxEditModel::SetPopupRichSuggestionBitmap(int result_index,
+                                                    const SkBitmap& bitmap) {
+  DCHECK(popup_model());
+  popup_model()->SetRichSuggestionBitmap(result_index, bitmap);
+}
+
 PrefService* OmniboxEditModel::GetPrefService() const {
   return autocomplete_controller()->autocomplete_provider_client()->GetPrefs();
 }
diff --git a/components/omnibox/browser/omnibox_edit_model.h b/components/omnibox/browser/omnibox_edit_model.h
index 78dfc75..ed3fc7d 100644
--- a/components/omnibox/browser/omnibox_edit_model.h
+++ b/components/omnibox/browser/omnibox_edit_model.h
@@ -76,6 +76,7 @@
   }
 
   void set_popup_view(OmniboxPopupView* popup_view);
+  OmniboxPopupView* get_popup_view();
 
   // NOTE: popup_model() can be NULL for testing.
   OmniboxPopupModel* popup_model() const { return popup_model_.get(); }
@@ -458,6 +459,11 @@
       OmniboxPopupSelection::Direction direction,
       OmniboxPopupSelection::Step step);
 
+  // Returns true if the control represented by |selection.state| is present on
+  // the match in |selection.line|. This is the source-of-truth the UI code
+  // should query to decide whether or not to draw the control.
+  bool IsPopupControlPresentOnMatch(OmniboxPopupSelection selection) const;
+
   // On popup, triggers the action on |selection| (usually an auxiliary button).
   // If the popup model supports the action and performs it, this returns true.
   // This can't handle all actions currently, and returns false in those cases.
@@ -484,6 +490,17 @@
       bool include_positional_info,
       int* label_prefix_length = nullptr);
 
+  // Invoked any time the result set of the controller changes.
+  // TODO(orinj): This method seems like a good candidate for removal; it is
+  // preserved here only to prevent possible behavior change while refactoring.
+  void OnPopupResultChanged();
+
+  // Lookup the bitmap for |result_index|. Returns nullptr if not found.
+  const SkBitmap* GetPopupRichSuggestionBitmap(int result_index) const;
+
+  // Stores the image in a local data member and schedules a repaint.
+  void SetPopupRichSuggestionBitmap(int result_index, const SkBitmap& bitmap);
+
  protected:
   // Utility method to get current PrefService; protected instead of private
   // because it may be overridden by derived test classes.
diff --git a/components/safe_browsing/content/browser/client_side_model_loader.cc b/components/safe_browsing/content/browser/client_side_model_loader.cc
index 9557e7d..69d6862 100644
--- a/components/safe_browsing/content/browser/client_side_model_loader.cc
+++ b/components/safe_browsing/content/browser/client_side_model_loader.cc
@@ -70,8 +70,6 @@
     "ClientSideDetectionModelOnAndroid";
 #endif
 const char ModelLoader::kClientModelFinchParam[] = "ModelNum";
-const char kUmaModelDownloadResponseMetricName[] =
-    "SBClientPhishing.ClientModelDownloadResponseOrErrorCode";
 
 // Command-line flag that can be used to override the current CSD model. Must be
 // provided with an absolute path.
@@ -222,9 +220,6 @@
   int response_code = 0;
   if (url_loader_->ResponseInfo() && url_loader_->ResponseInfo()->headers)
     response_code = url_loader_->ResponseInfo()->headers->response_code();
-  V4ProtocolManagerUtil::RecordHttpResponseOrErrorCode(
-      kUmaModelDownloadResponseMetricName, url_loader_->NetError(),
-      response_code);
 
   // max_age is valid iff !0.
   base::TimeDelta max_age;
diff --git a/components/safe_browsing/content/browser/password_protection/password_protection_request_content.cc b/components/safe_browsing/content/browser/password_protection/password_protection_request_content.cc
index cb2cc36..a7e46fe 100644
--- a/components/safe_browsing/content/browser/password_protection/password_protection_request_content.cc
+++ b/components/safe_browsing/content/browser/password_protection/password_protection_request_content.cc
@@ -265,23 +265,10 @@
       !password_protection_service()->IsIncognito()) {
     content::RenderWidgetHostView* view =
         web_contents_ ? web_contents_->GetRenderWidgetHostView() : nullptr;
-    base::UmaHistogramBoolean(
-        "PasswordProtection.AndroidVisualFeaturesViewNull", (view == nullptr));
-    if (view) {
-      base::UmaHistogramBoolean(
-          "PasswordProtection.AndroidVisualFeaturesNativeViewNull",
-          (view->GetNativeView() == nullptr));
-    }
     if (view && view->GetNativeView()) {
       gfx::SizeF content_area_size = view->GetNativeView()->viewport_size();
       request_proto_->set_content_area_height(content_area_size.height());
       request_proto_->set_content_area_width(content_area_size.width());
-      base::UmaHistogramCounts10000(
-          "PasswordProtection.AndroidVisualFeaturesNativeViewWidth",
-          content_area_size.width());
-      base::UmaHistogramCounts10000(
-          "PasswordProtection.AndroidVisualFeaturesNativeViewHeight",
-          content_area_size.height());
     }
   }
 #endif
diff --git a/components/safe_browsing/content/resources/PRESUBMIT.py b/components/safe_browsing/content/resources/PRESUBMIT.py
index dc5d2bfa..6fe451c 100644
--- a/components/safe_browsing/content/resources/PRESUBMIT.py
+++ b/components/safe_browsing/content/resources/PRESUBMIT.py
@@ -45,6 +45,19 @@
                     download_file_types_file.LocalPath() + ' if you are '
                     'updating the file types proto.'))
 
+    if len(download_file_types_files) == 1:
+        results.append(
+            output_api.PresubmitPromptWarning(
+                'You only modified either of download_file_types.asciipb or ' +
+                'download_file_types_experiment.asciipb, please make sure ' +
+                'your change does not affect any ongoing experiment.'))
+
+    results.append(
+        output_api.PresubmitPromptWarning(
+            'Please make sure you have read https://chromium.googlesource.com'
+            + '/chromium/src/+/HEAD/chrome/browser/resources/safe_browsing/' +
+            'README.md before editing the download_file_types config files.'))
+
     return results
 
 
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index d777ac54..7545c5e 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -27,6 +27,7 @@
 #include "content/browser/interest_group/ad_auction_service_impl.h"
 #include "content/browser/keyboard_lock/keyboard_lock_service_impl.h"
 #include "content/browser/loader/content_security_notifier.h"
+#include "content/browser/media/media_web_contents_observer.h"
 #include "content/browser/media/midi_host.h"
 #include "content/browser/media/session/media_session_service_impl.h"
 #include "content/browser/picture_in_picture/picture_in_picture_service_impl.h"
@@ -69,6 +70,7 @@
 #include "media/capture/mojom/video_capture.mojom.h"
 #include "media/mojo/mojom/interface_factory.mojom.h"
 #include "media/mojo/mojom/media_metrics_provider.mojom.h"
+#include "media/mojo/mojom/media_player.mojom.h"
 #include "media/mojo/mojom/remoting.mojom.h"
 #include "media/mojo/mojom/video_decode_perf_history.mojom.h"
 #include "services/device/public/mojom/battery_monitor.mojom.h"
@@ -587,6 +589,16 @@
     GetDeviceService().BindVibrationManager(std::move(receiver));
 }
 
+void BindMediaPlayerObserverClientHandler(
+    content::RenderFrameHost* frame_host,
+    mojo::PendingReceiver<media::mojom::MediaPlayerObserverClient> receiver) {
+  content::WebContentsImpl* web_contents =
+      static_cast<content::WebContentsImpl*>(
+          content::WebContents::FromRenderFrameHost(frame_host));
+  web_contents->media_web_contents_observer()->BindMediaPlayerObserverClient(
+      std::move(receiver));
+}
+
 void BindSocketManager(
     RenderFrameHostImpl* frame,
     mojo::PendingReceiver<network::mojom::P2PSocketManager> receiver) {
@@ -674,6 +686,9 @@
         GetIOThreadTaskRunner({}));
   }
 
+  map->Add<media::mojom::MediaPlayerObserverClient>(base::BindRepeating(
+      &BindMediaPlayerObserverClientHandler, base::Unretained(host)));
+
   map->Add<blink::mojom::NotificationService>(base::BindRepeating(
       &RenderFrameHostImpl::CreateNotificationService, base::Unretained(host)));
 
@@ -952,6 +967,8 @@
       base::BindRepeating(
           &EmptyBinderForFrame<
               media::mojom::SpeechRecognitionClientBrowserInterface>));
+  map->Add<media::mojom::MediaPlayerObserverClient>(base::BindRepeating(
+      &EmptyBinderForFrame<media::mojom::MediaPlayerObserverClient>));
 #endif
 #if BUILDFLAG(ENABLE_UNHANDLED_TAP)
   map->Add<blink::mojom::UnhandledTapNotifier>(base::BindRepeating(
diff --git a/content/browser/child_process_launcher_helper_win.cc b/content/browser/child_process_launcher_helper_win.cc
index a89da8e..c6d1bf0 100644
--- a/content/browser/child_process_launcher_helper_win.cc
+++ b/content/browser/child_process_launcher_helper_win.cc
@@ -72,11 +72,8 @@
   mojo_channel_->PrepareToPassRemoteEndpoint(&handles, command_line());
   base::FieldTrialList::AppendFieldTrialHandleIfNeeded(&handles);
   ChildProcessLauncherHelper::Process process;
-  *launch_result = StartSandboxedProcess(
-      delegate_.get(),
-      command_line(),
-      handles,
-      &process.process);
+  *launch_result = StartSandboxedProcess(delegate_.get(), *command_line(),
+                                         handles, &process.process);
   return process;
 }
 
diff --git a/content/browser/media/media_web_contents_observer.cc b/content/browser/media/media_web_contents_observer.cc
index 55b8ff5..1edce26 100644
--- a/content/browser/media/media_web_contents_observer.cc
+++ b/content/browser/media/media_web_contents_observer.cc
@@ -271,6 +271,17 @@
   session_controllers_manager_->WebContentsMutedStateChanged(muted);
 }
 
+void MediaWebContentsObserver::GetHasPlayedBefore(
+    GetHasPlayedBeforeCallback callback) {
+  std::move(callback).Run(has_played_before_);
+}
+
+void MediaWebContentsObserver::BindMediaPlayerObserverClient(
+    mojo::PendingReceiver<media::mojom::MediaPlayerObserverClient>
+        pending_receiver) {
+  receivers_.Add(this, std::move(pending_receiver));
+}
+
 void MediaWebContentsObserver::RequestPersistentVideo(bool value) {
   if (!fullscreen_player_)
     return;
@@ -442,6 +453,7 @@
   if (!player_info->is_playing())
     player_info->SetIsPlaying();
 
+  media_web_contents_observer_->OnMediaPlaying();
   NotifyAudioStreamMonitorIfNeeded();
 }
 
@@ -537,6 +549,10 @@
   web_contents_impl()->MediaEffectivelyFullscreenChanged(is_fullscreen);
 }
 
+void MediaWebContentsObserver::OnMediaPlaying() {
+  has_played_before_ = true;
+}
+
 void MediaWebContentsObserver::OnAudioOutputSinkChanged(
     const MediaPlayerId& player_id,
     std::string hashed_device_id) {
diff --git a/content/browser/media/media_web_contents_observer.h b/content/browser/media/media_web_contents_observer.h
index a064962..2bcbe3c 100644
--- a/content/browser/media/media_web_contents_observer.h
+++ b/content/browser/media/media_web_contents_observer.h
@@ -61,7 +61,9 @@
 // browser side. It receives IPC messages from media RenderFrameObservers and
 // forwards them to the corresponding managers. The managers are responsible
 // for sending IPCs back to the RenderFrameObservers at the render side.
-class CONTENT_EXPORT MediaWebContentsObserver : public WebContentsObserver {
+class CONTENT_EXPORT MediaWebContentsObserver
+    : public WebContentsObserver,
+      public media::mojom::MediaPlayerObserverClient {
  public:
   explicit MediaWebContentsObserver(WebContentsImpl* web_contents);
 
@@ -94,6 +96,13 @@
   void MediaPictureInPictureChanged(bool is_picture_in_picture) override;
   void DidUpdateAudioMutingState(bool muted) override;
 
+  // MediaPlayerObserverClient implementation.
+  void GetHasPlayedBefore(GetHasPlayedBeforeCallback callback) override;
+
+  void BindMediaPlayerObserverClient(
+      mojo::PendingReceiver<media::mojom::MediaPlayerObserverClient>
+          pending_receiver);
+
   // TODO(zqzhang): this method is temporarily in MediaWebContentsObserver as
   // the effectively fullscreen video code is also here. We need to consider
   // merging the logic of effectively fullscreen, hiding media controls and
@@ -255,6 +264,7 @@
   void OnMediaEffectivelyFullscreenChanged(
       const MediaPlayerId& player_id,
       blink::WebFullscreenVideoStatus fullscreen_status);
+  void OnMediaPlaying();
   void OnAudioOutputSinkChanged(const MediaPlayerId& player_id,
                                 std::string hashed_device_id);
 
@@ -285,6 +295,11 @@
   // Helper class for recording audible metrics.
   AudibleMetrics* audible_metrics_;
 
+  // A boolean indicating whether media has played before.
+  bool has_played_before_ = false;
+
+  mojo::ReceiverSet<media::mojom::MediaPlayerObserverClient> receivers_;
+
   // Tracking variables and associated wake locks for media playback.
   PlayerInfoMap player_info_map_;
   mojo::Remote<device::mojom::WakeLock> audio_wake_lock_;
diff --git a/content/common/sandbox_init_win.cc b/content/common/sandbox_init_win.cc
index 8d8e925..9fb01a2 100644
--- a/content/common/sandbox_init_win.cc
+++ b/content/common/sandbox_init_win.cc
@@ -26,29 +26,30 @@
 
 sandbox::ResultCode StartSandboxedProcess(
     SandboxedProcessLauncherDelegate* delegate,
-    base::CommandLine* child_command_line,
+    const base::CommandLine& target_command_line,
     const base::HandlesToInheritVector& handles_to_inherit,
     base::Process* process) {
   std::string type_str =
-      child_command_line->GetSwitchValueASCII(switches::kProcessType);
+      target_command_line.GetSwitchValueASCII(switches::kProcessType);
   TRACE_EVENT1("startup", "StartProcessWithAccess", "type", type_str);
 
   // Updates the command line arguments with debug-related flags. If debug
   // flags have been used with this process, they will be filtered and added
-  // to child_command_line as needed.
-  const base::CommandLine* current_command_line =
-      base::CommandLine::ForCurrentProcess();
-  if (current_command_line->HasSwitch(switches::kWaitForDebuggerChildren)) {
-    std::string value = current_command_line->GetSwitchValueASCII(
+  // to full_command_line as needed.
+  const base::CommandLine& current_command_line =
+      *base::CommandLine::ForCurrentProcess();
+  base::CommandLine full_command_line = target_command_line;
+  if (current_command_line.HasSwitch(switches::kWaitForDebuggerChildren)) {
+    std::string value = current_command_line.GetSwitchValueASCII(
         switches::kWaitForDebuggerChildren);
-    child_command_line->AppendSwitchASCII(switches::kWaitForDebuggerChildren,
-                                          value);
+    full_command_line.AppendSwitchASCII(switches::kWaitForDebuggerChildren,
+                                        value);
     if (value.empty() || value == type_str)
-      child_command_line->AppendSwitch(switches::kWaitForDebugger);
+      full_command_line.AppendSwitch(switches::kWaitForDebugger);
   }
 
   return sandbox::policy::SandboxWin::StartSandboxedProcess(
-      child_command_line, type_str, handles_to_inherit, delegate, process);
+      full_command_line, type_str, handles_to_inherit, delegate, process);
 }
 
 }  // namespace content
diff --git a/content/public/common/sandbox_init.h b/content/public/common/sandbox_init.h
index bc576cab..0935e81 100644
--- a/content/public/common/sandbox_init.h
+++ b/content/public/common/sandbox_init.h
@@ -47,9 +47,13 @@
 // then it just has to outlive this method call. |handles_to_inherit| is a list
 // of handles for the child process to inherit. The caller retains ownership of
 // the handles.
+//
+// Note that calling this function does not always create a sandboxed process,
+// as the process might be unsandboxed depending on the behavior of the
+// delegate, the command line of the caller, and the command line of the target.
 CONTENT_EXPORT sandbox::ResultCode StartSandboxedProcess(
     SandboxedProcessLauncherDelegate* delegate,
-    base::CommandLine* child_command_line,
+    const base::CommandLine& target_command_line,
     const base::HandlesToInheritVector& handles_to_inherit,
     base::Process* process);
 
diff --git a/extensions/browser/extension_host.cc b/extensions/browser/extension_host.cc
index c273c763c..6596a81 100644
--- a/extensions/browser/extension_host.cc
+++ b/extensions/browser/extension_host.cc
@@ -248,10 +248,6 @@
   if (first_load) {
     RecordStopLoadingUMA();
     OnDidStopFirstLoad();
-    content::NotificationService::current()->Notify(
-        extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD,
-        content::Source<BrowserContext>(browser_context_),
-        content::Details<ExtensionHost>(this));
     ExtensionHostRegistry::Get(browser_context_)
         ->ExtensionHostCompletedFirstLoad(this);
     for (auto& observer : observer_list_)
diff --git a/extensions/browser/notification_types.h b/extensions/browser/notification_types.h
index 03a1c7d..ed40a53 100644
--- a/extensions/browser/notification_types.h
+++ b/extensions/browser/notification_types.h
@@ -60,15 +60,6 @@
   // TODO(https://crbug.com/1174736): Remove.
   NOTIFICATION_EXTENSION_REMOVED,
 
-  // Sent by an ExtensionHost* when it has finished its initial page load,
-  // including any external resources.
-  // The details are an ExtensionHost* and the source is a BrowserContext*.
-  //
-  // DEPRECATED: Use extensions::DeferredStartRenderHostObserver::
-  // OnDeferredStartRenderHostDidStopFirstLoad()
-  // TODO(https://crbug.com/1174741): Remove.
-  NOTIFICATION_EXTENSION_HOST_DID_STOP_FIRST_LOAD,
-
   // Sent when extension render process ends (whether it crashes or closes). The
   // details are an ExtensionHost* and the source is a BrowserContext*. Not sent
   // during browser shutdown.
diff --git a/fuchsia/engine/browser/virtual_keyboard_browsertest.cc b/fuchsia/engine/browser/virtual_keyboard_browsertest.cc
index 6baf0ca..9516b69 100644
--- a/fuchsia/engine/browser/virtual_keyboard_browsertest.cc
+++ b/fuchsia/engine/browser/virtual_keyboard_browsertest.cc
@@ -137,8 +137,7 @@
 
 // Verifies that RequestShow() is not called redundantly if the virtual
 // keyboard is reported as visible.
-// TODO(https://crbug.com/1226757): Flaky on Fuchsia-x64.
-IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, DISABLED_ShowAndHideWithVisibility) {
+IN_PROC_BROWSER_TEST_F(VirtualKeyboardTest, ShowAndHideWithVisibility) {
   testing::InSequence s;
 
   // Alphanumeric field click.
@@ -165,6 +164,13 @@
           [&on_hide_run_loop]() { on_hide_run_loop.Quit(); }))
       .RetiresOnSaturation();
 
+  // In some cases, Blink may signal an
+  // InputMethodClient::OnTextInputTypeChanged event, which will cause
+  // an extra call to VirtualKeyboardController:RequestHide. This is harmless
+  // in practice due to RequestHide()'s idempotence, however we still need to
+  // anticipate that behavior in the controller mocks.
+  EXPECT_CALL(*controller_, RequestHide()).Times(testing::AtMost(1));
+
   // Give focus to an alphanumeric input field, which will result in
   // RequestShow() being called.
   content::SimulateTapAt(web_contents_,
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_image.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_image.cc
index 37b18c78..0f53c19 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_gl_image.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_image.cc
@@ -265,6 +265,12 @@
   *allow_legacy_mailbox = gr_context_type == GrContextType::kGL;
   return true;
 #else
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  // On ChromeOS Ash, use only for SHARED_MEMORY gmb
+  if (gmb_type != gfx::SHARED_MEMORY_BUFFER) {
+    return false;
+  }
+#endif
   // Doesn't support contexts other than GL for OOPR Canvas
   if (gr_context_type != GrContextType::kGL &&
       ((usage & SHARED_IMAGE_USAGE_DISPLAY) ||
@@ -283,6 +289,7 @@
     // return false if it needs interop factory
     return false;
   }
+
   *allow_legacy_mailbox = gr_context_type == GrContextType::kGL;
   return true;
 #endif
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
index f13a6ba..33307bd 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ozone.cc
@@ -15,6 +15,7 @@
 #include "gpu/command_buffer/service/shared_image_backing_ozone.h"
 #include "gpu/command_buffer/service/shared_memory_region_wrapper.h"
 #include "gpu/vulkan/vulkan_device_queue.h"
+#include "ui/gfx/buffer_types.h"
 #include "ui/gfx/gpu_memory_buffer.h"
 #include "ui/gfx/native_pixmap.h"
 #include "ui/gl/buildflags.h"
@@ -31,8 +32,7 @@
   } else if (usage & SHARED_IMAGE_USAGE_SCANOUT) {
     return gfx::BufferUsage::SCANOUT;
   } else {
-    NOTREACHED() << "Unsupported usage flags.";
-    return gfx::BufferUsage::SCANOUT;
+    return gfx::BufferUsage::GPU_READ;
   }
 }
 
@@ -71,6 +71,12 @@
       ui::OzonePlatform::GetInstance()->GetSurfaceFactoryOzone();
   scoped_refptr<gfx::NativePixmap> pixmap = surface_factory->CreateNativePixmap(
       surface_handle, vk_device, size, buffer_format, GetBufferUsage(usage));
+  // Fallback to GPU_READ if cannot create pixmap with SCANOUT
+  if (!pixmap) {
+    pixmap = surface_factory->CreateNativePixmap(surface_handle, vk_device,
+                                                 size, buffer_format,
+                                                 gfx::BufferUsage::GPU_READ);
+  }
   if (!pixmap) {
     return nullptr;
   }
@@ -183,21 +189,6 @@
       gmb_type != gfx::SHARED_MEMORY_BUFFER) {
     return false;
   }
-  // TODO(crbug.com/969114): Not all shared image factory implementations
-  // support concurrent read/write usage.
-  if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
-    return false;
-  }
-
-  // TODO(hitawala): Until SharedImageBackingOzone supports all use cases prefer
-  // using SharedImageBackingGLImage instead
-  bool needs_interop_factory = (gr_context_type == GrContextType::kVulkan &&
-                                (usage & SHARED_IMAGE_USAGE_DISPLAY)) ||
-                               (usage & SHARED_IMAGE_USAGE_WEBGPU) ||
-                               (usage & SHARED_IMAGE_USAGE_VIDEO_DECODE);
-  if (!needs_interop_factory) {
-    return false;
-  }
 
   *allow_legacy_mailbox = false;
   return true;
diff --git a/gpu/command_buffer/service/shared_image_backing_ozone.cc b/gpu/command_buffer/service/shared_image_backing_ozone.cc
index 39b42ae..1f85356 100644
--- a/gpu/command_buffer/service/shared_image_backing_ozone.cc
+++ b/gpu/command_buffer/service/shared_image_backing_ozone.cc
@@ -199,6 +199,7 @@
   gfx::BufferFormat buffer_format = viz::BufferFormat(format());
   auto image = base::MakeRefCounted<gl::GLImageNativePixmap>(
       pixmap_->GetBufferSize(), buffer_format);
+  image->Initialize(std::move(pixmap_));
   return std::make_unique<SharedImageRepresentationOverlayOzone>(
       manager, this, tracker, image);
 }
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc
index b41b0952..e21e257 100644
--- a/gpu/command_buffer/service/shared_image_factory.cc
+++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -244,12 +244,9 @@
   }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (gpu_preferences.enable_webgpu ||
-      gr_context_type_ == GrContextType::kVulkan) {
-    auto ozone_factory =
-        std::make_unique<SharedImageBackingFactoryOzone>(context_state);
-    factories_.push_back(std::move(ozone_factory));
-  }
+  auto ozone_factory =
+      std::make_unique<SharedImageBackingFactoryOzone>(context_state);
+  factories_.push_back(std::move(ozone_factory));
 #endif  // IS_CHROMEOS_ASH
 
 #if defined(OS_FUCHSIA)
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
index 54c5b7b..741c16e 100644
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
@@ -398,14 +398,11 @@
   }
   gl_renderer_id_ = context_renderer_id & kCGLRendererIDMatchingMask;
 
-  // Post a task holding a reference to the new GL context. The reason for
-  // this is to avoid creating-then-destroying the context for every image
-  // transport surface that is observing the GPU switch.
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          base::DoNothing::Once<scoped_refptr<ui::IOSurfaceContext>>(),
-          context_on_new_gpu));
+  // Delay releasing the reference to the new GL context. The reason for this
+  // is to avoid creating-then-destroying the context for every image transport
+  // surface that is observing the GPU switch.
+  base::ThreadTaskRunnerHandle::Get()->ReleaseSoon(
+      FROM_HERE, std::move(context_on_new_gpu));
 }
 
 // Template instantiation
diff --git a/ios/chrome/browser/flags/BUILD.gn b/ios/chrome/browser/flags/BUILD.gn
index a155def0..8730e92 100644
--- a/ios/chrome/browser/flags/BUILD.gn
+++ b/ios/chrome/browser/flags/BUILD.gn
@@ -59,6 +59,7 @@
     "//ios/chrome/browser/ui/download:features",
     "//ios/chrome/browser/ui/fullscreen:feature_flags",
     "//ios/chrome/browser/ui/ntp:feature_flags",
+    "//ios/chrome/browser/ui/overlays/infobar_banner:feature_flags",
     "//ios/chrome/browser/ui/popup_menu/public:feature_flags",
     "//ios/chrome/browser/ui/reading_list:features",
     "//ios/chrome/browser/ui/start_surface:feature_flags",
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 0ef5b97..f32aff6 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -71,6 +71,7 @@
 #import "ios/chrome/browser/ui/download/features.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_features.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_feature.h"
+#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.h"
 #import "ios/chrome/browser/ui/popup_menu/public/feature_flags.h"
 #import "ios/chrome/browser/ui/reading_list/reading_list_features.h"
 #import "ios/chrome/browser/ui/start_surface/start_surface_features.h"
@@ -471,6 +472,10 @@
      flag_descriptions::kEnableFullPageScreenshotName,
      flag_descriptions::kEnableFullPageScreenshotDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kEnableFullPageScreenshot)},
+    {"enable-long-message-duration",
+     flag_descriptions::kEnableLongMessageDurationName,
+     flag_descriptions::kEnableLongMessageDurationDescription, flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(kEnableLongMessageDuration)},
     {"enable-optimization-guide",
      flag_descriptions::kEnableOptimizationGuideName,
      flag_descriptions::kEnableOptimizationGuideDescription, flags_ui::kOsIos,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 7f2a9a1..79e468dd7 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -194,6 +194,10 @@
     "Enables the option of capturing an entire webpage as a PDF when a "
     "screenshot is taken.";
 
+const char kEnableLongMessageDurationName[] = "Enable long message duration";
+const char kEnableLongMessageDurationDescription[] =
+    "Enables a long duration when an overlay message is shown.";
+
 const char kEnableManualPasswordGenerationName[] =
     "Enable manual password generation.";
 const char kEnableManualPasswordGenerationDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index 3277d328..ef139bd 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -171,6 +171,10 @@
 extern const char kEnableFullPageScreenshotName[];
 extern const char kEnableFullPageScreenshotDescription[];
 
+// Title and description for the flag to enable long message duration.
+extern const char kEnableLongMessageDurationName[];
+extern const char kEnableLongMessageDurationDescription[];
+
 // Title and description for the flag to enable UI that allows the user to
 // create a strong password even if the field wasn't parsed as a new password
 // field.
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn
index 12bba23..9904074 100644
--- a/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn
+++ b/ios/chrome/browser/ui/overlays/infobar_banner/BUILD.gn
@@ -14,6 +14,17 @@
   ]
 }
 
+source_set("feature_flags") {
+  sources = [
+    "infobar_banner_features.h",
+    "infobar_banner_features.mm",
+  ]
+
+  configs += [ "//build/config/compiler:enable_arc" ]
+
+  deps = [ "//base" ]
+}
+
 source_set("coordinators") {
   sources = [
     "infobar_banner_overlay_coordinator.h",
@@ -23,6 +34,7 @@
   configs += [ "//build/config/compiler:enable_arc" ]
 
   deps = [
+    ":feature_flags",
     ":mediators",
     "//base",
     "//ios/chrome/browser/overlays",
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.h b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.h
new file mode 100644
index 0000000..7c35b44f
--- /dev/null
+++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.h
@@ -0,0 +1,30 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_FEATURES_H_
+#define IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_FEATURES_H_
+
+#include "base/feature_list.h"
+
+// The feature parameter that indicates the duration of a long presentation
+// message.
+extern const char kLongPresentationMessagesDurationFeatureParam[];
+
+// The feature parameter that indicates the duration of a default
+// presentation message.
+extern const char kDefaultPresentationMessagesDurationFeatureParam[];
+
+// The feature to enable long message duration
+extern const base::Feature kEnableLongMessageDuration;
+
+// Checks whether the long message duration feature is enabled.
+bool IsLongMessageDurationEnabled();
+
+// Returns the duration of the default presentation messages.
+double GetDefaultPresentationMessageDuration();
+
+// Returns the duration of the long presentation messages.
+double GetLongPresentationMessageDuration();
+
+#endif  // IOS_CHROME_BROWSER_UI_OVERLAYS_INFOBAR_BANNER_INFOBAR_BANNER_FEATURES_H_
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.mm
new file mode 100644
index 0000000..eb167d96
--- /dev/null
+++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.mm
@@ -0,0 +1,35 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+const base::Feature kEnableLongMessageDuration{
+    "EnableLongMessageDuration", base::FEATURE_DISABLED_BY_DEFAULT};
+
+const char kLongPresentationMessagesDurationFeatureParam[] =
+    "LongPresentationMessagesDurationFeatureParam";
+
+const char kDefaultPresentationMessagesDurationFeatureParam[] =
+    "DefaultPresentationMessagesDurationFeatureParam";
+
+bool IsLongMessageDurationEnabled() {
+  return base::FeatureList::IsEnabled(kEnableLongMessageDuration);
+}
+
+double GetDefaultPresentationMessageDuration() {
+  return base::GetFieldTrialParamByFeatureAsDouble(
+      kEnableLongMessageDuration,
+      kDefaultPresentationMessagesDurationFeatureParam,
+      15 /*default to 15 second*/);
+}
+
+double GetLongPresentationMessageDuration() {
+  return base::GetFieldTrialParamByFeatureAsDouble(
+      kEnableLongMessageDuration, kLongPresentationMessagesDurationFeatureParam,
+      20 /*default to 20 second*/);
+}
diff --git a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm
index ae964bd8..4d2714b 100644
--- a/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm
+++ b/ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_coordinator.mm
@@ -18,6 +18,7 @@
 #import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h"
 #import "ios/chrome/browser/ui/overlays/infobar_banner/autofill_address_profile/save_address_profile_infobar_banner_overlay_mediator.h"
 #import "ios/chrome/browser/ui/overlays/infobar_banner/confirm/confirm_infobar_banner_overlay_mediator.h"
+#import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_features.h"
 #import "ios/chrome/browser/ui/overlays/infobar_banner/infobar_banner_overlay_mediator.h"
 #import "ios/chrome/browser/ui/overlays/infobar_banner/passwords/save_password_infobar_banner_overlay_mediator.h"
 #import "ios/chrome/browser/ui/overlays/infobar_banner/passwords/update_password_infobar_banner_overlay_mediator.h"
@@ -119,12 +120,19 @@
   self.started = YES;
 
   if (!UIAccessibilityIsVoiceOverRunning()) {
-    // Auto-dismiss the banner after timeout if VoiceOver is off (banner should
-    // persist until user explicitly swipes it away).
-    NSTimeInterval timeout =
-        config->is_high_priority()
-            ? kInfobarBannerLongPresentationDurationInSeconds
-            : kInfobarBannerDefaultPresentationDurationInSeconds;
+    NSTimeInterval timeout;
+    if (IsLongMessageDurationEnabled()) {
+      // If long message duration is enabled, set a longer timeout.
+      timeout = config->is_high_priority()
+                    ? GetLongPresentationMessageDuration()
+                    : GetDefaultPresentationMessageDuration();
+    } else {
+      // Auto-dismiss the banner after timeout if VoiceOver is off (banner
+      // should persist until user explicitly swipes it away).
+      timeout = config->is_high_priority()
+                    ? kInfobarBannerLongPresentationDurationInSeconds
+                    : kInfobarBannerDefaultPresentationDurationInSeconds;
+    }
     [self performSelector:@selector(dismissBannerIfReady)
                withObject:nil
                afterDelay:timeout];
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
new file mode 100644
index 0000000..824b610e
--- /dev/null
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -0,0 +1 @@
+21f3b0fc61895a2d6633ffb8f433ae54fd622a2e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
new file mode 100644
index 0000000..12bce17
--- /dev/null
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -0,0 +1 @@
+821c52f56c62f19e2335510e7fd1e0023750c389
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
new file mode 100644
index 0000000..c09acdb
--- /dev/null
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -0,0 +1 @@
+25d38ea705b6018d6e16f50d49e31b1fea12439a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
new file mode 100644
index 0000000..75a5ff5
--- /dev/null
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -0,0 +1 @@
+558c9557211debb25c0a7bca2f46b075c87fa8f6
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
new file mode 100644
index 0000000..46d855a3
--- /dev/null
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -0,0 +1 @@
+cc3261714b58e88b96c0a474d119a1bf11d2eb6f
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
new file mode 100644
index 0000000..2b6e4cb
--- /dev/null
+++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -0,0 +1 @@
+4c695b9ff8bb0b8a97c225945995358730b6c51e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
new file mode 100644
index 0000000..81cb7ca
--- /dev/null
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -0,0 +1 @@
+ca91d9a136985387dfbff8be623271744f155f5e
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
new file mode 100644
index 0000000..a3438b0
--- /dev/null
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -0,0 +1 @@
+61610936ac0a2e0816d1594eea6ca05bd50fa7fc
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
new file mode 100644
index 0000000..7853209
--- /dev/null
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -0,0 +1 @@
+b1895ea885d05284b156c723951d841a9c4726c4
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
new file mode 100644
index 0000000..c7a5690
--- /dev/null
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -0,0 +1 @@
+245a2d4b7b0061a5f6223ddb9e1aa2be970a8cbc
\ No newline at end of file
diff --git a/media/mojo/mojom/media_player.mojom b/media/mojo/mojom/media_player.mojom
index fe8f5ee..83f8ade 100644
--- a/media/mojo/mojom/media_player.mojom
+++ b/media/mojo/mojom/media_player.mojom
@@ -56,6 +56,13 @@
   SuspendForFrameClosed();
 };
 
+// Implemented by the MediaWebContentsObserver. The remote lives in the renderer
+// process and the receiver lives in the browser process.
+interface MediaPlayerObserverClient {
+  // Gets a flag indicating whether media has been played before.
+  GetHasPlayedBefore() => (bool has_played_before);
+};
+
 // Implemented by MediaWebContentsObserver::MediaPlayerObserverHostImpl in the
 // browser process.
 interface MediaPlayerObserver {
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc
index 4dacb688..fd87f29d 100644
--- a/sandbox/policy/win/sandbox_win.cc
+++ b/sandbox/policy/win/sandbox_win.cc
@@ -433,7 +433,7 @@
   base::UmaHistogramSparse("Process.Sandbox.Launch.Warning", last_error);
 }
 
-ResultCode AddPolicyForSandboxedProcess(TargetPolicy* policy) {
+ResultCode AddDefaultPolicyForSandboxedProcess(TargetPolicy* policy) {
   ResultCode result = sandbox::SBOX_ALL_OK;
 
   // Win8+ adds a device DeviceApi that we don't need.
@@ -767,7 +767,7 @@
 // a Policy or TargetProcess. This supports both kNoSandbox and the --no-sandbox
 // command line flag.
 ResultCode LaunchWithoutSandbox(
-    base::CommandLine* cmd_line,
+    const base::CommandLine& cmd_line,
     const base::HandlesToInheritVector& handles_to_inherit,
     SandboxDelegate* delegate,
     base::Process* process) {
@@ -799,17 +799,30 @@
   // are not. When --no-sandbox is specified we disable CET for all children.
   // Otherwise we are here because the sandbox type is kNoSandbox, and allow
   // the process delegate to indicate if it is compatible with CET.
-  if (cmd_line->HasSwitch(switches::kNoSandbox) ||
+  if (cmd_line.HasSwitch(switches::kNoSandbox) ||
       base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kNoSandbox)) {
     options.disable_cetcompat = true;
   } else if (!delegate->CetCompatible()) {
     options.disable_cetcompat = true;
   }
 
-  *process = base::LaunchProcess(*cmd_line, options);
+  *process = base::LaunchProcess(cmd_line, options);
   return SBOX_ALL_OK;
 }
 
+bool IsUnsandboxedProcess(
+    SandboxType sandbox_type,
+    const base::CommandLine& cmd_line,
+    const base::CommandLine& launcher_process_command_line) {
+  if (IsUnsandboxedSandboxType(sandbox_type))
+    return true;
+  if (cmd_line.HasSwitch(switches::kNoSandbox))
+    return true;
+  if (launcher_process_command_line.HasSwitch(switches::kNoSandbox))
+    return true;
+  return false;
+}
+
 }  // namespace
 
 // static
@@ -977,29 +990,27 @@
 }
 
 // static
-ResultCode SandboxWin::StartSandboxedProcess(
-    base::CommandLine* cmd_line,
+ResultCode SandboxWin::GeneratePolicyForSandboxedProcess(
+    const base::CommandLine& cmd_line,
     const std::string& process_type,
     const base::HandlesToInheritVector& handles_to_inherit,
     SandboxDelegate* delegate,
-    base::Process* process) {
+    const scoped_refptr<TargetPolicy>& policy) {
   const base::CommandLine& launcher_process_command_line =
       *base::CommandLine::ForCurrentProcess();
 
   SandboxType sandbox_type = delegate->GetSandboxType();
-  // --no-sandbox and kNoSandbox are launched without creating a Policy.
-  if (IsUnsandboxedSandboxType(sandbox_type) ||
-      cmd_line->HasSwitch(switches::kNoSandbox) ||
-      launcher_process_command_line.HasSwitch(switches::kNoSandbox)) {
-    return LaunchWithoutSandbox(cmd_line, handles_to_inherit, delegate,
-                                process);
+  // --no-sandbox and kNoSandbox are launched without a policy.
+  if (IsUnsandboxedProcess(sandbox_type, cmd_line,
+                           launcher_process_command_line)) {
+    return ResultCode::SBOX_ERROR_UNSANDBOXED_PROCESS;
   }
 
-  scoped_refptr<TargetPolicy> policy = g_broker_services->CreatePolicy();
-
   // Allow no sandbox job if the --allow-no-sandbox-job switch is present.
-  if (launcher_process_command_line.HasSwitch(switches::kAllowNoSandboxJob))
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kAllowNoSandboxJob)) {
     policy->SetAllowNoSandboxJob();
+  }
 
   // Add any handles to be inherited to the policy.
   for (HANDLE handle : handles_to_inherit)
@@ -1038,7 +1049,7 @@
 
   // Post-startup mitigations.
   mitigations = MITIGATION_DLL_SEARCH_ORDER;
-  if (!cmd_line->HasSwitch(switches::kAllowThirdPartyModules) &&
+  if (!cmd_line.HasSwitch(switches::kAllowThirdPartyModules) &&
       sandbox_type != SandboxType::kSpeechRecognition) {
     mitigations |= MITIGATION_FORCE_MS_SIGNED_BINS;
   }
@@ -1053,12 +1064,12 @@
   if (result != SBOX_ALL_OK)
     return result;
 
-  result = SetJobLevel(*cmd_line, JOB_LOCKDOWN, 0, policy.get());
+  result = SetJobLevel(cmd_line, JOB_LOCKDOWN, 0, policy.get());
   if (result != SBOX_ALL_OK)
     return result;
 
   if (!delegate->DisableDefaultPolicy()) {
-    result = AddPolicyForSandboxedProcess(policy.get());
+    result = AddDefaultPolicyForSandboxedProcess(policy.get());
     if (result != SBOX_ALL_OK)
       return result;
   }
@@ -1086,9 +1097,9 @@
   }
 
   std::string appcontainer_id;
-  if (IsAppContainerEnabledForSandbox(*cmd_line, sandbox_type) &&
+  if (IsAppContainerEnabledForSandbox(cmd_line, sandbox_type) &&
       delegate->GetAppContainerId(&appcontainer_id)) {
-    result = AddAppContainerProfileToPolicy(*cmd_line, sandbox_type,
+    result = AddAppContainerProfileToPolicy(cmd_line, sandbox_type,
                                             appcontainer_id, policy.get());
     DCHECK(result == SBOX_ALL_OK);
     if (result != SBOX_ALL_OK)
@@ -1128,14 +1139,35 @@
   if (!delegate->PreSpawnTarget(policy.get()))
     return SBOX_ERROR_DELEGATE_PRE_SPAWN;
 
+  return result;
+}
+
+// static
+ResultCode SandboxWin::StartSandboxedProcess(
+    const base::CommandLine& cmd_line,
+    const std::string& process_type,
+    const base::HandlesToInheritVector& handles_to_inherit,
+    SandboxDelegate* delegate,
+    base::Process* process) {
+  scoped_refptr<TargetPolicy> policy = g_broker_services->CreatePolicy();
+  ResultCode result = GeneratePolicyForSandboxedProcess(
+      cmd_line, process_type, handles_to_inherit, delegate, policy);
+
+  if (ResultCode::SBOX_ERROR_UNSANDBOXED_PROCESS == result) {
+    return LaunchWithoutSandbox(cmd_line, handles_to_inherit, delegate,
+                                process);
+  }
+  if (SBOX_ALL_OK != result)
+    return result;
+
   TRACE_EVENT_BEGIN0("startup", "StartProcessWithAccess::LAUNCHPROCESS");
 
   PROCESS_INFORMATION temp_process_info = {};
   ResultCode last_warning = sandbox::SBOX_ALL_OK;
   DWORD last_error = ERROR_SUCCESS;
   result = g_broker_services->SpawnTarget(
-      cmd_line->GetProgram().value().c_str(),
-      cmd_line->GetCommandLineString().c_str(), policy, &last_warning,
+      cmd_line.GetProgram().value().c_str(),
+      cmd_line.GetCommandLineString().c_str(), policy, &last_warning,
       &last_error, &temp_process_info);
 
   base::win::ScopedProcessInformation target(temp_process_info);
@@ -1162,7 +1194,7 @@
       base::debug::GlobalActivityTracker::Get();
   if (tracker) {
     tracker->RecordProcessLaunch(target.process_id(),
-                                 cmd_line->GetCommandLineString());
+                                 cmd_line.GetCommandLineString());
   }
 
   if (SBOX_ALL_OK != last_warning)
diff --git a/sandbox/policy/win/sandbox_win.h b/sandbox/policy/win/sandbox_win.h
index bdc7672..167e557e 100644
--- a/sandbox/policy/win/sandbox_win.h
+++ b/sandbox/policy/win/sandbox_win.h
@@ -35,13 +35,34 @@
 
 class SANDBOX_POLICY_EXPORT SandboxWin {
  public:
+  // Create a sandboxed process `process` with the specified `cmd_line` of type
+  // `process_type` (e.g. 'renderer' or 'utility'). `handles_to_inherit`
+  // specifies a set of handles to inherit. `delegate` specifies the sandbox
+  // delegate to use when resolving specific sandbox policy.
+  //
+  // Returns SBOX_ALL_OK if the process was successfully created.
+  // Otherwise, returns one of sandbox::ResultCode for any other error.
   static ResultCode StartSandboxedProcess(
-      base::CommandLine* cmd_line,
+      const base::CommandLine& cmd_line,
       const std::string& process_type,
       const base::HandlesToInheritVector& handles_to_inherit,
       SandboxDelegate* delegate,
       base::Process* process);
 
+  // Generates a sandbox policy into `policy` to match the one that would be
+  // applied during `StartSandboxedProcess` for the identical set of arguments.
+  //
+  // Returns SBOX_ALL_OK if the policy was successfully generated.
+  // Returns SBOX_ERROR_UNSANDBOXED_PROCESS if the process has no valid
+  // sandbox policy because it should be run unsandboxed, otherwise returns one
+  // of sandbox::ResultCode for any other error while constructing the policy.
+  static ResultCode GeneratePolicyForSandboxedProcess(
+      const base::CommandLine& cmd_line,
+      const std::string& process_type,
+      const base::HandlesToInheritVector& handles_to_inherit,
+      SandboxDelegate* delegate,
+      const scoped_refptr<TargetPolicy>& policy);
+
   // Wrapper around TargetPolicy::SetJobLevel that checks if the
   // sandbox should be let to run without a job object assigned.
   static ResultCode SetJobLevel(const base::CommandLine& cmd_line,
diff --git a/sandbox/policy/win/sandbox_win_unittest.cc b/sandbox/policy/win/sandbox_win_unittest.cc
index 1d4e9a7..87638d9 100644
--- a/sandbox/policy/win/sandbox_win_unittest.cc
+++ b/sandbox/policy/win/sandbox_win_unittest.cc
@@ -28,11 +28,16 @@
 #include "sandbox/policy/sandbox_type.h"
 #include "sandbox/policy/switches.h"
 #include "sandbox/win/src/app_container_base.h"
+#include "sandbox/win/src/sandbox_factory.h"
 #include "sandbox/win/src/sandbox_policy.h"
 #include "sandbox/win/src/sandbox_policy_diagnostic.h"
 #include "sandbox/win/src/sid.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+using ::testing::_;
+using ::testing::Return;
+
 namespace sandbox {
 namespace policy {
 
@@ -390,5 +395,66 @@
   }
 }
 
+// Sandbox can't reach into content to pull the real policies, so these tests
+// merely verifies that various parts of the delegate are called correctly and a
+// policy can be generated.
+class TestSandboxDelegate : public SandboxDelegate {
+ public:
+  TestSandboxDelegate(SandboxType sandbox_type) : sandbox_type_(sandbox_type) {}
+  SandboxType GetSandboxType() override { return sandbox_type_; }
+  bool DisableDefaultPolicy() override { return false; }
+  bool GetAppContainerId(std::string* appcontainer_id) override {
+    NOTREACHED();
+    return false;
+  }
+
+  MOCK_METHOD1(PreSpawnTarget, bool(TargetPolicy* policy));
+
+  void PostSpawnTarget(base::ProcessHandle process) override {}
+
+  bool ShouldUnsandboxedRunInJob() override { return false; }
+
+  bool CetCompatible() override { return true; }
+
+ private:
+  SandboxType sandbox_type_;
+};
+
+TEST_F(SandboxWinTest, GeneratedPolicyTest) {
+  TestSandboxDelegate test_renderer_delegate(SandboxType::kRenderer);
+  base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
+  base::HandlesToInheritVector handles_to_inherit;
+  BrokerServices* broker = SandboxFactory::GetBrokerServices();
+  scoped_refptr<TargetPolicy> policy = broker->CreatePolicy();
+  // PreSpawn should get called, but not modifying the policy for this test.
+  EXPECT_CALL(test_renderer_delegate, PreSpawnTarget(_)).WillOnce(Return(true));
+  ResultCode result = SandboxWin::GeneratePolicyForSandboxedProcess(
+      cmd_line, switches::kRendererProcess, handles_to_inherit,
+      &test_renderer_delegate, policy);
+  ASSERT_EQ(ResultCode::SBOX_ALL_OK, result);
+  // Check some default values come back. No need to check the exact policy in
+  // detail, but just that GeneratePolicyForSandboxedProcess generated some kind
+  // of valid policy.
+  EXPECT_EQ(IntegrityLevel::INTEGRITY_LEVEL_LOW, policy->GetIntegrityLevel());
+  EXPECT_EQ(JobLevel::JOB_LOCKDOWN, policy->GetJobLevel());
+  EXPECT_EQ(TokenLevel::USER_LOCKDOWN, policy->GetLockdownTokenLevel());
+}
+
+TEST_F(SandboxWinTest, GeneratedPolicyTestNoSandbox) {
+  TestSandboxDelegate test_unsandboxed_delegate(SandboxType::kNoSandbox);
+  base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM);
+  base::HandlesToInheritVector handles_to_inherit;
+  BrokerServices* broker = SandboxFactory::GetBrokerServices();
+  scoped_refptr<TargetPolicy> policy = broker->CreatePolicy();
+  // Unsandboxed processes never call the delegate prespawn as there is no
+  // policy.
+  EXPECT_CALL(test_unsandboxed_delegate, PreSpawnTarget(_)).Times(0);
+
+  ResultCode result = SandboxWin::GeneratePolicyForSandboxedProcess(
+      cmd_line, switches::kRendererProcess, handles_to_inherit,
+      &test_unsandboxed_delegate, policy);
+  ASSERT_EQ(ResultCode::SBOX_ERROR_UNSANDBOXED_PROCESS, result);
+}
+
 }  // namespace policy
 }  // namespace sandbox
diff --git a/sandbox/win/src/sandbox_types.h b/sandbox/win/src/sandbox_types.h
index 5b6ab9f..5c959ec 100644
--- a/sandbox/win/src/sandbox_types.h
+++ b/sandbox/win/src/sandbox_types.h
@@ -143,6 +143,8 @@
   SBOX_ERROR_CANNOT_UPDATE_JOB_PROCESS_LIMIT = 60,
   // Cannot create an impersonation lowbox token
   SBOX_ERROR_CANNOT_CREATE_LOWBOX_IMPERSONATION_TOKEN = 61,
+  // Cannot create a sandbox policy for an unsandboxed process.
+  SBOX_ERROR_UNSANDBOXED_PROCESS = 62,
   // Placeholder for last item of the enum.
   SBOX_ERROR_LAST
 };
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json
index 03f86e5..097c053 100644
--- a/testing/buildbot/chromium.android.fyi.json
+++ b/testing/buildbot/chromium.android.fyi.json
@@ -5693,7 +5693,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M94",
-              "revision": "version:94.0.4606.63"
+              "revision": "version:94.0.4606.64"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5780,7 +5780,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M95",
-              "revision": "version:95.0.4638.24"
+              "revision": "version:95.0.4638.25"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -5954,7 +5954,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M94",
-              "revision": "version:94.0.4606.63"
+              "revision": "version:94.0.4606.64"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -6041,7 +6041,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M95",
-              "revision": "version:95.0.4638.24"
+              "revision": "version:95.0.4638.25"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 4b952b5..7fb1ee0 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -56581,7 +56581,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M94",
-              "revision": "version:94.0.4606.63"
+              "revision": "version:94.0.4606.64"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -56669,7 +56669,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M95",
-              "revision": "version:95.0.4638.24"
+              "revision": "version:95.0.4638.25"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -56845,7 +56845,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M94",
-              "revision": "version:94.0.4606.63"
+              "revision": "version:94.0.4606.64"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -56933,7 +56933,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M95",
-              "revision": "version:95.0.4638.24"
+              "revision": "version:95.0.4638.25"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -57182,7 +57182,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M94",
-              "revision": "version:94.0.4606.63"
+              "revision": "version:94.0.4606.64"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -57269,7 +57269,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M95",
-              "revision": "version:95.0.4638.24"
+              "revision": "version:95.0.4638.25"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -57443,7 +57443,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M94",
-              "revision": "version:94.0.4606.63"
+              "revision": "version:94.0.4606.64"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -57530,7 +57530,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M95",
-              "revision": "version:95.0.4638.24"
+              "revision": "version:95.0.4638.25"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -57779,7 +57779,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M94",
-              "revision": "version:94.0.4606.63"
+              "revision": "version:94.0.4606.64"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -57866,7 +57866,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M95",
-              "revision": "version:95.0.4638.24"
+              "revision": "version:95.0.4638.25"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -58040,7 +58040,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M94",
-              "revision": "version:94.0.4606.63"
+              "revision": "version:94.0.4606.64"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
@@ -58127,7 +58127,7 @@
             {
               "cipd_package": "chromium/testing/weblayer-x86",
               "location": "weblayer_instrumentation_test_M95",
-              "revision": "version:95.0.4638.24"
+              "revision": "version:95.0.4638.25"
             },
             {
               "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 5332bb3..dd257c73 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5840,21 +5840,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "dimension_sets": [
@@ -5898,21 +5898,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "dimension_sets": [
@@ -5948,21 +5948,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "dimension_sets": [
@@ -6006,21 +6006,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 51cfa68..1493f84 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -27033,9 +27033,6 @@
     ],
     "gtest_tests": [
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27054,9 +27051,6 @@
         "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27075,9 +27069,6 @@
         "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27096,9 +27087,6 @@
         "test_id_prefix": "ninja://ui/aura:aura_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27117,9 +27105,6 @@
         "test_id_prefix": "ninja://base:base_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27138,9 +27123,6 @@
         "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27159,9 +27141,6 @@
         "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27181,8 +27160,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.blink_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.blink_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -27202,9 +27180,6 @@
         "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27223,9 +27198,6 @@
         "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27244,9 +27216,6 @@
         "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27265,9 +27234,6 @@
         "test_id_prefix": "ninja://media/capture:capture_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27286,9 +27252,6 @@
         "test_id_prefix": "ninja://fuchsia/runners:cast_runner_browsertests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27307,9 +27270,6 @@
         "test_id_prefix": "ninja://fuchsia/runners:cast_runner_integration_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27328,9 +27288,6 @@
         "test_id_prefix": "ninja://fuchsia/runners:cast_runner_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27350,9 +27307,6 @@
         "test_id_prefix": "ninja://cc:cc_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27371,9 +27325,6 @@
         "test_id_prefix": "ninja://ui/color:color_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27393,8 +27344,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.content_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -27414,9 +27364,6 @@
         "test_id_prefix": "ninja://content/test:content_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27435,9 +27382,6 @@
         "test_id_prefix": "ninja://courgette:courgette_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27456,9 +27400,6 @@
         "test_id_prefix": "ninja://fuchsia/base:cr_fuchsia_base_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27477,9 +27418,6 @@
         "test_id_prefix": "ninja://components/cronet:cronet_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27498,9 +27436,6 @@
         "test_id_prefix": "ninja://components/cronet:cronet_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27519,9 +27454,6 @@
         "test_id_prefix": "ninja://crypto:crypto_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27540,9 +27472,6 @@
         "test_id_prefix": "ninja://ui/display:display_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27561,9 +27490,6 @@
         "test_id_prefix": "ninja://ui/events:events_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27582,9 +27508,6 @@
         "test_id_prefix": "ninja://extensions:extensions_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27603,9 +27526,6 @@
         "test_id_prefix": "ninja://fuchsia/mojom:fuchsia_mojo_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27624,9 +27544,6 @@
         "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27645,9 +27562,6 @@
         "test_id_prefix": "ninja://ui/gfx:gfx_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27666,9 +27580,6 @@
         "test_id_prefix": "ninja://gin:gin_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27687,9 +27598,6 @@
         "test_id_prefix": "ninja://google_apis:google_apis_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27708,9 +27616,6 @@
         "test_id_prefix": "ninja://gpu:gpu_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27730,8 +27635,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.headless_browsertests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.headless_browsertests.filter"
         ],
         "merge": {
           "args": [],
@@ -27751,9 +27655,6 @@
         "test_id_prefix": "ninja://headless:headless_browsertests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27772,9 +27673,6 @@
         "test_id_prefix": "ninja://headless:headless_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27793,9 +27691,6 @@
         "test_id_prefix": "ninja://fuchsia/http:http_service_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27815,8 +27710,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.jingle_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.jingle_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -27836,9 +27730,6 @@
         "test_id_prefix": "ninja://jingle:jingle_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27857,9 +27748,6 @@
         "test_id_prefix": "ninja://ui/latency:latency_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27878,9 +27766,6 @@
         "test_id_prefix": "ninja://media:media_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27899,9 +27784,6 @@
         "test_id_prefix": "ninja://ui/message_center:message_center_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27920,9 +27802,6 @@
         "test_id_prefix": "ninja://media/midi:midi_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27941,9 +27820,6 @@
         "test_id_prefix": "ninja://mojo:mojo_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -27963,8 +27839,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -27986,8 +27861,7 @@
       },
       {
         "args": [
-          "--child-arg=--ozone-platform=headless",
-          "--device=fvdl"
+          "--child-arg=--ozone-platform=headless"
         ],
         "merge": {
           "args": [],
@@ -28007,9 +27881,6 @@
         "test_id_prefix": "ninja://ui/ozone/gl:ozone_gl_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28028,9 +27899,6 @@
         "test_id_prefix": "ninja://ui/ozone:ozone_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28049,9 +27917,6 @@
         "test_id_prefix": "ninja://third_party/perfetto:perfetto_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28071,8 +27936,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -28092,9 +27956,6 @@
         "test_id_prefix": "ninja://services:services_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28113,9 +27974,6 @@
         "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28134,9 +27992,6 @@
         "test_id_prefix": "ninja://skia:skia_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28155,9 +28010,6 @@
         "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28177,8 +28029,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.storage_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.storage_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -28199,8 +28050,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -28220,9 +28070,6 @@
         "test_id_prefix": "ninja://ui/base:ui_base_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28241,9 +28088,6 @@
         "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28263,8 +28107,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -28285,8 +28128,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -28307,8 +28149,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -28328,9 +28169,6 @@
         "test_id_prefix": "ninja://components/viz:viz_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28350,8 +28188,7 @@
       },
       {
         "args": [
-          "--child-arg=--vmodule=test_navigation_listener=1",
-          "--device=fvdl"
+          "--child-arg=--vmodule=test_navigation_listener=1"
         ],
         "merge": {
           "args": [],
@@ -28371,9 +28208,6 @@
         "test_id_prefix": "ninja://fuchsia/engine:web_engine_integration_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28392,9 +28226,6 @@
         "test_id_prefix": "ninja://fuchsia/engine:web_engine_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28413,9 +28244,6 @@
         "test_id_prefix": "ninja://fuchsia/runners:web_runner_integration_tests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28434,9 +28262,6 @@
         "test_id_prefix": "ninja://ui/wm:wm_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28455,9 +28280,6 @@
         "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/"
       },
       {
-        "args": [
-          "--device=fvdl"
-        ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -28480,7 +28302,6 @@
       {
         "args": [
           "bin/run_angle_unittests",
-          "--device=fvdl",
           "--logs-dir=${ISOLATED_OUTDIR}/logs"
         ],
         "isolate_name": "angle_unittests",
@@ -28510,8 +28331,7 @@
     "gtest_tests": [
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.components_unittests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.components_unittests.filter"
         ],
         "merge": {
           "args": [],
@@ -28532,8 +28352,7 @@
       },
       {
         "args": [
-          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter",
-          "--device=fvdl"
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter"
         ],
         "merge": {
           "args": [],
@@ -28561,8 +28380,7 @@
           "--browser=web-engine-shell",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating",
-          "--device=fvdl"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=validating"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -28595,8 +28413,7 @@
           "--browser=web-engine-shell",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--device=fvdl"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -28629,8 +28446,7 @@
           "--browser=web-engine-shell",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--device=fvdl"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -28663,8 +28479,7 @@
           "--browser=web-engine-shell",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--device=fvdl"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -28701,8 +28516,7 @@
           "--expected-vendor-id",
           "0",
           "--expected-device-id",
-          "0",
-          "--device=fvdl"
+          "0"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -28736,7 +28550,6 @@
           "--passthrough",
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--device=fvdl",
           "--git-revision=${got_revision}"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
@@ -28775,8 +28588,7 @@
           "--browser=web-engine-shell",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_higher_performance_gpu --use-cmd-decoder=validating",
-          "--device=fvdl"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --force_higher_performance_gpu --use-cmd-decoder=validating"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -28810,7 +28622,6 @@
           "--passthrough",
           "-v",
           "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--device=fvdl",
           "--git-revision=${got_revision}"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
@@ -28849,8 +28660,7 @@
           "--browser=web-engine-shell",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--device=fvdl"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -28883,8 +28693,7 @@
           "--browser=web-engine-shell",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--device=fvdl"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -28917,8 +28726,7 @@
           "--browser=web-engine-shell",
           "--passthrough",
           "-v",
-          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc",
-          "--device=fvdl"
+          "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc"
         ],
         "isolate_name": "fuchsia_telemetry_gpu_integration_test",
         "merge": {
@@ -83613,7 +83421,7 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "isolate_profile_data": true,
@@ -83621,14 +83429,14 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -83663,7 +83471,7 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "isolate_profile_data": true,
@@ -83671,14 +83479,14 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -83705,7 +83513,7 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "isolate_profile_data": true,
@@ -83713,14 +83521,14 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -83755,7 +83563,7 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "isolate_profile_data": true,
@@ -83763,14 +83571,14 @@
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -85079,21 +84887,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "dimension_sets": [
@@ -85139,21 +84947,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "dimension_sets": [
@@ -85191,21 +84999,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "dimension_sets": [
@@ -85251,21 +85059,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "dimension_sets": [
@@ -86746,21 +86554,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "dimension_sets": [
@@ -86806,21 +86614,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "dimension_sets": [
@@ -86858,21 +86666,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "dimension_sets": [
@@ -86918,21 +86726,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "dimension_sets": [
@@ -87603,21 +87411,21 @@
     "gtest_tests": [
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v93.0.4577.85/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v93.0.4577.95/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 93.0.4577.85",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 93.0.4577.95",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v93.0.4577.85",
-              "revision": "version:93.0.4577.85"
+              "location": "lacros_version_skew_tests_v93.0.4577.95",
+              "revision": "version:93.0.4577.95"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -87627,21 +87435,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -87675,21 +87483,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -87699,21 +87507,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v93.0.4577.85/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v93.0.4577.95/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 93.0.4577.85",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 93.0.4577.95",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v93.0.4577.85",
-              "revision": "version:93.0.4577.85"
+              "location": "lacros_version_skew_tests_v93.0.4577.95",
+              "revision": "version:93.0.4577.95"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -87723,21 +87531,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.50",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 94.0.4606.58",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v94.0.4606.50",
-              "revision": "version:94.0.4606.50"
+              "location": "lacros_version_skew_tests_v94.0.4606.58",
+              "revision": "version:94.0.4606.58"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -87771,21 +87579,21 @@
       },
       {
         "args": [
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome",
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter"
         ],
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
-        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4652.0",
+        "name": "lacros_chrome_browsertests_run_in_series_Lacros version skew testing ash 96.0.4653.0",
         "swarming": {
           "can_use_on_swarming_builders": true,
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v96.0.4652.0",
-              "revision": "version:96.0.4652.0"
+              "location": "lacros_version_skew_tests_v96.0.4653.0",
+              "revision": "version:96.0.4653.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/testing/buildbot/chromium.json b/testing/buildbot/chromium.json
index 78fa9ef..b624855 100644
--- a/testing/buildbot/chromium.json
+++ b/testing/buildbot/chromium.json
@@ -32,6 +32,12 @@
     ],
     "scripts": []
   },
+  "linux-archive-tagged": {
+    "additional_compile_targets": [
+      "all"
+    ],
+    "scripts": []
+  },
   "linux-official": {
     "additional_compile_targets": [
       "all"
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index 86e606b..9220825 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -426,14 +426,7 @@
         '--device=aemu',
       ],
     },
-  },
-  'fuchsia-fvdl': {
-    '$mixin_append': {
-      'args': [
-        '--device=fvdl',
-      ],
-    },
-  },
+  }, 
   'fuchsia_logs': {
     '$mixin_append': {
       'args': [
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl
index 4407ebbf0..c90b42f 100644
--- a/testing/buildbot/test_suite_exceptions.pyl
+++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -802,6 +802,7 @@
     'remove_from': [
       'linux-archive-dbg',
       'linux-archive-rel',
+      'linux-archive-tagged',
       'mac-archive-dbg',
       'mac-archive-rel',
       'mac-arm64-archive-dbg',
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 45143ae0..28adaea 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -52,16 +52,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4652.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v96.0.4653.0/test_ash_chrome',
       '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter',
     ],
-    'identifier': 'Lacros version skew testing ash 96.0.4652.0',
+    'identifier': 'Lacros version skew testing ash 96.0.4653.0',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v96.0.4652.0',
-          'revision': 'version:96.0.4652.0',
+          'location': 'lacros_version_skew_tests_v96.0.4653.0',
+          'revision': 'version:96.0.4653.0',
         },
       ],
     },
@@ -84,32 +84,32 @@
   },
   'LACROS_VERSION_SKEW_BETA': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.50/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v94.0.4606.58/test_ash_chrome',
       '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter',
     ],
-    'identifier': 'Lacros version skew testing ash 94.0.4606.50',
+    'identifier': 'Lacros version skew testing ash 94.0.4606.58',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v94.0.4606.50',
-          'revision': 'version:94.0.4606.50',
+          'location': 'lacros_version_skew_tests_v94.0.4606.58',
+          'revision': 'version:94.0.4606.58',
         },
       ],
     },
   },
   'LACROS_VERSION_SKEW_STABLE': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v93.0.4577.85/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v93.0.4577.95/test_ash_chrome',
       '--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter',
     ],
-    'identifier': 'Lacros version skew testing ash 93.0.4577.85',
+    'identifier': 'Lacros version skew testing ash 93.0.4577.95',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v93.0.4577.85',
-          'revision': 'version:93.0.4577.85',
+          'location': 'lacros_version_skew_tests_v93.0.4577.95',
+          'revision': 'version:93.0.4577.95',
         },
       ],
     },
@@ -387,7 +387,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M95',
-          'revision': 'version:95.0.4638.24',
+          'revision': 'version:95.0.4638.25',
         }
       ],
     },
@@ -411,7 +411,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M94',
-          'revision': 'version:94.0.4606.63',
+          'revision': 'version:94.0.4606.64',
         }
       ],
     },
@@ -459,7 +459,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M95',
-          'revision': 'version:95.0.4638.24',
+          'revision': 'version:95.0.4638.25',
         }
       ],
     },
@@ -483,7 +483,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M94',
-          'revision': 'version:94.0.4606.63',
+          'revision': 'version:94.0.4606.64',
         }
       ],
     },
@@ -531,7 +531,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M95',
-          'revision': 'version:95.0.4638.24',
+          'revision': 'version:95.0.4638.25',
         }
       ],
     },
@@ -555,7 +555,7 @@
         {
           'cipd_package': 'chromium/testing/weblayer-x86',
           'location': 'weblayer_instrumentation_test_M94',
-          'revision': 'version:94.0.4606.63',
+          'revision': 'version:94.0.4606.64',
         }
       ],
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index fa9f4b4..887f539d 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -263,6 +263,17 @@
           'scripts': 'public_build_scripts',
         },
       },
+      'linux-archive-tagged': {
+        'mixins': [
+          'linux-archive-rel-args',
+        ],
+        'additional_compile_targets': [
+          'all',
+        ],
+        'test_suites': {
+          'scripts': 'public_build_scripts',
+        },
+      },
       'linux-official': {
         'additional_compile_targets': [
           'all',
@@ -2881,7 +2892,6 @@
           'all',
         ],
         'mixins': [
-          'fuchsia-fvdl',
           'linux-bionic',
         ],
         'swarming': {
@@ -2903,7 +2913,6 @@
         'browser_config': 'web-engine-shell',
         'os_type': 'linux',
         'mixins': [
-          'fuchsia-fvdl',
           'linux-bionic',
         ],
         'swarming': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index b637b5d..be5da9b 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1217,6 +1217,46 @@
             ]
         }
     ],
+    "AutofillSurveys": [
+        {
+            "platforms": [
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Card",
+                    "params": {
+                        "en_site_id": "F2fsskHvB0ugnJ3q1cK0NXLjUaK5",
+                        "probability": "1.0"
+                    },
+                    "enable_features": [
+                        "AutofillCardSurvey"
+                    ]
+                },
+                {
+                    "name": "Password",
+                    "params": {
+                        "en_site_id": "6VQ4NCCaq0ugnJ3q1cK0TR13rB8t",
+                        "probability": "1.0"
+                    },
+                    "enable_features": [
+                        "AutofillPasswordSurvey"
+                    ]
+                },
+                {
+                    "name": "Address",
+                    "params": {
+                        "en_site_id": "qQW9c2ho10ugnJ3q1cK0X48UQjZs",
+                        "probability": "1.0"
+                    },
+                    "enable_features": [
+                        "AutofillAddressSurvey"
+                    ]
+                }
+            ]
+        }
+    ],
     "AutofillUseOnlyFormRendererIDForOldDuplicateFormRemoval": [
         {
             "platforms": [
@@ -4388,33 +4428,6 @@
             ]
         }
     ],
-    "InterestFeedContentSuggestions": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "EnabledUndoableActions",
-                    "params": {
-                        "card_menu_tooltip_eligible": "true",
-                        "default_action_ttl_seconds": "90000",
-                        "feed_ui_enabled": "true",
-                        "init_feed_after_startup": "false",
-                        "manage_interests_enabled": "true",
-                        "snippets_enabled": "true",
-                        "spinner_delay": "500",
-                        "spinner_minimum_show_time": "0",
-                        "storage_miss_threshold": "100",
-                        "undoable_actions_enabled": "true"
-                    },
-                    "enable_features": [
-                        "InterestFeedContentSuggestions"
-                    ]
-                }
-            ]
-        }
-    ],
     "IsolatePasswordSites": [
         {
             "platforms": [
@@ -7400,6 +7413,29 @@
             ]
         }
     ],
+    "SharingHubDesktop": [
+        {
+            "platforms": [
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "EnabledOmnibox",
+                    "enable_features": [
+                        "SharingHubDesktopOmnibox"
+                    ]
+                },
+                {
+                    "name": "EnabledAppMenu",
+                    "enable_features": [
+                        "SharingHubDesktopAppMenu"
+                    ]
+                }
+            ]
+        }
+    ],
     "SharingHubLinkToggle": [
         {
             "platforms": [
diff --git a/third_party/.gitignore b/third_party/.gitignore
index e496483..0115415a 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -54,7 +54,9 @@
 /byte_buddy/android_sdk_build_tools_25_0_2
 /byte_buddy/lib/
 /cardboard-java/src
+/cast_core/prebuilts
 /cast_core/public/src
+/cast_web_runtime
 /catapult
 /ced/src
 /checkstyle/*.jar
diff --git a/third_party/android_support_test_runner/README.chromium b/third_party/android_support_test_runner/README.chromium
index d6cb4129..2172f98 100644
--- a/third_party/android_support_test_runner/README.chromium
+++ b/third_party/android_support_test_runner/README.chromium
@@ -15,3 +15,4 @@
 
 Local Modifications:
 - Imports were automatically sorted (annoying to avoid this, and shouldn't have any impact)
+- https:/crbug.com/1252584 Shorter log when JavaScriptBridge not found.
diff --git a/third_party/android_support_test_runner/runner/src/main/java/android/support/test/runner/MonitoringInstrumentation.java b/third_party/android_support_test_runner/runner/src/main/java/android/support/test/runner/MonitoringInstrumentation.java
index b8a9d7c..00b34c35 100644
--- a/third_party/android_support_test_runner/runner/src/main/java/android/support/test/runner/MonitoringInstrumentation.java
+++ b/third_party/android_support_test_runner/runner/src/main/java/android/support/test/runner/MonitoringInstrumentation.java
@@ -651,7 +651,7 @@
             Method install = jsBridge.getDeclaredMethod("installBridge");
             install.invoke(null);
         } catch (ClassNotFoundException ignored) {
-            Log.i(LOG_TAG, "No JSBridge.", ignored);
+            Log.i(LOG_TAG, "Espresso Web not found.");
         } catch (NoSuchMethodException nsme) {
             Log.i(LOG_TAG, "No JSBridge.", nsme);
         } catch (InvocationTargetException ite) {
diff --git a/third_party/blink/public/public_features.gni b/third_party/blink/public/public_features.gni
index b5cc81d..da83b8e 100644
--- a/third_party/blink/public/public_features.gni
+++ b/third_party/blink/public/public_features.gni
@@ -10,9 +10,6 @@
 
   # Enables young generation collections in Oilpan.
   enable_blink_heap_young_generation = false
-
-  # Enables Blink's heap to use V8's version of Oilpan.
-  enable_blink_heap_use_v8_oilpan = true
 }
 
 declare_args() {
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc b/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
index 25628294..5d94478 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc
@@ -4,691 +4,9 @@
 
 #include "third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.h"
 
-#include <memory>
-#include <sstream>
-#include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
-#include "third_party/blink/renderer/bindings/core/v8/v8_node.h"
-#include "third_party/blink/renderer/core/execution_context/execution_context.h"
-#include "third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
-#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
-#include "third_party/blink/renderer/platform/heap/unified_heap_controller.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
-
 namespace blink {
 void EmbedderGraphBuilder::BuildEmbedderGraphCallback(v8::Isolate* isolate,
                                                       v8::EmbedderGraph* graph,
                                                       void*) {}
 }  // namespace blink
 
-#else  // !USE_V8_OILPAN
-
-namespace blink {
-
-namespace {
-
-using Traceable = const void*;
-using Graph = v8::EmbedderGraph;
-using Detachedness = v8::EmbedderGraph::Node::Detachedness;
-
-class EmbedderNode : public Graph::Node {
- public:
-  EmbedderNode(const char* name,
-               Graph::Node* wrapper,
-               Detachedness detachedness)
-      : name_(name), wrapper_(wrapper), detachedness_(detachedness) {}
-
-  // Graph::Node overrides.
-  const char* Name() override { return name_; }
-  size_t SizeInBytes() override { return 0; }
-  Graph::Node* WrapperNode() override { return wrapper_; }
-  Detachedness GetDetachedness() override { return detachedness_; }
-
-  void AddEdgeName(std::unique_ptr<char[]> edge_name) {
-    edge_names_.push_back(std::move(edge_name));
-  }
-
- private:
-  const char* name_;
-  Graph::Node* wrapper_;
-  const Detachedness detachedness_;
-  // V8's API uses raw strings for edge names and expect the underlying memory
-  // to be retained until the end of graph building where strings are copied
-  // into its internal storage. The following vector retains those edge names
-  // until a node is freed which is at the end of graph building.
-  Vector<std::unique_ptr<char[]>> edge_names_;
-};
-
-class EmbedderRootNode : public EmbedderNode {
- public:
-  explicit EmbedderRootNode(const char* name)
-      : EmbedderNode(name, nullptr, Detachedness::kUnknown) {}
-  // Graph::Node override.
-  bool IsRootNode() override { return true; }
-};
-
-class NodeBuilder final {
-  USING_FAST_MALLOC(NodeBuilder);
-
- public:
-  explicit NodeBuilder(Graph* graph) : graph_(graph) {}
-
-  Graph::Node* GraphNode(const v8::Local<v8::Value>&);
-  EmbedderNode* GraphNode(Traceable,
-                          const char* name,
-                          Graph::Node* wrapper,
-                          Detachedness);
-  bool Contains(Traceable traceable) const {
-    return graph_nodes_.Contains(traceable);
-  }
-
- private:
-  Graph* const graph_;
-  HashMap<Traceable, EmbedderNode*> graph_nodes_;
-};
-
-v8::EmbedderGraph::Node* NodeBuilder::GraphNode(
-    const v8::Local<v8::Value>& value) {
-  return graph_->V8Node(value);
-}
-
-EmbedderNode* NodeBuilder::GraphNode(Traceable traceable,
-                                     const char* name,
-                                     v8::EmbedderGraph::Node* wrapper,
-                                     Detachedness detachedness) {
-  auto iter = graph_nodes_.find(traceable);
-  if (iter != graph_nodes_.end()) {
-    return iter->value;
-  }
-  // Ownership of the new node is transferred to the graph_.
-  // graph_node_.at(tracable) is valid for all BuildEmbedderGraph execution.
-  auto* raw_node = new EmbedderNode(name, wrapper, detachedness);
-  EmbedderNode* node = static_cast<EmbedderNode*>(
-      graph_->AddNode(std::unique_ptr<Graph::Node>(raw_node)));
-  graph_nodes_.insert(traceable, node);
-  return node;
-}
-
-// V8EmbedderGraphBuilder is used to build heap snapshots of Blink's managed
-// object graph. On a high level, the following operations are performed:
-// - Node objects are classified as attached, detached, or unknown.
-// - Depending an implicit mode, objects are classified as relevant or internal.
-//   This classification happens based on NameTrait and the fact that all
-//   ScriptWrappable objects (those that can have JS properties) are using that
-//   trait.
-// - Not relevant objects are filtered where possible, e.g., sub graphs of
-//   internals are filtered and not reported.
-//
-// The algorithm performs a single pass on the graph, starting from V8-to-Blink
-// references that identify attached nodes. Each object then starts a recursion
-// into its own subgraph to identify and filter subgraphs that only consist of
-// internals. Roots, which are potentially Blink only, are transitively
-// traversed after handling JavaScript related objects.
-class V8EmbedderGraphBuilder
-    : public Visitor,
-      public v8::PersistentHandleVisitor,
-      public v8::EmbedderHeapTracer::TracedGlobalHandleVisitor {
- public:
-  V8EmbedderGraphBuilder(v8::Isolate*, Graph*, NodeBuilder*);
-  ~V8EmbedderGraphBuilder() override;
-
-  void BuildEmbedderGraph();
-
-  // v8::PersistentHandleVisitor override.
-  void VisitPersistentHandle(v8::Persistent<v8::Value>*,
-                             uint16_t class_id) override;
-
-  // v8::EmbedderHeapTracer::TracedGlobalHandleVisitor override.
-  void VisitTracedReference(
-      const v8::TracedReference<v8::Value>& value) override;
-  void VisitTracedGlobalHandle(const v8::TracedGlobal<v8::Value>&) override;
-
-  // Visitor overrides.
-  void VisitRoot(const void*, TraceDescriptor, const base::Location&) final;
-  void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
-  void Visit(const void*, TraceDescriptor) final;
-  void VisitEphemeron(const void*, TraceDescriptor) final;
-  void VisitWeakContainer(const void*,
-                          const void* const*,
-                          TraceDescriptor,
-                          TraceDescriptor,
-                          WeakCallback,
-                          const void*) final;
-
- private:
-  class ParentScope {
-    STACK_ALLOCATED();
-
-   public:
-    ParentScope(V8EmbedderGraphBuilder* visitor, Traceable traceable)
-        : visitor_(visitor), old_parent_(visitor->current_parent_) {
-      visitor->current_parent_ = traceable;
-    }
-    ~ParentScope() { visitor_->current_parent_ = old_parent_; }
-
-    ParentScope(const ParentScope&) = delete;
-    ParentScope& operator=(const ParentScope&) = delete;
-
-   private:
-    V8EmbedderGraphBuilder* const visitor_;
-    Traceable old_parent_;
-  };
-
-  class State final {
-    USING_FAST_MALLOC(State);
-
-   public:
-    State(Traceable traceable, const char* name, Detachedness detachedness)
-        : traceable_(traceable), name_(name) {}
-    explicit State(EmbedderNode* node) : node_(node) {}
-
-    bool IsVisited() const { return visited_; }
-    void MarkVisited() { visited_ = true; }
-
-    bool IsPending() const { return pending_; }
-    void MarkPending() { pending_ = true; }
-    void UnmarkPending() { pending_ = false; }
-
-    bool HasNode() const { return node_; }
-    EmbedderNode* GetOrCreateNode(NodeBuilder* builder) {
-      if (!node_) {
-        DCHECK(name_);
-        node_ = builder->GraphNode(traceable_, name_, nullptr,
-                                   Detachedness::kUnknown);
-      }
-      return node_;
-    }
-
-    void AddEdgeName(State* destination, std::string edge_name) {
-      auto result = named_edges_.insert(destination, std::move(edge_name));
-      DCHECK(result.is_new_entry);
-    }
-
-    void AddRootEdgeName(State* destination, std::string edge_name) {
-      // State may represent root groups in which case there may exist multiple
-      // references to the same |destination|.
-      named_edges_.insert(destination, std::move(edge_name));
-    }
-
-    std::string EdgeName(State* destination) {
-      auto it = named_edges_.find(destination);
-      if (it != named_edges_.end())
-        return it->value;
-      return std::string();
-    }
-
-   private:
-    EmbedderNode* node_ = nullptr;
-    Traceable traceable_ = nullptr;
-    const char* name_ = nullptr;
-    HashMap<State* /*destination*/, std::string> named_edges_;
-    bool visited_ = false;
-    bool pending_ = false;
-  };
-
-  // WorklistItemBase is used for different kinds of items that require
-  // processing the regular worklist.
-  class WorklistItemBase {
-    USING_FAST_MALLOC(WorklistItemBase);
-
-   public:
-    explicit WorklistItemBase(State* parent, State* to_process)
-        : parent_(parent), to_process_(to_process) {}
-    virtual ~WorklistItemBase() = default;
-    virtual void Process(V8EmbedderGraphBuilder*) = 0;
-
-    State* to_process() const { return to_process_; }
-    State* parent() const { return parent_; }
-
-   private:
-    State* const parent_;
-    State* const to_process_;
-  };
-
-  // A VisitationItem processes a given object and visits all its children.
-  class VisitationItem final : public WorklistItemBase {
-   public:
-    VisitationItem(State* parent,
-                   State* to_process,
-                   Traceable traceable,
-                   TraceCallback trace_callback)
-        : WorklistItemBase(parent, to_process),
-          traceable_(traceable),
-          trace_callback_(trace_callback) {}
-
-    void Process(V8EmbedderGraphBuilder* builder) final {
-      // Post-order traversal as parent needs the full information on child.
-      builder->worklist_.push_back(std::unique_ptr<WorklistItemBase>{
-          new VisitationDoneItem(parent(), to_process())});
-      to_process()->MarkPending();
-      DCHECK(to_process()->IsPending());
-      DCHECK(to_process()->IsVisited());
-      ParentScope parent_scope(builder, traceable_);
-      trace_callback_(builder, const_cast<void*>(traceable_));
-    }
-
-   private:
-    Traceable traceable_;
-    TraceCallback trace_callback_;
-  };
-
-  // A VisitationDoneItem unmarks the pending state of an object and creates
-  // an edge from a parent in case there is one.
-  class VisitationDoneItem final : public WorklistItemBase {
-   public:
-    VisitationDoneItem(State* parent, State* to_process)
-        : WorklistItemBase(parent, to_process) {}
-
-    void Process(V8EmbedderGraphBuilder* builder) final {
-      if (parent() && to_process()->HasNode()) {
-        builder->AddEdge(parent(), to_process());
-      }
-      to_process()->UnmarkPending();
-    }
-  };
-
-  class EphemeronItem final {
-   public:
-    EphemeronItem(Traceable backing,
-                  Traceable key,
-                  Traceable value,
-                  TraceCallback value_tracing_callback)
-        : backing_(backing),
-          key_(key),
-          value_(value),
-          value_tracing_callback_(value_tracing_callback) {}
-
-    bool Process(V8EmbedderGraphBuilder* builder) {
-      if (!key_) {
-        // Don't trace the value if the key is nullptr.
-        return true;
-      }
-      if (!builder->StateExists(key_))
-        return false;
-      {
-        ParentScope scope(builder, key_);
-        builder->current_ephemeron_backing_ = backing_;
-        value_tracing_callback_(builder, const_cast<void*>(value_));
-        builder->current_ephemeron_backing_ = nullptr;
-      }
-      return true;
-    }
-
-   private:
-    Traceable backing_;
-    Traceable key_;
-    Traceable value_;
-    TraceCallback value_tracing_callback_;
-  };
-
-  State* GetOrCreateState(Traceable traceable,
-                          const char* name,
-                          Detachedness detachedness) {
-    if (!states_.Contains(traceable)) {
-      states_.insert(traceable, new State(traceable, name, detachedness));
-    }
-    return states_.at(traceable);
-  }
-
-  bool StateExists(Traceable traceable) const {
-    return states_.Contains(traceable);
-  }
-
-  State* GetStateNotNull(Traceable traceable) {
-    CHECK(states_.Contains(traceable));
-    return states_.at(traceable);
-  }
-
-  State* EnsureState(Traceable traceable, EmbedderNode* node) {
-    if (!states_.Contains(traceable)) {
-      states_.insert(traceable, new State(node));
-    }
-    return states_.at(traceable);
-  }
-
-  void EnsureRootState(EmbedderNode* node) {
-    CHECK(!states_.Contains(node));
-    states_.insert(node, new State(node));
-  }
-
-  void AddEdge(State*, State*);
-  void AddEphemeronEdgeName(Traceable backing, State* parent, State* current);
-
-  void VisitPersistentHandleInternal(v8::Local<v8::Object>, uint16_t);
-  void VisitBlinkRoots();
-  void VisitTransitiveClosure();
-
-  // Push a VisitatonItem to the main worklist in case the State has not been
-  // already visited.
-  void CreateAndPushVisitationItem(State* parent,
-                                   State* to_process,
-                                   Traceable traceable,
-                                   TraceCallback trace_callback) {
-    DCHECK(!to_process->IsVisited());
-    to_process->MarkVisited();
-    worklist_.push_back(std::unique_ptr<WorklistItemBase>{
-        new VisitationItem(parent, to_process, traceable, trace_callback)});
-  }
-
-  void PushVisitationItem(std::unique_ptr<VisitationItem> item) {
-    if (!item->to_process()->IsVisited()) {
-      item->to_process()->MarkVisited();
-      worklist_.push_back(std::move(item));
-    }
-  }
-
-  v8::Isolate* const isolate_;
-  Graph* const graph_;
-  NodeBuilder* const node_builder_;
-
-  Traceable current_parent_ = nullptr;
-  Traceable current_ephemeron_backing_ = nullptr;
-  HashMap<Traceable, State*> states_;
-  // Worklist that is used to visit transitive closure.
-  Deque<std::unique_ptr<WorklistItemBase>> worklist_;
-  // The worklist that collects Ephemeron entries for later processing.
-  Deque<std::unique_ptr<EphemeronItem>> ephemeron_worklist_;
-};
-
-V8EmbedderGraphBuilder::V8EmbedderGraphBuilder(v8::Isolate* isolate,
-                                               Graph* graph,
-                                               NodeBuilder* node_builder)
-    : Visitor(ThreadState::Current()),
-      isolate_(isolate),
-      graph_(graph),
-      node_builder_(node_builder) {
-  CHECK(isolate);
-  CHECK(graph);
-  CHECK_EQ(isolate, ThreadState::Current()->GetIsolate());
-}
-
-V8EmbedderGraphBuilder::~V8EmbedderGraphBuilder() {
-  for (const auto& kvp : states_) {
-    delete kvp.value;
-  }
-}
-
-void V8EmbedderGraphBuilder::BuildEmbedderGraph() {
-  isolate_->VisitHandlesWithClassIds(this);
-  v8::EmbedderHeapTracer* const tracer = static_cast<v8::EmbedderHeapTracer*>(
-      ThreadState::Current()->unified_heap_controller());
-  tracer->IterateTracedGlobalHandles(this);
-  VisitBlinkRoots();
-  VisitTransitiveClosure();
-  DCHECK(worklist_.empty());
-  // ephemeron_worklist_ might not be empty. We might have an ephemeron whose
-  // key is alive but was never observed by the snapshot (e.g. objects pointed
-  // to by the stack). Such entries will remain in the worklist.
-  //
-  // TODO(omerkatz): add DCHECK(ephemeron_worklist_.empty()) when heap snapshot
-  // covers all live objects.
-}
-
-void V8EmbedderGraphBuilder::VisitPersistentHandleInternal(
-    v8::Local<v8::Object> v8_value,
-    uint16_t class_id) {
-  const ScriptWrappable* traceable = ToScriptWrappable(v8_value);
-  if (!traceable)
-    return;
-  Graph::Node* wrapper = node_builder_->GraphNode(v8_value);
-  auto detachedness = V8GCController::DetachednessFromWrapper(
-      isolate_, v8_value.As<v8::Value>(), class_id, nullptr);
-  EmbedderNode* graph_node = node_builder_->GraphNode(
-      traceable, traceable->NameInHeapSnapshot(), wrapper, detachedness);
-  State* const to_process_state = EnsureState(traceable, graph_node);
-  if (to_process_state->IsVisited()) {
-    return;
-  }
-  const TraceDescriptor& descriptor =
-      TraceDescriptorFor<ScriptWrappable>(traceable);
-  CreateAndPushVisitationItem(nullptr, to_process_state, traceable,
-                              descriptor.callback);
-}
-
-void V8EmbedderGraphBuilder::VisitTracedReference(
-    const v8::TracedReference<v8::Value>& value) {
-  const uint16_t class_id = value.WrapperClassId();
-  if (class_id != WrapperTypeInfo::kNodeClassId &&
-      class_id != WrapperTypeInfo::kObjectClassId)
-    return;
-  VisitPersistentHandleInternal(value.As<v8::Object>().Get(isolate_), class_id);
-}
-
-void V8EmbedderGraphBuilder::VisitTracedGlobalHandle(
-    const v8::TracedGlobal<v8::Value>&) {
-  CHECK(false) << "Blink does not use v8::TracedGlobal.";
-}
-
-void V8EmbedderGraphBuilder::VisitPersistentHandle(
-    v8::Persistent<v8::Value>* value,
-    uint16_t class_id) {
-  if (class_id != WrapperTypeInfo::kNodeClassId &&
-      class_id != WrapperTypeInfo::kObjectClassId)
-    return;
-  v8::Local<v8::Object> v8_value = v8::Local<v8::Object>::New(
-      isolate_, v8::Persistent<v8::Object>::Cast(*value));
-  VisitPersistentHandleInternal(v8_value, class_id);
-}
-
-void V8EmbedderGraphBuilder::Visit(
-    const TraceWrapperV8Reference<v8::Value>& traced_wrapper) {
-  // Add an edge from the current parent to the V8 object.
-  v8::Local<v8::Value> v8_value = traced_wrapper.NewLocal(isolate_);
-  if (!v8_value.IsEmpty()) {
-    State* parent = GetStateNotNull(current_parent_);
-    graph_->AddEdge(parent->GetOrCreateNode(node_builder_),
-                    node_builder_->GraphNode(v8_value));
-  }
-}
-
-void V8EmbedderGraphBuilder::VisitRoot(const void* object,
-                                       TraceDescriptor wrapper_descriptor,
-                                       const base::Location& location) {
-  // Extract edge name if |location| is set.
-  if (location.has_source_info()) {
-    const void* traceable = wrapper_descriptor.base_object_payload;
-    State* const parent = GetStateNotNull(current_parent_);
-    State* const current = GetOrCreateState(
-        traceable, HeapObjectHeader::FromPayload(traceable)->Name(),
-        Detachedness::kUnknown);
-    parent->AddRootEdgeName(current, location.ToString());
-  }
-  Visit(object, wrapper_descriptor);
-}
-
-void V8EmbedderGraphBuilder::AddEphemeronEdgeName(Traceable backing,
-                                                  State* parent,
-                                                  State* current) {
-  const GCInfo& backing_info = GCInfo::From(
-      HeapObjectHeader::FromPayload(current_ephemeron_backing_)->GcInfoIndex());
-  HeapObjectName backing_name = backing_info.name(current_ephemeron_backing_);
-  std::stringstream ss;
-  ss << "part of key -> value pair in ephemeron table";
-  if (!backing_name.name_is_hidden) {
-    const std::string backing_name_str(backing_name.value);
-    const auto kvp_pos = backing_name_str.find("WTF::KeyValuePair");
-    // Ephemerons are defined through WTF::KeyValuePair.
-    CHECK_NE(std::string::npos, kvp_pos);
-    // Extracting the pair TYPE from for WTF::KeyValuePair<TYPE>.
-    ss << " (<";
-    size_t current_pos = kvp_pos + sizeof("WTF::KeyValuePair");
-    CHECK_EQ('<', backing_name_str[current_pos - 1]);
-    size_t nesting = 0;
-    while (backing_name_str[current_pos] != '>' || (nesting > 0)) {
-      if (backing_name_str[current_pos] == '<')
-        nesting++;
-      if (backing_name_str[current_pos] == '>')
-        nesting--;
-      ss << backing_name_str[current_pos];
-      current_pos++;
-    }
-    ss << ">)";
-  }
-  parent->AddEdgeName(current, ss.str());
-}
-
-void V8EmbedderGraphBuilder::Visit(const void* object,
-                                   TraceDescriptor wrapper_descriptor) {
-  const void* traceable = wrapper_descriptor.base_object_payload;
-  const GCInfo& info =
-      GCInfo::From(HeapObjectHeader::FromPayload(traceable)->GcInfoIndex());
-  HeapObjectName name = info.name(traceable);
-
-  State* const parent = GetStateNotNull(current_parent_);
-  State* const current =
-      GetOrCreateState(traceable, name.value, Detachedness::kUnknown);
-  if (current_ephemeron_backing_) {
-    // Just records an edge name in case the state gets later on materialized.
-    AddEphemeronEdgeName(current_ephemeron_backing_, parent, current);
-  }
-  if (current->IsPending()) {
-    if (parent->HasNode()) {
-      // Backedge in currently processed graph.
-      AddEdge(parent, current);
-    }
-    return;
-  }
-
-  // Immediately materialize the node if it is not hidden.
-  if (!name.name_is_hidden) {
-    current->GetOrCreateNode(node_builder_);
-  }
-
-  if (!current->IsVisited()) {
-    CreateAndPushVisitationItem(parent, current, traceable, info.trace);
-  } else {
-    // Edge into an already processed subgraph.
-    if (current->HasNode()) {
-      // Create an edge in case the current node has already been visited.
-      AddEdge(parent, current);
-    }
-  }
-}
-
-void V8EmbedderGraphBuilder::AddEdge(State* parent, State* current) {
-  EmbedderNode* parent_node = parent->GetOrCreateNode(node_builder_);
-  EmbedderNode* current_node = current->GetOrCreateNode(node_builder_);
-  if (!parent->EdgeName(current).empty()) {
-    std::string edge_name = parent->EdgeName(current);
-    // V8's API is based on raw C strings. Allocate and temporarily keep the
-    // edge name alive from the corresponding node.
-    const size_t len = edge_name.length();
-    auto holder = std::make_unique<char[]>(len + 1);
-    strncpy(holder.get(), edge_name.c_str(), len);
-    holder[len] = 0;
-    graph_->AddEdge(parent_node, current_node, holder.get());
-    parent_node->AddEdgeName(std::move(holder));
-    return;
-  }
-  graph_->AddEdge(parent_node, current_node);
-}
-
-void V8EmbedderGraphBuilder::VisitWeakContainer(
-    const void* object,
-    const void* const* slot,
-    TraceDescriptor strong_desc,
-    TraceDescriptor ephemeron_iteration,
-    WeakCallback weak_callback,
-    const void* weak_callback_parameter) {
-  // Only ephemerons have weak callbacks.
-  if (ephemeron_iteration.callback) {
-    // Heap snapshot is always run after a GC so we know there are no dead
-    // entries in the backing store. Using the weak descriptor here ensures that
-    // the key is not held alive from the backing store but rather from the
-    // object. A named edge ensures that we make the fact that value was held
-    // alive via ephemeron visible.
-    if (object) {
-      ParentScope parent(this, ephemeron_iteration.base_object_payload);
-      ephemeron_iteration.callback(this,
-                                   ephemeron_iteration.base_object_payload);
-    }
-  }
-}
-
-void V8EmbedderGraphBuilder::VisitEphemeron(
-    const void* key,
-    TraceDescriptor value_trace_descriptor) {
-  // During regular visitation of ephemerons, current_parent_ refers to the
-  // backing store.
-  ephemeron_worklist_.push_back(std::make_unique<EphemeronItem>(
-      current_parent_, key, value_trace_descriptor.base_object_payload,
-      value_trace_descriptor.callback));
-}
-
-void V8EmbedderGraphBuilder::VisitBlinkRoots() {
-  {
-    EmbedderNode* root = static_cast<EmbedderNode*>(graph_->AddNode(
-        std::unique_ptr<Graph::Node>(new EmbedderRootNode("Blink roots"))));
-    EnsureRootState(root);
-    ParentScope parent(this, root);
-    ThreadState::Current()->GetPersistentRegion()->TraceNodes(this);
-  }
-  {
-    EmbedderNode* root =
-        static_cast<EmbedderNode*>(graph_->AddNode(std::unique_ptr<Graph::Node>(
-            new EmbedderRootNode("Blink cross-thread roots"))));
-    EnsureRootState(root);
-    ParentScope parent(this, root);
-    MutexLocker persistent_lock(ProcessHeap::CrossThreadPersistentMutex());
-    ProcessHeap::GetCrossThreadPersistentRegion().TraceNodes(this);
-  }
-}
-
-void V8EmbedderGraphBuilder::VisitTransitiveClosure() {
-  // The following loop process the worklist and ephemerons. Since regular
-  // tracing can record new ephemerons, and tracing an ephemeron can add
-  // items to the regular worklist, we need to repeatedly process the worklist
-  // until a fixed point is reached.
-
-  // Because snapshots are processed in stages, there may be ephemerons that
-  // where key's do not have yet a state associated with them which prohibits
-  // them from being processed. Such ephemerons are stashed for later
-  // processing.
-  bool processed_ephemerons;
-  do {
-    // Step 1: Go through all items in the worklist using depth-first search.
-    while (!worklist_.empty()) {
-      std::unique_ptr<WorklistItemBase> item = std::move(worklist_.back());
-      worklist_.pop_back();
-      item->Process(this);
-    }
-
-    // Step 2: Go through ephemeron items.
-    processed_ephemerons = false;
-    Deque<std::unique_ptr<EphemeronItem>> unprocessed_ephemerons_;
-    //  Only process an ephemeron item if its key was already observed.
-    while (!ephemeron_worklist_.empty()) {
-      std::unique_ptr<EphemeronItem> item =
-          std::move(ephemeron_worklist_.front());
-      ephemeron_worklist_.pop_front();
-      if (!item->Process(this)) {
-        unprocessed_ephemerons_.push_back(std::move(item));
-      } else {
-        processed_ephemerons = true;
-      }
-    }
-    ephemeron_worklist_.Swap(unprocessed_ephemerons_);
-  } while (!worklist_.empty() || processed_ephemerons);
-}
-
-}  // namespace
-
-void EmbedderGraphBuilder::BuildEmbedderGraphCallback(v8::Isolate* isolate,
-                                                      v8::EmbedderGraph* graph,
-                                                      void*) {
-  // Synchronize with concurrent sweepers before taking a snapshot.
-  ThreadState::Current()->CompleteSweep();
-
-  NodeBuilder node_builder(graph);
-  V8EmbedderGraphBuilder builder(isolate, graph, &node_builder);
-  builder.BuildEmbedderGraph();
-}
-
-}  // namespace blink
-
-#endif  // !USE_V8_OILPAN
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc b/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
index 69256e7..91dcbaaf 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc
@@ -52,7 +52,6 @@
 #include "third_party/blink/renderer/platform/instrumentation/histogram.h"
 #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
@@ -94,26 +93,10 @@
   return v8::EmbedderGraph::Node::Detachedness::kDetached;
 }
 
-#if !BUILDFLAG(USE_V8_OILPAN)
-namespace {
-bool IsNestedInV8GC(ThreadState* thread_state, v8::GCType type) {
-  return thread_state && (type == v8::kGCTypeMarkSweepCompact ||
-                          type == v8::kGCTypeIncrementalMarking);
-}
-}  // namespace
-#endif  // !USE_V8_OILPAN
-
 void V8GCController::GcPrologue(v8::Isolate* isolate,
                                 v8::GCType type,
                                 v8::GCCallbackFlags flags) {
   RUNTIME_CALL_TIMER_SCOPE(isolate, RuntimeCallStats::CounterId::kGcPrologue);
-#if !BUILDFLAG(USE_V8_OILPAN)
-  ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
-      IsNestedInV8GC(ThreadState::Current(), type)
-          ? ThreadState::Current()->Heap().stats_collector()
-          : nullptr);
-#endif  // !USE_V8_OILPAN
-
   auto* per_isolate_data = V8PerIsolateData::From(isolate);
   per_isolate_data->EnterGC();
 
@@ -152,12 +135,6 @@
                                 v8::GCType type,
                                 v8::GCCallbackFlags flags) {
   RUNTIME_CALL_TIMER_SCOPE(isolate, RuntimeCallStats::CounterId::kGcEpilogue);
-#if !BUILDFLAG(USE_V8_OILPAN)
-  ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
-      IsNestedInV8GC(ThreadState::Current(), type)
-          ? ThreadState::Current()->Heap().stats_collector()
-          : nullptr);
-#endif  // !USE_V8_OILPAN
 
   V8PerIsolateData::From(isolate)->LeaveGC();
 
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_metrics.cc b/third_party/blink/renderer/bindings/core/v8/v8_metrics.cc
index 3a1cf177..9f78bd5 100644
--- a/third_party/blink/renderer/bindings/core/v8/v8_metrics.cc
+++ b/third_party/blink/renderer/bindings/core/v8/v8_metrics.cc
@@ -85,7 +85,6 @@
 
 namespace {
 
-#if BUILDFLAG(USE_V8_OILPAN)
 // Helper function to convert a byte count to a KB count, capping at
 // INT_MAX if the number is larger than that.
 constexpr int32_t CappedSizeInKB(int64_t size_in_bytes) {
@@ -120,15 +119,12 @@
   DCHECK_NE(-1, event.main_thread_efficiency_cpp_in_bytes_per_us);
   DCHECK_NE(-1, event.collection_rate_cpp_in_percent);
 }
-#endif  // USE_V8_OILPAN
 
 }  // namespace
 
 void V8MetricsRecorder::AddMainThreadEvent(
     const v8::metrics::GarbageCollectionFullCycle& event,
     ContextId context_id) {
-#if BUILDFLAG(USE_V8_OILPAN)
-  // Cpp events should always be populated when building with USE_V8_OILPAN.
   CheckCppEvents(event);
   // Report throughput metrics:
   UMA_HISTOGRAM_TIMES("V8.GC.Cycle.Full.Cpp",
@@ -245,7 +241,6 @@
                       ("V8.GC.Cycle.CollectionRate.Full.Cpp", 0, 100, 20));
   collection_rate_histogram.Count(base::saturated_cast<base::Histogram::Sample>(
       100 * event.collection_rate_cpp_in_percent));
-#endif  // USE_V8_OILPAN
 }
 
 namespace {
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index cd75056..aa6c44f3 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -85,6 +85,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_playback_event_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_current_change_event_init.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_current_change_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_options.cc",
@@ -535,6 +537,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_timeline.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_current_change_event.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_current_change_event.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_destination.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_destination.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_entry.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni
index a5f17d79..73a3f24 100644
--- a/third_party/blink/renderer/bindings/idl_in_core.gni
+++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -37,6 +37,8 @@
           "//third_party/blink/renderer/core/app_history/app_history.idl",
           "//third_party/blink/renderer/core/app_history/app_history_destination.idl",
           "//third_party/blink/renderer/core/app_history/app_history_entry.idl",
+          "//third_party/blink/renderer/core/app_history/app_history_current_change_event.idl",
+          "//third_party/blink/renderer/core/app_history/app_history_current_change_event_init.idl",
           "//third_party/blink/renderer/core/app_history/app_history_navigate_event.idl",
           "//third_party/blink/renderer/core/app_history/app_history_navigate_event_init.idl",
           "//third_party/blink/renderer/core/app_history/app_history_navigate_options.idl",
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index ae36d9d..8d33ed0 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -462,6 +462,7 @@
 
 generate_event_interfaces("core_event_interfaces") {
   sources = [
+    "app_history/app_history_current_change_event.idl",
     "app_history/app_history_navigate_event.idl",
     "css/font_face_set_load_event.idl",
     "css/media_query_list_event.idl",
diff --git a/third_party/blink/renderer/core/app_history/app_history.cc b/third_party/blink/renderer/core/app_history/app_history.cc
index d818d76..159bb84f 100644
--- a/third_party/blink/renderer/core/app_history/app_history.cc
+++ b/third_party/blink/renderer/core/app_history/app_history.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/script_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_app_history_current_change_event_init.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event_init.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_app_history_reload_options.h"
@@ -19,6 +20,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_app_history_update_current_options.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/app_history/app_history_api_navigation.h"
+#include "third_party/blink/renderer/core/app_history/app_history_current_change_event.h"
 #include "third_party/blink/renderer/core/app_history/app_history_destination.h"
 #include "third_party/blink/renderer/core/app_history/app_history_entry.h"
 #include "third_party/blink/renderer/core/app_history/app_history_navigate_event.h"
@@ -152,6 +154,22 @@
   return result;
 }
 
+String DetermineNavigationType(WebFrameLoadType type) {
+  switch (type) {
+    case WebFrameLoadType::kStandard:
+      return "push";
+    case WebFrameLoadType::kBackForward:
+      return "traverse";
+    case WebFrameLoadType::kReload:
+    case WebFrameLoadType::kReloadBypassingCache:
+      return "reload";
+    case WebFrameLoadType::kReplaceCurrentItem:
+      return "replace";
+  }
+  NOTREACHED();
+  return String();
+}
+
 const char AppHistory::kSupplementName[] = "AppHistory";
 
 AppHistory* AppHistory::appHistory(LocalDOMWindow& window) {
@@ -229,6 +247,8 @@
   if (entries_.IsEmpty())
     return;
 
+  AppHistoryEntry* old_current = current();
+
   HeapVector<Member<AppHistoryEntry>> disposed_entries;
   if (type == WebFrameLoadType::kBackForward) {
     // If this is a same-document back/forward navigation, the new current
@@ -259,6 +279,12 @@
     keys_to_indices_.insert(entries_[current_index_]->key(), current_index_);
   }
 
+  auto* init = AppHistoryCurrentChangeEventInit::Create();
+  init->setNavigationType(DetermineNavigationType(type));
+  init->setFrom(old_current);
+  DispatchEvent(*AppHistoryCurrentChangeEvent::Create(
+      event_type_names::kCurrentchange, init));
+
   // It's important to do this before firing dispose events, since dispose
   // events could start another navigation or otherwise mess with
   // ongoing_navigation_.
@@ -305,6 +331,11 @@
     return;
 
   current_entry->GetItem()->SetAppHistoryState(std::move(serialized_state));
+
+  auto* init = AppHistoryCurrentChangeEventInit::Create();
+  init->setFrom(current_entry);
+  DispatchEvent(*AppHistoryCurrentChangeEvent::Create(
+      event_type_names::kCurrentchange, init));
 }
 
 AppHistoryResult* AppHistory::navigate(ScriptState* script_state,
@@ -513,22 +544,6 @@
       exception_state);
 }
 
-String DetermineNavigationType(WebFrameLoadType type) {
-  switch (type) {
-    case WebFrameLoadType::kStandard:
-      return "push";
-    case WebFrameLoadType::kBackForward:
-      return "traverse";
-    case WebFrameLoadType::kReload:
-    case WebFrameLoadType::kReloadBypassingCache:
-      return "reload";
-    case WebFrameLoadType::kReplaceCurrentItem:
-      return "replace";
-  }
-  NOTREACHED();
-  return String();
-}
-
 void AppHistory::PromoteUpcomingNavigationToOngoing(const String& key) {
   DCHECK(!ongoing_navigation_);
   if (!key.IsNull()) {
diff --git a/third_party/blink/renderer/core/app_history/app_history.h b/third_party/blink/renderer/core/app_history/app_history.h
index e81cf3c..16287a36 100644
--- a/third_party/blink/renderer/core/app_history/app_history.h
+++ b/third_party/blink/renderer/core/app_history/app_history.h
@@ -80,6 +80,7 @@
   DEFINE_ATTRIBUTE_EVENT_LISTENER(navigate, kNavigate)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(navigatesuccess, kNavigatesuccess)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(navigateerror, kNavigateerror)
+  DEFINE_ATTRIBUTE_EVENT_LISTENER(currentchange, kCurrentchange)
 
   enum class DispatchResult { kContinue, kAbort, kTransitionWhile };
   DispatchResult DispatchNavigateEvent(const KURL& url,
diff --git a/third_party/blink/renderer/core/app_history/app_history.idl b/third_party/blink/renderer/core/app_history/app_history.idl
index 67b6a0a..3b091ca 100644
--- a/third_party/blink/renderer/core/app_history/app_history.idl
+++ b/third_party/blink/renderer/core/app_history/app_history.idl
@@ -25,4 +25,5 @@
   attribute EventHandler onnavigate;
   attribute EventHandler onnavigatesuccess;
   attribute EventHandler onnavigateerror;
+  attribute EventHandler oncurrentchange;
 };
diff --git a/third_party/blink/renderer/core/app_history/app_history_current_change_event.cc b/third_party/blink/renderer/core/app_history/app_history_current_change_event.cc
new file mode 100644
index 0000000..7708ed1f
--- /dev/null
+++ b/third_party/blink/renderer/core/app_history/app_history_current_change_event.cc
@@ -0,0 +1,30 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/app_history/app_history_current_change_event.h"
+
+#include "third_party/blink/renderer/bindings/core/v8/v8_app_history_current_change_event_init.h"
+#include "third_party/blink/renderer/core/app_history/app_history_entry.h"
+#include "third_party/blink/renderer/core/event_interface_names.h"
+
+namespace blink {
+
+AppHistoryCurrentChangeEvent::AppHistoryCurrentChangeEvent(
+    const AtomicString& type,
+    AppHistoryCurrentChangeEventInit* init)
+    : Event(type, init), from_(init->from()) {
+  if (init->navigationType())
+    navigation_type_ = *init->navigationType();
+}
+
+const AtomicString& AppHistoryCurrentChangeEvent::InterfaceName() const {
+  return event_interface_names::kAppHistoryCurrentChangeEvent;
+}
+
+void AppHistoryCurrentChangeEvent::Trace(Visitor* visitor) const {
+  Event::Trace(visitor);
+  visitor->Trace(from_);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/app_history/app_history_current_change_event.h b/third_party/blink/renderer/core/app_history/app_history_current_change_event.h
new file mode 100644
index 0000000..ddcf2a7
--- /dev/null
+++ b/third_party/blink/renderer/core/app_history/app_history_current_change_event.h
@@ -0,0 +1,43 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_APP_HISTORY_APP_HISTORY_CURRENT_CHANGE_EVENT_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_APP_HISTORY_APP_HISTORY_CURRENT_CHANGE_EVENT_H_
+
+#include "third_party/blink/renderer/core/dom/events/event.h"
+#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+
+namespace blink {
+class AppHistoryCurrentChangeEventInit;
+class AppHistoryEntry;
+
+class AppHistoryCurrentChangeEvent final : public Event {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  static AppHistoryCurrentChangeEvent* Create(
+      const AtomicString& type,
+      AppHistoryCurrentChangeEventInit* init) {
+    return MakeGarbageCollected<AppHistoryCurrentChangeEvent>(type, init);
+  }
+
+  AppHistoryCurrentChangeEvent(const AtomicString& type,
+                               AppHistoryCurrentChangeEventInit* init);
+
+  String navigationType() { return navigation_type_; }
+  AppHistoryEntry* from() { return from_; }
+
+  const AtomicString& InterfaceName() const final;
+  void Trace(Visitor* visitor) const final;
+
+ private:
+  String navigation_type_;
+  Member<AppHistoryEntry> from_;
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_APP_HISTORY_APP_HISTORY_CURRENT_CHANGE_EVENT_H_
diff --git a/third_party/blink/renderer/core/app_history/app_history_current_change_event.idl b/third_party/blink/renderer/core/app_history/app_history_current_change_event.idl
new file mode 100644
index 0000000..6f75e67
--- /dev/null
+++ b/third_party/blink/renderer/core/app_history/app_history_current_change_event.idl
@@ -0,0 +1,13 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/app-history/
+[
+  Exposed=Window,
+  RuntimeEnabled=AppHistory
+] interface AppHistoryCurrentChangeEvent : Event {
+  constructor(DOMString type, AppHistoryCurrentChangeEventInit eventInit);
+  readonly attribute AppHistoryNavigationType? navigationType;
+  readonly attribute AppHistoryEntry from;
+};
diff --git a/third_party/blink/renderer/core/app_history/app_history_current_change_event_init.idl b/third_party/blink/renderer/core/app_history/app_history_current_change_event_init.idl
new file mode 100644
index 0000000..eb3fa51
--- /dev/null
+++ b/third_party/blink/renderer/core/app_history/app_history_current_change_event_init.idl
@@ -0,0 +1,9 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// https://github.com/WICG/app-history/
+dictionary AppHistoryCurrentChangeEventInit : EventInit {
+  AppHistoryNavigationType? navigationType = null;
+  required AppHistoryEntry from;
+};
diff --git a/third_party/blink/renderer/core/app_history/build.gni b/third_party/blink/renderer/core/app_history/build.gni
index 2487b07..918b64c 100644
--- a/third_party/blink/renderer/core/app_history/build.gni
+++ b/third_party/blink/renderer/core/app_history/build.gni
@@ -7,6 +7,8 @@
   "app_history.h",
   "app_history_api_navigation.cc",
   "app_history_api_navigation.h",
+  "app_history_current_change_event.cc",
+  "app_history_current_change_event.h",
   "app_history_destination.h",
   "app_history_entry.cc",
   "app_history_entry.h",
diff --git a/third_party/blink/renderer/core/css/css_value.h b/third_party/blink/renderer/core/css/css_value.h
index 431bc266..08c7f06 100644
--- a/third_party/blink/renderer/core/css/css_value.h
+++ b/third_party/blink/renderer/core/css/css_value.h
@@ -33,18 +33,6 @@
 
 class CORE_EXPORT CSSValue : public GarbageCollected<CSSValue> {
  public:
-#if !BUILDFLAG(USE_V8_OILPAN)
-  template <typename T>
-  static void* AllocateObject(size_t size) {
-    ThreadState* state =
-        ThreadStateFor<ThreadingTrait<CSSValue>::kAffinity>::GetState();
-    const char* type_name = "blink::CSSValue";
-    return state->Heap().AllocateOnArenaIndex(
-        state, size, BlinkGC::kCSSValueArenaIndex,
-        GCInfoTrait<GCInfoFoldedType<CSSValue>>::Index(), type_name);
-  }
-#endif  // !USE_V8_OILPAN
-
   // TODO(sashab): Remove this method and move logic to the caller.
   static CSSValue* Create(const Length& value, float zoom);
 
@@ -351,7 +339,6 @@
 
 }  // namespace blink
 
-#if BUILDFLAG(USE_V8_OILPAN)
 namespace cppgc {
 // Assign CSSValue to be allocated on custom CSSValueSpace.
 template <typename T>
@@ -361,6 +348,5 @@
   using Space = blink::CSSValueSpace;
 };
 }  // namespace cppgc
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VALUE_H_
diff --git a/third_party/blink/renderer/core/dom/node.h b/third_party/blink/renderer/core/dom/node.h
index 52b1e3a..58df078e 100644
--- a/third_party/blink/renderer/core/dom/node.h
+++ b/third_party/blink/renderer/core/dom/node.h
@@ -38,7 +38,6 @@
 #include "third_party/blink/renderer/core/style/computed_style_constants.h"
 #include "third_party/blink/renderer/platform/heap/custom_spaces.h"
 #include "third_party/blink/renderer/platform/text/text_direction.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 
 // This needs to be here because element.cc also depends on it.
 #define DUMP_NODE_STATISTICS 0
@@ -179,18 +178,6 @@
     kDocumentPositionImplementationSpecific = 0x20,
   };
 
-#if !BUILDFLAG(USE_V8_OILPAN)
-  template <typename T>
-  static void* AllocateObject(size_t size) {
-    ThreadState* state =
-        ThreadStateFor<ThreadingTrait<Node>::kAffinity>::GetState();
-    const char* type_name = "blink::Node";
-    return state->Heap().AllocateOnArenaIndex(
-        state, size, BlinkGC::kNodeArenaIndex,
-        GCInfoTrait<GCInfoFoldedType<T>>::Index(), type_name);
-  }
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
-
   static void DumpStatistics();
 
   ~Node() override;
@@ -1197,7 +1184,6 @@
 void showNodePath(const blink::Node*);
 #endif
 
-#if BUILDFLAG(USE_V8_OILPAN)
 namespace cppgc {
 // Assign Node to be allocated on custom NodeSpace.
 template <typename T>
@@ -1215,6 +1201,4 @@
 };
 }  // namespace blink
 
-#endif  // USE_V8_OILPAN
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_NODE_H_
diff --git a/third_party/blink/renderer/core/dom/node_list.h b/third_party/blink/renderer/core/dom/node_list.h
index f3487ad..9e3fa27d 100644
--- a/third_party/blink/renderer/core/dom/node_list.h
+++ b/third_party/blink/renderer/core/dom/node_list.h
@@ -27,7 +27,6 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 
 namespace blink {
 
@@ -53,14 +52,12 @@
   NodeList() = default;
 };
 
-#if BUILDFLAG(USE_V8_OILPAN)
 template <typename T>
 struct ThreadingTrait<
     T,
     std::enable_if_t<std::is_base_of<blink::NodeList, T>::value>> {
   static constexpr ThreadAffinity kAffinity = kMainThreadOnly;
 };
-#endif  // USE_V8_OILPAN
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/dom/node_rare_data.h b/third_party/blink/renderer/core/dom/node_rare_data.h
index a64ec61..97c9a47 100644
--- a/third_party/blink/renderer/core/dom/node_rare_data.h
+++ b/third_party/blink/renderer/core/dom/node_rare_data.h
@@ -26,7 +26,6 @@
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/heap/thread_state.h"
 #include "third_party/blink/renderer/platform/wtf/bit_field.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/casting.h"
 #include "third_party/blink/renderer/platform/wtf/hash_set.h"
 
@@ -262,14 +261,12 @@
   Member<HeapHashSet<Member<ScrollTimeline>>> scroll_timelines_;
 };
 
-#if BUILDFLAG(USE_V8_OILPAN)
 template <typename T>
 struct ThreadingTrait<
     T,
     std::enable_if_t<std::is_base_of<blink::NodeRareData, T>::value>> {
   static constexpr ThreadAffinity kAffinity = kMainThreadOnly;
 };
-#endif  // USE_V8_OILPAN
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/core/events/event_type_names.json5 b/third_party/blink/renderer/core/events/event_type_names.json5
index f44f743..d1ed1f9 100644
--- a/third_party/blink/renderer/core/events/event_type_names.json5
+++ b/third_party/blink/renderer/core/events/event_type_names.json5
@@ -91,6 +91,7 @@
     "crossoriginmessage",
     "currentscreenchange",
     "cuechange",
+    "currentchange",
     "cut",
     "datachannel",
     "dblclick",
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index d3560b5..9abef249 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -300,19 +300,6 @@
   friend class VisualRectMappingTest;
 
  public:
-#if !BUILDFLAG(USE_V8_OILPAN)
-  // Use a type specific arena for LayoutObject
-  template <typename T>
-  static void* AllocateObject(size_t size) {
-    ThreadState* state =
-        ThreadStateFor<ThreadingTrait<LayoutObject>::kAffinity>::GetState();
-    const char* type_name = "blink::LayoutObject";
-    return state->Heap().AllocateOnArenaIndex(
-        state, size, BlinkGC::kLayoutObjectArenaIndex,
-        GCInfoTrait<GCInfoFoldedType<LayoutObject>>::Index(), type_name);
-  }
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
-
   // Anonymous objects should pass the document as their node, and they will
   // then automatically be marked as anonymous in the constructor.
   explicit LayoutObject(Node*);
@@ -4632,7 +4619,6 @@
 
 #endif
 
-#if BUILDFLAG(USE_V8_OILPAN)
 namespace cppgc {
 // Assign LayoutObject to be allocated on custom LayoutObjectSpace.
 template <typename T>
@@ -4642,6 +4628,5 @@
   using Space = blink::LayoutObjectSpace;
 };
 }  // namespace cppgc
-#endif  // USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_OBJECT_H_
diff --git a/third_party/blink/renderer/core/layout/line/inline_box.h b/third_party/blink/renderer/core/layout/line/inline_box.h
index 62a2fe37..285eaca2 100644
--- a/third_party/blink/renderer/core/layout/line/inline_box.h
+++ b/third_party/blink/renderer/core/layout/line/inline_box.h
@@ -45,19 +45,6 @@
 class CORE_EXPORT InlineBox : public GarbageCollected<InlineBox>,
                               public DisplayItemClient {
  public:
-#if !BUILDFLAG(USE_V8_OILPAN)
-  // Use a type specific arena
-  template <typename T>
-  static void* AllocateObject(size_t size) {
-    ThreadState* state =
-        ThreadStateFor<ThreadingTrait<InlineBox>::kAffinity>::GetState();
-    const char* type_name = "blink::InlineBox";
-    return state->Heap().AllocateOnArenaIndex(
-        state, size, BlinkGC::kLayoutObjectArenaIndex,
-        GCInfoTrait<GCInfoFoldedType<InlineBox>>::Index(), type_name);
-  }
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
-
   explicit InlineBox(LineLayoutItem obj)
       : next_(nullptr),
         prev_(nullptr),
@@ -531,7 +518,6 @@
 void showLineTree(const blink::InlineBox*);
 #endif
 
-#if BUILDFLAG(USE_V8_OILPAN)
 namespace cppgc {
 // Assign InlineBox to be allocated on custom LayoutObjectSpace.
 template <typename T>
@@ -541,6 +527,5 @@
   using Space = blink::LayoutObjectSpace;
 };
 }  // namespace cppgc
-#endif  // USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LINE_INLINE_BOX_H_
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
index 39b11ff..a42b31b 100644
--- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -133,11 +133,6 @@
   return AxisEdge::kStart;
 }
 
-LayoutUnit ComputeSizeFromAspectRatio(LayoutUnit extent,
-                                      const LogicalSize& aspect_ratio) {
-  return extent.MulDiv(aspect_ratio.inline_size, aspect_ratio.block_size);
-}
-
 }  // namespace
 
 void NGFlexLayoutAlgorithm::HandleOutOfFlowPositioned(NGBlockNode child) {
@@ -285,23 +280,6 @@
          DoesItemStretch(child);
 }
 
-LogicalSize NGFlexLayoutAlgorithm::GetMainOverCrossAspectRatio(
-    const NGBlockNode& child) const {
-  DCHECK(child.HasAspectRatio());
-  LogicalSize aspect_ratio = child.GetAspectRatio();
-
-  DCHECK_GT(aspect_ratio.inline_size, 0);
-  DCHECK_GT(aspect_ratio.block_size, 0);
-
-  // Multiplying by ratio will take something in the item's block axis and
-  // convert it to the inline axis. We want to convert from cross size to main
-  // size. If block axis and cross axis are the same, then we already have what
-  // we need. Otherwise we need to use the reciprocal.
-  if (!MainAxisIsInlineAxis(child))
-    aspect_ratio.Transpose();
-  return aspect_ratio;
-}
-
 NGConstraintSpace NGFlexLayoutAlgorithm::BuildSpaceForIntrinsicBlockSize(
     const NGBlockNode& flex_item) const {
   const ComputedStyle& child_style = flex_item.Style();
@@ -449,12 +427,14 @@
       DCHECK_GE(cross_size, LayoutUnit());
       cross_size = min_max_sizes_in_cross_axis_direction.ClampSizeToMinAndMax(
           cross_size);
-      // TODO(dgrogan): This isn't right for non-replaced aspect-ratio items
-      // with box-sizing: border-box, but it's what existing code does. Fix in a
-      // follow-up CL by reusing something from ng_length_utils.
-      return ComputeSizeFromAspectRatio(cross_size - cross_axis_border_padding,
-                                        GetMainOverCrossAspectRatio(child)) +
-             main_axis_border_padding;
+      if (MainAxisIsInlineAxis(child)) {
+        return InlineSizeFromAspectRatio(
+            border_padding_in_child_writing_mode, child.GetAspectRatio(),
+            child_style.BoxSizingForAspectRatio(), cross_size);
+      }
+      return BlockSizeFromAspectRatio(
+          border_padding_in_child_writing_mode, child.GetAspectRatio(),
+          child_style.BoxSizingForAspectRatio(), cross_size);
     };
 
     // The logic that calculates flex_base_border_box assumes that the used
@@ -550,13 +530,18 @@
       }
       DCHECK_GE(content_size_suggestion, main_axis_border_padding);
 
-      if (child.HasAspectRatio()) {
+      // TODO(crbug.com/1252693):
+      // This code block is needed because
+      // IntrinsicBlockSizeFunc incorrectly ignores the inline min/max
+      // constraints for aspect-ratio items. So we apply those constraints here
+      // in AdjustChildSizeForAspectRatioCrossAxisMinAndMax. Once 1252693 is
+      // fixed, we can delete this entire code block.
+      if (child.HasAspectRatio() && !MainAxisIsInlineAxis(child)) {
         content_size_suggestion =
             AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
                 child, content_size_suggestion,
-                min_max_sizes_in_cross_axis_direction.min_size,
-                min_max_sizes_in_cross_axis_direction.max_size,
-                main_axis_border_padding, cross_axis_border_padding);
+                min_max_sizes_in_cross_axis_direction,
+                border_padding_in_child_writing_mode);
       }
 
       LayoutUnit specified_size_suggestion = LayoutUnit::Max();
@@ -640,45 +625,24 @@
 NGFlexLayoutAlgorithm::AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
     const NGBlockNode& child,
     LayoutUnit content_size_suggestion,
-    LayoutUnit cross_min,
-    LayoutUnit cross_max,
-    LayoutUnit main_axis_border_padding,
-    LayoutUnit cross_axis_border_padding) {
+    const MinMaxSizes& cross_min_max,
+    const NGBoxStrut& border_padding_in_child_writing_mode) {
   DCHECK(child.HasAspectRatio());
 
-  const LogicalSize ratio = GetMainOverCrossAspectRatio(child);
   // Clamp content_suggestion by any definite min and max cross size properties
   // converted through the aspect ratio.
-  const Length& cross_max_length = is_horizontal_flow_
-                                       ? child.Style().MaxHeight()
-                                       : child.Style().MaxWidth();
-  DCHECK_GE(cross_max, cross_axis_border_padding);
-  // TODO(dgrogan): No tests fail if we unconditionally apply max_main_length.
-  // Either add a test that needs it or remove it.
-  if (IsItemCrossAxisLengthDefinite(child, cross_max_length)) {
-    LayoutUnit max_main_length =
-        main_axis_border_padding +
-        ComputeSizeFromAspectRatio(cross_max - cross_axis_border_padding,
-                                   ratio);
-    content_size_suggestion =
-        std::min(max_main_length, content_size_suggestion);
+  if (MainAxisIsInlineAxis(child)) {
+    auto min_max = ComputeTransferredMinMaxInlineSizes(
+        child.GetAspectRatio(), cross_min_max,
+        border_padding_in_child_writing_mode,
+        child.Style().BoxSizingForAspectRatio());
+    return min_max.ClampSizeToMinAndMax(content_size_suggestion);
   }
-
-  const Length& cross_min_length = is_horizontal_flow_
-                                       ? child.Style().MinHeight()
-                                       : child.Style().MinWidth();
-  DCHECK_GE(cross_min, cross_axis_border_padding);
-  // TODO(dgrogan): Same as above with min_main_length here -- it may be
-  // unneeded or untested.
-  if (IsItemCrossAxisLengthDefinite(child, cross_min_length)) {
-    LayoutUnit min_main_length =
-        main_axis_border_padding +
-        ComputeSizeFromAspectRatio(cross_min - cross_axis_border_padding,
-                                   ratio);
-    content_size_suggestion =
-        std::max(min_main_length, content_size_suggestion);
-  }
-  return content_size_suggestion;
+  auto min_max = ComputeTransferredMinMaxBlockSizes(
+      child.GetAspectRatio(), cross_min_max,
+      border_padding_in_child_writing_mode,
+      child.Style().BoxSizingForAspectRatio());
+  return min_max.ClampSizeToMinAndMax(content_size_suggestion);
 }
 
 scoped_refptr<const NGLayoutResult> NGFlexLayoutAlgorithm::Layout() {
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
index 478eef3..2f0704f 100644
--- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.h
@@ -40,7 +40,6 @@
                                      const Length& length) const;
   bool AspectRatioProvidesMainSize(const NGBlockNode& child,
                                    const Length& cross_axis_length) const;
-  LogicalSize GetMainOverCrossAspectRatio(const NGBlockNode& child) const;
   bool DoesItemStretch(const NGBlockNode& child) const;
   // This implements the first of the additional scenarios where a flex item
   // has definite sizes when it would not if it weren't a flex item.
@@ -49,10 +48,8 @@
   LayoutUnit AdjustChildSizeForAspectRatioCrossAxisMinAndMax(
       const NGBlockNode& child,
       LayoutUnit content_suggestion,
-      LayoutUnit cross_min,
-      LayoutUnit cross_max,
-      LayoutUnit main_axis_border_padding,
-      LayoutUnit cross_axis_border_padding);
+      const MinMaxSizes& cross_min_max,
+      const NGBoxStrut& border_padding_in_child_writing_mode);
 
   bool IsColumnContainerMainSizeDefinite() const;
   bool IsContainerCrossSizeDefinite() const;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
index 8d19bf0..d864ad2 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -614,6 +614,26 @@
   return transferred_min_max;
 }
 
+MinMaxSizes ComputeTransferredMinMaxBlockSizes(
+    const LogicalSize& ratio,
+    const MinMaxSizes& inline_min_max,
+    const NGBoxStrut& border_padding,
+    const EBoxSizing sizing) {
+  MinMaxSizes transferred_min_max = {LayoutUnit(), LayoutUnit::Max()};
+  if (inline_min_max.min_size > LayoutUnit()) {
+    transferred_min_max.min_size = BlockSizeFromAspectRatio(
+        border_padding, ratio, sizing, inline_min_max.min_size);
+  }
+  if (inline_min_max.max_size != LayoutUnit::Max()) {
+    transferred_min_max.max_size = BlockSizeFromAspectRatio(
+        border_padding, ratio, sizing, inline_min_max.max_size);
+  }
+  // Minimum size wins over maximum size.
+  transferred_min_max.max_size =
+      std::max(transferred_min_max.max_size, transferred_min_max.min_size);
+  return transferred_min_max;
+}
+
 MinMaxSizes ComputeMinMaxInlineSizesFromAspectRatio(
     const NGConstraintSpace& constraint_space,
     const ComputedStyle& style,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
index e462429a..ae1e9ea 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
@@ -297,6 +297,10 @@
     const MinMaxSizes& block_min_max,
     const NGBoxStrut& border_padding,
     const EBoxSizing sizing);
+MinMaxSizes ComputeTransferredMinMaxBlockSizes(const LogicalSize& ratio,
+                                               const MinMaxSizes& block_min_max,
+                                               const NGBoxStrut& border_padding,
+                                               const EBoxSizing sizing);
 
 // Computes the transferred min/max inline sizes from the min/max block
 // sizes and the aspect ratio.
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
index bfbf961..c4b6284 100644
--- a/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
+++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.cc
@@ -116,16 +116,4 @@
   return UnacceleratedStaticBitmapImage::Create(std::move(image));
 }
 
-absl::optional<SkBitmap> ToSkBitmap(
-    const scoped_refptr<blink::StaticBitmapImage>& static_bitmap_image) {
-  const sk_sp<SkImage> image =
-      static_bitmap_image->PaintImageForCurrentFrame().GetSwSkImage();
-  SkBitmap result;
-  if (image && image->asLegacyBitmap(
-                   &result, SkImage::LegacyBitmapMode::kRO_LegacyBitmapMode)) {
-    return result;
-  }
-  return absl::nullopt;
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message.h b/third_party/blink/renderer/core/messaging/blink_transferable_message.h
index c1140c07a..11549f9 100644
--- a/third_party/blink/renderer/core/messaging/blink_transferable_message.h
+++ b/third_party/blink/renderer/core/messaging/blink_transferable_message.h
@@ -39,9 +39,6 @@
 CORE_EXPORT scoped_refptr<blink::StaticBitmapImage> ToStaticBitmapImage(
     const SkBitmap& sk_bitmap);
 
-CORE_EXPORT absl::optional<SkBitmap> ToSkBitmap(
-    const scoped_refptr<blink::StaticBitmapImage>& static_bitmap_image);
-
 }  // namespace blink
 
 namespace WTF {
diff --git a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc
index c3cc5c5..de1c4cb 100644
--- a/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc
+++ b/third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.cc
@@ -5,12 +5,38 @@
 #include "third_party/blink/renderer/core/messaging/blink_transferable_message_mojom_traits.h"
 
 #include "mojo/public/cpp/base/big_buffer_mojom_traits.h"
+#include "skia/ext/skia_utils_base.h"
 #include "third_party/blink/public/mojom/messaging/transferable_message.mojom-blink.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
 namespace mojo {
 
+namespace {
+
+absl::optional<SkBitmap> ToSkBitmapN32(
+    const scoped_refptr<blink::StaticBitmapImage>& static_bitmap_image) {
+  const sk_sp<SkImage> image =
+      static_bitmap_image->PaintImageForCurrentFrame().GetSwSkImage();
+  if (!image)
+    return absl::nullopt;
+
+  SkBitmap sk_bitmap;
+  if (!image->asLegacyBitmap(&sk_bitmap,
+                             SkImage::LegacyBitmapMode::kRO_LegacyBitmapMode)) {
+    return absl::nullopt;
+  }
+
+  SkBitmap sk_bitmap_n32;
+  if (!skia::SkBitmapToN32OpaqueOrPremul(sk_bitmap, &sk_bitmap_n32)) {
+    return absl::nullopt;
+  }
+
+  return sk_bitmap_n32;
+}
+
+}  // namespace
+
 Vector<SkBitmap>
 StructTraits<blink::mojom::blink::TransferableMessage::DataView,
              blink::BlinkTransferableMessage>::
@@ -19,11 +45,13 @@
   out.ReserveInitialCapacity(
       input.message->GetImageBitmapContentsArray().size());
   for (auto& bitmap_contents : input.message->GetImageBitmapContentsArray()) {
-    absl::optional<SkBitmap> bitmap = blink::ToSkBitmap(bitmap_contents);
-    if (!bitmap) {
+    // TransferableMessage::image_bitmap_contents_array is an array of
+    // skia.mojom.BitmapN32, so SkBitmap should be in N32 format.
+    auto bitmap_n32 = ToSkBitmapN32(bitmap_contents);
+    if (!bitmap_n32) {
       return Vector<SkBitmap>();
     }
-    out.push_back(std::move(bitmap.value()));
+    out.push_back(std::move(bitmap_n32.value()));
   }
   return out;
 }
diff --git a/third_party/blink/renderer/core/paint/paint_layer.h b/third_party/blink/renderer/core/paint/paint_layer.h
index ab91cf4..4e6429e 100644
--- a/third_party/blink/renderer/core/paint/paint_layer.h
+++ b/third_party/blink/renderer/core/paint/paint_layer.h
@@ -250,19 +250,6 @@
 class CORE_EXPORT PaintLayer : public GarbageCollected<PaintLayer>,
                                public DisplayItemClient {
  public:
-#if !BUILDFLAG(USE_V8_OILPAN)
-  // Use a type specific arena
-  template <typename T>
-  static void* AllocateObject(size_t size) {
-    ThreadState* state =
-        ThreadStateFor<ThreadingTrait<PaintLayer>::kAffinity>::GetState();
-    const char* type_name = "blink::PaintLayer";
-    return state->Heap().AllocateOnArenaIndex(
-        state, size, BlinkGC::kLayoutObjectArenaIndex,
-        GCInfoTrait<GCInfoFoldedType<PaintLayer>>::Index(), type_name);
-  }
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
-
   explicit PaintLayer(LayoutBoxModelObject*);
   PaintLayer(const PaintLayer&) = delete;
   PaintLayer& operator=(const PaintLayer&) = delete;
@@ -1558,7 +1545,6 @@
 CORE_EXPORT void showLayerTree(const blink::LayoutObject*);
 #endif
 
-#if BUILDFLAG(USE_V8_OILPAN)
 namespace cppgc {
 // Assign PaintLayer to be allocated on custom LayoutObjectSpace.
 template <typename T>
@@ -1568,6 +1554,5 @@
   using Space = blink::LayoutObjectSpace;
 };
 }  // namespace cppgc
-#endif  // USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_LAYER_H_
diff --git a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
index c66341f..44378a4 100644
--- a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.cc
@@ -40,22 +40,13 @@
     : Credential(id, type.IsEmpty() ? kPublicKeyCredentialType : type),
       raw_id_(raw_id),
       response_(response),
-      authenticatorAttachment_(
-          GetAuthenticatorAttachment(has_transport, transport)),
+      authenticator_attachment_(
+          has_transport ? (transport == mojom::AuthenticatorTransport::INTERNAL
+                               ? absl::make_optional("platform")
+                               : absl::make_optional("cross-platform"))
+                        : absl::nullopt),
       extension_outputs_(extension_outputs) {}
 
-absl::optional<String> PublicKeyCredential::GetAuthenticatorAttachment(
-    bool has_transport,
-    mojom::AuthenticatorTransport transport) {
-  absl::optional<String> authenticatorAttachment;
-  if (has_transport) {
-    authenticatorAttachment =
-        transport == mojom::AuthenticatorTransport::INTERNAL ? "platform"
-                                                             : "cross-platform";
-  }
-  return authenticatorAttachment;
-}
-
 ScriptPromise
 PublicKeyCredential::isUserVerifyingPlatformAuthenticatorAvailable(
     ScriptState* script_state) {
diff --git a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
index 028a493..55b44cd 100644
--- a/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
+++ b/third_party/blink/renderer/modules/credentialmanager/public_key_credential.h
@@ -38,11 +38,8 @@
   DOMArrayBuffer* rawId() const { return raw_id_.Get(); }
   AuthenticatorResponse* response() const { return response_.Get(); }
   absl::optional<String> authenticatorAttachment() const {
-    return authenticatorAttachment_;
+    return authenticator_attachment_;
   }
-  absl::optional<String> GetAuthenticatorAttachment(
-      bool has_transport,
-      mojom::AuthenticatorTransport transport);
   static ScriptPromise isUserVerifyingPlatformAuthenticatorAvailable(
       ScriptState*);
   AuthenticationExtensionsClientOutputs* getClientExtensionResults() const;
@@ -54,7 +51,7 @@
  private:
   const Member<DOMArrayBuffer> raw_id_;
   const Member<AuthenticatorResponse> response_;
-  const absl::optional<String> authenticatorAttachment_;
+  const absl::optional<String> authenticator_attachment_;
   Member<const AuthenticationExtensionsClientOutputs> extension_outputs_;
 };
 
diff --git a/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.idl b/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.idl
index 34768ec..ce69ada9 100644
--- a/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.idl
+++ b/third_party/blink/renderer/modules/mediastream/focusable_media_stream_track.idl
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// TODO(crbug.com/1215480): Link to spec once produced.
+// https://wicg.github.io/conditional-focus/
 enum CaptureStartFocusBehavior {
   "focus-captured-surface",
   "no-focus-change"
 };
 
-// TODO(crbug.com/1215480): Link to spec once produced.
+// https://wicg.github.io/conditional-focus/
 [
     Exposed = Window,
     RuntimeEnabled = ConditionalFocus
@@ -23,7 +23,6 @@
   // Promise<MediaStream> is resolved, or if the call comes too late due
   // to processing delays, the user agent assumes an implicit call with |focus|
   // set to a value decided by the user agent itself.
-  // TODO(crbug.com/1215480): Link to WICG spec once produced.
   [CallWith = ExecutionContext, RaisesException]
   void focus(CaptureStartFocusBehavior focus_behavior);
 };
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index aa9130f..04bc65ba 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1670,7 +1670,6 @@
     "//third_party/blink/renderer/platform/loader",
     "//third_party/blink/renderer/platform/network",
     "//third_party/blink/renderer/platform/scheduler",
-    "//third_party/blink/renderer/platform/wtf:buildflags",
     "//third_party/fdlibm",
     "//third_party/pffft:pffft",
     "//ui/gfx",
@@ -1985,7 +1984,7 @@
 test("blink_platform_unittests") {
   deps = [ ":blink_platform_unittests_sources" ]
 
-  if (is_fuchsia && enable_blink_heap_use_v8_oilpan) {
+  if (is_fuchsia) {
     # Oilpan reuses V8's v8::PageAllocator which generally requires JIT
     # permissions.
     additional_manifest_fragments =
diff --git a/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h b/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h
index 24b700d..0af0d66 100644
--- a/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h
+++ b/third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h
@@ -42,8 +42,6 @@
 
 }  // namespace blink
 
-#if BUILDFLAG(USE_V8_OILPAN)
-
 namespace cppgc {
 template <typename T, typename Unused>
 struct PostConstructionCallbackTrait;
@@ -62,24 +60,4 @@
 };
 }  // namespace cppgc
 
-#else  // !USE_V8_OILPAN
-
-namespace blink {
-template <typename T>
-struct PostConstructionHookTrait<
-    T,
-    base::void_t<decltype(
-        std::declval<T>().ActiveScriptWrappableBaseConstructed())>> {
-  static void Call(T* object) {
-    static_assert(std::is_base_of<ActiveScriptWrappableBase, T>::value,
-                  "Only ActiveScriptWrappableBase should use the "
-                  "post-construction hook.");
-    object->ActiveScriptWrappableBaseConstructed();
-  }
-};
-
-}  // namespace blink
-
-#endif  // !USE_V8_OILPAN
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_ACTIVE_SCRIPT_WRAPPABLE_BASE_H_
diff --git a/third_party/blink/renderer/platform/bindings/name_client.h b/third_party/blink/renderer/platform/bindings/name_client.h
index f6e4cfb..83d70fb 100644
--- a/third_party/blink/renderer/platform/bindings/name_client.h
+++ b/third_party/blink/renderer/platform/bindings/name_client.h
@@ -7,11 +7,7 @@
 
 #include "third_party/blink/renderer/platform/bindings/buildflags.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "v8/include/cppgc/name-provider.h"
-#endif  // BUILDFLAG(USE_V8_OILPAN)
 
 namespace blink {
 
@@ -40,8 +36,6 @@
 //   Don't:
 //     class Bar : public GarbageCollected<Bar> {...};
 //     class Baz : public Bar, public NameClient {...};
-#if BUILDFLAG(USE_V8_OILPAN)
-
 class PLATFORM_EXPORT NameClient : public cppgc::NameProvider {
  public:
   NameClient() = default;
@@ -58,31 +52,6 @@
   }
 };
 
-#else  // !USE_V8_OILPAN
-
-class PLATFORM_EXPORT NameClient {
- public:
-  static constexpr bool HideInternalName() {
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS) && \
-    (defined(COMPILER_GCC) || defined(__clang__))
-    return false;
-#else
-    return true;
-#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-  }
-
-  NameClient() = default;
-  NameClient(const NameClient&) = delete;
-  NameClient& operator=(const NameClient&) = delete;
-  virtual ~NameClient() = default;
-
-  // Human-readable name of this object. The DevTools heap snapshot uses
-  // this method to show the object.
-  virtual const char* NameInHeapSnapshot() const = 0;
-};
-
-#endif  // !USE_V8_OILPAN
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_NAME_CLIENT_H_
diff --git a/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h b/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
index 7460e845..12b6702 100644
--- a/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
+++ b/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
@@ -10,14 +10,10 @@
 #include "base/compiler_specific.h"
 #include "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
 #include "third_party/blink/renderer/platform/wtf/vector_traits.h"
 #include "v8/include/v8.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "v8/include/cppgc/trace-trait.h"
-#endif  // USE_V8_OILPAN
 
 namespace blink {
 
@@ -121,31 +117,19 @@
  protected:
   ALWAYS_INLINE void InternalSet(v8::Isolate* isolate, v8::Local<T> handle) {
     handle_.Reset(isolate, handle);
-#if BUILDFLAG(USE_V8_OILPAN)
     UnifiedHeapMarkingVisitor::WriteBarrier(UnsafeCast<v8::Value>().Get());
-#else   // !USE_V8_OILPAN
-    UnifiedHeapMarkingVisitor::WriteBarrier(UnsafeCast<v8::Value>());
-#endif  // !USE_V8_OILPAN
   }
 
   ALWAYS_INLINE void WriteBarrier() const {
-#if BUILDFLAG(USE_V8_OILPAN)
     UnifiedHeapMarkingVisitor::WriteBarrier(UnsafeCast<v8::Value>().Get());
-#else   // !USE_V8_OILPAN
-    UnifiedHeapMarkingVisitor::WriteBarrier(UnsafeCast<v8::Value>());
-#endif  // !USE_V8_OILPAN
   }
 
   v8::TracedReference<T> handle_;
 
-#if BUILDFLAG(USE_V8_OILPAN)
   friend struct cppgc::TraceTrait<TraceWrapperV8Reference<T>>;
-#endif  // USE_V8_OILPAN
 };
 }  // namespace blink
 
-#if BUILDFLAG(USE_V8_OILPAN)
-
 namespace cppgc {
 template <typename T>
 struct TraceTrait<blink::TraceWrapperV8Reference<T>> {
@@ -163,26 +147,6 @@
 };
 }  // namespace cppgc
 
-#else  // !USE_V8_OILPAN
-
-namespace blink {
-template <typename T>
-struct TraceTrait<TraceWrapperV8Reference<T>> {
-  STATIC_ONLY(TraceTrait);
-
-  static TraceDescriptor GetTraceDescriptor(
-      const TraceWrapperV8Reference<T>* ref) {
-    return {ref, TraceTrait<TraceWrapperV8Reference<T>>::Trace};
-  }
-
-  static void Trace(Visitor* visitor, const void* ref) {
-    visitor->Trace(*static_cast<const TraceWrapperV8Reference<T>*>(ref));
-  }
-};
-}  // namespace blink
-
-#endif  // !USE_V8_OILPAN
-
 namespace WTF {
 
 template <typename T>
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn
index 3a498b9..3110172 100644
--- a/third_party/blink/renderer/platform/heap/BUILD.gn
+++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -33,14 +33,7 @@
     configs -= [ "//build/config/compiler:afdo_optimize_size" ]
   }
 
-  if (!enable_blink_heap_use_v8_oilpan) {
-    sources = [
-      "impl/unsanitized_atomic.cc",
-      "impl/unsanitized_atomic.h",
-    ]
-  } else {
-    sources = []
-  }
+  sources = []
 
   deps = [
     "//base",
@@ -90,100 +83,41 @@
     "//base",
     "//third_party/blink/renderer/platform:make_platform_generated",
     "//third_party/blink/renderer/platform/heap:heap_unsanitized",
-    "//third_party/blink/renderer/platform/heap/asm",
-    "//third_party/blink/renderer/platform/wtf:buildflags",
     "//third_party/icu",
     "//v8",
   ]
 
-  if (enable_blink_heap_use_v8_oilpan) {
-    sources += [
-      "v8_wrapper/blink_gc.h",
-      "v8_wrapper/blink_gc_memory_dump_provider.cc",
-      "v8_wrapper/blink_gc_memory_dump_provider.h",
-      "v8_wrapper/collection_support/heap_hash_table_backing.h",
-      "v8_wrapper/collection_support/heap_vector_backing.h",
-      "v8_wrapper/custom_spaces.cc",
-      "v8_wrapper/custom_spaces.h",
-      "v8_wrapper/garbage_collected.h",
-      "v8_wrapper/heap.h",
-      "v8_wrapper/heap_allocator_impl.h",
-      "v8_wrapper/member.h",
-      "v8_wrapper/persistent.h",
-      "v8_wrapper/process_heap.h",
-      "v8_wrapper/thread_local.h",
-      "v8_wrapper/thread_state.cc",
-      "v8_wrapper/thread_state.h",
-      "v8_wrapper/thread_state_scopes.h",
-      "v8_wrapper/trace_traits.h",
-      "v8_wrapper/unified_heap_marking_visitor.h",
-      "v8_wrapper/visitor.h",
-      "v8_wrapper/write_barrier.h",
-    ]
+  sources += [
+    "v8_wrapper/blink_gc.h",
+    "v8_wrapper/blink_gc_memory_dump_provider.cc",
+    "v8_wrapper/blink_gc_memory_dump_provider.h",
+    "v8_wrapper/collection_support/heap_hash_table_backing.h",
+    "v8_wrapper/collection_support/heap_vector_backing.h",
+    "v8_wrapper/custom_spaces.cc",
+    "v8_wrapper/custom_spaces.h",
+    "v8_wrapper/garbage_collected.h",
+    "v8_wrapper/heap.h",
+    "v8_wrapper/heap_allocator_impl.h",
+    "v8_wrapper/member.h",
+    "v8_wrapper/persistent.h",
+    "v8_wrapper/process_heap.h",
+    "v8_wrapper/thread_local.h",
+    "v8_wrapper/thread_state.cc",
+    "v8_wrapper/thread_state.h",
+    "v8_wrapper/thread_state_scopes.h",
+    "v8_wrapper/trace_traits.h",
+    "v8_wrapper/unified_heap_marking_visitor.h",
+    "v8_wrapper/visitor.h",
+    "v8_wrapper/write_barrier.h",
+  ]
 
-    deps += [
-      "//gin:gin",
+  deps += [
+    "//gin:gin",
 
-      # Dependency on V8 which transitively depends on cppgc but exposes
-      # JS-related C++ heap through V8's Isolate.
-      "//v8",
-    ]
-  } else {
-    sources += [
-      "impl/atomic_entry_flag.h",
-      "impl/blink_gc.cc",
-      "impl/blink_gc.h",
-      "impl/blink_gc_memory_dump_provider.cc",
-      "impl/blink_gc_memory_dump_provider.h",
-      "impl/collection_support/heap_hash_table_backing.h",
-      "impl/collection_support/heap_vector_backing.h",
-      "impl/finalizer_traits.h",
-      "impl/garbage_collected.h",
-      "impl/gc_info.cc",
-      "impl/gc_info.h",
-      "impl/heap.cc",
-      "impl/heap.h",
-      "impl/heap_allocator_impl.cc",
-      "impl/heap_allocator_impl.h",
-      "impl/heap_compact.cc",
-      "impl/heap_compact.h",
-      "impl/heap_page.cc",
-      "impl/heap_page.h",
-      "impl/heap_stats_collector.cc",
-      "impl/heap_stats_collector.h",
-      "impl/marking_scheduling_oracle.cc",
-      "impl/marking_scheduling_oracle.h",
-      "impl/marking_verifier.cc",
-      "impl/marking_verifier.h",
-      "impl/marking_visitor.cc",
-      "impl/marking_visitor.h",
-      "impl/member.h",
-      "impl/name_traits.h",
-      "impl/page_bloom_filter.h",
-      "impl/page_memory.cc",
-      "impl/page_memory.h",
-      "impl/page_pool.cc",
-      "impl/page_pool.h",
-      "impl/persistent.h",
-      "impl/persistent_node.cc",
-      "impl/persistent_node.h",
-      "impl/process_heap.cc",
-      "impl/process_heap.h",
-      "impl/thread_state.cc",
-      "impl/thread_state.h",
-      "impl/thread_state_scopes.h",
-      "impl/thread_state_statistics.cc",
-      "impl/thread_state_statistics.h",
-      "impl/threading_traits.h",
-      "impl/trace_traits.h",
-      "impl/unified_heap_controller.cc",
-      "impl/unified_heap_controller.h",
-      "impl/unified_heap_marking_visitor.cc",
-      "impl/unified_heap_marking_visitor.h",
-      "impl/visitor.h",
-      "impl/worklist.h",
-    ]
-  }
+    # Dependency on V8 which transitively depends on cppgc but exposes
+    # JS-related C++ heap through V8's Isolate.
+    "//v8",
+  ]
 
   if (!is_debug && !optimize_for_size) {
     configs -= [ "//build/config/compiler:default_optimization" ]
@@ -210,17 +144,10 @@
     "heap_test_utilities.h",
   ]
 
-  if (enable_blink_heap_use_v8_oilpan) {
-    sources += [
-      "v8_wrapper/heap_test_utilities.cc",
-      "v8_wrapper/heap_test_utilities.h",
-    ]
-  } else {
-    sources += [
-      "impl/heap_test_utilities.cc",
-      "impl/heap_test_utilities.h",
-    ]
-  }
+  sources += [
+    "v8_wrapper/heap_test_utilities.cc",
+    "v8_wrapper/heap_test_utilities.h",
+  ]
 
   deps = [
     ":blink_heap_buildflags",
@@ -228,15 +155,12 @@
     "//third_party/blink/public/mojom:mojom_platform_blink_headers",
     "//third_party/blink/renderer/platform:bindings_buildflags",
     "//third_party/blink/renderer/platform:platform",
-    "//third_party/blink/renderer/platform/wtf:buildflags",
   ]
 
   # TODO(v8:11952): Switch to `//v8:v8_for_testing` as target once it properly
   # depends on v8 without duplicating the whole library which causes ODR
   # violations when `//v8:v8` is also pulled in otherwise.
-  if (enable_blink_heap_use_v8_oilpan) {
-    deps += [ "//v8:v8" ]
-  }
+  deps += [ "//v8:v8" ]
 
   public_deps = [ "//base/test:test_support" ]
 }
@@ -253,7 +177,7 @@
     ]
   }
 
-  if (is_fuchsia && enable_blink_heap_use_v8_oilpan) {
+  if (is_fuchsia) {
     # Oilpan reuses V8's v8::PageAllocator which generally requires JIT
     # permissions.
     additional_manifest_fragments =
@@ -280,23 +204,6 @@
     "test/write_barrier_perftest.cc",
   ]
 
-  if (!enable_blink_heap_use_v8_oilpan) {
-    sources += [
-      "impl/test/card_table_test.cc",
-      "impl/test/gc_info_test.cc",
-      "impl/test/heap_internals_test.cc",
-      "impl/test/heap_stats_collector_test.cc",
-      "impl/test/heap_thread_test.cc",
-      "impl/test/incremental_marking_internals_test.cc",
-      "impl/test/marking_scheduling_oracle_test.cc",
-      "impl/test/marking_verifier_test.cc",
-      "impl/test/name_trait_test.cc",
-      "impl/test/object_start_bitmap_test.cc",
-      "impl/test/thread_state_scheduling_test.cc",
-      "impl/test/worklist_test.cc",
-    ]
-  }
-
   if (enable_blink_heap_young_generation) {
     sources += [ "test/minor_gc_test.cc" ]
   }
diff --git a/third_party/blink/renderer/platform/heap/asm/BUILD.gn b/third_party/blink/renderer/platform/heap/asm/BUILD.gn
deleted file mode 100644
index fe44daf..0000000
--- a/third_party/blink/renderer/platform/heap/asm/BUILD.gn
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-if (current_cpu == "x86" || current_cpu == "x64") {
-  import("//third_party/nasm/nasm_assemble.gni")
-
-  nasm_assemble("asm") {
-    assert(current_cpu == "x86" || current_cpu == "x64")
-
-    sources = [ "SaveRegisters_x86.asm" ]
-
-    defines = []
-    if (is_mac) {
-      # Necessary to ensure symbols end up with a _ prefix; added by
-      # yasm_compile.gypi for Windows, but not Mac.
-      defines += [ "PREFIX" ]
-    }
-    if (current_cpu == "x64") {
-      if (is_win) {
-        defines += [ "X64WIN=1" ]
-      } else {
-        defines += [ "X64POSIX=1" ]
-      }
-    } else {  # current_cpu == "x86"
-      defines += [ "IA32=1" ]
-    }
-  }
-} else {  # current_cpu == "x86" || current_cpu == "x64"
-  source_set("asm") {
-    if (current_cpu == "arm") {
-      sources = [ "SaveRegisters_arm.S" ]
-    } else if (current_cpu == "arm64") {
-      sources = [ "SaveRegisters_arm64.S" ]
-    } else if (current_cpu == "mipsel") {
-      sources = [ "SaveRegisters_mips.S" ]
-    } else if (current_cpu == "mips64el") {
-      sources = [ "SaveRegisters_mips64.S" ]
-    } else if (current_cpu == "ppc64") {
-      sources = [ "SaveRegisters_ppc64.S" ]
-    }
-
-    if (current_cpu == "arm") {
-      defines = [ "ARM=1" ]
-    }
-  }
-}  # current_cpu == "x86" || current_cpu == "x64"
diff --git a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_arm.S b/third_party/blink/renderer/platform/heap/asm/SaveRegisters_arm.S
deleted file mode 100644
index a869228..0000000
--- a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_arm.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/*
- * typedef void (*PushAllRegistersCallback)(ThreadState*, intptr_t*);
- * extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback)
- */
-
-.type PushAllRegisters, %function
-.global PushAllRegisters
-.hidden PushAllRegisters
-#ifdef __thumb__
-/* In THUMB Mode jump to ARM stub via bx to ensure CPU mode switch.
- * FIXME: This trampoline is provided to workaround bugs in
- * the THUMB/ARM interworking that appear in the component build.
- * When these issues are resolved this stub can be removed.
- */
-.align 2
-.code 16
-.thumb_func
-PushAllRegisters:
-        adr r3, pushAllRegistersARM
-        bx r3
-
-.type pushAllRegistersARM, %function
-.hidden pushAllRegistersARM
-.align 4
-.code 32
-pushAllRegistersARM:
-#else
-/* ARM Mode */
-.align 4
-.code 32
-PushAllRegisters:
-#endif
-        /* Push all callee-saved registers and save return address. */
-        push {r4-r11, lr}
-        /* Pass the first argument unchanged (r0)
-         * and pass the stack pointer after pushing callee-saved
-         * registers to the callback function.
-         */
-        mov r2, r1
-        mov r1, sp
-        blx r2
-        /* Discard all the registers, and pop lr into pc which returns
-         * and switches mode if needed.
-         */
-        add sp, sp, #32
-        pop {pc}
diff --git a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_arm64.S b/third_party/blink/renderer/platform/heap/asm/SaveRegisters_arm64.S
deleted file mode 100644
index db13c5d..0000000
--- a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_arm64.S
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/*
- * typedef void (*PushAllRegistersCallback)(ThreadState*, intptr_t*);
- * extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback)
- */
-
-/* Supplementary macro for setting function attributes */
-.macro asm_function fname
-#ifdef __APPLE__
-    .globl _\fname
-    .private_extern _\fname
-_\fname:
-#else
-    .global \fname
-#ifdef __ELF__
-    .hidden \fname
-    .type \fname, %function
-#endif
-\fname:
-#endif
-.endm
-
-#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT
-    // ENABLE_PAUTH must be defined to 1 since this value will be used in
-    // bitwise-shift later!
-    #define ENABLE_PAUTH 1
-
-    #if ((__ARM_FEATURE_PAC_DEFAULT&((1<<0)|(1<<1)))==0)
-        #error Pointer authentication defines no valid key!
-    #endif
-#else
-    #define ENABLE_PAUTH 0
-#endif
-
-#if defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT==1)
-    // ENABLE_BTI must be defined to 1 since this value will be used in
-    // bitwise-shift later!
-    #define ENABLE_BTI 1
-#else
-    #define ENABLE_BTI 0
-#endif
-
-
-// Although Pointer Authentication and Branch Target Instructions are technically
-// seperate features they work together, i.e. the paciasp and pacibsp instructions
-// serve as BTI landing pads.
-// Therefore PA-instructions are enabled when PA _or_ BTI is enabled!
-#if ENABLE_PAUTH || ENABLE_BTI
-    // See section "Pointer Authentication" of
-    // https://developer.arm.com/documentation/101028/0012/5--Feature-test-macros
-    // for details how to interpret __ARM_FEATURE_PAC_DEFAULT
-    #if (__ARM_FEATURE_PAC_DEFAULT & (1<<0))
-        #define PAUTH_SIGN_SP paciasp
-        #define PAUTH_AUTH_SP autiasp
-    #else
-        #define PAUTH_SIGN_SP pacibsp
-        #define PAUTH_AUTH_SP autibsp
-    #endif
-#else
-    #define PAUTH_SIGN_SP
-    #define PAUTH_AUTH_SP
-#endif
-
-
-
-asm_function PushAllRegisters
-        .p2align 2
-
-        PAUTH_SIGN_SP
-
-        /* Save return address. */
-        sub sp, sp, #96
-        stp x19, x20, [sp, #80]
-        stp x21, x22, [sp, #64]
-        stp x23, x24, [sp, #48]
-        stp x25, x26, [sp, #32]
-        stp x27, x28, [sp, #16]
-        stp x30, x29, [sp, #0]  // x30 is lr.
-
-        /* Pass the first argument unchanged (x0)
-         * and pass the stack pointer as third argument to the
-         * callback function.
-         */
-        mov x2, x1
-        mov x1, sp
-        blr x2
-
-        /* We don't restore all registers since they are callee saved (so
-         * the callback didn't clobber them) and we didn't modify them either.
-         */
-        ldr x30, [sp], #96
-
-        PAUTH_AUTH_SP
-
-        ret
-
-#if ENABLE_PAUTH || ENABLE_BTI
-// see
-// https://github.com/ARM-software/abi-aa/blob/main/aaelf64/aaelf64.rst#program-property
-.pushsection .note.gnu.property, "a";
-    .balign 8
-    .long 4
-    .long 0x10
-    .long 0x5
-    .asciz "GNU"
-    .long 0xc0000000 /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */
-    .long 4
-    .long ((ENABLE_PAUTH)<<1) | ((ENABLE_BTI)<<0) /* PAuth and BTI */
-    .long 0
-.popsection
-#endif
diff --git a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_mips.S b/third_party/blink/renderer/platform/heap/asm/SaveRegisters_mips.S
deleted file mode 100644
index 5c2e717a..0000000
--- a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_mips.S
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/*
- * typedef void (*PushAllRegistersCallback)(ThreadState*, intptr_t*);
- * extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback)
- */
-
-.type PushAllRegisters, %function
-.global PushAllRegisters
-.hidden PushAllRegisters
-PushAllRegisters:
-        // Reserve space for callee-saved registers, return address,
-        // as well as for the callee arguments.
-        addiu $sp,$sp,-56
-        // Save the callee-saved registers and the return address.
-        sw $s0,16($sp)
-        sw $s1,20($sp)
-        sw $s2,24($sp)
-        sw $s3,28($sp)
-        sw $s4,32($sp)
-        sw $s5,36($sp)
-        sw $s6,40($sp)
-        sw $s7,44($sp)
-        sw $ra,48($sp)
-        // Pass the first argument untouched in a0 and the
-        // stack pointer to the callback.
-        move $t9,$a1
-        move $a1,$sp
-        jalr $t9
-        // Restore return address, adjust stack and return. No
-        // callee-saved register was changed so we do not have to
-        // restore callee-saved registers.
-        lw $ra,48($sp)
-        addiu $sp,$sp,56
-        jr $ra
diff --git a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_mips64.S b/third_party/blink/renderer/platform/heap/asm/SaveRegisters_mips64.S
deleted file mode 100644
index 656cfb5..0000000
--- a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_mips64.S
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/*
- * typedef void (*PushAllRegistersCallback)(ThreadState*, intptr_t*);
- * extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback)
- */
-
-.type PushAllRegisters, %function
-.global PushAllRegisters
-.hidden PushAllRegisters
-PushAllRegisters:
-        // Push all callee-saves registers to get them
-        // on the stack for conservative stack scanning.
-        // Reserve space for callee-saved registers and return address.
-        daddiu $sp,$sp,-80
-        // Save the callee-saved registers and the return address.
-        sd $s0,0($sp)
-        sd $s1,8($sp)
-        sd $s2,16($sp)
-        sd $s3,24($sp)
-        sd $s4,32($sp)
-        sd $s5,40($sp)
-        sd $s6,48($sp)
-        sd $s7,56($sp)
-        sd $ra,64($sp)
-        // Note: the callee-saved floating point registers do not need to be
-        // copied to the stack, because fp registers never hold heap pointers
-        // and so do not need to be kept visible to the garbage collector.
-        // Pass the first argument untouched in a0 and the
-        // stack pointer to the callback.
-        move $t9,$a1
-        move $a1,$sp
-        jalr $t9
-        // Restore return address, adjust stack and return.
-        // Note: the copied registers do not need to be reloaded here,
-        // because they were preserved by the called routine.
-        ld $ra,64($sp)
-        daddiu $sp,$sp,80
-        jr $ra
diff --git a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_ppc64.S b/third_party/blink/renderer/platform/heap/asm/SaveRegisters_ppc64.S
deleted file mode 100644
index ef6c3326e..0000000
--- a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_ppc64.S
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * typedef void (*PushAllRegistersCallback)(ThreadState*, intptr_t*);
- * extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback)
- */
-
-.type PushAllRegisters, %function
-.global PushAllRegisters
-.hidden PushAllRegisters
-PushAllRegisters:
-        // Push all callee-saves registers to get them
-        // on the stack for conservative stack scanning.
-        // Reserve space for callee-saved registers and minimal stack frame.
-        mflr 0
-        std 0,16(1)
-        stdu 1,-176(1) // 3218*8 = min stack  non-volatile registers
-
-        // Save the callee-saved register
-        std 31,168(1)
-        std 30,160(1)
-        std 29,152(1)
-        std 28,144(1)
-        std 27,136(1)
-        std 26,128(1)
-        std 25,120(1)
-        std 24,112(1)
-        std 23,104(1)
-        std 22,96(1)
-        std 21,88(1)
-        std 20,80(1)
-        std 19,72(1)
-        std 18,64(1)
-        std 17,56(1)
-        std 16,48(1)
-        std 15,40(1)
-        std 14,32(1)
-        // Note: the callee-saved floating point registers do not need to be
-        // copied to the stack, because fp registers never hold heap pointers
-        // and so do not need to be kept visible to the garbage collector.
-        // Pass the first argument untouched in r3 and the
-        // stack pointer to the callback.
-        std 2, 24(1)
-        mtctr 4
-        mr 12, 4
-        mr 4, 1
-        bctrl
-        ld 2, 24(1)
-
-        // Adjust stack, restore return address and return.
-        // Note: the copied registers do not need to be reloaded here,
-        // because they were preserved by the called routine.
-        addi 1,1,176
-        ld 0,16(1)
-        mtlr 0
-        blr
diff --git a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_x86.asm b/third_party/blink/renderer/platform/heap/asm/SaveRegisters_x86.asm
deleted file mode 100644
index 9b23c82..0000000
--- a/third_party/blink/renderer/platform/heap/asm/SaveRegisters_x86.asm
+++ /dev/null
@@ -1,162 +0,0 @@
-;; Copyright (C) 2013 Google Inc. All rights reserved.
-;;
-;; Redistribution and use in source and binary forms, with or without
-;; modification, are permitted provided that the following conditions are
-;; met:
-;;
-;;     * Redistributions of source code must retain the above copyright
-;; notice, this list of conditions and the following disclaimer.
-;;     * Redistributions in binary form must reproduce the above
-;; copyright notice, this list of conditions and the following disclaimer
-;; in the documentation and/or other materials provided with the
-;; distribution.
-;;     * Neither the name of Google Inc. nor the names of its
-;; contributors may be used to endorse or promote products derived from
-;; this software without specific prior written permission.
-;;
-;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-;; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-;; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-;; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-;; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-;;
-
-%ifndef X64POSIX
-%define X64POSIX 0
-%endif
-
-%ifndef X64WIN
-%define X64WIN 0
-%endif
-
-%ifndef IA32
-%define IA32 0
-%endif
-
-%ifndef ARM
-%define ARM 0
-%endif
-
-;; Prefix symbols by '_' if PREFIX is defined.
-%ifdef PREFIX
-%define mangle(x) _ %+ x
-%else
-%define mangle(x) x
-%endif
-
-
-; global_private makes a symbol a global but private to this shared library.
-%ifidn   __OUTPUT_FORMAT__,elf32
-  %define global_private(x) global mangle(x) %+ :function hidden
-%elifidn __OUTPUT_FORMAT__,elf64
-  %define global_private(x) global mangle(x) %+ :function hidden
-%elifidn __OUTPUT_FORMAT__,elfx32
-  %define global_private(x) global mangle(x) %+ :function hidden
-%elifidn __OUTPUT_FORMAT__,macho32
-  %define global_private(x) global mangle(x) %+ :private_extern
-%elifidn __OUTPUT_FORMAT__,macho64
-  %define global_private(x) global mangle(x) %+ :private_extern
-%else
-  %define global_private(x) global mangle(x)
-%endif
-
-section .text
-
-;; typedef void (*PushAllRegistersCallback)(ThreadState*, intptr_t*);
-;; extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback)
-
-        global_private(PushAllRegisters)
-
-%if X64POSIX
-
-mangle(PushAllRegisters):
-        ;; Push all callee-saves registers to get them
-        ;; on the stack for conservative stack scanning.
-        ;; We maintain 16-byte alignment at calls (required on Mac).
-        ;; There is an 8-byte return address on the stack and we push
-        ;; 56 bytes which maintains 16-byte stack alignment
-        ;; at the call.
-        push 0
-        push rbx
-        push rbp
-        push r12
-        push r13
-        push r14
-        push r15
-        ;; Pass the first argument unchanged (rdi)
-        ;; and the stack pointer after pushing callee-saved
-        ;; registers to the callback.
-        mov r8, rsi
-        mov rsi, rsp
-        call r8
-        ;; Pop the callee-saved registers. None of them were
-        ;; modified so no restoring is needed.
-        add rsp, 56
-        ret
-
-%elif X64WIN
-
-mangle(PushAllRegisters):
-        ;; Push all callee-saves registers to get them
-        ;; on the stack for conservative stack scanning.
-        ;; There is an 8-byte return address on the stack and we push
-        ;; 72 bytes which maintains the required 16-byte stack alignment
-        ;; at the call.
-        push 0
-        push rsi
-        push rdi
-        push rbx
-        push rbp
-        push r12
-        push r13
-        push r14
-        push r15
-        ;; Pass the first argument unchanged (rcx)
-        ;; and the stack pointer after pushing callee-saved
-        ;; registers to the callback.
-        mov r9, rdx
-        mov rdx, rsp
-        call r9
-        ;; Pop the callee-saved registers. None of them were
-        ;; modified so no restoring is needed.
-        add rsp, 72
-        ret
-
-%elif IA32
-
-mangle(PushAllRegisters):
-        ;; Push all callee-saves registers to get them
-        ;; on the stack for conservative stack scanning.
-        ;; We maintain 16-byte alignment at calls (required on
-        ;; Mac). There is a 4-byte return address on the stack
-        ;; and we push 28 bytes which maintains 16-byte alignment
-        ;; at the call.
-        push ebx
-        push ebp
-        push esi
-        push edi
-        ;; Pass the first argument unchanged and the
-        ;; stack pointer after pushing callee-save registers
-        ;; to the callback.
-        mov ecx, [esp + 24]
-        push esp
-        push dword [esp + 24]
-        call ecx
-        ;; Pop arguments and the callee-saved registers.
-        ;; None of the callee-saved registers were modified
-        ;; so we do not need to restore them.
-        add esp, 24
-        ret
-
-
-%elif ARM
-%error "NASM does not support arm. Use SaveRegisters_arm.S on arm."
-%else
-%error "Unsupported platform."
-%endif
diff --git a/third_party/blink/renderer/platform/heap/blink_gc.h b/third_party/blink/renderer/platform/heap/blink_gc.h
index 227089f..28a94f0 100644
--- a/third_party/blink/renderer/platform/heap/blink_gc.h
+++ b/third_party/blink/renderer/platform/heap/blink_gc.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/blink_gc.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_H_
diff --git a/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h b/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h
index 3e6f4c2f..9ae4b7d 100644
--- a/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h
+++ b/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/blink_gc_memory_dump_provider.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
index f1c4c969..d21c4780 100644
--- a/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
+++ b/third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h
@@ -7,13 +7,8 @@
 
 #include "third_party/blink/renderer/platform/heap/trace_traits.h"
 #include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_hash_table_backing.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/collection_support/heap_hash_table_backing.h"
-#endif  // !USE_V8_OILPAN
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h b/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
index 0a29da5..7f7f24a 100644
--- a/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
+++ b/third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/collection_support/heap_vector_backing.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
diff --git a/third_party/blink/renderer/platform/heap/custom_spaces.h b/third_party/blink/renderer/platform/heap/custom_spaces.h
index 0ce834e3..7b98bda 100644
--- a/third_party/blink/renderer/platform/heap/custom_spaces.h
+++ b/third_party/blink/renderer/platform/heap/custom_spaces.h
@@ -5,10 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CUSTOM_SPACES_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CUSTOM_SPACES_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/custom_spaces.h"
-#endif  // USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_CUSTOM_SPACES_H_
diff --git a/third_party/blink/renderer/platform/heap/forward.h b/third_party/blink/renderer/platform/heap/forward.h
index 18a9238..1fb813f 100644
--- a/third_party/blink/renderer/platform/heap/forward.h
+++ b/third_party/blink/renderer/platform/heap/forward.h
@@ -5,10 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FORWARD_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FORWARD_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
-
 namespace cppgc {
 class Visitor;
 }
@@ -19,14 +15,4 @@
 
 }  // namespace blink
 
-#else  // !USE_V8_OILPAN
-
-namespace blink {
-
-class Visitor;
-
-}  // namespace blink
-
-#endif  // !USE_V8_OILPAN
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FORWARD_H_
diff --git a/third_party/blink/renderer/platform/heap/garbage_collected.h b/third_party/blink/renderer/platform/heap/garbage_collected.h
index 0226743..9b81a6c4 100644
--- a/third_party/blink/renderer/platform/heap/garbage_collected.h
+++ b/third_party/blink/renderer/platform/heap/garbage_collected.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/garbage_collected.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/garbage_collected.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GARBAGE_COLLECTED_H_
diff --git a/third_party/blink/renderer/platform/heap/heap.h b/third_party/blink/renderer/platform/heap/heap.h
index 530b1f79..cb41e7e6 100644
--- a/third_party/blink/renderer/platform/heap/heap.h
+++ b/third_party/blink/renderer/platform/heap/heap.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/heap.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/heap.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_H_
diff --git a/third_party/blink/renderer/platform/heap/heap_allocator.h b/third_party/blink/renderer/platform/heap/heap_allocator.h
index 7f72942..989490e 100644
--- a/third_party/blink/renderer/platform/heap/heap_allocator.h
+++ b/third_party/blink/renderer/platform/heap/heap_allocator.h
@@ -13,6 +13,5 @@
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_hash_set.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_ALLOCATOR_H_
diff --git a/third_party/blink/renderer/platform/heap/heap_allocator_impl.h b/third_party/blink/renderer/platform/heap/heap_allocator_impl.h
index e05ca5d..b67be25 100644
--- a/third_party/blink/renderer/platform/heap/heap_allocator_impl.h
+++ b/third_party/blink/renderer/platform/heap/heap_allocator_impl.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_ALLOCATOR_IMPL_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_ALLOCATOR_IMPL_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/heap_allocator_impl.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/heap_allocator_impl.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_ALLOCATOR_IMPL_H_
diff --git a/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
index 4b7f0657..3cda388 100644
--- a/third_party/blink/renderer/platform/heap/heap_stats_collector.h
+++ b/third_party/blink/renderer/platform/heap/heap_stats_collector.h
@@ -5,10 +5,4 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if !BUILDFLAG(USE_V8_OILPAN)
-#include "third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h"
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_
diff --git a/third_party/blink/renderer/platform/heap/heap_test_utilities.h b/third_party/blink/renderer/platform/heap/heap_test_utilities.h
index 3c5be39..8461f8af 100644
--- a/third_party/blink/renderer/platform/heap/heap_test_utilities.h
+++ b/third_party/blink/renderer/platform/heap/heap_test_utilities.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_TEST_UTILITIES_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_TEST_UTILITIES_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/heap_test_utilities.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/heap_test_utilities.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_TEST_UTILITIES_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/atomic_entry_flag.h b/third_party/blink/renderer/platform/heap/impl/atomic_entry_flag.h
deleted file mode 100644
index 46342d94..0000000
--- a/third_party/blink/renderer/platform/heap/impl/atomic_entry_flag.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_ATOMIC_ENTRY_FLAG_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_ATOMIC_ENTRY_FLAG_H_
-
-#include <atomic>
-
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-// A flag which provides a fast check whether a scope may be entered on the
-// current thread, without needing to access thread-local storage or mutex.
-//
-// Can have false positives (i.e., spuriously report that it might be entered),
-// so it is expected that this will be used in tandem with a precise check that
-// the scope is in fact entered on that thread.
-//
-// Example:
-//   g_frobnicating_flag.MightBeEntered() &&
-//   ThreadLocalFrobnicator().IsFrobnicating()
-//
-// Relaxed atomic operations are sufficient, since:
-// - all accesses remain atomic
-// - each thread must observe its own operations in order
-// - no thread ever exits the flag more times than it enters (if used correctly)
-// And so if a thread observes zero, it must be because it has observed an equal
-// number of exits as entries.
-class AtomicEntryFlag {
-  DISALLOW_NEW();
-
- public:
-  inline void Enter() { entries_.fetch_add(1, std::memory_order_relaxed); }
-  inline void Exit() { entries_.fetch_sub(1, std::memory_order_relaxed); }
-
-  // Returns false only if the current thread is not between a call to Enter and
-  // a call to Exit. Returns true if this thread or another thread may currently
-  // be in the scope guarded by this flag.
-  inline bool MightBeEntered() const {
-    return entries_.load(std::memory_order_relaxed) != 0;
-  }
-
- private:
-  std::atomic_int entries_{0};
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_ATOMIC_ENTRY_FLAG_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/blink_gc.cc b/third_party/blink/renderer/platform/heap/impl/blink_gc.cc
deleted file mode 100644
index 58c86eb..0000000
--- a/third_party/blink/renderer/platform/heap/impl/blink_gc.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-
-namespace blink {
-
-const char* BlinkGC::ToString(BlinkGC::GCReason reason) {
-  switch (reason) {
-    case BlinkGC::GCReason::kForcedGCForTesting:
-      return "ForcedGCForTesting";
-    case BlinkGC::GCReason::kThreadTerminationGC:
-      return "ThreadTerminationGC";
-    case BlinkGC::GCReason::kUnifiedHeapGC:
-      return "UnifiedHeapGC";
-    case BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC:
-      return "UnifiedHeapForMemoryReductionGC";
-    case BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC:
-      return "UnifiedHeapForcedForTestingGC";
-  }
-  IMMEDIATE_CRASH();
-}
-
-const char* BlinkGC::ToString(BlinkGC::MarkingType type) {
-  switch (type) {
-    case BlinkGC::MarkingType::kAtomicMarking:
-      return "AtomicMarking";
-    case BlinkGC::MarkingType::kIncrementalAndConcurrentMarking:
-      return "IncrementalAndConcurrentMarking";
-  }
-  IMMEDIATE_CRASH();
-}
-
-const char* BlinkGC::ToString(BlinkGC::SweepingType type) {
-  switch (type) {
-    case BlinkGC::SweepingType::kConcurrentAndLazySweeping:
-      return "ConcurrentAndLazySweeping";
-    case BlinkGC::SweepingType::kEagerSweeping:
-      return "EagerSweeping";
-  }
-  IMMEDIATE_CRASH();
-}
-
-const char* BlinkGC::ToString(BlinkGC::StackState stack_state) {
-  switch (stack_state) {
-    case BlinkGC::kNoHeapPointersOnStack:
-      return "NoHeapPointersOnStack";
-    case BlinkGC::kHeapPointersOnStack:
-      return "HeapPointersOnStack";
-  }
-  IMMEDIATE_CRASH();
-}
-
-const char* BlinkGC::ToString(BlinkGC::ArenaIndices arena_index) {
-#define ArenaCase(name)     \
-  case k##name##ArenaIndex: \
-    return "" #name "Arena";
-
-  switch (arena_index) {
-    FOR_EACH_ARENA(ArenaCase)
-
-    case BlinkGC::ArenaIndices::kNumberOfArenas:
-      IMMEDIATE_CRASH();
-  }
-  IMMEDIATE_CRASH();
-
-#undef ArenaCase
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/blink_gc.h b/third_party/blink/renderer/platform/heap/impl/blink_gc.h
deleted file mode 100644
index bb35f79..0000000
--- a/third_party/blink/renderer/platform/heap/impl/blink_gc.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_H_
-
-// BlinkGC.h is a file that defines common things used by Blink GC.
-
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-#define PRINT_HEAP_STATS 0  // Enable this macro to print heap stats to stderr.
-
-namespace blink {
-
-class LivenessBroker;
-class MarkingVisitor;
-class Visitor;
-
-using Address = uint8_t*;
-using ConstAddress = const uint8_t*;
-
-using VisitorCallback = void (*)(Visitor*, const void*);
-using MarkingVisitorCallback = void (*)(MarkingVisitor*, const void*);
-using TraceCallback = VisitorCallback;
-using WeakCallback = void (*)(const LivenessBroker&, const void*);
-using EphemeronCallback = VisitorCallback;
-
-// Simple alias to avoid heap compaction type signatures turning into
-// a sea of generic |void*|s.
-using MovableReference = const void*;
-
-// List of all arenas. Includes typed arenas as well.
-#define FOR_EACH_ARENA(H) \
-  H(NormalPage1)          \
-  H(NormalPage2)          \
-  H(NormalPage3)          \
-  H(NormalPage4)          \
-  H(Vector)               \
-  H(HashTable)            \
-  H(Node)                 \
-  H(CSSValue)             \
-  H(LayoutObject)         \
-  H(LargeObject)
-
-class PLATFORM_EXPORT WorklistTaskId {
- public:
-  static constexpr int MutatorThread = 0;
-  static constexpr int ConcurrentThreadBase = 1;
-};
-
-class PLATFORM_EXPORT BlinkGC final {
-  STATIC_ONLY(BlinkGC);
-
- public:
-  // CollectionType represents generational collection. kMinor collects objects
-  // in the young generation (i.e. allocated since the previous collection
-  // cycle, since we use sticky bits), kMajor collects the entire heap.
-  enum class CollectionType { kMinor, kMajor };
-
-  // When garbage collecting we need to know whether or not there
-  // can be pointers to Blink GC managed objects on the stack for
-  // each thread. When threads reach a safe point they record
-  // whether or not they have pointers on the stack.
-  enum StackState { kNoHeapPointersOnStack, kHeapPointersOnStack };
-
-  enum MarkingType {
-    // The marking completes synchronously.
-    kAtomicMarking,
-    // The marking task is split and executed in chunks (either on the mutator
-    // thread or concurrently).
-    kIncrementalAndConcurrentMarking
-  };
-
-  enum SweepingType {
-    // The sweeping task is split into chunks and scheduled lazily and
-    // concurrently.
-    kConcurrentAndLazySweeping,
-    // The sweeping task executes synchronously right after marking.
-    kEagerSweeping,
-  };
-
-  // Commented out reasons have been used in the past but are not used any
-  // longer. We keep them here as the corresponding UMA histograms cannot be
-  // changed.
-  enum class GCReason {
-    // kIdleGC = 0
-    // kPreciseGC = 1
-    // kConservativeGC = 2
-    kForcedGCForTesting = 3,
-    // kMemoryPressureGC = 4
-    // kPageNavigationGC = 5
-    kThreadTerminationGC = 6,
-    // kTesting = 7
-    // kIncrementalIdleGC = 8
-    // kIncrementalV8FollowupGC = 9
-    kUnifiedHeapGC = 10,
-    kUnifiedHeapForMemoryReductionGC = 11,
-    kUnifiedHeapForcedForTestingGC = 12,
-    // Used by UMA_HISTOGRAM_ENUMERATION macro.
-    kMaxValue = kUnifiedHeapForcedForTestingGC,
-  };
-
-#define DeclareArenaIndex(name) k##name##ArenaIndex,
-  enum ArenaIndices {
-    FOR_EACH_ARENA(DeclareArenaIndex)
-    // Values used for iteration of heap segments.
-    kNumberOfArenas,
-  };
-#undef DeclareArenaIndex
-
-  enum V8GCType {
-    kV8MinorGC,
-    kV8MajorGC,
-  };
-
-  static const char* ToString(GCReason);
-  static const char* ToString(MarkingType);
-  static const char* ToString(StackState);
-  static const char* ToString(SweepingType);
-  static const char* ToString(ArenaIndices);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.cc b/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.cc
deleted file mode 100644
index cb8ce72..0000000
--- a/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
-
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/memory_allocator_dump.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-#include "third_party/blink/renderer/platform/wtf/threading.h"
-
-namespace blink {
-namespace {
-
-constexpr const char* HeapTypeString(
-    BlinkGCMemoryDumpProvider::HeapType heap_type) {
-  switch (heap_type) {
-    case BlinkGCMemoryDumpProvider::HeapType::kBlinkMainThread:
-      return "main";
-    case BlinkGCMemoryDumpProvider::HeapType::kBlinkWorkerThread:
-      return "workers";
-  }
-}
-
-}  // namespace
-
-BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider(
-    ThreadState* thread_state,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    BlinkGCMemoryDumpProvider::HeapType heap_type)
-    : thread_state_(thread_state),
-      heap_type_(heap_type),
-      dump_base_name_(
-          "blink_gc/" + std::string(HeapTypeString(heap_type_)) + "/heap" +
-          (heap_type_ == HeapType::kBlinkWorkerThread
-               ? "/" + base::StringPrintf(
-                           "worker_0x%" PRIXPTR,
-                           reinterpret_cast<uintptr_t>(thread_state_))
-               : "")) {
-  base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
-      this, "BlinkGC", task_runner);
-}
-
-BlinkGCMemoryDumpProvider::~BlinkGCMemoryDumpProvider() {
-  base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
-      this);
-}
-
-bool BlinkGCMemoryDumpProvider::OnMemoryDump(
-    const base::trace_event::MemoryDumpArgs& args,
-    base::trace_event::ProcessMemoryDump* process_memory_dump) {
-  ThreadState::Statistics::DetailLevel detail_level =
-      args.level_of_detail ==
-              base::trace_event::MemoryDumpLevelOfDetail::DETAILED
-          ? ThreadState::Statistics::kDetailed
-          : ThreadState::Statistics::kBrief;
-
-  ThreadState::Statistics stats =
-      ThreadState::StatisticsCollector(thread_state_)
-          .CollectStatistics(detail_level);
-
-  auto* heap_dump = process_memory_dump->CreateAllocatorDump(dump_base_name_);
-  heap_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
-                       base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                       stats.committed_size_bytes);
-  heap_dump->AddScalar("allocated_objects_size",
-                       base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                       stats.used_size_bytes);
-
-  if (detail_level == ThreadState::Statistics::kBrief) {
-    return true;
-  }
-
-  // Detailed statistics.
-  for (const ThreadState::Statistics::ArenaStatistics& arena_stats :
-       stats.arena_stats) {
-    std::string arena_dump_name = dump_base_name_ + "/" + arena_stats.name;
-    auto* arena_dump =
-        process_memory_dump->CreateAllocatorDump(arena_dump_name);
-    arena_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
-                          base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                          arena_stats.committed_size_bytes);
-    arena_dump->AddScalar("allocated_objects_size",
-                          base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                          arena_stats.used_size_bytes);
-
-    size_t page_count = 0;
-    for (const ThreadState::Statistics::PageStatistics& page_stats :
-         arena_stats.page_stats) {
-      auto* page_dump = process_memory_dump->CreateAllocatorDump(
-          arena_dump_name + "/pages/page_" +
-          base::NumberToString(page_count++));
-      page_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
-                           base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                           page_stats.committed_size_bytes);
-      page_dump->AddScalar("allocated_objects_size",
-                           base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                           page_stats.used_size_bytes);
-    }
-
-    const ThreadState::Statistics::FreeListStatistics& free_list_stats =
-        arena_stats.free_list_stats;
-    for (wtf_size_t i = 0; i < free_list_stats.bucket_size.size(); ++i) {
-      constexpr size_t kDigits = 8;
-      std::string original_bucket_size =
-          base::NumberToString(free_list_stats.bucket_size[i]);
-      std::string padded_bucket_size =
-          std::string(kDigits - original_bucket_size.length(), '0') +
-          original_bucket_size;
-      auto* free_list_bucket_dump = process_memory_dump->CreateAllocatorDump(
-          arena_dump_name + "/freelist/bucket_" + padded_bucket_size);
-      free_list_bucket_dump->AddScalar(
-          "free_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-          free_list_stats.free_size[i]);
-    }
-
-    const ThreadState::Statistics::ObjectStatistics& object_stats =
-        arena_stats.object_stats;
-    for (wtf_size_t i = 1; i < object_stats.num_types; i++) {
-      if (object_stats.type_name[i].empty())
-        continue;
-
-      auto* class_dump = process_memory_dump->CreateAllocatorDump(
-          arena_dump_name + "/classes/" + object_stats.type_name[i]);
-      class_dump->AddScalar(
-          "object_count", base::trace_event::MemoryAllocatorDump::kUnitsObjects,
-          object_stats.type_count[i]);
-      class_dump->AddScalar("object_size",
-                            base::trace_event::MemoryAllocatorDump::kUnitsBytes,
-                            object_stats.type_bytes[i]);
-    }
-  }
-  return true;
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h b/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h
deleted file mode 100644
index e730f8d..0000000
--- a/third_party/blink/renderer/platform/heap/impl/blink_gc_memory_dump_provider.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
-
-#include "base/trace_event/memory_dump_provider.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}  // namespace base
-
-namespace blink {
-
-class ThreadState;
-
-class PLATFORM_EXPORT BlinkGCMemoryDumpProvider final
-    : public base::trace_event::MemoryDumpProvider {
-  USING_FAST_MALLOC(BlinkGCMemoryDumpProvider);
-
- public:
-  enum class HeapType { kBlinkMainThread, kBlinkWorkerThread };
-
-  ~BlinkGCMemoryDumpProvider() final;
-  BlinkGCMemoryDumpProvider(
-      ThreadState* thread_state,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      HeapType heap_type);
-
-  // MemoryDumpProvider implementation.
-  bool OnMemoryDump(const base::trace_event::MemoryDumpArgs&,
-                    base::trace_event::ProcessMemoryDump*) final;
-
- private:
-  ThreadState* const thread_state_;
-  const HeapType heap_type_;
-  const std::string dump_base_name_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_BLINK_GC_MEMORY_DUMP_PROVIDER_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/collection_support/heap_hash_table_backing.h b/third_party/blink/renderer/platform/heap/impl/collection_support/heap_hash_table_backing.h
deleted file mode 100644
index 1e81ebc..0000000
--- a/third_party/blink/renderer/platform/heap/impl/collection_support/heap_hash_table_backing.h
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_HASH_TABLE_BACKING_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_HASH_TABLE_BACKING_H_
-
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/impl/threading_traits.h"
-#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/conditional_destructor.h"
-
-namespace blink {
-
-template <typename Table>
-class HeapHashTableBacking final
-    : public GarbageCollected<HeapHashTableBacking<Table>>,
-      public WTF::ConditionalDestructor<
-          HeapHashTableBacking<Table>,
-          std::is_trivially_destructible<typename Table::ValueType>::value> {
- public:
-  template <typename Backing>
-  static void* AllocateObject(size_t);
-
-  // Conditionally invoked via destructor.
-  void Finalize();
-};
-
-template <typename Table>
-struct ThreadingTrait<HeapHashTableBacking<Table>> {
-  STATIC_ONLY(ThreadingTrait);
-  using Key = typename Table::KeyType;
-  using Value = typename Table::ValueType;
-  static const ThreadAffinity kAffinity =
-      (ThreadingTrait<Key>::kAffinity == kMainThreadOnly) &&
-              (ThreadingTrait<Value>::kAffinity == kMainThreadOnly)
-          ? kMainThreadOnly
-          : kAnyThread;
-};
-
-// static
-template <typename Table>
-template <typename Backing>
-void* HeapHashTableBacking<Table>::AllocateObject(size_t size) {
-  ThreadState* state =
-      ThreadStateFor<ThreadingTrait<Backing>::kAffinity>::GetState();
-  DCHECK(state->IsAllocationAllowed());
-  return state->Heap().AllocateOnArenaIndex(
-      state, size, BlinkGC::kHashTableArenaIndex, GCInfoTrait<Backing>::Index(),
-      WTF_HEAP_PROFILER_TYPE_NAME(Backing));
-}
-
-template <typename Table>
-void HeapHashTableBacking<Table>::Finalize() {
-  using Value = typename Table::ValueType;
-  static_assert(
-      !std::is_trivially_destructible<Value>::value,
-      "Finalization of trivially destructible classes should not happen.");
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(this);
-  // Use the payload size as recorded by the heap to determine how many
-  // elements to finalize.
-  size_t length = header->PayloadSize() / sizeof(Value);
-  Value* table = reinterpret_cast<Value*>(this);
-  for (unsigned i = 0; i < length; ++i) {
-    if (!Table::IsEmptyOrDeletedBucket(table[i]))
-      table[i].~Value();
-  }
-}
-
-template <typename Table>
-struct MakeGarbageCollectedTrait<HeapHashTableBacking<Table>> {
-  static HeapHashTableBacking<Table>* Call(size_t num_elements) {
-    static_assert(!std::is_polymorphic<HeapHashTableBacking<Table>>::value,
-                  "HeapHashTableBacking must not be polymorphic as it is "
-                  "converted to a raw array of buckets for certain operation");
-    CHECK_GT(num_elements, 0u);
-    void* memory = HeapHashTableBacking<Table>::template AllocateObject<
-        HeapHashTableBacking<Table>>(num_elements *
-                                     sizeof(typename Table::ValueType));
-    HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
-    // Placement new as regular operator new() is deleted.
-    HeapHashTableBacking<Table>* object =
-        ::new (memory) HeapHashTableBacking<Table>();
-    header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
-    return object;
-  }
-};
-
-// The trace trait for the heap hashtable backing is used when we find a
-// direct pointer to the backing from the conservative stack scanner. This
-// normally indicates that there is an ongoing iteration over the table, and so
-// we disable weak processing of table entries. When the backing is found
-// through the owning hash table we mark differently, in order to do weak
-// processing.
-template <typename Table>
-struct TraceTrait<HeapHashTableBacking<Table>> {
-  STATIC_ONLY(TraceTrait);
-  using Backing = HeapHashTableBacking<Table>;
-  using ValueType = typename Table::ValueTraits::TraitType;
-  using Traits = typename Table::ValueTraits;
-
- public:
-  static TraceDescriptor GetTraceDescriptor(const void* self) {
-    return {self, Trace<WTF::kNoWeakHandling>};
-  }
-
-  static TraceDescriptor GetWeakTraceDescriptor(const void* self) {
-    return GetWeakTraceDescriptorImpl<ValueType>::GetWeakTraceDescriptor(self);
-  }
-
-  template <WTF::WeakHandlingFlag WeakHandling = WTF::kNoWeakHandling>
-  static void Trace(Visitor* visitor, const void* self) {
-    if (!Traits::kCanTraceConcurrently && self) {
-      if (visitor->DeferredTraceIfConcurrent({self, &Trace<WeakHandling>},
-                                             GetBackingStoreSize(self)))
-        return;
-    }
-
-    static_assert(WTF::IsTraceableInCollectionTrait<Traits>::value ||
-                      WTF::IsWeak<ValueType>::value,
-                  "T should not be traced");
-    WTF::TraceInCollectionTrait<WeakHandling, Backing, void>::Trace(visitor,
-                                                                    self);
-  }
-
- private:
-  static size_t GetBackingStoreSize(const void* backing_store) {
-    const HeapObjectHeader* header =
-        HeapObjectHeader::FromPayload(backing_store);
-    return header->IsLargeObject<HeapObjectHeader::AccessMode::kAtomic>()
-               ? static_cast<LargeObjectPage*>(PageFromObject(header))
-                     ->ObjectSize()
-               : header->size<HeapObjectHeader::AccessMode::kAtomic>();
-  }
-
-  template <typename ValueType>
-  struct GetWeakTraceDescriptorImpl {
-    static TraceDescriptor GetWeakTraceDescriptor(const void* backing) {
-      return {backing, nullptr};
-    }
-  };
-
-  template <typename K, typename V>
-  struct GetWeakTraceDescriptorImpl<WTF::KeyValuePair<K, V>> {
-    static TraceDescriptor GetWeakTraceDescriptor(const void* backing) {
-      return GetWeakTraceDescriptorKVPImpl<K, V>::GetWeakTraceDescriptor(
-          backing);
-    }
-
-    template <typename KeyType,
-              typename ValueType,
-              bool ephemeron_semantics = (WTF::IsWeak<KeyType>::value &&
-                                          !WTF::IsWeak<ValueType>::value &&
-                                          WTF::IsTraceable<ValueType>::value) ||
-                                         (WTF::IsWeak<ValueType>::value &&
-                                          !WTF::IsWeak<KeyType>::value &&
-                                          WTF::IsTraceable<KeyType>::value)>
-    struct GetWeakTraceDescriptorKVPImpl {
-      static TraceDescriptor GetWeakTraceDescriptor(const void* backing) {
-        return {backing, nullptr};
-      }
-    };
-
-    template <typename KeyType, typename ValueType>
-    struct GetWeakTraceDescriptorKVPImpl<KeyType, ValueType, true> {
-      static TraceDescriptor GetWeakTraceDescriptor(const void* backing) {
-        return {backing, Trace<WTF::kWeakHandling>};
-      }
-    };
-  };
-};
-
-}  // namespace blink
-
-namespace WTF {
-
-namespace internal {
-
-// ConcurrentBucket is a wrapper for HashTable buckets for concurrent marking.
-// It is used to provide a snapshot view of the bucket key and guarantee
-// that the same key is used for checking empty/deleted buckets and tracing.
-template <typename T>
-class ConcurrentBucket {
-  using KeyExtractionCallback = void (*)(const T&, void*);
-
- public:
-  using BucketType = T;
-
-  ConcurrentBucket(const T& t, KeyExtractionCallback extract_key) {
-    extract_key(t, &buf_);
-  }
-
-  // for HashTable that don't use KeyValuePair (i.e. *HashSets), the key
-  // and the value are the same.
-  const T* key() const { return reinterpret_cast<const T*>(&buf_); }
-  const T* value() const { return key(); }
-  const T* bucket() const { return key(); }
-
- private:
-  // Alignment is needed for atomic accesses to |buf_| and to assure |buf_|
-  // can be accessed the same as objects of type T
-  static constexpr size_t boundary = std::max(alignof(T), sizeof(size_t));
-  alignas(boundary) char buf_[sizeof(T)];
-};
-
-template <typename Key, typename Value>
-class ConcurrentBucket<KeyValuePair<Key, Value>> {
-  using KeyExtractionCallback = void (*)(const KeyValuePair<Key, Value>&,
-                                         void*);
-
- public:
-  using BucketType = ConcurrentBucket;
-
-  ConcurrentBucket(const KeyValuePair<Key, Value>& pair,
-                   KeyExtractionCallback extract_key)
-      : value_(&pair.value) {
-    extract_key(pair, &buf_);
-  }
-
-  const Key* key() const { return reinterpret_cast<const Key*>(&buf_); }
-  const Value* value() const { return value_; }
-  const ConcurrentBucket* bucket() const { return this; }
-
- private:
-  // Alignment is needed for atomic accesses to |buf_| and to assure |buf_|
-  // can be accessed the same as objects of type Key
-  static constexpr size_t boundary = std::max(alignof(Key), sizeof(size_t));
-  alignas(boundary) char buf_[sizeof(Key)];
-  const Value* value_;
-};
-
-}  // namespace internal
-
-// This trace method is for tracing a HashTableBacking either through regular
-// tracing (via the relevant TraceTraits) or when finding a HashTableBacking
-// through conservative stack scanning (which will treat all references in the
-// backing strongly).
-template <WTF::WeakHandlingFlag WeakHandling, typename Table>
-struct TraceHashTableBackingInCollectionTrait {
-  using Value = typename Table::ValueType;
-  using Traits = typename Table::ValueTraits;
-  using Extractor = typename Table::ExtractorType;
-
-  static void Trace(blink::Visitor* visitor, const void* self) {
-    static_assert(IsTraceableInCollectionTrait<Traits>::value ||
-                      WTF::IsWeak<Value>::value,
-                  "Table should not be traced");
-    const Value* array = reinterpret_cast<const Value*>(self);
-    blink::HeapObjectHeader* header =
-        blink::HeapObjectHeader::FromPayload(self);
-    // Use the payload size as recorded by the heap to determine how many
-    // elements to trace.
-    size_t length = header->PayloadSize() / sizeof(Value);
-    const bool is_concurrent = visitor->IsConcurrent();
-    for (size_t i = 0; i < length; ++i) {
-      // If tracing concurrently, use a concurrent-safe version of
-      // IsEmptyOrDeletedBucket (check performed on a local copy instead
-      // of directly on the bucket).
-      if (is_concurrent) {
-        internal::ConcurrentBucket<Value> concurrent_bucket(
-            array[i], Extractor::ExtractSafe);
-        if (!HashTableHelper<Value, Extractor, typename Table::KeyTraitsType>::
-                IsEmptyOrDeletedBucketForKey(*concurrent_bucket.key())) {
-          blink::TraceCollectionIfEnabled<
-              WeakHandling,
-              typename internal::ConcurrentBucket<Value>::BucketType,
-              Traits>::Trace(visitor, concurrent_bucket.bucket());
-        }
-      } else {
-        if (!HashTableHelper<Value, Extractor, typename Table::KeyTraitsType>::
-                IsEmptyOrDeletedBucket(array[i])) {
-          blink::TraceCollectionIfEnabled<WeakHandling, Value, Traits>::Trace(
-              visitor, &array[i]);
-        }
-      }
-    }
-  }
-};
-
-}  // namespace WTF
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_HASH_TABLE_BACKING_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h b/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h
deleted file mode 100644
index c7b75ba..0000000
--- a/third_party/blink/renderer/platform/heap/impl/collection_support/heap_vector_backing.h
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
-
-#include "base/check_op.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/impl/finalizer_traits.h"
-#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
-#include "third_party/blink/renderer/platform/heap/impl/threading_traits.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/trace_traits.h"
-#include "third_party/blink/renderer/platform/wtf/conditional_destructor.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-template <typename T, typename Traits = WTF::VectorTraits<T>>
-class HeapVectorBacking final
-    : public GarbageCollected<HeapVectorBacking<T, Traits>>,
-      public WTF::ConditionalDestructor<HeapVectorBacking<T, Traits>,
-                                        !Traits::kNeedsDestruction> {
- public:
-  template <typename Backing>
-  static void* AllocateObject(size_t);
-
-  // Conditionally invoked via destructor.
-  void Finalize();
-};
-
-// static
-template <typename T, typename Traits>
-template <typename Backing>
-void* HeapVectorBacking<T, Traits>::AllocateObject(size_t size) {
-  ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-  DCHECK(state->IsAllocationAllowed());
-  return state->Heap().AllocateOnArenaIndex(
-      state, size, BlinkGC::kVectorArenaIndex, GCInfoTrait<Backing>::Index(),
-      WTF_HEAP_PROFILER_TYPE_NAME(Backing));
-}
-
-template <typename T, typename Traits>
-void HeapVectorBacking<T, Traits>::Finalize() {
-  static_assert(Traits::kNeedsDestruction,
-                "Only vector buffers with items requiring destruction should "
-                "be finalized");
-  static_assert(
-      Traits::kCanClearUnusedSlotsWithMemset || std::is_polymorphic<T>::value,
-      "HeapVectorBacking doesn't support objects that cannot be cleared as "
-      "unused with memset or don't have a vtable");
-
-  static_assert(
-      !std::is_trivially_destructible<T>::value,
-      "Finalization of trivially destructible classes should not happen.");
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(this);
-  // Use the payload size as recorded by the heap to determine how many
-  // elements to finalize.
-  size_t length = header->PayloadSize() / sizeof(T);
-  Address payload = header->Payload();
-#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
-  ANNOTATE_CHANGE_SIZE(payload, length * sizeof(T), 0, length * sizeof(T));
-#endif
-  // As commented above, HeapVectorBacking calls finalizers for unused slots
-  // (which are already zeroed out).
-  if (std::is_polymorphic<T>::value) {
-    for (unsigned i = 0; i < length; ++i) {
-      Address element = payload + i * sizeof(T);
-      if (blink::VTableInitialized(element))
-        reinterpret_cast<T*>(element)->~T();
-    }
-  } else {
-    T* buffer = reinterpret_cast<T*>(payload);
-    for (unsigned i = 0; i < length; ++i)
-      buffer[i].~T();
-  }
-}
-
-template <typename T>
-struct MakeGarbageCollectedTrait<HeapVectorBacking<T>> {
-  static HeapVectorBacking<T>* Call(size_t num_elements) {
-    static_assert(!std::is_polymorphic<HeapVectorBacking<T>>::value,
-                  "HeapVectorBacking must not be polymorphic as it is "
-                  "converted to a raw array of buckets for certain operation");
-    CHECK_GT(num_elements, 0u);
-    void* memory =
-        HeapVectorBacking<T>::template AllocateObject<HeapVectorBacking<T>>(
-            num_elements * sizeof(T));
-    HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
-    // Placement new as regular operator new() is deleted.
-    HeapVectorBacking<T>* object = ::new (memory) HeapVectorBacking<T>();
-    header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
-    return object;
-  }
-};
-
-template <typename T, typename Traits>
-struct ThreadingTrait<HeapVectorBacking<T, Traits>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity = ThreadingTrait<T>::Affinity;
-};
-
-template <typename T, typename Traits>
-struct TraceTrait<HeapVectorBacking<T, Traits>> {
-  STATIC_ONLY(TraceTrait);
-  using Backing = HeapVectorBacking<T, Traits>;
-
- public:
-  static TraceDescriptor GetTraceDescriptor(const void* self) {
-    return {self, TraceTrait<Backing>::Trace};
-  }
-
-  static void Trace(Visitor* visitor, const void* self) {
-    if (!Traits::kCanTraceConcurrently && self) {
-      if (visitor->DeferredTraceIfConcurrent({self, &Trace},
-                                             GetBackingStoreSize(self)))
-        return;
-    }
-
-    static_assert(!WTF::IsWeak<T>::value,
-                  "Weakness is not supported in HeapVector and HeapDeque");
-    if (WTF::IsTraceableInCollectionTrait<Traits>::value) {
-      WTF::TraceInCollectionTrait<WTF::kNoWeakHandling,
-                                  HeapVectorBacking<T, Traits>,
-                                  void>::Trace(visitor, self);
-    }
-  }
-
- private:
-  static size_t GetBackingStoreSize(const void* backing_store) {
-    const HeapObjectHeader* header =
-        HeapObjectHeader::FromPayload(backing_store);
-    return header->IsLargeObject<HeapObjectHeader::AccessMode::kAtomic>()
-               ? static_cast<LargeObjectPage*>(PageFromObject(header))
-                     ->ObjectSize()
-               : header->size<HeapObjectHeader::AccessMode::kAtomic>();
-  }
-};
-
-}  // namespace blink
-
-namespace WTF {
-
-// This trace method is used for all HeapVectorBacking objects. On-stack objects
-// are found and dispatched using conservative stack scanning. HeapVector (i.e.
-// Vector) dispatches all regular on-heap backings to this method.
-template <typename T, typename Traits>
-struct TraceInCollectionTrait<kNoWeakHandling,
-                              blink::HeapVectorBacking<T, Traits>,
-                              void> {
-  static void Trace(blink::Visitor* visitor, const void* self) {
-    // HeapVectorBacking does not know the exact size of the vector
-    // and just knows the capacity of the vector. Due to the constraint,
-    // HeapVectorBacking can support only the following objects:
-    //
-    // - An object that has a vtable. In this case, HeapVectorBacking
-    //   traces only slots that are not zeroed out. This is because if
-    //   the object has a vtable, the zeroed slot means that it is
-    //   an unused slot (Remember that the unused slots are guaranteed
-    //   to be zeroed out by VectorUnusedSlotClearer).
-    //
-    // - An object that can be initialized with memset. In this case,
-    //   HeapVectorBacking traces all slots including unused slots.
-    //   This is fine because the fact that the object can be initialized
-    //   with memset indicates that it is safe to treat the zerod slot
-    //   as a valid object.
-    static_assert(!IsTraceableInCollectionTrait<Traits>::value ||
-                      Traits::kCanClearUnusedSlotsWithMemset ||
-                      std::is_polymorphic<T>::value,
-                  "HeapVectorBacking doesn't support objects that cannot be "
-                  "cleared as unused with memset.");
-
-    // This trace method is instantiated for vectors where
-    // IsTraceableInCollectionTrait<Traits>::value is false, but the trace
-    // method should not be called. Thus we cannot static-assert
-    // IsTraceableInCollectionTrait<Traits>::value but should runtime-assert it.
-    DCHECK(IsTraceableInCollectionTrait<Traits>::value);
-
-    const T* array = reinterpret_cast<const T*>(self);
-    blink::HeapObjectHeader* header =
-        blink::HeapObjectHeader::FromPayload(self);
-    // Use the payload size as recorded by the heap to determine how many
-    // elements to trace.
-    size_t length = header->PayloadSize() / sizeof(T);
-#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
-    // As commented above, HeapVectorBacking can trace unused slots
-    // (which are already zeroed out).
-    ANNOTATE_CHANGE_SIZE(array, length, 0, length);
-#endif
-    if (std::is_polymorphic<T>::value) {
-      const char* pointer = reinterpret_cast<const char*>(array);
-      for (unsigned i = 0; i < length; ++i) {
-        const char* element = pointer + i * sizeof(T);
-        if (blink::VTableInitialized(element)) {
-          blink::TraceIfNeeded<
-              T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor,
-                                                                     array[i]);
-        }
-      }
-    } else {
-      for (size_t i = 0; i < length; ++i) {
-        blink::TraceIfNeeded<
-            T, IsTraceableInCollectionTrait<Traits>::value>::Trace(visitor,
-                                                                   array[i]);
-      }
-    }
-  }
-};
-
-}  // namespace WTF
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_COLLECTION_SUPPORT_HEAP_VECTOR_BACKING_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/finalizer_traits.h b/third_party/blink/renderer/platform/heap/impl/finalizer_traits.h
deleted file mode 100644
index 2f0e0ee..0000000
--- a/third_party/blink/renderer/platform/heap/impl/finalizer_traits.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_FINALIZER_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_FINALIZER_TRAITS_H_
-
-#include <type_traits>
-
-#include "base/template_util.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-namespace internal {
-
-using FinalizationCallback = void (*)(void*);
-
-template <typename T, typename = void>
-struct HasFinalizeGarbageCollectedObject : std::false_type {};
-
-template <typename T>
-struct HasFinalizeGarbageCollectedObject<
-    T,
-    base::void_t<decltype(std::declval<T>().FinalizeGarbageCollectedObject())>>
-    : std::true_type {};
-
-// The FinalizerTraitImpl specifies how to finalize objects.
-template <typename T, bool isFinalized>
-struct FinalizerTraitImpl;
-
-template <typename T>
-struct FinalizerTraitImpl<T, true> {
- private:
-  STATIC_ONLY(FinalizerTraitImpl);
-  struct Custom {
-    static void Call(void* obj) {
-      static_cast<T*>(obj)->FinalizeGarbageCollectedObject();
-    }
-  };
-  struct Destructor {
-    static void Call(void* obj) {
-// The garbage collector differs from regular C++ here as it remembers whether
-// an object's base class has a virtual destructor. In case there is no virtual
-// destructor present, the object is always finalized through its leaf type. In
-// other words: there is no finalization through a base pointer.
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
-      static_cast<T*>(obj)->~T();
-#pragma GCC diagnostic pop
-    }
-  };
-  using FinalizeImpl =
-      std::conditional_t<HasFinalizeGarbageCollectedObject<T>::value,
-                         Custom,
-                         Destructor>;
-
- public:
-  static void Finalize(void* obj) {
-    static_assert(sizeof(T), "T must be fully defined");
-    FinalizeImpl::Call(obj);
-  }
-};
-
-template <typename T>
-struct FinalizerTraitImpl<T, false> {
-  STATIC_ONLY(FinalizerTraitImpl);
-  static void Finalize(void* obj) {
-    static_assert(sizeof(T), "T must be fully defined");
-  }
-};
-
-// The FinalizerTrait is used to determine if a type requires finalization and
-// what finalization means.
-template <typename T>
-struct FinalizerTrait {
-  STATIC_ONLY(FinalizerTrait);
-
- private:
-  static constexpr bool kNonTrivialFinalizer =
-      internal::HasFinalizeGarbageCollectedObject<T>::value ||
-      !std::is_trivially_destructible<typename std::remove_cv<T>::type>::value;
-
-  static void Finalize(void* obj) {
-    internal::FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj);
-  }
-
- public:
-  static constexpr FinalizationCallback kCallback =
-      kNonTrivialFinalizer ? Finalize : nullptr;
-};
-
-}  // namespace internal
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_FINALIZER_TRAITS_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/garbage_collected.h b/third_party/blink/renderer/platform/heap/impl/garbage_collected.h
deleted file mode 100644
index ccdeb37c..0000000
--- a/third_party/blink/renderer/platform/heap/impl/garbage_collected.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GARBAGE_COLLECTED_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GARBAGE_COLLECTED_H_
-
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
-
-namespace blink {
-
-template <typename T>
-class GarbageCollected;
-
-// GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or
-// field when checking for proper usage.  When using GC_PLUGIN_IGNORE
-// a bug-number should be provided as an argument where the bug describes
-// what needs to happen to remove the GC_PLUGIN_IGNORE again.
-#if defined(__clang__)
-#define GC_PLUGIN_IGNORE(bug) \
-  __attribute__((annotate("blink_gc_plugin_ignore")))
-#else
-#define GC_PLUGIN_IGNORE(bug)
-#endif
-
-// Template to determine if a class is a GarbageCollectedMixin by checking if it
-// has IsGarbageCollectedMixinMarker
-template <typename T>
-struct IsGarbageCollectedMixin {
- private:
-  typedef char YesType;
-  struct NoType {
-    char padding[8];
-  };
-
-  template <typename U>
-  static YesType CheckMarker(typename U::IsGarbageCollectedMixinMarker*);
-  template <typename U>
-  static NoType CheckMarker(...);
-
- public:
-  static const bool value = sizeof(CheckMarker<T>(nullptr)) == sizeof(YesType);
-};
-
-// TraceDescriptor is used to describe how to trace an object.
-struct TraceDescriptor {
-  STACK_ALLOCATED();
-
- public:
-  // The adjusted base pointer of the object that should be traced.
-  const void* base_object_payload;
-  // A callback for tracing the object.
-  TraceCallback callback;
-};
-
-// The GarbageCollectedMixin interface can be used to automatically define
-// TraceTrait/ObjectAliveTrait on non-leftmost deriving classes which need
-// to be garbage collected.
-class PLATFORM_EXPORT GarbageCollectedMixin {
- public:
-  typedef int IsGarbageCollectedMixinMarker;
-  virtual void Trace(Visitor*) const {}
-};
-
-// Base class for objects allocated in the Blink garbage-collected heap.
-//
-// Instances of GarbageCollected will be finalized if they are non-trivially
-// destructible.
-template <typename T>
-class GarbageCollected;
-
-template <typename T,
-          bool = WTF::IsSubclassOfTemplate<typename std::remove_const<T>::type,
-                                           GarbageCollected>::value>
-class NeedsAdjustPointer;
-
-template <typename T>
-class NeedsAdjustPointer<T, true> {
-  static_assert(sizeof(T), "T must be fully defined");
-
- public:
-  static const bool value = false;
-};
-
-template <typename T>
-class NeedsAdjustPointer<T, false> {
-  static_assert(sizeof(T), "T must be fully defined");
-
- public:
-  static const bool value = true;
-};
-
-// TODO(sof): migrate to wtf/TypeTraits.h
-template <typename T>
-class IsFullyDefined {
-  using TrueType = char;
-  struct FalseType {
-    char dummy[2];
-  };
-
-  template <typename U, size_t sz = sizeof(U)>
-  static TrueType IsSizeofKnown(U*);
-  static FalseType IsSizeofKnown(...);
-  static T& t_;
-
- public:
-  static const bool value = sizeof(TrueType) == sizeof(IsSizeofKnown(&t_));
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GARBAGE_COLLECTED_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/gc_info.cc b/third_party/blink/renderer/platform/heap/impl/gc_info.cc
deleted file mode 100644
index a527169..0000000
--- a/third_party/blink/renderer/platform/heap/impl/gc_info.cc
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
-
-#include "base/allocator/partition_allocator/page_allocator.h"
-#include "base/bits.h"
-#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
-
-namespace blink {
-
-namespace {
-
-constexpr size_t kEntrySize = sizeof(GCInfo*);
-
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR GCInfoIndex
-ComputeInitialTableLimit() {
-  // (Light) experimentation suggests that Blink doesn't need more than this
-  // while handling content on popular web properties.
-  constexpr size_t kInitialWantedLimit = 512;
-
-  // Different OSes have different page sizes, so we have to choose the minimum
-  // of memory wanted and OS page size.
-  constexpr size_t memory_wanted = kInitialWantedLimit * kEntrySize;
-  return static_cast<GCInfoIndex>(
-      base::RoundUpToPageAllocationGranularity(memory_wanted) / kEntrySize);
-}
-
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t MaxTableSize() {
-  return base::RoundUpToPageAllocationGranularity(GCInfoTable::kMaxIndex *
-                                                  kEntrySize);
-}
-
-}  // namespace
-
-GCInfoTable* GCInfoTable::global_table_ = nullptr;
-constexpr GCInfoIndex GCInfoTable::kMaxIndex;
-constexpr GCInfoIndex GCInfoTable::kMinIndex;
-
-void GCInfoTable::CreateGlobalTable() {
-  // Allocation and resizing are built around the following invariants.
-  static_assert(base::bits::IsPowerOfTwo(kEntrySize),
-                "GCInfoTable entries size must be power of "
-                "two");
-
-#if defined(PAGE_ALLOCATOR_CONSTANTS_ARE_CONSTEXPR)
-#define STATIC_ASSERT_OR_CHECK(condition, message) \
-  static_assert(condition, message)
-#else
-#define STATIC_ASSERT_OR_CHECK(condition, message) \
-  do {                                             \
-    CHECK(condition) << (message);                 \
-  } while (false)
-#endif
-
-  STATIC_ASSERT_OR_CHECK(
-      0 == base::PageAllocationGranularity() % base::SystemPageSize(),
-      "System page size must be a multiple of page allocation granularity");
-
-#undef STATIC_ASSERT_OR_CHECK
-
-  DEFINE_STATIC_LOCAL(GCInfoTable, table, ());
-  global_table_ = &table;
-}
-
-GCInfoIndex GCInfoTable::EnsureGCInfoIndex(
-    const GCInfo* gc_info,
-    std::atomic<GCInfoIndex>* gc_info_index_slot) {
-  DCHECK(gc_info);
-  DCHECK(gc_info_index_slot);
-
-  // Ensuring a new index involves current index adjustment as well as
-  // potentially resizing the table. For simplicity we use a lock.
-  MutexLocker locker(table_mutex_);
-
-  // If more than one thread ends up allocating a slot for the same GCInfo, have
-  // later threads reuse the slot allocated by the first.
-  GCInfoIndex gc_info_index =
-      gc_info_index_slot->load(std::memory_order_relaxed);
-  if (gc_info_index)
-    return gc_info_index;
-
-  if (current_index_ == limit_)
-    Resize();
-
-  gc_info_index = current_index_++;
-  CHECK_LT(gc_info_index, GCInfoTable::kMaxIndex);
-
-  table_[gc_info_index] = gc_info;
-  gc_info_index_slot->store(gc_info_index, std::memory_order_release);
-  return gc_info_index;
-}
-
-void GCInfoTable::Resize() {
-  const GCInfoIndex new_limit =
-      (limit_) ? 2 * limit_ : ComputeInitialTableLimit();
-  CHECK_GT(new_limit, limit_);
-  const size_t old_committed_size = limit_ * kEntrySize;
-  const size_t new_committed_size = new_limit * kEntrySize;
-  CHECK(table_);
-  CHECK_EQ(0u, new_committed_size % base::PageAllocationGranularity());
-  CHECK_GE(MaxTableSize(), limit_ * kEntrySize);
-
-  // Recommitting and zapping assumes byte-addressable storage.
-  uint8_t* const current_table_end =
-      reinterpret_cast<uint8_t*>(table_) + old_committed_size;
-  const size_t table_size_delta = new_committed_size - old_committed_size;
-
-  // Commit the new size and allow read/write.
-  base::RecommitSystemPages(current_table_end, table_size_delta,
-                            base::PageReadWrite, base::PageUpdatePermissions);
-
-#if DCHECK_IS_ON()
-  // Check that newly-committed memory is zero-initialized.
-  for (size_t i = 0; i < (table_size_delta / sizeof(uintptr_t)); ++i) {
-    DCHECK(!reinterpret_cast<uintptr_t*>(current_table_end)[i]);
-  }
-#endif  // DCHECK_IS_ON()
-
-  limit_ = new_limit;
-}
-
-GCInfoTable::GCInfoTable() {
-  table_ = reinterpret_cast<GCInfo const**>(base::AllocPages(
-      nullptr, MaxTableSize(), base::PageAllocationGranularity(),
-      base::PageInaccessible, base::PageTag::kBlinkGC));
-  CHECK(table_);
-  Resize();
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/gc_info.h b/third_party/blink/renderer/platform/heap/impl/gc_info.h
deleted file mode 100644
index bec05ee6..0000000
--- a/third_party/blink/renderer/platform/heap/impl/gc_info.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_INFO_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_INFO_H_
-
-#include <atomic>
-#include "base/gtest_prod_util.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/impl/finalizer_traits.h"
-#include "third_party/blink/renderer/platform/heap/impl/name_traits.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-
-namespace blink {
-
-template <typename T>
-struct TraceTrait;
-
-using GCInfoIndex = uint32_t;
-
-// GCInfo contains metadata for objects that are instantiated from classes that
-// inherit from GarbageCollected.
-struct PLATFORM_EXPORT GCInfo final {
-  static inline const GCInfo& From(GCInfoIndex);
-
-  const TraceCallback trace;
-  const internal::FinalizationCallback finalize;
-  const NameCallback name;
-  const bool has_v_table;
-};
-
-class PLATFORM_EXPORT GCInfoTable final {
- public:
-  // At maximum |kMaxIndex - 1| indices are supported.
-  //
-  // We assume that 14 bits is enough to represent all possible types: during
-  // telemetry runs, we see about 1,000 different types; looking at the output
-  // of the Oilpan GC Clang plugin, there appear to be at most about 6,000
-  // types. Thus 14 bits should be more than twice as many bits as we will ever
-  // need.
-  static constexpr GCInfoIndex kMaxIndex = 1 << 14;
-
-  // Minimum index returned. Values smaller |kMinIndex| may be used as
-  // sentinels.
-  static constexpr GCInfoIndex kMinIndex = 1;
-
-  // Sets up a singleton table that can be acquired using Get().
-  static void CreateGlobalTable();
-
-  static GCInfoTable* GetMutable() { return global_table_; }
-  static const GCInfoTable& Get() { return *global_table_; }
-
-  const GCInfo& GCInfoFromIndex(GCInfoIndex index) const {
-    DCHECK_GE(index, kMinIndex);
-    DCHECK_LT(index, kMaxIndex);
-    DCHECK(table_);
-    const GCInfo* info = table_[index];
-    DCHECK(info);
-    return *info;
-  }
-
-  GCInfoIndex EnsureGCInfoIndex(const GCInfo*, std::atomic<GCInfoIndex>*);
-
-  // Returns the number of recorded GCInfo objects, including |kMinIndex|.
-  GCInfoIndex NumberOfGCInfos() const { return current_index_; }
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(GCInfoTest, InitialEmpty);
-  FRIEND_TEST_ALL_PREFIXES(GCInfoTest, ResizeToMaxIndex);
-  FRIEND_TEST_ALL_PREFIXES(GCInfoDeathTest, MoreThanMaxIndexInfos);
-
-  // Singleton for each process. Retrieved through Get().
-  static GCInfoTable* global_table_;
-
-  // Use GCInfoTable::Get() for retrieving the global table outside of testing
-  // code.
-  GCInfoTable();
-
-  void Resize();
-
-  // Holds the per-class GCInfo descriptors; each HeapObjectHeader keeps an
-  // index into this table.
-  const GCInfo** table_ = nullptr;
-
-  // Current index used when requiring a new GCInfo object.
-  GCInfoIndex current_index_ = kMinIndex;
-
-  // The limit (exclusive) of the currently allocated table.
-  GCInfoIndex limit_ = 0;
-
-  Mutex table_mutex_;
-};
-
-// static
-const GCInfo& GCInfo::From(GCInfoIndex index) {
-  return GCInfoTable::Get().GCInfoFromIndex(index);
-}
-
-template <typename T>
-struct GCInfoTrait {
-  STATIC_ONLY(GCInfoTrait);
-
-  static GCInfoIndex Index() {
-    static_assert(sizeof(T), "T must be fully defined");
-    static const GCInfo kGcInfo = {
-        TraceTrait<T>::Trace, internal::FinalizerTrait<T>::kCallback,
-        NameTrait<T>::GetName, std::is_polymorphic<T>::value};
-    // This is more complicated than using threadsafe initialization, but this
-    // is instantiated many times (once for every GC type).
-    static std::atomic<GCInfoIndex> gc_info_index{0};
-    GCInfoIndex index = gc_info_index.load(std::memory_order_acquire);
-    if (!index) {
-      index = GCInfoTable::GetMutable()->EnsureGCInfoIndex(&kGcInfo,
-                                                           &gc_info_index);
-    }
-    DCHECK_GE(index, GCInfoTable::kMinIndex);
-    DCHECK_LT(index, GCInfoTable::kMaxIndex);
-    return index;
-  }
-};
-
-template <typename U>
-class GCInfoTrait<const U> : public GCInfoTrait<U> {};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_GC_INFO_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/heap.cc b/third_party/blink/renderer/platform/heap/impl/heap.cc
deleted file mode 100644
index 577bb37c..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap.cc
+++ /dev/null
@@ -1,794 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/platform/heap/heap.h"
-
-#include <algorithm>
-#include <limits>
-#include <memory>
-
-#include "base/trace_event/process_memory_dump.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
-#include "third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h"
-#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h"
-#include "third_party/blink/renderer/platform/heap/impl/page_memory.h"
-#include "third_party/blink/renderer/platform/heap/impl/page_pool.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
-#include "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
-#include "third_party/blink/renderer/platform/wtf/leak_annotations.h"
-
-namespace blink {
-
-class ProcessHeapReporter final : public ThreadHeapStatsObserver {
- public:
-  void IncreaseAllocatedSpace(size_t bytes) final {
-    ProcessHeap::IncreaseTotalAllocatedSpace(bytes);
-  }
-
-  void DecreaseAllocatedSpace(size_t bytes) final {
-    ProcessHeap::DecreaseTotalAllocatedSpace(bytes);
-  }
-
-  void ResetAllocatedObjectSize(size_t bytes) final {
-    ProcessHeap::DecreaseTotalAllocatedObjectSize(prev_incremented_);
-    ProcessHeap::IncreaseTotalAllocatedObjectSize(bytes);
-    prev_incremented_ = bytes;
-  }
-
-  void IncreaseAllocatedObjectSize(size_t bytes) final {
-    ProcessHeap::IncreaseTotalAllocatedObjectSize(bytes);
-    prev_incremented_ += bytes;
-  }
-
-  void DecreaseAllocatedObjectSize(size_t bytes) final {
-    ProcessHeap::DecreaseTotalAllocatedObjectSize(bytes);
-    prev_incremented_ -= bytes;
-  }
-
- private:
-  size_t prev_incremented_ = 0;
-};
-
-ThreadHeap::ThreadHeap(ThreadState* thread_state)
-    : thread_state_(thread_state),
-      heap_stats_collector_(std::make_unique<ThreadHeapStatsCollector>()),
-      region_tree_(std::make_unique<RegionTree>()),
-      page_bloom_filter_(std::make_unique<PageBloomFilter>()),
-      free_page_pool_(std::make_unique<PagePool>()),
-      process_heap_reporter_(std::make_unique<ProcessHeapReporter>()) {
-  if (ThreadState::Current()->IsMainThread())
-    main_thread_heap_ = this;
-
-  for (int arena_index = 0; arena_index < BlinkGC::kLargeObjectArenaIndex;
-       arena_index++) {
-    arenas_[arena_index] = new NormalPageArena(thread_state_, arena_index);
-  }
-  arenas_[BlinkGC::kLargeObjectArenaIndex] =
-      new LargeObjectArena(thread_state_, BlinkGC::kLargeObjectArenaIndex);
-
-  stats_collector()->RegisterObserver(process_heap_reporter_.get());
-}
-
-ThreadHeap::~ThreadHeap() {
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
-    delete arenas_[i];
-}
-
-Address ThreadHeap::CheckAndMarkPointer(MarkingVisitor* visitor,
-                                        Address address) {
-  DCHECK(thread_state_->InAtomicMarkingPause());
-
-#if !DCHECK_IS_ON()
-  if (!page_bloom_filter_->MayContain(address)) {
-    return nullptr;
-  }
-#endif
-
-  if (BasePage* page = LookupPageForAddress(address)) {
-#if DCHECK_IS_ON()
-    DCHECK(page->Contains(address))
-        << "address " << address << " not part of page " << page;
-#endif
-    DCHECK(page_bloom_filter_->MayContain(address));
-    DCHECK(&visitor->Heap() == &page->Arena()->GetThreadState()->Heap());
-    visitor->ConservativelyMarkAddress(page, address);
-    return address;
-  }
-
-  return nullptr;
-}
-
-void ThreadHeap::VisitRememberedSets(MarkingVisitor* visitor) {
-  static_assert(BlinkGC::kLargeObjectArenaIndex + 1 == BlinkGC::kNumberOfArenas,
-                "LargeObject arena must be the last one.");
-  const auto visit_header = [visitor](HeapObjectHeader* header) {
-    // Process only old objects.
-    if (header->IsOld<HeapObjectHeader::AccessMode::kNonAtomic>()) {
-      // The design of young generation requires collections to be executed at
-      // the top level (with the guarantee that no objects are currently being
-      // in construction). This can be ensured by running young GCs from safe
-      // points or by reintroducing nested allocation scopes that avoid
-      // finalization.
-      DCHECK(header->IsMarked());
-      DCHECK(!header->IsInConstruction());
-      const GCInfo& gc_info = GCInfo::From(header->GcInfoIndex());
-      gc_info.trace(visitor, header->Payload());
-    }
-  };
-  for (size_t i = 0; i < BlinkGC::kLargeObjectArenaIndex; ++i) {
-    static_cast<NormalPageArena*>(arenas_[i])
-        ->IterateAndClearCardTables(visit_header);
-  }
-  static_cast<LargeObjectArena*>(arenas_[BlinkGC::kLargeObjectArenaIndex])
-      ->IterateAndClearRememberedPages(visit_header);
-}
-
-void ThreadHeap::SetupWorklists(bool should_initialize_compaction_worklists) {
-  marking_worklist_ = std::make_unique<MarkingWorklist>();
-  write_barrier_worklist_ = std::make_unique<WriteBarrierWorklist>();
-  not_fully_constructed_worklist_ =
-      std::make_unique<NotFullyConstructedWorklist>();
-  previously_not_fully_constructed_worklist_ =
-      std::make_unique<NotFullyConstructedWorklist>();
-  weak_callback_worklist_ = std::make_unique<WeakCallbackWorklist>();
-  discovered_ephemeron_pairs_worklist_ =
-      std::make_unique<EphemeronPairsWorklist>();
-  ephemeron_pairs_to_process_worklist_ =
-      std::make_unique<EphemeronPairsWorklist>();
-  v8_references_worklist_ = std::make_unique<V8ReferencesWorklist>();
-  not_safe_to_concurrently_trace_worklist_ =
-      std::make_unique<NotSafeToConcurrentlyTraceWorklist>();
-  weak_containers_worklist_ = std::make_unique<WeakContainersWorklist>();
-  if (should_initialize_compaction_worklists) {
-    movable_reference_worklist_ = std::make_unique<MovableReferenceWorklist>();
-  }
-}
-
-void ThreadHeap::DestroyMarkingWorklists(BlinkGC::StackState stack_state) {
-  marking_worklist_.reset();
-  write_barrier_worklist_.reset();
-  previously_not_fully_constructed_worklist_.reset();
-  weak_callback_worklist_.reset();
-  ephemeron_pairs_to_process_worklist_.reset();
-  v8_references_worklist_.reset();
-  not_safe_to_concurrently_trace_worklist_.reset();
-  weak_containers_worklist_.reset();
-  // The fixed point iteration may have found not-fully-constructed objects.
-  // Such objects should have already been found through the stack scan though
-  // and should thus already be marked.
-  //
-  // Possible reasons for encountering unmarked objects here:
-  // - Object is not allocated through MakeGarbageCollected.
-  // - Broken stack (roots) scanning.
-  if (!not_fully_constructed_worklist_->IsGlobalEmpty()) {
-#if DCHECK_IS_ON()
-    const bool conservative_gc =
-        BlinkGC::StackState::kHeapPointersOnStack == stack_state;
-    NotFullyConstructedItem item;
-    while (not_fully_constructed_worklist_->Pop(WorklistTaskId::MutatorThread,
-                                                &item)) {
-      HeapObjectHeader* const header = HeapObjectHeader::FromInnerAddress(
-          reinterpret_cast<Address>(const_cast<void*>(item)));
-      DCHECK(conservative_gc && header->IsMarked())
-          << " conservative: " << (conservative_gc ? "yes" : "no")
-          << " type: " << header->Name();
-    }
-#else
-    not_fully_constructed_worklist_->Clear();
-#endif
-  }
-  not_fully_constructed_worklist_.reset();
-
-  // |discovered_ephemeron_pairs_worklist_| may still hold ephemeron pairs with
-  // dead keys.
-  if (!discovered_ephemeron_pairs_worklist_->IsGlobalEmpty()) {
-#if DCHECK_IS_ON()
-    EphemeronPairItem item;
-    while (discovered_ephemeron_pairs_worklist_->Pop(
-        WorklistTaskId::MutatorThread, &item)) {
-      const HeapObjectHeader* const header = HeapObjectHeader::FromInnerAddress(
-          reinterpret_cast<ConstAddress>(item.key));
-      DCHECK(!header->IsMarked());
-    }
-#else
-    discovered_ephemeron_pairs_worklist_->Clear();
-#endif
-  }
-  discovered_ephemeron_pairs_worklist_.reset();
-}
-
-void ThreadHeap::DestroyCompactionWorklists() {
-  movable_reference_worklist_.reset();
-}
-
-HeapCompact* ThreadHeap::Compaction() {
-  if (!compaction_)
-    compaction_ = std::make_unique<HeapCompact>(this);
-  return compaction_.get();
-}
-
-bool ThreadHeap::ShouldRegisterMovingAddress() {
-  return Compaction()->ShouldRegisterMovingAddress();
-}
-
-void ThreadHeap::FlushNotFullyConstructedObjects() {
-  NotFullyConstructedWorklist::View view(not_fully_constructed_worklist_.get(),
-                                         WorklistTaskId::MutatorThread);
-  if (!view.IsLocalViewEmpty()) {
-    view.FlushToGlobal();
-    previously_not_fully_constructed_worklist_->MergeGlobalPool(
-        not_fully_constructed_worklist_.get());
-  }
-  DCHECK(view.IsLocalViewEmpty());
-}
-
-void ThreadHeap::FlushEphemeronPairs(EphemeronProcessing ephemeron_processing) {
-  if (ephemeron_processing == EphemeronProcessing::kPartialProcessing) {
-    if (steps_since_last_ephemeron_pairs_flush_ <
-        kStepsBeforeEphemeronPairsFlush)
-      return;
-  }
-
-  ThreadHeapStatsCollector::EnabledScope stats_scope(
-      stats_collector(), ThreadHeapStatsCollector::kMarkFlushEphemeronPairs);
-
-  EphemeronPairsWorklist::View view(discovered_ephemeron_pairs_worklist_.get(),
-                                    WorklistTaskId::MutatorThread);
-  if (!view.IsLocalViewEmpty()) {
-    view.FlushToGlobal();
-    ephemeron_pairs_to_process_worklist_->MergeGlobalPool(
-        discovered_ephemeron_pairs_worklist_.get());
-  }
-
-  steps_since_last_ephemeron_pairs_flush_ = 0;
-}
-
-void ThreadHeap::MarkNotFullyConstructedObjects(MarkingVisitor* visitor) {
-  DCHECK(!thread_state_->IsIncrementalMarking());
-  ThreadHeapStatsCollector::Scope stats_scope(
-      stats_collector(),
-      ThreadHeapStatsCollector::kMarkNotFullyConstructedObjects);
-
-  DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id());
-  NotFullyConstructedItem item;
-  while (not_fully_constructed_worklist_->Pop(WorklistTaskId::MutatorThread,
-                                              &item)) {
-    BasePage* const page = PageFromObject(item);
-    visitor->ConservativelyMarkAddress(page,
-                                       reinterpret_cast<ConstAddress>(item));
-  }
-}
-
-namespace {
-
-static constexpr size_t kDefaultDeadlineCheckInterval = 150u;
-static constexpr size_t kDefaultConcurrentDeadlineCheckInterval =
-    5 * kDefaultDeadlineCheckInterval;
-
-template <size_t kDeadlineCheckInterval = kDefaultDeadlineCheckInterval,
-          typename Worklist,
-          typename Callback,
-          typename YieldPredicate>
-bool DrainWorklist(Worklist* worklist,
-                   Callback callback,
-                   YieldPredicate should_yield,
-                   int task_id) {
-  // For concurrent markers, should_yield also reports marked bytes.
-  if (worklist->IsLocalViewEmpty(task_id))
-    return true;
-  if (should_yield())
-    return false;
-  size_t processed_callback_count = kDeadlineCheckInterval;
-  typename Worklist::EntryType item;
-  while (worklist->Pop(task_id, &item)) {
-    callback(item);
-    if (--processed_callback_count == 0) {
-      if (should_yield()) {
-        return false;
-      }
-      processed_callback_count = kDeadlineCheckInterval;
-    }
-  }
-  return true;
-}
-
-template <size_t kDeadlineCheckInterval = kDefaultDeadlineCheckInterval,
-          typename Worklist,
-          typename Callback>
-bool DrainWorklistWithDeadline(base::TimeTicks deadline,
-                               Worklist* worklist,
-                               Callback callback,
-                               int task_id) {
-  return DrainWorklist<kDeadlineCheckInterval>(
-      worklist, std::move(callback),
-      [deadline]() { return deadline <= base::TimeTicks::Now(); }, task_id);
-}
-
-}  // namespace
-
-bool ThreadHeap::InvokeEphemeronCallbacks(
-    EphemeronProcessing ephemeron_processing,
-    MarkingVisitor* visitor,
-    base::TimeTicks deadline) {
-  if (ephemeron_processing == EphemeronProcessing::kPartialProcessing) {
-    if (steps_since_last_ephemeron_processing_ <
-        kStepsBeforeEphemeronProcessing) {
-      // Returning "no more work" to avoid excessive processing. The fixed
-      // point computation in the atomic pause takes care of correctness.
-      return true;
-    }
-  }
-
-  FlushEphemeronPairs(EphemeronProcessing::kFullProcessing);
-
-  steps_since_last_ephemeron_processing_ = 0;
-
-  // Mark any strong pointers that have now become reachable in ephemeron maps.
-  ThreadHeapStatsCollector::EnabledScope stats_scope(
-      stats_collector(),
-      ThreadHeapStatsCollector::kMarkInvokeEphemeronCallbacks);
-
-  DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id());
-
-  // Then we iterate over the new callbacks found by the marking visitor.
-  // Callbacks found by the concurrent marking will be flushed eventually
-  // and then invoked by the mutator thread (in the atomic pause at latest).
-  return DrainWorklistWithDeadline(
-      deadline, ephemeron_pairs_to_process_worklist_.get(),
-      [visitor](EphemeronPairItem& item) {
-        visitor->VisitEphemeron(item.key, item.value_desc);
-      },
-      WorklistTaskId::MutatorThread);
-}
-
-bool ThreadHeap::AdvanceMarking(MarkingVisitor* visitor,
-                                base::TimeTicks deadline,
-                                EphemeronProcessing ephemeron_processing) {
-  DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id());
-
-  ++steps_since_last_ephemeron_pairs_flush_;
-  ++steps_since_last_ephemeron_processing_;
-
-  bool finished;
-  bool processed_ephemerons = false;
-  FlushEphemeronPairs(ephemeron_processing);
-  // Ephemeron fixed point loop.
-  do {
-    {
-      // Iteratively mark all objects that are reachable from the objects
-      // currently pushed onto the marking worklist.
-      ThreadHeapStatsCollector::EnabledScope stats_scope(
-          stats_collector(), ThreadHeapStatsCollector::kMarkProcessWorklists);
-
-      // Start with mutator-thread-only worklists (not fully constructed).
-      // If time runs out, concurrent markers can take care of the rest.
-
-      {
-        ThreadHeapStatsCollector::EnabledScope inner_scope(
-            stats_collector(), ThreadHeapStatsCollector::kMarkBailOutObjects);
-        // Items in the bailout worklist are only collection backing stores.
-        // These items could take a long time to process, so we should check
-        // the deadline more often (backing stores and large items can also be
-        // found in the regular marking worklist, but those are interleaved
-        // with smaller objects).
-        finished = DrainWorklistWithDeadline<kDefaultDeadlineCheckInterval / 5>(
-            deadline, not_safe_to_concurrently_trace_worklist_.get(),
-            [visitor](const NotSafeToConcurrentlyTraceItem& item) {
-              item.desc.callback(visitor, item.desc.base_object_payload);
-              visitor->AccountMarkedBytes(item.bailout_size);
-            },
-            WorklistTaskId::MutatorThread);
-        if (!finished)
-          break;
-      }
-
-      {
-        ThreadHeapStatsCollector::EnabledScope inner_scope(
-            stats_collector(),
-            ThreadHeapStatsCollector::kMarkFlushV8References);
-        finished = FlushV8References(deadline);
-        if (!finished)
-          break;
-      }
-
-      {
-        ThreadHeapStatsCollector::EnabledScope inner_scope(
-            stats_collector(),
-            ThreadHeapStatsCollector::kMarkProcessNotFullyconstructeddWorklist);
-        // Convert |previously_not_fully_constructed_worklist_| to
-        // |marking_worklist_|. This merely re-adds items with the proper
-        // callbacks.
-        finished = DrainWorklistWithDeadline(
-            deadline, previously_not_fully_constructed_worklist_.get(),
-            [visitor](NotFullyConstructedItem& item) {
-              visitor->DynamicallyMarkAddress(
-                  reinterpret_cast<ConstAddress>(item));
-            },
-            WorklistTaskId::MutatorThread);
-        if (!finished)
-          break;
-      }
-
-      {
-        ThreadHeapStatsCollector::EnabledScope inner_scope(
-            stats_collector(),
-            ThreadHeapStatsCollector::kMarkProcessMarkingWorklist);
-        finished = DrainWorklistWithDeadline(
-            deadline, marking_worklist_.get(),
-            [visitor](const MarkingItem& item) {
-              HeapObjectHeader* header =
-                  HeapObjectHeader::FromPayload(item.base_object_payload);
-              DCHECK(!header->IsInConstruction());
-              item.callback(visitor, item.base_object_payload);
-              visitor->AccountMarkedBytes(header);
-            },
-            WorklistTaskId::MutatorThread);
-        if (!finished)
-          break;
-      }
-
-      {
-        ThreadHeapStatsCollector::EnabledScope inner_scope(
-            stats_collector(),
-            ThreadHeapStatsCollector::kMarkProcessWriteBarrierWorklist);
-        finished = DrainWorklistWithDeadline(
-            deadline, write_barrier_worklist_.get(),
-            [visitor](HeapObjectHeader* header) {
-              DCHECK(!header->IsInConstruction());
-              GCInfo::From(header->GcInfoIndex())
-                  .trace(visitor, header->Payload());
-              visitor->AccountMarkedBytes(header);
-            },
-            WorklistTaskId::MutatorThread);
-        if (!finished)
-          break;
-      }
-    }
-
-    if ((ephemeron_processing == EphemeronProcessing::kFullProcessing) ||
-        !processed_ephemerons) {
-      processed_ephemerons = true;
-      finished =
-          InvokeEphemeronCallbacks(ephemeron_processing, visitor, deadline);
-      if (!finished)
-        break;
-    }
-
-    // Rerun loop if ephemeron processing queued more objects for tracing.
-  } while (!marking_worklist_->IsLocalViewEmpty(WorklistTaskId::MutatorThread));
-
-  return finished;
-}
-
-bool ThreadHeap::HasWorkForConcurrentMarking() const {
-  return !marking_worklist_->IsGlobalPoolEmpty() ||
-         !write_barrier_worklist_->IsGlobalPoolEmpty() ||
-         !previously_not_fully_constructed_worklist_->IsGlobalPoolEmpty() ||
-         !ephemeron_pairs_to_process_worklist_->IsGlobalPoolEmpty();
-}
-
-size_t ThreadHeap::ConcurrentMarkingGlobalWorkSize() const {
-  return marking_worklist_->GlobalPoolSize() +
-         write_barrier_worklist_->GlobalPoolSize() +
-         previously_not_fully_constructed_worklist_->GlobalPoolSize() +
-         ephemeron_pairs_to_process_worklist_->GlobalPoolSize();
-}
-
-bool ThreadHeap::AdvanceConcurrentMarking(
-    ConcurrentMarkingVisitor* visitor,
-    base::JobDelegate* delegate,
-    MarkingSchedulingOracle* marking_scheduler) {
-  auto should_yield_callback = [marking_scheduler, visitor, delegate]() {
-    marking_scheduler->AddConcurrentlyMarkedBytes(
-        visitor->RecentlyMarkedBytes());
-    return delegate->ShouldYield();
-  };
-  bool finished;
-  do {
-    // Convert |previously_not_fully_constructed_worklist_| to
-    // |marking_worklist_|. This merely re-adds items with the proper
-    // callbacks.
-    finished = DrainWorklist<kDefaultConcurrentDeadlineCheckInterval>(
-        previously_not_fully_constructed_worklist_.get(),
-        [visitor](NotFullyConstructedItem& item) {
-          PageFromObject(item)->SynchronizedLoad();
-          visitor->DynamicallyMarkAddress(reinterpret_cast<ConstAddress>(item));
-        },
-        should_yield_callback, visitor->task_id());
-    if (!finished)
-      break;
-
-    // Iteratively mark all objects that are reachable from the objects
-    // currently pushed onto the marking worklist.
-    finished = DrainWorklist<kDefaultConcurrentDeadlineCheckInterval>(
-        marking_worklist_.get(),
-        [visitor](const MarkingItem& item) {
-          HeapObjectHeader* header =
-              HeapObjectHeader::FromPayload(item.base_object_payload);
-          PageFromObject(header)->SynchronizedLoad();
-          DCHECK(
-              !header
-                   ->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>());
-          item.callback(visitor, item.base_object_payload);
-          visitor->AccountMarkedBytes(header);
-        },
-        should_yield_callback, visitor->task_id());
-    if (!finished)
-      break;
-
-    finished = DrainWorklist<kDefaultConcurrentDeadlineCheckInterval>(
-        write_barrier_worklist_.get(),
-        [visitor](HeapObjectHeader* header) {
-          PageFromObject(header)->SynchronizedLoad();
-          DCHECK(
-              !header
-                   ->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>());
-          GCInfo::From(header->GcInfoIndex()).trace(visitor, header->Payload());
-          visitor->AccountMarkedBytes(header);
-        },
-        should_yield_callback, visitor->task_id());
-    if (!finished)
-      break;
-
-    {
-      ThreadHeapStatsCollector::ConcurrentScope stats_scope(
-          stats_collector(),
-          ThreadHeapStatsCollector::kConcurrentMarkInvokeEphemeronCallbacks);
-
-      // Then we iterate over the new ephemerons found by the marking visitor.
-      // Callbacks found by the concurrent marking will be flushed eventually
-      // by the mutator thread and then invoked either concurrently or by the
-      // mutator thread (in the atomic pause at latest).
-      finished = DrainWorklist<kDefaultConcurrentDeadlineCheckInterval>(
-          ephemeron_pairs_to_process_worklist_.get(),
-          [visitor](EphemeronPairItem& item) {
-            visitor->VisitEphemeron(item.key, item.value_desc);
-          },
-          should_yield_callback, visitor->task_id());
-      if (!finished)
-        break;
-    }
-
-  } while (HasWorkForConcurrentMarking());
-
-  return finished;
-}
-
-void ThreadHeap::WeakProcessing(MarkingVisitor* visitor) {
-  ThreadHeapStatsCollector::Scope stats_scope(
-      stats_collector(), ThreadHeapStatsCollector::kMarkWeakProcessing);
-
-  // Weak processing may access unmarked objects but are forbidden from
-  // resurrecting them or allocating new ones.
-  ThreadState::NoAllocationScope allocation_forbidden(ThreadState::Current());
-
-  DCHECK_EQ(WorklistTaskId::MutatorThread, visitor->task_id());
-
-  // Call weak callbacks on objects that may now be pointing to dead objects.
-  CustomCallbackItem item;
-  LivenessBroker broker = internal::LivenessBrokerFactory::Create();
-  while (weak_callback_worklist_->Pop(WorklistTaskId::MutatorThread, &item)) {
-    item.callback(broker, item.parameter);
-  }
-  // Weak callbacks should not add any new objects for marking.
-  DCHECK(marking_worklist_->IsGlobalEmpty());
-}
-
-void ThreadHeap::VerifyMarking() {
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i) {
-    arenas_[i]->VerifyMarking();
-  }
-}
-
-size_t ThreadHeap::ObjectPayloadSizeForTesting() {
-  ThreadState::AtomicPauseScope atomic_pause_scope(thread_state_);
-  ScriptForbiddenScope script_forbidden_scope;
-  size_t object_payload_size = 0;
-  thread_state_->SetGCPhase(ThreadState::GCPhase::kMarking);
-  thread_state_->Heap().MakeConsistentForGC();
-  thread_state_->Heap().PrepareForSweep(BlinkGC::CollectionType::kMajor);
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
-    object_payload_size += arenas_[i]->ObjectPayloadSizeForTesting();
-  MakeConsistentForMutator();
-  thread_state_->SetGCPhase(ThreadState::GCPhase::kSweeping);
-  thread_state_->SetGCPhase(ThreadState::GCPhase::kNone);
-  return object_payload_size;
-}
-
-void ThreadHeap::ResetAllocationPointForTesting() {
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
-    arenas_[i]->ResetAllocationPoint();
-}
-
-BasePage* ThreadHeap::LookupPageForAddress(ConstAddress address) {
-  if (PageMemoryRegion* region = region_tree_->Lookup(address)) {
-    return region->PageFromAddress(address);
-  }
-  return nullptr;
-}
-
-void ThreadHeap::MakeConsistentForGC() {
-  DCHECK(thread_state_->InAtomicMarkingPause());
-  for (BaseArena* arena : arenas_) {
-    arena->MakeConsistentForGC();
-  }
-}
-
-void ThreadHeap::MakeConsistentForMutator() {
-  DCHECK(thread_state_->InAtomicMarkingPause());
-  for (BaseArena* arena : arenas_) {
-    arena->MakeConsistentForMutator();
-  }
-}
-
-void ThreadHeap::Unmark() {
-  DCHECK(thread_state_->InAtomicMarkingPause());
-  for (BaseArena* arena : arenas_) {
-    arena->Unmark();
-  }
-}
-
-void ThreadHeap::Compact() {
-  if (!Compaction()->IsCompacting())
-    return;
-
-  ThreadHeapStatsCollector::Scope stats_scope(
-      stats_collector(), ThreadHeapStatsCollector::kAtomicPauseCompaction);
-  // Compaction is done eagerly and before the mutator threads get
-  // to run again. Doing it lazily is problematic, as the mutator's
-  // references to live objects could suddenly be invalidated by
-  // compaction of a page/heap. We do know all the references to
-  // the relocating objects just after marking, but won't later.
-  // (e.g., stack references could have been created, new objects
-  // created which refer to old collection objects, and so on.)
-
-  // Compact the hash table backing store arena first, it usually has
-  // higher fragmentation and is larger.
-  for (int i = BlinkGC::kHashTableArenaIndex; i >= BlinkGC::kVectorArenaIndex;
-       --i)
-    static_cast<NormalPageArena*>(arenas_[i])->SweepAndCompact();
-  Compaction()->Finish();
-}
-
-void ThreadHeap::PrepareForSweep(BlinkGC::CollectionType collection_type) {
-  DCHECK(thread_state_->InAtomicMarkingPause());
-  DCHECK(thread_state_->CheckThread());
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; i++)
-    arenas_[i]->PrepareForSweep(collection_type);
-}
-
-void ThreadHeap::RemoveAllPages() {
-  DCHECK(thread_state_->CheckThread());
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i)
-    arenas_[i]->RemoveAllPages();
-}
-
-void ThreadHeap::CompleteSweep() {
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; i++)
-    arenas_[i]->CompleteSweep();
-}
-
-void ThreadHeap::InvokeFinalizersOnSweptPages() {
-  for (size_t i = BlinkGC::kNormalPage1ArenaIndex; i < BlinkGC::kNumberOfArenas;
-       i++)
-    arenas_[i]->InvokeFinalizersOnSweptPages();
-}
-
-#if defined(ADDRESS_SANITIZER)
-void ThreadHeap::PoisonUnmarkedObjects() {
-  // Poisoning all unmarked objects in the other arenas.
-  for (int i = 1; i < BlinkGC::kNumberOfArenas; i++)
-    arenas_[i]->PoisonUnmarkedObjects();
-}
-#endif
-
-#if DCHECK_IS_ON()
-BasePage* ThreadHeap::FindPageFromAddress(Address address) {
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i) {
-    if (BasePage* page = arenas_[i]->FindPageFromAddress(address))
-      return page;
-  }
-  return nullptr;
-}
-#endif
-
-void ThreadHeap::CollectStatistics(ThreadState::Statistics* stats) {
-#define SNAPSHOT_ARENA(name)                                \
-  arenas_[BlinkGC::k##name##ArenaIndex]->CollectStatistics( \
-      BlinkGC::ToString(BlinkGC::k##name##ArenaIndex), stats);
-
-  FOR_EACH_ARENA(SNAPSHOT_ARENA)
-#undef SNAPSHOT_ARENA
-}
-
-bool ThreadHeap::AdvanceLazySweep(base::TimeTicks deadline) {
-  static constexpr base::TimeDelta slack = base::TimeDelta::FromSecondsD(0.001);
-  for (size_t i = 0; i < BlinkGC::kNumberOfArenas; i++) {
-    // lazySweepWithDeadline() won't check the deadline until it sweeps
-    // 10 pages. So we give a small slack for safety.
-    const base::TimeDelta remaining_budget =
-        deadline - slack - base::TimeTicks::Now();
-    if (remaining_budget <= base::TimeDelta() ||
-        !arenas_[i]->LazySweepWithDeadline(deadline)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-bool ThreadHeap::AdvanceConcurrentSweep(base::JobDelegate* job) {
-  for (size_t i = 0; i < BlinkGC::kNumberOfArenas; i++) {
-    while (!arenas_[i]->ConcurrentSweepOnePage()) {
-      if (job->ShouldYield())
-        return false;
-    }
-  }
-  return true;
-}
-
-// TODO(omerkatz): Temporary solution until concurrent marking is ready. see
-// https://crrev.com/c/1730054 for details. Eventually this will be removed.
-bool ThreadHeap::FlushV8References(base::TimeTicks deadline) {
-  if (!thread_state_->IsUnifiedGCMarkingInProgress())
-    return true;
-
-  DCHECK(base::FeatureList::IsEnabled(
-             blink::features::kBlinkHeapConcurrentMarking) ||
-         v8_references_worklist_->IsGlobalEmpty());
-
-  v8::EmbedderHeapTracer* controller =
-      reinterpret_cast<v8::EmbedderHeapTracer*>(
-          thread_state_->unified_heap_controller());
-  return DrainWorklistWithDeadline(
-      deadline, v8_references_worklist_.get(),
-      [controller](const V8Reference& reference) {
-        if (!reference->Get().IsEmpty()) {
-          controller->RegisterEmbedderReference(
-              reference->template Cast<v8::Data>().Get());
-        }
-      },
-      WorklistTaskId::MutatorThread);
-}
-
-ThreadHeap* ThreadHeap::main_thread_heap_ = nullptr;
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/heap.h b/third_party/blink/renderer/platform/heap/impl/heap.h
deleted file mode 100644
index 687463da..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap.h
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_H_
-
-#include <limits>
-#include <memory>
-#include <unordered_set>
-
-#include "base/dcheck_is_on.h"
-#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h"
-#include "third_party/blink/renderer/platform/heap/impl/worklist.h"
-#include "third_party/blink/renderer/platform/heap/process_heap.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-
-namespace blink {
-
-namespace incremental_marking_test {
-class IncrementalMarkingScopeBase;
-}  // namespace incremental_marking_test
-
-class ConcurrentMarkingVisitor;
-class ThreadHeapStatsCollector;
-class PageBloomFilter;
-class PagePool;
-class ProcessHeapReporter;
-class RegionTree;
-class MarkingSchedulingOracle;
-
-using MarkingItem = TraceDescriptor;
-using NotFullyConstructedItem = const void*;
-
-struct EphemeronPairItem {
-  const void* key;
-  TraceDescriptor value_desc;
-};
-
-struct CustomCallbackItem {
-  WeakCallback callback;
-  const void* parameter;
-};
-
-struct NotSafeToConcurrentlyTraceItem {
-  TraceDescriptor desc;
-  size_t bailout_size;
-};
-
-using V8Reference = const TraceWrapperV8Reference<v8::Value>*;
-
-// Segment size of 512 entries necessary to avoid throughput regressions. Since
-// the work list is currently a temporary object this is not a problem.
-using MarkingWorklist = Worklist<MarkingItem, 512 /* local entries */>;
-using WriteBarrierWorklist = Worklist<HeapObjectHeader*, 64>;
-using NotFullyConstructedWorklist =
-    Worklist<NotFullyConstructedItem, 16 /* local entries */>;
-using WeakCallbackWorklist =
-    Worklist<CustomCallbackItem, 64 /* local entries */>;
-// Using large local segments here (sized 512 entries) to avoid throughput
-// regressions.
-using MovableReferenceWorklist =
-    Worklist<const MovableReference*, 256 /* local entries */>;
-using EphemeronPairsWorklist =
-    Worklist<EphemeronPairItem, 64 /* local entries */>;
-using V8ReferencesWorklist = Worklist<V8Reference, 16 /* local entries */>;
-using NotSafeToConcurrentlyTraceWorklist =
-    Worklist<NotSafeToConcurrentlyTraceItem, 64 /* local entries */>;
-
-class WeakContainersWorklist {
- public:
-  inline void Push(const HeapObjectHeader* object) {
-    DCHECK(object);
-    WTF::MutexLocker locker(lock_);
-    objects_.insert(object);
-  }
-
-  inline bool Contains(const HeapObjectHeader* object) {
-    // This method is called only during atomic pause, so lock is not needed.
-    DCHECK(object);
-    return objects_.find(object) != objects_.end();
-  }
-
- private:
-  WTF::Mutex lock_;
-  std::unordered_set<const HeapObjectHeader*> objects_;
-};
-
-class HeapCompact;
-template <typename T>
-class Member;
-template <typename T>
-class WeakMember;
-template <typename T>
-class UntracedMember;
-
-namespace internal {
-
-class LivenessBrokerFactory;
-
-template <typename T, bool = NeedsAdjustPointer<T>::value>
-class ObjectAliveTrait;
-
-template <typename T>
-class ObjectAliveTrait<T, false> {
-  STATIC_ONLY(ObjectAliveTrait);
-
- public:
-  static bool IsHeapObjectAlive(const T* object) {
-    static_assert(sizeof(T), "T must be fully defined");
-    return HeapObjectHeader::FromPayload(object)->IsMarked();
-  }
-};
-
-template <typename T>
-class ObjectAliveTrait<T, true> {
-  STATIC_ONLY(ObjectAliveTrait);
-
- public:
-  NO_SANITIZE_ADDRESS
-  static bool IsHeapObjectAlive(const T* object) {
-    static_assert(sizeof(T), "T must be fully defined");
-    const HeapObjectHeader* header = HeapObjectHeader::FromPayload(
-        TraceTrait<T>::GetTraceDescriptor(object).base_object_payload);
-    DCHECK(!header->IsInConstruction() || header->IsMarked());
-    return header->IsMarked();
-  }
-};
-
-template <typename T, typename = int>
-struct IsGarbageCollectedContainer : std::false_type {};
-
-template <typename T>
-struct IsGarbageCollectedContainer<
-    T,
-    typename T::IsGarbageCollectedCollectionTypeMarker> : std::true_type {};
-
-}  // namespace internal
-
-class PLATFORM_EXPORT ThreadHeap {
-  USING_FAST_MALLOC(ThreadHeap);
-
-  using EphemeronProcessing = ThreadState::EphemeronProcessing;
-
- public:
-  explicit ThreadHeap(ThreadState*);
-  ~ThreadHeap();
-
-  MarkingWorklist* GetMarkingWorklist() const {
-    return marking_worklist_.get();
-  }
-
-  WriteBarrierWorklist* GetWriteBarrierWorklist() const {
-    return write_barrier_worklist_.get();
-  }
-
-  NotFullyConstructedWorklist* GetNotFullyConstructedWorklist() const {
-    return not_fully_constructed_worklist_.get();
-  }
-
-  NotFullyConstructedWorklist* GetPreviouslyNotFullyConstructedWorklist()
-      const {
-    return previously_not_fully_constructed_worklist_.get();
-  }
-
-  WeakCallbackWorklist* GetWeakCallbackWorklist() const {
-    return weak_callback_worklist_.get();
-  }
-
-  MovableReferenceWorklist* GetMovableReferenceWorklist() const {
-    return movable_reference_worklist_.get();
-  }
-
-  EphemeronPairsWorklist* GetDiscoveredEphemeronPairsWorklist() const {
-    return discovered_ephemeron_pairs_worklist_.get();
-  }
-
-  EphemeronPairsWorklist* GetEphemeronPairsToProcessWorklist() const {
-    return ephemeron_pairs_to_process_worklist_.get();
-  }
-
-  V8ReferencesWorklist* GetV8ReferencesWorklist() const {
-    return v8_references_worklist_.get();
-  }
-
-  NotSafeToConcurrentlyTraceWorklist* GetNotSafeToConcurrentlyTraceWorklist()
-      const {
-    return not_safe_to_concurrently_trace_worklist_.get();
-  }
-
-  WeakContainersWorklist* GetWeakContainersWorklist() const {
-    return weak_containers_worklist_.get();
-  }
-
-  // Register an ephemeron table for fixed-point iteration.
-  void RegisterWeakTable(void* container_object, EphemeronCallback);
-
-  // Heap compaction registration methods:
-
-  // Checks whether we need to register |addr| as a backing store or a slot
-  // containing reference to it.
-  bool ShouldRegisterMovingAddress();
-
-  RegionTree* GetRegionTree() { return region_tree_.get(); }
-
-  static inline size_t AllocationSizeFromSize(size_t size) {
-    // Add space for header.
-    size_t allocation_size = size + sizeof(HeapObjectHeader);
-    // The allocation size calculation can overflow for large sizes.
-    CHECK_GT(allocation_size, size);
-    // Align size with allocation granularity.
-    allocation_size = (allocation_size + kAllocationMask) & ~kAllocationMask;
-    return allocation_size;
-  }
-  Address AllocateOnArenaIndex(ThreadState*,
-                               size_t,
-                               int arena_index,
-                               uint32_t gc_info_index,
-                               const char* type_name);
-  template <typename T>
-  static Address Allocate(size_t);
-
-  void WeakProcessing(MarkingVisitor*);
-
-  // Moves not fully constructed objects to previously not fully constructed
-  // objects. Such objects can be iterated using the Trace() method and do
-  // not need to rely on conservative handling.
-  void FlushNotFullyConstructedObjects();
-
-  // Moves ephemeron pairs from |discovered_ephemeron_pairs_worklist_| to
-  // |ephemeron_pairs_to_process_worklist_|
-  void FlushEphemeronPairs(EphemeronProcessing);
-
-  // Marks not fully constructed objects.
-  void MarkNotFullyConstructedObjects(MarkingVisitor*);
-  // Marks the transitive closure including ephemerons.
-  bool AdvanceMarking(MarkingVisitor*, base::TimeTicks, EphemeronProcessing);
-  void VerifyMarking();
-
-  // Returns true if concurrent markers will have work to steal
-  bool HasWorkForConcurrentMarking() const;
-  // Returns the amount of work currently available for stealing (there could be
-  // work remaining even if this is 0).
-  size_t ConcurrentMarkingGlobalWorkSize() const;
-  // Returns true if marker is done
-  bool AdvanceConcurrentMarking(ConcurrentMarkingVisitor*,
-                                base::JobDelegate*,
-                                MarkingSchedulingOracle* marking_scheduler);
-
-  // Conservatively checks whether an address is a pointer in any of the
-  // thread heaps.  If so marks the object pointed to as live.
-  Address CheckAndMarkPointer(MarkingVisitor*, Address);
-
-  // Visits remembered sets.
-  void VisitRememberedSets(MarkingVisitor*);
-
-  size_t ObjectPayloadSizeForTesting();
-  void ResetAllocationPointForTesting();
-
-  PagePool* GetFreePagePool() { return free_page_pool_.get(); }
-
-  // This look-up uses the region search tree and a negative contains cache to
-  // provide an efficient mapping from arbitrary addresses to the containing
-  // heap-page if one exists.
-  BasePage* LookupPageForAddress(ConstAddress);
-
-  HeapCompact* Compaction();
-
-  // Get one of the heap structures for this thread.
-  // The thread heap is split into multiple heap parts based on object types
-  // and object sizes.
-  BaseArena* Arena(int arena_index) const {
-    DCHECK_LE(0, arena_index);
-    DCHECK_LT(arena_index, BlinkGC::kNumberOfArenas);
-    return arenas_[arena_index];
-  }
-
-  static bool IsVectorArenaIndex(int arena_index) {
-    return BlinkGC::kVectorArenaIndex == arena_index;
-  }
-  static bool IsNormalArenaIndex(int);
-
-  void MakeConsistentForGC();
-  // MakeConsistentForMutator() drops marks from marked objects and rebuild
-  // free lists. This is called after taking a snapshot and before resuming
-  // the executions of mutators.
-  void MakeConsistentForMutator();
-
-  // Unmarks all objects in the entire heap. This is supposed to be called in
-  // the beginning of major GC.
-  void Unmark();
-
-  void Compact();
-
-  bool AdvanceLazySweep(base::TimeTicks deadline);
-  bool AdvanceConcurrentSweep(base::JobDelegate*);
-
-  void PrepareForSweep(BlinkGC::CollectionType);
-  void RemoveAllPages();
-  void InvokeFinalizersOnSweptPages();
-  void CompleteSweep();
-
-  void CollectStatistics(ThreadState::Statistics* statistics);
-
-  ThreadHeapStatsCollector* stats_collector() const {
-    return heap_stats_collector_.get();
-  }
-
-#if defined(ADDRESS_SANITIZER)
-  void PoisonUnmarkedObjects();
-#endif
-
-#if DCHECK_IS_ON()
-  // Infrastructure to determine if an address is within one of the
-  // address ranges for the Blink heap. If the address is in the Blink
-  // heap the containing heap page is returned.
-  BasePage* FindPageFromAddress(Address);
-  BasePage* FindPageFromAddress(const void* pointer) {
-    return FindPageFromAddress(
-        reinterpret_cast<Address>(const_cast<void*>(pointer)));
-  }
-#endif
-
-  PageBloomFilter* page_bloom_filter() { return page_bloom_filter_.get(); }
-
-  bool IsInLastAllocatedRegion(Address address) const;
-  void SetLastAllocatedRegion(Address start, size_t length);
-
- private:
-  struct LastAllocatedRegion {
-    Address start = nullptr;
-    size_t length = 0;
-  };
-
-  static int ArenaIndexForObjectSize(size_t);
-
-  void SetupWorklists(bool);
-  void DestroyMarkingWorklists(BlinkGC::StackState);
-  void DestroyCompactionWorklists();
-
-  bool InvokeEphemeronCallbacks(EphemeronProcessing,
-                                MarkingVisitor*,
-                                base::TimeTicks);
-
-  bool FlushV8References(base::TimeTicks);
-
-  ThreadState* thread_state_;
-  std::unique_ptr<ThreadHeapStatsCollector> heap_stats_collector_;
-  std::unique_ptr<RegionTree> region_tree_;
-  std::unique_ptr<PageBloomFilter> page_bloom_filter_;
-  std::unique_ptr<PagePool> free_page_pool_;
-  std::unique_ptr<ProcessHeapReporter> process_heap_reporter_;
-
-  // All objects on this worklist have been fully initialized and assigned a
-  // trace callback for iterating the body of the object. This worklist should
-  // contain almost all objects.
-  std::unique_ptr<MarkingWorklist> marking_worklist_;
-
-  // Objects on this worklist have been collected in the write barrier. The
-  // worklist is different from |marking_worklist_| to minimize execution in the
-  // path where a write barrier is executed.
-  std::unique_ptr<WriteBarrierWorklist> write_barrier_worklist_;
-
-  // Objects on this worklist were observed to be in construction (in their
-  // constructor) and thus have been delayed for processing. They have not yet
-  // been assigned a valid header and trace callback.
-  std::unique_ptr<NotFullyConstructedWorklist> not_fully_constructed_worklist_;
-
-  // Objects on this worklist were previously in construction but have been
-  // moved here upon observing a safepoint, i.e., processing without stack. They
-  // have not yet been assigned a valid header and trace callback but are fully
-  // specified and can thus be iterated using the trace callback (which can be
-  // looked up dynamically).
-  std::unique_ptr<NotFullyConstructedWorklist>
-      previously_not_fully_constructed_worklist_;
-
-  // Worklist of weak callbacks accumulated for objects. Such callbacks are
-  // processed after finishing marking objects.
-  std::unique_ptr<WeakCallbackWorklist> weak_callback_worklist_;
-
-  // The worklist is to remember slots that are traced during
-  // marking phases. The mapping between the slots and the backing stores are
-  // created at the atomic pause phase.
-  std::unique_ptr<MovableReferenceWorklist> movable_reference_worklist_;
-
-  // Worklist of ephemeron callbacks. Used to pass new callbacks from
-  // MarkingVisitor to ThreadHeap.
-  std::unique_ptr<EphemeronPairsWorklist> discovered_ephemeron_pairs_worklist_;
-  std::unique_ptr<EphemeronPairsWorklist> ephemeron_pairs_to_process_worklist_;
-
-  // Worklist for storing the V8 references until ThreadHeap can flush them
-  // to V8.
-  std::unique_ptr<V8ReferencesWorklist> v8_references_worklist_;
-
-  std::unique_ptr<NotSafeToConcurrentlyTraceWorklist>
-      not_safe_to_concurrently_trace_worklist_;
-
-  std::unique_ptr<WeakContainersWorklist> weak_containers_worklist_;
-
-  std::unique_ptr<HeapCompact> compaction_;
-
-  LastAllocatedRegion last_allocated_region_;
-
-  BaseArena* arenas_[BlinkGC::kNumberOfArenas];
-
-  static ThreadHeap* main_thread_heap_;
-
-  static constexpr size_t kStepsBeforeEphemeronPairsFlush = 4u;
-  size_t steps_since_last_ephemeron_pairs_flush_ = 0;
-  static constexpr size_t kStepsBeforeEphemeronProcessing = 16u;
-  size_t steps_since_last_ephemeron_processing_ = 0;
-
-  friend class incremental_marking_test::IncrementalMarkingScopeBase;
-  template <typename T>
-  friend class Member;
-  friend class ThreadState;
-};
-
-template <typename T>
-class GarbageCollected {
-  IS_GARBAGE_COLLECTED_TYPE();
-
- public:
-  using ParentMostGarbageCollectedType = T;
-
-  // Must use MakeGarbageCollected.
-  void* operator new(size_t) = delete;
-  void* operator new[](size_t) = delete;
-  // The garbage collector is taking care of reclaiming the object. Also,
-  // virtual destructor requires an unambiguous, accessible 'operator delete'.
-  void operator delete(void*) { NOTREACHED(); }
-  void operator delete[](void*) = delete;
-
-  template <typename Derived>
-  static void* AllocateObject(size_t size) {
-    return ThreadHeap::Allocate<GCInfoFoldedType<Derived>>(size);
-  }
-
- protected:
-  // This trait in theory can be moved to gc_info.h, but that would cause
-  // significant memory bloat caused by huge number of ThreadHeap::Allocate<>
-  // instantiations, which linker is not able to fold.
-  template <typename Derived>
-  class GCInfoFolded {
-    static constexpr bool is_virtual_destructor_at_base =
-        std::has_virtual_destructor<ParentMostGarbageCollectedType>::value;
-    static constexpr bool both_trivially_destructible =
-        std::is_trivially_destructible<ParentMostGarbageCollectedType>::value &&
-        std::is_trivially_destructible<Derived>::value;
-    static constexpr bool has_custom_dispatch_at_base =
-        internal::HasFinalizeGarbageCollectedObject<
-            ParentMostGarbageCollectedType>::value;
-
-   public:
-    using Type = std::conditional_t<is_virtual_destructor_at_base ||
-                                        both_trivially_destructible ||
-                                        has_custom_dispatch_at_base,
-                                    ParentMostGarbageCollectedType,
-                                    Derived>;
-  };
-
-  template <typename Derived>
-  using GCInfoFoldedType = typename GCInfoFolded<Derived>::Type;
-
-  GarbageCollected() = default;
-};
-
-// Used for passing custom sizes to MakeGarbageCollected.
-struct AdditionalBytes {
-  explicit AdditionalBytes(wtf_size_t bytes) : value(bytes) {}
-  const wtf_size_t value;
-};
-
-template <typename T>
-struct MakeGarbageCollectedTrait {
-  template <typename... Args>
-  static T* Call(Args&&... args) {
-    static_assert(WTF::IsGarbageCollectedType<T>::value,
-                  "T needs to be a garbage collected object");
-    static_assert(
-        std::is_trivially_destructible<T>::value ||
-            std::has_virtual_destructor<T>::value || std::is_final<T>::value ||
-            internal::IsGarbageCollectedContainer<T>::value ||
-            internal::HasFinalizeGarbageCollectedObject<T>::value,
-        "Finalized GarbageCollected class should either have a virtual "
-        "destructor or be marked as final");
-    static_assert(!IsGarbageCollectedMixin<T>::value ||
-                      sizeof(T) <= kLargeObjectSizeThreshold,
-                  "GarbageCollectedMixin may not be a large object");
-    void* memory = T::template AllocateObject<T>(sizeof(T));
-    HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
-    // Placement new as regular operator new() is deleted.
-    T* object = ::new (memory) T(std::forward<Args>(args)...);
-    header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
-    return object;
-  }
-
-  template <typename... Args>
-  static T* Call(AdditionalBytes additional_bytes, Args&&... args) {
-    static_assert(WTF::IsGarbageCollectedType<T>::value,
-                  "T needs to be a garbage collected object");
-    static_assert(
-        std::is_trivially_destructible<T>::value ||
-            std::has_virtual_destructor<T>::value || std::is_final<T>::value ||
-            internal::IsGarbageCollectedContainer<T>::value ||
-            internal::HasFinalizeGarbageCollectedObject<T>::value,
-        "Finalized GarbageCollected class should either have a virtual "
-        "destructor or be marked as final.");
-    const size_t size = sizeof(T) + additional_bytes.value;
-    if (IsGarbageCollectedMixin<T>::value) {
-      // Ban large mixin so we can use PageFromObject() on them.
-      CHECK_GE(kLargeObjectSizeThreshold, size)
-          << "GarbageCollectedMixin may not be a large object";
-    }
-    void* memory = T::template AllocateObject<T>(size);
-    HeapObjectHeader* header = HeapObjectHeader::FromPayload(memory);
-    // Placement new as regular operator new() is deleted.
-    T* object = ::new (memory) T(std::forward<Args>(args)...);
-    header->MarkFullyConstructed<HeapObjectHeader::AccessMode::kAtomic>();
-    return object;
-  }
-};
-
-template <typename T, typename = void>
-struct PostConstructionHookTrait {
-  static void Call(T*) {}
-};
-
-// Default MakeGarbageCollected: Constructs an instance of T, which is a garbage
-// collected type.
-template <typename T, typename... Args>
-T* MakeGarbageCollected(Args&&... args) {
-  T* object = MakeGarbageCollectedTrait<T>::Call(std::forward<Args>(args)...);
-  PostConstructionHookTrait<T>::Call(object);
-  return object;
-}
-
-// Constructs an instance of T, which is a garbage collected type. This special
-// version takes size which enables constructing inline objects.
-template <typename T, typename... Args>
-T* MakeGarbageCollected(AdditionalBytes additional_bytes, Args&&... args) {
-  T* object = MakeGarbageCollectedTrait<T>::Call(additional_bytes,
-                                                 std::forward<Args>(args)...);
-  PostConstructionHookTrait<T>::Call(object);
-  return object;
-}
-
-// Assigning class types to their arenas.
-//
-// We use sized arenas for most 'normal' objects to improve memory locality.
-// It seems that the same type of objects are likely to be accessed together,
-// which means that we want to group objects by type. That's one reason
-// why we provide dedicated arenas for popular types (e.g., Node, CSSValue),
-// but it's not practical to prepare dedicated arenas for all types.
-// Thus we group objects by their sizes, hoping that this will approximately
-// group objects by their types.
-//
-
-inline int ThreadHeap::ArenaIndexForObjectSize(size_t size) {
-  if (size < 64) {
-    if (size < 32)
-      return BlinkGC::kNormalPage1ArenaIndex;
-    return BlinkGC::kNormalPage2ArenaIndex;
-  }
-  if (size < 128)
-    return BlinkGC::kNormalPage3ArenaIndex;
-  return BlinkGC::kNormalPage4ArenaIndex;
-}
-
-inline bool ThreadHeap::IsNormalArenaIndex(int index) {
-  return index >= BlinkGC::kNormalPage1ArenaIndex &&
-         index <= BlinkGC::kNormalPage4ArenaIndex;
-}
-
-inline Address ThreadHeap::AllocateOnArenaIndex(ThreadState* state,
-                                                size_t size,
-                                                int arena_index,
-                                                uint32_t gc_info_index,
-                                                const char* type_name) {
-  DCHECK(state->IsAllocationAllowed());
-  DCHECK_NE(arena_index, BlinkGC::kLargeObjectArenaIndex);
-  NormalPageArena* arena = static_cast<NormalPageArena*>(Arena(arena_index));
-  Address address =
-      arena->AllocateObject(AllocationSizeFromSize(size), gc_info_index);
-  return address;
-}
-
-template <typename T>
-Address ThreadHeap::Allocate(size_t size) {
-  ThreadState* state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-  const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(T);
-  return state->Heap().AllocateOnArenaIndex(
-      state, size, ThreadHeap::ArenaIndexForObjectSize(size),
-      GCInfoTrait<T>::Index(), type_name);
-}
-
-inline bool ThreadHeap::IsInLastAllocatedRegion(Address address) const {
-  return last_allocated_region_.start <= address &&
-         address <
-             (last_allocated_region_.start + last_allocated_region_.length);
-}
-
-inline void ThreadHeap::SetLastAllocatedRegion(Address start, size_t length) {
-  last_allocated_region_.start = start;
-  last_allocated_region_.length = length;
-}
-
-class PLATFORM_EXPORT LivenessBroker final {
- public:
-  template <typename T>
-  bool IsHeapObjectAlive(const T*) const;
-  template <typename T>
-  bool IsHeapObjectAlive(const WeakMember<T>&) const;
-  template <typename T>
-  bool IsHeapObjectAlive(const UntracedMember<T>&) const;
-
- private:
-  LivenessBroker() = default;
-  friend class internal::LivenessBrokerFactory;
-};
-
-template <typename T>
-bool LivenessBroker::IsHeapObjectAlive(const T* object) const {
-  static_assert(sizeof(T), "T must be fully defined");
-  // The strongification of collections relies on the fact that once a
-  // collection has been strongified, there is no way that it can contain
-  // non-live entries, so no entries will be removed. Since you can't set
-  // the mark bit on a null pointer, that means that null pointers are
-  // always 'alive'.
-  if (!object)
-    return true;
-  // TODO(keishi): some tests create CrossThreadPersistent on non attached
-  // threads.
-  if (!ThreadState::Current())
-    return true;
-  DCHECK(&ThreadState::Current()->Heap() ==
-         &PageFromObject(object)->Arena()->GetThreadState()->Heap());
-  return internal::ObjectAliveTrait<T>::IsHeapObjectAlive(object);
-}
-
-template <typename T>
-bool LivenessBroker::IsHeapObjectAlive(const WeakMember<T>& weak_member) const {
-  return IsHeapObjectAlive(weak_member.Get());
-}
-
-template <typename T>
-bool LivenessBroker::IsHeapObjectAlive(
-    const UntracedMember<T>& untraced_member) const {
-  return IsHeapObjectAlive(untraced_member.Get());
-}
-
-template <typename T>
-void Visitor::HandleWeakCell(const LivenessBroker& broker, const void* object) {
-  WeakMember<T>* weak_member =
-      reinterpret_cast<WeakMember<T>*>(const_cast<void*>(object));
-  if (weak_member->Get()) {
-    if (weak_member->IsHashTableDeletedValue()) {
-      // This can happen when weak fields are deleted while incremental marking
-      // is running. Deleted values need to be preserved to avoid reviving
-      // objects in containers.
-      return;
-    }
-    if (!broker.IsHeapObjectAlive(weak_member->Get()))
-      weak_member->Clear();
-  }
-}
-
-namespace internal {
-
-class LivenessBrokerFactory final {
- public:
-  static LivenessBroker Create() { return LivenessBroker(); }
-};
-
-}  // namespace internal
-
-#if DCHECK_IS_ON()
-static constexpr bool kBlinkGCHasDebugChecks = true;
-#else
-static constexpr bool kBlinkGCHasDebugChecks = false;
-#endif  // DCHECK_IS_ON()
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_allocator_impl.cc b/third_party/blink/renderer/platform/heap/impl/heap_allocator_impl.cc
deleted file mode 100644
index 8f690a3..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_allocator_impl.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/heap_allocator_impl.h"
-
-namespace blink {
-
-namespace {
-
-struct BackingModifier {
-  bool can_modify;
-  BasePage* const page;
-  HeapObjectHeader* const header;
-};
-
-BackingModifier CanModifyBacking(ThreadState* const state, void* address) {
-  // - |SweepForbidden| protects against modifying objects from destructors.
-  // - |IsSweepingInProgress| protects against modifying objects while
-  // concurrent sweeping is in progress.
-  // - |in_atomic_pause| protects against modifying objects from within the GC.
-  // This can
-  //   e.g. happen when hash table buckets that have containers inlined are
-  //   freed during weakness processing.
-  // - |IsMarkingInProgress| protects against incremental marking which may have
-  //   registered callbacks.
-  if (state->SweepForbidden() || state->IsSweepingInProgress() ||
-      state->in_atomic_pause() || state->IsMarkingInProgress())
-    return {false, nullptr, nullptr};
-
-  // - Don't adjust large objects because their page is never reused.
-  // - Don't free backings allocated on other threads.
-  BasePage* page = PageFromObject(address);
-  if (page->IsLargeObjectPage() || page->Arena()->GetThreadState() != state)
-    return {false, nullptr, nullptr};
-
-  HeapObjectHeader* const header = HeapObjectHeader::FromPayload(address);
-  // - Guards against pages that have not been swept. Technically, it should be
-  // fine to modify those backings. We bail out to maintain the invariant that
-  // no marked backing is modified.
-  if (header->IsMarked())
-    return {false, nullptr, nullptr};
-  return {true, page, header};
-}
-
-}  // namespace
-
-void HeapAllocator::BackingFree(void* address) {
-  if (!address)
-    return;
-
-  ThreadState* const state = ThreadState::Current();
-  BackingModifier result = CanModifyBacking(state, address);
-  if (!result.can_modify)
-    return;
-
-  static_cast<NormalPage*>(result.page)
-      ->ArenaForNormalPage()
-      ->PromptlyFreeObject(result.header);
-}
-
-void HeapAllocator::FreeVectorBacking(void* address) {
-  BackingFree(address);
-}
-
-bool HeapAllocator::BackingExpand(void* address, size_t new_size) {
-  if (!address)
-    return false;
-
-  ThreadState* state = ThreadState::Current();
-
-  BackingModifier result = CanModifyBacking(state, address);
-  if (!result.can_modify)
-    return false;
-  DCHECK(!state->in_atomic_pause());
-  DCHECK(state->IsAllocationAllowed());
-  DCHECK_EQ(&state->Heap(), &ThreadState::FromObject(address)->Heap());
-
-  // FIXME: Support expand for large objects.
-  // Don't expand backings allocated on other threads.
-  BasePage* page = PageFromObject(address);
-  if (page->IsLargeObjectPage() || page->Arena()->GetThreadState() != state)
-    return false;
-
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(address);
-  NormalPageArena* arena = static_cast<NormalPage*>(page)->ArenaForNormalPage();
-  return arena->ExpandObject(header, new_size);
-}
-
-bool HeapAllocator::ExpandVectorBacking(void* address, size_t new_size) {
-  return BackingExpand(address, new_size);
-}
-
-bool HeapAllocator::BackingShrink(void* address,
-                                  size_t quantized_current_size,
-                                  size_t quantized_shrunk_size) {
-  if (!address || quantized_shrunk_size == quantized_current_size)
-    return true;
-
-  DCHECK_LT(quantized_shrunk_size, quantized_current_size);
-
-  ThreadState* const state = ThreadState::Current();
-  BackingModifier result = CanModifyBacking(state, address);
-  if (!result.can_modify)
-    return false;
-
-  DCHECK(state->IsAllocationAllowed());
-  DCHECK_EQ(&state->Heap(), &ThreadState::FromObject(address)->Heap());
-
-  NormalPageArena* arena =
-      static_cast<NormalPage*>(result.page)->ArenaForNormalPage();
-  // We shrink the object only if the shrinking will make a non-small
-  // prompt-free block.
-  // FIXME: Optimize the threshold size.
-  if (quantized_current_size <= quantized_shrunk_size +
-                                    sizeof(HeapObjectHeader) +
-                                    sizeof(void*) * 32 &&
-      !arena->IsObjectAllocatedAtAllocationPoint(result.header))
-    return true;
-
-  arena->ShrinkObject(result.header, quantized_shrunk_size);
-  return true;
-}
-
-bool HeapAllocator::ShrinkVectorBacking(void* address,
-                                        size_t quantized_current_size,
-                                        size_t quantized_shrunk_size) {
-  return BackingShrink(address, quantized_current_size, quantized_shrunk_size);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_allocator_impl.h b/third_party/blink/renderer/platform/heap/impl/heap_allocator_impl.h
deleted file mode 100644
index d58dc394..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_allocator_impl.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_ALLOCATOR_IMPL_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_ALLOCATOR_IMPL_H_
-
-#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_table_backing.h"
-#include "third_party/blink/renderer/platform/heap/collection_support/heap_vector_backing.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap.h"
-#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
-
-namespace blink {
-
-// This is a static-only class used as a trait on collections to make them heap
-// allocated.
-class PLATFORM_EXPORT HeapAllocator {
-  STATIC_ONLY(HeapAllocator);
-
- public:
-  using LivenessBroker = blink::LivenessBroker;
-  using Visitor = blink::Visitor;
-  static constexpr bool kIsGarbageCollected = true;
-
-  // See wtf/size_t.h for details.
-  static constexpr size_t kMaxHeapObjectSizeLog2 = 27;
-  static constexpr size_t kMaxHeapObjectSize = 1 << kMaxHeapObjectSizeLog2;
-
-  template <typename T>
-  static size_t MaxElementCountInBackingStore() {
-    return kMaxHeapObjectSize / sizeof(T);
-  }
-
-  template <typename T>
-  static size_t QuantizedSize(size_t count) {
-    CHECK_LE(count, MaxElementCountInBackingStore<T>());
-    // Oilpan's internal size is independent of MaxElementCountInBackingStore()
-    // and the required size to match capacity needs.
-    return count * sizeof(T);
-  }
-
-  template <typename T>
-  static T* AllocateVectorBacking(size_t size) {
-    return reinterpret_cast<T*>(
-        MakeGarbageCollected<HeapVectorBacking<T>>(size / sizeof(T)));
-  }
-  static void FreeVectorBacking(void*);
-  static bool ExpandVectorBacking(void*, size_t);
-  static bool ShrinkVectorBacking(void* address,
-                                  size_t quantized_current_size,
-                                  size_t quantized_shrunk_size);
-
-  template <typename T, typename HashTable>
-  static T* AllocateHashTableBacking(size_t size) {
-    static_assert(sizeof(T) == sizeof(typename HashTable::ValueType),
-                  "T must match ValueType.");
-    return reinterpret_cast<T*>(
-        MakeGarbageCollected<HeapHashTableBacking<HashTable>>(size /
-                                                              sizeof(T)));
-  }
-  template <typename T, typename HashTable>
-  static T* AllocateZeroedHashTableBacking(size_t size) {
-    return AllocateHashTableBacking<T, HashTable>(size);
-  }
-  template <typename T, typename HashTable>
-  static void FreeHashTableBacking(void* address) {
-    BackingFree(address);
-  }
-  template <typename T, typename HashTable>
-  static bool ExpandHashTableBacking(T* address, size_t new_size) {
-    return BackingExpand(address, new_size);
-  }
-
-  template <typename Traits>
-  static bool CanReuseHashTableDeletedBucket() {
-    if (Traits::kEmptyValueIsZero || !Traits::kCanTraceConcurrently)
-      return true;
-    return !ThreadState::Current()->IsMarkingInProgress();
-  }
-
-  static bool IsAllocationAllowed() {
-    return ThreadState::Current()->IsAllocationAllowed();
-  }
-
-  static bool IsIncrementalMarking() {
-    return ThreadState::IsAnyIncrementalMarking() &&
-           ThreadState::Current()->IsIncrementalMarking();
-  }
-
-  static void EnterGCForbiddenScope() {
-    ThreadState::Current()->EnterGCForbiddenScope();
-  }
-
-  static void LeaveGCForbiddenScope() {
-    ThreadState::Current()->LeaveGCForbiddenScope();
-  }
-
-  template <typename T, typename Traits>
-  static void Trace(Visitor* visitor, const T& t) {
-    TraceCollectionIfEnabled<WTF::WeakHandlingTrait<T>::value, T,
-                             Traits>::Trace(visitor, &t);
-  }
-
-  template <typename T>
-  static void TraceVectorBacking(Visitor* visitor,
-                                 const T* backing,
-                                 const T* const* backing_slot) {
-    visitor->TraceMovablePointer(backing_slot);
-    visitor->Trace(reinterpret_cast<const HeapVectorBacking<T>*>(backing));
-  }
-
-  template <typename T, typename HashTable>
-  static void TraceHashTableBackingStrongly(Visitor* visitor,
-                                            const T* backing,
-                                            const T* const* backing_slot) {
-    visitor->TraceMovablePointer(backing_slot);
-    visitor->Trace(
-        reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing));
-  }
-
-  template <typename T, typename HashTable>
-  static void TraceHashTableBackingWeakly(Visitor* visitor,
-                                          const T* backing,
-                                          const T* const* backing_slot,
-                                          WeakCallback callback,
-                                          const void* parameter) {
-    visitor->TraceMovablePointer(backing_slot);
-    visitor->TraceWeakContainer(
-        reinterpret_cast<const HeapHashTableBacking<HashTable>*>(backing),
-        reinterpret_cast<const HeapHashTableBacking<HashTable>* const*>(
-            backing_slot),
-        TraceTrait<HeapHashTableBacking<HashTable>>::GetTraceDescriptor(
-            backing),
-        TraceTrait<HeapHashTableBacking<HashTable>>::GetWeakTraceDescriptor(
-            backing),
-        callback, parameter);
-  }
-
-  template <typename T>
-  static void BackingWriteBarrier(T** slot) {
-    MarkingVisitor::WriteBarrier(reinterpret_cast<void**>(slot));
-  }
-
-  template <typename T>
-  static void TraceBackingStoreIfMarked(T* object) {
-    MarkingVisitor::RetraceObject(object);
-  }
-
-  template <typename T, typename Traits>
-  static void NotifyNewObject(T* object) {
-    MarkingVisitor::WriteBarrier(
-        []() { return ThreadState::Current(); }, object, sizeof(T), 1,
-        TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace);
-  }
-
-  template <typename T, typename Traits>
-  static void NotifyNewObjects(T* array, size_t len) {
-    MarkingVisitor::WriteBarrier(
-        []() { return ThreadState::Current(); }, array, sizeof(T), len,
-        TraceCollectionIfEnabled<WTF::kNoWeakHandling, T, Traits>::Trace);
-  }
-
-  static bool DeferTraceToMutatorThreadIfConcurrent(Visitor* visitor,
-                                                    const void* object,
-                                                    TraceCallback callback,
-                                                    size_t deferred_size) {
-    return visitor->DeferredTraceIfConcurrent({object, callback},
-                                              deferred_size);
-  }
-
- private:
-  static void BackingFree(void*);
-  static bool BackingExpand(void*, size_t);
-  static bool BackingShrink(void*,
-                            size_t quantized_current_size,
-                            size_t quantized_shrunk_size);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_ALLOCATOR_IMPL_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_compact.cc b/third_party/blink/renderer/platform/heap/impl/heap_compact.cc
deleted file mode 100644
index 1a5cf4c..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_compact.cc
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
-
-#include <memory>
-
-#include "base/debug/alias.h"
-#include "base/memory/ptr_util.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-
-namespace blink {
-
-// The real worker behind heap compaction, recording references to movable
-// objects ("slots".) When the objects end up being compacted and moved,
-// relocate() will adjust the slots to point to the new location of the
-// object along with handling fixups for interior pointers.
-//
-// The "fixups" object is created and maintained for the lifetime of one
-// heap compaction-enhanced GC.
-class HeapCompact::MovableObjectFixups final {
-  USING_FAST_MALLOC(HeapCompact::MovableObjectFixups);
-
- public:
-  explicit MovableObjectFixups(ThreadHeap* heap) : heap_(heap) {}
-  ~MovableObjectFixups() = default;
-
-  // For the arenas being compacted, record all pages belonging to them.
-  // This is needed to handle interior pointers that reside on areas that are
-  // compacted themselves.
-  void AddCompactingPage(BasePage* page);
-
-  // Adds a slot for compaction. Filters slots in dead objects.
-  void AddOrFilter(const MovableReference*);
-
-  // Relocates a backing store |from| -> |to|.
-  void Relocate(Address from, Address to);
-
-  // Relocates interior slots in a backing store that is moved |from| -> |to|.
-  void RelocateInteriorFixups(Address from, Address to, size_t size);
-
-  // Updates the collection of callbacks from the item pushed the worklist by
-  // marking visitors.
-  void UpdateCallbacks();
-
-#if DEBUG_HEAP_COMPACTION
-  void dumpDebugStats() {
-    LOG_HEAP_COMPACTION() << "Fixups: pages=" << relocatable_pages_.size()
-                          << " objects=" << fixups_.size()
-                          << " interior-size=" << interior_fixups_.size();
-  }
-#endif
-
- private:
-  void VerifyUpdatedSlot(MovableReference* slot);
-
-  ThreadHeap* const heap_;
-
-  // Map from movable reference (value) to its slots. Upon moving an object its
-  // slot pointing to it requires updating.
-  HashMap<MovableReference, MovableReference*> fixups_;
-
-  // Map of interior slots to their final location. Needs to be an ordered map
-  // as it is used to walk through slots starting at a given memory address.
-  // Requires log(n) lookup to make the early bailout reasonably fast. Currently
-  // only std::map fullfills those requirements.
-  //
-  // - The initial value for a given key is nullptr.
-  // - Upon moving a an object this value is adjusted accordingly.
-  std::map<MovableReference*, Address> interior_fixups_;
-
-  // All pages that are being compacted. The set keeps references to
-  // BasePage instances. The void* type was selected to allow to check
-  // arbitrary addresses.
-  HashSet<void*> relocatable_pages_;
-
-#if DCHECK_IS_ON()
-  // The following two collections are used to allow refer back from a slot to
-  // an already moved object.
-  HashSet<const void*> moved_objects_;
-  HashMap<MovableReference*, MovableReference> interior_slot_to_object_;
-#endif  // DCHECK_IS_ON()
-};
-
-void HeapCompact::MovableObjectFixups::AddCompactingPage(BasePage* page) {
-  DCHECK(!page->IsLargeObjectPage());
-  relocatable_pages_.insert(page);
-}
-
-void HeapCompact::MovableObjectFixups::AddOrFilter(
-    const MovableReference* const_slot) {
-  const void* value = *const_slot;
-  CHECK(value);
-
-  // All slots and values are part of Oilpan's heap.
-  // - Slots may be contained within dead objects if e.g. the write barrier
-  //   registered the slot while the out backing itself has not been marked
-  //   live in time. Slots in dead objects are filtered below.
-  // - Values may only be contained in or point to live objects.
-
-  // Slots handling.
-  BasePage* const slot_page =
-      heap_->LookupPageForAddress(reinterpret_cast<ConstAddress>(const_slot));
-  CHECK(slot_page);
-  HeapObjectHeader* const header =
-      slot_page->IsLargeObjectPage()
-          ? static_cast<LargeObjectPage*>(slot_page)->ObjectHeader()
-          : static_cast<NormalPage*>(slot_page)->FindHeaderFromAddress(
-                reinterpret_cast<ConstAddress>(const_slot));
-  CHECK(header);
-  // Filter the slot since the object that contains the slot is dead.
-  if (!header->IsMarked())
-    return;
-
-  // Value handling.
-  BasePage* const value_page =
-      heap_->LookupPageForAddress(reinterpret_cast<ConstAddress>(value));
-  CHECK(value_page);
-
-  // The following cases are not compacted and do not require recording:
-  // - Backings in large pages.
-  // - Inline backings that are part of a non-backing arena.
-  if (value_page->IsLargeObjectPage() ||
-      !HeapCompact::IsCompactableArena(value_page->Arena()->ArenaIndex()))
-    return;
-
-  // Slots must reside in and values must point to live objects at this
-  // point, with the exception of slots in eagerly swept arenas where objects
-  // have already been processed. |value| usually points to a separate
-  // backing store but can also point to inlined storage which is why the
-  // dynamic header lookup is required.
-  HeapObjectHeader* const value_header =
-      static_cast<NormalPage*>(value_page)
-          ->FindHeaderFromAddress(reinterpret_cast<ConstAddress>(value));
-  CHECK(value_header);
-  CHECK(value_header->IsMarked());
-
-  // Slots may have been recorded already but must point to the same
-  // value. Example: Ephemeron iterations may register slots multiple
-  // times.
-  auto fixup_it = fixups_.find(value);
-  if (UNLIKELY(fixup_it != fixups_.end())) {
-    CHECK_EQ(const_slot, fixup_it->value);
-    return;
-  }
-
-  // Add regular fixup.
-  MovableReference* slot = const_cast<MovableReference*>(const_slot);
-  fixups_.insert(value, slot);
-
-  // Check whether the slot itself resides on a page that is compacted.
-  if (LIKELY(!relocatable_pages_.Contains(slot_page)))
-    return;
-
-  auto interior_it = interior_fixups_.find(slot);
-  CHECK(interior_fixups_.end() == interior_it);
-  interior_fixups_.emplace(slot, nullptr);
-#if DCHECK_IS_ON()
-  interior_slot_to_object_.insert(slot, header->Payload());
-#endif  // DCHECK_IS_ON()
-  LOG_HEAP_COMPACTION() << "Interior slot: " << slot;
-}
-
-void HeapCompact::MovableObjectFixups::Relocate(Address from, Address to) {
-#if DCHECK_IS_ON()
-  moved_objects_.insert(from);
-#endif  // DCHECK_IS_ON()
-
-  const HeapObjectHeader* header = HeapObjectHeader::FromPayload(to);
-  const size_t size = header->PayloadSize();
-
-  // Interior slots always need to be processed for moved objects.
-  // Consider an object A with slot A.x pointing to value B where A is
-  // allocated on a movable page itself. When B is finally moved, it needs to
-  // find the corresponding slot A.x. Object A may be moved already and the
-  // memory may have been freed, which would result in a crash.
-  if (!interior_fixups_.empty()) {
-    RelocateInteriorFixups(from, to, size);
-  }
-
-  auto it = fixups_.find(from);
-  // This means that there is no corresponding slot for a live backing store.
-  // This may happen because a mutator may change the slot to point to a
-  // different backing store because e.g. incremental marking marked a backing
-  // store as live that was later on replaced.
-  if (it == fixups_.end()) {
-    return;
-  }
-
-#if DCHECK_IS_ON()
-  BasePage* from_page = PageFromObject(from);
-  DCHECK(relocatable_pages_.Contains(from_page));
-#endif
-
-  // If the object is referenced by a slot that is contained on a compacted
-  // area itself, check whether it can be updated already.
-  MovableReference* slot = it->value;
-  auto interior_it = interior_fixups_.find(slot);
-  if (interior_it != interior_fixups_.end()) {
-    MovableReference* slot_location =
-        reinterpret_cast<MovableReference*>(interior_it->second);
-    if (!slot_location) {
-      interior_it->second = to;
-#if DCHECK_IS_ON()
-      // Check that the containing object has not been moved yet.
-      auto reverse_it = interior_slot_to_object_.find(slot);
-      DCHECK(interior_slot_to_object_.end() != reverse_it);
-      DCHECK(moved_objects_.end() == moved_objects_.find(reverse_it->value));
-#endif  // DCHECK_IS_ON()
-    } else {
-      LOG_HEAP_COMPACTION()
-          << "Redirected slot: " << slot << " => " << slot_location;
-      slot = slot_location;
-    }
-  }
-
-  // If the slot has subsequently been updated, e.g. a destructor having
-  // mutated and expanded/shrunk the collection, do not update and relocate
-  // the slot -- |from| is no longer valid and referenced.
-  if (UNLIKELY(*slot != from)) {
-    LOG_HEAP_COMPACTION() << "No relocation: slot = " << slot
-                          << ", *slot = " << *slot << ", from = " << from
-                          << ", to = " << to;
-    VerifyUpdatedSlot(slot);
-    return;
-  }
-
-  // Update the slots new value.
-  *slot = to;
-}
-
-void HeapCompact::MovableObjectFixups::RelocateInteriorFixups(Address from,
-                                                              Address to,
-                                                              size_t size) {
-  // |from| is a valid address for a slot.
-  auto interior_it =
-      interior_fixups_.lower_bound(reinterpret_cast<MovableReference*>(from));
-  if (interior_it == interior_fixups_.end())
-    return;
-
-  CHECK_GE(reinterpret_cast<Address>(interior_it->first), from);
-  size_t offset = reinterpret_cast<Address>(interior_it->first) - from;
-  while (offset < size) {
-    if (!interior_it->second) {
-      // Update the interior fixup value, so that when the object the slot is
-      // pointing to is moved, it can re-use this value.
-      Address fixup = to + offset;
-      interior_it->second = fixup;
-
-      // If the |slot|'s content is pointing into the region [from, from +
-      // size) we are dealing with an interior pointer that does not point to
-      // a valid HeapObjectHeader. Such references need to be fixed up
-      // immediately.
-      Address fixup_contents = *reinterpret_cast<Address*>(fixup);
-      if (fixup_contents > from && fixup_contents < (from + size)) {
-        *reinterpret_cast<Address*>(fixup) = fixup_contents - from + to;
-      }
-    }
-
-    interior_it++;
-    if (interior_it == interior_fixups_.end())
-      return;
-    offset = reinterpret_cast<Address>(interior_it->first) - from;
-  }
-}
-
-void HeapCompact::MovableObjectFixups::VerifyUpdatedSlot(
-    MovableReference* slot) {
-// Verify that the already updated slot is valid, meaning:
-//  - has been cleared.
-//  - has been updated & expanded with a large object backing store.
-//  - has been updated with a larger, freshly allocated backing store.
-//    (on a fresh page in a compactable arena that is not being
-//    compacted.)
-#if DCHECK_IS_ON()
-  if (!*slot)
-    return;
-  BasePage* slot_page =
-      heap_->LookupPageForAddress(reinterpret_cast<ConstAddress>(*slot));
-  // ref_page is null if *slot is pointing to an off-heap region. This may
-  // happy if *slot is pointing to an inline buffer of HeapVector with
-  // inline capacity.
-  if (!slot_page)
-    return;
-  DCHECK(slot_page->IsLargeObjectPage() ||
-         (HeapCompact::IsCompactableArena(slot_page->Arena()->ArenaIndex()) &&
-          !relocatable_pages_.Contains(slot_page)));
-#endif  // DCHECK_IS_ON()
-}
-
-HeapCompact::HeapCompact(ThreadHeap* heap) : heap_(heap) {
-  // The heap compaction implementation assumes the contiguous range,
-  //
-  //   [VectorArenaIndex, HashTableArenaIndex]
-  //
-  // in a few places. Use static asserts here to not have that assumption
-  // be silently invalidated by ArenaIndices changes.
-  static_assert(BlinkGC::kVectorArenaIndex + 1 == BlinkGC::kHashTableArenaIndex,
-                "unexpected ArenaIndices ordering");
-}
-
-HeapCompact::~HeapCompact() = default;
-
-HeapCompact::MovableObjectFixups& HeapCompact::Fixups() {
-  if (!fixups_)
-    fixups_ = std::make_unique<MovableObjectFixups>(heap_);
-  return *fixups_;
-}
-
-bool HeapCompact::ShouldCompact(BlinkGC::StackState stack_state,
-                                BlinkGC::MarkingType marking_type,
-                                BlinkGC::GCReason reason) {
-  if (marking_type == BlinkGC::MarkingType::kAtomicMarking &&
-      stack_state == BlinkGC::StackState::kHeapPointersOnStack) {
-    // The following check ensures that tests that want to test compaction are
-    // not interrupted by garbage collections that cannot use compaction.
-    CHECK(!force_for_next_gc_);
-    return false;
-  }
-
-  UpdateHeapResidency();
-
-  if (force_for_next_gc_) {
-    return true;
-  }
-
-  if (!base::FeatureList::IsEnabled(blink::features::kBlinkHeapCompaction)) {
-    return false;
-  }
-
-  // Only enable compaction when in a memory reduction garbage collection as it
-  // may significantly increase the final garbage collection pause.
-  if (reason == BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC ||
-      reason == BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC) {
-    return free_list_size_ > kFreeListSizeThreshold;
-  }
-
-  return false;
-}
-
-void HeapCompact::Initialize(ThreadState* state) {
-  CHECK(force_for_next_gc_ ||
-        base::FeatureList::IsEnabled(blink::features::kBlinkHeapCompaction));
-  CHECK(!do_compact_);
-  CHECK(!fixups_);
-  LOG_HEAP_COMPACTION() << "Compacting: free=" << free_list_size_;
-  do_compact_ = true;
-  gc_count_since_last_compaction_ = 0;
-  force_for_next_gc_ = false;
-}
-
-bool HeapCompact::ShouldRegisterMovingAddress() {
-  return do_compact_;
-}
-
-void HeapCompact::UpdateHeapResidency() {
-  size_t total_free_list_size = 0;
-
-  compactable_arenas_ = 0;
-#if DEBUG_HEAP_FREELIST
-  std::stringstream stream;
-  size_t total_arena_size = 0;
-#endif
-  for (int i = BlinkGC::kVectorArenaIndex; i <= BlinkGC::kHashTableArenaIndex;
-       ++i) {
-    NormalPageArena* arena = static_cast<NormalPageArena*>(heap_->Arena(i));
-    size_t arena_size = arena->ArenaSize();
-    size_t free_list_size = arena->FreeListSize();
-    total_free_list_size += free_list_size;
-#if DEBUG_HEAP_FREELIST
-    total_arena_size += arena_size;
-    stream << i << ": [" << arena_size << ", " << free_list_size << "], ";
-#endif
-    // TODO: be more discriminating and consider arena
-    // load factor, effectiveness of past compactions etc.
-    if (!arena_size)
-      continue;
-    // Mark the arena as compactable.
-    compactable_arenas_ |= 0x1u << i;
-  }
-#if DEBUG_HEAP_FREELIST
-  LOG_HEAP_FREELIST() << "Arena residencies: {" << stream.str() << "}";
-  LOG_HEAP_FREELIST() << "Total = " << total_arena_size
-                      << ", Free = " << total_free_list_size;
-#endif
-
-  // TODO(sof): consider smoothing the reported sizes.
-  free_list_size_ = total_free_list_size;
-}
-
-void HeapCompact::FinishedArenaCompaction(NormalPageArena* arena,
-                                          size_t freed_pages,
-                                          size_t freed_size) {
-  if (!do_compact_)
-    return;
-
-  heap_->stats_collector()->IncreaseCompactionFreedPages(freed_pages);
-  heap_->stats_collector()->IncreaseCompactionFreedSize(freed_size);
-}
-
-void HeapCompact::Relocate(Address from, Address to) {
-  Fixups().Relocate(from, to);
-}
-
-void HeapCompact::FilterNonLiveSlots() {
-  if (!do_compact_)
-    return;
-
-  last_fixup_count_for_testing_ = 0;
-  MovableReferenceWorklist::View traced_slots(
-      heap_->GetMovableReferenceWorklist(), WorklistTaskId::MutatorThread);
-  const MovableReference* slot;
-  while (traced_slots.Pop(&slot)) {
-    CHECK(heap_->LookupPageForAddress(reinterpret_cast<ConstAddress>(slot)));
-    if (*slot) {
-      Fixups().AddOrFilter(slot);
-      last_fixup_count_for_testing_++;
-    }
-  }
-}
-
-void HeapCompact::Finish() {
-  if (!do_compact_)
-    return;
-
-#if DEBUG_HEAP_COMPACTION
-  if (fixups_)
-    fixups_->dumpDebugStats();
-#endif
-  do_compact_ = false;
-  fixups_.reset();
-}
-
-void HeapCompact::Cancel() {
-  if (!do_compact_)
-    return;
-
-  last_fixup_count_for_testing_ = 0;
-  do_compact_ = false;
-  heap_->GetMovableReferenceWorklist()->Clear();
-  fixups_.reset();
-}
-
-void HeapCompact::AddCompactingPage(BasePage* page) {
-  DCHECK(do_compact_);
-  DCHECK(IsCompactingArena(page->Arena()->ArenaIndex()));
-  Fixups().AddCompactingPage(page);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_compact.h b/third_party/blink/renderer/platform/heap/impl/heap_compact.h
deleted file mode 100644
index e39c9c5..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_compact.h
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_COMPACT_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_COMPACT_H_
-
-#include <memory>
-
-#include "base/memory/ptr_util.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-
-#include <bitset>
-#include <utility>
-
-// Compaction-specific debug switches:
-
-// Emit debug info during compaction.
-#define DEBUG_HEAP_COMPACTION 0
-
-// Emit stats on freelist occupancy.
-// 0 - disabled, 1 - minimal, 2 - verbose.
-#define DEBUG_HEAP_FREELIST 0
-
-namespace blink {
-
-class NormalPageArena;
-class BasePage;
-class ThreadState;
-class ThreadHeap;
-
-class PLATFORM_EXPORT HeapCompact final {
- public:
-  // Returns |true| if the ongoing GC may compact the given arena/sub-heap.
-  static bool IsCompactableArena(int arena_index) {
-    return arena_index >= BlinkGC::kVectorArenaIndex &&
-           arena_index <= BlinkGC::kHashTableArenaIndex;
-  }
-
-  explicit HeapCompact(ThreadHeap*);
-  ~HeapCompact();
-
-  // Returns true if compaction can and should be used for the provided
-  // parameters.
-  bool ShouldCompact(BlinkGC::StackState,
-                     BlinkGC::MarkingType,
-                     BlinkGC::GCReason);
-
-  // Compaction should be performed as part of the ongoing GC, initialize
-  // the heap compaction pass.
-  void Initialize(ThreadState*);
-
-  // Returns true if the ongoing GC will perform compaction.
-  bool IsCompacting() const { return do_compact_; }
-
-  // Returns true if the ongoing GC will perform compaction for the given
-  // heap arena.
-  bool IsCompactingArena(int arena_index) const {
-    return do_compact_ && (compactable_arenas_ & (0x1u << arena_index));
-  }
-
-  // See |Heap::ShouldRegisterMovingAddress()| documentation.
-  bool ShouldRegisterMovingAddress();
-
-  // Slots that are not contained within live objects are filtered. This can
-  // happen when the write barrier for in-payload objects triggers but the outer
-  // backing store does not survive the marking phase because all its referents
-  // die before being reached by the marker.
-  void FilterNonLiveSlots();
-
-  // Finishes compaction and clears internal state.
-  void Finish();
-
-  // Cancels compaction after slots may have been recorded already.
-  void Cancel();
-
-  // Perform any relocation post-processing after having completed compacting
-  // the given arena. The number of pages that were freed together with the
-  // total size (in bytes) of freed heap storage, are passed in as arguments.
-  void FinishedArenaCompaction(NormalPageArena*,
-                               size_t freed_pages,
-                               size_t freed_size);
-
-  // Register the heap page as containing live objects that will all be
-  // compacted. Registration happens as part of making the arenas ready
-  // for a GC.
-  void AddCompactingPage(BasePage*);
-
-  // Notify heap compaction that object at |from| has been relocated to.. |to|.
-  // (Called by the sweep compaction pass.)
-  void Relocate(Address from, Address to);
-
-  // Enables compaction for the next garbage collection if technically possible.
-  void EnableCompactionForNextGCForTesting() { force_for_next_gc_ = true; }
-
-  // Returns true if one or more vector arenas are being compacted.
-  bool IsCompactingVectorArenasForTesting() const {
-    return IsCompactingArena(BlinkGC::kVectorArenaIndex);
-  }
-
-  size_t LastFixupCountForTesting() const {
-    return last_fixup_count_for_testing_;
-  }
-
- private:
-  class MovableObjectFixups;
-
-  // Freelist size threshold that must be exceeded before compaction
-  // should be considered.
-  static const size_t kFreeListSizeThreshold = 512 * 1024;
-
-  // Sample the amount of fragmentation and heap memory currently residing
-  // on the freelists of the arenas we're able to compact. The computed
-  // numbers will be subsequently used to determine if a heap compaction
-  // is on order (shouldCompact().)
-  void UpdateHeapResidency();
-
-  MovableObjectFixups& Fixups();
-
-  ThreadHeap* const heap_;
-  std::unique_ptr<MovableObjectFixups> fixups_;
-
-  // Set to |true| when a compacting sweep will go ahead.
-  bool do_compact_ = false;
-  size_t gc_count_since_last_compaction_ = 0;
-
-  // Last reported freelist size, across all compactable arenas.
-  size_t free_list_size_ = 0;
-
-  // If compacting, i'th heap arena will be compacted if corresponding bit is
-  // set. Indexes are in the range of BlinkGC::ArenaIndices.
-  unsigned compactable_arenas_ = 0u;
-
-  size_t last_fixup_count_for_testing_ = 0;
-
-  bool force_for_next_gc_ = false;
-};
-
-}  // namespace blink
-
-// Logging macros activated by debug switches.
-
-#define LOG_HEAP_COMPACTION_INTERNAL() DLOG(INFO)
-
-#if DEBUG_HEAP_COMPACTION
-#define LOG_HEAP_COMPACTION() LOG_HEAP_COMPACTION_INTERNAL()
-#else
-#define LOG_HEAP_COMPACTION() EAT_STREAM_PARAMETERS
-#endif
-
-#if DEBUG_HEAP_FREELIST
-#define LOG_HEAP_FREELIST() LOG_HEAP_COMPACTION_INTERNAL()
-#else
-#define LOG_HEAP_FREELIST() EAT_STREAM_PARAMETERS
-#endif
-
-#if DEBUG_HEAP_FREELIST == 2
-#define LOG_HEAP_FREELIST_VERBOSE() LOG_HEAP_COMPACTION_INTERNAL()
-#else
-#define LOG_HEAP_FREELIST_VERBOSE() EAT_STREAM_PARAMETERS
-#endif
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_COMPACT_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_page.cc b/third_party/blink/renderer/platform/heap/impl/heap_page.cc
deleted file mode 100644
index 96f3b88..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_page.cc
+++ /dev/null
@@ -1,1931 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-
-#include "base/allocator/partition_allocator/page_allocator.h"
-#include "base/auto_reset.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
-#include "third_party/blink/renderer/platform/heap/impl/marking_verifier.h"
-#include "third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h"
-#include "third_party/blink/renderer/platform/heap/impl/page_memory.h"
-#include "third_party/blink/renderer/platform/heap/impl/page_pool.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
-#include "third_party/blink/renderer/platform/instrumentation/memory_pressure_listener.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
-#include "third_party/blink/renderer/platform/wtf/container_annotations.h"
-#include "third_party/blink/renderer/platform/wtf/leak_annotations.h"
-
-#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
-
-// When finalizing a non-inlined vector backing store/container, remove
-// its contiguous container annotation. Required as it will not be destructed
-// from its Vector.
-#define ASAN_RETIRE_CONTAINER_ANNOTATION(object, objectSize)          \
-  do {                                                                \
-    BasePage* page = PageFromObject(object);                          \
-    DCHECK(page);                                                     \
-    bool is_container =                                               \
-        ThreadHeap::IsVectorArenaIndex(page->Arena()->ArenaIndex());  \
-    if (!is_container && page->IsLargeObjectPage())                   \
-      is_container =                                                  \
-          static_cast<LargeObjectPage*>(page)->IsVectorBackingPage(); \
-    if (is_container)                                                 \
-      ANNOTATE_DELETE_BUFFER(object, objectSize, 0);                  \
-  } while (0)
-
-// A vector backing store represented by a large object is marked
-// so that when it is finalized, its ASan annotation will be
-// correctly retired.
-#define ASAN_MARK_LARGE_VECTOR_CONTAINER(arena, large_object)            \
-  if (ThreadHeap::IsVectorArenaIndex(arena->ArenaIndex())) {             \
-    BasePage* large_page = PageFromObject(large_object);                 \
-    DCHECK(large_page->IsLargeObjectPage());                             \
-    static_cast<LargeObjectPage*>(large_page)->SetIsVectorBackingPage(); \
-  }
-#else
-#define ASAN_RETIRE_CONTAINER_ANNOTATION(payload, payloadSize)
-#define ASAN_MARK_LARGE_VECTOR_CONTAINER(arena, largeObject)
-#endif
-
-namespace blink {
-
-void HeapObjectHeader::Finalize(Address object, size_t object_size) {
-  DCHECK(!IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>());
-  const GCInfo& gc_info = GCInfo::From(GcInfoIndex());
-  if (gc_info.finalize)
-    gc_info.finalize(object);
-
-  ASAN_RETIRE_CONTAINER_ANNOTATION(object, object_size);
-}
-
-bool HeapObjectHeader::HasNonTrivialFinalizer() const {
-  return GCInfo::From(GcInfoIndex()).finalize;
-}
-
-const char* HeapObjectHeader::Name() const {
-  return GCInfo::From(GcInfoIndex()).name(Payload()).value;
-}
-
-BaseArena::BaseArena(ThreadState* state, int index)
-    : thread_state_(state), index_(index) {}
-
-BaseArena::~BaseArena() {
-  DCHECK(swept_pages_.IsEmpty());
-  DCHECK(unswept_pages_.IsEmpty());
-  DCHECK(swept_unfinalized_pages_.IsEmpty());
-  DCHECK(swept_unfinalized_empty_pages_.IsEmpty());
-}
-
-void BaseArena::RemoveAllPages() {
-  ClearFreeLists();
-
-  DCHECK(SweepingAndFinalizationCompleted());
-  while (BasePage* page = swept_pages_.Pop()) {
-    page->RemoveFromHeap();
-  }
-}
-
-void BaseArena::CollectStatistics(std::string name,
-                                  ThreadState::Statistics* stats) {
-  ThreadState::Statistics::ArenaStatistics arena_stats;
-
-  ResetAllocationPoint();
-
-  if (!NameClient::HideInternalName()) {
-    const size_t num_types = GCInfoTable::Get().NumberOfGCInfos();
-    arena_stats.object_stats.num_types = num_types;
-    arena_stats.object_stats.type_name.resize(num_types);
-    arena_stats.object_stats.type_count.resize(num_types);
-    arena_stats.object_stats.type_bytes.resize(num_types);
-  }
-
-  arena_stats.name = std::move(name);
-  DCHECK(unswept_pages_.IsEmpty());
-  for (BasePage* page : swept_pages_) {
-    page->CollectStatistics(&arena_stats);
-  }
-  CollectFreeListStatistics(&arena_stats.free_list_stats);
-  stats->used_size_bytes += arena_stats.used_size_bytes;
-  stats->committed_size_bytes += arena_stats.committed_size_bytes;
-  stats->arena_stats.emplace_back(std::move(arena_stats));
-}
-
-size_t BaseArena::AllocatedBytes() {
-  DCHECK(unswept_pages_.IsEmpty());
-  size_t result = 0;
-  for (BasePage* page : swept_pages_) {
-    result += page->AllocatedBytes();
-  }
-  return result;
-}
-
-void NormalPageArena::CollectFreeListStatistics(
-    ThreadState::Statistics::FreeListStatistics* stats) {
-  free_list_.CollectStatistics(stats);
-}
-
-#if DCHECK_IS_ON()
-BasePage* BaseArena::FindPageFromAddress(ConstAddress address) const {
-  for (BasePage* page : swept_pages_) {
-    if (page->Contains(address))
-      return page;
-  }
-  for (BasePage* page : unswept_pages_) {
-    if (page->Contains(address))
-      return page;
-  }
-  for (BasePage* page : swept_unfinalized_pages_) {
-    if (page->Contains(address))
-      return page;
-  }
-  for (BasePage* page : swept_unfinalized_empty_pages_) {
-    if (page->Contains(address))
-      return page;
-  }
-  return nullptr;
-}
-#endif
-
-void BaseArena::MakeConsistentForGC() {
-#if DCHECK_IS_ON()
-  DCHECK(IsConsistentForGC());
-#endif
-
-  // We should not start a new GC until we finish sweeping in the current GC.
-  CHECK(SweepingAndFinalizationCompleted());
-
-  HeapCompact* heap_compactor = GetThreadState()->Heap().Compaction();
-  if (!heap_compactor->IsCompactingArena(ArenaIndex()))
-    return;
-
-  for (BasePage* page : swept_pages_) {
-    if (!page->IsLargeObjectPage())
-      heap_compactor->AddCompactingPage(page);
-  }
-}
-
-void BaseArena::MakeConsistentForMutator() {
-  ClearFreeLists();
-#if DCHECK_IS_ON()
-  DCHECK(IsConsistentForGC());
-#endif
-  DCHECK(swept_pages_.IsEmpty());
-
-  // Drop marks from marked objects and rebuild free lists in preparation for
-  // resuming the executions of mutators.
-  for (BasePage* page : unswept_pages_) {
-    page->MakeConsistentForMutator();
-    page->MarkAsSwept();
-  }
-
-  swept_pages_.MoveFrom(std::move(unswept_pages_));
-  DCHECK(SweepingAndFinalizationCompleted());
-
-  VerifyObjectStartBitmap();
-}
-
-void BaseArena::Unmark() {
-  DCHECK(GetThreadState()->InAtomicMarkingPause());
-  DCHECK(SweepingAndFinalizationCompleted());
-
-  for (BasePage* page : swept_pages_) {
-    page->Unmark();
-  }
-}
-
-size_t BaseArena::ObjectPayloadSizeForTesting() {
-#if DCHECK_IS_ON()
-  DCHECK(IsConsistentForGC());
-#endif
-  // DCHECK(SweepingCompleted());
-
-  size_t object_payload_size = 0;
-  for (BasePage* page : unswept_pages_) {
-    object_payload_size += page->ObjectPayloadSizeForTesting();
-  }
-  return object_payload_size;
-}
-
-void BaseArena::PrepareForSweep(BlinkGC::CollectionType collection_type) {
-  DCHECK(GetThreadState()->InAtomicMarkingPause());
-  DCHECK(SweepingAndFinalizationCompleted());
-
-  ClearFreeLists();
-
-  // Verification depends on the allocation point being cleared.
-  VerifyObjectStartBitmap();
-
-  if (collection_type == BlinkGC::CollectionType::kMinor) {
-    auto** first_young =
-        std::partition(swept_pages_.begin(), swept_pages_.end(),
-                       [](BasePage* page) { return !page->IsYoung(); });
-    for (auto** it = first_young; it != swept_pages_.end(); ++it) {
-      BasePage* page = *it;
-      page->MarkAsUnswept();
-      page->SetAsYoung(false);
-      unswept_pages_.Push(page);
-    }
-    swept_pages_.erase(first_young, swept_pages_.end());
-    return;
-  }
-
-  for (BasePage* page : swept_pages_) {
-    page->MarkAsUnswept();
-  }
-  // Move all pages to a list of unswept pages.
-  unswept_pages_.MoveFrom(std::move(swept_pages_));
-  DCHECK(swept_pages_.IsEmpty());
-}
-
-#if defined(ADDRESS_SANITIZER)
-void BaseArena::PoisonUnmarkedObjects() {
-  for (BasePage* page : unswept_pages_) {
-    page->PoisonUnmarkedObjects();
-  }
-}
-#endif
-
-Address BaseArena::LazySweep(size_t allocation_size, size_t gc_info_index) {
-  // If there are no pages to be swept, return immediately.
-  if (SweepingAndFinalizationCompleted())
-    return nullptr;
-
-  CHECK(GetThreadState()->IsSweepingInProgress());
-
-  // lazySweepPages() can be called recursively if finalizers invoked in
-  // page->Sweep() allocate memory and the allocation triggers
-  // lazySweepPages(). This check prevents the sweeping from being executed
-  // recursively.
-  if (GetThreadState()->SweepForbidden())
-    return nullptr;
-
-  ThreadHeapStatsCollector::EnabledScope stats_scope(
-      GetThreadState()->Heap().stats_collector(),
-      ThreadHeapStatsCollector::kLazySweepOnAllocation);
-  ThreadState::SweepForbiddenScope sweep_forbidden(GetThreadState());
-  ScriptForbiddenScope script_forbidden;
-  return LazySweepPages(allocation_size, gc_info_index);
-}
-
-bool BaseArena::SweepUnsweptPageOnConcurrentThread(BasePage* page) {
-  const bool is_empty = page->Sweep(FinalizeType::kDeferred);
-  if (is_empty) {
-    swept_unfinalized_empty_pages_.PushLocked(page);
-  } else {
-    swept_unfinalized_pages_.PushLocked(page);
-  }
-  return is_empty;
-}
-
-bool BaseArena::SweepUnsweptPage(BasePage* page) {
-  const bool is_empty = page->Sweep(FinalizeType::kInlined);
-  if (is_empty) {
-    page->FinalizeSweep(SweepResult::kPageEmpty);
-  } else {
-    // First, we add page to the list of swept pages
-    // so that the FindPageFromAddress check is happy.
-    swept_pages_.PushLocked(page);
-    page->FinalizeSweep(SweepResult::kPageNotEmpty);
-  }
-  return is_empty;
-}
-
-bool BaseArena::LazySweepWithDeadline(base::TimeTicks deadline) {
-  // It might be heavy to call
-  // Platform::current()->monotonicallyIncreasingTimeSeconds() per page (i.e.,
-  // 128 KB sweep or one LargeObject sweep), so we check the deadline per 10
-  // pages.
-  static constexpr size_t kDeadlineCheckInterval = 10;
-
-  CHECK(GetThreadState()->IsSweepingInProgress());
-  DCHECK(GetThreadState()->SweepForbidden());
-  DCHECK(ScriptForbiddenScope::IsScriptForbidden());
-
-  size_t page_count = 1;
-  // First, process empty pages to faster reduce memory footprint.
-  while (BasePage* page = swept_unfinalized_empty_pages_.PopLocked()) {
-    page->FinalizeSweep(SweepResult::kPageEmpty);
-    if (page_count % kDeadlineCheckInterval == 0) {
-      if (deadline <= base::TimeTicks::Now()) {
-        // Deadline has come.
-        return SweepingAndFinalizationCompleted();
-      }
-    }
-    page_count++;
-  }
-  // Second, execute finalizers to leave more work for concurrent sweeper.
-  while (BasePage* page = swept_unfinalized_pages_.PopLocked()) {
-    swept_pages_.PushLocked(page);
-    page->FinalizeSweep(SweepResult::kPageNotEmpty);
-    if (page_count % kDeadlineCheckInterval == 0) {
-      if (deadline <= base::TimeTicks::Now()) {
-        // Deadline has come.
-        return SweepingAndFinalizationCompleted();
-      }
-    }
-    page_count++;
-  }
-  // Help concurrent sweeper.
-  while (BasePage* page = unswept_pages_.PopLocked()) {
-    SweepUnsweptPage(page);
-    if (page_count % kDeadlineCheckInterval == 0) {
-      if (deadline <= base::TimeTicks::Now()) {
-        // Deadline has come.
-        return SweepingAndFinalizationCompleted();
-      }
-    }
-    page_count++;
-  }
-
-  return true;
-}
-
-void BaseArena::InvokeFinalizersOnSweptPages() {
-  DCHECK(GetThreadState()->CheckThread());
-  DCHECK(GetThreadState()->IsSweepingInProgress());
-  DCHECK(GetThreadState()->SweepForbidden());
-  while (BasePage* page = swept_unfinalized_pages_.PopLocked()) {
-    swept_pages_.PushLocked(page);
-    page->FinalizeSweep(SweepResult::kPageNotEmpty);
-  }
-  while (BasePage* page = swept_unfinalized_empty_pages_.PopLocked()) {
-    page->FinalizeSweep(SweepResult::kPageEmpty);
-  }
-}
-
-bool BaseArena::ConcurrentSweepOnePage() {
-  BasePage* page = unswept_pages_.PopLocked();
-  if (!page)
-    return true;
-  SweepUnsweptPageOnConcurrentThread(page);
-  return false;
-}
-
-void BaseArena::CompleteSweep() {
-  CHECK(GetThreadState()->IsSweepingInProgress());
-  DCHECK(GetThreadState()->SweepForbidden());
-  DCHECK(ScriptForbiddenScope::IsScriptForbidden());
-
-  // Some phases, e.g. verification, require iterability of a page.
-  MakeIterable();
-
-  // First, finalize pages that have been processed by concurrent sweepers.
-  InvokeFinalizersOnSweptPages();
-
-  // Then, sweep and finalize pages.
-  while (BasePage* page = unswept_pages_.PopLocked()) {
-    SweepUnsweptPage(page);
-  }
-
-  // Verify object start bitmap after all freelists have been merged.
-  VerifyObjectStartBitmap();
-}
-
-Address BaseArena::AllocateLargeObject(size_t allocation_size,
-                                       size_t gc_info_index) {
-  LargeObjectArena* large_object_arena = static_cast<LargeObjectArena*>(
-      GetThreadState()->Heap().Arena(BlinkGC::kLargeObjectArenaIndex));
-  Address large_object = large_object_arena->AllocateLargeObjectPage(
-      allocation_size, gc_info_index);
-  ASAN_MARK_LARGE_VECTOR_CONTAINER(this, large_object);
-  return large_object;
-}
-
-NormalPageArena::NormalPageArena(ThreadState* state, int index)
-    : BaseArena(state, index),
-      current_allocation_point_(nullptr),
-      remaining_allocation_size_(0),
-      promptly_freed_size_(0) {}
-
-void NormalPageArena::AddToFreeList(Address address, size_t size) {
-#if DCHECK_IS_ON()
-  DCHECK(FindPageFromAddress(address));
-  DCHECK(FindPageFromAddress(address + size - 1));
-#endif
-  free_list_.Add(address, size);
-  static_cast<NormalPage*>(PageFromObject(address))
-      ->object_start_bit_map()
-      ->SetBit<HeapObjectHeader::AccessMode::kAtomic>(address);
-}
-
-void NormalPageArena::MakeConsistentForGC() {
-  BaseArena::MakeConsistentForGC();
-
-  // Remove linear allocation area.
-  SetAllocationPoint(nullptr, 0);
-}
-
-void NormalPageArena::ClearFreeLists() {
-  SetAllocationPoint(nullptr, 0);
-  free_list_.Clear();
-  promptly_freed_size_ = 0;
-}
-
-void NormalPageArena::MakeIterable() {
-  SetAllocationPoint(nullptr, 0);
-}
-
-size_t NormalPageArena::ArenaSize() {
-  size_t size = 0;
-  for (BasePage* page : swept_pages_) {
-    size += page->size();
-  }
-  LOG_HEAP_FREELIST_VERBOSE()
-      << "Heap size: " << size << "(" << ArenaIndex() << ")";
-  return size;
-}
-
-size_t NormalPageArena::FreeListSize() {
-  size_t free_size = free_list_.FreeListSize();
-  LOG_HEAP_FREELIST_VERBOSE()
-      << "Free size: " << free_size << "(" << ArenaIndex() << ")";
-  return free_size;
-}
-
-void NormalPageArena::SweepAndCompact() {
-  ThreadHeap& heap = GetThreadState()->Heap();
-  if (!heap.Compaction()->IsCompactingArena(ArenaIndex()))
-    return;
-
-  if (SweepingCompleted()) {
-    heap.Compaction()->FinishedArenaCompaction(this, 0, 0);
-    return;
-  }
-
-  // Compaction is performed in-place, sliding objects down over unused
-  // holes for a smaller heap page footprint and improved locality.
-  // A "compaction pointer" is consequently kept, pointing to the next
-  // available address to move objects down to. It will belong to one
-  // of the already sweep-compacted pages for this arena, but as compaction
-  // proceeds, it will not belong to the same page as the one being
-  // currently compacted.
-  //
-  // The compaction pointer is represented by the
-  // |(currentPage, allocationPoint)| pair, with |allocationPoint|
-  // being the offset into |currentPage|, making up the next
-  // available location. When the compaction of an arena page causes the
-  // compaction pointer to exhaust the current page it is compacting into,
-  // page compaction will advance the current page of the compaction
-  // pointer, as well as the allocation point.
-  //
-  // By construction, the page compaction can be performed without having
-  // to allocate any new pages. So to arrange for the page compaction's
-  // supply of freed, available pages, we chain them together after each
-  // has been "compacted from". The page compaction will then reuse those
-  // as needed, and once finished, the chained, available pages can be
-  // released back to the OS.
-  //
-  // To ease the passing of the compaction state when iterating over an
-  // arena's pages, package it up into a |CompactionContext|.
-  NormalPage::CompactionContext context;
-  context.compacted_pages_ = &swept_pages_;
-
-  while (BasePage* page = unswept_pages_.Pop()) {
-    // Large objects do not belong to this arena.
-    DCHECK(!page->IsLargeObjectPage());
-    NormalPage* normal_page = static_cast<NormalPage*>(page);
-    normal_page->MarkAsSwept();
-    // If not the first page, add |normalPage| onto the available pages chain.
-    if (!context.current_page_) {
-      context.current_page_ = normal_page;
-    } else {
-      context.available_pages_.Push(normal_page);
-    }
-    normal_page->SweepAndCompact(context);
-  }
-
-  // All pages were empty; nothing to compact.
-  if (!context.current_page_) {
-    heap.Compaction()->FinishedArenaCompaction(this, 0, 0);
-    return;
-  }
-
-  size_t freed_size = 0;
-  size_t freed_page_count = 0;
-
-  // If the current page hasn't been allocated into, add it to the available
-  // list, for subsequent release below.
-  size_t allocation_point = context.allocation_point_;
-  if (!allocation_point) {
-    context.available_pages_.Push(context.current_page_);
-  } else {
-    NormalPage* current_page = context.current_page_;
-    swept_pages_.Push(current_page);
-    if (allocation_point != current_page->PayloadSize()) {
-      // Put the remainder of the page onto the free list.
-      freed_size = current_page->PayloadSize() - allocation_point;
-      Address payload = current_page->Payload();
-      SET_MEMORY_INACCESSIBLE(payload + allocation_point, freed_size);
-      current_page->ArenaForNormalPage()->AddToFreeList(
-          payload + allocation_point, freed_size);
-    }
-  }
-
-  // Return available pages to the free page pool, decommitting them from
-  // the pagefile.
-#if DEBUG_HEAP_COMPACTION
-  std::stringstream stream;
-#endif
-  while (BasePage* available_pages = context.available_pages_.Pop()) {
-    size_t page_size = available_pages->size();
-#if DEBUG_HEAP_COMPACTION
-    if (!freed_page_count)
-      stream << "Releasing:";
-    stream << " [" << available_pages << ", "
-           << static_cast<void*>(reinterpret_cast<char*>(available_pages) +
-                                 page_size)
-           << "]";
-#endif
-    freed_size += page_size;
-    freed_page_count++;
-#if !(DCHECK_IS_ON() || defined(LEAK_SANITIZER) || \
-      defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER))
-    // Clear out the page before adding it to the free page pool, which
-    // decommits it. Recommitting the page must find a zeroed page later.
-    // We cannot assume that the OS will hand back a zeroed page across
-    // its "decommit" operation.
-    //
-    // If in a debug setting, the unused page contents will have been
-    // zapped already; leave it in that state.
-    DCHECK(!available_pages->IsLargeObjectPage());
-    NormalPage* unused_page = static_cast<NormalPage*>(available_pages);
-    memset(unused_page->Payload(), 0, unused_page->PayloadSize());
-#endif
-    available_pages->RemoveFromHeap();
-  }
-#if DEBUG_HEAP_COMPACTION
-  if (freed_page_count)
-    LOG_HEAP_COMPACTION() << stream.str();
-#endif
-  heap.Compaction()->FinishedArenaCompaction(this, freed_page_count,
-                                             freed_size);
-
-  VerifyObjectStartBitmap();
-}
-
-void NormalPageArena::VerifyObjectStartBitmap() {
-#if DCHECK_IS_ON()
-  // Verifying object start bitmap requires iterability of pages. As compaction
-  // may set up a new we have to reset here.
-  SetAllocationPoint(nullptr, 0);
-  for (BasePage* page : swept_pages_) {
-    static_cast<NormalPage*>(page)
-        ->VerifyObjectStartBitmapIsConsistentWithPayload();
-  }
-#endif  // DCHECK_IS_ON()
-}
-
-void BaseArena::VerifyMarking() {
-#if DCHECK_IS_ON()
-  // We cannot rely on other marking phases to clear the allocation area as
-  // for incremental marking the application is running between steps and
-  // might set up a new area. For large object arenas this is a no-op.
-  ResetAllocationPoint();
-
-  DCHECK(swept_unfinalized_pages_.IsEmpty());
-  DCHECK(swept_unfinalized_empty_pages_.IsEmpty());
-  // There may be objects on |swept_pages_| as pre-finalizers may allocate.
-  // These objects may point to other object on |swept_pages_| or marked objects
-  // on |unswept_pages_| but may never point to a dead (unmarked) object in
-  // |unswept_pages_|.
-  for (BasePage* page : swept_pages_) {
-    page->VerifyMarking();
-  }
-  for (BasePage* page : unswept_pages_) {
-    page->VerifyMarking();
-  }
-#endif  // DCHECK_IS_ON()
-}
-
-#if DCHECK_IS_ON()
-bool NormalPageArena::IsConsistentForGC() {
-  // A thread heap is consistent for sweeping if none of the pages to be swept
-  // contain a freelist block or the current allocation point.
-  FreeListEntry* entry = free_list_.FindEntry([this](FreeListEntry* entry) {
-    return PagesToBeSweptContains(entry->GetAddress());
-  });
-  if (entry)
-    return false;
-
-  if (HasCurrentAllocationArea()) {
-    if (PagesToBeSweptContains(CurrentAllocationPoint()))
-      return false;
-  }
-  return true;
-}
-
-bool NormalPageArena::PagesToBeSweptContains(ConstAddress address) const {
-  for (BasePage* page : unswept_pages_) {
-    if (page->Contains(address))
-      return true;
-  }
-  return false;
-}
-#endif
-
-void NormalPageArena::AllocatePage() {
-  PageMemory* page_memory =
-      GetThreadState()->Heap().GetFreePagePool()->Take(ArenaIndex());
-
-  if (!page_memory) {
-    // Allocate a memory region for blinkPagesPerRegion pages that
-    // will each have the following layout.
-    //
-    //    [ guard os page | ... payload ... | guard os page ]
-    //    ^---{ aligned to blink page size }
-    PageMemoryRegion* region = PageMemoryRegion::AllocateNormalPages(
-        GetThreadState()->Heap().GetRegionTree());
-
-    // Setup the PageMemory object for each of the pages in the region.
-    for (size_t i = 0; i < kBlinkPagesPerRegion; ++i) {
-      PageMemory* memory = PageMemory::SetupPageMemoryInRegion(
-          region, i * kBlinkPageSize, BlinkPagePayloadSize());
-      // Take the first possible page ensuring that this thread actually
-      // gets a page and add the rest to the page pool.
-      if (!page_memory) {
-        // If you hit the CHECK in the call to Commit(), it means that you're
-        // hitting the limit of the number of mmapped regions the OS can support
-        // (e.g., /proc/sys/vm/max_map_count in Linux) or on that Windows you
-        // have exceeded the max commit charge across all processes for the
-        // system.
-        memory->Commit();
-        page_memory = memory;
-      } else {
-        GetThreadState()->Heap().GetFreePagePool()->Add(ArenaIndex(), memory);
-      }
-    }
-  }
-  NormalPage* page =
-      new (page_memory->WritableStart()) NormalPage(page_memory, this);
-  swept_pages_.PushLocked(page);
-
-  ThreadHeap& heap = GetThreadState()->Heap();
-  heap.stats_collector()->IncreaseAllocatedSpace(page->size());
-  heap.page_bloom_filter()->Add(page->GetAddress());
-#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
-  // Allow the following addToFreeList() to add the newly allocated memory
-  // to the free list.
-  ASAN_UNPOISON_MEMORY_REGION(page->Payload(), page->PayloadSize());
-  Address address = page->Payload();
-  for (size_t i = 0; i < page->PayloadSize(); i++)
-    address[i] = kReuseAllowedZapValue;
-  ASAN_POISON_MEMORY_REGION(page->Payload(), page->PayloadSize());
-#endif
-  AddToFreeList(page->Payload(), page->PayloadSize());
-  SynchronizedStore(page);
-}
-
-void NormalPageArena::FreePage(NormalPage* page) {
-  ThreadHeap& heap = GetThreadState()->Heap();
-  heap.stats_collector()->DecreaseAllocatedSpace(page->size());
-  heap.page_bloom_filter()->Remove(page->GetAddress());
-
-  PageMemory* memory = page->Storage();
-  page->~NormalPage();
-  GetThreadState()->Heap().GetFreePagePool()->Add(ArenaIndex(), memory);
-}
-
-PlatformAwareObjectStartBitmap::PlatformAwareObjectStartBitmap(Address offset)
-    : ObjectStartBitmap(offset) {}
-
-ObjectStartBitmap::ObjectStartBitmap(Address offset) : offset_(offset) {
-  Clear();
-}
-
-void ObjectStartBitmap::Clear() {
-  memset(&object_start_bit_map_, 0, kReservedForBitmap);
-}
-
-void NormalPageArena::PromptlyFreeObject(HeapObjectHeader* header) {
-  DCHECK(!GetThreadState()->IsMarkingInProgress());
-  DCHECK(!GetThreadState()->SweepForbidden());
-  Address address = reinterpret_cast<Address>(header);
-  Address payload = header->Payload();
-  size_t size = header->size();
-  size_t payload_size = header->PayloadSize();
-  DCHECK_GT(size, 0u);
-#if DCHECK_IS_ON()
-  DCHECK_EQ(PageFromObject(address), FindPageFromAddress(address));
-#endif
-  {
-    ThreadState::SweepForbiddenScope forbidden_scope(GetThreadState());
-    header->Finalize(payload, payload_size);
-    if (IsObjectAllocatedAtAllocationPoint(header)) {
-      current_allocation_point_ -= size;
-      DCHECK_EQ(address, current_allocation_point_);
-      remaining_allocation_size_ += size;
-      SET_MEMORY_INACCESSIBLE(address, size);
-      // Memory that is part of the allocation point is not allowed to be part
-      // of the object start bit map.
-      reinterpret_cast<NormalPage*>(PageFromObject(header))
-          ->object_start_bit_map()
-          ->ClearBit(address);
-      return;
-    }
-    DCHECK(!header->IsMarked());
-    PromptlyFreeObjectInFreeList(header, size);
-  }
-}
-
-void NormalPageArena::PromptlyFreeObjectInFreeList(HeapObjectHeader* header,
-                                                   size_t size) {
-  DCHECK(!header->IsMarked());
-  Address address = reinterpret_cast<Address>(header);
-  NormalPage* page = static_cast<NormalPage*>(PageFromObject(header));
-  DCHECK(page->HasBeenSwept());
-  Address payload = header->Payload();
-  size_t payload_size = header->PayloadSize();
-  // If the page has been swept a promptly freed object may be adjacent
-  // to other free list entries. We make the object available for future
-  // allocation right away by adding it to the free list and increase the
-  // promptly_freed_size_ counter which may result in coalescing later.
-  SET_MEMORY_INACCESSIBLE(payload, payload_size);
-  CHECK_MEMORY_INACCESSIBLE(payload, payload_size);
-  AddToFreeList(address, size);
-  promptly_freed_size_ += size;
-  GetThreadState()->Heap().stats_collector()->DecreaseAllocatedObjectSize(size);
-  page->DecreaseAllocatedBytes(size);
-}
-
-bool NormalPageArena::ExpandObject(HeapObjectHeader* header, size_t new_size) {
-  // It's possible that Vector requests a smaller expanded size because
-  // Vector::shrinkCapacity can set a capacity smaller than the actual payload
-  // size.
-  if (header->PayloadSize() >= new_size)
-    return true;
-  size_t allocation_size = ThreadHeap::AllocationSizeFromSize(new_size);
-  DCHECK_GT(allocation_size, header->size());
-  size_t expand_size = allocation_size - header->size();
-  if (IsObjectAllocatedAtAllocationPoint(header) &&
-      expand_size <= remaining_allocation_size_) {
-    current_allocation_point_ += expand_size;
-    DCHECK_GE(remaining_allocation_size_, expand_size);
-    remaining_allocation_size_ -= expand_size;
-    // Unpoison the memory used for the object (payload).
-    SET_MEMORY_ACCESSIBLE(header->PayloadEnd(), expand_size);
-    header->SetSize(allocation_size);
-#if DCHECK_IS_ON()
-    DCHECK(FindPageFromAddress(header->PayloadEnd() - 1));
-#endif
-    return true;
-  }
-  return false;
-}
-
-bool NormalPageArena::ShrinkObject(HeapObjectHeader* header, size_t new_size) {
-  DCHECK_GT(header->PayloadSize(), new_size);
-  size_t allocation_size = ThreadHeap::AllocationSizeFromSize(new_size);
-  DCHECK_GT(header->size(), allocation_size);
-  size_t shrink_size = header->size() - allocation_size;
-  if (IsObjectAllocatedAtAllocationPoint(header)) {
-    current_allocation_point_ -= shrink_size;
-    remaining_allocation_size_ += shrink_size;
-    SET_MEMORY_INACCESSIBLE(current_allocation_point_, shrink_size);
-    header->SetSize(allocation_size);
-    return true;
-  }
-  DCHECK_GE(shrink_size, sizeof(HeapObjectHeader));
-  DCHECK_GT(header->GcInfoIndex(), 0u);
-  Address shrink_address = header->PayloadEnd() - shrink_size;
-  HeapObjectHeader* freed_header = new (NotNullTag::kNotNull, shrink_address)
-      HeapObjectHeader(shrink_size, header->GcInfoIndex());
-  // Since only size has been changed, we don't need to update object starts.
-  PromptlyFreeObjectInFreeList(freed_header, shrink_size);
-#if DCHECK_IS_ON()
-  DCHECK_EQ(PageFromObject(reinterpret_cast<Address>(header)),
-            FindPageFromAddress(reinterpret_cast<Address>(header)));
-#endif
-  header->SetSize(allocation_size);
-
-  return false;
-}
-
-Address NormalPageArena::AllocateFromFreeList(size_t allocation_size,
-                                              size_t gc_info_index) {
-  FreeListEntry* entry = free_list_.Allocate(allocation_size);
-  if (!entry)
-    return nullptr;
-
-  SetAllocationPoint(entry->GetAddress(), entry->size());
-  DCHECK(HasCurrentAllocationArea());
-  DCHECK_GE(RemainingAllocationSize(), allocation_size);
-  return AllocateObject(allocation_size, gc_info_index);
-}
-
-Address NormalPageArena::LazySweepPages(size_t allocation_size,
-                                        size_t gc_info_index) {
-  DCHECK(!HasCurrentAllocationArea());
-  Address result = nullptr;
-  // First, process unfinalized pages as finalizing a page is faster than
-  // sweeping.
-  while (BasePage* page = swept_unfinalized_pages_.PopLocked()) {
-    swept_pages_.PushLocked(page);
-    page->FinalizeSweep(SweepResult::kPageNotEmpty);
-    // For NormalPage, stop lazy sweeping once we find a slot to
-    // allocate a new object.
-    result = AllocateFromFreeList(allocation_size, gc_info_index);
-    if (result)
-      return result;
-  }
-  while (BasePage* page = unswept_pages_.PopLocked()) {
-    const bool is_empty = SweepUnsweptPage(page);
-    if (!is_empty) {
-      // For NormalPage, stop lazy sweeping once we find a slot to
-      // allocate a new object.
-      result = AllocateFromFreeList(allocation_size, gc_info_index);
-      if (result)
-        return result;
-    }
-  }
-  return result;
-}
-
-void NormalPageArena::SetAllocationPoint(Address point, size_t size) {
-#if DCHECK_IS_ON()
-  if (point) {
-    DCHECK(size);
-    BasePage* page = PageFromObject(point);
-    DCHECK(!page->IsLargeObjectPage());
-    DCHECK_LE(size, static_cast<NormalPage*>(page)->PayloadSize());
-  }
-#endif
-  // Free and clear the old linear allocation area.
-  if (HasCurrentAllocationArea()) {
-    size_t remaining_size = RemainingAllocationSize();
-    AddToFreeList(CurrentAllocationPoint(), remaining_size);
-    GetThreadState()->Heap().stats_collector()->DecreaseAllocatedObjectSize(
-        remaining_size);
-    static_cast<NormalPage*>(PageFromObject(CurrentAllocationPoint()))
-        ->DecreaseAllocatedBytes(remaining_size);
-  }
-  // Set up a new linear allocation area.
-  current_allocation_point_ = point;
-  remaining_allocation_size_ = size;
-  // Update last allocated region in ThreadHeap. This must also be done if the
-  // allocation point is set to 0 (before doing GC), so that the last allocated
-  // region is automatically reset after GC.
-  GetThreadState()->Heap().SetLastAllocatedRegion(point, size);
-  if (point) {
-    // Only, update allocated size and object start bitmap if the area is
-    // actually set up with a non-null address.
-    GetThreadState()->Heap().stats_collector()->IncreaseAllocatedObjectSize(
-        size);
-    NormalPage* page = static_cast<NormalPage*>(PageFromObject(point));
-    page->IncreaseAllocatedBytes(size);
-    // Current allocation point can never be part of the object bitmap start
-    // because the area can grow or shrink. Will be added back before a GC when
-    // clearing the allocation point.
-    page->object_start_bit_map()
-        ->ClearBit<HeapObjectHeader::AccessMode::kAtomic>(point);
-    // Mark page as containing young objects.
-    page->SetAsYoung(true);
-  }
-}
-
-Address NormalPageArena::OutOfLineAllocate(size_t allocation_size,
-                                           size_t gc_info_index) {
-  Address result = OutOfLineAllocateImpl(allocation_size, gc_info_index);
-  GetThreadState()->Heap().stats_collector()->AllocatedObjectSizeSafepoint();
-  return result;
-}
-
-Address NormalPageArena::OutOfLineAllocateImpl(size_t allocation_size,
-                                               size_t gc_info_index) {
-  DCHECK_GT(allocation_size, RemainingAllocationSize());
-  DCHECK_GE(allocation_size, kAllocationGranularity);
-
-  // 1. If this allocation is big enough, allocate a large object.
-  if (allocation_size >= kLargeObjectSizeThreshold)
-    return AllocateLargeObject(allocation_size, gc_info_index);
-
-  // 2. Try to allocate from a free list.
-  Address result = AllocateFromFreeList(allocation_size, gc_info_index);
-  if (result)
-    return result;
-
-  // 3. Reset the allocation point.
-  SetAllocationPoint(nullptr, 0);
-
-  // 4. Lazily sweep pages of this heap until we find a freed area for
-  // this allocation or we finish sweeping all pages of this heap.
-  result = LazySweep(allocation_size, gc_info_index);
-  if (result)
-    return result;
-
-  // 5. Complete sweeping.
-  GetThreadState()->CompleteSweep();
-
-  // 6. Check if we should trigger a GC.
-  GetThreadState()->ScheduleGCIfNeeded();
-
-  // 7. Add a new page to this heap.
-  AllocatePage();
-
-  // 8. Try to allocate from a free list. This allocation must succeed.
-  result = AllocateFromFreeList(allocation_size, gc_info_index);
-  CHECK(result);
-  return result;
-}
-
-LargeObjectArena::LargeObjectArena(ThreadState* state, int index)
-    : BaseArena(state, index) {}
-
-Address LargeObjectArena::AllocateLargeObjectPage(size_t allocation_size,
-                                                  size_t gc_info_index) {
-  // Caller already added space for object header and rounded up to allocation
-  // alignment
-  DCHECK(!(allocation_size & kAllocationMask));
-
-  // 1. Try to sweep large objects more than allocationSize bytes
-  // before allocating a new large object.
-  Address result = LazySweep(allocation_size, gc_info_index);
-  if (result)
-    return result;
-
-  // 2. If we have failed in sweeping allocationSize bytes,
-  // we complete sweeping before allocating this large object.
-  GetThreadState()->CompleteSweep();
-
-  // 3. Check if we should trigger a GC.
-  GetThreadState()->ScheduleGCIfNeeded();
-
-  return DoAllocateLargeObjectPage(allocation_size, gc_info_index);
-}
-
-Address LargeObjectArena::DoAllocateLargeObjectPage(size_t allocation_size,
-                                                    size_t gc_info_index) {
-  size_t large_page_size = LargeObjectPage::PageHeaderSize() + allocation_size;
-// If ASan is supported we add allocationGranularity bytes to the allocated
-// space and poison that to detect overflows
-#if defined(ADDRESS_SANITIZER)
-  large_page_size += kAllocationGranularity;
-#endif
-
-  PageMemory* page_memory = PageMemory::Allocate(
-      large_page_size, GetThreadState()->Heap().GetRegionTree());
-  Address large_page_address = page_memory->WritableStart();
-  Address header_address =
-      large_page_address + LargeObjectPage::PageHeaderSize();
-#if DCHECK_IS_ON()
-  // Verify that the allocated PageMemory is expectedly zeroed.
-  for (size_t i = 0; i < large_page_size; ++i)
-    DCHECK(!large_page_address[i]);
-#endif
-  DCHECK_GT(gc_info_index, 0u);
-  LargeObjectPage* large_page = new (large_page_address)
-      LargeObjectPage(page_memory, this, allocation_size);
-  HeapObjectHeader* header = new (NotNullTag::kNotNull, header_address)
-      HeapObjectHeader(kLargeObjectSizeInHeader, gc_info_index);
-  Address result = header_address + sizeof(*header);
-  DCHECK(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
-
-  // Poison the object header and allocationGranularity bytes after the object
-  ASAN_POISON_MEMORY_REGION(header, sizeof(*header));
-  ASAN_POISON_MEMORY_REGION(large_page->GetAddress() + large_page->size(),
-                            kAllocationGranularity);
-
-  swept_pages_.PushLocked(large_page);
-
-  // Update last allocated region in ThreadHeap.
-  GetThreadState()->Heap().SetLastAllocatedRegion(large_page->Payload(),
-                                                  large_page->PayloadSize());
-
-  // Add all segments of kBlinkPageSize to the bloom filter so that the large
-  // object can be kept by derived pointers on stack. An alternative might be to
-  // prohibit derived pointers to large objects, but that is dangerous since the
-  // compiler is free to optimize on-stack base pointers away.
-  for (Address page_begin = RoundToBlinkPageStart(large_page->GetAddress());
-       page_begin < large_page->PayloadEnd(); page_begin += kBlinkPageSize) {
-    GetThreadState()->Heap().page_bloom_filter()->Add(page_begin);
-  }
-  GetThreadState()->Heap().stats_collector()->IncreaseAllocatedSpace(
-      large_page->size());
-  GetThreadState()->Heap().stats_collector()->IncreaseAllocatedObjectSize(
-      large_page->ObjectSize());
-  large_page->IncreaseAllocatedBytes(large_page->ObjectSize());
-  // Add page to the list of young pages.
-  large_page->SetAsYoung(true);
-  SynchronizedStore(large_page);
-  return result;
-}
-
-void LargeObjectArena::FreeLargeObjectPage(LargeObjectPage* object) {
-  ASAN_UNPOISON_MEMORY_REGION(object->Payload(), object->PayloadSize());
-  object->ObjectHeader()->Finalize(object->Payload(), object->PayloadSize());
-  ThreadHeap& heap = GetThreadState()->Heap();
-  heap.stats_collector()->DecreaseAllocatedSpace(object->size());
-  heap.page_bloom_filter()->Remove(object->GetAddress());
-
-  // Unpoison the object header and allocationGranularity bytes after the
-  // object before freeing.
-  ASAN_UNPOISON_MEMORY_REGION(object->ObjectHeader(), sizeof(HeapObjectHeader));
-  ASAN_UNPOISON_MEMORY_REGION(object->GetAddress() + object->size(),
-                              kAllocationGranularity);
-
-  PageMemory* memory = object->Storage();
-  object->~LargeObjectPage();
-  delete memory;
-}
-
-Address LargeObjectArena::LazySweepPages(size_t allocation_size,
-                                         size_t gc_info_index) {
-  Address result = nullptr;
-  size_t swept_size = 0;
-  while (BasePage* page = unswept_pages_.PopLocked()) {
-    if (page->Sweep(FinalizeType::kInlined)) {
-      swept_size += static_cast<LargeObjectPage*>(page)->ObjectSize();
-      page->RemoveFromHeap();
-      // For LargeObjectPage, stop lazy sweeping once we have swept
-      // more than |allocation_size| bytes.
-      if (swept_size >= allocation_size) {
-        result = DoAllocateLargeObjectPage(allocation_size, gc_info_index);
-        DCHECK(result);
-        break;
-      }
-    } else {
-      swept_pages_.PushLocked(page);
-      page->MarkAsSwept();
-    }
-  }
-  return result;
-}
-
-FreeList::FreeList() : biggest_free_list_index_(0) {
-  Clear();
-}
-
-void FreeList::Add(Address address, size_t size) {
-  DCHECK_LT(size, BlinkPagePayloadSize());
-  // The free list entries are only pointer aligned (but when we allocate
-  // from them we are 8 byte aligned due to the header size).
-  DCHECK(!((reinterpret_cast<uintptr_t>(address) + sizeof(HeapObjectHeader)) &
-           kAllocationMask));
-  DCHECK(!(size & kAllocationMask));
-  DCHECK(!PageFromObject(address)->IsLargeObjectPage());
-  ASAN_UNPOISON_MEMORY_REGION(address, size);
-  FreeListEntry* entry;
-  if (size < sizeof(*entry)) {
-    // Create a dummy header with only a size and freelist bit set.
-    DCHECK_GE(size, sizeof(HeapObjectHeader));
-    // Free list encode the size to mark the lost memory as freelist memory.
-    new (NotNullTag::kNotNull, address)
-        HeapObjectHeader(size, kGcInfoIndexForFreeListHeader);
-    ASAN_POISON_MEMORY_REGION(address, size);
-    // This memory gets lost. Sweeping can reclaim it.
-    return;
-  }
-  entry = new (NotNullTag::kNotNull, address) FreeListEntry(size);
-
-#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
-  // The following logic delays reusing free lists for (at least) one GC
-  // cycle. This is helpful to detect use-after-free errors that could be caused
-  // by lazy sweeping etc.
-  size_t allowed_count = 0;
-  size_t forbidden_count = 0;
-  GetAllowedAndForbiddenCounts(address, size, allowed_count, forbidden_count);
-  size_t entry_count = size - sizeof(FreeListEntry);
-  if (forbidden_count == entry_count) {
-    // If all values in the memory region are reuseForbiddenZapValue,
-    // we flip them to reuseAllowedZapValue. This allows the next
-    // addToFreeList() to add the memory region to the free list
-    // (unless someone concatenates the memory region with another memory
-    // region that contains reuseForbiddenZapValue.)
-    for (size_t i = sizeof(FreeListEntry); i < size; i++)
-      address[i] = kReuseAllowedZapValue;
-    ASAN_POISON_MEMORY_REGION(address, size);
-    // Don't add the memory region to the free list in this addToFreeList().
-    return;
-  }
-  if (allowed_count != entry_count) {
-    // If the memory region mixes reuseForbiddenZapValue and
-    // reuseAllowedZapValue, we (conservatively) flip all the values
-    // to reuseForbiddenZapValue. These values will be changed to
-    // reuseAllowedZapValue in the next addToFreeList().
-    for (size_t i = sizeof(FreeListEntry); i < size; i++)
-      address[i] = kReuseForbiddenZapValue;
-    ASAN_POISON_MEMORY_REGION(address, size);
-    // Don't add the memory region to the free list in this addToFreeList().
-    return;
-  }
-// We reach here only when all the values in the memory region are
-// reuseAllowedZapValue. In this case, we are allowed to add the memory
-// region to the free list and reuse it for another object.
-#endif
-  ASAN_POISON_MEMORY_REGION(address, size);
-
-  const int index = BucketIndexForSize(size);
-  entry->Link(&free_list_heads_[index]);
-  if (index > biggest_free_list_index_) {
-    biggest_free_list_index_ = index;
-  }
-  if (!entry->Next()) {
-    free_list_tails_[index] = entry;
-  }
-}
-
-void FreeList::MoveFrom(FreeList* other) {
-#if DCHECK_IS_ON()
-  const size_t expected_size = FreeListSize() + other->FreeListSize();
-#endif
-
-  // Newly created entries get added to the head.
-  for (size_t index = 0; index < kBlinkPageSizeLog2; ++index) {
-    FreeListEntry* other_tail = other->free_list_tails_[index];
-    FreeListEntry*& this_head = this->free_list_heads_[index];
-    if (other_tail) {
-      other_tail->Append(this_head);
-      if (!this_head) {
-        this->free_list_tails_[index] = other_tail;
-      }
-      this_head = other->free_list_heads_[index];
-      other->free_list_heads_[index] = nullptr;
-      other->free_list_tails_[index] = nullptr;
-    }
-  }
-
-  biggest_free_list_index_ =
-      std::max(biggest_free_list_index_, other->biggest_free_list_index_);
-  other->biggest_free_list_index_ = 0;
-
-#if DCHECK_IS_ON()
-  DCHECK_EQ(expected_size, FreeListSize());
-#endif
-  DCHECK(other->IsEmpty());
-}
-
-FreeListEntry* FreeList::Allocate(size_t allocation_size) {
-  // Try reusing a block from the largest bin. The underlying reasoning
-  // being that we want to amortize this slow allocation call by carving
-  // off as a large a free block as possible in one go; a block that will
-  // service this block and let following allocations be serviced quickly
-  // by bump allocation.
-  size_t bucket_size = static_cast<size_t>(1) << biggest_free_list_index_;
-  int index = biggest_free_list_index_;
-  for (; index > 0; --index, bucket_size >>= 1) {
-    DCHECK(IsConsistent(index));
-    FreeListEntry* entry = free_list_heads_[index];
-    if (allocation_size > bucket_size) {
-      // Final bucket candidate; check initial entry if it is able
-      // to service this allocation. Do not perform a linear scan,
-      // as it is considered too costly.
-      if (!entry || entry->size() < allocation_size)
-        break;
-    }
-    if (entry) {
-      if (!entry->Next()) {
-        DCHECK_EQ(entry, free_list_tails_[index]);
-        free_list_tails_[index] = nullptr;
-      }
-      entry->Unlink(&free_list_heads_[index]);
-      biggest_free_list_index_ = index;
-      return entry;
-    }
-  }
-  biggest_free_list_index_ = index;
-  return nullptr;
-}
-
-#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) || \
-    defined(MEMORY_SANITIZER)
-NO_SANITIZE_MEMORY
-NOINLINE void FreeList::GetAllowedAndForbiddenCounts(Address address,
-                                                     size_t size,
-                                                     size_t& allowed_count,
-                                                     size_t& forbidden_count) {
-  for (size_t i = sizeof(FreeListEntry); i < size; i++) {
-    if (address[i] == kReuseAllowedZapValue)
-      allowed_count++;
-    else if (address[i] == kReuseForbiddenZapValue)
-      forbidden_count++;
-    else
-      NOTREACHED();
-  }
-}
-
-NO_SANITIZE_ADDRESS
-NO_SANITIZE_MEMORY
-NOINLINE void FreeList::ZapFreedMemory(Address address, size_t size) {
-  for (size_t i = 0; i < size; i++) {
-    // See the comment in addToFreeList().
-    if (address[i] != kReuseAllowedZapValue)
-      address[i] = kReuseForbiddenZapValue;
-  }
-}
-
-NOINLINE void FreeList::CheckFreedMemoryIsZapped(Address address, size_t size) {
-  for (size_t i = 0; i < size; i++) {
-    DCHECK(address[i] == kReuseAllowedZapValue ||
-           address[i] == kReuseForbiddenZapValue);
-  }
-}
-#endif
-
-size_t FreeList::FreeListSize() const {
-  size_t free_size = 0;
-  for (unsigned i = 0; i < kBlinkPageSizeLog2; ++i) {
-    FreeListEntry* entry = free_list_heads_[i];
-    while (entry) {
-      free_size += entry->size();
-      entry = entry->Next();
-    }
-  }
-#if DEBUG_HEAP_FREELIST
-  if (free_size) {
-    LOG_HEAP_FREELIST_VERBOSE() << "FreeList(" << this << "): " << free_size;
-    for (unsigned i = 0; i < kBlinkPageSizeLog2; ++i) {
-      FreeListEntry* entry = free_list_heads_[i];
-      size_t bucket = 0;
-      size_t count = 0;
-      while (entry) {
-        bucket += entry->size();
-        count++;
-        entry = entry->Next();
-      }
-      if (bucket) {
-        LOG_HEAP_FREELIST_VERBOSE()
-            << "[" << (0x1 << i) << ", " << (0x1 << (i + 1)) << "]: " << bucket
-            << " (" << count << ")";
-      }
-    }
-  }
-#endif
-  return free_size;
-}
-
-void FreeList::Clear() {
-  biggest_free_list_index_ = 0;
-  for (size_t i = 0; i < kBlinkPageSizeLog2; ++i) {
-    free_list_heads_[i] = nullptr;
-    free_list_tails_[i] = nullptr;
-  }
-}
-
-bool FreeList::IsEmpty() const {
-  if (biggest_free_list_index_)
-    return false;
-  for (size_t i = 0; i < kBlinkPageSizeLog2; ++i) {
-    if (free_list_heads_[i]) {
-      DCHECK(free_list_tails_[i]);
-      return false;
-    }
-  }
-  return true;
-}
-
-int FreeList::BucketIndexForSize(size_t size) {
-  DCHECK_GT(size, 0u);
-  int index = -1;
-  while (size) {
-    size >>= 1;
-    index++;
-  }
-  return index;
-}
-
-void FreeList::CollectStatistics(
-    ThreadState::Statistics::FreeListStatistics* stats) {
-  Vector<size_t> bucket_size;
-  Vector<size_t> free_count;
-  Vector<size_t> free_size;
-  for (size_t i = 0; i < kBlinkPageSizeLog2; ++i) {
-    size_t entry_count = 0;
-    size_t entry_size = 0;
-    for (FreeListEntry* entry = free_list_heads_[i]; entry;
-         entry = entry->Next()) {
-      ++entry_count;
-      entry_size += entry->size();
-    }
-    bucket_size.push_back(1 << i);
-    free_count.push_back(entry_count);
-    free_size.push_back(entry_size);
-  }
-  *stats = {std::move(bucket_size), std::move(free_count),
-            std::move(free_size)};
-}
-
-BasePage::BasePage(PageMemory* storage, BaseArena* arena, PageType page_type)
-    : storage_(storage),
-      arena_(arena),
-      thread_state_(arena->GetThreadState()),
-      page_type_(page_type) {
-#if DCHECK_IS_ON()
-  DCHECK(IsPageHeaderAddress(reinterpret_cast<Address>(this)));
-#endif
-}
-
-NormalPage::NormalPage(PageMemory* storage, BaseArena* arena)
-    : BasePage(storage, arena, PageType::kNormalPage),
-      object_start_bit_map_(Payload()) {
-#if DCHECK_IS_ON()
-  DCHECK(IsPageHeaderAddress(reinterpret_cast<Address>(this)));
-#endif  // DCHECK_IS_ON()
-}
-
-NormalPage::~NormalPage() {
-#if DCHECK_IS_ON()
-  DCHECK(IsPageHeaderAddress(reinterpret_cast<Address>(this)));
-#endif
-}
-
-size_t NormalPage::ObjectPayloadSizeForTesting() {
-  size_t object_payload_size = 0;
-  Address header_address = Payload();
-  DCHECK_NE(header_address, PayloadEnd());
-  do {
-    HeapObjectHeader* header =
-        reinterpret_cast<HeapObjectHeader*>(header_address);
-    if (!header->IsFree()) {
-      object_payload_size += header->PayloadSize();
-    }
-    DCHECK_LT(header->size(), BlinkPagePayloadSize());
-    header_address += header->size();
-    DCHECK_LE(header_address, PayloadEnd());
-  } while (header_address < PayloadEnd());
-  return object_payload_size;
-}
-
-void NormalPage::RemoveFromHeap() {
-  ArenaForNormalPage()->FreePage(this);
-}
-
-#if !DCHECK_IS_ON() && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER)
-static void DiscardPages(Address begin, Address end) {
-  uintptr_t begin_address =
-      base::RoundUpToSystemPage(reinterpret_cast<uintptr_t>(begin));
-  uintptr_t end_address =
-      base::RoundDownToSystemPage(reinterpret_cast<uintptr_t>(end));
-  if (begin_address < end_address) {
-    base::DiscardSystemPages(reinterpret_cast<void*>(begin_address),
-                             end_address - begin_address);
-  }
-}
-#endif
-
-void NormalPage::ToBeFinalizedObject::Finalize() {
-  const size_t size = header->size();
-  // This is a fast version of header->PayloadSize().
-  const size_t payload_size = size - sizeof(HeapObjectHeader);
-  const Address payload = header->Payload();
-  // For ASan, unpoison the object before calling the finalizer. The
-  // finalized object will be zero-filled and poison'ed afterwards.
-  // Given all other unmarked objects are poisoned, ASan will detect
-  // an error if the finalizer touches any other on-heap object that
-  // die at the same GC cycle.
-  ASAN_UNPOISON_MEMORY_REGION(payload, payload_size);
-
-  header->Finalize(payload, payload_size);
-  // This memory will be added to the freelist. Maintain the invariant
-  // that memory on the freelist is zero filled.
-  SET_MEMORY_INACCESSIBLE(reinterpret_cast<Address>(header), size);
-}
-
-void NormalPage::FinalizeSweep(SweepResult action) {
-  // Call finalizers.
-  for (ToBeFinalizedObject& object : to_be_finalized_objects_) {
-    object.Finalize();
-  }
-  to_be_finalized_objects_.clear();
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-  // Copy object start bit map.
-  DCHECK(cached_object_start_bit_map_);
-  object_start_bit_map_ = *cached_object_start_bit_map_;
-  cached_object_start_bit_map_.reset();
-#endif
-  // Merge freelists or unmap the page.
-  if (action == SweepResult::kPageNotEmpty) {
-    MergeFreeLists();
-    MarkAsSwept();
-  } else {
-    DCHECK(action == SweepResult::kPageEmpty);
-    RemoveFromHeap();
-  }
-}
-
-void NormalPage::AddToFreeList(Address start,
-                               size_t size,
-                               FinalizeType finalize_type,
-                               bool found_finalizer) {
-  // If a free allocation block contains an object that is yet to be
-  // finalized, push it in a separate freelist to preserve the guarantee
-  // that all freelist entries are zeroed out.
-  if (found_finalizer && finalize_type == FinalizeType::kDeferred) {
-    FutureFreelistEntry entry{start, size};
-    unfinalized_freelist_.push_back(std::move(entry));
-  } else {
-    cached_freelist_.Add(start, size);
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-    cached_object_start_bit_map_->SetBit(start);
-#else
-    object_start_bit_map_.SetBit(start);
-#endif
-#if !DCHECK_IS_ON() && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER)
-    if (Arena()->GetThreadState()->IsMemoryReducingGC()) {
-      DiscardPages(start + sizeof(FreeListEntry), start + size);
-    }
-#endif
-  }
-}
-
-void NormalPage::MergeFreeLists() {
-  NormalPageArena* arena = ArenaForNormalPage();
-  arena->AddToFreeList(&cached_freelist_);
-  DCHECK(cached_freelist_.IsEmpty());
-
-  for (const FutureFreelistEntry& entry : unfinalized_freelist_) {
-    arena->AddToFreeList(entry.start, entry.size);
-#if !DCHECK_IS_ON() && !defined(LEAK_SANITIZER) && !defined(ADDRESS_SANITIZER)
-    if (Arena()->GetThreadState()->IsMemoryReducingGC()) {
-      DiscardPages(entry.start + sizeof(FreeListEntry),
-                   entry.start + entry.size);
-    }
-#endif
-  }
-  unfinalized_freelist_.clear();
-}
-
-bool NormalPage::Sweep(FinalizeType finalize_type) {
-  PlatformAwareObjectStartBitmap* bitmap;
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-  cached_object_start_bit_map_ =
-      std::make_unique<PlatformAwareObjectStartBitmap>(Payload());
-  bitmap = cached_object_start_bit_map_.get();
-#else
-  object_start_bit_map()->Clear();
-  bitmap = object_start_bit_map();
-#endif
-  cached_freelist_.Clear();
-  unfinalized_freelist_.clear();
-  Address start_of_gap = Payload();
-  size_t live_bytes = 0;
-  bool found_finalizer = false;
-  for (Address header_address = start_of_gap; header_address < PayloadEnd();) {
-    HeapObjectHeader* header =
-        reinterpret_cast<HeapObjectHeader*>(header_address);
-    const size_t size = header->size();
-    DCHECK_GT(size, 0u);
-    DCHECK_LT(size, BlinkPagePayloadSize());
-
-    if (header->IsFree<HeapObjectHeader::AccessMode::kAtomic>()) {
-      // Zero the memory in the free list header to maintain the
-      // invariant that memory on the free list is zero filled.
-      // The rest of the memory is already on the free list and is
-      // therefore already zero filled.
-      SET_MEMORY_INACCESSIBLE(header_address,
-                              std::min(size, sizeof(FreeListEntry)));
-      CHECK_MEMORY_INACCESSIBLE(header_address, size);
-      header_address += size;
-      continue;
-    }
-    if (!header->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
-      // The following accesses to the header are safe non-atomically, because
-      // we just established the invariant that the object is not marked.
-      ToBeFinalizedObject object{header};
-      if (finalize_type == FinalizeType::kInlined ||
-          !header->HasNonTrivialFinalizer()) {
-        // In case the header doesn't have a finalizer, we eagerly call a
-        // freehook.
-        // TODO(bikineev): It may be unsafe to do this concurrently.
-        object.Finalize();
-      } else {
-        to_be_finalized_objects_.push_back(std::move(object));
-        found_finalizer = true;
-      }
-      header_address += size;
-      continue;
-    }
-    if (start_of_gap != header_address) {
-      AddToFreeList(start_of_gap, header_address - start_of_gap, finalize_type,
-                    found_finalizer);
-      found_finalizer = false;
-    }
-    bitmap->SetBit(header_address);
-#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-    header->Unmark<HeapObjectHeader::AccessMode::kAtomic>();
-#endif
-    live_bytes += size;
-    header_address += size;
-    start_of_gap = header_address;
-  }
-  SetAllocatedBytes(live_bytes);
-  // Only add the memory to the free list if the page is not completely empty
-  // and we are not at the end of the page. Empty pages are not added to the
-  // free list as the pages are removed immediately.
-  if (start_of_gap != Payload() && start_of_gap != PayloadEnd()) {
-    AddToFreeList(start_of_gap, PayloadEnd() - start_of_gap, finalize_type,
-                  found_finalizer);
-  }
-  return start_of_gap == Payload();
-}
-
-void NormalPage::SweepAndCompact(CompactionContext& context) {
-  object_start_bit_map()->Clear();
-  NormalPage*& current_page = context.current_page_;
-  size_t& allocation_point = context.allocation_point_;
-  SetAllocatedBytes(0u);
-
-  NormalPageArena* page_arena = ArenaForNormalPage();
-#if defined(ADDRESS_SANITIZER)
-  bool is_vector_arena =
-      ThreadHeap::IsVectorArenaIndex(page_arena->ArenaIndex());
-#endif
-  HeapCompact* compact = page_arena->GetThreadState()->Heap().Compaction();
-  for (Address header_address = Payload(); header_address < PayloadEnd();) {
-    HeapObjectHeader* header =
-        reinterpret_cast<HeapObjectHeader*>(header_address);
-    size_t size = header->size();
-    DCHECK_GT(size, 0u);
-    DCHECK_LT(size, BlinkPagePayloadSize());
-
-    if (header->IsFree()) {
-      // Unpoison the freelist entry so that we
-      // can compact into it as wanted.
-      ASAN_UNPOISON_MEMORY_REGION(header_address, size);
-      header_address += size;
-      continue;
-    }
-    // This is a fast version of header->PayloadSize().
-    size_t payload_size = size - sizeof(HeapObjectHeader);
-    Address payload = header->Payload();
-    if (!header->IsMarked()) {
-      // For ASan, unpoison the object before calling the finalizer. The
-      // finalized object will be zero-filled and poison'ed afterwards.
-      // Given all other unmarked objects are poisoned, ASan will detect
-      // an error if the finalizer touches any other on-heap object that
-      // die at the same GC cycle.
-      ASAN_UNPOISON_MEMORY_REGION(header_address, size);
-      // Compaction is currently launched only from AtomicPhaseEpilogue, so it's
-      // guaranteed to be on the mutator thread - no need to postpone
-      // finalization.
-      header->Finalize(payload, payload_size);
-
-// As compaction is under way, leave the freed memory accessible
-// while compacting the rest of the page. We just zap the payload
-// to catch out other finalizers trying to access it.
-#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) || \
-    defined(MEMORY_SANITIZER)
-      FreeList::ZapFreedMemory(payload, payload_size);
-#endif
-      header_address += size;
-      continue;
-    }
-#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-    header->Unmark();
-#endif
-    // Allocate and copy over the live object.
-    Address compact_frontier = current_page->Payload() + allocation_point;
-    if (compact_frontier + size > current_page->PayloadEnd()) {
-      // Can't fit on current allocation page; add remaining onto the
-      // freelist and advance to next available page.
-      //
-      // TODO(sof): be more clever & compact later objects into
-      // |currentPage|'s unused slop.
-      context.compacted_pages_->Push(current_page);
-      size_t free_size = current_page->PayloadSize() - allocation_point;
-      if (free_size) {
-        SET_MEMORY_INACCESSIBLE(compact_frontier, free_size);
-        current_page->ArenaForNormalPage()->AddToFreeList(compact_frontier,
-                                                          free_size);
-      }
-
-      current_page = static_cast<NormalPage*>(context.available_pages_.Pop());
-      allocation_point = 0;
-      compact_frontier = current_page->Payload();
-    }
-    if (LIKELY(compact_frontier != header_address)) {
-#if defined(ADDRESS_SANITIZER)
-      // Unpoison the header + if it is a vector backing
-      // store object, let go of the container annotations.
-      // Do that by unpoisoning the payload entirely.
-      ASAN_UNPOISON_MEMORY_REGION(header, sizeof(HeapObjectHeader));
-      if (is_vector_arena) {
-        ASAN_UNPOISON_MEMORY_REGION(payload, payload_size);
-      }
-#endif
-      // Use a non-overlapping copy, if possible.
-      if (current_page == this)
-        memmove(compact_frontier, header_address, size);
-      else
-        memcpy(compact_frontier, header_address, size);
-      compact->Relocate(payload, compact_frontier + sizeof(HeapObjectHeader));
-    }
-    current_page->object_start_bit_map()->SetBit(compact_frontier);
-    current_page->IncreaseAllocatedBytes(size);
-    header_address += size;
-    allocation_point += size;
-    DCHECK(allocation_point <= current_page->PayloadSize());
-  }
-
-#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) || \
-    defined(MEMORY_SANITIZER)
-  // Zap the unused portion, until it is either compacted into or freed.
-  if (current_page != this) {
-    FreeList::ZapFreedMemory(Payload(), PayloadSize());
-  } else {
-    FreeList::ZapFreedMemory(Payload() + allocation_point,
-                             PayloadSize() - allocation_point);
-  }
-#endif
-}
-
-void NormalPage::MakeConsistentForMutator() {
-  object_start_bit_map()->Clear();
-  Address start_of_gap = Payload();
-  NormalPageArena* normal_arena = ArenaForNormalPage();
-  size_t live_bytes = 0;
-  for (Address header_address = Payload(); header_address < PayloadEnd();) {
-    HeapObjectHeader* header =
-        reinterpret_cast<HeapObjectHeader*>(header_address);
-    size_t size = header->size();
-    DCHECK_LT(size, BlinkPagePayloadSize());
-    if (header->IsFree()) {
-      // Zero the memory in the free list header to maintain the
-      // invariant that memory on the free list is zero filled.
-      // The rest of the memory is already on the free list and is
-      // therefore already zero filled.
-      SET_MEMORY_INACCESSIBLE(header_address, size < sizeof(FreeListEntry)
-                                                  ? size
-                                                  : sizeof(FreeListEntry));
-      CHECK_MEMORY_INACCESSIBLE(header_address, size);
-      header_address += size;
-      continue;
-    }
-    if (start_of_gap != header_address)
-      normal_arena->AddToFreeList(start_of_gap, header_address - start_of_gap);
-    if (header->IsMarked()) {
-      header->Unmark();
-    }
-    object_start_bit_map()->SetBit(header_address);
-    live_bytes += size;
-    header_address += size;
-    start_of_gap = header_address;
-    DCHECK_LE(header_address, PayloadEnd());
-  }
-  SetAllocatedBytes(live_bytes);
-  if (start_of_gap != PayloadEnd())
-    normal_arena->AddToFreeList(start_of_gap, PayloadEnd() - start_of_gap);
-
-  VerifyObjectStartBitmapIsConsistentWithPayload();
-}
-
-// This is assumed to be called from the atomic pause, so no concurrency should
-// be involved here.
-void NormalPage::Unmark() {
-  const Address current_allocation_point =
-      ArenaForNormalPage()->CurrentAllocationPoint();
-  const size_t allocation_area_size =
-      ArenaForNormalPage()->RemainingAllocationSize();
-  for (Address header_address = Payload(); header_address < PayloadEnd();) {
-    // Since unmarking can happen inside IncrementalMarkingStart, the current
-    // allocation point can be set and we need to skip over it.
-    if (header_address == current_allocation_point && allocation_area_size) {
-      header_address += allocation_area_size;
-      continue;
-    }
-    HeapObjectHeader* header =
-        reinterpret_cast<HeapObjectHeader*>(header_address);
-    if (header->IsMarked()) {
-      header->Unmark();
-    }
-    header_address += header->size();
-  }
-  ClearCardTable();
-}
-
-#if defined(ADDRESS_SANITIZER)
-void NormalPage::PoisonUnmarkedObjects() {
-  for (Address header_address = Payload(); header_address < PayloadEnd();) {
-    HeapObjectHeader* header =
-        reinterpret_cast<HeapObjectHeader*>(header_address);
-    DCHECK_LT(header->size(), BlinkPagePayloadSize());
-    // Check if a free list entry first since we cannot call
-    // isMarked on a free list entry.
-    if (header->IsFree()) {
-      header_address += header->size();
-      continue;
-    }
-    if (!header->IsMarked()) {
-      ASAN_POISON_MEMORY_REGION(header->Payload(), header->PayloadSize());
-    }
-    header_address += header->size();
-  }
-}
-#endif
-
-void NormalPage::VerifyObjectStartBitmapIsConsistentWithPayload() {
-#if DCHECK_IS_ON()
-  HeapObjectHeader* current_header =
-      reinterpret_cast<HeapObjectHeader*>(Payload());
-  object_start_bit_map()->Iterate([this,
-                                   &current_header](Address object_address) {
-    const HeapObjectHeader* object_header =
-        reinterpret_cast<HeapObjectHeader*>(object_address);
-    DCHECK_EQ(object_header, current_header);
-    current_header = reinterpret_cast<HeapObjectHeader*>(object_address +
-                                                         object_header->size());
-    // Skip over allocation area.
-    if (reinterpret_cast<Address>(current_header) ==
-        ArenaForNormalPage()->CurrentAllocationPoint()) {
-      current_header = reinterpret_cast<HeapObjectHeader*>(
-          ArenaForNormalPage()->CurrentAllocationPoint() +
-          ArenaForNormalPage()->RemainingAllocationSize());
-    }
-  });
-#endif  // DCHECK_IS_ON()
-}
-
-void NormalPage::VerifyMarking() {
-  DCHECK(!ArenaForNormalPage()->CurrentAllocationPoint());
-  MarkingVerifier verifier(ArenaForNormalPage()->GetThreadState());
-  for (Address header_address = Payload(); header_address < PayloadEnd();) {
-    HeapObjectHeader* header =
-        reinterpret_cast<HeapObjectHeader*>(header_address);
-    verifier.VerifyObject(header);
-    header_address += header->size();
-  }
-}
-
-void LargeObjectPage::VerifyMarking() {
-  MarkingVerifier verifier(Arena()->GetThreadState());
-  verifier.VerifyObject(ObjectHeader());
-}
-
-HeapObjectHeader* NormalPage::ConservativelyFindHeaderFromAddress(
-    ConstAddress address) const {
-  if (!ContainedInObjectPayload(address))
-    return nullptr;
-  if (ArenaForNormalPage()->IsInCurrentAllocationPointRegion(address))
-    return nullptr;
-  HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
-      object_start_bit_map()->FindHeader(address));
-  if (header->IsFree())
-    return nullptr;
-  DCHECK_LT(0u, header->GcInfoIndex());
-  DCHECK_GT(header->PayloadEnd(), address);
-  return header;
-}
-
-void NormalPage::CollectStatistics(
-    ThreadState::Statistics::ArenaStatistics* arena_stats) {
-  HeapObjectHeader* header = nullptr;
-  size_t live_size = 0;
-  for (Address header_address = Payload(); header_address < PayloadEnd();
-       header_address += header->size()) {
-    header = reinterpret_cast<HeapObjectHeader*>(header_address);
-    if (!header->IsFree()) {
-      // All non-free objects, dead or alive, are considered as live for the
-      // purpose of taking a snapshot.
-      live_size += header->size();
-      if (!NameClient::HideInternalName()) {
-        // Detailed names available.
-        uint32_t gc_info_index = header->GcInfoIndex();
-        arena_stats->object_stats.type_count[gc_info_index]++;
-        arena_stats->object_stats.type_bytes[gc_info_index] += header->size();
-        if (arena_stats->object_stats.type_name[gc_info_index].empty()) {
-          arena_stats->object_stats.type_name[gc_info_index] = header->Name();
-        }
-      }
-    }
-  }
-  DCHECK_EQ(live_size, AllocatedBytes());
-  arena_stats->committed_size_bytes += kBlinkPageSize;
-  arena_stats->used_size_bytes += live_size;
-  arena_stats->page_stats.emplace_back(
-      ThreadState::Statistics::PageStatistics{kBlinkPageSize, live_size});
-}
-
-#if DCHECK_IS_ON()
-bool NormalPage::Contains(ConstAddress addr) const {
-  Address blink_page_start = RoundToBlinkPageStart(GetAddress());
-  // Page is at aligned address plus guard page size.
-  DCHECK_EQ(blink_page_start, GetAddress() - BlinkGuardPageSize());
-  return blink_page_start <= addr && addr < blink_page_start + kBlinkPageSize;
-}
-#endif
-
-LargeObjectPage::LargeObjectPage(PageMemory* storage,
-                                 BaseArena* arena,
-                                 size_t object_size)
-    : BasePage(storage, arena, PageType::kLargeObjectPage),
-      object_size_(object_size)
-#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
-      ,
-      is_vector_backing_page_(false)
-#endif
-{
-}
-
-size_t LargeObjectPage::ObjectPayloadSizeForTesting() {
-  return PayloadSize();
-}
-
-void LargeObjectPage::RemoveFromHeap() {
-  static_cast<LargeObjectArena*>(Arena())->FreeLargeObjectPage(this);
-}
-
-bool LargeObjectPage::Sweep(FinalizeType) {
-  if (!ObjectHeader()->IsMarked()) {
-    SetAllocatedBytes(0u);
-    return true;
-  }
-#if !BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-  ObjectHeader()->Unmark();
-#endif
-  DCHECK_EQ(AllocatedBytes(), ObjectSize());
-  return false;
-}
-
-void LargeObjectPage::Unmark() {
-  HeapObjectHeader* header = ObjectHeader();
-  if (header->IsMarked()) {
-    header->Unmark();
-  }
-  SetRemembered(false);
-}
-
-void LargeObjectPage::MakeConsistentForMutator() {
-  Unmark();
-  DCHECK_EQ(AllocatedBytes(), ObjectSize());
-}
-
-void LargeObjectPage::FinalizeSweep(SweepResult action) {
-  if (action == SweepResult::kPageNotEmpty) {
-    MarkAsSwept();
-  } else {
-    DCHECK(action == SweepResult::kPageEmpty);
-    RemoveFromHeap();
-  }
-}
-
-#if defined(ADDRESS_SANITIZER)
-void LargeObjectPage::PoisonUnmarkedObjects() {
-  HeapObjectHeader* header = ObjectHeader();
-  if (!header->IsMarked()) {
-    ASAN_POISON_MEMORY_REGION(header->Payload(), header->PayloadSize());
-  }
-}
-#endif
-
-void LargeObjectPage::CollectStatistics(
-    ThreadState::Statistics::ArenaStatistics* arena_stats) {
-  HeapObjectHeader* header = ObjectHeader();
-  // All non-free objects, dead or alive, are considered as live for the
-  // purpose of taking a snapshot.
-  size_t live_size = ObjectSize();
-  if (!NameClient::HideInternalName()) {
-    // Detailed names available.
-    uint32_t gc_info_index = header->GcInfoIndex();
-    arena_stats->object_stats.type_count[gc_info_index]++;
-    arena_stats->object_stats.type_bytes[gc_info_index] += live_size;
-  }
-  DCHECK_EQ(live_size, AllocatedBytes());
-  arena_stats->committed_size_bytes += size();
-  arena_stats->used_size_bytes += live_size;
-  arena_stats->page_stats.emplace_back(
-      ThreadState::Statistics::PageStatistics{size(), live_size});
-}
-
-#if DCHECK_IS_ON()
-bool LargeObjectPage::Contains(ConstAddress object) const {
-  return RoundToBlinkPageStart(GetAddress()) <= object &&
-         object < RoundToBlinkPageEnd(GetAddress() + size());
-}
-#endif
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_page.h b/third_party/blink/renderer/platform/heap/impl/heap_page.h
deleted file mode 100644
index f68c999..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_page.h
+++ /dev/null
@@ -1,1632 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_PAGE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_PAGE_H_
-
-#include <stdint.h>
-#include <array>
-#include <atomic>
-
-#include "base/bits.h"
-#include "base/compiler_specific.h"
-#include "base/dcheck_is_on.h"
-#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
-#include "third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h"
-#include "third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
-#include "third_party/blink/renderer/platform/wtf/container_annotations.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-
-namespace blink {
-
-// TODO(palmer): Document the reason for 17.
-constexpr size_t kBlinkPageSizeLog2 = 17;
-constexpr size_t kBlinkPageSize = 1 << kBlinkPageSizeLog2;
-constexpr size_t kBlinkPageOffsetMask = kBlinkPageSize - 1;
-constexpr size_t kBlinkPageBaseMask = ~kBlinkPageOffsetMask;
-
-// We allocate pages at random addresses but in groups of kBlinkPagesPerRegion
-// at a given random address. We group pages to not spread out too much over the
-// address space which would blow away the page tables and lead to bad
-// performance.
-constexpr size_t kBlinkPagesPerRegion = 10;
-
-// TODO(nya): Replace this with something like #if ENABLE_NACL.
-#if defined(ARCH_CPU_PPC64)
-// NaCl's system page size is 64 KiB. This causes a problem in Oilpan's heap
-// layout because Oilpan allocates two guard pages for each Blink page (whose
-// size is kBlinkPageSize = 2^17 = 128 KiB). So we don't use guard pages in
-// NaCl.
-// The same issue holds for ppc64 systems, which use a 64k page size.
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-BlinkGuardPageSize() {
-  return 0;
-}
-#else
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-BlinkGuardPageSize() {
-  return base::SystemPageSize();
-}
-#endif
-
-// Double precision floats are more efficient when 8-byte aligned, so we 8-byte
-// align all allocations (even on 32 bit systems).
-static_assert(8 == sizeof(double), "We expect sizeof(double) to be 8");
-constexpr size_t kAllocationGranularity = sizeof(double);
-constexpr size_t kAllocationMask = kAllocationGranularity - 1;
-constexpr size_t kLargeObjectSizeThreshold = kBlinkPageSize / 2;
-
-// A zap value used for freed memory that is allowed to be added to the free
-// list in the next call to AddToFreeList.
-constexpr uint8_t kReuseAllowedZapValue = 0x2a;
-// A zap value used for freed memory that is forbidden to be added to the free
-// list in the next call to AddToFreeList.
-constexpr uint8_t kReuseForbiddenZapValue = 0x2c;
-
-// In non-production builds, memory is zapped when it's freed. The zapped memory
-// is zeroed out when the memory is reused in ThreadHeap::AllocateObject.
-//
-// In production builds, memory is not zapped (for performance). The memory is
-// just zeroed out when it is added to the free list.
-#if defined(MEMORY_SANITIZER)
-// TODO(kojii): We actually need __msan_poison/unpoison here, but it'll be
-// added later.
-#define SET_MEMORY_INACCESSIBLE(address, size) \
-  FreeList::ZapFreedMemory(address, size);
-#define SET_MEMORY_ACCESSIBLE(address, size) memset((address), 0, (size))
-#define CHECK_MEMORY_INACCESSIBLE(address, size)     \
-  ASAN_UNPOISON_MEMORY_REGION(address, size);        \
-  FreeList::CheckFreedMemoryIsZapped(address, size); \
-  ASAN_POISON_MEMORY_REGION(address, size)
-#elif DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
-#define SET_MEMORY_INACCESSIBLE(address, size) \
-  FreeList::ZapFreedMemory(address, size);     \
-  ASAN_POISON_MEMORY_REGION(address, size)
-#define SET_MEMORY_ACCESSIBLE(address, size)  \
-  ASAN_UNPOISON_MEMORY_REGION(address, size); \
-  memset((address), 0, (size))
-#define CHECK_MEMORY_INACCESSIBLE(address, size)     \
-  ASAN_UNPOISON_MEMORY_REGION(address, size);        \
-  FreeList::CheckFreedMemoryIsZapped(address, size); \
-  ASAN_POISON_MEMORY_REGION(address, size)
-#else
-#define SET_MEMORY_INACCESSIBLE(address, size) memset((address), 0, (size))
-#define SET_MEMORY_ACCESSIBLE(address, size) \
-  do {                                       \
-  } while (false)
-#define CHECK_MEMORY_INACCESSIBLE(address, size) \
-  do {                                           \
-  } while (false)
-#endif
-
-class NormalPageArena;
-class PageMemory;
-class BaseArena;
-class ThreadHeap;
-
-// HeapObjectHeader is a 32-bit object that has the following layout:
-//
-// | padding (32 bits)            | Only present on 64-bit platforms.
-// | gc_info_index (14 bits)      |
-// | unused (1 bit)               |
-// | in construction (1 bit)      | true: bit not set; false bit set
-//
-// | size (14 bits)               | Actually 17 bits because sizes are aligned.
-// | unused (1 bit)               |
-// | mark bit (1 bit)             |
-//
-// Notes:
-// - 14 bits for |gc_info_index} (type information) are enough as there are
-//   fewer than 2^14 types allocated in Blink.
-// - |size| for regular objects is encoded with 14 bits but can actually
-//   represent sizes up to |kBlinkPageSize| (2^17) because allocations are
-//   always 8 byte aligned (see kAllocationGranularity).
-// - |size| for large objects is encoded as 0. The size of a large object is
-//   stored in |LargeObjectPage::PayloadSize()|.
-// - |mark bit| and |in construction| bits are located in separate variables and
-//   therefore can be accessed concurrently. Since tsan works with word-size
-//   objects they still should be accessed atomically.
-constexpr uint16_t kHeaderMarkBitMask = 1;
-constexpr uint16_t kHeaderSizeShift = 2;
-constexpr uint16_t kHeaderSizeMask =
-    static_cast<uint16_t>(((1 << 14) - 1) << kHeaderSizeShift);
-
-constexpr uint16_t kHeaderIsInConstructionMask = 1;
-constexpr uint16_t kHeaderGCInfoIndexShift = 2;
-constexpr uint16_t kHeaderGCInfoSize = static_cast<uint16_t>(1 << 14);
-constexpr uint16_t kHeaderGCInfoIndexMask =
-    static_cast<uint16_t>((kHeaderGCInfoSize - 1) << kHeaderGCInfoIndexShift);
-
-constexpr uint16_t kLargeObjectSizeInHeader = 0;
-constexpr uint16_t kGcInfoIndexForFreeListHeader = 0;
-constexpr size_t kNonLargeObjectPageSizeMax = 1 << kBlinkPageSizeLog2;
-
-static_assert(kHeaderGCInfoSize == GCInfoTable::kMaxIndex,
-              "GCInfoTable size and and header GCInfo index size must match");
-
-static_assert(
-    kNonLargeObjectPageSizeMax >= kBlinkPageSize,
-    "max size supported by HeapObjectHeader must at least be kBlinkPageSize");
-
-namespace internal {
-
-NO_SANITIZE_ADDRESS constexpr uint16_t EncodeSize(size_t size) {
-  // Essentially, gets optimized to >> 1.
-  return static_cast<uint16_t>((size << kHeaderSizeShift) /
-                               kAllocationGranularity);
-}
-
-NO_SANITIZE_ADDRESS constexpr size_t DecodeSize(uint16_t encoded) {
-  // Essentially, gets optimized to << 1.
-  return ((encoded & kHeaderSizeMask) >> kHeaderSizeShift) *
-         kAllocationGranularity;
-}
-
-}  // namespace internal
-
-class PLATFORM_EXPORT HeapObjectHeader {
-  DISALLOW_NEW();
-
- public:
-  enum class AccessMode : uint8_t { kNonAtomic, kAtomic };
-
-  static HeapObjectHeader* FromPayload(const void*);
-  template <AccessMode = AccessMode::kNonAtomic>
-  static HeapObjectHeader* FromInnerAddress(const void*);
-
-  // Checks sanity of the header given a payload pointer.
-  static void CheckFromPayload(const void*);
-
-  // If |gc_info_index| is 0, this header is interpreted as a free list header.
-  HeapObjectHeader(size_t, size_t);
-
-  template <AccessMode mode = AccessMode::kNonAtomic>
-  NO_SANITIZE_ADDRESS bool IsFree() const {
-    return GcInfoIndex<mode>() == kGcInfoIndexForFreeListHeader;
-  }
-
-  template <AccessMode mode = AccessMode::kNonAtomic>
-  NO_SANITIZE_ADDRESS uint32_t GcInfoIndex() const {
-    const uint16_t encoded =
-        LoadEncoded<mode, EncodedHalf::kHigh, std::memory_order_acquire>();
-    return (encoded & kHeaderGCInfoIndexMask) >> kHeaderGCInfoIndexShift;
-  }
-
-  template <AccessMode = AccessMode::kNonAtomic>
-  size_t size() const;
-  void SetSize(size_t size);
-
-  template <AccessMode = AccessMode::kNonAtomic>
-  bool IsLargeObject() const;
-
-  template <AccessMode = AccessMode::kNonAtomic>
-  bool IsMarked() const;
-  template <AccessMode = AccessMode::kNonAtomic>
-  void Unmark();
-  template <AccessMode = AccessMode::kNonAtomic>
-  bool TryMark();
-
-  template <AccessMode = AccessMode::kNonAtomic>
-  bool IsOld() const;
-
-  template <AccessMode = AccessMode::kNonAtomic>
-  bool IsInConstruction() const;
-  template <AccessMode = AccessMode::kNonAtomic>
-  void MarkFullyConstructed();
-
-  // The payload starts directly after the HeapObjectHeader, and the payload
-  // size does not include the sizeof(HeapObjectHeader).
-  Address Payload() const;
-  size_t PayloadSize() const;
-  template <AccessMode = AccessMode::kNonAtomic>
-  Address PayloadEnd() const;
-
-  void Finalize(Address, size_t);
-
-  // Returns true if object has finalizer.
-  bool HasNonTrivialFinalizer() const;
-
-  // Returns a human-readable name of this object.
-  const char* Name() const;
-
- private:
-  enum class EncodedHalf : uint8_t { kLow, kHigh };
-
-  template <AccessMode,
-            EncodedHalf part,
-            std::memory_order = std::memory_order_seq_cst>
-  uint16_t LoadEncoded() const;
-  template <AccessMode mode,
-            EncodedHalf part,
-            std::memory_order = std::memory_order_seq_cst>
-  void StoreEncoded(uint16_t bits, uint16_t mask);
-
-#if defined(ARCH_CPU_64_BITS)
-  uint32_t padding_ = 0;
-#endif  // defined(ARCH_CPU_64_BITS)
-  uint16_t encoded_high_;
-  uint16_t encoded_low_;
-};
-
-class FreeListEntry final : public HeapObjectHeader {
- public:
-  NO_SANITIZE_ADDRESS
-  explicit FreeListEntry(size_t size)
-      : HeapObjectHeader(size, kGcInfoIndexForFreeListHeader), next_(nullptr) {}
-
-  Address GetAddress() { return reinterpret_cast<Address>(this); }
-
-  NO_SANITIZE_ADDRESS
-  void Unlink(FreeListEntry** previous_next) {
-    *previous_next = next_;
-    next_ = nullptr;
-  }
-
-  NO_SANITIZE_ADDRESS
-  void Link(FreeListEntry** previous_next) {
-    next_ = *previous_next;
-    *previous_next = this;
-  }
-
-  NO_SANITIZE_ADDRESS
-  FreeListEntry* Next() const { return next_; }
-
-  NO_SANITIZE_ADDRESS
-  void Append(FreeListEntry* next) {
-    DCHECK(!next_);
-    next_ = next;
-  }
-
- private:
-  FreeListEntry* next_;
-
-  friend class FreeList;
-};
-
-class FreeList {
-  DISALLOW_NEW();
-
- public:
-  // Returns a bucket number for inserting a |FreeListEntry| of a given size.
-  // All entries in the given bucket, n, have size >= 2^n.
-  static int BucketIndexForSize(size_t);
-
-#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER) || \
-    defined(MEMORY_SANITIZER)
-  static void GetAllowedAndForbiddenCounts(Address, size_t, size_t&, size_t&);
-  static void ZapFreedMemory(Address, size_t);
-  static void CheckFreedMemoryIsZapped(Address, size_t);
-#endif
-
-  FreeList();
-
-  FreeListEntry* Allocate(size_t);
-  void Add(Address, size_t);
-  void MoveFrom(FreeList*);
-  void Clear();
-
-  bool IsEmpty() const;
-  size_t FreeListSize() const;
-
-  void CollectStatistics(ThreadState::Statistics::FreeListStatistics*);
-
-  template <typename Predicate>
-  FreeListEntry* FindEntry(Predicate pred) {
-    for (size_t i = 0; i < kBlinkPageSizeLog2; ++i) {
-      for (FreeListEntry* entry = free_list_heads_[i]; entry;
-           entry = entry->Next()) {
-        if (pred(entry)) {
-          return entry;
-        }
-      }
-    }
-    return nullptr;
-  }
-
- private:
-  bool IsConsistent(size_t index) const {
-    return (!free_list_heads_[index] && !free_list_tails_[index]) ||
-           (free_list_heads_[index] && free_list_tails_[index] &&
-            !free_list_tails_[index]->Next());
-  }
-
-  // All |FreeListEntry|s in the nth list have size >= 2^n.
-  FreeListEntry* free_list_heads_[kBlinkPageSizeLog2];
-  FreeListEntry* free_list_tails_[kBlinkPageSizeLog2];
-  int biggest_free_list_index_;
-};
-
-// Blink heap pages are set up with a guard page before and after the payload.
-PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-BlinkPagePayloadSize() {
-  return kBlinkPageSize - 2 * BlinkGuardPageSize();
-}
-
-// Blink heap pages are aligned to the Blink heap page size. Therefore, the
-// start of a Blink page can be obtained by rounding down to the Blink page
-// size.
-inline Address RoundToBlinkPageStart(Address address) {
-  return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) &
-                                   kBlinkPageBaseMask);
-}
-
-inline Address RoundToBlinkPageEnd(Address address) {
-  return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address - 1) &
-                                   kBlinkPageBaseMask) +
-         kBlinkPageSize;
-}
-
-// Masks an address down to the enclosing Blink page base address.
-inline Address BlinkPageAddress(Address address) {
-  return reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address) &
-                                   kBlinkPageBaseMask);
-}
-
-inline bool VTableInitialized(const void* object_pointer) {
-  return !!(*reinterpret_cast<const ConstAddress*>(object_pointer));
-}
-
-#if DCHECK_IS_ON()
-
-// Sanity check for a page header address: the address of the page header should
-// be 1 OS page size away from being Blink page size-aligned.
-inline bool IsPageHeaderAddress(Address address) {
-  return !((reinterpret_cast<uintptr_t>(address) & kBlinkPageOffsetMask) -
-           BlinkGuardPageSize());
-}
-
-#endif
-
-// |FinalizeType| specifies when finalization should take place.
-// In case of concurrent sweeper we defer finalization to be done
-// on the main thread.
-enum class FinalizeType : uint8_t { kInlined, kDeferred };
-
-// |SweepResult| indicates if page turned out to be empty after sweeping.
-enum class SweepResult : uint8_t { kPageEmpty, kPageNotEmpty };
-
-// |PageType| indicates whether a page is used for normal objects or whether it
-// holds a large object.
-enum class PageType : uint8_t { kNormalPage, kLargeObjectPage };
-
-// |BasePage| is a base class for |NormalPage| and |LargeObjectPage|.
-//
-// - |NormalPage| is a page whose size is |kBlinkPageSize|. A |NormalPage| can
-//   contain multiple objects. An object whose size is smaller than
-//   |kLargeObjectSizeThreshold| is stored in a |NormalPage|.
-//
-// - |LargeObjectPage| is a page that contains only one object. The object size
-//   is arbitrary. An object whose size is larger than |kBlinkPageSize| is
-//   stored as a single project in |LargeObjectPage|.
-//
-// Note: An object whose size is between |kLargeObjectSizeThreshold| and
-// |kBlinkPageSize| can go to either of |NormalPage| or |LargeObjectPage|.
-class BasePage {
-  DISALLOW_NEW();
-
- public:
-  BasePage(PageMemory*, BaseArena*, PageType);
-  virtual ~BasePage() = default;
-
-  // Virtual methods are slow. So performance-sensitive methods should be
-  // defined as non-virtual methods on |NormalPage| and |LargeObjectPage|. The
-  // following methods are not performance-sensitive.
-  virtual size_t ObjectPayloadSizeForTesting() = 0;
-  virtual void RemoveFromHeap() = 0;
-  // Sweeps a page. Returns true when that page is empty and false otherwise.
-  // Does not create free list entries for empty pages.
-  virtual bool Sweep(FinalizeType) = 0;
-  virtual void MakeConsistentForMutator() = 0;
-  virtual void Unmark() = 0;
-
-  // Calls finalizers after sweeping is done.
-  virtual void FinalizeSweep(SweepResult) = 0;
-
-#if defined(ADDRESS_SANITIZER)
-  virtual void PoisonUnmarkedObjects() = 0;
-#endif
-
-  virtual void CollectStatistics(
-      ThreadState::Statistics::ArenaStatistics* arena_stats) = 0;
-
-#if DCHECK_IS_ON()
-  virtual bool Contains(ConstAddress) const = 0;
-#endif
-  virtual size_t size() const = 0;
-
-  Address GetAddress() const {
-    return reinterpret_cast<Address>(const_cast<BasePage*>(this));
-  }
-  PageMemory* Storage() const { return storage_; }
-  BaseArena* Arena() const { return arena_; }
-  ThreadState* thread_state() const { return thread_state_; }
-
-  // Returns true if this page has been swept by the ongoing sweep; false
-  // otherwise.
-  bool HasBeenSwept() const { return swept_; }
-
-  void MarkAsSwept() {
-    DCHECK(!swept_);
-    swept_ = true;
-  }
-
-  void MarkAsUnswept() {
-    DCHECK(swept_);
-    swept_ = false;
-  }
-
-  // Returns true  if this page is a large object page; false otherwise.
-  bool IsLargeObjectPage() const {
-    return page_type_ == PageType::kLargeObjectPage;
-  }
-
-  // Young pages are pages that contain at least a single young object.
-  bool IsYoung() const { return is_young_; }
-
-  void SetAsYoung(bool young) { is_young_ = young; }
-
-  // The number of bytes that allocated on the page and are not freed yet.
-  size_t AllocatedBytes() { return allocated_bytes_; }
-
-  void SetAllocatedBytes(size_t bytes) { allocated_bytes_ = bytes; }
-
-  void IncreaseAllocatedBytes(size_t bytes) { allocated_bytes_ += bytes; }
-
-  void DecreaseAllocatedBytes(size_t bytes) {
-    DCHECK_GE(allocated_bytes_, bytes);
-    allocated_bytes_ -= bytes;
-  }
-
-  virtual void VerifyMarking() = 0;
-
- private:
-  void SynchronizedLoad() {
-#if defined(THREAD_SANITIZER)
-    WTF::AsAtomicPtr(&page_type_)->load(std::memory_order_acquire);
-#endif
-  }
-  void SynchronizedStore() {
-    std::atomic_thread_fence(std::memory_order_seq_cst);
-#if defined(THREAD_SANITIZER)
-    WTF::AsAtomicPtr(&page_type_)->store(page_type_, std::memory_order_release);
-#endif
-  }
-
-  PageMemory* const storage_;
-  BaseArena* const arena_;
-  ThreadState* const thread_state_;
-
-  // The counter is updated by the sweeper and the allocator.
-  // It is the sum of objects marked at the last GC and objects allocated on
-  // the page since the last GC.
-  size_t allocated_bytes_ = 0;
-
-  // Track the sweeping state of a page. Set to false at the start of a sweep,
-  // true upon completion of sweeping that page.
-  bool swept_ = true;
-  bool is_young_ = false;
-
-  PageType page_type_;
-
-  friend class BaseArena;
-  friend class HeapObjectHeader;
-  friend class ThreadHeap;
-};
-
-class PageStack : Vector<BasePage*> {
-  using Base = Vector<BasePage*>;
-
- public:
-  PageStack() = default;
-
-  void Push(BasePage* page) { push_back(page); }
-
-  BasePage* Pop() {
-    if (IsEmpty())
-      return nullptr;
-    BasePage* top = back();
-    pop_back();
-    return top;
-  }
-
-  BasePage* Top() const {
-    if (IsEmpty())
-      return nullptr;
-    return back();
-  }
-
-  using Base::begin;
-  using Base::end;
-
-  using Base::clear;
-  using Base::erase;
-
-  using Base::IsEmpty;
-  using Base::size;
-};
-
-class PageStackThreadSafe : public PageStack {
- public:
-  void PushLocked(BasePage* page) {
-    WTF::MutexLocker locker(mutex_);
-    Push(page);
-  }
-
-  BasePage* PopLocked() {
-    WTF::MutexLocker locker(mutex_);
-    return Pop();
-  }
-
-  bool IsEmptyLocked() const {
-    WTF::MutexLocker locker(mutex_);
-    return IsEmpty();
-  }
-
-  // Explicit unsafe move assignment.
-  void MoveFrom(PageStack&& other) { PageStack::operator=(std::move(other)); }
-
- private:
-  mutable WTF::Mutex mutex_;
-};
-
-// A bitmap for recording object starts. Objects have to be allocated at
-// minimum granularity of kGranularity.
-//
-// Depends on internals such as:
-// - kBlinkPageSize
-// - kAllocationGranularity
-class PLATFORM_EXPORT ObjectStartBitmap {
-  USING_FAST_MALLOC(ObjectStartBitmap);
-
- public:
-  // Granularity of addresses added to the bitmap.
-  static constexpr size_t Granularity() { return kAllocationGranularity; }
-
-  // Maximum number of entries in the bitmap.
-  static constexpr size_t MaxEntries() {
-    return kReservedForBitmap * kCellSize;
-  }
-
-  explicit ObjectStartBitmap(Address offset);
-
-  // Finds an object header based on a
-  // address_maybe_pointing_to_the_middle_of_object. Will search for an object
-  // start in decreasing address order.
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  Address FindHeader(
-      ConstAddress address_maybe_pointing_to_the_middle_of_object) const;
-
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  inline void SetBit(Address);
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  inline void ClearBit(Address);
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  inline bool CheckBit(Address) const;
-
-  // Iterates all object starts recorded in the bitmap.
-  //
-  // The callback is of type
-  //   void(Address)
-  // and is passed the object start address as parameter.
-  template <typename Callback>
-  inline void Iterate(Callback) const;
-
-  // Clear the object start bitmap.
-  void Clear();
-
- private:
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  void store(size_t cell_index, uint8_t value);
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  uint8_t load(size_t cell_index) const;
-
-  static const size_t kCellSize = sizeof(uint8_t) * 8;
-  static const size_t kCellMask = sizeof(uint8_t) * 8 - 1;
-  static const size_t kBitmapSize =
-      (kBlinkPageSize + ((kCellSize * kAllocationGranularity) - 1)) /
-      (kCellSize * kAllocationGranularity);
-  static const size_t kReservedForBitmap =
-      ((kBitmapSize + kAllocationMask) & ~kAllocationMask);
-
-  inline void ObjectStartIndexAndBit(Address, size_t*, size_t*) const;
-
-  Address offset_;
-  // The bitmap contains a bit for every kGranularity aligned address on a
-  // a NormalPage, i.e., for a page of size kBlinkPageSize.
-  uint8_t object_start_bit_map_[kReservedForBitmap];
-};
-
-// A platform aware version of ObjectStartBitmap to provide platform specific
-// optimizations (e.g. Use non-atomic stores on ARMv7 when not marking).
-class PLATFORM_EXPORT PlatformAwareObjectStartBitmap
-    : public ObjectStartBitmap {
-  USING_FAST_MALLOC(PlatformAwareObjectStartBitmap);
-
- public:
-  explicit PlatformAwareObjectStartBitmap(Address offset);
-
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  inline void SetBit(Address);
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  inline void ClearBit(Address);
-
- private:
-  template <HeapObjectHeader::AccessMode>
-  static bool ShouldForceNonAtomic();
-};
-
-class PLATFORM_EXPORT NormalPage final : public BasePage {
- public:
-  NormalPage(PageMemory*, BaseArena*);
-  ~NormalPage() override;
-
-  Address Payload() const { return GetAddress() + PageHeaderSize(); }
-  static PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-  PayloadSize() {
-    return (BlinkPagePayloadSize() - PageHeaderSize()) & ~kAllocationMask;
-  }
-  Address PayloadEnd() const { return Payload() + PayloadSize(); }
-  bool ContainedInObjectPayload(ConstAddress address) const {
-    return Payload() <= address && address < PayloadEnd();
-  }
-
-  size_t ObjectPayloadSizeForTesting() override;
-  void RemoveFromHeap() override;
-  bool Sweep(FinalizeType) override;
-  void MakeConsistentForMutator() override;
-  void Unmark() override;
-  void FinalizeSweep(SweepResult) override;
-#if defined(ADDRESS_SANITIZER)
-  void PoisonUnmarkedObjects() override;
-#endif
-
-  void CollectStatistics(
-      ThreadState::Statistics::ArenaStatistics* arena_stats) override;
-
-#if DCHECK_IS_ON()
-  // Returns true for the whole |kBlinkPageSize| page that the page is on, even
-  // for the header, and the unmapped guard page at the start. That ensures the
-  // result can be used to populate the negative page cache.
-  bool Contains(ConstAddress) const override;
-#endif
-  size_t size() const override { return kBlinkPageSize; }
-  static constexpr size_t PageHeaderSize() {
-    // Compute the amount of padding we have to add to a header to make the size
-    // of the header plus the padding a multiple of 8 bytes.
-    constexpr size_t kPaddingSize =
-        (sizeof(NormalPage) + kAllocationGranularity -
-         (sizeof(HeapObjectHeader) % kAllocationGranularity)) %
-        kAllocationGranularity;
-    return sizeof(NormalPage) + kPaddingSize;
-  }
-
-  inline NormalPageArena* ArenaForNormalPage() const;
-
-  // Context object holding the state of the arena page compaction pass, passed
-  // in when compacting individual pages.
-  class CompactionContext {
-    STACK_ALLOCATED();
-
-   public:
-    // Page compacting into.
-    NormalPage* current_page_ = nullptr;
-    // Offset into |current_page_| to the next free address.
-    size_t allocation_point_ = 0;
-    // Vector of available pages to use for compaction. Page compaction picks
-    // the next one when the current one is exhausted.
-    PageStack available_pages_;
-    // Vector of pages that have been compacted. Page compaction will add
-    // compacted pages once the current one becomes exhausted.
-    PageStack* compacted_pages_;
-  };
-
-  void SweepAndCompact(CompactionContext&);
-
-  // Object start bitmap of this page.
-  PlatformAwareObjectStartBitmap* object_start_bit_map() {
-    return &object_start_bit_map_;
-  }
-  const PlatformAwareObjectStartBitmap* object_start_bit_map() const {
-    return &object_start_bit_map_;
-  }
-
-  // Verifies that the object start bitmap only contains a bit iff the object
-  // is also reachable through iteration on the page.
-  void VerifyObjectStartBitmapIsConsistentWithPayload();
-
-  // Uses the object_start_bit_map_ to find an object for a given address. The
-  // returned header is either nullptr, indicating that no object could be
-  // found, or it is pointing to valid object or free list entry.
-  // This method is called only during stack scanning when there are no
-  // concurrent markers, thus no atomics required.
-  HeapObjectHeader* ConservativelyFindHeaderFromAddress(ConstAddress) const;
-
-  // Uses the object_start_bit_map_ to find an object for a given address. It is
-  // assumed that the address points into a valid heap object. Use the
-  // conservative version if that assumption does not hold.
-  template <
-      HeapObjectHeader::AccessMode = HeapObjectHeader::AccessMode::kNonAtomic>
-  HeapObjectHeader* FindHeaderFromAddress(ConstAddress) const;
-
-  void VerifyMarking() override;
-
-  // Marks a card corresponding to address.
-  void MarkCard(Address address);
-
-  // Iterates over all objects in marked cards.
-  template <typename Function>
-  void IterateCardTable(Function function) const;
-
-  // Clears all bits in the card table.
-  void ClearCardTable() { card_table_.Clear(); }
-
- private:
-  // Data structure that divides a page in a number of cards each of 512 bytes
-  // size. Marked cards are stored in bytes, not bits, to make write barrier
-  // faster and reduce chances of false sharing. This gives only ~0.1% of memory
-  // overhead. Also, since there are guard pages before and after a Blink page,
-  // some of card bits are wasted and unneeded.
-  class CardTable final {
-   public:
-    struct value_type {
-      uint8_t bit;
-      size_t index;
-    };
-
-    struct iterator {
-      iterator& operator++() {
-        ++index;
-        return *this;
-      }
-      value_type operator*() const { return {table->table_[index], index}; }
-      bool operator!=(iterator other) const {
-        return table != other.table || index != other.index;
-      }
-
-      size_t index = 0;
-      const CardTable* table = nullptr;
-    };
-
-    using const_iterator = iterator;
-
-    static constexpr size_t kBitsPerCard = 9;
-    static constexpr size_t kCardSize = 1 << kBitsPerCard;
-
-    const_iterator begin() const { return {FirstPayloadCard(), this}; }
-    const_iterator end() const { return {LastPayloadCard(), this}; }
-
-    void Mark(size_t card) {
-      DCHECK_LE(FirstPayloadCard(), card);
-      DCHECK_GT(LastPayloadCard(), card);
-      table_[card] = 1;
-    }
-
-    bool IsMarked(size_t card) const {
-      DCHECK_LE(FirstPayloadCard(), card);
-      DCHECK_GT(LastPayloadCard(), card);
-      return table_[card];
-    }
-
-    void Clear() { std::fill(table_.begin(), table_.end(), 0); }
-
-   private:
-    static PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-    FirstPayloadCard() {
-      return (BlinkGuardPageSize() + NormalPage::PageHeaderSize()) / kCardSize;
-    }
-    static PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR ALWAYS_INLINE size_t
-    LastPayloadCard() {
-      return (BlinkGuardPageSize() + BlinkPagePayloadSize()) / kCardSize;
-    }
-
-    std::array<uint8_t, kBlinkPageSize / kCardSize> table_{};
-  };
-
-  struct ToBeFinalizedObject {
-    HeapObjectHeader* header;
-    void Finalize();
-  };
-  struct FutureFreelistEntry {
-    Address start;
-    size_t size;
-  };
-
-  template <typename Function>
-  void IterateOnCard(Function function, size_t card_number) const;
-
-  void MergeFreeLists();
-  void AddToFreeList(Address start,
-                     size_t size,
-                     FinalizeType finalize_type,
-                     bool found_finalizer);
-
-  CardTable card_table_;
-  PlatformAwareObjectStartBitmap object_start_bit_map_;
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-  std::unique_ptr<PlatformAwareObjectStartBitmap> cached_object_start_bit_map_;
-#endif
-  Vector<ToBeFinalizedObject> to_be_finalized_objects_;
-  FreeList cached_freelist_;
-  Vector<FutureFreelistEntry> unfinalized_freelist_;
-
-  friend class CardTableTest;
-};
-
-// Large allocations are allocated as separate objects and linked in a list.
-//
-// In order to use the same memory allocation routines for everything allocated
-// in the heap, large objects are considered heap pages containing only one
-// object.
-class PLATFORM_EXPORT LargeObjectPage final : public BasePage {
- public:
-  static size_t PageHeaderSize() {
-    // Compute the amount of padding we have to add to a header to make the size
-    // of the header plus the padding a multiple of 8 bytes.
-    size_t padding_size =
-        (sizeof(LargeObjectPage) + kAllocationGranularity -
-         (sizeof(HeapObjectHeader) % kAllocationGranularity)) %
-        kAllocationGranularity;
-    return sizeof(LargeObjectPage) + padding_size;
-  }
-
-  LargeObjectPage(PageMemory*, BaseArena*, size_t);
-
-  // LargeObjectPage has the following memory layout:
-  //   this          -> +------------------+
-  //                    | Header           | PageHeaderSize()
-  //   ObjectHeader() -> +------------------+
-  //                    | HeapObjectHeader | sizeof(HeapObjectHeader)
-  //   Payload()     -> +------------------+
-  //                    | Object payload   | PayloadSize()
-  //                    |                  |
-  //   PayloadEnd()  -> +------------------+
-  //
-  //   ObjectSize(): PayloadSize() + sizeof(HeapObjectHeader)
-  //   size():       ObjectSize() + PageHeaderSize()
-
-  HeapObjectHeader* ObjectHeader() const {
-    Address header_address = GetAddress() + PageHeaderSize();
-    return reinterpret_cast<HeapObjectHeader*>(header_address);
-  }
-
-  // Returns the size of the page that is allocatable for objects. This differs
-  // from PayloadSize() as it also includes the HeapObjectHeader.
-  size_t ObjectSize() const { return object_size_; }
-
-  // Returns the size of the page including the header.
-  size_t size() const override { return PageHeaderSize() + object_size_; }
-
-  // Returns the payload start of the underlying object.
-  Address Payload() const { return ObjectHeader()->Payload(); }
-
-  // Returns the payload size of the underlying object.
-  size_t PayloadSize() const { return object_size_ - sizeof(HeapObjectHeader); }
-
-  // Points to the payload end of the underlying object.
-  Address PayloadEnd() const { return Payload() + PayloadSize(); }
-
-  bool ContainedInObjectPayload(ConstAddress address) const {
-    return Payload() <= address && address < PayloadEnd();
-  }
-
-  size_t ObjectPayloadSizeForTesting() override;
-  void RemoveFromHeap() override;
-  bool Sweep(FinalizeType) override;
-  void MakeConsistentForMutator() override;
-  void Unmark() override;
-  void FinalizeSweep(SweepResult) override;
-
-  void CollectStatistics(
-      ThreadState::Statistics::ArenaStatistics* arena_stats) override;
-
-  void VerifyMarking() override;
-
-#if defined(ADDRESS_SANITIZER)
-  void PoisonUnmarkedObjects() override;
-#endif
-
-#if DCHECK_IS_ON()
-  // Returns true for any address that is on one of the pages that this large
-  // object uses. That ensures that we can use a negative result to populate the
-  // negative page cache.
-  bool Contains(ConstAddress) const override;
-#endif
-
-#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
-  void SetIsVectorBackingPage() { is_vector_backing_page_ = true; }
-  bool IsVectorBackingPage() const { return is_vector_backing_page_; }
-#endif
-
-  // Remembers the page as containing inter-generational pointers.
-  void SetRemembered(bool remembered) { is_remembered_ = remembered; }
-  bool IsRemembered() const { return is_remembered_; }
-
- private:
-  // The size of the underlying object including HeapObjectHeader.
-  size_t object_size_;
-#ifdef ANNOTATE_CONTIGUOUS_CONTAINER
-  bool is_vector_backing_page_;
-#endif
-  bool is_remembered_ = false;
-};
-
-// Each thread has a number of thread arenas (e.g., Generic arenas, typed arenas
-// for |Node|, arenas for collection backings, etc.) and |BaseArena| represents
-// each thread arena.
-//
-// |BaseArena| is a parent class of |NormalPageArena| and |LargeObjectArena|.
-// |NormalPageArena| represents a part of a heap that contains |NormalPage|s,
-// and |LargeObjectArena| represents a part of a heap that contains
-// |LargeObjectPage|s.
-class PLATFORM_EXPORT BaseArena {
-  USING_FAST_MALLOC(BaseArena);
-
- public:
-  BaseArena(ThreadState*, int);
-  virtual ~BaseArena();
-  void RemoveAllPages();
-
-  void CollectStatistics(std::string, ThreadState::Statistics*);
-  virtual void CollectFreeListStatistics(
-      ThreadState::Statistics::FreeListStatistics*) {}
-  size_t AllocatedBytes();
-
-#if DCHECK_IS_ON()
-  BasePage* FindPageFromAddress(ConstAddress) const;
-#endif
-  virtual void ClearFreeLists() {}
-  virtual void MakeIterable() {}
-  virtual void MakeConsistentForGC();
-  void MakeConsistentForMutator();
-  void Unmark();
-#if DCHECK_IS_ON()
-  virtual bool IsConsistentForGC() = 0;
-#endif
-  size_t ObjectPayloadSizeForTesting();
-  void PrepareForSweep(BlinkGC::CollectionType);
-#if defined(ADDRESS_SANITIZER)
-  void PoisonUnmarkedObjects();
-#endif
-  Address LazySweep(size_t, size_t gc_info_index);
-  bool SweepUnsweptPage(BasePage*);
-  bool SweepUnsweptPageOnConcurrentThread(BasePage*);
-  // Returns true if we have swept all pages within the deadline. Returns false
-  // otherwise.
-  bool LazySweepWithDeadline(base::TimeTicks deadline);
-  // Returns true if the arena has been fully swept.
-  bool ConcurrentSweepOnePage();
-  void CompleteSweep();
-  void InvokeFinalizersOnSweptPages();
-
-  ThreadState* GetThreadState() { return thread_state_; }
-  int ArenaIndex() const { return index_; }
-
-  Address AllocateLargeObject(size_t allocation_size, size_t gc_info_index);
-
-  // Resets the allocation point if it exists for an arena.
-  virtual void ResetAllocationPoint() {}
-
-  void VerifyMarking();
-  virtual void VerifyObjectStartBitmap() {}
-
- protected:
-  bool SweepingCompleted() const { return unswept_pages_.IsEmptyLocked(); }
-  bool SweepingAndFinalizationCompleted() const {
-    return unswept_pages_.IsEmptyLocked() &&
-           swept_unfinalized_pages_.IsEmptyLocked() &&
-           swept_unfinalized_empty_pages_.IsEmptyLocked();
-  }
-
-  // Pages for allocation.
-  PageStackThreadSafe swept_pages_;
-  // Pages that are being swept.
-  PageStackThreadSafe unswept_pages_;
-  // Pages that have been swept but contain unfinalized objects.
-  PageStackThreadSafe swept_unfinalized_pages_;
-  // Pages that have been swept and need to be removed from the heap.
-  PageStackThreadSafe swept_unfinalized_empty_pages_;
-
- protected:
-  void SynchronizedStore(BasePage* page) { page->SynchronizedStore(); }
-
- private:
-  virtual Address LazySweepPages(size_t, size_t gc_info_index) = 0;
-
-  ThreadState* thread_state_;
-
-  // Index into the page pools. This is used to ensure that the pages of the
-  // same type go into the correct page pool and thus avoid type confusion.
-  //
-  // TODO(palmer): Should this be size_t?
-  int index_;
-};
-
-class PLATFORM_EXPORT NormalPageArena final : public BaseArena {
- public:
-  NormalPageArena(ThreadState*, int index);
-  void AddToFreeList(Address address, size_t size);
-  void AddToFreeList(FreeList* other) { free_list_.MoveFrom(other); }
-  void ClearFreeLists() override;
-  void CollectFreeListStatistics(
-      ThreadState::Statistics::FreeListStatistics*) override;
-  void MakeIterable() override;
-
-#if DCHECK_IS_ON()
-  bool IsConsistentForGC() override;
-  bool PagesToBeSweptContains(ConstAddress) const;
-#endif
-
-  Address AllocateObject(size_t allocation_size, size_t gc_info_index);
-
-  void FreePage(NormalPage*);
-
-  void PromptlyFreeObject(HeapObjectHeader*);
-  void PromptlyFreeObjectInFreeList(HeapObjectHeader*, size_t);
-  bool ExpandObject(HeapObjectHeader*, size_t);
-  bool ShrinkObject(HeapObjectHeader*, size_t);
-  size_t promptly_freed_size() const { return promptly_freed_size_; }
-
-  bool IsObjectAllocatedAtAllocationPoint(HeapObjectHeader* header) {
-    return header->PayloadEnd() == current_allocation_point_;
-  }
-
-  size_t ArenaSize();
-  size_t FreeListSize();
-
-  void SweepAndCompact();
-
-  void ResetAllocationPoint() override { SetAllocationPoint(nullptr, 0); }
-
-  void VerifyObjectStartBitmap() override;
-
-  Address CurrentAllocationPoint() const { return current_allocation_point_; }
-
-  bool IsInCurrentAllocationPointRegion(ConstAddress address) const {
-    return HasCurrentAllocationArea() &&
-           (CurrentAllocationPoint() <= address) &&
-           (address < (CurrentAllocationPoint() + RemainingAllocationSize()));
-  }
-
-  size_t RemainingAllocationSize() const { return remaining_allocation_size_; }
-
-  void MakeConsistentForGC() override;
-
-  template <typename Function>
-  void IterateAndClearCardTables(Function function);
-
- private:
-  void AllocatePage();
-
-  // OutOfLineAllocate represent the slow-path allocation. The suffixed version
-  // contains just allocation code while the other version also invokes a
-  // safepoint where allocated bytes are reported to observers.
-  Address OutOfLineAllocate(size_t allocation_size, size_t gc_info_index);
-  Address OutOfLineAllocateImpl(size_t allocation_size, size_t gc_info_index);
-
-  Address AllocateFromFreeList(size_t, size_t gc_info_index);
-
-  Address LazySweepPages(size_t, size_t gc_info_index) override;
-
-  bool HasCurrentAllocationArea() const {
-    return CurrentAllocationPoint() && RemainingAllocationSize();
-  }
-  void SetAllocationPoint(Address, size_t);
-
-  FreeList free_list_;
-  Address current_allocation_point_;
-  size_t remaining_allocation_size_;
-
-  // The size of promptly freed objects in the heap. This counter is set to
-  // zero before sweeping when clearing the free list and after coalescing.
-  // It will increase for promptly freed objects on already swept pages.
-  size_t promptly_freed_size_;
-};
-
-class LargeObjectArena final : public BaseArena {
- public:
-  LargeObjectArena(ThreadState*, int index);
-  Address AllocateLargeObjectPage(size_t, size_t gc_info_index);
-  void FreeLargeObjectPage(LargeObjectPage*);
-
-#if DCHECK_IS_ON()
-  bool IsConsistentForGC() override { return true; }
-#endif
-
-  template <typename Function>
-  void IterateAndClearRememberedPages(Function function);
-
- private:
-  Address DoAllocateLargeObjectPage(size_t, size_t gc_info_index);
-  Address LazySweepPages(size_t, size_t gc_info_index) override;
-};
-
-// Mask an address down to the enclosing Oilpan heap base page. All Oilpan heap
-// pages are aligned at |kBlinkPageBase| plus the size of a guard page. This
-// will work only for 1) a pointer pointing to a non-large object and 2) a
-// pointer pointing to the beginning of a large object.
-//
-// FIXME: Remove PLATFORM_EXPORT once we get a proper public interface to our
-// typed arenas. This is only exported to enable tests in HeapTest.cpp.
-PLATFORM_EXPORT ALWAYS_INLINE BasePage* PageFromObject(const void* object) {
-  Address address = reinterpret_cast<Address>(const_cast<void*>(object));
-  BasePage* page = reinterpret_cast<BasePage*>(BlinkPageAddress(address) +
-                                               BlinkGuardPageSize());
-#if DCHECK_IS_ON()
-  DCHECK(page->Contains(address));
-#endif
-  return page;
-}
-
-inline HeapObjectHeader* HeapObjectHeader::FromPayload(const void* payload) {
-  Address addr = reinterpret_cast<Address>(const_cast<void*>(payload));
-  HeapObjectHeader* header =
-      reinterpret_cast<HeapObjectHeader*>(addr - sizeof(HeapObjectHeader));
-  return header;
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline HeapObjectHeader* HeapObjectHeader::FromInnerAddress(
-    const void* address) {
-  BasePage* const page = PageFromObject(address);
-  page->SynchronizedLoad();
-  return page->IsLargeObjectPage()
-             ? static_cast<LargeObjectPage*>(page)->ObjectHeader()
-             : static_cast<NormalPage*>(page)->FindHeaderFromAddress<mode>(
-                   reinterpret_cast<ConstAddress>(address));
-}
-
-inline void HeapObjectHeader::CheckFromPayload(const void* payload) {
-  (void)FromPayload(payload);
-}
-
-template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::size() const {
-  // Size is immutable after construction while either marking or sweeping
-  // is running so relaxed load (if mode == kAtomic) is enough.
-  uint16_t encoded_low_value =
-      LoadEncoded<mode, EncodedHalf::kLow, std::memory_order_relaxed>();
-  const size_t result = internal::DecodeSize(encoded_low_value);
-  // Large objects should not refer to header->size() but use
-  // LargeObjectPage::PayloadSize().
-  DCHECK(result != kLargeObjectSizeInHeader);
-  DCHECK(!PageFromObject(this)->IsLargeObjectPage());
-  return result;
-}
-
-NO_SANITIZE_ADDRESS inline void HeapObjectHeader::SetSize(size_t size) {
-  DCHECK(!PageFromObject(Payload())->thread_state()->IsIncrementalMarking());
-  DCHECK_LT(size, kNonLargeObjectPageSizeMax);
-  encoded_low_ = static_cast<uint16_t>(internal::EncodeSize(size) |
-                                       (encoded_low_ & ~kHeaderSizeMask));
-}
-
-template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsLargeObject() const {
-  uint16_t encoded_low_value =
-      LoadEncoded<mode, EncodedHalf::kLow, std::memory_order_relaxed>();
-  return internal::DecodeSize(encoded_low_value) == kLargeObjectSizeInHeader;
-}
-
-template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsInConstruction() const {
-  return (LoadEncoded<mode, EncodedHalf::kHigh, std::memory_order_acquire>() &
-          kHeaderIsInConstructionMask) == 0;
-}
-
-template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline void HeapObjectHeader::MarkFullyConstructed() {
-  DCHECK(IsInConstruction());
-  StoreEncoded<mode, EncodedHalf::kHigh, std::memory_order_release>(
-      kHeaderIsInConstructionMask, kHeaderIsInConstructionMask);
-}
-
-inline Address HeapObjectHeader::Payload() const {
-  return reinterpret_cast<Address>(const_cast<HeapObjectHeader*>(this)) +
-         sizeof(HeapObjectHeader);
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline Address HeapObjectHeader::PayloadEnd() const {
-  return reinterpret_cast<Address>(const_cast<HeapObjectHeader*>(this)) +
-         size<mode>();
-}
-
-NO_SANITIZE_ADDRESS inline size_t HeapObjectHeader::PayloadSize() const {
-  const size_t size = internal::DecodeSize(encoded_low_);
-  if (UNLIKELY(size == kLargeObjectSizeInHeader)) {
-    DCHECK(PageFromObject(this)->IsLargeObjectPage());
-    return static_cast<LargeObjectPage*>(PageFromObject(this))->PayloadSize();
-  }
-  DCHECK(!PageFromObject(this)->IsLargeObjectPage());
-  return size - sizeof(HeapObjectHeader);
-}
-
-template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsMarked() const {
-  const uint16_t encoded =
-      LoadEncoded<mode, EncodedHalf::kLow, std::memory_order_relaxed>();
-  return encoded & kHeaderMarkBitMask;
-}
-
-template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::IsOld() const {
-  // Oilpan uses the sticky-mark-bits technique to encode old objects.
-  return IsMarked<mode>();
-}
-
-template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline void HeapObjectHeader::Unmark() {
-  DCHECK(IsMarked<mode>());
-  StoreEncoded<mode, EncodedHalf::kLow, std::memory_order_relaxed>(
-      0u, kHeaderMarkBitMask);
-}
-
-// The function relies on size bits being unmodified when the function is
-// called, i.e. SetSize() and TryMark() can't be called concurrently.
-template <HeapObjectHeader::AccessMode mode>
-NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::TryMark() {
-  if (mode == AccessMode::kNonAtomic) {
-    if (encoded_low_ & kHeaderMarkBitMask)
-      return false;
-    encoded_low_ |= kHeaderMarkBitMask;
-    return true;
-  }
-  auto* atomic_encoded = internal::AsUnsanitizedAtomic(&encoded_low_);
-  uint16_t old_value = atomic_encoded->load(std::memory_order_relaxed);
-  if (old_value & kHeaderMarkBitMask)
-    return false;
-  const uint16_t new_value = old_value | kHeaderMarkBitMask;
-  return atomic_encoded->compare_exchange_strong(old_value, new_value,
-                                                 std::memory_order_relaxed);
-}
-
-inline Address NormalPageArena::AllocateObject(size_t allocation_size,
-                                               size_t gc_info_index) {
-  if (LIKELY(allocation_size <= remaining_allocation_size_)) {
-    Address header_address = current_allocation_point_;
-    current_allocation_point_ += allocation_size;
-    remaining_allocation_size_ -= allocation_size;
-    DCHECK_GT(gc_info_index, 0u);
-    new (NotNullTag::kNotNull, header_address)
-        HeapObjectHeader(allocation_size, gc_info_index);
-    DCHECK(!PageFromObject(header_address)->IsLargeObjectPage());
-    static_cast<NormalPage*>(PageFromObject(header_address))
-        ->object_start_bit_map()
-        ->SetBit<HeapObjectHeader::AccessMode::kAtomic>(header_address);
-    Address result = header_address + sizeof(HeapObjectHeader);
-    DCHECK(!(reinterpret_cast<uintptr_t>(result) & kAllocationMask));
-
-    SET_MEMORY_ACCESSIBLE(result, allocation_size - sizeof(HeapObjectHeader));
-#if DCHECK_IS_ON()
-    DCHECK(FindPageFromAddress(header_address + allocation_size - 1));
-#endif
-    return result;
-  }
-  return OutOfLineAllocate(allocation_size, gc_info_index);
-}
-
-inline NormalPageArena* NormalPage::ArenaForNormalPage() const {
-  return static_cast<NormalPageArena*>(Arena());
-}
-
-// Iterates over all card tables and clears them.
-template <typename Function>
-inline void NormalPageArena::IterateAndClearCardTables(Function function) {
-  for (BasePage* page : swept_pages_) {
-    auto* normal_page = static_cast<NormalPage*>(page);
-    normal_page->IterateCardTable(function);
-    normal_page->ClearCardTable();
-  }
-}
-
-// Iterates over all pages that may contain inter-generational pointers.
-template <typename Function>
-inline void LargeObjectArena::IterateAndClearRememberedPages(
-    Function function) {
-  for (BasePage* page : swept_pages_) {
-    auto* large_page = static_cast<LargeObjectPage*>(page);
-    if (large_page->IsRemembered()) {
-      function(large_page->ObjectHeader());
-      large_page->SetRemembered(false);
-    }
-  }
-}
-
-// static
-template <HeapObjectHeader::AccessMode mode>
-bool PlatformAwareObjectStartBitmap::ShouldForceNonAtomic() {
-#if defined(ARCH_CPU_ARMEL)
-  // Use non-atomic accesses on ARMv7 when marking is not active.
-  if (mode == HeapObjectHeader::AccessMode::kAtomic) {
-    if (LIKELY(!ThreadState::Current()->IsAnyIncrementalMarking()))
-      return true;
-  }
-#endif  // defined(ARCH_CPU_ARMEL)
-  return false;
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline void PlatformAwareObjectStartBitmap::SetBit(Address header_address) {
-  if (ShouldForceNonAtomic<mode>()) {
-    ObjectStartBitmap::SetBit<HeapObjectHeader::AccessMode::kNonAtomic>(
-        header_address);
-    return;
-  }
-  ObjectStartBitmap::SetBit<mode>(header_address);
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline void PlatformAwareObjectStartBitmap::ClearBit(Address header_address) {
-  if (ShouldForceNonAtomic<mode>()) {
-    ObjectStartBitmap::ClearBit<HeapObjectHeader::AccessMode::kNonAtomic>(
-        header_address);
-    return;
-  }
-  ObjectStartBitmap::ClearBit<mode>(header_address);
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline void ObjectStartBitmap::store(size_t cell_index, uint8_t value) {
-  if (mode == HeapObjectHeader::AccessMode::kNonAtomic) {
-    object_start_bit_map_[cell_index] = value;
-    return;
-  }
-  WTF::AsAtomicPtr(&object_start_bit_map_[cell_index])
-      ->store(value, std::memory_order_release);
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline uint8_t ObjectStartBitmap::load(size_t cell_index) const {
-  if (mode == HeapObjectHeader::AccessMode::kNonAtomic) {
-    return object_start_bit_map_[cell_index];
-  }
-  return WTF::AsAtomicPtr(&object_start_bit_map_[cell_index])
-      ->load(std::memory_order_acquire);
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline void ObjectStartBitmap::SetBit(Address header_address) {
-  size_t cell_index, object_bit;
-  ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
-  // Only the mutator thread writes to the bitmap during concurrent marking,
-  // so no need for CAS here.
-  store<mode>(cell_index,
-              static_cast<uint8_t>(load(cell_index) | (1 << object_bit)));
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline void ObjectStartBitmap::ClearBit(Address header_address) {
-  size_t cell_index, object_bit;
-  ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
-  store<mode>(cell_index,
-              static_cast<uint8_t>(load(cell_index) & ~(1 << object_bit)));
-}
-
-template <HeapObjectHeader::AccessMode mode>
-inline bool ObjectStartBitmap::CheckBit(Address header_address) const {
-  size_t cell_index, object_bit;
-  ObjectStartIndexAndBit(header_address, &cell_index, &object_bit);
-  return load<mode>(cell_index) & (1 << object_bit);
-}
-
-inline void ObjectStartBitmap::ObjectStartIndexAndBit(Address header_address,
-                                                      size_t* cell_index,
-                                                      size_t* bit) const {
-  const size_t object_offset = header_address - offset_;
-  DCHECK(!(object_offset & kAllocationMask));
-  const size_t object_start_number = object_offset / kAllocationGranularity;
-  *cell_index = object_start_number / kCellSize;
-#if DCHECK_IS_ON()
-  const size_t bitmap_size = kBitmapSize;
-  DCHECK_LT(*cell_index, bitmap_size);
-#endif
-  *bit = object_start_number & kCellMask;
-}
-
-template <typename Callback>
-inline void ObjectStartBitmap::Iterate(Callback callback) const {
-  for (size_t cell_index = 0; cell_index < kReservedForBitmap; cell_index++) {
-    uint8_t value = load(cell_index);
-    while (value) {
-      const int trailing_zeroes = base::bits::CountTrailingZeroBits(value);
-      const size_t object_start_number =
-          (cell_index * kCellSize) + trailing_zeroes;
-      const Address object_address =
-          offset_ + (kAllocationGranularity * object_start_number);
-      callback(object_address);
-      // Clear current object bit in temporary value to advance iteration.
-      value &= ~(1 << (object_start_number & kCellMask));
-    }
-  }
-}
-
-template <HeapObjectHeader::AccessMode mode>
-Address ObjectStartBitmap::FindHeader(
-    ConstAddress address_maybe_pointing_to_the_middle_of_object) const {
-  size_t object_offset =
-      address_maybe_pointing_to_the_middle_of_object - offset_;
-  size_t object_start_number = object_offset / kAllocationGranularity;
-  size_t cell_index = object_start_number / kCellSize;
-#if DCHECK_IS_ON()
-  const size_t bitmap_size = kReservedForBitmap;
-  DCHECK_LT(cell_index, bitmap_size);
-#endif
-  size_t bit = object_start_number & kCellMask;
-  uint8_t byte = load<mode>(cell_index) & ((1 << (bit + 1)) - 1);
-  while (!byte) {
-    DCHECK_LT(0u, cell_index);
-    byte = load<mode>(--cell_index);
-  }
-  int leading_zeroes = base::bits::CountLeadingZeroBits(byte);
-  object_start_number =
-      (cell_index * kCellSize) + (kCellSize - 1) - leading_zeroes;
-  object_offset = object_start_number * kAllocationGranularity;
-  return object_offset + offset_;
-}
-
-NO_SANITIZE_ADDRESS inline HeapObjectHeader::HeapObjectHeader(
-    size_t size,
-    size_t gc_info_index) {
-  // sizeof(HeapObjectHeader) must be equal to or smaller than
-  // |kAllocationGranularity|, because |HeapObjectHeader| is used as a header
-  // for a freed entry. Given that the smallest entry size is
-  // |kAllocationGranurarity|, |HeapObjectHeader| must fit into the size.
-  static_assert(
-      sizeof(HeapObjectHeader) <= kAllocationGranularity,
-      "size of HeapObjectHeader must be smaller than kAllocationGranularity");
-
-  DCHECK_LT(gc_info_index, GCInfoTable::kMaxIndex);
-  DCHECK_LT(size, kNonLargeObjectPageSizeMax);
-  DCHECK_EQ(0u, size & kAllocationMask);
-  // Relaxed memory order is enough as in construction is created/synchronized
-  // as follows:
-  // - Page allocator gets zeroed page and uses page initialization fence.
-  // - Sweeper zeroes memory and synchronizes via global lock.
-  internal::AsUnsanitizedAtomic(&encoded_high_)
-      ->store(static_cast<uint16_t>(gc_info_index << kHeaderGCInfoIndexShift),
-              std::memory_order_relaxed);
-  encoded_low_ = internal::EncodeSize(size);
-  DCHECK(IsInConstruction());
-}
-
-template <HeapObjectHeader::AccessMode mode,
-          HeapObjectHeader::EncodedHalf part,
-          std::memory_order memory_order>
-NO_SANITIZE_ADDRESS inline uint16_t HeapObjectHeader::LoadEncoded() const {
-  const uint16_t& half =
-      part == EncodedHalf::kLow ? encoded_low_ : encoded_high_;
-  if (mode == AccessMode::kNonAtomic)
-    return half;
-  return internal::AsUnsanitizedAtomic(&half)->load(memory_order);
-}
-
-// Sets bits selected by the mask to the given value. Please note that atomicity
-// of the whole operation is not guaranteed.
-template <HeapObjectHeader::AccessMode mode,
-          HeapObjectHeader::EncodedHalf part,
-          std::memory_order memory_order>
-NO_SANITIZE_ADDRESS inline void HeapObjectHeader::StoreEncoded(uint16_t bits,
-                                                               uint16_t mask) {
-  DCHECK_EQ(static_cast<uint16_t>(0u), bits & ~mask);
-  uint16_t& half = part == EncodedHalf::kLow ? encoded_low_ : encoded_high_;
-  if (mode == AccessMode::kNonAtomic) {
-    half = (half & ~mask) | bits;
-    return;
-  }
-  // We don't perform CAS loop here assuming that the data is constant and no
-  // one except for us can change this half concurrently.
-  auto* atomic_encoded = internal::AsUnsanitizedAtomic(&half);
-  uint16_t value = atomic_encoded->load(std::memory_order_relaxed);
-  value = (value & ~mask) | bits;
-  atomic_encoded->store(value, memory_order);
-}
-
-template <HeapObjectHeader::AccessMode mode>
-HeapObjectHeader* NormalPage::FindHeaderFromAddress(
-    ConstAddress address) const {
-  DCHECK(ContainedInObjectPayload(address));
-  HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
-      object_start_bit_map()->FindHeader<mode>(address));
-  DCHECK_LT(0u, header->GcInfoIndex<mode>());
-  DCHECK_GT(header->PayloadEnd<HeapObjectHeader::AccessMode::kAtomic>(),
-            address);
-  return header;
-}
-
-template <typename Function>
-void NormalPage::IterateCardTable(Function function) const {
-  // TODO(bikineev): Consider introducing a "dirty" per-page bit to avoid
-  // the loop (this may in turn pessimize barrier implementation).
-  for (auto card : card_table_) {
-    if (UNLIKELY(card.bit)) {
-      IterateOnCard(function, card.index);
-    }
-  }
-}
-
-// Iterates over all objects in the specified marked card. Please note that
-// since objects are not aligned by the card boundary, it starts from the
-// object which may reside on a previous card.
-template <typename Function>
-void NormalPage::IterateOnCard(Function function, size_t card_number) const {
-#if DCHECK_IS_ON()
-  DCHECK(card_table_.IsMarked(card_number));
-  DCHECK(ArenaForNormalPage()->IsConsistentForGC());
-#endif
-
-  const Address card_begin = RoundToBlinkPageStart(GetAddress()) +
-                             (card_number << CardTable::kBitsPerCard);
-  const Address card_end = card_begin + CardTable::kCardSize;
-  // Generational barrier marks cards corresponding to slots (not source
-  // objects), therefore the potential source object may reside on a
-  // previous card.
-  HeapObjectHeader* header = reinterpret_cast<HeapObjectHeader*>(
-      card_number == card_table_.begin().index
-          ? Payload()
-          : object_start_bit_map_.FindHeader(card_begin));
-  for (; header < reinterpret_cast<HeapObjectHeader*>(card_end);
-       reinterpret_cast<Address&>(header) += header->size()) {
-    if (!header->IsFree()) {
-      function(header);
-    }
-  }
-}
-
-inline void NormalPage::MarkCard(Address address) {
-#if DCHECK_IS_ON()
-  DCHECK(Contains(address));
-#endif
-  const size_t byte = reinterpret_cast<size_t>(address) & kBlinkPageOffsetMask;
-  const size_t card = byte / CardTable::kCardSize;
-  card_table_.Mark(card);
-}
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_PAGE_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.cc b/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.cc
deleted file mode 100644
index bb4180f..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-
-#include <cmath>
-
-#include "base/check_op.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
-
-namespace blink {
-
-void ThreadHeapStatsCollector::IncreaseCompactionFreedSize(size_t bytes) {
-  DCHECK(is_started_);
-  current_.compaction_freed_bytes += bytes;
-  current_.compaction_recorded_events = true;
-}
-
-void ThreadHeapStatsCollector::IncreaseCompactionFreedPages(size_t pages) {
-  DCHECK(is_started_);
-  current_.compaction_freed_pages += pages;
-  current_.compaction_recorded_events = true;
-}
-
-void ThreadHeapStatsCollector::IncreaseAllocatedObjectSize(size_t bytes) {
-  // The current GC may not have been started. This is ok as recording considers
-  // the whole time range between garbage collections.
-  pos_delta_allocated_bytes_since_prev_gc_ += bytes;
-}
-
-void ThreadHeapStatsCollector::IncreaseAllocatedObjectSizeForTesting(
-    size_t bytes) {
-  IncreaseAllocatedObjectSize(bytes);
-  AllocatedObjectSizeSafepointImpl();
-}
-
-void ThreadHeapStatsCollector::DecreaseAllocatedObjectSize(size_t bytes) {
-  // See IncreaseAllocatedObjectSize.
-  neg_delta_allocated_bytes_since_prev_gc_ += bytes;
-}
-
-void ThreadHeapStatsCollector::DecreaseAllocatedObjectSizeForTesting(
-    size_t bytes) {
-  DecreaseAllocatedObjectSize(bytes);
-  AllocatedObjectSizeSafepointImpl();
-}
-
-void ThreadHeapStatsCollector::AllocatedObjectSizeSafepoint() {
-  if (std::abs(pos_delta_allocated_bytes_since_prev_gc_ -
-               neg_delta_allocated_bytes_since_prev_gc_) > kUpdateThreshold) {
-    AllocatedObjectSizeSafepointImpl();
-  }
-}
-
-void ThreadHeapStatsCollector::AllocatedObjectSizeSafepointImpl() {
-  allocated_bytes_since_prev_gc_ +=
-      static_cast<int64_t>(pos_delta_allocated_bytes_since_prev_gc_) -
-      static_cast<int64_t>(neg_delta_allocated_bytes_since_prev_gc_);
-
-  // These observer methods may start or finalize GC. In case they trigger a
-  // final GC pause, the delta counters are reset there and the following
-  // observer calls are called with '0' updates.
-  ForAllObservers([this](ThreadHeapStatsObserver* observer) {
-    // Recompute delta here so that a GC finalization is able to clear the
-    // delta for other observer calls.
-    int64_t delta = pos_delta_allocated_bytes_since_prev_gc_ -
-                    neg_delta_allocated_bytes_since_prev_gc_;
-    if (delta < 0) {
-      observer->DecreaseAllocatedObjectSize(static_cast<size_t>(-delta));
-    } else {
-      observer->IncreaseAllocatedObjectSize(static_cast<size_t>(delta));
-    }
-  });
-  pos_delta_allocated_bytes_since_prev_gc_ = 0;
-  neg_delta_allocated_bytes_since_prev_gc_ = 0;
-}
-
-void ThreadHeapStatsCollector::IncreaseAllocatedSpace(size_t bytes) {
-  allocated_space_bytes_ += bytes;
-  ForAllObservers([bytes](ThreadHeapStatsObserver* observer) {
-    observer->IncreaseAllocatedSpace(bytes);
-  });
-}
-
-void ThreadHeapStatsCollector::DecreaseAllocatedSpace(size_t bytes) {
-  allocated_space_bytes_ -= bytes;
-  ForAllObservers([bytes](ThreadHeapStatsObserver* observer) {
-    observer->DecreaseAllocatedSpace(bytes);
-  });
-}
-
-ThreadHeapStatsCollector::Event::Event() {
-  static std::atomic<size_t> counter{0};
-  unique_id = counter.fetch_add(1);
-}
-
-void ThreadHeapStatsCollector::NotifyMarkingStarted(
-    BlinkGC::CollectionType collection_type,
-    BlinkGC::GCReason reason,
-    bool is_forced_gc) {
-  DCHECK(!is_started_);
-  DCHECK(current_.marking_time().is_zero());
-  is_started_ = true;
-  current_.reason = reason;
-  current_.collection_type = collection_type;
-  current_.is_forced_gc = is_forced_gc;
-}
-
-void ThreadHeapStatsCollector::NotifyMarkingCompleted(size_t marked_bytes) {
-  allocated_bytes_since_prev_gc_ +=
-      static_cast<int64_t>(pos_delta_allocated_bytes_since_prev_gc_) -
-      static_cast<int64_t>(neg_delta_allocated_bytes_since_prev_gc_);
-  current_.marked_bytes = marked_bytes;
-  current_.object_size_in_bytes_before_sweeping = object_size_in_bytes();
-  current_.allocated_space_in_bytes_before_sweeping = allocated_space_bytes();
-  current_.partition_alloc_bytes_before_sweeping =
-      WTF::Partitions::TotalSizeOfCommittedPages();
-  allocated_bytes_since_prev_gc_ = 0;
-  pos_delta_allocated_bytes_since_prev_gc_ = 0;
-  neg_delta_allocated_bytes_since_prev_gc_ = 0;
-
-  ForAllObservers([marked_bytes](ThreadHeapStatsObserver* observer) {
-    observer->ResetAllocatedObjectSize(marked_bytes);
-  });
-
-  is_sweeping_ = true;
-}
-
-void ThreadHeapStatsCollector::NotifySweepingCompleted() {
-  is_started_ = false;
-  current_.live_object_rate =
-      current_.object_size_in_bytes_before_sweeping
-          ? static_cast<double>(current().marked_bytes) /
-                current_.object_size_in_bytes_before_sweeping
-          : 0.0;
-  current_.gc_nested_in_v8 = gc_nested_in_v8_;
-  gc_nested_in_v8_ = base::TimeDelta();
-  // Reset the current state.
-  static_assert(std::is_trivially_copyable<Event>::value,
-                "Event should be trivially copyable");
-  previous_ = std::move(current_);
-  current_ = Event();
-  is_sweeping_ = false;
-}
-
-void ThreadHeapStatsCollector::UpdateReason(BlinkGC::GCReason reason) {
-  current_.reason = reason;
-}
-
-size_t ThreadHeapStatsCollector::object_size_in_bytes() const {
-  const Event& event = is_sweeping_ ? current_ : previous_;
-  DCHECK_GE(
-      static_cast<int64_t>(event.marked_bytes) + allocated_bytes_since_prev_gc_,
-      0);
-  return static_cast<size_t>(static_cast<int64_t>(event.marked_bytes) +
-                             allocated_bytes_since_prev_gc_);
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::roots_marking_time() const {
-  return scope_data[kVisitRoots];
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::incremental_marking_time()
-    const {
-  return scope_data[kIncrementalMarkingStartMarking] +
-         scope_data[kIncrementalMarkingStep] + scope_data[kUnifiedMarkingStep];
-}
-
-base::TimeDelta
-ThreadHeapStatsCollector::Event::worklist_processing_time_foreground() const {
-  return scope_data[kMarkProcessWorklists];
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::flushing_v8_references_time()
-    const {
-  return scope_data[kMarkFlushV8References];
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::atomic_marking_time() const {
-  return scope_data[kAtomicPauseMarkPrologue] +
-         scope_data[kAtomicPauseMarkRoots] +
-         scope_data[kAtomicPauseMarkTransitiveClosure] +
-         scope_data[kAtomicPauseMarkEpilogue];
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::atomic_sweep_and_compact_time()
-    const {
-  return scope_data[ThreadHeapStatsCollector::kAtomicPauseSweepAndCompact];
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::foreground_marking_time()
-    const {
-  return incremental_marking_time() + atomic_marking_time();
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::background_marking_time()
-    const {
-  return base::TimeDelta::FromMicroseconds(base::subtle::NoBarrier_Load(
-      &concurrent_scope_data[kConcurrentMarkingStep]));
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::marking_time() const {
-  return foreground_marking_time() + background_marking_time();
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::gc_cycle_time() const {
-  // Note that scopes added here also have to have a proper BlinkGCInV8Scope
-  // scope if they are nested in a V8 scope.
-  return incremental_marking_time() + atomic_marking_time() +
-         atomic_sweep_and_compact_time() + foreground_sweeping_time();
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::atomic_pause_time() const {
-  return atomic_marking_time() + atomic_sweep_and_compact_time();
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::foreground_sweeping_time()
-    const {
-  return scope_data[kCompleteSweep] + scope_data[kLazySweepInIdle] +
-         scope_data[kLazySweepOnAllocation];
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::background_sweeping_time()
-    const {
-  return base::TimeDelta::FromMicroseconds(
-      concurrent_scope_data[kConcurrentSweepingStep]);
-}
-
-base::TimeDelta ThreadHeapStatsCollector::Event::sweeping_time() const {
-  return foreground_sweeping_time() + background_sweeping_time();
-}
-
-int64_t ThreadHeapStatsCollector::allocated_bytes_since_prev_gc() const {
-  return allocated_bytes_since_prev_gc_;
-}
-
-size_t ThreadHeapStatsCollector::marked_bytes() const {
-  return current_.marked_bytes;
-}
-
-base::TimeDelta ThreadHeapStatsCollector::marking_time_so_far() const {
-  return current_.marking_time();
-}
-
-base::TimeDelta ThreadHeapStatsCollector::worklist_processing_time_foreground()
-    const {
-  return current_.worklist_processing_time_foreground();
-}
-
-base::TimeDelta ThreadHeapStatsCollector::flushing_v8_references_time() const {
-  return current_.flushing_v8_references_time();
-}
-
-size_t ThreadHeapStatsCollector::allocated_space_bytes() const {
-  return allocated_space_bytes_;
-}
-
-void ThreadHeapStatsCollector::RegisterObserver(
-    ThreadHeapStatsObserver* observer) {
-  DCHECK(!observers_.Contains(observer));
-  observers_.push_back(observer);
-}
-
-void ThreadHeapStatsCollector::UnregisterObserver(
-    ThreadHeapStatsObserver* observer) {
-  wtf_size_t index = observers_.Find(observer);
-  DCHECK_NE(WTF::kNotFound, index);
-  observers_.EraseAt(index);
-}
-
-template <typename Callback>
-void ThreadHeapStatsCollector::ForAllObservers(Callback callback) {
-  for (ThreadHeapStatsObserver* observer : observers_) {
-    callback(observer);
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h b/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h
deleted file mode 100644
index b252157..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_stats_collector.h
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_STATS_COLLECTOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_STATS_COLLECTOR_H_
-
-#include <stddef.h>
-
-#include "base/atomicops.h"
-#include "base/gtest_prod_util.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-// Interface for observing changes to heap sizing.
-class PLATFORM_EXPORT ThreadHeapStatsObserver {
- public:
-  // Called upon allocating/releasing chunks of memory that contain objects.
-  //
-  // Must not trigger GC or allocate.
-  virtual void IncreaseAllocatedSpace(size_t) = 0;
-  virtual void DecreaseAllocatedSpace(size_t) = 0;
-
-  // Called once per GC cycle with the accurate number of live |bytes|.
-  //
-  // Must not trigger GC or allocate.
-  virtual void ResetAllocatedObjectSize(size_t bytes) = 0;
-
-  // Called after observing at least
-  // |ThreadHeapStatsCollector::kUpdateThreshold| changed bytes through
-  // allocation or explicit free. Reports both, negative and positive
-  // increments, to allow observer to decide whether absolute values or only the
-  // deltas is interesting.
-  //
-  // May trigger GC but most not allocate.
-  virtual void IncreaseAllocatedObjectSize(size_t) = 0;
-  virtual void DecreaseAllocatedObjectSize(size_t) = 0;
-};
-
-#define FOR_ALL_SCOPES(V)                    \
-  V(AtomicPauseCompaction)                   \
-  V(AtomicPauseMarkEpilogue)                 \
-  V(AtomicPauseMarkPrologue)                 \
-  V(AtomicPauseMarkRoots)                    \
-  V(AtomicPauseMarkTransitiveClosure)        \
-  V(AtomicPauseSweepAndCompact)              \
-  V(CompleteSweep)                           \
-  V(IncrementalMarkingFinalize)              \
-  V(IncrementalMarkingStartMarking)          \
-  V(IncrementalMarkingStep)                  \
-  V(IncrementalMarkingWithDeadline)          \
-  V(InvokePreFinalizers)                     \
-  V(LazySweepInIdle)                         \
-  V(LazySweepOnAllocation)                   \
-  V(MarkBailOutObjects)                      \
-  V(MarkInvokeEphemeronCallbacks)            \
-  V(MarkFlushV8References)                   \
-  V(MarkFlushEphemeronPairs)                 \
-  V(MarkProcessWorklists)                    \
-  V(MarkProcessMarkingWorklist)              \
-  V(MarkProcessWriteBarrierWorklist)         \
-  V(MarkProcessNotFullyconstructeddWorklist) \
-  V(MarkNotFullyConstructedObjects)          \
-  V(MarkWeakProcessing)                      \
-  V(UnifiedMarkingStep)                      \
-  V(VisitCrossThreadPersistents)             \
-  V(VisitPersistentRoots)                    \
-  V(VisitPersistents)                        \
-  V(VisitRoots)                              \
-  V(VisitStackRoots)                         \
-  V(VisitRememberedSets)
-
-#define FOR_ALL_CONCURRENT_SCOPES(V)        \
-  V(ConcurrentMarkInvokeEphemeronCallbacks) \
-  V(ConcurrentMarkingStep)                  \
-  V(ConcurrentSweepingStep)
-
-// Manages counters and statistics across garbage collection cycles.
-//
-// Usage:
-//   ThreadHeapStatsCollector stats_collector;
-//   stats_collector.NotifyMarkingStarted(<BlinkGC::CollectionType>,
-//                                        <BlinkGC::GCReason>);
-//   // Use tracer.
-//   stats_collector.NotifySweepingCompleted();
-//   // Previous event is available using stats_collector.previous().
-class PLATFORM_EXPORT ThreadHeapStatsCollector {
-  USING_FAST_MALLOC(ThreadHeapStatsCollector);
-
- public:
-  // These ids will form human readable names when used in Scopes.
-  enum Id {
-#define DECLARE_ENUM(name) k##name,
-    FOR_ALL_SCOPES(DECLARE_ENUM)
-#undef DECLARE_ENUM
-        kNumScopeIds,
-  };
-
-  enum ConcurrentId {
-#define DECLARE_ENUM(name) k##name,
-    FOR_ALL_CONCURRENT_SCOPES(DECLARE_ENUM)
-#undef DECLARE_ENUM
-        kNumConcurrentScopeIds
-  };
-
-  constexpr static const char* ToString(Id id, BlinkGC::CollectionType type) {
-    switch (id) {
-#define CASE(name)                                                    \
-  case k##name:                                                       \
-    return type == BlinkGC::CollectionType::kMajor ? "BlinkGC." #name \
-                                                   : "BlinkGC." #name \
-                                                     ".Minor";
-      FOR_ALL_SCOPES(CASE)
-#undef CASE
-      default:
-        NOTREACHED();
-    }
-    return nullptr;
-  }
-
-  constexpr static const char* ToString(ConcurrentId id,
-                                        BlinkGC::CollectionType type) {
-    switch (id) {
-#define CASE(name)                                                    \
-  case k##name:                                                       \
-    return type == BlinkGC::CollectionType::kMajor ? "BlinkGC." #name \
-                                                   : "BlinkGC." #name \
-                                                     ".Minor";
-      FOR_ALL_CONCURRENT_SCOPES(CASE)
-#undef CASE
-      default:
-        NOTREACHED();
-    }
-    return nullptr;
-  }
-
-  enum TraceCategory { kEnabled, kDisabled };
-  enum ScopeContext { kMutatorThread, kConcurrentThread };
-
-  // Trace a particular scope. Will emit a trace event and record the time in
-  // the corresponding ThreadHeapStatsCollector.
-  template <TraceCategory trace_category = kDisabled,
-            ScopeContext scope_category = kMutatorThread>
-  class PLATFORM_EXPORT InternalScope {
-    DISALLOW_NEW();
-
-    using IdType =
-        std::conditional_t<scope_category == kMutatorThread, Id, ConcurrentId>;
-
-   public:
-    template <typename... Args>
-    InternalScope(ThreadHeapStatsCollector* tracer, IdType id, Args... args)
-        : tracer_(tracer), start_time_(base::TimeTicks::Now()), id_(id) {
-      StartTrace(args...);
-    }
-    InternalScope(const InternalScope&) = delete;
-    InternalScope& operator=(const InternalScope&) = delete;
-
-    ~InternalScope() {
-      StopTrace();
-      IncreaseScopeTime(id_);
-    }
-
-   private:
-    inline constexpr static const char* TraceCategory();
-
-    inline void StartTrace();
-    template <typename Value1>
-    inline void StartTrace(const char* k1, Value1 v1);
-    template <typename Value1, typename Value2>
-    inline void StartTrace(const char* k1,
-                           Value1 v1,
-                           const char* k2,
-                           Value2 v2);
-    inline void StopTrace();
-
-    inline void IncreaseScopeTime(Id);
-    inline void IncreaseScopeTime(ConcurrentId);
-
-    ThreadHeapStatsCollector* const tracer_;
-    const base::TimeTicks start_time_;
-    const IdType id_;
-  };
-
-  using Scope = InternalScope<kDisabled>;
-  using EnabledScope = InternalScope<kEnabled>;
-  using ConcurrentScope = InternalScope<kDisabled, kConcurrentThread>;
-  using EnabledConcurrentScope = InternalScope<kEnabled, kConcurrentThread>;
-
-  // BlinkGCInV8Scope keeps track of time spent in Blink's GC when called by V8.
-  // This is necessary to avoid double-accounting of Blink's time when computing
-  // the overall time (V8 + Blink) spent in GC on the main thread.
-  class PLATFORM_EXPORT BlinkGCInV8Scope {
-    DISALLOW_NEW();
-
-   public:
-    template <typename... Args>
-    BlinkGCInV8Scope(ThreadHeapStatsCollector* tracer)
-        : tracer_(tracer), start_time_(base::TimeTicks::Now()) {}
-    BlinkGCInV8Scope(const BlinkGCInV8Scope&) = delete;
-    BlinkGCInV8Scope& operator=(const BlinkGCInV8Scope&) = delete;
-
-    ~BlinkGCInV8Scope() {
-      if (tracer_)
-        tracer_->gc_nested_in_v8_ += base::TimeTicks::Now() - start_time_;
-    }
-
-   private:
-    ThreadHeapStatsCollector* const tracer_;
-    const base::TimeTicks start_time_;
-  };
-
-  // POD to hold interesting data accumulated during a garbage collection cycle.
-  // The event is always fully populated when looking at previous events but
-  // is only be partially populated when looking at the current event. See
-  // members on when they are available.
-  //
-  // Note that all getters include time for stand-alone as well as unified heap
-  // GCs. E.g., |atomic_marking_time()| report the marking time of the atomic
-  // phase, independent of whether the GC was a stand-alone or unified heap GC.
-  struct PLATFORM_EXPORT Event {
-    Event();
-
-    // Overall time spent in the GC cycle. This includes marking time as well as
-    // sweeping time.
-    base::TimeDelta gc_cycle_time() const;
-
-    // Time spent in the final atomic pause of a GC cycle.
-    base::TimeDelta atomic_pause_time() const;
-
-    // Time spent in the final atomic pause for marking the heap.
-    base::TimeDelta atomic_marking_time() const;
-
-    // Time spent in the final atomic pause in sweeping and compacting the heap.
-    base::TimeDelta atomic_sweep_and_compact_time() const;
-
-    // Time spent marking the roots.
-    base::TimeDelta roots_marking_time() const;
-
-    // Time spent incrementally marking the heap.
-    base::TimeDelta incremental_marking_time() const;
-
-    // Time spent processing worklist in the foreground thread.
-    base::TimeDelta worklist_processing_time_foreground() const;
-
-    // Time spent flushing v8 references (this is done only in the foreground)
-    base::TimeDelta flushing_v8_references_time() const;
-
-    // Time spent in foreground tasks marking the heap.
-    base::TimeDelta foreground_marking_time() const;
-
-    // Time spent in background tasks marking the heap.
-    base::TimeDelta background_marking_time() const;
-
-    // Overall time spent marking the heap.
-    base::TimeDelta marking_time() const;
-
-    // Time spent in foreground tasks sweeping the heap.
-    base::TimeDelta foreground_sweeping_time() const;
-
-    // Time spent in background tasks sweeping the heap.
-    base::TimeDelta background_sweeping_time() const;
-
-    // Overall time spent sweeping the heap.
-    base::TimeDelta sweeping_time() const;
-
-    // Marked bytes collected during sweeping.
-    size_t unique_id = -1;
-    size_t marked_bytes = 0;
-    size_t compaction_freed_bytes = 0;
-    size_t compaction_freed_pages = 0;
-    bool compaction_recorded_events = false;
-    base::TimeDelta scope_data[kNumScopeIds];
-    base::subtle::Atomic32 concurrent_scope_data[kNumConcurrentScopeIds]{0};
-    BlinkGC::GCReason reason = static_cast<BlinkGC::GCReason>(0);
-    BlinkGC::CollectionType collection_type = BlinkGC::CollectionType::kMajor;
-    size_t object_size_in_bytes_before_sweeping = 0;
-    size_t allocated_space_in_bytes_before_sweeping = 0;
-    size_t partition_alloc_bytes_before_sweeping = 0;
-    double live_object_rate = 0;
-    base::TimeDelta gc_nested_in_v8;
-    bool is_forced_gc = true;
-  };
-
-  // Indicates a new garbage collection cycle.
-  void NotifyMarkingStarted(BlinkGC::CollectionType,
-                            BlinkGC::GCReason,
-                            bool is_forced_gc);
-
-  // Indicates that marking of the current garbage collection cycle is
-  // completed.
-  void NotifyMarkingCompleted(size_t marked_bytes);
-
-  // Indicates the end of a garbage collection cycle. This means that sweeping
-  // is finished at this point.
-  void NotifySweepingCompleted();
-
-  void IncreaseScopeTime(Id id, base::TimeDelta time) {
-    DCHECK(is_started_);
-    current_.scope_data[id] += time;
-  }
-
-  void IncreaseConcurrentScopeTime(ConcurrentId id, base::TimeDelta time) {
-    using Atomic32 = base::subtle::Atomic32;
-    DCHECK(is_started_);
-    const int64_t ms = time.InMicroseconds();
-    DCHECK(ms <= std::numeric_limits<Atomic32>::max());
-    base::subtle::NoBarrier_AtomicIncrement(&current_.concurrent_scope_data[id],
-                                            static_cast<Atomic32>(ms));
-  }
-
-  void UpdateReason(BlinkGC::GCReason);
-  void IncreaseCompactionFreedSize(size_t);
-  void IncreaseCompactionFreedPages(size_t);
-  void IncreaseAllocatedObjectSize(size_t);
-  void DecreaseAllocatedObjectSize(size_t);
-  void IncreaseAllocatedSpace(size_t);
-  void DecreaseAllocatedSpace(size_t);
-  void IncreaseWrapperCount(size_t);
-  void DecreaseWrapperCount(size_t);
-  void IncreaseCollectedWrapperCount(size_t);
-
-  // Called by the GC when it hits a point where allocated memory may be
-  // reported and garbage collection is possible. This is necessary, as
-  // increments and decrements are reported as close to their actual
-  // allocation/reclamation as possible.
-  void AllocatedObjectSizeSafepoint();
-
-  // Size of objects on the heap. Based on marked bytes in the previous cycle
-  // and newly allocated bytes since the previous cycle.
-  size_t object_size_in_bytes() const;
-
-  size_t marked_bytes() const;
-  base::TimeDelta marking_time_so_far() const;
-
-  base::TimeDelta worklist_processing_time_foreground() const;
-
-  base::TimeDelta flushing_v8_references_time() const;
-
-  int64_t allocated_bytes_since_prev_gc() const;
-
-  size_t allocated_space_bytes() const;
-
-  size_t wrapper_count() const;
-  size_t collected_wrapper_count() const;
-
-  bool is_started() const { return is_started_; }
-
-  // Statistics for the previously running garbage collection.
-  const Event& previous() const { return previous_; }
-
-  void RegisterObserver(ThreadHeapStatsObserver* observer);
-  void UnregisterObserver(ThreadHeapStatsObserver* observer);
-
-  void IncreaseAllocatedObjectSizeForTesting(size_t);
-  void DecreaseAllocatedObjectSizeForTesting(size_t);
-
- private:
-  // Observers are implemented using virtual calls. Avoid notifications below
-  // reasonably interesting sizes.
-  static constexpr int64_t kUpdateThreshold = 1024;
-
-  // Invokes |callback| for all registered observers.
-  template <typename Callback>
-  void ForAllObservers(Callback callback);
-
-  void AllocatedObjectSizeSafepointImpl();
-
-  // Statistics for the currently running garbage collection. Note that the
-  // Event may not be fully populated yet as some phase may not have been run.
-  const Event& current() const { return current_; }
-
-  Event current_;
-  Event previous_;
-
-  // Allocated bytes since the last garbage collection. These bytes are reset
-  // after marking as they are accounted in marked_bytes then.
-  int64_t allocated_bytes_since_prev_gc_ = 0;
-  int64_t pos_delta_allocated_bytes_since_prev_gc_ = 0;
-  int64_t neg_delta_allocated_bytes_since_prev_gc_ = 0;
-
-  // Allocated space in bytes for all arenas.
-  size_t allocated_space_bytes_ = 0;
-
-  bool is_started_ = false;
-  bool is_sweeping_ = false;
-
-  // base::TimeDelta for RawScope. These don't need to be nested within a
-  // garbage collection cycle to make them easier to use.
-  base::TimeDelta gc_nested_in_v8_;
-
-  Vector<ThreadHeapStatsObserver*> observers_;
-
-  FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, InitialEmpty);
-  FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, IncreaseScopeTime);
-  FRIEND_TEST_ALL_PREFIXES(ThreadHeapStatsCollectorTest, StopResetsCurrent);
-};
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
-          ThreadHeapStatsCollector::ScopeContext scope_category>
-constexpr const char*
-ThreadHeapStatsCollector::InternalScope<trace_category,
-                                        scope_category>::TraceCategory() {
-  switch (trace_category) {
-    case kEnabled:
-      return "blink_gc,devtools.timeline";
-    case kDisabled:
-      return TRACE_DISABLED_BY_DEFAULT("blink_gc");
-  }
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
-          ThreadHeapStatsCollector::ScopeContext scope_category>
-void ThreadHeapStatsCollector::InternalScope<trace_category,
-                                             scope_category>::StartTrace() {
-  TRACE_EVENT_BEGIN0(TraceCategory(),
-                     ToString(id_, tracer_->current_.collection_type));
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
-          ThreadHeapStatsCollector::ScopeContext scope_category>
-template <typename Value1>
-void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
-    StartTrace(const char* k1, Value1 v1) {
-  TRACE_EVENT_BEGIN1(TraceCategory(),
-                     ToString(id_, tracer_->current_.collection_type), k1, v1);
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
-          ThreadHeapStatsCollector::ScopeContext scope_category>
-template <typename Value1, typename Value2>
-void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
-    StartTrace(const char* k1, Value1 v1, const char* k2, Value2 v2) {
-  TRACE_EVENT_BEGIN2(TraceCategory(),
-                     ToString(id_, tracer_->current_.collection_type), k1, v1,
-                     k2, v2);
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
-          ThreadHeapStatsCollector::ScopeContext scope_category>
-void ThreadHeapStatsCollector::InternalScope<trace_category,
-                                             scope_category>::StopTrace() {
-  TRACE_EVENT_END2(TraceCategory(),
-                   ToString(id_, tracer_->current_.collection_type), "epoch",
-                   tracer_->current_.unique_id, "forced",
-                   tracer_->current_.is_forced_gc);
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
-          ThreadHeapStatsCollector::ScopeContext scope_category>
-void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
-    IncreaseScopeTime(Id) {
-  tracer_->IncreaseScopeTime(id_, base::TimeTicks::Now() - start_time_);
-}
-
-template <ThreadHeapStatsCollector::TraceCategory trace_category,
-          ThreadHeapStatsCollector::ScopeContext scope_category>
-void ThreadHeapStatsCollector::InternalScope<trace_category, scope_category>::
-    IncreaseScopeTime(ConcurrentId) {
-  tracer_->IncreaseConcurrentScopeTime(id_,
-                                       base::TimeTicks::Now() - start_time_);
-}
-
-#undef FOR_ALL_SCOPES
-#undef FOR_ALL_CONCURRENT_SCOPES
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_STATS_COLLECTOR_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.cc b/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.cc
deleted file mode 100644
index 3d487a099..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
-
-namespace blink {
-
-// static
-void TestSupportingGC::PreciselyCollectGarbage(
-    BlinkGC::SweepingType sweeping_type) {
-  ThreadState::Current()->CollectGarbageForTesting(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
-      BlinkGC::kAtomicMarking, sweeping_type,
-      BlinkGC::GCReason::kForcedGCForTesting);
-}
-
-// static
-void TestSupportingGC::ConservativelyCollectGarbage(
-    BlinkGC::SweepingType sweeping_type) {
-  ThreadState::Current()->CollectGarbageForTesting(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
-      BlinkGC::kAtomicMarking, sweeping_type,
-      BlinkGC::GCReason::kForcedGCForTesting);
-}
-
-TestSupportingGC::~TestSupportingGC() {
-  // Complete sweeping before |task_environment_| is destroyed.
-  if (ThreadState::Current()->IsSweepingInProgress())
-    ThreadState::Current()->CompleteSweep();
-}
-
-void TestSupportingGC::ClearOutOldGarbage() {
-  PreciselyCollectGarbage();
-  ThreadHeap& heap = ThreadState::Current()->Heap();
-  while (true) {
-    size_t used = heap.ObjectPayloadSizeForTesting();
-    PreciselyCollectGarbage();
-    if (heap.ObjectPayloadSizeForTesting() >= used)
-      break;
-  }
-}
-
-void CompactionTestDriver::ForceCompactionForNextGC() {
-  ThreadState::Current()->EnableCompactionForNextGCForTesting();
-}
-
-IncrementalMarkingTestDriver::~IncrementalMarkingTestDriver() {
-  if (thread_state_->IsIncrementalMarking())
-    FinishGC();
-}
-
-void IncrementalMarkingTestDriver::StartGC() {
-  thread_state_->IncrementalMarkingStartForTesting();
-}
-
-bool IncrementalMarkingTestDriver::TriggerSingleMarkingStep(
-    BlinkGC::StackState stack_state) {
-  CHECK(thread_state_->IsIncrementalMarking());
-  if (thread_state_->GetGCState() ==
-      ThreadState::kIncrementalMarkingStepScheduled) {
-    thread_state_->IncrementalMarkingStep(stack_state);
-    return true;
-  }
-  return false;
-}
-
-void IncrementalMarkingTestDriver::TriggerMarkingSteps(
-    BlinkGC::StackState stack_state) {
-  CHECK(thread_state_->IsIncrementalMarking());
-  while (TriggerSingleMarkingStep(stack_state)) {
-  }
-}
-
-void IncrementalMarkingTestDriver::FinishGC(bool complete_sweep) {
-  CHECK(thread_state_->IsIncrementalMarking());
-  IncrementalMarkingTestDriver::TriggerMarkingSteps(
-      BlinkGC::StackState::kNoHeapPointersOnStack);
-  CHECK_EQ(ThreadState::kIncrementalMarkingFinalizeScheduled,
-           thread_state_->GetGCState());
-  thread_state_->ForceNoFollowupFullGCForTesting();
-  thread_state_->IncrementalMarkingFinalize();
-  CHECK(!thread_state_->IsIncrementalMarking());
-  if (complete_sweep) {
-    thread_state_->CompleteSweep();
-  }
-}
-
-size_t IncrementalMarkingTestDriver::GetHeapCompactLastFixupCount() const {
-  HeapCompact* compaction = ThreadState::Current()->Heap().Compaction();
-  return compaction->LastFixupCountForTesting();
-}
-
-void ConcurrentMarkingTestDriver::TriggerMarkingSteps(
-    BlinkGC::StackState stack_state) {
-  if (thread_state_->GetGCState() ==
-      ThreadState::kIncrementalMarkingStepScheduled) {
-    thread_state_->SkipIncrementalMarkingForTesting();
-    TriggerSingleMarkingStep();
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.h b/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.h
deleted file mode 100644
index 3158d586..0000000
--- a/third_party/blink/renderer/platform/heap/impl/heap_test_utilities.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2017 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_TEST_UTILITIES_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_TEST_UTILITIES_H_
-
-#include "base/callback.h"
-#include "base/test/task_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-
-namespace blink {
-
-class HeapPointersOnStackScope final {
-  STACK_ALLOCATED();
-
- public:
-  explicit HeapPointersOnStackScope(ThreadState* state) : state_(state) {
-    DCHECK(!state_->heap_pointers_on_stack_forced_);
-    state_->heap_pointers_on_stack_forced_ = true;
-  }
-  ~HeapPointersOnStackScope() {
-    DCHECK(state_->heap_pointers_on_stack_forced_);
-    state_->heap_pointers_on_stack_forced_ = false;
-  }
-
- private:
-  ThreadState* const state_;
-};
-
-class TestSupportingGC : public testing::Test {
- public:
-  // Performs a precise garbage collection with eager sweeping.
-  static void PreciselyCollectGarbage(
-      BlinkGC::SweepingType sweeping_type = BlinkGC::kEagerSweeping);
-
-  // Performs a conservative garbage collection.
-  static void ConservativelyCollectGarbage(
-      BlinkGC::SweepingType sweeping_type = BlinkGC::kEagerSweeping);
-
-  ~TestSupportingGC() override;
-
-  // Performs multiple rounds of garbage collections until no more memory can be
-  // freed. This is useful to avoid other garbage collections having to deal
-  // with stale memory.
-  void ClearOutOldGarbage();
-
- protected:
-  base::test::TaskEnvironment task_environment_;
-};
-
-// Test driver for compaction.
-class CompactionTestDriver {
- public:
-  explicit CompactionTestDriver(ThreadState* thread_state)
-      : thread_state_(thread_state) {}
-
-  void ForceCompactionForNextGC();
-
- protected:
-  ThreadState* const thread_state_;
-};
-
-// Test driver for incremental marking. Assumes that no stack handling is
-// required.
-class IncrementalMarkingTestDriver {
- public:
-  explicit IncrementalMarkingTestDriver(ThreadState* thread_state)
-      : thread_state_(thread_state) {}
-  ~IncrementalMarkingTestDriver();
-
-  void StartGC();
-  virtual void TriggerMarkingSteps(
-      BlinkGC::StackState stack_state =
-          BlinkGC::StackState::kNoHeapPointersOnStack);
-  void FinishGC(bool complete_sweep = true);
-
-  size_t GetHeapCompactLastFixupCount() const;
-
- protected:
-  bool TriggerSingleMarkingStep(
-      BlinkGC::StackState stack_state =
-          BlinkGC::StackState::kNoHeapPointersOnStack);
-
-  ThreadState* const thread_state_;
-};
-
-// Test driver for concurrent marking. Assumes that no stack handling is
-// required.
-class ConcurrentMarkingTestDriver : public IncrementalMarkingTestDriver {
- public:
-  explicit ConcurrentMarkingTestDriver(ThreadState* thread_state)
-      : IncrementalMarkingTestDriver(thread_state) {}
-
-  void TriggerMarkingSteps(
-      BlinkGC::StackState stack_state =
-          BlinkGC::StackState::kNoHeapPointersOnStack) override;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_HEAP_TEST_UTILITIES_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.cc b/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.cc
deleted file mode 100644
index e75cd530..0000000
--- a/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h"
-
-#include "base/cxx17_backports.h"
-
-namespace blink {
-
-constexpr double MarkingSchedulingOracle::kEstimatedMarkingTimeMs;
-constexpr base::TimeDelta
-    MarkingSchedulingOracle::kDefaultIncrementalMarkingStepDuration;
-constexpr size_t MarkingSchedulingOracle::kMinimumMarkedBytesInStep;
-constexpr base::TimeDelta
-    MarkingSchedulingOracle::kMaximumIncrementalMarkingStepDuration;
-
-MarkingSchedulingOracle::MarkingSchedulingOracle()
-    : incremental_marking_start_time_(base::TimeTicks::Now()) {}
-
-void MarkingSchedulingOracle::UpdateIncrementalMarkingStats(
-    size_t overall_marked_bytes,
-    base::TimeDelta overall_marking_time,
-    base::TimeDelta non_contributing_time) {
-  incrementally_marked_bytes_ = overall_marked_bytes;
-  // |non_contributing_time| is time spent during |overall_marking_time| which
-  // does not contribute to |overall_marked_bytes| and is thus ignored so that
-  // it doesn't affect the marking speed.
-  DCHECK_LE(non_contributing_time, overall_marking_time);
-  incremental_marking_time_so_far_ =
-      overall_marking_time - non_contributing_time;
-}
-
-void MarkingSchedulingOracle::AddConcurrentlyMarkedBytes(size_t marked_bytes) {
-  concurrently_marked_bytes_.fetch_add(marked_bytes, std::memory_order_relaxed);
-}
-
-size_t MarkingSchedulingOracle::GetConcurrentlyMarkedBytes() {
-  return concurrently_marked_bytes_.load(std::memory_order_relaxed);
-}
-
-size_t MarkingSchedulingOracle::GetOverallMarkedBytes() {
-  return incrementally_marked_bytes_ + GetConcurrentlyMarkedBytes();
-}
-
-double MarkingSchedulingOracle::GetElapsedTimeInMs(base::TimeTicks start_time) {
-  if (elapsed_time_for_testing_ != kNoSetElapsedTimeForTesting) {
-    double elapsed_time = elapsed_time_for_testing_;
-    elapsed_time_for_testing_ = kNoSetElapsedTimeForTesting;
-    return elapsed_time;
-  }
-  return (base::TimeTicks::Now() - start_time).InMillisecondsF();
-}
-
-base::TimeDelta MarkingSchedulingOracle::GetMinimumStepDuration() {
-  DCHECK_LT(0u, incrementally_marked_bytes_);
-  DCHECK(!incremental_marking_time_so_far_.is_zero());
-  base::TimeDelta minimum_duration = incremental_marking_time_so_far_ *
-                                     kMinimumMarkedBytesInStep /
-                                     incrementally_marked_bytes_;
-  return std::min(minimum_duration, kMaximumIncrementalMarkingStepDuration);
-}
-
-base::TimeDelta MarkingSchedulingOracle::GetNextIncrementalStepDurationForTask(
-    size_t estimated_live_bytes) {
-  if ((incrementally_marked_bytes_ == 0) ||
-      incremental_marking_time_so_far_.is_zero()) {
-    // Impossible to estimate marking speed. Fallback to default duration.
-    return kDefaultIncrementalMarkingStepDuration;
-  }
-  double elapsed_time_in_ms =
-      GetElapsedTimeInMs(incremental_marking_start_time_);
-  size_t actual_marked_bytes = GetOverallMarkedBytes();
-  double expected_marked_bytes =
-      estimated_live_bytes * elapsed_time_in_ms / kEstimatedMarkingTimeMs;
-  base::TimeDelta minimum_duration = GetMinimumStepDuration();
-  if (expected_marked_bytes < actual_marked_bytes) {
-    // Marking is ahead of schedule, incremental marking doesn't need to
-    // do anything.
-    return minimum_duration;
-  }
-  // Assuming marking will take |kEstimatedMarkingTime|, overall there will
-  // be |estimated_live_bytes| live bytes to mark, and that marking speed is
-  // constant, after |elapsed_time| the number of marked_bytes should be
-  // |estimated_live_bytes| * (|elapsed_time| / |kEstimatedMarkingTime|),
-  // denoted as |expected_marked_bytes|.  If |actual_marked_bytes| is less,
-  // i.e. marking is behind schedule, incremental marking should help "catch
-  // up" by marking (|expected_marked_bytes| - |actual_marked_bytes|).
-  // Assuming constant marking speed, duration of the next incremental step
-  // should be as follows:
-  const base::TimeDelta marking_time_to_catch_up =
-      incremental_marking_time_so_far_ *
-      (expected_marked_bytes - actual_marked_bytes) /
-      incrementally_marked_bytes_;
-  return base::clamp(marking_time_to_catch_up, minimum_duration,
-                     kMaximumIncrementalMarkingStepDuration);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h b/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h
deleted file mode 100644
index 19c9e0b..0000000
--- a/third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_SCHEDULING_ORACLE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_SCHEDULING_ORACLE_H_
-
-#include <atomic>
-
-#include "base/time/time.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-
-namespace blink {
-
-class PLATFORM_EXPORT MarkingSchedulingOracle {
- public:
-  // Estimated duration of GC cycle in milliseconds.
-  static constexpr double kEstimatedMarkingTimeMs = 500.0;
-
-  // Duration of one incremental marking step. Should be short enough that it
-  // doesn't cause jank even though it is scheduled as a normal task.
-  static constexpr base::TimeDelta kDefaultIncrementalMarkingStepDuration =
-      base::TimeDelta::FromMillisecondsD(0.5);
-
-  // Minimum number of bytes that should be marked during an incremental
-  // marking step.
-  static constexpr size_t kMinimumMarkedBytesInStep = 64 * 1024;
-
-  // Maximum duration of one incremental marking step. Should be short enough
-  // that it doesn't cause jank even though it is scheduled as a normal task.
-  static constexpr base::TimeDelta kMaximumIncrementalMarkingStepDuration =
-      base::TimeDelta::FromMillisecondsD(2.0);
-
-  explicit MarkingSchedulingOracle();
-
-  void UpdateIncrementalMarkingStats(size_t, base::TimeDelta, base::TimeDelta);
-  void AddConcurrentlyMarkedBytes(size_t);
-
-  size_t GetConcurrentlyMarkedBytes();
-  size_t GetOverallMarkedBytes();
-
-  base::TimeDelta GetNextIncrementalStepDurationForTask(size_t);
-
-  void SetElapsedTimeForTesting(double elapsed_time) {
-    elapsed_time_for_testing_ = elapsed_time;
-  }
-
- private:
-  double GetElapsedTimeInMs(base::TimeTicks);
-  base::TimeDelta GetMinimumStepDuration();
-
-  base::TimeTicks incremental_marking_start_time_;
-  base::TimeDelta incremental_marking_time_so_far_;
-
-  size_t incrementally_marked_bytes_ = 0;
-  std::atomic_size_t concurrently_marked_bytes_{0};
-
-  // Using -1 as sentinel to denote
-  static constexpr double kNoSetElapsedTimeForTesting = -1;
-  double elapsed_time_for_testing_ = kNoSetElapsedTimeForTesting;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_SCHEDULING_ORACLE_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/marking_verifier.cc b/third_party/blink/renderer/platform/heap/impl/marking_verifier.cc
deleted file mode 100644
index bf9ee20..0000000
--- a/third_party/blink/renderer/platform/heap/impl/marking_verifier.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/marking_verifier.h"
-
-#include "base/logging.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-
-namespace blink {
-
-void MarkingVerifier::VerifyObject(HeapObjectHeader* header) {
-  // Verify only non-free marked objects.
-  if (header->IsFree() || !header->IsMarked())
-    return;
-
-  const GCInfo& info = GCInfo::From(header->GcInfoIndex());
-  const bool can_verify =
-      !info.has_v_table || blink::VTableInitialized(header->Payload());
-  if (can_verify) {
-    parent_ = header;
-    info.trace(this, header->Payload());
-  }
-}
-
-void MarkingVerifier::Visit(const void* object, TraceDescriptor desc) {
-  VerifyChild(object, desc.base_object_payload);
-}
-
-void MarkingVerifier::VisitWeak(const void* object,
-                                const void* object_weak_ref,
-                                TraceDescriptor desc,
-                                WeakCallback callback) {
-  // Weak objects should have been cleared at this point. As a consequence, all
-  // objects found through weak references have to point to live objects at this
-  // point.
-  VerifyChild(object, desc.base_object_payload);
-}
-
-void MarkingVerifier::VisitWeakContainer(const void* object,
-                                         const void* const*,
-                                         TraceDescriptor,
-                                         TraceDescriptor weak_desc,
-                                         WeakCallback,
-                                         const void*) {
-  if (!object)
-    return;
-
-  // Contents of weak backing stores are found themselves through page
-  // iteration and are treated strongly that way, similar to how they are
-  // treated strongly when found through stack scanning. The verification
-  // here only makes sure that the backing itself is properly marked. Weak
-  // backing stores found through
-  VerifyChild(object, weak_desc.base_object_payload);
-}
-
-void MarkingVerifier::VerifyChild(const void* object,
-                                  const void* base_object_payload) {
-  CHECK(object);
-  // Verification may check objects that are currently under construction and
-  // would require vtable access to figure out their headers. A nullptr in
-  // |base_object_payload| indicates that a mixin object is in construction
-  // and the vtable cannot be used to get to the object header.
-  const HeapObjectHeader* const child_header =
-      (base_object_payload) ? HeapObjectHeader::FromPayload(base_object_payload)
-                            : HeapObjectHeader::FromInnerAddress(object);
-  // These checks ensure that any children reachable from marked parents are
-  // also marked. If you hit these checks then marking is in an inconsistent
-  // state meaning that there are unmarked objects reachable from marked
-  // ones.
-  CHECK(child_header);
-  if (!child_header->IsMarked()) {
-    CHECK(!PageFromObject(child_header->Payload())->HasBeenSwept());
-    LOG(FATAL) << "MarkingVerifier: Encountered unmarked object. " << std::endl
-               << std::endl
-               << "Hint: " << std::endl
-               << parent_->Name() << std::endl
-               << "\\-> " << child_header->Name() << std::endl;
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/marking_verifier.h b/third_party/blink/renderer/platform/heap/impl/marking_verifier.h
deleted file mode 100644
index ee4266a..0000000
--- a/third_party/blink/renderer/platform/heap/impl/marking_verifier.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VERIFIER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VERIFIER_H_
-
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-
-namespace blink {
-
-class HeapObjectHeader;
-
-// Marking verifier that checks that a child is marked if its parent is marked.
-class MarkingVerifier final : public Visitor {
- public:
-  explicit MarkingVerifier(ThreadState* state) : Visitor(state) {}
-  ~MarkingVerifier() override = default;
-
-  void VerifyObject(HeapObjectHeader* header);
-
-  void Visit(const void* object, TraceDescriptor desc) final;
-  void VisitWeak(const void* object,
-                 const void* object_weak_ref,
-                 TraceDescriptor desc,
-                 WeakCallback callback) final;
-
-  void VisitWeakContainer(const void*,
-                          const void* const*,
-                          TraceDescriptor,
-                          TraceDescriptor,
-                          WeakCallback,
-                          const void*) final;
-
- private:
-  void VerifyChild(const void* object, const void* base_object_payload);
-
-  HeapObjectHeader* parent_ = nullptr;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VERIFIER_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/marking_visitor.cc b/third_party/blink/renderer/platform/heap/impl/marking_visitor.cc
deleted file mode 100644
index 91300b48..0000000
--- a/third_party/blink/renderer/platform/heap/impl/marking_visitor.cc
+++ /dev/null
@@ -1,370 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
-
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-
-namespace blink {
-
-MarkingVisitorBase::MarkingVisitorBase(ThreadState* state,
-                                       MarkingMode marking_mode,
-                                       int task_id)
-    : Visitor(state),
-      marking_worklist_(Heap().GetMarkingWorklist(), task_id),
-      write_barrier_worklist_(Heap().GetWriteBarrierWorklist(), task_id),
-      not_fully_constructed_worklist_(Heap().GetNotFullyConstructedWorklist(),
-                                      task_id),
-      weak_callback_worklist_(Heap().GetWeakCallbackWorklist(), task_id),
-      movable_reference_worklist_(Heap().GetMovableReferenceWorklist(),
-                                  task_id),
-      discovered_ephemeron_pairs_worklist_(
-          Heap().GetDiscoveredEphemeronPairsWorklist(),
-          task_id),
-      ephemeron_pairs_to_process_worklist_(
-          Heap().GetEphemeronPairsToProcessWorklist(),
-          task_id),
-      weak_containers_worklist_(Heap().GetWeakContainersWorklist()),
-      marking_mode_(marking_mode),
-      task_id_(task_id) {}
-
-void MarkingVisitorBase::FlushCompactionWorklists() {
-  if (marking_mode_ != kGlobalMarkingWithCompaction)
-    return;
-  movable_reference_worklist_.FlushToGlobal();
-}
-
-void MarkingVisitorBase::RegisterWeakCallback(WeakCallback callback,
-                                              const void* object) {
-  weak_callback_worklist_.Push({callback, object});
-}
-
-void MarkingVisitorBase::RegisterMovableSlot(const void* const* slot) {
-  if (marking_mode_ != kGlobalMarkingWithCompaction)
-    return;
-  if (Heap().ShouldRegisterMovingAddress()) {
-    movable_reference_worklist_.Push(slot);
-  }
-}
-
-void MarkingVisitorBase::VisitWeak(const void* object,
-                                   const void* object_weak_ref,
-                                   TraceDescriptor desc,
-                                   WeakCallback callback) {
-  HeapObjectHeader* header =
-      HeapObjectHeader::FromPayload(desc.base_object_payload);
-  if (header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>()) {
-    not_fully_constructed_worklist_.Push(desc.base_object_payload);
-    return;
-  }
-  // Filter out already marked values. The write barrier for WeakMember
-  // ensures that any newly set value after this point is kept alive and does
-  // not require the callback.
-  if (header->IsMarked<HeapObjectHeader::AccessMode::kAtomic>())
-    return;
-  RegisterWeakCallback(callback, object_weak_ref);
-}
-
-void MarkingVisitorBase::VisitEphemeron(const void* key,
-                                        TraceDescriptor value_desc) {
-  HeapObjectHeader* key_header = HeapObjectHeader::FromPayload(key);
-  if (!key_header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>() &&
-      !key_header->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
-    // In construction keys are considered as marked because they are
-    // guaranteed to be marked by the end of GC (e.g. by write barrier
-    // on insertion to HashTable).
-    discovered_ephemeron_pairs_worklist_.Push({key, value_desc});
-    return;
-  }
-  value_desc.callback(this, value_desc.base_object_payload);
-}
-
-void MarkingVisitorBase::VisitWeakContainer(
-    const void* object,
-    const void* const*,
-    TraceDescriptor,
-    TraceDescriptor weak_desc,
-    WeakCallback weak_callback,
-    const void* weak_callback_parameter) {
-  // In case there's no object present, weakness processing is omitted. The GC
-  // relies on the fact that in such cases touching the weak data structure will
-  // strongify its references.
-  if (!object)
-    return;
-
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
-  // We shouldn't trace an in-construction backing store of a weak container.
-  // If this container is an ephemeron, we will try to iterate over it's
-  // bucket which is unsafe when the backing store is in construction.
-  if (header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>()) {
-    not_fully_constructed_worklist_.Push(object);
-    return;
-  }
-
-  // Only trace the container initially. Its buckets will be processed after
-  // marking. The interesting cases  are:
-  // - The backing of the container is dropped using clear(): The backing can
-  //   still be compacted but empty/deleted buckets will only be destroyed once
-  //   the backing is reclaimed by the garbage collector on the next cycle.
-  // - The container expands/shrinks: Buckets are moved to the new backing
-  //   store and strongified, resulting in all buckets being alive. The old
-  //   backing store is marked but only contains empty/deleted buckets as all
-  //   non-empty/deleted buckets have been moved to the new backing store.
-  MarkHeaderNoTracing(header);
-  AccountMarkedBytes(header);
-  weak_containers_worklist_->Push(header);
-
-  // Register final weak processing of the backing store.
-  RegisterWeakCallback(weak_callback, weak_callback_parameter);
-  // Register ephemeron callbacks if necessary.
-  if (weak_desc.callback)
-    weak_desc.callback(this, weak_desc.base_object_payload);
-}
-
-void MarkingVisitorBase::DynamicallyMarkAddress(ConstAddress address) {
-  constexpr HeapObjectHeader::AccessMode mode =
-      HeapObjectHeader::AccessMode::kAtomic;
-  HeapObjectHeader* const header =
-      HeapObjectHeader::FromInnerAddress<mode>(address);
-  DCHECK(header);
-  DCHECK(!header->IsInConstruction<mode>());
-  if (MarkHeaderNoTracing(header)) {
-    marking_worklist_.Push({reinterpret_cast<void*>(header->Payload()),
-                            GCInfo::From(header->GcInfoIndex<mode>()).trace});
-  }
-}
-
-// static
-bool MarkingVisitor::MarkValue(void* value,
-                               BasePage* base_page,
-                               ThreadState* thread_state) {
-  HeapObjectHeader* header;
-  if (LIKELY(!base_page->IsLargeObjectPage())) {
-    header = reinterpret_cast<HeapObjectHeader*>(
-        static_cast<NormalPage*>(base_page)->FindHeaderFromAddress(
-            reinterpret_cast<Address>(value)));
-  } else {
-    LargeObjectPage* large_page = static_cast<LargeObjectPage*>(base_page);
-    header = large_page->ObjectHeader();
-  }
-
-  if (!header->TryMark<HeapObjectHeader::AccessMode::kAtomic>())
-    return false;
-
-  MarkingVisitor* visitor = thread_state->CurrentVisitor();
-  if (UNLIKELY(
-          header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>())) {
-    // It is assumed that objects on not_fully_constructed_worklist_ are not
-    // marked.
-    header->Unmark<HeapObjectHeader::AccessMode::kAtomic>();
-    visitor->not_fully_constructed_worklist_.Push(header->Payload());
-    return true;
-  }
-
-  visitor->write_barrier_worklist_.Push(header);
-  return true;
-}
-
-// static
-bool MarkingVisitor::WriteBarrierSlow(void* value) {
-  if (!value || internal::IsHashTableDeleteValue(value))
-    return false;
-
-  // It is guaranteed that managed references point to either GarbageCollected
-  // or GarbageCollectedMixin. Mixins are restricted to regular objects sizes.
-  // It is thus possible to get to the page header by aligning properly.
-  BasePage* base_page = PageFromObject(value);
-
-  ThreadState* const thread_state = base_page->thread_state();
-  if (!thread_state->IsIncrementalMarking())
-    return false;
-
-  return MarkValue(value, base_page, thread_state);
-}
-
-void MarkingVisitor::GenerationalBarrierSlow(Address slot,
-                                             ThreadState* thread_state) {
-  BasePage* slot_page = thread_state->Heap().LookupPageForAddress(slot);
-  DCHECK(slot_page);
-
-  if (UNLIKELY(slot_page->IsLargeObjectPage())) {
-    auto* large_page = static_cast<LargeObjectPage*>(slot_page);
-    if (UNLIKELY(large_page->ObjectHeader()->IsOld())) {
-      large_page->SetRemembered(true);
-    }
-    return;
-  }
-
-  auto* normal_page = static_cast<NormalPage*>(slot_page);
-  const HeapObjectHeader* source_header = reinterpret_cast<HeapObjectHeader*>(
-      normal_page->object_start_bit_map()->FindHeader(slot));
-  DCHECK_LT(0u, source_header->GcInfoIndex());
-  DCHECK_GT(source_header->PayloadEnd(), slot);
-  if (UNLIKELY(source_header->IsOld())) {
-    normal_page->MarkCard(slot);
-  }
-}
-
-void MarkingVisitor::RetraceObjectSlow(const void* object) {
-  if (!object)
-    return;
-
-  // Trace object only if it is marked and thus has been traced before. The
-  // marker may be active on the backing store which requires atomic mark bit
-  // access.
-  if (!HeapObjectHeader::FromPayload(object)
-           ->IsMarked<HeapObjectHeader::AccessMode::kAtomic>()) {
-    return;
-  }
-
-  ThreadState* const thread_state = ThreadState::Current();
-  if (!thread_state->IsIncrementalMarking())
-    return;
-
-  // |value| is pointing to the start of a backing store.
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
-  CHECK(header->IsMarked());
-  DCHECK(thread_state->CurrentVisitor());
-  // No weak handling for write barriers. Modifying weakly reachable objects
-  // strongifies them for the current cycle.
-
-  GCInfo::From(header->GcInfoIndex())
-      .trace(thread_state->CurrentVisitor(), object);
-}
-
-constexpr size_t MarkingVisitor::RecentlyRetracedWeakContainers::kMaxCacheSize;
-
-bool MarkingVisitor::RecentlyRetracedWeakContainers::Contains(
-    const HeapObjectHeader* header) {
-  return std::find(recently_retraced_cache_.begin(),
-                   recently_retraced_cache_.end(),
-                   header) != recently_retraced_cache_.end();
-}
-
-void MarkingVisitor::RecentlyRetracedWeakContainers::Insert(
-    const HeapObjectHeader* header) {
-  last_used_index_ = (last_used_index_ + 1) % kMaxCacheSize;
-  if (recently_retraced_cache_.size() <= last_used_index_)
-    recently_retraced_cache_.push_back(header);
-  else
-    recently_retraced_cache_[last_used_index_] = header;
-}
-
-MarkingVisitor::MarkingVisitor(ThreadState* state, MarkingMode marking_mode)
-    : MarkingVisitorBase(state, marking_mode, WorklistTaskId::MutatorThread) {
-  DCHECK(state->InAtomicMarkingPause());
-  DCHECK(state->CheckThread());
-}
-
-void MarkingVisitor::ConservativelyMarkAddress(BasePage* page,
-                                               ConstAddress address) {
-#if DCHECK_IS_ON()
-  DCHECK(page->Contains(address));
-#endif
-  HeapObjectHeader* const header =
-      page->IsLargeObjectPage()
-          ? static_cast<LargeObjectPage*>(page)->ObjectHeader()
-          : static_cast<NormalPage*>(page)->ConservativelyFindHeaderFromAddress(
-                address);
-  if (!header)
-    return;
-  if (header->IsMarked()) {
-    // Weak containers found through conservative GC need to be strongified. In
-    // case the container was previously marked and weakly traced, it should be
-    // retraced strongly now. Previously marked/traced weak containers are
-    // marked using the |weak_containers_worklist_|. Other marked object can be
-    // skipped.
-    if (weak_containers_worklist_->Contains(header) &&
-        !recently_retraced_weak_containers_.Contains(header)) {
-      DCHECK(!header->IsInConstruction());
-      // Record the weak container backing store to avoid retracing it again.
-      recently_retraced_weak_containers_.Insert(header);
-      marking_worklist_.Push(
-          {header->Payload(), GCInfo::From(header->GcInfoIndex()).trace});
-    }
-    return;
-  }
-
-  // Simple case for fully constructed objects. This just adds the object to the
-  // regular marking worklist.
-  if (!header->IsInConstruction()) {
-    MarkHeader(header,
-               {header->Payload(), GCInfo::From(header->GcInfoIndex()).trace});
-    return;
-  }
-
-  // This case is reached for not-fully-constructed objects with vtables.
-  // We can differentiate multiple cases:
-  // 1. No vtable set up. Example:
-  //      class A : public GarbageCollected<A> { virtual void f() = 0; };
-  //      class B : public A { B() : A(foo()) {}; };
-  //    The vtable for A is not set up if foo() allocates and triggers a GC.
-  //
-  // 2. Vtables properly set up (non-mixin case).
-  // 3. Vtables not properly set up (mixin) if GC is allowed during mixin
-  //    construction.
-  //
-  // We use a simple conservative approach for these cases as they are not
-  // performance critical.
-  MarkHeaderNoTracing(header);
-  Address* payload = reinterpret_cast<Address*>(header->Payload());
-  const size_t payload_size = header->PayloadSize();
-  for (size_t i = 0; i < (payload_size / sizeof(Address)); ++i) {
-    Address maybe_ptr = payload[i];
-#if defined(MEMORY_SANITIZER)
-    // |payload| may be uninitialized by design or just contain padding bytes.
-    // Copy into a local variable that is unpoisoned for conservative marking.
-    // Copy into a temporary variable to maintain the original MSAN state.
-    __msan_unpoison(&maybe_ptr, sizeof(maybe_ptr));
-#endif
-    if (maybe_ptr)
-      Heap().CheckAndMarkPointer(this, maybe_ptr);
-  }
-  AccountMarkedBytes(header);
-}
-
-void MarkingVisitor::FlushMarkingWorklists() {
-  marking_worklist_.FlushToGlobal();
-  write_barrier_worklist_.FlushToGlobal();
-}
-
-ConcurrentMarkingVisitor::ConcurrentMarkingVisitor(ThreadState* state,
-                                                   MarkingMode marking_mode,
-                                                   int task_id)
-    : MarkingVisitorBase(state, marking_mode, task_id),
-      not_safe_to_concurrently_trace_worklist_(
-          Heap().GetNotSafeToConcurrentlyTraceWorklist(),
-          task_id),
-      previously_not_fully_constructed_worklist_(
-          Heap().GetPreviouslyNotFullyConstructedWorklist(),
-          task_id) {
-  DCHECK(!state->CheckThread());
-  DCHECK_NE(WorklistTaskId::MutatorThread, task_id);
-}
-
-ConcurrentMarkingVisitor::~ConcurrentMarkingVisitor() {
-  // ConcurrentMarkingVisitor should report all its marked_bytes before dying.
-  DCHECK_EQ(marked_bytes_, last_marked_bytes_);
-}
-
-void ConcurrentMarkingVisitor::FlushWorklists() {
-  // Flush marking worklists for further marking on the mutator thread.
-  marking_worklist_.FlushToGlobal();
-  write_barrier_worklist_.FlushToGlobal();
-  not_fully_constructed_worklist_.FlushToGlobal();
-  previously_not_fully_constructed_worklist_.FlushToGlobal();
-  weak_callback_worklist_.FlushToGlobal();
-  discovered_ephemeron_pairs_worklist_.FlushToGlobal();
-  ephemeron_pairs_to_process_worklist_.FlushToGlobal();
-  not_safe_to_concurrently_trace_worklist_.FlushToGlobal();
-  // Flush compaction worklists.
-  if (marking_mode_ == kGlobalMarkingWithCompaction) {
-    movable_reference_worklist_.FlushToGlobal();
-  }
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/marking_visitor.h b/third_party/blink/renderer/platform/heap/impl/marking_visitor.h
deleted file mode 100644
index afa594b..0000000
--- a/third_party/blink/renderer/platform/heap/impl/marking_visitor.h
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VISITOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VISITOR_H_
-
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-
-namespace blink {
-
-namespace internal {
-
-ALWAYS_INLINE bool IsHashTableDeleteValue(const void* value) {
-  return value == reinterpret_cast<void*>(-1);
-}
-
-}  // namespace internal
-
-class BasePage;
-enum class TracenessMemberConfiguration;
-template <typename T, TracenessMemberConfiguration tracenessConfiguration>
-class MemberBase;
-
-// Base visitor used to mark Oilpan objects on any thread.
-class PLATFORM_EXPORT MarkingVisitorBase : public Visitor {
- public:
-  enum MarkingMode {
-    // Default visitor mode used for regular marking.
-    kGlobalMarking,
-    // Visitor mode recording slots for compaction during marking.
-    kGlobalMarkingWithCompaction,
-  };
-
-  void VisitWeakContainer(const void*,
-                          const void* const*,
-                          TraceDescriptor,
-                          TraceDescriptor,
-                          WeakCallback,
-                          const void*) final;
-  void VisitEphemeron(const void*, TraceDescriptor) final;
-
-  // Marks an object dynamically using any address within its body and adds a
-  // tracing callback for processing of the object. The object is not allowed
-  // to be in construction.
-  void DynamicallyMarkAddress(ConstAddress);
-
-  void RegisterMovableSlot(const void* const*) final;
-
-  void RegisterWeakCallback(WeakCallback, const void*) final;
-
-  // Flush private segments remaining in visitor's worklists to global pools.
-  void FlushCompactionWorklists();
-
-  size_t marked_bytes() const { return marked_bytes_; }
-
-  int task_id() const { return task_id_; }
-
-  // Account for object's live bytes. Should only be adjusted when
-  // actually tracing through an already marked object. Logically, this means
-  // accounting for the bytes when transitioning from grey to black.
-  ALWAYS_INLINE void AccountMarkedBytes(HeapObjectHeader*);
-  ALWAYS_INLINE void AccountMarkedBytes(size_t);
-
- protected:
-  MarkingVisitorBase(ThreadState*, MarkingMode, int task_id);
-  ~MarkingVisitorBase() override = default;
-
-  void Visit(const void* object, TraceDescriptor desc) final;
-  void VisitWeak(const void*, const void*, TraceDescriptor, WeakCallback) final;
-
-  // Marks an object and adds a tracing callback for processing of the object.
-  void MarkHeader(HeapObjectHeader*, const TraceDescriptor&);
-  // Try to mark an object without tracing. Returns true when the object was not
-  // marked upon calling.
-  bool MarkHeaderNoTracing(HeapObjectHeader*);
-
-  MarkingWorklist::View marking_worklist_;
-  WriteBarrierWorklist::View write_barrier_worklist_;
-  NotFullyConstructedWorklist::View not_fully_constructed_worklist_;
-  WeakCallbackWorklist::View weak_callback_worklist_;
-  MovableReferenceWorklist::View movable_reference_worklist_;
-  EphemeronPairsWorklist::View discovered_ephemeron_pairs_worklist_;
-  EphemeronPairsWorklist::View ephemeron_pairs_to_process_worklist_;
-  WeakContainersWorklist* const weak_containers_worklist_;
-  size_t marked_bytes_ = 0;
-  const MarkingMode marking_mode_;
-  int task_id_;
-};
-
-ALWAYS_INLINE void MarkingVisitorBase::AccountMarkedBytes(
-    HeapObjectHeader* header) {
-  AccountMarkedBytes(
-      header->IsLargeObject<HeapObjectHeader::AccessMode::kAtomic>()
-          ? static_cast<LargeObjectPage*>(PageFromObject(header))->ObjectSize()
-          : header->size<HeapObjectHeader::AccessMode::kAtomic>());
-}
-
-ALWAYS_INLINE void MarkingVisitorBase::AccountMarkedBytes(size_t marked_bytes) {
-  marked_bytes_ += marked_bytes;
-}
-
-ALWAYS_INLINE bool MarkingVisitorBase::MarkHeaderNoTracing(
-    HeapObjectHeader* header) {
-  DCHECK(header);
-  DCHECK(State()->IsIncrementalMarking() || State()->InAtomicMarkingPause());
-  // A GC should only mark the objects that belong in its heap.
-  DCHECK_EQ(State(),
-            PageFromObject(header->Payload())->Arena()->GetThreadState());
-  // Never mark free space objects. This would e.g. hint to marking a promptly
-  // freed backing store.
-  DCHECK(!header->IsFree());
-
-  return header->TryMark<HeapObjectHeader::AccessMode::kAtomic>();
-}
-
-inline void MarkingVisitorBase::Visit(const void* object,
-                                      TraceDescriptor desc) {
-  DCHECK(object);
-  MarkHeader(HeapObjectHeader::FromPayload(desc.base_object_payload), desc);
-}
-
-// Marks an object and adds a tracing callback for processing of the object.
-ALWAYS_INLINE void MarkingVisitorBase::MarkHeader(HeapObjectHeader* header,
-                                                  const TraceDescriptor& desc) {
-  DCHECK(header);
-  DCHECK(desc.callback);
-
-  if (header->IsInConstruction<HeapObjectHeader::AccessMode::kAtomic>()) {
-    not_fully_constructed_worklist_.Push(header->Payload());
-  } else if (MarkHeaderNoTracing(header)) {
-    marking_worklist_.Push(desc);
-  }
-}
-
-// Visitor used to mark Oilpan objects on the main thread. Also implements
-// various sorts of write barriers that should only be called from the main
-// thread.
-class PLATFORM_EXPORT MarkingVisitor : public MarkingVisitorBase {
- public:
-  // Write barrier that adds a value the |slot| refers to to the set of marked
-  // objects. The barrier bails out if marking is off or the object is not yet
-  // marked. Returns true if the value has been marked on this call.
-  ALWAYS_INLINE static bool WriteBarrier(void** slot);
-
-  using ThreadStateCallback = ThreadState*();
-  // Write barrier where for a range of |number_of_elements| elements of size
-  // |element_size| starting at |first_element|. The |callback| will be invoked
-  // for each element if necessary.
-  ALWAYS_INLINE static void WriteBarrier(
-      ThreadStateCallback thread_state_callback,
-      void* first_element,
-      size_t element_size,
-      size_t number_of_elements,
-      TraceCallback callback);
-
-  // Eagerly traces an already marked |object| ensuring that all its children
-  // are discovered by the marker. The barrier bails out if marking is off and
-  // on individual objects reachable if they are already marked. The barrier
-  // uses the callback function through GcInfo.
-  //
-  // Note: |object| must point to the beginning of the heap object.
-  ALWAYS_INLINE static void RetraceObject(const void* object);
-
-  MarkingVisitor(ThreadState*, MarkingMode);
-  ~MarkingVisitor() override = default;
-
-  // Conservatively marks an object if pointed to by Address. The object may
-  // be in construction as the scan is conservative without relying on a
-  // Trace method.
-  void ConservativelyMarkAddress(BasePage*, ConstAddress);
-
-  void FlushMarkingWorklists();
-
- private:
-  ALWAYS_INLINE static void GenerationalBarrier(Address slot,
-                                                ThreadState* state);
-
-  // Exact version of the marking and generational write barriers.
-  static bool WriteBarrierSlow(void*);
-  static void GenerationalBarrierSlow(Address, ThreadState*);
-  static bool MarkValue(void*, BasePage*, ThreadState*);
-  static void RetraceObjectSlow(const void*);
-
-  // Weak containers are strongly retraced during conservative stack scanning.
-  // Stack scanning happens once per GC at the start of the atomic pause.
-  // Because the visitor is not retained between GCs, there is no need to clear
-  // the set at the end of GC.
-  class RecentlyRetracedWeakContainers {
-    static constexpr size_t kMaxCacheSize = 8;
-
-   public:
-    bool Contains(const HeapObjectHeader*);
-    void Insert(const HeapObjectHeader*);
-
-   private:
-    std::vector<const HeapObjectHeader*> recently_retraced_cache_;
-    size_t last_used_index_ = -1;
-  } recently_retraced_weak_containers_;
-
-  template <typename T, TracenessMemberConfiguration tracenessConfiguration>
-  friend class MemberBase;
-};
-
-// static
-bool MarkingVisitor::WriteBarrier(void** slot) {
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-  void* value = *slot;
-  if (!value || internal::IsHashTableDeleteValue(value))
-    return false;
-
-  // Dijkstra barrier if concurrent marking is in progress.
-  BasePage* value_page = PageFromObject(value);
-  ThreadState* thread_state = value_page->thread_state();
-
-  if (UNLIKELY(thread_state->IsIncrementalMarking()))
-    return MarkValue(value, value_page, thread_state);
-
-  GenerationalBarrier(reinterpret_cast<Address>(slot), thread_state);
-  return false;
-#else
-  if (!ThreadState::IsAnyIncrementalMarking())
-    return false;
-
-  // Avoid any further checks and dispatch to a call at this point. Aggressive
-  // inlining otherwise pollutes the regular execution paths.
-  return WriteBarrierSlow(*slot);
-#endif
-}
-
-// static
-void MarkingVisitor::WriteBarrier(ThreadStateCallback thread_state_callback,
-                                  void* first_element,
-                                  size_t element_size,
-                                  size_t number_of_elements,
-                                  TraceCallback callback) {
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-  ThreadState* const thread_state = thread_state_callback();
-  if (!thread_state->IsIncrementalMarking()) {
-    MarkingVisitor::GenerationalBarrier(
-        reinterpret_cast<Address>(first_element), thread_state);
-    return;
-  }
-#else   // !BLINK_HEAP_YOUNG_GENERATION
-  if (!ThreadState::IsAnyIncrementalMarking())
-    return;
-  // The object may have been in-place constructed as part of a large object.
-  // It is not safe to retrieve the page from the object here.
-  ThreadState* const thread_state = thread_state_callback();
-  if (!thread_state->IsIncrementalMarking()) {
-    return;
-  }
-#endif  // !BLINK_HEAP_YOUNG_GENERATION
-  ThreadState::NoAllocationScope no_allocation_scope(thread_state);
-  DCHECK(thread_state->CurrentVisitor());
-  // No weak handling for write barriers. Modifying weakly reachable objects
-  // strongifies them for the current cycle.
-  char* array = static_cast<char*>(first_element);
-  while (number_of_elements-- > 0) {
-    callback(thread_state->CurrentVisitor(), array);
-    array += element_size;
-  }
-}
-
-// static
-void MarkingVisitor::GenerationalBarrier(Address slot, ThreadState* state) {
-  // First, check if the source object is in the last allocated region of heap.
-  if (LIKELY(state->Heap().IsInLastAllocatedRegion(slot)))
-    return;
-  if (UNLIKELY(state->IsOnStack(slot)))
-    return;
-  GenerationalBarrierSlow(slot, state);
-}
-
-// static
-void MarkingVisitor::RetraceObject(const void* object) {
-  if (!ThreadState::IsAnyIncrementalMarking())
-    return;
-
-  RetraceObjectSlow(object);
-}
-
-// Visitor used to mark Oilpan objects on concurrent threads.
-class PLATFORM_EXPORT ConcurrentMarkingVisitor : public MarkingVisitorBase {
- public:
-  ConcurrentMarkingVisitor(ThreadState*, MarkingMode, int);
-  ~ConcurrentMarkingVisitor() override;
-
-  virtual void FlushWorklists();
-
-  bool IsConcurrent() const override { return true; }
-
-  bool DeferredTraceIfConcurrent(TraceDescriptor desc,
-                                 size_t bailout_size) override {
-    not_safe_to_concurrently_trace_worklist_.Push({desc, bailout_size});
-    // The object is bailed out from concurrent marking, so updating
-    // marked_bytes_ to reflect how many bytes were actually traced.
-    // This deducted bytes will be added to the mutator thread marking
-    // visitor's marked_bytes_ count when the object is popped from
-    // the bailout worklist.
-    marked_bytes_ -= bailout_size;
-    return true;
-  }
-
-  size_t RecentlyMarkedBytes() {
-    return marked_bytes_ - std::exchange(last_marked_bytes_, marked_bytes_);
-  }
-
- private:
-  NotSafeToConcurrentlyTraceWorklist::View
-      not_safe_to_concurrently_trace_worklist_;
-  NotFullyConstructedWorklist::View previously_not_fully_constructed_worklist_;
-  size_t last_marked_bytes_ = 0;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MARKING_VISITOR_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/member.h b/third_party/blink/renderer/platform/heap/impl/member.h
deleted file mode 100644
index d5d373f8..0000000
--- a/third_party/blink/renderer/platform/heap/impl/member.h
+++ /dev/null
@@ -1,543 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MEMBER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MEMBER_H_
-
-#include "base/dcheck_is_on.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/construct_traits.h"
-#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
-#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h"
-#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
-
-namespace WTF {
-template <typename P, typename Traits, typename Allocator>
-class MemberConstructTraits;
-}  // namespace WTF
-
-namespace blink {
-
-template <typename T>
-class Persistent;
-
-enum class TracenessMemberConfiguration {
-  kTraced,
-  kUntraced,
-};
-
-template <typename T,
-          TracenessMemberConfiguration tracenessConfiguration =
-              TracenessMemberConfiguration::kTraced>
-class MemberPointerVerifier {
- public:
-  MemberPointerVerifier() = default;
-
-  void SaveCreationThreadState(T* pointer) {
-    if (tracenessConfiguration == TracenessMemberConfiguration::kUntraced) {
-      creation_thread_state_ = nullptr;
-    } else {
-      creation_thread_state_ = ThreadState::Current();
-      // Members should be created in an attached thread. But an empty
-      // value Member may be created on an unattached thread by a heap
-      // collection iterator.
-      DCHECK(creation_thread_state_ || !pointer);
-    }
-  }
-
-  void CheckPointer(T* pointer) {
-    if (!pointer)
-      return;
-
-    ThreadState* current = ThreadState::Current();
-    DCHECK(current);
-    if (tracenessConfiguration != TracenessMemberConfiguration::kUntraced) {
-      // creation_thread_state_ may be null when this is used in a heap
-      // collection which initialized the Member with memset and the
-      // constructor wasn't called.
-      if (creation_thread_state_) {
-        // Member should point to objects that belong in the same ThreadHeap.
-        DCHECK(creation_thread_state_->IsOnThreadHeap(pointer));
-        // Member should point to objects that belong in the same ThreadHeap.
-        DCHECK_EQ(&current->Heap(), &creation_thread_state_->Heap());
-      } else {
-        DCHECK(current->IsOnThreadHeap(pointer));
-      }
-    }
-
-    if (current->IsSweepingInProgress()) {
-      // During sweeping the object start bitmap is invalid. Check the header
-      // when the type is available and not pointing to a mixin.
-      if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
-        HeapObjectHeader::CheckFromPayload(pointer);
-    } else {
-      DCHECK(HeapObjectHeader::FromInnerAddress<
-             HeapObjectHeader::AccessMode::kAtomic>(pointer));
-    }
-  }
-
- private:
-  const ThreadState* creation_thread_state_;
-};
-
-template <typename T,
-          TracenessMemberConfiguration tracenessConfiguration =
-              TracenessMemberConfiguration::kTraced>
-class MemberBase {
-  DISALLOW_NEW();
-
- public:
-  MemberBase() : raw_(nullptr) { SaveCreationThreadState(); }
-
-  MemberBase(std::nullptr_t) : raw_(nullptr) { SaveCreationThreadState(); }
-
-  explicit MemberBase(T* raw) : raw_(raw) {
-    SaveCreationThreadState();
-    CheckPointer();
-    // No write barrier for initializing stores.
-  }
-
-  explicit MemberBase(T& raw) : raw_(&raw) {
-    SaveCreationThreadState();
-    CheckPointer();
-    // No write barrier for initializing stores.
-  }
-
-  MemberBase(WTF::HashTableDeletedValueType)
-      : raw_(reinterpret_cast<T*>(kHashTableDeletedRawValue)) {
-    SaveCreationThreadState();
-  }
-
-  MemberBase(const MemberBase& other) : raw_(other) {
-    SaveCreationThreadState();
-    CheckPointer();
-    // No write barrier for initializing stores.
-  }
-
-  template <typename U>
-  MemberBase(const Persistent<U>& other) : raw_(other) {
-    SaveCreationThreadState();
-    CheckPointer();
-    // No write barrier for initializing stores.
-  }
-
-  template <typename U>
-  MemberBase(const MemberBase<U>& other) : raw_(other) {
-    SaveCreationThreadState();
-    CheckPointer();
-    // No write barrier for initializing stores.
-  }
-
-  template <typename U>
-  MemberBase& operator=(const Persistent<U>& other) {
-    SetRaw(other);
-    CheckPointer();
-    WriteBarrier();
-    return *this;
-  }
-
-  MemberBase& operator=(const MemberBase& other) {
-    SetRaw(other);
-    CheckPointer();
-    WriteBarrier();
-    return *this;
-  }
-
-  template <typename U>
-  MemberBase& operator=(const MemberBase<U>& other) {
-    SetRaw(other);
-    CheckPointer();
-    WriteBarrier();
-    return *this;
-  }
-
-  template <typename U>
-  MemberBase& operator=(U* other) {
-    SetRaw(other);
-    CheckPointer();
-    WriteBarrier();
-    return *this;
-  }
-
-  MemberBase& operator=(WTF::HashTableDeletedValueType) {
-    SetRaw(reinterpret_cast<T*>(-1));
-    return *this;
-  }
-
-  MemberBase& operator=(std::nullptr_t) {
-    SetRaw(nullptr);
-    return *this;
-  }
-
-  void Swap(MemberBase<T>& other) {
-    T* tmp = GetRaw();
-    SetRaw(other.GetRaw());
-    other.SetRaw(tmp);
-    CheckPointer();
-    WriteBarrier();
-    other.WriteBarrier();
-  }
-
-  explicit operator bool() const { return GetRaw(); }
-  operator T*() const { return GetRaw(); }
-  T* operator->() const { return GetRaw(); }
-  T& operator*() const { return *GetRaw(); }
-
-  T* Get() const { return GetRaw(); }
-
-  void Clear() { SetRaw(nullptr); }
-
-  T* Release() {
-    T* result = GetRaw();
-    SetRaw(nullptr);
-    return result;
-  }
-
-  static bool IsMemberHashTableDeletedValue(const T* t) {
-    return t == reinterpret_cast<T*>(kHashTableDeletedRawValue);
-  }
-
-  bool IsHashTableDeletedValue() const {
-    return IsMemberHashTableDeletedValue(GetRaw());
-  }
-
- protected:
-  static constexpr intptr_t kHashTableDeletedRawValue = -1;
-
-  enum class AtomicCtorTag { Atomic };
-
-  // MemberBase ctors that use atomic write to set raw_.
-
-  MemberBase(AtomicCtorTag, T* raw) {
-    SetRaw(raw);
-    SaveCreationThreadState();
-    CheckPointer();
-    // No write barrier for initializing stores.
-  }
-
-  MemberBase(AtomicCtorTag, T& raw) {
-    SetRaw(&raw);
-    SaveCreationThreadState();
-    CheckPointer();
-    // No write barrier for initializing stores.
-  }
-
-  void WriteBarrier() const {
-    MarkingVisitor::WriteBarrier(
-        reinterpret_cast<void**>(const_cast<std::remove_const_t<T>**>(&raw_)));
-  }
-
-  void CheckPointer() {
-#if DCHECK_IS_ON()
-    // Should not be called for deleted hash table values. A value can be
-    // propagated here if a MemberBase containing the deleted value is copied.
-    if (IsHashTableDeletedValue())
-      return;
-    pointer_verifier_.CheckPointer(GetRaw());
-#endif  // DCHECK_IS_ON()
-  }
-
-  void SaveCreationThreadState() {
-#if DCHECK_IS_ON()
-    pointer_verifier_.SaveCreationThreadState(GetRaw());
-#endif  // DCHECK_IS_ON()
-  }
-
-  ALWAYS_INLINE void SetRaw(T* raw) {
-    if (tracenessConfiguration == TracenessMemberConfiguration::kUntraced)
-      raw_ = raw;
-    else
-      WTF::AsAtomicPtr(&raw_)->store(raw, std::memory_order_relaxed);
-  }
-  ALWAYS_INLINE T* GetRaw() const { return raw_; }
-
- private:
-  // Thread safe version of Get() for marking visitors.
-  // This is used to prevent data races between concurrent marking visitors
-  // and writes on the main thread.
-  const T* GetSafe() const {
-    // TOOD(omerkatz): replace this cast with std::atomic_ref (C++20) once it
-    // becomes available
-    return WTF::AsAtomicPtr(&raw_)->load(std::memory_order_relaxed);
-  }
-
-  T* raw_;
-#if DCHECK_IS_ON()
-  MemberPointerVerifier<T, tracenessConfiguration> pointer_verifier_;
-#endif  // DCHECK_IS_ON()
-
-  friend class Visitor;
-};
-
-// Members are used in classes to contain strong pointers to other oilpan heap
-// allocated objects.
-// All Member fields of a class must be traced in the class' trace method.
-// During the mark phase of the GC all live objects are marked as live and
-// all Member fields of a live object will be traced marked as live as well.
-template <typename T>
-class Member : public MemberBase<T, TracenessMemberConfiguration::kTraced> {
-  DISALLOW_NEW();
-  typedef MemberBase<T, TracenessMemberConfiguration::kTraced> Parent;
-
- public:
-  Member() : Parent() {}
-  Member(std::nullptr_t) : Parent(nullptr) {}
-  Member(T* raw) : Parent(raw) {}
-  Member(T& raw) : Parent(raw) {}
-  Member(WTF::HashTableDeletedValueType x) : Parent(x) {}
-
-  Member(const Member& other) : Parent(other) {}
-
-  template <typename U>
-  Member(const Member<U>& other) : Parent(other) {}
-
-  template <typename U>
-  Member(const Persistent<U>& other) : Parent(other) {}
-
-  template <typename U>
-  Member& operator=(const Persistent<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  Member& operator=(const Member& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  Member& operator=(const Member<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  Member& operator=(const WeakMember<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  Member& operator=(U* other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  Member& operator=(WTF::HashTableDeletedValueType x) {
-    Parent::operator=(x);
-    return *this;
-  }
-
-  Member& operator=(std::nullptr_t) {
-    Parent::operator=(nullptr);
-    return *this;
-  }
-
- private:
-  using typename Parent::AtomicCtorTag;
-  Member(AtomicCtorTag atomic, T* raw) : Parent(atomic, raw) {}
-  Member(AtomicCtorTag atomic, T& raw) : Parent(atomic, raw) {}
-
-  template <typename P, typename Traits, typename Allocator>
-  friend class WTF::MemberConstructTraits;
-};
-
-// WeakMember is similar to Member in that it is used to point to other oilpan
-// heap allocated objects.
-// However instead of creating a strong pointer to the object, the WeakMember
-// creates a weak pointer, which does not keep the pointee alive. Hence if all
-// pointers to a heap allocated object are weak the object will be garbage
-// collected. At the time of GC the weak pointers will automatically be set to
-// null.
-template <typename T>
-class WeakMember : public MemberBase<T, TracenessMemberConfiguration::kTraced> {
-  typedef MemberBase<T, TracenessMemberConfiguration::kTraced> Parent;
-
- public:
-  WeakMember() : Parent() {}
-
-  WeakMember(std::nullptr_t) : Parent(nullptr) {}
-
-  WeakMember(T* raw) : Parent(raw) {}
-
-  WeakMember(WTF::HashTableDeletedValueType x) : Parent(x) {}
-
-  template <typename U>
-  WeakMember(const Persistent<U>& other) : Parent(other) {}
-
-  template <typename U>
-  WeakMember(const Member<U>& other) : Parent(other) {}
-
-  template <typename U>
-  WeakMember& operator=(const Persistent<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  WeakMember& operator=(const Member<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  WeakMember& operator=(U* other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  WeakMember& operator=(std::nullptr_t) {
-    this->SetRaw(nullptr);
-    return *this;
-  }
-
- private:
-  using typename Parent::AtomicCtorTag;
-  WeakMember(AtomicCtorTag atomic, T* raw) : Parent(atomic, raw) {}
-  WeakMember(AtomicCtorTag atomic, T& raw) : Parent(atomic, raw) {}
-
-  template <typename P, typename Traits, typename Allocator>
-  friend class WTF::MemberConstructTraits;
-};
-
-// UntracedMember is a pointer to an on-heap object that is not traced for some
-// reason. Please don't use this unless you understand what you're doing.
-// Basically, all pointers to on-heap objects must be stored in either of
-// Persistent, Member or WeakMember. It is not allowed to leave raw pointers to
-// on-heap objects. However, there can be scenarios where you have to use raw
-// pointers for some reason, and in that case you can use UntracedMember. Of
-// course, it must be guaranteed that the pointing on-heap object is kept alive
-// while the raw pointer is pointing to the object.
-template <typename T>
-class UntracedMember final
-    : public MemberBase<T, TracenessMemberConfiguration::kUntraced> {
-  typedef MemberBase<T, TracenessMemberConfiguration::kUntraced> Parent;
-
- public:
-  UntracedMember() : Parent() {}
-
-  UntracedMember(std::nullptr_t) : Parent(nullptr) {}
-
-  UntracedMember(T* raw) : Parent(raw) {}
-
-  UntracedMember(const UntracedMember& other) : Parent(other) {}
-
-  template <typename U>
-  UntracedMember(const Persistent<U>& other) : Parent(other) {}
-
-  template <typename U>
-  UntracedMember(const Member<U>& other) : Parent(other) {}
-
-  UntracedMember(WTF::HashTableDeletedValueType x) : Parent(x) {}
-
-  UntracedMember& operator=(const UntracedMember& other) {
-    this->SetRaw(other);
-    this->CheckPointer();
-    return *this;
-  }
-
-  template <typename U>
-  UntracedMember& operator=(const Persistent<U>& other) {
-    this->SetRaw(other);
-    this->CheckPointer();
-    return *this;
-  }
-
-  template <typename U>
-  UntracedMember& operator=(const Member<U>& other) {
-    this->SetRaw(other);
-    this->CheckPointer();
-    return *this;
-  }
-
-  template <typename U>
-  UntracedMember& operator=(U* other) {
-    this->SetRaw(other);
-    this->CheckPointer();
-    return *this;
-  }
-
-  UntracedMember& operator=(std::nullptr_t) {
-    this->SetRaw(nullptr);
-    return *this;
-  }
-};
-
-template <typename T>
-struct MemberTraceTraits {
-  STATIC_ONLY(MemberTraceTraits);
-
- public:
-  static TraceDescriptor GetTraceDescriptor(const T* ref) {
-    return {ref, TraceTrait<T>::Trace};
-  }
-
-  static void Trace(Visitor* visitor, const void* ref) {
-    visitor->Trace(*static_cast<const T*>(ref));
-  }
-};
-
-template <typename T>
-struct TraceTrait<Member<T>> : public MemberTraceTraits<Member<T>> {};
-
-template <typename T>
-struct TraceTrait<WeakMember<T>> : public MemberTraceTraits<WeakMember<T>> {};
-
-template <typename T>
-inline bool IsHashTableDeletedValue(const Member<T>& m) {
-  return m.IsHashTableDeletedValue();
-}
-
-constexpr auto kMemberDeletedValue = WTF::kHashTableDeletedValue;
-
-}  // namespace blink
-
-namespace WTF {
-
-template <typename T, typename Traits, typename Allocator>
-class MemberConstructTraits {
-  STATIC_ONLY(MemberConstructTraits);
-
- public:
-  template <typename... Args>
-  static T* Construct(void* location, Args&&... args) {
-    return new (NotNullTag::kNotNull, location) T(std::forward<Args>(args)...);
-  }
-
-  static void NotifyNewElement(T* element) { element->WriteBarrier(); }
-
-  template <typename... Args>
-  static T* ConstructAndNotifyElement(void* location, Args&&... args) {
-    // ConstructAndNotifyElement updates an existing Member which might
-    // also be comncurrently traced while we update it. The regular ctors
-    // for Member don't use an atomic write which can lead to data races.
-    T* object = Construct(location, T::AtomicCtorTag::Atomic,
-                          std::forward<Args>(args)...);
-    NotifyNewElement(object);
-    return object;
-  }
-
-  static void NotifyNewElements(T* array, size_t len) {
-    while (len-- > 0) {
-      array->WriteBarrier();
-      array++;
-    }
-  }
-};
-
-template <typename T, typename Traits, typename Allocator>
-class ConstructTraits<blink::Member<T>, Traits, Allocator>
-    : public MemberConstructTraits<blink::Member<T>, Traits, Allocator> {};
-
-template <typename T, typename Traits, typename Allocator>
-class ConstructTraits<blink::WeakMember<T>, Traits, Allocator>
-    : public MemberConstructTraits<blink::WeakMember<T>, Traits, Allocator> {};
-
-}  // namespace WTF
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_MEMBER_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/name_traits.h b/third_party/blink/renderer/platform/heap/impl/name_traits.h
deleted file mode 100644
index c44305f..0000000
--- a/third_party/blink/renderer/platform/heap/impl/name_traits.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_NAME_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_NAME_TRAITS_H_
-
-#include <cstring>
-
-#include "build/build_config.h"
-#include "third_party/blink/renderer/platform/bindings/name_client.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
-
-namespace blink {
-
-struct HeapObjectName {
-  const char* value;
-  bool name_is_hidden;
-};
-
-using NameCallback = HeapObjectName (*)(const void*);
-
-template <typename T>
-class NameTrait {
-  STATIC_ONLY(NameTrait);
-
- public:
-  static HeapObjectName GetName(const void* obj) {
-    return GetNameFor(static_cast<const T*>(obj));
-  }
-
- private:
-  static HeapObjectName GetNameFor(const NameClient* wrapper_tracable) {
-    return {wrapper_tracable->NameInHeapSnapshot(), false};
-  }
-
-  static HeapObjectName GetNameFor(...) {
-    if (NameClient::HideInternalName())
-      return {"InternalNode", true};
-
-    DCHECK(!NameClient::HideInternalName());
-    static const char* leaky_class_name = nullptr;
-    if (leaky_class_name)
-      return {leaky_class_name, false};
-
-    // Parsing string of structure:
-    //   const char *WTF::GetStringWithTypeName<TYPE>() [T = TYPE]
-    // Note that this only works on clang or GCC builds.
-    const std::string raw(WTF::GetStringWithTypeName<T>());
-    const auto start_pos = raw.rfind("T = ") + 4;
-    DCHECK(std::string::npos != start_pos);
-    const auto len = raw.length() - start_pos - 1;
-    const std::string name = raw.substr(start_pos, len).c_str();
-    leaky_class_name = strcpy(new char[name.length() + 1], name.c_str());
-    return {leaky_class_name, false};
-  }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_NAME_TRAITS_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h b/third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h
deleted file mode 100644
index 19263ae..0000000
--- a/third_party/blink/renderer/platform/heap/impl/page_bloom_filter.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_BLOOM_FILTER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_BLOOM_FILTER_H_
-
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/wtf/bloom_filter.h"
-
-namespace blink {
-
-// Bloom filter for Oilpan pages. Use counting to support correct deletion. This
-// is needed for stack scanning to quickly check if an arbitrary address doesn't
-// point inside Oilpan pages. May return false positives but never false
-// negatives.
-class PageBloomFilter {
- public:
-  void Add(Address address) {
-    filter_.Add(Hash(RoundToBlinkPageStart(address)));
-  }
-
-  void Remove(Address address) {
-    filter_.Remove(Hash(RoundToBlinkPageStart(address)));
-  }
-
-  bool MayContain(Address address) const {
-    return filter_.MayContain(Hash(RoundToBlinkPageStart(address)));
-  }
-
- private:
-  static constexpr size_t kNumberOfEntriesLog2 = 12;
-  static constexpr size_t kNumberOfEntries = 1 << kNumberOfEntriesLog2;
-
-  static unsigned Hash(Address address) {
-    size_t value = reinterpret_cast<size_t>(address) >> kBlinkPageSizeLog2;
-    value ^= value >> kNumberOfEntriesLog2;
-    value ^= value >> (kNumberOfEntriesLog2 * 2);
-    value &= kNumberOfEntries - 1;
-    return static_cast<unsigned>(value);
-  }
-
-  WTF::BloomFilter<kNumberOfEntriesLog2> filter_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_BLOOM_FILTER_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/page_memory.cc b/third_party/blink/renderer/platform/heap/impl/page_memory.cc
deleted file mode 100644
index c463e17..0000000
--- a/third_party/blink/renderer/platform/heap/impl/page_memory.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/page_memory.h"
-
-#include "base/allocator/partition_allocator/oom.h"
-#include "base/allocator/partition_allocator/page_allocator.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
-
-namespace blink {
-
-void MemoryRegion::Release() {
-  base::FreePages(base_, size_);
-}
-
-void MemoryRegion::Commit() {
-  base::RecommitSystemPages(base_, size_, base::PageReadWrite,
-                            base::PageUpdatePermissions);
-}
-
-void MemoryRegion::Decommit() {
-  ASAN_UNPOISON_MEMORY_REGION(base_, size_);
-  base::DecommitSystemPages(base_, size_, base::PageUpdatePermissions);
-}
-
-PageMemoryRegion::PageMemoryRegion(Address base,
-                                   size_t size,
-                                   unsigned num_pages,
-                                   RegionTree* region_tree)
-    : MemoryRegion(base, size),
-      is_large_page_(num_pages == 1),
-      num_pages_(num_pages),
-      region_tree_(region_tree) {
-  DCHECK(region_tree);
-  region_tree_->Add(this);
-  for (size_t i = 0; i < kBlinkPagesPerRegion; ++i)
-    in_use_[i] = false;
-}
-
-PageMemoryRegion::~PageMemoryRegion() {
-  region_tree_->Remove(this);
-  Release();
-}
-
-void PageMemoryRegion::PageDeleted(Address page) {
-  MarkPageUnused(page);
-  if (!num_pages_.Decrement())
-    delete this;
-}
-
-// TODO(haraken): Like partitionOutOfMemoryWithLotsOfUncommitedPages(),
-// we should probably have a way to distinguish physical memory OOM from
-// virtual address space OOM.
-static NOINLINE void BlinkGCOutOfMemory() {
-  // TODO(lizeb): Add the real allocation size here as well.
-  OOM_CRASH(0);
-}
-
-PageMemoryRegion* PageMemoryRegion::Allocate(size_t size,
-                                             unsigned num_pages,
-                                             RegionTree* region_tree) {
-  // Round size up to the allocation granularity.
-  size = base::RoundUpToPageAllocationGranularity(size);
-  Address base = static_cast<Address>(
-      base::AllocPages(nullptr, size, kBlinkPageSize, base::PageInaccessible,
-                       base::PageTag::kBlinkGC));
-  if (!base)
-    BlinkGCOutOfMemory();
-  return new PageMemoryRegion(base, size, num_pages, region_tree);
-}
-
-PageMemoryRegion* RegionTree::Lookup(ConstAddress address) {
-  auto it = set_.upper_bound(address);
-  // This check also covers set_.size() > 0, since for empty vectors it is
-  // guaranteed that begin() == end().
-  if (it == set_.begin())
-    return nullptr;
-  auto* result = std::next(it, -1)->second;
-  if (address < result->Base() + result->size())
-    return result;
-  return nullptr;
-}
-
-void RegionTree::Add(PageMemoryRegion* region) {
-  DCHECK(region);
-  auto result = set_.emplace(region->Base(), region);
-  DCHECK(result.second);
-}
-
-void RegionTree::Remove(PageMemoryRegion* region) {
-  DCHECK(region);
-  auto size = set_.erase(region->Base());
-  DCHECK_EQ(1u, size);
-}
-
-PageMemory::PageMemory(PageMemoryRegion* reserved, const MemoryRegion& writable)
-    : reserved_(reserved), writable_(writable) {
-  DCHECK(reserved->Contains(writable));
-
-  // Register the writable area of the memory as part of the LSan root set.
-  // Only the writable area is mapped and can contain C++ objects.  Those
-  // C++ objects can contain pointers to objects outside of the heap and
-  // should therefore be part of the LSan root set.
-  __lsan_register_root_region(writable_.Base(), writable_.size());
-}
-
-PageMemory* PageMemory::SetupPageMemoryInRegion(PageMemoryRegion* region,
-                                                size_t page_offset,
-                                                size_t payload_size) {
-  // Setup the payload one guard page into the page memory.
-  Address payload_address = region->Base() + page_offset + BlinkGuardPageSize();
-  return new PageMemory(region, MemoryRegion(payload_address, payload_size));
-}
-
-PageMemory* PageMemory::Allocate(size_t payload_size, RegionTree* region_tree) {
-  DCHECK_GT(payload_size, 0u);
-
-  // Virtual memory allocation routines operate in OS page sizes.
-  // Round up the requested size to nearest os page size.
-  payload_size = base::RoundUpToSystemPage(payload_size);
-
-  // Overallocate by 2 times OS page size to have space for a
-  // guard page at the beginning and end of blink heap page.
-  size_t allocation_size = payload_size + 2 * BlinkGuardPageSize();
-  PageMemoryRegion* page_memory_region =
-      PageMemoryRegion::AllocateLargePage(allocation_size, region_tree);
-  PageMemory* storage =
-      SetupPageMemoryInRegion(page_memory_region, 0, payload_size);
-  storage->Commit();
-  return storage;
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/page_memory.h b/third_party/blink/renderer/platform/heap/impl/page_memory.h
deleted file mode 100644
index 2d25530..0000000
--- a/third_party/blink/renderer/platform/heap/impl/page_memory.h
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_
-
-#include "base/atomic_ref_count.h"
-#include "base/containers/flat_map.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class RegionTree;
-
-class MemoryRegion {
-  USING_FAST_MALLOC(MemoryRegion);
-
- public:
-  MemoryRegion(Address base, size_t size) : base_(base), size_(size) {
-    DCHECK_GT(size, 0u);
-  }
-
-  bool Contains(ConstAddress addr) const {
-    return base_ <= addr && addr < (base_ + size_);
-  }
-
-  bool Contains(const MemoryRegion& other) const {
-    return Contains(other.base_) && Contains(other.base_ + other.size_ - 1);
-  }
-
-  void Release();
-  void Commit();
-  void Decommit();
-
-  Address Base() const { return base_; }
-  size_t size() const { return size_; }
-
- private:
-  Address base_;
-  size_t size_;
-};
-
-// A PageMemoryRegion represents a chunk of reserved virtual address
-// space containing a number of blink heap pages. On Windows, reserved
-// virtual address space can only be given back to the system as a
-// whole. The PageMemoryRegion allows us to do that by keeping track
-// of the number of pages using it in order to be able to release all
-// of the virtual address space when there are no more pages using it.
-class PageMemoryRegion : public MemoryRegion {
- public:
-  ~PageMemoryRegion();
-
-  void PageDeleted(Address);
-
-  void MarkPageUsed(Address page) {
-    DCHECK(!in_use_[Index(page)]);
-    in_use_[Index(page)] = true;
-  }
-
-  void MarkPageUnused(Address page) { in_use_[Index(page)] = false; }
-
-  static PageMemoryRegion* AllocateLargePage(size_t size,
-                                             RegionTree* region_tree) {
-    return Allocate(size, 1, region_tree);
-  }
-
-  static PageMemoryRegion* AllocateNormalPages(RegionTree* region_tree) {
-    return Allocate(kBlinkPageSize * kBlinkPagesPerRegion, kBlinkPagesPerRegion,
-                    region_tree);
-  }
-
-  BasePage* PageFromAddress(ConstAddress address) {
-    DCHECK(Contains(address));
-    if (!in_use_[Index(address)])
-      return nullptr;
-    if (is_large_page_)
-      return PageFromObject(Base());
-    return PageFromObject(address);
-  }
-
- private:
-  PageMemoryRegion(Address base, size_t, unsigned num_pages, RegionTree*);
-
-  unsigned Index(ConstAddress address) const {
-    DCHECK(Contains(address));
-    if (is_large_page_)
-      return 0;
-    size_t offset = BlinkPageAddress(const_cast<Address>(address)) - Base();
-    DCHECK_EQ(offset % kBlinkPageSize, 0u);
-    return static_cast<unsigned>(offset / kBlinkPageSize);
-  }
-
-  static PageMemoryRegion* Allocate(size_t, unsigned num_pages, RegionTree*);
-
-  const bool is_large_page_;
-  // A thread owns a page, but not a region. Represent the in-use
-  // bitmap such that thread non-interference comes for free.
-  bool in_use_[kBlinkPagesPerRegion];
-  base::AtomicRefCount num_pages_;
-  RegionTree* const region_tree_;
-};
-
-// A RegionTree is a simple binary search tree of PageMemoryRegions sorted
-// by base addresses.
-class RegionTree {
-  USING_FAST_MALLOC(RegionTree);
-
- public:
-  void Add(PageMemoryRegion*);
-  void Remove(PageMemoryRegion*);
-  PageMemoryRegion* Lookup(ConstAddress);
-
- private:
-  // Using flat_map allows to improve locality to minimize cache misses and
-  // balance binary lookup.
-  base::flat_map<ConstAddress, PageMemoryRegion*> set_;
-};
-
-// Representation of the memory used for a Blink heap page.
-//
-// The representation keeps track of two memory regions:
-//
-// 1. The virtual memory reserved from the system in order to be able
-//    to free all the virtual memory reserved.  Multiple PageMemory
-//    instances can share the same reserved memory region and
-//    therefore notify the reserved memory region on destruction so
-//    that the system memory can be given back when all PageMemory
-//    instances for that memory are gone.
-//
-// 2. The writable memory (a sub-region of the reserved virtual
-//    memory region) that is used for the actual heap page payload.
-//
-// Guard pages are created before and after the writable memory.
-class PageMemory {
-  USING_FAST_MALLOC(PageMemory);
-
- public:
-  ~PageMemory() {
-    __lsan_unregister_root_region(writable_.Base(), writable_.size());
-    reserved_->PageDeleted(WritableStart());
-  }
-
-  void Commit() {
-    reserved_->MarkPageUsed(WritableStart());
-    writable_.Commit();
-  }
-
-  void Decommit() {
-    reserved_->MarkPageUnused(WritableStart());
-    writable_.Decommit();
-  }
-
-  void MarkUnused() { reserved_->MarkPageUnused(WritableStart()); }
-
-  PageMemoryRegion* Region() { return reserved_; }
-
-  Address WritableStart() { return writable_.Base(); }
-
-  static PageMemory* SetupPageMemoryInRegion(PageMemoryRegion*,
-                                             size_t page_offset,
-                                             size_t payload_size);
-
-  // Allocate a virtual address space for one blink page with the
-  // following layout:
-  //
-  //    [ guard os page | ... payload ... | guard os page ]
-  //    ^---{ aligned to blink page size }
-  //
-  // The returned page memory region will be zeroed.
-  //
-  static PageMemory* Allocate(size_t payload_size, RegionTree*);
-
- private:
-  PageMemory(PageMemoryRegion* reserved, const MemoryRegion& writable);
-
-  PageMemoryRegion* reserved_;
-  MemoryRegion writable_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_MEMORY_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/page_pool.cc b/third_party/blink/renderer/platform/heap/impl/page_pool.cc
deleted file mode 100644
index 94360c2..0000000
--- a/third_party/blink/renderer/platform/heap/impl/page_pool.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/page_pool.h"
-
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/impl/page_memory.h"
-
-namespace blink {
-
-PagePool::PagePool() {
-  for (int i = 0; i < BlinkGC::kNumberOfArenas; ++i) {
-    pool_[i] = nullptr;
-  }
-}
-
-PagePool::~PagePool() {
-  for (int index = 0; index < BlinkGC::kNumberOfArenas; ++index) {
-    while (PoolEntry* entry = pool_[index]) {
-      pool_[index] = entry->next;
-      PageMemory* memory = entry->data;
-      DCHECK(memory);
-      delete memory;
-      delete entry;
-    }
-  }
-}
-
-void PagePool::Add(int index, PageMemory* memory) {
-  // When adding a page to the pool we decommit it to ensure it is unused
-  // while in the pool.  This also allows the physical memory, backing the
-  // page, to be given back to the OS.
-  memory->Decommit();
-  PoolEntry* entry = new PoolEntry(memory, pool_[index]);
-  pool_[index] = entry;
-}
-
-PageMemory* PagePool::Take(int index) {
-  if (PoolEntry* entry = pool_[index]) {
-    pool_[index] = entry->next;
-    PageMemory* memory = entry->data;
-    DCHECK(memory);
-    delete entry;
-    memory->Commit();
-    return memory;
-  }
-  return nullptr;
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/page_pool.h b/third_party/blink/renderer/platform/heap/impl/page_pool.h
deleted file mode 100644
index fdf448f..0000000
--- a/third_party/blink/renderer/platform/heap/impl/page_pool.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_POOL_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_POOL_H_
-
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class PageMemory;
-
-// Once pages have been used for one type of thread heap they will never be
-// reused for another type of thread heap.  Instead of unmapping, we add the
-// pages to a pool of pages to be reused later by a thread heap of the same
-// type. This is done as a security feature to avoid type confusion.  The
-// heaps are type segregated by having separate thread arenas for different
-// types of objects.  Holding on to pages ensures that the same virtual address
-// space cannot be used for objects of another type than the type contained
-// in this page to begin with.
-class PagePool {
-  USING_FAST_MALLOC(PagePool);
-
- public:
-  PagePool();
-  ~PagePool();
-  void Add(int, PageMemory*);
-  PageMemory* Take(int);
-
- private:
-  class PoolEntry {
-    USING_FAST_MALLOC(PoolEntry);
-
-   public:
-    PoolEntry(PageMemory* data, PoolEntry* next) : data(data), next(next) {}
-
-    PageMemory* data;
-    PoolEntry* next;
-  };
-
-  PoolEntry* pool_[BlinkGC::kNumberOfArenas];
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PAGE_POOL_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/persistent.h b/third_party/blink/renderer/platform/heap/impl/persistent.h
deleted file mode 100644
index 4a7328b..0000000
--- a/third_party/blink/renderer/platform/heap/impl/persistent.h
+++ /dev/null
@@ -1,865 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_H_
-
-#include "base/bind.h"
-#include "base/dcheck_is_on.h"
-#include "base/location.h"
-#include "third_party/blink/renderer/platform/bindings/buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
-#include "third_party/blink/renderer/platform/heap/impl/persistent_node.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
-
-namespace blink {
-
-template <typename T>
-class CrossThreadWeakPersistent;
-
-// Wrapping type to force callers to go through macros that expand or drop
-// base::Location. This is needed to avoid adding the strings when not needed.
-// The type can be dropped once http://crbug.com/760702 is resolved and
-// ENABLE_LOCATION_SOURCE is disabled for release builds.
-class PersistentLocation final {
- public:
-  PersistentLocation() = default;
-  explicit PersistentLocation(const base::Location& location)
-      : location_(location) {}
-  PersistentLocation(const PersistentLocation& other) = default;
-
-  const base::Location& get() const { return location_; }
-
- private:
-  base::Location location_;
-};
-
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-#define PERSISTENT_FROM_HERE PersistentLocation(base::Location::Current())
-#else  // !RAW_HEAP_SNAPSHOTS
-#define PERSISTENT_FROM_HERE PersistentLocation()
-#endif  // !RAW_HEAP_SNAPSHOTS
-
-template <typename T,
-          WeaknessPersistentConfiguration weaknessConfiguration,
-          CrossThreadnessPersistentConfiguration crossThreadnessConfiguration>
-class PersistentBase {
-  USING_FAST_MALLOC(PersistentBase);
-
- public:
-  bool IsHashTableDeletedValue() const {
-    return raw_ == reinterpret_cast<T*>(-1);
-  }
-
-  T* Release() {
-    T* result = raw_;
-    AssignSafe(nullptr);
-    return result;
-  }
-
-  void Clear() {
-    // Note that this also frees up related data in the backend.
-    AssignSafe(nullptr);
-  }
-
-  T* Get() const {
-    CheckPointer();
-    return raw_;
-  }
-
-  explicit operator bool() const { return Get(); }
-  T& operator*() const { return *Get(); }
-  operator T*() const { return Get(); }
-  T* operator->() const { return Get(); }
-
-  NO_SANITIZE_ADDRESS
-  void ClearWithLockHeld() {
-    static_assert(
-        crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
-        "This Persistent does not require the cross-thread lock.");
-    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
-    raw_ = nullptr;
-    persistent_node_.ClearWithLockHeld();
-  }
-
-  void UpdateLocation(const PersistentLocation& other) {
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-    location_ = other;
-#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-  }
-
- protected:
-  ~PersistentBase() {
-    UninitializeSafe();
-    // Not resetting raw_ as it is not observable.
-  }
-
-  PersistentBase() : raw_(nullptr) {
-    SaveCreationThreadHeap();
-    // No initialization needed for empty handle.
-  }
-  PersistentBase(const PersistentLocation& location) : PersistentBase() {
-    UpdateLocation(location);
-  }
-
-  PersistentBase(std::nullptr_t) : raw_(nullptr) {
-    SaveCreationThreadHeap();
-    // No initialization needed for empty handle.
-  }
-  PersistentBase(const PersistentLocation& location, std::nullptr_t)
-      : PersistentBase(nullptr) {
-    UpdateLocation(location);
-  }
-
-  PersistentBase(T* raw) : raw_(raw) {
-    SaveCreationThreadHeap();
-    InitializeSafe();
-    CheckPointer();
-  }
-  PersistentBase(const PersistentLocation& location, T* raw)
-      : PersistentBase(raw) {
-    UpdateLocation(location);
-  }
-
-  PersistentBase(T& raw) : raw_(&raw) {
-    SaveCreationThreadHeap();
-    InitializeSafe();
-    CheckPointer();
-  }
-  PersistentBase(const PersistentLocation& location, T& raw)
-      : PersistentBase(raw) {
-    UpdateLocation(location);
-  }
-
-  PersistentBase(const PersistentBase& other) : raw_(other) {
-    SaveCreationThreadHeap();
-    InitializeSafe();
-    CheckPointer();
-  }
-  PersistentBase(const PersistentLocation& location, PersistentBase& other)
-      : PersistentBase(other) {
-    UpdateLocation(location);
-  }
-
-  template <typename U>
-  PersistentBase(const PersistentBase<U,
-                                      weaknessConfiguration,
-                                      crossThreadnessConfiguration>& other)
-      : raw_(other) {
-    SaveCreationThreadHeap();
-    InitializeSafe();
-    CheckPointer();
-  }
-  template <typename U>
-  PersistentBase(const PersistentLocation& location,
-                 const PersistentBase<U,
-                                      weaknessConfiguration,
-                                      crossThreadnessConfiguration>& other)
-      : PersistentBase(other) {
-    UpdateLocation(location);
-  }
-
-  template <typename U>
-  PersistentBase(const Member<U>& other) : raw_(other) {
-    SaveCreationThreadHeap();
-    InitializeSafe();
-    CheckPointer();
-  }
-  template <typename U>
-  PersistentBase(const PersistentLocation& location, const Member<U>& other)
-      : PersistentBase(other) {
-    UpdateLocation(location);
-  }
-
-  PersistentBase(WTF::HashTableDeletedValueType)
-      : raw_(reinterpret_cast<T*>(-1)) {
-    SaveCreationThreadHeap();
-    // No initialization needed for empty handle.
-  }
-  PersistentBase(const PersistentLocation& location,
-                 WTF::HashTableDeletedValueType)
-      : PersistentBase(WTF::kHashTableDeletedValue) {
-    UpdateLocation(location);
-  }
-
-  template <typename U>
-  PersistentBase& operator=(U* other) {
-    AssignSafe(other);
-    return *this;
-  }
-
-  PersistentBase& operator=(std::nullptr_t) {
-    AssignSafe(nullptr);
-    return *this;
-  }
-
-  template <typename U>
-  PersistentBase& operator=(const Member<U>& other) {
-    AssignSafe(other);
-    return *this;
-  }
-
-  // Using unsafe operations and assuming that caller acquires the lock for
-  // kCrossThreadPersistentConfiguration configuration.
-  PersistentBase& operator=(const PersistentBase& other) {
-    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
-    AssignUnsafe(other);
-    return *this;
-  }
-
-  // Using unsafe operations and assuming that caller acquires the lock for
-  // kCrossThreadPersistentConfiguration configuration.
-  template <typename U>
-  PersistentBase& operator=(
-      const PersistentBase<U,
-                           weaknessConfiguration,
-                           crossThreadnessConfiguration>& other) {
-    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
-    AssignUnsafe(static_cast<T*>(other.Get()));
-    return *this;
-  }
-
-  // Using unsafe operations and assuming that caller acquires the lock for
-  // kCrossThreadPersistentConfiguration configuration.
-  template <typename U>
-  PersistentBase& operator=(
-      PersistentBase<U, weaknessConfiguration, crossThreadnessConfiguration>&&
-          other) {
-    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
-    if (persistent_node_.IsInitialized()) {
-      // Drop persistent node if present as it's always possible to reuse the
-      // node (if present) from |other|.
-      persistent_node_.Uninitialize();
-    }
-    // Explicit cast enabling downcasting.
-    raw_ = static_cast<T*>(other.raw_);
-    other.raw_ = nullptr;
-    // Efficiently move by just rewiring the node pointer.
-    persistent_node_ = std::move(other.persistent_node_);
-    DCHECK(!other.persistent_node_.Get());
-    if (persistent_node_.IsInitialized()) {
-      // If |raw_| points to a non-null or deleted value, just reuse the node.
-      TraceCallback trace_callback =
-          TraceMethodDelegate<PersistentBase,
-                              &PersistentBase::TracePersistent>::Trampoline;
-      persistent_node_.Get()->Reinitialize(this, trace_callback);
-    }
-    CheckPointer();
-    return *this;
-  }
-
-  NO_SANITIZE_ADDRESS
-  bool IsNotNull() const { return raw_; }
-
-  NO_SANITIZE_ADDRESS
-  void AssignSafe(T* ptr) {
-    typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
-    AssignUnsafe(ptr);
-  }
-
-  NO_SANITIZE_ADDRESS
-  void AssignUnsafe(T* ptr) {
-    raw_ = ptr;
-    CheckPointer();
-    if (raw_ && !IsHashTableDeletedValue()) {
-      if (!persistent_node_.IsInitialized())
-        InitializeUnsafe();
-      return;
-    }
-    UninitializeUnsafe();
-  }
-
-  void TracePersistent(Visitor* visitor) const {
-    static_assert(sizeof(T), "T must be fully defined");
-    static_assert(IsGarbageCollectedType<T>::value,
-                  "T needs to be a garbage collected object");
-    DCHECK(!IsHashTableDeletedValue());
-    if (weaknessConfiguration == kWeakPersistentConfiguration) {
-      visitor->RegisterWeakCallback(HandleWeakPersistent, this);
-    } else {
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-      visitor->TraceRoot(raw_, location_.get());
-#else
-      visitor->TraceRoot(raw_, base::Location());
-#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-    }
-  }
-
-  NO_SANITIZE_ADDRESS
-  void InitializeSafe() {
-    DCHECK(!persistent_node_.IsInitialized());
-    if (!raw_ || IsHashTableDeletedValue())
-      return;
-
-    TraceCallback trace_callback =
-        TraceMethodDelegate<PersistentBase,
-                            &PersistentBase::TracePersistent>::Trampoline;
-    typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
-    persistent_node_.Initialize(this, trace_callback);
-  }
-
-  NO_SANITIZE_ADDRESS
-  void InitializeUnsafe() {
-    DCHECK(!persistent_node_.IsInitialized());
-    if (!raw_ || IsHashTableDeletedValue())
-      return;
-
-    TraceCallback trace_callback =
-        TraceMethodDelegate<PersistentBase,
-                            &PersistentBase::TracePersistent>::Trampoline;
-    persistent_node_.Initialize(this, trace_callback);
-  }
-
-  void UninitializeSafe() {
-    if (persistent_node_.IsInitialized()) {
-      typename PersistentMutexTraits<crossThreadnessConfiguration>::Locker lock;
-      persistent_node_.Uninitialize();
-    }
-  }
-
-  void UninitializeUnsafe() {
-    if (persistent_node_.IsInitialized())
-      persistent_node_.Uninitialize();
-  }
-
-  void CheckPointer() const {
-#if DCHECK_IS_ON()
-    if (!raw_ || IsHashTableDeletedValue())
-      return;
-
-    if (crossThreadnessConfiguration != kCrossThreadPersistentConfiguration) {
-      ThreadState* current = ThreadState::Current();
-      DCHECK(current);
-      // m_creationThreadState may be null when this is used in a heap
-      // collection which initialized the Persistent with memset and the
-      // constructor wasn't called.
-      if (creation_thread_state_) {
-        // Member should point to objects that belong in the same ThreadHeap.
-        DCHECK_EQ(&ThreadState::FromObject(raw_)->Heap(),
-                  &creation_thread_state_->Heap());
-        // Member should point to objects that belong in the same ThreadHeap.
-        DCHECK_EQ(&current->Heap(), &creation_thread_state_->Heap());
-      }
-    }
-#endif
-  }
-
-  void SaveCreationThreadHeap() {
-#if DCHECK_IS_ON()
-    if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) {
-      creation_thread_state_ = nullptr;
-    } else {
-      creation_thread_state_ = ThreadState::Current();
-      DCHECK(creation_thread_state_);
-    }
-#endif
-  }
-
-  static void HandleWeakPersistent(const LivenessBroker& broker,
-                                   const void* persistent_pointer) {
-    using Base =
-        PersistentBase<typename std::remove_const<T>::type,
-                       weaknessConfiguration, crossThreadnessConfiguration>;
-    Base* persistent =
-        reinterpret_cast<Base*>(const_cast<void*>(persistent_pointer));
-    T* object = persistent->Get();
-    if (object && !broker.IsHeapObjectAlive(object))
-      ClearWeakPersistent(persistent);
-  }
-
-  static void ClearWeakPersistent(
-      PersistentBase<std::remove_const_t<T>,
-                     kWeakPersistentConfiguration,
-                     kCrossThreadPersistentConfiguration>* persistent) {
-    PersistentMutexTraits<crossThreadnessConfiguration>::AssertAcquired();
-    persistent->ClearWithLockHeld();
-  }
-
-  static void ClearWeakPersistent(
-      PersistentBase<std::remove_const_t<T>,
-                     kWeakPersistentConfiguration,
-                     kSingleThreadPersistentConfiguration>* persistent) {
-    persistent->Clear();
-  }
-
-  template <typename BadPersistent>
-  static void ClearWeakPersistent(BadPersistent* non_weak_persistent) {
-    NOTREACHED();
-  }
-
-  // raw_ is accessed most, so put it at the first field.
-  T* raw_;
-
-  // The pointer to the underlying persistent node.
-  //
-  // Since accesses are atomics in the cross-thread case, a different type is
-  // needed to prevent the compiler producing an error when it encounters
-  // operations that are legal on raw pointers but not on atomics, or
-  // vice-versa.
-  std::conditional_t<
-      crossThreadnessConfiguration == kCrossThreadPersistentConfiguration,
-      CrossThreadPersistentNodePtr<weaknessConfiguration>,
-      PersistentNodePtr<ThreadingTrait<T>::kAffinity, weaknessConfiguration>>
-      persistent_node_;
-
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-  PersistentLocation location_;
-#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-
-#if DCHECK_IS_ON()
-  const ThreadState* creation_thread_state_;
-#endif
-
-  template <typename F,
-            WeaknessPersistentConfiguration,
-            CrossThreadnessPersistentConfiguration>
-  friend class PersistentBase;
-};
-
-// Persistent is a way to create a strong pointer from an off-heap object
-// to another on-heap object. As long as the Persistent handle is alive
-// the GC will keep the object pointed to alive. The Persistent handle is
-// always a GC root from the point of view of the GC.
-//
-// We have to construct and destruct Persistent in the same thread.
-template <typename T>
-class Persistent : public PersistentBase<T,
-                                         kNonWeakPersistentConfiguration,
-                                         kSingleThreadPersistentConfiguration> {
-  using Parent = PersistentBase<T,
-                                kNonWeakPersistentConfiguration,
-                                kSingleThreadPersistentConfiguration>;
-
- public:
-  Persistent() : Parent() {}
-  Persistent(const PersistentLocation& location) : Parent(location) {}
-  Persistent(std::nullptr_t) : Parent(nullptr) {}
-  Persistent(const PersistentLocation& location, std::nullptr_t)
-      : Parent(location, nullptr) {}
-  Persistent(T* raw) : Parent(raw) {}
-  Persistent(const PersistentLocation& location, T* raw)
-      : Parent(location, raw) {}
-  Persistent(T& raw) : Parent(raw) {}
-  Persistent(const PersistentLocation& location, T& raw)
-      : Parent(location, raw) {}
-  Persistent(const Persistent& other) : Parent(other) {}
-  Persistent(const PersistentLocation& location, const Persistent& other)
-      : Parent(location, other) {}
-  template <typename U>
-  Persistent(const Persistent<U>& other) : Parent(other) {}
-  template <typename U>
-  Persistent(const PersistentLocation& location, const Persistent<U>& other)
-      : Parent(location, other) {}
-  template <typename U>
-  Persistent(const Member<U>& other) : Parent(other) {}
-  template <typename U>
-  Persistent(const PersistentLocation& location, const Member<U>& other)
-      : Parent(location, other) {}
-  Persistent(WTF::HashTableDeletedValueType x) : Parent(x) {}
-  Persistent(const PersistentLocation& location,
-             WTF::HashTableDeletedValueType x)
-      : Parent(location, x) {}
-
-  template <typename U>
-  Persistent& operator=(U* other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  Persistent& operator=(std::nullptr_t) {
-    Parent::operator=(nullptr);
-    return *this;
-  }
-
-  Persistent& operator=(const Persistent& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  Persistent& operator=(const Persistent<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  Persistent& operator=(const Member<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-};
-
-// WeakPersistent is a way to create a weak pointer from an off-heap object
-// to an on-heap object. The m_raw is automatically cleared when the pointee
-// gets collected.
-//
-// We have to construct and destruct WeakPersistent in the same thread.
-//
-// Note that collections of WeakPersistents are not supported. Use a collection
-// of WeakMembers instead.
-//
-//   HashSet<WeakPersistent<T>> m_set; // wrong
-//   Persistent<HeapHashSet<WeakMember<T>>> m_set; // correct
-template <typename T>
-class WeakPersistent
-    : public PersistentBase<T,
-                            kWeakPersistentConfiguration,
-                            kSingleThreadPersistentConfiguration> {
-  using Parent = PersistentBase<T,
-                                kWeakPersistentConfiguration,
-                                kSingleThreadPersistentConfiguration>;
-
- public:
-  WeakPersistent() : Parent() {}
-  WeakPersistent(std::nullptr_t) : Parent(nullptr) {}
-  WeakPersistent(T* raw) : Parent(raw) {}
-  WeakPersistent(T& raw) : Parent(raw) {}
-  WeakPersistent(const WeakPersistent& other) : Parent(other) {}
-  template <typename U>
-  WeakPersistent(const WeakPersistent<U>& other) : Parent(other) {}
-  template <typename U>
-  WeakPersistent(const Member<U>& other) : Parent(other) {}
-
-  template <typename U>
-  WeakPersistent& operator=(U* other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  WeakPersistent& operator=(std::nullptr_t) {
-    Parent::operator=(nullptr);
-    return *this;
-  }
-
-  WeakPersistent& operator=(const WeakPersistent& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  WeakPersistent& operator=(const WeakPersistent<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  WeakPersistent& operator=(const Member<U>& other) {
-    Parent::operator=(other);
-    return *this;
-  }
-};
-
-// CrossThreadPersistent allows for holding onto an object strongly on a
-// different thread.
-//
-// Thread-safe operations:
-// - Construction
-// - Destruction
-// - Copy and move construction and assignment
-// - Clearing
-// - Deref if treated as immutable reference or if externally synchronized (e.g.
-//   mutex, task). The current implementation of Get() uses a raw load (on
-//   purpose) which prohibits mutation while accessing the reference on a
-//   different thread.
-template <typename T>
-class CrossThreadPersistent
-    : public PersistentBase<T,
-                            kNonWeakPersistentConfiguration,
-                            kCrossThreadPersistentConfiguration> {
-  using Parent = PersistentBase<T,
-                                kNonWeakPersistentConfiguration,
-                                kCrossThreadPersistentConfiguration>;
-
- public:
-  CrossThreadPersistent() : Parent() {}
-  CrossThreadPersistent(const PersistentLocation& location)
-      : Parent(location) {}
-  CrossThreadPersistent(std::nullptr_t) : Parent(nullptr) {}
-  CrossThreadPersistent(const PersistentLocation& location, std::nullptr_t)
-      : Parent(location, nullptr) {}
-  explicit CrossThreadPersistent(T* raw) : Parent(raw) {}
-  CrossThreadPersistent(const PersistentLocation& location, T* raw)
-      : Parent(location, raw) {}
-  explicit CrossThreadPersistent(T& raw) : Parent(raw) {}
-  CrossThreadPersistent(const PersistentLocation& location, T& raw)
-      : Parent(location, raw) {}
-  CrossThreadPersistent(const CrossThreadPersistent& other) { *this = other; }
-  CrossThreadPersistent(const PersistentLocation& location,
-                        const CrossThreadPersistent& other) {
-    *this = other;
-  }
-  template <typename U>
-  CrossThreadPersistent(const CrossThreadPersistent<U>& other) {
-    *this = other;
-  }
-  template <typename U>
-  CrossThreadPersistent(const PersistentLocation& location,
-                        const CrossThreadPersistent<U>& other) {
-    *this = other;
-  }
-  template <typename U>
-  CrossThreadPersistent(const Member<U>& other) : Parent(other) {}
-  template <typename U>
-  CrossThreadPersistent(const PersistentLocation& location,
-                        const Member<U>& other)
-      : Parent(location, other) {}
-  CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) {}
-  CrossThreadPersistent(const PersistentLocation& location,
-                        WTF::HashTableDeletedValueType x)
-      : Parent(location, x) {}
-  template <typename U>
-  CrossThreadPersistent(const CrossThreadWeakPersistent<U>& other) {
-    *this = other;
-  }
-
-  // Instead of using release(), assign then clear() instead.
-  // Using release() with per thread heap enabled can cause the object to be
-  // destroyed before assigning it to a new handle.
-  T* Release() = delete;
-
-  template <typename U>
-  CrossThreadPersistent& operator=(U* other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  CrossThreadPersistent& operator=(std::nullptr_t) {
-    Parent::operator=(nullptr);
-    return *this;
-  }
-
-  CrossThreadPersistent& operator=(const CrossThreadPersistent& other) {
-    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  CrossThreadPersistent& operator=(const CrossThreadPersistent<U>& other) {
-    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  CrossThreadPersistent& operator=(const CrossThreadWeakPersistent<U>&);
-};
-
-// CrossThreadWeakPersistent combines behavior of CrossThreadPersistent and
-// WeakPersistent, i.e., it allows holding onto an object weakly on a different
-// thread.
-//
-// Thread-safe operations:
-// - Construction
-// - Destruction
-// - Copy and move construction and assignment
-// - Clearing
-//
-// Note that this does not include dereferencing and using the raw pointer as
-// there is no guarantee that the object will be alive at the time it is used.
-template <typename T>
-class CrossThreadWeakPersistent
-    : public PersistentBase<T,
-                            kWeakPersistentConfiguration,
-                            kCrossThreadPersistentConfiguration> {
-  using Parent = PersistentBase<T,
-                                kWeakPersistentConfiguration,
-                                kCrossThreadPersistentConfiguration>;
-
- public:
-  CrossThreadWeakPersistent() : Parent() {}
-  explicit CrossThreadWeakPersistent(T* raw) : Parent(raw) {}
-  explicit CrossThreadWeakPersistent(T& raw) : Parent(raw) {}
-  CrossThreadWeakPersistent(const CrossThreadWeakPersistent& other) {
-    *this = other;
-  }
-  template <typename U>
-  CrossThreadWeakPersistent(const CrossThreadWeakPersistent<U>& other) {
-    *this = other;
-  }
-  CrossThreadWeakPersistent(CrossThreadWeakPersistent&& other) {
-    *this = std::move(other);
-  }
-  template <typename U>
-  CrossThreadWeakPersistent(CrossThreadWeakPersistent<U>&& other) {
-    *this = std::move(other);
-  }
-
-  CrossThreadWeakPersistent& operator=(const CrossThreadWeakPersistent& other) {
-    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
-    Parent::operator=(other);
-    return *this;
-  }
-
-  template <typename U>
-  CrossThreadWeakPersistent& operator=(
-      const CrossThreadWeakPersistent<U>& other) {
-    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
-    Parent::operator=(other);
-    return *this;
-  }
-
-  CrossThreadWeakPersistent& operator=(CrossThreadWeakPersistent&& other) {
-    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
-    Parent::operator=(std::move(other));
-    return *this;
-  }
-
-  template <typename U>
-  CrossThreadWeakPersistent& operator=(CrossThreadWeakPersistent<U>&& other) {
-    MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
-    Parent::operator=(std::move(other));
-    return *this;
-  }
-
-  template <typename U>
-  CrossThreadWeakPersistent& operator=(U* other) {
-    Parent::operator=(other);
-    return *this;
-  }
-
-  // Create a CrossThreadPersistent that keeps the underlying object alive if
-  // there is still on set. Can be used to work with an object on a different
-  // thread than it was allocated. Note that CTP does not block threads from
-  // terminating, in which case the reference would still be invalid.
-  const CrossThreadPersistent<T> Lock() const {
-    return CrossThreadPersistent<T>(*this);
-  }
-
-  // Disallow directly using CrossThreadWeakPersistent. Users must go through
-  // CrossThreadPersistent to access the pointee. Note that this does not
-  // guarantee that the object is still alive at that point. Users must check
-  // the state of CTP manually before invoking any calls.
-  T* operator->() const = delete;
-  T& operator*() const = delete;
-  operator T*() const = delete;
-  T* Get() const = delete;
-
- private:
-  template <typename U>
-  friend class CrossThreadPersistent;
-};
-
-template <typename T>
-template <typename U>
-CrossThreadPersistent<T>& CrossThreadPersistent<T>::operator=(
-    const CrossThreadWeakPersistent<U>& other) {
-  MutexLocker locker(ProcessHeap::CrossThreadPersistentMutex());
-  using ParentU = PersistentBase<U, kWeakPersistentConfiguration,
-                                 kCrossThreadPersistentConfiguration>;
-  this->AssignUnsafe(static_cast<const ParentU&>(other).Get());
-  return *this;
-}
-
-template <typename T>
-Persistent<T> WrapPersistentInternal(const PersistentLocation& location,
-                                     T* value) {
-  return Persistent<T>(location, value);
-}
-
-template <typename T>
-Persistent<T> WrapPersistentInternal(T* value) {
-  return Persistent<T>(value);
-}
-
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-#define WrapPersistent(value) \
-  WrapPersistentInternal(PERSISTENT_FROM_HERE, value)
-#else
-#define WrapPersistent(value) WrapPersistentInternal(value)
-#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-
-template <typename T>
-WeakPersistent<T> WrapWeakPersistent(T* value) {
-  return WeakPersistent<T>(value);
-}
-
-template <typename T>
-CrossThreadPersistent<T> WrapCrossThreadPersistentInternal(
-    const PersistentLocation& location,
-    T* value) {
-  return CrossThreadPersistent<T>(location, value);
-}
-
-template <typename T>
-CrossThreadPersistent<T> WrapCrossThreadPersistentInternal(T* value) {
-  return CrossThreadPersistent<T>(value);
-}
-
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-#define WrapCrossThreadPersistent(value) \
-  WrapCrossThreadPersistentInternal(PERSISTENT_FROM_HERE, value)
-#else
-#define WrapCrossThreadPersistent(value) \
-  WrapCrossThreadPersistentInternal(value)
-#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-
-template <typename T>
-CrossThreadWeakPersistent<T> WrapCrossThreadWeakPersistent(T* value) {
-  return CrossThreadWeakPersistent<T>(value);
-}
-
-// Comparison operators between (Weak)Members, Persistents, and UntracedMembers.
-template <typename T, typename U>
-inline bool operator==(const Member<T>& a, const Member<U>& b) {
-  return a.Get() == b.Get();
-}
-template <typename T, typename U>
-inline bool operator!=(const Member<T>& a, const Member<U>& b) {
-  return a.Get() != b.Get();
-}
-template <typename T, typename U>
-inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) {
-  return a.Get() == b.Get();
-}
-template <typename T, typename U>
-inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) {
-  return a.Get() != b.Get();
-}
-
-template <typename T, typename U>
-inline bool operator==(const Member<T>& a, const Persistent<U>& b) {
-  return a.Get() == b.Get();
-}
-template <typename T, typename U>
-inline bool operator!=(const Member<T>& a, const Persistent<U>& b) {
-  return a.Get() != b.Get();
-}
-template <typename T, typename U>
-inline bool operator==(const Persistent<T>& a, const Member<U>& b) {
-  return a.Get() == b.Get();
-}
-template <typename T, typename U>
-inline bool operator!=(const Persistent<T>& a, const Member<U>& b) {
-  return a.Get() != b.Get();
-}
-
-template <typename U, typename T>
-Persistent<U> DownCast(const Persistent<T>& p) {
-  return Persistent<U>(p);
-}
-
-template <typename U, typename T>
-WeakPersistent<U> DownCast(const WeakPersistent<T>& p) {
-  return WeakPersistent<U>(p);
-}
-
-template <typename U, typename T>
-CrossThreadPersistent<U> DownCast(const CrossThreadPersistent<T>& p) {
-  return CrossThreadPersistent<U>(p);
-}
-
-template <typename U, typename T>
-CrossThreadWeakPersistent<U> DownCast(const CrossThreadWeakPersistent<T>& p) {
-  return CrossThreadWeakPersistent<U>(p);
-}
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/persistent_node.cc b/third_party/blink/renderer/platform/heap/impl/persistent_node.cc
deleted file mode 100644
index f61c39b..0000000
--- a/third_party/blink/renderer/platform/heap/impl/persistent_node.cc
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/persistent_node.h"
-
-#include "base/debug/alias.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/heap/process_heap.h"
-
-namespace blink {
-
-namespace {
-
-class DummyGCBase final : public GarbageCollected<DummyGCBase> {
- public:
-  void Trace(Visitor* visitor) const {}
-};
-}  // namespace
-
-PersistentRegionBase::~PersistentRegionBase() {
-  PersistentNodeSlots* slots = slots_;
-  while (slots) {
-    PersistentNodeSlots* dead_slots = slots;
-    slots = slots->next;
-    delete dead_slots;
-  }
-}
-
-int PersistentRegionBase::NodesInUse() const {
-  int persistent_count = 0;
-  for (PersistentNodeSlots* slots = slots_; slots; slots = slots->next) {
-    for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) {
-      if (!slots->slot[i].IsUnused())
-        ++persistent_count;
-    }
-  }
-#if DCHECK_IS_ON()
-  DCHECK_EQ(persistent_count, used_node_count_);
-#endif
-  return persistent_count;
-}
-
-void PersistentRegionBase::EnsureNodeSlots() {
-  DCHECK(!free_list_head_);
-  PersistentNodeSlots* slots = new PersistentNodeSlots;
-  for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) {
-    PersistentNode* node = &slots->slot[i];
-    node->SetFreeListNext(free_list_head_);
-    free_list_head_ = node;
-    DCHECK(node->IsUnused());
-  }
-  slots->next = slots_;
-  slots_ = slots;
-}
-
-void PersistentRegionBase::TraceNodesImpl(Visitor* visitor,
-                                          ShouldTraceCallback should_trace) {
-  free_list_head_ = nullptr;
-  int persistent_count = 0;
-  PersistentNodeSlots** prev_next = &slots_;
-  PersistentNodeSlots* slots = slots_;
-  while (slots) {
-    PersistentNode* free_list_next = nullptr;
-    PersistentNode* free_list_last = nullptr;
-    int free_count = 0;
-    for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) {
-      PersistentNode* node = &slots->slot[i];
-      if (node->IsUnused()) {
-        if (!free_list_next)
-          free_list_last = node;
-        node->SetFreeListNext(free_list_next);
-        free_list_next = node;
-        ++free_count;
-      } else {
-        ++persistent_count;
-        if (!should_trace(visitor, node))
-          continue;
-        node->TracePersistentNode(visitor);
-      }
-    }
-    if (free_count == PersistentNodeSlots::kSlotCount) {
-      PersistentNodeSlots* dead_slots = slots;
-      *prev_next = slots->next;
-      slots = slots->next;
-      delete dead_slots;
-    } else {
-      if (free_list_last) {
-        DCHECK(free_list_next);
-        DCHECK(!free_list_last->FreeListNext());
-        free_list_last->SetFreeListNext(free_list_head_);
-        free_list_head_ = free_list_next;
-      }
-      prev_next = &slots->next;
-      slots = slots->next;
-    }
-  }
-#if DCHECK_IS_ON()
-  DCHECK_EQ(persistent_count, used_node_count_);
-#endif
-}
-
-void PersistentRegion::ReleaseNode(PersistentNode* persistent_node) {
-  DCHECK(!persistent_node->IsUnused());
-  // 'self' is in use, containing the persistent wrapper object.
-  void* self = persistent_node->Self();
-  Persistent<DummyGCBase>* persistent =
-      reinterpret_cast<Persistent<DummyGCBase>*>(self);
-  persistent->Clear();
-  DCHECK(persistent_node->IsUnused());
-}
-
-void PersistentRegion::PrepareForThreadStateTermination(ThreadState* state) {
-  DCHECK_EQ(state, ThreadState::Current());
-  DCHECK(!IsMainThread());
-  PersistentNodeSlots* slots = slots_;
-  while (slots) {
-    for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) {
-      PersistentNode* node = &slots->slot[i];
-      if (node->IsUnused())
-        continue;
-      // It is safe to cast to Persistent<DummyGCBase> because persistent heap
-      // collections are banned in non-main threads.
-      Persistent<DummyGCBase>* persistent =
-          reinterpret_cast<Persistent<DummyGCBase>*>(node->Self());
-      DCHECK(persistent);
-      persistent->Clear();
-      DCHECK(node->IsUnused());
-    }
-    slots = slots->next;
-  }
-#if DCHECK_IS_ON()
-  DCHECK_EQ(used_node_count_, 0);
-#endif
-}
-
-bool CrossThreadPersistentRegion::ShouldTracePersistentNode(
-    Visitor* visitor,
-    PersistentNode* node) {
-  CrossThreadPersistent<DummyGCBase>* persistent =
-      reinterpret_cast<CrossThreadPersistent<DummyGCBase>*>(node->Self());
-  DCHECK(persistent);
-  DCHECK(!persistent->IsHashTableDeletedValue());
-  Address raw_object = reinterpret_cast<Address>(persistent->Get());
-  if (!raw_object)
-    return false;
-  return &visitor->Heap() == &ThreadState::FromObject(raw_object)->Heap();
-}
-
-void CrossThreadPersistentRegion::PrepareForThreadStateTermination(
-    ThreadState* thread_state) {
-  // For heaps belonging to a thread that's detaching, any cross-thread
-  // persistents pointing into them needs to be disabled. Do that by clearing
-  // out the underlying heap reference.
-  MutexLocker lock(ProcessHeap::CrossThreadPersistentMutex());
-
-  PersistentNodeSlots* slots = slots_;
-  while (slots) {
-    for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) {
-      if (slots->slot[i].IsUnused())
-        continue;
-
-      // 'self' is in use, containing the cross-thread persistent wrapper
-      // object.
-      CrossThreadPersistent<DummyGCBase>* persistent =
-          reinterpret_cast<CrossThreadPersistent<DummyGCBase>*>(
-              slots->slot[i].Self());
-      DCHECK(persistent);
-      void* raw_object = persistent->Get();
-      if (!raw_object)
-        continue;
-      BasePage* page = PageFromObject(raw_object);
-      DCHECK(page);
-      if (page->Arena()->GetThreadState() == thread_state) {
-        persistent->ClearWithLockHeld();
-        DCHECK(slots->slot[i].IsUnused());
-      }
-    }
-    slots = slots->next;
-  }
-}
-
-#if defined(ADDRESS_SANITIZER)
-void CrossThreadPersistentRegion::UnpoisonCrossThreadPersistents() {
-#if DCHECK_IS_ON()
-  ProcessHeap::CrossThreadPersistentMutex().AssertAcquired();
-#endif
-  int persistent_count = 0;
-  for (PersistentNodeSlots* slots = slots_; slots; slots = slots->next) {
-    for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) {
-      const PersistentNode& node = slots->slot[i];
-      if (!node.IsUnused()) {
-        ASAN_UNPOISON_MEMORY_REGION(node.Self(),
-                                    sizeof(CrossThreadPersistent<void*>));
-        ++persistent_count;
-      }
-    }
-  }
-#if DCHECK_IS_ON()
-  DCHECK_EQ(persistent_count, used_node_count_);
-#endif
-}
-#endif
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/persistent_node.h b/third_party/blink/renderer/platform/heap/impl/persistent_node.h
deleted file mode 100644
index ab99685..0000000
--- a/third_party/blink/renderer/platform/heap/impl/persistent_node.h
+++ /dev/null
@@ -1,386 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_NODE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_NODE_H_
-
-#include <atomic>
-#include <memory>
-
-#include "base/dcheck_is_on.h"
-#include "third_party/blink/renderer/platform/heap/process_heap.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-
-namespace blink {
-
-class CrossThreadPersistentRegion;
-class PersistentRegion;
-
-enum WeaknessPersistentConfiguration {
-  kNonWeakPersistentConfiguration,
-  kWeakPersistentConfiguration
-};
-
-enum CrossThreadnessPersistentConfiguration {
-  kSingleThreadPersistentConfiguration,
-  kCrossThreadPersistentConfiguration
-};
-
-template <CrossThreadnessPersistentConfiguration>
-struct PersistentMutexTraits {
-  struct [[maybe_unused]] Locker{};
-  static void AssertAcquired() {}
-};
-
-template <>
-struct PersistentMutexTraits<kCrossThreadPersistentConfiguration> {
-  struct Locker {
-    MutexLocker locker{ProcessHeap::CrossThreadPersistentMutex()};
-  };
-  static void AssertAcquired() {
-#if DCHECK_IS_ON()
-    ProcessHeap::CrossThreadPersistentMutex().AssertAcquired();
-#endif
-  }
-};
-
-class PersistentNode final {
-  DISALLOW_NEW();
-
- public:
-  PersistentNode() { DCHECK(IsUnused()); }
-
-#if DCHECK_IS_ON()
-  ~PersistentNode() {
-    // If you hit this assert, it means that the thread finished
-    // without clearing persistent handles that the thread created.
-    // We don't enable the assert for the main thread because the
-    // main thread finishes without clearing all persistent handles.
-    DCHECK(IsMainThread() || IsUnused());
-  }
-#endif
-
-  // It is dangerous to copy the PersistentNode because it breaks the
-  // free list.
-  PersistentNode& operator=(const PersistentNode& otherref) = delete;
-
-  // Ideally the trace method should be virtual and automatically dispatch
-  // to the most specific implementation. However having a virtual method
-  // on PersistentNode leads to too eager template instantiation with MSVC
-  // which leads to include cycles.
-  // Instead we call the constructor with a TraceCallback which knows the
-  // type of the most specific child and calls trace directly. See
-  // TraceMethodDelegate in Visitor.h for how this is done.
-  void TracePersistentNode(Visitor* visitor) const {
-    DCHECK(!IsUnused());
-    DCHECK(trace_);
-    trace_(visitor, self_);
-  }
-
-  void Initialize(void* self, TraceCallback trace) {
-    DCHECK(IsUnused());
-    self_ = self;
-    trace_ = trace;
-  }
-
-  void Reinitialize(void* self, TraceCallback trace) {
-    self_ = self;
-    trace_ = trace;
-  }
-
-  void SetFreeListNext(PersistentNode* node) {
-    DCHECK(!node || node->IsUnused());
-    self_ = node;
-    trace_ = nullptr;
-    DCHECK(IsUnused());
-  }
-
-  PersistentNode* FreeListNext() {
-    DCHECK(IsUnused());
-    PersistentNode* node = reinterpret_cast<PersistentNode*>(self_);
-    DCHECK(!node || node->IsUnused());
-    return node;
-  }
-
-  bool IsUnused() const { return !trace_; }
-
-  void* Self() const { return self_; }
-
- private:
-  // If this PersistentNode is in use:
-  //   - m_self points to the corresponding Persistent handle.
-  //   - m_trace points to the trace method.
-  // If this PersistentNode is freed:
-  //   - m_self points to the next freed PersistentNode.
-  //   - m_trace is nullptr.
-  void* self_ = nullptr;
-  TraceCallback trace_ = nullptr;
-};
-
-struct PersistentNodeSlots final {
-  USING_FAST_MALLOC(PersistentNodeSlots);
-
- public:
-  static constexpr int kSlotCount = 256;
-
-  PersistentNodeSlots* next;
-  PersistentNode slot[kSlotCount];
-};
-
-// Used by PersistentBase to manage a pointer to a thread heap persistent node.
-// This class mostly passes accesses through, but provides an interface
-// compatible with CrossThreadPersistentNodePtr.
-template <ThreadAffinity affinity,
-          WeaknessPersistentConfiguration weakness_configuration>
-class PersistentNodePtr {
-  STACK_ALLOCATED();
-
- public:
-  PersistentNode* Get() const { return ptr_; }
-  bool IsInitialized() const { return ptr_; }
-
-  void Initialize(void* owner, TraceCallback);
-  void Uninitialize();
-
-  PersistentNodePtr& operator=(PersistentNodePtr&& other) {
-    ptr_ = other.ptr_;
-    other.ptr_ = nullptr;
-    return *this;
-  }
-
- private:
-  PersistentNode* ptr_ = nullptr;
-#if DCHECK_IS_ON()
-  ThreadState* state_ = nullptr;
-#endif
-};
-
-// Used by PersistentBase to manage a pointer to a cross-thread persistent node.
-// It uses ProcessHeap::CrossThreadPersistentMutex() to protect most accesses,
-// but can be polled to see whether it is initialized without the mutex.
-template <WeaknessPersistentConfiguration weakness_configuration>
-class CrossThreadPersistentNodePtr {
-  STACK_ALLOCATED();
-
- public:
-  PersistentNode* Get() const {
-    PersistentMutexTraits<
-        kCrossThreadPersistentConfiguration>::AssertAcquired();
-    return ptr_.load(std::memory_order_relaxed);
-  }
-  bool IsInitialized() const { return ptr_.load(std::memory_order_acquire); }
-
-  void Initialize(void* owner, TraceCallback);
-  void Uninitialize();
-
-  void ClearWithLockHeld();
-
-  CrossThreadPersistentNodePtr& operator=(
-      CrossThreadPersistentNodePtr&& other) {
-    PersistentMutexTraits<
-        kCrossThreadPersistentConfiguration>::AssertAcquired();
-    PersistentNode* node = other.ptr_.load(std::memory_order_relaxed);
-    ptr_.store(node, std::memory_order_relaxed);
-    other.ptr_.store(nullptr, std::memory_order_relaxed);
-    return *this;
-  }
-
- private:
-  // Access must either be protected by the cross-thread persistent mutex or
-  // handle the fact that this may be changed concurrently (with a
-  // release-store).
-  std::atomic<PersistentNode*> ptr_{nullptr};
-};
-
-class PLATFORM_EXPORT PersistentRegionBase {
- public:
-  ~PersistentRegionBase();
-
-  inline PersistentNode* AllocateNode(void* self, TraceCallback trace);
-  inline void FreeNode(PersistentNode* persistent_node);
-  int NodesInUse() const;
-
- protected:
-  using ShouldTraceCallback = bool (*)(Visitor*, PersistentNode*);
-
-  void TraceNodesImpl(Visitor*, ShouldTraceCallback);
-
-  void EnsureNodeSlots();
-
-  PersistentNode* free_list_head_ = nullptr;
-  PersistentNodeSlots* slots_ = nullptr;
-#if DCHECK_IS_ON()
-  int used_node_count_ = 0;
-#endif
-};
-
-inline PersistentNode* PersistentRegionBase::AllocateNode(void* self,
-                                                          TraceCallback trace) {
-#if DCHECK_IS_ON()
-  ++used_node_count_;
-#endif
-  if (UNLIKELY(!free_list_head_))
-    EnsureNodeSlots();
-  DCHECK(free_list_head_);
-  PersistentNode* node = free_list_head_;
-  free_list_head_ = free_list_head_->FreeListNext();
-  node->Initialize(self, trace);
-  DCHECK(!node->IsUnused());
-  return node;
-}
-
-void PersistentRegionBase::FreeNode(PersistentNode* persistent_node) {
-#if DCHECK_IS_ON()
-  DCHECK_GT(used_node_count_, 0);
-#endif
-  persistent_node->SetFreeListNext(free_list_head_);
-  free_list_head_ = persistent_node;
-#if DCHECK_IS_ON()
-  --used_node_count_;
-#endif
-}
-
-class PLATFORM_EXPORT PersistentRegion final : public PersistentRegionBase {
-  USING_FAST_MALLOC(PersistentRegion);
-
- public:
-  inline void TraceNodes(Visitor*);
-
-  // Clears the Persistent and then frees the node.
-  void ReleaseNode(PersistentNode*);
-
-  void PrepareForThreadStateTermination(ThreadState*);
-
- private:
-  static constexpr bool ShouldTracePersistentNode(Visitor*, PersistentNode*) {
-    return true;
-  }
-};
-
-inline void PersistentRegion::TraceNodes(Visitor* visitor) {
-  PersistentRegionBase::TraceNodesImpl(visitor, ShouldTracePersistentNode);
-}
-
-class PLATFORM_EXPORT CrossThreadPersistentRegion final
-    : public PersistentRegionBase {
-  USING_FAST_MALLOC(CrossThreadPersistentRegion);
-
- public:
-  inline PersistentNode* AllocateNode(void* self, TraceCallback trace);
-  inline void FreeNode(PersistentNode*);
-  inline void TraceNodes(Visitor*);
-
-  void PrepareForThreadStateTermination(ThreadState*);
-
-#if defined(ADDRESS_SANITIZER)
-  void UnpoisonCrossThreadPersistents();
-#endif
-
- private:
-  NO_SANITIZE_ADDRESS
-  static bool ShouldTracePersistentNode(Visitor*, PersistentNode*);
-};
-
-inline PersistentNode* CrossThreadPersistentRegion::AllocateNode(
-    void* self,
-    TraceCallback trace) {
-  PersistentMutexTraits<kCrossThreadPersistentConfiguration>::AssertAcquired();
-  return PersistentRegionBase::AllocateNode(self, trace);
-}
-
-inline void CrossThreadPersistentRegion::FreeNode(PersistentNode* node) {
-  PersistentMutexTraits<kCrossThreadPersistentConfiguration>::AssertAcquired();
-  // PersistentBase::UninitializeSafe opportunistically checks for uninitialized
-  // nodes to allow a fast path destruction of unused nodes. This check is
-  // performed without taking the lock that is required for processing a
-  // cross-thread node. After taking the lock the condition needs to checked
-  // again to avoid double-freeing a node because the node may have been
-  // concurrently freed by the garbage collector on another thread.
-  if (!node)
-    return;
-  PersistentRegionBase::FreeNode(node);
-}
-
-inline void CrossThreadPersistentRegion::TraceNodes(Visitor* visitor) {
-  PersistentRegionBase::TraceNodesImpl(visitor, ShouldTracePersistentNode);
-}
-
-template <ThreadAffinity affinity,
-          WeaknessPersistentConfiguration weakness_configuration>
-void PersistentNodePtr<affinity, weakness_configuration>::Initialize(
-    void* owner,
-    TraceCallback trace_callback) {
-  ThreadState* state = ThreadStateFor<affinity>::GetState();
-  DCHECK(state->CheckThread());
-  PersistentRegion* region =
-      weakness_configuration == kWeakPersistentConfiguration
-          ? state->GetWeakPersistentRegion()
-          : state->GetPersistentRegion();
-  ptr_ = region->AllocateNode(owner, trace_callback);
-#if DCHECK_IS_ON()
-  state_ = state;
-#endif
-}
-
-template <ThreadAffinity affinity,
-          WeaknessPersistentConfiguration weakness_configuration>
-void PersistentNodePtr<affinity, weakness_configuration>::Uninitialize() {
-  if (!ptr_)
-    return;
-  ThreadState* state = ThreadStateFor<affinity>::GetState();
-  DCHECK(state->CheckThread());
-#if DCHECK_IS_ON()
-  DCHECK_EQ(state_, state)
-      << "must be initialized and uninitialized on the same thread";
-  state_ = nullptr;
-#endif
-  PersistentRegion* region =
-      weakness_configuration == kWeakPersistentConfiguration
-          ? state->GetWeakPersistentRegion()
-          : state->GetPersistentRegion();
-  region->FreeNode(ptr_);
-  ptr_ = nullptr;
-}
-
-template <WeaknessPersistentConfiguration weakness_configuration>
-void CrossThreadPersistentNodePtr<weakness_configuration>::Initialize(
-    void* owner,
-    TraceCallback trace_callback) {
-  PersistentMutexTraits<kCrossThreadPersistentConfiguration>::AssertAcquired();
-  CrossThreadPersistentRegion& region =
-      weakness_configuration == kWeakPersistentConfiguration
-          ? ProcessHeap::GetCrossThreadWeakPersistentRegion()
-          : ProcessHeap::GetCrossThreadPersistentRegion();
-  PersistentNode* node = region.AllocateNode(owner, trace_callback);
-  ptr_.store(node, std::memory_order_release);
-}
-
-template <WeaknessPersistentConfiguration weakness_configuration>
-void CrossThreadPersistentNodePtr<weakness_configuration>::Uninitialize() {
-  PersistentMutexTraits<kCrossThreadPersistentConfiguration>::AssertAcquired();
-  CrossThreadPersistentRegion& region =
-      weakness_configuration == kWeakPersistentConfiguration
-          ? ProcessHeap::GetCrossThreadWeakPersistentRegion()
-          : ProcessHeap::GetCrossThreadPersistentRegion();
-  region.FreeNode(ptr_.load(std::memory_order_relaxed));
-  ptr_.store(nullptr, std::memory_order_release);
-}
-
-template <WeaknessPersistentConfiguration weakness_configuration>
-void CrossThreadPersistentNodePtr<weakness_configuration>::ClearWithLockHeld() {
-  PersistentMutexTraits<kCrossThreadPersistentConfiguration>::AssertAcquired();
-  CrossThreadPersistentRegion& region =
-      weakness_configuration == kWeakPersistentConfiguration
-          ? ProcessHeap::GetCrossThreadWeakPersistentRegion()
-          : ProcessHeap::GetCrossThreadPersistentRegion();
-  region.FreeNode(ptr_.load(std::memory_order_relaxed));
-  ptr_.store(nullptr, std::memory_order_release);
-}
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PERSISTENT_NODE_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/process_heap.cc b/third_party/blink/renderer/platform/heap/impl/process_heap.cc
deleted file mode 100644
index 7390044..0000000
--- a/third_party/blink/renderer/platform/heap/impl/process_heap.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/process_heap.h"
-
-#include "base/sampling_heap_profiler/poisson_allocation_sampler.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
-#include "third_party/blink/renderer/platform/heap/impl/persistent_node.h"
-
-namespace blink {
-
-void ProcessHeap::Init() {
-  DCHECK(!base::FeatureList::IsEnabled(
-             blink::features::kBlinkHeapConcurrentMarking) ||
-         base::FeatureList::IsEnabled(
-             blink::features::kBlinkHeapIncrementalMarking));
-
-  total_allocated_space_ = 0;
-  total_allocated_object_size_ = 0;
-
-  GCInfoTable::CreateGlobalTable();
-}
-
-void ProcessHeap::ResetHeapCounters() {
-  total_allocated_object_size_ = 0;
-}
-
-CrossThreadPersistentRegion& ProcessHeap::GetCrossThreadPersistentRegion() {
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(CrossThreadPersistentRegion,
-                                  persistent_region, ());
-  return persistent_region;
-}
-
-CrossThreadPersistentRegion& ProcessHeap::GetCrossThreadWeakPersistentRegion() {
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(CrossThreadPersistentRegion,
-                                  persistent_region, ());
-  return persistent_region;
-}
-
-Mutex& ProcessHeap::CrossThreadPersistentMutex() {
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, ());
-  return mutex;
-}
-
-std::atomic_size_t ProcessHeap::total_allocated_space_{0};
-std::atomic_size_t ProcessHeap::total_allocated_object_size_{0};
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/process_heap.h b/third_party/blink/renderer/platform/heap/impl/process_heap.h
deleted file mode 100644
index 91112a7c..0000000
--- a/third_party/blink/renderer/platform/heap/impl/process_heap.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PROCESS_HEAP_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PROCESS_HEAP_H_
-
-#include <atomic>
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-
-namespace blink {
-
-class CrossThreadPersistentRegion;
-
-class PLATFORM_EXPORT ProcessHeap {
-  STATIC_ONLY(ProcessHeap);
-
- public:
-  static void Init();
-
-  static CrossThreadPersistentRegion& GetCrossThreadPersistentRegion();
-  static CrossThreadPersistentRegion& GetCrossThreadWeakPersistentRegion();
-
-  // Access to the CrossThreadPersistentRegion from multiple threads has to be
-  // prevented as allocation, freeing, and iteration of nodes may otherwise
-  // cause data races.
-  //
-  // Examples include:
-  // - Iteration of strong cross-thread Persistents.
-  // - Iteration and processing of weak cross-thread Persistents. The lock
-  //   needs to span both operations as iteration of weak persistents only
-  //   registers memory regions that are then processed afterwards.
-  // - Marking phase in garbage collection: The whole phase requires locking
-  //   as CrossThreadWeakPersistents may be converted to CrossThreadPersistent
-  //   which must observe GC as an atomic operation.
-  static Mutex& CrossThreadPersistentMutex();
-
-  static void IncreaseTotalAllocatedObjectSize(size_t delta) {
-    total_allocated_object_size_.fetch_add(delta, std::memory_order_relaxed);
-  }
-  static void DecreaseTotalAllocatedObjectSize(size_t delta) {
-    total_allocated_object_size_.fetch_sub(delta, std::memory_order_relaxed);
-  }
-  static size_t TotalAllocatedObjectSize() {
-    return total_allocated_object_size_.load(std::memory_order_relaxed);
-  }
-  static void IncreaseTotalAllocatedSpace(size_t delta) {
-    total_allocated_space_.fetch_add(delta, std::memory_order_relaxed);
-  }
-  static void DecreaseTotalAllocatedSpace(size_t delta) {
-    total_allocated_space_.fetch_sub(delta, std::memory_order_relaxed);
-  }
-  static size_t TotalAllocatedSpace() {
-    return total_allocated_space_.load(std::memory_order_relaxed);
-  }
-  static void ResetHeapCounters();
-
- private:
-  static std::atomic_size_t total_allocated_space_;
-  static std::atomic_size_t total_allocated_object_size_;
-
-  friend class ThreadState;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_PROCESS_HEAP_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/test/card_table_test.cc b/third_party/blink/renderer/platform/heap/impl/test/card_table_test.cc
deleted file mode 100644
index 6f975c5..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/card_table_test.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <vector>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/trace_traits.h"
-
-namespace blink {
-
-namespace {
-
-class BaseObject : public GarbageCollected<BaseObject> {
- public:
-  size_t CardNumber() const;
-  void Trace(Visitor*) const {}
-};
-
-}  // namespace
-
-class CardTableTest : public TestSupportingGC {
- public:
-  static constexpr size_t kCardSize = NormalPage::CardTable::kCardSize;
-
-  CardTableTest() { ClearOutOldGarbage(); }
-
-  static void CheckObjects(const std::vector<BaseObject*>& objects,
-                           const NormalPage& page) {
-    page.IterateCardTable([&objects](HeapObjectHeader* header) {
-      const BaseObject* object =
-          reinterpret_cast<BaseObject*>(header->Payload());
-      auto it = std::find(objects.begin(), objects.end(), object);
-      EXPECT_NE(it, objects.end());
-    });
-  }
-
-  static void MarkCardForObject(BaseObject* object) {
-    NormalPage* page = static_cast<NormalPage*>(PageFromObject(object));
-    page->MarkCard(reinterpret_cast<Address>(object));
-  }
-
-  static bool IsCardMarked(const NormalPage& page, size_t card_number) {
-    return page.card_table_.IsMarked(card_number);
-  }
-
-  static size_t ObjectsInCard(const NormalPage& page, size_t card_number) {
-    const NormalPage::CardTable& cards = page.card_table_;
-
-    size_t objects = 0;
-    Address card_begin =
-        RoundToBlinkPageStart(page.GetAddress()) + (card_number * kCardSize);
-    const Address card_end = card_begin + kCardSize;
-    if (card_number == cards.begin().index) {
-      // First card is misaligned due to padding.
-      card_begin = page.Payload();
-    }
-
-    page.ArenaForNormalPage()->MakeConsistentForGC();
-
-    page.IterateOnCard(
-        [card_begin, card_end, &objects](HeapObjectHeader* header) {
-          const Address header_address = reinterpret_cast<Address>(header);
-          if (header_address < card_begin) {
-            const Address next_header_address = header_address + header->size();
-            EXPECT_GT(next_header_address, card_begin);
-          } else {
-            objects++;
-            EXPECT_LT(header_address, card_end);
-          }
-        },
-        card_number);
-
-    return objects;
-  }
-
-  static size_t MarkedObjects(const NormalPage& page) {
-    size_t objects = 0;
-    page.ArenaForNormalPage()->MakeConsistentForGC();
-    page.IterateCardTable([&objects](HeapObjectHeader*) { ++objects; });
-    return objects;
-  }
-
-  static void ClearCardTable(NormalPage& page) { page.card_table_.Clear(); }
-};
-
-namespace {
-
-size_t BaseObject::CardNumber() const {
-  return (reinterpret_cast<uintptr_t>(this) & kBlinkPageOffsetMask) /
-         CardTableTest::kCardSize;
-}
-
-template <size_t Size>
-class Object : public BaseObject {
- private:
-  uint8_t array[Size];
-};
-
-}  // namespace
-
-TEST_F(CardTableTest, Empty) {
-  BaseObject* obj = MakeGarbageCollected<BaseObject>();
-  EXPECT_EQ(0u, MarkedObjects(*static_cast<NormalPage*>(PageFromObject(obj))));
-}
-
-TEST_F(CardTableTest, SingleObjectOnFirstCard) {
-  BaseObject* obj = MakeGarbageCollected<BaseObject>();
-  MarkCardForObject(obj);
-
-  const NormalPage& page = *static_cast<NormalPage*>(PageFromObject(obj));
-  const size_t card_number = obj->CardNumber();
-  EXPECT_TRUE(IsCardMarked(page, card_number));
-
-  const size_t objects = ObjectsInCard(page, card_number);
-  EXPECT_EQ(1u, objects);
-}
-
-TEST_F(CardTableTest, SingleObjectOnSecondCard) {
-  MakeGarbageCollected<Object<kCardSize>>();
-  BaseObject* obj = MakeGarbageCollected<Object<kCardSize>>();
-  MarkCardForObject(obj);
-
-  const NormalPage& page = *static_cast<NormalPage*>(PageFromObject(obj));
-  const size_t card_number = obj->CardNumber();
-  EXPECT_TRUE(IsCardMarked(page, card_number));
-
-  const size_t objects = ObjectsInCard(page, card_number);
-  EXPECT_EQ(1u, objects);
-}
-
-TEST_F(CardTableTest, TwoObjectsOnSecondCard) {
-  static constexpr size_t kHalfCardSize = kCardSize / 2;
-  MakeGarbageCollected<Object<kHalfCardSize>>();
-  MakeGarbageCollected<Object<kHalfCardSize>>();
-  // The card on which 'obj' resides is guaranteed to have two objects, either
-  // the previously allocated one or the following one.
-  BaseObject* obj = MakeGarbageCollected<Object<kHalfCardSize>>();
-  MakeGarbageCollected<Object<kHalfCardSize>>();
-  MarkCardForObject(obj);
-
-  const NormalPage& page = *static_cast<NormalPage*>(PageFromObject(obj));
-  const size_t card_number = obj->CardNumber();
-  EXPECT_TRUE(IsCardMarked(page, card_number));
-
-  const size_t objects = ObjectsInCard(page, card_number);
-  EXPECT_EQ(2u, objects);
-}
-
-TEST_F(CardTableTest, Clear) {
-  MakeGarbageCollected<Object<kCardSize>>();
-  MakeGarbageCollected<Object<kCardSize / 2>>();
-  BaseObject* obj = MakeGarbageCollected<Object<kCardSize / 2>>();
-  MarkCardForObject(obj);
-
-  NormalPage& page = *static_cast<NormalPage*>(PageFromObject(obj));
-  ClearCardTable(page);
-
-  const size_t card_number = obj->CardNumber();
-  EXPECT_FALSE(IsCardMarked(page, card_number));
-}
-
-TEST_F(CardTableTest, MultipleObjects) {
-  std::vector<BaseObject*> objects;
-  BaseObject* obj = MakeGarbageCollected<Object<kCardSize>>();
-  BasePage* const first_page = PageFromObject(obj);
-  BasePage* new_page = first_page;
-
-  while (first_page == new_page) {
-    objects.push_back(obj);
-    MarkCardForObject(obj);
-
-    obj = MakeGarbageCollected<Object<kCardSize>>();
-    new_page = PageFromObject(obj);
-  }
-
-  CheckObjects(objects, *static_cast<NormalPage*>(first_page));
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/gc_info_test.cc b/third_party/blink/renderer/platform/heap/impl/test/gc_info_test.cc
deleted file mode 100644
index 3e007c35..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/gc_info_test.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-TEST(GCInfoTest, InitialEmpty) {
-  GCInfoTable table;
-  EXPECT_EQ(GCInfoTable::kMinIndex, table.NumberOfGCInfos());
-}
-
-TEST(GCInfoTest, ResizeToMaxIndex) {
-  GCInfoTable table;
-  GCInfo info = {nullptr, nullptr, nullptr, false};
-  std::atomic<GCInfoIndex> slot{0};
-  for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
-       i++) {
-    slot = 0;
-    GCInfoIndex index = table.EnsureGCInfoIndex(&info, &slot);
-    EXPECT_EQ(index, slot);
-    EXPECT_LT(0u, slot);
-    EXPECT_EQ(&info, &table.GCInfoFromIndex(index));
-  }
-}
-
-TEST(GCInfoDeathTest, MoreThanMaxIndexInfos) {
-  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
-  GCInfoTable table;
-  GCInfo info = {nullptr, nullptr, nullptr, false};
-  std::atomic<GCInfoIndex> slot{0};
-  // Create GCInfoTable::kMaxIndex entries.
-  for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
-       i++) {
-    slot = 0;
-    table.EnsureGCInfoIndex(&info, &slot);
-  }
-  slot = 0;
-  EXPECT_DEATH(table.EnsureGCInfoIndex(&info, &slot), "");
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/heap_internals_test.cc b/third_party/blink/renderer/platform/heap/impl/test/heap_internals_test.cc
deleted file mode 100644
index 829db0d..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/heap_internals_test.cc
+++ /dev/null
@@ -1,2201 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/test/scoped_feature_list.h"
-#include "build/build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_objects.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/self_keep_alive.h"
-#include "third_party/blink/renderer/platform/wtf/size_assertions.h"
-
-namespace blink {
-
-namespace {
-class HeapInternalsTest : public TestSupportingGC {};
-}  // namespace
-
-namespace {
-
-class IntWrapper : public GarbageCollected<IntWrapper> {
- public:
-  virtual ~IntWrapper() {
-    destructor_calls_.fetch_add(1, std::memory_order_relaxed);
-  }
-
-  static std::atomic_int destructor_calls_;
-  void Trace(Visitor* visitor) const {}
-
-  int Value() const { return x_; }
-
-  bool operator==(const IntWrapper& other) const {
-    return other.Value() == Value();
-  }
-
-  unsigned GetHash() { return IntHash<int>::GetHash(x_); }
-
-  explicit IntWrapper(int x) : x_(x) {}
-
-  IntWrapper() = delete;
-
- private:
-  int x_;
-};
-std::atomic_int IntWrapper::destructor_calls_{0};
-
-struct SameSizeAsPersistent {
-  void* pointers[2];
-#if DCHECK_IS_ON()
-  void* pointers_dcheck_[2];
-#endif
-#if BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-  PersistentLocation location;
-#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-};
-ASSERT_SIZE(Persistent<IntWrapper>, SameSizeAsPersistent);
-
-}  // namespace
-
-class TestGCScope {
-  STACK_ALLOCATED();
-
- public:
-  explicit TestGCScope(BlinkGC::StackState state) {
-    DCHECK(ThreadState::Current()->CheckThread());
-    ThreadState::Current()->Heap().stats_collector()->NotifyMarkingStarted(
-        BlinkGC::CollectionType::kMajor, BlinkGC::GCReason::kForcedGCForTesting,
-        true /* is_forced_gc */);
-    ThreadState::Current()->AtomicPauseMarkPrologue(
-        BlinkGC::CollectionType::kMajor, state, BlinkGC::kAtomicMarking,
-        BlinkGC::GCReason::kForcedGCForTesting);
-  }
-  ~TestGCScope() {
-    ThreadState::Current()->AtomicPauseMarkEpilogue(BlinkGC::kAtomicMarking);
-    ThreadState::Current()->AtomicPauseSweepAndCompact(
-        BlinkGC::CollectionType::kMajor, BlinkGC::kAtomicMarking,
-        BlinkGC::kEagerSweeping);
-    ThreadState::Current()->AtomicPauseEpilogue();
-    ThreadState::Current()->CompleteSweep();
-  }
-};
-
-namespace {
-class SimpleObject : public GarbageCollected<SimpleObject> {
- public:
-  SimpleObject() = default;
-  virtual void Trace(Visitor* visitor) const {}
-  char GetPayload(int i) { return payload[i]; }
-  // This virtual method is unused but it is here to make sure
-  // that this object has a vtable. This object is used
-  // as the super class for objects that also have garbage
-  // collected mixins and having a virtual here makes sure
-  // that adjustment is needed both for marking and for isAlive
-  // checks.
-  virtual void VirtualMethod() {}
-
- protected:
-  char payload[64];
-};
-
-class LargeHeapObject final : public GarbageCollected<LargeHeapObject> {
- public:
-  LargeHeapObject() { int_wrapper_ = MakeGarbageCollected<IntWrapper>(23); }
-  ~LargeHeapObject() { destructor_calls_++; }
-
-  char Get(size_t i) { return data_[i]; }
-  void Set(size_t i, char c) { data_[i] = c; }
-  size_t length() { return kLength; }
-  void Trace(Visitor* visitor) const { visitor->Trace(int_wrapper_); }
-  static int destructor_calls_;
-
- private:
-  static const size_t kLength = 1024 * 1024;
-  Member<IntWrapper> int_wrapper_;
-  char data_[kLength];
-};
-int LargeHeapObject::destructor_calls_ = 0;
-
-void ExpectObjectMarkedAndUnmark(MarkingWorklist* worklist, void* expected) {
-  MarkingItem item;
-  CHECK(worklist->Pop(0, &item));
-  CHECK_EQ(expected, item.base_object_payload);
-  HeapObjectHeader* header =
-      HeapObjectHeader::FromPayload(item.base_object_payload);
-  CHECK(header->IsMarked());
-  header->Unmark();
-  CHECK(worklist->IsGlobalEmpty());
-}
-}  // namespace
-
-TEST_F(HeapInternalsTest, CheckAndMarkPointer) {
-  // This test ensures that conservative marking primitives can use any address
-  // contained within an object to mark the corresponding object.
-
-  ThreadHeap& heap = ThreadState::Current()->Heap();
-  ClearOutOldGarbage();
-
-  Vector<Address> object_addresses;
-  Vector<Address> end_addresses;
-  for (int i = 0; i < 10; i++) {
-    auto* object = MakeGarbageCollected<SimpleObject>();
-    Address object_address = reinterpret_cast<Address>(object);
-    object_addresses.push_back(object_address);
-    end_addresses.push_back(object_address + sizeof(SimpleObject) - 1);
-  }
-  Address large_object_address =
-      reinterpret_cast<Address>(MakeGarbageCollected<LargeHeapObject>());
-  Address large_object_end_address =
-      large_object_address + sizeof(LargeHeapObject) - 1;
-
-  {
-    TestGCScope scope(BlinkGC::kHeapPointersOnStack);
-    MarkingVisitor visitor(ThreadState::Current(),
-                           MarkingVisitor::kGlobalMarking);
-    // Record marking speed as counter generation requires valid marking timings
-    // for heaps >1MB.
-    ThreadHeapStatsCollector::Scope stats_scope(
-        heap.stats_collector(),
-        ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure);
-
-    // Conservative marker should find the interesting objects by using anything
-    // between object start and end.
-    MarkingWorklist* worklist = heap.GetMarkingWorklist();
-    CHECK(worklist->IsGlobalEmpty());
-    for (wtf_size_t i = 0; i < object_addresses.size(); i++) {
-      heap.CheckAndMarkPointer(&visitor, object_addresses[i]);
-      ExpectObjectMarkedAndUnmark(worklist, object_addresses[i]);
-      heap.CheckAndMarkPointer(&visitor, end_addresses[i]);
-      ExpectObjectMarkedAndUnmark(worklist, object_addresses[i]);
-    }
-    heap.CheckAndMarkPointer(&visitor, large_object_address);
-    ExpectObjectMarkedAndUnmark(worklist, large_object_address);
-    heap.CheckAndMarkPointer(&visitor, large_object_end_address);
-    ExpectObjectMarkedAndUnmark(worklist, large_object_address);
-  }
-
-  // This forces a GC without stack scanning which results in the objects
-  // being collected. This will also rebuild the above mentioned freelists,
-  // however we don't rely on that below since we don't have any allocations.
-  ClearOutOldGarbage();
-
-  {
-    TestGCScope scope(BlinkGC::kHeapPointersOnStack);
-    MarkingVisitor visitor(ThreadState::Current(),
-                           MarkingVisitor::kGlobalMarking);
-    // Record marking speed as counter generation requires valid marking timings
-    // for heaps >1MB.
-    ThreadHeapStatsCollector::Scope stats_scope(
-        heap.stats_collector(),
-        ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure);
-
-    // After collecting all interesting objects the conservative marker should
-    // not find them anymore.
-    MarkingWorklist* worklist = heap.GetMarkingWorklist();
-    CHECK(worklist->IsGlobalEmpty());
-    for (wtf_size_t i = 0; i < object_addresses.size(); i++) {
-      heap.CheckAndMarkPointer(&visitor, object_addresses[i]);
-      CHECK(worklist->IsGlobalEmpty());
-      heap.CheckAndMarkPointer(&visitor, end_addresses[i]);
-      CHECK(worklist->IsGlobalEmpty());
-    }
-    heap.CheckAndMarkPointer(&visitor, large_object_address);
-    CHECK(worklist->IsGlobalEmpty());
-    heap.CheckAndMarkPointer(&visitor, large_object_end_address);
-    CHECK(worklist->IsGlobalEmpty());
-  }
-}
-
-TEST_F(HeapInternalsTest, LazySweepingLargeObjectPages) {
-  // Disable concurrent sweeping to check lazy sweeping on allocation.
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(
-      blink::features::kBlinkHeapConcurrentSweeping);
-
-  ClearOutOldGarbage();
-
-  // Create free lists that can be reused for IntWrappers created in
-  // MakeGarbageCollected<LargeHeapObject>().
-  Persistent<IntWrapper> p1 = MakeGarbageCollected<IntWrapper>(1);
-  for (int i = 0; i < 100; i++) {
-    MakeGarbageCollected<IntWrapper>(i);
-  }
-  Persistent<IntWrapper> p2 = MakeGarbageCollected<IntWrapper>(2);
-  PreciselyCollectGarbage();
-  PreciselyCollectGarbage();
-
-  LargeHeapObject::destructor_calls_ = 0;
-  EXPECT_EQ(0, LargeHeapObject::destructor_calls_);
-  for (int i = 0; i < 10; i++)
-    MakeGarbageCollected<LargeHeapObject>();
-  ThreadState::Current()->CollectGarbageForTesting(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
-      BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
-      BlinkGC::GCReason::kForcedGCForTesting);
-  EXPECT_EQ(0, LargeHeapObject::destructor_calls_);
-  for (int i = 0; i < 10; i++) {
-    MakeGarbageCollected<LargeHeapObject>();
-    EXPECT_EQ(i + 1, LargeHeapObject::destructor_calls_);
-  }
-  MakeGarbageCollected<LargeHeapObject>();
-  MakeGarbageCollected<LargeHeapObject>();
-  EXPECT_EQ(10, LargeHeapObject::destructor_calls_);
-  ThreadState::Current()->CollectGarbageForTesting(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
-      BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
-      BlinkGC::GCReason::kForcedGCForTesting);
-  EXPECT_EQ(10, LargeHeapObject::destructor_calls_);
-  PreciselyCollectGarbage();
-  EXPECT_EQ(22, LargeHeapObject::destructor_calls_);
-}
-
-namespace {
-class Mixin : public GarbageCollectedMixin {
- public:
-  void Trace(Visitor* visitor) const override {}
-
-  virtual char GetPayload(int i) { return padding_[i]; }
-
- protected:
-  int padding_[8];
-};
-
-class UseMixin : public SimpleObject, public Mixin {
- public:
-  UseMixin() {
-    // Verify that WTF::IsGarbageCollectedType<> works as expected for mixins.
-    static_assert(WTF::IsGarbageCollectedType<UseMixin>::value,
-                  "IsGarbageCollectedType<> sanity check failed for GC mixin.");
-    trace_count_ = 0;
-  }
-
-  static int trace_count_;
-  void Trace(Visitor* visitor) const override {
-    SimpleObject::Trace(visitor);
-    Mixin::Trace(visitor);
-    ++trace_count_;
-  }
-};
-int UseMixin::trace_count_ = 0;
-}  // namespace
-
-TEST_F(HeapInternalsTest, NeedsAdjustPointer) {
-  // class Mixin : public GarbageCollectedMixin {};
-  static_assert(NeedsAdjustPointer<Mixin>::value,
-                "A Mixin pointer needs adjustment");
-  static_assert(NeedsAdjustPointer<const Mixin>::value,
-                "A const Mixin pointer needs adjustment");
-
-  // class SimpleObject : public GarbageCollected<SimpleObject> {};
-  static_assert(!NeedsAdjustPointer<SimpleObject>::value,
-                "A SimpleObject pointer does not need adjustment");
-  static_assert(!NeedsAdjustPointer<const SimpleObject>::value,
-                "A const SimpleObject pointer does not need adjustment");
-
-  // class UseMixin : public SimpleObject, public Mixin {};
-  static_assert(!NeedsAdjustPointer<UseMixin>::value,
-                "A UseMixin pointer does not need adjustment");
-  static_assert(!NeedsAdjustPointer<const UseMixin>::value,
-                "A const UseMixin pointer does not need adjustment");
-}
-
-namespace {
-class DeepEagerly final : public GarbageCollected<DeepEagerly> {
- public:
-  explicit DeepEagerly(DeepEagerly* next) : next_(next) {}
-
-  void Trace(Visitor* visitor) const {
-    int calls = ++s_trace_calls_;
-    if (s_trace_lazy_ <= 2)
-      visitor->Trace(next_);
-    if (s_trace_calls_ == calls)
-      s_trace_lazy_++;
-  }
-
-  Member<DeepEagerly> next_;
-
-  static int s_trace_calls_;
-  static int s_trace_lazy_;
-};
-int DeepEagerly::s_trace_calls_ = 0;
-int DeepEagerly::s_trace_lazy_ = 0;
-}  // namespace
-
-TEST_F(HeapInternalsTest, TraceDeepEagerly) {
-// The allocation & GC overhead is considerable for this test,
-// straining debug builds and lower-end targets too much to be
-// worth running.
-#if !DCHECK_IS_ON() && !defined(OS_ANDROID)
-  DeepEagerly* obj = nullptr;
-  for (int i = 0; i < 10000000; i++)
-    obj = MakeGarbageCollected<DeepEagerly>(obj);
-
-  Persistent<DeepEagerly> persistent(obj);
-  PreciselyCollectGarbage();
-
-  // Verify that the DeepEagerly chain isn't completely unravelled
-  // by performing eager trace() calls, but the explicit mark
-  // stack is switched once some nesting limit is exceeded.
-  EXPECT_GT(DeepEagerly::s_trace_lazy_, 2);
-#endif
-}
-
-#if defined(ADDRESS_SANITIZER)
-TEST_F(HeapInternalsTest, SuccessfulUnsanitizedAccessToObjectHeader) {
-  auto* ptr = MakeGarbageCollected<IntWrapper>(1);
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(ptr);
-  auto* low = reinterpret_cast<uint16_t*>(header);
-  volatile uint16_t half = internal::AsUnsanitizedAtomic(low)->load();
-  internal::AsUnsanitizedAtomic(low)->store(half);
-}
-
-TEST(HeapInternalsDeathTest, DieOnPoisonedObjectHeaderAccess) {
-  auto* ptr = MakeGarbageCollected<IntWrapper>(1);
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(ptr);
-  auto* low = reinterpret_cast<uint16_t*>(header);
-  auto access = [low] {
-    volatile uint16_t half = WTF::AsAtomicPtr(low)->load();
-    WTF::AsAtomicPtr(low)->store(half);
-  };
-  EXPECT_DEATH(access(), "");
-}
-#endif  // ADDRESS_SANITIZER
-
-namespace {
-class LargeMixin : public GarbageCollected<LargeMixin>, public Mixin {
- protected:
-  char data[65536];
-};
-}  // namespace
-
-TEST(HeapInternalsDeathTest, LargeGarbageCollectedMixin) {
-  EXPECT_DEATH(MakeGarbageCollected<LargeMixin>(AdditionalBytes(1)), "");
-}
-
-namespace {
-class PreFinalizerAllocationForbidden
-    : public GarbageCollected<PreFinalizerAllocationForbidden> {
-  USING_PRE_FINALIZER(PreFinalizerAllocationForbidden, Dispose);
-
- public:
-  void Dispose() {
-    EXPECT_FALSE(ThreadState::Current()->IsAllocationAllowed());
-#if DCHECK_IS_ON()
-    EXPECT_DEATH(MakeGarbageCollected<IntWrapper>(1), "");
-#endif  // DCHECK_IS_ON()
-  }
-
-  void Trace(Visitor* visitor) const {}
-};
-}  // namespace
-
-TEST(HeapInternalsDeathTest, PreFinalizerAllocationForbidden) {
-  MakeGarbageCollected<PreFinalizerAllocationForbidden>();
-  TestSupportingGC::PreciselyCollectGarbage();
-}
-
-namespace {
-class Bar : public GarbageCollected<Bar> {
- public:
-  Bar() : magic_(kMagic) { live_++; }
-
-  virtual ~Bar() {
-    EXPECT_TRUE(magic_ == kMagic);
-    magic_ = 0;
-    live_--;
-  }
-  bool HasBeenFinalized() const { return !magic_; }
-
-  virtual void Trace(Visitor* visitor) const {}
-  static unsigned live_;
-
- protected:
-  static const int kMagic = 1337;
-  int magic_;
-};
-
-unsigned Bar::live_ = 0;
-
-class Bars final : public Bar {
- public:
-  Bars() {
-    for (auto& bar : bars_) {
-      bar = MakeGarbageCollected<Bar>();
-      width_++;
-    }
-  }
-
-  void Trace(Visitor* visitor) const override {
-    Bar::Trace(visitor);
-    for (unsigned i = 0; i < width_; i++)
-      visitor->Trace(bars_[i]);
-  }
-
-  unsigned GetWidth() const { return width_; }
-
-  static const unsigned kWidth = 7500;
-
- private:
-  unsigned width_ = 0;
-  Member<Bar> bars_[kWidth];
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, WideTest) {
-  ClearOutOldGarbage();
-  Bar::live_ = 0;
-  {
-    auto* bars = MakeGarbageCollected<Bars>();
-    unsigned width = Bars::kWidth;
-    EXPECT_EQ(width + 1, Bar::live_);
-    ConservativelyCollectGarbage();
-    EXPECT_EQ(width + 1, Bar::live_);
-    // Use bars here to make sure that it will be on the stack
-    // for the conservative stack scan to find.
-    EXPECT_EQ(width, bars->GetWidth());
-  }
-  EXPECT_EQ(Bars::kWidth + 1, Bar::live_);
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0u, Bar::live_);
-}
-
-namespace {
-// The accounting for memory includes the memory used by rounding up object
-// sizes. This is done in a different way on 32 bit and 64 bit, so we have to
-// have some slack in the tests.
-template <typename T>
-void CheckWithSlack(T expected, T actual, int slack) {
-  EXPECT_LE(expected, actual);
-  EXPECT_GE((intptr_t)expected + slack, (intptr_t)actual);
-}
-}  // namespace
-
-TEST_F(HeapInternalsTest, LargeHeapObjects) {
-  ThreadHeap& heap = ThreadState::Current()->Heap();
-  ClearOutOldGarbage();
-  size_t initial_object_payload_size = heap.ObjectPayloadSizeForTesting();
-  size_t initial_allocated_space =
-      heap.stats_collector()->allocated_space_bytes();
-  IntWrapper::destructor_calls_ = 0;
-  LargeHeapObject::destructor_calls_ = 0;
-  {
-    int slack =
-        8;  // LargeHeapObject points to an IntWrapper that is also allocated.
-    Persistent<LargeHeapObject> object =
-        MakeGarbageCollected<LargeHeapObject>();
-#if DCHECK_IS_ON()
-    DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(object));
-    DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(
-        reinterpret_cast<char*>(object.Get()) + sizeof(LargeHeapObject) - 1));
-#endif
-    ClearOutOldGarbage();
-    size_t after_allocation = heap.stats_collector()->allocated_space_bytes();
-    {
-      object->Set(0, 'a');
-      EXPECT_EQ('a', object->Get(0));
-      object->Set(object->length() - 1, 'b');
-      EXPECT_EQ('b', object->Get(object->length() - 1));
-      size_t expected_large_heap_object_payload_size =
-          ThreadHeap::AllocationSizeFromSize(sizeof(LargeHeapObject)) -
-          sizeof(HeapObjectHeader);
-      size_t expected_object_payload_size =
-          expected_large_heap_object_payload_size + sizeof(IntWrapper);
-      size_t actual_object_payload_size =
-          heap.ObjectPayloadSizeForTesting() - initial_object_payload_size;
-      CheckWithSlack(expected_object_payload_size, actual_object_payload_size,
-                     slack);
-      // There is probably space for the IntWrapper in a heap page without
-      // allocating extra pages. However, the IntWrapper allocation might cause
-      // the addition of a heap page.
-      size_t large_object_allocation_size =
-          sizeof(LargeObjectPage) + expected_large_heap_object_payload_size;
-      size_t allocated_space_lower_bound =
-          initial_allocated_space + large_object_allocation_size;
-      size_t allocated_space_upper_bound =
-          allocated_space_lower_bound + slack + kBlinkPageSize;
-      EXPECT_LE(allocated_space_lower_bound, after_allocation);
-      EXPECT_LE(after_allocation, allocated_space_upper_bound);
-      EXPECT_EQ(0, IntWrapper::destructor_calls_);
-      EXPECT_EQ(0, LargeHeapObject::destructor_calls_);
-      for (int i = 0; i < 10; i++)
-        object = MakeGarbageCollected<LargeHeapObject>();
-    }
-    ClearOutOldGarbage();
-    EXPECT_EQ(after_allocation,
-              heap.stats_collector()->allocated_space_bytes());
-    EXPECT_EQ(10, IntWrapper::destructor_calls_);
-    EXPECT_EQ(10, LargeHeapObject::destructor_calls_);
-  }
-  ClearOutOldGarbage();
-  EXPECT_TRUE(initial_object_payload_size ==
-              heap.ObjectPayloadSizeForTesting());
-  EXPECT_EQ(initial_allocated_space,
-            heap.stats_collector()->allocated_space_bytes());
-  EXPECT_EQ(11, IntWrapper::destructor_calls_);
-  EXPECT_EQ(11, LargeHeapObject::destructor_calls_);
-  PreciselyCollectGarbage();
-}
-
-namespace {
-class MixinA : public GarbageCollectedMixin {
- public:
-  MixinA() : obj_(MakeGarbageCollected<IntWrapper>(100)) {}
-  void Trace(Visitor* visitor) const override {
-    trace_count_++;
-    visitor->Trace(obj_);
-  }
-
-  static int trace_count_;
-
-  Member<IntWrapper> obj_;
-};
-
-int MixinA::trace_count_ = 0;
-
-class MixinB : public GarbageCollectedMixin {
- public:
-  MixinB() : obj_(MakeGarbageCollected<IntWrapper>(101)) {}
-  void Trace(Visitor* visitor) const override { visitor->Trace(obj_); }
-  Member<IntWrapper> obj_;
-};
-
-class MultipleMixins : public GarbageCollected<MultipleMixins>,
-                       public MixinA,
-                       public MixinB {
- public:
-  MultipleMixins() : obj_(MakeGarbageCollected<IntWrapper>(102)) {}
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(obj_);
-    MixinA::Trace(visitor);
-    MixinB::Trace(visitor);
-  }
-  Member<IntWrapper> obj_;
-};
-
-static const bool kIsMixinTrue = IsGarbageCollectedMixin<MultipleMixins>::value;
-static const bool kIsMixinFalse = IsGarbageCollectedMixin<IntWrapper>::value;
-}  // namespace
-
-TEST_F(HeapInternalsTest, MultipleMixins) {
-  EXPECT_TRUE(kIsMixinTrue);
-  EXPECT_FALSE(kIsMixinFalse);
-
-  ClearOutOldGarbage();
-  IntWrapper::destructor_calls_ = 0;
-  MultipleMixins* obj = MakeGarbageCollected<MultipleMixins>();
-  {
-    Persistent<MixinA> a = obj;
-    PreciselyCollectGarbage();
-    EXPECT_EQ(0, IntWrapper::destructor_calls_);
-  }
-  {
-    Persistent<MixinB> b = obj;
-    PreciselyCollectGarbage();
-    EXPECT_EQ(0, IntWrapper::destructor_calls_);
-  }
-  PreciselyCollectGarbage();
-  EXPECT_EQ(3, IntWrapper::destructor_calls_);
-}
-
-namespace {
-class DerivedMultipleMixins : public MultipleMixins {
- public:
-  DerivedMultipleMixins() : obj_(MakeGarbageCollected<IntWrapper>(103)) {}
-
-  void Trace(Visitor* visitor) const override {
-    trace_called_++;
-    visitor->Trace(obj_);
-    MultipleMixins::Trace(visitor);
-  }
-
-  static int trace_called_;
-
- private:
-  Member<IntWrapper> obj_;
-};
-int DerivedMultipleMixins::trace_called_ = 0;
-}  // namespace
-
-TEST_F(HeapInternalsTest, DerivedMultipleMixins) {
-  ClearOutOldGarbage();
-  IntWrapper::destructor_calls_ = 0;
-  DerivedMultipleMixins::trace_called_ = 0;
-
-  DerivedMultipleMixins* obj = MakeGarbageCollected<DerivedMultipleMixins>();
-  {
-    Persistent<MixinA> a = obj;
-    PreciselyCollectGarbage();
-    EXPECT_EQ(0, IntWrapper::destructor_calls_);
-    EXPECT_LT(0, DerivedMultipleMixins::trace_called_);
-  }
-  {
-    Persistent<MixinB> b = obj;
-    PreciselyCollectGarbage();
-    EXPECT_EQ(0, IntWrapper::destructor_calls_);
-    EXPECT_LT(0, DerivedMultipleMixins::trace_called_);
-  }
-  PreciselyCollectGarbage();
-  EXPECT_EQ(4, IntWrapper::destructor_calls_);
-}
-
-namespace {
-static bool AllocateAndReturnBool() {
-  TestSupportingGC::ConservativelyCollectGarbage();
-  return true;
-}
-
-class AllocInSuperConstructorArgumentSuper
-    : public GarbageCollected<AllocInSuperConstructorArgumentSuper> {
- public:
-  explicit AllocInSuperConstructorArgumentSuper(bool value) : value_(value) {}
-  virtual ~AllocInSuperConstructorArgumentSuper() = default;
-  virtual void Trace(Visitor* visitor) const {}
-  bool Value() { return value_; }
-
- private:
-  bool value_;
-};
-
-class AllocInSuperConstructorArgument
-    : public AllocInSuperConstructorArgumentSuper {
- public:
-  AllocInSuperConstructorArgument()
-      : AllocInSuperConstructorArgumentSuper(AllocateAndReturnBool()) {}
-};
-}  // namespace
-
-// Regression test for crbug.com/404511. Tests conservative marking of
-// an object with an uninitialized vtable.
-TEST_F(HeapInternalsTest, AllocationInSuperConstructorArgument) {
-  AllocInSuperConstructorArgument* object =
-      MakeGarbageCollected<AllocInSuperConstructorArgument>();
-  EXPECT_TRUE(object);
-  ThreadState::Current()->CollectAllGarbageForTesting();
-}
-
-namespace {
-class TestMixinAllocationA : public GarbageCollected<TestMixinAllocationA>,
-                             public GarbageCollectedMixin {
- public:
-  TestMixinAllocationA() = default;
-
-  void Trace(Visitor* visitor) const override {}
-};
-
-class TestMixinAllocationB : public TestMixinAllocationA {
- public:
-  TestMixinAllocationB()
-      // Construct object during a mixin construction.
-      : a_(MakeGarbageCollected<TestMixinAllocationA>()) {}
-
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(a_);
-    TestMixinAllocationA::Trace(visitor);
-  }
-
- private:
-  Member<TestMixinAllocationA> a_;
-};
-
-class TestMixinAllocationC final : public TestMixinAllocationB {
- public:
-  TestMixinAllocationC() { DCHECK(!ThreadState::Current()->IsGCForbidden()); }
-
-  void Trace(Visitor* visitor) const override {
-    TestMixinAllocationB::Trace(visitor);
-  }
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, NestedMixinConstruction) {
-  TestMixinAllocationC* object = MakeGarbageCollected<TestMixinAllocationC>();
-  EXPECT_TRUE(object);
-}
-
-TEST_F(HeapInternalsTest, IsHeapObjectAliveForConstPointer) {
-  // See http://crbug.com/661363.
-  auto* object = MakeGarbageCollected<SimpleObject>();
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
-  LivenessBroker broker = internal::LivenessBrokerFactory::Create();
-  EXPECT_TRUE(header->TryMark());
-  EXPECT_TRUE(broker.IsHeapObjectAlive(object));
-  const SimpleObject* const_object = const_cast<const SimpleObject*>(object);
-  EXPECT_TRUE(broker.IsHeapObjectAlive(const_object));
-}
-
-namespace {
-// This test class served a more important role while Blink
-// was transitioned over to using Oilpan. That required classes
-// that were hybrid, both ref-counted and on the Oilpan heap
-// (the RefCountedGarbageCollected<> class providing just that.)
-//
-// There's no current need for having a ref-counted veneer on
-// top of a GCed class, but we preserve it here to exercise the
-// implementation technique that it used -- keeping an internal
-// "keep alive" persistent reference that is set & cleared across
-// ref-counting operations.
-//
-class RefCountedAndGarbageCollected final
-    : public GarbageCollected<RefCountedAndGarbageCollected> {
- public:
-  RefCountedAndGarbageCollected() : keep_alive_(PERSISTENT_FROM_HERE) {}
-  ~RefCountedAndGarbageCollected() { ++destructor_calls_; }
-
-  void AddRef() {
-    if (UNLIKELY(!ref_count_)) {
-#if DCHECK_IS_ON()
-      DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(
-          reinterpret_cast<Address>(this)));
-#endif
-      keep_alive_ = this;
-    }
-    ++ref_count_;
-  }
-
-  void Release() {
-    DCHECK_GT(ref_count_, 0);
-    if (!--ref_count_)
-      keep_alive_.Clear();
-  }
-
-  void Trace(Visitor* visitor) const {}
-
-  static int destructor_calls_;
-
- private:
-  int ref_count_ = 0;
-  SelfKeepAlive<RefCountedAndGarbageCollected> keep_alive_;
-};
-int RefCountedAndGarbageCollected::destructor_calls_ = 0;
-
-class SuperClass;
-
-class PointsBack final : public GarbageCollected<PointsBack> {
- public:
-  PointsBack() : back_pointer_(nullptr) { ++alive_count_; }
-  ~PointsBack() { --alive_count_; }
-
-  void SetBackPointer(SuperClass* back_pointer) {
-    back_pointer_ = back_pointer;
-  }
-
-  SuperClass* BackPointer() const { return back_pointer_; }
-
-  void Trace(Visitor* visitor) const { visitor->Trace(back_pointer_); }
-
-  static int alive_count_;
-
- private:
-  WeakMember<SuperClass> back_pointer_;
-};
-int PointsBack::alive_count_ = 0;
-
-class SuperClass : public GarbageCollected<SuperClass> {
- public:
-  explicit SuperClass(PointsBack* points_back) : points_back_(points_back) {
-    points_back_->SetBackPointer(this);
-    ++alive_count_;
-  }
-  virtual ~SuperClass() { --alive_count_; }
-
-  void DoStuff(SuperClass* target,
-               PointsBack* points_back,
-               int super_class_count) {
-    TestSupportingGC::ConservativelyCollectGarbage();
-    EXPECT_EQ(points_back, target->GetPointsBack());
-    EXPECT_EQ(super_class_count, SuperClass::alive_count_);
-  }
-
-  virtual void Trace(Visitor* visitor) const { visitor->Trace(points_back_); }
-
-  PointsBack* GetPointsBack() const { return points_back_.Get(); }
-
-  static int alive_count_;
-
- private:
-  Member<PointsBack> points_back_;
-};
-
-int SuperClass::alive_count_ = 0;
-class SubData final : public GarbageCollected<SubData> {
- public:
-  SubData() { ++alive_count_; }
-  ~SubData() { --alive_count_; }
-
-  void Trace(Visitor* visitor) const {}
-
-  static int alive_count_;
-};
-int SubData::alive_count_ = 0;
-
-class SubClass : public SuperClass {
- public:
-  explicit SubClass(PointsBack* points_back)
-      : SuperClass(points_back), data_(MakeGarbageCollected<SubData>()) {
-    ++alive_count_;
-  }
-  ~SubClass() override { --alive_count_; }
-
-  void Trace(Visitor* visitor) const override {
-    visitor->Trace(data_);
-    SuperClass::Trace(visitor);
-  }
-
-  static int alive_count_;
-
- private:
-  Member<SubData> data_;
-};
-int SubClass::alive_count_ = 0;
-}  // namespace
-
-TEST_F(HeapInternalsTest, Transition) {
-  {
-    RefCountedAndGarbageCollected::destructor_calls_ = 0;
-    Persistent<RefCountedAndGarbageCollected> ref_counted =
-        MakeGarbageCollected<RefCountedAndGarbageCollected>();
-    PreciselyCollectGarbage();
-    EXPECT_EQ(0, RefCountedAndGarbageCollected::destructor_calls_);
-  }
-  PreciselyCollectGarbage();
-  EXPECT_EQ(1, RefCountedAndGarbageCollected::destructor_calls_);
-  RefCountedAndGarbageCollected::destructor_calls_ = 0;
-
-  Persistent<PointsBack> points_back1 = MakeGarbageCollected<PointsBack>();
-  Persistent<PointsBack> points_back2 = MakeGarbageCollected<PointsBack>();
-  Persistent<SuperClass> super_class =
-      MakeGarbageCollected<SuperClass>(points_back1);
-  Persistent<SubClass> sub_class = MakeGarbageCollected<SubClass>(points_back2);
-  EXPECT_EQ(2, PointsBack::alive_count_);
-  EXPECT_EQ(2, SuperClass::alive_count_);
-  EXPECT_EQ(1, SubClass::alive_count_);
-  EXPECT_EQ(1, SubData::alive_count_);
-
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0, RefCountedAndGarbageCollected::destructor_calls_);
-  EXPECT_EQ(2, PointsBack::alive_count_);
-  EXPECT_EQ(2, SuperClass::alive_count_);
-  EXPECT_EQ(1, SubClass::alive_count_);
-  EXPECT_EQ(1, SubData::alive_count_);
-
-  super_class->DoStuff(super_class.Release(), points_back1.Get(), 2);
-  PreciselyCollectGarbage();
-  EXPECT_EQ(2, PointsBack::alive_count_);
-  EXPECT_EQ(1, SuperClass::alive_count_);
-  EXPECT_EQ(1, SubClass::alive_count_);
-  EXPECT_EQ(1, SubData::alive_count_);
-  EXPECT_EQ(nullptr, points_back1->BackPointer());
-
-  points_back1.Release();
-  PreciselyCollectGarbage();
-  EXPECT_EQ(1, PointsBack::alive_count_);
-  EXPECT_EQ(1, SuperClass::alive_count_);
-  EXPECT_EQ(1, SubClass::alive_count_);
-  EXPECT_EQ(1, SubData::alive_count_);
-
-  sub_class->DoStuff(sub_class.Release(), points_back2.Get(), 1);
-  PreciselyCollectGarbage();
-  EXPECT_EQ(1, PointsBack::alive_count_);
-  EXPECT_EQ(0, SuperClass::alive_count_);
-  EXPECT_EQ(0, SubClass::alive_count_);
-  EXPECT_EQ(0, SubData::alive_count_);
-  EXPECT_EQ(nullptr, points_back2->BackPointer());
-
-  points_back2.Release();
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0, PointsBack::alive_count_);
-  EXPECT_EQ(0, SuperClass::alive_count_);
-  EXPECT_EQ(0, SubClass::alive_count_);
-  EXPECT_EQ(0, SubData::alive_count_);
-
-  EXPECT_TRUE(super_class == sub_class);
-}
-
-namespace {
-class DynamicallySizedObject : public GarbageCollected<DynamicallySizedObject> {
- public:
-  static DynamicallySizedObject* Create(size_t size) {
-    return MakeGarbageCollected<DynamicallySizedObject>(AdditionalBytes(
-        base::checked_cast<wtf_size_t>(size - sizeof(DynamicallySizedObject))));
-  }
-
-  uint8_t Get(int i) { return *(reinterpret_cast<uint8_t*>(this) + i); }
-
-  void Trace(Visitor* visitor) const {}
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, BasicFunctionality) {
-  ThreadHeap& heap = ThreadState::Current()->Heap();
-  ClearOutOldGarbage();
-  size_t initial_object_payload_size = heap.ObjectPayloadSizeForTesting();
-  {
-    wtf_size_t slack = 0;
-
-    // When the test starts there may already have been leaked some memory
-    // on the heap, so we establish a base line.
-    size_t base_level = initial_object_payload_size;
-    bool test_pages_allocated = !base_level;
-    if (test_pages_allocated)
-      EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes());
-
-    // This allocates objects on the general heap which should add a page of
-    // memory.
-    DynamicallySizedObject* alloc32 = DynamicallySizedObject::Create(32);
-    slack += 4;
-    memset(alloc32, 40, 32);
-    DynamicallySizedObject* alloc64 = DynamicallySizedObject::Create(64);
-    slack += 4;
-    memset(alloc64, 27, 64);
-
-    size_t total = 96;
-
-    CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(),
-                   slack);
-    if (test_pages_allocated) {
-      EXPECT_EQ(kBlinkPageSize * 2,
-                heap.stats_collector()->allocated_space_bytes());
-    }
-
-    EXPECT_EQ(alloc32->Get(0), 40);
-    EXPECT_EQ(alloc32->Get(31), 40);
-    EXPECT_EQ(alloc64->Get(0), 27);
-    EXPECT_EQ(alloc64->Get(63), 27);
-
-    ConservativelyCollectGarbage();
-
-    EXPECT_EQ(alloc32->Get(0), 40);
-    EXPECT_EQ(alloc32->Get(31), 40);
-    EXPECT_EQ(alloc64->Get(0), 27);
-    EXPECT_EQ(alloc64->Get(63), 27);
-  }
-
-  ClearOutOldGarbage();
-  size_t total = 0;
-  wtf_size_t slack = 0;
-  size_t base_level = heap.ObjectPayloadSizeForTesting();
-  bool test_pages_allocated = !base_level;
-  if (test_pages_allocated)
-    EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes());
-
-  size_t big = 1008;
-  Persistent<DynamicallySizedObject> big_area =
-      DynamicallySizedObject::Create(big);
-  total += big;
-  slack += 4;
-
-  size_t persistent_count = 0;
-  const size_t kNumPersistents = 100000;
-  Persistent<DynamicallySizedObject>* persistents[kNumPersistents];
-
-  for (int i = 0; i < 1000; i++) {
-    size_t size = 128 + i * 8;
-    total += size;
-    persistents[persistent_count++] = new Persistent<DynamicallySizedObject>(
-        DynamicallySizedObject::Create(size));
-    slack += 4;
-    // The allocations in the loop may trigger GC with lazy sweeping.
-    if (ThreadState::Current()->IsSweepingInProgress())
-      ThreadState::Current()->CompleteSweep();
-    CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(),
-                   slack);
-    if (test_pages_allocated) {
-      EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
-                         (kBlinkPageSize - 1));
-    }
-  }
-
-  {
-    DynamicallySizedObject* alloc32b(DynamicallySizedObject::Create(32));
-    slack += 4;
-    memset(alloc32b, 40, 32);
-    DynamicallySizedObject* alloc64b(DynamicallySizedObject::Create(64));
-    slack += 4;
-    memset(alloc64b, 27, 64);
-    EXPECT_TRUE(alloc32b != alloc64b);
-
-    total += 96;
-    CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(),
-                   slack);
-    if (test_pages_allocated) {
-      EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
-                         (kBlinkPageSize - 1));
-    }
-  }
-
-  ClearOutOldGarbage();
-  total -= 96;
-  slack -= 8;
-  if (test_pages_allocated) {
-    EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
-                       (kBlinkPageSize - 1));
-  }
-
-  // Clear the persistent, so that the big area will be garbage collected.
-  big_area.Release();
-  ClearOutOldGarbage();
-
-  total -= big;
-  slack -= 4;
-  CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(), slack);
-  if (test_pages_allocated) {
-    EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
-                       (kBlinkPageSize - 1));
-  }
-
-  CheckWithSlack(base_level + total, heap.ObjectPayloadSizeForTesting(), slack);
-  if (test_pages_allocated) {
-    EXPECT_EQ(0ul, heap.stats_collector()->allocated_space_bytes() &
-                       (kBlinkPageSize - 1));
-  }
-
-  for (size_t i = 0; i < persistent_count; i++) {
-    delete persistents[i];
-    persistents[i] = nullptr;
-  }
-}
-
-namespace {
-class HeapAllocatedArray : public GarbageCollected<HeapAllocatedArray> {
- public:
-  HeapAllocatedArray() {
-    for (int i = 0; i < kArraySize; ++i) {
-      array_[i] = i % 128;
-    }
-  }
-
-  int8_t at(size_t i) { return array_[i]; }
-  void Trace(Visitor* visitor) const {}
-
- private:
-  static const int kArraySize = 1000;
-  int8_t array_[kArraySize];
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, SimpleAllocation) {
-  ThreadHeap& heap = ThreadState::Current()->Heap();
-  ClearOutOldGarbage();
-  EXPECT_EQ(0ul, heap.ObjectPayloadSizeForTesting());
-
-  // Allocate an object in the heap.
-  HeapAllocatedArray* array = MakeGarbageCollected<HeapAllocatedArray>();
-  EXPECT_TRUE(heap.ObjectPayloadSizeForTesting() >= sizeof(HeapAllocatedArray));
-
-  // Sanity check of the contents in the heap.
-  EXPECT_EQ(0, array->at(0));
-  EXPECT_EQ(42, array->at(42));
-  EXPECT_EQ(0, array->at(128));
-  EXPECT_EQ(999 % 128, array->at(999));
-}
-
-namespace {
-class TraceCounter final : public GarbageCollected<TraceCounter> {
- public:
-  void Trace(Visitor* visitor) const { trace_count_++; }
-  int TraceCount() const { return trace_count_; }
-
- private:
-  mutable int trace_count_ = 0;
-};
-
-class ClassWithMember : public GarbageCollected<ClassWithMember> {
- public:
-  ClassWithMember() : trace_counter_(MakeGarbageCollected<TraceCounter>()) {}
-
-  void Trace(Visitor* visitor) const { visitor->Trace(trace_counter_); }
-  int TraceCount() const { return trace_counter_->TraceCount(); }
-
- private:
-  Member<TraceCounter> trace_counter_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, SimplePersistent) {
-  Persistent<TraceCounter> trace_counter = MakeGarbageCollected<TraceCounter>();
-  EXPECT_EQ(0, trace_counter->TraceCount());
-  PreciselyCollectGarbage();
-  int saved_trace_count = trace_counter->TraceCount();
-  EXPECT_LT(0, saved_trace_count);
-
-  Persistent<ClassWithMember> class_with_member =
-      MakeGarbageCollected<ClassWithMember>();
-  EXPECT_EQ(0, class_with_member->TraceCount());
-  PreciselyCollectGarbage();
-  EXPECT_LT(0, class_with_member->TraceCount());
-  EXPECT_LT(saved_trace_count, trace_counter->TraceCount());
-}
-
-namespace {
-class SimpleFinalizedObject final
-    : public GarbageCollected<SimpleFinalizedObject> {
- public:
-  SimpleFinalizedObject() = default;
-  ~SimpleFinalizedObject() { ++destructor_calls_; }
-
-  static int destructor_calls_;
-
-  void Trace(Visitor* visitor) const {}
-};
-int SimpleFinalizedObject::destructor_calls_ = 0;
-}  // namespace
-
-TEST_F(HeapInternalsTest, SimpleFinalization) {
-  ClearOutOldGarbage();
-  {
-    SimpleFinalizedObject::destructor_calls_ = 0;
-    Persistent<SimpleFinalizedObject> finalized =
-        MakeGarbageCollected<SimpleFinalizedObject>();
-    EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
-    PreciselyCollectGarbage();
-    EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
-  }
-
-  PreciselyCollectGarbage();
-  EXPECT_EQ(1, SimpleFinalizedObject::destructor_calls_);
-}
-
-#if DCHECK_IS_ON() || defined(LEAK_SANITIZER) || defined(ADDRESS_SANITIZER)
-TEST_F(HeapInternalsTest, FreelistReuse) {
-  ClearOutOldGarbage();
-
-  for (int i = 0; i < 100; i++)
-    MakeGarbageCollected<IntWrapper>(i);
-  IntWrapper* p1 = MakeGarbageCollected<IntWrapper>(100);
-  PreciselyCollectGarbage();
-  // In non-production builds, we delay reusing freed memory for at least
-  // one GC cycle.
-  for (int i = 0; i < 100; i++) {
-    IntWrapper* p2 = MakeGarbageCollected<IntWrapper>(i);
-    EXPECT_NE(p1, p2);
-  }
-
-  PreciselyCollectGarbage();
-  PreciselyCollectGarbage();
-  // Now the freed memory in the first GC should be reused.
-  bool reused_memory_found = false;
-  for (int i = 0; i < 10000; i++) {
-    IntWrapper* p2 = MakeGarbageCollected<IntWrapper>(i);
-    if (p1 == p2) {
-      reused_memory_found = true;
-      break;
-    }
-  }
-  EXPECT_TRUE(reused_memory_found);
-}
-#endif
-
-TEST_F(HeapInternalsTest, LazySweepingPages) {
-  ClearOutOldGarbage();
-
-  SimpleFinalizedObject::destructor_calls_ = 0;
-  EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
-  for (int i = 0; i < 1000; i++)
-    MakeGarbageCollected<SimpleFinalizedObject>();
-  ThreadState::Current()->CollectGarbageForTesting(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
-      BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
-      BlinkGC::GCReason::kForcedGCForTesting);
-  EXPECT_EQ(0, SimpleFinalizedObject::destructor_calls_);
-  for (int i = 0; i < 10000; i++)
-    MakeGarbageCollected<SimpleFinalizedObject>();
-  EXPECT_EQ(1000, SimpleFinalizedObject::destructor_calls_);
-  PreciselyCollectGarbage();
-  EXPECT_EQ(11000, SimpleFinalizedObject::destructor_calls_);
-}
-
-namespace {
-class HeapTestSuperClass : public GarbageCollected<HeapTestSuperClass> {
- public:
-  HeapTestSuperClass() = default;
-  virtual ~HeapTestSuperClass() { ++destructor_calls_; }
-
-  static int destructor_calls_;
-  void Trace(Visitor* visitor) const {}
-};
-int HeapTestSuperClass::destructor_calls_ = 0;
-
-class HeapTestOtherSuperClass {
- public:
-  int payload;
-};
-
-class HeapTestSubClass : public HeapTestSuperClass,
-                         public HeapTestOtherSuperClass {
-  static constexpr size_t kClassMagic = 0xABCDDBCA;
-
- public:
-  HeapTestSubClass() : magic_(kClassMagic) {}
-  ~HeapTestSubClass() override {
-    EXPECT_EQ(kClassMagic, magic_);
-    ++destructor_calls_;
-  }
-
-  static int destructor_calls_;
-
- private:
-  const size_t magic_;
-};
-int HeapTestSubClass::destructor_calls_ = 0;
-constexpr size_t HeapTestSubClass::kClassMagic;
-}  // namespace
-
-TEST_F(HeapInternalsTest, Finalization) {
-  {
-    HeapTestSubClass::destructor_calls_ = 0;
-    HeapTestSuperClass::destructor_calls_ = 0;
-    auto* t1 = MakeGarbageCollected<HeapTestSubClass>();
-    auto* t2 = MakeGarbageCollected<HeapTestSubClass>();
-    auto* t3 = MakeGarbageCollected<HeapTestSuperClass>();
-    // FIXME(oilpan): Ignore unused variables.
-    (void)t1;
-    (void)t2;
-    (void)t3;
-  }
-  // Nothing is marked so the GC should free everything and call
-  // the finalizer on all three objects.
-  PreciselyCollectGarbage();
-  EXPECT_EQ(2, HeapTestSubClass::destructor_calls_);
-  EXPECT_EQ(3, HeapTestSuperClass::destructor_calls_);
-  // Destructors not called again when GCing again.
-  PreciselyCollectGarbage();
-  EXPECT_EQ(2, HeapTestSubClass::destructor_calls_);
-  EXPECT_EQ(3, HeapTestSuperClass::destructor_calls_);
-}
-
-namespace {
-class IntNode : public GarbageCollected<IntNode> {
- public:
-  template <typename T>
-  static void* AllocateObject(size_t size) {
-    ThreadState* state = ThreadState::Current();
-    const char* type_name = WTF_HEAP_PROFILER_TYPE_NAME(IntNode);
-    return state->Heap().AllocateOnArenaIndex(
-        state, size, BlinkGC::kNodeArenaIndex,
-        GCInfoTrait<GCInfoFoldedType<IntNode>>::Index(), type_name);
-  }
-
-  explicit IntNode(int i) : value_(i) {}
-
-  static IntNode* Create(int i) { return MakeGarbageCollected<IntNode>(i); }
-
-  void Trace(Visitor* visitor) const {}
-
-  int Value() { return value_; }
-
- private:
-  int value_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, TypedArenaSanity) {
-  // We use TraceCounter for allocating an object on the general heap.
-  Persistent<TraceCounter> general_heap_object =
-      MakeGarbageCollected<TraceCounter>();
-  Persistent<IntNode> typed_heap_object = IntNode::Create(0);
-  EXPECT_NE(PageFromObject(general_heap_object.Get()),
-            PageFromObject(typed_heap_object.Get()));
-}
-
-TEST_F(HeapInternalsTest, NoAllocation) {
-  ThreadState* state = ThreadState::Current();
-  EXPECT_TRUE(state->IsAllocationAllowed());
-  {
-    // Disallow allocation
-    ThreadState::NoAllocationScope no_allocation_scope(state);
-    EXPECT_FALSE(state->IsAllocationAllowed());
-  }
-  EXPECT_TRUE(state->IsAllocationAllowed());
-}
-
-namespace {
-class Baz : public GarbageCollected<Baz> {
- public:
-  explicit Baz(Bar* bar) : bar_(bar) {}
-
-  void Trace(Visitor* visitor) const { visitor->Trace(bar_); }
-
-  void Clear() { bar_.Release(); }
-
-  // willFinalize is called by FinalizationObserver.
-  void WillFinalize() { EXPECT_TRUE(!bar_->HasBeenFinalized()); }
-
- private:
-  Member<Bar> bar_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, Members) {
-  ClearOutOldGarbage();
-  Bar::live_ = 0;
-  {
-    Persistent<Baz> h1;
-    Persistent<Baz> h2;
-    {
-      h1 = MakeGarbageCollected<Baz>(MakeGarbageCollected<Bar>());
-      PreciselyCollectGarbage();
-      EXPECT_EQ(1u, Bar::live_);
-      h2 = MakeGarbageCollected<Baz>(MakeGarbageCollected<Bar>());
-      PreciselyCollectGarbage();
-      EXPECT_EQ(2u, Bar::live_);
-    }
-    PreciselyCollectGarbage();
-    EXPECT_EQ(2u, Bar::live_);
-    h1->Clear();
-    PreciselyCollectGarbage();
-    EXPECT_EQ(1u, Bar::live_);
-  }
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0u, Bar::live_);
-}
-
-namespace {
-class Foo final : public Bar {
- public:
-  explicit Foo(Bar* bar) : bar_(bar), points_to_foo_(false) {}
-
-  explicit Foo(Foo* foo) : bar_(foo), points_to_foo_(true) {}
-
-  void Trace(Visitor* visitor) const override {
-    Bar::Trace(visitor);
-    if (points_to_foo_)
-      visitor->Trace(static_cast<const Foo*>(bar_.Get()));
-    else
-      visitor->Trace(bar_);
-  }
-
- private:
-  const Member<Bar> bar_;
-  const bool points_to_foo_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, MarkTest) {
-  ClearOutOldGarbage();
-  {
-    Bar::live_ = 0;
-    Persistent<Bar> bar = MakeGarbageCollected<Bar>();
-#if DCHECK_IS_ON()
-    DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(bar));
-#endif
-    EXPECT_EQ(1u, Bar::live_);
-    {
-      auto* foo = MakeGarbageCollected<Foo>(bar);
-#if DCHECK_IS_ON()
-      DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(foo));
-#endif
-      EXPECT_EQ(2u, Bar::live_);
-      EXPECT_TRUE(reinterpret_cast<Address>(foo) !=
-                  reinterpret_cast<Address>(bar.Get()));
-      ConservativelyCollectGarbage();
-      EXPECT_TRUE(foo != bar);  // To make sure foo is kept alive.
-      EXPECT_EQ(2u, Bar::live_);
-    }
-    PreciselyCollectGarbage();
-    EXPECT_EQ(1u, Bar::live_);
-  }
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0u, Bar::live_);
-}
-
-TEST_F(HeapInternalsTest, DeepTest) {
-  ClearOutOldGarbage();
-  const unsigned kDepth = 100000;
-  Bar::live_ = 0;
-  {
-    auto* bar = MakeGarbageCollected<Bar>();
-#if DCHECK_IS_ON()
-    DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(bar));
-#endif
-    auto* foo = MakeGarbageCollected<Foo>(bar);
-#if DCHECK_IS_ON()
-    DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(foo));
-#endif
-    EXPECT_EQ(2u, Bar::live_);
-    for (unsigned i = 0; i < kDepth; i++) {
-      auto* foo2 = MakeGarbageCollected<Foo>(foo);
-      foo = foo2;
-#if DCHECK_IS_ON()
-      DCHECK(ThreadState::Current()->Heap().FindPageFromAddress(foo));
-#endif
-    }
-    EXPECT_EQ(kDepth + 2, Bar::live_);
-    ConservativelyCollectGarbage();
-    EXPECT_TRUE(foo != bar);  // To make sure foo and bar are kept alive.
-    EXPECT_EQ(kDepth + 2, Bar::live_);
-  }
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0u, Bar::live_);
-}
-
-namespace {
-class ConstructorAllocation : public GarbageCollected<ConstructorAllocation> {
- public:
-  ConstructorAllocation() {
-    int_wrapper_ = MakeGarbageCollected<IntWrapper>(42);
-  }
-
-  void Trace(Visitor* visitor) const { visitor->Trace(int_wrapper_); }
-
- private:
-  Member<IntWrapper> int_wrapper_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, NestedAllocation) {
-  ThreadHeap& heap = ThreadState::Current()->Heap();
-  ClearOutOldGarbage();
-  size_t initial_object_payload_size = heap.ObjectPayloadSizeForTesting();
-  {
-    Persistent<ConstructorAllocation> constructor_allocation =
-        MakeGarbageCollected<ConstructorAllocation>();
-  }
-  ClearOutOldGarbage();
-  size_t after_free = heap.ObjectPayloadSizeForTesting();
-  EXPECT_TRUE(initial_object_payload_size == after_free);
-}
-
-namespace {
-class Weak final : public Bar {
- public:
-  Weak(Bar* strong_bar, Bar* weak_bar)
-      : strong_bar_(strong_bar), weak_bar_(weak_bar) {}
-
-  void Trace(Visitor* visitor) const override {
-    Bar::Trace(visitor);
-    visitor->Trace(strong_bar_);
-    visitor->template RegisterWeakCallbackMethod<Weak, &Weak::ZapWeakMembers>(
-        this);
-  }
-
-  void ZapWeakMembers(const LivenessBroker& info) {
-    if (!info.IsHeapObjectAlive(weak_bar_))
-      weak_bar_ = nullptr;
-  }
-
-  bool StrongIsThere() { return !!strong_bar_; }
-  bool WeakIsThere() { return !!weak_bar_; }
-
- private:
-  Member<Bar> strong_bar_;
-  UntracedMember<Bar> weak_bar_;
-};
-
-class WithWeakMember final : public Bar {
- public:
-  WithWeakMember(Bar* strong_bar, Bar* weak_bar)
-      : strong_bar_(strong_bar), weak_bar_(weak_bar) {}
-
-  void Trace(Visitor* visitor) const override {
-    Bar::Trace(visitor);
-    visitor->Trace(strong_bar_);
-    visitor->Trace(weak_bar_);
-  }
-
-  bool StrongIsThere() { return !!strong_bar_; }
-  bool WeakIsThere() { return !!weak_bar_; }
-
- private:
-  Member<Bar> strong_bar_;
-  WeakMember<Bar> weak_bar_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, WeakMembers) {
-  ClearOutOldGarbage();
-  Bar::live_ = 0;
-  {
-    Persistent<Bar> h1 = MakeGarbageCollected<Bar>();
-    Persistent<Weak> h4;
-    Persistent<WithWeakMember> h5;
-    PreciselyCollectGarbage();
-    ASSERT_EQ(1u, Bar::live_);  // h1 is live.
-    {
-      auto* h2 = MakeGarbageCollected<Bar>();
-      auto* h3 = MakeGarbageCollected<Bar>();
-      h4 = MakeGarbageCollected<Weak>(h2, h3);
-      h5 = MakeGarbageCollected<WithWeakMember>(h2, h3);
-      ConservativelyCollectGarbage();
-      EXPECT_EQ(5u, Bar::live_);  // The on-stack pointer keeps h3 alive.
-      EXPECT_FALSE(h3->HasBeenFinalized());
-      EXPECT_TRUE(h4->StrongIsThere());
-      EXPECT_TRUE(h4->WeakIsThere());
-      EXPECT_TRUE(h5->StrongIsThere());
-      EXPECT_TRUE(h5->WeakIsThere());
-    }
-    // h3 is collected, weak pointers from h4 and h5 don't keep it alive.
-    PreciselyCollectGarbage();
-    EXPECT_EQ(4u, Bar::live_);
-    EXPECT_TRUE(h4->StrongIsThere());
-    EXPECT_FALSE(h4->WeakIsThere());  // h3 is gone from weak pointer.
-    EXPECT_TRUE(h5->StrongIsThere());
-    EXPECT_FALSE(h5->WeakIsThere());  // h3 is gone from weak pointer.
-    h1.Release();                     // Zero out h1.
-    PreciselyCollectGarbage();
-    EXPECT_EQ(3u, Bar::live_);         // Only h4, h5 and h2 are left.
-    EXPECT_TRUE(h4->StrongIsThere());  // h2 is still pointed to from h4.
-    EXPECT_TRUE(h5->StrongIsThere());  // h2 is still pointed to from h5.
-  }
-  // h4 and h5 have gone out of scope now and they were keeping h2 alive.
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0u, Bar::live_);  // All gone.
-}
-
-namespace {
-class Observable final : public GarbageCollected<Observable> {
-  USING_PRE_FINALIZER(Observable, WillFinalize);
-
- public:
-  explicit Observable(Bar* bar) : bar_(bar), was_destructed_(false) {}
-  ~Observable() { was_destructed_ = true; }
-  void Trace(Visitor* visitor) const { visitor->Trace(bar_); }
-
-  // willFinalize is called by FinalizationObserver. willFinalize can touch
-  // other on-heap objects.
-  void WillFinalize() {
-    EXPECT_FALSE(was_destructed_);
-    EXPECT_FALSE(bar_->HasBeenFinalized());
-    will_finalize_was_called_ = true;
-  }
-  static bool will_finalize_was_called_;
-
- private:
-  Member<Bar> bar_;
-  bool was_destructed_;
-};
-bool Observable::will_finalize_was_called_ = false;
-
-template <typename T>
-class FinalizationObserver : public GarbageCollected<FinalizationObserver<T>> {
- public:
-  explicit FinalizationObserver(T* data)
-      : data_(data), did_call_will_finalize_(false) {}
-
-  bool DidCallWillFinalize() const { return did_call_will_finalize_; }
-
-  void Trace(Visitor* visitor) const {
-    visitor->template RegisterWeakCallbackMethod<
-        FinalizationObserver<T>, &FinalizationObserver<T>::ZapWeakMembers>(
-        this);
-  }
-
-  void ZapWeakMembers(const LivenessBroker& info) {
-    if (data_ && !info.IsHeapObjectAlive(data_)) {
-      data_->WillFinalize();
-      data_ = nullptr;
-      did_call_will_finalize_ = true;
-    }
-  }
-
- private:
-  UntracedMember<T> data_;
-  bool did_call_will_finalize_;
-};
-
-class FinalizationObserverWithHashMap {
- public:
-  typedef HeapHashMap<WeakMember<Observable>,
-                      std::unique_ptr<FinalizationObserverWithHashMap>>
-      ObserverMap;
-
-  explicit FinalizationObserverWithHashMap(Observable* target)
-      : target_(target) {}
-  ~FinalizationObserverWithHashMap() {
-    target_->WillFinalize();
-    did_call_will_finalize_ = true;
-  }
-
-  static ObserverMap& Observe(Observable* target) {
-    ObserverMap& map = Observers();
-    ObserverMap::AddResult result = map.insert(target, nullptr);
-    if (result.is_new_entry) {
-      result.stored_value->value =
-          std::make_unique<FinalizationObserverWithHashMap>(target);
-    } else {
-      DCHECK(result.stored_value->value);
-    }
-    return map;
-  }
-
-  static void ClearObservers() {
-    delete observer_map_;
-    observer_map_ = nullptr;
-  }
-
-  static bool did_call_will_finalize_;
-
- private:
-  static ObserverMap& Observers() {
-    if (!observer_map_) {
-      observer_map_ =
-          new Persistent<ObserverMap>(MakeGarbageCollected<ObserverMap>());
-    }
-    return **observer_map_;
-  }
-
-  UntracedMember<Observable> target_;
-  static Persistent<ObserverMap>* observer_map_;
-};
-bool FinalizationObserverWithHashMap::did_call_will_finalize_ = false;
-Persistent<FinalizationObserverWithHashMap::ObserverMap>*
-    FinalizationObserverWithHashMap::observer_map_;
-}  // namespace
-
-TEST_F(HeapInternalsTest, FinalizationObserver) {
-  Persistent<FinalizationObserver<Observable>> o;
-  {
-    auto* foo = MakeGarbageCollected<Observable>(MakeGarbageCollected<Bar>());
-    // |o| observes |foo|.
-    o = MakeGarbageCollected<FinalizationObserver<Observable>>(foo);
-  }
-  // FinalizationObserver doesn't have a strong reference to |foo|. So |foo|
-  // and its member will be collected.
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0u, Bar::live_);
-  EXPECT_TRUE(o->DidCallWillFinalize());
-
-  FinalizationObserverWithHashMap::did_call_will_finalize_ = false;
-  auto* foo = MakeGarbageCollected<Observable>(MakeGarbageCollected<Bar>());
-  FinalizationObserverWithHashMap::ObserverMap& map =
-      FinalizationObserverWithHashMap::Observe(foo);
-  EXPECT_EQ(1u, map.size());
-  foo = nullptr;
-  // FinalizationObserverWithHashMap doesn't have a strong reference to
-  // |foo|. So |foo| and its member will be collected.
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0u, Bar::live_);
-  EXPECT_EQ(0u, map.size());
-  EXPECT_TRUE(FinalizationObserverWithHashMap::did_call_will_finalize_);
-
-  FinalizationObserverWithHashMap::ClearObservers();
-}
-
-TEST_F(HeapInternalsTest, PreFinalizer) {
-  Observable::will_finalize_was_called_ = false;
-  { MakeGarbageCollected<Observable>(MakeGarbageCollected<Bar>()); }
-  PreciselyCollectGarbage();
-  EXPECT_TRUE(Observable::will_finalize_was_called_);
-}
-
-namespace {
-class ObservableWithPreFinalizer final
-    : public GarbageCollected<ObservableWithPreFinalizer> {
-  USING_PRE_FINALIZER(ObservableWithPreFinalizer, Dispose);
-
- public:
-  ~ObservableWithPreFinalizer() { was_destructed_ = true; }
-  void Trace(Visitor* visitor) const {}
-  void Dispose() {
-    EXPECT_FALSE(was_destructed_);
-    dispose_was_called_ = true;
-  }
-  static bool dispose_was_called_;
-
- protected:
-  bool was_destructed_ = false;
-};
-bool ObservableWithPreFinalizer::dispose_was_called_ = false;
-}  // namespace
-
-TEST_F(HeapInternalsTest, PreFinalizerUnregistersItself) {
-  ObservableWithPreFinalizer::dispose_was_called_ = false;
-  MakeGarbageCollected<ObservableWithPreFinalizer>();
-  PreciselyCollectGarbage();
-  EXPECT_TRUE(ObservableWithPreFinalizer::dispose_was_called_);
-  // Don't crash, and assertions don't fail.
-}
-
-namespace {
-bool g_dispose_was_called_for_pre_finalizer_base = false;
-bool g_dispose_was_called_for_pre_finalizer_mixin = false;
-bool g_dispose_was_called_for_pre_finalizer_sub_class = false;
-
-class PreFinalizerBase : public GarbageCollected<PreFinalizerBase> {
-  USING_PRE_FINALIZER(PreFinalizerBase, Dispose);
-
- public:
-  virtual ~PreFinalizerBase() { was_destructed_ = true; }
-  virtual void Trace(Visitor* visitor) const {}
-  void Dispose() {
-    EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_base);
-    EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_sub_class);
-    EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_mixin);
-    EXPECT_FALSE(was_destructed_);
-    g_dispose_was_called_for_pre_finalizer_base = true;
-  }
-
- protected:
-  bool was_destructed_ = false;
-};
-
-class PreFinalizerMixin : public GarbageCollectedMixin {
-  USING_PRE_FINALIZER(PreFinalizerMixin, Dispose);
-
- public:
-  ~PreFinalizerMixin() { was_destructed_ = true; }
-  void Trace(Visitor* visitor) const override {}
-  void Dispose() {
-    EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_base);
-    EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_sub_class);
-    EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_mixin);
-    EXPECT_FALSE(was_destructed_);
-    g_dispose_was_called_for_pre_finalizer_mixin = true;
-  }
-
- protected:
-  bool was_destructed_ = false;
-};
-
-class PreFinalizerSubClass : public PreFinalizerBase, public PreFinalizerMixin {
-  USING_PRE_FINALIZER(PreFinalizerSubClass, Dispose);
-
- public:
-  ~PreFinalizerSubClass() override { was_destructed_ = true; }
-  void Trace(Visitor* visitor) const override {
-    PreFinalizerBase::Trace(visitor);
-    PreFinalizerMixin::Trace(visitor);
-  }
-  void Dispose() {
-    EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_base);
-    EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_sub_class);
-    EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_mixin);
-    EXPECT_FALSE(was_destructed_);
-    g_dispose_was_called_for_pre_finalizer_sub_class = true;
-  }
-
- protected:
-  bool was_destructed_ = false;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, NestedPreFinalizer) {
-  g_dispose_was_called_for_pre_finalizer_base = false;
-  g_dispose_was_called_for_pre_finalizer_sub_class = false;
-  g_dispose_was_called_for_pre_finalizer_mixin = false;
-  MakeGarbageCollected<PreFinalizerSubClass>();
-  PreciselyCollectGarbage();
-  EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_base);
-  EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_sub_class);
-  EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_mixin);
-  // Don't crash, and assertions don't fail.
-}
-
-TEST_F(HeapInternalsTest, Comparisons) {
-  Persistent<Bar> bar_persistent = MakeGarbageCollected<Bar>();
-  Persistent<Foo> foo_persistent = MakeGarbageCollected<Foo>(bar_persistent);
-  EXPECT_TRUE(bar_persistent != foo_persistent);
-  bar_persistent = foo_persistent;
-  EXPECT_TRUE(bar_persistent == foo_persistent);
-}
-
-namespace {
-class DisableHeapVerificationScope {
- public:
-  explicit DisableHeapVerificationScope(const char*) {
-    ThreadState::Current()->EnterNoHeapVerificationScopeForTesting();
-  }
-  ~DisableHeapVerificationScope() {
-    ThreadState::Current()->LeaveNoHeapVerificationScopeForTesting();
-  }
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, GarbageCollectedMixin) {
-  ClearOutOldGarbage();
-
-  Persistent<UseMixin> usemixin = MakeGarbageCollected<UseMixin>();
-  EXPECT_EQ(0, UseMixin::trace_count_);
-  {
-    DisableHeapVerificationScope scope(
-        "Avoid tracing UseMixin during verification");
-    PreciselyCollectGarbage();
-  }
-  EXPECT_EQ(1, UseMixin::trace_count_);
-
-  Persistent<Mixin> mixin = usemixin;
-  usemixin = nullptr;
-  {
-    DisableHeapVerificationScope scope(
-        "Avoid tracing UseMixin during verification");
-    PreciselyCollectGarbage();
-  }
-  EXPECT_EQ(2, UseMixin::trace_count_);
-
-  Persistent<HeapHashSet<WeakMember<Mixin>>> weak_map =
-      MakeGarbageCollected<HeapHashSet<WeakMember<Mixin>>>();
-  weak_map->insert(MakeGarbageCollected<UseMixin>());
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0u, weak_map->size());
-}
-
-namespace {
-class OneKiloByteObject final : public GarbageCollected<OneKiloByteObject> {
- public:
-  ~OneKiloByteObject() { destructor_calls_++; }
-  char* Data() { return data_; }
-  void Trace(Visitor* visitor) const {}
-  static int destructor_calls_;
-
- private:
-  static const size_t kLength = 1024;
-  char data_[kLength];
-};
-int OneKiloByteObject::destructor_calls_ = 0;
-
-class FinalizationAllocator final
-    : public GarbageCollected<FinalizationAllocator> {
- public:
-  explicit FinalizationAllocator(Persistent<IntWrapper>* wrapper) {
-    wrapper_ = wrapper;
-  }
-
-  ~FinalizationAllocator() {
-    for (int i = 0; i < 10; ++i)
-      *wrapper_ = MakeGarbageCollected<IntWrapper>(42);
-    for (int i = 0; i < 512; ++i)
-      MakeGarbageCollected<OneKiloByteObject>();
-    for (int i = 0; i < 32; ++i)
-      MakeGarbageCollected<LargeHeapObject>();
-  }
-
-  void Trace(Visitor* visitor) const {}
-
- private:
-  static Persistent<IntWrapper>* wrapper_;
-};
-
-Persistent<IntWrapper>* FinalizationAllocator::wrapper_;
-}  // namespace
-
-TEST_F(HeapInternalsTest, AllocationDuringFinalization) {
-  ClearOutOldGarbage();
-  IntWrapper::destructor_calls_ = 0;
-  OneKiloByteObject::destructor_calls_ = 0;
-  LargeHeapObject::destructor_calls_ = 0;
-
-  Persistent<IntWrapper> wrapper;
-  MakeGarbageCollected<FinalizationAllocator>(&wrapper);
-
-  PreciselyCollectGarbage();
-  EXPECT_EQ(0, IntWrapper::destructor_calls_);
-  EXPECT_EQ(0, OneKiloByteObject::destructor_calls_);
-  EXPECT_EQ(0, LargeHeapObject::destructor_calls_);
-  // Check that the wrapper allocated during finalization is not
-  // swept away and zapped later in the same sweeping phase.
-  EXPECT_EQ(42, wrapper->Value());
-
-  wrapper.Clear();
-  PreciselyCollectGarbage();
-  // The 42 IntWrappers were the ones allocated in ~FinalizationAllocator
-  // and the ones allocated in LargeHeapObject.
-  EXPECT_EQ(42, IntWrapper::destructor_calls_);
-  EXPECT_EQ(512, OneKiloByteObject::destructor_calls_);
-  EXPECT_EQ(32, LargeHeapObject::destructor_calls_);
-}
-
-namespace {
-class MixinInstanceWithoutTrace
-    : public GarbageCollected<MixinInstanceWithoutTrace>,
-      public MixinA {
- public:
-  MixinInstanceWithoutTrace() = default;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, MixinInstanceWithoutTrace) {
-  // Verify that a mixin instance without any traceable
-  // references inherits the mixin's trace implementation.
-  ClearOutOldGarbage();
-  MixinA::trace_count_ = 0;
-  MixinInstanceWithoutTrace* obj =
-      MakeGarbageCollected<MixinInstanceWithoutTrace>();
-  int saved_trace_count = 0;
-  {
-    Persistent<MixinA> a = obj;
-    PreciselyCollectGarbage();
-    saved_trace_count = MixinA::trace_count_;
-    EXPECT_LT(0, saved_trace_count);
-  }
-  {
-    Persistent<MixinInstanceWithoutTrace> b = obj;
-    PreciselyCollectGarbage();
-    EXPECT_LT(saved_trace_count, MixinA::trace_count_);
-    saved_trace_count = MixinA::trace_count_;
-  }
-  PreciselyCollectGarbage();
-  // Oilpan might still call trace on dead objects for various reasons which is
-  // valid before sweeping started.
-  EXPECT_LE(saved_trace_count, MixinA::trace_count_);
-}
-
-namespace {
-class PartObjectWithVirtualMethod {
- public:
-  virtual void Trace(Visitor* visitor) const {}
-};
-
-class ObjectWithVirtualPartObject
-    : public GarbageCollected<ObjectWithVirtualPartObject> {
- public:
-  ObjectWithVirtualPartObject() : dummy_(AllocateAndReturnBool()) {}
-  void Trace(Visitor* visitor) const { visitor->Trace(part_); }
-
- private:
-  bool dummy_;
-  PartObjectWithVirtualMethod part_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, PartObjectWithVirtualMethod) {
-  ObjectWithVirtualPartObject* object =
-      MakeGarbageCollected<ObjectWithVirtualPartObject>();
-  EXPECT_TRUE(object);
-}
-
-namespace {
-class NonNodeAllocatingNodeInDestructor final
-    : public GarbageCollected<NonNodeAllocatingNodeInDestructor> {
- public:
-  ~NonNodeAllocatingNodeInDestructor() {
-    node_ = new Persistent<IntNode>(IntNode::Create(10));
-  }
-
-  void Trace(Visitor* visitor) const {}
-
-  static Persistent<IntNode>* node_;
-};
-
-Persistent<IntNode>* NonNodeAllocatingNodeInDestructor::node_ = nullptr;
-}  // namespace
-
-TEST_F(HeapInternalsTest, NonNodeAllocatingNodeInDestructor) {
-  MakeGarbageCollected<NonNodeAllocatingNodeInDestructor>();
-  PreciselyCollectGarbage();
-  EXPECT_EQ(10, (*NonNodeAllocatingNodeInDestructor::node_)->Value());
-  delete NonNodeAllocatingNodeInDestructor::node_;
-  NonNodeAllocatingNodeInDestructor::node_ = nullptr;
-}
-
-namespace {
-class WeakPersistentHolder final {
- public:
-  explicit WeakPersistentHolder(IntWrapper* object) : object_(object) {}
-  IntWrapper* Object() const { return object_; }
-
- private:
-  WeakPersistent<IntWrapper> object_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, WeakPersistent) {
-  Persistent<IntWrapper> object = MakeGarbageCollected<IntWrapper>(20);
-  std::unique_ptr<WeakPersistentHolder> holder =
-      std::make_unique<WeakPersistentHolder>(object);
-  PreciselyCollectGarbage();
-  EXPECT_TRUE(holder->Object());
-  object = nullptr;
-  PreciselyCollectGarbage();
-  EXPECT_FALSE(holder->Object());
-}
-
-namespace {
-class WithWeakConstObject final : public GarbageCollected<WithWeakConstObject> {
- public:
-  explicit WithWeakConstObject(const IntWrapper* int_wrapper)
-      : wrapper_(int_wrapper) {}
-
-  void Trace(Visitor* visitor) const { visitor->Trace(wrapper_); }
-
-  const IntWrapper* Value() const { return wrapper_; }
-
- private:
-  WeakMember<const IntWrapper> wrapper_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, TestWeakConstObject) {
-  Persistent<WithWeakConstObject> weak_wrapper;
-  {
-    const auto* wrapper = MakeGarbageCollected<IntWrapper>(42);
-    weak_wrapper = MakeGarbageCollected<WithWeakConstObject>(wrapper);
-    ConservativelyCollectGarbage();
-    EXPECT_EQ(wrapper, weak_wrapper->Value());
-    // Stub out any stack reference.
-    wrapper = nullptr;
-  }
-  PreciselyCollectGarbage();
-  EXPECT_EQ(nullptr, weak_wrapper->Value());
-}
-
-namespace {
-class EmptyMixin : public GarbageCollectedMixin {};
-class UseMixinFromLeftmostInherited : public UseMixin, public EmptyMixin {
- public:
-  ~UseMixinFromLeftmostInherited() = default;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, IsGarbageCollected) {
-  // Static sanity checks covering the correct operation of
-  // IsGarbageCollectedType<>.
-
-  static_assert(WTF::IsGarbageCollectedType<SimpleObject>::value,
-                "GarbageCollected<>");
-  static_assert(WTF::IsGarbageCollectedType<const SimpleObject>::value,
-                "const GarbageCollected<>");
-  static_assert(WTF::IsGarbageCollectedType<IntWrapper>::value,
-                "GarbageCollected<>");
-  static_assert(WTF::IsGarbageCollectedType<GarbageCollectedMixin>::value,
-                "GarbageCollectedMixin");
-  static_assert(WTF::IsGarbageCollectedType<const GarbageCollectedMixin>::value,
-                "const GarbageCollectedMixin");
-  static_assert(WTF::IsGarbageCollectedType<UseMixin>::value,
-                "GarbageCollectedMixin instance");
-  static_assert(WTF::IsGarbageCollectedType<const UseMixin>::value,
-                "const GarbageCollectedMixin instance");
-  static_assert(
-      WTF::IsGarbageCollectedType<UseMixinFromLeftmostInherited>::value,
-      "GarbageCollectedMixin derived instance");
-  static_assert(WTF::IsGarbageCollectedType<MultipleMixins>::value,
-                "GarbageCollectedMixin");
-
-  static_assert(
-      WTF::IsGarbageCollectedType<HeapHashSet<Member<IntWrapper>>>::value,
-      "HeapHashSet");
-  static_assert(
-      WTF::IsGarbageCollectedType<HeapLinkedHashSet<Member<IntWrapper>>>::value,
-      "HeapLinkedHashSet");
-  static_assert(WTF::IsGarbageCollectedType<
-                    HeapHashCountedSet<Member<IntWrapper>>>::value,
-                "HeapHashCountedSet");
-  static_assert(
-      WTF::IsGarbageCollectedType<HeapHashMap<int, Member<IntWrapper>>>::value,
-      "HeapHashMap");
-  static_assert(
-      WTF::IsGarbageCollectedType<HeapVector<Member<IntWrapper>>>::value,
-      "HeapVector");
-  static_assert(
-      WTF::IsGarbageCollectedType<HeapDeque<Member<IntWrapper>>>::value,
-      "HeapDeque");
-}
-
-TEST_F(HeapInternalsTest, ShrinkVector) {
-  // Regression test: https://crbug.com/823289
-
-  HeapVector<Member<IntWrapper>> vector;
-  vector.ReserveCapacity(32);
-  for (int i = 0; i < 4; i++) {
-    vector.push_back(MakeGarbageCollected<IntWrapper>(i));
-  }
-
-  ConservativelyCollectGarbage(BlinkGC::kConcurrentAndLazySweeping);
-
-  // The following call tries to promptly free the left overs. In the buggy
-  // scenario that would create a free HeapObjectHeader that is assumed to be
-  // black which it is not.
-  vector.ShrinkToFit();
-}
-
-TEST_F(HeapInternalsTest, GarbageCollectedInConstruction) {
-  using O = ObjectWithCallbackBeforeInitializer<IntWrapper>;
-  MakeGarbageCollected<O>(base::BindOnce([](O* thiz) {
-    CHECK(HeapObjectHeader::FromPayload(thiz)->IsInConstruction());
-  }));
-}
-
-TEST_F(HeapInternalsTest, GarbageCollectedMixinInConstruction) {
-  using O = ObjectWithMixinWithCallbackBeforeInitializer<IntWrapper>;
-  MakeGarbageCollected<O>(base::BindOnce([](O::Mixin* thiz) {
-    const HeapObjectHeader* const header =
-        HeapObjectHeader::FromInnerAddress(reinterpret_cast<Address>(thiz));
-    CHECK(header->IsInConstruction());
-  }));
-}
-
-TEST_F(HeapInternalsTest, PersistentAssignsDeletedValue) {
-  // Regression test: https://crbug.com/982313
-
-  Persistent<IntWrapper> deleted(WTF::kHashTableDeletedValue);
-  Persistent<IntWrapper> pre_initialized(MakeGarbageCollected<IntWrapper>(1));
-  pre_initialized = deleted;
-  PreciselyCollectGarbage();
-}
-
-namespace {
-struct HeapHashMapWrapper final : GarbageCollected<HeapHashMapWrapper> {
-  HeapHashMapWrapper() {
-    for (int i = 0; i < 100; ++i) {
-      map_.insert(MakeGarbageCollected<IntWrapper>(i),
-                  NonTriviallyDestructible());
-    }
-  }
-  // This should call ~HeapHapMap() -> ~HashMap() -> ~HashTable().
-  ~HeapHashMapWrapper() = default;
-
-  void Trace(Visitor* visitor) const { visitor->Trace(map_); }
-
- private:
-  struct NonTriviallyDestructible {
-    ~NonTriviallyDestructible() {}
-  };
-  HeapHashMap<Member<IntWrapper>, NonTriviallyDestructible> map_;
-};
-}  // namespace
-
-TEST_F(HeapInternalsTest, AccessDeletedBackingStore) {
-  // Regression test: https://crbug.com/985443
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(
-      blink::features::kBlinkHeapConcurrentSweeping);
-  ClearOutOldGarbage();
-
-  ThreadState* thread_state = ThreadState::Current();
-
-  auto* map = MakeGarbageCollected<HeapHashMapWrapper>();
-  // Run marking.
-  PreciselyCollectGarbage(BlinkGC::kConcurrentAndLazySweeping);
-  // Perform complete sweep on hash_arena.
-  BaseArena* hash_arena =
-      thread_state->Heap().Arena(BlinkGC::kHashTableArenaIndex);
-  {
-    ThreadState::AtomicPauseScope scope(thread_state);
-    ScriptForbiddenScope script_forbidden_scope;
-    ThreadState::SweepForbiddenScope sweep_forbidden(thread_state);
-    hash_arena->CompleteSweep();
-  }
-  BaseArena* map_arena = PageFromObject(map)->Arena();
-  // Sweep normal arena, but don't call finalizers.
-  while (!map_arena->ConcurrentSweepOnePage()) {
-  }
-  // Now complete sweeping with PerformIdleLazySweep and call finalizers.
-  while (thread_state->IsSweepingInProgress()) {
-    thread_state->PerformIdleLazySweep(base::TimeTicks::Max());
-  }
-}
-
-namespace {
-class GCBase : public GarbageCollected<GCBase> {
- public:
-  virtual void Trace(Visitor*) const {}
-};
-
-class GCDerived final : public GCBase {
- public:
-  static int destructor_called;
-  void Trace(Visitor* visitor) const override { GCBase::Trace(visitor); }
-  ~GCDerived() { ++destructor_called; }
-};
-int GCDerived::destructor_called = 0;
-}  // namespace
-
-TEST_F(HeapInternalsTest, CallMostDerivedFinalizer) {
-  MakeGarbageCollected<GCDerived>();
-  PreciselyCollectGarbage();
-  EXPECT_EQ(1, GCDerived::destructor_called);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/heap_stats_collector_test.cc b/third_party/blink/renderer/platform/heap/impl/test/heap_stats_collector_test.cc
deleted file mode 100644
index 6f8ac67..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/heap_stats_collector_test.cc
+++ /dev/null
@@ -1,690 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-namespace {
-
-constexpr size_t kNoMarkedBytes = 0;
-
-}  // namespace
-
-// =============================================================================
-// ThreadHeapStatsCollector. ===================================================
-// =============================================================================
-
-TEST(ThreadHeapStatsCollectorTest, InitialEmpty) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  for (int i = 0; i < ThreadHeapStatsCollector::kNumScopeIds; i++) {
-    EXPECT_EQ(base::TimeDelta(), stats_collector.current().scope_data[i]);
-  }
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, IncreaseScopeTime) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStep,
-      base::TimeDelta::FromMilliseconds(1));
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
-            stats_collector.current()
-                .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, StopMovesCurrentToPrevious) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStep,
-      base::TimeDelta::FromMilliseconds(1));
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
-            stats_collector.previous()
-                .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]);
-}
-
-TEST(ThreadHeapStatsCollectorTest, StopResetsCurrent) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStep,
-      base::TimeDelta::FromMilliseconds(1));
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(base::TimeDelta(),
-            stats_collector.current()
-                .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]);
-}
-
-TEST(ThreadHeapStatsCollectorTest, StartStop) {
-  ThreadHeapStatsCollector stats_collector;
-  EXPECT_FALSE(stats_collector.is_started());
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  EXPECT_TRUE(stats_collector.is_started());
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_FALSE(stats_collector.is_started());
-}
-
-TEST(ThreadHeapStatsCollectorTest, ScopeToString) {
-  EXPECT_STREQ("BlinkGC.IncrementalMarkingStartMarking",
-               ThreadHeapStatsCollector::ToString(
-                   ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
-                   BlinkGC::CollectionType::kMajor));
-}
-
-TEST(ThreadHeapStatsCollectorTest, UpdateReason) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.UpdateReason(BlinkGC::GCReason::kForcedGCForTesting);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(BlinkGC::GCReason::kForcedGCForTesting,
-            stats_collector.previous().reason);
-}
-
-TEST(ThreadHeapStatsCollectorTest, InitialEstimatedObjectSize) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  EXPECT_EQ(0u, stats_collector.object_size_in_bytes());
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, EstimatedObjectSizeNoMarkedBytes) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseAllocatedObjectSizeForTesting(512);
-  EXPECT_EQ(512u, stats_collector.object_size_in_bytes());
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EstimatedObjectSizeIgnoresPreviouslyMarkedBytes) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.IncreaseAllocatedObjectSizeForTesting(512);
-  EXPECT_EQ(512u, stats_collector.object_size_in_bytes());
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EstimatedObjectSizeUsesCurrentlyMarkedBytes) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(256);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  // Currently marked bytes should not account to the estimated object size.
-  stats_collector.IncreaseAllocatedObjectSizeForTesting(512);
-  EXPECT_EQ(640u, stats_collector.object_size_in_bytes());
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, PreInitializedEstimatedMarkingTime) {
-  // Checks that a marking time estimate can be retrieved before the first
-  // garbage collection triggers.
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime1) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
-      base::TimeDelta::FromSeconds(1));
-  stats_collector.NotifyMarkingCompleted(1024);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, EstimatedMarkingTime2) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
-      base::TimeDelta::FromSeconds(1));
-  stats_collector.NotifyMarkingCompleted(1024);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseAllocatedObjectSizeForTesting(512);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, SubMilliSecondMarkingTime) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
-      base::TimeDelta::FromMillisecondsD(.5));
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-}
-
-TEST(ThreadHeapStatsCollectorTest, AllocatedSpaceInBytesInitialZero) {
-  ThreadHeapStatsCollector stats_collector;
-  EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
-}
-
-TEST(ThreadHeapStatsCollectorTest, AllocatedSpaceInBytesIncrease) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.IncreaseAllocatedSpace(1024);
-  EXPECT_EQ(1024u, stats_collector.allocated_space_bytes());
-}
-
-TEST(ThreadHeapStatsCollectorTest, AllocatedSpaceInBytesDecrease) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.IncreaseAllocatedSpace(1024);
-  stats_collector.DecreaseAllocatedSpace(1024);
-  EXPECT_EQ(0u, stats_collector.allocated_space_bytes());
-}
-
-// =============================================================================
-// ThreadHeapStatsCollector::Event. ============================================
-// =============================================================================
-
-TEST(ThreadHeapStatsCollectorTest, EventPrevGCMarkedObjectSize) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(1024);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(1024u, stats_collector.previous().marked_bytes);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EventMarkingTimeFromIncrementalStandAloneGC) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
-      base::TimeDelta::FromMilliseconds(7));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStep,
-      base::TimeDelta::FromMilliseconds(2));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
-      base::TimeDelta::FromMilliseconds(4));
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(13.0,
-                   stats_collector.previous().marking_time().InMillisecondsF());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeFromIncrementalUnifiedGC) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStartMarking,
-      base::TimeDelta::FromMilliseconds(7));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStep,
-      base::TimeDelta::FromMilliseconds(2));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kUnifiedMarkingStep,
-      base::TimeDelta::FromMilliseconds(1));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkPrologue,
-      base::TimeDelta::FromMilliseconds(3));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
-      base::TimeDelta::FromMilliseconds(2));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkEpilogue,
-      base::TimeDelta::FromMilliseconds(1));
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(16.0,
-                   stats_collector.previous().marking_time().InMillisecondsF());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventMarkingTime) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kIncrementalMarkingStep,
-      base::TimeDelta::FromMilliseconds(2));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
-      base::TimeDelta::FromMilliseconds(11));
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(13.0,
-                   stats_collector.previous().marking_time().InMillisecondsF());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventAtomicMarkingTime) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkPrologue,
-      base::TimeDelta::FromMilliseconds(5));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
-      base::TimeDelta::FromMilliseconds(3));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkEpilogue,
-      base::TimeDelta::FromMilliseconds(1));
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(9),
-            stats_collector.previous().atomic_marking_time());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventAtomicPause) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure,
-      base::TimeDelta::FromMilliseconds(17));
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kAtomicPauseSweepAndCompact,
-      base::TimeDelta::FromMilliseconds(15));
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(32),
-            stats_collector.previous().atomic_pause_time());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventSweepingTime) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle,
-                                    base::TimeDelta::FromMilliseconds(1));
-  stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle,
-                                    base::TimeDelta::FromMilliseconds(2));
-  stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle,
-                                    base::TimeDelta::FromMilliseconds(3));
-  stats_collector.IncreaseScopeTime(
-      ThreadHeapStatsCollector::kLazySweepOnAllocation,
-      base::TimeDelta::FromMilliseconds(4));
-  stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kCompleteSweep,
-                                    base::TimeDelta::FromMilliseconds(5));
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(base::TimeDelta::FromMilliseconds(15),
-            stats_collector.previous().sweeping_time());
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedBytes) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.IncreaseCompactionFreedSize(512);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(512u, stats_collector.previous().compaction_freed_bytes);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventCompactionFreedPages) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.IncreaseCompactionFreedPages(3);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(3u, stats_collector.previous().compaction_freed_pages);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventInitialEstimatedLiveObjectRate) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(0.0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EventEstimatedLiveObjectRateSameMarkedBytes) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(1.0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EventEstimatedLiveObjectRateHalfMarkedBytes) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(256);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(0.5, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventEstimatedLiveObjectRateNoMarkedBytes) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(256);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(0.0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EventEstimatedLiveObjectRateWithAllocatedBytes1) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.IncreaseAllocatedObjectSize(128);
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(.5, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EventEstimatedLiveObjectRateWithAllocatedBytes2) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.IncreaseAllocatedObjectSize(128);
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(1.0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EventEstimatedLiveObjectRateWithAllocatedBytes3) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest,
-     EventEstimatedLiveObjectRateWithAllocatedBytes4) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(128);
-  stats_collector.NotifySweepingCompleted();
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_DOUBLE_EQ(0, stats_collector.previous().live_object_rate);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping1) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseAllocatedSpace(1024);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.IncreaseAllocatedSpace(2048);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(
-      1024u,
-      stats_collector.previous().allocated_space_in_bytes_before_sweeping);
-}
-
-TEST(ThreadHeapStatsCollectorTest, EventAllocatedSpaceBeforeSweeping2) {
-  ThreadHeapStatsCollector stats_collector;
-  stats_collector.NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                       BlinkGC::GCReason::kForcedGCForTesting,
-                                       true /* is_forced_gc */);
-  stats_collector.IncreaseAllocatedSpace(1024);
-  stats_collector.NotifyMarkingCompleted(kNoMarkedBytes);
-  stats_collector.DecreaseAllocatedSpace(1024);
-  stats_collector.NotifySweepingCompleted();
-  EXPECT_EQ(
-      1024u,
-      stats_collector.previous().allocated_space_in_bytes_before_sweeping);
-}
-
-// =============================================================================
-// ThreadHeapStatsObserver. ====================================================
-// =============================================================================
-
-namespace {
-
-class MockThreadHeapStatsObserver : public ThreadHeapStatsObserver {
- public:
-  MOCK_METHOD1(IncreaseAllocatedSpace, void(size_t));
-  MOCK_METHOD1(DecreaseAllocatedSpace, void(size_t));
-  MOCK_METHOD1(ResetAllocatedObjectSize, void(size_t));
-  MOCK_METHOD1(IncreaseAllocatedObjectSize, void(size_t));
-  MOCK_METHOD1(DecreaseAllocatedObjectSize, void(size_t));
-};
-
-void FakeGC(ThreadHeapStatsCollector* stats_collector, size_t marked_bytes) {
-  stats_collector->NotifyMarkingStarted(BlinkGC::CollectionType::kMajor,
-                                        BlinkGC::GCReason::kForcedGCForTesting,
-                                        true /* is_forced_gc */);
-  stats_collector->NotifyMarkingCompleted(marked_bytes);
-  stats_collector->NotifySweepingCompleted();
-}
-
-}  // namespace
-
-TEST(ThreadHeapStatsCollectorTest, RegisterUnregisterObserver) {
-  ThreadHeapStatsCollector stats_collector;
-  MockThreadHeapStatsObserver observer;
-  stats_collector.RegisterObserver(&observer);
-  stats_collector.UnregisterObserver(&observer);
-}
-
-TEST(ThreadHeapStatsCollectorTest, ObserveAllocatedSpace) {
-  ThreadHeapStatsCollector stats_collector;
-  MockThreadHeapStatsObserver observer;
-  stats_collector.RegisterObserver(&observer);
-  EXPECT_CALL(observer, IncreaseAllocatedSpace(1024));
-  stats_collector.IncreaseAllocatedSpace(1024);
-  EXPECT_CALL(observer, DecreaseAllocatedSpace(1024));
-  stats_collector.DecreaseAllocatedSpace(1024);
-  stats_collector.UnregisterObserver(&observer);
-}
-
-TEST(ThreadHeapStatsCollectorTest, ObserveResetAllocatedObjectSize) {
-  ThreadHeapStatsCollector stats_collector;
-  MockThreadHeapStatsObserver observer;
-  stats_collector.RegisterObserver(&observer);
-  EXPECT_CALL(observer, ResetAllocatedObjectSize(2048));
-  FakeGC(&stats_collector, 2048);
-  stats_collector.UnregisterObserver(&observer);
-}
-
-TEST(ThreadHeapStatsCollectorTest, ObserveAllocatedObjectSize) {
-  ThreadHeapStatsCollector stats_collector;
-  MockThreadHeapStatsObserver observer;
-  stats_collector.RegisterObserver(&observer);
-  EXPECT_CALL(observer, IncreaseAllocatedObjectSize(1024));
-  stats_collector.IncreaseAllocatedObjectSizeForTesting(1024);
-  EXPECT_CALL(observer, DecreaseAllocatedObjectSize(1024));
-  stats_collector.DecreaseAllocatedObjectSizeForTesting(1024);
-  stats_collector.UnregisterObserver(&observer);
-}
-
-namespace {
-
-class ObserverTriggeringGC final : public ThreadHeapStatsObserver {
- public:
-  explicit ObserverTriggeringGC(ThreadHeapStatsCollector* stats_collector)
-      : stats_collector_(stats_collector) {}
-
-  void IncreaseAllocatedObjectSize(size_t bytes) final {
-    increase_call_count++;
-    increased_size_bytes_ += bytes;
-    if (increase_call_count == 1) {
-      FakeGC(stats_collector_, bytes);
-    }
-  }
-
-  void ResetAllocatedObjectSize(size_t marked) final {
-    reset_call_count++;
-    marked_bytes_ = marked;
-  }
-
-  // Mock out the rest to trigger warnings if used.
-  MOCK_METHOD1(IncreaseAllocatedSpace, void(size_t));
-  MOCK_METHOD1(DecreaseAllocatedSpace, void(size_t));
-  MOCK_METHOD1(DecreaseAllocatedObjectSize, void(size_t));
-
-  size_t marked_bytes() const { return marked_bytes_; }
-  size_t increased_size_bytes() const { return increased_size_bytes_; }
-
-  size_t increase_call_count = 0;
-  size_t reset_call_count = 0;
-
- private:
-  ThreadHeapStatsCollector* const stats_collector_;
-  size_t marked_bytes_ = 0;
-  size_t increased_size_bytes_ = 0;
-};
-
-}  // namespace
-
-TEST(ThreadHeapStatsCollectorTest, ObserverTriggersGC) {
-  ThreadHeapStatsCollector stats_collector;
-  ObserverTriggeringGC gc_observer(&stats_collector);
-  MockThreadHeapStatsObserver mock_observer;
-  // Internal detail: First registered observer is also notified first.
-  stats_collector.RegisterObserver(&gc_observer);
-  stats_collector.RegisterObserver(&mock_observer);
-
-  // mock_observer is notified after triggering GC. This means that it should
-  // see the reset call with the fully marked size (as gc_observer fakes a GC
-  // with that size).
-  EXPECT_CALL(mock_observer, ResetAllocatedObjectSize(1024));
-  // Since the GC clears counters, it should see an increase call with a delta
-  // of zero bytes.
-  EXPECT_CALL(mock_observer, IncreaseAllocatedObjectSize(0));
-
-  // Trigger scenario.
-  stats_collector.IncreaseAllocatedObjectSizeForTesting(1024);
-
-  // gc_observer sees both calls exactly once.
-  EXPECT_EQ(1u, gc_observer.increase_call_count);
-  EXPECT_EQ(1u, gc_observer.reset_call_count);
-  // gc_observer sees the increased bytes and the reset call with the fully
-  // marked size.
-  EXPECT_EQ(1024u, gc_observer.increased_size_bytes());
-  EXPECT_EQ(1024u, gc_observer.marked_bytes());
-
-  stats_collector.UnregisterObserver(&gc_observer);
-  stats_collector.UnregisterObserver(&mock_observer);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/heap_thread_test.cc b/third_party/blink/renderer/platform/heap/impl/test/heap_thread_test.cc
deleted file mode 100644
index 529f259..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/heap_thread_test.cc
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "build/build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-
-namespace blink {
-
-class HeapThreadTest : public TestSupportingGC {};
-
-class HeapThreadDeathTest : public TestSupportingGC {
- public:
-  HeapThreadDeathTest() {
-    testing::FLAGS_gtest_death_test_style = "threadsafe";
-  }
-};
-
-namespace heap_thread_test {
-
-static Mutex& ActiveThreadMutex() {
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, active_thread_mutex, ());
-  return active_thread_mutex;
-}
-
-static ThreadCondition& ActiveThreadCondition() {
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadCondition, active_thread_condition,
-                                  (ActiveThreadMutex()));
-  return active_thread_condition;
-}
-
-enum ActiveThreadState {
-  kNoThreadActive,
-  kMainThreadActive,
-  kWorkerThreadActive,
-};
-
-static ActiveThreadState& ActiveThread() {
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(ActiveThreadState, active_thread,
-                                  (kNoThreadActive));
-  return active_thread;
-}
-
-static void WakeMainThread() {
-  ActiveThread() = kMainThreadActive;
-  ActiveThreadCondition().Signal();
-}
-
-static void WakeWorkerThread() {
-  ActiveThread() = kWorkerThreadActive;
-  ActiveThreadCondition().Signal();
-}
-
-static void ParkMainThread() {
-  while (ActiveThread() != kMainThreadActive) {
-    ActiveThreadCondition().Wait();
-  }
-}
-
-static void ParkWorkerThread() {
-  while (ActiveThread() != kWorkerThreadActive) {
-    ActiveThreadCondition().Wait();
-  }
-}
-
-class Object : public GarbageCollected<Object> {
- public:
-  Object() {}
-  void Trace(Visitor* visitor) const {}
-};
-
-class AlternatingThreadTester {
-  STACK_ALLOCATED();
-
- public:
-  void Test() {
-    MutexLocker locker(ActiveThreadMutex());
-    ActiveThread() = kMainThreadActive;
-
-    std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread(
-        ThreadCreationParams(ThreadType::kTestThread)
-            .SetThreadNameForTest("Test Worker Thread"));
-    PostCrossThreadTask(
-        *worker_thread->GetTaskRunner(), FROM_HERE,
-        CrossThreadBindOnce(&AlternatingThreadTester::StartWorkerThread,
-                            CrossThreadUnretained(this)));
-
-    MainThreadMain();
-  }
-
-  void SwitchToWorkerThread() {
-    WakeWorkerThread();
-    ParkMainThread();
-  }
-
-  void SwitchToMainThread() {
-    WakeMainThread();
-    ParkWorkerThread();
-  }
-
- protected:
-  // Override with code you want to execute on the main thread.
-  virtual void MainThreadMain() = 0;
-  // Override with code you want to execute on the worker thread. At the end,
-  // the ThreadState is detached and we switch back to the main thread
-  // automatically.
-  virtual void WorkerThreadMain() = 0;
-
- private:
-  void StartWorkerThread() {
-    ThreadState::AttachCurrentThread();
-
-    MutexLocker locker(ActiveThreadMutex());
-
-    WorkerThreadMain();
-
-    ThreadState::DetachCurrentThread();
-    WakeMainThread();
-  }
-};
-
-class MemberSameThreadCheckTester final : public AlternatingThreadTester {
- public:
-  MemberSameThreadCheckTester()
-      : object_wrapper_(MakeGarbageCollected<ObjectWrapper>()) {}
-
- private:
-  class ObjectWrapper : public GarbageCollected<ObjectWrapper> {
-   public:
-    void Trace(Visitor* visitor) const { visitor->Trace(object_); }
-
-    Member<Object> object_;
-  };
-
-  void MainThreadMain() override { SwitchToWorkerThread(); }
-
-  void WorkerThreadMain() override {
-    // Setting an object created on the worker thread to a Member allocated on
-    // the main thread is not allowed.
-    object_wrapper_->object_ = MakeGarbageCollected<Object>();
-  }
-
-  ObjectWrapper* object_wrapper_;
-};
-
-#if DCHECK_IS_ON()
-TEST_F(HeapThreadDeathTest, MemberSameThreadCheck) {
-  EXPECT_DEATH(MemberSameThreadCheckTester().Test(), "");
-}
-#endif
-
-class PersistentSameThreadCheckTester : public AlternatingThreadTester {
- private:
-  void MainThreadMain() override { SwitchToWorkerThread(); }
-
-  void WorkerThreadMain() override {
-    // Setting an object created on the worker thread to a Persistent allocated
-    // on the main thread is not allowed.
-    object_ = MakeGarbageCollected<Object>();
-  }
-
-  Persistent<Object> object_;
-};
-
-#if DCHECK_IS_ON()
-TEST_F(HeapThreadDeathTest, PersistentSameThreadCheck) {
-  EXPECT_DEATH(PersistentSameThreadCheckTester().Test(), "");
-}
-#endif
-
-class MarkingSameThreadCheckTester : public AlternatingThreadTester {
- private:
-  class MainThreadObject final : public GarbageCollected<MainThreadObject> {
-   public:
-    void Trace(Visitor* visitor) const { visitor->Trace(set_); }
-    void AddToSet(Object* object) { set_.insert(42, object); }
-
-   private:
-    HeapHashMap<int, Member<Object>> set_;
-  };
-
-  void MainThreadMain() override {
-    main_thread_object_ = MakeGarbageCollected<MainThreadObject>();
-
-    SwitchToWorkerThread();
-
-    // This will try to mark MainThreadObject when it tries to mark Object
-    // it should crash.
-    TestSupportingGC::PreciselyCollectGarbage();
-  }
-
-  void WorkerThreadMain() override {
-    // Adding a reference to an object created on the worker thread to a
-    // HeapHashMap created on the main thread is not allowed.
-    main_thread_object_->AddToSet(MakeGarbageCollected<Object>());
-  }
-
-  CrossThreadPersistent<MainThreadObject> main_thread_object_;
-};
-
-#if DCHECK_IS_ON()
-TEST_F(HeapThreadDeathTest, DISABLED_MarkingSameThreadCheck) {
-  // This will crash during marking, at the DCHECK in Visitor::markHeader() or
-  // earlier.
-  EXPECT_DEATH(MarkingSameThreadCheckTester().Test(), "");
-}
-#endif
-
-class DestructorLockingObject
-    : public GarbageCollected<DestructorLockingObject> {
- public:
-  DestructorLockingObject() = default;
-  virtual ~DestructorLockingObject() { ++destructor_calls_; }
-
-  static int destructor_calls_;
-  void Trace(Visitor* visitor) const {}
-};
-
-int DestructorLockingObject::destructor_calls_ = 0;
-
-class CrossThreadWeakPersistentTester : public AlternatingThreadTester {
- private:
-  void MainThreadMain() override {
-    // Create an object in the worker thread, have a CrossThreadWeakPersistent
-    // pointing to it on the main thread, run a GC in the worker thread, and see
-    // if the CrossThreadWeakPersistent is cleared.
-
-    DestructorLockingObject::destructor_calls_ = 0;
-
-    // Step 1: Initiate a worker thread, and wait for |Object| to get allocated
-    // on the worker thread.
-    SwitchToWorkerThread();
-
-    // Step 3: Set up a CrossThreadWeakPersistent.
-    ASSERT_TRUE(object_);
-    EXPECT_EQ(0, DestructorLockingObject::destructor_calls_);
-
-    // Pretend we have no pointers on stack during the step 4.
-    SwitchToWorkerThread();
-
-    // Step 5: Make sure the weak persistent is cleared.
-    EXPECT_FALSE(object_);
-    EXPECT_EQ(1, DestructorLockingObject::destructor_calls_);
-
-    SwitchToWorkerThread();
-  }
-
-  void WorkerThreadMain() override {
-    // Step 2: Create an object and store the pointer.
-    object_ = MakeGarbageCollected<DestructorLockingObject>();
-    SwitchToMainThread();
-
-    // Step 4: Run a GC.
-    ThreadState::Current()->CollectAllGarbageForTesting(
-        BlinkGC::kNoHeapPointersOnStack);
-    SwitchToMainThread();
-  }
-
-  CrossThreadWeakPersistent<DestructorLockingObject> object_;
-};
-
-TEST_F(HeapThreadTest, CrossThreadWeakPersistent) {
-  CrossThreadWeakPersistentTester().Test();
-}
-
-}  // namespace heap_thread_test
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/incremental_marking_internals_test.cc b/third_party/blink/renderer/platform/heap/impl/test/incremental_marking_internals_test.cc
deleted file mode 100644
index 4b82e85..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/incremental_marking_internals_test.cc
+++ /dev/null
@@ -1,617 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <initializer_list>
-
-#include "base/bind.h"
-#include "base/test/scoped_feature_list.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
-#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_objects.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
-#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-class IncrementalMarkingInternalsTest : public TestSupportingGC {};
-
-namespace incremental_marking_test {
-
-// Visitor that expects every directly reachable object from a given backing
-// store to be in the set of provided objects.
-class BackingVisitor final : public Visitor {
- public:
-  BackingVisitor(ThreadState* state, Vector<void*>* objects)
-      : Visitor(state), objects_(objects) {}
-  ~BackingVisitor() override = default;
-
-  void ProcessBackingStore(HeapObjectHeader* header) {
-    EXPECT_TRUE(header->IsMarked());
-    header->Unmark();
-
-    GCInfo::From(header->GcInfoIndex()).trace(this, header->Payload());
-  }
-
-  void Visit(const void* obj, TraceDescriptor desc) override {
-    EXPECT_TRUE(obj);
-    auto** pos = std::find(objects_->begin(), objects_->end(), obj);
-    if (objects_->end() != pos)
-      objects_->erase(pos);
-    // The garbage collector will find those objects so we can mark them.
-    HeapObjectHeader* const header =
-        HeapObjectHeader::FromPayload(desc.base_object_payload);
-    if (!header->IsMarked())
-      EXPECT_TRUE(header->TryMark());
-  }
-
-  void VisitEphemeron(const void* key, TraceDescriptor value_desc) override {
-    if (!HeapObjectHeader::FromPayload(key)->IsMarked())
-      return;
-    value_desc.callback(this, value_desc.base_object_payload);
-  }
-
- private:
-  Vector<void*>* objects_;
-};
-
-// Base class for initializing worklists.
-class IncrementalMarkingScopeBase {
-  DISALLOW_NEW();
-
- public:
-  explicit IncrementalMarkingScopeBase(ThreadState* thread_state)
-      : thread_state_(thread_state), heap_(thread_state_->Heap()) {
-    if (thread_state_->IsMarkingInProgress() ||
-        thread_state_->IsSweepingInProgress()) {
-      TestSupportingGC::PreciselyCollectGarbage();
-    }
-    heap_.SetupWorklists(false);
-  }
-
-  ~IncrementalMarkingScopeBase() {
-    heap_.DestroyMarkingWorklists(BlinkGC::StackState::kNoHeapPointersOnStack);
-    heap_.DestroyCompactionWorklists();
-  }
-
-  ThreadHeap& heap() const { return heap_; }
-
- protected:
-  ThreadState* const thread_state_;
-  ThreadHeap& heap_;
-};
-
-class IncrementalMarkingScope : public IncrementalMarkingScopeBase {
-  STACK_ALLOCATED();
-
- public:
-  explicit IncrementalMarkingScope(ThreadState* thread_state)
-      : IncrementalMarkingScopeBase(thread_state),
-        gc_forbidden_scope_(thread_state),
-        marking_worklist_(heap_.GetMarkingWorklist()),
-        write_barrier_worklist_(heap_.GetWriteBarrierWorklist()),
-        not_fully_constructed_worklist_(
-            heap_.GetNotFullyConstructedWorklist()) {
-    thread_state_->SetGCPhase(ThreadState::GCPhase::kMarking);
-    ThreadState::AtomicPauseScope atomic_pause_scope_(thread_state_);
-    ScriptForbiddenScope script_forbidden_scope;
-    EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
-    EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
-    EXPECT_TRUE(not_fully_constructed_worklist_->IsGlobalEmpty());
-    thread_state->EnableIncrementalMarkingBarrier();
-    thread_state->current_gc_data_.visitor = std::make_unique<MarkingVisitor>(
-        thread_state, MarkingVisitor::kGlobalMarking);
-  }
-
-  ~IncrementalMarkingScope() {
-    EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
-    EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
-    EXPECT_TRUE(not_fully_constructed_worklist_->IsGlobalEmpty());
-    thread_state_->DisableIncrementalMarkingBarrier();
-    // Need to clear out unused worklists that might have been polluted during
-    // test.
-    heap_.GetWeakCallbackWorklist()->Clear();
-    thread_state_->SetGCPhase(ThreadState::GCPhase::kSweeping);
-    thread_state_->SetGCPhase(ThreadState::GCPhase::kNone);
-  }
-
-  MarkingWorklist* marking_worklist() const { return marking_worklist_; }
-  WriteBarrierWorklist* write_barrier_worklist() const {
-    return write_barrier_worklist_;
-  }
-  NotFullyConstructedWorklist* not_fully_constructed_worklist() const {
-    return not_fully_constructed_worklist_;
-  }
-
- protected:
-  ThreadState::GCForbiddenScope gc_forbidden_scope_;
-  MarkingWorklist* const marking_worklist_;
-  WriteBarrierWorklist* const write_barrier_worklist_;
-  NotFullyConstructedWorklist* const not_fully_constructed_worklist_;
-};
-
-// Expects that the write barrier fires for the objects passed to the
-// constructor. This requires that the objects are added to the marking stack
-// as well as headers being marked.
-class ExpectWriteBarrierFires : public IncrementalMarkingScope {
- public:
-  ExpectWriteBarrierFires(ThreadState* thread_state,
-                          std::initializer_list<void*> objects)
-      : IncrementalMarkingScope(thread_state),
-        objects_(objects),
-        backing_visitor_(thread_state_, &objects_) {
-    EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
-    EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
-    for (void* object : objects_) {
-      // Ensure that the object is in the normal arena so we can ignore backing
-      // objects on the marking stack.
-      CHECK(ThreadHeap::IsNormalArenaIndex(
-          PageFromObject(object)->Arena()->ArenaIndex()));
-      headers_.push_back(HeapObjectHeader::FromPayload(object));
-      EXPECT_FALSE(headers_.back()->IsMarked());
-    }
-    EXPECT_FALSE(objects_.IsEmpty());
-  }
-
-  ~ExpectWriteBarrierFires() {
-    // All objects watched should be on the marking or write barrier worklist.
-    MarkingItem item;
-    while (marking_worklist_->Pop(WorklistTaskId::MutatorThread, &item)) {
-      // Inspect backing stores to allow specifying objects that are only
-      // reachable through a backing store.
-      if (!ThreadHeap::IsNormalArenaIndex(
-              PageFromObject(item.base_object_payload)
-                  ->Arena()
-                  ->ArenaIndex())) {
-        backing_visitor_.ProcessBackingStore(
-            HeapObjectHeader::FromPayload(item.base_object_payload));
-        continue;
-      }
-      auto** pos =
-          std::find(objects_.begin(), objects_.end(), item.base_object_payload);
-      if (objects_.end() != pos)
-        objects_.erase(pos);
-    }
-    HeapObjectHeader* header;
-    while (
-        write_barrier_worklist_->Pop(WorklistTaskId::MutatorThread, &header)) {
-      // Inspect backing stores to allow specifying objects that are only
-      // reachable through a backing store.
-      if (!ThreadHeap::IsNormalArenaIndex(
-              PageFromObject(header->Payload())->Arena()->ArenaIndex())) {
-        backing_visitor_.ProcessBackingStore(header);
-        continue;
-      }
-      auto** pos =
-          std::find(objects_.begin(), objects_.end(), header->Payload());
-      if (objects_.end() != pos)
-        objects_.erase(pos);
-    }
-    EXPECT_TRUE(objects_.IsEmpty());
-    // All headers of objects watched should be marked at this point.
-    for (HeapObjectHeader* hdr : headers_) {
-      EXPECT_TRUE(hdr->IsMarked());
-      hdr->Unmark();
-    }
-    EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
-    EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
-  }
-
- private:
-  Vector<void*> objects_;
-  Vector<HeapObjectHeader*> headers_;
-  BackingVisitor backing_visitor_;
-};
-
-// Expects that no write barrier fires for the objects passed to the
-// constructor. This requires that the marking stack stays empty and the marking
-// state of the object stays the same across the lifetime of the scope.
-class ExpectNoWriteBarrierFires : public IncrementalMarkingScope {
- public:
-  ExpectNoWriteBarrierFires(ThreadState* thread_state,
-                            std::initializer_list<void*> objects)
-      : IncrementalMarkingScope(thread_state) {
-    EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
-    EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
-    for (void* object : objects) {
-      HeapObjectHeader* header = HeapObjectHeader::FromPayload(object);
-      headers_.push_back(std::make_pair(header, header->IsMarked()));
-    }
-  }
-
-  ~ExpectNoWriteBarrierFires() {
-    EXPECT_TRUE(marking_worklist_->IsGlobalEmpty());
-    EXPECT_TRUE(write_barrier_worklist_->IsGlobalEmpty());
-    for (const auto& pair : headers_) {
-      EXPECT_EQ(pair.second, pair.first->IsMarked());
-      pair.first->Unmark();
-    }
-  }
-
- private:
-  Vector<std::pair<HeapObjectHeader*, bool /* was marked */>> headers_;
-};
-
-class Object : public LinkedObject {
- public:
-  Object() = default;
-  explicit Object(Object* next) : LinkedObject(next) {}
-
-  bool IsMarked() const {
-    return HeapObjectHeader::FromPayload(this)->IsMarked();
-  }
-
-  void Trace(Visitor* visitor) const override { LinkedObject::Trace(visitor); }
-};
-
-class ObjectWithWriteBarrier : public GarbageCollected<ObjectWithWriteBarrier> {
- public:
-  void Trace(Visitor* v) const { v->Trace(object_); }
-
-  void Set(Object* object) { object_ = object; }
-
- private:
-  Member<Object> object_;
-};
-
-// =============================================================================
-// Member<T> support. ==========================================================
-// =============================================================================
-
-TEST_F(IncrementalMarkingInternalsTest, MemberSetUnmarkedObject) {
-  auto* parent = MakeGarbageCollected<Object>();
-  auto* child = MakeGarbageCollected<Object>();
-  {
-    ExpectWriteBarrierFires scope(ThreadState::Current(), {child});
-    EXPECT_FALSE(child->IsMarked());
-    parent->set_next(child);
-    EXPECT_TRUE(child->IsMarked());
-  }
-}
-
-TEST_F(IncrementalMarkingInternalsTest, MemberSetMarkedObjectNoBarrier) {
-  auto* parent = MakeGarbageCollected<Object>();
-  auto* child = MakeGarbageCollected<Object>();
-  EXPECT_TRUE(HeapObjectHeader::FromPayload(child)->TryMark());
-  {
-    ExpectNoWriteBarrierFires scope(ThreadState::Current(), {child});
-    parent->set_next(child);
-  }
-}
-
-TEST_F(IncrementalMarkingInternalsTest, MemberInitializingStoreNoBarrier) {
-  auto* object1 = MakeGarbageCollected<Object>();
-  HeapObjectHeader* object1_header = HeapObjectHeader::FromPayload(object1);
-  {
-    IncrementalMarkingScope scope(ThreadState::Current());
-    EXPECT_FALSE(object1_header->IsMarked());
-    auto* object2 = MakeGarbageCollected<Object>(object1);
-    HeapObjectHeader* object2_header = HeapObjectHeader::FromPayload(object2);
-    EXPECT_FALSE(object1_header->IsMarked());
-    EXPECT_FALSE(object2_header->IsMarked());
-  }
-}
-
-TEST_F(IncrementalMarkingInternalsTest, MemberReferenceAssignMember) {
-  auto* obj = MakeGarbageCollected<LinkedObject>();
-  auto* ref_obj = MakeGarbageCollected<LinkedObject>();
-  Member<LinkedObject>& m2 = ref_obj->next_ref();
-  Member<LinkedObject> m3(obj);
-  {
-    ExpectWriteBarrierFires scope(ThreadState::Current(), {obj});
-    m2 = m3;
-  }
-}
-
-TEST_F(IncrementalMarkingInternalsTest, MemberSetDeletedValueNoBarrier) {
-  auto* obj = MakeGarbageCollected<LinkedObject>();
-  Member<LinkedObject>& m = obj->next_ref();
-  {
-    ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
-    m = WTF::kHashTableDeletedValue;
-  }
-}
-
-TEST_F(IncrementalMarkingInternalsTest, MemberCopyDeletedValueNoBarrier) {
-  auto* obj1 = MakeGarbageCollected<LinkedObject>();
-  Member<LinkedObject>& m1 = obj1->next_ref();
-  m1 = WTF::kHashTableDeletedValue;
-  {
-    ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
-    auto* obj2 = MakeGarbageCollected<LinkedObject>();
-    obj2->next_ref() = m1;
-  }
-}
-
-TEST_F(IncrementalMarkingInternalsTest,
-       MemberHashTraitConstructDeletedValueNoBarrier) {
-  auto* obj = MakeGarbageCollected<LinkedObject>();
-  Member<LinkedObject>& m = obj->next_ref();
-  {
-    ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
-    HashTraits<Member<LinkedObject>>::ConstructDeletedValue(m, false);
-  }
-}
-
-TEST_F(IncrementalMarkingInternalsTest,
-       MemberHashTraitIsDeletedValueNoBarrier) {
-  auto* obj =
-      MakeGarbageCollected<LinkedObject>(MakeGarbageCollected<LinkedObject>());
-  Member<LinkedObject>& m = obj->next_ref();
-  {
-    ExpectNoWriteBarrierFires scope(ThreadState::Current(), {});
-    EXPECT_FALSE(HashTraits<Member<LinkedObject>>::IsDeletedValue(m));
-  }
-}
-
-// =============================================================================
-// Mixin support. ==============================================================
-// =============================================================================
-
-namespace {
-
-class Mixin : public GarbageCollectedMixin {
- public:
-  Mixin() : next_(nullptr) {}
-  virtual ~Mixin() = default;
-
-  void Trace(Visitor* visitor) const override { visitor->Trace(next_); }
-
-  virtual void Bar() {}
-
- protected:
-  Member<Object> next_;
-};
-
-class ClassWithVirtual {
- protected:
-  virtual void Foo() {}
-};
-
-class Child : public GarbageCollected<Child>,
-              public ClassWithVirtual,
-              public Mixin {
- public:
-  Child() : ClassWithVirtual() {}
-  ~Child() override = default;
-
-  void Trace(Visitor* visitor) const override { Mixin::Trace(visitor); }
-
-  void Foo() override {}
-  void Bar() override {}
-};
-
-class ParentWithMixinPointer : public GarbageCollected<ParentWithMixinPointer> {
- public:
-  ParentWithMixinPointer() : mixin_(nullptr) {}
-
-  void set_mixin(Mixin* mixin) { mixin_ = mixin; }
-
-  virtual void Trace(Visitor* visitor) const { visitor->Trace(mixin_); }
-
- protected:
-  Member<Mixin> mixin_;
-};
-
-}  // namespace
-
-TEST_F(IncrementalMarkingInternalsTest,
-       WriteBarrierOnUnmarkedMixinApplication) {
-  ParentWithMixinPointer* parent =
-      MakeGarbageCollected<ParentWithMixinPointer>();
-  auto* child = MakeGarbageCollected<Child>();
-  Mixin* mixin = static_cast<Mixin*>(child);
-  EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin));
-  {
-    ExpectWriteBarrierFires scope(ThreadState::Current(), {child});
-    parent->set_mixin(mixin);
-  }
-}
-
-TEST_F(IncrementalMarkingInternalsTest,
-       NoWriteBarrierOnMarkedMixinApplication) {
-  ParentWithMixinPointer* parent =
-      MakeGarbageCollected<ParentWithMixinPointer>();
-  auto* child = MakeGarbageCollected<Child>();
-  EXPECT_TRUE(HeapObjectHeader::FromPayload(child)->TryMark());
-  Mixin* mixin = static_cast<Mixin*>(child);
-  EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin));
-  {
-    ExpectNoWriteBarrierFires scope(ThreadState::Current(), {child});
-    parent->set_mixin(mixin);
-  }
-}
-
-// TODO(keishi) Non-weak hash table backings should be promptly freed but they
-// are currently not because we emit write barriers for the backings, and we
-// don't free marked backings.
-TEST_F(IncrementalMarkingInternalsTest,
-       DISABLED_WeakHashMapPromptlyFreeDisabled) {
-  ThreadState* state = ThreadState::Current();
-  state->SetGCState(ThreadState::kIncrementalMarkingStepScheduled);
-  Persistent<Object> obj1 = MakeGarbageCollected<Object>();
-  NormalPageArena* arena = static_cast<NormalPageArena*>(
-      ThreadState::Current()->Heap().Arena(BlinkGC::kHashTableArenaIndex));
-  CHECK(arena);
-  {
-    size_t before = arena->promptly_freed_size();
-    // Create two maps so we don't promptly free at the allocation point.
-    HeapHashMap<WeakMember<Object>, Member<Object>> weak_map1;
-    HeapHashMap<WeakMember<Object>, Member<Object>> weak_map2;
-    weak_map1.insert(obj1, obj1);
-    weak_map2.insert(obj1, obj1);
-    weak_map1.clear();
-    size_t after = arena->promptly_freed_size();
-    // Weak hash table backings should not be promptly freed.
-    EXPECT_EQ(after, before);
-  }
-  {
-    size_t before = arena->promptly_freed_size();
-    // Create two maps so we don't promptly free at the allocation point.
-    HeapHashMap<Member<Object>, Member<Object>> map1;
-    HeapHashMap<Member<Object>, Member<Object>> map2;
-    map1.insert(obj1, obj1);
-    map2.insert(obj1, obj1);
-    map1.clear();
-    size_t after = arena->promptly_freed_size();
-    // Non-weak hash table backings should be promptly freed.
-    EXPECT_GT(after, before);
-  }
-  state->SetGCState(ThreadState::kIncrementalMarkingFinalizeScheduled);
-  state->SetGCState(ThreadState::kNoGCScheduled);
-}
-
-namespace {
-
-class RegisteringMixin;
-using ObjectRegistry = HeapHashMap<void*, Member<RegisteringMixin>>;
-
-class RegisteringMixin : public GarbageCollectedMixin {
- public:
-  explicit RegisteringMixin(ObjectRegistry* registry) {
-    HeapObjectHeader* header = HeapObjectHeader::FromPayload(
-        TraceTrait<RegisteringMixin>::GetTraceDescriptor(this)
-            .base_object_payload);
-    EXPECT_TRUE(header->IsInConstruction());
-    registry->insert(reinterpret_cast<void*>(this), this);
-  }
-};
-
-class RegisteringObject : public GarbageCollected<RegisteringObject>,
-                          public RegisteringMixin {
- public:
-  explicit RegisteringObject(ObjectRegistry* registry)
-      : RegisteringMixin(registry) {}
-};
-
-}  // namespace
-
-TEST_F(IncrementalMarkingInternalsTest, WriteBarrierDuringMixinConstruction) {
-  IncrementalMarkingScope scope(ThreadState::Current());
-  ObjectRegistry registry;
-  RegisteringObject* object =
-      MakeGarbageCollected<RegisteringObject>(&registry);
-
-  // Clear any objects that have been added to the regular marking worklist in
-  // the process of calling the constructor.
-  MarkingItem marking_item;
-  while (scope.marking_worklist()->Pop(WorklistTaskId::MutatorThread,
-                                       &marking_item)) {
-    HeapObjectHeader* header =
-        HeapObjectHeader::FromPayload(marking_item.base_object_payload);
-    if (header->IsMarked())
-      header->Unmark();
-  }
-  EXPECT_TRUE(scope.marking_worklist()->IsGlobalEmpty());
-  // Clear any write barriers so far.
-  HeapObjectHeader* header;
-  while (scope.write_barrier_worklist()->Pop(WorklistTaskId::MutatorThread,
-                                             &header)) {
-    if (header->IsMarked())
-      header->Unmark();
-  }
-  EXPECT_TRUE(scope.write_barrier_worklist()->IsGlobalEmpty());
-
-  EXPECT_FALSE(scope.not_fully_constructed_worklist()->IsGlobalEmpty());
-  NotFullyConstructedItem partial_item;
-  bool found_mixin_object = false;
-  // The same object may be on the marking work list because of expanding
-  // and rehashing of the backing store in the registry.
-  while (scope.not_fully_constructed_worklist()->Pop(
-      WorklistTaskId::MutatorThread, &partial_item)) {
-    if (object == partial_item)
-      found_mixin_object = true;
-    HeapObjectHeader* hdr = HeapObjectHeader::FromPayload(partial_item);
-    if (hdr->IsMarked())
-      hdr->Unmark();
-  }
-  EXPECT_TRUE(found_mixin_object);
-  EXPECT_TRUE(scope.not_fully_constructed_worklist()->IsGlobalEmpty());
-}
-
-TEST_F(IncrementalMarkingInternalsTest, OverrideAfterMixinConstruction) {
-  ObjectRegistry registry;
-  RegisteringMixin* mixin = MakeGarbageCollected<RegisteringObject>(&registry);
-  HeapObjectHeader* header = HeapObjectHeader::FromPayload(
-      TraceTrait<RegisteringMixin>::GetTraceDescriptor(mixin)
-          .base_object_payload);
-
-  EXPECT_FALSE(header->IsInConstruction());
-}
-
-// =============================================================================
-// Tests that execute complete incremental garbage collections. ================
-// =============================================================================
-
-TEST_F(IncrementalMarkingInternalsTest,
-       HasInlineCapacityCollectionWithHeapCompaction) {
-  using Store = HeapVector<Member<Object>, 2>;
-
-  Persistent<Store> persistent(MakeGarbageCollected<Store>());
-  Persistent<Store> persistent2(MakeGarbageCollected<Store>());
-
-  IncrementalMarkingTestDriver driver(ThreadState::Current());
-  ThreadState::Current()->EnableCompactionForNextGCForTesting();
-  persistent->push_back(MakeGarbageCollected<Object>());
-  driver.StartGC();
-  driver.FinishGC();
-
-  // Should collect also slots that has only inline buffer and nullptr
-  // references.
-#if defined(ANNOTATE_CONTIGUOUS_CONTAINER)
-  // When ANNOTATE_CONTIGUOUS_CONTAINER is defined, inline capacity is ignored.
-  EXPECT_EQ(driver.GetHeapCompactLastFixupCount(), 1u);
-#else
-  EXPECT_EQ(driver.GetHeapCompactLastFixupCount(), 2u);
-#endif
-}
-
-TEST_F(IncrementalMarkingInternalsTest, WeakHashMapHeapCompaction) {
-  using Store = HeapHashCountedSet<WeakMember<Object>>;
-
-  Persistent<Store> persistent(MakeGarbageCollected<Store>());
-
-  IncrementalMarkingTestDriver driver(ThreadState::Current());
-  ThreadState::Current()->EnableCompactionForNextGCForTesting();
-  driver.StartGC();
-  driver.TriggerMarkingSteps();
-  persistent->insert(MakeGarbageCollected<Object>());
-  driver.FinishGC();
-
-  // Weak callback should register the slot.
-  EXPECT_EQ(1u, driver.GetHeapCompactLastFixupCount());
-}
-
-TEST_F(IncrementalMarkingInternalsTest,
-       ConservativeGCWhileCompactionScheduled) {
-  using Store = HeapVector<Member<Object>>;
-  Persistent<Store> persistent(MakeGarbageCollected<Store>());
-  persistent->push_back(MakeGarbageCollected<Object>());
-
-  IncrementalMarkingTestDriver driver(ThreadState::Current());
-  ThreadState::Current()->EnableCompactionForNextGCForTesting();
-  driver.StartGC();
-  driver.TriggerMarkingSteps();
-  ThreadState::Current()->CollectGarbageForTesting(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
-      BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
-      BlinkGC::GCReason::kForcedGCForTesting);
-
-  // Heap compaction should be canceled if incremental marking finishes with a
-  // conservative GC.
-  EXPECT_EQ(driver.GetHeapCompactLastFixupCount(), 0u);
-}
-
-}  // namespace incremental_marking_test
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/marking_scheduling_oracle_test.cc b/third_party/blink/renderer/platform/heap/impl/test/marking_scheduling_oracle_test.cc
deleted file mode 100644
index ad2839d..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/marking_scheduling_oracle_test.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h"
-
-#include "base/time/time.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-
-namespace blink {
-
-namespace {
-class MarkingSchedulingOracleTest : public testing::Test {
- public:
-  static constexpr size_t kObjectSize = 1024 * 1024 * 1024;
-};
-}  // namespace
-
-TEST_F(MarkingSchedulingOracleTest, FirstStepReturnsDefaultDuration) {
-  MarkingSchedulingOracle oracle;
-  oracle.SetElapsedTimeForTesting(0);
-  EXPECT_EQ(MarkingSchedulingOracle::kDefaultIncrementalMarkingStepDuration,
-            oracle.GetNextIncrementalStepDurationForTask(kObjectSize));
-}
-
-// If marking is not behind schedule and very small time passed between steps
-// the oracle should return the minimum step duration.
-TEST_F(MarkingSchedulingOracleTest, NoTimePassedReturnsMinimumDuration) {
-  MarkingSchedulingOracle oracle;
-  // Add incrementally marked bytes to tell oracle this is not the first step.
-  oracle.UpdateIncrementalMarkingStats(
-      MarkingSchedulingOracle::kMinimumMarkedBytesInStep,
-      base::TimeDelta::FromMilliseconds(1),
-      base::TimeDelta::FromMilliseconds(0));
-  oracle.SetElapsedTimeForTesting(0);
-  // Given marking speed set above, Minimum duration should be 1ms.
-  EXPECT_EQ(1, oracle.GetNextIncrementalStepDurationForTask(kObjectSize)
-                   .InMilliseconds());
-}
-
-TEST_F(MarkingSchedulingOracleTest, OracleDoesntExccedMaximumStepDuration) {
-  MarkingSchedulingOracle oracle;
-  // Add incrementally marked bytes to tell oracle this is not the first step.
-  oracle.UpdateIncrementalMarkingStats(
-      1,
-      base::TimeDelta::FromMilliseconds(
-          MarkingSchedulingOracle::kEstimatedMarkingTimeMs),
-      base::TimeDelta::FromMilliseconds(0));
-  oracle.SetElapsedTimeForTesting(
-      MarkingSchedulingOracle::kEstimatedMarkingTimeMs);
-  EXPECT_EQ(MarkingSchedulingOracle::kMaximumIncrementalMarkingStepDuration,
-            oracle.GetNextIncrementalStepDurationForTask(kObjectSize));
-}
-
-TEST_F(MarkingSchedulingOracleTest, AheadOfScheduleReturnsMinimumDuration) {
-  MarkingSchedulingOracle oracle;
-  // Add incrementally marked bytes to tell oracle this is not the first step.
-  oracle.UpdateIncrementalMarkingStats(
-      MarkingSchedulingOracle::kMinimumMarkedBytesInStep,
-      base::TimeDelta::FromMilliseconds(1),
-      base::TimeDelta::FromMilliseconds(0));
-  oracle.AddConcurrentlyMarkedBytes(0.6 * kObjectSize);
-  oracle.SetElapsedTimeForTesting(
-      0.5 * MarkingSchedulingOracle::kEstimatedMarkingTimeMs);
-  // Given marking speed set above, Minimum duration should be 1ms.
-  EXPECT_EQ(1, oracle.GetNextIncrementalStepDurationForTask(kObjectSize)
-                   .InMilliseconds());
-}
-
-TEST_F(MarkingSchedulingOracleTest, BehindScheduleReturnsCorrectDuration) {
-  static constexpr size_t kForegoundMarkingTime = 1;
-  MarkingSchedulingOracle oracle;
-  oracle.UpdateIncrementalMarkingStats(
-      0.1 * kObjectSize,
-      base::TimeDelta::FromMilliseconds(kForegoundMarkingTime),
-      base::TimeDelta::FromMilliseconds(0));
-  oracle.AddConcurrentlyMarkedBytes(0.25 * kObjectSize);
-  oracle.SetElapsedTimeForTesting(
-      0.5 * MarkingSchedulingOracle::kEstimatedMarkingTimeMs);
-  EXPECT_EQ(1.5 * kForegoundMarkingTime,
-            oracle.GetNextIncrementalStepDurationForTask(kObjectSize)
-                .InMillisecondsF());
-  oracle.AddConcurrentlyMarkedBytes(0.05 * kObjectSize);
-  oracle.SetElapsedTimeForTesting(
-      0.5 * MarkingSchedulingOracle::kEstimatedMarkingTimeMs);
-  EXPECT_EQ(kForegoundMarkingTime,
-            oracle.GetNextIncrementalStepDurationForTask(kObjectSize)
-                .InMillisecondsF());
-  oracle.AddConcurrentlyMarkedBytes(0.05 * kObjectSize);
-  oracle.SetElapsedTimeForTesting(
-      0.5 * MarkingSchedulingOracle::kEstimatedMarkingTimeMs);
-  EXPECT_EQ(0.5 * kForegoundMarkingTime,
-            oracle.GetNextIncrementalStepDurationForTask(kObjectSize)
-                .InMillisecondsF());
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/marking_verifier_test.cc b/third_party/blink/renderer/platform/heap/impl/test/marking_verifier_test.cc
deleted file mode 100644
index 2289fc0..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/marking_verifier_test.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/marking_verifier.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_objects.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-
-namespace blink {
-
-#if DCHECK_IS_ON()
-class MarkingVerifierDeathTest : public TestSupportingGC {};
-
-namespace {
-
-class ResurrectingPreFinalizer
-    : public GarbageCollected<ResurrectingPreFinalizer> {
-  USING_PRE_FINALIZER(ResurrectingPreFinalizer, Dispose);
-
- public:
-  enum TestType {
-    kMember,
-    kWeakMember,
-  };
-
-  class GlobalStorage : public GarbageCollected<GlobalStorage> {
-   public:
-    void Trace(Visitor* visitor) const {
-      visitor->Trace(strong);
-      visitor->Trace(weak);
-    }
-
-    Member<LinkedObject> strong;
-    WeakMember<LinkedObject> weak;
-  };
-
-  ResurrectingPreFinalizer(TestType test_type,
-                           GlobalStorage* storage,
-                           LinkedObject* object_that_dies)
-      : test_type_(test_type),
-        storage_(storage),
-        object_that_dies_(object_that_dies) {}
-
-  void Trace(Visitor* visitor) const {
-    visitor->Trace(storage_);
-    visitor->Trace(object_that_dies_);
-  }
-
- private:
-  void Dispose() {
-    switch (test_type_) {
-      case TestType::kMember:
-        storage_->strong = object_that_dies_;
-        break;
-      case TestType::kWeakMember:
-        storage_->weak = object_that_dies_;
-        break;
-    }
-  }
-
-  TestType test_type_;
-  Member<GlobalStorage> storage_;
-  Member<LinkedObject> object_that_dies_;
-};
-
-}  // namespace
-
-TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedMember) {
-  if (!ThreadState::Current()->IsVerifyMarkingEnabled())
-    return;
-
-  Persistent<ResurrectingPreFinalizer::GlobalStorage> storage(
-      MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>());
-  MakeGarbageCollected<ResurrectingPreFinalizer>(
-      ResurrectingPreFinalizer::kMember, storage.Get(),
-      MakeGarbageCollected<LinkedObject>());
-  ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(),
-                            "MarkingVerifier: Encountered unmarked object.");
-}
-
-TEST_F(MarkingVerifierDeathTest, DiesOnResurrectedWeakMember) {
-  if (!ThreadState::Current()->IsVerifyMarkingEnabled())
-    return;
-
-  Persistent<ResurrectingPreFinalizer::GlobalStorage> storage(
-      MakeGarbageCollected<ResurrectingPreFinalizer::GlobalStorage>());
-  MakeGarbageCollected<ResurrectingPreFinalizer>(
-      ResurrectingPreFinalizer::kWeakMember, storage.Get(),
-      MakeGarbageCollected<LinkedObject>());
-  ASSERT_DEATH_IF_SUPPORTED(PreciselyCollectGarbage(),
-                            "MarkingVerifier: Encountered unmarked object.");
-}
-#endif  // DCHECK_IS_ON()
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/name_trait_test.cc b/third_party/blink/renderer/platform/heap/impl/test/name_trait_test.cc
deleted file mode 100644
index f69cded..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/name_trait_test.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string.h>
-
-#include "build/build_config.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/bindings/name_client.h"
-#include "third_party/blink/renderer/platform/heap/impl/name_traits.h"
-
-namespace blink {
-
-namespace {
-
-class ClassWithoutName final {
- public:
-  ClassWithoutName() = default;
-};
-
-class ClassWithName final : public NameClient {
- public:
-  explicit ClassWithName(const char* name) : name_(name) {}
-  ~ClassWithName() final = default;
-
-  const char* NameInHeapSnapshot() const final { return name_; }
-
- private:
-  const char* name_;
-};
-
-}  // namespace
-
-TEST(NameTraitTest, InternalNamesHiddenInOfficialBuild) {
-  // Use a test instead of static_assert to allow local builds but block
-  // enabling the feature accidentally through the waterfall.
-  //
-  // Do not include such type information in official builds to
-  // (a) safe binary size on string literals, and
-  // (b) avoid exposing internal types until it has been clarified whether
-  //     exposing internals in DevTools is fine.
-#if defined(OFFICIAL_BUILD)
-  EXPECT_TRUE(NameClient::HideInternalName());
-#endif
-}
-
-TEST(NameTraitTest, InternalNamesHiddenWhenFlagIsTurnedOff) {
-#if !BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-  EXPECT_TRUE(NameClient::HideInternalName());
-#endif  // BUILDFLAG(RAW_HEAP_SNAPSHOTS)
-}
-
-TEST(NameTraitTest, DefaultName) {
-  ClassWithoutName no_name;
-  const char* name = NameTrait<ClassWithoutName>::GetName(&no_name).value;
-  if (NameClient::HideInternalName()) {
-    EXPECT_EQ(0, strcmp(name, "InternalNode"));
-  } else {
-    EXPECT_NE(nullptr, strstr(name, "ClassWithoutName"));
-  }
-}
-
-TEST(NameTraitTest, CustomName) {
-  ClassWithName with_name("CustomName");
-  const char* name = NameTrait<ClassWithName>::GetName(&with_name).value;
-  EXPECT_EQ(0, strcmp(name, "CustomName"));
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/object_start_bitmap_test.cc b/third_party/blink/renderer/platform/heap/impl/test/object_start_bitmap_test.cc
deleted file mode 100644
index cdb20c5c..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/object_start_bitmap_test.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-namespace {
-
-bool IsEmpty(const ObjectStartBitmap& bitmap) {
-  size_t count = 0;
-  bitmap.Iterate([&count](Address) { count++; });
-  return count == 0;
-}
-
-// Abstraction for objects that hides ObjectStartBitmap::kGranularity and
-// the base address as getting either of it wrong will result in failed DCHECKs.
-class Object {
-  STACK_ALLOCATED();
-
- public:
-  static Address kBaseOffset;
-
-  Object(size_t number) : number_(number) {
-    const size_t max_entries = ObjectStartBitmap::MaxEntries();
-    EXPECT_GE(max_entries, number_);
-  }
-
-  Address address() const {
-    return kBaseOffset + ObjectStartBitmap::Granularity() * number_;
-  }
-
-  // Allow implicitly converting Object to Address.
-  operator Address() const { return address(); }
-
- private:
-  const size_t number_;
-};
-
-Address Object::kBaseOffset = reinterpret_cast<Address>(0x4000);
-
-}  // namespace
-
-TEST(ObjectStartBitmapTest, MoreThanZeroEntriesPossible) {
-  const size_t max_entries = ObjectStartBitmap::MaxEntries();
-  EXPECT_LT(0u, max_entries);
-}
-
-TEST(ObjectStartBitmapTest, InitialEmpty) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  EXPECT_TRUE(IsEmpty(bitmap));
-}
-
-TEST(ObjectStartBitmapTest, SetBitImpliesNonEmpty) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  bitmap.SetBit(Object(0));
-  EXPECT_FALSE(IsEmpty(bitmap));
-}
-
-TEST(ObjectStartBitmapTest, SetBitCheckBit) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object(7);
-  bitmap.SetBit(object);
-  EXPECT_TRUE(bitmap.CheckBit(object));
-}
-
-TEST(ObjectStartBitmapTest, SetBitClearbitCheckBit) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object(77);
-  bitmap.SetBit(object);
-  bitmap.ClearBit(object);
-  EXPECT_FALSE(bitmap.CheckBit(object));
-}
-
-TEST(ObjectStartBitmapTest, SetBitClearBitImpliesEmpty) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object(123);
-  bitmap.SetBit(object);
-  bitmap.ClearBit(object);
-  EXPECT_TRUE(IsEmpty(bitmap));
-}
-
-TEST(ObjectStartBitmapTest, AdjacentObjectsAtBegin) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object0(0);
-  Object object1(1);
-  bitmap.SetBit(object0);
-  bitmap.SetBit(object1);
-  EXPECT_FALSE(bitmap.CheckBit(Object(3)));
-  size_t count = 0;
-  bitmap.Iterate([&count, object0, object1](Address current) {
-    if (count == 0) {
-      EXPECT_EQ(object0.address(), current);
-    } else if (count == 1) {
-      EXPECT_EQ(object1.address(), current);
-    }
-    count++;
-  });
-  EXPECT_EQ(2u, count);
-}
-
-TEST(ObjectStartBitmapTest, AdjacentObjectsAtEnd) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  const size_t last_entry_index = ObjectStartBitmap::MaxEntries() - 1;
-  Object object0(last_entry_index - 1);
-  Object object1(last_entry_index);
-  bitmap.SetBit(object0);
-  bitmap.SetBit(object1);
-  EXPECT_FALSE(bitmap.CheckBit(Object(last_entry_index - 2)));
-  size_t count = 0;
-  bitmap.Iterate([&count, object0, object1](Address current) {
-    if (count == 0) {
-      EXPECT_EQ(object0.address(), current);
-    } else if (count == 1) {
-      EXPECT_EQ(object1.address(), current);
-    }
-    count++;
-  });
-  EXPECT_EQ(2u, count);
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderExact) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object(654);
-  bitmap.SetBit(object);
-  EXPECT_EQ(object.address(), bitmap.FindHeader(object.address()));
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderApproximate) {
-  static const size_t kInternalDelta = 37;
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object(654);
-  bitmap.SetBit(object);
-  EXPECT_EQ(object.address(),
-            bitmap.FindHeader(object.address() + kInternalDelta));
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderIteratingWholeBitmap) {
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object_to_find(Object(0));
-  Address hint_index = Object(ObjectStartBitmap::MaxEntries() - 1);
-  bitmap.SetBit(object_to_find);
-  EXPECT_EQ(object_to_find.address(), bitmap.FindHeader(hint_index));
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderNextCell) {
-  // This white box test makes use of the fact that cells are of type uint8_t.
-  const size_t kCellSize = sizeof(uint8_t);
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object_to_find(Object(kCellSize - 1));
-  Address hint = Object(kCellSize);
-  bitmap.SetBit(Object(0));
-  bitmap.SetBit(object_to_find);
-  EXPECT_EQ(object_to_find.address(), bitmap.FindHeader(hint));
-}
-
-TEST(ObjectStartBitmapTest, FindHeaderSameCell) {
-  // This white box test makes use of the fact that cells are of type uint8_t.
-  const size_t kCellSize = sizeof(uint8_t);
-  ObjectStartBitmap bitmap(Object::kBaseOffset);
-  Object object_to_find(Object(kCellSize - 1));
-  bitmap.SetBit(Object(0));
-  bitmap.SetBit(object_to_find);
-  EXPECT_EQ(object_to_find.address(),
-            bitmap.FindHeader(object_to_find.address()));
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/thread_state_scheduling_test.cc b/third_party/blink/renderer/platform/heap/impl/test/thread_state_scheduling_test.cc
deleted file mode 100644
index 0de0c32..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/thread_state_scheduling_test.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/run_loop.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
-#include "third_party/blink/renderer/platform/wtf/functional.h"
-
-namespace blink {
-
-namespace {
-
-void RunLoop() {
-  base::RunLoop rl;
-  // Push quit task.
-  ThreadScheduler::Current()->V8TaskRunner()->PostNonNestableTask(
-      FROM_HERE, WTF::Bind(rl.QuitWhenIdleClosure()));
-  rl.Run();
-}
-
-}  // namespace
-
-class ThreadStateSchedulingTest : public TestSupportingGC {
- public:
-  void SetUp() override {
-    state_ = ThreadState::Current();
-    ClearOutOldGarbage();
-  }
-
-  void TearDown() override {
-    PreciselyCollectGarbage();
-    EXPECT_EQ(ThreadState::kNoGCScheduled, state_->GetGCState());
-    EXPECT_FALSE(state_->IsMarkingInProgress());
-    EXPECT_FALSE(state_->IsSweepingInProgress());
-  }
-
-  BlinkGC::GCReason LastReason() const {
-    return state_->reason_for_scheduled_gc_;
-  }
-
-  void RunScheduledGC(BlinkGC::StackState stack_state) {
-    state_->RunScheduledGC(stack_state);
-  }
-
-  ThreadState* state() { return state_; }
-
- private:
-  ThreadState* state_;
-};
-
-TEST_F(ThreadStateSchedulingTest, RunIncrementalGCForTesting) {
-  ThreadStateSchedulingTest* test = this;
-
-  EXPECT_EQ(ThreadState::kNoGCScheduled, test->state()->GetGCState());
-  test->state()->StartIncrementalMarking(
-      BlinkGC::GCReason::kForcedGCForTesting);
-  EXPECT_EQ(ThreadState::kIncrementalMarkingStepScheduled,
-            test->state()->GetGCState());
-
-  RunLoop();
-  EXPECT_EQ(ThreadState::kNoGCScheduled, test->state()->GetGCState());
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/test/worklist_test.cc b/third_party/blink/renderer/platform/heap/impl/test/worklist_test.cc
deleted file mode 100644
index 206e6f4..0000000
--- a/third_party/blink/renderer/platform/heap/impl/test/worklist_test.cc
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Copied and adopted from V8.
-//
-// Copyright 2017 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/worklist.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-namespace {
-class SomeObject {};
-}  // namespace
-
-using TestWorklist = Worklist<SomeObject*, 64 /* entries */, 8 /* tasks */>;
-
-TEST(WorklistTest, SegmentCreate) {
-  TestWorklist::Segment segment;
-  EXPECT_TRUE(segment.IsEmpty());
-  EXPECT_EQ(0u, segment.Size());
-  EXPECT_FALSE(segment.IsFull());
-}
-
-TEST(WorklistTest, SegmentPush) {
-  TestWorklist::Segment segment;
-  EXPECT_EQ(0u, segment.Size());
-  EXPECT_TRUE(segment.Push(nullptr));
-  EXPECT_EQ(1u, segment.Size());
-}
-
-TEST(WorklistTest, SegmentPushPop) {
-  TestWorklist::Segment segment;
-  EXPECT_TRUE(segment.Push(nullptr));
-  EXPECT_EQ(1u, segment.Size());
-  SomeObject dummy;
-  SomeObject* object = &dummy;
-  EXPECT_TRUE(segment.Pop(&object));
-  EXPECT_EQ(0u, segment.Size());
-  EXPECT_EQ(nullptr, object);
-}
-
-TEST(WorklistTest, SegmentIsEmpty) {
-  TestWorklist::Segment segment;
-  EXPECT_TRUE(segment.IsEmpty());
-  EXPECT_TRUE(segment.Push(nullptr));
-  EXPECT_FALSE(segment.IsEmpty());
-}
-
-TEST(WorklistTest, SegmentIsFull) {
-  TestWorklist::Segment segment;
-  EXPECT_FALSE(segment.IsFull());
-  for (size_t i = 0; i < TestWorklist::Segment::kCapacity; i++) {
-    EXPECT_TRUE(segment.Push(nullptr));
-  }
-  EXPECT_TRUE(segment.IsFull());
-}
-
-TEST(WorklistTest, SegmentClear) {
-  TestWorklist::Segment segment;
-  EXPECT_TRUE(segment.Push(nullptr));
-  EXPECT_FALSE(segment.IsEmpty());
-  segment.Clear();
-  EXPECT_TRUE(segment.IsEmpty());
-  for (size_t i = 0; i < TestWorklist::Segment::kCapacity; i++) {
-    EXPECT_TRUE(segment.Push(nullptr));
-  }
-}
-
-TEST(WorklistTest, SegmentFullPushFails) {
-  TestWorklist::Segment segment;
-  EXPECT_FALSE(segment.IsFull());
-  for (size_t i = 0; i < TestWorklist::Segment::kCapacity; i++) {
-    EXPECT_TRUE(segment.Push(nullptr));
-  }
-  EXPECT_TRUE(segment.IsFull());
-  EXPECT_FALSE(segment.Push(nullptr));
-}
-
-TEST(WorklistTest, SegmentEmptyPopFails) {
-  TestWorklist::Segment segment;
-  EXPECT_TRUE(segment.IsEmpty());
-  SomeObject* object;
-  EXPECT_FALSE(segment.Pop(&object));
-}
-
-TEST(WorklistTest, SegmentUpdateFalse) {
-  TestWorklist::Segment segment;
-  SomeObject* object;
-  object = reinterpret_cast<SomeObject*>(&object);
-  EXPECT_TRUE(segment.Push(object));
-  segment.Update([](SomeObject* object, SomeObject** out) { return false; });
-  EXPECT_TRUE(segment.IsEmpty());
-}
-
-TEST(WorklistTest, SegmentUpdate) {
-  TestWorklist::Segment segment;
-  SomeObject* objectA;
-  objectA = reinterpret_cast<SomeObject*>(&objectA);
-  SomeObject* objectB;
-  objectB = reinterpret_cast<SomeObject*>(&objectB);
-  EXPECT_TRUE(segment.Push(objectA));
-  segment.Update([objectB](SomeObject* object, SomeObject** out) {
-    *out = objectB;
-    return true;
-  });
-  SomeObject* object;
-  EXPECT_TRUE(segment.Pop(&object));
-  EXPECT_EQ(object, objectB);
-}
-
-TEST(WorklistTest, CreateEmpty) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view(&worklist, 0);
-  EXPECT_TRUE(worklist_view.IsLocalEmpty());
-  EXPECT_TRUE(worklist.IsGlobalEmpty());
-}
-
-TEST(WorklistTest, LocalPushPop) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view(&worklist, 0);
-  SomeObject dummy;
-  SomeObject* retrieved = nullptr;
-  EXPECT_TRUE(worklist_view.Push(&dummy));
-  EXPECT_FALSE(worklist_view.IsLocalEmpty());
-  EXPECT_TRUE(worklist_view.Pop(&retrieved));
-  EXPECT_EQ(&dummy, retrieved);
-}
-
-TEST(WorklistTest, LocalIsBasedOnId) {
-  TestWorklist worklist;
-  // Use the same id.
-  TestWorklist::View worklist_view1(&worklist, 0);
-  TestWorklist::View worklist_view2(&worklist, 0);
-  SomeObject dummy;
-  SomeObject* retrieved = nullptr;
-  EXPECT_TRUE(worklist_view1.Push(&dummy));
-  EXPECT_FALSE(worklist_view1.IsLocalEmpty());
-  EXPECT_FALSE(worklist_view2.IsLocalEmpty());
-  EXPECT_TRUE(worklist_view2.Pop(&retrieved));
-  EXPECT_EQ(&dummy, retrieved);
-  EXPECT_TRUE(worklist_view1.IsLocalEmpty());
-  EXPECT_TRUE(worklist_view2.IsLocalEmpty());
-}
-
-TEST(WorklistTest, LocalPushStaysPrivate) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view1(&worklist, 0);
-  TestWorklist::View worklist_view2(&worklist, 1);
-  SomeObject dummy;
-  SomeObject* retrieved = nullptr;
-  EXPECT_TRUE(worklist.IsGlobalEmpty());
-  EXPECT_EQ(0U, worklist.GlobalPoolSize());
-  EXPECT_TRUE(worklist_view1.Push(&dummy));
-  EXPECT_FALSE(worklist.IsGlobalEmpty());
-  EXPECT_EQ(0U, worklist.GlobalPoolSize());
-  EXPECT_FALSE(worklist_view2.Pop(&retrieved));
-  EXPECT_EQ(nullptr, retrieved);
-  EXPECT_TRUE(worklist_view1.Pop(&retrieved));
-  EXPECT_EQ(&dummy, retrieved);
-  EXPECT_TRUE(worklist.IsGlobalEmpty());
-  EXPECT_EQ(0U, worklist.GlobalPoolSize());
-}
-
-TEST(WorklistTest, GlobalUpdateNull) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view(&worklist, 0);
-  SomeObject* object;
-  object = reinterpret_cast<SomeObject*>(&object);
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view.Push(object));
-  }
-  EXPECT_TRUE(worklist_view.Push(object));
-  worklist.Update([](SomeObject* object, SomeObject** out) { return false; });
-  EXPECT_TRUE(worklist.IsGlobalEmpty());
-  EXPECT_EQ(0U, worklist.GlobalPoolSize());
-}
-
-TEST(WorklistTest, GlobalUpdate) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view(&worklist, 0);
-  SomeObject* objectA = nullptr;
-  objectA = reinterpret_cast<SomeObject*>(&objectA);
-  SomeObject* objectB = nullptr;
-  objectB = reinterpret_cast<SomeObject*>(&objectB);
-  SomeObject* objectC = nullptr;
-  objectC = reinterpret_cast<SomeObject*>(&objectC);
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view.Push(objectA));
-  }
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view.Push(objectB));
-  }
-  EXPECT_TRUE(worklist_view.Push(objectA));
-  worklist.Update([objectA, objectC](SomeObject* object, SomeObject** out) {
-    if (object != objectA) {
-      *out = objectC;
-      return true;
-    }
-    return false;
-  });
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    SomeObject* object;
-    EXPECT_TRUE(worklist_view.Pop(&object));
-    EXPECT_EQ(object, objectC);
-  }
-}
-
-TEST(WorklistTest, FlushToGlobalPushSegment) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view0(&worklist, 0);
-  TestWorklist::View worklist_view1(&worklist, 1);
-  SomeObject* object = nullptr;
-  SomeObject* objectA = nullptr;
-  objectA = reinterpret_cast<SomeObject*>(&objectA);
-  EXPECT_TRUE(worklist_view0.Push(objectA));
-  worklist.FlushToGlobal(0);
-  EXPECT_EQ(1U, worklist.GlobalPoolSize());
-  EXPECT_TRUE(worklist_view1.Pop(&object));
-}
-
-TEST(WorklistTest, FlushToGlobalPopSegment) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view0(&worklist, 0);
-  TestWorklist::View worklist_view1(&worklist, 1);
-  SomeObject* object = nullptr;
-  SomeObject* objectA = nullptr;
-  objectA = reinterpret_cast<SomeObject*>(&objectA);
-  EXPECT_TRUE(worklist_view0.Push(objectA));
-  EXPECT_TRUE(worklist_view0.Push(objectA));
-  EXPECT_TRUE(worklist_view0.Pop(&object));
-  worklist.FlushToGlobal(0);
-  EXPECT_EQ(1U, worklist.GlobalPoolSize());
-  EXPECT_TRUE(worklist_view1.Pop(&object));
-}
-
-TEST(WorklistTest, Clear) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view(&worklist, 0);
-  SomeObject* object;
-  object = reinterpret_cast<SomeObject*>(&object);
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view.Push(object));
-  }
-  EXPECT_TRUE(worklist_view.Push(object));
-  EXPECT_EQ(1U, worklist.GlobalPoolSize());
-  worklist.Clear();
-  EXPECT_TRUE(worklist.IsGlobalEmpty());
-  EXPECT_EQ(0U, worklist.GlobalPoolSize());
-}
-
-TEST(WorklistTest, SingleSegmentSteal) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view1(&worklist, 0);
-  TestWorklist::View worklist_view2(&worklist, 1);
-  SomeObject dummy;
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view1.Push(&dummy));
-  }
-  SomeObject* retrieved = nullptr;
-  // One more push/pop to publish the full segment.
-  EXPECT_TRUE(worklist_view1.Push(nullptr));
-  EXPECT_TRUE(worklist_view1.Pop(&retrieved));
-  EXPECT_EQ(nullptr, retrieved);
-  EXPECT_EQ(1U, worklist.GlobalPoolSize());
-  // Stealing.
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view2.Pop(&retrieved));
-    EXPECT_EQ(&dummy, retrieved);
-    EXPECT_FALSE(worklist_view1.Pop(&retrieved));
-  }
-  EXPECT_TRUE(worklist.IsGlobalEmpty());
-  EXPECT_EQ(0U, worklist.GlobalPoolSize());
-}
-
-TEST(WorklistTest, MultipleSegmentsStolen) {
-  TestWorklist worklist;
-  TestWorklist::View worklist_view1(&worklist, 0);
-  TestWorklist::View worklist_view2(&worklist, 1);
-  TestWorklist::View worklist_view3(&worklist, 2);
-  SomeObject dummy1;
-  SomeObject dummy2;
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view1.Push(&dummy1));
-  }
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view1.Push(&dummy2));
-  }
-  SomeObject* retrieved = nullptr;
-  SomeObject dummy3;
-  // One more push/pop to publish the full segment.
-  EXPECT_TRUE(worklist_view1.Push(&dummy3));
-  EXPECT_TRUE(worklist_view1.Pop(&retrieved));
-  EXPECT_EQ(&dummy3, retrieved);
-  EXPECT_EQ(2U, worklist.GlobalPoolSize());
-  // Stealing.
-  EXPECT_TRUE(worklist_view2.Pop(&retrieved));
-  SomeObject* const expect_bag2 = retrieved;
-  EXPECT_TRUE(worklist_view3.Pop(&retrieved));
-  SomeObject* const expect_bag3 = retrieved;
-  EXPECT_EQ(0U, worklist.GlobalPoolSize());
-  EXPECT_NE(expect_bag2, expect_bag3);
-  EXPECT_TRUE(expect_bag2 == &dummy1 || expect_bag2 == &dummy2);
-  EXPECT_TRUE(expect_bag3 == &dummy1 || expect_bag3 == &dummy2);
-  for (size_t i = 1; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view2.Pop(&retrieved));
-    EXPECT_EQ(expect_bag2, retrieved);
-    EXPECT_FALSE(worklist_view1.Pop(&retrieved));
-  }
-  for (size_t i = 1; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view3.Pop(&retrieved));
-    EXPECT_EQ(expect_bag3, retrieved);
-    EXPECT_FALSE(worklist_view1.Pop(&retrieved));
-  }
-  EXPECT_TRUE(worklist.IsGlobalEmpty());
-}
-
-TEST(WorklistTest, MergeGlobalPool) {
-  TestWorklist worklist1;
-  TestWorklist::View worklist_view1(&worklist1, 0);
-  SomeObject dummy;
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view1.Push(&dummy));
-  }
-  SomeObject* retrieved = nullptr;
-  // One more push/pop to publish the full segment.
-  EXPECT_TRUE(worklist_view1.Push(nullptr));
-  EXPECT_TRUE(worklist_view1.Pop(&retrieved));
-  EXPECT_EQ(nullptr, retrieved);
-  EXPECT_EQ(1U, worklist1.GlobalPoolSize());
-  // Merging global pool into a new Worklist.
-  TestWorklist worklist2;
-  TestWorklist::View worklist_view2(&worklist2, 0);
-  EXPECT_EQ(0U, worklist2.GlobalPoolSize());
-  worklist2.MergeGlobalPool(&worklist1);
-  EXPECT_EQ(1U, worklist2.GlobalPoolSize());
-  EXPECT_FALSE(worklist2.IsGlobalEmpty());
-  for (size_t i = 0; i < TestWorklist::kSegmentCapacity; i++) {
-    EXPECT_TRUE(worklist_view2.Pop(&retrieved));
-    EXPECT_EQ(&dummy, retrieved);
-    EXPECT_FALSE(worklist_view1.Pop(&retrieved));
-  }
-  EXPECT_TRUE(worklist1.IsGlobalEmpty());
-  EXPECT_TRUE(worklist2.IsGlobalEmpty());
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/thread_state.cc b/third_party/blink/renderer/platform/heap/impl/thread_state.cc
deleted file mode 100644
index 101dc30..0000000
--- a/third_party/blink/renderer/platform/heap/impl/thread_state.cc
+++ /dev/null
@@ -1,1798 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-
-#include <algorithm>
-#include <iomanip>
-#include <limits>
-#include <memory>
-
-#include "base/atomicops.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/numerics/safe_conversions.h"
-#include "base/task_runner.h"
-#include "base/trace_event/process_memory_dump.h"
-#include "build/build_config.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/platform/platform.h"
-#include "third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h"
-#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
-#include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h"
-#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
-#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h"
-#include "third_party/blink/renderer/platform/heap/handle.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_buildflags.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_compact.h"
-#include "third_party/blink/renderer/platform/heap/impl/marking_scheduling_oracle.h"
-#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/impl/page_pool.h"
-#include "third_party/blink/renderer/platform/heap/persistent.h"
-#include "third_party/blink/renderer/platform/heap/thread_state_scopes.h"
-#include "third_party/blink/renderer/platform/heap/unified_heap_controller.h"
-#include "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/instrumentation/histogram.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h"
-#include "third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump.h"
-#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
-#include "third_party/blink/renderer/platform/scheduler/public/worker_pool.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
-#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
-#include "third_party/blink/renderer/platform/wtf/stack_util.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-#include "v8/include/v8-profiler.h"
-#include "v8/include/v8.h"
-
-#if defined(OS_WIN)
-#include <stddef.h>
-#include <windows.h>
-#include <winnt.h>
-#endif
-
-#if defined(MEMORY_SANITIZER)
-#include <sanitizer/msan_interface.h>
-#endif
-
-#if defined(OS_FREEBSD)
-#include <pthread_np.h>
-#endif
-
-namespace blink {
-
-WTF::ThreadSpecific<ThreadState*>* ThreadState::thread_specific_ = nullptr;
-uint8_t ThreadState::main_thread_state_storage_[sizeof(ThreadState)];
-
-namespace {
-
-constexpr double kMarkingScheduleRatioBeforeConcurrentPriorityIncrease = 0.5;
-
-// Helper function to convert a byte count to a KB count, capping at
-// INT_MAX if the number is larger than that.
-constexpr base::Histogram::Sample CappedSizeInKB(size_t size_in_bytes) {
-  return base::saturated_cast<base::Histogram::Sample>(size_in_bytes / 1024);
-}
-
-class WorkerPoolTaskRunner : public base::TaskRunner {
- public:
-  bool PostDelayedTask(const base::Location& location,
-                       base::OnceClosure task,
-                       base::TimeDelta) override {
-    worker_pool::PostTask(location, WTF::CrossThreadBindOnce(std::move(task)));
-    return true;
-  }
-};
-
-}  // namespace
-
-class ThreadState::IncrementalMarkingScheduler {
- public:
-  explicit IncrementalMarkingScheduler(ThreadState* thread_state)
-      : thread_state_(thread_state) {}
-
-  // Starts incremental marking with further scheduled steps.
-  void Start(BlinkGC::GCReason reason) {
-    Init(reason);
-    thread_state_->IncrementalMarkingStart(reason_);
-    ScheduleTask();
-  }
-
-  void Restart() {
-    DCHECK(!task_.IsActive());
-    ScheduleTask();
-  }
-
-  // Cancels incremental marking task in case there is any pending.
-  void Cancel() { task_.Cancel(); }
-
- private:
-  void Init(BlinkGC::GCReason reason) {
-    DCHECK(!task_.IsActive());
-    reason_ = reason;
-  }
-
-  void ScheduleTask() {
-    // Reassigning to the task will cancel the currently scheduled one.
-    task_ = PostNonNestableCancellableTask(
-        *ThreadScheduler::Current()->V8TaskRunner(), FROM_HERE,
-        WTF::Bind(&IncrementalMarkingScheduler::Dispatch,
-                  WTF::Unretained(this)));
-  }
-
-  void Dispatch() {
-    switch (thread_state_->GetGCState()) {
-      case ThreadState::kIncrementalMarkingStepScheduled:
-        thread_state_->IncrementalMarkingStep(BlinkGC::kNoHeapPointersOnStack);
-        if (thread_state_->GetGCState() !=
-            ThreadState::kIncrementalMarkingStepPaused) {
-          ScheduleTask();
-        }
-        break;
-      case ThreadState::kIncrementalMarkingFinalizeScheduled:
-        thread_state_->IncrementalMarkingFinalize();
-        break;
-      default:
-        break;
-    }
-  }
-
-  ThreadState* thread_state_;
-  BlinkGC::GCReason reason_;
-  TaskHandle task_;
-};
-
-ThreadState::ThreadState()
-    : thread_(CurrentThread()),
-      persistent_region_(std::make_unique<PersistentRegion>()),
-      weak_persistent_region_(std::make_unique<PersistentRegion>()),
-      start_of_stack_(reinterpret_cast<Address*>(WTF::GetStackStart())),
-#if defined(ADDRESS_SANITIZER)
-      asan_fake_stack_(__asan_get_current_fake_stack()),
-#endif
-      incremental_marking_scheduler_(
-          std::make_unique<IncrementalMarkingScheduler>(this)) {
-  DCHECK(CheckThread());
-  DCHECK(!**thread_specific_);
-  **thread_specific_ = this;
-  heap_ = std::make_unique<ThreadHeap>(this);
-}
-
-ThreadState::~ThreadState() {
-  DCHECK(CheckThread());
-  if (IsMainThread())
-    DCHECK_EQ(0u, Heap().stats_collector()->allocated_space_bytes());
-  CHECK(GetGCState() == ThreadState::kNoGCScheduled);
-
-  **thread_specific_ = nullptr;
-}
-
-ThreadState* ThreadState::AttachMainThreadForTesting(v8::Platform*) {
-  return AttachMainThread();
-}
-
-ThreadState* ThreadState::AttachMainThread() {
-  thread_specific_ = new WTF::ThreadSpecific<ThreadState*>();
-  return new (main_thread_state_storage_) ThreadState();
-}
-
-ThreadState* ThreadState::AttachCurrentThread() {
-  return new ThreadState();
-}
-
-ThreadState* ThreadState::AttachCurrentThreadForTesting(v8::Platform*) {
-  return AttachCurrentThread();
-}
-
-void ThreadState::DetachCurrentThread() {
-  ThreadState* state = Current();
-  DCHECK(!state->IsMainThread());
-  state->RunTerminationGC();
-  delete state;
-}
-
-namespace {
-
-// See platform/heap/v8_wrapper/thread_state.cc version for details.
-class BlinkRootsHandler final : public v8::EmbedderRootsHandler {
- public:
-  explicit BlinkRootsHandler(ThreadState& thread_state)
-      : thread_state_(thread_state) {}
-  ~BlinkRootsHandler() final = default;
-
-  bool IsRoot(const v8::TracedReference<v8::Value>& handle) final {
-    const uint16_t class_id = handle.WrapperClassId();
-    // Stand-alone reference or kCustomWrappableId. Keep as root as
-    // we don't know better.
-    if (class_id != WrapperTypeInfo::kNodeClassId &&
-        class_id != WrapperTypeInfo::kObjectClassId)
-      return true;
-
-    const v8::TracedReference<v8::Object>& traced =
-        handle.template As<v8::Object>();
-    if (ToWrapperTypeInfo(traced)->IsActiveScriptWrappable() &&
-        ToScriptWrappable(traced)->HasPendingActivity()) {
-      return true;
-    }
-
-    if (ToScriptWrappable(traced)->HasEventListeners()) {
-      return true;
-    }
-
-    return false;
-  }
-
-  bool IsRoot(const v8::TracedGlobal<v8::Value>& handle) final {
-    CHECK(false) << "Blink does not use v8::TracedGlobal.";
-    return false;
-  }
-
-  void ResetRoot(const v8::TracedReference<v8::Value>& handle) final {
-    const uint16_t class_id = handle.WrapperClassId();
-    // Only consider handles that have not been treated as roots, see
-    // IsRootForNonTracingGCInternal.
-    if (class_id != WrapperTypeInfo::kNodeClassId &&
-        class_id != WrapperTypeInfo::kObjectClassId)
-      return;
-
-    // Clearing the wrapper below adjusts the DOM wrapper store which may
-    // re-allocate its backing. We have to avoid report memory to V8 as that may
-    // trigger GC during GC.
-    ThreadState::GCForbiddenScope no_gc(&thread_state_);
-    const v8::TracedReference<v8::Object>& traced = handle.As<v8::Object>();
-    bool success = DOMWrapperWorld::UnsetSpecificWrapperIfSet(
-        ToScriptWrappable(traced), traced);
-    // Since V8 found a handle, Blink needs to find it as well when trying to
-    // remove it.
-    CHECK(success);
-  }
-
- private:
-  ThreadState& thread_state_;
-};
-
-}  // namespace
-
-void ThreadState::AttachToIsolate(
-    v8::Isolate* isolate,
-    V8BuildEmbedderGraphCallback v8_build_embedder_graph) {
-  DCHECK(isolate);
-  isolate_ = isolate;
-  v8_build_embedder_graph_ = v8_build_embedder_graph;
-  unified_heap_controller_ = std::make_unique<UnifiedHeapController>(this);
-  isolate_->SetEmbedderHeapTracer(unified_heap_controller_.get());
-  unified_heap_controller_.get()->SetStackStart(WTF::GetStackStart());
-  if (v8::HeapProfiler* profiler = isolate->GetHeapProfiler()) {
-    profiler->AddBuildEmbedderGraphCallback(v8_build_embedder_graph, nullptr);
-  }
-  embedder_roots_handler_ = std::make_unique<BlinkRootsHandler>(*this);
-  isolate_->SetEmbedderRootsHandler(embedder_roots_handler_.get());
-}
-
-void ThreadState::DetachFromIsolate() {
-  FinishIncrementalMarkingIfRunning(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
-      BlinkGC::kAtomicMarking, BlinkGC::kEagerSweeping,
-      BlinkGC::GCReason::kThreadTerminationGC);
-  if (isolate_) {
-    isolate_->SetEmbedderHeapTracer(nullptr);
-    if (v8::HeapProfiler* profiler = isolate_->GetHeapProfiler()) {
-      profiler->RemoveBuildEmbedderGraphCallback(v8_build_embedder_graph_,
-                                                 nullptr);
-    }
-    isolate_->SetEmbedderRootsHandler(nullptr);
-  }
-  isolate_ = nullptr;
-  v8_build_embedder_graph_ = nullptr;
-  unified_heap_controller_.reset();
-}
-
-void ThreadState::RunTerminationGC() {
-  DCHECK(!IsMainThread());
-  DCHECK(CheckThread());
-
-  FinishIncrementalMarkingIfRunning(BlinkGC::CollectionType::kMajor,
-                                    BlinkGC::kNoHeapPointersOnStack,
-                                    BlinkGC::kIncrementalAndConcurrentMarking,
-                                    BlinkGC::kConcurrentAndLazySweeping,
-                                    BlinkGC::GCReason::kThreadTerminationGC);
-  // Finish sweeping.
-  CompleteSweep();
-
-  // The constant specifies how many rounds of GCs should at most be needed to
-  // clean up the heap. If we crash below this means that there's finalizers
-  // adding more objects and roots than the GC is able to clean up.
-  constexpr size_t kMaxTerminationGCsForHeapCleanup = 20;
-  size_t i = 0;
-  do {
-    CHECK_LT(i++, kMaxTerminationGCsForHeapCleanup);
-    // Remove strong cross-thread roots.
-    ProcessHeap::GetCrossThreadPersistentRegion()
-        .PrepareForThreadStateTermination(this);
-    // Remove regular roots.
-    GetPersistentRegion()->PrepareForThreadStateTermination(this);
-    CHECK_EQ(0, GetPersistentRegion()->NodesInUse());
-    CollectGarbage(BlinkGC::CollectionType::kMajor,
-                   BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking,
-                   BlinkGC::kEagerSweeping,
-                   BlinkGC::GCReason::kThreadTerminationGC);
-  } while (GetPersistentRegion()->NodesInUse() != 0);
-
-  // All of pre-finalizers should be consumed.
-  CHECK(ordered_pre_finalizers_.empty());
-  CHECK_EQ(GetGCState(), kNoGCScheduled);
-
-  Heap().RemoveAllPages();
-}
-
-NO_SANITIZE_ADDRESS
-void ThreadState::VisitAsanFakeStackForPointer(MarkingVisitor* visitor,
-                                               Address ptr,
-                                               Address* start_of_stack,
-                                               Address* end_of_stack) {
-#if defined(ADDRESS_SANITIZER)
-  Address* fake_frame_start = nullptr;
-  Address* fake_frame_end = nullptr;
-  Address* maybe_fake_frame = reinterpret_cast<Address*>(ptr);
-  Address* real_frame_for_fake_frame = reinterpret_cast<Address*>(
-      __asan_addr_is_in_fake_stack(asan_fake_stack_, maybe_fake_frame,
-                                   reinterpret_cast<void**>(&fake_frame_start),
-                                   reinterpret_cast<void**>(&fake_frame_end)));
-  if (real_frame_for_fake_frame) {
-    // This is a fake frame from the asan fake stack.
-    if (real_frame_for_fake_frame > end_of_stack &&
-        start_of_stack > real_frame_for_fake_frame) {
-      // The real stack address for the asan fake frame is
-      // within the stack range that we need to scan so we need
-      // to visit the values in the fake frame.
-      for (Address* p = fake_frame_start; p < fake_frame_end; ++p)
-        heap_->CheckAndMarkPointer(visitor, *p);
-    }
-  }
-#endif  // ADDRESS_SANITIZER
-}
-
-// Stack scanning may overrun the bounds of local objects and/or race with
-// other threads that use this stack.
-NO_SANITIZE_ADDRESS
-NO_SANITIZE_HWADDRESS
-NO_SANITIZE_THREAD
-void ThreadState::VisitStackImpl(MarkingVisitor* visitor,
-                                 Address* start_of_stack,
-                                 Address* end_of_stack) {
-  DCHECK_EQ(current_gc_data_.stack_state, BlinkGC::kHeapPointersOnStack);
-
-  // Ensure that current is aligned by address size otherwise the loop below
-  // will read past start address.
-  Address* current = reinterpret_cast<Address*>(
-      reinterpret_cast<intptr_t>(end_of_stack) & ~(sizeof(Address) - 1));
-
-  for (; current < start_of_stack; ++current) {
-    Address ptr = *current;
-#if defined(MEMORY_SANITIZER)
-    // |ptr| may be uninitialized by design. Mark it as initialized to keep
-    // MSan from complaining.
-    // Note: it may be tempting to get rid of |ptr| and simply use |current|
-    // here, but that would be incorrect. We intentionally use a local
-    // variable because we don't want to unpoison the original stack.
-    __msan_unpoison(&ptr, sizeof(ptr));
-#endif
-    heap_->CheckAndMarkPointer(visitor, ptr);
-    VisitAsanFakeStackForPointer(visitor, ptr, start_of_stack, end_of_stack);
-  }
-}
-
-void ThreadState::VisitStack(MarkingVisitor* visitor, Address* end_of_stack) {
-  VisitStackImpl(visitor, start_of_stack_, end_of_stack);
-}
-
-void ThreadState::VisitUnsafeStack(MarkingVisitor* visitor) {
-#if HAS_FEATURE(safe_stack)
-  VisitStackImpl(visitor,
-                 static_cast<Address*>(__builtin___get_unsafe_stack_top()),
-                 static_cast<Address*>(__builtin___get_unsafe_stack_ptr()));
-#endif  // HAS_FEATURE(safe_stack)
-}
-
-void ThreadState::VisitPersistents(Visitor* visitor) {
-  ThreadHeapStatsCollector::Scope stats_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kVisitPersistentRoots);
-  {
-    ThreadHeapStatsCollector::Scope inner_stats_scope(
-        Heap().stats_collector(),
-        ThreadHeapStatsCollector::kVisitCrossThreadPersistents);
-    ProcessHeap::CrossThreadPersistentMutex().AssertAcquired();
-    ProcessHeap::GetCrossThreadPersistentRegion().TraceNodes(visitor);
-  }
-  {
-    ThreadHeapStatsCollector::Scope inner_stats_scope(
-        Heap().stats_collector(), ThreadHeapStatsCollector::kVisitPersistents);
-    persistent_region_->TraceNodes(visitor);
-  }
-}
-
-void ThreadState::VisitRememberedSets(MarkingVisitor* visitor) {
-  ThreadHeapStatsCollector::EnabledScope stats_scope(
-      Heap().stats_collector(), ThreadHeapStatsCollector::kVisitRememberedSets);
-  Heap().VisitRememberedSets(visitor);
-}
-
-void ThreadState::VisitWeakPersistents(Visitor* visitor) {
-  ProcessHeap::GetCrossThreadWeakPersistentRegion().TraceNodes(visitor);
-  weak_persistent_region_->TraceNodes(visitor);
-}
-
-void ThreadState::ScheduleForcedGCForTesting() {
-  DCHECK(CheckThread());
-  CompleteSweep();
-  SetGCState(kForcedGCForTestingScheduled);
-}
-
-void ThreadState::ScheduleGCIfNeeded() {
-  VLOG(2) << "[state:" << this << "] ScheduleGCIfNeeded";
-  DCHECK(CheckThread());
-
-  // Allocation is allowed during sweeping, but those allocations should not
-  // trigger nested GCs.
-  if (IsGCForbidden() || SweepForbidden())
-    return;
-
-  // This method should not call out to V8 during unified heap garbage
-  // collections. Specifically, reporting memory to V8 may trigger a marking
-  // step which is not allowed during construction of an object. The reason is
-  // that a parent object's constructor is potentially being invoked which may
-  // have already published the object. In that case the object may be colored
-  // black in a v8 marking step which invalidates the assumption that write
-  // barriers may be avoided when constructing an object as it is white.
-  if (IsUnifiedGCMarkingInProgress())
-    return;
-
-  if (GetGCState() == kNoGCScheduled &&
-      base::FeatureList::IsEnabled(
-          blink::features::kBlinkHeapIncrementalMarkingStress)) {
-    VLOG(2) << "[state:" << this << "] "
-            << "ScheduleGCIfNeeded: Scheduled incremental marking for testing";
-    StartIncrementalMarking(BlinkGC::GCReason::kForcedGCForTesting);
-    return;
-  }
-}
-
-ThreadState* ThreadState::FromObject(const void* object) {
-  DCHECK(object);
-  BasePage* page = PageFromObject(object);
-  DCHECK(page);
-  DCHECK(page->Arena());
-  return page->Arena()->GetThreadState();
-}
-
-void ThreadState::PerformIdleLazySweep(base::TimeTicks deadline) {
-  DCHECK(CheckThread());
-
-  // If we are not in a sweeping phase, there is nothing to do here.
-  if (!IsSweepingInProgress())
-    return;
-
-  // This check is here to prevent performIdleLazySweep() from being called
-  // recursively. I'm not sure if it can happen but it would be safer to have
-  // the check just in case.
-  if (SweepForbidden())
-    return;
-
-  if (!AdvanceLazySweep(deadline)) {
-    ScheduleIdleLazySweep();
-  }
-}
-
-bool ThreadState::AdvanceLazySweep(base::TimeTicks deadline) {
-  DCHECK(CheckThread());
-  DCHECK(IsSweepingInProgress());
-  DCHECK(!SweepForbidden());
-
-  RUNTIME_CALL_TIMER_SCOPE_IF_ISOLATE_EXISTS(
-      GetIsolate(), RuntimeCallStats::CounterId::kPerformIdleLazySweep);
-
-  bool sweep_completed = false;
-  {
-    AtomicPauseScope atomic_pause_scope(this);
-    ScriptForbiddenScope script_forbidden_scope;
-    SweepForbiddenScope scope(this);
-    ThreadHeapStatsCollector::EnabledScope stats_scope(
-        Heap().stats_collector(), ThreadHeapStatsCollector::kLazySweepInIdle,
-        "idleDeltaInSeconds", (deadline - base::TimeTicks::Now()).InSecondsF());
-    sweep_completed = Heap().AdvanceLazySweep(deadline);
-    // We couldn't finish the sweeping within the deadline.
-    // We request another idle task for the remaining sweeping.
-    if (sweep_completed) {
-      SynchronizeAndFinishConcurrentSweeping();
-    }
-  }
-
-  if (sweep_completed) {
-    NotifySweepDone();
-  }
-  return sweep_completed;
-}
-
-void ThreadState::PerformConcurrentSweep(base::JobDelegate* job) {
-  VLOG(2) << "[state:" << this << "] [threadid:" << CurrentThread() << "] "
-          << "ConcurrentSweep";
-  ThreadHeapStatsCollector::EnabledConcurrentScope stats_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kConcurrentSweepingStep);
-
-  if (Heap().AdvanceConcurrentSweep(job))
-    has_unswept_pages_.store(false, std::memory_order_relaxed);
-}
-
-void ThreadState::StartIncrementalMarking(BlinkGC::GCReason reason) {
-  DCHECK(CheckThread());
-  // Schedule an incremental GC only when no GC is scheduled. Otherwise, already
-  // scheduled GCs should be prioritized.
-  if (GetGCState() != kNoGCScheduled) {
-    return;
-  }
-  CompleteSweep();
-  reason_for_scheduled_gc_ = reason;
-  SetGCState(kIncrementalGCScheduled);
-  incremental_marking_scheduler_->Start(reason);
-}
-
-void ThreadState::ScheduleIdleLazySweep() {
-  ThreadScheduler::Current()->PostIdleTask(
-      FROM_HERE,
-      WTF::Bind(&ThreadState::PerformIdleLazySweep, WTF::Unretained(this)));
-}
-
-void ThreadState::ScheduleConcurrentAndLazySweep() {
-  ScheduleIdleLazySweep();
-
-  if (!base::FeatureList::IsEnabled(
-          blink::features::kBlinkHeapConcurrentSweeping)) {
-    return;
-  }
-
-  has_unswept_pages_ = true;
-  sweeper_handle_ = base::PostJob(
-      FROM_HERE,
-      {base::TaskPriority::USER_VISIBLE,
-       base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
-      ConvertToBaseRepeatingCallback(
-          WTF::CrossThreadBindRepeating(&ThreadState::PerformConcurrentSweep,
-                                        WTF::CrossThreadUnretained(this))),
-      ConvertToBaseRepeatingCallback(WTF::CrossThreadBindRepeating(
-          [](ThreadState* state, size_t /*worker_count*/) -> size_t {
-            return state->has_unswept_pages_.load(std::memory_order_relaxed)
-                       ? 1
-                       : 0;
-          },
-          WTF::CrossThreadUnretained(this))));
-}
-
-namespace {
-
-#define UNEXPECTED_GCSTATE(s)                                   \
-  case ThreadState::s:                                          \
-    LOG(FATAL) << "Unexpected transition while in GCState " #s; \
-    return
-
-void UnexpectedGCState(ThreadState::GCState gc_state) {
-  switch (gc_state) {
-    UNEXPECTED_GCSTATE(kNoGCScheduled);
-    UNEXPECTED_GCSTATE(kForcedGCForTestingScheduled);
-    UNEXPECTED_GCSTATE(kIncrementalMarkingStepPaused);
-    UNEXPECTED_GCSTATE(kIncrementalMarkingStepScheduled);
-    UNEXPECTED_GCSTATE(kIncrementalMarkingFinalizeScheduled);
-    UNEXPECTED_GCSTATE(kIncrementalGCScheduled);
-  }
-}
-
-#undef UNEXPECTED_GCSTATE
-
-}  // namespace
-
-#define VERIFY_STATE_TRANSITION(condition) \
-  if (UNLIKELY(!(condition)))              \
-  UnexpectedGCState(gc_state_)
-
-void ThreadState::SetGCState(GCState gc_state) {
-  switch (gc_state) {
-    case kNoGCScheduled:
-      DCHECK(CheckThread());
-      VERIFY_STATE_TRANSITION(gc_state_ == kNoGCScheduled ||
-                              gc_state_ == kForcedGCForTestingScheduled ||
-                              gc_state_ == kIncrementalMarkingStepPaused ||
-                              gc_state_ == kIncrementalMarkingStepScheduled ||
-                              gc_state_ ==
-                                  kIncrementalMarkingFinalizeScheduled ||
-                              gc_state_ == kIncrementalGCScheduled);
-      break;
-    case kIncrementalMarkingStepScheduled:
-      DCHECK(CheckThread());
-      VERIFY_STATE_TRANSITION(gc_state_ == kNoGCScheduled ||
-                              gc_state_ == kIncrementalMarkingStepScheduled ||
-                              gc_state_ == kIncrementalGCScheduled ||
-                              gc_state_ == kIncrementalMarkingStepPaused);
-      break;
-    case kIncrementalMarkingFinalizeScheduled:
-      DCHECK(CheckThread());
-      VERIFY_STATE_TRANSITION(gc_state_ == kIncrementalMarkingStepScheduled);
-      break;
-    case kForcedGCForTestingScheduled:
-      DCHECK(CheckThread());
-      DCHECK(!IsSweepingInProgress());
-      VERIFY_STATE_TRANSITION(gc_state_ == kNoGCScheduled ||
-                              gc_state_ == kIncrementalMarkingStepPaused ||
-                              gc_state_ == kIncrementalMarkingStepScheduled ||
-                              gc_state_ ==
-                                  kIncrementalMarkingFinalizeScheduled ||
-                              gc_state_ == kForcedGCForTestingScheduled ||
-                              gc_state_ == kIncrementalGCScheduled);
-      break;
-    case kIncrementalGCScheduled:
-      DCHECK(CheckThread());
-      DCHECK(!IsMarkingInProgress());
-      DCHECK(!IsSweepingInProgress());
-      VERIFY_STATE_TRANSITION(gc_state_ == kNoGCScheduled);
-      break;
-    case kIncrementalMarkingStepPaused:
-      DCHECK(CheckThread());
-      DCHECK(IsMarkingInProgress());
-      DCHECK(!IsSweepingInProgress());
-      VERIFY_STATE_TRANSITION(gc_state_ == kIncrementalMarkingStepScheduled);
-      break;
-    default:
-      NOTREACHED();
-  }
-  gc_state_ = gc_state;
-}
-
-#undef VERIFY_STATE_TRANSITION
-
-void ThreadState::SetGCPhase(GCPhase gc_phase) {
-  switch (gc_phase) {
-    case GCPhase::kNone:
-      DCHECK_EQ(gc_phase_, GCPhase::kSweeping);
-      break;
-    case GCPhase::kMarking:
-      DCHECK_EQ(gc_phase_, GCPhase::kNone);
-      break;
-    case GCPhase::kSweeping:
-      DCHECK_EQ(gc_phase_, GCPhase::kMarking);
-      break;
-  }
-  gc_phase_ = gc_phase;
-}
-
-void ThreadState::RunScheduledGC(BlinkGC::StackState stack_state) {
-  DCHECK(CheckThread());
-  if (stack_state != BlinkGC::kNoHeapPointersOnStack)
-    return;
-
-  // If a safe point is entered while initiating a GC, we clearly do
-  // not want to do another as part of that -- the safe point is only
-  // entered after checking if a scheduled GC ought to run first.
-  // Prevent that from happening by marking GCs as forbidden while
-  // one is initiated and later running.
-  if (IsGCForbidden())
-    return;
-
-  switch (GetGCState()) {
-    case kForcedGCForTestingScheduled:
-      forced_scheduled_gc_for_testing_ = true;
-      CollectAllGarbageForTesting();
-      forced_scheduled_gc_for_testing_ = false;
-      break;
-    default:
-      break;
-  }
-}
-
-void ThreadState::AtomicPauseMarkPrologue(
-    BlinkGC::CollectionType collection_type,
-    BlinkGC::StackState stack_state,
-    BlinkGC::MarkingType marking_type,
-    BlinkGC::GCReason reason) {
-  ThreadHeapStatsCollector::EnabledScope mark_prologue_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kAtomicPauseMarkPrologue);
-  EnterAtomicPause();
-  EnterNoAllocationScope();
-  EnterGCForbiddenScope();
-
-  if (HeapPointersOnStackForced()) {
-    stack_state = BlinkGC::kHeapPointersOnStack;
-  }
-
-  if (IsMarkingInProgress()) {
-    // Incremental marking is already in progress. Only update the state
-    // that is necessary to update.
-    SetGCState(kNoGCScheduled);
-    if (base::FeatureList::IsEnabled(
-            blink::features::kBlinkHeapConcurrentMarking)) {
-      // Stop concurrent markers and wait synchronously until they have all
-      // returned.
-      marker_handle_.Cancel();
-    }
-#if DCHECK_IS_ON()
-    MarkingWorklist* marking_worklist = Heap().GetMarkingWorklist();
-    WriteBarrierWorklist* write_barrier_worklist =
-        Heap().GetWriteBarrierWorklist();
-    for (int concurrent_task = WorklistTaskId::ConcurrentThreadBase;
-         concurrent_task < MarkingWorklist::kNumTasks; ++concurrent_task) {
-      DCHECK(marking_worklist->IsLocalEmpty(concurrent_task));
-      DCHECK(write_barrier_worklist->IsLocalEmpty(concurrent_task));
-    }
-#endif  // DCHECK_IS_ON()
-    // Compaction needs to be canceled when incremental marking ends with a
-    // conservative GC.
-    if (stack_state == BlinkGC::kHeapPointersOnStack)
-      Heap().Compaction()->Cancel();
-    DisableIncrementalMarkingBarrier();
-    current_gc_data_.reason = reason;
-    current_gc_data_.stack_state = stack_state;
-    Heap().stats_collector()->UpdateReason(reason);
-  } else {
-    DCHECK(!Heap().Compaction()->IsCompacting());
-    MarkPhasePrologue(collection_type, stack_state, marking_type, reason);
-  }
-
-  if (stack_state == BlinkGC::kNoHeapPointersOnStack) {
-    Heap().FlushNotFullyConstructedObjects();
-  }
-
-  DCHECK(InAtomicMarkingPause());
-  Heap().MakeConsistentForGC();
-  // AtomicPauseMarkPrologue is the common entry point for marking. The
-  // requirement is to lock from roots marking to weakness processing which is
-  // why the lock is taken at the end of the prologue.
-  static_cast<MutexBase&>(ProcessHeap::CrossThreadPersistentMutex()).lock();
-}
-
-void ThreadState::AtomicPauseEpilogue() {
-  if (!IsSweepingInProgress()) {
-    // Sweeping was finished during the atomic pause. Update statistics needs to
-    // run outside of the top-most stats scope.
-    PostSweep();
-  }
-}
-
-void ThreadState::CompleteSweep() {
-  DCHECK(CheckThread());
-  // If we are not in a sweeping phase, there is nothing to do here.
-  if (!IsSweepingInProgress())
-    return;
-
-  // CompleteSweep() can be called recursively if finalizers can allocate
-  // memory and the allocation triggers completeSweep(). This check prevents
-  // the sweeping from being executed recursively.
-  if (SweepForbidden())
-    return;
-
-  {
-    // CompleteSweep may be called during regular mutator execution, from a
-    // task, or from the atomic pause in which the atomic scope has already been
-    // opened.
-    const bool was_in_atomic_pause = in_atomic_pause();
-    if (!was_in_atomic_pause)
-      EnterAtomicPause();
-    ScriptForbiddenScope script_forbidden;
-    SweepForbiddenScope scope(this);
-    ThreadHeapStatsCollector::EnabledScope stats_scope(
-        Heap().stats_collector(), ThreadHeapStatsCollector::kCompleteSweep);
-    // Boost priority of sweeping job to complete ASAP and avoid taking time on
-    // the main thread.
-    if (sweeper_handle_)
-      sweeper_handle_.UpdatePriority(base::TaskPriority::USER_BLOCKING);
-    Heap().CompleteSweep();
-    SynchronizeAndFinishConcurrentSweeping();
-
-    if (!was_in_atomic_pause)
-      LeaveAtomicPause();
-  }
-  NotifySweepDone();
-}
-
-void ThreadState::SynchronizeAndFinishConcurrentSweeping() {
-  DCHECK(CheckThread());
-  DCHECK(IsSweepingInProgress());
-  DCHECK(SweepForbidden());
-
-  // Wait for concurrent sweepers.
-  if (sweeper_handle_)
-    sweeper_handle_.Cancel();
-
-  // Concurrent sweepers may perform some work at the last stage (e.g.
-  // sweeping the last page and preparing finalizers).
-  Heap().InvokeFinalizersOnSweptPages();
-}
-
-namespace {
-
-// Update trace counters with statistics from the current and previous garbage
-// collection cycle. We allow emitting current values here since these values
-// can be useful for inspecting traces.
-void UpdateTraceCounters(const ThreadHeapStatsCollector& stats_collector) {
-  bool gc_tracing_enabled;
-  TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-                                     &gc_tracing_enabled);
-  if (!gc_tracing_enabled)
-    return;
-
-  // Previous garbage collection cycle values.
-  const ThreadHeapStatsCollector::Event& event = stats_collector.previous();
-  const int collection_rate_percent =
-      static_cast<int>(100 * (1.0 - event.live_object_rate));
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-                 "BlinkGC.CollectionRate", collection_rate_percent);
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-                 "BlinkGC.MarkedObjectSizeAtLastCompleteSweepKB",
-                 CappedSizeInKB(event.marked_bytes));
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-                 "BlinkGC.ObjectSizeAtLastGCKB",
-                 CappedSizeInKB(event.object_size_in_bytes_before_sweeping));
-  TRACE_COUNTER1(
-      TRACE_DISABLED_BY_DEFAULT("blink_gc"), "BlinkGC.AllocatedSpaceAtLastGCKB",
-      CappedSizeInKB(event.allocated_space_in_bytes_before_sweeping));
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-                 "BlinkGC.PartitionAllocSizeAtLastGCKB",
-                 CappedSizeInKB(event.partition_alloc_bytes_before_sweeping));
-
-  // Current values.
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-                 "BlinkGC.AllocatedSpaceKB",
-                 CappedSizeInKB(stats_collector.allocated_space_bytes()));
-  size_t allocated_bytes_since_prev_gc =
-      stats_collector.allocated_bytes_since_prev_gc() > 0
-          ? static_cast<size_t>(stats_collector.allocated_bytes_since_prev_gc())
-          : 0;
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-                 "BlinkGC.AllocatedObjectSizeSincePreviousGCKB",
-                 CappedSizeInKB(allocated_bytes_since_prev_gc));
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"),
-                 "PartitionAlloc.TotalSizeOfCommittedPagesKB",
-                 CappedSizeInKB(WTF::Partitions::TotalSizeOfCommittedPages()));
-}
-
-// Update histograms with statistics from the previous garbage collection cycle.
-// Anything that is part of a histogram should have a well-defined lifetime wrt.
-// to a garbage collection cycle.
-void UpdateHistograms(const ThreadHeapStatsCollector::Event& event) {
-  UMA_HISTOGRAM_ENUMERATION("BlinkGC.GCReason", event.reason);
-
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForAtomicPhase", event.atomic_pause_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForAtomicPhaseMarking",
-                      event.atomic_marking_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForGCCycle", event.gc_cycle_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForMarkingRoots",
-                      event.roots_marking_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForIncrementalMarking",
-                      event.incremental_marking_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForMarking.Foreground",
-                      event.foreground_marking_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForMarking.Background",
-                      event.background_marking_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForMarking", event.marking_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForNestedInV8", event.gc_nested_in_v8);
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForSweepingForeground",
-                      event.foreground_sweeping_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForSweepingBackground",
-                      event.background_sweeping_time());
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForSweepingSum", event.sweeping_time());
-  UMA_HISTOGRAM_TIMES(
-      "BlinkGC.TimeForCompleteSweep",
-      event.scope_data[ThreadHeapStatsCollector::kCompleteSweep]);
-  UMA_HISTOGRAM_TIMES(
-      "BlinkGC.TimeForInvokingPreFinalizers",
-      event.scope_data[ThreadHeapStatsCollector::kInvokePreFinalizers]);
-  UMA_HISTOGRAM_TIMES(
-      "BlinkGC.TimeForHeapCompaction",
-      event.scope_data[ThreadHeapStatsCollector::kAtomicPauseCompaction]);
-  UMA_HISTOGRAM_TIMES(
-      "BlinkGC.TimeForGlobalWeakProcessing",
-      event.scope_data[ThreadHeapStatsCollector::kMarkWeakProcessing]);
-
-  base::TimeDelta marking_duration = event.foreground_marking_time();
-  constexpr size_t kMinMarkedBytesForReportingThroughput = 1024 * 1024;
-  if (base::TimeTicks::IsHighResolution() &&
-      (event.marked_bytes > kMinMarkedBytesForReportingThroughput) &&
-      !marking_duration.is_zero()) {
-    DCHECK_GT(marking_duration.InMillisecondsF(), 0.0);
-    const int main_thread_marking_throughput_mb_per_s = static_cast<int>(
-        static_cast<double>(event.marked_bytes) /
-        marking_duration.InMillisecondsF() * 1000 / 1024 / 1024);
-    UMA_HISTOGRAM_COUNTS_100000("BlinkGC.MainThreadMarkingThroughput",
-                                main_thread_marking_throughput_mb_per_s);
-  }
-
-  DEFINE_STATIC_LOCAL(
-      CustomCountHistogram, object_size_freed_by_heap_compaction,
-      ("BlinkGC.ObjectSizeFreedByHeapCompaction", 1, 4 * 1024 * 1024, 50));
-  if (event.compaction_recorded_events) {
-    object_size_freed_by_heap_compaction.Count(
-        CappedSizeInKB(event.compaction_freed_bytes));
-  }
-
-  DEFINE_STATIC_LOCAL(CustomCountHistogram, object_size_before_gc_histogram,
-                      ("BlinkGC.ObjectSizeBeforeGC", 1, 4 * 1024 * 1024, 50));
-  object_size_before_gc_histogram.Count(
-      CappedSizeInKB(event.object_size_in_bytes_before_sweeping));
-  DEFINE_STATIC_LOCAL(CustomCountHistogram, object_size_after_gc_histogram,
-                      ("BlinkGC.ObjectSizeAfterGC", 1, 4 * 1024 * 1024, 50));
-  object_size_after_gc_histogram.Count(CappedSizeInKB(event.marked_bytes));
-
-  const int collection_rate_percent =
-      static_cast<int>(100 * (1.0 - event.live_object_rate));
-  DEFINE_STATIC_LOCAL(CustomCountHistogram, collection_rate_histogram,
-                      ("BlinkGC.CollectionRate", 1, 100, 20));
-  collection_rate_histogram.Count(collection_rate_percent);
-
-  // Per GCReason metrics.
-  switch (event.reason) {
-#define COUNT_BY_GC_REASON(reason)                                        \
-  case BlinkGC::GCReason::k##reason: {                                    \
-    UMA_HISTOGRAM_TIMES("BlinkGC.AtomicPhaseMarking_" #reason,            \
-                        event.atomic_marking_time());                     \
-    DEFINE_STATIC_LOCAL(CustomCountHistogram,                             \
-                        collection_rate_reason_histogram,                 \
-                        ("BlinkGC.CollectionRate_" #reason, 1, 100, 20)); \
-    collection_rate_reason_histogram.Count(collection_rate_percent);      \
-    break;                                                                \
-  }
-
-    COUNT_BY_GC_REASON(ForcedGCForTesting)
-    COUNT_BY_GC_REASON(ThreadTerminationGC)
-    COUNT_BY_GC_REASON(UnifiedHeapGC)
-    COUNT_BY_GC_REASON(UnifiedHeapForMemoryReductionGC)
-    COUNT_BY_GC_REASON(UnifiedHeapForcedForTestingGC)
-
-#undef COUNT_BY_GC_REASON
-  }
-}
-
-}  // namespace
-
-void ThreadState::NotifySweepDone() {
-  DCHECK(CheckThread());
-  SetGCPhase(GCPhase::kNone);
-  if (!in_atomic_pause()) {
-    PostSweep();
-  }
-
-  ThreadState::StatisticsCollector(this).Verify();
-}
-
-void ThreadState::PostSweep() {
-  DCHECK(!in_atomic_pause());
-  DCHECK(!IsSweepingInProgress());
-
-  Heap().stats_collector()->NotifySweepingCompleted();
-
-  if (IsMainThread())
-    UpdateHistograms(Heap().stats_collector()->previous());
-  // Emit trace counters for all threads.
-  UpdateTraceCounters(*Heap().stats_collector());
-}
-
-void ThreadState::SafePoint(BlinkGC::StackState stack_state) {
-  DCHECK(CheckThread());
-
-  RunScheduledGC(stack_state);
-}
-
-using PushAllRegistersCallback = void (*)(ThreadState*, intptr_t*);
-extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback);
-
-// static
-void ThreadState::VisitStackAfterPushingRegisters(ThreadState* state,
-                                                  intptr_t* end_of_stack) {
-  state->VisitStack(static_cast<MarkingVisitor*>(state->CurrentVisitor()),
-                    reinterpret_cast<Address*>(end_of_stack));
-}
-
-void ThreadState::PushRegistersAndVisitStack() {
-  DCHECK(CheckThread());
-  DCHECK(IsGCForbidden());
-  DCHECK_EQ(current_gc_data_.stack_state, BlinkGC::kHeapPointersOnStack);
-  // Visit registers, native stack, and asan fake stack.
-  PushAllRegisters(this, ThreadState::VisitStackAfterPushingRegisters);
-  // For builds that use safe stack, also visit the unsafe stack.
-  VisitUnsafeStack(static_cast<MarkingVisitor*>(CurrentVisitor()));
-}
-
-void ThreadState::InvokePreFinalizers() {
-  DCHECK(CheckThread());
-  DCHECK(!SweepForbidden());
-
-  ThreadHeapStatsCollector::Scope stats_scope(
-      Heap().stats_collector(), ThreadHeapStatsCollector::kInvokePreFinalizers);
-  SweepForbiddenScope sweep_forbidden(this);
-  // Pre finalizers are forbidden from allocating objects
-  NoAllocationScope no_allocation_scope(this);
-
-  // Call the prefinalizers in the opposite order to their registration.
-  //
-  // Deque does not support modification during iteration, so
-  // copy items first.
-  //
-  // The prefinalizer callback wrapper returns |true| when its associated
-  // object is unreachable garbage and the prefinalizer callback has run.
-  // The registered prefinalizer entry must then be removed and deleted.
-  LivenessBroker broker = internal::LivenessBrokerFactory::Create();
-  Deque<PreFinalizer> remaining_ordered_pre_finalizers;
-  for (auto rit = ordered_pre_finalizers_.rbegin();
-       rit != ordered_pre_finalizers_.rend(); ++rit) {
-    const PreFinalizer& pre_finalizer = *rit;
-    if (!(pre_finalizer.second)(broker, pre_finalizer.first))
-      remaining_ordered_pre_finalizers.push_front(pre_finalizer);
-  }
-
-  ordered_pre_finalizers_ = std::move(remaining_ordered_pre_finalizers);
-}
-
-// static
-AtomicEntryFlag ThreadState::incremental_marking_flag_;
-
-void ThreadState::EnableIncrementalMarkingBarrier() {
-  CHECK(!IsIncrementalMarking());
-  incremental_marking_flag_.Enter();
-  SetIncrementalMarking(true);
-}
-
-void ThreadState::DisableIncrementalMarkingBarrier() {
-  CHECK(IsIncrementalMarking());
-  incremental_marking_flag_.Exit();
-  SetIncrementalMarking(false);
-}
-
-void ThreadState::IncrementalMarkingStartForTesting() {
-  // kIncrementalGCScheduled state requires sweeping to not be in progress.
-  CompleteSweep();
-  SetGCState(kIncrementalGCScheduled);
-  IncrementalMarkingStart(BlinkGC::GCReason::kForcedGCForTesting);
-}
-
-void ThreadState::IncrementalMarkingStart(BlinkGC::GCReason reason) {
-  DCHECK(!IsGCForbidden());
-  DCHECK_EQ(kIncrementalGCScheduled, GetGCState());
-
-  VLOG(2) << "[state:" << this << "] "
-          << "IncrementalMarking: Start";
-  DCHECK(!IsMarkingInProgress());
-  // Sweeping is performed in driver functions.
-  DCHECK(!IsSweepingInProgress());
-  Heap().stats_collector()->NotifyMarkingStarted(
-      BlinkGC::CollectionType::kMajor, reason, IsForcedGC(reason));
-  {
-    ThreadHeapStatsCollector::EnabledScope stats_scope(
-        Heap().stats_collector(),
-        ThreadHeapStatsCollector::kIncrementalMarkingStartMarking, "reason",
-        BlinkGC::ToString(reason));
-    AtomicPauseScope atomic_pause_scope(this);
-    ScriptForbiddenScope script_forbidden_scope;
-    MarkPhasePrologue(BlinkGC::CollectionType::kMajor,
-                      BlinkGC::kNoHeapPointersOnStack,
-                      BlinkGC::kIncrementalAndConcurrentMarking, reason);
-    {
-      MutexLocker persistent_lock(ProcessHeap::CrossThreadPersistentMutex());
-      MarkPhaseVisitRoots();
-    }
-    DCHECK(Heap().GetV8ReferencesWorklist()->IsGlobalEmpty());
-    EnableIncrementalMarkingBarrier();
-    if (base::FeatureList::IsEnabled(
-            blink::features::kBlinkHeapConcurrentMarking)) {
-      current_gc_data_.visitor->FlushMarkingWorklists();
-      static_assert(
-          MarkingWorklist::kNumTasks == WriteBarrierWorklist::kNumTasks,
-          "Marking worklist and write-barrier worklist should be the "
-          "same size");
-      last_concurrently_marked_bytes_ = 0;
-      last_concurrently_marked_bytes_update_ = base::TimeTicks::Now();
-      concurrent_marking_priority_increased_ = false;
-      ScheduleConcurrentMarking();
-    }
-    SetGCState(kIncrementalMarkingStepScheduled);
-    DCHECK(IsMarkingInProgress());
-  }
-}
-
-void ThreadState::IncrementalMarkingStep(BlinkGC::StackState stack_state) {
-  DCHECK(IsMarkingInProgress());
-  DCHECK_EQ(kIncrementalMarkingStepScheduled, GetGCState());
-
-  ThreadHeapStatsCollector::EnabledScope stats_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kIncrementalMarkingStep);
-  VLOG(2) << "[state:" << this << "] "
-          << "IncrementalMarking: Step "
-          << "Reason: " << BlinkGC::ToString(current_gc_data_.reason);
-  AtomicPauseScope atomic_pause_scope(this);
-  ScriptForbiddenScope script_forbidden_scope;
-  if (stack_state == BlinkGC::kNoHeapPointersOnStack) {
-    Heap().FlushNotFullyConstructedObjects();
-  }
-
-  bool complete;
-  if (skip_incremental_marking_for_testing_) {
-    complete = true;
-    skip_incremental_marking_for_testing_ = false;
-  } else {
-    complete = MarkPhaseAdvanceMarking(
-        marking_scheduling_->GetNextIncrementalStepDurationForTask(
-            Heap().stats_collector()->object_size_in_bytes()),
-        EphemeronProcessing::kPartialProcessing);
-  }
-
-  if (base::FeatureList::IsEnabled(
-          blink::features::kBlinkHeapConcurrentMarking)) {
-    complete = ConcurrentMarkingStep() && complete;
-  }
-
-  if (complete) {
-    if (IsUnifiedGCMarkingInProgress()) {
-      // If there are no more objects to mark for unified garbage collections
-      // just bail out of helping incrementally using tasks. V8 will drive
-      // further marking if new objects are discovered. Otherwise, just process
-      // the rest in the atomic pause.
-      DCHECK(IsUnifiedGCMarkingInProgress());
-      SetGCState(kIncrementalMarkingStepPaused);
-    } else {
-      SetGCState(kIncrementalMarkingFinalizeScheduled);
-    }
-  } else {
-    SetGCState(kIncrementalMarkingStepScheduled);
-  }
-  DCHECK(IsMarkingInProgress());
-}
-
-bool ThreadState::ConcurrentMarkingStep() {
-  current_gc_data_.visitor->FlushMarkingWorklists();
-  if (Heap().HasWorkForConcurrentMarking()) {
-    // Notifies the scheduler that max concurrency might have increased.
-    // This will adjust the number of markers if necessary.
-    marker_handle_.NotifyConcurrencyIncrease();
-    if (!concurrent_marking_priority_increased_) {
-      // If concurrent tasks aren't executed, it might delay GC finalization.
-      // As long as GC is active so is the write barrier, which incurs a
-      // performance cost. Marking is estimated to take overall
-      // |MarkingSchedulingOracle::kEstimatedMarkingTimeMs| (500ms). If
-      // concurrent marking tasks have not reported any progress (i.e. the
-      // concurrently marked bytes count as not changed) in over
-      // |kMarkingScheduleRatioBeforeConcurrentPriorityIncrease| (50%) of
-      // that expected duration, we increase the concurrent task priority
-      // for the duration of the current GC. This is meant to prevent the
-      // GC from exceeding it's expected end time.
-      size_t current_concurrently_marked_bytes_ =
-          marking_scheduling_->GetConcurrentlyMarkedBytes();
-      if (current_concurrently_marked_bytes_ >
-          last_concurrently_marked_bytes_) {
-        last_concurrently_marked_bytes_ = current_concurrently_marked_bytes_;
-        last_concurrently_marked_bytes_update_ = base::TimeTicks::Now();
-      } else if ((base::TimeTicks::Now() -
-                  last_concurrently_marked_bytes_update_)
-                     .InMilliseconds() >
-                 kMarkingScheduleRatioBeforeConcurrentPriorityIncrease *
-                     MarkingSchedulingOracle::kEstimatedMarkingTimeMs) {
-        marker_handle_.UpdatePriority(base::TaskPriority::USER_BLOCKING);
-        concurrent_marking_priority_increased_ = true;
-      }
-    }
-    return false;
-  }
-  return !marker_handle_.IsActive();
-}
-
-void ThreadState::IncrementalMarkingFinalize() {
-  DCHECK(IsMarkingInProgress());
-  DCHECK(!IsUnifiedGCMarkingInProgress());
-  DCHECK_EQ(kIncrementalMarkingFinalizeScheduled, GetGCState());
-
-  ThreadHeapStatsCollector::EnabledScope stats_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kIncrementalMarkingFinalize);
-  VLOG(2) << "[state:" << this << "] "
-          << "IncrementalMarking: Finalize "
-          << "Reason: " << BlinkGC::ToString(current_gc_data_.reason);
-  // Call into the regular bottleneck instead of the internal version to get
-  // UMA accounting and allow follow up GCs if necessary.
-  DCHECK_EQ(BlinkGC::kIncrementalAndConcurrentMarking,
-            current_gc_data_.marking_type);
-  CollectGarbage(current_gc_data_.collection_type,
-                 BlinkGC::kNoHeapPointersOnStack, current_gc_data_.marking_type,
-                 BlinkGC::kConcurrentAndLazySweeping, current_gc_data_.reason);
-}
-
-bool ThreadState::FinishIncrementalMarkingIfRunning(
-    BlinkGC::CollectionType collection_type,
-    BlinkGC::StackState stack_state,
-    BlinkGC::MarkingType marking_type,
-    BlinkGC::SweepingType sweeping_type,
-    BlinkGC::GCReason reason) {
-  if (IsMarkingInProgress()) {
-    // TODO(mlippautz): Consider improving this mechanism as it will pull in
-    // finalization of V8 upon Oilpan GCs during a unified GC. Alternative
-    // include either breaking up the GCs or avoiding the call in first place.
-    if (IsUnifiedGCMarkingInProgress()) {
-      unified_heap_controller()->FinalizeTracing();
-    } else {
-      RunAtomicPause(collection_type, stack_state, marking_type, sweeping_type,
-                     reason);
-    }
-    return true;
-  }
-  return false;
-}
-
-void ThreadState::RestartIncrementalMarkingIfPaused() {
-  if (GetGCState() != ThreadState::kIncrementalMarkingStepPaused)
-    return;
-  SetGCState(ThreadState::kIncrementalMarkingStepScheduled);
-  incremental_marking_scheduler_->Restart();
-}
-
-void ThreadState::CollectGarbage(BlinkGC::CollectionType collection_type,
-                                 BlinkGC::StackState stack_state,
-                                 BlinkGC::MarkingType marking_type,
-                                 BlinkGC::SweepingType sweeping_type,
-                                 BlinkGC::GCReason reason) {
-  // Nested garbage collection invocations are not supported.
-  CHECK(!IsGCForbidden());
-  // Garbage collection during sweeping is not supported. This can happen when
-  // finalizers trigger garbage collections.
-  if (SweepForbidden())
-    return;
-
-  base::TimeTicks start_total_collect_garbage_time = base::TimeTicks::Now();
-  RUNTIME_CALL_TIMER_SCOPE_IF_ISOLATE_EXISTS(
-      GetIsolate(), RuntimeCallStats::CounterId::kCollectGarbage);
-
-  const bool was_incremental_marking = FinishIncrementalMarkingIfRunning(
-      collection_type, stack_state, marking_type, sweeping_type, reason);
-
-  // We don't want floating garbage for the specific garbage collection types
-  // mentioned below. In this case we will follow up with a regular full
-  // garbage collection.
-  const bool should_do_full_gc =
-      !no_followup_full_gc_for_testing_ &&
-      (!was_incremental_marking ||
-       reason == BlinkGC::GCReason::kForcedGCForTesting ||
-       reason == BlinkGC::GCReason::kThreadTerminationGC);
-  no_followup_full_gc_for_testing_ = false;
-  if (should_do_full_gc) {
-    CompleteSweep();
-    SetGCState(kNoGCScheduled);
-    Heap().stats_collector()->NotifyMarkingStarted(collection_type, reason,
-                                                   IsForcedGC(reason));
-    RunAtomicPause(collection_type, stack_state, marking_type, sweeping_type,
-                   reason);
-  }
-
-  const base::TimeDelta total_collect_garbage_time =
-      base::TimeTicks::Now() - start_total_collect_garbage_time;
-  UMA_HISTOGRAM_TIMES("BlinkGC.TimeForTotalCollectGarbage",
-                      total_collect_garbage_time);
-
-#define COUNT_BY_GC_REASON(reason)                                     \
-  case BlinkGC::GCReason::k##reason: {                                 \
-    UMA_HISTOGRAM_TIMES("BlinkGC.TimeForTotalCollectGarbage_" #reason, \
-                        total_collect_garbage_time);                   \
-    break;                                                             \
-  }
-
-  switch (reason) {
-    COUNT_BY_GC_REASON(ForcedGCForTesting)
-    COUNT_BY_GC_REASON(ThreadTerminationGC)
-    COUNT_BY_GC_REASON(UnifiedHeapGC)
-    COUNT_BY_GC_REASON(UnifiedHeapForMemoryReductionGC)
-    COUNT_BY_GC_REASON(UnifiedHeapForcedForTestingGC)
-  }
-#undef COUNT_BY_GC_REASON
-
-  VLOG(1) << "[state:" << this << "]"
-          << " CollectGarbage: time: " << std::setprecision(2)
-          << total_collect_garbage_time.InMillisecondsF() << "ms"
-          << " stack: " << BlinkGC::ToString(stack_state)
-          << " marking: " << BlinkGC::ToString(marking_type)
-          << " sweeping: " << BlinkGC::ToString(sweeping_type)
-          << " reason: " << BlinkGC::ToString(reason);
-}
-
-void ThreadState::AtomicPauseMarkRoots(BlinkGC::StackState stack_state,
-                                       BlinkGC::MarkingType marking_type,
-                                       BlinkGC::GCReason reason) {
-  ThreadHeapStatsCollector::EnabledScope advance_tracing_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kAtomicPauseMarkRoots);
-  MarkPhaseVisitRoots();
-  MarkPhaseVisitNotFullyConstructedObjects();
-}
-
-void ThreadState::AtomicPauseMarkTransitiveClosure() {
-  ThreadHeapStatsCollector::EnabledScope advance_tracing_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kAtomicPauseMarkTransitiveClosure);
-  // base::TimeTicks::Now() + base::TimeDelta::Max() == base::TimeTicks::Max()
-  CHECK(MarkPhaseAdvanceMarking(base::TimeDelta::Max(),
-                                EphemeronProcessing::kFullProcessing));
-}
-
-void ThreadState::AtomicPauseMarkEpilogue(BlinkGC::MarkingType marking_type) {
-  ThreadHeapStatsCollector::EnabledScope stats_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kAtomicPauseMarkEpilogue);
-  MarkPhaseEpilogue(marking_type);
-  LeaveGCForbiddenScope();
-  LeaveNoAllocationScope();
-  LeaveAtomicPause();
-  static_cast<MutexBase&>(ProcessHeap::CrossThreadPersistentMutex()).unlock();
-}
-
-void ThreadState::AtomicPauseSweepAndCompact(
-    BlinkGC::CollectionType collection_type,
-    BlinkGC::MarkingType marking_type,
-    BlinkGC::SweepingType sweeping_type) {
-  ThreadHeapStatsCollector::EnabledScope stats(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kAtomicPauseSweepAndCompact);
-  AtomicPauseScope atomic_pause_scope(this);
-  ScriptForbiddenScope script_forbidden_scope;
-
-  DCHECK(InAtomicMarkingPause());
-  DCHECK(CheckThread());
-  Heap().PrepareForSweep(collection_type);
-
-  // We have to set the GCPhase to Sweeping before calling pre-finalizers
-  // to disallow a GC during the pre-finalizers.
-  SetGCPhase(GCPhase::kSweeping);
-
-  InvokePreFinalizers();
-
-  if (collection_type == BlinkGC::CollectionType::kMajor) {
-    // Slots filtering requires liveness information which is only present
-    // before sweeping any arena.
-    ThreadHeapStatsCollector::Scope stats_scope(
-        Heap().stats_collector(),
-        ThreadHeapStatsCollector::kAtomicPauseCompaction);
-    Heap().Compaction()->FilterNonLiveSlots();
-  }
-
-  // Last point where all mark bits are present.
-  VerifyMarking(marking_type);
-
-  if (collection_type == BlinkGC::CollectionType::kMajor) {
-    // Any sweep compaction must happen after pre-finalizers, as it will
-    // finalize dead objects in compactable arenas (e.g., backing stores
-    // for container objects.)
-    //
-    // As per-contract for prefinalizers, those finalizable objects must
-    // still be accessible when the prefinalizer runs, hence we cannot
-    // schedule compaction until those have run.
-    SweepForbiddenScope scope(this);
-    NoAllocationScope no_allocation_scope(this);
-    Heap().Compact();
-    Heap().DestroyCompactionWorklists();
-  }
-
-#if defined(ADDRESS_SANITIZER)
-  PoisonUnmarkedObjects();
-#endif  // ADDRESS_SANITIZER
-  DCHECK(IsSweepingInProgress());
-  if (sweeping_type == BlinkGC::kEagerSweeping) {
-    // Eager sweeping should happen only in testing.
-    CompleteSweep();
-  } else {
-    DCHECK(sweeping_type == BlinkGC::kConcurrentAndLazySweeping);
-    // The default behavior is concurrent and lazy sweeping.
-    ScheduleConcurrentAndLazySweep();
-  }
-}
-
-#if defined(ADDRESS_SANITIZER)
-namespace {
-
-// Visitor unpoisoning all handles. Unpoisoning is required when dead objects
-// are poisoned until they are later on processed.
-//
-// The raceful operations are:
-// a. Running destructor that clears the handle.
-// b. Running a stand-alone V8 GC (e.g. Scavenger) that clears the handle.
-//
-// Both operations run on the main thread and not concurrent.
-class UnpoisonHandlesVisitor final
-    : public v8::PersistentHandleVisitor,
-      public v8::EmbedderHeapTracer::TracedGlobalHandleVisitor {
- public:
-  explicit UnpoisonHandlesVisitor(ThreadHeap* heap) : heap_(heap) {}
-
-  void VisitPersistentHandle(v8::Persistent<v8::Value>* value,
-                             uint16_t class_id) final {
-    VisitSlot(value, sizeof(v8::Persistent<v8::Value>));
-  }
-
-  void VisitTracedGlobalHandle(const v8::TracedGlobal<v8::Value>&) final {
-    CHECK(false) << "Blink does not use v8::TracedGlobal.";
-  }
-
-  void VisitTracedReference(const v8::TracedReference<v8::Value>& value) final {
-    // TODO(mlippautz): Avoid const_cast after changing the API to allow
-    // modificaton of the handle.
-    VisitSlot(&const_cast<v8::TracedReference<v8::Value>&>(value),
-              sizeof(v8::TracedReference<v8::Value>));
-  }
-
- private:
-  void VisitSlot(void* address, size_t size) {
-    // Filter slots not on the heap.
-    if (!heap_->LookupPageForAddress(reinterpret_cast<Address>(address)))
-      return;
-
-    HeapObjectHeader* header = HeapObjectHeader::FromInnerAddress(address);
-    if (!header->IsMarked()) {
-      DCHECK(ASAN_REGION_IS_POISONED(address, size));
-      ASAN_UNPOISON_MEMORY_REGION(address, size);
-    }
-  }
-
-  ThreadHeap* const heap_;
-};
-
-}  // namespace
-
-void ThreadState::PoisonUnmarkedObjects() {
-  {
-    // This lock must be held because other threads may access cross-thread
-    // persistents and should not observe them in a poisoned state.
-    MutexLocker lock(ProcessHeap::CrossThreadPersistentMutex());
-
-    Heap().PoisonUnmarkedObjects();
-
-    // CrossThreadPersistents in unmarked objects may be accessed from other
-    // threads (e.g. in CrossThreadPersistentRegion::ShouldTracePersistent) and
-    // that would be fine.
-    ProcessHeap::GetCrossThreadPersistentRegion()
-        .UnpoisonCrossThreadPersistents();
-    ProcessHeap::GetCrossThreadWeakPersistentRegion()
-        .UnpoisonCrossThreadPersistents();
-  }
-
-  // Similarly, unmarked object may contain handles to V8 that may be accessed
-  // (cleared) until the destructors are run.
-  if (GetIsolate()) {
-    UnpoisonHandlesVisitor visitor(&Heap());
-    GetIsolate()->VisitHandlesWithClassIds(&visitor);
-    unified_heap_controller()->IterateTracedGlobalHandles(&visitor);
-  }
-}
-#endif  // ADDRESS_SANITIZER
-
-void ThreadState::RunAtomicPause(BlinkGC::CollectionType collection_type,
-                                 BlinkGC::StackState stack_state,
-                                 BlinkGC::MarkingType marking_type,
-                                 BlinkGC::SweepingType sweeping_type,
-                                 BlinkGC::GCReason reason) {
-  // Legacy scope that is used to add stand-alone Oilpan GCs to DevTools
-  // timeline.
-  TRACE_EVENT1("blink_gc,devtools.timeline", "BlinkGC.AtomicPhase", "forced",
-               IsForcedGC(reason));
-
-  AtomicPauseMarkPrologue(collection_type, stack_state, marking_type, reason);
-  AtomicPauseMarkRoots(stack_state, marking_type, reason);
-  AtomicPauseMarkTransitiveClosure();
-  AtomicPauseMarkEpilogue(marking_type);
-  AtomicPauseSweepAndCompact(collection_type, marking_type, sweeping_type);
-  AtomicPauseEpilogue();
-}
-
-namespace {
-
-MarkingVisitor::MarkingMode GetMarkingMode(bool should_compact) {
-  return (should_compact) ? MarkingVisitor::kGlobalMarkingWithCompaction
-                          : MarkingVisitor::kGlobalMarking;
-}
-
-}  // namespace
-
-void ThreadState::MarkPhasePrologue(BlinkGC::CollectionType collection_type,
-                                    BlinkGC::StackState stack_state,
-                                    BlinkGC::MarkingType marking_type,
-                                    BlinkGC::GCReason reason) {
-  SetGCPhase(GCPhase::kMarking);
-
-  ThreadState::StatisticsCollector(this).Verify();
-
-  const bool compaction_enabled =
-      Heap().Compaction()->ShouldCompact(stack_state, marking_type, reason);
-
-  Heap().SetupWorklists(compaction_enabled);
-
-  if (compaction_enabled) {
-    Heap().Compaction()->Initialize(this);
-  }
-
-#if BUILDFLAG(BLINK_HEAP_YOUNG_GENERATION)
-  if (collection_type == BlinkGC::CollectionType::kMajor) {
-    // Unmark heap before doing major collection cycle.
-    Heap().Unmark();
-  }
-#endif
-
-  current_gc_data_.reason = reason;
-  current_gc_data_.collection_type = collection_type;
-  current_gc_data_.visitor =
-      IsUnifiedGCMarkingInProgress()
-          ? std::make_unique<UnifiedHeapMarkingVisitor>(
-                this, GetMarkingMode(compaction_enabled), GetIsolate())
-          : std::make_unique<MarkingVisitor>(
-                this, GetMarkingMode(compaction_enabled));
-  current_gc_data_.stack_state = stack_state;
-  current_gc_data_.marking_type = marking_type;
-
-  marking_scheduling_ = std::make_unique<MarkingSchedulingOracle>();
-}
-
-void ThreadState::MarkPhaseVisitRoots() {
-  ThreadHeapStatsCollector::EnabledScope stats_scope(
-      Heap().stats_collector(), ThreadHeapStatsCollector::kVisitRoots);
-
-  Visitor* visitor = current_gc_data_.visitor.get();
-
-  VisitPersistents(visitor);
-
-  if (current_gc_data_.stack_state == BlinkGC::kHeapPointersOnStack) {
-    ThreadHeapStatsCollector::Scope stack_stats_scope(
-        Heap().stats_collector(), ThreadHeapStatsCollector::kVisitStackRoots);
-    PushRegistersAndVisitStack();
-  }
-
-  // Visit remembered sets (card tables) for minor collections.
-  if (current_gc_data_.collection_type == BlinkGC::CollectionType::kMinor) {
-    VisitRememberedSets(static_cast<MarkingVisitor*>(visitor));
-  }
-}
-
-bool ThreadState::MarkPhaseAdvanceMarkingBasedOnSchedule(
-    base::TimeDelta max_deadline,
-    EphemeronProcessing ephemeron_processing) {
-  return MarkPhaseAdvanceMarking(
-      std::min(max_deadline,
-               marking_scheduling_->GetNextIncrementalStepDurationForTask(
-                   Heap().stats_collector()->object_size_in_bytes())),
-      ephemeron_processing);
-}
-
-bool ThreadState::MarkPhaseAdvanceMarking(
-    base::TimeDelta deadline,
-    EphemeronProcessing ephemeron_processing) {
-  MarkingVisitor* visitor = current_gc_data_.visitor.get();
-  ThreadHeapStatsCollector::EnabledScope deadline_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kIncrementalMarkingWithDeadline, "deadline_ms",
-      deadline.InMillisecondsF());
-  const bool finished = Heap().AdvanceMarking(
-      reinterpret_cast<MarkingVisitor*>(visitor),
-      base::TimeTicks::Now() + deadline, ephemeron_processing);
-  // visitor->marked_bytes() can also include bytes marked during roots
-  // visitation which is not counted in worklist_processing_time_foreground.
-  // Since the size of the roots is usually small relative to the size of
-  // the object graph, this is fine.
-  marking_scheduling_->UpdateIncrementalMarkingStats(
-      visitor->marked_bytes(),
-      Heap().stats_collector()->worklist_processing_time_foreground(),
-      Heap().stats_collector()->flushing_v8_references_time());
-  return finished;
-}
-
-bool ThreadState::IsVerifyMarkingEnabled() const {
-  bool should_verify_marking = base::FeatureList::IsEnabled(
-      blink::features::kBlinkHeapIncrementalMarkingStress);
-#if BUILDFLAG(BLINK_HEAP_VERIFICATION)
-  should_verify_marking = (disable_heap_verification_scope_ == 0);
-#endif  // BLINK_HEAP_VERIFICATION
-  return should_verify_marking;
-}
-
-void ThreadState::MarkPhaseVisitNotFullyConstructedObjects() {
-  Heap().MarkNotFullyConstructedObjects(
-      reinterpret_cast<MarkingVisitor*>(current_gc_data_.visitor.get()));
-}
-
-void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) {
-  MarkingVisitor* visitor = current_gc_data_.visitor.get();
-  {
-    ProcessHeap::CrossThreadPersistentMutex().AssertAcquired();
-    VisitWeakPersistents(visitor);
-    Heap().WeakProcessing(visitor);
-  }
-  Heap().DestroyMarkingWorklists(current_gc_data_.stack_state);
-
-  incremental_marking_scheduler_->Cancel();
-
-  current_gc_data_.visitor->FlushCompactionWorklists();
-  current_gc_data_.visitor.reset();
-
-  Heap().stats_collector()->NotifyMarkingCompleted(
-      marking_scheduling_->GetOverallMarkedBytes());
-  marking_scheduling_.reset();
-
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, total_object_space_histogram,
-      ("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, 50));
-  total_object_space_histogram.Count(
-      CappedSizeInKB(ProcessHeap::TotalAllocatedObjectSize()));
-  DEFINE_THREAD_SAFE_STATIC_LOCAL(
-      CustomCountHistogram, total_allocated_space_histogram,
-      ("BlinkGC.TotalAllocatedSpace", 0, 4 * 1024 * 1024, 50));
-  total_allocated_space_histogram.Count(
-      CappedSizeInKB(ProcessHeap::TotalAllocatedSpace()));
-}
-
-void ThreadState::VerifyMarking(BlinkGC::MarkingType marking_type) {
-  if (IsVerifyMarkingEnabled())
-    Heap().VerifyMarking();
-}
-
-void ThreadState::CollectGarbageForTesting(
-    BlinkGC::CollectionType collection_type,
-    BlinkGC::StackState stack_state,
-    BlinkGC::MarkingType marking_type,
-    BlinkGC::SweepingType sweeping_type,
-    BlinkGC::GCReason reason) {
-  CollectGarbage(collection_type, stack_state, marking_type, sweeping_type,
-                 reason);
-}
-
-void ThreadState::CollectAllGarbageForTesting(BlinkGC::StackState stack_state) {
-  // We need to run multiple GCs to collect a chain of persistent handles.
-  size_t previous_live_objects = 0;
-  for (int i = 0; i < 5; ++i) {
-    if (isolate_) {
-      unified_heap_controller()->GarbageCollectionForTesting(
-          stack_state == BlinkGC::kNoHeapPointersOnStack
-              ? v8::EmbedderHeapTracer::EmbedderStackState::kNoHeapPointers
-              : v8::EmbedderHeapTracer::EmbedderStackState::
-                    kMayContainHeapPointers);
-    } else {
-      CollectGarbage(BlinkGC::CollectionType::kMajor, stack_state,
-                     BlinkGC::kAtomicMarking, BlinkGC::kEagerSweeping,
-                     BlinkGC::GCReason::kForcedGCForTesting);
-    }
-    const size_t live_objects =
-        Heap().stats_collector()->previous().marked_bytes;
-    if (live_objects == previous_live_objects)
-      break;
-    previous_live_objects = live_objects;
-  }
-}
-
-void ThreadState::EnableCompactionForNextGCForTesting() {
-  Heap().Compaction()->EnableCompactionForNextGCForTesting();
-}
-
-void ThreadState::ScheduleConcurrentMarking() {
-  DCHECK(base::FeatureList::IsEnabled(
-      blink::features::kBlinkHeapConcurrentMarking));
-
-  marker_handle_ = base::PostJob(
-      FROM_HERE, {base::TaskPriority::USER_VISIBLE},
-      ConvertToBaseRepeatingCallback(
-          WTF::CrossThreadBindRepeating(&ThreadState::PerformConcurrentMark,
-                                        WTF::CrossThreadUnretained(this))),
-      ConvertToBaseRepeatingCallback(WTF::CrossThreadBindRepeating(
-          [](ThreadState* state, size_t active_worker_count) -> size_t {
-            // We need to account for local segments in addition to
-            // ConcurrentMarkingGlobalWorkSize().
-            return std::min<size_t>(
-                state->Heap().ConcurrentMarkingGlobalWorkSize() +
-                    active_worker_count,
-                MarkingWorklist::kNumTasks -
-                    WorklistTaskId::ConcurrentThreadBase);
-          },
-          WTF::CrossThreadUnretained(this))));
-}
-
-void ThreadState::PerformConcurrentMark(base::JobDelegate* job) {
-  VLOG(2) << "[state:" << this << "] [threadid:" << CurrentThread() << "] "
-          << "ConcurrentMark";
-  ThreadHeapStatsCollector::EnabledConcurrentScope stats_scope(
-      Heap().stats_collector(),
-      ThreadHeapStatsCollector::kConcurrentMarkingStep);
-
-  if (!Heap().HasWorkForConcurrentMarking())
-    return;
-
-  uint8_t task_id = job->GetTaskId() + 1;
-
-  std::unique_ptr<ConcurrentMarkingVisitor> concurrent_visitor =
-      IsUnifiedGCMarkingInProgress()
-          ? std::make_unique<ConcurrentUnifiedHeapMarkingVisitor>(
-                this, GetMarkingMode(Heap().Compaction()->IsCompacting()),
-                GetIsolate(), task_id)
-          : std::make_unique<ConcurrentMarkingVisitor>(
-                this, GetMarkingMode(Heap().Compaction()->IsCompacting()),
-                task_id);
-
-  Heap().AdvanceConcurrentMarking(concurrent_visitor.get(), job,
-                                  marking_scheduling_.get());
-
-  marking_scheduling_->AddConcurrentlyMarkedBytes(
-      concurrent_visitor->RecentlyMarkedBytes());
-
-  concurrent_visitor->FlushWorklists();
-}
-
-void ThreadState::NotifyGarbageCollection(v8::GCType type,
-                                          v8::GCCallbackFlags flags) {
-  if (!IsGCForbidden() && (flags & v8::kGCCallbackFlagForced)) {
-    // Forces a precise GC at the end of the current event loop. This is
-    // required for testing code that cannot use GC internals but rather has
-    // to rely on window.gc(). Only schedule additional GCs if the last GC was
-    // using conservative stack scanning.
-    if (type == v8::kGCTypeScavenge || RequiresForcedGCForTesting()) {
-      ScheduleForcedGCForTesting();
-    }
-  }
-}
-
-void ThreadState::CollectNodeAndCssStatistics(
-    base::OnceCallback<void(size_t allocated_node_bytes,
-                            size_t allocated_css_bytes)> callback) {
-  if (IsSweepingInProgress()) {
-    // Help the sweeper to make progress using short-running delayed tasks.
-    // We use delayed tasks to give background threads a chance to sweep
-    // most of the heap.
-    const base::TimeDelta kStepSizeMs = base::TimeDelta::FromMilliseconds(5);
-    const base::TimeDelta kTaskDelayMs = base::TimeDelta::FromMilliseconds(10);
-    if (!AdvanceLazySweep(base::TimeTicks::Now() + kStepSizeMs)) {
-      ThreadScheduler::Current()->V8TaskRunner()->PostDelayedTask(
-          FROM_HERE,
-          WTF::Bind(&ThreadState::CollectNodeAndCssStatistics,
-                    WTF::Unretained(this), std::move(callback)),
-          kTaskDelayMs);
-      return;
-    }
-  }
-  size_t allocated_node_bytes =
-      Heap().Arena(BlinkGC::kNodeArenaIndex)->AllocatedBytes();
-  size_t allocated_css_bytes =
-      Heap().Arena(BlinkGC::kCSSValueArenaIndex)->AllocatedBytes();
-  std::move(callback).Run(allocated_node_bytes, allocated_css_bytes);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/thread_state.h b/third_party/blink/renderer/platform/heap/impl/thread_state.h
deleted file mode 100644
index 3c7922d1..0000000
--- a/third_party/blink/renderer/platform/heap/impl/thread_state.h
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_H_
-
-#include <atomic>
-#include <memory>
-
-#include "base/dcheck_is_on.h"
-#include "base/synchronization/lock.h"
-#include "base/task/post_job.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/impl/atomic_entry_flag.h"
-#include "third_party/blink/renderer/platform/heap/impl/threading_traits.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/sanitizers.h"
-#include "third_party/blink/renderer/platform/wtf/thread_specific.h"
-#include "third_party/blink/renderer/platform/wtf/threading.h"
-#include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-#include "v8/include/v8.h"
-
-namespace v8 {
-class EmbedderGraph;
-class Isolate;
-}  // namespace v8
-
-namespace blink {
-
-namespace incremental_marking_test {
-class IncrementalMarkingScope;
-}  // namespace incremental_marking_test
-
-class MarkingVisitor;
-class MarkingSchedulingOracle;
-class PersistentRegion;
-class ThreadHeap;
-class ThreadState;
-template <ThreadAffinity affinity>
-class ThreadStateFor;
-class UnifiedHeapController;
-class Visitor;
-
-// Declare that a class has a pre-finalizer which gets invoked before objects
-// get swept. It is thus safe to touch on-heap objects that may be collected in
-// the same GC cycle. This is useful when it's not possible to avoid touching
-// on-heap objects in a destructor which is forbidden.
-//
-// Note that:
-// (a) Pre-finalizers *must* not resurrect dead objects.
-// (b) Run on the same thread they are registered.
-// (c) Decrease GC performance which means that they should only be used if
-//     absolute necessary.
-//
-// Usage:
-//   class Foo : GarbageCollected<Foo> {
-//     USING_PRE_FINALIZER(Foo, Dispose);
-//    private:
-//     void Dispose() {
-//       bar_->...; // It is safe to touch other on-heap objects.
-//     }
-//     Member<Bar> bar_;
-//   };
-#define USING_PRE_FINALIZER(Class, PreFinalizer)                             \
- public:                                                                     \
-  static bool InvokePreFinalizer(const LivenessBroker& info, void* object) { \
-    Class* self = reinterpret_cast<Class*>(object);                          \
-    if (info.IsHeapObjectAlive(self))                                        \
-      return false;                                                          \
-    self->Class::PreFinalizer();                                             \
-    return true;                                                             \
-  }                                                                          \
-                                                                             \
- private:                                                                    \
-  ThreadState::PrefinalizerRegistration<Class> prefinalizer_dummy_{this};    \
-  using UsingPreFinalizerMacroNeedsTrailingSemiColon = char
-
-class PLATFORM_EXPORT ThreadState final {
-  USING_FAST_MALLOC(ThreadState);
-
- public:
-  // Register the pre-finalizer for the |self| object. The class T be using
-  // USING_PRE_FINALIZER() macro.
-  template <typename T>
-  class PrefinalizerRegistration final {
-    DISALLOW_NEW();
-
-   public:
-    PrefinalizerRegistration(T* self) {  // NOLINT
-      static_assert(sizeof(&T::InvokePreFinalizer) > 0,
-                    "USING_PRE_FINALIZER(T) must be defined.");
-      ThreadState* state =
-          ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState();
-#if DCHECK_IS_ON()
-      DCHECK(state->CheckThread());
-#endif
-      DCHECK(!state->SweepForbidden());
-      DCHECK(std::find(state->ordered_pre_finalizers_.begin(),
-                       state->ordered_pre_finalizers_.end(),
-                       PreFinalizer(self, T::InvokePreFinalizer)) ==
-             state->ordered_pre_finalizers_.end());
-      state->ordered_pre_finalizers_.emplace_back(self, T::InvokePreFinalizer);
-    }
-  };
-
-  // See setGCState() for possible state transitions.
-  enum GCState {
-    kNoGCScheduled,
-    kIncrementalMarkingStepPaused,
-    kIncrementalMarkingStepScheduled,
-    kIncrementalMarkingFinalizeScheduled,
-    kForcedGCForTestingScheduled,
-    kIncrementalGCScheduled,
-  };
-
-  // The phase that the GC is in. The GCPhase will not return kNone for mutators
-  // running during incremental marking and lazy sweeping. See SetGCPhase() for
-  // possible state transitions.
-  enum class GCPhase {
-    // GC is doing nothing.
-    kNone,
-    // GC is in marking phase.
-    kMarking,
-    // GC is in sweeping phase.
-    kSweeping,
-  };
-
-  enum class EphemeronProcessing {
-    kPartialProcessing,  // Perofrm one ephemeron processing iteration every
-                         // few step
-    kFullProcessing  // Perofrm full fixed-point ephemeron processing on each
-                     // step
-  };
-
-  class AtomicPauseScope;
-  class GCForbiddenScope;
-  class LsanDisabledScope;
-  class NoAllocationScope;
-  class StatisticsCollector;
-  struct Statistics;
-  class SweepForbiddenScope;
-
-  using V8BuildEmbedderGraphCallback = void (*)(v8::Isolate*,
-                                                v8::EmbedderGraph*,
-                                                void*);
-
-  // Returns true if some thread (possibly the current thread) may be doing
-  // incremental marking. If false is returned, the *current* thread is
-  // definitely not doing incremental marking. See atomic_entry_flag.h for
-  // details.
-  //
-  // For an exact check, use ThreadState::IsIncrementalMarking.
-  ALWAYS_INLINE static bool IsAnyIncrementalMarking() {
-    return incremental_marking_flag_.MightBeEntered();
-  }
-
-  static ThreadState* AttachMainThread();
-  static ThreadState* AttachMainThreadForTesting(v8::Platform* platform);
-
-  // Associate ThreadState object with the current thread. After this
-  // call thread can start using the garbage collected heap infrastructure.
-  // It also has to periodically check for safepoints.
-  static ThreadState* AttachCurrentThread();
-  static ThreadState* AttachCurrentThreadForTesting(v8::Platform* platform);
-
-  // Disassociate attached ThreadState from the current thread. The thread
-  // can no longer use the garbage collected heap after this call.
-  //
-  // When ThreadState is detaching from non-main thread its heap is expected to
-  // be empty (because it is going away). Perform registered cleanup tasks and
-  // garbage collection to sweep away any objects that are left on this heap.
-  //
-  // This method asserts that no objects remain after this cleanup. If assertion
-  // does not hold we crash as we are potentially in the dangling pointer
-  // situation.
-  static void DetachCurrentThread();
-
-  static ThreadState* Current() { return **thread_specific_; }
-
-  static ThreadState* MainThreadState() {
-    return reinterpret_cast<ThreadState*>(main_thread_state_storage_);
-  }
-
-  static ThreadState* FromObject(const void*);
-
-  ThreadState(const ThreadState&) = delete;
-  ThreadState& operator=(const ThreadState&) = delete;
-
-  bool IsMainThread() const { return this == MainThreadState(); }
-  bool CheckThread() const { return thread_ == CurrentThread(); }
-
-  ThreadHeap& Heap() const { return *heap_; }
-  base::PlatformThreadId ThreadId() const { return thread_; }
-
-  // Associates |ThreadState| with a given |v8::Isolate|, essentially tying
-  // there garbage collectors together.
-  void AttachToIsolate(v8::Isolate*, V8BuildEmbedderGraphCallback);
-
-  // Removes the association from a potentially attached |v8::Isolate|.
-  void DetachFromIsolate();
-
-  // Returns an |UnifiedHeapController| if ThreadState is attached to a V8
-  // isolate (see |AttachToIsolate|) and nullptr otherwise.
-  UnifiedHeapController* unified_heap_controller() const {
-    DCHECK(isolate_);
-    return unified_heap_controller_.get();
-  }
-
-  void PerformIdleLazySweep(base::TimeTicks deadline);
-  void PerformConcurrentSweep(base::JobDelegate*);
-
-  void ScheduleForcedGCForTesting();
-  void ScheduleGCIfNeeded();
-  void SetGCState(GCState);
-  GCState GetGCState() const { return gc_state_; }
-  void SetGCPhase(GCPhase);
-
-  // Immediately starts incremental marking and schedules further steps if
-  // necessary.
-  void StartIncrementalMarking(BlinkGC::GCReason);
-
-  // Returns true if marking is in progress.
-  bool IsMarkingInProgress() const { return gc_phase_ == GCPhase::kMarking; }
-
-  // Returns true if unified heap marking is in progress.
-  bool IsUnifiedGCMarkingInProgress() const {
-    return IsMarkingInProgress() && IsUnifiedHeapGC();
-  }
-
-  // Returns true if sweeping is in progress.
-  bool IsSweepingInProgress() const { return gc_phase_ == GCPhase::kSweeping; }
-
-  // Returns true if the current GC is a memory reducing GC.
-  bool IsMemoryReducingGC() const {
-    return current_gc_data_.reason ==
-               BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC ||
-           current_gc_data_.reason ==
-               BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
-  }
-
-  bool IsUnifiedHeapGC() const {
-    return current_gc_data_.reason == BlinkGC::GCReason::kUnifiedHeapGC ||
-           current_gc_data_.reason ==
-               BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC ||
-           current_gc_data_.reason ==
-               BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
-  }
-
-  bool FinishIncrementalMarkingIfRunning(BlinkGC::CollectionType,
-                                         BlinkGC::StackState,
-                                         BlinkGC::MarkingType,
-                                         BlinkGC::SweepingType,
-                                         BlinkGC::GCReason);
-
-  void EnableIncrementalMarkingBarrier();
-  void DisableIncrementalMarkingBarrier();
-
-  void RestartIncrementalMarkingIfPaused();
-
-  void CompleteSweep();
-
-  // Returns whether it is currently allowed to allocate an object. Mainly used
-  // for sanity checks asserts.
-  bool IsAllocationAllowed() const {
-    // Allocation is not allowed during atomic marking pause, but it is allowed
-    // during atomic sweeping pause.
-    return !InAtomicMarkingPause() && !no_allocation_count_;
-  }
-
-  // Returns whether it is currently forbidden to trigger a GC.
-  bool IsGCForbidden() const { return gc_forbidden_count_; }
-
-  // Returns whether it is currently forbidden to sweep objects.
-  bool SweepForbidden() const { return sweep_forbidden_; }
-
-  bool in_atomic_pause() const { return in_atomic_pause_; }
-
-  bool InAtomicMarkingPause() const {
-    return in_atomic_pause() && IsMarkingInProgress();
-  }
-  bool InAtomicSweepingPause() const {
-    return in_atomic_pause() && IsSweepingInProgress();
-  }
-
-  bool IsIncrementalMarking() const { return incremental_marking_; }
-  void SetIncrementalMarking(bool value) { incremental_marking_ = value; }
-
-  void SafePoint(BlinkGC::StackState);
-
-  // A region of non-weak PersistentNodes allocated on the given thread.
-  PersistentRegion* GetPersistentRegion() const {
-    return persistent_region_.get();
-  }
-
-  // A region of PersistentNodes for WeakPersistents allocated on the given
-  // thread.
-  PersistentRegion* GetWeakPersistentRegion() const {
-    return weak_persistent_region_.get();
-  }
-
-  v8::Isolate* GetIsolate() const { return isolate_; }
-
-  // Returns |true| if |object| resides on this thread's heap.
-  // It is well-defined to call this method on any heap allocated
-  // reference, provided its associated heap hasn't been detached
-  // and shut down. Its behavior is undefined for any other pointer
-  // value.
-  bool IsOnThreadHeap(const void* object) const {
-    return &FromObject(object)->Heap() == &Heap();
-  }
-
-  ALWAYS_INLINE bool IsOnStack(Address address) const {
-    return reinterpret_cast<Address>(start_of_stack_) >= address &&
-           address >= reinterpret_cast<Address>(WTF::GetCurrentStackPosition());
-  }
-
-  MarkingVisitor* CurrentVisitor() const {
-    return current_gc_data_.visitor.get();
-  }
-
-  // Returns true if the marking verifier is enabled, false otherwise.
-  bool IsVerifyMarkingEnabled() const;
-
-  void SkipIncrementalMarkingForTesting() {
-    skip_incremental_marking_for_testing_ = true;
-  }
-
-  // Performs stand-alone garbage collections considering only C++ objects for
-  // testing.
-  //
-  // Since it only considers C++ objects this type of GC is mostly useful for
-  // unit tests.
-  void CollectGarbageForTesting(BlinkGC::CollectionType,
-                                BlinkGC::StackState,
-                                BlinkGC::MarkingType,
-                                BlinkGC::SweepingType,
-                                BlinkGC::GCReason);
-
-  // Forced garbage collection for testing:
-  // - Performs unified heap garbage collections if ThreadState is attached to a
-  //   v8::Isolate using ThreadState::AttachToIsolate.
-  // - Otherwise, performs stand-alone garbage collections.
-  // - Collects garbage as long as live memory decreases (capped at 5).
-  void CollectAllGarbageForTesting(
-      BlinkGC::StackState stack_state =
-          BlinkGC::StackState::kNoHeapPointersOnStack);
-
-  // Enables compaction for next garbage collection.
-  void EnableCompactionForNextGCForTesting();
-
-  bool RequiresForcedGCForTesting() const {
-    return current_gc_data_.stack_state ==
-               BlinkGC::StackState::kHeapPointersOnStack &&
-           !forced_scheduled_gc_for_testing_;
-  }
-
-  void EnterNoHeapVerificationScopeForTesting() {
-    ++disable_heap_verification_scope_;
-  }
-  void LeaveNoHeapVerificationScopeForTesting() {
-    --disable_heap_verification_scope_;
-  }
-
-  void EnableDetachedGarbageCollectionsForTesting() { CHECK(!isolate_); }
-
-  void NotifyGarbageCollection(v8::GCType, v8::GCCallbackFlags);
-
-  // Waits until sweeping is done and invokes the given callback with
-  // the total sizes of live objects in Node and CSS arenas.
-  void CollectNodeAndCssStatistics(
-      base::OnceCallback<void(size_t allocated_node_bytes,
-                              size_t allocated_css_bytes)>);
-
-  void ForceNoFollowupFullGCForTesting() {
-    no_followup_full_gc_for_testing_ = true;
-  }
-
- private:
-  class IncrementalMarkingScheduler;
-
-  // Stores whether some ThreadState is currently in incremental marking.
-  static AtomicEntryFlag incremental_marking_flag_;
-
-  static WTF::ThreadSpecific<ThreadState*>* thread_specific_;
-
-  // We can't create a static member of type ThreadState here because it will
-  // introduce global constructor and destructor. We would like to manage
-  // lifetime of the ThreadState attached to the main thread explicitly instead
-  // and still use normal constructor and destructor for the ThreadState class.
-  // For this we reserve static storage for the main ThreadState and lazily
-  // construct ThreadState in it using placement new.
-  static uint8_t main_thread_state_storage_[];
-
-  // Callback executed directly after pushing all callee-saved registers.
-  // |end_of_stack| denotes the end of the stack that can hold references to
-  // managed objects.
-  static void VisitStackAfterPushingRegisters(ThreadState*,
-                                              intptr_t* end_of_stack);
-
-  static bool IsForcedGC(BlinkGC::GCReason reason) {
-    return reason == BlinkGC::GCReason::kThreadTerminationGC ||
-           reason == BlinkGC::GCReason::kForcedGCForTesting ||
-           reason == BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
-  }
-
-  ThreadState();
-  ~ThreadState();
-
-  void EnterNoAllocationScope() { no_allocation_count_++; }
-  void LeaveNoAllocationScope() { no_allocation_count_--; }
-
-  void EnterAtomicPause() {
-    DCHECK(!in_atomic_pause_);
-    in_atomic_pause_ = true;
-  }
-  void LeaveAtomicPause() {
-    DCHECK(in_atomic_pause_);
-    in_atomic_pause_ = false;
-  }
-
-  void EnterGCForbiddenScope() { gc_forbidden_count_++; }
-  void LeaveGCForbiddenScope() {
-    DCHECK_GT(gc_forbidden_count_, 0u);
-    gc_forbidden_count_--;
-  }
-
-  // Performs stand-alone garbage collections considering only C++ objects.
-  //
-  // Use the public *ForTesting calls for calling GC in tests.
-  void CollectGarbage(BlinkGC::CollectionType,
-                      BlinkGC::StackState,
-                      BlinkGC::MarkingType,
-                      BlinkGC::SweepingType,
-                      BlinkGC::GCReason);
-
-  // The following methods are used to compose RunAtomicPause. Public users
-  // should use the CollectGarbage entrypoint. Internal users should use these
-  // methods to compose a full garbage collection.
-  void AtomicPauseMarkPrologue(BlinkGC::CollectionType,
-                               BlinkGC::StackState,
-                               BlinkGC::MarkingType,
-                               BlinkGC::GCReason);
-  void AtomicPauseMarkRoots(BlinkGC::StackState,
-                            BlinkGC::MarkingType,
-                            BlinkGC::GCReason);
-  void AtomicPauseMarkTransitiveClosure();
-  void AtomicPauseMarkEpilogue(BlinkGC::MarkingType);
-  void AtomicPauseSweepAndCompact(BlinkGC::CollectionType,
-                                  BlinkGC::MarkingType marking_type,
-                                  BlinkGC::SweepingType sweeping_type);
-  void AtomicPauseEpilogue();
-
-  // RunAtomicPause composes the final atomic pause that finishes a mark-compact
-  // phase of a garbage collection. Depending on SweepingType it may also finish
-  // sweeping or schedule lazy/concurrent sweeping.
-  void RunAtomicPause(BlinkGC::CollectionType,
-                      BlinkGC::StackState,
-                      BlinkGC::MarkingType,
-                      BlinkGC::SweepingType,
-                      BlinkGC::GCReason);
-
-  // The version is needed to be able to start incremental marking.
-  void MarkPhasePrologue(BlinkGC::CollectionType,
-                         BlinkGC::StackState,
-                         BlinkGC::MarkingType,
-                         BlinkGC::GCReason);
-  void MarkPhaseEpilogue(BlinkGC::MarkingType);
-  void MarkPhaseVisitRoots();
-  void MarkPhaseVisitNotFullyConstructedObjects();
-  bool MarkPhaseAdvanceMarkingBasedOnSchedule(base::TimeDelta,
-                                              EphemeronProcessing);
-  bool MarkPhaseAdvanceMarking(base::TimeDelta, EphemeronProcessing);
-  void VerifyMarking(BlinkGC::MarkingType);
-
-  // Visit the stack after pushing registers onto the stack.
-  void PushRegistersAndVisitStack();
-
-  // Visit local thread stack and trace all pointers conservatively. Never call
-  // directly but always call through |PushRegistersAndVisitStack|.
-  void VisitStackImpl(MarkingVisitor*, Address*, Address*);
-  void VisitStack(MarkingVisitor*, Address*);
-  void VisitUnsafeStack(MarkingVisitor*);
-
-  // Visit the asan fake stack frame corresponding to a slot on the real machine
-  // stack if there is one. Never call directly but always call through
-  // |PushRegistersAndVisitStack|.
-  void VisitAsanFakeStackForPointer(MarkingVisitor*,
-                                    Address,
-                                    Address*,
-                                    Address*);
-
-  // Visit all non-weak persistents allocated on this thread.
-  void VisitPersistents(Visitor*);
-
-  // Visit all weak persistents allocated on this thread.
-  void VisitWeakPersistents(Visitor*);
-
-  // Visit card tables (remembered sets) containing inter-generational pointers.
-  void VisitRememberedSets(MarkingVisitor*);
-
-  // Incremental marking implementation functions.
-  void IncrementalMarkingStartForTesting();
-  void IncrementalMarkingStart(BlinkGC::GCReason);
-  // Incremental marking step advance marking on the mutator thread. This method
-  // also reschedules concurrent marking tasks if needed. The duration parameter
-  // applies only to incremental marking steps on the mutator thread.
-  void IncrementalMarkingStep(BlinkGC::StackState);
-  void IncrementalMarkingFinalize();
-
-  // Returns true if concurrent marking is finished (i.e. all current threads
-  // terminated and the worklist is empty)
-  bool ConcurrentMarkingStep();
-  void ScheduleConcurrentMarking();
-  void PerformConcurrentMark(base::JobDelegate* job);
-
-  // Schedule helpers.
-  void ScheduleIdleLazySweep();
-  void ScheduleConcurrentAndLazySweep();
-  // Advances sweeping and returns true if sweeping is complete.
-  bool AdvanceLazySweep(base::TimeTicks deadline);
-
-  void NotifySweepDone();
-  void PostSweep();
-
-  // See |DetachCurrentThread|.
-  void RunTerminationGC();
-
-  void RunScheduledGC(BlinkGC::StackState);
-
-  void SynchronizeAndFinishConcurrentSweeping();
-
-  void InvokePreFinalizers();
-
-  bool IsForcedGC() const { return IsForcedGC(current_gc_data_.reason); }
-
-  // Returns whether stack scanning is forced. This is currently only used in
-  // platform tests where non nested tasks can be run with heap pointers on
-  // stack.
-  bool HeapPointersOnStackForced() const {
-    return heap_pointers_on_stack_forced_;
-  }
-
-#if defined(ADDRESS_SANITIZER)
-  // Poisons payload of unmarked objects.
-  //
-  // Also unpoisons memory areas for handles that may require resetting which
-  // can race with destructors. Note that cross-thread access still requires
-  // synchronization using a lock.
-  void PoisonUnmarkedObjects();
-#endif  // ADDRESS_SANITIZER
-
-  std::unique_ptr<ThreadHeap> heap_;
-  base::PlatformThreadId thread_;
-  std::unique_ptr<PersistentRegion> persistent_region_;
-  std::unique_ptr<PersistentRegion> weak_persistent_region_;
-
-  // Start of the stack which is the boundary until conservative stack scanning
-  // needs to search for managed pointers.
-  Address* start_of_stack_;
-
-  bool in_atomic_pause_ = false;
-  bool sweep_forbidden_ = false;
-  bool heap_pointers_on_stack_forced_ = false;
-  bool incremental_marking_ = false;
-  bool should_optimize_for_load_time_ = false;
-  bool forced_scheduled_gc_for_testing_ = false;
-  size_t no_allocation_count_ = 0;
-  size_t gc_forbidden_count_ = 0;
-
-  GCState gc_state_ = GCState::kNoGCScheduled;
-  GCPhase gc_phase_ = GCPhase::kNone;
-  BlinkGC::GCReason reason_for_scheduled_gc_ =
-      BlinkGC::GCReason::kForcedGCForTesting;
-
-  using PreFinalizerCallback = bool (*)(const LivenessBroker&, void*);
-  using PreFinalizer = std::pair<void*, PreFinalizerCallback>;
-
-  // Pre-finalizers are called in the reverse order in which they are
-  // registered by the constructors (including constructors of Mixin objects)
-  // for an object, by processing the ordered_pre_finalizers_ back-to-front.
-  Deque<PreFinalizer> ordered_pre_finalizers_;
-
-  v8::Isolate* isolate_ = nullptr;
-  V8BuildEmbedderGraphCallback v8_build_embedder_graph_ = nullptr;
-  std::unique_ptr<UnifiedHeapController> unified_heap_controller_;
-  std::unique_ptr<v8::EmbedderRootsHandler> embedder_roots_handler_;
-
-#if defined(ADDRESS_SANITIZER)
-  void* asan_fake_stack_;
-#endif
-
-  struct GCData {
-    BlinkGC::CollectionType collection_type;
-    BlinkGC::StackState stack_state;
-    BlinkGC::MarkingType marking_type;
-    BlinkGC::GCReason reason;
-    std::unique_ptr<MarkingVisitor> visitor;
-  };
-  GCData current_gc_data_;
-
-  std::unique_ptr<IncrementalMarkingScheduler> incremental_marking_scheduler_;
-  std::unique_ptr<MarkingSchedulingOracle> marking_scheduling_;
-
-  base::JobHandle marker_handle_;
-
-  base::JobHandle sweeper_handle_;
-  std::atomic_bool has_unswept_pages_{false};
-
-  size_t disable_heap_verification_scope_ = 0;
-
-  bool skip_incremental_marking_for_testing_ = false;
-
-  size_t last_concurrently_marked_bytes_ = 0;
-  base::TimeTicks last_concurrently_marked_bytes_update_;
-  bool concurrent_marking_priority_increased_ = false;
-
-  bool no_followup_full_gc_for_testing_ = false;
-
-  friend class incremental_marking_test::IncrementalMarkingScope;
-  friend class HeapPointersOnStackScope;
-  friend class IncrementalMarkingTestDriver;
-  friend class HeapAllocator;
-  template <typename T>
-  friend class PrefinalizerRegistration;
-  friend class TestGCScope;
-  friend class TestSupportingGC;
-  friend class ThreadStateSchedulingTest;
-  friend class UnifiedHeapController;
-};
-
-template <>
-class ThreadStateFor<kMainThreadOnly> {
-  STATIC_ONLY(ThreadStateFor);
-
- public:
-  static ThreadState* GetState() {
-    // This specialization must only be used from the main thread.
-    DCHECK(ThreadState::Current()->IsMainThread());
-    return ThreadState::MainThreadState();
-  }
-};
-
-template <>
-class ThreadStateFor<kAnyThread> {
-  STATIC_ONLY(ThreadStateFor);
-
- public:
-  static ThreadState* GetState() { return ThreadState::Current(); }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h b/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h
deleted file mode 100644
index 77fc380..0000000
--- a/third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_SCOPES_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_SCOPES_H_
-
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-
-#if defined(LEAK_SANITIZER)
-#include "third_party/blink/renderer/platform/wtf/leak_annotations.h"
-#endif
-
-namespace blink {
-
-// The NoAllocationScope class is used in debug mode to catch unwanted
-// allocations. E.g. allocations during GC.
-class ThreadState::NoAllocationScope final {
-  STACK_ALLOCATED();
-
- public:
-  explicit NoAllocationScope(ThreadState* state) : state_(state) {
-    state_->EnterNoAllocationScope();
-  }
-  NoAllocationScope(const NoAllocationScope&) = delete;
-  NoAllocationScope& operator=(const NoAllocationScope&) = delete;
-  ~NoAllocationScope() { state_->LeaveNoAllocationScope(); }
-
- private:
-  ThreadState* const state_;
-};
-
-class ThreadState::SweepForbiddenScope final {
-  STACK_ALLOCATED();
-
- public:
-  explicit SweepForbiddenScope(ThreadState* state) : state_(state) {
-    DCHECK(!state_->sweep_forbidden_);
-    state_->sweep_forbidden_ = true;
-  }
-  SweepForbiddenScope(const SweepForbiddenScope&) = delete;
-  SweepForbiddenScope& operator=(const SweepForbiddenScope&) = delete;
-  ~SweepForbiddenScope() {
-    DCHECK(state_->sweep_forbidden_);
-    state_->sweep_forbidden_ = false;
-  }
-
- private:
-  ThreadState* const state_;
-};
-
-class ThreadState::GCForbiddenScope final {
-  STACK_ALLOCATED();
-
- public:
-  explicit GCForbiddenScope(ThreadState* thread_state)
-      : thread_state_(thread_state) {
-    thread_state_->EnterGCForbiddenScope();
-  }
-  ~GCForbiddenScope() { thread_state_->LeaveGCForbiddenScope(); }
-
- private:
-  ThreadState* const thread_state_;
-};
-
-// Used to mark when we are in an atomic pause for GC.
-class ThreadState::AtomicPauseScope final {
-  STACK_ALLOCATED();
-
- public:
-  explicit AtomicPauseScope(ThreadState* thread_state)
-      : thread_state_(thread_state), gc_forbidden_scope(thread_state) {
-    thread_state_->EnterAtomicPause();
-  }
-  ~AtomicPauseScope() { thread_state_->LeaveAtomicPause(); }
-
- private:
-  ThreadState* const thread_state_;
-  GCForbiddenScope gc_forbidden_scope;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_SCOPES_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.cc b/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.cc
deleted file mode 100644
index f561bc3..0000000
--- a/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h"
-
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-
-namespace blink {
-
-ThreadState::Statistics ThreadState::StatisticsCollector::CollectStatistics(
-    Statistics::DetailLevel detail_level) const {
-  Statistics stats;
-  stats.detail_level = detail_level;
-  if (detail_level == Statistics::kBrief) {
-    ThreadHeapStatsCollector* stats_collector =
-        thread_state_->Heap().stats_collector();
-    stats.committed_size_bytes = stats_collector->allocated_space_bytes();
-    stats.used_size_bytes = stats_collector->object_size_in_bytes();
-    return stats;
-  }
-
-  thread_state_->CompleteSweep();
-
-  // Detailed statistics.
-  thread_state_->Heap().CollectStatistics(&stats);
-  stats.detail_level = Statistics::kDetailed;
-  return stats;
-}
-
-void ThreadState::StatisticsCollector::Verify() const {
-#if BUILDFLAG(BLINK_HEAP_VERIFICATION) && DCHECK_IS_ON()
-  // CollectStatistics checks counter consistency with DCHECKs.
-  CollectStatistics(Statistics::kDetailed);
-#endif  // BUILDFLAG(BLINK_HEAP_VERIFICATION) && DCHECK_IS_ON()
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h b/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h
deleted file mode 100644
index e68d12f2..0000000
--- a/third_party/blink/renderer/platform/heap/impl/thread_state_statistics.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_STATISTICS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_STATISTICS_H_
-
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-
-namespace blink {
-
-struct PLATFORM_EXPORT ThreadState::Statistics final {
-  enum DetailLevel : uint32_t {
-    kBrief,
-    kDetailed,
-  };
-
-  struct ObjectStatistics {
-    size_t num_types = 0;
-    Vector<std::string> type_name;
-    Vector<size_t> type_count;
-    Vector<size_t> type_bytes;
-  };
-
-  struct PageStatistics {
-    size_t committed_size_bytes = 0;
-    size_t used_size_bytes = 0;
-  };
-
-  struct FreeListStatistics {
-    Vector<size_t> bucket_size;
-    Vector<size_t> free_count;
-    Vector<size_t> free_size;
-  };
-
-  struct ArenaStatistics {
-    std::string name;
-    size_t committed_size_bytes = 0;
-    size_t used_size_bytes = 0;
-    Vector<PageStatistics> page_stats;
-    FreeListStatistics free_list_stats;
-    // Only filled when NameClient::HideInternalName() is false.
-    ObjectStatistics object_stats;
-  };
-
-  size_t committed_size_bytes = 0;
-  size_t used_size_bytes = 0;
-  DetailLevel detail_level;
-
-  // Only filled when detail_level is kDetailed.
-  Vector<ArenaStatistics> arena_stats;
-};
-
-class PLATFORM_EXPORT ThreadState::StatisticsCollector {
- public:
-  explicit StatisticsCollector(ThreadState* thread_state)
-      : thread_state_(thread_state) {}
-
-  ThreadState::Statistics CollectStatistics(Statistics::DetailLevel) const;
-  void Verify() const;
-
- private:
-  ThreadState* const thread_state_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREAD_STATE_STATISTICS_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/threading_traits.h b/third_party/blink/renderer/platform/heap/impl/threading_traits.h
deleted file mode 100644
index 28c10e9e..0000000
--- a/third_party/blink/renderer/platform/heap/impl/threading_traits.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREADING_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREADING_TRAITS_H_
-
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/deque.h"
-#include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/hash_table.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
-#include "third_party/blink/renderer/platform/wtf/vector.h"
-
-namespace blink {
-
-// ThreadAffinity indicates which threads objects can be used on. We
-// distinguish between objects that can be used on the main thread
-// only and objects that can be used on any thread.
-//
-// For objects that can only be used on the main thread, we avoid going
-// through thread-local storage to get to the thread state. This is
-// important for performance.
-enum ThreadAffinity {
-  kAnyThread,
-  kMainThreadOnly,
-};
-
-// TODO(haraken): These forward declarations violate dependency rules.
-// Remove them.
-class LayoutObject;
-class Node;
-class NodeList;
-class NodeRareData;
-
-template <
-    typename T,
-    bool mainThreadOnly =
-        WTF::IsSubclass<typename std::remove_const<T>::type,
-                        LayoutObject>::value ||
-        WTF::IsSubclass<typename std::remove_const<T>::type, Node>::value ||
-        WTF::IsSubclass<typename std::remove_const<T>::type, NodeList>::value ||
-        WTF::IsSubclass<typename std::remove_const<T>::type,
-                        NodeRareData>::value>
-struct DefaultThreadingTrait;
-
-template <typename T>
-struct DefaultThreadingTrait<T, false> {
-  STATIC_ONLY(DefaultThreadingTrait);
-  static const ThreadAffinity kAffinity = kAnyThread;
-};
-
-template <typename T>
-struct DefaultThreadingTrait<T, true> {
-  STATIC_ONLY(DefaultThreadingTrait);
-  static const ThreadAffinity kAffinity = kMainThreadOnly;
-};
-
-class HeapAllocator;
-template <typename T>
-class Member;
-template <typename T>
-class WeakMember;
-
-template <typename T>
-struct ThreadingTrait {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity = DefaultThreadingTrait<T>::kAffinity;
-};
-
-template <typename U>
-class ThreadingTrait<const U> : public ThreadingTrait<U> {};
-
-template <typename T>
-struct ThreadingTrait<Member<T>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
-};
-
-template <typename T>
-struct ThreadingTrait<WeakMember<T>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
-};
-
-template <typename Key, typename Value, typename T, typename U, typename V>
-struct ThreadingTrait<HashMap<Key, Value, T, U, V, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity =
-      (ThreadingTrait<Key>::kAffinity == kMainThreadOnly) &&
-              (ThreadingTrait<Value>::kAffinity == kMainThreadOnly)
-          ? kMainThreadOnly
-          : kAnyThread;
-};
-
-template <typename First, typename Second>
-struct ThreadingTrait<WTF::KeyValuePair<First, Second>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity =
-      (ThreadingTrait<First>::kAffinity == kMainThreadOnly) &&
-              (ThreadingTrait<Second>::kAffinity == kMainThreadOnly)
-          ? kMainThreadOnly
-          : kAnyThread;
-};
-
-template <typename T, typename U, typename V>
-struct ThreadingTrait<HashSet<T, U, V, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
-};
-
-template <typename T, size_t inlineCapacity>
-struct ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
-};
-
-template <typename T, size_t inlineCapacity>
-struct ThreadingTrait<Deque<T, inlineCapacity, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
-};
-
-template <typename T, typename U, typename V>
-struct ThreadingTrait<HashCountedSet<T, U, V, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-  static const ThreadAffinity kAffinity = ThreadingTrait<T>::kAffinity;
-};
-
-template <typename T, typename U, typename V, typename W, typename X>
-class HeapHashMap;
-template <typename T, typename U, typename V>
-class HeapHashSet;
-template <typename T, wtf_size_t inlineCapacity>
-class HeapVector;
-template <typename T>
-class HeapDeque;
-template <typename T, typename U, typename V>
-class HeapHashCountedSet;
-
-template <typename T, typename U, typename V, typename W, typename X>
-struct ThreadingTrait<HeapHashMap<T, U, V, W, X>>
-    : public ThreadingTrait<HashMap<T, U, V, W, X, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-};
-template <typename T, typename U, typename V>
-struct ThreadingTrait<HeapHashSet<T, U, V>>
-    : public ThreadingTrait<HashSet<T, U, V, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-};
-template <typename T, size_t inlineCapacity>
-struct ThreadingTrait<HeapVector<T, inlineCapacity>>
-    : public ThreadingTrait<Vector<T, inlineCapacity, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-};
-template <typename T>
-struct ThreadingTrait<HeapDeque<T>>
-    : public ThreadingTrait<Deque<T, 0, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-};
-template <typename T, typename U, typename V>
-struct ThreadingTrait<HeapHashCountedSet<T, U, V>>
-    : public ThreadingTrait<HashCountedSet<T, U, V, HeapAllocator>> {
-  STATIC_ONLY(ThreadingTrait);
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_THREADING_TRAITS_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/trace_traits.h b/third_party/blink/renderer/platform/heap/impl/trace_traits.h
deleted file mode 100644
index 217b252..0000000
--- a/third_party/blink/renderer/platform/heap/impl/trace_traits.h
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_TRACE_TRAITS_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_TRACE_TRAITS_H_
-
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/impl/gc_info.h"
-#include "third_party/blink/renderer/platform/heap/impl/heap_page.h"
-#include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/hash_counted_set.h"
-#include "third_party/blink/renderer/platform/wtf/hash_map.h"
-#include "third_party/blink/renderer/platform/wtf/hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/hash_table.h"
-#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
-
-namespace blink {
-
-template <typename T>
-struct TraceTrait;
-
-template <typename T, bool = NeedsAdjustPointer<T>::value>
-struct AdjustPointerTrait;
-
-template <typename T>
-struct AdjustPointerTrait<T, false> {
-  STATIC_ONLY(AdjustPointerTrait);
-
-  static TraceDescriptor GetTraceDescriptor(const void* self) {
-    return {self, TraceTrait<T>::Trace};
-  }
-};
-
-template <typename T>
-struct AdjustPointerTrait<T, true> {
-  STATIC_ONLY(AdjustPointerTrait);
-
-  static TraceDescriptor GetTraceDescriptor(const void* self) {
-    // Tracing an object, and more specifically GetTraceDescriptor for an
-    // object, implies having a reference which means the object is at least in
-    // construction. Therefore it is guaranteed that the ObjectStartBitmap was
-    // already updated to include the object, and its HeapObjectHeader was
-    // already created.
-    HeapObjectHeader* const header = HeapObjectHeader::FromInnerAddress<
-        HeapObjectHeader::AccessMode::kAtomic>(self);
-    return {header->Payload(),
-            GCInfo::From(
-                header->GcInfoIndex<HeapObjectHeader::AccessMode::kAtomic>())
-                .trace};
-  }
-};
-
-template <typename T, bool = WTF::IsTraceable<T>::value>
-struct TraceIfNeeded;
-
-template <typename T>
-struct TraceIfNeeded<T, false> {
-  STATIC_ONLY(TraceIfNeeded);
-  static void Trace(Visitor*, const T&) {}
-};
-
-template <typename T>
-struct TraceIfNeeded<T, true> {
-  STATIC_ONLY(TraceIfNeeded);
-  static void Trace(Visitor* visitor, const T& t) { visitor->Trace(t); }
-};
-
-// The TraceTrait is used to specify how to trace and object for Oilpan and
-// wrapper tracing.
-//
-//
-// By default, the 'Trace' method implemented on an object itself is
-// used to trace the pointers to other heap objects inside the object.
-//
-// However, the TraceTrait can be specialized to use a different
-// implementation. A common case where a TraceTrait specialization is
-// needed is when multiple inheritance leads to pointers that are not
-// to the start of the object in the Blink garbage-collected heap. In
-// that case the pointer has to be adjusted before marking.
-template <typename T>
-struct TraceTrait {
-  STATIC_ONLY(TraceTrait);
-
- public:
-  static TraceDescriptor GetTraceDescriptor(const void* self) {
-    return AdjustPointerTrait<T>::GetTraceDescriptor(
-        static_cast<const T*>(self));
-  }
-
-  static TraceDescriptor GetWeakTraceDescriptor(const void* self) {
-    return {self, nullptr};
-  }
-
-  static void Trace(Visitor*, const void* self);
-};
-
-template <typename T>
-struct TraceTrait<const T> : public TraceTrait<T> {};
-
-template <typename T>
-void TraceTrait<T>::Trace(Visitor* visitor, const void* self) {
-  static_assert(WTF::IsTraceable<T>::value, "T should be traceable");
-  static_cast<const T*>(self)->Trace(visitor);
-}
-
-// This trace trait for std::pair will null weak members if their referent is
-// collected. If you have a collection that contain weakness it does not remove
-// entries from the collection that contain nulled weak members.
-template <typename T, typename U>
-struct TraceTrait<std::pair<T, U>> {
-  STATIC_ONLY(TraceTrait);
-
- public:
-  static void Trace(Visitor* visitor, const std::pair<T, U>* pair) {
-    TraceIfNeeded<T>::Trace(visitor, pair->first);
-    TraceIfNeeded<U>::Trace(visitor, pair->second);
-  }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_TRACE_TRAITS_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.cc b/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.cc
deleted file mode 100644
index c622451..0000000
--- a/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.cc
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/unified_heap_controller.h"
-
-#include "base/logging.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h"
-#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h"
-#include "third_party/blink/renderer/platform/heap/heap.h"
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-
-namespace blink {
-
-namespace {
-
-constexpr BlinkGC::StackState ToBlinkGCStackState(
-    v8::EmbedderHeapTracer::EmbedderStackState stack_state) {
-  return stack_state ==
-                 v8::EmbedderHeapTracer::EmbedderStackState::kNoHeapPointers
-             ? BlinkGC::kNoHeapPointersOnStack
-             : BlinkGC::kHeapPointersOnStack;
-}
-
-}  // namespace
-
-UnifiedHeapController::UnifiedHeapController(ThreadState* thread_state)
-    : thread_state_(thread_state) {
-  thread_state->Heap().stats_collector()->RegisterObserver(this);
-}
-
-UnifiedHeapController::~UnifiedHeapController() {
-  thread_state_->Heap().stats_collector()->UnregisterObserver(this);
-}
-
-void UnifiedHeapController::TracePrologue(
-    v8::EmbedderHeapTracer::TraceFlags v8_flags) {
-  VLOG(2) << "UnifiedHeapController::TracePrologue";
-  ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
-      thread_state_->Heap().stats_collector());
-
-  // Be conservative here as a new garbage collection gets started right away.
-  thread_state_->FinishIncrementalMarkingIfRunning(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kHeapPointersOnStack,
-      BlinkGC::kIncrementalAndConcurrentMarking,
-      BlinkGC::kConcurrentAndLazySweeping,
-      thread_state_->current_gc_data_.reason);
-
-  thread_state_->SetGCState(ThreadState::kNoGCScheduled);
-  BlinkGC::GCReason gc_reason;
-  if (v8_flags & v8::EmbedderHeapTracer::TraceFlags::kForced) {
-    gc_reason = BlinkGC::GCReason::kUnifiedHeapForcedForTestingGC;
-  } else if (v8_flags & v8::EmbedderHeapTracer::TraceFlags::kReduceMemory) {
-    gc_reason = BlinkGC::GCReason::kUnifiedHeapForMemoryReductionGC;
-  } else {
-    gc_reason = BlinkGC::GCReason::kUnifiedHeapGC;
-  }
-  thread_state_->StartIncrementalMarking(gc_reason);
-
-  is_tracing_done_ = false;
-}
-
-void UnifiedHeapController::EnterFinalPause(EmbedderStackState stack_state) {
-  VLOG(2) << "UnifiedHeapController::EnterFinalPause";
-  ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
-      thread_state_->Heap().stats_collector());
-  thread_state_->AtomicPauseMarkPrologue(
-      BlinkGC::CollectionType::kMajor, ToBlinkGCStackState(stack_state),
-      BlinkGC::kIncrementalAndConcurrentMarking,
-      thread_state_->current_gc_data_.reason);
-  thread_state_->AtomicPauseMarkRoots(ToBlinkGCStackState(stack_state),
-                                      BlinkGC::kIncrementalAndConcurrentMarking,
-                                      thread_state_->current_gc_data_.reason);
-}
-
-void UnifiedHeapController::TraceEpilogue(
-    v8::EmbedderHeapTracer::TraceSummary* summary) {
-  VLOG(2) << "UnifiedHeapController::TraceEpilogue";
-  {
-    ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
-        thread_state_->Heap().stats_collector());
-    thread_state_->AtomicPauseMarkEpilogue(
-        BlinkGC::kIncrementalAndConcurrentMarking);
-    const BlinkGC::SweepingType sweeping_type =
-        thread_state_->IsForcedGC() ? BlinkGC::kEagerSweeping
-                                    : BlinkGC::kConcurrentAndLazySweeping;
-    thread_state_->AtomicPauseSweepAndCompact(
-        BlinkGC::CollectionType::kMajor,
-        BlinkGC::kIncrementalAndConcurrentMarking, sweeping_type);
-
-    ThreadHeapStatsCollector* const stats_collector =
-        thread_state_->Heap().stats_collector();
-    summary->allocated_size =
-        static_cast<size_t>(stats_collector->marked_bytes());
-    summary->time = stats_collector->marking_time_so_far().InMillisecondsF();
-    buffered_allocated_size_ = 0;
-  }
-  thread_state_->AtomicPauseEpilogue();
-}
-
-void UnifiedHeapController::RegisterV8References(
-    const std::vector<std::pair<void*, void*>>&
-        internal_fields_of_potential_wrappers) {
-  VLOG(2) << "UnifiedHeapController::RegisterV8References";
-  DCHECK(thread_state()->IsMarkingInProgress());
-
-  const bool was_in_atomic_pause = thread_state()->in_atomic_pause();
-  if (!was_in_atomic_pause)
-    ThreadState::Current()->EnterAtomicPause();
-  for (const auto& internal_fields : internal_fields_of_potential_wrappers) {
-    const WrapperTypeInfo* wrapper_type_info =
-        reinterpret_cast<const WrapperTypeInfo*>(internal_fields.first);
-    if (wrapper_type_info->gin_embedder != gin::GinEmbedder::kEmbedderBlink) {
-      continue;
-    }
-    is_tracing_done_ = false;
-    wrapper_type_info->Trace(thread_state_->CurrentVisitor(),
-                             internal_fields.second);
-  }
-  if (!was_in_atomic_pause)
-    ThreadState::Current()->LeaveAtomicPause();
-}
-
-bool UnifiedHeapController::AdvanceTracing(double deadline_in_ms) {
-  VLOG(2) << "UnifiedHeapController::AdvanceTracing";
-  ThreadHeapStatsCollector::BlinkGCInV8Scope nested_scope(
-      thread_state_->Heap().stats_collector());
-  if (!thread_state_->in_atomic_pause()) {
-    ThreadHeapStatsCollector::EnabledScope advance_tracing_scope(
-        thread_state_->Heap().stats_collector(),
-        ThreadHeapStatsCollector::kUnifiedMarkingStep);
-    // V8 calls into embedder tracing from its own marking to ensure
-    // progress. Oilpan will additionally schedule marking steps.
-    ThreadState::AtomicPauseScope atomic_pause_scope(thread_state_);
-    ScriptForbiddenScope script_forbidden_scope;
-    is_tracing_done_ = thread_state_->MarkPhaseAdvanceMarkingBasedOnSchedule(
-        base::TimeDelta::FromMillisecondsD(deadline_in_ms),
-        ThreadState::EphemeronProcessing::kPartialProcessing);
-    if (!is_tracing_done_) {
-      if (base::FeatureList::IsEnabled(
-              blink::features::kBlinkHeapConcurrentMarking)) {
-        thread_state_->ConcurrentMarkingStep();
-      }
-      thread_state_->RestartIncrementalMarkingIfPaused();
-    }
-    return is_tracing_done_;
-  }
-  thread_state_->AtomicPauseMarkTransitiveClosure();
-  is_tracing_done_ = true;
-  return true;
-}
-
-bool UnifiedHeapController::IsTracingDone() {
-  return is_tracing_done_;
-}
-
-void UnifiedHeapController::ReportBufferedAllocatedSizeIfPossible() {
-  // Avoid reporting to V8 in the following conditions as that may trigger GC
-  // finalizations where not allowed.
-  // - Recursive sweeping.
-  // - GC forbidden scope.
-  if ((thread_state()->IsSweepingInProgress() &&
-       thread_state()->SweepForbidden()) ||
-      thread_state()->IsGCForbidden()) {
-    return;
-  }
-
-  if (buffered_allocated_size_ < 0) {
-    DecreaseAllocatedSize(static_cast<size_t>(-buffered_allocated_size_));
-  } else {
-    IncreaseAllocatedSize(static_cast<size_t>(buffered_allocated_size_));
-  }
-  buffered_allocated_size_ = 0;
-}
-
-void UnifiedHeapController::IncreaseAllocatedObjectSize(size_t delta_bytes) {
-  buffered_allocated_size_ += static_cast<int64_t>(delta_bytes);
-  ReportBufferedAllocatedSizeIfPossible();
-}
-
-void UnifiedHeapController::DecreaseAllocatedObjectSize(size_t delta_bytes) {
-  buffered_allocated_size_ -= static_cast<int64_t>(delta_bytes);
-  ReportBufferedAllocatedSizeIfPossible();
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h b/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h
deleted file mode 100644
index 574ab570..0000000
--- a/third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_CONTROLLER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_CONTROLLER_H_
-
-#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "v8/include/v8.h"
-
-namespace blink {
-
-class ThreadState;
-
-// UnifiedHeapController ties V8's garbage collector to Oilpan for performing a
-// garbage collection across both managed heaps.
-//
-// Unified heap garbage collections are triggered by V8 and mark the full
-// transitive closure of V8 and Blink (Oilpan) objects. The garbage collection
-// is initially triggered by V8. Both collecters report live references using
-// the EmbedderHeapTracer APIs. V8 and Blink both run separate incremental
-// marking steps to compute their live closures, respectively. The final atomic
-// pause is then initiated by V8 and triggers a fixed-point computation between
-// V8 and Blink where both GCs report live references to each other and drain
-// their marking work lists until they are empty and no new references are
-// found.
-//
-// Oilpan does not consider references from DOM wrappers (JavaScript objects on
-// V8's heap) as roots for such garbage collections.
-class PLATFORM_EXPORT UnifiedHeapController final
-    : public v8::EmbedderHeapTracer,
-      public ThreadHeapStatsObserver {
- public:
-  UnifiedHeapController() = delete;
-  explicit UnifiedHeapController(ThreadState*);
-  UnifiedHeapController(const UnifiedHeapController&) = delete;
-  UnifiedHeapController& operator=(const UnifiedHeapController&) = delete;
-  ~UnifiedHeapController() override;
-
-  // v8::EmbedderHeapTracer implementation.
-  void TracePrologue(v8::EmbedderHeapTracer::TraceFlags) final;
-  void TraceEpilogue(v8::EmbedderHeapTracer::TraceSummary*) final;
-  void EnterFinalPause(EmbedderStackState) final;
-  void RegisterV8References(const std::vector<std::pair<void*, void*>>&) final;
-  bool AdvanceTracing(double) final;
-  bool IsTracingDone() final;
-
-  ThreadState* thread_state() const { return thread_state_; }
-
-  // ThreadHeapStatsObserver implementation.
-  void IncreaseAllocatedObjectSize(size_t) final;
-  void DecreaseAllocatedObjectSize(size_t) final;
-  // Not needed.
-  void ResetAllocatedObjectSize(size_t) final {}
-  void IncreaseAllocatedSpace(size_t) final {}
-  void DecreaseAllocatedSpace(size_t) final {}
-
- private:
-  void ReportBufferedAllocatedSizeIfPossible();
-
-  ThreadState* const thread_state_;
-  // Returns whether the Blink heap has been fully processed.
-  bool is_tracing_done_ = false;
-
-  // Buffered allocated size. Only positive values are forwarded to V8.
-  int64_t buffered_allocated_size_ = 0;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_CONTROLLER_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.cc b/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.cc
deleted file mode 100644
index 57c2e11d..0000000
--- a/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.cc
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h"
-
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
-#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/thread_state.h"
-#include "third_party/blink/renderer/platform/heap/unified_heap_controller.h"
-
-namespace blink {
-
-UnifiedHeapMarkingVisitorBase::UnifiedHeapMarkingVisitorBase(
-    ThreadState* thread_state,
-    v8::Isolate* isolate,
-    int task_id)
-    : isolate_(isolate),
-      controller_(thread_state->unified_heap_controller()),
-      v8_references_worklist_(thread_state->Heap().GetV8ReferencesWorklist(),
-                              task_id),
-      task_id_(task_id) {
-  DCHECK(controller_);
-}
-
-void UnifiedHeapMarkingVisitorBase::VisitImpl(
-    const TraceWrapperV8Reference<v8::Value>& v8_reference) {
-  DCHECK(isolate_);
-  if (v8_reference.IsEmptySafe())
-    return;
-  if (task_id_ != WorklistTaskId::MutatorThread) {
-    // This is a temporary solution. Pushing directly from concurrent threads
-    // to V8 marking worklist will currently result in data races. This
-    // solution guarantees correctness until we implement a long-term solution
-    // (i.e. allowing Oilpan concurrent threads concurrent-safe access to V8
-    // marking worklist without data-races)
-    v8_references_worklist_.Push(&v8_reference);
-    return;
-  }
-  controller_->RegisterEmbedderReference(
-      v8_reference.template Cast<v8::Data>().Get());
-}
-
-UnifiedHeapMarkingVisitor::UnifiedHeapMarkingVisitor(ThreadState* thread_state,
-                                                     MarkingMode mode,
-                                                     v8::Isolate* isolate)
-    : MarkingVisitor(thread_state, mode),
-      UnifiedHeapMarkingVisitorBase(thread_state,
-                                    isolate,
-                                    WorklistTaskId::MutatorThread) {}
-
-// static
-void UnifiedHeapMarkingVisitor::WriteBarrier(
-    const TraceWrapperV8Reference<v8::Value>& object) {
-  if (object.IsEmpty() || !ThreadState::IsAnyIncrementalMarking())
-    return;
-
-  ThreadState* thread_state = ThreadState::Current();
-  if (!thread_state->IsIncrementalMarking())
-    return;
-
-  thread_state->CurrentVisitor()->Trace(object);
-}
-
-// static
-void UnifiedHeapMarkingVisitor::WriteBarrier(
-    v8::Isolate* isolate,
-    v8::Local<v8::Object>&,
-    const WrapperTypeInfo* wrapper_type_info,
-    const void* object) {
-  // |object| here is either ScriptWrappable or CustomWrappable.
-
-  if (!ThreadState::IsAnyIncrementalMarking())
-    return;
-
-  ThreadState* thread_state = ThreadState::Current();
-  if (!thread_state->IsIncrementalMarking())
-    return;
-
-  wrapper_type_info->Trace(thread_state->CurrentVisitor(), object);
-}
-
-void UnifiedHeapMarkingVisitor::Visit(
-    const TraceWrapperV8Reference<v8::Value>& v) {
-  VisitImpl(v);
-}
-
-ConcurrentUnifiedHeapMarkingVisitor::ConcurrentUnifiedHeapMarkingVisitor(
-    ThreadState* thread_state,
-    MarkingMode mode,
-    v8::Isolate* isolate,
-    int task_id)
-    : ConcurrentMarkingVisitor(thread_state, mode, task_id),
-      UnifiedHeapMarkingVisitorBase(thread_state, isolate, task_id) {}
-
-void ConcurrentUnifiedHeapMarkingVisitor::FlushWorklists() {
-  ConcurrentMarkingVisitor::FlushWorklists();
-  v8_references_worklist_.FlushToGlobal();
-}
-
-void ConcurrentUnifiedHeapMarkingVisitor::Visit(
-    const TraceWrapperV8Reference<v8::Value>& v) {
-  VisitImpl(v);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h b/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h
deleted file mode 100644
index 6d0f475..0000000
--- a/third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_MARKING_VISITOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_MARKING_VISITOR_H_
-
-#include "third_party/blink/renderer/platform/heap/impl/marking_visitor.h"
-#include "v8/include/v8.h"
-
-namespace v8 {
-class EmbedderHeapTracer;
-}
-
-namespace blink {
-
-struct WrapperTypeInfo;
-
-// Marking visitor for unified heap garbage collections. Extends the regular
-// Oilpan marking visitor by also providing write barriers and visitation
-// methods that allow for announcing reachable objects to V8. Visitor can be
-// used from any thread.
-class PLATFORM_EXPORT UnifiedHeapMarkingVisitorBase {
- public:
-  UnifiedHeapMarkingVisitorBase(const UnifiedHeapMarkingVisitorBase&) = delete;
-  UnifiedHeapMarkingVisitorBase& operator=(
-      const UnifiedHeapMarkingVisitorBase&) = delete;
-  virtual ~UnifiedHeapMarkingVisitorBase() = default;
-
- protected:
-  UnifiedHeapMarkingVisitorBase(ThreadState*, v8::Isolate*, int);
-
-  // Visitation methods that announce reachable wrappers to V8.
-  void VisitImpl(const TraceWrapperV8Reference<v8::Value>&);
-
-  v8::Isolate* const isolate_;
-  v8::EmbedderHeapTracer* const controller_;
-  V8ReferencesWorklist::View v8_references_worklist_;
-
- private:
-  int task_id_;
-};
-
-// Same as the base visitor with the difference that it is bound to main thread.
-// Also implements various sorts of write barriers that should only be called
-// from the main thread.
-class PLATFORM_EXPORT UnifiedHeapMarkingVisitor
-    : public MarkingVisitor,
-      public UnifiedHeapMarkingVisitorBase {
- public:
-  // Write barriers for annotating a write during incremental marking.
-  static void WriteBarrier(const TraceWrapperV8Reference<v8::Value>&);
-  static void WriteBarrier(v8::Isolate*,
-                           v8::Local<v8::Object>&,
-                           const WrapperTypeInfo*,
-                           const void*);
-
-  UnifiedHeapMarkingVisitor(ThreadState*, MarkingMode, v8::Isolate*);
-  UnifiedHeapMarkingVisitor(const UnifiedHeapMarkingVisitor&) = delete;
-  UnifiedHeapMarkingVisitor& operator=(const UnifiedHeapMarkingVisitor&) =
-      delete;
-  ~UnifiedHeapMarkingVisitor() override = default;
-
- protected:
-  using Visitor::Visit;
-  void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
-};
-
-// Same as the base visitor with the difference that it is bound to a
-// concurrent thread.
-class PLATFORM_EXPORT ConcurrentUnifiedHeapMarkingVisitor
-    : public ConcurrentMarkingVisitor,
-      public UnifiedHeapMarkingVisitorBase {
- public:
-  ConcurrentUnifiedHeapMarkingVisitor(ThreadState*,
-                                      MarkingMode,
-                                      v8::Isolate*,
-                                      int task_id);
-  ConcurrentUnifiedHeapMarkingVisitor(
-      const ConcurrentUnifiedHeapMarkingVisitor&) = delete;
-  ConcurrentUnifiedHeapMarkingVisitor& operator=(
-      const ConcurrentUnifiedHeapMarkingVisitor&) = delete;
-  ~ConcurrentUnifiedHeapMarkingVisitor() override = default;
-
-  void FlushWorklists() override;
-
- protected:
-  using Visitor::Visit;
-  void Visit(const TraceWrapperV8Reference<v8::Value>&) final;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNIFIED_HEAP_MARKING_VISITOR_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.cc b/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.cc
deleted file mode 100644
index 5bd25b9..0000000
--- a/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h"
-
-#include "cstdint"
-
-#include "base/compiler_specific.h"
-
-#if HAS_FEATURE(address_sanitizer)
-#error "Must be built without asan."
-#endif
-
-namespace blink {
-namespace internal {
-
-namespace {
-constexpr int ToGCCMemoryOrder(std::memory_order order) {
-  switch (order) {
-    case std::memory_order_seq_cst:
-      return __ATOMIC_SEQ_CST;
-    case std::memory_order_relaxed:
-      return __ATOMIC_RELAXED;
-    case std::memory_order_acquire:
-      return __ATOMIC_ACQUIRE;
-    case std::memory_order_release:
-      return __ATOMIC_RELEASE;
-    case std::memory_order_acq_rel:
-      return __ATOMIC_ACQ_REL;
-    case std::memory_order_consume:
-      return __ATOMIC_CONSUME;
-  }
-}
-}  // namespace
-
-template <typename T>
-void UnsanitizedAtomic<T>::store(T desired, std::memory_order order) {
-  __atomic_store(&value_, &desired, ToGCCMemoryOrder(order));
-}
-
-template <typename T>
-T UnsanitizedAtomic<T>::load(std::memory_order order) const {
-  T result;
-  __atomic_load(&value_, &result, ToGCCMemoryOrder(order));
-  return result;
-}
-
-template <typename T>
-bool UnsanitizedAtomic<T>::compare_exchange_strong(T& expected,
-                                                   T desired,
-                                                   std::memory_order order) {
-  return compare_exchange_strong(expected, desired, order, order);
-}
-
-template <typename T>
-bool UnsanitizedAtomic<T>::compare_exchange_strong(
-    T& expected,
-    T desired,
-    std::memory_order succ_order,
-    std::memory_order fail_order) {
-  return __atomic_compare_exchange(&value_, &expected, &desired, false,
-                                   ToGCCMemoryOrder(succ_order),
-                                   ToGCCMemoryOrder(fail_order));
-}
-
-template <typename T>
-bool UnsanitizedAtomic<T>::compare_exchange_weak(T& expected,
-                                                 T desired,
-                                                 std::memory_order order) {
-  return compare_exchange_weak(expected, desired, order, order);
-}
-
-template <typename T>
-bool UnsanitizedAtomic<T>::compare_exchange_weak(T& expected,
-                                                 T desired,
-                                                 std::memory_order succ_order,
-                                                 std::memory_order fail_order) {
-  return __atomic_compare_exchange(&value_, &expected, &desired, true,
-                                   ToGCCMemoryOrder(succ_order),
-                                   ToGCCMemoryOrder(fail_order));
-}
-
-template class PLATFORM_EXPORT UnsanitizedAtomic<uint16_t>;
-
-}  // namespace internal
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h b/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h
deleted file mode 100644
index 7c6828d..0000000
--- a/third_party/blink/renderer/platform/heap/impl/unsanitized_atomic.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNSANITIZED_ATOMIC_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNSANITIZED_ATOMIC_H_
-
-#include <atomic>
-
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-namespace internal {
-
-// Simple wrapper for std::atomic<> that makes sure that accesses to underlying
-// data are not sanitized. This is needed because the no_sanitize_address
-// attribute doesn't propagate down to callees. Must be used with care.
-// Currently is only used to access poisoned HeapObjectHeader. For derived or
-// user types an explicit instantiation must be added to unsanitized_atomic.cc.
-template <typename T>
-class PLATFORM_EXPORT UnsanitizedAtomic final {
- public:
-  UnsanitizedAtomic() = default;
-  explicit UnsanitizedAtomic(T value) : value_(value) {}
-
-  void store(T, std::memory_order = std::memory_order_seq_cst);
-  T load(std::memory_order = std::memory_order_seq_cst) const;
-
-  bool compare_exchange_strong(T&,
-                               T,
-                               std::memory_order = std::memory_order_seq_cst);
-  bool compare_exchange_strong(T&, T, std::memory_order, std::memory_order);
-
-  bool compare_exchange_weak(T&,
-                             T,
-                             std::memory_order = std::memory_order_seq_cst);
-  bool compare_exchange_weak(T&, T, std::memory_order, std::memory_order);
-
- private:
-  T value_;
-};
-
-template <typename T>
-auto* AsUnsanitizedAtomic(T* ptr) {
-#if defined(ADDRESS_SANITIZER)
-  return reinterpret_cast<UnsanitizedAtomic<T>*>(ptr);
-#else
-  return WTF::AsAtomicPtr(ptr);
-#endif
-}
-
-template <typename T>
-const auto* AsUnsanitizedAtomic(const T* ptr) {
-#if defined(ADDRESS_SANITIZER)
-  return reinterpret_cast<const UnsanitizedAtomic<T>*>(ptr);
-#else
-  return WTF::AsAtomicPtr(ptr);
-#endif
-}
-
-}  // namespace internal
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_UNSANITIZED_ATOMIC_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/visitor.h b/third_party/blink/renderer/platform/heap/impl/visitor.h
deleted file mode 100644
index 8b16937..0000000
--- a/third_party/blink/renderer/platform/heap/impl/visitor.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_VISITOR_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_VISITOR_H_
-
-#include <memory>
-#include "third_party/blink/renderer/platform/heap/blink_gc.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/forward.h"
-#include "third_party/blink/renderer/platform/wtf/hash_traits.h"
-#include "third_party/blink/renderer/platform/wtf/type_traits.h"
-
-namespace base {
-class Location;
-}
-
-namespace v8 {
-class Value;
-}
-
-namespace blink {
-
-class LivenessBroker;
-template <typename T>
-struct TraceTrait;
-class ThreadState;
-class Visitor;
-template <typename T>
-class TraceWrapperV8Reference;
-
-// The TraceMethodDelegate is used to convert a trace method for type T to a
-// TraceCallback.  This allows us to pass a type's trace method as a parameter
-// to the PersistentNode constructor. The PersistentNode constructor needs the
-// specific trace method due an issue with the Windows compiler which
-// instantiates even unused variables. This causes problems
-// in header files where we have only forward declarations of classes.
-//
-// This interface is safe to use on concurrent threads. All accesses (reads)
-// from member are done atomically.
-template <typename T, void (T::*method)(Visitor*) const>
-struct TraceMethodDelegate {
-  STATIC_ONLY(TraceMethodDelegate);
-  static void Trampoline(Visitor* visitor, const void* self) {
-    (reinterpret_cast<const T*>(self)->*method)(visitor);
-  }
-};
-
-template <typename T, void (T::*method)(const LivenessBroker&)>
-struct WeakCallbackMethodDelegate {
-  STATIC_ONLY(WeakCallbackMethodDelegate);
-  static void Trampoline(const LivenessBroker& info, const void* self) {
-    (reinterpret_cast<T*>(const_cast<void*>(self))->*method)(info);
-  }
-};
-
-// Visitor is used to traverse Oilpan's object graph.
-class PLATFORM_EXPORT Visitor {
-  USING_FAST_MALLOC(Visitor);
-
- public:
-  explicit Visitor(ThreadState* state) : state_(state) {}
-  virtual ~Visitor() = default;
-
-  inline ThreadState* State() const { return state_; }
-  inline ThreadHeap& Heap() const { return state_->Heap(); }
-
-  // Static visitor implementation forwarding to dynamic interface.
-
-  template <typename T>
-  void TraceRoot(const T* t, const base::Location& location) {
-    static_assert(sizeof(T), "T must be fully defined");
-    static_assert(IsGarbageCollectedType<T>::value,
-                  "T needs to be a garbage collected object");
-    if (!t)
-      return;
-    VisitRoot(t, TraceDescriptorFor(t), location);
-  }
-
-  template <typename T>
-  void Trace(const Member<T>& t) {
-    const T* value = t.GetSafe();
-
-    DCHECK(!Member<T>::IsMemberHashTableDeletedValue(value));
-
-    Trace(value);
-  }
-
-  // TraceStrongly strongifies WeakMembers.
-  template <typename T>
-  ALWAYS_INLINE void TraceStrongly(const WeakMember<T>& t) {
-    const T* value = t.GetSafe();
-
-    DCHECK(!WeakMember<T>::IsMemberHashTableDeletedValue(value));
-
-    Trace<T>(value);
-  }
-  // Fallback methods used only when we need to trace raw pointers of T. This is
-  // the case when a member is a union where we do not support members.
-  template <typename T>
-  void Trace(T* t) {
-    Trace(const_cast<const T*>(t));
-  }
-  template <typename T>
-  void Trace(const T* t) {
-    static_assert(sizeof(T), "T must be fully defined");
-    static_assert(IsGarbageCollectedType<T>::value,
-                  "T needs to be a garbage collected object");
-    if (!t)
-      return;
-    Visit(t, TraceDescriptorFor(t));
-  }
-
-  // WeakMember version of the templated trace method. It doesn't keep
-  // the traced thing alive, but will write null to the WeakMember later
-  // if the pointed-to object is dead. It's lying for this to be const,
-  // but the overloading resolver prioritizes constness too high when
-  // picking the correct overload, so all these trace methods have to have
-  // the same constness on their argument to allow the type to decide.
-  template <typename T>
-  void Trace(const WeakMember<T>& weak_member) {
-    static_assert(sizeof(T), "T must be fully defined");
-    static_assert(IsGarbageCollectedType<T>::value,
-                  "T needs to be a garbage collected object");
-
-    const T* value = weak_member.GetSafe();
-
-    if (!value)
-      return;
-
-    DCHECK(!WeakMember<T>::IsMemberHashTableDeletedValue(value));
-    VisitWeak(value, &weak_member, TraceDescriptorFor(value),
-              &HandleWeakCell<T>);
-  }
-
-  // Fallback trace method for part objects to allow individual trace methods
-  // to trace through a part object with visitor->trace(m_partObject). This
-  // takes a const argument, because otherwise it will match too eagerly: a
-  // non-const argument would match a non-const Vector<T>& argument better
-  // than the specialization that takes const Vector<T>&. For a similar reason,
-  // the other specializations take a const argument even though they are
-  // usually used with non-const arguments, otherwise this function would match
-  // too well.
-  template <typename T>
-  void Trace(const T& t) {
-    static_assert(sizeof(T), "T must be fully defined");
-    if (std::is_polymorphic<T>::value) {
-      const intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t);
-      if (!vtable)
-        return;
-    }
-    TraceTrait<T>::Trace(this, &t);
-  }
-
-  template <typename T, typename U>
-  void TraceEphemeron(const WeakMember<T>& key, const U* value) {
-    const T* t = key.GetSafe();
-    if (!t)
-      return;
-    VisitEphemeron(TraceDescriptorFor(t).base_object_payload,
-                   TraceDescriptorFor(value));
-  }
-
-  template <typename T>
-  void TraceWeakContainer(const T* object,
-                          const T* const* slot,
-                          TraceDescriptor strong_desc,
-                          TraceDescriptor weak_dec,
-                          WeakCallback weak_callback,
-                          const void* weak_callback_parameter) {
-    static_assert(sizeof(T), "T must be fully defined");
-    static_assert(IsGarbageCollectedType<T>::value,
-                  "T needs to be a garbage collected object");
-    VisitWeakContainer(reinterpret_cast<const void*>(object),
-                       reinterpret_cast<const void* const*>(slot), strong_desc,
-                       weak_dec, weak_callback, weak_callback_parameter);
-  }
-
-  template <typename T>
-  void TraceMovablePointer(const T* const* slot) {
-    RegisterMovableSlot(reinterpret_cast<const void* const*>(slot));
-  }
-
-  // Cross-component tracing interface.
-  template <typename V8Type>
-  void Trace(const TraceWrapperV8Reference<V8Type>& v8reference) {
-    TraceV8ReferenceImpl(v8reference);
-  }
-
-  // Dynamic visitor interface.
-
-  // Adds a |callback| that is invoked with |parameter| after liveness has been
-  // computed on the whole object graph. The |callback| may use the provided
-  // |LivenessBroker| to determine whether an object is considered alive or
-  // dead.
-  //
-  // - Upon returning from the callback all references to dead objects must have
-  //   been cleared.
-  // - Any operation that extends the object graph, including allocation
-  //   or reviving objects, is prohibited.
-  // - Clearing out pointers is allowed.
-  // - Removing elements from heap collections is allowed as these collections
-  //   are aware of custom weakness and won't resize their backings.
-  virtual void RegisterWeakCallback(WeakCallback callback,
-                                    const void* parameter) {}
-
-  // Registers an instance method using |RegisterWeakCallback|. See description
-  // below.
-  template <typename T, void (T::*method)(const LivenessBroker&)>
-  void RegisterWeakCallbackMethod(const T* obj) {
-    RegisterWeakCallback(&WeakCallbackMethodDelegate<T, method>::Trampoline,
-                         obj);
-  }
-
-  // Returns whether the visitor is used in a concurrent setting.
-  virtual bool IsConcurrent() const { return false; }
-
-  // Defers invoking |desc| to the main thread when running concurrently.
-  // Returns true if |desc| has been queued for later processing and false if
-  // running in a non-concurrent setting.
-  //
-  // This can be used to defer processing data structures to the main thread
-  // when support for concurrent processing is missing.
-  virtual bool DeferredTraceIfConcurrent(TraceDescriptor, size_t) {
-    return false;
-  }
-
- protected:
-  // Visits an object through a strong reference.
-  virtual void Visit(const void*, TraceDescriptor) {}
-
-  // Visits an object through a weak reference.
-  virtual void VisitWeak(const void*,
-                         const void*,
-                         TraceDescriptor,
-                         WeakCallback) {}
-
-  // Visits cross-component references to V8.
-  virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) {}
-
-  virtual void VisitRoot(const void* t,
-                         TraceDescriptor desc,
-                         const base::Location&) {
-    Visit(t, desc);
-  }
-
-  // Visits ephemeron pairs which are a combination of weak and strong keys and
-  // values.
-  virtual void VisitEphemeron(const void*, TraceDescriptor) {}
-
-  // Visits a container |object| holding ephemeron pairs held from |slot|.  The
-  // descriptor |strong_desc| can be used to enforce strong treatment of
-  // |object|. The |weak_desc| descriptor is invoked repeatedly until no
-  // more new objects are found. It is expected that |weak_desc| processing
-  // ultimately yields in a call to VisitEphemeron. After marking all reachable
-  // objects, |weak_callback| is invoked with |weak_callback_parameter|. It is
-  // expected that this callback is used to reset non-live entries in the
-  // ephemeron container.
-  virtual void VisitWeakContainer(const void* object,
-                                  const void* const* slot,
-                                  TraceDescriptor strong_desc,
-                                  TraceDescriptor weak_desc,
-                                  WeakCallback weak_callback,
-                                  const void* weak_callback_parameter) {}
-
-  virtual void RegisterMovableSlot(const void* const* slot) {}
-
-  template <typename T>
-  static TraceDescriptor TraceDescriptorFor(const T* traceable) {
-    return TraceTrait<T>::GetTraceDescriptor(traceable);
-  }
-
- private:
-  template <typename V8Type>
-  void TraceV8ReferenceImpl(
-      const TraceWrapperV8Reference<V8Type>& v8reference,
-      std::enable_if_t<std::is_base_of<v8::Value, V8Type>::value>* = nullptr) {
-    Visit(v8reference.template Cast<v8::Value>());
-  }
-
-  template <typename V8Type>
-  void TraceV8ReferenceImpl(
-      const TraceWrapperV8Reference<V8Type>& v8reference,
-      std::enable_if_t<!std::is_base_of<v8::Value, V8Type>::value &&
-                       std::is_base_of<v8::Data, V8Type>::value>* = nullptr) {
-    // The following cast is technically unsafe but works as the memory layout
-    // for the references is the same and V8 only needs to know that the value
-    // is a heap object.
-    Visit(v8reference.template UnsafeCast<v8::Value>());
-  }
-
-  template <typename T>
-  static void HandleWeakCell(const LivenessBroker&, const void*);
-
-  ThreadState* const state_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_VISITOR_H_
diff --git a/third_party/blink/renderer/platform/heap/impl/worklist.h b/third_party/blink/renderer/platform/heap/impl/worklist.h
deleted file mode 100644
index a26c6189..0000000
--- a/third_party/blink/renderer/platform/heap/impl/worklist.h
+++ /dev/null
@@ -1,469 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Copied and adopted from V8.
-//
-// Copyright 2017 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_WORKLIST_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_WORKLIST_H_
-
-#include <atomic>
-#include <cstddef>
-#include <utility>
-
-#include "base/atomicops.h"
-#include "base/check_op.h"
-#include "base/compiler_specific.h"
-#include "base/gtest_prod_util.h"
-#include "base/synchronization/lock.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace blink {
-
-// A concurrent worklist based on segments. Each tasks gets private
-// push and pop segments. Empty pop segments are swapped with their
-// corresponding push segments. Full push segments are published to a global
-// pool of segments and replaced with empty segments.
-//
-// Work stealing is best effort, i.e., there is no way to inform other tasks
-// of the need of items.
-template <typename _EntryType, int segment_size, int num_tasks = 4>
-class Worklist {
-  USING_FAST_MALLOC(Worklist);
-  using WorklistType = Worklist<_EntryType, segment_size, num_tasks>;
-
- public:
-  using EntryType = _EntryType;
-
-  static constexpr int kNumTasks = num_tasks;
-
-  class View {
-    DISALLOW_NEW();
-
-   public:
-    View(WorklistType* worklist, int task_id)
-        : worklist_(worklist), task_id_(task_id) {}
-
-    // Pushes an entry onto the worklist.
-    bool Push(EntryType entry) { return worklist_->Push(task_id_, entry); }
-
-    // Pops an entry from the worklist.
-    bool Pop(EntryType* entry) { return worklist_->Pop(task_id_, entry); }
-
-    // Returns true if the local portion of the worklist is empty.
-    bool IsLocalEmpty() const { return worklist_->IsLocalEmpty(task_id_); }
-
-    // Returns true if the worklist is empty. Can only be used from the main
-    // thread without concurrent access.
-    bool IsGlobalEmpty() const { return worklist_->IsGlobalEmpty(); }
-
-    bool IsGlobalPoolEmpty() const { return worklist_->IsGlobalPoolEmpty(); }
-
-    // Returns true if the local portion and the global pool are empty (i.e.
-    // whether the current view cannot pop anymore).
-    bool IsLocalViewEmpty() const {
-      return worklist_->IsLocalViewEmpty(task_id_);
-    }
-
-    void FlushToGlobal() { worklist_->FlushToGlobal(task_id_); }
-
-    size_t LocalPushSegmentSize() const {
-      return worklist_->LocalPushSegmentSize(task_id_);
-    }
-
-   private:
-    WorklistType* const worklist_;
-    const int task_id_;
-  };
-
-  static constexpr size_t kSegmentCapacity = segment_size;
-
-  Worklist() {
-    for (int i = 0; i < kNumTasks; i++) {
-      private_push_segment(i) = NewSegment();
-      private_pop_segment(i) = NewSegment();
-    }
-  }
-
-  ~Worklist() {
-    CHECK(IsGlobalEmpty());
-    for (int i = 0; i < kNumTasks; i++) {
-      DCHECK(private_push_segment(i));
-      DCHECK(private_pop_segment(i));
-      delete private_push_segment(i);
-      delete private_pop_segment(i);
-    }
-  }
-
-  bool Push(int task_id, EntryType entry) {
-    DCHECK_LT(task_id, kNumTasks);
-    DCHECK(private_push_segment(task_id));
-    if (!private_push_segment(task_id)->Push(entry)) {
-      PublishPushSegmentToGlobal(task_id);
-      bool success = private_push_segment(task_id)->Push(entry);
-      ANALYZER_ALLOW_UNUSED(success);
-      DCHECK(success);
-    }
-    return true;
-  }
-
-  bool Pop(int task_id, EntryType* entry) {
-    DCHECK_LT(task_id, kNumTasks);
-    DCHECK(private_pop_segment(task_id));
-    if (!private_pop_segment(task_id)->Pop(entry)) {
-      if (!private_push_segment(task_id)->IsEmpty()) {
-        Segment* tmp = private_pop_segment(task_id);
-        private_pop_segment(task_id) = private_push_segment(task_id);
-        private_push_segment(task_id) = tmp;
-      } else if (!StealPopSegmentFromGlobal(task_id)) {
-        return false;
-      }
-      bool success = private_pop_segment(task_id)->Pop(entry);
-      ANALYZER_ALLOW_UNUSED(success);
-      DCHECK(success);
-    }
-    return true;
-  }
-
-  bool IsLocalEmpty(int task_id) const {
-    return private_pop_segment(task_id)->IsEmpty() &&
-           private_push_segment(task_id)->IsEmpty();
-  }
-
-  bool IsGlobalPoolEmpty() const { return global_pool_.IsEmpty(); }
-
-  bool IsGlobalEmpty() const {
-    for (int i = 0; i < kNumTasks; i++) {
-      if (!IsLocalEmpty(i))
-        return false;
-    }
-    return global_pool_.IsEmpty();
-  }
-
-  bool IsLocalViewEmpty(int task_id) const {
-    return IsLocalEmpty(task_id) && IsGlobalPoolEmpty();
-  }
-
-  size_t LocalSize(int task_id) const {
-    return private_pop_segment(task_id)->Size() +
-           private_push_segment(task_id)->Size();
-  }
-
-  // Thread-safe but may return an outdated result.
-  size_t GlobalPoolSize() const { return global_pool_.Size(); }
-
-  size_t LocalPushSegmentSize(int task_id) const {
-    return private_push_segment(task_id)->Size();
-  }
-
-  // Clears all segments. Frees the global segment pool.
-  //
-  // Assumes that no other tasks are running.
-  void Clear() {
-    for (int i = 0; i < kNumTasks; i++) {
-      private_pop_segment(i)->Clear();
-      private_push_segment(i)->Clear();
-    }
-    global_pool_.Clear();
-  }
-
-  // Calls the specified callback on each element of the deques and replaces
-  // the element with the result of the callback.
-  // The signature of the callback is
-  //   bool Callback(EntryType old, EntryType* new).
-  // If the callback returns |false| then the element is removed from the
-  // worklist. Otherwise the |new| entry is updated.
-  //
-  // Assumes that no other tasks are running.
-  template <typename Callback>
-  void Update(Callback callback) {
-    for (int i = 0; i < kNumTasks; i++) {
-      private_pop_segment(i)->Update(callback);
-      private_push_segment(i)->Update(callback);
-    }
-    global_pool_.Update(callback);
-  }
-
-  template <typename Callback>
-  void IterateGlobalPool(Callback callback) {
-    global_pool_.Iterate(callback);
-  }
-
-  void FlushToGlobal(int task_id) {
-    PublishPushSegmentToGlobal(task_id);
-    PublishPopSegmentToGlobal(task_id);
-  }
-
-  void MergeGlobalPool(Worklist* other) {
-    global_pool_.Merge(&other->global_pool_);
-  }
-
-  size_t SizeForTesting() {
-    size_t size = global_pool_.SizeForTesting();
-    for (int i = 0; i < kNumTasks; i++) {
-      size += private_pop_segment(i)->Size() + private_push_segment(i)->Size();
-    }
-    return size;
-  }
-
- private:
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentCreate);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentPush);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentPushPop);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentIsEmpty);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentIsFull);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentClear);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentFullPushFails);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentEmptyPopFails);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentUpdateFalse);
-  FRIEND_TEST_ALL_PREFIXES(WorklistTest, SegmentUpdate);
-
-  class Segment {
-    USING_FAST_MALLOC(Segment);
-
-   public:
-    static const size_t kCapacity = kSegmentCapacity;
-
-    Segment() : index_(0) {}
-
-    bool Push(EntryType entry) {
-      if (IsFull())
-        return false;
-      entries_[index_++] = entry;
-      return true;
-    }
-
-    bool Pop(EntryType* entry) {
-      if (IsEmpty())
-        return false;
-      *entry = entries_[--index_];
-      return true;
-    }
-
-    size_t Size() const { return index_; }
-    bool IsEmpty() const { return index_ == 0; }
-    bool IsFull() const { return index_ == kCapacity; }
-    void Clear() { index_ = 0; }
-
-    template <typename Callback>
-    void Update(Callback callback) {
-      size_t new_index = 0;
-      for (size_t i = 0; i < index_; i++) {
-        if (callback(entries_[i], &entries_[new_index])) {
-          new_index++;
-        }
-      }
-      index_ = new_index;
-    }
-
-    template <typename Callback>
-    void Iterate(Callback callback) const {
-      for (size_t i = 0; i < index_; i++) {
-        callback(entries_[i]);
-      }
-    }
-
-    Segment* next() const { return next_; }
-    void set_next(Segment* segment) { next_ = segment; }
-
-   private:
-    Segment* next_;
-    size_t index_;
-    EntryType entries_[kCapacity];
-  };
-
-  struct PrivateSegmentHolder {
-    Segment* private_push_segment;
-    Segment* private_pop_segment;
-    char cache_line_padding[64];
-  };
-
-  class GlobalPool {
-    DISALLOW_NEW();
-
-   public:
-    GlobalPool() : top_(nullptr) {}
-
-    inline void Push(Segment* segment) {
-      base::AutoLock guard(lock_);
-      segment->set_next(top_);
-      set_top(segment);
-      size_.fetch_add(1, std::memory_order_relaxed);
-    }
-
-    inline bool Pop(Segment** segment) {
-      base::AutoLock guard(lock_);
-      if (top_) {
-        DCHECK_LT(0U, size_);
-        size_.fetch_sub(1, std::memory_order_relaxed);
-        *segment = top_;
-        set_top(top_->next());
-        return true;
-      }
-      return false;
-    }
-
-    inline bool IsEmpty() const {
-      return base::subtle::NoBarrier_Load(
-                 reinterpret_cast<const base::subtle::AtomicWord*>(&top_)) == 0;
-    }
-
-    inline size_t Size() const {
-      // It is safe to read |size_| without a lock since this variable is
-      // atomic, keeping in mind that threads may not immediately see the new
-      // value when it is updated.
-      return TS_UNCHECKED_READ(size_).load(std::memory_order_relaxed);
-    }
-
-    void Clear() {
-      base::AutoLock guard(lock_);
-      size_.store(0, std::memory_order_relaxed);
-      Segment* current = top_;
-      while (current) {
-        Segment* tmp = current;
-        current = current->next();
-        delete tmp;
-      }
-      set_top(nullptr);
-    }
-
-    // See Worklist::Update.
-    template <typename Callback>
-    void Update(Callback callback) {
-      base::AutoLock guard(lock_);
-      Segment* prev = nullptr;
-      Segment* current = top_;
-      while (current) {
-        current->Update(callback);
-        if (current->IsEmpty()) {
-          DCHECK_LT(0U, size_);
-          size_.fetch_sub(1, std::memory_order_relaxed);
-          if (!prev) {
-            top_ = current->next();
-          } else {
-            prev->set_next(current->next());
-          }
-          Segment* tmp = current;
-          current = current->next();
-          delete tmp;
-        } else {
-          prev = current;
-          current = current->next();
-        }
-      }
-    }
-
-    // See Worklist::Iterate.
-    template <typename Callback>
-    void Iterate(Callback callback) {
-      base::AutoLock guard(lock_);
-      for (Segment* current = top_; current; current = current->next()) {
-        current->Iterate(callback);
-      }
-    }
-
-    void Merge(GlobalPool* other) {
-      Segment* top = nullptr;
-      size_t other_size = 0;
-      {
-        base::AutoLock guard(other->lock_);
-        if (!other->top_)
-          return;
-        top = other->top_;
-        other_size = other->size_.load(std::memory_order_relaxed);
-        other->size_.store(0, std::memory_order_relaxed);
-        other->set_top(nullptr);
-      }
-
-      Segment* end = top;
-      while (end->next())
-        end = end->next();
-
-      {
-        base::AutoLock guard(lock_);
-        size_.fetch_add(other_size, std::memory_order_relaxed);
-        end->set_next(top_);
-        set_top(top);
-      }
-    }
-
-    size_t SizeForTesting() {
-      size_t size = 0;
-      base::AutoLock guard(lock_);
-      for (Segment* current = top_; current; current = current->next())
-        size += current->Size();
-      return size;
-    }
-
-   private:
-    void set_top(Segment* segment) {
-      return base::subtle::NoBarrier_Store(
-          reinterpret_cast<base::subtle::AtomicWord*>(&top_),
-          reinterpret_cast<base::subtle::AtomicWord>(segment));
-    }
-
-    mutable base::Lock lock_;
-    Segment* top_ GUARDED_BY(lock_);
-    std::atomic<size_t> size_ GUARDED_BY(lock_){0};
-  };
-
-  ALWAYS_INLINE Segment*& private_push_segment(int task_id) {
-    return private_segments_[task_id].private_push_segment;
-  }
-
-  ALWAYS_INLINE Segment* const& private_push_segment(int task_id) const {
-    return const_cast<const PrivateSegmentHolder*>(private_segments_)[task_id]
-        .private_push_segment;
-  }
-
-  ALWAYS_INLINE Segment*& private_pop_segment(int task_id) {
-    return private_segments_[task_id].private_pop_segment;
-  }
-
-  ALWAYS_INLINE Segment* const& private_pop_segment(int task_id) const {
-    return const_cast<const PrivateSegmentHolder*>(private_segments_)[task_id]
-        .private_pop_segment;
-  }
-
-  ALWAYS_INLINE void PublishPushSegmentToGlobal(int task_id) {
-    if (!private_push_segment(task_id)->IsEmpty()) {
-      global_pool_.Push(private_push_segment(task_id));
-      private_push_segment(task_id) = NewSegment();
-    }
-  }
-
-  ALWAYS_INLINE void PublishPopSegmentToGlobal(int task_id) {
-    if (!private_pop_segment(task_id)->IsEmpty()) {
-      global_pool_.Push(private_pop_segment(task_id));
-      private_pop_segment(task_id) = NewSegment();
-    }
-  }
-
-  ALWAYS_INLINE bool StealPopSegmentFromGlobal(int task_id) {
-    if (global_pool_.IsEmpty())
-      return false;
-    Segment* new_segment = nullptr;
-    if (global_pool_.Pop(&new_segment)) {
-      delete private_pop_segment(task_id);
-      private_pop_segment(task_id) = new_segment;
-      return true;
-    }
-    return false;
-  }
-
-  ALWAYS_INLINE Segment* NewSegment() {
-    // Bottleneck for filtering in crash dumps.
-    return new Segment();
-  }
-
-  PrivateSegmentHolder private_segments_[kNumTasks];
-  GlobalPool global_pool_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_IMPL_WORKLIST_H_
diff --git a/third_party/blink/renderer/platform/heap/member.h b/third_party/blink/renderer/platform/heap/member.h
index 68ec7c42..b8487f1a 100644
--- a/third_party/blink/renderer/platform/heap/member.h
+++ b/third_party/blink/renderer/platform/heap/member.h
@@ -5,16 +5,11 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MEMBER_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_MEMBER_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/hash_functions.h"
 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
 #include "third_party/blink/renderer/platform/wtf/type_traits.h"
 
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/member.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/member.h"
-#endif  // !USE_V8_OILPAN
 
 namespace blink {
 
@@ -102,19 +97,11 @@
   }
 
   static void ConstructDeletedValue(MemberType& slot, bool) {
-#if BUILDFLAG(USE_V8_OILPAN)
     slot = cppgc::kSentinelPointer;
-#else   // !USE_V8_OILPAN
-    slot = WTF::kHashTableDeletedValue;
-#endif  // !USE_V8_OILPAN
   }
 
   static bool IsDeletedValue(const MemberType& value) {
-#if BUILDFLAG(USE_V8_OILPAN)
     return value.Get() == cppgc::kSentinelPointer;
-#else   // !USE_V8_OILPAN
-    return value.IsHashTableDeletedValue();
-#endif  // !USE_V8_OILPAN
   }
 };
 
diff --git a/third_party/blink/renderer/platform/heap/persistent.h b/third_party/blink/renderer/platform/heap/persistent.h
index 91e83824..8ad0b11 100644
--- a/third_party/blink/renderer/platform/heap/persistent.h
+++ b/third_party/blink/renderer/platform/heap/persistent.h
@@ -6,16 +6,11 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PERSISTENT_H_
 
 #include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/cross_thread_copier.h"
 #include "third_party/blink/renderer/platform/wtf/type_traits.h"
 #include "third_party/blink/renderer/platform/wtf/vector_traits.h"
 
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/persistent.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/persistent.h"
-#endif  // !USE_V8_OILPAN
 
 namespace blink {
 
@@ -85,19 +80,11 @@
   static PeekOutType Peek(const PersistentType& value) { return value; }
 
   static void ConstructDeletedValue(PersistentType& slot, bool) {
-#if BUILDFLAG(USE_V8_OILPAN)
     new (&slot) PersistentType(cppgc::kSentinelPointer);
-#else   // !USE_V8_OILPAN
-    new (&slot) PersistentType(WTF::kHashTableDeletedValue);
-#endif  // !USE_V8_OILPAN
   }
 
   static bool IsDeletedValue(const PersistentType& value) {
-#if BUILDFLAG(USE_V8_OILPAN)
     return value.Get() == cppgc::kSentinelPointer;
-#else   // !USE_V8_OILPAN
-    return value.IsHashTableDeletedValue();
-#endif  // !USE_V8_OILPAN
   }
 };
 
diff --git a/third_party/blink/renderer/platform/heap/process_heap.h b/third_party/blink/renderer/platform/heap/process_heap.h
index 4993d40..d94b420 100644
--- a/third_party/blink/renderer/platform/heap/process_heap.h
+++ b/third_party/blink/renderer/platform/heap/process_heap.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PROCESS_HEAP_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PROCESS_HEAP_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/process_heap.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/process_heap.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_PROCESS_HEAP_H_
diff --git a/third_party/blink/renderer/platform/heap/test/allocation_perftest.cc b/third_party/blink/renderer/platform/heap/test/allocation_perftest.cc
index 85cfa0f..fe76ac4 100644
--- a/third_party/blink/renderer/platform/heap/test/allocation_perftest.cc
+++ b/third_party/blink/renderer/platform/heap/test/allocation_perftest.cc
@@ -25,10 +25,8 @@
 };
 
 class LargeObject final : public GarbageCollected<LargeObject> {
-#if BUILDFLAG(USE_V8_OILPAN)
   static constexpr size_t kLargeObjectSizeThreshold =
       cppgc::internal::api_constants::kLargeObjectSizeThreshold;
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
  public:
   void Trace(Visitor*) const {}
   char padding[kLargeObjectSizeThreshold + 1];
diff --git a/third_party/blink/renderer/platform/heap/test/blink_gc_memory_dump_provider_test.cc b/third_party/blink/renderer/platform/heap/test/blink_gc_memory_dump_provider_test.cc
index 0c68f331..00d3633 100644
--- a/third_party/blink/renderer/platform/heap/test/blink_gc_memory_dump_provider_test.cc
+++ b/third_party/blink/renderer/platform/heap/test/blink_gc_memory_dump_provider_test.cc
@@ -10,10 +10,7 @@
 #include "third_party/blink/renderer/platform/heap/blink_gc.h"
 #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h"
 #include "third_party/blink/renderer/platform/wtf/threading.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/custom_spaces.h"
-#endif  // !USE_V8_OILPAN
 
 namespace blink {
 
@@ -52,7 +49,6 @@
 
 void CheckSpacesInDump(base::trace_event::ProcessMemoryDump& dump,
                        const std::string dump_prefix) {
-#if BUILDFLAG(USE_V8_OILPAN)
   size_t custom_space_count = 0;
   IterateMemoryDumps(
       dump, dump_prefix + "CustomSpace",
@@ -60,14 +56,6 @@
         custom_space_count++;
       });
   EXPECT_EQ(CustomSpaces::CreateCustomSpaces().size(), custom_space_count);
-#else  // !USE_V8_OILPAN
-#define CheckArena(name)                  \
-  EXPECT_NE(dump.allocator_dumps().end(), \
-            dump.allocator_dumps().find(dump_prefix + #name "Arena"));
-
-  FOR_EACH_ARENA(CheckArena)
-#undef CheckArena
-#endif  // !USE_V8_OILPAN
 }
 
 }  // namespace
@@ -137,13 +125,8 @@
           BlinkGCMemoryDumpProvider::HeapType::kBlinkWorkerThread));
   dump_provider->OnMemoryDump(args, dump.get());
 
-#if BUILDFLAG(USE_V8_OILPAN)
   const std::string worker_path_prefix = "blink_gc/workers";
   const std::string worker_path_suffix = "/heap";
-#else   // !USE_V8_OILPAN
-  const std::string worker_path_prefix = "blink_gc/workers/heap";
-  const std::string worker_path_suffix = "";
-#endif  // !USE_V8_OILPAN
 
   // Find worker suffix.
   std::string worker_suffix;
diff --git a/third_party/blink/renderer/platform/heap/test/heap_test.cc b/third_party/blink/renderer/platform/heap/test/heap_test.cc
index 026a6f1a..f22d1035 100644
--- a/third_party/blink/renderer/platform/heap/test/heap_test.cc
+++ b/third_party/blink/renderer/platform/heap/test/heap_test.cc
@@ -46,10 +46,7 @@
 #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
 #include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "v8/include/cppgc/internal/api-constants.h"
-#endif
 
 namespace blink {
 
@@ -615,14 +612,10 @@
 
 namespace {
 size_t GetOverallObjectSize() {
-#if BUILDFLAG(USE_V8_OILPAN)
   return ThreadState::Current()
       ->cpp_heap()
       .CollectStatistics(cppgc::HeapStatistics::DetailLevel::kDetailed)
       .used_size_bytes;
-#else   // !BUILDFLAG(USE_V8_OILPAN)
-  return ThreadState::Current()->Heap().ObjectPayloadSizeForTesting();
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
 }
 }  // namespace
 
@@ -901,10 +894,8 @@
 }  // namespace
 
 TEST_F(HeapTest, HeapVectorOnStackLargeObjectPageSized) {
-#if BUILDFLAG(USE_V8_OILPAN)
   static constexpr size_t kLargeObjectSizeThreshold =
       cppgc::internal::api_constants::kLargeObjectSizeThreshold;
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
   ClearOutOldGarbage();
   using Container = HeapVector<Member<IntWrapper>>;
   Container vector;
@@ -2815,11 +2806,7 @@
 }
 
 class AllocatesOnAssignment : public GarbageCollected<AllocatesOnAssignment> {
-#if BUILDFLAG(USE_V8_OILPAN)
   static constexpr auto kHashTableDeletedValue = cppgc::kSentinelPointer;
-#else   // !USE_V8_OILPAN
-  static constexpr auto kHashTableDeletedValue = WTF::kHashTableDeletedValue;
-#endif  // !USE_V8_OILPAN
 
  public:
   AllocatesOnAssignment(std::nullptr_t) : value_(nullptr) {}
@@ -2834,9 +2821,6 @@
   enum DeletedMarker { kDeletedValue };
 
   AllocatesOnAssignment(const AllocatesOnAssignment& other) {
-#if !BUILDFLAG(USE_V8_OILPAN)
-    DCHECK(!ThreadState::Current()->IsGCForbidden());
-#endif
     TestSupportingGC::ConservativelyCollectGarbage();
     value_ = MakeGarbageCollected<IntWrapper>(other.value_->Value());
   }
@@ -2845,11 +2829,7 @@
       : value_(kHashTableDeletedValue) {}
 
   inline bool IsDeleted() const {
-#if BUILDFLAG(USE_V8_OILPAN)
     return value_ == cppgc::kSentinelPointer;
-#else   // !USE_V8_OILPAN
-    return value_.IsHashTableDeletedValue();
-#endif  // !USE_V8_OILPAN
   }
 
   void Trace(Visitor* visitor) const { visitor->Trace(value_); }
@@ -3197,14 +3177,6 @@
 namespace {
 class FakeCSSValue : public GarbageCollected<FakeCSSValue> {
  public:
-#if !BUILDFLAG(USE_V8_OILPAN)
-  template <typename T>
-  static void* AllocateObject(size_t size) {
-    return ThreadState::Current()->Heap().AllocateOnArenaIndex(
-        ThreadState::Current(), size, BlinkGC::kCSSValueArenaIndex,
-        GCInfoTrait<GCInfoFoldedType<FakeCSSValue>>::Index(), "FakeCSSValue");
-  }
-#endif
   virtual void Trace(Visitor*) const {}
   char* Data() { return data_; }
 
@@ -3215,14 +3187,6 @@
 
 class FakeNode : public GarbageCollected<FakeNode> {
  public:
-#if !BUILDFLAG(USE_V8_OILPAN)
-  template <typename T>
-  static void* AllocateObject(size_t size) {
-    return ThreadState::Current()->Heap().AllocateOnArenaIndex(
-        ThreadState::Current(), size, BlinkGC::kNodeArenaIndex,
-        GCInfoTrait<GCInfoFoldedType<FakeNode>>::Index(), "FakeNode");
-  }
-#endif
   virtual void Trace(Visitor*) const {}
   char* Data() { return data_; }
 
@@ -3232,7 +3196,6 @@
 };
 }  // namespace
 
-#if BUILDFLAG(USE_V8_OILPAN)
 }  // namespace blink
 
 namespace cppgc {
@@ -3250,7 +3213,6 @@
 }  // namespace cppgc
 
 namespace blink {
-#endif
 
 TEST_F(HeapTest, CollectNodeAndCssStatistics) {
   PreciselyCollectGarbage();
diff --git a/third_party/blink/renderer/platform/heap/thread_state.h b/third_party/blink/renderer/platform/heap/thread_state.h
index eb763b5..0e077f4 100644
--- a/third_party/blink/renderer/platform/heap/thread_state.h
+++ b/third_party/blink/renderer/platform/heap/thread_state.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/thread_state.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_H_
diff --git a/third_party/blink/renderer/platform/heap/thread_state_scopes.h b/third_party/blink/renderer/platform/heap/thread_state_scopes.h
index 85e74893..9a64977 100644
--- a/third_party/blink/renderer/platform/heap/thread_state_scopes.h
+++ b/third_party/blink/renderer/platform/heap/thread_state_scopes.h
@@ -6,13 +6,8 @@
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_THREAD_STATE_SCOPES_H_
 
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/thread_state_scopes.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/thread_state_scopes.h"
-#endif  // !USE_V8_OILPAN
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/heap/trace_traits.h b/third_party/blink/renderer/platform/heap/trace_traits.h
index 76b89917..cb66498 100644
--- a/third_party/blink/renderer/platform/heap/trace_traits.h
+++ b/third_party/blink/renderer/platform/heap/trace_traits.h
@@ -8,14 +8,9 @@
 #include "third_party/blink/renderer/platform/heap/heap.h"
 #include "third_party/blink/renderer/platform/heap/member.h"
 #include "third_party/blink/renderer/platform/heap/visitor.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/hash_table.h"
 
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/trace_traits.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/trace_traits.h"
-#endif  // !USE_V8_OILPAN
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_controller.h b/third_party/blink/renderer/platform/heap/unified_heap_controller.h
index c1fd663..01ab304 100644
--- a/third_party/blink/renderer/platform/heap/unified_heap_controller.h
+++ b/third_party/blink/renderer/platform/heap/unified_heap_controller.h
@@ -5,10 +5,4 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_CONTROLLER_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_CONTROLLER_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if !BUILDFLAG(USE_V8_OILPAN)
-#include "third_party/blink/renderer/platform/heap/impl/unified_heap_controller.h"
-#endif  // !BUILDFLAG(USE_V8_OILPAN)
-
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_CONTROLLER_H_
diff --git a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
index 267ee32..3c1576e 100644
--- a/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
+++ b/third_party/blink/renderer/platform/heap/unified_heap_marking_visitor.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_MARKING_VISITOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_MARKING_VISITOR_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/unified_heap_marking_visitor.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/unified_heap_marking_visitor.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_UNIFIED_HEAP_MARKING_VISITOR_H_
diff --git a/third_party/blink/renderer/platform/heap/visitor.h b/third_party/blink/renderer/platform/heap/visitor.h
index 5ace61d..9fb80dc 100644
--- a/third_party/blink/renderer/platform/heap/visitor.h
+++ b/third_party/blink/renderer/platform/heap/visitor.h
@@ -5,12 +5,6 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_VISITOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_VISITOR_H_
 
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "third_party/blink/renderer/platform/heap/v8_wrapper/visitor.h"
-#else  // !USE_V8_OILPAN
-#include "third_party/blink/renderer/platform/heap/impl/visitor.h"
-#endif  // !USE_V8_OILPAN
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_VISITOR_H_
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
index 1902d1d..c9bbcf5 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_test.cc
@@ -14,7 +14,6 @@
 #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
 #include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h"
 #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
index 6bdd9d1..d29810f 100644
--- a/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
+++ b/third_party/blink/renderer/platform/mojo/heap_mojo_receiver_test.cc
@@ -15,7 +15,6 @@
 #include "third_party/blink/renderer/platform/mojo/heap_mojo_wrapper_mode.h"
 #include "third_party/blink/renderer/platform/mojo/mojo_binding_context.h"
 #include "third_party/blink/renderer/platform/testing/mock_context_lifecycle_notifier.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 
 namespace blink {
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 3c38e93..2396d6bd 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -432,6 +432,7 @@
     },
     {
       name: "ConditionalFocus",
+      origin_trial_feature_name: "ConditionalFocus",
       depends_on: ["GetDisplayMedia"],
       status: {"Android": "", "default": "experimental"},
     },
diff --git a/third_party/blink/renderer/platform/timer_test.cc b/third_party/blink/renderer/platform/timer_test.cc
index d752a84..924641f4 100644
--- a/third_party/blink/renderer/platform/timer_test.cc
+++ b/third_party/blink/renderer/platform/timer_test.cc
@@ -11,12 +11,12 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/platform.h"
+#include "third_party/blink/renderer/platform/heap/thread_state.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
 #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
 
 using base::sequence_manager::TaskQueue;
@@ -641,8 +641,7 @@
 }
 
 // TODO(1056170): Re-enable test.
-#if !BUILDFLAG(USE_V8_OILPAN)
-TEST_F(TimerTest, MarkOnHeapTimerAsUnreachable) {
+TEST_F(TimerTest, DISABLED_MarkOnHeapTimerAsUnreachable) {
   scoped_refptr<OnHeapTimerOwner::Record> record =
       OnHeapTimerOwner::Record::Create();
   Persistent<OnHeapTimerOwner> owner =
@@ -653,10 +652,12 @@
 
   owner = nullptr;
   // Explicit regular GC call to allow lazy sweeping.
-  ThreadState::Current()->CollectGarbageForTesting(
-      BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
-      BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
-      BlinkGC::GCReason::kForcedGCForTesting);
+  // TODO(1056170): Needs a specific forced GC call to be able to test the
+  // scenario below.
+  // ThreadState::Current()->CollectGarbageForTesting(
+  //     BlinkGC::CollectionType::kMajor, BlinkGC::kNoHeapPointersOnStack,
+  //     BlinkGC::kAtomicMarking, BlinkGC::kConcurrentAndLazySweeping,
+  //     BlinkGC::GCReason::kForcedGCForTesting);
   // Since the heap is laziy swept, owner is not yet destructed.
   EXPECT_FALSE(record->OwnerIsDestructed());
 
@@ -666,10 +667,9 @@
     platform_->RunUntilIdle();
     EXPECT_FALSE(record->TimerHasFired());
     EXPECT_FALSE(record->OwnerIsDestructed());
-    ThreadState::Current()->CompleteSweep();
+    // ThreadState::Current()->CompleteSweep();
   }
 }
-#endif  // !USE_V8_OILPAN
 
 namespace {
 
diff --git a/third_party/blink/renderer/platform/wtf/BUILD.gn b/third_party/blink/renderer/platform/wtf/BUILD.gn
index ea947cc..777c48c 100644
--- a/third_party/blink/renderer/platform/wtf/BUILD.gn
+++ b/third_party/blink/renderer/platform/wtf/BUILD.gn
@@ -10,13 +10,6 @@
 import("//third_party/blink/public/public_features.gni")
 import("//third_party/blink/renderer/config.gni")
 
-buildflag_header("buildflags") {
-  header = "buildflags.h"
-  header_dir = "third_party/blink/renderer/platform/wtf"
-
-  flags = [ "USE_V8_OILPAN=$enable_blink_heap_use_v8_oilpan" ]
-}
-
 visibility = [
   ":*",
   "//:gn_all",
@@ -211,7 +204,6 @@
   ]
 
   deps = [
-    ":buildflags",
     "//base/allocator:buildflags",
     "//build:chromeos_buildflags",
 
@@ -226,9 +218,7 @@
     "//third_party/icu",
   ]
 
-  if (enable_blink_heap_use_v8_oilpan) {
-    public_deps += [ "//v8:cppgc_headers" ]
-  }
+  public_deps += [ "//v8:cppgc_headers" ]
 
   # Rules changing the |sources| list are temporarily commented out, until
   # those files are actually moved to here.
diff --git a/third_party/blink/renderer/platform/wtf/type_traits.h b/third_party/blink/renderer/platform/wtf/type_traits.h
index 562628a92..992c79d 100644
--- a/third_party/blink/renderer/platform/wtf/type_traits.h
+++ b/third_party/blink/renderer/platform/wtf/type_traits.h
@@ -28,19 +28,7 @@
 #include "base/compiler_specific.h"
 #include "base/template_util.h"
 #include "build/build_config.h"
-#include "third_party/blink/renderer/platform/wtf/buildflags.h"
-
-#if BUILDFLAG(USE_V8_OILPAN)
 #include "v8/include/cppgc/type-traits.h"  // nogncheck
-#else                                      // !BUILDFLAG(USE_V8_OILPAN)
-namespace blink {
-template <typename T>
-class Member;
-class Visitor;
-template <typename T>
-class WeakMember;
-}  // namespace blink
-#endif                                     // !BUILDFLAG(USE_V8_OILPAN)
 
 namespace WTF {
 
@@ -117,8 +105,6 @@
   static const bool value = sizeof(SubclassCheck(t_)) == sizeof(YesType);
 };
 
-#if BUILDFLAG(USE_V8_OILPAN)
-
 template <typename T>
 struct IsTraceable : cppgc::internal::IsTraceable<T> {};
 
@@ -142,106 +128,6 @@
                              cppgc::IsMemberTypeV<T> ||
                                  cppgc::IsWeakMemberTypeV<T>> {};
 
-#else  // !USE_V8_OILPAN
-
-namespace internal {
-// IsTraceMethodConst is used to verify that all Trace methods are marked as
-// const. It is equivalent to IsTraceable but for a non-const object.
-template <typename T, typename = void>
-struct IsTraceMethodConst : std::false_type {};
-
-template <typename T>
-struct IsTraceMethodConst<T,
-                          base::void_t<decltype(std::declval<const T>().Trace(
-                              std::declval<blink::Visitor*>()))>>
-    : std::true_type {};
-}  // namespace internal
-
-template <typename T, typename = void>
-struct IsTraceable : std::false_type {
-  // Fail on incomplete types.
-  static_assert(sizeof(T), "incomplete type T");
-};
-
-// Note: This also checks if a superclass of T has a trace method.
-template <typename T>
-struct IsTraceable<T,
-                   base::void_t<decltype(std::declval<T>().Trace(
-                       std::declval<blink::Visitor*>()))>> : std::true_type {
-  // All Trace methods should be marked as const. If an object of type
-  // 'T' is traceable then any object of type 'const T' should also
-  // be traceable.
-  static_assert(internal::IsTraceMethodConst<T>(),
-                "Trace methods should be marked as const.");
-};
-
-template <typename T>
-class IsGarbageCollectedTypeInternal {
-  typedef char YesType;
-  typedef struct NoType { char padding[8]; } NoType;
-
-  using NonConstType = typename std::remove_const<T>::type;
-  template <typename U>
-  static YesType CheckGarbageCollectedType(
-      typename U::IsGarbageCollectedTypeMarker*);
-  template <typename U>
-  static NoType CheckGarbageCollectedType(...);
-
-  // Separately check for GarbageCollectedMixin, which declares a different
-  // marker typedef, to avoid resolution ambiguity for cases like
-  // IsGarbageCollectedType<B> over:
-  //
-  //    class A : public GarbageCollected<A>, public GarbageCollectedMixin {
-  //        ...
-  //    };
-  //    class B : public A, public GarbageCollectedMixin { ... };
-  //
-  template <typename U>
-  static YesType CheckGarbageCollectedMixinType(
-      typename U::IsGarbageCollectedMixinMarker*);
-  template <typename U>
-  static NoType CheckGarbageCollectedMixinType(...);
-
- public:
-  static const bool value =
-      (sizeof(YesType) ==
-       sizeof(CheckGarbageCollectedType<NonConstType>(nullptr))) ||
-      (sizeof(YesType) ==
-       sizeof(CheckGarbageCollectedMixinType<NonConstType>(nullptr)));
-};
-
-template <typename T>
-class IsGarbageCollectedType : public IsGarbageCollectedTypeInternal<T> {
-  static_assert(sizeof(T), "T must be fully defined");
-};
-
-// Specifies whether a type should be treated weakly by the memory management
-// system. Only supported by the garbage collector and not by PartitionAlloc.
-// Requires garbage collection support, so it is only safe to  override in sync
-// with changing garbage collection semantics.
-template <typename T>
-struct IsWeak : std::false_type {};
-
-template <typename T>
-struct IsMemberType : std::integral_constant<
-                          bool,
-                          WTF::IsSubclassOfTemplate<T, blink::Member>::value> {
-};
-
-template <typename T>
-struct IsWeakMemberType
-    : std::integral_constant<
-          bool,
-          WTF::IsSubclassOfTemplate<T, blink::WeakMember>::value> {};
-
-template <typename T>
-struct IsMemberOrWeakMemberType
-    : std::integral_constant<bool,
-                             IsMemberType<T>::value ||
-                                 IsWeakMemberType<T>::value> {};
-
-#endif  // !USE_V8_OILPAN
-
 template <typename T, typename U>
 struct IsTraceable<std::pair<T, U>>
     : std::integral_constant<bool,
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
index 5d80bc24..e64e17ce 100644
--- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
+++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -155,7 +155,7 @@
                              help=('Do not log Zircon debug messages.')),
         optparse.make_option('--device',
                              choices=['aemu', 'qemu', 'device', 'fvdl'],
-                             default='aemu',
+                             default='fvdl',
                              help=('Choose device to launch Fuchsia with. '
                                    'Defaults to AEMU.')),
         optparse.make_option('--fuchsia-target-cpu',
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index 28d8030..b9fe83e8 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -297,7 +297,7 @@
 crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-002.html [ Pass ]
 crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-004.html [ Pass ]
 crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-024.html [ Failure ]
-crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-025.html [ Pass ]
+crbug.com/1157740 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-026.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-sizing/clone-nowrap-intrinsic-size-bidi.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-sizing/intrinsic-percent-non-replaced-004.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-sizing/intrinsic-percent-non-replaced-005.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 76b8a4e..78b1230 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -781,8 +781,6 @@
 
 #### external/wpt/css/css-sizing
 crbug.com/1251788 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-002.html [ Failure ]
-crbug.com/1166834 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-025.html [ Failure ]
-crbug.com/1166834 external/wpt/css/css-sizing/aspect-ratio/flex-aspect-ratio-026.html [ Failure ]
 crbug.com/970201 external/wpt/css/css-sizing/slice-intrinsic-size.html [ Failure ]
 crbug.com/970201 external/wpt/css/css-sizing/clone-intrinsic-size.html [ Failure ]
 
@@ -2851,8 +2849,8 @@
 crbug.com/626703 virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https.html [ Pass ]
 
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 [ Linux ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-start-delay.https.html [ Crash ]
-crbug.com/626703 [ Mac10.15 ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-start-delay.https.html [ Crash ]
+crbug.com/626703 [ Linux ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-start-delay.https.html [ Failure ]
+crbug.com/626703 [ Mac10.15 ] virtual/threaded/external/wpt/animation-worklet/worklet-animation-start-delay.https.html [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-parts-structure.tentative.html [ Timeout ]
 crbug.com/626703 [ Mac ] external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-parts-structure.tentative.html [ Timeout ]
 crbug.com/626703 [ Linux ] virtual/synchronous_html_parser/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-parts-structure.tentative.html [ Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index bbc69ad0..4c355a0 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -2600,49 +2600,49 @@
     },
     "icons-member": {
      "icons-member-cors-fail-manual.sub.html": [
-      "a6acdd4b0147184c1b73d153657a1b6e6090ba45",
+      "f49dac6057ae12f97f524ba5d3a61ffa94b10be8",
       [
        null,
        {}
       ]
      ],
      "icons-member-cors-manual.sub.html": [
-      "a54f3629caf7ab7f55ecb60e46007f62a3d1b51a",
+      "aa0fe89db653fe5db1da5ddd5fcb91ff2625eb99",
       [
        null,
        {}
       ]
      ],
      "icons-member-csp-fail-manual.sub.html": [
-      "7f35fc318e8c0c38ad576578537e024b2dc0ce4b",
+      "e4706011f8437dcad920644dafc313ee7889f659",
       [
        null,
        {}
       ]
      ],
      "icons-member-csp-manual.sub.html": [
-      "15e09129e972b907033968b0b49205d98dfb334b",
+      "c76364b83feab36ff16d1a54981cb6f85df7eec5",
       [
        null,
        {}
       ]
      ],
      "icons-member-last-matching-manual.html": [
-      "04f18f47e2090987352a707a54c7857c75b446b4",
+      "a02ddc3a50294b6977e8919aa2aa2ab66935622a",
       [
        null,
        {}
       ]
      ],
      "icons-member-manual.html": [
-      "f42db8d6b273e498be0f0e66daa6087f4063716f",
+      "6a9b7620ed1c102391ebb4f1987f2fcfa5c219e5",
       [
        null,
        {}
       ]
      ],
      "icons-member-next-appropriate-manual.html": [
-      "1e84ba948f028e67ff31d65dea85400e972e311c",
+      "8e87fc106207f97f92b710769d637bbd71bd3497",
       [
        null,
        {}
@@ -2674,6 +2674,15 @@
       ]
      ]
     },
+    "protocol_handlers-member": {
+     "protocol_handlers-member-manual.tentative.html": [
+      "fa9c958e0e4ba03a3820f2364314ffc1fff7b93f",
+      [
+       null,
+       {}
+      ]
+     ]
+    },
     "short_name-member": {
      "short_name-member-manual.html": [
       "2ccb68cf0a7007c58b8a6c3e32fddc85690b2b86",
@@ -134156,6 +134165,19 @@
        {}
       ]
      ],
+     "highlight-cascade-004.html": [
+      "eb181096ce1ee035aa10e21e6f35fba58c5c7acb",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-cascade-004-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "highlight-painting-001.html": [
       "ef253e6117c94ef63f9be97eaac0d94667c9fce3",
       [
@@ -214478,6 +214500,12 @@
       ]
      }
     },
+    "currentchange-event": {
+     "currentchange-app-history-reload-transitionWhile-expected.txt": [
+      "4f115e002d99400418c9fca8f85a490cb10fe9ff",
+      []
+     ]
+    },
     "navigate": {
      "reload-service-worker-fetch-event-expected.txt": [
       "cf4b285328a985e8413570fcc80e16d4501b3d09",
@@ -214657,74 +214685,84 @@
      }
     },
     "icons-member": {
-     "fail.png": [
-      "1d596c6ba6ab8a6a2636ce524a8cd8cf06538b41",
+     "icons-member-service-worker.js": [
+      "21b07f8515a1cdc225a72884fc40899fe57f5afe",
       []
      ],
-     "icons-member-cors-fail.sub.webmanifest": [
-      "e8b9327ed8fec3b30d7ba2dafc31a73b269c0a19",
-      []
-     ],
-     "icons-member-cors-fail.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "icons-member-cors.sub.webmanifest": [
-      "5d95262af3e7842eb3e4e79b87c3f98e86ad1fd7",
-      []
-     ],
-     "icons-member-cors.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "icons-member-csp-fail.webmanifest": [
-      "a17364871ec00da8a5f13ebc434b3873fcef1e4e",
-      []
-     ],
-     "icons-member-csp-fail.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "icons-member-csp.sub.webmanifest": [
-      "5d95262af3e7842eb3e4e79b87c3f98e86ad1fd7",
-      []
-     ],
-     "icons-member-csp.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "icons-member-last-matching.webmanifest": [
-      "f4423d28f7e743013c7aa6fafe8aeb9db10dc52a",
-      []
-     ],
-     "icons-member-last-matching.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "icons-member-next-appropriate.webmanifest": [
-      "5ae381ec65ebff3a43c6921d2386076d8f21f957",
-      []
-     ],
-     "icons-member-next-appropriate.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "icons-member.webmanifest": [
-      "a744fee8a828f33ce6d4972c80b67c614db5df9b",
-      []
-     ],
-     "icons-member.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "pass.png": [
-      "be7433a3e2c305ff699e74f9bbd56e87484ba35c",
-      []
-     ],
-     "pass.png.sub.headers": [
-      "adf190aa8ea92e24e74c3c90f21d2155f809abbe",
-      []
-     ]
+     "resources": {
+      "fail.png": [
+       "1d596c6ba6ab8a6a2636ce524a8cd8cf06538b41",
+       []
+      ],
+      "icons-member-cors-fail.sub.webmanifest": [
+       "24e2214365bd218697e479d7537edbe37d9e7c5d",
+       []
+      ],
+      "icons-member-cors-fail.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "icons-member-cors.sub.webmanifest": [
+       "33cb12654b662dbcf4334a5607e038fb84850608",
+       []
+      ],
+      "icons-member-cors.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "icons-member-csp-fail.webmanifest": [
+       "2b614ebb01fef241b434e90d77899a9d6380857b",
+       []
+      ],
+      "icons-member-csp-fail.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "icons-member-csp.sub.webmanifest": [
+       "f1089bba3c57afd7f1cc8feee5d903154672a6f2",
+       []
+      ],
+      "icons-member-csp.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "icons-member-last-matching.webmanifest": [
+       "04ac33112d576d6723266ec5a7c99023686f973b",
+       []
+      ],
+      "icons-member-last-matching.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "icons-member-manual.js": [
+       "cf149792a3ee7c63d72b01d95604b32e526c7373",
+       []
+      ],
+      "icons-member-next-appropriate.webmanifest": [
+       "e65169b06a2f5873f47dee9c6235d5f66229d761",
+       []
+      ],
+      "icons-member-next-appropriate.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "icons-member.webmanifest": [
+       "8e7a2c34268c8878d99372dfb9948c44d3e8ed7e",
+       []
+      ],
+      "icons-member.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "pass.png": [
+       "be7433a3e2c305ff699e74f9bbd56e87484ba35c",
+       []
+      ],
+      "pass.png.sub.headers": [
+       "adf190aa8ea92e24e74c3c90f21d2155f809abbe",
+       []
+      ]
+     }
     },
     "name-member": {
      "name-member-fail.webmanifest": [
@@ -214762,6 +214800,30 @@
       []
      ]
     },
+    "protocol_handlers-member": {
+     "protocol_handlers-member-service-worker.js": [
+      "e502e2a9859f6df6f4793fb43e155623c8547a94",
+      []
+     ],
+     "resources": {
+      "icon.png": [
+       "9255547fae08775cce76b769ad4c6d13cc9b241a",
+       []
+      ],
+      "protocol_handlers-member.webmanifest": [
+       "cce6ae1e22b7813db32b060d86e5c499f6f3d84f",
+       []
+      ],
+      "protocol_handlers-member.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "protocol_handlers_entry.html": [
+       "c5fa629f22bfdabef4cac02927646f76f66baafc",
+       []
+      ]
+     }
+    },
     "short_name-member": {
      "short_name-member.webmanifest": [
       "66f357e294cb810a90e6b39f9d87a7a45ab8029d",
@@ -233961,7 +234023,7 @@
        []
       ],
       "font-palette-values-valid-expected.txt": [
-       "d8f9ffbb55ae057e1ee3e637bb19e1bce1a46cfe",
+       "252eb64ff6414742251f11b772d35d730290d146",
        []
       ],
       "font-size-adjust-computed-expected.txt": [
@@ -246179,6 +246241,10 @@
       "256c28ba0c068630cf675698e019b656a6c56da7",
       []
      ],
+     "highlight-cascade-004-ref.html": [
+      "f9bf83f9c1d63b50b61b96a4edadc1241d3c640b",
+      []
+     ],
      "highlight-painting-001-ref.html": [
       "c5d8814a8252b0a8e4be1b43f635cd7b11f548fc",
       []
@@ -256225,6 +256291,14 @@
       "8b1783d785c1cbd71cbeecb58bd21dcb18edf763",
       []
      ],
+     "round-mod-rem-serialize-expected.txt": [
+      "162be5e295a67ef0c12240a65387e8490f3221a9",
+      []
+     ],
+     "signs-abs-serialize-expected.txt": [
+      "2dc9ef1833ebaf5354f62518f85f6b2c700d0802",
+      []
+     ],
      "sin-cos-tan-computed-expected.txt": [
       "30a56d770fdd6004c52441c671c5f27ee5ad1758",
       []
@@ -319955,6 +320029,162 @@
       ]
      ]
     },
+    "currentchange-event": {
+     "currentchange-anchor-href.html": [
+      "2a93abf9937942200d4c2d28c8051456de438003",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-back-forward-cross-doc.html": [
+      "7782d11b0c31a578637f9b7c17c00f95fe6f3cec",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-back-forward-same-doc.html": [
+      "85a93a21bd0f4a708dc99b751c533342743410ce",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-navigate-cross-doc.html": [
+      "d6a657a1b1174ce0f3ced3bba8fd617620fefc3d",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-navigate-preventDefault.html": [
+      "82f10006832e16522844cdb7fa0bcf2e6a3a8578",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-navigate-replace-cross-doc.html": [
+      "3d8ceb746b80da1564a539e080ae965aa30d03b9",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-navigate-replace-same-doc.html": [
+      "2967f21d973aa6e6dd8b38ad0b1d0b7e09917d93",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-navigate-replace-transitionWhile.html": [
+      "86079e777cb9059b13e6763ea31877475142d368",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-navigate-same-doc.html": [
+      "d112e2592806e8fe9830de8fbb2e8b2a8f1a97c7",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-navigate-transitionWhile.html": [
+      "d6a39d204ed72c6d578556798e1b9527f58ba219",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-reload-cross-doc.html": [
+      "ae142fb5d3bc4d600037077cf5bbbbcece64b6f2",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-reload-transitionWhile.html": [
+      "d1f022f584218fec9fb6fb584175adabd7a1a286",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-app-history-updateCurrent.html": [
+      "9e3a3ec387a2ce682e433dc39c6d2e94bfb3f27e",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-dispose-ordering.html": [
+      "f9d23f7dd5da79afb95bd998c618685c225c9e6a",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-history-back-same-doc.html": [
+      "7cfecb15b8ef9e4dc4e2cf678262e889b8d02550",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-history-pushState.html": [
+      "e5468eafc3938f71c907410ed33fad1a184141ce",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-history-replaceState.html": [
+      "5a99561ebd2f929e082cfd6b7938898f03243747",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-location-api.html": [
+      "8cf52ca6d288387036a5d93a007f33c1c79deef3",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-navigate-from-initial-about-blank-same-doc.html": [
+      "80782613203ae437937cc7de7f440c9446224d50",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-navigate-from-initial-about-blank.html": [
+      "f97e1e898e94b4790c2d138ebcd48dee2b638626",
+      [
+       null,
+       {}
+      ]
+     ],
+     "currentchange-properties.html": [
+      "a5417fa312c1b43db84b90c7f67fa1ab88be9333",
+      [
+       null,
+       {}
+      ]
+     ],
+     "event-constructor.html": [
+      "6c489363567fd61d210ad92e8336605ea02f1704",
+      [
+       null,
+       {}
+      ]
+     ]
+    },
     "navigate": {
      "back-forward-multiple-frames.html": [
       "80a8fb65a05fb622988e8f64ac78f16c9172869d",
@@ -342624,7 +342854,7 @@
        ]
       ],
       "font-palette-values-valid.html": [
-       "c6774efbb14931ebf50808c3cb35fbff8a1379b8",
+       "665841cc21a5f5aab6ec897a301446003364f5cd",
        [
         null,
         {}
@@ -360232,6 +360462,48 @@
        {}
       ]
      ],
+     "round-mod-rem-computed.html": [
+      "a98e4a4332250c08b5996a03455a682d26abdc5e",
+      [
+       null,
+       {}
+      ]
+     ],
+     "round-mod-rem-invalid.html": [
+      "99ef2c64b453ac0b56580378a1c4ab59577e90b4",
+      [
+       null,
+       {}
+      ]
+     ],
+     "round-mod-rem-serialize.html": [
+      "490249591947022e09c58b69f1c703483fad2e7d",
+      [
+       null,
+       {}
+      ]
+     ],
+     "signs-abs-computed.html": [
+      "ba672f23cec532befccc2947c4ee14e48d1e2a79",
+      [
+       null,
+       {}
+      ]
+     ],
+     "signs-abs-invalid.html": [
+      "15b058d0c42bade38f083838eaaabadc64410627",
+      [
+       null,
+       {}
+      ]
+     ],
+     "signs-abs-serialize.html": [
+      "b7b5ad2b7529fd81cfc54909c333aed588632549",
+      [
+       null,
+       {}
+      ]
+     ],
      "sin-cos-tan-computed.html": [
       "7f85727bdbad130c9dae323e4e0c9b249c5132aa",
       [
@@ -432328,15 +432600,6 @@
          {}
         ]
        ],
-       "popup-light-dismiss-resize.tentative.html": [
-        "cec65f77dcaddfd170581992ddec02c53619898e",
-        [
-         null,
-         {
-          "testdriver": true
-         }
-        ]
-       ],
        "popup-light-dismiss.tentative.html": [
         "e0012587fd217a935409b6c70af4db5c94a73332",
         [
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-anchor-href.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-anchor-href.html
new file mode 100644
index 0000000..2a93abf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-anchor-href.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<a id="a" href="#foo"></a>
+<script>
+test(t => {
+  let oncurrentchange_called = false;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, appHistory.entries()[0]);
+    assert_equals(e.from.index, 0);
+    assert_equals(e.navigationType, "push");
+    assert_equals(appHistory.current.index, 1);
+  });
+  a.click();
+  assert_true(oncurrentchange_called);
+}, "AppHistoryCurrentChangeEvent fires for link click");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-cross-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-cross-doc.html
new file mode 100644
index 0000000..7782d11
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-cross-doc.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  await new Promise(resolve => window.onload = resolve);
+  i.contentWindow.appHistory.navigate("/common/blank.html?1");
+  await new Promise(resolve => i.onload = resolve);
+  assert_equals(i.contentWindow.appHistory.entries().length, 2);
+
+  i.contentWindow.appHistory.oncurrentchange = t.unreached_func("currentchange should not fire for cross-document navigations");
+  i.contentWindow.appHistory.back();
+  await new Promise(resolve => i.onload = resolve);
+
+  i.contentWindow.appHistory.oncurrentchange = t.unreached_func("currentchange should not fire for cross-document navigations");
+  i.contentWindow.appHistory.forward();
+  await new Promise(resolve => i.onload = resolve);
+}, "AppHistoryCurrentChangeEvent does not fire for cross-document appHistory.back() and appHistory.forward()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-same-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-same-doc.html
new file mode 100644
index 0000000..85a93a21
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-back-forward-same-doc.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async t => {
+  // Wait for after the load event so that the navigation doesn't get converted
+  // into a replace navigation.
+  await new Promise(resolve => window.onload = t.step_timeout(resolve, 0));
+  await appHistory.navigate("#foo");
+  assert_equals(appHistory.entries().length, 2);
+
+  let oncurrentchange_back_called = false;
+  let back_committed = false;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_back_called = true;
+    assert_equals(e.from, appHistory.entries()[1]);
+    assert_equals(e.navigationType, "traverse");
+    assert_equals(appHistory.current.index, 0);
+    assert_false(back_committed);
+  });
+  let back_result = appHistory.back();
+  assert_false(oncurrentchange_back_called);
+  await back_result.committed.then(() => back_committed = true);
+  assert_true(oncurrentchange_back_called);
+
+  let oncurrentchange_forward_called = false;
+  let forward_committed = false;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_forward_called = true;
+    assert_equals(e.from, appHistory.entries()[0]);
+    assert_equals(e.navigationType, "traverse");
+    assert_equals(appHistory.current.index, 1);
+    assert_false(forward_committed);
+  });
+  let forward_result = appHistory.forward();
+  assert_false(oncurrentchange_forward_called);
+  await forward_result.committed.then(() => forward_committed = true);
+  assert_true(oncurrentchange_forward_called);
+}, "AppHistoryCurrentChangeEvent fires for appHistory.back() and appHistory.forward()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-cross-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-cross-doc.html
new file mode 100644
index 0000000..d6a657a1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-cross-doc.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  await new Promise(resolve => window.onload = resolve);
+  i.contentWindow.appHistory.oncurrentchange = t.unreached_func("currentchange should not fire for cross-document navigations");
+  i.contentWindow.appHistory.navigate("/common/blank.html?1");
+  await new Promise(resolve => i.onload = resolve);
+}, "AppHistoryCurrentChangeEvent does not fire for cross-document appHistory.navigate()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-preventDefault.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-preventDefault.html
new file mode 100644
index 0000000..82f1000
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-preventDefault.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async t => {
+  appHistory.oncurrentchange = t.unreached_func("currentchange should not fire");
+  appHistory.onnavigate = e => e.preventDefault();
+  await promise_rejects_dom(t, "AbortError", appHistory.navigate("#foo").committed);
+}, "AppHistoryCurrentChangeEvent does not fire when onnavigate preventDefault() is called");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-cross-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-cross-doc.html
new file mode 100644
index 0000000..3d8ceb7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-cross-doc.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  await new Promise(resolve => window.onload = resolve);
+  i.contentWindow.appHistory.oncurrentchange = t.unreached_func("currentchange should not fire for cross-document navigations");
+  i.contentWindow.appHistory.navigate("/common/blank.html?1", { replace: true });
+  await new Promise(resolve => i.onload = resolve);
+}, "AppHistoryCurrentChangeEvent does not fire for cross-document appHistory.navigate() with replace");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-same-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-same-doc.html
new file mode 100644
index 0000000..2967f21d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-same-doc.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async t => {
+  // Wait for after the load event so that the navigation doesn't get converted
+  // into a replace navigation.
+  await new Promise(resolve => window.onload = t.step_timeout(resolve, 0));
+
+  let oncurrentchange_called = false;
+  let original_entry = appHistory.current;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, original_entry);
+    assert_equals(e.from.index, -1);
+    assert_equals(e.navigationType, "replace");
+    assert_equals(appHistory.current.index, 0);
+  });
+  let result = appHistory.navigate("#foo", { replace: true });
+  assert_true(oncurrentchange_called);
+  await result.committed;
+}, "AppHistoryCurrentChangeEvent fires for appHistory.navigate() with replace");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-transitionWhile.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-transitionWhile.html
new file mode 100644
index 0000000..86079e7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-replace-transitionWhile.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  await new Promise(resolve => window.onload = resolve);
+
+  let oncurrentchange_called = false;
+  let original_entry = i.contentWindow.appHistory.current;
+  i.contentWindow.appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, original_entry);
+    assert_equals(e.from.index, -1);
+    assert_equals(e.navigationType, "replace");
+    assert_equals(i.contentWindow.appHistory.current.index, 0);
+  });
+  i.contentWindow.appHistory.onnavigate = e => e.transitionWhile(Promise.resolve());
+  let result = i.contentWindow.appHistory.navigate("/common/blank.html?1", { replace: true });
+  assert_true(oncurrentchange_called);
+  await result.committed;
+}, "AppHistoryCurrentChangeEvent fires for appHistory.navigate() with replace intercepted by transitionWhile");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-same-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-same-doc.html
new file mode 100644
index 0000000..d112e25
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-same-doc.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async t => {
+  // Wait for after the load event so that the navigation doesn't get converted
+  // into a replace navigation.
+  await new Promise(resolve => window.onload = t.step_timeout(resolve, 0));
+
+  let oncurrentchange_called = false;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, appHistory.entries()[0]);
+    assert_equals(e.navigationType, "push");
+    assert_equals(appHistory.current.index, 1);
+  });
+  let result = appHistory.navigate("#foo");
+  assert_true(oncurrentchange_called);
+  await result.committed;
+}, "AppHistoryCurrentChangeEvent fires for appHistory.navigate()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-transitionWhile.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-transitionWhile.html
new file mode 100644
index 0000000..d6a39d2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-navigate-transitionWhile.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  await new Promise(resolve => window.onload = resolve);
+
+  let oncurrentchange_called = false;
+  i.contentWindow.appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, i.contentWindow.appHistory.entries()[0]);
+    assert_equals(e.navigationType, "push");
+    assert_equals(i.contentWindow.appHistory.current.index, 1);
+  });
+  i.contentWindow.appHistory.onnavigate = e => e.transitionWhile(Promise.resolve());
+  let result = i.contentWindow.appHistory.navigate("/common/blank.html?1");
+  assert_true(oncurrentchange_called);
+  await result.committed;
+}, "AppHistoryCurrentChangeEvent fires for appHistory.navigate() intercepted by transitionWhile");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-cross-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-cross-doc.html
new file mode 100644
index 0000000..ae142fb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-cross-doc.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  await new Promise(resolve => window.onload = resolve);
+  i.contentWindow.appHistory.oncurrentchange = t.unreached_func("currentchange should not fire for cross-document navigations");
+  i.contentWindow.appHistory.reload();
+  await new Promise(resolve => i.onload = resolve);
+}, "AppHistoryCurrentChangeEvent does not fire for cross-document appHistory.reload()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-transitionWhile-expected.txt b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-transitionWhile-expected.txt
new file mode 100644
index 0000000..4f115e00
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-transitionWhile-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL AppHistoryCurrentChangeEvent fires for appHistory.reload() intercepted by transitionWhile assert_equals: expected object "[object AppHistoryEntry]" but got object "[object AppHistoryEntry]"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-transitionWhile.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-transitionWhile.html
new file mode 100644
index 0000000..d1f022f5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-reload-transitionWhile.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  await new Promise(resolve => window.onload = resolve);
+
+  let oncurrentchange_called = false;
+  i.contentWindow.appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, i.contentWindow.appHistory.current);
+    assert_equals(e.navigationType, "reload");
+    assert_equals(i.contentWindow.appHistory.current.index, 0);
+  });
+  i.contentWindow.appHistory.onnavigate = e => e.transitionWhile(Promise.resolve());
+  let result = i.contentWindow.appHistory.reload();
+  assert_true(oncurrentchange_called);
+  await result.committed;
+}, "AppHistoryCurrentChangeEvent fires for appHistory.reload() intercepted by transitionWhile");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-updateCurrent.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-updateCurrent.html
new file mode 100644
index 0000000..9e3a3ec
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-app-history-updateCurrent.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(t => {
+  let oncurrentchange_count = 0;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_count++;
+    assert_equals(e.from, appHistory.current);
+    assert_equals(e.navigationType, null);
+    assert_equals(appHistory.current.getState(), "newState");
+  });
+  appHistory.updateCurrent({ state: "newState" });
+  assert_equals(oncurrentchange_count, 1);
+
+  // "Updating" the state to the current state should still fire currentchange.
+  appHistory.updateCurrent({ state: appHistory.current.getState() });
+  assert_equals(oncurrentchange_count, 2);
+}, "AppHistoryCurrentChangeEvent fires for appHistory.updateCurrent()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-dispose-ordering.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-dispose-ordering.html
new file mode 100644
index 0000000..f9d23f7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-dispose-ordering.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(t => {
+  let oncurrentchange_called = false;
+  let ondispose_called = false;
+
+  let original_entry = appHistory.current;
+  original_entry.ondispose = t.step_func(() => {
+    assert_true(oncurrentchange_called);
+    ondispose_called = true;
+  });
+
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, original_entry);
+    assert_equals(e.from.index, -1);
+    assert_equals(e.navigationType, "replace");
+    assert_equals(appHistory.current.index, 0);
+  });
+  appHistory.navigate("#foo", { replace: true });
+  assert_true(oncurrentchange_called);
+  assert_true(ondispose_called);
+}, "Ordering between AppHistoryCurrentChangeEvent and AppHistoryEntry dispose events");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-back-same-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-back-same-doc.html
new file mode 100644
index 0000000..7cfecb1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-back-same-doc.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async t => {
+  // Wait for after the load event so that the navigation doesn't get converted
+  // into a replace navigation.
+  await new Promise(resolve => window.onload = t.step_timeout(resolve, 0));
+  await appHistory.navigate("#foo");
+  assert_equals(appHistory.entries().length, 2);
+
+  let oncurrentchange_called = false;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, appHistory.entries()[1]);
+    assert_equals(e.navigationType, "traverse");
+    assert_equals(appHistory.current.index, 0);
+  });
+  history.back();
+  assert_false(oncurrentchange_called);
+  await new Promise(resolve => window.onpopstate = resolve);
+  assert_true(oncurrentchange_called);
+}, "AppHistoryCurrentChangeEvent fires for history.back()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-pushState.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-pushState.html
new file mode 100644
index 0000000..e5468ea
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-pushState.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(t => {
+  let oncurrentchange_called = false;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, appHistory.entries()[0]);
+    assert_equals(e.navigationType, "push");
+    assert_equals(appHistory.current.index, 1);
+  });
+  history.pushState(1, "", "#1");
+  assert_true(oncurrentchange_called);
+}, "AppHistoryCurrentChangeEvent fires for history.pushState()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-replaceState.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-replaceState.html
new file mode 100644
index 0000000..5a99561e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-history-replaceState.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(t => {
+  let oncurrentchange_called = false;
+  let original_current = appHistory.current;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, original_current);
+    assert_equals(e.from.index, -1);
+    assert_equals(e.navigationType, "replace");
+    assert_equals(appHistory.current.index, 0);
+  });
+  history.replaceState(1, "", "#1");
+  assert_true(oncurrentchange_called);
+}, "AppHistoryCurrentChangeEvent fires for history.replaceState()");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-location-api.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-location-api.html
new file mode 100644
index 0000000..8cf52ca
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-location-api.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(t => {
+  let oncurrentchange_called = false;
+  let original_entry = appHistory.current;
+  appHistory.oncurrentchange = t.step_func(e => {
+    oncurrentchange_called = true;
+    assert_equals(e.from, original_entry);
+    assert_equals(e.from.index, -1);
+    assert_equals(e.navigationType, "replace");
+    assert_equals(appHistory.current.index, 0);
+  });
+  location.hash = "#foo";
+  assert_true(oncurrentchange_called);
+}, "AppHistoryCurrentChangeEvent fires for location API navigations");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-navigate-from-initial-about-blank-same-doc.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-navigate-from-initial-about-blank-same-doc.html
new file mode 100644
index 0000000..8078261
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-navigate-from-initial-about-blank-same-doc.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  i.contentWindow.appHistory.oncurrentchange = t.unreached_func("currentchange should not fire");
+  history.pushState(1, "", "#1");
+  await new Promise(resolve => i.onload = resolve);
+}, "AppHistoryCurrentChangeEvent does not fire when navigating away from the initial about:blank");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-navigate-from-initial-about-blank.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-navigate-from-initial-about-blank.html
new file mode 100644
index 0000000..f97e1e8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-navigate-from-initial-about-blank.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="i" src="/common/blank.html"></iframe>
+<script>
+promise_test(async t => {
+  i.contentWindow.appHistory.oncurrentchange = t.unreached_func("currentchange should not fire");
+  i.contentWindow.appHistory.navigate("/common/blank.html#1");
+  await new Promise(resolve => i.onload = resolve);
+}, "AppHistoryCurrentChangeEvent does not fire when navigating away from the initial about:blank");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-properties.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-properties.html
new file mode 100644
index 0000000..a5417fa3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/currentchange-properties.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+async_test(t => {
+  appHistory.oncurrentchange = t.step_func_done(e => {
+    assert_equals(e.constructor, AppHistoryCurrentChangeEvent);
+    assert_false(e.bubbles);
+    assert_false(e.cancelable);
+    assert_true(e.isTrusted);
+  });
+  location.href = "#1";
+}, "AppHistoryCurrentChangeEvent's properties");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/event-constructor.html b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/event-constructor.html
new file mode 100644
index 0000000..6c48936
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/app-history/currentchange-event/event-constructor.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+  assert_throws_js(TypeError, () => {
+    new AppHistoryCurrentChangeEvent("currentchange");
+  });
+}, "can't bypass required members by omitting the dictionary entirely");
+
+test(() => {
+  assert_throws_js(TypeError, () => {
+    new AppHistoryCurrentChangeEvent("currentchange", {
+      navigationType: "push"
+    });
+  });
+}, "from is required");
+
+test(() => {
+  const event = new AppHistoryCurrentChangeEvent("currentchange", {
+    navigationType: "replace",
+    from: appHistory.current
+  });
+  assert_equals(event.navigationType, "replace");
+  assert_equals(event.from, appHistory.current);
+}, "all properties are reflected back");
+
+test(t => {
+  const event = new AppHistoryCurrentChangeEvent("currentchange", { from: appHistory.current });
+  assert_equals(event.navigationType, null);
+}, "defaults are as expected");
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail-manual.sub.html b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail-manual.sub.html
index a6acdd4..f49dac60 100644
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail-manual.sub.html
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail-manual.sub.html
@@ -1,7 +1,8 @@
 <!DOCTYPE html>
 <title>Test that icons member is supported (CORS violation)</title>
 <link rel="help" href="https://w3c.github.io/manifest#icons-member" />
-<link rel="manifest" href="icons-member-cors-fail.sub.webmanifest" />
+<link rel="manifest" href="resources/icons-member-cors-fail.sub.webmanifest" />
+<script src="resources/icons-member-manual.js"></script>
 <h1>Testing support for icons member (CORS violation)</h1>
 <script>
     // Force the port of the origin to be ports[https][0] (likely :8443)
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail.sub.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail.sub.webmanifest
deleted file mode 100644
index e8b9327..0000000
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail.sub.webmanifest
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "icons": [{
-        "src": "https://{{host}}:{{ports[https][1]}}/appmanifest/icons-member/fail.png",
-        "sizes": "256x256",
-        "type": "image/png"
-    }]
-}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-manual.sub.html b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-manual.sub.html
index a54f3629..aa0fe89 100644
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-manual.sub.html
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-manual.sub.html
@@ -1,7 +1,8 @@
 <!DOCTYPE html>
 <title>Test that icons member is supported (via CORS)</title>
 <link rel="help" href="https://w3c.github.io/manifest#icons-member" />
-<link rel="manifest" href="icons-member-cors.sub.webmanifest" />
+<link rel="manifest" href="resources/icons-member-cors.sub.webmanifest" />
+<script src="resources/icons-member-manual.js"></script>
 <h1>Testing support for icons member (via CORS)</h1>
 <script>
     // Force the port of the origin to be ports[https][0] (likely :8443)
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors.sub.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors.sub.webmanifest
deleted file mode 100644
index 5d95262..0000000
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors.sub.webmanifest
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "icons": [{
-        "src": "https://{{host}}:{{ports[https][1]}}/appmanifest/icons-member/pass.png",
-        "sizes": "256x256",
-        "type": "image/png"
-    }]
-}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail-manual.sub.html b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail-manual.sub.html
index 7f35fc31..e4706011 100644
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail-manual.sub.html
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail-manual.sub.html
@@ -2,7 +2,8 @@
 <meta http-equiv="Content-Security-Policy" content="img-src {{host}}:{{ports[https][1]}}">
 <title>Test that icons member is supported (CSP violation)</title>
 <link rel="help" href="https://w3c.github.io/manifest#icons-member" />
-<link rel="manifest" href="icons-member-csp-fail.webmanifest" />
+<link rel="manifest" href="resources/icons-member-csp-fail.webmanifest" />
+<script src="resources/icons-member-manual.js"></script>
 <h1>Testing support for icons member (CSP violation)</h1>
 <script>
     // Force the port of the origin to be ports[https][0] (likely :8443)
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail.webmanifest
deleted file mode 100644
index a1736487..0000000
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail.webmanifest
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "icons": [{
-        "src": "fail.png",
-        "sizes": "256x256",
-        "type": "image/png"
-    }]
-}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-manual.sub.html b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-manual.sub.html
index 15e0912..c76364b 100644
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-manual.sub.html
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-manual.sub.html
@@ -2,7 +2,8 @@
 <meta http-equiv="Content-Security-Policy" content="img-src {{host}}:{{ports[https][1]}}">
 <title>Test that icons member is supported (CSP check)</title>
 <link rel="help" href="https://w3c.github.io/manifest#icons-member" />
-<link rel="manifest" href="icons-member-csp.sub.webmanifest" />
+<link rel="manifest" href="resources/icons-member-csp.sub.webmanifest" />
+<script src="resources/icons-member-manual.js"></script>
 <h1>Testing support for icons member (CSP check)</h1>
 <script>
     // Force the port of the origin to be ports[https][0] (likely :8443)
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp.sub.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp.sub.webmanifest
deleted file mode 100644
index 5d95262..0000000
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp.sub.webmanifest
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "icons": [{
-        "src": "https://{{host}}:{{ports[https][1]}}/appmanifest/icons-member/pass.png",
-        "sizes": "256x256",
-        "type": "image/png"
-    }]
-}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching-manual.html b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching-manual.html
index 04f18f4..a02ddc3a 100644
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching-manual.html
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching-manual.html
@@ -1,7 +1,8 @@
 <!DOCTYPE html>
 <title>Test that icons member is supported</title>
 <link rel="help" href="https://w3c.github.io/manifest#icons-member" />
-<link rel="manifest" href="icons-member-last-matching.webmanifest" />
+<link rel="manifest" href="resources/icons-member-last-matching.webmanifest" />
+<script src="resources/icons-member-manual.js"></script>
 <h1>Testing support for icons member</h1>
 <p>
   To pass, the icon must show a white check mark on a green background.
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-manual.html b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-manual.html
index f42db8d..6a9b762 100644
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-manual.html
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-manual.html
@@ -1,7 +1,8 @@
 <!DOCTYPE html>
 <title>Test that icons member is supported</title>
 <link rel="help" href="https://w3c.github.io/manifest#icons-member" />
-<link rel="manifest" href="icons-member.webmanifest" />
+<link rel="manifest" href="resources/icons-member.webmanifest" />
+<script src="resources/icons-member-manual.js"></script>
 <h1>Testing support for icons member</h1>
 <p>
   To pass, the icon should must a white check mark on a green background.
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate-manual.html b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate-manual.html
index 1e84ba9..8e87fc1 100644
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate-manual.html
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate-manual.html
@@ -1,7 +1,8 @@
 <!DOCTYPE html>
 <title>Test that icons member is supported</title>
 <link rel="help" href="https://w3c.github.io/manifest#icons-member" />
-<link rel="manifest" href="icons-member-next-appropriate.webmanifest" />
+<link rel="manifest" href="resources/icons-member-next-appropriate.webmanifest" />
+<script src="resources/icons-member-manual.js"></script>
 <h1>Testing support for icons member</h1>
 <p>
   To pass, the icon must show a white check mark on a green background.
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate.webmanifest
deleted file mode 100644
index 5ae381e..0000000
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate.webmanifest
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "icons": [{
-        "src": "pass.png",
-        "sizes": "256x256",
-        "type": "image/png"
-    }, {
-        "src": "icons-member-manual.html",
-        "sizes": "256x256"
-    }]
-}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-service-worker.js b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-service-worker.js
new file mode 100644
index 0000000..21b07f8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-service-worker.js
@@ -0,0 +1,59 @@
+// Some user agents only offer app installation if there is a SW and it handles
+// offline requests.
+
+const cacheVersion = "1.2";
+const CACHE_NAME = `cache-v${cacheVersion}`;
+
+// The resources cached by this service worker.
+const resources = [
+  "icons-member-cors-fail-manual.sub.html",
+  "icons-member-cors-manual.sub.html",
+  "icons-member-csp-fail-manual.sub.html",
+  "icons-member-csp-manual.sub.html",
+  "icons-member-last-matching-manual.html",
+  "icons-member-manual.html",
+  "icons-member-next-appropriate-manual.html",
+  "icons-member-service-worker.js",
+  "resources/icons-member-manual.js",
+  "resources/fail.png",
+  "resources/pass.png"
+];
+
+// Load all resources for this service worker.
+const precache = async () => {
+  const cache = await caches.open(CACHE_NAME);
+  await cache.addAll(resources);
+};
+
+// Get a resource from the cache.
+const fromCache = async request => {
+  const cache = await caches.open(CACHE_NAME);
+  return await cache.match(request.url);
+};
+
+// Attempt to get resources from the network first, fallback to the cache if we're
+// offline.
+const networkFallbackToCache = async request => {
+  try {
+    const response = await fetch(request);
+    if (response.ok) return response;
+  } catch (err) {}
+  return await fromCache(request);
+};
+
+// When we have a new service worker, update the caches and swap immediately.
+self.addEventListener("install", e => {
+  e.waitUntil(precache().then(() => self.skipWaiting()));
+});
+
+// Claim existing clients.
+self.addEventListener("activate", e => {
+  e.waitUntil(self.clients.claim());
+});
+
+// When a resource need to be fetched, check whether it is
+// contained in the cache and return the cached version, otherwise
+// get it from the network.
+self.addEventListener("fetch", e => {
+  e.respondWith(networkFallbackToCache(e.request));
+});
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member.webmanifest
deleted file mode 100644
index a744fee..0000000
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member.webmanifest
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-    "icons": [{
-        "src": "pass.png",
-        "sizes": "256x256",
-        "type": "image/png"
-    }]
-}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/fail.png b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/fail.png
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/fail.png
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/fail.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors-fail.sub.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors-fail.sub.webmanifest
new file mode 100644
index 0000000..24e2214
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors-fail.sub.webmanifest
@@ -0,0 +1,10 @@
+{
+    "name": "Icons member (CORS violation) WPT",
+    "icons": [{
+        "src": "https://{{host}}:{{ports[https][1]}}/appmanifest/icons-member/resources/fail.png",
+        "sizes": "256x256",
+        "type": "image/png"
+    }],
+    "start_url": "../icons-member-cors-fail-manual.sub.html",
+    "display": "fullscreen"
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors-fail.webmanifest.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors-fail.webmanifest.headers
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors-fail.webmanifest.headers
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors.sub.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors.sub.webmanifest
new file mode 100644
index 0000000..33cb126
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors.sub.webmanifest
@@ -0,0 +1,10 @@
+{
+    "name": "Icons member (via CORS) WPT",
+    "icons": [{
+        "src": "https://{{host}}:{{ports[https][1]}}/appmanifest/icons-member/resources/pass.png",
+        "sizes": "256x256",
+        "type": "image/png"
+    }],
+    "start_url": "../icons-member-cors-manual.sub.html",
+    "display": "fullscreen"
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors.webmanifest.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-cors.webmanifest.headers
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-cors.webmanifest.headers
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp-fail.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp-fail.webmanifest
new file mode 100644
index 0000000..2b614eb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp-fail.webmanifest
@@ -0,0 +1,10 @@
+{
+    "name": "Icons member (CSP violation) WPT",
+    "icons": [{
+        "src": "fail.png",
+        "sizes": "256x256",
+        "type": "image/png"
+    }],
+    "start_url": "../icons-member-csp-fail-manual.sub.html",
+    "display": "fullscreen"
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp-fail.webmanifest.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp-fail.webmanifest.headers
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp-fail.webmanifest.headers
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp.sub.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp.sub.webmanifest
new file mode 100644
index 0000000..f1089bba
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp.sub.webmanifest
@@ -0,0 +1,10 @@
+{
+    "name": "Icons member (CSP check) WPT",
+    "icons": [{
+        "src": "https://{{host}}:{{ports[https][1]}}/appmanifest/icons-member/resources/pass.png",
+        "sizes": "256x256",
+        "type": "image/png"
+    }],
+    "start_url": "../icons-member-csp-manual.sub.html",
+    "display": "fullscreen"
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp.webmanifest.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-csp.webmanifest.headers
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-csp.webmanifest.headers
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-last-matching.webmanifest
similarity index 60%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching.webmanifest
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-last-matching.webmanifest
index f4423d2..04ac331 100644
--- a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching.webmanifest
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-last-matching.webmanifest
@@ -1,4 +1,5 @@
 {
+    "name": "Icons member WPT",
     "icons": [{
         "src": "fail.png",
         "sizes": "256x256",
@@ -7,5 +8,7 @@
         "src": "pass.png",
         "sizes": "256x256",
         "type": "image/png"
-    }]
+    }],
+    "start_url": "../icons-member-last-matching-manual.html",
+    "display": "fullscreen"
 }
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-last-matching.webmanifest.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-last-matching.webmanifest.headers
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-last-matching.webmanifest.headers
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-manual.js b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-manual.js
new file mode 100644
index 0000000..cf149792
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-manual.js
@@ -0,0 +1,4 @@
+if ('serviceWorker' in navigator) {
+  navigator.serviceWorker.register(
+    'icons-member-service-worker.js');
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-next-appropriate.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-next-appropriate.webmanifest
new file mode 100644
index 0000000..e65169b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-next-appropriate.webmanifest
@@ -0,0 +1,13 @@
+{
+    "name": "Icons member WPT",
+    "icons": [{
+        "src": "pass.png",
+        "sizes": "256x256",
+        "type": "image/png"
+    }, {
+        "src": "../icons-member-manual.html",
+        "sizes": "256x256"
+    }],
+    "start_url": "../icons-member-next-appropriate-manual.html",
+    "display": "fullscreen"
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-next-appropriate.webmanifest.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member-next-appropriate.webmanifest.headers
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member-next-appropriate.webmanifest.headers
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member.webmanifest b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member.webmanifest
new file mode 100644
index 0000000..8e7a2c3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member.webmanifest
@@ -0,0 +1,10 @@
+{
+    "name": "Icons member WPT",
+    "icons": [{
+        "src": "pass.png",
+        "sizes": "256x256",
+        "type": "image/png"
+    }],
+    "start_url": "../icons-member-manual.html",
+    "display": "fullscreen"
+}
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member.webmanifest.headers b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member.webmanifest.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/icons-member.webmanifest.headers
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/icons-member.webmanifest.headers
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/pass.png b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/pass.png
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/pass.png
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/pass.png
Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/pass.png.sub.headers b/third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/pass.png.sub.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/appmanifest/icons-member/pass.png.sub.headers
rename to third_party/blink/web_tests/external/wpt/appmanifest/icons-member/resources/pass.png.sub.headers
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid-expected.txt
index d8f9ffb..252eb64 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid-expected.txt
@@ -19,5 +19,17 @@
 FAIL CSS Fonts Module Level 4: parsing @font-palette-values 17 Cannot read properties of undefined (reading 'fontFamily')
 FAIL CSS Fonts Module Level 4: parsing @font-palette-values 18 Cannot read properties of undefined (reading 'cssText')
 FAIL CSS Fonts Module Level 4: parsing @font-palette-values 19 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 20 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 21 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 22 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 23 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 24 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 25 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 26 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 27 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 28 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 29 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 30 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 31 Cannot read properties of undefined (reading 'fontFamily')
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid.html
index c6774ef..665841c 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid.html
@@ -69,6 +69,36 @@
 @font-palette-values J {
     override-color: -3 rgb(17, 34, 51);
 }
+
+/* 10 */
+@font-palette-values K {
+    override-color: 0 #0000FF;
+}
+
+/* 11 */
+@font-palette-values L {
+    override-color: 0 green;
+}
+
+/* 12 */
+@font-palette-values M {
+    override-color: 0 transparent;
+}
+
+/* 13 */
+@font-palette-values N {
+    override-color: 0 rgba(1 2 3 / 4);
+}
+
+/* 14 */
+@font-palette-values O {
+    override-color: 0 lab(29.2345% 39.3825 20.0664);
+}
+
+/* 15 */
+@font-palette-values P {
+    override-color: 0 color(display-p3 100% 100% 100%);
+}
 </style>
 </head>
 <body>
@@ -228,6 +258,90 @@
     assert_equals(rule.get(7), undefined);
     assert_equals(rule.get(-3), undefined);
 });
+
+test(function() {
+    let text = rules[10].cssText;
+    assert_not_equals(text.indexOf("override-color"), -1);
+    assert_not_equals(text.indexOf("rgb(0, 0, 255)"), -1);
+});
+
+test(function() {
+    let rule = rules[10];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_equals(rule.get(0), "rgb(0, 0, 255)");
+});
+
+test(function() {
+    let text = rules[11].cssText;
+    assert_not_equals(text.indexOf("override-color"), -1);
+    assert_not_equals(text.indexOf("rgb(0, 128, 0)"), -1);
+});
+
+test(function() {
+    let rule = rules[11];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_equals(rule.get(0), "rgb(0, 128, 0)");
+});
+
+test(function() {
+    let text = rules[12].cssText;
+    assert_not_equals(text.indexOf("override-color"), -1);
+    assert_not_equals(text.indexOf("rgba(0, 0, 0, 0)"), -1);
+});
+
+test(function() {
+    let rule = rules[12];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_equals(rule.get(0), "rgba(0, 0, 0, 0)");
+});
+
+test(function() {
+    let text = rules[13].cssText;
+    assert_not_equals(text.indexOf("override-color"), -1);
+    assert_not_equals(text.indexOf("2"), -1);
+});
+
+test(function() {
+    let rule = rules[13];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_not_equals(rule.get(0).indexOf("2"), -1);
+});
+
+test(function() {
+    let text = rules[14].cssText;
+    assert_not_equals(text.indexOf("override-color"), -1);
+    assert_not_equals(text.indexOf("29"), -1);
+});
+
+test(function() {
+    let rule = rules[14];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_not_equals(rule.get(0).indexOf("lab"), -1);
+});
+
+test(function() {
+    let text = rules[15].cssText;
+    assert_not_equals(text.indexOf("override-color"), -1);
+    assert_not_equals(text.indexOf("display-p3"), -1);
+});
+
+test(function() {
+    let rule = rules[15];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_not_equals(rule.get(0).indexOf("display-p3"), -1);
+});
 </script>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-computed.html b/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-computed.html
new file mode 100644
index 0000000..a98e4a4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-computed.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+// Simple tests
+test_math_used('round(10,10)', '10', {type:'number'});
+test_math_used('mod(1,1)', '0', {type:'number'});
+test_math_used('rem(1,1)', '0', {type:'number'});
+
+//Test basic round
+test_math_used('calc(round(100,10))', '100', {type:'number'});
+test_math_used('calc(round(up, 101,10))', '110', {type:'number'});
+test_math_used('calc(round(down, 106,10))', '100', {type:'number'});
+test_math_used('calc(round(to-zero,105, 10))', '100', {type:'number'});
+test_math_used('calc(round(to-zero,-105, 10))', '100', {type:'number'});
+test_math_used('calc(round(-100,10))', '-100', {type:'number'});
+test_math_used('calc(round(up, -103,10))', '-100', {type:'number'});
+
+//Test basic mod/rem
+test_math_used('mod(18,5)', '3', {type:'number'});
+test_math_used('rem(18,5)', '3', {type:'number'});
+test_math_used('mod(-140,-90)', '-50', {type:'number'});
+test_math_used('mod(-18,5)', '2', {type:'number'});
+test_math_used('rem(-18,5)', '-3', {type:'number'});
+test_math_used('mod(140,-90)', '-40', {type:'number'});
+test_math_used('rem(140,-90)', '50', {type:'number'});
+
+//Test basic calculations
+test_math_used('calc(round(round(100,10), 10))', '100', {type:'number'});
+test_math_used('calc(round(up, round(100,10) + 1,10))', '110', {type:'number'});
+test_math_used('calc(round(down, round(100,10) + 2 * 3,10))', '100', {type:'number'});
+test_math_used('calc(round(to-zero,round(100,10) * 2 - 95, 10))', '100', {type:'number'});
+test_math_used('calc(round(round(100,10)* -1,10))', '-100', {type:'number'});
+test_math_used('calc(round(up, -103 + -103 / -103 - 1,10))', '-100', {type:'number'});
+test_math_used('calc(mod(18,5) * 2 + mod(17,5))', '8', {type:'number'});
+test_math_used('calc(rem(mod(18,5),5))', '3', {type:'number'});
+test_math_used('calc(rem(mod(18,5),mod(17,5)))', '1', {type:'number'});
+test_math_used('calc(mod(-140,-90))', '-50', {type:'number'});
+test_math_used('calc(mod(rem(1,18)* -1,5))', '-1', {type:'number'});
+
+// Type check
+test_math_used('round(10px,6px)', '12px');
+test_math_used('round(10cm,6cm)', '12cm');
+test_math_used('round(10mm,6mm)', '12mm');
+test_math_used('round(10Q, 6Q)', '12Q');
+test_math_used('round(10in,6in)', '12in');
+test_math_used('round(10pc,6pc)', '12pc');
+test_math_used('round(10pt,6pt)', '12pt');
+test_math_used('round(10em,6em)', '12em');
+test_math_used('round(10ex,6ex)', '12ex');
+test_math_used('round(10ch,6ch)', '12ch');
+test_math_used('round(10rem,6rem)', '12rem');
+test_math_used('round(10vh,6vh)', '12vh');
+test_math_used('round(10vw,6vw)', '12vw');
+test_math_used('round(10vmin,6vmin)', '12vmin');
+test_math_used('round(10vmax,6vmax)', '12vmax');
+test_math_used('round(10s,6s)', '12s');
+test_math_used('round(10ms,6ms)', '12ms');
+test_math_used('round(10deg,6deg)', '12deg', {type:'angle', approx:0.1});
+test_math_used('round(10grad,6grad)', '12grad', {type:'angle', approx:0.1});
+test_math_used('round(10rad,6rad)', '12rad',{type:'angle', approx:0.1});
+test_math_used('round(10turn,6turn)', '12turn',{type:'angle', approx:0.1});
+
+test_math_used('mod(10px,6px)', '4px');
+test_math_used('mod(10cm,6cm)', '4cm');
+test_math_used('mod(10mm,6mm)', '4mm');
+test_math_used('mod(10Q, 6Q)', '4Q');
+test_math_used('mod(10in,6in)', '4in');
+test_math_used('mod(10pc,6pc)', '4pc');
+test_math_used('mod(10em,6em)', '4em');
+test_math_used('mod(10ex,6ex)', '4ex');
+test_math_used('mod(10ch,6ch)', '4ch');
+test_math_used('mod(10rem,6rem)', '4rem');
+test_math_used('mod(10vh,6vh)', '4vh');
+test_math_used('mod(10vw,6vw)', '4vw');
+test_math_used('mod(10vmin,6vmin)', '4vmin');
+test_math_used('mod(10vmax,6vmax)', '4vmax');
+test_math_used('mod(10s,6s)', '4s');
+test_math_used('mod(10ms,6ms)', '4ms');
+test_math_used('mod(10deg,6deg)', '4deg', {type:'angle', approx:0.1});
+test_math_used('mod(10grad,6grad)', '4grad', {type:'angle', approx:0.1});
+test_math_used('mod(10rad,6rad)', '4rad',{type:'angle', approx:0.1});
+test_math_used('mod(10turn,6turn)', '4turn',{type:'angle', approx:0.1});
+
+test_math_used('rem(10px,6px)', '4px');
+test_math_used('rem(10cm,6cm)', '4cm');
+test_math_used('rem(10mm,6mm)', '4mm');
+test_math_used('rem(10Q, 6Q)', '4Q');
+test_math_used('rem(10in,6in)', '4in');
+test_math_used('rem(10pc,6pc)', '4pc');
+test_math_used('rem(10em,6em)', '4em');
+test_math_used('rem(10ex,6ex)', '4ex');
+test_math_used('rem(10ch,6ch)', '4ch');
+test_math_used('rem(10rem,6rem)', '4rem');
+test_math_used('rem(10vh,6vh)', '4vh');
+test_math_used('rem(10vw,6vw)', '4vw');
+test_math_used('rem(10vmin,6vmin)', '4vmin');
+test_math_used('rem(10vmax,6vmax)', '4vmax');
+test_math_used('rem(10s,6s)', '4s');
+test_math_used('rem(10ms,6ms)', '4ms');
+test_math_used('rem(10deg,6deg)', '4deg', {type:'angle', approx:0.1});
+test_math_used('rem(10grad,6grad)', '4grad', {type:'angle', approx:0.1});
+test_math_used('rem(10rad,6rad)', '4rad',{type:'angle', approx:0.1});
+test_math_used('rem(10turn,6turn)', '4turn',{type:'angle', approx:0.1});
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-invalid.html
new file mode 100644
index 0000000..99ef2c64
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-invalid.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_number(value) {
+  test_invalid_value('opacity', value);
+}
+
+// Syntax checking
+test_invalid_number('round()');
+test_invalid_number('round( )');
+test_invalid_number('round(,)');
+test_invalid_number('round(1, )');
+test_invalid_number('round(, 1)');
+test_invalid_number('round(1 + )');
+test_invalid_number('round(1 - )');
+test_invalid_number('round(1 * )');
+test_invalid_number('round(1 / )');
+test_invalid_number('round(1 2)');
+test_invalid_number('round(nearest, 1 2)');
+test_invalid_number('round(1, nearest, 12)');
+test_invalid_number('round(1, nearest)');
+test_invalid_number('round(nearest, 1, nearest)');
+test_invalid_number('round(nearest, 1)');
+test_invalid_number('round(1, , 2)');
+test_invalid_number('mod()');
+test_invalid_number('mod( )');
+test_invalid_number('mod(,)');
+test_invalid_number('mod(1, )');
+test_invalid_number('mod(, 1)');
+test_invalid_number('mod(1 + )');
+test_invalid_number('mod(1 - )');
+test_invalid_number('mod(1 * )');
+test_invalid_number('mod(1 / )');
+test_invalid_number('mod(1 2)');
+test_invalid_number('mod(1, , 2)');
+test_invalid_number('rem()');
+test_invalid_number('rem( )');
+test_invalid_number('rem(,)');
+test_invalid_number('rem(1, )');
+test_invalid_number('rem(, 1)');
+test_invalid_number('rem(1 + )');
+test_invalid_number('rem(1 - )');
+test_invalid_number('rem(1 * )');
+test_invalid_number('rem(1 / )');
+test_invalid_number('rem(1 2)');
+test_invalid_number('rem(1, , 2)');
+
+// Type checking
+test_invalid_number('round(0px)');
+test_invalid_number('round(0s)');
+test_invalid_number('round(0deg)');
+test_invalid_number('round(0Hz)');
+test_invalid_number('round(0dpi)');
+test_invalid_number('round(0fr)');
+test_invalid_number('round(1, 1%)');
+test_invalid_number('round(1, 0px)');
+test_invalid_number('round(1, 0s)');
+test_invalid_number('round(1, 0deg)');
+test_invalid_number('round(1, 0Hz)');
+test_invalid_number('round(1, 0dpi)');
+test_invalid_number('round(1, 0fr)');
+test_invalid_number('mod(0px)');
+test_invalid_number('mod(0s)');
+test_invalid_number('mod(0deg)');
+test_invalid_number('mod(0Hz)');
+test_invalid_number('mod(0dpi)');
+test_invalid_number('mod(0fr)');
+test_invalid_number('mod(1, 1%)');
+test_invalid_number('mod(1, 0px)');
+test_invalid_number('mod(1, 0s)');
+test_invalid_number('mod(1, 0deg)');
+test_invalid_number('mod(1, 0Hz)');
+test_invalid_number('mod(1, 0dpi)');
+test_invalid_number('mod(1, 0fr)');
+test_invalid_number('rem(0px)');
+test_invalid_number('rem(0s)');
+test_invalid_number('rem(0deg)');
+test_invalid_number('rem(0Hz)');
+test_invalid_number('rem(0dpi)');
+test_invalid_number('rem(0fr)');
+test_invalid_number('rem(1, 1%)');
+test_invalid_number('rem(1, 0px)');
+test_invalid_number('rem(1, 0s)');
+test_invalid_number('rem(1, 0deg)');
+test_invalid_number('rem(1, 0Hz)');
+test_invalid_number('rem(1, 0dpi)');
+test_invalid_number('rem(1, 0fr)');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-serialize-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-serialize-expected.txt
new file mode 100644
index 0000000..162be5e2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-serialize-expected.txt
@@ -0,0 +1,15 @@
+This is a testharness.js-based test.
+FAIL 'round(1.1,1)' as a specified value should serialize as 'calc(1)'. assert_not_equals: 'round(1.1,1)' should be valid in opacity. got disallowed value ""
+FAIL 'scale(round(1.1,1))' as a specified value should serialize as 'scale(calc(1))'. assert_not_equals: 'scale(round(1.1,1))' should be valid in transform. got disallowed value ""
+PASS 'round(1.1,1)' as a computed value should serialize as '1'.
+FAIL 'scale(round(1.1,1))' as a computed value should serialize as 'matrix(1, 0, 0, 1, 0, 0)'. assert_equals: 'scale(round(1.1,1))' and 'matrix(1, 0, 0, 1, 0, 0)' should serialize the same in computed values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL 'mod(1,1)' as a specified value should serialize as 'calc(0)'. assert_not_equals: 'mod(1,1)' should be valid in opacity. got disallowed value ""
+FAIL 'scale(mod(1,1))' as a specified value should serialize as 'scale(calc(0))'. assert_not_equals: 'scale(mod(1,1))' should be valid in transform. got disallowed value ""
+FAIL 'mod(1,1)' as a computed value should serialize as '0'. assert_equals: 'mod(1,1)' and '0' should serialize the same in computed values. expected "0" but got "1"
+FAIL 'scale(mod(1,1))' as a computed value should serialize as 'matrix(0, 0, 0, 0, 0, 0)'. assert_equals: 'scale(mod(1,1))' and 'matrix(0, 0, 0, 0, 0, 0)' should serialize the same in computed values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL 'rem(1,1)' as a specified value should serialize as 'calc(0)'. assert_not_equals: 'rem(1,1)' should be valid in opacity. got disallowed value ""
+FAIL 'scale(rem(1,1))' as a specified value should serialize as 'scale(calc(0))'. assert_not_equals: 'scale(rem(1,1))' should be valid in transform. got disallowed value ""
+FAIL 'rem(1,1)' as a computed value should serialize as '0'. assert_equals: 'rem(1,1)' and '0' should serialize the same in computed values. expected "0" but got "1"
+FAIL 'scale(rem(1,1))' as a computed value should serialize as 'matrix(0, 0, 0, 0, 0, 0)'. assert_equals: 'scale(rem(1,1))' and 'matrix(0, 0, 0, 0, 0, 0)' should serialize the same in computed values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-serialize.html b/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-serialize.html
new file mode 100644
index 0000000..4902495
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/round-mod-rem-serialize.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Xiaocheng Hu" href="mailto:xiaochengh@chromium.org">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c) {
+    test_specified_serialization('opacity', t, s);
+    test_specified_serialization('transform', `scale(${t})`, `scale(calc(${c}))`);
+    test_computed_serialization('opacity', t, c);
+    test_computed_serialization('transform', `scale(${t})`, `matrix(${c}, 0, 0, ${c}, 0, 0)`);
+}
+
+test_serialization(
+    'round(1.1,1)',
+    'calc(1)',
+    '1');
+test_serialization(
+    'mod(1,1)',
+    'calc(0)',
+    '0');
+test_serialization(
+    'rem(1,1)',
+    'calc(0)',
+    '0');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-computed.html b/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-computed.html
new file mode 100644
index 0000000..ba672f2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-computed.html
@@ -0,0 +1,164 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/numeric-testcommon.js"></script>
+<div id="target"></div>
+<script>
+// Identity tests
+test_math_used('abs(1)', '1', {type:'number'});
+test_math_used('sign(1)', '1', {type:'number'});
+test_math_used('abs(-1)', '1', {type:'number'});
+test_math_used('sign(-1)', '-1', {type:'number'});
+
+// Nestings
+test_math_used('abs(sign(1))', '1');
+test_math_used('abs(sign(sign(1)))', '1');
+test_math_used('sign(sign(sign(1) + sign(1)))', '1');
+
+// General calculations
+test_math_used('calc(abs(0.1 + 0.2) + 0.05)', '0.35', {type:'number', approx:0.1});
+test_math_used('calc(sign(0.1 + 0.2) - 0.05)', '0.95', {type:'number', approx:0.1});
+test_math_used('calc(abs(0.1 + 0.2) * 2)', '0.6', {type:'number', approx:0.1});
+test_math_used('calc(abs(sign(0.1) + 0.2) / 2)', '0.6', {type:'number', approx:0.1});
+test_math_used('calc(abs(0.1 + 0.2) * -2)', '-0.6', {type:'number', approx:0.1});
+test_math_used('calc(sign(0.1 - 0.2) - 0.05)', '-1.05', {type:'number', approx:0.1});
+test_math_used('calc(sign(1) + sign(1) - 0.05)', '1.95', {type:'number', approx:0.1});
+
+// Test sign for zero
+test_math_used('calc(sign(-0))', '-0', {type:'number'});
+test_math_used('calc(sign(0))', '0', {type:'number'});
+
+//Type checking sign
+test_math_used('sign(1px)', '1');
+test_math_used('sign(1cm)', '1');
+test_math_used('sign(1mm)', '1');
+test_math_used('sign(1Q)', '1');
+test_math_used('sign(1in)', '1');
+test_math_used('sign(1pc)', '1');
+test_math_used('sign(1pt)', '1');
+test_math_used('sign(1em)', '1');
+test_math_used('sign(1ex)', '1');
+test_math_used('sign(1ch)', '1');
+test_math_used('sign(1rem)', '1');
+test_math_used('sign(1vh)', '1');
+test_math_used('sign(1vw)', '1');
+test_math_used('sign(1vmin)', '1');
+test_math_used('sign(1vmax)', '1');
+test_math_used('sign(-1px)', '-1');
+test_math_used('sign(-1cm)', '-1');
+test_math_used('sign(-1mm)', '-1');
+test_math_used('sign(-1Q)', '-1');
+test_math_used('sign(-1in)', '-1');
+test_math_used('sign(-1pc)', '-1');
+test_math_used('sign(-1pt)', '-1');
+test_math_used('sign(-1em)', '-1');
+test_math_used('sign(-1ex)', '-1');
+test_math_used('sign(-1ch)', '-1');
+test_math_used('sign(-1rem)', '-1');
+test_math_used('sign(-1vh)', '-1');
+test_math_used('sign(-1vw)', '-1');
+test_math_used('sign(-1vmin)', '-1');
+test_math_used('sign(-1vmax)', '-1');
+test_math_used('sign(1s)', '1');
+test_math_used('sign(1ms)', '1');
+test_math_used('sign(-1s)', '-1');
+test_math_used('sign(-1ms)', '-1');
+test_math_used('sign(1deg)', '1');
+test_math_used('sign(1grad)', '1');
+test_math_used('sign(1rad)', '1');
+test_math_used('sign(1turn)', '1');
+test_math_used('sign(-1deg)', '-1');
+test_math_used('sign(-1grad)', '-1');
+test_math_used('sign(-1rad)', '-1');
+test_math_used('sign(-1turn)', '-1');
+test_math_used('sign(0px)', '0');
+test_math_used('sign(0cm)', '0');
+test_math_used('sign(0mm)', '0');
+test_math_used('sign(0Q)', '0');
+test_math_used('sign(0in)', '0');
+test_math_used('sign(0pc)', '0');
+test_math_used('sign(0pt)', '0');
+test_math_used('sign(0em)', '0');
+test_math_used('sign(0ex)', '0');
+test_math_used('sign(0ch)', '0');
+test_math_used('sign(0rem)', '0');
+test_math_used('sign(0vh)', '0');
+test_math_used('sign(0vw)', '0');
+test_math_used('sign(0vmin)', '0');
+test_math_used('sign(0vmax)', '0');
+test_math_used('sign(-0px)', '-0');
+test_math_used('sign(-0cm)', '-0');
+test_math_used('sign(-0mm)', '-0');
+test_math_used('sign(-0Q)', '-0');
+test_math_used('sign(-0in)', '-0');
+test_math_used('sign(-0pc)', '-0');
+test_math_used('sign(-0pt)', '-0');
+test_math_used('sign(-0em)', '-0');
+test_math_used('sign(-0ex)', '-0');
+test_math_used('sign(-0ch)', '-0');
+test_math_used('sign(-0rem)', '-0');
+test_math_used('sign(-0vh)', '-0');
+test_math_used('sign(-0vw)', '-0');
+test_math_used('sign(-0vmin)', '-0');
+test_math_used('sign(-0vmax)', '-0');
+test_math_used('sign(0s)', '0');
+test_math_used('sign(0ms)', '0');
+test_math_used('sign(-0s)', '0');
+test_math_used('sign(-0ms)', '0');
+test_math_used('sign(0deg)', '0');
+test_math_used('sign(0grad)', '0');
+test_math_used('sign(0rad)', '0');
+test_math_used('sign(0turn)', '0');
+test_math_used('sign(-0deg)', '-0');
+test_math_used('sign(-0grad)', '-0');
+test_math_used('sign(-0rad)', '-0');
+test_math_used('sign(-0turn)', '-0');
+
+//Type checking abs
+test_math_used('abs(1px)', '1px');
+test_math_used('abs(1cm)', '1cm');
+test_math_used('abs(1mm)', '1mm');
+test_math_used('abs(1Q)', '1Q');
+test_math_used('abs(1in)', '1in');
+test_math_used('abs(1pc)', '1pc');
+test_math_used('abs(1pt)', '1pt');
+test_math_used('abs(1em)', '1em');
+test_math_used('abs(1ex)', '1ex');
+test_math_used('abs(1ch)', '1ch');
+test_math_used('abs(1rem)', '1rem');
+test_math_used('abs(1vh)', '1vh');
+test_math_used('abs(1vw)', '1vw');
+test_math_used('abs(1vmin)', '1vmin');
+test_math_used('abs(1vmax)', '1vmax');
+test_math_used('abs(-1px)', '1px');
+test_math_used('abs(-1cm)', '1cm');
+test_math_used('abs(-1mm)', '1mm');
+test_math_used('abs(-1Q)', '1Q');
+test_math_used('abs(-1in)', '1in');
+test_math_used('abs(-1pc)', '1pc');
+test_math_used('abs(-1pt)', '1pt');
+test_math_used('abs(-1em)', '1em');
+test_math_used('abs(-1ex)', '1ex');
+test_math_used('abs(-1ch)', '1ch');
+test_math_used('abs(-1rem)', '1rem');
+test_math_used('abs(-1vh)', '1vh');
+test_math_used('abs(-1vw)', '1vw');
+test_math_used('abs(-1vmin)', '1vmin');
+test_math_used('abs(-1vmax)', '1vmax');
+test_math_used('abs(1s)', '1s', {type:'time'});
+test_math_used('abs(1ms)', '1ms', {type:'time'});
+test_math_used('abs(-1s)', '1s', {type:'time'});
+test_math_used('abs(-1ms)', '1ms', {type:'time'});
+test_math_used('abs(1deg)', '1deg', {type:'angle', approx:0.001});
+test_math_used('abs(1grad)', '1grad', {type:'angle', approx:0.001});
+test_math_used('abs(1rad)', '1rad', {type:'angle', approx:0.001});
+test_math_used('abs(1turn)', '1turn', {type:'angle', approx:0.001});
+test_math_used('abs(-1deg)', '1deg', {type:'angle', approx:0.001});
+test_math_used('abs(-1grad)', '1grad', {type:'angle', approx:0.001});
+test_math_used('abs(-1rad)', '1rad', {type:'angle', approx:0.001});
+test_math_used('abs(-1turn)', '1turn', {type:'angle', approx:0.001});
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-invalid.html
new file mode 100644
index 0000000..15b058d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-invalid.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-type-checking">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/parsing-testcommon.js"></script>
+<script>
+function test_invalid_number(value) {
+  test_invalid_value('opacity', value);
+}
+
+// Syntax checking
+test_invalid_number('abs()');
+test_invalid_number('abs( )');
+test_invalid_number('abs(,)');
+test_invalid_number('abs(1, )');
+test_invalid_number('abs(, 1)');
+test_invalid_number('abs(1 + )');
+test_invalid_number('abs(1 - )');
+test_invalid_number('abs(1 * )');
+test_invalid_number('abs(1 / )');
+test_invalid_number('abs(1 2)');
+test_invalid_number('abs(1, , 2)');
+test_invalid_number('abs(1, 2)');
+test_invalid_number('sign()');
+test_invalid_number('sign( )');
+test_invalid_number('sign(,)');
+test_invalid_number('sign(1, )');
+test_invalid_number('sign(, 1)');
+test_invalid_number('sign(1 + )');
+test_invalid_number('sign(1 - )');
+test_invalid_number('sign(1 * )');
+test_invalid_number('sign(1 / )');
+test_invalid_number('sign(1 2)');
+test_invalid_number('sign(1, , 2)');
+test_invalid_number('sign(1, 2)');
+
+// Type checking
+test_invalid_number('abs(0px)');
+test_invalid_number('abs(0s)');
+test_invalid_number('abs(0deg)');
+test_invalid_number('abs(0Hz)');
+test_invalid_number('abs(0dpi)');
+test_invalid_number('abs(0fr)');
+test_invalid_number('abs(1, 1%)');
+test_invalid_number('abs(1, 0px)');
+test_invalid_number('abs(1, 0s)');
+test_invalid_number('abs(1, 0deg)');
+test_invalid_number('abs(1, 0Hz)');
+test_invalid_number('abs(1, 0dpi)');
+test_invalid_number('abs(1, 0fr)');
+test_invalid_number('sign(1, 1%)');
+test_invalid_number('sign(1, 0px)');
+test_invalid_number('sign(1, 0s)');
+test_invalid_number('sign(1, 0deg)');
+test_invalid_number('sign(1, 0Hz)');
+test_invalid_number('sign(1, 0dpi)');
+test_invalid_number('sign(1, 0fr)');
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-serialize-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-serialize-expected.txt
new file mode 100644
index 0000000..2dc9ef1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-serialize-expected.txt
@@ -0,0 +1,35 @@
+This is a testharness.js-based test.
+FAIL 'abs(1)' as a specified value should serialize as 'calc(1)'. assert_not_equals: 'abs(1)' should be valid in opacity. got disallowed value ""
+FAIL 'scale(abs(1))' as a specified value should serialize as 'scale(calc(1))'. assert_not_equals: 'scale(abs(1))' should be valid in transform. got disallowed value ""
+PASS 'abs(1)' as a computed value should serialize as '1'.
+FAIL 'scale(abs(1))' as a computed value should serialize as 'matrix(1, 0, 0, 1, 0, 0)'. assert_equals: 'scale(abs(1))' and 'matrix(1, 0, 0, 1, 0, 0)' should serialize the same in computed values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL 'sign(.1)' as a specified value should serialize as 'calc(1)'. assert_not_equals: 'sign(.1)' should be valid in opacity. got disallowed value ""
+FAIL 'scale(sign(.1))' as a specified value should serialize as 'scale(calc(1))'. assert_not_equals: 'scale(sign(.1))' should be valid in transform. got disallowed value ""
+PASS 'sign(.1)' as a computed value should serialize as '1'.
+FAIL 'scale(sign(.1))' as a computed value should serialize as 'matrix(1, 0, 0, 1, 0, 0)'. assert_equals: 'scale(sign(.1))' and 'matrix(1, 0, 0, 1, 0, 0)' should serialize the same in computed values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL 'abs(1 + 2 + 3)' as a specified value should serialize as 'calc(6)'. assert_not_equals: 'abs(1 + 2 + 3)' should be valid in opacity. got disallowed value ""
+FAIL 'scale(abs(1 + 2 + 3))' as a specified value should serialize as 'scale(calc(6))'. assert_not_equals: 'scale(abs(1 + 2 + 3))' should be valid in transform. got disallowed value ""
+FAIL 'abs(1 + 2 + 3)' as a computed value should serialize as '6'. assert_equals: '6' should round-trip exactly in computed values. expected "6" but got "1"
+FAIL 'scale(abs(1 + 2 + 3))' as a computed value should serialize as 'matrix(6, 0, 0, 6, 0, 0)'. assert_equals: 'scale(abs(1 + 2 + 3))' and 'matrix(6, 0, 0, 6, 0, 0)' should serialize the same in computed values. expected "matrix(6, 0, 0, 6, 0, 0)" but got "none"
+FAIL 'sign(1 + 2 + 3)' as a specified value should serialize as 'calc(1)'. assert_not_equals: 'sign(1 + 2 + 3)' should be valid in opacity. got disallowed value ""
+FAIL 'scale(sign(1 + 2 + 3))' as a specified value should serialize as 'scale(calc(1))'. assert_not_equals: 'scale(sign(1 + 2 + 3))' should be valid in transform. got disallowed value ""
+PASS 'sign(1 + 2 + 3)' as a computed value should serialize as '1'.
+FAIL 'scale(sign(1 + 2 + 3))' as a computed value should serialize as 'matrix(1, 0, 0, 1, 0, 0)'. assert_equals: 'scale(sign(1 + 2 + 3))' and 'matrix(1, 0, 0, 1, 0, 0)' should serialize the same in computed values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL 'calc(abs(1) + abs(2))' as a specified value should serialize as 'calc(3)'. assert_not_equals: 'calc(abs(1) + abs(2))' should be valid in opacity. got disallowed value ""
+FAIL 'scale(calc(abs(1) + abs(2)))' as a specified value should serialize as 'scale(calc(3))'. assert_not_equals: 'scale(calc(abs(1) + abs(2)))' should be valid in transform. got disallowed value ""
+FAIL 'calc(abs(1) + abs(2))' as a computed value should serialize as '3'. assert_equals: '3' should round-trip exactly in computed values. expected "3" but got "1"
+FAIL 'scale(calc(abs(1) + abs(2)))' as a computed value should serialize as 'matrix(3, 0, 0, 3, 0, 0)'. assert_equals: 'scale(calc(abs(1) + abs(2)))' and 'matrix(3, 0, 0, 3, 0, 0)' should serialize the same in computed values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL 'calc(sign(.1) + sign(.2))' as a specified value should serialize as 'calc(2)'. assert_not_equals: 'calc(sign(.1) + sign(.2))' should be valid in opacity. got disallowed value ""
+FAIL 'scale(calc(sign(.1) + sign(.2)))' as a specified value should serialize as 'scale(calc(2))'. assert_not_equals: 'scale(calc(sign(.1) + sign(.2)))' should be valid in transform. got disallowed value ""
+FAIL 'calc(sign(.1) + sign(.2))' as a computed value should serialize as '2'. assert_equals: '2' should round-trip exactly in computed values. expected "2" but got "1"
+FAIL 'scale(calc(sign(.1) + sign(.2)))' as a computed value should serialize as 'matrix(2, 0, 0, 2, 0, 0)'. assert_equals: 'scale(calc(sign(.1) + sign(.2)))' and 'matrix(2, 0, 0, 2, 0, 0)' should serialize the same in computed values. expected "matrix(2, 0, 0, 2, 0, 0)" but got "none"
+FAIL 'calc(1 + abs(1))' as a specified value should serialize as 'calc(2)'. assert_not_equals: 'calc(1 + abs(1))' should be valid in opacity. got disallowed value ""
+FAIL 'scale(calc(1 + abs(1)))' as a specified value should serialize as 'scale(calc(2))'. assert_not_equals: 'scale(calc(1 + abs(1)))' should be valid in transform. got disallowed value ""
+FAIL 'calc(1 + abs(1))' as a computed value should serialize as '2'. assert_equals: '2' should round-trip exactly in computed values. expected "2" but got "1"
+FAIL 'scale(calc(1 + abs(1)))' as a computed value should serialize as 'matrix(2, 0, 0, 2, 0, 0)'. assert_equals: 'scale(calc(1 + abs(1)))' and 'matrix(2, 0, 0, 2, 0, 0)' should serialize the same in computed values. expected "matrix(2, 0, 0, 2, 0, 0)" but got "none"
+FAIL 'calc(sign(.1) + 1)' as a specified value should serialize as 'calc(2)'. assert_not_equals: 'calc(sign(.1) + 1)' should be valid in opacity. got disallowed value ""
+FAIL 'scale(calc(sign(.1) + 1))' as a specified value should serialize as 'scale(calc(2))'. assert_not_equals: 'scale(calc(sign(.1) + 1))' should be valid in transform. got disallowed value ""
+FAIL 'calc(sign(.1) + 1)' as a computed value should serialize as '2'. assert_equals: '2' should round-trip exactly in computed values. expected "2" but got "1"
+FAIL 'scale(calc(sign(.1) + 1))' as a computed value should serialize as 'matrix(2, 0, 0, 2, 0, 0)'. assert_equals: 'scale(calc(sign(.1) + 1))' and 'matrix(2, 0, 0, 2, 0, 0)' should serialize the same in computed values. expected "matrix(2, 0, 0, 2, 0, 0)" but got "none"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-serialize.html b/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-serialize.html
new file mode 100644
index 0000000..b7b5ad2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-values/signs-abs-serialize.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#comp-func">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#numbers">
+<link rel="help" href="https://drafts.csswg.org/css-values-4/#calc-serialize">
+<link rel="author" title="Apple Inc">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../support/serialize-testcommon.js"></script>
+<div id=target></div>
+<script>
+function test_serialization(t,s,c) {
+    test_specified_serialization('opacity', t, s);
+    test_specified_serialization('transform', `scale(${t})`, `scale(calc(${c}))`);
+    test_computed_serialization('opacity', t, c);
+    test_computed_serialization('transform', `scale(${t})`, `matrix(${c}, 0, 0, ${c}, 0, 0)`);
+}
+
+test_serialization(
+    'abs(1)',
+    'calc(1)',
+    '1');
+test_serialization(
+    'sign(.1)',
+    'calc(1)',
+    '1');
+
+test_serialization(
+    'abs(1 + 2 + 3)',
+    'calc(6)',
+    '6');
+test_serialization(
+    'sign(1 + 2 + 3)',
+    'calc(1)',
+    '1');
+
+test_serialization(
+    'calc(abs(1) + abs(2))',
+    'calc(3)',
+    '3');
+test_serialization(
+    'calc(sign(.1) + sign(.2))',
+    'calc(2)',
+    '2');
+
+test_serialization(
+    'calc(1 + abs(1))',
+    'calc(2)',
+    '2');
+test_serialization(
+    'calc(sign(.1) + 1)',
+    'calc(2)',
+    '2');
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
index 91f89ee..3127c03 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-navigated-expected.txt
@@ -6,6 +6,7 @@
 PASS window.cached_appHistory.canGoBack is false
 PASS window.cached_appHistory.canGoForward is false
 PASS window.cached_appHistory.current is null
+PASS window.cached_appHistory.oncurrentchange is null
 PASS window.cached_appHistory.onnavigate is null
 PASS window.cached_appHistory.onnavigateerror is null
 PASS window.cached_appHistory.onnavigatesuccess is null
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
index 9e8dd78..01b6895 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-and-gced-expected.txt
@@ -6,6 +6,7 @@
 PASS window.cached_appHistory.canGoBack is false
 PASS window.cached_appHistory.canGoForward is false
 PASS window.cached_appHistory.current is null
+PASS window.cached_appHistory.oncurrentchange is null
 PASS window.cached_appHistory.onnavigate is null
 PASS window.cached_appHistory.onnavigateerror is null
 PASS window.cached_appHistory.onnavigatesuccess is null
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
index 5970667..f41566e 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-properties-after-frame-removed-expected.txt
@@ -6,6 +6,7 @@
 PASS window.cached_appHistory.canGoBack is false
 PASS window.cached_appHistory.canGoForward is false
 PASS window.cached_appHistory.current is null
+PASS window.cached_appHistory.oncurrentchange is null
 PASS window.cached_appHistory.onnavigate is null
 PASS window.cached_appHistory.onnavigateerror is null
 PASS window.cached_appHistory.onnavigatesuccess is null
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
index 5c865af..610a926 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-navigated-expected.txt
@@ -6,6 +6,7 @@
 PASS oldChildWindow.appHistory.canGoBack is newChildWindow.appHistory.canGoBack
 PASS oldChildWindow.appHistory.canGoForward is newChildWindow.appHistory.canGoForward
 PASS oldChildWindow.appHistory.current is newChildWindow.appHistory.current
+PASS oldChildWindow.appHistory.oncurrentchange is newChildWindow.appHistory.oncurrentchange
 PASS oldChildWindow.appHistory.onnavigate is newChildWindow.appHistory.onnavigate
 PASS oldChildWindow.appHistory.onnavigateerror is newChildWindow.appHistory.onnavigateerror
 PASS oldChildWindow.appHistory.onnavigatesuccess is newChildWindow.appHistory.onnavigatesuccess
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
index 86c57a2..e9468e57 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-and-gced-expected.txt
@@ -6,6 +6,7 @@
 PASS childWindow.appHistory.canGoBack is false
 PASS childWindow.appHistory.canGoForward is false
 PASS childWindow.appHistory.current is null
+PASS childWindow.appHistory.oncurrentchange is null
 PASS childWindow.appHistory.onnavigate is null
 PASS childWindow.appHistory.onnavigateerror is null
 PASS childWindow.appHistory.onnavigatesuccess is null
diff --git a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
index 655a0b1..79e12524 100644
--- a/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
+++ b/third_party/blink/web_tests/fast/dom/Window/property-access-on-cached-window-after-frame-removed-expected.txt
@@ -6,6 +6,7 @@
 PASS childWindow.appHistory.canGoBack is false
 PASS childWindow.appHistory.canGoForward is false
 PASS childWindow.appHistory.current is null
+PASS childWindow.appHistory.oncurrentchange is null
 PASS childWindow.appHistory.onnavigate is null
 PASS childWindow.appHistory.onnavigateerror is null
 PASS childWindow.appHistory.onnavigatesuccess is null
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-values/round-mod-rem-computed-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-values/round-mod-rem-computed-expected.txt
new file mode 100644
index 0000000..af52fc8
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-values/round-mod-rem-computed-expected.txt
@@ -0,0 +1,93 @@
+This is a testharness.js-based test.
+Found 89 tests; 6 PASS, 83 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL round(10,10) should be used-value-equivalent to 10 assert_equals: round(10,10) and 10 serialize to the same thing in used values. expected "matrix(10, 0, 0, 10, 0, 0)" but got "none"
+FAIL mod(1,1) should be used-value-equivalent to 0 assert_equals: mod(1,1) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL rem(1,1) should be used-value-equivalent to 0 assert_equals: rem(1,1) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL calc(round(100,10)) should be used-value-equivalent to 100 assert_equals: calc(round(100,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(up, 101,10)) should be used-value-equivalent to 110 assert_equals: calc(round(up, 101,10)) and 110 serialize to the same thing in used values. expected "matrix(110, 0, 0, 110, 0, 0)" but got "none"
+FAIL calc(round(down, 106,10)) should be used-value-equivalent to 100 assert_equals: calc(round(down, 106,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,105, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,105, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,-105, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,-105, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(-100,10)) should be used-value-equivalent to -100 assert_equals: calc(round(-100,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(round(up, -103,10)) should be used-value-equivalent to -100 assert_equals: calc(round(up, -103,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL mod(18,5) should be used-value-equivalent to 3 assert_equals: mod(18,5) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL rem(18,5) should be used-value-equivalent to 3 assert_equals: rem(18,5) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL mod(-140,-90) should be used-value-equivalent to -50 assert_equals: mod(-140,-90) and -50 serialize to the same thing in used values. expected "matrix(-50, 0, 0, -50, 0, 0)" but got "none"
+FAIL mod(-18,5) should be used-value-equivalent to 2 assert_equals: mod(-18,5) and 2 serialize to the same thing in used values. expected "matrix(2, 0, 0, 2, 0, 0)" but got "none"
+FAIL rem(-18,5) should be used-value-equivalent to -3 assert_equals: rem(-18,5) and -3 serialize to the same thing in used values. expected "matrix(-3, 0, 0, -3, 0, 0)" but got "none"
+FAIL mod(140,-90) should be used-value-equivalent to -40 assert_equals: mod(140,-90) and -40 serialize to the same thing in used values. expected "matrix(-40, 0, 0, -40, 0, 0)" but got "none"
+FAIL rem(140,-90) should be used-value-equivalent to 50 assert_equals: rem(140,-90) and 50 serialize to the same thing in used values. expected "matrix(50, 0, 0, 50, 0, 0)" but got "none"
+FAIL calc(round(round(100,10), 10)) should be used-value-equivalent to 100 assert_equals: calc(round(round(100,10), 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(up, round(100,10) + 1,10)) should be used-value-equivalent to 110 assert_equals: calc(round(up, round(100,10) + 1,10)) and 110 serialize to the same thing in used values. expected "matrix(110, 0, 0, 110, 0, 0)" but got "none"
+FAIL calc(round(down, round(100,10) + 2 * 3,10)) should be used-value-equivalent to 100 assert_equals: calc(round(down, round(100,10) + 2 * 3,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,round(100,10) * 2 - 95, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,round(100,10) * 2 - 95, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(round(100,10)* -1,10)) should be used-value-equivalent to -100 assert_equals: calc(round(round(100,10)* -1,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(round(up, -103 + -103 / -103 - 1,10)) should be used-value-equivalent to -100 assert_equals: calc(round(up, -103 + -103 / -103 - 1,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(mod(18,5) * 2 + mod(17,5)) should be used-value-equivalent to 8 assert_equals: calc(mod(18,5) * 2 + mod(17,5)) and 8 serialize to the same thing in used values. expected "matrix(8, 0, 0, 8, 0, 0)" but got "none"
+FAIL calc(rem(mod(18,5),5)) should be used-value-equivalent to 3 assert_equals: calc(rem(mod(18,5),5)) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL calc(rem(mod(18,5),mod(17,5))) should be used-value-equivalent to 1 assert_equals: calc(rem(mod(18,5),mod(17,5))) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL calc(mod(-140,-90)) should be used-value-equivalent to -50 assert_equals: calc(mod(-140,-90)) and -50 serialize to the same thing in used values. expected "matrix(-50, 0, 0, -50, 0, 0)" but got "none"
+FAIL calc(mod(rem(1,18)* -1,5)) should be used-value-equivalent to -1 assert_equals: calc(mod(rem(1,18)* -1,5)) and -1 serialize to the same thing in used values. expected "matrix(-1, 0, 0, -1, 0, 0)" but got "none"
+FAIL round(10px,6px) should be used-value-equivalent to 12px assert_equals: round(10px,6px) and 12px serialize to the same thing in used values. expected "12px" but got "0px"
+FAIL round(10cm,6cm) should be used-value-equivalent to 12cm assert_equals: round(10cm,6cm) and 12cm serialize to the same thing in used values. expected "453.543px" but got "0px"
+FAIL round(10mm,6mm) should be used-value-equivalent to 12mm assert_equals: round(10mm,6mm) and 12mm serialize to the same thing in used values. expected "45.3543px" but got "0px"
+FAIL round(10Q, 6Q) should be used-value-equivalent to 12Q assert_equals: round(10Q, 6Q) and 12Q serialize to the same thing in used values. expected "11.3386px" but got "0px"
+FAIL round(10in,6in) should be used-value-equivalent to 12in assert_equals: round(10in,6in) and 12in serialize to the same thing in used values. expected "1152px" but got "0px"
+FAIL round(10pc,6pc) should be used-value-equivalent to 12pc assert_equals: round(10pc,6pc) and 12pc serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10pt,6pt) should be used-value-equivalent to 12pt assert_equals: round(10pt,6pt) and 12pt serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL round(10em,6em) should be used-value-equivalent to 12em assert_equals: round(10em,6em) and 12em serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10ex,6ex) should be used-value-equivalent to 12ex assert_equals: round(10ex,6ex) and 12ex serialize to the same thing in used values. expected "88.125px" but got "0px"
+FAIL round(10ch,6ch) should be used-value-equivalent to 12ch assert_equals: round(10ch,6ch) and 12ch serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL round(10rem,6rem) should be used-value-equivalent to 12rem assert_equals: round(10rem,6rem) and 12rem serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10vh,6vh) should be used-value-equivalent to 12vh assert_equals: round(10vh,6vh) and 12vh serialize to the same thing in used values. expected "72px" but got "0px"
+FAIL round(10vw,6vw) should be used-value-equivalent to 12vw assert_equals: round(10vw,6vw) and 12vw serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL round(10vmin,6vmin) should be used-value-equivalent to 12vmin assert_equals: round(10vmin,6vmin) and 12vmin serialize to the same thing in used values. expected "72px" but got "0px"
+FAIL round(10vmax,6vmax) should be used-value-equivalent to 12vmax assert_equals: round(10vmax,6vmax) and 12vmax serialize to the same thing in used values. expected "96px" but got "0px"
+PASS round(10s,6s) should be used-value-equivalent to 12s
+PASS round(10ms,6ms) should be used-value-equivalent to 12ms
+FAIL round(10deg,6deg) should be used-value-equivalent to 12deg Cannot read properties of undefined (reading 'split')
+FAIL round(10grad,6grad) should be used-value-equivalent to 12grad Cannot read properties of undefined (reading 'split')
+FAIL round(10rad,6rad) should be used-value-equivalent to 12rad Cannot read properties of undefined (reading 'split')
+FAIL round(10turn,6turn) should be used-value-equivalent to 12turn Cannot read properties of undefined (reading 'split')
+FAIL mod(10px,6px) should be used-value-equivalent to 4px assert_equals: mod(10px,6px) and 4px serialize to the same thing in used values. expected "4px" but got "0px"
+FAIL mod(10cm,6cm) should be used-value-equivalent to 4cm assert_equals: mod(10cm,6cm) and 4cm serialize to the same thing in used values. expected "151.181px" but got "0px"
+FAIL mod(10mm,6mm) should be used-value-equivalent to 4mm assert_equals: mod(10mm,6mm) and 4mm serialize to the same thing in used values. expected "15.1181px" but got "0px"
+FAIL mod(10Q, 6Q) should be used-value-equivalent to 4Q assert_equals: mod(10Q, 6Q) and 4Q serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL mod(10in,6in) should be used-value-equivalent to 4in assert_equals: mod(10in,6in) and 4in serialize to the same thing in used values. expected "384px" but got "0px"
+FAIL mod(10pc,6pc) should be used-value-equivalent to 4pc assert_equals: mod(10pc,6pc) and 4pc serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10em,6em) should be used-value-equivalent to 4em assert_equals: mod(10em,6em) and 4em serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10ex,6ex) should be used-value-equivalent to 4ex assert_equals: mod(10ex,6ex) and 4ex serialize to the same thing in used values. expected "29.375px" but got "0px"
+FAIL mod(10ch,6ch) should be used-value-equivalent to 4ch assert_equals: mod(10ch,6ch) and 4ch serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL mod(10rem,6rem) should be used-value-equivalent to 4rem assert_equals: mod(10rem,6rem) and 4rem serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10vh,6vh) should be used-value-equivalent to 4vh assert_equals: mod(10vh,6vh) and 4vh serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL mod(10vw,6vw) should be used-value-equivalent to 4vw assert_equals: mod(10vw,6vw) and 4vw serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL mod(10vmin,6vmin) should be used-value-equivalent to 4vmin assert_equals: mod(10vmin,6vmin) and 4vmin serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL mod(10vmax,6vmax) should be used-value-equivalent to 4vmax assert_equals: mod(10vmax,6vmax) and 4vmax serialize to the same thing in used values. expected "32px" but got "0px"
+PASS mod(10s,6s) should be used-value-equivalent to 4s
+PASS mod(10ms,6ms) should be used-value-equivalent to 4ms
+FAIL mod(10deg,6deg) should be used-value-equivalent to 4deg Cannot read properties of undefined (reading 'split')
+FAIL mod(10grad,6grad) should be used-value-equivalent to 4grad Cannot read properties of undefined (reading 'split')
+FAIL mod(10rad,6rad) should be used-value-equivalent to 4rad Cannot read properties of undefined (reading 'split')
+FAIL mod(10turn,6turn) should be used-value-equivalent to 4turn Cannot read properties of undefined (reading 'split')
+FAIL rem(10px,6px) should be used-value-equivalent to 4px assert_equals: rem(10px,6px) and 4px serialize to the same thing in used values. expected "4px" but got "0px"
+FAIL rem(10cm,6cm) should be used-value-equivalent to 4cm assert_equals: rem(10cm,6cm) and 4cm serialize to the same thing in used values. expected "151.181px" but got "0px"
+FAIL rem(10mm,6mm) should be used-value-equivalent to 4mm assert_equals: rem(10mm,6mm) and 4mm serialize to the same thing in used values. expected "15.1181px" but got "0px"
+FAIL rem(10Q, 6Q) should be used-value-equivalent to 4Q assert_equals: rem(10Q, 6Q) and 4Q serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL rem(10in,6in) should be used-value-equivalent to 4in assert_equals: rem(10in,6in) and 4in serialize to the same thing in used values. expected "384px" but got "0px"
+FAIL rem(10pc,6pc) should be used-value-equivalent to 4pc assert_equals: rem(10pc,6pc) and 4pc serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10em,6em) should be used-value-equivalent to 4em assert_equals: rem(10em,6em) and 4em serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10ex,6ex) should be used-value-equivalent to 4ex assert_equals: rem(10ex,6ex) and 4ex serialize to the same thing in used values. expected "29.375px" but got "0px"
+FAIL rem(10ch,6ch) should be used-value-equivalent to 4ch assert_equals: rem(10ch,6ch) and 4ch serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL rem(10rem,6rem) should be used-value-equivalent to 4rem assert_equals: rem(10rem,6rem) and 4rem serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10vh,6vh) should be used-value-equivalent to 4vh assert_equals: rem(10vh,6vh) and 4vh serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL rem(10vw,6vw) should be used-value-equivalent to 4vw assert_equals: rem(10vw,6vw) and 4vw serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL rem(10vmin,6vmin) should be used-value-equivalent to 4vmin assert_equals: rem(10vmin,6vmin) and 4vmin serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL rem(10vmax,6vmax) should be used-value-equivalent to 4vmax assert_equals: rem(10vmax,6vmax) and 4vmax serialize to the same thing in used values. expected "32px" but got "0px"
+PASS rem(10s,6s) should be used-value-equivalent to 4s
+PASS rem(10ms,6ms) should be used-value-equivalent to 4ms
+FAIL rem(10deg,6deg) should be used-value-equivalent to 4deg Cannot read properties of undefined (reading 'split')
+FAIL rem(10grad,6grad) should be used-value-equivalent to 4grad Cannot read properties of undefined (reading 'split')
+FAIL rem(10rad,6rad) should be used-value-equivalent to 4rad Cannot read properties of undefined (reading 'split')
+FAIL rem(10turn,6turn) should be used-value-equivalent to 4turn Cannot read properties of undefined (reading 'split')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-values/signs-abs-computed-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-values/signs-abs-computed-expected.txt
new file mode 100644
index 0000000..dcc3832
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-values/signs-abs-computed-expected.txt
@@ -0,0 +1,146 @@
+This is a testharness.js-based test.
+Found 142 tests; 87 PASS, 55 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL abs(1) should be used-value-equivalent to 1 assert_equals: abs(1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL sign(1) should be used-value-equivalent to 1 assert_equals: sign(1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL abs(-1) should be used-value-equivalent to 1 assert_equals: abs(-1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL sign(-1) should be used-value-equivalent to -1 assert_equals: sign(-1) and -1 serialize to the same thing in used values. expected "matrix(-1, 0, 0, -1, 0, 0)" but got "none"
+PASS abs(sign(1)) should be used-value-equivalent to 1
+PASS abs(sign(sign(1))) should be used-value-equivalent to 1
+PASS sign(sign(sign(1) + sign(1))) should be used-value-equivalent to 1
+FAIL calc(abs(0.1 + 0.2) + 0.05) should be used-value-equivalent to 0.35 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(0.1 + 0.2) - 0.05) should be used-value-equivalent to 0.95 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(0.1 + 0.2) * 2) should be used-value-equivalent to 0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(sign(0.1) + 0.2) / 2) should be used-value-equivalent to 0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(0.1 + 0.2) * -2) should be used-value-equivalent to -0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(0.1 - 0.2) - 0.05) should be used-value-equivalent to -1.05 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(1) + sign(1) - 0.05) should be used-value-equivalent to 1.95 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(-0)) should be used-value-equivalent to -0 assert_equals: calc(sign(-0)) and -0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL calc(sign(0)) should be used-value-equivalent to 0 assert_equals: calc(sign(0)) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+PASS sign(1px) should be used-value-equivalent to 1
+PASS sign(1cm) should be used-value-equivalent to 1
+PASS sign(1mm) should be used-value-equivalent to 1
+PASS sign(1Q) should be used-value-equivalent to 1
+PASS sign(1in) should be used-value-equivalent to 1
+PASS sign(1pc) should be used-value-equivalent to 1
+PASS sign(1pt) should be used-value-equivalent to 1
+PASS sign(1em) should be used-value-equivalent to 1
+PASS sign(1ex) should be used-value-equivalent to 1
+PASS sign(1ch) should be used-value-equivalent to 1
+PASS sign(1rem) should be used-value-equivalent to 1
+PASS sign(1vh) should be used-value-equivalent to 1
+PASS sign(1vw) should be used-value-equivalent to 1
+PASS sign(1vmin) should be used-value-equivalent to 1
+PASS sign(1vmax) should be used-value-equivalent to 1
+PASS sign(-1px) should be used-value-equivalent to -1
+PASS sign(-1cm) should be used-value-equivalent to -1
+PASS sign(-1mm) should be used-value-equivalent to -1
+PASS sign(-1Q) should be used-value-equivalent to -1
+PASS sign(-1in) should be used-value-equivalent to -1
+PASS sign(-1pc) should be used-value-equivalent to -1
+PASS sign(-1pt) should be used-value-equivalent to -1
+PASS sign(-1em) should be used-value-equivalent to -1
+PASS sign(-1ex) should be used-value-equivalent to -1
+PASS sign(-1ch) should be used-value-equivalent to -1
+PASS sign(-1rem) should be used-value-equivalent to -1
+PASS sign(-1vh) should be used-value-equivalent to -1
+PASS sign(-1vw) should be used-value-equivalent to -1
+PASS sign(-1vmin) should be used-value-equivalent to -1
+PASS sign(-1vmax) should be used-value-equivalent to -1
+PASS sign(1s) should be used-value-equivalent to 1
+PASS sign(1ms) should be used-value-equivalent to 1
+PASS sign(-1s) should be used-value-equivalent to -1
+PASS sign(-1ms) should be used-value-equivalent to -1
+PASS sign(1deg) should be used-value-equivalent to 1
+PASS sign(1grad) should be used-value-equivalent to 1
+PASS sign(1rad) should be used-value-equivalent to 1
+PASS sign(1turn) should be used-value-equivalent to 1
+PASS sign(-1deg) should be used-value-equivalent to -1
+PASS sign(-1grad) should be used-value-equivalent to -1
+PASS sign(-1rad) should be used-value-equivalent to -1
+PASS sign(-1turn) should be used-value-equivalent to -1
+PASS sign(0px) should be used-value-equivalent to 0
+PASS sign(0cm) should be used-value-equivalent to 0
+PASS sign(0mm) should be used-value-equivalent to 0
+PASS sign(0Q) should be used-value-equivalent to 0
+PASS sign(0in) should be used-value-equivalent to 0
+PASS sign(0pc) should be used-value-equivalent to 0
+PASS sign(0pt) should be used-value-equivalent to 0
+PASS sign(0em) should be used-value-equivalent to 0
+PASS sign(0ex) should be used-value-equivalent to 0
+PASS sign(0ch) should be used-value-equivalent to 0
+PASS sign(0rem) should be used-value-equivalent to 0
+PASS sign(0vh) should be used-value-equivalent to 0
+PASS sign(0vw) should be used-value-equivalent to 0
+PASS sign(0vmin) should be used-value-equivalent to 0
+PASS sign(0vmax) should be used-value-equivalent to 0
+PASS sign(-0px) should be used-value-equivalent to -0
+PASS sign(-0cm) should be used-value-equivalent to -0
+PASS sign(-0mm) should be used-value-equivalent to -0
+PASS sign(-0Q) should be used-value-equivalent to -0
+PASS sign(-0in) should be used-value-equivalent to -0
+PASS sign(-0pc) should be used-value-equivalent to -0
+PASS sign(-0pt) should be used-value-equivalent to -0
+PASS sign(-0em) should be used-value-equivalent to -0
+PASS sign(-0ex) should be used-value-equivalent to -0
+PASS sign(-0ch) should be used-value-equivalent to -0
+PASS sign(-0rem) should be used-value-equivalent to -0
+PASS sign(-0vh) should be used-value-equivalent to -0
+PASS sign(-0vw) should be used-value-equivalent to -0
+PASS sign(-0vmin) should be used-value-equivalent to -0
+PASS sign(-0vmax) should be used-value-equivalent to -0
+PASS sign(0s) should be used-value-equivalent to 0
+PASS sign(0ms) should be used-value-equivalent to 0
+PASS sign(-0s) should be used-value-equivalent to 0
+PASS sign(-0ms) should be used-value-equivalent to 0
+PASS sign(0deg) should be used-value-equivalent to 0
+PASS sign(0grad) should be used-value-equivalent to 0
+PASS sign(0rad) should be used-value-equivalent to 0
+PASS sign(0turn) should be used-value-equivalent to 0
+PASS sign(-0deg) should be used-value-equivalent to -0
+PASS sign(-0grad) should be used-value-equivalent to -0
+PASS sign(-0rad) should be used-value-equivalent to -0
+PASS sign(-0turn) should be used-value-equivalent to -0
+FAIL abs(1px) should be used-value-equivalent to 1px assert_equals: abs(1px) and 1px serialize to the same thing in used values. expected "1px" but got "0px"
+FAIL abs(1cm) should be used-value-equivalent to 1cm assert_equals: abs(1cm) and 1cm serialize to the same thing in used values. expected "37.7953px" but got "0px"
+FAIL abs(1mm) should be used-value-equivalent to 1mm assert_equals: abs(1mm) and 1mm serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL abs(1Q) should be used-value-equivalent to 1Q assert_equals: abs(1Q) and 1Q serialize to the same thing in used values. expected "0.944882px" but got "0px"
+FAIL abs(1in) should be used-value-equivalent to 1in assert_equals: abs(1in) and 1in serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL abs(1pc) should be used-value-equivalent to 1pc assert_equals: abs(1pc) and 1pc serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1pt) should be used-value-equivalent to 1pt assert_equals: abs(1pt) and 1pt serialize to the same thing in used values. expected "1.33333px" but got "0px"
+FAIL abs(1em) should be used-value-equivalent to 1em assert_equals: abs(1em) and 1em serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1ex) should be used-value-equivalent to 1ex assert_equals: abs(1ex) and 1ex serialize to the same thing in used values. expected "7.34375px" but got "0px"
+FAIL abs(1ch) should be used-value-equivalent to 1ch assert_equals: abs(1ch) and 1ch serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1rem) should be used-value-equivalent to 1rem assert_equals: abs(1rem) and 1rem serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1vh) should be used-value-equivalent to 1vh assert_equals: abs(1vh) and 1vh serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(1vw) should be used-value-equivalent to 1vw assert_equals: abs(1vw) and 1vw serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1vmin) should be used-value-equivalent to 1vmin assert_equals: abs(1vmin) and 1vmin serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(1vmax) should be used-value-equivalent to 1vmax assert_equals: abs(1vmax) and 1vmax serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1px) should be used-value-equivalent to 1px assert_equals: abs(-1px) and 1px serialize to the same thing in used values. expected "1px" but got "0px"
+FAIL abs(-1cm) should be used-value-equivalent to 1cm assert_equals: abs(-1cm) and 1cm serialize to the same thing in used values. expected "37.7953px" but got "0px"
+FAIL abs(-1mm) should be used-value-equivalent to 1mm assert_equals: abs(-1mm) and 1mm serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL abs(-1Q) should be used-value-equivalent to 1Q assert_equals: abs(-1Q) and 1Q serialize to the same thing in used values. expected "0.944882px" but got "0px"
+FAIL abs(-1in) should be used-value-equivalent to 1in assert_equals: abs(-1in) and 1in serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL abs(-1pc) should be used-value-equivalent to 1pc assert_equals: abs(-1pc) and 1pc serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1pt) should be used-value-equivalent to 1pt assert_equals: abs(-1pt) and 1pt serialize to the same thing in used values. expected "1.33333px" but got "0px"
+FAIL abs(-1em) should be used-value-equivalent to 1em assert_equals: abs(-1em) and 1em serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1ex) should be used-value-equivalent to 1ex assert_equals: abs(-1ex) and 1ex serialize to the same thing in used values. expected "7.34375px" but got "0px"
+FAIL abs(-1ch) should be used-value-equivalent to 1ch assert_equals: abs(-1ch) and 1ch serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1rem) should be used-value-equivalent to 1rem assert_equals: abs(-1rem) and 1rem serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1vh) should be used-value-equivalent to 1vh assert_equals: abs(-1vh) and 1vh serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(-1vw) should be used-value-equivalent to 1vw assert_equals: abs(-1vw) and 1vw serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1vmin) should be used-value-equivalent to 1vmin assert_equals: abs(-1vmin) and 1vmin serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(-1vmax) should be used-value-equivalent to 1vmax assert_equals: abs(-1vmax) and 1vmax serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1s) should be used-value-equivalent to 1s assert_equals: abs(1s) and 1s serialize to the same thing in used values. expected "1s" but got "0s"
+FAIL abs(1ms) should be used-value-equivalent to 1ms assert_equals: abs(1ms) and 1ms serialize to the same thing in used values. expected "0.001s" but got "0s"
+FAIL abs(-1s) should be used-value-equivalent to 1s assert_equals: abs(-1s) and 1s serialize to the same thing in used values. expected "1s" but got "0s"
+FAIL abs(-1ms) should be used-value-equivalent to 1ms assert_equals: abs(-1ms) and 1ms serialize to the same thing in used values. expected "0.001s" but got "0s"
+FAIL abs(1deg) should be used-value-equivalent to 1deg Cannot read properties of undefined (reading 'split')
+FAIL abs(1grad) should be used-value-equivalent to 1grad Cannot read properties of undefined (reading 'split')
+FAIL abs(1rad) should be used-value-equivalent to 1rad Cannot read properties of undefined (reading 'split')
+FAIL abs(1turn) should be used-value-equivalent to 1turn Cannot read properties of undefined (reading 'split')
+FAIL abs(-1deg) should be used-value-equivalent to 1deg Cannot read properties of undefined (reading 'split')
+FAIL abs(-1grad) should be used-value-equivalent to 1grad Cannot read properties of undefined (reading 'split')
+FAIL abs(-1rad) should be used-value-equivalent to 1rad Cannot read properties of undefined (reading 'split')
+FAIL abs(-1turn) should be used-value-equivalent to 1turn Cannot read properties of undefined (reading 'split')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/round-mod-rem-computed-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/round-mod-rem-computed-expected.txt
new file mode 100644
index 0000000..af52fc8
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/round-mod-rem-computed-expected.txt
@@ -0,0 +1,93 @@
+This is a testharness.js-based test.
+Found 89 tests; 6 PASS, 83 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL round(10,10) should be used-value-equivalent to 10 assert_equals: round(10,10) and 10 serialize to the same thing in used values. expected "matrix(10, 0, 0, 10, 0, 0)" but got "none"
+FAIL mod(1,1) should be used-value-equivalent to 0 assert_equals: mod(1,1) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL rem(1,1) should be used-value-equivalent to 0 assert_equals: rem(1,1) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL calc(round(100,10)) should be used-value-equivalent to 100 assert_equals: calc(round(100,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(up, 101,10)) should be used-value-equivalent to 110 assert_equals: calc(round(up, 101,10)) and 110 serialize to the same thing in used values. expected "matrix(110, 0, 0, 110, 0, 0)" but got "none"
+FAIL calc(round(down, 106,10)) should be used-value-equivalent to 100 assert_equals: calc(round(down, 106,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,105, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,105, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,-105, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,-105, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(-100,10)) should be used-value-equivalent to -100 assert_equals: calc(round(-100,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(round(up, -103,10)) should be used-value-equivalent to -100 assert_equals: calc(round(up, -103,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL mod(18,5) should be used-value-equivalent to 3 assert_equals: mod(18,5) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL rem(18,5) should be used-value-equivalent to 3 assert_equals: rem(18,5) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL mod(-140,-90) should be used-value-equivalent to -50 assert_equals: mod(-140,-90) and -50 serialize to the same thing in used values. expected "matrix(-50, 0, 0, -50, 0, 0)" but got "none"
+FAIL mod(-18,5) should be used-value-equivalent to 2 assert_equals: mod(-18,5) and 2 serialize to the same thing in used values. expected "matrix(2, 0, 0, 2, 0, 0)" but got "none"
+FAIL rem(-18,5) should be used-value-equivalent to -3 assert_equals: rem(-18,5) and -3 serialize to the same thing in used values. expected "matrix(-3, 0, 0, -3, 0, 0)" but got "none"
+FAIL mod(140,-90) should be used-value-equivalent to -40 assert_equals: mod(140,-90) and -40 serialize to the same thing in used values. expected "matrix(-40, 0, 0, -40, 0, 0)" but got "none"
+FAIL rem(140,-90) should be used-value-equivalent to 50 assert_equals: rem(140,-90) and 50 serialize to the same thing in used values. expected "matrix(50, 0, 0, 50, 0, 0)" but got "none"
+FAIL calc(round(round(100,10), 10)) should be used-value-equivalent to 100 assert_equals: calc(round(round(100,10), 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(up, round(100,10) + 1,10)) should be used-value-equivalent to 110 assert_equals: calc(round(up, round(100,10) + 1,10)) and 110 serialize to the same thing in used values. expected "matrix(110, 0, 0, 110, 0, 0)" but got "none"
+FAIL calc(round(down, round(100,10) + 2 * 3,10)) should be used-value-equivalent to 100 assert_equals: calc(round(down, round(100,10) + 2 * 3,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,round(100,10) * 2 - 95, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,round(100,10) * 2 - 95, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(round(100,10)* -1,10)) should be used-value-equivalent to -100 assert_equals: calc(round(round(100,10)* -1,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(round(up, -103 + -103 / -103 - 1,10)) should be used-value-equivalent to -100 assert_equals: calc(round(up, -103 + -103 / -103 - 1,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(mod(18,5) * 2 + mod(17,5)) should be used-value-equivalent to 8 assert_equals: calc(mod(18,5) * 2 + mod(17,5)) and 8 serialize to the same thing in used values. expected "matrix(8, 0, 0, 8, 0, 0)" but got "none"
+FAIL calc(rem(mod(18,5),5)) should be used-value-equivalent to 3 assert_equals: calc(rem(mod(18,5),5)) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL calc(rem(mod(18,5),mod(17,5))) should be used-value-equivalent to 1 assert_equals: calc(rem(mod(18,5),mod(17,5))) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL calc(mod(-140,-90)) should be used-value-equivalent to -50 assert_equals: calc(mod(-140,-90)) and -50 serialize to the same thing in used values. expected "matrix(-50, 0, 0, -50, 0, 0)" but got "none"
+FAIL calc(mod(rem(1,18)* -1,5)) should be used-value-equivalent to -1 assert_equals: calc(mod(rem(1,18)* -1,5)) and -1 serialize to the same thing in used values. expected "matrix(-1, 0, 0, -1, 0, 0)" but got "none"
+FAIL round(10px,6px) should be used-value-equivalent to 12px assert_equals: round(10px,6px) and 12px serialize to the same thing in used values. expected "12px" but got "0px"
+FAIL round(10cm,6cm) should be used-value-equivalent to 12cm assert_equals: round(10cm,6cm) and 12cm serialize to the same thing in used values. expected "453.543px" but got "0px"
+FAIL round(10mm,6mm) should be used-value-equivalent to 12mm assert_equals: round(10mm,6mm) and 12mm serialize to the same thing in used values. expected "45.3543px" but got "0px"
+FAIL round(10Q, 6Q) should be used-value-equivalent to 12Q assert_equals: round(10Q, 6Q) and 12Q serialize to the same thing in used values. expected "11.3386px" but got "0px"
+FAIL round(10in,6in) should be used-value-equivalent to 12in assert_equals: round(10in,6in) and 12in serialize to the same thing in used values. expected "1152px" but got "0px"
+FAIL round(10pc,6pc) should be used-value-equivalent to 12pc assert_equals: round(10pc,6pc) and 12pc serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10pt,6pt) should be used-value-equivalent to 12pt assert_equals: round(10pt,6pt) and 12pt serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL round(10em,6em) should be used-value-equivalent to 12em assert_equals: round(10em,6em) and 12em serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10ex,6ex) should be used-value-equivalent to 12ex assert_equals: round(10ex,6ex) and 12ex serialize to the same thing in used values. expected "88.125px" but got "0px"
+FAIL round(10ch,6ch) should be used-value-equivalent to 12ch assert_equals: round(10ch,6ch) and 12ch serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL round(10rem,6rem) should be used-value-equivalent to 12rem assert_equals: round(10rem,6rem) and 12rem serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10vh,6vh) should be used-value-equivalent to 12vh assert_equals: round(10vh,6vh) and 12vh serialize to the same thing in used values. expected "72px" but got "0px"
+FAIL round(10vw,6vw) should be used-value-equivalent to 12vw assert_equals: round(10vw,6vw) and 12vw serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL round(10vmin,6vmin) should be used-value-equivalent to 12vmin assert_equals: round(10vmin,6vmin) and 12vmin serialize to the same thing in used values. expected "72px" but got "0px"
+FAIL round(10vmax,6vmax) should be used-value-equivalent to 12vmax assert_equals: round(10vmax,6vmax) and 12vmax serialize to the same thing in used values. expected "96px" but got "0px"
+PASS round(10s,6s) should be used-value-equivalent to 12s
+PASS round(10ms,6ms) should be used-value-equivalent to 12ms
+FAIL round(10deg,6deg) should be used-value-equivalent to 12deg Cannot read properties of undefined (reading 'split')
+FAIL round(10grad,6grad) should be used-value-equivalent to 12grad Cannot read properties of undefined (reading 'split')
+FAIL round(10rad,6rad) should be used-value-equivalent to 12rad Cannot read properties of undefined (reading 'split')
+FAIL round(10turn,6turn) should be used-value-equivalent to 12turn Cannot read properties of undefined (reading 'split')
+FAIL mod(10px,6px) should be used-value-equivalent to 4px assert_equals: mod(10px,6px) and 4px serialize to the same thing in used values. expected "4px" but got "0px"
+FAIL mod(10cm,6cm) should be used-value-equivalent to 4cm assert_equals: mod(10cm,6cm) and 4cm serialize to the same thing in used values. expected "151.181px" but got "0px"
+FAIL mod(10mm,6mm) should be used-value-equivalent to 4mm assert_equals: mod(10mm,6mm) and 4mm serialize to the same thing in used values. expected "15.1181px" but got "0px"
+FAIL mod(10Q, 6Q) should be used-value-equivalent to 4Q assert_equals: mod(10Q, 6Q) and 4Q serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL mod(10in,6in) should be used-value-equivalent to 4in assert_equals: mod(10in,6in) and 4in serialize to the same thing in used values. expected "384px" but got "0px"
+FAIL mod(10pc,6pc) should be used-value-equivalent to 4pc assert_equals: mod(10pc,6pc) and 4pc serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10em,6em) should be used-value-equivalent to 4em assert_equals: mod(10em,6em) and 4em serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10ex,6ex) should be used-value-equivalent to 4ex assert_equals: mod(10ex,6ex) and 4ex serialize to the same thing in used values. expected "29.375px" but got "0px"
+FAIL mod(10ch,6ch) should be used-value-equivalent to 4ch assert_equals: mod(10ch,6ch) and 4ch serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL mod(10rem,6rem) should be used-value-equivalent to 4rem assert_equals: mod(10rem,6rem) and 4rem serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10vh,6vh) should be used-value-equivalent to 4vh assert_equals: mod(10vh,6vh) and 4vh serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL mod(10vw,6vw) should be used-value-equivalent to 4vw assert_equals: mod(10vw,6vw) and 4vw serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL mod(10vmin,6vmin) should be used-value-equivalent to 4vmin assert_equals: mod(10vmin,6vmin) and 4vmin serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL mod(10vmax,6vmax) should be used-value-equivalent to 4vmax assert_equals: mod(10vmax,6vmax) and 4vmax serialize to the same thing in used values. expected "32px" but got "0px"
+PASS mod(10s,6s) should be used-value-equivalent to 4s
+PASS mod(10ms,6ms) should be used-value-equivalent to 4ms
+FAIL mod(10deg,6deg) should be used-value-equivalent to 4deg Cannot read properties of undefined (reading 'split')
+FAIL mod(10grad,6grad) should be used-value-equivalent to 4grad Cannot read properties of undefined (reading 'split')
+FAIL mod(10rad,6rad) should be used-value-equivalent to 4rad Cannot read properties of undefined (reading 'split')
+FAIL mod(10turn,6turn) should be used-value-equivalent to 4turn Cannot read properties of undefined (reading 'split')
+FAIL rem(10px,6px) should be used-value-equivalent to 4px assert_equals: rem(10px,6px) and 4px serialize to the same thing in used values. expected "4px" but got "0px"
+FAIL rem(10cm,6cm) should be used-value-equivalent to 4cm assert_equals: rem(10cm,6cm) and 4cm serialize to the same thing in used values. expected "151.181px" but got "0px"
+FAIL rem(10mm,6mm) should be used-value-equivalent to 4mm assert_equals: rem(10mm,6mm) and 4mm serialize to the same thing in used values. expected "15.1181px" but got "0px"
+FAIL rem(10Q, 6Q) should be used-value-equivalent to 4Q assert_equals: rem(10Q, 6Q) and 4Q serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL rem(10in,6in) should be used-value-equivalent to 4in assert_equals: rem(10in,6in) and 4in serialize to the same thing in used values. expected "384px" but got "0px"
+FAIL rem(10pc,6pc) should be used-value-equivalent to 4pc assert_equals: rem(10pc,6pc) and 4pc serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10em,6em) should be used-value-equivalent to 4em assert_equals: rem(10em,6em) and 4em serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10ex,6ex) should be used-value-equivalent to 4ex assert_equals: rem(10ex,6ex) and 4ex serialize to the same thing in used values. expected "29.375px" but got "0px"
+FAIL rem(10ch,6ch) should be used-value-equivalent to 4ch assert_equals: rem(10ch,6ch) and 4ch serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL rem(10rem,6rem) should be used-value-equivalent to 4rem assert_equals: rem(10rem,6rem) and 4rem serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10vh,6vh) should be used-value-equivalent to 4vh assert_equals: rem(10vh,6vh) and 4vh serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL rem(10vw,6vw) should be used-value-equivalent to 4vw assert_equals: rem(10vw,6vw) and 4vw serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL rem(10vmin,6vmin) should be used-value-equivalent to 4vmin assert_equals: rem(10vmin,6vmin) and 4vmin serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL rem(10vmax,6vmax) should be used-value-equivalent to 4vmax assert_equals: rem(10vmax,6vmax) and 4vmax serialize to the same thing in used values. expected "32px" but got "0px"
+PASS rem(10s,6s) should be used-value-equivalent to 4s
+PASS rem(10ms,6ms) should be used-value-equivalent to 4ms
+FAIL rem(10deg,6deg) should be used-value-equivalent to 4deg Cannot read properties of undefined (reading 'split')
+FAIL rem(10grad,6grad) should be used-value-equivalent to 4grad Cannot read properties of undefined (reading 'split')
+FAIL rem(10rad,6rad) should be used-value-equivalent to 4rad Cannot read properties of undefined (reading 'split')
+FAIL rem(10turn,6turn) should be used-value-equivalent to 4turn Cannot read properties of undefined (reading 'split')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/linux/virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/signs-abs-computed-expected.txt b/third_party/blink/web_tests/platform/linux/virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/signs-abs-computed-expected.txt
new file mode 100644
index 0000000..dcc3832
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/css-calc-infinity-and-nan-disabled/external/wpt/css/css-values/signs-abs-computed-expected.txt
@@ -0,0 +1,146 @@
+This is a testharness.js-based test.
+Found 142 tests; 87 PASS, 55 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL abs(1) should be used-value-equivalent to 1 assert_equals: abs(1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL sign(1) should be used-value-equivalent to 1 assert_equals: sign(1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL abs(-1) should be used-value-equivalent to 1 assert_equals: abs(-1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL sign(-1) should be used-value-equivalent to -1 assert_equals: sign(-1) and -1 serialize to the same thing in used values. expected "matrix(-1, 0, 0, -1, 0, 0)" but got "none"
+PASS abs(sign(1)) should be used-value-equivalent to 1
+PASS abs(sign(sign(1))) should be used-value-equivalent to 1
+PASS sign(sign(sign(1) + sign(1))) should be used-value-equivalent to 1
+FAIL calc(abs(0.1 + 0.2) + 0.05) should be used-value-equivalent to 0.35 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(0.1 + 0.2) - 0.05) should be used-value-equivalent to 0.95 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(0.1 + 0.2) * 2) should be used-value-equivalent to 0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(sign(0.1) + 0.2) / 2) should be used-value-equivalent to 0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(0.1 + 0.2) * -2) should be used-value-equivalent to -0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(0.1 - 0.2) - 0.05) should be used-value-equivalent to -1.05 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(1) + sign(1) - 0.05) should be used-value-equivalent to 1.95 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(-0)) should be used-value-equivalent to -0 assert_equals: calc(sign(-0)) and -0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL calc(sign(0)) should be used-value-equivalent to 0 assert_equals: calc(sign(0)) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+PASS sign(1px) should be used-value-equivalent to 1
+PASS sign(1cm) should be used-value-equivalent to 1
+PASS sign(1mm) should be used-value-equivalent to 1
+PASS sign(1Q) should be used-value-equivalent to 1
+PASS sign(1in) should be used-value-equivalent to 1
+PASS sign(1pc) should be used-value-equivalent to 1
+PASS sign(1pt) should be used-value-equivalent to 1
+PASS sign(1em) should be used-value-equivalent to 1
+PASS sign(1ex) should be used-value-equivalent to 1
+PASS sign(1ch) should be used-value-equivalent to 1
+PASS sign(1rem) should be used-value-equivalent to 1
+PASS sign(1vh) should be used-value-equivalent to 1
+PASS sign(1vw) should be used-value-equivalent to 1
+PASS sign(1vmin) should be used-value-equivalent to 1
+PASS sign(1vmax) should be used-value-equivalent to 1
+PASS sign(-1px) should be used-value-equivalent to -1
+PASS sign(-1cm) should be used-value-equivalent to -1
+PASS sign(-1mm) should be used-value-equivalent to -1
+PASS sign(-1Q) should be used-value-equivalent to -1
+PASS sign(-1in) should be used-value-equivalent to -1
+PASS sign(-1pc) should be used-value-equivalent to -1
+PASS sign(-1pt) should be used-value-equivalent to -1
+PASS sign(-1em) should be used-value-equivalent to -1
+PASS sign(-1ex) should be used-value-equivalent to -1
+PASS sign(-1ch) should be used-value-equivalent to -1
+PASS sign(-1rem) should be used-value-equivalent to -1
+PASS sign(-1vh) should be used-value-equivalent to -1
+PASS sign(-1vw) should be used-value-equivalent to -1
+PASS sign(-1vmin) should be used-value-equivalent to -1
+PASS sign(-1vmax) should be used-value-equivalent to -1
+PASS sign(1s) should be used-value-equivalent to 1
+PASS sign(1ms) should be used-value-equivalent to 1
+PASS sign(-1s) should be used-value-equivalent to -1
+PASS sign(-1ms) should be used-value-equivalent to -1
+PASS sign(1deg) should be used-value-equivalent to 1
+PASS sign(1grad) should be used-value-equivalent to 1
+PASS sign(1rad) should be used-value-equivalent to 1
+PASS sign(1turn) should be used-value-equivalent to 1
+PASS sign(-1deg) should be used-value-equivalent to -1
+PASS sign(-1grad) should be used-value-equivalent to -1
+PASS sign(-1rad) should be used-value-equivalent to -1
+PASS sign(-1turn) should be used-value-equivalent to -1
+PASS sign(0px) should be used-value-equivalent to 0
+PASS sign(0cm) should be used-value-equivalent to 0
+PASS sign(0mm) should be used-value-equivalent to 0
+PASS sign(0Q) should be used-value-equivalent to 0
+PASS sign(0in) should be used-value-equivalent to 0
+PASS sign(0pc) should be used-value-equivalent to 0
+PASS sign(0pt) should be used-value-equivalent to 0
+PASS sign(0em) should be used-value-equivalent to 0
+PASS sign(0ex) should be used-value-equivalent to 0
+PASS sign(0ch) should be used-value-equivalent to 0
+PASS sign(0rem) should be used-value-equivalent to 0
+PASS sign(0vh) should be used-value-equivalent to 0
+PASS sign(0vw) should be used-value-equivalent to 0
+PASS sign(0vmin) should be used-value-equivalent to 0
+PASS sign(0vmax) should be used-value-equivalent to 0
+PASS sign(-0px) should be used-value-equivalent to -0
+PASS sign(-0cm) should be used-value-equivalent to -0
+PASS sign(-0mm) should be used-value-equivalent to -0
+PASS sign(-0Q) should be used-value-equivalent to -0
+PASS sign(-0in) should be used-value-equivalent to -0
+PASS sign(-0pc) should be used-value-equivalent to -0
+PASS sign(-0pt) should be used-value-equivalent to -0
+PASS sign(-0em) should be used-value-equivalent to -0
+PASS sign(-0ex) should be used-value-equivalent to -0
+PASS sign(-0ch) should be used-value-equivalent to -0
+PASS sign(-0rem) should be used-value-equivalent to -0
+PASS sign(-0vh) should be used-value-equivalent to -0
+PASS sign(-0vw) should be used-value-equivalent to -0
+PASS sign(-0vmin) should be used-value-equivalent to -0
+PASS sign(-0vmax) should be used-value-equivalent to -0
+PASS sign(0s) should be used-value-equivalent to 0
+PASS sign(0ms) should be used-value-equivalent to 0
+PASS sign(-0s) should be used-value-equivalent to 0
+PASS sign(-0ms) should be used-value-equivalent to 0
+PASS sign(0deg) should be used-value-equivalent to 0
+PASS sign(0grad) should be used-value-equivalent to 0
+PASS sign(0rad) should be used-value-equivalent to 0
+PASS sign(0turn) should be used-value-equivalent to 0
+PASS sign(-0deg) should be used-value-equivalent to -0
+PASS sign(-0grad) should be used-value-equivalent to -0
+PASS sign(-0rad) should be used-value-equivalent to -0
+PASS sign(-0turn) should be used-value-equivalent to -0
+FAIL abs(1px) should be used-value-equivalent to 1px assert_equals: abs(1px) and 1px serialize to the same thing in used values. expected "1px" but got "0px"
+FAIL abs(1cm) should be used-value-equivalent to 1cm assert_equals: abs(1cm) and 1cm serialize to the same thing in used values. expected "37.7953px" but got "0px"
+FAIL abs(1mm) should be used-value-equivalent to 1mm assert_equals: abs(1mm) and 1mm serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL abs(1Q) should be used-value-equivalent to 1Q assert_equals: abs(1Q) and 1Q serialize to the same thing in used values. expected "0.944882px" but got "0px"
+FAIL abs(1in) should be used-value-equivalent to 1in assert_equals: abs(1in) and 1in serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL abs(1pc) should be used-value-equivalent to 1pc assert_equals: abs(1pc) and 1pc serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1pt) should be used-value-equivalent to 1pt assert_equals: abs(1pt) and 1pt serialize to the same thing in used values. expected "1.33333px" but got "0px"
+FAIL abs(1em) should be used-value-equivalent to 1em assert_equals: abs(1em) and 1em serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1ex) should be used-value-equivalent to 1ex assert_equals: abs(1ex) and 1ex serialize to the same thing in used values. expected "7.34375px" but got "0px"
+FAIL abs(1ch) should be used-value-equivalent to 1ch assert_equals: abs(1ch) and 1ch serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1rem) should be used-value-equivalent to 1rem assert_equals: abs(1rem) and 1rem serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1vh) should be used-value-equivalent to 1vh assert_equals: abs(1vh) and 1vh serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(1vw) should be used-value-equivalent to 1vw assert_equals: abs(1vw) and 1vw serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1vmin) should be used-value-equivalent to 1vmin assert_equals: abs(1vmin) and 1vmin serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(1vmax) should be used-value-equivalent to 1vmax assert_equals: abs(1vmax) and 1vmax serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1px) should be used-value-equivalent to 1px assert_equals: abs(-1px) and 1px serialize to the same thing in used values. expected "1px" but got "0px"
+FAIL abs(-1cm) should be used-value-equivalent to 1cm assert_equals: abs(-1cm) and 1cm serialize to the same thing in used values. expected "37.7953px" but got "0px"
+FAIL abs(-1mm) should be used-value-equivalent to 1mm assert_equals: abs(-1mm) and 1mm serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL abs(-1Q) should be used-value-equivalent to 1Q assert_equals: abs(-1Q) and 1Q serialize to the same thing in used values. expected "0.944882px" but got "0px"
+FAIL abs(-1in) should be used-value-equivalent to 1in assert_equals: abs(-1in) and 1in serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL abs(-1pc) should be used-value-equivalent to 1pc assert_equals: abs(-1pc) and 1pc serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1pt) should be used-value-equivalent to 1pt assert_equals: abs(-1pt) and 1pt serialize to the same thing in used values. expected "1.33333px" but got "0px"
+FAIL abs(-1em) should be used-value-equivalent to 1em assert_equals: abs(-1em) and 1em serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1ex) should be used-value-equivalent to 1ex assert_equals: abs(-1ex) and 1ex serialize to the same thing in used values. expected "7.34375px" but got "0px"
+FAIL abs(-1ch) should be used-value-equivalent to 1ch assert_equals: abs(-1ch) and 1ch serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1rem) should be used-value-equivalent to 1rem assert_equals: abs(-1rem) and 1rem serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1vh) should be used-value-equivalent to 1vh assert_equals: abs(-1vh) and 1vh serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(-1vw) should be used-value-equivalent to 1vw assert_equals: abs(-1vw) and 1vw serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1vmin) should be used-value-equivalent to 1vmin assert_equals: abs(-1vmin) and 1vmin serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(-1vmax) should be used-value-equivalent to 1vmax assert_equals: abs(-1vmax) and 1vmax serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1s) should be used-value-equivalent to 1s assert_equals: abs(1s) and 1s serialize to the same thing in used values. expected "1s" but got "0s"
+FAIL abs(1ms) should be used-value-equivalent to 1ms assert_equals: abs(1ms) and 1ms serialize to the same thing in used values. expected "0.001s" but got "0s"
+FAIL abs(-1s) should be used-value-equivalent to 1s assert_equals: abs(-1s) and 1s serialize to the same thing in used values. expected "1s" but got "0s"
+FAIL abs(-1ms) should be used-value-equivalent to 1ms assert_equals: abs(-1ms) and 1ms serialize to the same thing in used values. expected "0.001s" but got "0s"
+FAIL abs(1deg) should be used-value-equivalent to 1deg Cannot read properties of undefined (reading 'split')
+FAIL abs(1grad) should be used-value-equivalent to 1grad Cannot read properties of undefined (reading 'split')
+FAIL abs(1rad) should be used-value-equivalent to 1rad Cannot read properties of undefined (reading 'split')
+FAIL abs(1turn) should be used-value-equivalent to 1turn Cannot read properties of undefined (reading 'split')
+FAIL abs(-1deg) should be used-value-equivalent to 1deg Cannot read properties of undefined (reading 'split')
+FAIL abs(-1grad) should be used-value-equivalent to 1grad Cannot read properties of undefined (reading 'split')
+FAIL abs(-1rad) should be used-value-equivalent to 1rad Cannot read properties of undefined (reading 'split')
+FAIL abs(-1turn) should be used-value-equivalent to 1turn Cannot read properties of undefined (reading 'split')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-values/round-mod-rem-computed-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-values/round-mod-rem-computed-expected.txt
new file mode 100644
index 0000000..605af99d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-values/round-mod-rem-computed-expected.txt
@@ -0,0 +1,93 @@
+This is a testharness.js-based test.
+Found 89 tests; 6 PASS, 83 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL round(10,10) should be used-value-equivalent to 10 assert_equals: round(10,10) and 10 serialize to the same thing in used values. expected "matrix(10, 0, 0, 10, 0, 0)" but got "none"
+FAIL mod(1,1) should be used-value-equivalent to 0 assert_equals: mod(1,1) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL rem(1,1) should be used-value-equivalent to 0 assert_equals: rem(1,1) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL calc(round(100,10)) should be used-value-equivalent to 100 assert_equals: calc(round(100,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(up, 101,10)) should be used-value-equivalent to 110 assert_equals: calc(round(up, 101,10)) and 110 serialize to the same thing in used values. expected "matrix(110, 0, 0, 110, 0, 0)" but got "none"
+FAIL calc(round(down, 106,10)) should be used-value-equivalent to 100 assert_equals: calc(round(down, 106,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,105, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,105, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,-105, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,-105, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(-100,10)) should be used-value-equivalent to -100 assert_equals: calc(round(-100,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(round(up, -103,10)) should be used-value-equivalent to -100 assert_equals: calc(round(up, -103,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL mod(18,5) should be used-value-equivalent to 3 assert_equals: mod(18,5) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL rem(18,5) should be used-value-equivalent to 3 assert_equals: rem(18,5) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL mod(-140,-90) should be used-value-equivalent to -50 assert_equals: mod(-140,-90) and -50 serialize to the same thing in used values. expected "matrix(-50, 0, 0, -50, 0, 0)" but got "none"
+FAIL mod(-18,5) should be used-value-equivalent to 2 assert_equals: mod(-18,5) and 2 serialize to the same thing in used values. expected "matrix(2, 0, 0, 2, 0, 0)" but got "none"
+FAIL rem(-18,5) should be used-value-equivalent to -3 assert_equals: rem(-18,5) and -3 serialize to the same thing in used values. expected "matrix(-3, 0, 0, -3, 0, 0)" but got "none"
+FAIL mod(140,-90) should be used-value-equivalent to -40 assert_equals: mod(140,-90) and -40 serialize to the same thing in used values. expected "matrix(-40, 0, 0, -40, 0, 0)" but got "none"
+FAIL rem(140,-90) should be used-value-equivalent to 50 assert_equals: rem(140,-90) and 50 serialize to the same thing in used values. expected "matrix(50, 0, 0, 50, 0, 0)" but got "none"
+FAIL calc(round(round(100,10), 10)) should be used-value-equivalent to 100 assert_equals: calc(round(round(100,10), 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(up, round(100,10) + 1,10)) should be used-value-equivalent to 110 assert_equals: calc(round(up, round(100,10) + 1,10)) and 110 serialize to the same thing in used values. expected "matrix(110, 0, 0, 110, 0, 0)" but got "none"
+FAIL calc(round(down, round(100,10) + 2 * 3,10)) should be used-value-equivalent to 100 assert_equals: calc(round(down, round(100,10) + 2 * 3,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,round(100,10) * 2 - 95, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,round(100,10) * 2 - 95, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(round(100,10)* -1,10)) should be used-value-equivalent to -100 assert_equals: calc(round(round(100,10)* -1,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(round(up, -103 + -103 / -103 - 1,10)) should be used-value-equivalent to -100 assert_equals: calc(round(up, -103 + -103 / -103 - 1,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(mod(18,5) * 2 + mod(17,5)) should be used-value-equivalent to 8 assert_equals: calc(mod(18,5) * 2 + mod(17,5)) and 8 serialize to the same thing in used values. expected "matrix(8, 0, 0, 8, 0, 0)" but got "none"
+FAIL calc(rem(mod(18,5),5)) should be used-value-equivalent to 3 assert_equals: calc(rem(mod(18,5),5)) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL calc(rem(mod(18,5),mod(17,5))) should be used-value-equivalent to 1 assert_equals: calc(rem(mod(18,5),mod(17,5))) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL calc(mod(-140,-90)) should be used-value-equivalent to -50 assert_equals: calc(mod(-140,-90)) and -50 serialize to the same thing in used values. expected "matrix(-50, 0, 0, -50, 0, 0)" but got "none"
+FAIL calc(mod(rem(1,18)* -1,5)) should be used-value-equivalent to -1 assert_equals: calc(mod(rem(1,18)* -1,5)) and -1 serialize to the same thing in used values. expected "matrix(-1, 0, 0, -1, 0, 0)" but got "none"
+FAIL round(10px,6px) should be used-value-equivalent to 12px assert_equals: round(10px,6px) and 12px serialize to the same thing in used values. expected "12px" but got "0px"
+FAIL round(10cm,6cm) should be used-value-equivalent to 12cm assert_equals: round(10cm,6cm) and 12cm serialize to the same thing in used values. expected "453.543px" but got "0px"
+FAIL round(10mm,6mm) should be used-value-equivalent to 12mm assert_equals: round(10mm,6mm) and 12mm serialize to the same thing in used values. expected "45.3543px" but got "0px"
+FAIL round(10Q, 6Q) should be used-value-equivalent to 12Q assert_equals: round(10Q, 6Q) and 12Q serialize to the same thing in used values. expected "11.3386px" but got "0px"
+FAIL round(10in,6in) should be used-value-equivalent to 12in assert_equals: round(10in,6in) and 12in serialize to the same thing in used values. expected "1152px" but got "0px"
+FAIL round(10pc,6pc) should be used-value-equivalent to 12pc assert_equals: round(10pc,6pc) and 12pc serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10pt,6pt) should be used-value-equivalent to 12pt assert_equals: round(10pt,6pt) and 12pt serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL round(10em,6em) should be used-value-equivalent to 12em assert_equals: round(10em,6em) and 12em serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10ex,6ex) should be used-value-equivalent to 12ex assert_equals: round(10ex,6ex) and 12ex serialize to the same thing in used values. expected "86.1562px" but got "0px"
+FAIL round(10ch,6ch) should be used-value-equivalent to 12ch assert_equals: round(10ch,6ch) and 12ch serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL round(10rem,6rem) should be used-value-equivalent to 12rem assert_equals: round(10rem,6rem) and 12rem serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10vh,6vh) should be used-value-equivalent to 12vh assert_equals: round(10vh,6vh) and 12vh serialize to the same thing in used values. expected "72px" but got "0px"
+FAIL round(10vw,6vw) should be used-value-equivalent to 12vw assert_equals: round(10vw,6vw) and 12vw serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL round(10vmin,6vmin) should be used-value-equivalent to 12vmin assert_equals: round(10vmin,6vmin) and 12vmin serialize to the same thing in used values. expected "72px" but got "0px"
+FAIL round(10vmax,6vmax) should be used-value-equivalent to 12vmax assert_equals: round(10vmax,6vmax) and 12vmax serialize to the same thing in used values. expected "96px" but got "0px"
+PASS round(10s,6s) should be used-value-equivalent to 12s
+PASS round(10ms,6ms) should be used-value-equivalent to 12ms
+FAIL round(10deg,6deg) should be used-value-equivalent to 12deg Cannot read properties of undefined (reading 'split')
+FAIL round(10grad,6grad) should be used-value-equivalent to 12grad Cannot read properties of undefined (reading 'split')
+FAIL round(10rad,6rad) should be used-value-equivalent to 12rad Cannot read properties of undefined (reading 'split')
+FAIL round(10turn,6turn) should be used-value-equivalent to 12turn Cannot read properties of undefined (reading 'split')
+FAIL mod(10px,6px) should be used-value-equivalent to 4px assert_equals: mod(10px,6px) and 4px serialize to the same thing in used values. expected "4px" but got "0px"
+FAIL mod(10cm,6cm) should be used-value-equivalent to 4cm assert_equals: mod(10cm,6cm) and 4cm serialize to the same thing in used values. expected "151.181px" but got "0px"
+FAIL mod(10mm,6mm) should be used-value-equivalent to 4mm assert_equals: mod(10mm,6mm) and 4mm serialize to the same thing in used values. expected "15.1181px" but got "0px"
+FAIL mod(10Q, 6Q) should be used-value-equivalent to 4Q assert_equals: mod(10Q, 6Q) and 4Q serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL mod(10in,6in) should be used-value-equivalent to 4in assert_equals: mod(10in,6in) and 4in serialize to the same thing in used values. expected "384px" but got "0px"
+FAIL mod(10pc,6pc) should be used-value-equivalent to 4pc assert_equals: mod(10pc,6pc) and 4pc serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10em,6em) should be used-value-equivalent to 4em assert_equals: mod(10em,6em) and 4em serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10ex,6ex) should be used-value-equivalent to 4ex assert_equals: mod(10ex,6ex) and 4ex serialize to the same thing in used values. expected "28.7188px" but got "0px"
+FAIL mod(10ch,6ch) should be used-value-equivalent to 4ch assert_equals: mod(10ch,6ch) and 4ch serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL mod(10rem,6rem) should be used-value-equivalent to 4rem assert_equals: mod(10rem,6rem) and 4rem serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10vh,6vh) should be used-value-equivalent to 4vh assert_equals: mod(10vh,6vh) and 4vh serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL mod(10vw,6vw) should be used-value-equivalent to 4vw assert_equals: mod(10vw,6vw) and 4vw serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL mod(10vmin,6vmin) should be used-value-equivalent to 4vmin assert_equals: mod(10vmin,6vmin) and 4vmin serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL mod(10vmax,6vmax) should be used-value-equivalent to 4vmax assert_equals: mod(10vmax,6vmax) and 4vmax serialize to the same thing in used values. expected "32px" but got "0px"
+PASS mod(10s,6s) should be used-value-equivalent to 4s
+PASS mod(10ms,6ms) should be used-value-equivalent to 4ms
+FAIL mod(10deg,6deg) should be used-value-equivalent to 4deg Cannot read properties of undefined (reading 'split')
+FAIL mod(10grad,6grad) should be used-value-equivalent to 4grad Cannot read properties of undefined (reading 'split')
+FAIL mod(10rad,6rad) should be used-value-equivalent to 4rad Cannot read properties of undefined (reading 'split')
+FAIL mod(10turn,6turn) should be used-value-equivalent to 4turn Cannot read properties of undefined (reading 'split')
+FAIL rem(10px,6px) should be used-value-equivalent to 4px assert_equals: rem(10px,6px) and 4px serialize to the same thing in used values. expected "4px" but got "0px"
+FAIL rem(10cm,6cm) should be used-value-equivalent to 4cm assert_equals: rem(10cm,6cm) and 4cm serialize to the same thing in used values. expected "151.181px" but got "0px"
+FAIL rem(10mm,6mm) should be used-value-equivalent to 4mm assert_equals: rem(10mm,6mm) and 4mm serialize to the same thing in used values. expected "15.1181px" but got "0px"
+FAIL rem(10Q, 6Q) should be used-value-equivalent to 4Q assert_equals: rem(10Q, 6Q) and 4Q serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL rem(10in,6in) should be used-value-equivalent to 4in assert_equals: rem(10in,6in) and 4in serialize to the same thing in used values. expected "384px" but got "0px"
+FAIL rem(10pc,6pc) should be used-value-equivalent to 4pc assert_equals: rem(10pc,6pc) and 4pc serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10em,6em) should be used-value-equivalent to 4em assert_equals: rem(10em,6em) and 4em serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10ex,6ex) should be used-value-equivalent to 4ex assert_equals: rem(10ex,6ex) and 4ex serialize to the same thing in used values. expected "28.7188px" but got "0px"
+FAIL rem(10ch,6ch) should be used-value-equivalent to 4ch assert_equals: rem(10ch,6ch) and 4ch serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL rem(10rem,6rem) should be used-value-equivalent to 4rem assert_equals: rem(10rem,6rem) and 4rem serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10vh,6vh) should be used-value-equivalent to 4vh assert_equals: rem(10vh,6vh) and 4vh serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL rem(10vw,6vw) should be used-value-equivalent to 4vw assert_equals: rem(10vw,6vw) and 4vw serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL rem(10vmin,6vmin) should be used-value-equivalent to 4vmin assert_equals: rem(10vmin,6vmin) and 4vmin serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL rem(10vmax,6vmax) should be used-value-equivalent to 4vmax assert_equals: rem(10vmax,6vmax) and 4vmax serialize to the same thing in used values. expected "32px" but got "0px"
+PASS rem(10s,6s) should be used-value-equivalent to 4s
+PASS rem(10ms,6ms) should be used-value-equivalent to 4ms
+FAIL rem(10deg,6deg) should be used-value-equivalent to 4deg Cannot read properties of undefined (reading 'split')
+FAIL rem(10grad,6grad) should be used-value-equivalent to 4grad Cannot read properties of undefined (reading 'split')
+FAIL rem(10rad,6rad) should be used-value-equivalent to 4rad Cannot read properties of undefined (reading 'split')
+FAIL rem(10turn,6turn) should be used-value-equivalent to 4turn Cannot read properties of undefined (reading 'split')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-values/signs-abs-computed-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-values/signs-abs-computed-expected.txt
new file mode 100644
index 0000000..111e9ed
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-values/signs-abs-computed-expected.txt
@@ -0,0 +1,146 @@
+This is a testharness.js-based test.
+Found 142 tests; 87 PASS, 55 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL abs(1) should be used-value-equivalent to 1 assert_equals: abs(1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL sign(1) should be used-value-equivalent to 1 assert_equals: sign(1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL abs(-1) should be used-value-equivalent to 1 assert_equals: abs(-1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL sign(-1) should be used-value-equivalent to -1 assert_equals: sign(-1) and -1 serialize to the same thing in used values. expected "matrix(-1, 0, 0, -1, 0, 0)" but got "none"
+PASS abs(sign(1)) should be used-value-equivalent to 1
+PASS abs(sign(sign(1))) should be used-value-equivalent to 1
+PASS sign(sign(sign(1) + sign(1))) should be used-value-equivalent to 1
+FAIL calc(abs(0.1 + 0.2) + 0.05) should be used-value-equivalent to 0.35 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(0.1 + 0.2) - 0.05) should be used-value-equivalent to 0.95 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(0.1 + 0.2) * 2) should be used-value-equivalent to 0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(sign(0.1) + 0.2) / 2) should be used-value-equivalent to 0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(0.1 + 0.2) * -2) should be used-value-equivalent to -0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(0.1 - 0.2) - 0.05) should be used-value-equivalent to -1.05 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(1) + sign(1) - 0.05) should be used-value-equivalent to 1.95 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(-0)) should be used-value-equivalent to -0 assert_equals: calc(sign(-0)) and -0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL calc(sign(0)) should be used-value-equivalent to 0 assert_equals: calc(sign(0)) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+PASS sign(1px) should be used-value-equivalent to 1
+PASS sign(1cm) should be used-value-equivalent to 1
+PASS sign(1mm) should be used-value-equivalent to 1
+PASS sign(1Q) should be used-value-equivalent to 1
+PASS sign(1in) should be used-value-equivalent to 1
+PASS sign(1pc) should be used-value-equivalent to 1
+PASS sign(1pt) should be used-value-equivalent to 1
+PASS sign(1em) should be used-value-equivalent to 1
+PASS sign(1ex) should be used-value-equivalent to 1
+PASS sign(1ch) should be used-value-equivalent to 1
+PASS sign(1rem) should be used-value-equivalent to 1
+PASS sign(1vh) should be used-value-equivalent to 1
+PASS sign(1vw) should be used-value-equivalent to 1
+PASS sign(1vmin) should be used-value-equivalent to 1
+PASS sign(1vmax) should be used-value-equivalent to 1
+PASS sign(-1px) should be used-value-equivalent to -1
+PASS sign(-1cm) should be used-value-equivalent to -1
+PASS sign(-1mm) should be used-value-equivalent to -1
+PASS sign(-1Q) should be used-value-equivalent to -1
+PASS sign(-1in) should be used-value-equivalent to -1
+PASS sign(-1pc) should be used-value-equivalent to -1
+PASS sign(-1pt) should be used-value-equivalent to -1
+PASS sign(-1em) should be used-value-equivalent to -1
+PASS sign(-1ex) should be used-value-equivalent to -1
+PASS sign(-1ch) should be used-value-equivalent to -1
+PASS sign(-1rem) should be used-value-equivalent to -1
+PASS sign(-1vh) should be used-value-equivalent to -1
+PASS sign(-1vw) should be used-value-equivalent to -1
+PASS sign(-1vmin) should be used-value-equivalent to -1
+PASS sign(-1vmax) should be used-value-equivalent to -1
+PASS sign(1s) should be used-value-equivalent to 1
+PASS sign(1ms) should be used-value-equivalent to 1
+PASS sign(-1s) should be used-value-equivalent to -1
+PASS sign(-1ms) should be used-value-equivalent to -1
+PASS sign(1deg) should be used-value-equivalent to 1
+PASS sign(1grad) should be used-value-equivalent to 1
+PASS sign(1rad) should be used-value-equivalent to 1
+PASS sign(1turn) should be used-value-equivalent to 1
+PASS sign(-1deg) should be used-value-equivalent to -1
+PASS sign(-1grad) should be used-value-equivalent to -1
+PASS sign(-1rad) should be used-value-equivalent to -1
+PASS sign(-1turn) should be used-value-equivalent to -1
+PASS sign(0px) should be used-value-equivalent to 0
+PASS sign(0cm) should be used-value-equivalent to 0
+PASS sign(0mm) should be used-value-equivalent to 0
+PASS sign(0Q) should be used-value-equivalent to 0
+PASS sign(0in) should be used-value-equivalent to 0
+PASS sign(0pc) should be used-value-equivalent to 0
+PASS sign(0pt) should be used-value-equivalent to 0
+PASS sign(0em) should be used-value-equivalent to 0
+PASS sign(0ex) should be used-value-equivalent to 0
+PASS sign(0ch) should be used-value-equivalent to 0
+PASS sign(0rem) should be used-value-equivalent to 0
+PASS sign(0vh) should be used-value-equivalent to 0
+PASS sign(0vw) should be used-value-equivalent to 0
+PASS sign(0vmin) should be used-value-equivalent to 0
+PASS sign(0vmax) should be used-value-equivalent to 0
+PASS sign(-0px) should be used-value-equivalent to -0
+PASS sign(-0cm) should be used-value-equivalent to -0
+PASS sign(-0mm) should be used-value-equivalent to -0
+PASS sign(-0Q) should be used-value-equivalent to -0
+PASS sign(-0in) should be used-value-equivalent to -0
+PASS sign(-0pc) should be used-value-equivalent to -0
+PASS sign(-0pt) should be used-value-equivalent to -0
+PASS sign(-0em) should be used-value-equivalent to -0
+PASS sign(-0ex) should be used-value-equivalent to -0
+PASS sign(-0ch) should be used-value-equivalent to -0
+PASS sign(-0rem) should be used-value-equivalent to -0
+PASS sign(-0vh) should be used-value-equivalent to -0
+PASS sign(-0vw) should be used-value-equivalent to -0
+PASS sign(-0vmin) should be used-value-equivalent to -0
+PASS sign(-0vmax) should be used-value-equivalent to -0
+PASS sign(0s) should be used-value-equivalent to 0
+PASS sign(0ms) should be used-value-equivalent to 0
+PASS sign(-0s) should be used-value-equivalent to 0
+PASS sign(-0ms) should be used-value-equivalent to 0
+PASS sign(0deg) should be used-value-equivalent to 0
+PASS sign(0grad) should be used-value-equivalent to 0
+PASS sign(0rad) should be used-value-equivalent to 0
+PASS sign(0turn) should be used-value-equivalent to 0
+PASS sign(-0deg) should be used-value-equivalent to -0
+PASS sign(-0grad) should be used-value-equivalent to -0
+PASS sign(-0rad) should be used-value-equivalent to -0
+PASS sign(-0turn) should be used-value-equivalent to -0
+FAIL abs(1px) should be used-value-equivalent to 1px assert_equals: abs(1px) and 1px serialize to the same thing in used values. expected "1px" but got "0px"
+FAIL abs(1cm) should be used-value-equivalent to 1cm assert_equals: abs(1cm) and 1cm serialize to the same thing in used values. expected "37.7953px" but got "0px"
+FAIL abs(1mm) should be used-value-equivalent to 1mm assert_equals: abs(1mm) and 1mm serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL abs(1Q) should be used-value-equivalent to 1Q assert_equals: abs(1Q) and 1Q serialize to the same thing in used values. expected "0.944882px" but got "0px"
+FAIL abs(1in) should be used-value-equivalent to 1in assert_equals: abs(1in) and 1in serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL abs(1pc) should be used-value-equivalent to 1pc assert_equals: abs(1pc) and 1pc serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1pt) should be used-value-equivalent to 1pt assert_equals: abs(1pt) and 1pt serialize to the same thing in used values. expected "1.33333px" but got "0px"
+FAIL abs(1em) should be used-value-equivalent to 1em assert_equals: abs(1em) and 1em serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1ex) should be used-value-equivalent to 1ex assert_equals: abs(1ex) and 1ex serialize to the same thing in used values. expected "7.17969px" but got "0px"
+FAIL abs(1ch) should be used-value-equivalent to 1ch assert_equals: abs(1ch) and 1ch serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1rem) should be used-value-equivalent to 1rem assert_equals: abs(1rem) and 1rem serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1vh) should be used-value-equivalent to 1vh assert_equals: abs(1vh) and 1vh serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(1vw) should be used-value-equivalent to 1vw assert_equals: abs(1vw) and 1vw serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1vmin) should be used-value-equivalent to 1vmin assert_equals: abs(1vmin) and 1vmin serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(1vmax) should be used-value-equivalent to 1vmax assert_equals: abs(1vmax) and 1vmax serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1px) should be used-value-equivalent to 1px assert_equals: abs(-1px) and 1px serialize to the same thing in used values. expected "1px" but got "0px"
+FAIL abs(-1cm) should be used-value-equivalent to 1cm assert_equals: abs(-1cm) and 1cm serialize to the same thing in used values. expected "37.7953px" but got "0px"
+FAIL abs(-1mm) should be used-value-equivalent to 1mm assert_equals: abs(-1mm) and 1mm serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL abs(-1Q) should be used-value-equivalent to 1Q assert_equals: abs(-1Q) and 1Q serialize to the same thing in used values. expected "0.944882px" but got "0px"
+FAIL abs(-1in) should be used-value-equivalent to 1in assert_equals: abs(-1in) and 1in serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL abs(-1pc) should be used-value-equivalent to 1pc assert_equals: abs(-1pc) and 1pc serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1pt) should be used-value-equivalent to 1pt assert_equals: abs(-1pt) and 1pt serialize to the same thing in used values. expected "1.33333px" but got "0px"
+FAIL abs(-1em) should be used-value-equivalent to 1em assert_equals: abs(-1em) and 1em serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1ex) should be used-value-equivalent to 1ex assert_equals: abs(-1ex) and 1ex serialize to the same thing in used values. expected "7.17969px" but got "0px"
+FAIL abs(-1ch) should be used-value-equivalent to 1ch assert_equals: abs(-1ch) and 1ch serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1rem) should be used-value-equivalent to 1rem assert_equals: abs(-1rem) and 1rem serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1vh) should be used-value-equivalent to 1vh assert_equals: abs(-1vh) and 1vh serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(-1vw) should be used-value-equivalent to 1vw assert_equals: abs(-1vw) and 1vw serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1vmin) should be used-value-equivalent to 1vmin assert_equals: abs(-1vmin) and 1vmin serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(-1vmax) should be used-value-equivalent to 1vmax assert_equals: abs(-1vmax) and 1vmax serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1s) should be used-value-equivalent to 1s assert_equals: abs(1s) and 1s serialize to the same thing in used values. expected "1s" but got "0s"
+FAIL abs(1ms) should be used-value-equivalent to 1ms assert_equals: abs(1ms) and 1ms serialize to the same thing in used values. expected "0.001s" but got "0s"
+FAIL abs(-1s) should be used-value-equivalent to 1s assert_equals: abs(-1s) and 1s serialize to the same thing in used values. expected "1s" but got "0s"
+FAIL abs(-1ms) should be used-value-equivalent to 1ms assert_equals: abs(-1ms) and 1ms serialize to the same thing in used values. expected "0.001s" but got "0s"
+FAIL abs(1deg) should be used-value-equivalent to 1deg Cannot read properties of undefined (reading 'split')
+FAIL abs(1grad) should be used-value-equivalent to 1grad Cannot read properties of undefined (reading 'split')
+FAIL abs(1rad) should be used-value-equivalent to 1rad Cannot read properties of undefined (reading 'split')
+FAIL abs(1turn) should be used-value-equivalent to 1turn Cannot read properties of undefined (reading 'split')
+FAIL abs(-1deg) should be used-value-equivalent to 1deg Cannot read properties of undefined (reading 'split')
+FAIL abs(-1grad) should be used-value-equivalent to 1grad Cannot read properties of undefined (reading 'split')
+FAIL abs(-1rad) should be used-value-equivalent to 1rad Cannot read properties of undefined (reading 'split')
+FAIL abs(-1turn) should be used-value-equivalent to 1turn Cannot read properties of undefined (reading 'split')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-values/round-mod-rem-computed-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-values/round-mod-rem-computed-expected.txt
new file mode 100644
index 0000000..7de46f0
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-values/round-mod-rem-computed-expected.txt
@@ -0,0 +1,93 @@
+This is a testharness.js-based test.
+Found 89 tests; 6 PASS, 83 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL round(10,10) should be used-value-equivalent to 10 assert_equals: round(10,10) and 10 serialize to the same thing in used values. expected "matrix(10, 0, 0, 10, 0, 0)" but got "none"
+FAIL mod(1,1) should be used-value-equivalent to 0 assert_equals: mod(1,1) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL rem(1,1) should be used-value-equivalent to 0 assert_equals: rem(1,1) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL calc(round(100,10)) should be used-value-equivalent to 100 assert_equals: calc(round(100,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(up, 101,10)) should be used-value-equivalent to 110 assert_equals: calc(round(up, 101,10)) and 110 serialize to the same thing in used values. expected "matrix(110, 0, 0, 110, 0, 0)" but got "none"
+FAIL calc(round(down, 106,10)) should be used-value-equivalent to 100 assert_equals: calc(round(down, 106,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,105, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,105, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,-105, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,-105, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(-100,10)) should be used-value-equivalent to -100 assert_equals: calc(round(-100,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(round(up, -103,10)) should be used-value-equivalent to -100 assert_equals: calc(round(up, -103,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL mod(18,5) should be used-value-equivalent to 3 assert_equals: mod(18,5) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL rem(18,5) should be used-value-equivalent to 3 assert_equals: rem(18,5) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL mod(-140,-90) should be used-value-equivalent to -50 assert_equals: mod(-140,-90) and -50 serialize to the same thing in used values. expected "matrix(-50, 0, 0, -50, 0, 0)" but got "none"
+FAIL mod(-18,5) should be used-value-equivalent to 2 assert_equals: mod(-18,5) and 2 serialize to the same thing in used values. expected "matrix(2, 0, 0, 2, 0, 0)" but got "none"
+FAIL rem(-18,5) should be used-value-equivalent to -3 assert_equals: rem(-18,5) and -3 serialize to the same thing in used values. expected "matrix(-3, 0, 0, -3, 0, 0)" but got "none"
+FAIL mod(140,-90) should be used-value-equivalent to -40 assert_equals: mod(140,-90) and -40 serialize to the same thing in used values. expected "matrix(-40, 0, 0, -40, 0, 0)" but got "none"
+FAIL rem(140,-90) should be used-value-equivalent to 50 assert_equals: rem(140,-90) and 50 serialize to the same thing in used values. expected "matrix(50, 0, 0, 50, 0, 0)" but got "none"
+FAIL calc(round(round(100,10), 10)) should be used-value-equivalent to 100 assert_equals: calc(round(round(100,10), 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(up, round(100,10) + 1,10)) should be used-value-equivalent to 110 assert_equals: calc(round(up, round(100,10) + 1,10)) and 110 serialize to the same thing in used values. expected "matrix(110, 0, 0, 110, 0, 0)" but got "none"
+FAIL calc(round(down, round(100,10) + 2 * 3,10)) should be used-value-equivalent to 100 assert_equals: calc(round(down, round(100,10) + 2 * 3,10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(to-zero,round(100,10) * 2 - 95, 10)) should be used-value-equivalent to 100 assert_equals: calc(round(to-zero,round(100,10) * 2 - 95, 10)) and 100 serialize to the same thing in used values. expected "matrix(100, 0, 0, 100, 0, 0)" but got "none"
+FAIL calc(round(round(100,10)* -1,10)) should be used-value-equivalent to -100 assert_equals: calc(round(round(100,10)* -1,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(round(up, -103 + -103 / -103 - 1,10)) should be used-value-equivalent to -100 assert_equals: calc(round(up, -103 + -103 / -103 - 1,10)) and -100 serialize to the same thing in used values. expected "matrix(-100, 0, 0, -100, 0, 0)" but got "none"
+FAIL calc(mod(18,5) * 2 + mod(17,5)) should be used-value-equivalent to 8 assert_equals: calc(mod(18,5) * 2 + mod(17,5)) and 8 serialize to the same thing in used values. expected "matrix(8, 0, 0, 8, 0, 0)" but got "none"
+FAIL calc(rem(mod(18,5),5)) should be used-value-equivalent to 3 assert_equals: calc(rem(mod(18,5),5)) and 3 serialize to the same thing in used values. expected "matrix(3, 0, 0, 3, 0, 0)" but got "none"
+FAIL calc(rem(mod(18,5),mod(17,5))) should be used-value-equivalent to 1 assert_equals: calc(rem(mod(18,5),mod(17,5))) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL calc(mod(-140,-90)) should be used-value-equivalent to -50 assert_equals: calc(mod(-140,-90)) and -50 serialize to the same thing in used values. expected "matrix(-50, 0, 0, -50, 0, 0)" but got "none"
+FAIL calc(mod(rem(1,18)* -1,5)) should be used-value-equivalent to -1 assert_equals: calc(mod(rem(1,18)* -1,5)) and -1 serialize to the same thing in used values. expected "matrix(-1, 0, 0, -1, 0, 0)" but got "none"
+FAIL round(10px,6px) should be used-value-equivalent to 12px assert_equals: round(10px,6px) and 12px serialize to the same thing in used values. expected "12px" but got "0px"
+FAIL round(10cm,6cm) should be used-value-equivalent to 12cm assert_equals: round(10cm,6cm) and 12cm serialize to the same thing in used values. expected "453.543px" but got "0px"
+FAIL round(10mm,6mm) should be used-value-equivalent to 12mm assert_equals: round(10mm,6mm) and 12mm serialize to the same thing in used values. expected "45.3543px" but got "0px"
+FAIL round(10Q, 6Q) should be used-value-equivalent to 12Q assert_equals: round(10Q, 6Q) and 12Q serialize to the same thing in used values. expected "11.3386px" but got "0px"
+FAIL round(10in,6in) should be used-value-equivalent to 12in assert_equals: round(10in,6in) and 12in serialize to the same thing in used values. expected "1152px" but got "0px"
+FAIL round(10pc,6pc) should be used-value-equivalent to 12pc assert_equals: round(10pc,6pc) and 12pc serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10pt,6pt) should be used-value-equivalent to 12pt assert_equals: round(10pt,6pt) and 12pt serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL round(10em,6em) should be used-value-equivalent to 12em assert_equals: round(10em,6em) and 12em serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10ex,6ex) should be used-value-equivalent to 12ex assert_equals: round(10ex,6ex) and 12ex serialize to the same thing in used values. expected "84px" but got "0px"
+FAIL round(10ch,6ch) should be used-value-equivalent to 12ch assert_equals: round(10ch,6ch) and 12ch serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL round(10rem,6rem) should be used-value-equivalent to 12rem assert_equals: round(10rem,6rem) and 12rem serialize to the same thing in used values. expected "192px" but got "0px"
+FAIL round(10vh,6vh) should be used-value-equivalent to 12vh assert_equals: round(10vh,6vh) and 12vh serialize to the same thing in used values. expected "72px" but got "0px"
+FAIL round(10vw,6vw) should be used-value-equivalent to 12vw assert_equals: round(10vw,6vw) and 12vw serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL round(10vmin,6vmin) should be used-value-equivalent to 12vmin assert_equals: round(10vmin,6vmin) and 12vmin serialize to the same thing in used values. expected "72px" but got "0px"
+FAIL round(10vmax,6vmax) should be used-value-equivalent to 12vmax assert_equals: round(10vmax,6vmax) and 12vmax serialize to the same thing in used values. expected "96px" but got "0px"
+PASS round(10s,6s) should be used-value-equivalent to 12s
+PASS round(10ms,6ms) should be used-value-equivalent to 12ms
+FAIL round(10deg,6deg) should be used-value-equivalent to 12deg Cannot read properties of undefined (reading 'split')
+FAIL round(10grad,6grad) should be used-value-equivalent to 12grad Cannot read properties of undefined (reading 'split')
+FAIL round(10rad,6rad) should be used-value-equivalent to 12rad Cannot read properties of undefined (reading 'split')
+FAIL round(10turn,6turn) should be used-value-equivalent to 12turn Cannot read properties of undefined (reading 'split')
+FAIL mod(10px,6px) should be used-value-equivalent to 4px assert_equals: mod(10px,6px) and 4px serialize to the same thing in used values. expected "4px" but got "0px"
+FAIL mod(10cm,6cm) should be used-value-equivalent to 4cm assert_equals: mod(10cm,6cm) and 4cm serialize to the same thing in used values. expected "151.181px" but got "0px"
+FAIL mod(10mm,6mm) should be used-value-equivalent to 4mm assert_equals: mod(10mm,6mm) and 4mm serialize to the same thing in used values. expected "15.1181px" but got "0px"
+FAIL mod(10Q, 6Q) should be used-value-equivalent to 4Q assert_equals: mod(10Q, 6Q) and 4Q serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL mod(10in,6in) should be used-value-equivalent to 4in assert_equals: mod(10in,6in) and 4in serialize to the same thing in used values. expected "384px" but got "0px"
+FAIL mod(10pc,6pc) should be used-value-equivalent to 4pc assert_equals: mod(10pc,6pc) and 4pc serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10em,6em) should be used-value-equivalent to 4em assert_equals: mod(10em,6em) and 4em serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10ex,6ex) should be used-value-equivalent to 4ex assert_equals: mod(10ex,6ex) and 4ex serialize to the same thing in used values. expected "28px" but got "0px"
+FAIL mod(10ch,6ch) should be used-value-equivalent to 4ch assert_equals: mod(10ch,6ch) and 4ch serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL mod(10rem,6rem) should be used-value-equivalent to 4rem assert_equals: mod(10rem,6rem) and 4rem serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL mod(10vh,6vh) should be used-value-equivalent to 4vh assert_equals: mod(10vh,6vh) and 4vh serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL mod(10vw,6vw) should be used-value-equivalent to 4vw assert_equals: mod(10vw,6vw) and 4vw serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL mod(10vmin,6vmin) should be used-value-equivalent to 4vmin assert_equals: mod(10vmin,6vmin) and 4vmin serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL mod(10vmax,6vmax) should be used-value-equivalent to 4vmax assert_equals: mod(10vmax,6vmax) and 4vmax serialize to the same thing in used values. expected "32px" but got "0px"
+PASS mod(10s,6s) should be used-value-equivalent to 4s
+PASS mod(10ms,6ms) should be used-value-equivalent to 4ms
+FAIL mod(10deg,6deg) should be used-value-equivalent to 4deg Cannot read properties of undefined (reading 'split')
+FAIL mod(10grad,6grad) should be used-value-equivalent to 4grad Cannot read properties of undefined (reading 'split')
+FAIL mod(10rad,6rad) should be used-value-equivalent to 4rad Cannot read properties of undefined (reading 'split')
+FAIL mod(10turn,6turn) should be used-value-equivalent to 4turn Cannot read properties of undefined (reading 'split')
+FAIL rem(10px,6px) should be used-value-equivalent to 4px assert_equals: rem(10px,6px) and 4px serialize to the same thing in used values. expected "4px" but got "0px"
+FAIL rem(10cm,6cm) should be used-value-equivalent to 4cm assert_equals: rem(10cm,6cm) and 4cm serialize to the same thing in used values. expected "151.181px" but got "0px"
+FAIL rem(10mm,6mm) should be used-value-equivalent to 4mm assert_equals: rem(10mm,6mm) and 4mm serialize to the same thing in used values. expected "15.1181px" but got "0px"
+FAIL rem(10Q, 6Q) should be used-value-equivalent to 4Q assert_equals: rem(10Q, 6Q) and 4Q serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL rem(10in,6in) should be used-value-equivalent to 4in assert_equals: rem(10in,6in) and 4in serialize to the same thing in used values. expected "384px" but got "0px"
+FAIL rem(10pc,6pc) should be used-value-equivalent to 4pc assert_equals: rem(10pc,6pc) and 4pc serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10em,6em) should be used-value-equivalent to 4em assert_equals: rem(10em,6em) and 4em serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10ex,6ex) should be used-value-equivalent to 4ex assert_equals: rem(10ex,6ex) and 4ex serialize to the same thing in used values. expected "28px" but got "0px"
+FAIL rem(10ch,6ch) should be used-value-equivalent to 4ch assert_equals: rem(10ch,6ch) and 4ch serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL rem(10rem,6rem) should be used-value-equivalent to 4rem assert_equals: rem(10rem,6rem) and 4rem serialize to the same thing in used values. expected "64px" but got "0px"
+FAIL rem(10vh,6vh) should be used-value-equivalent to 4vh assert_equals: rem(10vh,6vh) and 4vh serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL rem(10vw,6vw) should be used-value-equivalent to 4vw assert_equals: rem(10vw,6vw) and 4vw serialize to the same thing in used values. expected "32px" but got "0px"
+FAIL rem(10vmin,6vmin) should be used-value-equivalent to 4vmin assert_equals: rem(10vmin,6vmin) and 4vmin serialize to the same thing in used values. expected "24px" but got "0px"
+FAIL rem(10vmax,6vmax) should be used-value-equivalent to 4vmax assert_equals: rem(10vmax,6vmax) and 4vmax serialize to the same thing in used values. expected "32px" but got "0px"
+PASS rem(10s,6s) should be used-value-equivalent to 4s
+PASS rem(10ms,6ms) should be used-value-equivalent to 4ms
+FAIL rem(10deg,6deg) should be used-value-equivalent to 4deg Cannot read properties of undefined (reading 'split')
+FAIL rem(10grad,6grad) should be used-value-equivalent to 4grad Cannot read properties of undefined (reading 'split')
+FAIL rem(10rad,6rad) should be used-value-equivalent to 4rad Cannot read properties of undefined (reading 'split')
+FAIL rem(10turn,6turn) should be used-value-equivalent to 4turn Cannot read properties of undefined (reading 'split')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-values/signs-abs-computed-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-values/signs-abs-computed-expected.txt
new file mode 100644
index 0000000..031583b
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-values/signs-abs-computed-expected.txt
@@ -0,0 +1,146 @@
+This is a testharness.js-based test.
+Found 142 tests; 87 PASS, 55 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL abs(1) should be used-value-equivalent to 1 assert_equals: abs(1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL sign(1) should be used-value-equivalent to 1 assert_equals: sign(1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL abs(-1) should be used-value-equivalent to 1 assert_equals: abs(-1) and 1 serialize to the same thing in used values. expected "matrix(1, 0, 0, 1, 0, 0)" but got "none"
+FAIL sign(-1) should be used-value-equivalent to -1 assert_equals: sign(-1) and -1 serialize to the same thing in used values. expected "matrix(-1, 0, 0, -1, 0, 0)" but got "none"
+PASS abs(sign(1)) should be used-value-equivalent to 1
+PASS abs(sign(sign(1))) should be used-value-equivalent to 1
+PASS sign(sign(sign(1) + sign(1))) should be used-value-equivalent to 1
+FAIL calc(abs(0.1 + 0.2) + 0.05) should be used-value-equivalent to 0.35 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(0.1 + 0.2) - 0.05) should be used-value-equivalent to 0.95 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(0.1 + 0.2) * 2) should be used-value-equivalent to 0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(sign(0.1) + 0.2) / 2) should be used-value-equivalent to 0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(abs(0.1 + 0.2) * -2) should be used-value-equivalent to -0.6 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(0.1 - 0.2) - 0.05) should be used-value-equivalent to -1.05 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(1) + sign(1) - 0.05) should be used-value-equivalent to 1.95 Cannot read properties of undefined (reading 'split')
+FAIL calc(sign(-0)) should be used-value-equivalent to -0 assert_equals: calc(sign(-0)) and -0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+FAIL calc(sign(0)) should be used-value-equivalent to 0 assert_equals: calc(sign(0)) and 0 serialize to the same thing in used values. expected "matrix(0, 0, 0, 0, 0, 0)" but got "none"
+PASS sign(1px) should be used-value-equivalent to 1
+PASS sign(1cm) should be used-value-equivalent to 1
+PASS sign(1mm) should be used-value-equivalent to 1
+PASS sign(1Q) should be used-value-equivalent to 1
+PASS sign(1in) should be used-value-equivalent to 1
+PASS sign(1pc) should be used-value-equivalent to 1
+PASS sign(1pt) should be used-value-equivalent to 1
+PASS sign(1em) should be used-value-equivalent to 1
+PASS sign(1ex) should be used-value-equivalent to 1
+PASS sign(1ch) should be used-value-equivalent to 1
+PASS sign(1rem) should be used-value-equivalent to 1
+PASS sign(1vh) should be used-value-equivalent to 1
+PASS sign(1vw) should be used-value-equivalent to 1
+PASS sign(1vmin) should be used-value-equivalent to 1
+PASS sign(1vmax) should be used-value-equivalent to 1
+PASS sign(-1px) should be used-value-equivalent to -1
+PASS sign(-1cm) should be used-value-equivalent to -1
+PASS sign(-1mm) should be used-value-equivalent to -1
+PASS sign(-1Q) should be used-value-equivalent to -1
+PASS sign(-1in) should be used-value-equivalent to -1
+PASS sign(-1pc) should be used-value-equivalent to -1
+PASS sign(-1pt) should be used-value-equivalent to -1
+PASS sign(-1em) should be used-value-equivalent to -1
+PASS sign(-1ex) should be used-value-equivalent to -1
+PASS sign(-1ch) should be used-value-equivalent to -1
+PASS sign(-1rem) should be used-value-equivalent to -1
+PASS sign(-1vh) should be used-value-equivalent to -1
+PASS sign(-1vw) should be used-value-equivalent to -1
+PASS sign(-1vmin) should be used-value-equivalent to -1
+PASS sign(-1vmax) should be used-value-equivalent to -1
+PASS sign(1s) should be used-value-equivalent to 1
+PASS sign(1ms) should be used-value-equivalent to 1
+PASS sign(-1s) should be used-value-equivalent to -1
+PASS sign(-1ms) should be used-value-equivalent to -1
+PASS sign(1deg) should be used-value-equivalent to 1
+PASS sign(1grad) should be used-value-equivalent to 1
+PASS sign(1rad) should be used-value-equivalent to 1
+PASS sign(1turn) should be used-value-equivalent to 1
+PASS sign(-1deg) should be used-value-equivalent to -1
+PASS sign(-1grad) should be used-value-equivalent to -1
+PASS sign(-1rad) should be used-value-equivalent to -1
+PASS sign(-1turn) should be used-value-equivalent to -1
+PASS sign(0px) should be used-value-equivalent to 0
+PASS sign(0cm) should be used-value-equivalent to 0
+PASS sign(0mm) should be used-value-equivalent to 0
+PASS sign(0Q) should be used-value-equivalent to 0
+PASS sign(0in) should be used-value-equivalent to 0
+PASS sign(0pc) should be used-value-equivalent to 0
+PASS sign(0pt) should be used-value-equivalent to 0
+PASS sign(0em) should be used-value-equivalent to 0
+PASS sign(0ex) should be used-value-equivalent to 0
+PASS sign(0ch) should be used-value-equivalent to 0
+PASS sign(0rem) should be used-value-equivalent to 0
+PASS sign(0vh) should be used-value-equivalent to 0
+PASS sign(0vw) should be used-value-equivalent to 0
+PASS sign(0vmin) should be used-value-equivalent to 0
+PASS sign(0vmax) should be used-value-equivalent to 0
+PASS sign(-0px) should be used-value-equivalent to -0
+PASS sign(-0cm) should be used-value-equivalent to -0
+PASS sign(-0mm) should be used-value-equivalent to -0
+PASS sign(-0Q) should be used-value-equivalent to -0
+PASS sign(-0in) should be used-value-equivalent to -0
+PASS sign(-0pc) should be used-value-equivalent to -0
+PASS sign(-0pt) should be used-value-equivalent to -0
+PASS sign(-0em) should be used-value-equivalent to -0
+PASS sign(-0ex) should be used-value-equivalent to -0
+PASS sign(-0ch) should be used-value-equivalent to -0
+PASS sign(-0rem) should be used-value-equivalent to -0
+PASS sign(-0vh) should be used-value-equivalent to -0
+PASS sign(-0vw) should be used-value-equivalent to -0
+PASS sign(-0vmin) should be used-value-equivalent to -0
+PASS sign(-0vmax) should be used-value-equivalent to -0
+PASS sign(0s) should be used-value-equivalent to 0
+PASS sign(0ms) should be used-value-equivalent to 0
+PASS sign(-0s) should be used-value-equivalent to 0
+PASS sign(-0ms) should be used-value-equivalent to 0
+PASS sign(0deg) should be used-value-equivalent to 0
+PASS sign(0grad) should be used-value-equivalent to 0
+PASS sign(0rad) should be used-value-equivalent to 0
+PASS sign(0turn) should be used-value-equivalent to 0
+PASS sign(-0deg) should be used-value-equivalent to -0
+PASS sign(-0grad) should be used-value-equivalent to -0
+PASS sign(-0rad) should be used-value-equivalent to -0
+PASS sign(-0turn) should be used-value-equivalent to -0
+FAIL abs(1px) should be used-value-equivalent to 1px assert_equals: abs(1px) and 1px serialize to the same thing in used values. expected "1px" but got "0px"
+FAIL abs(1cm) should be used-value-equivalent to 1cm assert_equals: abs(1cm) and 1cm serialize to the same thing in used values. expected "37.7953px" but got "0px"
+FAIL abs(1mm) should be used-value-equivalent to 1mm assert_equals: abs(1mm) and 1mm serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL abs(1Q) should be used-value-equivalent to 1Q assert_equals: abs(1Q) and 1Q serialize to the same thing in used values. expected "0.944882px" but got "0px"
+FAIL abs(1in) should be used-value-equivalent to 1in assert_equals: abs(1in) and 1in serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL abs(1pc) should be used-value-equivalent to 1pc assert_equals: abs(1pc) and 1pc serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1pt) should be used-value-equivalent to 1pt assert_equals: abs(1pt) and 1pt serialize to the same thing in used values. expected "1.33333px" but got "0px"
+FAIL abs(1em) should be used-value-equivalent to 1em assert_equals: abs(1em) and 1em serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1ex) should be used-value-equivalent to 1ex assert_equals: abs(1ex) and 1ex serialize to the same thing in used values. expected "7px" but got "0px"
+FAIL abs(1ch) should be used-value-equivalent to 1ch assert_equals: abs(1ch) and 1ch serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1rem) should be used-value-equivalent to 1rem assert_equals: abs(1rem) and 1rem serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(1vh) should be used-value-equivalent to 1vh assert_equals: abs(1vh) and 1vh serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(1vw) should be used-value-equivalent to 1vw assert_equals: abs(1vw) and 1vw serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1vmin) should be used-value-equivalent to 1vmin assert_equals: abs(1vmin) and 1vmin serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(1vmax) should be used-value-equivalent to 1vmax assert_equals: abs(1vmax) and 1vmax serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1px) should be used-value-equivalent to 1px assert_equals: abs(-1px) and 1px serialize to the same thing in used values. expected "1px" but got "0px"
+FAIL abs(-1cm) should be used-value-equivalent to 1cm assert_equals: abs(-1cm) and 1cm serialize to the same thing in used values. expected "37.7953px" but got "0px"
+FAIL abs(-1mm) should be used-value-equivalent to 1mm assert_equals: abs(-1mm) and 1mm serialize to the same thing in used values. expected "3.77953px" but got "0px"
+FAIL abs(-1Q) should be used-value-equivalent to 1Q assert_equals: abs(-1Q) and 1Q serialize to the same thing in used values. expected "0.944882px" but got "0px"
+FAIL abs(-1in) should be used-value-equivalent to 1in assert_equals: abs(-1in) and 1in serialize to the same thing in used values. expected "96px" but got "0px"
+FAIL abs(-1pc) should be used-value-equivalent to 1pc assert_equals: abs(-1pc) and 1pc serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1pt) should be used-value-equivalent to 1pt assert_equals: abs(-1pt) and 1pt serialize to the same thing in used values. expected "1.33333px" but got "0px"
+FAIL abs(-1em) should be used-value-equivalent to 1em assert_equals: abs(-1em) and 1em serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1ex) should be used-value-equivalent to 1ex assert_equals: abs(-1ex) and 1ex serialize to the same thing in used values. expected "7px" but got "0px"
+FAIL abs(-1ch) should be used-value-equivalent to 1ch assert_equals: abs(-1ch) and 1ch serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1rem) should be used-value-equivalent to 1rem assert_equals: abs(-1rem) and 1rem serialize to the same thing in used values. expected "16px" but got "0px"
+FAIL abs(-1vh) should be used-value-equivalent to 1vh assert_equals: abs(-1vh) and 1vh serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(-1vw) should be used-value-equivalent to 1vw assert_equals: abs(-1vw) and 1vw serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(-1vmin) should be used-value-equivalent to 1vmin assert_equals: abs(-1vmin) and 1vmin serialize to the same thing in used values. expected "6px" but got "0px"
+FAIL abs(-1vmax) should be used-value-equivalent to 1vmax assert_equals: abs(-1vmax) and 1vmax serialize to the same thing in used values. expected "8px" but got "0px"
+FAIL abs(1s) should be used-value-equivalent to 1s assert_equals: abs(1s) and 1s serialize to the same thing in used values. expected "1s" but got "0s"
+FAIL abs(1ms) should be used-value-equivalent to 1ms assert_equals: abs(1ms) and 1ms serialize to the same thing in used values. expected "0.001s" but got "0s"
+FAIL abs(-1s) should be used-value-equivalent to 1s assert_equals: abs(-1s) and 1s serialize to the same thing in used values. expected "1s" but got "0s"
+FAIL abs(-1ms) should be used-value-equivalent to 1ms assert_equals: abs(-1ms) and 1ms serialize to the same thing in used values. expected "0.001s" but got "0s"
+FAIL abs(1deg) should be used-value-equivalent to 1deg Cannot read properties of undefined (reading 'split')
+FAIL abs(1grad) should be used-value-equivalent to 1grad Cannot read properties of undefined (reading 'split')
+FAIL abs(1rad) should be used-value-equivalent to 1rad Cannot read properties of undefined (reading 'split')
+FAIL abs(1turn) should be used-value-equivalent to 1turn Cannot read properties of undefined (reading 'split')
+FAIL abs(-1deg) should be used-value-equivalent to 1deg Cannot read properties of undefined (reading 'split')
+FAIL abs(-1grad) should be used-value-equivalent to 1grad Cannot read properties of undefined (reading 'split')
+FAIL abs(-1rad) should be used-value-equivalent to 1rad Cannot read properties of undefined (reading 'split')
+FAIL abs(-1turn) should be used-value-equivalent to 1turn Cannot read properties of undefined (reading 'split')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 7b176c77..fd1255fa 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -235,6 +235,7 @@
     getter canGoBack
     getter canGoForward
     getter current
+    getter oncurrentchange
     getter onnavigate
     getter onnavigateerror
     getter onnavigatesuccess
@@ -247,9 +248,15 @@
     method navigate
     method reload
     method updateCurrent
+    setter oncurrentchange
     setter onnavigate
     setter onnavigateerror
     setter onnavigatesuccess
+interface AppHistoryCurrentChangeEvent : Event
+    attribute @@toStringTag
+    getter from
+    getter navigationType
+    method constructor
 interface AppHistoryDestination
     attribute @@toStringTag
     getter id
diff --git a/tools/cast3p/OWNERS b/tools/cast3p/OWNERS
new file mode 100644
index 0000000..b886434
--- /dev/null
+++ b/tools/cast3p/OWNERS
@@ -0,0 +1,4 @@
+chonggu@google.com
+mfoltz@google.com
+riazantsevv@google.com
+rwkeane@google.com
\ No newline at end of file
diff --git a/tools/cast3p/README.md b/tools/cast3p/README.md
new file mode 100644
index 0000000..0b273d5
--- /dev/null
+++ b/tools/cast3p/README.md
@@ -0,0 +1,5 @@
+This directory contains Python code used for interacting with the binaries
+related to OEM integration for Cast running on third-party hardware. 
+These binaries can be fetched by setting checkout_cast3p=True in .gclient.
+go/upstreaming-the-cast-web-runtime details the effort to upstream the
+Cast Web Runtime.
diff --git a/tools/cast3p/runtime.version b/tools/cast3p/runtime.version
new file mode 100644
index 0000000..3f82e17
--- /dev/null
+++ b/tools/cast3p/runtime.version
@@ -0,0 +1 @@
+273826
\ No newline at end of file
diff --git a/tools/cast3p/update_runtime.py b/tools/cast3p/update_runtime.py
new file mode 100755
index 0000000..1624be1
--- /dev/null
+++ b/tools/cast3p/update_runtime.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import logging
+import os
+import subprocess
+import shutil
+import sys
+import tempfile
+
+from zipfile import ZipFile
+
+DIR_SOURCE_ROOT = os.path.abspath(
+    os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
+
+sys.path.append(os.path.join(DIR_SOURCE_ROOT, 'build'))
+import find_depot_tools
+
+RUNTIME_SIGNATURE_FILE = '.version'
+WEB_RUNTIME_ROOT = os.path.abspath(
+    os.path.join(DIR_SOURCE_ROOT, 'third_party', 'cast_web_runtime'))
+ZIP_PATH_TEMPLATE = (
+    'gs://gtv-eureka/internal/master/core_runtime-eng/{version}' \
+    '/core_runtime_package.zip')
+
+
+# Fetches a .zip file from GCS and uncompresses it to |output_dir|.
+def DownloadAndUnpackFromCloudStorage(url, output_dir):
+  with tempfile.TemporaryDirectory() as tmpdir:
+    temp_zip_file = os.path.join(tmpdir, 'web_runtime.zip')
+    cmd = [
+        os.path.join(find_depot_tools.DEPOT_TOOLS_PATH, 'gsutil.py'), 'cp', url,
+        temp_zip_file
+    ]
+    task = subprocess.check_call(cmd,
+                                 stdout=subprocess.DEVNULL,
+                                 stderr=subprocess.DEVNULL)
+    with ZipFile(temp_zip_file, 'r') as zip_ref:
+      zip_ref.extractall(output_dir)
+
+
+def MakeCleanDirectory(directory_name):
+  if os.path.exists(directory_name):
+    shutil.rmtree(directory_name)
+  os.mkdir(directory_name)
+
+
+def main():
+  runtime_version = open(
+      os.path.join(os.path.dirname(__file__),
+                   'runtime.version')).read().strip()
+  signature_file_path = os.path.join(WEB_RUNTIME_ROOT, RUNTIME_SIGNATURE_FILE)
+  current_signature = (open(signature_file_path, 'r').read().strip()
+                       if os.path.exists(signature_file_path) else '')
+  if current_signature != runtime_version:
+    logging.info(
+        'Downloading Cast Web Runtime version {}...'.format(runtime_version))
+    MakeCleanDirectory(WEB_RUNTIME_ROOT)
+    DownloadAndUnpackFromCloudStorage(
+        ZIP_PATH_TEMPLATE.format(version=runtime_version), WEB_RUNTIME_ROOT)
+  with open(signature_file_path, 'w') as f:
+    f.write(runtime_version)
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index d71fb1c..1f6376b2 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -49,6 +49,7 @@
       'fuchsia-official': 'fuchsia_official_optimize_goma',
       'linux-archive-rel': 'release_bot',
       'linux-archive-dbg': 'debug_bot',
+      'linux-archive-tagged': 'release_bot',
       'linux-official': 'official_optimize_goma',
       'mac-archive-rel': 'release_bot_mac_strip_minimal_symbols',
       'mac-archive-dbg': 'debug_bot',
diff --git a/tools/mb/mb_config_expectations/chromium.json b/tools/mb/mb_config_expectations/chromium.json
index 3497b9ed..1557087 100644
--- a/tools/mb/mb_config_expectations/chromium.json
+++ b/tools/mb/mb_config_expectations/chromium.json
@@ -49,6 +49,14 @@
       "use_goma": true
     }
   },
+  "linux-archive-tagged": {
+    "gn_args": {
+      "dcheck_always_on": false,
+      "is_component_build": false,
+      "is_debug": false,
+      "use_goma": true
+    }
+  },
   "linux-official": {
     "gn_args": {
       "is_official_build": true,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index d9a8816..1a9cd2ab 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -45904,6 +45904,7 @@
   <int value="59" label="SBOX_ERROR_CANNOT_INIT_BROKERSERVICES"/>
   <int value="60" label="SBOX_ERROR_CANNOT_UPDATE_JOB_PROCESS_LIMIT"/>
   <int value="61" label="SBOX_ERROR_CANNOT_CREATE_LOWBOX_IMPERSONATION_TOKEN"/>
+  <int value="62" label="SBOX_ERROR_UNSANDBOXED_PROCESS"/>
   <int value="1002" label="LAUNCH_RESULT_SUCCESS"/>
   <int value="1003" label="LAUNCH_RESULT_FAILURE"/>
 </enum>
@@ -47648,6 +47649,7 @@
       label="OverlayScrollbarFlashAfterAnyScrollUpdate:enabled"/>
   <int value="-1907565048" label="HtmlBaseUsernameDetector:disabled"/>
   <int value="-1907342706" label="ReadItLaterInMenu:disabled"/>
+  <int value="-1905470520" label="FirmwareUpdaterApp:enabled"/>
   <int value="-1903365454" label="SyncPseudoUSSPreferences:disabled"/>
   <int value="-1899715534" label="GamepadPollingInterval:enabled"/>
   <int value="-1899652563" label="ReportFeedUserActions:enabled"/>
@@ -48782,6 +48784,7 @@
   <int value="-1052219252" label="disable-captive-portal-bypass-proxy"/>
   <int value="-1052115254" label="TextfieldFocusOnTapUp:disabled"/>
   <int value="-1051509976" label="ServiceWorkerOnUI:disabled"/>
+  <int value="-1050006327" label="FirmwareUpdaterApp:disabled"/>
   <int value="-1048901516" label="ChromeMemex:enabled"/>
   <int value="-1048011353" label="LongPressBackNewDesign:disabled"/>
   <int value="-1046641729" label="TranslateUI:enabled"/>
@@ -50086,6 +50089,7 @@
   <int value="-15879016"
       label="OmniboxUIExperimentUnboldSuggestionText:disabled"/>
   <int value="-13918890" label="disable-download-notification"/>
+  <int value="-13180015" label="WebUsbDeviceDetection:disabled"/>
   <int value="-12225998" label="ShareButtonInTopToolbar:disabled"/>
   <int value="-11983392"
       label="MagnifierContinuousMouseFollowingModeSetting:enabled"/>
@@ -50172,6 +50176,7 @@
   <int value="54258707" label="NewTabstripAnimation:enabled"/>
   <int value="54571864" label="EnableDisplayZoomSetting:enabled"/>
   <int value="56072855" label="VaapiWebPImageDecodeAcceleration:disabled"/>
+  <int value="56605515" label="BookmarksImprovedSaveFlow:enabled"/>
   <int value="56723110" label="enable-webfonts-intervention"/>
   <int value="56900498" label="OmniboxOneClickUnelide:enabled"/>
   <int value="57255632" label="site-isolation-for-password-sites:disabled"/>
@@ -52298,6 +52303,7 @@
   <int value="1713230497" label="ColorCorrectRendering:disabled"/>
   <int value="1714016217" label="EnableHeuristicPalmDetectionFilter:enabled"/>
   <int value="1714520147" label="MBIMode:disabled"/>
+  <int value="1714746366" label="BookmarksImprovedSaveFlow:disabled"/>
   <int value="1714922056" label="GlobalMediaControls:disabled"/>
   <int value="1715338237" label="ContextualSearchSecondTap:disabled"/>
   <int value="1716104463" label="enable-fullscreen-app-list"/>
@@ -52408,6 +52414,7 @@
   <int value="1803465156" label="enable-zero-suggest-most-visited"/>
   <int value="1803470125" label="SyncUSSSessions:enabled"/>
   <int value="1803914892" label="TemporaryUnexpireFlagsM76:enabled"/>
+  <int value="1806450300" label="WebUsbDeviceDetection:enabled"/>
   <int value="1807374811" label="CCTModuleCache:enabled"/>
   <int value="1809940714" label="SpeculativeLaunchServiceWorker:disabled"/>
   <int value="1810258949" label="DisplayLocking:enabled"/>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml
index cc6be8c..49a57c2f 100644
--- a/tools/metrics/histograms/metadata/arc/histograms.xml
+++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -635,7 +635,10 @@
 </histogram>
 
 <histogram name="Arc.CupsPrinting.PageCount" units="units"
-    expires_after="2022-03-04">
+    expires_after="2020-10-04">
+  <obsolete>
+    Removed 2021-09.
+  </obsolete>
   <owner>skau@chromium.org</owner>
   <owner>vkuzkokov@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml
index 4b6351f..163a6bcc4 100644
--- a/tools/metrics/histograms/metadata/browser/histograms.xml
+++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -101,6 +101,7 @@
   <token key="Survey">
     <variant name=".General"/>
     <variant name=".OnboardingExperience"/>
+    <variant name=".SmartLock"/>
     <variant name=".Unlock"/>
   </token>
 </histogram>
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml
index 66a0c02..147cb2d 100644
--- a/tools/metrics/histograms/metadata/content/histograms.xml
+++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -1547,6 +1547,19 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSuggestions.Feed.WebFeed.NewFollow.IsRecommended"
+    enum="Boolean" expires_after="2022-09-01">
+  <owner>harringtond@chromium.org</owner>
+  <owner>feed@chromium.org</owner>
+  <summary>
+    Whether the followed web feed was recommended by the server.
+
+    Reported upon successfully following a web feed. Reported as 'true' if the
+    web feed was recommended, even if the user did not see or interact with
+    recommendation UI.
+  </summary>
+</histogram>
+
 <histogram name="ContentSuggestions.Feed.WebFeed.Opened" units="index"
     expires_after="never">
 <!-- expires-never: key feature metric.  We will need the Opened
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index ddeaee9..7f52c84 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -2664,6 +2664,9 @@
 
 <histogram name="PasswordProtection.AndroidVisualFeaturesNativeViewHeight"
     units="dip" expires_after="2021-10-04">
+  <obsolete>
+    Removed 09-2021
+  </obsolete>
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -2677,6 +2680,9 @@
 
 <histogram name="PasswordProtection.AndroidVisualFeaturesNativeViewNull"
     enum="BooleanNull" expires_after="2021-10-04">
+  <obsolete>
+    Removed 09-2021
+  </obsolete>
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -2690,6 +2696,9 @@
 
 <histogram name="PasswordProtection.AndroidVisualFeaturesNativeViewWidth"
     units="dip" expires_after="2021-10-04">
+  <obsolete>
+    Removed 09-2021
+  </obsolete>
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -2703,6 +2712,9 @@
 
 <histogram name="PasswordProtection.AndroidVisualFeaturesViewNull"
     enum="BooleanNull" expires_after="2021-10-04">
+  <obsolete>
+    Removed 09-2021
+  </obsolete>
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/sb_client/histograms.xml b/tools/metrics/histograms/metadata/sb_client/histograms.xml
index 48b67c2..8192e124 100644
--- a/tools/metrics/histograms/metadata/sb_client/histograms.xml
+++ b/tools/metrics/histograms/metadata/sb_client/histograms.xml
@@ -439,7 +439,7 @@
 </histogram>
 
 <histogram name="SBClientPhishing.CacheDetectsPhishing"
-    enum="BooleanIsPhishing" expires_after="2021-09-17">
+    enum="BooleanIsPhishing" expires_after="2022-09-17">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -501,7 +501,9 @@
 
 <histogram name="SBClientPhishing.ClientModelDownloadResponseOrErrorCode"
     enum="CombinedHttpResponseAndNetErrorCode" expires_after="M94">
-  <owner>drubery@google.com</owner>
+  <obsolete>
+    Remove 09-2021
+  </obsolete>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
     Response or error codes from the SafeBrowsing service. Logged after a
@@ -828,7 +830,7 @@
 </histogram>
 
 <histogram name="SBClientPhishing.TermFeatureChunkTime" units="ms"
-    expires_after="2021-10-17">
+    expires_after="2022-10-17">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -837,7 +839,7 @@
 </histogram>
 
 <histogram name="SBClientPhishing.TermFeatureIterations" units="units"
-    expires_after="2021-10-31">
+    expires_after="2022-10-17">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
@@ -846,7 +848,7 @@
 </histogram>
 
 <histogram name="SBClientPhishing.TermFeatureTimeout" units="units"
-    expires_after="2021-10-17">
+    expires_after="2022-10-17">
   <owner>drubery@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/software/histograms.xml b/tools/metrics/histograms/metadata/software/histograms.xml
index b5cf64c4..ab0993f 100644
--- a/tools/metrics/histograms/metadata/software/histograms.xml
+++ b/tools/metrics/histograms/metadata/software/histograms.xml
@@ -361,6 +361,9 @@
 
 <histogram name="SoftwareReporter.OnDemandUpdateRequired"
     enum="BooleanRequired" expires_after="M95">
+  <obsolete>
+    Removed 09-2021
+  </obsolete>
   <owner>drubery@chromium.org</owner>
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
@@ -372,7 +375,7 @@
 </histogram>
 
 <histogram name="SoftwareReporter.OnDemandUpdateSucceeded"
-    enum="BooleanSuccess" expires_after="M95">
+    enum="BooleanSuccess" expires_after="2022-08-25">
   <owner>drubery@chromium.org</owner>
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
@@ -384,7 +387,7 @@
 </histogram>
 
 <histogram name="SoftwareReporter.PostCleanupSettingsReset" units="counts"
-    expires_after="M95">
+    expires_after="2022-08-25">
   <owner>drubery@chromium.org</owner>
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
@@ -396,7 +399,7 @@
 </histogram>
 
 <histogram name="SoftwareReporter.PromptDialogResponse"
-    enum="SoftwareReporterPromptDialogResponse" expires_after="M95">
+    enum="SoftwareReporterPromptDialogResponse" expires_after="2022-08-25">
   <owner>drubery@chromium.org</owner>
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
@@ -409,6 +412,9 @@
 
 <histogram name="SoftwareReporter.PromptShownWithType"
     enum="SoftwareReporterPromptShownWithType" expires_after="M95">
+  <obsolete>
+    Removed 09-2021
+  </obsolete>
   <owner>drubery@chromium.org</owner>
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
@@ -423,7 +429,7 @@
 </histogram>
 
 <histogram name="SoftwareReporter.ReporterSequenceType"
-    enum="SoftwareReporterSequenceType" expires_after="M95">
+    enum="SoftwareReporterSequenceType" expires_after="2022-08-25">
   <owner>drubery@chromium.org</owner>
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
@@ -460,6 +466,9 @@
 
 <histogram name="SoftwareReporter.ScannerLogsAcceptance" enum="BooleanAccepted"
     expires_after="M95">
+  <obsolete>
+    Removed 09-2021
+  </obsolete>
   <owner>drubery@chromium.org</owner>
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
@@ -473,6 +482,9 @@
 
 <histogram name="SoftwareReporter.TaggedProfileForResetting" enum="Boolean"
     expires_after="M95">
+  <obsolete>
+    Removed 09-2021
+  </obsolete>
   <owner>drubery@chromium.org</owner>
   <owner>bdea@chromium.org</owner>
   <owner>chrome-safebrowsing-alerts@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/uma/histograms.xml b/tools/metrics/histograms/metadata/uma/histograms.xml
index 212ce46b..aeaf128 100644
--- a/tools/metrics/histograms/metadata/uma/histograms.xml
+++ b/tools/metrics/histograms/metadata/uma/histograms.xml
@@ -505,7 +505,7 @@
 </histogram>
 
 <histogram name="UMA.MetricsReporting.Toggle" enum="MetricsReportingChange"
-    expires_after="2021-10-31">
+    expires_after="2022-05-01">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -528,7 +528,7 @@
 </histogram>
 
 <histogram name="UMA.MetricsService.Initialize.Time" units="microseconds"
-    expires_after="2021-10-31">
+    expires_after="2022-05-01">
   <owner>asvitkine@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
   <summary>
@@ -550,7 +550,7 @@
 </histogram>
 
 <histogram name="UMA.NegativeSamples.Increment" units="increment"
-    expires_after="2021-10-31">
+    expires_after="2022-05-01">
   <owner>asvitkine@chromium.org</owner>
   <owner>bcwhite@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
@@ -560,7 +560,7 @@
 </histogram>
 
 <histogram name="UMA.NegativeSamples.Reason" enum="NegativeSampleReason"
-    expires_after="2021-10-31">
+    expires_after="2022-05-01">
   <owner>asvitkine@chromium.org</owner>
   <owner>bcwhite@chromium.org</owner>
   <owner>src/base/metrics/OWNERS</owner>
diff --git a/ui/base/ime/fuchsia/input_method_fuchsia.cc b/ui/base/ime/fuchsia/input_method_fuchsia.cc
index 7751b9f..20f0ccb 100644
--- a/ui/base/ime/fuchsia/input_method_fuchsia.cc
+++ b/ui/base/ime/fuchsia/input_method_fuchsia.cc
@@ -10,6 +10,7 @@
 #include <utility>
 
 #include "base/fuchsia/process_context.h"
+#include "base/logging.h"
 #include "ui/base/ime/text_input_client.h"
 #include "ui/events/base_event_utils.h"
 #include "ui/events/keycodes/dom/dom_code.h"
@@ -54,6 +55,8 @@
 }
 
 void InputMethodFuchsia::CancelComposition(const TextInputClient* client) {
+  DVLOG(1) << __func__;
+
   if (virtual_keyboard_controller_) {
     // FIDL asynchronicity makes it impossible to know whether a recent
     // visibility update might be in flight, so always call Dismiss.
@@ -62,6 +65,8 @@
 }
 
 void InputMethodFuchsia::OnTextInputTypeChanged(const TextInputClient* client) {
+  DVLOG(1) << __func__;
+
   InputMethodBase::OnTextInputTypeChanged(client);
 
   if (!virtual_keyboard_controller_)
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc
index fab6ad29..03a8fcd 100644
--- a/ui/base/ui_base_features.cc
+++ b/ui/base/ui_base_features.cc
@@ -92,13 +92,6 @@
 const base::Feature kSystemKeyboardLock{"SystemKeyboardLock",
                                         base::FEATURE_ENABLED_BY_DEFAULT};
 
-const base::Feature kNotificationIndicator = {"EnableNotificationIndicator",
-                                              base::FEATURE_ENABLED_BY_DEFAULT};
-
-bool IsNotificationIndicatorEnabled() {
-  return base::FeatureList::IsEnabled(kNotificationIndicator);
-}
-
 // Enables GPU rasterization for all UI drawing (where not blocklisted).
 const base::Feature kUiGpuRasterization = {"UiGpuRasterization",
 #if defined(OS_APPLE) || BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_FUCHSIA) || \
diff --git a/ui/base/ui_base_features.h b/ui/base/ui_base_features.h
index fefa70b4..fdd2755 100644
--- a/ui/base/ui_base_features.h
+++ b/ui/base/ui_base_features.h
@@ -38,12 +38,8 @@
 COMPONENT_EXPORT(UI_BASE_FEATURES)
 extern const base::Feature kSystemKeyboardLock;
 COMPONENT_EXPORT(UI_BASE_FEATURES)
-extern const base::Feature kNotificationIndicator;
-COMPONENT_EXPORT(UI_BASE_FEATURES)
 extern const base::Feature kUiCompositorScrollWithLayers;
 
-COMPONENT_EXPORT(UI_BASE_FEATURES) bool IsNotificationIndicatorEnabled();
-
 COMPONENT_EXPORT(UI_BASE_FEATURES) bool IsUiGpuRasterizationEnabled();
 
 #if defined(OS_WIN) || defined(OS_ANDROID)
diff --git a/ui/gfx/linux/gpu_memory_buffer_support_x11.cc b/ui/gfx/linux/gpu_memory_buffer_support_x11.cc
index 5b89bfd..aa5641c 100644
--- a/ui/gfx/linux/gpu_memory_buffer_support_x11.cc
+++ b/ui/gfx/linux/gpu_memory_buffer_support_x11.cc
@@ -11,6 +11,7 @@
 
 #include "base/containers/contains.h"
 #include "base/debug/crash_logging.h"
+#include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/buffer_types.h"
@@ -118,7 +119,10 @@
     gfx::BufferFormat format,
     const gfx::Size& size,
     gfx::BufferUsage usage) {
-  DCHECK(device_);
+  if (!device_) {
+    LOG(ERROR) << "Device could not be created.";
+    return nullptr;
+  }
   DCHECK(base::Contains(supported_configs_,
                         gfx::BufferUsageAndFormat(usage, format)));
 
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
index a039b40..8bb847d 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.cc
@@ -104,12 +104,12 @@
   DCHECK_EQ(state_, State::kIdle);
   DCHECK(!origin_window_);
 
-  origin_window_ = source == DragEventSource::kTouch
-                       ? window_manager_->GetCurrentTouchFocusedWindow()
-                       : window_manager_->GetCurrentPointerFocusedWindow();
-  if (!origin_window_) {
-    LOG(ERROR) << "Failed to get focused window. drag_source="
-               << static_cast<int>(source);
+  WaylandWindow* origin_window =
+      source == DragEventSource::kTouch
+          ? window_manager_->GetCurrentTouchFocusedWindow()
+          : window_manager_->GetCurrentPointerFocusedWindow();
+  if (!origin_window) {
+    LOG(ERROR) << "Failed to get focused window. source=" << source;
     return false;
   }
 
@@ -120,8 +120,7 @@
   // causing hangs as observerd in crbug.com/1209269.
   auto serial = GetAndValidateSerialForDrag(source);
   if (!serial.has_value()) {
-    LOG(ERROR) << "Invalid state when trying to start drag. source="
-               << static_cast<int>(source);
+    LOG(ERROR) << "Invalid state when trying to start drag. source=" << source;
     return false;
   }
 
@@ -137,7 +136,7 @@
     icon_surface_ = std::make_unique<WaylandSurface>(connection_, nullptr);
     if (icon_surface_->Initialize()) {
       // Corresponds to actual scale factor of the origin surface.
-      icon_surface_->SetSurfaceBufferScale(origin_window_->window_scale());
+      icon_surface_->SetSurfaceBufferScale(origin_window->window_scale());
     } else {
       LOG(ERROR) << "Failed to create drag icon surface.";
       icon_surface_.reset();
@@ -146,10 +145,11 @@
 
   // Starts the wayland drag session setting |this| object as delegate.
   state_ = State::kStarted;
-  data_device_->StartDrag(*data_source_, *origin_window_, serial->value,
+  data_device_->StartDrag(*data_source_, *origin_window, serial->value,
                           icon_surface_ ? icon_surface_->surface() : nullptr,
                           this);
 
+  origin_window_ = origin_window;
   window_manager_->AddObserver(this);
   return true;
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
index 8240102..8ffb84784 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller.h
@@ -102,6 +102,7 @@
   FRIEND_TEST_ALL_PREFIXES(WaylandDataDragControllerTest, ReceiveDrag);
   FRIEND_TEST_ALL_PREFIXES(WaylandDataDragControllerTest, StartDrag);
   FRIEND_TEST_ALL_PREFIXES(WaylandDataDragControllerTest, StartDragWithText);
+  FRIEND_TEST_ALL_PREFIXES(WaylandDataDragControllerTest, AsyncNoopStartDrag);
   FRIEND_TEST_ALL_PREFIXES(WaylandDataDragControllerTest,
                            StartDragWithWrongMimeType);
 
diff --git a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
index 6c264b4..dfb2b53d 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_drag_controller_unittest.cc
@@ -867,9 +867,9 @@
   FocusAndPressLeftPointerButton(window_.get(), &delegate_);
 
   // Emulate a "quick" wl_pointer.button release event being processed by the
-  // compositor, which leads to a no-op subsequent wl_data_device.start_drag.
-  // In this case, the client is expected to gracefully reset state and quit
-  // drag loop as if the drag session was cancelled as usual.
+  // compositor, which leads to a no-op subsequent WaylandWindow::StartDrag. In
+  // this case, the client is expected to gracefully reset state and quit drag
+  // loop as if the drag session was cancelled as usual.
   SendPointerButton(window_.get(), &delegate_, BTN_LEFT, /*pressed=*/false);
   Sync();
 
@@ -884,6 +884,8 @@
   Mock::VerifyAndClearExpectations(drop_handler_.get());
   Mock::VerifyAndClearExpectations(this);
 
+  EXPECT_FALSE(drag_controller()->origin_window_);
+
   window_->SetPointerFocus(restored_focus);
 }
 
diff --git a/ui/webui/resources/cr_components/BUILD.gn b/ui/webui/resources/cr_components/BUILD.gn
index 008b2c9bb..aff05f1 100644
--- a/ui/webui/resources/cr_components/BUILD.gn
+++ b/ui/webui/resources/cr_components/BUILD.gn
@@ -126,6 +126,7 @@
       "chromeos/bluetooth/bluetooth_icon.js",
       "chromeos/bluetooth/bluetooth_icons.js",
       "chromeos/bluetooth/bluetooth_pairing_device_selection_page.js",
+      "chromeos/bluetooth/bluetooth_pairing_request_code_page.js",
       "chromeos/bluetooth/bluetooth_pairing_device_item.js",
       "chromeos/bluetooth/bluetooth_pairing_ui.js",
       "chromeos/cellular_setup/activation_code_page.m.js",
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/BUILD.gn b/ui/webui/resources/cr_components/chromeos/bluetooth/BUILD.gn
index 88c251d..0f0bb7f1 100644
--- a/ui/webui/resources/cr_components/chromeos/bluetooth/BUILD.gn
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/BUILD.gn
@@ -87,9 +87,18 @@
   ]
 }
 
+js_library("bluetooth_pairing_request_code_page") {
+  deps = [
+    ":bluetooth_base_page",
+    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+    "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
+  ]
+}
+
 js_library("bluetooth_pairing_ui") {
   deps = [
     ":bluetooth_pairing_device_selection_page",
+    ":bluetooth_pairing_request_code_page",
     ":cros_bluetooth_config",
     "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
     "//ui/webui/resources/js:assert.m",
@@ -115,6 +124,7 @@
     "bluetooth_icon.js",
     "bluetooth_icons.js",
     "bluetooth_pairing_device_selection_page.js",
+    "bluetooth_pairing_request_code_page.js",
     "bluetooth_pairing_device_item.js",
     "bluetooth_pairing_ui.js",
     "bluetooth_base_page.js",
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_device_item.js b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_device_item.js
index b4ff61c..c852466 100644
--- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_device_item.js
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_device_item.js
@@ -71,7 +71,7 @@
     this.dispatchEvent(new CustomEvent('pair-device', {
       bubbles: true,
       composed: true,
-      detail: {deviceId: this.device.id},
+      detail: {device: this.device},
     }));
   }
 }
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page.html b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page.html
new file mode 100644
index 0000000..bf644e9
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page.html
@@ -0,0 +1,26 @@
+<style>
+  #pageBody {
+    align-items: center;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+  }
+
+  #message {
+    margin-bottom: 56px;
+  }
+
+  #pin {
+    width: 336px;
+  }
+</style>
+<bluetooth-base-page button-bar-state="[[buttonBarState_]]">
+  <div slot="page-body" id="pageBody">
+    <div id="message">
+      [[getMessage_(device.*)]]
+    </div>
+    <cr-input id="pin" minlength="1" maxlength="16" type="text"
+        auto-validate value="{{pinCode_}}">
+    </cr-input>
+  </div>
+</bluetooth-base-page>
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page.js b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page.js
new file mode 100644
index 0000000..b86a8e6
--- /dev/null
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_request_code_page.js
@@ -0,0 +1,100 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * UI element shown when authentication via PIN or PASSKEY is required
+ * during Bluetooth device pairing.
+ */
+
+import './bluetooth_base_page.js';
+import '../../../cr_elements/shared_style_css.m.js';
+import '../../../cr_elements/cr_input/cr_input.m.js';
+
+import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js';
+import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {ButtonBarState, ButtonState} from './bluetooth_types.js';
+import {mojoString16ToString} from './bluetooth_utils.js';
+
+/**
+ * @constructor
+ * @extends {PolymerElement}
+ * @implements {I18nBehaviorInterface}
+ */
+const SettingsBluetoothPairingRequestCodePageElementBase =
+    mixinBehaviors([I18nBehavior], PolymerElement);
+
+/** @polymer */
+export class SettingsBluetoothRequestCodePageElement extends
+    SettingsBluetoothPairingRequestCodePageElementBase {
+  static get is() {
+    return 'bluetooth-pairing-request-code-page';
+  }
+
+  static get template() {
+    return html`{__html_template__}`;
+  }
+
+  static get properties() {
+    return {
+      /**
+       * @type {?chromeos.bluetoothConfig.mojom.BluetoothDeviceProperties}
+       */
+      device: {
+        type: Object,
+        value: null,
+      },
+
+      /** @private {!ButtonBarState} */
+      buttonBarState_: {
+        type: Object,
+        computed: 'computeButtonBarState_(pinCode_)',
+      },
+
+      /** @private {string} */
+      pinCode_: {
+        type: String,
+        value: '',
+      }
+    };
+  }
+
+  /**
+   * @private
+   * @return {string}
+   */
+  getMessage_() {
+    return this.i18n('bluetoothEnterPin', this.getDeviceName_());
+  }
+
+  /**
+   * @private
+   * @return {string}
+   */
+  getDeviceName_() {
+    if (!this.device) {
+      return '';
+    }
+
+    return mojoString16ToString(this.device.publicName);
+  }
+
+  /**
+   * @return {!ButtonBarState}
+   * @private
+   */
+  computeButtonBarState_() {
+    const pairButtonState =
+        !this.pinCode_ ? ButtonState.DISABLED : ButtonState.ENABLED;
+
+    return {
+      cancel: ButtonState.ENABLED,
+      pair: pairButtonState,
+    };
+  }
+}
+
+customElements.define(
+    SettingsBluetoothRequestCodePageElement.is,
+    SettingsBluetoothRequestCodePageElement);
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.html b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.html
index 4712c68..d2e510ae 100644
--- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.html
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.html
@@ -7,11 +7,21 @@
   <iron-pages
       attr-for-selected="id"
       selected="[[selectedPageId_]]">
-    <bluetooth-pairing-device-selection-page
-        devices="[[discoveredDevices_]]"
-        on-pair-device="onPairDevice_"
-        id="deviceSelectionPage">
-    </bluetooth-pairing-device-selection-page>
+    <template is="dom-if" if="[[shouldShowSubpage_(
+        SubpageId.DEVICE_SELECTION_PAGE, selectedPageId_)]]" restamp>
+      <bluetooth-pairing-device-selection-page
+          devices="[[discoveredDevices_]]"
+          on-pair-device="onPairDevice_"
+          id="deviceSelectionPage">
+      </bluetooth-pairing-device-selection-page>
+    </template>
+    <template is="dom-if" if="[[shouldShowSubpage_(
+        SubpageId.DEVICE_REQUEST_CODE_PAGE, selectedPageId_)]]" restamp>
+      <bluetooth-pairing-request-code-page
+          device="[[selectedDevice_]]"
+          id="deviceRequestCodePage">
+      </bluetooth-pairing-request-code-page>
+    </template>
     <!-- TODO(crbug.com/1010321): Add other bluetooth pairing subpage UI elements. -->
   </iron-pages>
 </div>
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js
index 2651fae0..ab9f8e2 100644
--- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js
+++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js
@@ -8,8 +8,8 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import './bluetooth_base_page.js';
 import './bluetooth_pairing_device_selection_page.js';
+import './bluetooth_pairing_request_code_page.js';
 
 import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 import {assert} from '../../../js/assert.m.js';
@@ -19,6 +19,7 @@
 const BluetoothPairingSubpageId = {
   // TODO(crbug.com/1010321): Add missing bluetooth pairing subpages.
   DEVICE_SELECTION_PAGE: 'deviceSelectionPage',
+  DEVICE_REQUEST_CODE_PAGE: 'deviceRequestCodePage',
 };
 
 /**
@@ -53,6 +54,23 @@
         type: Array,
         value: [],
       },
+
+      /**
+       * @private {?chromeos.bluetoothConfig.mojom.BluetoothDeviceProperties}
+       */
+      devicePendingPairing_: {
+        type: Object,
+        value: null,
+      },
+
+      /**
+       * Used to access |BluetoothPairingSubpageId| type in HTML.
+       * @private {!BluetoothPairingSubpageId}
+       */
+      SubpageId: {
+        type: Object,
+        value: BluetoothPairingSubpageId,
+      },
     };
   }
 
@@ -98,7 +116,8 @@
   }
 
   /**
-   * @param {!CustomEvent<!{deviceId: string}>} event
+   * @param {!CustomEvent<!{device:
+   *     chromeos.bluetoothConfig.mojom.BluetoothDeviceProperties}>} event
    * @private
    */
   onPairDevice_(event) {
@@ -110,9 +129,15 @@
 
     this.pairingDelegateReceiver_ =
         new chromeos.bluetoothConfig.mojom.DevicePairingDelegateReceiver(this);
+
+    // TODO(crbug.com/1010321): Add test for |devicePendingPairing_| when
+    // request code page UI is added.
+    this.devicePendingPairing_ = event.detail.device;
+    assert(this.devicePendingPairing_);
+
     this.devicePairingHandler_
         .pairDevice(
-            event.detail.deviceId,
+            this.devicePendingPairing_.id,
             this.pairingDelegateReceiver_.$.bindNewPipeAndPassRemote())
         .then(result => {
           this.handlePairDeviceResult_(result.result);
@@ -125,6 +150,7 @@
    */
   handlePairDeviceResult_(result) {
     this.pairingDelegateReceiver_ = null;
+    this.devicePendingPairing_ = null;
 
     if (result === chromeos.bluetoothConfig.mojom.PairingResult.kSuccess) {
       this.dispatchEvent(new CustomEvent('finished', {
@@ -170,6 +196,15 @@
   authorizePairing() {
     // TODO(crbug.com/1010321): Implement this function.
   }
+
+  /**
+   * @param {!BluetoothPairingSubpageId} subpageId
+   * @return {boolean}
+   * @private
+   */
+  shouldShowSubpage_(subpageId) {
+    return this.selectedPageId_ === subpageId;
+  }
 }
 
 customElements.define(
diff --git a/url/DIR_METADATA b/url/DIR_METADATA
index 6d266b0..16c80be 100644
--- a/url/DIR_METADATA
+++ b/url/DIR_METADATA
@@ -7,5 +7,5 @@
 #   https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
 
 monorail {
-  component: "Internals>Core"
+  component: "Blink>Network"
 }
\ No newline at end of file